~ubuntu-branches/debian/jessie/scummvm/jessie

« back to all changes in this revision

Viewing changes to engines/hugo/inventory.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Moritz Muehlenhoff
  • Date: 2011-05-25 19:02:23 UTC
  • mto: This revision was merged to the branch mainline in revision 23.
  • Revision ID: james.westby@ubuntu.com-20110525190223-fiqm0oaec714xk31
Tags: upstream-1.3.0
ImportĀ upstreamĀ versionĀ 1.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 * along with this program; if not, write to the Free Software
19
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
20
 *
21
 
 * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/tags/release-1-2-1/engines/hugo/inventory.cpp $
22
 
 * $Id: inventory.cpp 52177 2010-08-17 23:55:31Z drmccoy $
 
21
 * $URL$
 
22
 * $Id$
23
23
 *
24
24
 */
25
25
 
30
30
 *
31
31
 */
32
32
 
 
33
#include "common/debug.h"
33
34
#include "common/system.h"
34
35
 
35
36
#include "hugo/hugo.h"
40
41
#include "hugo/mouse.h"
41
42
#include "hugo/inventory.h"
42
43
#include "hugo/parser.h"
 
44
#include "hugo/object.h"
43
45
 
44
46
namespace Hugo {
45
47
 
46
 
#define MAX_DISP       (XPIX / INV_DX)              // Max icons displayable
47
 
 
48
 
InventoryHandler::InventoryHandler(HugoEngine &vm) : _vm(vm) {
49
 
}
50
 
 
51
 
// Construct the inventory scrollbar in dib_i
52
 
// imageTotNumb is total number of inventory icons
53
 
// displayNumb is number requested for display
54
 
// scrollFl is TRUE if scroll arrows required
55
 
// firstObjId is index of first (scrolled) inventory object to display
56
 
void InventoryHandler::constructInventory(int16 imageTotNumb, int displayNumb, bool scrollFl, int16 firstObjId) {
57
 
        int16 ux, uy, ix;                           // Coordinates of icons
58
 
 
 
48
static const int kMaxDisp = (kXPix / kInvDx);       // Max icons displayable
 
49
 
 
50
InventoryHandler::InventoryHandler(HugoEngine *vm) : _vm(vm), _invent(0) {
 
51
        _firstIconId = 0;
 
52
        _inventoryState  = kInventoryOff;               // Inventory icon bar state
 
53
        _inventoryHeight = 0;                           // Inventory icon bar pos
 
54
        _inventoryObjId  = -1;                          // Inventory object selected (none)
 
55
        _maxInvent = 0;
 
56
}
 
57
 
 
58
void InventoryHandler::setInventoryObjId(int16 objId) {
 
59
        _inventoryObjId = objId;
 
60
}
 
61
 
 
62
void InventoryHandler::setInventoryState(istate_t state) {
 
63
        _inventoryState = state;
 
64
}
 
65
 
 
66
void InventoryHandler::freeInvent() {
 
67
        free(_invent);
 
68
}
 
69
 
 
70
int16 InventoryHandler::getInventoryObjId() const {
 
71
        return _inventoryObjId;
 
72
}
 
73
 
 
74
istate_t InventoryHandler::getInventoryState() const {
 
75
        return _inventoryState;
 
76
}
 
77
 
 
78
/**
 
79
 * Read _invent from Hugo.dat
 
80
 */
 
81
void InventoryHandler::loadInvent(Common::SeekableReadStream &in) {
 
82
        for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
 
83
                int16 numElem = in.readUint16BE();
 
84
                if (varnt == _vm->_gameVariant) {
 
85
                        _maxInvent = numElem;
 
86
                        _invent = (int16 *)malloc(sizeof(int16) * numElem);
 
87
                        for (int i = 0; i < numElem; i++)
 
88
                                _invent[i] = in.readSint16BE();
 
89
                } else {
 
90
                        in.skip(numElem * sizeof(int16));
 
91
                }
 
92
        }
 
93
}
 
94
 
 
95
/**
 
96
 * Construct the inventory scrollbar in dib_i
 
97
 * imageTotNumb is total number of inventory icons
 
98
 * displayNumb is number requested for display
 
99
 * scrollFl is TRUE if scroll arrows required
 
100
 * firstObjId is index of first (scrolled) inventory object to display
 
101
 */
 
102
void InventoryHandler::constructInventory(const int16 imageTotNumb, int displayNumb, const bool scrollFl, int16 firstObjId) {
59
103
        debugC(1, kDebugInventory, "constructInventory(%d, %d, %d, %d)", imageTotNumb, displayNumb, (scrollFl) ? 0 : 1, firstObjId);
60
104
 
61
105
        // Clear out icon buffer
62
 
        memset(_vm.screen().getIconBuffer(), 0, sizeof(_vm.screen().getIconBuffer()));
 
106
        memset(_vm->_screen->getIconBuffer(), 0, sizeof(_vm->_screen->getIconBuffer()));
63
107
 
64
108
        // If needed, copy arrows - reduce number of icons displayable
65
109
        if (scrollFl) { // Display at first and last icon positions
66
 
                _vm.screen().moveImage(_vm.screen().getGUIBuffer(), 0, 0, INV_DX, INV_DY, XPIX, _vm.screen().getIconBuffer(), 0, 0, XPIX);
67
 
                _vm.screen().moveImage(_vm.screen().getGUIBuffer(), INV_DX, 0, INV_DX, INV_DY, XPIX, _vm.screen().getIconBuffer(), INV_DX *(MAX_DISP - 1), 0, XPIX);
68
 
                displayNumb = MIN(displayNumb, MAX_DISP - NUM_ARROWS);
 
110
                _vm->_screen->moveImage(_vm->_screen->getGUIBuffer(), 0, 0, kInvDx, kInvDy, kXPix, _vm->_screen->getIconBuffer(), 0, 0, kXPix);
 
111
                _vm->_screen->moveImage(_vm->_screen->getGUIBuffer(), kInvDx, 0, kInvDx, kInvDy, kXPix, _vm->_screen->getIconBuffer(), kInvDx *(kMaxDisp - 1), 0, kXPix);
 
112
                displayNumb = MIN(displayNumb, kMaxDisp - kArrowNumb);
69
113
        } else  // No, override first index - we can show 'em all!
70
114
                firstObjId = 0;
71
115
 
72
116
        // Copy inventory icons to remaining positions
73
117
        int16 displayed = 0;
74
118
        int16 carried = 0;
75
 
        for (int16 i = 0; i < imageTotNumb; i++) {
76
 
                if (_vm._objects[_vm._invent[i]].carriedFl) {
 
119
        for (int16 i = 0; (i < imageTotNumb) && (displayed < displayNumb); i++) {
 
120
                if (_vm->_object->isCarried(_invent[i])) {
77
121
                        // Check still room to display and past first scroll index
78
122
                        if (displayed < displayNumb && carried >= firstObjId) {
79
123
                                // Compute source coordinates in dib_u
80
 
                                ux = (i + NUM_ARROWS) * INV_DX % XPIX;
81
 
                                uy = (i + NUM_ARROWS) * INV_DX / XPIX * INV_DY;
 
124
                                int16 ux = (i + kArrowNumb) * kInvDx % kXPix;
 
125
                                int16 uy = (i + kArrowNumb) * kInvDx / kXPix * kInvDy;
82
126
 
83
127
                                // Compute dest coordinates in dib_i
84
 
                                ix = ((scrollFl) ? displayed + 1 : displayed) * INV_DX;
85
 
                                displayed++;        // Count number displayed
 
128
                                int16 ix = ((scrollFl) ? displayed + 1 : displayed) * kInvDx;
 
129
                                displayed++;                        // Count number displayed
86
130
 
87
131
                                // Copy the icon
88
 
                                _vm.screen().moveImage(_vm.screen().getGUIBuffer(), ux, uy, INV_DX, INV_DY, XPIX, _vm.screen().getIconBuffer(), ix, 0, XPIX);
 
132
                                _vm->_screen->moveImage(_vm->_screen->getGUIBuffer(), ux, uy, kInvDx, kInvDy, kXPix, _vm->_screen->getIconBuffer(), ix, 0, kXPix);
89
133
                        }
90
134
                        carried++;                              // Count number carried
91
135
                }
92
136
        }
93
137
}
94
138
 
95
 
// Process required action for inventory
96
 
// Returns objId under cursor (or -1) for INV_GET
97
 
int16 InventoryHandler::processInventory(invact_t action, ...) {
98
 
        static int16 firstIconId = 0;                   // Index of first icon to display
99
 
        int16 i, j;
100
 
        int16 objId = -1;                               // Return objid under cursor
 
139
/**
 
140
 * Process required action for inventory
 
141
 * Returns objId under cursor (or -1) for INV_GET
 
142
 */
 
143
int16 InventoryHandler::processInventory(const invact_t action, ...) {
 
144
        debugC(1, kDebugInventory, "processInventory(invact_t action, ...)");
 
145
 
101
146
        int16 imageNumb;                                // Total number of inventory items
102
147
        int displayNumb;                                // Total number displayed/carried
103
 
        int16 cursorx, cursory;                         // Current cursor position
104
 
        bool scrollFl;                                  // TRUE if scroll arrows needed
105
 
        va_list marker;                                 // Args used for D_ADD operation
106
 
 
107
 
        debugC(1, kDebugInventory, "processInventory(invact_t action, ...)");
108
 
 
109
148
        // Compute total number and number displayed, i.e. number carried
110
 
        for (imageNumb = 0, displayNumb = 0; imageNumb < _vm._maxInvent && _vm._invent[imageNumb] != -1; imageNumb++)
111
 
                if (_vm._objects[_vm._invent[imageNumb]].carriedFl)
 
149
        for (imageNumb = 0, displayNumb = 0; imageNumb < _maxInvent && _invent[imageNumb] != -1; imageNumb++) {
 
150
                if (_vm->_object->isCarried(_invent[imageNumb]))
112
151
                        displayNumb++;
 
152
        }
113
153
 
114
154
        // Will we need the scroll arrows?
115
 
        scrollFl = displayNumb > MAX_DISP;
 
155
        bool scrollFl = displayNumb > kMaxDisp;
 
156
        va_list marker;                                 // Args used for D_ADD operation
 
157
        int16 cursorx, cursory;                         // Current cursor position
 
158
        int16 objId = -1;                               // Return objid under cursor
116
159
 
117
160
        switch (action) {
118
 
        case INV_INIT:                                  // Initialize inventory display
119
 
                constructInventory(imageNumb, displayNumb, scrollFl, firstIconId);
120
 
                break;
121
 
        case INV_LEFT:                                  // Scroll left by one icon
122
 
                firstIconId = MAX(0, firstIconId - 1);
123
 
                constructInventory(imageNumb, displayNumb, scrollFl, firstIconId);
124
 
                break;
125
 
        case INV_RIGHT:                                 // Scroll right by one icon
126
 
                firstIconId = MIN(displayNumb, firstIconId + 1);
127
 
                constructInventory(imageNumb, displayNumb, scrollFl, firstIconId);
128
 
                break;
129
 
        case INV_GET:                                   // Return object id under cursor
 
161
        case kInventoryActionInit:                      // Initialize inventory display
 
162
                constructInventory(imageNumb, displayNumb, scrollFl, _firstIconId);
 
163
                break;
 
164
        case kInventoryActionLeft:                      // Scroll left by one icon
 
165
                _firstIconId = MAX(0, _firstIconId - 1);
 
166
                constructInventory(imageNumb, displayNumb, scrollFl, _firstIconId);
 
167
                break;
 
168
        case kInventoryActionRight:                     // Scroll right by one icon
 
169
                _firstIconId = MIN(displayNumb, _firstIconId + 1);
 
170
                constructInventory(imageNumb, displayNumb, scrollFl, _firstIconId);
 
171
                break;
 
172
        case kInventoryActionGet:                       // Return object id under cursor
130
173
                // Get cursor position from variable argument list
131
174
                va_start(marker, action);                   // Initialize variable arguments
132
175
                cursorx = va_arg(marker, int);              // Cursor x
133
176
                cursory = va_arg(marker, int);              // Cursor y
134
177
                va_end(marker);                             // Reset variable arguments
135
178
 
136
 
                cursory -= DIBOFF_Y;                        // Icon bar is at true zero
137
 
                if (cursory > 0 && cursory < INV_DY) {      // Within icon bar?
138
 
                        i = cursorx / INV_DX;                   // Compute icon index
139
 
                        if (scrollFl) {                          // Scroll buttons displayed
140
 
                                if (i == 0)                         // Left scroll button
141
 
                                        objId = LEFT_ARROW;
142
 
                                else {
143
 
                                        if (i == MAX_DISP - 1)          // Right scroll button
144
 
                                                objId = RIGHT_ARROW;
 
179
                cursory -= kDibOffY;                        // Icon bar is at true zero
 
180
                if (cursory > 0 && cursory < kInvDy) {      // Within icon bar?
 
181
                        int16 i = cursorx / kInvDx;             // Compute icon index
 
182
                        if (scrollFl) {                         // Scroll buttons displayed
 
183
                                if (i == 0) {                       // Left scroll button
 
184
                                        objId = kLeftArrow;
 
185
                                } else {
 
186
                                        if (i == kMaxDisp - 1)          // Right scroll button
 
187
                                                objId = kRightArrow;
145
188
                                        else                            // Adjust for scroll
146
 
                                                i += firstIconId - 1;       // i is icon index
 
189
                                                i += _firstIconId - 1;      // i is icon index
147
190
                                }
148
191
                        }
149
192
 
150
193
                        // If not an arrow, find object id - limit to valid range
151
 
                        if (objId == -1 && i < displayNumb)
 
194
                        if (objId == -1 && i < displayNumb) {
152
195
                                // Find objid by counting # carried objects == i+1
153
 
                                for (j = 0, i++; i > 0 && j < _vm._numObj; j++)
154
 
                                        if (_vm._objects[j].carriedFl)
 
196
                                int16 j;
 
197
                                for (j = 0, i++; i > 0 && j < _vm->_object->_numObj; j++) {
 
198
                                        if (_vm->_object->isCarried(j)) {
155
199
                                                if (--i == 0)
156
200
                                                        objId = j;
 
201
                                        }
 
202
                                }
 
203
                        }
157
204
                }
158
205
                break;
159
206
        }
160
 
        return objId;               // For the INV_GET action
 
207
        return objId;                                   // For the INV_GET action
161
208
}
162
209
 
 
210
/**
 
211
 * Process inventory state machine
 
212
 */
163
213
void InventoryHandler::runInventory() {
164
 
        status_t &gameStatus = _vm.getGameStatus();
 
214
        status_t &gameStatus = _vm->getGameStatus();
165
215
 
166
216
        debugC(1, kDebugInventory, "runInventory");
167
217
 
168
 
// Process inventory state machine
169
 
        switch (gameStatus.inventoryState) {
170
 
        case I_OFF:                                     // Icon bar off screen
 
218
        switch (_inventoryState) {
 
219
        case kInventoryOff:                             // Icon bar off screen
171
220
                break;
172
 
        case I_UP:                                      // Icon bar moving up
173
 
                gameStatus.inventoryHeight -= STEP_DY;      // Move the icon bar up
174
 
                if (gameStatus.inventoryHeight <= 0)        // Limit travel
175
 
                        gameStatus.inventoryHeight = 0;
 
221
        case kInventoryUp:                              // Icon bar moving up
 
222
                _inventoryHeight -= kStepDy;                // Move the icon bar up
 
223
                if (_inventoryHeight <= 0)                  // Limit travel
 
224
                        _inventoryHeight = 0;
176
225
 
177
226
                // Move visible portion to _frontBuffer, restore uncovered portion, display results
178
 
                _vm.screen().moveImage(_vm.screen().getIconBuffer(), 0, 0, XPIX, gameStatus.inventoryHeight, XPIX, _vm.screen().getFrontBuffer(), 0, DIBOFF_Y, XPIX);
179
 
                _vm.screen().moveImage(_vm.screen().getBackBufferBackup(), 0, gameStatus.inventoryHeight + DIBOFF_Y, XPIX, STEP_DY, XPIX, _vm.screen().getFrontBuffer(), 0, gameStatus.inventoryHeight + DIBOFF_Y, XPIX);
180
 
                _vm.screen().displayRect(0, DIBOFF_Y, XPIX, gameStatus.inventoryHeight + STEP_DY);
 
227
                _vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, kXPix, _inventoryHeight, kXPix, _vm->_screen->getFrontBuffer(), 0, kDibOffY, kXPix);
 
228
                _vm->_screen->moveImage(_vm->_screen->getBackBufferBackup(), 0, _inventoryHeight + kDibOffY, kXPix, kStepDy, kXPix, _vm->_screen->getFrontBuffer(), 0, _inventoryHeight + kDibOffY, kXPix);
 
229
                _vm->_screen->displayRect(0, kDibOffY, kXPix, _inventoryHeight + kStepDy);
181
230
 
182
 
                if (gameStatus.inventoryHeight == 0) {      // Finished moving up?
 
231
                if (_inventoryHeight == 0) {                // Finished moving up?
183
232
                        // Yes, restore dibs and exit back to game state machine
184
 
                        _vm.screen().moveImage(_vm.screen().getBackBufferBackup(), 0, 0, XPIX, YPIX, XPIX, _vm.screen().getBackBuffer(), 0, 0, XPIX);
185
 
                        _vm.screen().moveImage(_vm.screen().getBackBuffer(), 0, 0, XPIX, YPIX, XPIX, _vm.screen().getFrontBuffer(), 0, 0, XPIX);
186
 
                        _vm.updateImages();                     // Add objects back into display list for restore
187
 
                        gameStatus.inventoryState = I_OFF;
188
 
                        gameStatus.viewState = V_PLAY;
 
233
                        _vm->_screen->moveImage(_vm->_screen->getBackBufferBackup(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getBackBuffer(), 0, 0, kXPix);
 
234
                        _vm->_screen->moveImage(_vm->_screen->getBackBuffer(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getFrontBuffer(), 0, 0, kXPix);
 
235
                        _vm->_object->updateImages();           // Add objects back into display list for restore
 
236
                        _inventoryState = kInventoryOff;
 
237
                        gameStatus.viewState = kViewPlay;
189
238
                }
190
239
                break;
191
 
        case I_DOWN:                                    // Icon bar moving down
 
240
        case kInventoryDown:                            // Icon bar moving down
192
241
                // If this is the first step, initialize dib_i
193
242
                // and get any icon/text out of _frontBuffer
194
 
                if (gameStatus.inventoryHeight == 0) {
195
 
                        processInventory(INV_INIT);             // Initialize dib_i
196
 
                        _vm.screen().displayList(D_RESTORE);    // Restore _frontBuffer
197
 
                        _vm.updateImages();                     // Rebuild _frontBuffer without icons/text
198
 
                        _vm.screen().displayList(D_DISPLAY);    // Blit display list to screen
 
243
                if (_inventoryHeight == 0) {
 
244
                        processInventory(kInventoryActionInit); // Initialize dib_i
 
245
                        _vm->_screen->displayList(kDisplayRestore); // Restore _frontBuffer
 
246
                        _vm->_object->updateImages();           // Rebuild _frontBuffer without icons/text
 
247
                        _vm->_screen->displayList(kDisplayDisplay); // Blit display list to screen
199
248
                }
200
249
 
201
 
                gameStatus.inventoryHeight += STEP_DY;      // Move the icon bar down
202
 
                if (gameStatus.inventoryHeight >= INV_DY)   // Limit travel
203
 
                        gameStatus.inventoryHeight = INV_DY;
 
250
                _inventoryHeight += kStepDy;                // Move the icon bar down
 
251
                if (_inventoryHeight > kInvDy)              // Limit travel
 
252
                        _inventoryHeight = kInvDy;
204
253
 
205
254
                // Move visible portion to _frontBuffer, display results
206
 
                _vm.screen().moveImage(_vm.screen().getIconBuffer(), 0, 0, XPIX, gameStatus.inventoryHeight, XPIX, _vm.screen().getFrontBuffer(), 0, DIBOFF_Y, XPIX);
207
 
                _vm.screen().displayRect(0, DIBOFF_Y, XPIX, gameStatus.inventoryHeight);
 
255
                _vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, kXPix, _inventoryHeight, kXPix, _vm->_screen->getFrontBuffer(), 0, kDibOffY, kXPix);
 
256
                _vm->_screen->displayRect(0, kDibOffY, kXPix, _inventoryHeight);
208
257
 
209
 
                if (gameStatus.inventoryHeight == INV_DY) { // Finished moving down?
 
258
                if (_inventoryHeight == kInvDy) {           // Finished moving down?
210
259
                        // Yes, prepare view dibs for special inventory display since
211
260
                        // we can't refresh objects while icon bar overlayed...
212
261
                        // 1. Save backing store _backBuffer in temporary dib_c
213
262
                        // 2. Make snapshot of _frontBuffer the new _backBuffer backing store
214
263
                        // 3. Reset the display list
215
 
                        _vm.screen().moveImage(_vm.screen().getBackBuffer(), 0, 0, XPIX, YPIX, XPIX, _vm.screen().getBackBufferBackup(), 0, 0, XPIX);
216
 
                        _vm.screen().moveImage(_vm.screen().getFrontBuffer(), 0, 0, XPIX, YPIX, XPIX, _vm.screen().getBackBuffer(), 0, 0, XPIX);
217
 
                        _vm.screen().displayList(D_INIT);
218
 
                        gameStatus.inventoryState = I_ACTIVE;
 
264
                        _vm->_screen->moveImage(_vm->_screen->getBackBuffer(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getBackBufferBackup(), 0, 0, kXPix);
 
265
                        _vm->_screen->moveImage(_vm->_screen->getFrontBuffer(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getBackBuffer(), 0, 0, kXPix);
 
266
                        _vm->_screen->displayList(kDisplayInit);
 
267
                        _inventoryState = kInventoryActive;
219
268
                }
220
269
                break;
221
 
        case I_ACTIVE:                                  // Inventory active
222
 
                _vm.parser().charHandler();                 // Still allow commands
223
 
                _vm.screen().displayList(D_RESTORE);        // Restore previous background
224
 
                _vm.mouse().mouseHandler();                 // Mouse activity - adds to display list
225
 
                _vm.screen().displayList(D_DISPLAY);        // Blit the display list to screen
 
270
        case kInventoryActive:                          // Inventory active
 
271
                _vm->_parser->charHandler();                // Still allow commands
 
272
                _vm->_screen->displayList(kDisplayRestore); // Restore previous background
 
273
                _vm->_screen->displayList(kDisplayDisplay); // Blit the display list to screen
226
274
                break;
227
275
        }
228
276
}
229
277
 
 
278
 
 
279
/**
 
280
 * Find index of dragged icon
 
281
 */
 
282
int16 InventoryHandler::findIconId(int16 objId) {
 
283
        int16 iconId = 0;
 
284
        for (; iconId < _maxInvent; iconId++) {
 
285
                if (objId == _invent[iconId])
 
286
                        break;
 
287
        }
 
288
 
 
289
        return iconId;
 
290
}
 
291
 
230
292
} // End of namespace Hugo