diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/hugo/display.cpp | 121 | ||||
-rw-r--r-- | engines/hugo/display.h | 13 | ||||
-rw-r--r-- | engines/hugo/engine.cpp | 335 | ||||
-rw-r--r-- | engines/hugo/file.cpp | 331 | ||||
-rw-r--r-- | engines/hugo/file.h | 29 | ||||
-rw-r--r-- | engines/hugo/game.h | 4 | ||||
-rw-r--r-- | engines/hugo/global.h | 13 | ||||
-rw-r--r-- | engines/hugo/hugo.cpp | 57 | ||||
-rw-r--r-- | engines/hugo/hugo.h | 2 | ||||
-rw-r--r-- | engines/hugo/intro.cpp | 2 | ||||
-rw-r--r-- | engines/hugo/inventory.cpp | 45 | ||||
-rw-r--r-- | engines/hugo/mouse.cpp | 65 | ||||
-rw-r--r-- | engines/hugo/parser.cpp | 197 | ||||
-rw-r--r-- | engines/hugo/route.cpp | 149 | ||||
-rw-r--r-- | engines/hugo/schedule.cpp | 104 | ||||
-rw-r--r-- | engines/hugo/schedule.h | 20 | ||||
-rw-r--r-- | engines/hugo/sound.cpp | 6 | ||||
-rw-r--r-- | engines/hugo/util.cpp | 57 | ||||
-rw-r--r-- | engines/hugo/util.h | 2 |
19 files changed, 744 insertions, 808 deletions
diff --git a/engines/hugo/display.cpp b/engines/hugo/display.cpp index 4493c756b3..74b9d4636b 100644 --- a/engines/hugo/display.cpp +++ b/engines/hugo/display.cpp @@ -50,13 +50,6 @@ namespace Hugo { #define INY(Y, B) (Y >= B->y && Y <= B->y + B->dy) #define OVERLAP(A, B) ((INX(A->x, B) || INX(A->x + A->dx, B) || INX(B->x, A) || INX(B->x + B->dx, A)) && (INY(A->y, B) || INY(A->y + A->dy, B) || INY(B->y, A) || INY(B->y + B->dy, A))) -struct rect_t { // Rectangle used in Display list - int16 x; // Position in dib - int16 y; // Position in dib - int16 dx; // width - int16 dy; // height -}; - Screen::Screen(HugoEngine &vm) : _vm(vm) { } @@ -78,17 +71,16 @@ void Screen::initDisplay() { // Move an image from source to destination void Screen::moveImage(image_pt srcImage, uint16 x1, uint16 y1, uint16 dx, uint16 dy, uint16 width1, image_pt dstImage, uint16 x2, uint16 y2, uint16 width2) { + debugC(3, kDebugDisplay, "moveImage(srcImage, %d, %d, %d, %d, %d, dstImage, %d, %d, %d)", x1, y1, dx, dy, width1, x2, y2, width2); + int16 wrap_src = width1 - dx; // Wrap to next src row int16 wrap_dst = width2 - dx; // Wrap to next dst row - int16 x; - - debugC(3, kDebugDisplay, "moveImage(srcImage, %d, %d, %d, %d, %d, dstImage, %d, %d, %d)", x1, y1, dx, dy, width1, x2, y2, width2); srcImage += y1 * width1 + x1; // Offset into src image dstImage += y2 * width2 + x2; // offset into dst image while (dy--) { // For each row - for (x = dx; x--;) // For each column + for (int16 x = dx; x--;) // For each column *dstImage++ = *srcImage++; srcImage += wrap_src; // Wrap to next line dstImage += wrap_dst; @@ -157,24 +149,17 @@ overlayState_t Screen::findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) { // Merge an object frame into _frontBuffer at sx, sy and update rectangle list. // If fore TRUE, force object above any overlay void Screen::displayFrame(int sx, int sy, seq_t *seq, bool foreFl) { - overlayState_t overlayState = UNDEF; // Overlay state of object - image_pt image; // Ptr to object image data - image_pt subFrontBuffer; // Ptr to offset in _frontBuffer - image_pt overlay; // Ptr to overlay data - int16 frontBufferwrap; // Wrap dst_p to next line - int16 imageWrap; // Wrap src_p to next line - uint16 x, y; // Index into object data - debugC(3, kDebugDisplay, "displayFrame(%d, %d, seq, %d)", sx, sy, (foreFl) ? 1 : 0); - image = seq->imagePtr; // Source ptr - subFrontBuffer = &_frontBuffer[sy * XPIX + sx]; // Destination ptr - overlay = &_vm.getFirstOverlay()[(sy * XPIX + sx) >> 3]; // Overlay ptr - frontBufferwrap = XPIX - seq->x2 - 1; // Wraps dest_p after each line - imageWrap = seq->bytesPerLine8 - seq->x2 - 1; + image_pt image = seq->imagePtr; // Ptr to object image data + image_pt subFrontBuffer = &_frontBuffer[sy * XPIX + sx]; // Ptr to offset in _frontBuffer + image_pt overlay = &_vm.getFirstOverlay()[(sy * XPIX + sx) >> 3]; // Ptr to overlay data + int16 frontBufferwrap = XPIX - seq->x2 - 1; // Wraps dest_p after each line + int16 imageWrap = seq->bytesPerLine8 - seq->x2 - 1; - for (y = 0; y < seq->lines; y++) { // Each line in object - for (x = 0; x <= seq->x2; x++) { + overlayState_t overlayState = UNDEF; // Overlay state of object + for (uint16 y = 0; y < seq->lines; y++) { // Each line in object + for (uint16 x = 0; x <= seq->x2; x++) { if (*image) { // Non-transparent overlay = _vm.getFirstOverlay() + ((uint16)(subFrontBuffer - _frontBuffer) >> 3); // Ptr into overlay bits if (*overlay & (0x80 >> ((uint16)(subFrontBuffer - _frontBuffer) & 7))) { // Overlay bit is set @@ -182,8 +167,9 @@ void Screen::displayFrame(int sx, int sy, seq_t *seq, bool foreFl) { overlayState = findOvl(seq, subFrontBuffer, y);// No, find it. if (foreFl || overlayState == FG) // Object foreground *subFrontBuffer = *image; // Copy pixel - } else // No overlay + } else { // No overlay *subFrontBuffer = *image; // Copy pixel + } } image++; subFrontBuffer++; @@ -216,24 +202,24 @@ void Screen::merge(rect_t *rectA, rect_t *rectB) { // of blist. bmax is the max size of the blist. Note that blist can // have holes, in which case dx = 0. Returns used length of blist. int16 Screen::mergeLists(rect_t *list, rect_t *blist, int16 len, int16 blen, int16 bmax) { - int16 coalesce[BMAX]; // List of overlapping rects - debugC(4, kDebugDisplay, "mergeLists"); + int16 coalesce[BMAX]; // List of overlapping rects // Process the list for (int16 a = 0; a < len; a++, list++) { // Compile list of overlapping rectangles in blit list int16 c = 0; rect_t *bp = blist; - for (int16 b = 0; b < blen; b++, bp++) + for (int16 b = 0; b < blen; b++, bp++) { if (bp->dx) // blist entry used if (OVERLAP(list, bp)) coalesce[c++] = b; - + } + // Any overlapping blit rects? - if (c == 0) // None, add a new entry + if (c == 0) { // None, add a new entry blist[blen++] = *list; - else { // At least one overlapping + } else { // At least one overlapping // Merge add-list entry with first blist entry bp = &blist[coalesce[0]]; merge(list, bp); @@ -252,15 +238,15 @@ int16 Screen::mergeLists(rect_t *list, rect_t *blist, int16 len, int16 blen, int // Process the display list // Trailing args are int16 x,y,dx,dy for the D_ADD operation void Screen::displayList(dupdate_t update, ...) { + debugC(6, kDebugDisplay, "displayList"); + static int16 addIndex, restoreIndex; // Index into add/restore lists static rect_t restoreList[DMAX]; // The restore list static rect_t addList[DMAX]; // The add list static rect_t blistList[BMAX]; // The blit list int16 blitLength = 0; // Length of blit list - rect_t *p; // Ptr to dlist entry va_list marker; // Args used for D_ADD operation - - debugC(6, kDebugDisplay, "displayList"); + rect_t *p; // Ptr to dlist entry switch (update) { case D_INIT: // Init lists, restore whole screen @@ -269,7 +255,7 @@ void Screen::displayList(dupdate_t update, ...) { break; case D_ADD: // Add a rectangle to list if (addIndex >= DMAX) { - Utils::Warn(false, "%s", "Display list exceeded"); + Utils::Warn("%s", "Display list exceeded"); return; } va_start(marker, update); // Initialize variable arguments @@ -295,9 +281,10 @@ void Screen::displayList(dupdate_t update, ...) { blitLength = mergeLists(addList, blistList, addIndex, blitLength, BMAX); // Blit the combined blit-list - for (restoreIndex = 0, p = blistList; restoreIndex < blitLength; restoreIndex++, p++) + for (restoreIndex = 0, p = blistList; restoreIndex < blitLength; restoreIndex++, p++) { if (p->dx) // Marks a used entry displayRect(p->x, p->y, p->dx, p->dy); + } break; case D_RESTORE: // Restore each rectangle for (restoreIndex = 0, p = addList; restoreIndex < addIndex; restoreIndex++, p++) { @@ -311,22 +298,19 @@ void Screen::displayList(dupdate_t update, ...) { } void Screen::writeChr(int sx, int sy, byte color, char *local_fontdata) { - /* - Write supplied character (font data) at sx,sy in supplied color - Font data as follows: - - *(fontdata+1) = Font Height (pixels) - *(fontdata+1) = Font Width (pixels) - *(fontdata+x) = Font Bitmap (monochrome) - */ - +// Write supplied character (font data) at sx,sy in supplied color +// Font data as follows: +// +// *(fontdata+1) = Font Height (pixels) +// *(fontdata+1) = Font Width (pixels) +// *(fontdata+x) = Font Bitmap (monochrome) debugC(2, kDebugDisplay, "writeChr(%d, %d, %d, %d)", sx, sy, color, local_fontdata[0]); byte height = local_fontdata[0]; byte width = 8; //local_fontdata[1]; // This can probably be optimized quite a bit... - for (int y = 0; y < height; ++y) + for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { int pixel = y * width + x; int bitpos = pixel % 8; @@ -334,8 +318,8 @@ void Screen::writeChr(int sx, int sy, byte color, char *local_fontdata) { byte bitTest = (1 << bitpos); if ((local_fontdata[2 + offset] & bitTest) == bitTest) _frontBuffer[(sy + y) * 320 + sx + x] = color; - //printf("offset: %u, bitpos %u\n", offset, bitpos); } + } } // Returns height of characters in current font @@ -343,40 +327,38 @@ int16 Screen::fontHeight() { debugC(2, kDebugDisplay, "fontHeight"); static int16 height[NUM_FONTS] = {5, 7, 8}; - return(height[_fnt - FIRST_FONT]); + return height[_fnt - FIRST_FONT]; } // Returns length of supplied string in pixels int16 Screen::stringLength(const char *s) { - int16 sum; - byte **fontArr = _font[_fnt]; - debugC(2, kDebugDisplay, "stringLength(%s)", s); - for (sum = 0; *s; s++) + byte **fontArr = _font[_fnt]; + int16 sum = 0; + for (; *s; s++) sum += *(fontArr[(uint)*s] + 1) + 1; - return(sum); + return sum; } // Return x which would center supplied string int16 Screen::center(const char *s) { debugC(1, kDebugDisplay, "center(%s)", s); - return ((int16)((XPIX - stringLength(s)) >> 1)); + return (int16)((XPIX - stringLength(s)) >> 1); } // Write string at sx,sy in supplied color in current font // If sx == CENTER, center it void Screen::writeStr(int16 sx, int16 sy, const char *s, byte color) { - byte **font = _font[_fnt]; - debugC(2, kDebugDisplay, "writeStr(%d, %d, %s, %d)", sx, sy, s, color); if (sx == CENTER) sx = center(s); + byte **font = _font[_fnt]; for (; *s; s++) { writeChr(sx, sy, color, (char *)font[(uint)*s]); sx += *(font[(uint)*s] + 1) + 1; @@ -430,8 +412,6 @@ void Screen::drawStatusText() { } void Screen::drawShape(int x, int y, int color1, int color2) { -#define shapeSize 24 - for (int i = 0; i < shapeSize; i++) { for (int j = 0; j < i; j++) { _backBuffer[320 * (y + i) + (x + shapeSize + j - i)] = color1; @@ -451,11 +431,12 @@ void Screen::drawRectangle(bool filledFl, uint16 x1, uint16 y1, uint16 x2, uint1 assert(y1 <= y2); if (filledFl) { - for (int i = y1; i < y2; i++) + for (int i = y1; i < y2; i++) { for (int j = x1; j < x2; j++) { _backBuffer[320 * i + j] = color; _frontBuffer[320 * i + j] = color; } + } } else { warning("STUB: drawRectangle()"); } @@ -471,11 +452,10 @@ Screen_v1d::~Screen_v1d() { // TODO: This uses hardcoded fonts in hugo.dat, it should be replaced // by a proper implementation of .FON files void Screen_v1d::loadFont(int16 fontId) { - byte height, width; - static bool fontLoadedFl[NUM_FONTS] = {false, false, false}; - debugC(2, kDebugDisplay, "loadFont(%d)", fontId); + static bool fontLoadedFl[NUM_FONTS] = {false, false, false}; + _fnt = fontId - FIRST_FONT; // Set current font number if (fontLoadedFl[_fnt]) // If already loaded, return @@ -491,8 +471,8 @@ void Screen_v1d::loadFont(int16 fontId) { // Setup the font array (127 characters) for (int i = 1; i < 128; i++) { _font[_fnt][i] = _fontdata[_fnt] + offset; - height = *(_fontdata[_fnt] + offset); - width = *(_fontdata[_fnt] + offset + 1); + byte height = *(_fontdata[_fnt] + offset); + byte width = *(_fontdata[_fnt] + offset + 1); int16 size = height * ((width + 7) >> 3); for (int j = 0; j < size; j++) @@ -510,11 +490,10 @@ Screen_v1w::~Screen_v1w() { // Load font file, construct font ptrs and reverse data bytes void Screen_v1w::loadFont(int16 fontId) { - byte height, width; - static bool fontLoadedFl[NUM_FONTS] = {false, false, false}; - debugC(2, kDebugDisplay, "loadFont(%d)", fontId); + static bool fontLoadedFl[NUM_FONTS] = {false, false, false}; + _fnt = fontId - FIRST_FONT; // Set current font number if (fontLoadedFl[_fnt]) // If already loaded, return @@ -531,8 +510,8 @@ void Screen_v1w::loadFont(int16 fontId) { // Setup the font array (127 characters) for (int i = 1; i < 128; i++) { _font[_fnt][i] = _fontdata[_fnt] + offset; - height = *(_fontdata[_fnt] + offset); - width = *(_fontdata[_fnt] + offset + 1); + byte height = *(_fontdata[_fnt] + offset); + byte width = *(_fontdata[_fnt] + offset + 1); int16 size = height * ((width + 7) >> 3); for (int j = 0; j < size; j++) diff --git a/engines/hugo/display.h b/engines/hugo/display.h index 372ccab32d..16dd87fc6f 100644 --- a/engines/hugo/display.h +++ b/engines/hugo/display.h @@ -32,10 +32,17 @@ #ifndef HUGO_DISPLAY_H #define HUGO_DISPLAY_H -namespace Hugo { -enum overlayState_t {UNDEF, FG, BG}; // Overlay state -struct rect_t; +namespace Hugo { +#define shapeSize 24 + +enum overlayState_t {UNDEF, FG, BG}; // Overlay state +struct rect_t { // Rectangle used in Display list + int16 x; // Position in dib + int16 y; // Position in dib + int16 dx; // width + int16 dy; // height +}; class Screen { public: diff --git a/engines/hugo/engine.cpp b/engines/hugo/engine.cpp index 4e90f24a03..4b93b2216b 100644 --- a/engines/hugo/engine.cpp +++ b/engines/hugo/engine.cpp @@ -48,14 +48,14 @@ namespace Hugo { -#define EDGE 10 // Closest object can get to edge of screen -#define EDGE2 (EDGE * 2) // Push object further back on edge collision +#define EDGE 10 // Closest object can get to edge of screen +#define EDGE2 (EDGE * 2) // Push object further back on edge collision #define SHIFT 8 // Place hero this far inside bounding box -#define MAX_OBJECTS 128 // Used in Update_images() +#define MAX_OBJECTS 128 // Used in Update_images() #define BOUND(X, Y) ((_boundary[Y * XBYTES + X / 8] & (0x80 >> X % 8)) != 0) // Boundary bit set config_t _config; // User's config -maze_t _maze = {false, 0, 0, 0, 0, 0, 0, 0, 0}; // Default to not in maze +maze_t _maze = {false, 0, 0, 0, 0, 0, 0, 0, 0};// Default to not in maze hugo_boot_t _boot; // Boot info structure file char _textBoxBuffer[MAX_BOX]; // Buffer for text box command_t _line = ""; // Line of user text input @@ -126,11 +126,12 @@ void HugoEngine::initConfig(inst_t action) { break; case RESET: // Find first tune and play it - for (int16 i = 0; i < MAX_TUNES; i++) + for (int16 i = 0; i < MAX_TUNES; i++) { if (_config.playlist[i]) { sound().playMusic(i); break; } + } file().initSavedGame(); // Initialize saved game break; @@ -210,12 +211,6 @@ void HugoEngine::readScreenFiles(int screenNum) { // Update all object positions. Process object 'local' events // including boundary events and collisions void HugoEngine::moveObjects() { - object_t *obj; - seq_t *currImage; - int x1, x2, y1, y2; // object coordinates - int dx, dy; // Allowable motion wrt boundary - int8 radius; // Radius for chase (8 bit signed) - debugC(4, kDebugEngine, "moveObjects"); // If route mode enabled, do special route processing @@ -226,18 +221,19 @@ void HugoEngine::moveObjects() { // and store all (visible) object baselines into the boundary file. // Don't store foreground or background objects for (int i = 0; i < _numObj; i++) { - obj = &_objects[i]; // Get pointer to object - currImage = obj->currImagePtr; // Get ptr to current image + object_t *obj = &_objects[i]; // Get pointer to object + seq_t *currImage = obj->currImagePtr; // Get ptr to current image if (obj->screenIndex == *_screen_p) { switch (obj->pathType) { case CHASE: - case CHASE2: - radius = obj->radius; // Default to object's radius + case CHASE2: { + int8 radius = obj->radius; // Default to object's radius if (radius < 0) // If radius infinity, use closer value radius = DX; - dx = _hero->x + _hero->currImagePtr->x1 - obj->x - currImage->x1; - dy = _hero->y + _hero->currImagePtr->y2 - obj->y - currImage->y2 - 1; + // Allowable motion wrt boundary + int dx = _hero->x + _hero->currImagePtr->x1 - obj->x - currImage->x1; + int dy = _hero->y + _hero->currImagePtr->y2 - obj->y - currImage->y2 - 1; if (abs(dx) <= radius) obj->vx = 0; else @@ -266,7 +262,7 @@ void HugoEngine::moveObjects() { break; case 3: case 2: - if (obj->vx != obj->oldvx) { // vx just stopped + if (obj->vx != obj->oldvx) { // vx just stopped if (dx > 0) // Left & right only obj->currImagePtr = obj->seqList[RIGHT].seqPtr; else @@ -285,6 +281,7 @@ void HugoEngine::moveObjects() { obj->oldvy = obj->vy; currImage = obj->currImagePtr; // Get (new) ptr to current image break; + } case WANDER2: case WANDER: if (!_rnd->getRandomNumber(3 * NORMAL_TPS)) { // Kick on random interval @@ -325,29 +322,31 @@ void HugoEngine::moveObjects() { // Move objects, allowing for boundaries for (int i = 0; i < _numObj; i++) { - obj = &_objects[i]; // Get pointer to object + object_t *obj = &_objects[i]; // Get pointer to object if ((obj->screenIndex == *_screen_p) && (obj->vx || obj->vy)) { // Only process if it's moving // Do object movement. Delta_x,y return allowed movement in x,y - // to move as close to a boundary as possible without crossing it. - currImage = obj->currImagePtr; // Get ptr to current image - x1 = obj->x + currImage->x1; // Left edge of object - x2 = obj->x + currImage->x2; // Right edge - y1 = obj->y + currImage->y1; // Top edge - y2 = obj->y + currImage->y2; // Bottom edge + // to move as close to a boundary as possible without crossing it. + seq_t *currImage = obj->currImagePtr; // Get ptr to current image + // object coordinates + int x1 = obj->x + currImage->x1; // Left edge of object + int x2 = obj->x + currImage->x2; // Right edge + int y1 = obj->y + currImage->y1; // Top edge + int y2 = obj->y + currImage->y2; // Bottom edge if ((obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING)) clearBoundary(x1, x2, y2); // Clear our own boundary - dx = deltaX(x1, x2, obj->vx, y2); + + // Allowable motion wrt boundary + int dx = deltaX(x1, x2, obj->vx, y2); if (dx != obj->vx) { // An object boundary collision! boundaryCollision(obj); obj->vx = 0; } - dy = deltaY(x1, x2, obj->vy, y2); - + int dy = deltaY(x1, x2, obj->vy, y2); if (dy != obj->vy) { // An object boundary collision! boundaryCollision(obj); @@ -377,8 +376,8 @@ void HugoEngine::moveObjects() { // Clear all object baselines from the boundary file. for (int i = 0; i < _numObj; i++) { - obj = &_objects[i]; // Get pointer to object - currImage = obj->currImagePtr; // Get ptr to current image + object_t *obj = &_objects[i]; // Get pointer to object + seq_t *currImage = obj->currImagePtr; // Get ptr to current image if ((obj->screenIndex == *_screen_p) && (obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING)) clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2); } @@ -405,70 +404,72 @@ int HugoEngine::deltaX(int x1, int x2, int vx, int y) { // by comparing the intersection with half the object width pos. If the // intersection is in the other half wrt the intended direction, use the // desired vx, else use the computed delta. i.e. believe the desired vx - int b; debugC(3, kDebugEngine, "deltaX(%d, %d, %d, %d)", x1, x2, vx, y); if (vx == 0) - return(0); // Object stationary + return 0 ; // Object stationary y *= XBYTES; // Offset into boundary file if (vx > 0) { // Moving to right - for (int i = x1 >> 3; i <= (x2 + vx) >> 3; i++) // Search by byte - if ((b = Utils::firstBit((byte)(_boundary[y + i] | _objBound[y + i]))) < 8) { // b is index or 8 + for (int i = x1 >> 3; i <= (x2 + vx) >> 3; i++) {// Search by byte + int b = Utils::firstBit((byte)(_boundary[y + i] | _objBound[y + i])); + if (b < 8) { // b is index or 8 // Compute x of boundary and test if intersection b += i << 3; if ((b >= x1) && (b <= x2 + vx)) - return((b < x1 + ((x2 - x1) >> 1)) ? vx : b - x2 - 1); // return dx + return (b < x1 + ((x2 - x1) >> 1)) ? vx : b - x2 - 1; // return dx } + } } else { // Moving to left - for (int i = x2 >> 3; i >= (x1 + vx) >> 3; i--)// Search by byte - if ((b = Utils::lastBit((byte)(_boundary[y + i] | _objBound[y + i]))) < 8) { // b is index or 8 + for (int i = x2 >> 3; i >= (x1 + vx) >> 3; i--) {// Search by byte + int b = Utils::lastBit((byte)(_boundary[y + i] | _objBound[y + i])); + if (b < 8) { // b is index or 8 // Compute x of boundary and test if intersection b += i << 3; if ((b >= x1 + vx) && (b <= x2)) - return((b > x1 + ((x2 - x1) >> 1)) ? vx : b - x1 + 1); // return dx + return (b > x1 + ((x2 - x1) >> 1)) ? vx : b - x1 + 1; // return dx } + } } - return(vx); + return vx; } // Similar to Delta_x, but for movement in y direction. Special case of // bytes at end of line segment; must only count boundary bits falling on // line segment. int HugoEngine::deltaY(int x1, int x2, int vy, int y) { - int inc, i, j, b; - debugC(3, kDebugEngine, "deltaY(%d, %d, %d, %d)", x1, x2, vy, y); if (vy == 0) - return(0); // Object stationary + return 0; // Object stationary - inc = (vy > 0) ? 1 : -1; - for (j = y + inc; j != (y + vy + inc); j += inc) //Search by byte - for (i = x1 >> 3; i <= x2 >> 3; i++) - if ((b = _boundary[j * XBYTES + i] | _objBound[j * XBYTES + i]) != 0) { // Any bit set + int inc = (vy > 0) ? 1 : -1; + for (int j = y + inc; j != (y + vy + inc); j += inc) { //Search by byte + for (int i = x1 >> 3; i <= x2 >> 3; i++) { + int b = _boundary[j * XBYTES + i] | _objBound[j * XBYTES + i]; + if (b != 0) { // Any bit set // Make sure boundary bits fall on line segment if (i == (x2 >> 3)) // Adjust right end b &= 0xff << ((i << 3) + 7 - x2); else if (i == (x1 >> 3)) // Adjust left end b &= 0xff >> (x1 - (i << 3)); if (b) - return(j - y - inc); + return j - y - inc; } - return(vy); + } + } + return vy; } // Store a horizontal line segment in the object boundary file void HugoEngine::storeBoundary(int x1, int x2, int y) { - byte *b; // ptr to boundary byte - debugC(5, kDebugEngine, "storeBoundary(%d, %d, %d)", x1, x2, y); for (int i = x1 >> 3; i <= x2 >> 3; i++) { // For each byte in line - b = &_objBound[y * XBYTES + i]; // get boundary byte + byte *b = &_objBound[y * XBYTES + i]; // get boundary byte if (i == x2 >> 3) // Adjust right end *b |= 0xff << ((i << 3) + 7 - x2); else if (i == x1 >> 3) // Adjust left end @@ -480,13 +481,10 @@ void HugoEngine::storeBoundary(int x1, int x2, int y) { // Clear a horizontal line segment in the object boundary file void HugoEngine::clearBoundary(int x1, int x2, int y) { - int i; - byte *b; // ptr to boundary byte - debugC(5, kDebugEngine, "clearBoundary(%d, %d, %d)", x1, x2, y); - for (i = x1 >> 3; i <= x2 >> 3; i++) { // For each byte in line - b = &_objBound[y * XBYTES + i]; // get boundary byte + for (int i = x1 >> 3; i <= x2 >> 3; i++) { // For each byte in line + byte *b = &_objBound[y * XBYTES + i]; // get boundary byte if (i == x2 >> 3) // Adjust right end *b &= ~(0xff << ((i << 3) + 7 - x2)); else if (i == x1 >> 3) // Adjust left end @@ -499,16 +497,15 @@ void HugoEngine::clearBoundary(int x1, int x2, int y) { // Maze mode is enabled. Check to see whether hero has crossed the maze // bounding box, if so, go to the next room */ void HugoEngine::processMaze() { - seq_t *currImage; - int x1, x2, y1, y2; // hero coordinates - debugC(1, kDebugEngine, "processMaze"); - currImage = _hero->currImagePtr; // Get ptr to current image - x1 = _hero->x + currImage->x1; // Left edge of object - x2 = _hero->x + currImage->x2; // Right edge - y1 = _hero->y + currImage->y1; // Top edge - y2 = _hero->y + currImage->y2; // Bottom edge + seq_t *currImage = _hero->currImagePtr; // Get ptr to current image + + // hero coordinates + int x1 = _hero->x + currImage->x1; // Left edge of object + int x2 = _hero->x + currImage->x2; // Right edge + int y1 = _hero->y + currImage->y1; // Top edge + int y2 = _hero->y + currImage->y2; // Bottom edge if (x1 < _maze.x1) { // Exit west @@ -545,8 +542,6 @@ void HugoEngine::processMaze() { // increasing vertical position, using y+y2 as the baseline // Returns -1 if ay2 < by2 else 1 if ay2 > by2 else 0 int HugoEngine::y2comp(const void *a, const void *b) { - int ay2, by2; - debugC(6, kDebugEngine, "y2comp"); const object_t *p1 = &s_Engine->_objects[*(const byte *)a]; @@ -554,24 +549,24 @@ int HugoEngine::y2comp(const void *a, const void *b) { if (p1 == p2) // Why does qsort try the same indexes? - return (0); + return 0; if (p1->priority == BACKGROUND) - return (-1); + return -1; if (p2->priority == BACKGROUND) - return (1); + return 1; if (p1->priority == FOREGROUND) - return (1); + return 1; if (p2->priority == FOREGROUND) - return (-1); + return -1; - ay2 = p1->y + p1->currImagePtr->y2; - by2 = p2->y + p2->currImagePtr->y2; + int ay2 = p1->y + p1->currImagePtr->y2; + int by2 = p2->y + p2->currImagePtr->y2; - return(ay2 - by2); + return ay2 - by2; } // Draw all objects on screen as follows: @@ -579,16 +574,14 @@ int HugoEngine::y2comp(const void *a, const void *b) { // 2. Display new object frames/positions in dib // Finally, cycle any animating objects to next frame void HugoEngine::updateImages() { - int i, j, num_objs; - object_t *obj; // Pointer to object - seq_t *seqPtr; // Save curr_seq_p - byte objindex[MAX_OBJECTS]; // Array of indeces to objects - debugC(5, kDebugEngine, "updateImages"); // Initialise the index array to visible objects in current screen - for (i = 0, num_objs = 0; i < _numObj; i++) { - obj = &_objects[i]; + int num_objs = 0; + byte objindex[MAX_OBJECTS]; // Array of indeces to objects + + for (int i = 0; i < _numObj; i++) { + object_t *obj = &_objects[i]; if ((obj->screenIndex == *_screen_p) && (obj->cycling >= ALMOST_INVISIBLE)) objindex[num_objs++] = i; } @@ -597,13 +590,13 @@ void HugoEngine::updateImages() { qsort(objindex, num_objs, sizeof(objindex[0]), y2comp); // Add each visible object to display list - for (i = 0; i < num_objs; i++) { - obj = &_objects[objindex[i]]; + for (int i = 0; i < num_objs; i++) { + object_t *obj = &_objects[objindex[i]]; // Count down inter-frame timer if (obj->frameTimer) obj->frameTimer--; - if (obj->cycling > ALMOST_INVISIBLE) // Only if visible + if (obj->cycling > ALMOST_INVISIBLE) { // Only if visible switch (obj->cycling) { case NOT_CYCLING: screen().displayFrame(obj->x, obj->y, obj->currImagePtr, obj->priority == OVEROVL); @@ -614,21 +607,24 @@ void HugoEngine::updateImages() { else screen().displayFrame(obj->x, obj->y, obj->currImagePtr->nextSeqPtr, obj->priority == OVEROVL); break; - case CYCLE_BACKWARD: - seqPtr = obj->currImagePtr; - if (!obj->frameTimer) // Show next frame + case CYCLE_BACKWARD: { + seq_t *seqPtr = obj->currImagePtr; + if (!obj->frameTimer) { // Show next frame while (seqPtr->nextSeqPtr != obj->currImagePtr) seqPtr = seqPtr->nextSeqPtr; + } screen().displayFrame(obj->x, obj->y, seqPtr, obj->priority == OVEROVL); break; + } default: break; } + } } // Cycle any animating objects - for (i = 0; i < num_objs; i++) { - obj = &_objects[objindex[i]]; + for (int i = 0; i < num_objs; i++) { + object_t *obj = &_objects[objindex[i]]; if (obj->cycling != INVISIBLE) { // Only if it's visible if (obj->cycling == ALMOST_INVISIBLE) @@ -646,32 +642,39 @@ void HugoEngine::updateImages() { // If so, reset frame_timer and decrement n_cycle if (obj->frameInterval || obj->cycleNumb) { obj->frameTimer = obj->frameInterval; - for (j = 0; j < obj->seqNumb; j++) - if (obj->currImagePtr->nextSeqPtr == obj->seqList[j].seqPtr) - if (obj->cycleNumb) // Decr cycleNumb if Non-continous + for (int j = 0; j < obj->seqNumb; j++) { + if (obj->currImagePtr->nextSeqPtr == obj->seqList[j].seqPtr) { + if (obj->cycleNumb) { // Decr cycleNumb if Non-continous if (!--obj->cycleNumb) obj->cycling = NOT_CYCLING; + } + } + } } } break; - case CYCLE_BACKWARD: + case CYCLE_BACKWARD: { if (!obj->frameTimer) { // Time to step to prev frame - seqPtr = obj->currImagePtr; + seq_t *seqPtr = obj->currImagePtr; while (obj->currImagePtr->nextSeqPtr != seqPtr) obj->currImagePtr = obj->currImagePtr->nextSeqPtr; // Find out if this is first frame of sequence // If so, reset frame_timer and decrement n_cycle if (obj->frameInterval || obj->cycleNumb) { obj->frameTimer = obj->frameInterval; - for (j = 0; j < obj->seqNumb; j++) - if (obj->currImagePtr == obj->seqList[j].seqPtr) - if (obj->cycleNumb) // Decr cycleNumb if Non-continous + for (int j = 0; j < obj->seqNumb; j++) { + if (obj->currImagePtr == obj->seqList[j].seqPtr) { + if (obj->cycleNumb){ // Decr cycleNumb if Non-continous if (!--obj->cycleNumb) obj->cycling = NOT_CYCLING; + } + } + } } } break; + } default: break; } @@ -684,39 +687,39 @@ void HugoEngine::updateImages() { // Return object index of the topmost object under the cursor, or -1 if none // Objects are filtered if not "useful" int16 HugoEngine::findObject(uint16 x, uint16 y) { - object_t *obj; - seq_t *curImage; - int16 objIndex = -1; // Index of found object - uint16 y2Max = 0; // Greatest y2 - int i; - debugC(3, kDebugEngine, "findObject(%d, %d)", x, y); + int16 objIndex = -1; // Index of found object + uint16 y2Max = 0; // Greatest y2 + object_t *obj = _objects; // Check objects on screen - for (i = 0, obj = _objects; i < _numObj; i++, obj++) { + for (int i = 0; i < _numObj; i++, obj++) { // Object must be in current screen and "useful" if (obj->screenIndex == *_screen_p && (obj->genericCmd || obj->objValue || obj->cmdIndex)) { - curImage = obj->currImagePtr; + seq_t *curImage = obj->currImagePtr; // Object must have a visible image... - if (curImage != NULL && obj->cycling != INVISIBLE) { + if (curImage != 0 && obj->cycling != INVISIBLE) { // If cursor inside object - if (x >= (uint16)obj->x && x <= obj->x + curImage->x2 && y >= (uint16)obj->y && y <= obj->y + curImage->y2) + if (x >= (uint16)obj->x && x <= obj->x + curImage->x2 && y >= (uint16)obj->y && y <= obj->y + curImage->y2) { // If object is closest so far if (obj->y + curImage->y2 > y2Max) { y2Max = obj->y + curImage->y2; objIndex = i; // Found an object! } - } else + } + } else { // ...or a dummy object that has a hotspot rectangle - if (curImage == NULL && obj->vxPath != 0 && !obj->carriedFl) { + if (curImage == 0 && obj->vxPath != 0 && !obj->carriedFl) { // If cursor inside special rectangle - if ((int16)x >= obj->oldx && (int16)x < obj->oldx + obj->vxPath && (int16)y >= obj->oldy && (int16)y < obj->oldy + obj->vyPath) + if ((int16)x >= obj->oldx && (int16)x < obj->oldx + obj->vxPath && (int16)y >= obj->oldy && (int16)y < obj->oldy + obj->vyPath) { // If object is closest so far if (obj->oldy + obj->vyPath - 1 > (int16)y2Max) { y2Max = obj->oldy + obj->vyPath - 1; objIndex = i; // Found an object! } + } } + } } } return objIndex; @@ -724,64 +727,70 @@ int16 HugoEngine::findObject(uint16 x, uint16 y) { // Find a clear space around supplied object that hero can walk to bool HugoEngine::findObjectSpace(object_t *obj, int16 *destx, int16 *desty) { -// bool found = false; // TRUE if we found a clear space - bool foundFl; - seq_t *curImage = obj->currImagePtr; - int16 x; - int16 y = obj->y + curImage->y2 - 1; - debugC(1, kDebugEngine, "findObjectSpace(obj, %d, %d)", *destx, *desty); -// if (!found) // Try left rear corner - for (foundFl = true, *destx = x = obj->x + curImage->x1; x < *destx + HERO_MAX_WIDTH; x++) + seq_t *curImage = obj->currImagePtr; + int16 y = obj->y + curImage->y2 - 1; + + bool foundFl = true; + // Try left rear corner + for (int16 x = *destx = obj->x + curImage->x1; x < *destx + HERO_MAX_WIDTH; x++) { if (BOUND(x, y)) foundFl = false; + } - if (!foundFl) // Try right rear corner - for (foundFl = true, *destx = x = obj->x + curImage->x2 - HERO_MAX_WIDTH + 1; x <= obj->x + (int16)curImage->x2; x++) + if (!foundFl) { // Try right rear corner + foundFl = true; + for (int16 x = *destx = obj->x + curImage->x2 - HERO_MAX_WIDTH + 1; x <= obj->x + (int16)curImage->x2; x++) { if (BOUND(x, y)) foundFl = false; + } + } - if (!foundFl) // Try left front corner - for (foundFl = true, y += 2, *destx = x = obj->x + curImage->x1; x < *destx + HERO_MAX_WIDTH; x++) + if (!foundFl) { // Try left front corner + foundFl = true; + y += 2; + for (int16 x = *destx = obj->x + curImage->x1; x < *destx + HERO_MAX_WIDTH; x++) { if (BOUND(x, y)) foundFl = false; + } + } - if (!foundFl) // Try right rear corner - for (foundFl = true, *destx = x = obj->x + curImage->x2 - HERO_MAX_WIDTH + 1; x <= obj->x + (int16)curImage->x2; x++) + if (!foundFl) { // Try right rear corner + foundFl = true; + for (int16 x = *destx = obj->x + curImage->x2 - HERO_MAX_WIDTH + 1; x <= obj->x + (int16)curImage->x2; x++) { if (BOUND(x, y)) foundFl = false; + } + } *desty = y; - return(foundFl); + return foundFl; } // Search background command list for this screen for supplied object. -// Return first associated verb (not "look") or NULL if none found. +// Return first associated verb (not "look") or 0 if none found. char *HugoEngine::useBG(char *name) { debugC(1, kDebugEngine, "useBG(%s)", name); objectList_t p = _backgroundObjects[*_screen_p]; - for (int i = 0; *_arrayVerbs[p[i].verbIndex]; i++) + for (int i = 0; *_arrayVerbs[p[i].verbIndex]; i++) { if ((name == _arrayNouns[p[i].nounIndex][0] && - p[i].verbIndex != _look) && - ((p[i].roomState == DONT_CARE) || (p[i].roomState == _screenStates[*_screen_p]))) - return (_arrayVerbs[p[i].verbIndex][0]); + p[i].verbIndex != _look) && + ((p[i].roomState == DONT_CARE) || (p[i].roomState == _screenStates[*_screen_p]))) + return _arrayVerbs[p[i].verbIndex][0]; + } - return (NULL); + return 0; } // If status.objid = -1, pick up objid, else use status.objid on objid, // if objid can't be picked up, use it directly void HugoEngine::useObject(int16 objId) { - object_t *obj = &_objects[objId]; // Ptr to object - uses_t *use; // Ptr to use entry - target_t *target; // Ptr to target entry - bool foundFl; // TRUE if found target entry - char *verb; // Background verb to use directly - debugC(1, kDebugEngine, "useObject(%d)", objId); + char *verb; // Background verb to use directly + object_t *obj = &_objects[objId]; // Ptr to object if (_status.inventoryObjId == -1) { // Get or use objid directly if ((obj->genericCmd & TAKE) || obj->objValue) // Get collectible item @@ -792,7 +801,7 @@ void HugoEngine::useObject(int16 objId) { sprintf(_line, "%s %s", _arrayVerbs[_drop][0], _arrayNouns[obj->nounIndex][0]); else if (obj->cmdIndex != 0) // Use non-collectible item if able sprintf(_line, "%s %s", _arrayVerbs[_cmdList[obj->cmdIndex][1].verbIndex][0], _arrayNouns[obj->nounIndex][0]); - else if ((verb = useBG(_arrayNouns[obj->nounIndex][0])) != NULL) + else if ((verb = useBG(_arrayNouns[obj->nounIndex][0])) != 0) sprintf(_line, "%s %s", verb, _arrayNouns[obj->nounIndex][0]); else return; // Can't use object directly @@ -802,10 +811,11 @@ void HugoEngine::useObject(int16 objId) { sprintf(_line, "%s %s %s", _arrayVerbs[_cmdList[_objects[_status.inventoryObjId].cmdIndex][1].verbIndex][0], _arrayNouns[_objects[_status.inventoryObjId].nounIndex][0], _arrayNouns[obj->nounIndex][0]); // Check valid use of objects and override verb if necessary - for (use = _uses; use->objId != _numObj; use++) + for (uses_t *use = _uses; use->objId != _numObj; use++) { if (_status.inventoryObjId == use->objId) { // Look for secondary object, if found use matching verb - for (foundFl = false, target = use->targets; _arrayNouns[target->nounIndex] != NULL; target++) + bool foundFl = false; + for (target_t *target = use->targets; _arrayNouns[target->nounIndex] != 0; target++) if (_arrayNouns[target->nounIndex][0] == _arrayNouns[obj->nounIndex][0]) { foundFl = true; sprintf(_line, "%s %s %s", _arrayVerbs[target->verbIndex][0], _arrayNouns[_objects[_status.inventoryObjId].nounIndex][0], _arrayNouns[obj->nounIndex][0]); @@ -820,6 +830,7 @@ void HugoEngine::useObject(int16 objId) { return; } } + } } if (_status.inventoryState == I_ACTIVE) // If inventory active, remove it @@ -833,30 +844,27 @@ void HugoEngine::useObject(int16 objId) { void HugoEngine::lookObject(object_t *obj) { debugC(1, kDebugEngine, "lookObject"); - if (obj == _hero) { + if (obj == _hero) // Hero swapped - look at other obj = &_objects[_heroImage]; - } + parser().command("%s %s", _arrayVerbs[_look][0], _arrayNouns[obj->nounIndex][0]); } // Free all object images void HugoEngine::freeObjects() { - object_t *obj; - seq_t *seq; - debugC(1, kDebugEngine, "freeObjects"); // Nothing to do if not allocated yet - if (_hero->seqList[0].seqPtr == NULL) + if (_hero->seqList[0].seqPtr == 0) return; // Free all sequence lists and image data for (int i = 0; i < _numObj; i++) { - obj = &_objects[i]; - for (int j = 0; j < obj->seqNumb; j++) { // for each sequence - seq = obj->seqList[j].seqPtr; // Free image - if (seq == NULL) // Failure during database load + object_t *obj = &_objects[i]; + for (int j = 0; j < obj->seqNumb; j++) { // for each sequence + seq_t *seq = obj->seqList[j].seqPtr; // Free image + if (seq == 0) // Failure during database load break; do { free(seq->imagePtr); @@ -869,10 +877,9 @@ void HugoEngine::freeObjects() { // Add action lists for this screen to event queue void HugoEngine::screenActions(int screenNum) { - uint16 *screenAct = _screenActs[screenNum]; - debugC(1, kDebugEngine, "screenActions(%d)", screenNum); + uint16 *screenAct = _screenActs[screenNum]; if (screenAct) { for (int i = 0; screenAct[i]; i++) scheduler().insertActionList(screenAct[i]); @@ -884,29 +891,27 @@ void HugoEngine::setNewScreen(int screenNum) { debugC(1, kDebugEngine, "setNewScreen(%d)", screenNum); *_screen_p = screenNum; // HERO object - for (int i = HERO + 1; i < _numObj; i++) // Any others + for (int i = HERO + 1; i < _numObj; i++) { // Any others if (_objects[i].carriedFl) // being carried _objects[i].screenIndex = screenNum; + } } // An object has collided with a boundary. See if any actions are required void HugoEngine::boundaryCollision(object_t *obj) { - int x, y, dx, dy; - int8 radius; // 8 bits signed - hotspot_t *hotspot; - debugC(1, kDebugEngine, "boundaryCollision"); if (obj == _hero) { // Hotspots only relevant to HERO + int x; if (obj->vx > 0) x = obj->x + obj->currImagePtr->x2; else x = obj->x + obj->currImagePtr->x1; - y = obj->y + obj->currImagePtr->y2; + int y = obj->y + obj->currImagePtr->y2; for (int i = 0; _hotspots[i].screenIndex >= 0; i++) { - hotspot = &_hotspots[i]; + hotspot_t *hotspot = &_hotspots[i]; if (hotspot->screenIndex == obj->screenIndex) if ((x >= hotspot->x1) && (x <= hotspot->x2) && (y >= hotspot->y1) && (y <= hotspot->y2)) { scheduler().insertActionList(hotspot->actIndex); @@ -915,10 +920,10 @@ void HugoEngine::boundaryCollision(object_t *obj) { } } else { // Check whether an object collided with HERO - dx = _hero->x + _hero->currImagePtr->x1 - obj->x - obj->currImagePtr->x1; - dy = _hero->y + _hero->currImagePtr->y2 - obj->y - obj->currImagePtr->y2; + int dx = _hero->x + _hero->currImagePtr->x1 - obj->x - obj->currImagePtr->x1; + int dy = _hero->y + _hero->currImagePtr->y2 - obj->y - obj->currImagePtr->y2; // If object's radius is infinity, use a closer value - radius = obj->radius; + int8 radius = obj->radius; if (radius < 0) radius = DX * 2; if ((abs(dx) <= radius) && (abs(dy) <= radius)) @@ -940,14 +945,12 @@ void HugoEngine::initNewScreenDisplay() { // Add up all the object values and all the bonus points void HugoEngine::calcMaxScore() { - int i; - debugC(1, kDebugEngine, "calcMaxScore"); - for (i = 0; i < _numObj; i++) + for (int i = 0; i < _numObj; i++) _maxscore += _objects[i].objValue; - for (i = 0; i < _numBonuses; i++) + for (int i = 0; i < _numBonuses; i++) _maxscore += _points[i].score; } diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp index 6a0abadcf4..1cc84e77c8 100644 --- a/engines/hugo/file.cpp +++ b/engines/hugo/file.cpp @@ -52,18 +52,17 @@ FileManager::~FileManager() { byte *FileManager::convertPCC(byte *p, uint16 y, uint16 bpl, image_pt dataPtr) { // Convert 4 planes (RGBI) data to 8-bit DIB format // Return original plane data ptr - uint16 r, g, b, i; // Byte index within each plane - int8 bit; // Bit index within a byte - debugC(2, kDebugFile, "convertPCC(byte *p, %d, %d, image_pt data_p)", y, bpl); dataPtr += y * bpl * 8; // Point to correct DIB line - for (r = 0, g = bpl, b = g + bpl, i = b + bpl; r < bpl; r++, g++, b++, i++) // Each byte in all planes - for (bit = 7; bit >= 0; bit--) // Each bit in byte + for (int16 r = 0, g = bpl, b = g + bpl, i = b + bpl; r < bpl; r++, g++, b++, i++) { // Each byte in all planes + for (int8 bit = 7; bit >= 0; bit--) { // Each bit in byte *dataPtr++ = (((p[r] >> bit & 1) << 0) | ((p[g] >> bit & 1) << 1) | ((p[b] >> bit & 1) << 2) | ((p[i] >> bit & 1) << 3)); + } + } return p; } @@ -71,28 +70,10 @@ seq_t *FileManager::readPCX(Common::File &f, seq_t *seqPtr, byte *imagePtr, bool // Read a pcx file of length len. Use supplied seq_p and image_p or // allocate space if NULL. Name used for errors. Returns address of seq_p // Set first TRUE to initialize b_index (i.e. not reading a sequential image in file). - - struct { // Structure of PCX file header - byte mfctr, vers, enc, bpx; - uint16 x1, y1, x2, y2; // bounding box - uint16 xres, yres; - byte palette[48]; // EGA color palette - byte vmode, planes; - uint16 bytesPerLine; // Bytes per line - byte fill2[60]; - } PCC_header; // Header of a PCC file - - byte c, d; // code and data bytes from PCX file - byte pline[XPIX]; // Hold 4 planes of data - byte *p = pline; // Ptr to above - byte i; // PCX repeat count - uint16 bytesPerLine4; // BPL in 4-bit format - uint16 size; // Size of image - uint16 y = 0; // Current line index - debugC(1, kDebugFile, "readPCX(..., %s)", name); // Read in the PCC header and check consistency + static PCC_header_t PCC_header; PCC_header.mfctr = f.readByte(); PCC_header.vers = f.readByte(); PCC_header.enc = f.readByte(); @@ -112,31 +93,38 @@ seq_t *FileManager::readPCX(Common::File &f, seq_t *seqPtr, byte *imagePtr, bool if (PCC_header.mfctr != 10) Utils::Error(PCCH_ERR, "%s", name); - // Allocate memory for seq_t if NULL - if (seqPtr == NULL) - if ((seqPtr = (seq_t *)malloc(sizeof(seq_t))) == NULL) + // Allocate memory for seq_t if 0 + if (seqPtr == 0) { + if ((seqPtr = (seq_t *)malloc(sizeof(seq_t))) == 0) Utils::Error(HEAP_ERR, "%s", name); - + } + // Find size of image data in 8-bit DIB format // Note save of x2 - marks end of valid data before garbage - bytesPerLine4 = PCC_header.bytesPerLine * 4; // 4-bit bpl + uint16 bytesPerLine4 = PCC_header.bytesPerLine * 4; // 4-bit bpl seqPtr->bytesPerLine8 = bytesPerLine4 * 2; // 8-bit bpl seqPtr->lines = PCC_header.y2 - PCC_header.y1 + 1; seqPtr->x2 = PCC_header.x2 - PCC_header.x1 + 1; - size = seqPtr->lines * seqPtr->bytesPerLine8; + // Size of the image + uint16 size = seqPtr->lines * seqPtr->bytesPerLine8; // Allocate memory for image data if NULL - if (imagePtr == NULL) - if ((imagePtr = (byte *)malloc((size_t) size)) == NULL) + if (imagePtr == 0) { + if ((imagePtr = (byte *)malloc((size_t) size)) == 0) Utils::Error(HEAP_ERR, "%s", name); + } + seqPtr->imagePtr = imagePtr; // Process the image data, converting to 8-bit DIB format + uint16 y = 0; // Current line index + byte pline[XPIX]; // Hold 4 planes of data + byte *p = pline; // Ptr to above while (y < seqPtr->lines) { - c = f.readByte(); + byte c = f.readByte(); if ((c & REP_MASK) == REP_MASK) { - d = f.readByte(); // Read data byte - for (i = 0; i < (c & LEN_MASK); i++) { + byte d = f.readByte(); // Read data byte + for (int i = 0; i < (c & LEN_MASK); i++) { *p++ = d; if ((uint16)(p - pline) == bytesPerLine4) p = convertPCC(pline, y++, PCC_header.bytesPerLine, imagePtr); @@ -152,13 +140,6 @@ seq_t *FileManager::readPCX(Common::File &f, seq_t *seqPtr, byte *imagePtr, bool void FileManager::readImage(int objNum, object_t *objPtr) { // Read object file of PCC images into object supplied - byte x, y, j, k; - uint16 x2; // Limit on x in image data - seq_t *seqPtr = 0; // Ptr to sequence structure - image_pt dibPtr; // Ptr to DIB data - objBlock_t objBlock; // Info on file within database - bool firstFl = true; // Initializes pcx read function - debugC(1, kDebugFile, "readImage(%d, object_t *objPtr)", objNum); if (!objPtr->seqNumb) // This object has no images @@ -167,6 +148,7 @@ void FileManager::readImage(int objNum, object_t *objPtr) { if (_vm.isPacked()) { _objectsArchive.seek((uint32)objNum * sizeof(objBlock_t), SEEK_SET); + objBlock_t objBlock; // Info on file within database objBlock.objOffset = _objectsArchive.readUint32LE(); objBlock.objLength = _objectsArchive.readUint32LE(); @@ -182,31 +164,35 @@ void FileManager::readImage(int objNum, object_t *objPtr) { } } + bool firstFl = true; // Initializes pcx read function + seq_t *seqPtr = 0; // Ptr to sequence structure + // Now read the images into an images list - for (j = 0; j < objPtr->seqNumb; j++) { // for each sequence - for (k = 0; k < objPtr->seqList[j].imageNbr; k++) { // each image + for (int j = 0; j < objPtr->seqNumb; j++) { // for each sequence + for (int k = 0; k < objPtr->seqList[j].imageNbr; k++) { // each image if (k == 0) { // First image // Read this image - allocate both seq and image memory - seqPtr = readPCX(_objectsArchive, NULL, NULL, firstFl, _vm._arrayNouns[objPtr->nounIndex][0]); + seqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm._arrayNouns[objPtr->nounIndex][0]); objPtr->seqList[j].seqPtr = seqPtr; firstFl = false; } else { // Subsequent image // Read this image - allocate both seq and image memory - seqPtr->nextSeqPtr = readPCX(_objectsArchive, NULL, NULL, firstFl, _vm._arrayNouns[objPtr->nounIndex][0]); + seqPtr->nextSeqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm._arrayNouns[objPtr->nounIndex][0]); seqPtr = seqPtr->nextSeqPtr; } // Compute the bounding box - x1, x2, y1, y2 // Note use of x2 - marks end of valid data in row - x2 = seqPtr->x2; + uint16 x2 = seqPtr->x2; seqPtr->x1 = seqPtr->x2; seqPtr->x2 = 0; seqPtr->y1 = seqPtr->lines; seqPtr->y2 = 0; - dibPtr = seqPtr->imagePtr; - for (y = 0; y < seqPtr->lines; y++, dibPtr += seqPtr->bytesPerLine8 - x2) - for (x = 0; x < x2; x++) - if (*dibPtr++) { // Some data found + + image_pt dibPtr = seqPtr->imagePtr; + for (int y = 0; y < seqPtr->lines; y++, dibPtr += seqPtr->bytesPerLine8 - x2) { + for (int x = 0; x < x2; x++) { + if (*dibPtr++) { // Some data found if (x < seqPtr->x1) seqPtr->x1 = x; if (x > seqPtr->x2) @@ -216,6 +202,8 @@ void FileManager::readImage(int objNum, object_t *objPtr) { if (y > seqPtr->y2) seqPtr->y2 = y; } + } + } } seqPtr->nextSeqPtr = objPtr->seqList[j].seqPtr; // loop linked list to head } @@ -242,27 +230,23 @@ void FileManager::readImage(int objNum, object_t *objPtr) { sound_pt FileManager::getSound(int16 sound, uint16 *size) { // Read sound (or music) file data. Call with SILENCE to free-up // any allocated memory. Also returns size of data - - static sound_hdr_t s_hdr[MAX_SOUNDS]; // Sound lookup table - sound_pt soundPtr; // Ptr to sound data - Common::File fp; // Handle to SOUND_FILE -// bool music = sound < NUM_TUNES; // TRUE if music, else sound file - debugC(1, kDebugFile, "getSound(%d, %d)", sound, *size); // No more to do if SILENCE (called for cleanup purposes) if (sound == _vm._soundSilence) - return(NULL); + return 0; // Open sounds file + Common::File fp; // Handle to SOUND_FILE if (!fp.open(SOUND_FILE)) { -// Error(FILE_ERR, "%s", SOUND_FILE); warning("Hugo Error: File not found %s", SOUND_FILE); - return(NULL); + return 0; } // If this is the first call, read the lookup table static bool has_read_header = false; + static sound_hdr_t s_hdr[MAX_SOUNDS]; // Sound lookup table + if (!has_read_header) { if (fp.read(s_hdr, sizeof(s_hdr)) != sizeof(s_hdr)) Utils::Error(FILE_ERR, "%s", SOUND_FILE); @@ -274,9 +258,10 @@ sound_pt FileManager::getSound(int16 sound, uint16 *size) { Utils::Error(SOUND_ERR, "%s", SOUND_FILE); // Allocate memory for sound or music, if possible - if ((soundPtr = (byte *)malloc(s_hdr[sound].size)) == 0) { - Utils::Warn(false, "%s", "Low on memory"); - return(NULL); + sound_pt soundPtr = (byte *)malloc(s_hdr[sound].size); // Ptr to sound data + if (soundPtr == 0) { + Utils::Warn("%s", "Low on memory"); + return 0; } // Seek to data and read it @@ -301,46 +286,39 @@ bool FileManager::fileExists(char *filename) { void FileManager::saveSeq(object_t *obj) { // Save sequence number and image number in given object - byte j, k; - seq_t *q; - bool found; - debugC(1, kDebugFile, "saveSeq"); - for (j = 0, found = false; !found && (j < obj->seqNumb); j++) { - q = obj->seqList[j].seqPtr; - for (k = 0; !found && (k < obj->seqList[j].imageNbr); k++) { + bool found = false; + for (int j = 0; !found && (j < obj->seqNumb); j++) { + seq_t *q = obj->seqList[j].seqPtr; + for (int k = 0; !found && (k < obj->seqList[j].imageNbr); k++) { if (obj->currImagePtr == q) { found = true; obj->curSeqNum = j; obj->curImageNum = k; - } else + } else { q = q->nextSeqPtr; + } } } } void FileManager::restoreSeq(object_t *obj) { // Set up cur_seq_p from stored sequence and image number in object - int j; - seq_t *q; - debugC(1, kDebugFile, "restoreSeq"); - q = obj->seqList[obj->curSeqNum].seqPtr; - for (j = 0; j < obj->curImageNum; j++) + seq_t *q = obj->seqList[obj->curSeqNum].seqPtr; + for (int j = 0; j < obj->curImageNum; j++) q = q->nextSeqPtr; obj->currImagePtr = q; } void FileManager::saveGame(int16 slot, const char *descrip) { // Save game to supplied slot (-1 is INITFILE) - int i; - char path[256]; // Full path of saved game - debugC(1, kDebugFile, "saveGame(%d, %s)", slot, descrip); // Get full path of saved game file - note test for INITFILE + char path[256]; // Full path of saved game if (slot == -1) sprintf(path, "%s", _vm._initFilename); else @@ -359,7 +337,7 @@ void FileManager::saveGame(int16 slot, const char *descrip) { out->write(descrip, DESCRIPLEN); // Save objects - for (i = 0; i < _vm._numObj; i++) { + for (int i = 0; i < _vm._numObj; i++) { // Save where curr_seq_p is pointing to saveSeq(&_vm._objects[i]); out->write(&_vm._objects[i], sizeof(object_t)); @@ -405,20 +383,13 @@ void FileManager::saveGame(int16 slot, const char *descrip) { void FileManager::restoreGame(int16 slot) { // Restore game from supplied slot number (-1 is INITFILE) - int i; - char path[256]; // Full path of saved game - object_t *p; - seqList_t seqList[MAX_SEQUENCES]; -// cmdList *cmds; // Save command list pointer - uint16 cmdIndex; // Save command list pointer -// char ver[sizeof(VER)]; // Compare versions - debugC(1, kDebugFile, "restoreGame(%d)", slot); // Initialize new-game status _vm.initStatus(); // Get full path of saved game file - note test for INITFILE + char path[256]; // Full path of saved game if (slot == -1) sprintf(path, "%s", _vm._initFilename); else @@ -445,10 +416,11 @@ void FileManager::restoreGame(int16 slot) { // Restore objects, retain current seqList which points to dynamic mem // Also, retain cmnd_t pointers - for (i = 0; i < _vm._numObj; i++) { - p = &_vm._objects[i]; + for (int i = 0; i < _vm._numObj; i++) { + object_t *p = &_vm._objects[i]; + seqList_t seqList[MAX_SEQUENCES]; memcpy(seqList, p->seqList, sizeof(seqList_t)); - cmdIndex = p->cmdIndex; + uint16 cmdIndex = p->cmdIndex; in->read(p, sizeof(object_t)); p->cmdIndex = cmdIndex; memcpy(p->seqList, seqList, sizeof(seqList_t)); @@ -457,9 +429,10 @@ void FileManager::restoreGame(int16 slot) { in->read(&_vm._heroImage, sizeof(_vm._heroImage)); // If hero swapped in saved game, swap it - if ((i = _vm._heroImage) != HERO) + int heroImg = _vm._heroImage; + if (heroImg != HERO) _vm.scheduler().swapImages(HERO, _vm._heroImage); - _vm._heroImage = i; + _vm._heroImage = heroImg; status_t &gameStatus = _vm.getGameStatus(); @@ -476,7 +449,7 @@ void FileManager::restoreGame(int16 slot) { in->read(_vm._points, sizeof(point_t) * _vm._numBonuses); // Restore ptrs to currently loaded objects - for (i = 0; i < _vm._numObj; i++) + for (int i = 0; i < _vm._numObj; i++) restoreSeq(&_vm._objects[i]); // Now restore time of the save and the event queue @@ -498,15 +471,12 @@ void FileManager::initSavedGame() { // the initial game file but useful to force a write during development // when the size is changeable. // The net result is a valid INITFILE, with status.savesize initialized. - Common::File f; // Handle of saved game file - char path[256]; // Full path of INITFILE - debugC(1, kDebugFile, "initSavedGame"); // Get full path of INITFILE + char path[256]; // Full path of INITFILE sprintf(path, "%s", _vm._initFilename); - // Force save of initial game if (_vm.getGameStatus().initSaveFl) saveGame(-1, ""); @@ -530,22 +500,15 @@ void FileManager::initSavedGame() { Utils::Error(WRITE_ERR, "%s", path); } -// Record and playback handling stuff: -typedef struct { -// int key; // Character - uint32 time; // Time at which character was pressed -} pbdata_t; -static pbdata_t pbdata; -FILE *fpb; - void FileManager::openPlaybackFile(bool playbackFl, bool recordFl) { debugC(1, kDebugFile, "openPlaybackFile(%d, %d)", (playbackFl) ? 1 : 0, (recordFl) ? 1 : 0); if (playbackFl) { if (!(fpb = fopen(PBFILE, "r+b"))) Utils::Error(FILE_ERR, "%s", PBFILE); - } else if (recordFl) + } else if (recordFl) { fpb = fopen(PBFILE, "wb"); + } pbdata.time = 0; // Say no key available } @@ -555,23 +518,21 @@ void FileManager::closePlaybackFile() { void FileManager::printBootText() { // Read the encrypted text from the boot file and print it - Common::File ofp; - int i; - char *buf; - debugC(1, kDebugFile, "printBootText"); + Common::File ofp; if (!ofp.open(BOOTFILE)) { if (_vm._gameVariant == 3) { //TODO initialize properly _boot structure warning("printBootText - Skipping as H1 Dos may be a freeware"); return; - } else + } else { Utils::Error(FILE_ERR, "%s", BOOTFILE); + } } // Allocate space for the text and print it - buf = (char *)malloc(_boot.exit_len + 1); + char *buf = (char *)malloc(_boot.exit_len + 1); if (buf) { // Skip over the boot structure (already read) and read exit text ofp.seek((long)sizeof(_boot), SEEK_SET); @@ -579,6 +540,7 @@ void FileManager::printBootText() { Utils::Error(FILE_ERR, "%s", BOOTFILE); // Decrypt the exit text, using CRYPT substring + int i; for (i = 0; i < _boot.exit_len; i++) buf[i] ^= CRYPT[i % strlen(CRYPT)]; @@ -595,20 +557,17 @@ void FileManager::printBootText() { void FileManager::readBootFile() { // Reads boot file for program environment. Fatal error if not there or // file checksum is bad. De-crypts structure while checking checksum - byte checksum; - byte *p; - Common::File ofp; - uint32 i; - debugC(1, kDebugFile, "readBootFile"); + Common::File ofp; if (!ofp.open(BOOTFILE)) { if (_vm._gameVariant == 3) { //TODO initialize properly _boot structure warning("readBootFile - Skipping as H1 Dos may be a freeware"); return; - } else + } else { Utils::Error(FILE_ERR, "%s", BOOTFILE); + } } if (ofp.size() < (int32)sizeof(_boot)) @@ -620,8 +579,10 @@ void FileManager::readBootFile() { ofp.read(_boot.distrib, sizeof(_boot.distrib)); _boot.exit_len = ofp.readUint16LE(); - p = (byte *)&_boot; - for (i = 0, checksum = 0; i < sizeof(_boot); i++) { + byte *p = (byte *)&_boot; + + byte checksum = 0; + for (uint32 i = 0; i < sizeof(_boot); i++) { checksum ^= p[i]; p[i] ^= CRYPT[i % strlen(CRYPT)]; } @@ -633,16 +594,16 @@ void FileManager::readBootFile() { uif_hdr_t *FileManager::getUIFHeader(uif_t id) { // Returns address of uif_hdr[id], reading it in if first call - static uif_hdr_t UIFHeader[MAX_UIFS]; // Lookup for uif fonts/images - static bool firstFl = true; - Common::File ip; // Image data file - debugC(1, kDebugFile, "getUIFHeader(%d)", id); + static bool firstFl = true; + static uif_hdr_t UIFHeader[MAX_UIFS]; // Lookup for uif fonts/images + // Initialize offset lookup if not read yet if (firstFl) { firstFl = false; // Open unbuffered to do far read + Common::File ip; // Image data file if (!ip.open(UIF_FILE)) Utils::Error(FILE_ERR, "%s", UIF_FILE); @@ -661,24 +622,22 @@ uif_hdr_t *FileManager::getUIFHeader(uif_t id) { void FileManager::readUIFItem(int16 id, byte *buf) { // Read uif item into supplied buffer. - Common::File ip; // UIF_FILE handle - uif_hdr_t *UIFHeaderPtr; // Lookup table of items - seq_t seq; // Dummy seq_t for image data - debugC(1, kDebugFile, "readUIFItem(%d, ...)", id); // Open uif file to read data + Common::File ip; // UIF_FILE handle if (!ip.open(UIF_FILE)) Utils::Error(FILE_ERR, "%s", UIF_FILE); // Seek to data - UIFHeaderPtr = getUIFHeader((uif_t)id); + uif_hdr_t *UIFHeaderPtr = getUIFHeader((uif_t)id); ip.seek(UIFHeaderPtr->offset, SEEK_SET); // We support pcx images and straight data + seq_t dummySeq; // Dummy seq_t for image data switch (id) { case UIF_IMAGES: // Read uif images file - readPCX(ip, &seq, buf, true, UIF_FILE); + readPCX(ip, &dummySeq, buf, true, UIF_FILE); break; default: // Read file data into supplied array if (ip.read(buf, UIFHeaderPtr->size) != UIFHeaderPtr->size) @@ -694,30 +653,28 @@ void FileManager::instructions() { // Only in DOS versions Common::File f; - char line[1024], *wrkLine; - char readBuf[2]; - - wrkLine = line; if (!f.open(HELPFILE)) { warning("help.dat not found"); return; } + char readBuf[2]; while (f.read(readBuf, 1)) { + char line[1024], *wrkLine; + wrkLine = line; wrkLine[0] = readBuf[0]; wrkLine++; do { f.read(wrkLine, 1); } while (*wrkLine++ != EOP); - wrkLine[-2] = '\0'; /* Remove EOP and previous CR */ + wrkLine[-2] = '\0'; // Remove EOP and previous CR Utils::Box(BOX_ANY, "%s", line); wrkLine = line; - f.read(readBuf, 2); /* Remove CRLF after EOP */ + f.read(readBuf, 2); // Remove CRLF after EOP } f.close(); } - FileManager_v1d::FileManager_v1d(HugoEngine &vm) : FileManager(vm) { } @@ -734,18 +691,15 @@ void FileManager_v1d::closeDatabaseFiles() { void FileManager_v1d::readOverlay(int screenNum, image_pt image, ovl_t overlayType) { // Open and read in an overlay file, close file - uint32 i = 0; - image_pt tmpImage = image; // temp ptr to overlay file - debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum); - const char *ovl_ext[] = {".b", ".o", ".ob"}; - char *buf = (char *) malloc(2048 + 1); // Buffer for file access + const char *ovl_ext[] = {".b", ".o", ".ob"}; + char *buf = (char *) malloc(2048 + 1); // Buffer for file access strcat(strcpy(buf, _vm._screenNames[screenNum]), ovl_ext[overlayType]); if (!fileExists(buf)) { - for (i = 0; i < OVL_SIZE; i++) + for (uint32 i = 0; i < OVL_SIZE; i++) image[i] = 0; return; } @@ -753,22 +707,23 @@ void FileManager_v1d::readOverlay(int screenNum, image_pt image, ovl_t overlayTy if (!_sceneryArchive1.open(buf)) Utils::Error(FILE_ERR, "%s", buf); + image_pt tmpImage = image; // temp ptr to overlay file + _sceneryArchive1.read(tmpImage, OVL_SIZE); _sceneryArchive1.close(); } void FileManager_v1d::readBackground(int screenIndex) { // Read a PCX image into dib_a - seq_t seq; // Image sequence structure for Read_pcx - debugC(1, kDebugFile, "readBackground(%d)", screenIndex); - char *buf = (char *) malloc(2048 + 1); // Buffer for file access + char *buf = (char *) malloc(2048 + 1); // Buffer for file access strcat(strcpy(buf, _vm._screenNames[screenIndex]), ".ART"); if (!_sceneryArchive1.open(buf)) Utils::Error(FILE_ERR, "%s", buf); // Read the image into dummy seq and static dib_a - readPCX(_sceneryArchive1, &seq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]); + seq_t dummySeq; // Image sequence structure for Read_pcx + readPCX(_sceneryArchive1, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]); _sceneryArchive1.close(); } @@ -806,13 +761,11 @@ void FileManager_v2d::closeDatabaseFiles() { void FileManager_v2d::readBackground(int screenIndex) { // Read a PCX image into dib_a - seq_t seq; // Image sequence structure for Read_pcx - sceneBlock_t sceneBlock; // Read a database header entry - debugC(1, kDebugFile, "readBackground(%d)", screenIndex); _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET); + sceneBlock_t sceneBlock; // Read a database header entry sceneBlock.scene_off = _sceneryArchive1.readUint32LE(); sceneBlock.scene_len = _sceneryArchive1.readUint32LE(); sceneBlock.b_off = _sceneryArchive1.readUint32LE(); @@ -825,21 +778,18 @@ void FileManager_v2d::readBackground(int screenIndex) { _sceneryArchive1.seek(sceneBlock.scene_off, SEEK_SET); // Read the image into dummy seq and static dib_a - readPCX(_sceneryArchive1, &seq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]); + seq_t dummySeq; // Image sequence structure for Read_pcx + readPCX(_sceneryArchive1, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]); } void FileManager_v2d::readOverlay(int screenNum, image_pt image, ovl_t overlayType) { // Open and read in an overlay file, close file - uint32 i = 0; - int16 j, k; - int8 data; // Must be 8 bits signed - image_pt tmpImage = image; // temp ptr to overlay file - sceneBlock_t sceneBlock; // Database header entry - debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum); + image_pt tmpImage = image; // temp ptr to overlay file _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET); + sceneBlock_t sceneBlock; // Database header entry sceneBlock.scene_off = _sceneryArchive1.readUint32LE(); sceneBlock.scene_len = _sceneryArchive1.readUint32LE(); sceneBlock.b_off = _sceneryArchive1.readUint32LE(); @@ -849,6 +799,7 @@ void FileManager_v2d::readOverlay(int screenNum, image_pt image, ovl_t overlayTy sceneBlock.ob_off = _sceneryArchive1.readUint32LE(); sceneBlock.ob_len = _sceneryArchive1.readUint32LE(); + uint32 i = 0; switch (overlayType) { case BOUNDARY: _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET); @@ -873,16 +824,16 @@ void FileManager_v2d::readOverlay(int screenNum, image_pt image, ovl_t overlayTy } // Read in the overlay file using MAC Packbits. (We're not proud!) - k = 0; // byte count + int16 k = 0; // byte count do { - data = _sceneryArchive1.readByte(); // Read a code byte - if ((byte)data == 0x80) // Noop + int8 data = _sceneryArchive1.readByte(); // Read a code byte + if ((byte)data == 0x80) // Noop k = k; - else if (data >= 0) { // Copy next data+1 literally + else if (data >= 0) { // Copy next data+1 literally for (i = 0; i <= (byte)data; i++, k++) *tmpImage++ = _sceneryArchive1.readByte(); - } else { // Repeat next byte -data+1 times - j = _sceneryArchive1.readByte(); + } else { // Repeat next byte -data+1 times + int16 j = _sceneryArchive1.readByte(); for (i = 0; i < (byte)(-data + 1); i++, k++) *tmpImage++ = j; @@ -892,12 +843,11 @@ void FileManager_v2d::readOverlay(int screenNum, image_pt image, ovl_t overlayTy char *FileManager_v2d::fetchString(int index) { // Fetch string from file, decode and return ptr to string in memory - uint32 off1, off2; - debugC(1, kDebugFile, "fetchString(%d)", index); // Get offset to string[index] (and next for length calculation) _stringArchive.seek((uint32)index * sizeof(uint32), SEEK_SET); + uint32 off1, off2; if (_stringArchive.read((char *)&off1, sizeof(uint32)) == 0) Utils::Error(FILE_ERR, "%s", "String offset"); if (_stringArchive.read((char *)&off2, sizeof(uint32)) == 0) @@ -927,14 +877,12 @@ FileManager_v1w::~FileManager_v1w() { void FileManager_v1w::readOverlay(int screenNum, image_pt image, ovl_t overlayType) { // Open and read in an overlay file, close file - uint32 i = 0; - image_pt tmpImage = image; // temp ptr to overlay file - sceneBlock_t sceneBlock; // Database header entry - debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum); + image_pt tmpImage = image; // temp ptr to overlay file _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET); + sceneBlock_t sceneBlock; // Database header entry sceneBlock.scene_off = _sceneryArchive1.readUint32LE(); sceneBlock.scene_len = _sceneryArchive1.readUint32LE(); sceneBlock.b_off = _sceneryArchive1.readUint32LE(); @@ -944,6 +892,7 @@ void FileManager_v1w::readOverlay(int screenNum, image_pt image, ovl_t overlayTy sceneBlock.ob_off = _sceneryArchive1.readUint32LE(); sceneBlock.ob_len = _sceneryArchive1.readUint32LE(); + uint32 i = 0; switch (overlayType) { case BOUNDARY: _sceneryArchive1.seek(sceneBlock.b_off, SEEK_SET); @@ -966,7 +915,6 @@ void FileManager_v1w::readOverlay(int screenNum, image_pt image, ovl_t overlayTy image[i] = 0; return; } - _sceneryArchive1.read(tmpImage, OVL_SIZE); } @@ -978,14 +926,11 @@ FileManager_v3d::~FileManager_v3d() { void FileManager_v3d::readBackground(int screenIndex) { // Read a PCX image into dib_a - seq_t seq; // Image sequence structure for Read_pcx - sceneBlock_t sceneBlock; // Read a database header entry - Common::File sceneryArchive; - debugC(1, kDebugFile, "readBackground(%d)", screenIndex); _sceneryArchive1.seek((uint32) screenIndex * sizeof(sceneBlock_t), SEEK_SET); + sceneBlock_t sceneBlock; // Read a database header entry sceneBlock.scene_off = _sceneryArchive1.readUint32LE(); sceneBlock.scene_len = _sceneryArchive1.readUint32LE(); sceneBlock.b_off = _sceneryArchive1.readUint32LE(); @@ -995,16 +940,15 @@ void FileManager_v3d::readBackground(int screenIndex) { sceneBlock.ob_off = _sceneryArchive1.readUint32LE(); sceneBlock.ob_len = _sceneryArchive1.readUint32LE(); + seq_t dummySeq; // Image sequence structure for Read_pcx if (screenIndex < 20) { _sceneryArchive1.seek(sceneBlock.scene_off, SEEK_SET); - // Read the image into dummy seq and static dib_a - readPCX(_sceneryArchive1, &seq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]); + readPCX(_sceneryArchive1, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]); } else { _sceneryArchive2.seek(sceneBlock.scene_off, SEEK_SET); - // Read the image into dummy seq and static dib_a - readPCX(_sceneryArchive2, &seq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]); + readPCX(_sceneryArchive2, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]); } } @@ -1032,17 +976,12 @@ void FileManager_v3d::closeDatabaseFiles() { void FileManager_v3d::readOverlay(int screenNum, image_pt image, ovl_t overlayType) { // Open and read in an overlay file, close file - uint32 i = 0; - int16 j, k; - int8 data; // Must be 8 bits signed - image_pt tmpImage = image; // temp ptr to overlay file - sceneBlock_t sceneBlock; // Database header entry - Common::File sceneryArchive; - debugC(1, kDebugFile, "readOverlay(%d, ...)", screenNum); + image_pt tmpImage = image; // temp ptr to overlay file _sceneryArchive1.seek((uint32)screenNum * sizeof(sceneBlock_t), SEEK_SET); + sceneBlock_t sceneBlock; // Database header entry sceneBlock.scene_off = _sceneryArchive1.readUint32LE(); sceneBlock.scene_len = _sceneryArchive1.readUint32LE(); sceneBlock.b_off = _sceneryArchive1.readUint32LE(); @@ -1052,6 +991,8 @@ void FileManager_v3d::readOverlay(int screenNum, image_pt image, ovl_t overlayTy sceneBlock.ob_off = _sceneryArchive1.readUint32LE(); sceneBlock.ob_len = _sceneryArchive1.readUint32LE(); + uint32 i = 0; + if (screenNum < 20) { switch (overlayType) { case BOUNDARY: @@ -1077,16 +1018,16 @@ void FileManager_v3d::readOverlay(int screenNum, image_pt image, ovl_t overlayTy } // Read in the overlay file using MAC Packbits. (We're not proud!) - k = 0; // byte count + int16 k = 0; // byte count do { - data = _sceneryArchive1.readByte(); // Read a code byte - if ((byte)data == 0x80) // Noop + int8 data = _sceneryArchive1.readByte();// Read a code byte + if ((byte)data == 0x80) // Noop k = k; else if (data >= 0) { // Copy next data+1 literally for (i = 0; i <= (byte)data; i++, k++) *tmpImage++ = _sceneryArchive1.readByte(); } else { // Repeat next byte -data+1 times - j = _sceneryArchive1.readByte(); + int16 j = _sceneryArchive1.readByte(); for (i = 0; i < (byte)(-data + 1); i++, k++) *tmpImage++ = j; @@ -1117,16 +1058,16 @@ void FileManager_v3d::readOverlay(int screenNum, image_pt image, ovl_t overlayTy } // Read in the overlay file using MAC Packbits. (We're not proud!) - k = 0; // byte count + int16 k = 0; // byte count do { - data = _sceneryArchive2.readByte(); // Read a code byte - if ((byte)data == 0x80) // Noop + int8 data = _sceneryArchive2.readByte();// Read a code byte + if ((byte)data == 0x80) // Noop k = k; else if (data >= 0) { // Copy next data+1 literally for (i = 0; i <= (byte)data; i++, k++) *tmpImage++ = _sceneryArchive2.readByte(); - } else { // Repeat next byte -data+1 times - j = _sceneryArchive2.readByte(); + } else { // Repeat next byte -data+1 times + int16 j = _sceneryArchive2.readByte(); for (i = 0; i < (byte)(-data + 1); i++, k++) *tmpImage++ = j; diff --git a/engines/hugo/file.h b/engines/hugo/file.h index 8a0188f2f3..a5679d0e1b 100644 --- a/engines/hugo/file.h +++ b/engines/hugo/file.h @@ -35,7 +35,23 @@ // TODO get rid of those defines #define HELPFILE "help.dat" -#define EOP '#' /* Marks end of a page in help file */ +#define EOP '#' // Marks end of a page in help file + +struct PCC_header_t { // Structure of PCX file header + byte mfctr, vers, enc, bpx; + uint16 x1, y1, x2, y2; // bounding box + uint16 xres, yres; + byte palette[48]; // EGA color palette + byte vmode, planes; + uint16 bytesPerLine; // Bytes per line + byte fill2[60]; +}; // Header of a PCC file + +// Record and playback handling stuff: +struct pbdata_t { +// int key; // Character + uint32 time; // Time at which character was pressed +}; namespace Hugo { @@ -70,9 +86,9 @@ public: protected: HugoEngine &_vm; - Common::File _stringArchive; /* Handle for string file */ - Common::File _sceneryArchive1; /* Handle for scenery file */ - Common::File _objectsArchive; /* Handle for objects file */ + Common::File _stringArchive; // Handle for string file + Common::File _sceneryArchive1; // Handle for scenery file + Common::File _objectsArchive; // Handle for objects file seq_t *readPCX(Common::File &f, seq_t *seqPtr, byte *imagePtr, bool firstFl, const char *name); private: @@ -80,6 +96,9 @@ private: byte *convertPCC(byte *p, uint16 y, uint16 bpl, image_pt data_p); uif_hdr_t *getUIFHeader(uif_t id); + pbdata_t pbdata; + FILE *fpb; + //Strangerke : Not used? void openPlaybackFile(bool playbackFl, bool recordFl); void printBootText(); @@ -121,7 +140,7 @@ public: void readBackground(int screenIndex); void readOverlay(int screenNum, image_pt image, ovl_t overlayType); private: - Common::File _sceneryArchive2; /* Handle for scenery file */ + Common::File _sceneryArchive2; // Handle for scenery file }; class FileManager_v1w : public FileManager_v2d { diff --git a/engines/hugo/game.h b/engines/hugo/game.h index fd019e9084..09bdce711d 100644 --- a/engines/hugo/game.h +++ b/engines/hugo/game.h @@ -841,7 +841,7 @@ extern hugo_boot_t _boot; // Boot info structure extern char _textBoxBuffer[]; // Useful box text buffer extern command_t _line; // Line of user text input -/* Structure of scenery file lookup entry */ +// Structure of scenery file lookup entry struct sceneBlock_t { uint32 scene_off; uint32 scene_len; @@ -853,7 +853,7 @@ struct sceneBlock_t { uint32 ob_len; }; -/* Structure of object file lookup entry */ +// Structure of object file lookup entry struct objBlock_t { uint32 objOffset; uint32 objLength; diff --git a/engines/hugo/global.h b/engines/hugo/global.h index 1437eb3734..0ab21ddb9c 100644 --- a/engines/hugo/global.h +++ b/engines/hugo/global.h @@ -34,18 +34,19 @@ namespace Hugo { #define HERO 0 // In all enums, HERO is the first element -#define DESCRIPLEN 32 /* Length of description string */ -#define MAX_SOUNDS 64 /* Max number of sounds */ -#define BOOTFILE "HUGO.BSF" /* Name of boot structure file */ -#define LEN_MASK 0x3F /* Lower 6 bits are length */ +#define DESCRIPLEN 32 // Length of description string +#define MAX_SOUNDS 64 // Max number of sounds +#define BOOTFILE "HUGO.BSF" // Name of boot structure file +#define LEN_MASK 0x3F // Lower 6 bits are length #define PBFILE "playback.dat" -/* Name scenery and objects picture databases */ +// Name scenery and objects picture databases #define OBJECTS_FILE "objects.dat" #define STRING_FILE "strings.dat" #define SOUND_FILE "sounds.dat" -/* User interface database (Windows Only) */ +// User interface database (Windows Only) +// This file contains, between others, the bitmaps of the fonts used in the application #define UIF_FILE "uif.dat" static const int kSavegameVersion = 1; diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp index f36a195198..58629b5189 100644 --- a/engines/hugo/hugo.cpp +++ b/engines/hugo/hugo.cpp @@ -44,7 +44,7 @@ namespace Hugo { -HugoEngine *HugoEngine::s_Engine = NULL; +HugoEngine *HugoEngine::s_Engine = 0; overlay_t HugoEngine::_boundary; overlay_t HugoEngine::_overlay; @@ -273,7 +273,6 @@ void HugoEngine::runMachine() { static uint32 lastTime; status_t &gameStatus = getGameStatus(); - // Don't process if we're in a textbox if (gameStatus.textBoxFl) return; @@ -324,10 +323,6 @@ void HugoEngine::runMachine() { bool HugoEngine::loadHugoDat() { Common::File in; - int numElem, numSubElem, numSubAct; - char buf[256]; - int majVer, minVer; - in.open("hugo.dat"); if (!in.isOpen()) { @@ -338,6 +333,7 @@ bool HugoEngine::loadHugoDat() { } // Read header + char buf[256]; in.read(buf, 4); buf[4] = '\0'; @@ -348,8 +344,8 @@ bool HugoEngine::loadHugoDat() { return false; } - majVer = in.readByte(); - minVer = in.readByte(); + int majVer = in.readByte(); + int minVer = in.readByte(); if ((majVer != HUGO_DAT_VER_MAJ) || (minVer != HUGO_DAT_VER_MIN)) { snprintf(buf, 256, "File 'hugo.dat' is wrong version. Expected %d.%d but got %d.%d. Get it from the ScummVM website", HUGO_DAT_VER_MAJ, HUGO_DAT_VER_MIN, majVer, minVer); @@ -380,9 +376,8 @@ bool HugoEngine::loadHugoDat() { // Read palette _paletteSize = in.readUint16BE(); _palette = (byte *)malloc(sizeof(byte) * _paletteSize); - for (int i = 0; i < _paletteSize; i++) { + for (int i = 0; i < _paletteSize; i++) _palette[i] = in.readByte(); - } // Read textEngine _textEngine = loadTexts(in); @@ -455,6 +450,7 @@ bool HugoEngine::loadHugoDat() { } } + int numElem, numSubElem, numSubAct; //Read _invent for (int varnt = 0; varnt < _numVariant; varnt++) { numElem = in.readUint16BE(); @@ -614,9 +610,9 @@ bool HugoEngine::loadHugoDat() { _screenActs = (uint16 **)malloc(sizeof(uint16 *) * numElem); for (int i = 0; i < numElem; i++) { numSubElem = in.readUint16BE(); - if (numSubElem == 0) + if (numSubElem == 0) { _screenActs[i] = 0; - else { + } else { _screenActs[i] = (uint16 *)malloc(sizeof(uint16) * numSubElem); for (int j = 0; j < numSubElem; j++) _screenActs[i][j] = in.readUint16BE(); @@ -1432,25 +1428,23 @@ char **HugoEngine::loadTextsVariante(Common::File &in, uint16 *arraySize) { uint16 **HugoEngine::loadLongArray(Common::File &in) { uint16 **resArray = 0; - uint16 *resRow = 0; - uint16 dummy, numRows, numElems; for (int varnt = 0; varnt < _numVariant; varnt++) { - numRows = in.readUint16BE(); + uint16 numRows = in.readUint16BE(); if (varnt == _gameVariant) { resArray = (uint16 **)malloc(sizeof(uint16 *) * (numRows + 1)); resArray[numRows] = 0; } for (int i = 0; i < numRows; i++) { - numElems = in.readUint16BE(); + uint16 numElems = in.readUint16BE(); if (varnt == _gameVariant) { - resRow = (uint16 *)malloc(sizeof(uint16) * numElems); + uint16 *resRow = (uint16 *)malloc(sizeof(uint16) * numElems); for (int j = 0; j < numElems; j++) resRow[j] = in.readUint16BE(); resArray[i] = resRow; } else { for (int j = 0; j < numElems; j++) - dummy = in.readUint16BE(); + in.readUint16BE(); } } } @@ -1458,24 +1452,19 @@ uint16 **HugoEngine::loadLongArray(Common::File &in) { } char ***HugoEngine::loadTextsArray(Common::File &in) { - int numNouns; - int numTexts; - int entryLen; - int len; char ***resArray = 0; - char **res = 0; - char *pos = 0; for (int varnt = 0; varnt < _numVariant; varnt++) { - numNouns = in.readUint16BE(); + int numNouns = in.readUint16BE(); if (varnt == _gameVariant) { resArray = (char ** *)malloc(sizeof(char **) * (numNouns + 1)); resArray[numNouns] = 0; } for (int i = 0; i < numNouns; i++) { - numTexts = in.readUint16BE(); - entryLen = in.readUint16BE(); - pos = (char *)malloc(entryLen); + int numTexts = in.readUint16BE(); + int entryLen = in.readUint16BE(); + char *pos = (char *)malloc(entryLen); + char **res = 0; if (varnt == _gameVariant) { res = (char **)malloc(sizeof(char *) * numTexts); res[0] = pos; @@ -1492,7 +1481,7 @@ char ***HugoEngine::loadTextsArray(Common::File &in) { res[j] = pos; pos -= 2; - len = READ_BE_UINT16(pos); + int len = READ_BE_UINT16(pos); pos += 2 + len; } @@ -1507,12 +1496,8 @@ char ***HugoEngine::loadTextsArray(Common::File &in) { char **HugoEngine::loadTexts(Common::File &in) { int numTexts = in.readUint16BE(); char **res = (char **)malloc(sizeof(char *) * numTexts); - int entryLen; - char *pos = 0; - int len; - - entryLen = in.readUint16BE(); - pos = (char *)malloc(entryLen); + int entryLen = in.readUint16BE(); + char *pos = (char *)malloc(entryLen); in.read(pos, entryLen); @@ -1521,7 +1506,7 @@ char **HugoEngine::loadTexts(Common::File &in) { for (int i = 1; i < numTexts; i++) { pos -= 2; - len = READ_BE_UINT16(pos); + int len = READ_BE_UINT16(pos); pos += 2 + len; res[i] = pos; } diff --git a/engines/hugo/hugo.h b/engines/hugo/hugo.h index 7bab3a95ad..9ba7b47b22 100644 --- a/engines/hugo/hugo.h +++ b/engines/hugo/hugo.h @@ -157,7 +157,7 @@ public: // Temporary, until the engine is fully objectified. static HugoEngine &get() { - assert(s_Engine != NULL); + assert(s_Engine != 0); return *s_Engine; } diff --git a/engines/hugo/intro.cpp b/engines/hugo/intro.cpp index d988b998b2..499f0136e9 100644 --- a/engines/hugo/intro.cpp +++ b/engines/hugo/intro.cpp @@ -149,8 +149,8 @@ void intro_v1d::introInit() { } bool intro_v1d::introPlay() { - byte introSize = _vm.getIntroSize(); static int state = 0; + byte introSize = _vm.getIntroSize(); if (introTicks < introSize) { switch (state++) { diff --git a/engines/hugo/inventory.cpp b/engines/hugo/inventory.cpp index c5f09ad653..5046d191c3 100644 --- a/engines/hugo/inventory.cpp +++ b/engines/hugo/inventory.cpp @@ -54,8 +54,6 @@ InventoryHandler::InventoryHandler(HugoEngine &vm) : _vm(vm) { // scrollFl is TRUE if scroll arrows required // firstObjId is index of first (scrolled) inventory object to display void InventoryHandler::constructInventory(int16 imageTotNumb, int displayNumb, bool scrollFl, int16 firstObjId) { - int16 ux, uy, ix; // Coordinates of icons - debugC(1, kDebugInventory, "constructInventory(%d, %d, %d, %d)", imageTotNumb, displayNumb, (scrollFl) ? 0 : 1, firstObjId); // Clear out icon buffer @@ -77,11 +75,11 @@ void InventoryHandler::constructInventory(int16 imageTotNumb, int displayNumb, b // Check still room to display and past first scroll index if (displayed < displayNumb && carried >= firstObjId) { // Compute source coordinates in dib_u - ux = (i + NUM_ARROWS) * INV_DX % XPIX; - uy = (i + NUM_ARROWS) * INV_DX / XPIX * INV_DY; + int16 ux = (i + NUM_ARROWS) * INV_DX % XPIX; + int16 uy = (i + NUM_ARROWS) * INV_DX / XPIX * INV_DY; // Compute dest coordinates in dib_i - ix = ((scrollFl) ? displayed + 1 : displayed) * INV_DX; + int16 ix = ((scrollFl) ? displayed + 1 : displayed) * INV_DX; displayed++; // Count number displayed // Copy the icon @@ -95,24 +93,23 @@ void InventoryHandler::constructInventory(int16 imageTotNumb, int displayNumb, b // Process required action for inventory // Returns objId under cursor (or -1) for INV_GET int16 InventoryHandler::processInventory(invact_t action, ...) { + debugC(1, kDebugInventory, "processInventory(invact_t action, ...)"); + static int16 firstIconId = 0; // Index of first icon to display - int16 i, j; - int16 objId = -1; // Return objid under cursor + int16 imageNumb; // Total number of inventory items int displayNumb; // Total number displayed/carried - int16 cursorx, cursory; // Current cursor position - bool scrollFl; // TRUE if scroll arrows needed - va_list marker; // Args used for D_ADD operation - - debugC(1, kDebugInventory, "processInventory(invact_t action, ...)"); - // Compute total number and number displayed, i.e. number carried - for (imageNumb = 0, displayNumb = 0; imageNumb < _vm._maxInvent && _vm._invent[imageNumb] != -1; imageNumb++) + for (imageNumb = 0, displayNumb = 0; imageNumb < _vm._maxInvent && _vm._invent[imageNumb] != -1; imageNumb++) { if (_vm._objects[_vm._invent[imageNumb]].carriedFl) displayNumb++; + } // Will we need the scroll arrows? - scrollFl = displayNumb > MAX_DISP; + bool scrollFl = displayNumb > MAX_DISP; + va_list marker; // Args used for D_ADD operation + int16 cursorx, cursory; // Current cursor position + int16 objId = -1; // Return objid under cursor switch (action) { case INV_INIT: // Initialize inventory display @@ -135,11 +132,11 @@ int16 InventoryHandler::processInventory(invact_t action, ...) { cursory -= DIBOFF_Y; // Icon bar is at true zero if (cursory > 0 && cursory < INV_DY) { // Within icon bar? - i = cursorx / INV_DX; // Compute icon index - if (scrollFl) { // Scroll buttons displayed - if (i == 0) // Left scroll button + int16 i = cursorx / INV_DX; // Compute icon index + if (scrollFl) { // Scroll buttons displayed + if (i == 0) { // Left scroll button objId = LEFT_ARROW; - else { + } else { if (i == MAX_DISP - 1) // Right scroll button objId = RIGHT_ARROW; else // Adjust for scroll @@ -148,12 +145,16 @@ int16 InventoryHandler::processInventory(invact_t action, ...) { } // If not an arrow, find object id - limit to valid range - if (objId == -1 && i < displayNumb) + if (objId == -1 && i < displayNumb) { // Find objid by counting # carried objects == i+1 - for (j = 0, i++; i > 0 && j < _vm._numObj; j++) - if (_vm._objects[j].carriedFl) + int16 j; + for (j = 0, i++; i > 0 && j < _vm._numObj; j++) { + if (_vm._objects[j].carriedFl) { if (--i == 0) objId = j; + } + } + } } break; } diff --git a/engines/hugo/mouse.cpp b/engines/hugo/mouse.cpp index 01df8f8ac9..b305489568 100644 --- a/engines/hugo/mouse.cpp +++ b/engines/hugo/mouse.cpp @@ -64,7 +64,6 @@ MouseHandler::MouseHandler(HugoEngine &vm) : _vm(vm) { // Shadow-blit supplied string into dib_a at cx,cy and add to display list void MouseHandler::cursorText(char *buffer, int16 cx, int16 cy, uif_t fontId, int16 color) { - debugC(1, kDebugMouse, "cursorText(%s, %d, %d, %d, %d)", buffer, cx, cy, fontId, color); _vm.screen().loadFont(fontId); @@ -80,28 +79,23 @@ void MouseHandler::cursorText(char *buffer, int16 cx, int16 cy, uif_t fontId, in _vm.screen().displayList(D_ADD, sx, sy, sdx, sdy); } - // Find the exit hotspot containing cx, cy. // Return hotspot index or -1 if not found. int16 MouseHandler::findExit(int16 cx, int16 cy) { - int i; - hotspot_t *hotspot; - debugC(2, kDebugMouse, "findExit(%d, %d)", cx, cy); - for (i = 0, hotspot = _vm._hotspots; hotspot->screenIndex >= 0; i++, hotspot++) - if (hotspot->screenIndex == *_vm._screen_p) + int i = 0; + for (hotspot_t *hotspot = _vm._hotspots; hotspot->screenIndex >= 0; i++, hotspot++) { + if (hotspot->screenIndex == *_vm._screen_p) { if (cx >= hotspot->x1 && cx <= hotspot->x2 && cy >= hotspot->y1 && cy <= hotspot->y2) - return(i); - return(-1); + return i; + } + } + return -1; } // Process a mouse right click at coord cx, cy over object objid void MouseHandler::processRightClick(int16 objId, int16 cx, int16 cy) { - object_t *obj; - int16 x, y; - bool foundFl = false; // TRUE if route found to object - debugC(1, kDebugMouse, "Process_rclick(%d, %d, %d)", objId, cx, cy); status_t &gameStatus = _vm.getGameStatus(); @@ -109,21 +103,23 @@ void MouseHandler::processRightClick(int16 objId, int16 cx, int16 cy) { if (gameStatus.storyModeFl || _vm._hero->pathType == QUIET) // Make sure user has control return; + bool foundFl = false; // TRUE if route found to object // Check if this was over iconbar if (gameStatus.inventoryState == I_ACTIVE && cy < INV_DY + DIBOFF_Y) { // Clicked over iconbar object if (gameStatus.inventoryObjId == -1) gameStatus.inventoryObjId = objId; // Not using so select new object else if (gameStatus.inventoryObjId == objId) - gameStatus.inventoryObjId = -1; // Same icon - deselect it + gameStatus.inventoryObjId = -1; // Same icon - deselect it else - _vm.useObject(objId); // Use status.objid on object + _vm.useObject(objId); // Use status.objid on object } else { // Clicked over viewport object - obj = &_vm._objects[objId]; + object_t *obj = &_vm._objects[objId]; + int16 x, y; switch (obj->viewx) { // Where to walk to case -1: // Walk to object position if (_vm.findObjectSpace(obj, &x, &y)) foundFl = _vm.route().startRoute(GO_GET, objId, x, y); - if (!foundFl) // Can't get there, try to use from here + if (!foundFl) // Can't get there, try to use from here _vm.useObject(objId); break; case 0: // Immediate use @@ -131,7 +127,7 @@ void MouseHandler::processRightClick(int16 objId, int16 cx, int16 cy) { break; default: // Walk to view point if possible if (!_vm.route().startRoute(GO_GET, objId, obj->viewx, obj->viewy)) { - if (_vm._hero->cycling == INVISIBLE) // If invisible do + if (_vm._hero->cycling == INVISIBLE)// If invisible do _vm.useObject(objId); // immediate use else Utils::Box(BOX_ANY, "%s", _vm._textMouse[kMsNoWayText]); // Can't get there @@ -148,11 +144,10 @@ void MouseHandler::processRightClick(int16 objId, int16 cx, int16 cy) { // 4. Nothing - attempt to walk there // 5. Exit - walk to exit hotspot void MouseHandler::processLeftClick(int16 objId, int16 cx, int16 cy) { + debugC(1, kDebugMouse, "Process_lclick(%d, %d, %d)", objId, cx, cy); + int16 i, x, y; object_t *obj; - bool foundFl = false; // TRUE if route found to object - - debugC(1, kDebugMouse, "Process_lclick(%d, %d, %d)", objId, cx, cy); status_t &gameStatus = _vm.getGameStatus(); @@ -202,11 +197,12 @@ void MouseHandler::processLeftClick(int16 objId, int16 cx, int16 cy) { if (gameStatus.inventoryState == I_ACTIVE && cy < INV_DY + DIBOFF_Y) _vm.lookObject(obj); else { + bool foundFl = false; // TRUE if route found to object switch (obj->viewx) { // Clicked over viewport object case -1: // Walk to object position if (_vm.findObjectSpace(obj, &x, &y)) foundFl = _vm.route().startRoute(GO_LOOK, objId, x, y); - if (!foundFl) // Can't get there, immediate description + if (!foundFl) // Can't get there, immediate description _vm.lookObject(obj); break; case 0: // Immediate description @@ -215,7 +211,7 @@ void MouseHandler::processLeftClick(int16 objId, int16 cx, int16 cy) { default: // Walk to view point if possible if (!_vm.route().startRoute(GO_LOOK, objId, obj->viewx, obj->viewy)) { if (_vm._hero->cycling == INVISIBLE) // If invisible do - _vm.lookObject(obj); // immediate decription + _vm.lookObject(obj); // immediate decription else Utils::Box(BOX_ANY, "%s", _vm._textMouse[kMsNoWayText]); // Can't get there } @@ -228,12 +224,6 @@ void MouseHandler::processLeftClick(int16 objId, int16 cx, int16 cy) { // Process mouse activity void MouseHandler::mouseHandler() { - int16 iconId; // Find index of dragged icon - int iconx, icony; // Icon position (in dib_a) - int16 ux, uy; // Icon position (in dib_u) - int16 objId = -1; // Current source object - char *name; // Name of object to display - debugC(2, kDebugMouse, "mouseHandler"); int16 cx = _vm.getMouseX(); @@ -241,7 +231,7 @@ void MouseHandler::mouseHandler() { status_t &gameStatus = _vm.getGameStatus(); - gameStatus.cx = cx; // Save cursor coords + gameStatus.cx = cx; // Save cursor coords gameStatus.cy = cy; // Don't process if outside client area @@ -251,17 +241,19 @@ void MouseHandler::mouseHandler() { // Display dragged inventory icon if one currently selected if (gameStatus.inventoryObjId != -1) { // Find index of icon - for (iconId = 0; iconId < _vm._maxInvent; iconId++) + int16 iconId; // Find index of dragged icon + for (iconId = 0; iconId < _vm._maxInvent; iconId++) { if (gameStatus.inventoryObjId == _vm._invent[iconId]) break; + } // Compute source coordinates in dib_u - ux = (iconId + NUM_ARROWS) * INV_DX % XPIX; - uy = (iconId + NUM_ARROWS) * INV_DX / XPIX * INV_DY; + int16 ux = (iconId + NUM_ARROWS) * INV_DX % XPIX; + int16 uy = (iconId + NUM_ARROWS) * INV_DX / XPIX * INV_DY; // Compute destination coordinates in dib_a - iconx = cx + IX_OFF; - icony = cy + IY_OFF; + int iconx = cx + IX_OFF; + int icony = cy + IY_OFF; iconx = MAX(iconx, 0); // Keep within dib_a bounds iconx = MIN(iconx, XPIX - INV_DX); icony = MAX(icony, 0); @@ -272,6 +264,7 @@ void MouseHandler::mouseHandler() { _vm.screen().displayList(D_ADD, iconx, icony, INV_DX, INV_DY); } + int16 objId = -1; // Current source object // Process cursor over an object or icon if (gameStatus.inventoryState == I_ACTIVE) // Check inventory icon bar first objId = _vm.inventory().processInventory(INV_GET, cx, cy); @@ -280,7 +273,7 @@ void MouseHandler::mouseHandler() { if (objId >= 0) { // Got a match // Display object name next to cursor (unless CURSOR_NOCHAR) // Note test for swapped hero name - name = _vm._arrayNouns[_vm._objects[(objId == HERO) ? _vm._heroImage : objId].nounIndex][CURSOR_NAME]; + char *name = _vm._arrayNouns[_vm._objects[(objId == HERO) ? _vm._heroImage : objId].nounIndex][CURSOR_NAME]; if (name[0] != CURSOR_NOCHAR) cursorText(name, cx, cy, U_FONT8, _TBRIGHTWHITE); diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp index aa7c1d68c3..59fe023788 100644 --- a/engines/hugo/parser.cpp +++ b/engines/hugo/parser.cpp @@ -57,11 +57,11 @@ Parser::Parser(HugoEngine &vm) : } void Parser::keyHandler(uint16 nChar, uint16 nFlags) { + debugC(1, kDebugParser, "keyHandler(%d, %d)", nChar, nFlags); + status_t &gameStatus = _vm.getGameStatus(); bool repeatedFl = (nFlags & 0x4000); // TRUE if key is a repeat - debugC(1, kDebugParser, "keyHandler(%d, %d)", nChar, nFlags); - // Process key down event - called from OnKeyDown() switch (nChar) { // Set various toggle states case Common::KEYCODE_ESCAPE: // Escape key, may want to QUIT @@ -126,21 +126,17 @@ void Parser::keyHandler(uint16 nChar, uint16 nFlags) { // Add any new chars to line buffer and display them. // If CR pressed, pass line to Line_handler() void Parser::charHandler() { + debugC(4, kDebugParser, "charHandler"); + static int16 lineIndex = 0; // Index into line static uint32 tick = 0; // For flashing cursor static char cursor = '_'; - char c; static command_t cmdLine; // Build command line status_t &gameStatus = _vm.getGameStatus(); -// Strangerke : Useless ? -// bool updateFl = (_getIndex != _putIndex); // TRUE if any chars processed -// command_t status_line; // Includes prompt, cursor - - debugC(4, kDebugParser, "charHandler"); // Check for one or more characters in ring buffer while (_getIndex != _putIndex) { - c = _ringBuffer[_getIndex++]; + char c = _ringBuffer[_getIndex++]; if (_getIndex >= sizeof(_ringBuffer)) _getIndex = 0; @@ -172,11 +168,8 @@ void Parser::charHandler() { } // See if time to blink cursor, set cursor character - if ((tick++ % (TPS / BLINKS)) == 0) { -// Strangerke : Useless ? -// updateFl = true; // Force an update + if ((tick++ % (TPS / BLINKS)) == 0) cursor = (cursor == '_') ? ' ' : '_'; - } // See if recall button pressed if (gameStatus.recallFl) { @@ -211,15 +204,10 @@ void Parser::command(const char *format, ...) { // Parse the user's line of text input. Generate events as necessary void Parser::lineHandler() { - char *noun, *verb; // ptrs to noun and verb strings - object_t *obj; - char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby - char contextComment[XBYTES * 5] = ""; // Unused comment for context objects - status_t &gameStatus = _vm.getGameStatus(); - - debugC(1, kDebugParser, "lineHandler"); + status_t &gameStatus = _vm.getGameStatus(); + // Toggle God Mode if (!strncmp(_line, "PPG", 3)) { _vm.sound().playSound(!_vm._soundTest, BOTH_CHANNELS, HIGH_PRI); @@ -236,36 +224,42 @@ void Parser::lineHandler() { // find <object name> Takes hero to screen containing named object if (gameStatus.godModeFl) { // Special code to allow me to go straight to any screen - if (strstr(_line, "goto")) - for (int i = 0; i < _vm._numScreens; i++) + if (strstr(_line, "goto")) { + for (int i = 0; i < _vm._numScreens; i++) { if (!strcmp(&_line[strlen("goto") + 1], _vm._screenNames[i])) { _vm.scheduler().newScreen(i); return; } + } + } // Special code to allow me to get objects from anywhere if (strstr(_line, "fetch all")) { - for (int i = 0; i < _vm._numObj; i++) + for (int i = 0; i < _vm._numObj; i++) { if (_vm._objects[i].genericCmd & TAKE) takeObject(&_vm._objects[i]); + } return; } if (strstr(_line, "fetch")) { - for (int i = 0; i < _vm._numObj; i++) + for (int i = 0; i < _vm._numObj; i++) { if (!strcmp(&_line[strlen("fetch") + 1], _vm._arrayNouns[_vm._objects[i].nounIndex][0])) { takeObject(&_vm._objects[i]); return; } + } } // Special code to allow me to goto objects - if (strstr(_line, "find")) - for (int i = 0; i < _vm._numObj; i++) + if (strstr(_line, "find")) { + for (int i = 0; i < _vm._numObj; i++) { if (!strcmp(&_line[strlen("find") + 1], _vm._arrayNouns[_vm._objects[i].nounIndex][0])) { _vm.scheduler().newScreen(_vm._objects[i].screenIndex); return; } + } + } } // Special meta commands @@ -300,21 +294,26 @@ void Parser::lineHandler() { return; } + char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby + // Test for nearby objects referenced explicitly for (int i = 0; i < _vm._numObj; i++) { - obj = &_vm._objects[i]; - if (isWordPresent(_vm._arrayNouns[obj->nounIndex])) + object_t *obj = &_vm._objects[i]; + if (isWordPresent(_vm._arrayNouns[obj->nounIndex])) { if (isObjectVerb(obj, farComment) || isGenericVerb(obj, farComment)) return; + } } // Test for nearby objects that only require a verb // Note comment is unused if not near. for (int i = 0; i < _vm._numObj; i++) { - obj = &_vm._objects[i]; - if (obj->verbOnlyFl) + object_t *obj = &_vm._objects[i]; + if (obj->verbOnlyFl) { + char contextComment[XBYTES * 5] = ""; // Unused comment for context objects if (isObjectVerb(obj, contextComment) || isGenericVerb(obj, contextComment)) return; + } } // No objects match command line, try background and catchall commands @@ -334,19 +333,20 @@ void Parser::lineHandler() { } // Nothing matches. Report recognition success to user. - verb = findVerb(); - noun = findNoun(); + char *verb = findVerb(); + char *noun = findNoun(); if (verb == _vm._arrayVerbs[_vm._look][0] && _maze.enabledFl) { Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBMaze]); showTakeables(); - } else if (verb && noun) // A combination I didn't think of + } else if (verb && noun) { // A combination I didn't think of Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoPoint]); - else if (noun) + } else if (noun) { Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoun]); - else if (verb) + } else if (verb) { Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBVerb]); - else + } else { Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh]); + } } // Search for matching verb/noun pairs in background command list @@ -354,15 +354,16 @@ void Parser::lineHandler() { bool Parser::isBackgroundWord(objectList_t obj) { debugC(1, kDebugParser, "isBackgroundWord(object_list_t obj)"); - for (int i = 0; obj[i].verbIndex != 0; i++) + for (int i = 0; obj[i].verbIndex != 0; i++) { if (isWordPresent(_vm._arrayVerbs[obj[i].verbIndex]) && - isWordPresent(_vm._arrayNouns[obj[i].nounIndex]) && - ((obj[i].roomState == DONT_CARE) || - (obj[i].roomState == _vm._screenStates[*_vm._screen_p]))) { + isWordPresent(_vm._arrayNouns[obj[i].nounIndex]) && + ((obj[i].roomState == DONT_CARE) || + (obj[i].roomState == _vm._screenStates[*_vm._screen_p]))) { Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex)); _vm.scheduler().processBonus(obj[i].bonusIndex); return true; } + } return false; } @@ -373,7 +374,7 @@ bool Parser::isBackgroundWord(objectList_t obj) { bool Parser::isCatchallVerb(objectList_t obj) { debugC(1, kDebugParser, "isCatchallVerb(object_list_t obj)"); - for (int i = 0; obj[i].verbIndex != 0; i++) + for (int i = 0; obj[i].verbIndex != 0; i++) { if (isWordPresent(_vm._arrayVerbs[obj[i].verbIndex]) && obj[i].nounIndex == 0 && (!obj[i].matchFl || !findNoun()) && ((obj[i].roomState == DONT_CARE) || @@ -385,8 +386,9 @@ bool Parser::isCatchallVerb(objectList_t obj) { if (*(_vm._arrayVerbs[obj[i].verbIndex]) == _vm._arrayVerbs[_vm._look][0]) showTakeables(); - return(true); + return true; } + } return false; } @@ -398,7 +400,7 @@ bool Parser::isNear(object_t *obj, char *verb, char *comment) { debugC(1, kDebugParser, "isNear(object_t *obj, %s, %s)", verb, comment); if (obj->carriedFl) // Object is being carried - return(true); + return true; if (obj->screenIndex != *_vm._screen_p) { // Not in same screen @@ -406,41 +408,42 @@ bool Parser::isNear(object_t *obj, char *verb, char *comment) { strcpy(comment, _vm._textParser[kCmtAny1]); else strcpy(comment, _vm._textParser[kCmtAny2]); - return(false); + return false; } if (obj->cycling == INVISIBLE) { if (obj->seqNumb) { // There is an image strcpy(comment, _vm._textParser[kCmtAny3]); - return(false); - } else + return false; + } else { // No image, assume visible if ((obj->radius < 0) || ((abs(obj->x - _vm._hero->x) <= obj->radius) && - (abs(obj->y - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) - return(true); - else { + (abs(obj->y - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) { + return true; + } else { // User is not close enough if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0])) strcpy(comment, _vm._textParser[kCmtAny1]); else strcpy(comment, _vm._textParser[kCmtClose]); - return(false); + return false; } + } } if ((obj->radius < 0) || ((abs(obj->x - _vm._hero->x) <= obj->radius) && - (abs(obj->y + obj->currImagePtr->y2 - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) - return(true); - else { + (abs(obj->y + obj->currImagePtr->y2 - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) { + return true; + } else { // User is not close enough if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0])) strcpy(comment, _vm._textParser[kCmtAny1]); else strcpy(comment, _vm._textParser[kCmtClose]); - return(false); + return false; } return true; } @@ -449,12 +452,12 @@ bool Parser::isNear(object_t *obj, char *verb, char *comment) { bool Parser::isWordPresent(char **wordArr) { debugC(1, kDebugParser, "isWordPresent(%s)", wordArr[0]); - if (wordArr != NULL) { - for (int i = 0; strlen(wordArr[i]); i++) + if (wordArr != 0) { + for (int i = 0; strlen(wordArr[i]); i++) { if (strstr(_line, wordArr[i])) - return(true); + return true; + } } - return false; } @@ -462,36 +465,37 @@ bool Parser::isWordPresent(char **wordArr) { char *Parser::findNoun() { debugC(1, kDebugParser, "findNoun()"); - for (int i = 0; _vm._arrayNouns[i]; i++) - for (int j = 0; strlen(_vm._arrayNouns[i][j]); j++) + for (int i = 0; _vm._arrayNouns[i]; i++) { + for (int j = 0; strlen(_vm._arrayNouns[i][j]); j++) { if (strstr(_line, _vm._arrayNouns[i][j])) - return(_vm._arrayNouns[i][0]); - return NULL; + return _vm._arrayNouns[i][0]; + } + } + return 0; } // Locate word in list of verbs and return ptr to first string in verb list char *Parser::findVerb() { debugC(1, kDebugParser, "findVerb()"); - for (int i = 0; _vm._arrayVerbs[i]; i++) - for (int j = 0; strlen(_vm._arrayVerbs[i][j]); j++) + for (int i = 0; _vm._arrayVerbs[i]; i++) { + for (int j = 0; strlen(_vm._arrayVerbs[i][j]); j++) { if (strstr(_line, _vm._arrayVerbs[i][j])) - return(_vm._arrayVerbs[i][0]); - return NULL; + return _vm._arrayVerbs[i][0]; + } + } + return 0; } // Describe any takeable objects visible in this screen void Parser::showTakeables() { - object_t *obj; - debugC(1, kDebugParser, "showTakeables"); for (int j = 0; j < _vm._numObj; j++) { - obj = &_vm._objects[j]; + object_t *obj = &_vm._objects[j]; if ((obj->cycling != INVISIBLE) && (obj->screenIndex == *_vm._screen_p) && (((TAKE & obj->genericCmd) == TAKE) || obj->objValue)) { -// sprintf(_textBoxBuffer, "You can also see:\n%s.", _vm._arrayNouns[obj->nounIndex][LOOK_NAME]); Utils::Box(BOX_ANY, "You can also see:\n%s.", _vm._arrayNouns[obj->nounIndex][LOOK_NAME]); } } @@ -545,13 +549,14 @@ bool Parser::isGenericVerb(object_t *obj, char *comment) { Utils::Box(BOX_ANY, "%s", _vm._textData[obj->stateDataIndex[obj->state]]); warning("isGenericVerb: use of state dependant look - To be validated"); } else { - if ((LOOK & obj->genericCmd) == LOOK) + if ((LOOK & obj->genericCmd) == LOOK) { if (_vm._textData[obj->dataIndex]) Utils::Box(BOX_ANY, "%s", _vm._textData[obj->dataIndex]); else - return(false); - else + return false; + } else { Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBUnusual]); + } } } else if (isWordPresent(_vm._arrayVerbs[_vm._take]) && isNear(obj, _vm._arrayVerbs[_vm._take][0], comment)) { if (obj->carriedFl) @@ -573,8 +578,9 @@ bool Parser::isGenericVerb(object_t *obj, char *comment) { Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNeed]); else return false; - } else // It was not a generic cmd + } else { // It was not a generic cmd return false; + } return true; } @@ -583,9 +589,10 @@ bool Parser::isGenericVerb(object_t *obj, char *comment) { bool Parser::isCarrying(uint16 wordIndex) { debugC(1, kDebugParser, "isCarrying(%d)", wordIndex); - for (int i = 0; i < _vm._numObj; i++) + for (int i = 0; i < _vm._numObj; i++) { if ((wordIndex == _vm._objects[i].nounIndex) && _vm._objects[i].carriedFl) return true; + } return false; } @@ -593,39 +600,37 @@ bool Parser::isCarrying(uint16 wordIndex) { // If it does, and the object is near and passes the tests in the command // list then carry out the actions in the action list and return TRUE bool Parser::isObjectVerb(object_t *obj, char *comment) { - int i; - cmd *cmnd; - char *verb; - uint16 *reqs; - uint16 cmdIndex; - debugC(1, kDebugParser, "isObjectVerb(object_t *obj, %s)", comment); // First, find matching verb in cmd list - cmdIndex = obj->cmdIndex; // ptr to list of commands + uint16 cmdIndex = obj->cmdIndex; // ptr to list of commands if (cmdIndex == 0) // No commands for this obj return false; - for (i = 0; _vm._cmdList[cmdIndex][i].verbIndex != 0; i++) // For each cmd + int i; + for (i = 0; _vm._cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd if (isWordPresent(_vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex])) // Was this verb used? break; + } + if (_vm._cmdList[cmdIndex][i].verbIndex == 0) // No verbs used. return false; // Verb match found. Check if object is Near - verb = *_vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex]; + char *verb = *_vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex]; if (!isNear(obj, verb, comment)) - return(false); + return false; // Check all required objects are being carried - cmnd = &_vm._cmdList[cmdIndex][i]; // ptr to struct cmd + cmd *cmnd = &_vm._cmdList[cmdIndex][i]; // ptr to struct cmd if (cmnd->reqIndex) { // At least 1 thing in list - reqs = _vm._arrayReqs[cmnd->reqIndex]; // ptr to list of required objects - for (i = 0; reqs[i]; i++) // for each obj + uint16 *reqs = _vm._arrayReqs[cmnd->reqIndex]; // ptr to list of required objects + for (i = 0; reqs[i]; i++) { // for each obj if (!isCarrying(reqs[i])) { Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataNoCarryIndex]); return true; } + } } // Required objects are present, now check state is correct @@ -649,27 +654,27 @@ bool Parser::isObjectVerb(object_t *obj, char *comment) { void Parser::showDosInventory() { // Show user all objects being carried in a variable width 2 column format static const char *blanks = " "; - uint16 index, len, len1 = 0, len2 = 0; - char buffer[XBYTES *NUM_ROWS] = "\0"; + uint16 index = 0, len1 = 0, len2 = 0; - index = 0; - for (int i = 0; i < _vm._numObj; i++) /* Find widths of 2 columns */ + for (int i = 0; i < _vm._numObj; i++) { // Find widths of 2 columns if (_vm._objects[i].carriedFl) { - len = strlen(_vm._arrayNouns[_vm._objects[i].nounIndex][1]); - if (index++ & 1) /* Right hand column */ + uint16 len = strlen(_vm._arrayNouns[_vm._objects[i].nounIndex][1]); + if (index++ & 1) // Right hand column len2 = (len > len2) ? len : len2; else len1 = (len > len1) ? len : len1; } - len1 += 1; /* For gap between columns */ + } + len1 += 1; // For gap between columns if (len1 + len2 < (uint16)strlen(_vm._textParser[kTBOutro])) len1 = strlen(_vm._textParser[kTBOutro]); + char buffer[XBYTES *NUM_ROWS] = "\0"; strncat(buffer, blanks, (len1 + len2 - strlen(_vm._textParser[kTBIntro])) / 2); strcat(strcat(buffer, _vm._textParser[kTBIntro]), "\n"); index = 0; - for (int i = 0; i < _vm._numObj; i++) { /* Assign strings */ + for (int i = 0; i < _vm._numObj; i++) { // Assign strings if (_vm._objects[i].carriedFl) { if (index++ & 1) strcat(strcat(buffer, _vm._arrayNouns[_vm._objects[i].nounIndex][1]), "\n"); diff --git a/engines/hugo/route.cpp b/engines/hugo/route.cpp index deb4dc27d5..9b3d929543 100644 --- a/engines/hugo/route.cpp +++ b/engines/hugo/route.cpp @@ -45,10 +45,10 @@ Route::Route(HugoEngine &vm) : _vm(vm) { // Face hero in new direction, based on cursor key input by user. void Route::setDirection(uint16 keyCode) { - object_t *obj = _vm._hero; // Pointer to hero object - debugC(1, kDebugRoute, "setDirection(%d)", keyCode); + object_t *obj = _vm._hero; // Pointer to hero object + // Set first image in sequence switch (keyCode) { case Common::KEYCODE_UP: @@ -81,11 +81,11 @@ void Route::setDirection(uint16 keyCode) { // Set hero walking, based on cursor key input by user. // Hitting same key twice will stop hero. void Route::setWalk(uint16 direction) { - object_t *obj = _vm._hero; // Pointer to hero object - static uint16 oldDirection = 0; // Last direction char - debugC(1, kDebugRoute, "setWalk(%d)", direction); + static uint16 oldDirection = 0; // Last direction char + object_t *obj = _vm._hero; // Pointer to hero object + if (_vm.getGameStatus().storyModeFl || obj->pathType != USER) // Make sure user has control return; @@ -148,13 +148,12 @@ void Route::setWalk(uint16 direction) { // around this, make sure any narrow gaps are 2 or more pixels high. // An example of this was the blocking guard in Hugo1/Dead-End. void Route::segment(int16 x, int16 y) { - int16 x1, x2; // Range of segment + debugC(1, kDebugRoute, "segment(%d, %d)", x, y); + // Note use of static - can't waste stack static image_pt p; // Ptr to _boundaryMap[y] static segment_t *seg_p; // Ptr to segment - debugC(1, kDebugRoute, "segment(%d, %d)", x, y); - // Bomb out if stack exhausted // Vinterstum: Is this just a safeguard, or actually used? //_fullStackFl = _stackavail () < 256; @@ -162,16 +161,21 @@ void Route::segment(int16 x, int16 y) { // Find and fill on either side of point p = _boundaryMap[y]; - for (x1 = x; x1 > 0; x1--) + int16 x1, x2; // Range of segment + for (x1 = x; x1 > 0; x1--) { if (p[x1] == 0) { p[x1] = kMapFill; - } else + } else { break; - for (x2 = x + 1; x2 < XPIX; x2++) + } + } + for (x2 = x + 1; x2 < XPIX; x2++) { if (p[x2] == 0) { p[x2] = kMapFill; - } else + } else { break; + } + } x1++; x2--; @@ -190,48 +194,59 @@ void Route::segment(int16 x, int16 y) { if (_vm._hero->x < x1) { // Hero x not in segment, search x1..x2 // Find all segments above current - for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) + for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); + } // Find all segments below current - for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) + for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); + } } else if (_vm._hero->x + HERO_MAX_WIDTH > x2) { // Hero x not in segment, search x1..x2 // Find all segments above current - for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) + for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); + } // Find all segments below current - for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) + for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); + } } else { // Organize search around hero x position - this gives // better chance for more direct route. - for (x = _vm._hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) + for (x = _vm._hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); - for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm._hero->x; x++) + } + + for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm._hero->x; x++) { if (_boundaryMap[y - 1][x] == 0) segment(x, y - 1); - for (x = _vm._hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) + } + + for (x = _vm._hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); - for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm._hero->x; x++) + } + + for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm._hero->x; x++) { if (_boundaryMap[y + 1][x] == 0) segment(x, y + 1); + } } // If found, surface, leaving trail back to hero if (_routeFoundFl) { // Bomb out if too many segments (leave one spare) - if (_segmentNumb >= kMaxSeg - 1) + if (_segmentNumb >= kMaxSeg - 1) { _fullSegmentFl = true; - else { + } else { // Create segment seg_p = &_segment[_segmentNumb]; seg_p->y = y; @@ -243,15 +258,15 @@ void Route::segment(int16 x, int16 y) { } // Create and return ptr to new node. Initialize with previous node. -// Returns NULL if MAX_NODES exceeded +// Returns 0 if MAX_NODES exceeded Point *Route::newNode() { debugC(1, kDebugRoute, "newNode"); if (_routeListIndex >= kMaxNodes) // Too many nodes - return(NULL); // Incomplete route - failure + return 0; // Incomplete route - failure _routeListIndex++; _route[_routeListIndex] = _route[_routeListIndex - 1]; // Initialize with previous node - return(&_route[_routeListIndex]); + return &_route[_routeListIndex]; } // Construct route to cx, cy. Return TRUE if successful. @@ -259,13 +274,6 @@ Point *Route::newNode() { // 2. Construct list of segments segment[] from hero to destination // 3. Compress to shortest route in route[] bool Route::findRoute(int16 cx, int16 cy) { - int16 i, j, x, y; // Loop on coordinates - int16 x1, x2, dx; // Overlap between segments - int16 herox1, herox2, heroy; // Current hero baseline - object_t *obj; // Ptr to object - segment_t *seg_p; // Ptr to segment - Point *routeNode; // Ptr to route node - debugC(1, kDebugRoute, "findRoute(%d, %d)", cx, cy); // Initialize for search @@ -276,32 +284,39 @@ bool Route::findRoute(int16 cx, int16 cy) { _heroWidth = HERO_MIN_WIDTH; // Minimum width of hero _destY = cy; // Destination coords _destX = cx; // Destination coords - herox1 = _vm._hero->x + _vm._hero->currImagePtr->x1; // Hero baseline - herox2 = _vm._hero->x + _vm._hero->currImagePtr->x2; // Hero baseline - heroy = _vm._hero->y + _vm._hero->currImagePtr->y2; // Hero baseline + + int16 herox1 = _vm._hero->x + _vm._hero->currImagePtr->x1; // Hero baseline + int16 herox2 = _vm._hero->x + _vm._hero->currImagePtr->x2; // Hero baseline + int16 heroy = _vm._hero->y + _vm._hero->currImagePtr->y2; // Hero baseline // Store all object baselines into objbound (except hero's = [0]) - for (i = 1, obj = &_vm._objects[i]; i < _vm._numObj; i++, obj++) + object_t *obj; // Ptr to object + int i; + for (i = 1, obj = &_vm._objects[i]; i < _vm._numObj; i++, obj++) { if ((obj->screenIndex == *_vm._screen_p) && (obj->cycling != INVISIBLE) && (obj->priority == FLOATING)) _vm.storeBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2); + } // Combine objbound and boundary bitmaps to local byte map - for (y = 0; y < YPIX; y++) - for (x = 0; x < XBYTES; x++) + for (int16 y = 0; y < YPIX; y++) { + for (int16 x = 0; x < XBYTES; x++) { for (i = 0; i < 8; i++) _boundaryMap[y][x * 8 + i] = ((_vm.getObjectBoundaryOverlay()[y * XBYTES + x] | _vm.getBoundaryOverlay()[y * XBYTES + x]) & (0x80 >> i)) ? kMapBound : 0; - + } + } + // Clear all object baselines from objbound - for (i = 0, obj = _vm._objects; i < _vm._numObj; i++, obj++) + for (i = 0, obj = _vm._objects; i < _vm._numObj; i++, obj++) { if ((obj->screenIndex == *_vm._screen_p) && (obj->cycling != INVISIBLE) && (obj->priority == FLOATING)) _vm.clearBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2); - + } + // Search from hero to destination segment(herox1, heroy); // Not found or not enough stack or MAX_SEG exceeded if (!_routeFoundFl || _fullStackFl || _fullSegmentFl) { - return(false); + return false; } // Now find the route of nodes from destination back to hero @@ -315,29 +330,30 @@ bool Route::findRoute(int16 cx, int16 cy) { _segment[_segmentNumb].x2 = herox2; _segmentNumb++; + Point *routeNode; // Ptr to route node // Look in segments[] for straight lines from destination to hero for (i = 0, _routeListIndex = 0; i < _segmentNumb - 1; i++) { - if ((routeNode = newNode()) == NULL) // New node for new segment - return(false); // Too many nodes + if ((routeNode = newNode()) == 0) // New node for new segment + return false; // Too many nodes routeNode->y = _segment[i].y; // Look ahead for furthest straight line - for (j = i + 1; j < _segmentNumb; j++) { - seg_p = &_segment[j]; + for (int16 j = i + 1; j < _segmentNumb; j++) { + segment_t *seg_p = &_segment[j]; // Can we get to this segment from previous node? - if (seg_p->x1 <= routeNode->x && seg_p->x2 >= routeNode->x + _heroWidth - 1) + if (seg_p->x1 <= routeNode->x && seg_p->x2 >= routeNode->x + _heroWidth - 1) { routeNode->y = seg_p->y; // Yes, keep updating node - else { + } else { // No, create another node on previous segment to reach it - if ((routeNode = newNode()) == NULL) // Add new route node - return (false); // Too many nodes + if ((routeNode = newNode()) == 0) // Add new route node + return false; // Too many nodes // Find overlap between old and new segments - x1 = MAX(_segment[j - 1].x1, seg_p->x1); - x2 = MIN(_segment[j - 1].x2, seg_p->x2); + int16 x1 = MAX(_segment[j - 1].x1, seg_p->x1); + int16 x2 = MIN(_segment[j - 1].x2, seg_p->x2); // If room, add a little offset to reduce staircase effect - dx = HERO_MAX_WIDTH >> 1; + int16 dx = HERO_MAX_WIDTH >> 1; if (x2 - x1 < _heroWidth + dx) dx = 0; @@ -364,18 +380,15 @@ bool Route::findRoute(int16 cx, int16 cy) { // Process hero in route mode - called from Move_objects() void Route::processRoute() { - int16 herox, heroy; // Hero position - Point *routeNode; // Ptr to current route node - static bool turnedFl = false; // Used to get extra cylce for turning - - status_t &gameStatus = _vm.getGameStatus(); - debugC(1, kDebugRoute, "processRoute"); + static bool turnedFl = false; // Used to get extra cylce for turning + // Current hero position - herox = _vm._hero->x + _vm._hero->currImagePtr->x1; - heroy = _vm._hero->y + _vm._hero->currImagePtr->y2; - routeNode = &_route[gameStatus.routeIndex]; + int16 herox = _vm._hero->x + _vm._hero->currImagePtr->x1; + int16 heroy = _vm._hero->y + _vm._hero->currImagePtr->y2; + status_t &gameStatus = _vm.getGameStatus(); + Point *routeNode = &_route[gameStatus.routeIndex]; // Arrived at node? if (abs(herox - routeNode->x) < DX + 1 && abs(heroy - routeNode->y) < DY) { @@ -422,11 +435,11 @@ void Route::processRoute() { // Set direction of travel if at a node // Note realignment when changing to (thinner) up/down sprite, // otherwise hero could bump into boundaries along route. - if (herox < routeNode->x) + if (herox < routeNode->x) { setWalk(Common::KEYCODE_RIGHT); - else if (herox > routeNode->x) + } else if (herox > routeNode->x) { setWalk(Common::KEYCODE_LEFT); - else if (heroy < routeNode->y) { + } else if (heroy < routeNode->y) { setWalk(Common::KEYCODE_DOWN); _vm._hero->x = _vm._hero->oldx = routeNode->x - _vm._hero->currImagePtr->x1; } else if (heroy > routeNode->y) { @@ -440,16 +453,13 @@ void Route::processRoute() { // go_for is the purpose, id indexes the exit or object to walk to // Returns FALSE if route not found bool Route::startRoute(go_t go_for, int16 id, int16 cx, int16 cy) { - bool foundFl = false; // TRUE if route found ok - - status_t &gameStatus = _vm.getGameStatus(); - debugC(1, kDebugRoute, "startRoute(%d, %d, %d, %d)", go_for, id, cx, cy); // Don't attempt to walk if user does not have control if (_vm._hero->pathType != USER) return false; + status_t &gameStatus = _vm.getGameStatus(); // if inventory showing, make it go away if (gameStatus.inventoryState != I_OFF) gameStatus.inventoryState = I_UP; @@ -461,6 +471,7 @@ bool Route::startRoute(go_t go_for, int16 id, int16 cx, int16 cy) { if (gameStatus.go_for == GO_SPACE) cx -= HERO_MIN_WIDTH / 2; + bool foundFl = false; // TRUE if route found ok if ((foundFl = findRoute(cx, cy))) { // Found a route? gameStatus.routeIndex = _routeListIndex; // Node index _vm._hero->vx = _vm._hero->vy = 0; // Stop manual motion diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp index 2354208ac3..439e651e8c 100644 --- a/engines/hugo/schedule.cpp +++ b/engines/hugo/schedule.cpp @@ -76,11 +76,10 @@ void Scheduler::initEventQueue() { // Return a ptr to an event structure from the free list event_t *Scheduler::getQueue() { debugC(4, kDebugSchedule, "getQueue"); - event_t *resEvent; if (!_freeEvent) // Error: no more events available Utils::Error(EVNT_ERR, "%s", "getQueue"); - resEvent = _freeEvent; + event_t *resEvent = _freeEvent; _freeEvent = _freeEvent->nextEvent; resEvent->nextEvent = 0; return resEvent; @@ -94,10 +93,11 @@ event_t *Scheduler::getQueue() { // was modified to allow deletes anywhere in the list, and the DEL_EVENT // action was modified to perform the actual delete. void Scheduler::delQueue(event_t *curEvent) { - debugC(4, kDebugSchedule, "delQueue"); - if (curEvent == _headEvent) // If p was the head ptr + debugC(4, kDebugSchedule, "delQueue()"); + + if (curEvent == _headEvent) { // If p was the head ptr _headEvent = curEvent->nextEvent; // then make new head_p - else { // Unlink p + } else { // Unlink p curEvent->prevEvent->nextEvent = curEvent->nextEvent; if (curEvent->nextEvent) curEvent->nextEvent->prevEvent = curEvent->prevEvent; @@ -119,7 +119,7 @@ void Scheduler::delQueue(event_t *curEvent) { // Insert the action pointed to by p into the timer event queue // The queue goes from head (earliest) to tail (latest) timewise void Scheduler::insertAction(act *action) { - debugC(1, kDebugSchedule, "insertAction - Action type A%d", action->a0.actType); + debugC(1, kDebugSchedule, "insertAction() - Action type A%d", action->a0.actType); // First, get and initialise the event structure event_t *curEvent = getQueue(); @@ -138,7 +138,7 @@ void Scheduler::insertAction(act *action) { // Now find the place to insert the event if (!_tailEvent) { // Empty queue _tailEvent = _headEvent = curEvent; - curEvent->nextEvent = curEvent->prevEvent = NULL; + curEvent->nextEvent = curEvent->prevEvent = 0; } else { event_t *wrkEvent = _tailEvent; // Search from latest time back bool found = false; @@ -160,7 +160,7 @@ void Scheduler::insertAction(act *action) { if (!found) { // Must be earliest in list _headEvent->prevEvent = curEvent; // So insert as new head curEvent->nextEvent = _headEvent; - curEvent->prevEvent = NULL; + curEvent->prevEvent = 0; _headEvent = curEvent; } } @@ -170,16 +170,17 @@ void Scheduler::insertActionList(uint16 actIndex) { // Call Insert_action for each action in the list supplied debugC(1, kDebugSchedule, "insertActionList(%d)", actIndex); - if (_vm._actListArr[actIndex]) + if (_vm._actListArr[actIndex]) { for (int i = 0; _vm._actListArr[actIndex][i].a0.actType != ANULL; i++) insertAction(&_vm._actListArr[actIndex][i]); + } } void Scheduler::decodeString(char *line) { // Decode a string debugC(1, kDebugSchedule, "decodeString(%s)", line); - const char *cypher = getCypher(); + static const char *cypher = getCypher(); for (uint16 i = 0; i < strlen(line); i++) line[i] -= cypher[i % strlen(cypher)]; @@ -190,18 +191,16 @@ event_t *Scheduler::doAction(event_t *curEvent) { // This function performs the action in the event structure pointed to by p // It dequeues the event and returns it to the free list. It returns a ptr // to the next action in the list, except special case of NEW_SCREEN - event_t *wrkEvent; // Save ev_p->next_p for return - event_t *saveEvent; // Used in DEL_EVENTS + debugC(1, kDebugSchedule, "doAction - Event action type : %d", curEvent->action->a0.actType); + + status_t &gameStatus = _vm.getGameStatus(); + act *action = curEvent->action; char *response; // User's response string object_t *obj1; object_t *obj2; int dx, dy; - act *action; // Ptr to action structure - - status_t &gameStatus = _vm.getGameStatus(); - - action = curEvent->action; - debugC(1, kDebugSchedule, "doAction - Event action type : %d", action->a0.actType); + event_t *wrkEvent; // Save ev_p->next_p for return + event_t *saveEvent; // Used in DEL_EVENTS switch (action->a0.actType) { case ANULL: // Big NOP from DEL_EVENTS @@ -217,7 +216,7 @@ event_t *Scheduler::doAction(event_t *curEvent) { _vm._objects[action->a2.objNumb].x = action->a2.x; // Coordinates _vm._objects[action->a2.objNumb].y = action->a2.y; break; - case PROMPT: // act3: Prompt user for key phrase + case PROMPT: { // act3: Prompt user for key phrase // TODO : Add specific code for Hugo 1 DOS, which is handled differently, response = Utils::Box(BOX_PROMPT, "%s", _vm.file().fetchString(action->a3.promptIndex)); @@ -243,6 +242,7 @@ event_t *Scheduler::doAction(event_t *curEvent) { //HACK: As the answer is not read, currently it's always considered correct insertActionList(action->a3.actPassIndex); break; + } case BKGD_COLOR: // act4: Set new background color _vm.screen().setBackgroundColor(action->a4.newBackgroundColor); break; @@ -443,7 +443,7 @@ event_t *Scheduler::doAction(event_t *curEvent) { break; case YESNO: // act43: Prompt user for Yes or No warning("doAction(act43) - Yes/No Box"); - if (Utils::Box(BOX_YESNO, "%s", _vm.file().fetchString(action->a43.promptIndex)) != NULL) + if (Utils::Box(BOX_YESNO, "%s", _vm.file().fetchString(action->a43.promptIndex)) != 0) insertActionList(action->a43.actYesIndex); else insertActionList(action->a43.actNoIndex); @@ -486,12 +486,12 @@ event_t *Scheduler::doAction(event_t *curEvent) { break; } - if (action->a0.actType == NEW_SCREEN) // New_screen() deletes entire list - return (NULL); // next_p = NULL since list now empty - else { + if (action->a0.actType == NEW_SCREEN) { // New_screen() deletes entire list + return 0; // next_p = 0 since list now empty + } else { wrkEvent = curEvent->nextEvent; delQueue(curEvent); // Return event to free list - return(wrkEvent); // Return next event ptr + return wrkEvent; // Return next event ptr } } @@ -502,8 +502,8 @@ void Scheduler::runScheduler() { debugC(6, kDebugSchedule, "runScheduler"); status_t &gameStatus = _vm.getGameStatus(); - event_t *curEvent = _headEvent; // The earliest event + while (curEvent && curEvent->time <= gameStatus.tick) // While mature events found curEvent = doAction(curEvent); // Perform the action (returns next_p) gameStatus.tick++; // Accessed elsewhere via getTicks() @@ -573,45 +573,39 @@ void Scheduler::newScreen(int screenIndex) { // using -1 for NULL. We can't convert the action ptrs to indexes // so we save address of first dummy action ptr to compare on restore. void Scheduler::saveEvents(Common::WriteStream *f) { - uint32 curTime; - event_t saveEvents_[kMaxEvents]; // Convert event ptrs to indexes - event_t *wrkEvent; // Event ptr - int16 freeIndex; // Free list index - int16 headIndex; // Head of list index - int16 tailIndex; // Tail of list index - - debugC(1, kDebugSchedule, "saveEvents"); + debugC(1, kDebugSchedule, "saveEvents()"); - curTime = getTicks(); + uint32 curTime = getTicks(); + event_t saveEventArr[kMaxEvents]; // Convert event ptrs to indexes // Convert event ptrs to indexes for (int16 i = 0; i < kMaxEvents; i++) { - wrkEvent = &_events[i]; - saveEvents_[i] = *wrkEvent; - saveEvents_[i].prevEvent = (wrkEvent->prevEvent == NULL) ? (event_t *) - 1 : (event_t *)(wrkEvent->prevEvent - _events); - saveEvents_[i].nextEvent = (wrkEvent->nextEvent == NULL) ? (event_t *) - 1 : (event_t *)(wrkEvent->nextEvent - _events); + event_t *wrkEvent = &_events[i]; + saveEventArr[i] = *wrkEvent; + saveEventArr[i].prevEvent = (wrkEvent->prevEvent == 0) ? (event_t *) - 1 : (event_t *)(wrkEvent->prevEvent - _events); + saveEventArr[i].nextEvent = (wrkEvent->nextEvent == 0) ? (event_t *) - 1 : (event_t *)(wrkEvent->nextEvent - _events); } - freeIndex = (_freeEvent == 0) ? -1 : _freeEvent - _events; - headIndex = (_headEvent == 0) ? -1 : _headEvent - _events; - tailIndex = (_tailEvent == 0) ? -1 : _tailEvent - _events; + + int16 freeIndex = (_freeEvent == 0) ? -1 : _freeEvent - _events; + int16 headIndex = (_headEvent == 0) ? -1 : _headEvent - _events; + int16 tailIndex = (_tailEvent == 0) ? -1 : _tailEvent - _events; f->write(&curTime, sizeof(curTime)); f->write(&freeIndex, sizeof(freeIndex)); f->write(&headIndex, sizeof(headIndex)); f->write(&tailIndex, sizeof(tailIndex)); - f->write(saveEvents_, sizeof(saveEvents_)); + f->write(saveEventArr, sizeof(saveEventArr)); } // Restore the event list from file with handle f void Scheduler::restoreEvents(Common::SeekableReadStream *f) { - uint32 curTime, saveTime; - event_t *wrkEvent; // Event ptr - event_t savedEvents[kMaxEvents]; // Convert event ptrs to indexes + debugC(1, kDebugSchedule, "restoreEvents"); + + uint32 saveTime; int16 freeIndex; // Free list index int16 headIndex; // Head of list index int16 tailIndex; // Tail of list index - - debugC(1, kDebugSchedule, "restoreEvents"); + event_t savedEvents[kMaxEvents]; // Convert event ptrs to indexes f->read(&saveTime, sizeof(saveTime)); // time of save f->read(&freeIndex, sizeof(freeIndex)); @@ -619,6 +613,7 @@ void Scheduler::restoreEvents(Common::SeekableReadStream *f) { f->read(&tailIndex, sizeof(tailIndex)); f->read(savedEvents, sizeof(savedEvents)); + event_t *wrkEvent; // Restore events indexes to pointers for (int i = 0; i < kMaxEvents; i++) { wrkEvent = &savedEvents[i]; @@ -626,12 +621,12 @@ void Scheduler::restoreEvents(Common::SeekableReadStream *f) { _events[i].prevEvent = (wrkEvent->prevEvent == (event_t *) - 1) ? (event_t *)0 : &_events[(size_t)wrkEvent->prevEvent ]; _events[i].nextEvent = (wrkEvent->nextEvent == (event_t *) - 1) ? (event_t *)0 : &_events[(size_t)wrkEvent->nextEvent ]; } - _freeEvent = (freeIndex == -1) ? NULL : &_events[freeIndex]; - _headEvent = (headIndex == -1) ? NULL : &_events[headIndex]; - _tailEvent = (tailIndex == -1) ? NULL : &_events[tailIndex]; + _freeEvent = (freeIndex == -1) ? 0 : &_events[freeIndex]; + _headEvent = (headIndex == -1) ? 0 : &_events[headIndex]; + _tailEvent = (tailIndex == -1) ? 0 : &_events[tailIndex]; // Adjust times to fit our time - curTime = getTicks(); + uint32 curTime = getTicks(); wrkEvent = _headEvent; // The earliest event while (wrkEvent) { // While mature events found wrkEvent->time = wrkEvent->time - saveTime + curTime; @@ -661,12 +656,13 @@ void Scheduler::swapImages(int objNumb1, int objNumb2) { // Swap all the images of one object with another. Set hero_image (we make // the assumption for now that the first obj is always the HERO) to the object // number of the swapped image - seqList_t tmpSeqList[MAX_SEQUENCES]; - int seqListSize = sizeof(seqList_t) * MAX_SEQUENCES; - debugC(1, kDebugSchedule, "swapImages(%d, %d)", objNumb1, objNumb2); _vm.file().saveSeq(&_vm._objects[objNumb1]); + + seqList_t tmpSeqList[MAX_SEQUENCES]; + int seqListSize = sizeof(seqList_t) * MAX_SEQUENCES; + memcpy(tmpSeqList, _vm._objects[objNumb1].seqList, seqListSize); memcpy(_vm._objects[objNumb1].seqList, _vm._objects[objNumb2].seqList, seqListSize); memcpy(_vm._objects[objNumb2].seqList, tmpSeqList, seqListSize); diff --git a/engines/hugo/schedule.h b/engines/hugo/schedule.h index efece354be..b77abd4302 100644 --- a/engines/hugo/schedule.h +++ b/engines/hugo/schedule.h @@ -35,14 +35,14 @@ namespace Hugo { -#define kMaxEvents 50 /* Max events in event queue */ +#define kMaxEvents 50 // Max events in event queue struct event_t { - act *action; /* Ptr to action to perform */ - bool localActionFl; /* TRUE if action is only for this screen */ - uint32 time; /* (absolute) time to perform action */ - struct event_t *prevEvent; /* Chain to previous event */ - struct event_t *nextEvent; /* Chain to next event */ + act *action; // Ptr to action to perform + bool localActionFl; // true if action is only for this screen + uint32 time; // (absolute) time to perform action + struct event_t *prevEvent; // Chain to previous event + struct event_t *nextEvent; // Chain to next event }; class Scheduler { @@ -71,11 +71,11 @@ private: HugoEngine &_vm; - event_t _events[kMaxEvents]; /* Statically declare event structures */ + event_t _events[kMaxEvents]; // Statically declare event structures - event_t *_freeEvent; /* Free list of event structures */ - event_t *_headEvent; /* Head of list (earliest time) */ - event_t *_tailEvent; /* Tail of list (latest time) */ + event_t *_freeEvent; // Free list of event structures + event_t *_headEvent; // Head of list (earliest time) + event_t *_tailEvent; // Tail of list (latest time) event_t *getQueue(); void delQueue(event_t *curEvent); diff --git a/engines/hugo/sound.cpp b/engines/hugo/sound.cpp index 7b6ae2ec24..e5f55afcc8 100644 --- a/engines/hugo/sound.cpp +++ b/engines/hugo/sound.cpp @@ -184,11 +184,11 @@ int MidiPlayer::open() { void MidiPlayer::close() { stop(); _mutex.lock(); - _driver->setTimerCallback(NULL, NULL); + _driver->setTimerCallback(0, 0); _driver->close(); delete _driver; _driver = 0; - _parser->setMidiDriver(NULL); + _parser->setMidiDriver(0); delete _parser; _mutex.unlock(); } @@ -314,7 +314,7 @@ void SoundHandler::playSound(int16 sound, stereo_t channel, byte priority) { curPriority = priority; // /* Get sound data */ - if ((sound_p = _vm.file().getSound(sound, &size)) == NULL) + if ((sound_p = _vm.file().getSound(sound, &size)) == 0) return; Audio::AudioStream *stream = Audio::makeRawStream(sound_p, size, 11025, Audio::FLAG_UNSIGNED); diff --git a/engines/hugo/util.cpp b/engines/hugo/util.cpp index 0d439584db..8cca4b7d84 100644 --- a/engines/hugo/util.cpp +++ b/engines/hugo/util.cpp @@ -41,67 +41,68 @@ namespace Hugo { int Utils::firstBit(byte data) { - /* Returns index (0 to 7) of first 1 in supplied byte, or 8 if not found */ - int i; - +// Returns index (0 to 7) of first 1 in supplied byte, or 8 if not found if (!data) - return(8); + return 8; + int i; for (i = 0; i < 8; i++) { if ((data << i) & 0x80) break; } - return(i); + return i; } int Utils::lastBit(byte data) { - /* Returns index (0 to 7) of last 1 in supplied byte, or 8 if not found */ - int i; +// Returns index (0 to 7) of last 1 in supplied byte, or 8 if not found if (!data) - return(8); + return 8; + int i; for (i = 7; i >= 0; i--) { if ((data << i) & 0x80) break; } - return(i); + return i; } void Utils::reverseByte(byte *data) { - /* Reverse the bit order in supplied byte */ +// Reverse the bit order in supplied byte byte maskIn = 0x80; byte maskOut = 0x01; byte result = 0; - for (byte i = 0; i < 8; i++, maskIn >>= 1, maskOut <<= 1) + for (byte i = 0; i < 8; i++, maskIn >>= 1, maskOut <<= 1) { if (*data & maskIn) result |= maskOut; - + } + *data = result; } char *Utils::Box(box_t dismiss, const char *s, ...) { static char buffer[MAX_STRLEN + 1]; // Format text into this - va_list marker; - if (!s) return(NULL); // NULL strings catered for + if (!s) + return 0; // NULL strings catered for if (s[0] == '\0') - return(NULL); + return 0; if (strlen(s) > MAX_STRLEN - 100) { // Test length - Warn(false, "String too big:\n%s", s); - return(NULL); + Warn("String too big:\n%s", s); + return 0; } + va_list marker; va_start(marker, s); vsprintf(buffer, s, marker); // Format string into buffer va_end(marker); if (buffer[0] == '\0') - return(NULL); + return 0; switch(dismiss) { case BOX_ANY: @@ -113,7 +114,7 @@ char *Utils::Box(box_t dismiss, const char *s, ...) { case BOX_YESNO: { GUI::MessageDialog dialog(buffer, "YES", "NO"); if (dialog.runModal() == GUI::kMessageOK) - return(buffer); + return buffer; return 0; break; } @@ -128,27 +129,20 @@ char *Utils::Box(box_t dismiss, const char *s, ...) { return buffer; } -void Utils::Warn(bool technote, const char *format, ...) { - /* Warning handler. Print supplied message and continue */ - /* Arguments are same as printf */ - /* technote TRUE if we are to refer user to technote file */ +void Utils::Warn(const char *format, ...) { +// Warning handler. Print supplied message and continue +// Arguments are same as printf char buffer[WARNLEN]; va_list marker; - va_start(marker, format); vsnprintf(buffer, WARNLEN, format, marker); va_end(marker); -//// if (technote) -//// strcat (buffer, sTech); - //MessageBeep(MB_ICONEXCLAMATION); - //MessageBox(hwnd, buffer, "HugoWin Warning", MB_OK | MB_ICONEXCLAMATION); warning("Hugo warning: %s", buffer); } void Utils::Error(int error_type, const char *format, ...) { - /* Fatal error handler. Reset environment, print error and exit */ - /* Arguments are same as printf */ - va_list marker; +// Fatal error handler. Reset environment, print error and exit +// Arguments are same as printf char buffer[ERRLEN + 1]; bool fatal = true; // Fatal error, else continue @@ -177,6 +171,7 @@ void Utils::Error(int error_type, const char *format, ...) { if (fatal) HugoEngine::get().shutdown(); // Restore any devices before exit + va_list marker; va_start(marker, format); vsnprintf(&buffer[strlen(buffer)], ERRLEN - strlen(buffer), format, marker); va_end(marker); diff --git a/engines/hugo/util.h b/engines/hugo/util.h index 91d42c296f..69428fb3bb 100644 --- a/engines/hugo/util.h +++ b/engines/hugo/util.h @@ -55,7 +55,7 @@ int lastBit(byte data); void gameOverMsg(); void reverseByte(byte *data); void Error(int code, const char *format, ...) GCC_PRINTF(2, 3); -void Warn(bool technote, const char *format, ...) GCC_PRINTF(2, 3); +void Warn(const char *format, ...) GCC_PRINTF(1, 2); char *Box(box_t, const char *, ...) GCC_PRINTF(2, 3); char *strlwr(char *buffer); |