/** * Draw one overlay * @param it Overlay info * @todo Add handling of type 22 overlays */ void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) { int len, idx, width, height; ObjectStruct *obj; AnimData *sprite; byte *mask; byte color; switch (it->type) { // color sprite case 0: if (g_cine->_objectTable[it->objIdx].frame < 0) { break; } sprite = &g_cine->_animDataTable[g_cine->_objectTable[it->objIdx].frame]; len = sprite->_realWidth * sprite->_height; mask = new byte[len]; generateMask(sprite->data(), mask, len, g_cine->_objectTable[it->objIdx].part); remaskSprite(mask, it); drawMaskedSprite(g_cine->_objectTable[it->objIdx], mask); delete[] mask; break; // game message case 2: if (it->objIdx >= g_cine->_messageTable.size()) { return; } _messageLen += g_cine->_messageTable[it->objIdx].size(); drawMessage(g_cine->_messageTable[it->objIdx].c_str(), it->x, it->y, it->width, it->color); if (it->color >= 0) { // This test isn't in Future Wars's implementation waitForPlayerClick = 1; } break; // action failure message case 3: idx = it->objIdx * 4 + g_cine->_rnd.getRandomNumber(3); len = strlen(failureMessages[idx]); _messageLen += len; width = 6 * len + 20; width = width > 300 ? 300 : width; // The used color here differs from Future Wars drawMessage(failureMessages[idx], (320 - width) / 2, 80, width, _messageBg); waitForPlayerClick = 1; break; // bitmap case 4: if (g_cine->_objectTable[it->objIdx].frame >= 0) { FWRenderer::renderOverlay(it); } break; // masked background case 20: assert(it->objIdx < NUM_MAX_OBJECT); var5 = it->x; // A global variable updated here! obj = &g_cine->_objectTable[it->objIdx]; sprite = &g_cine->_animDataTable[obj->frame]; if (obj->frame < 0 || it->x < 0 || it->x > 8 || !_bgTable[it->x].bg || sprite->_bpp != 1) { break; } maskBgOverlay(_bgTable[it->x].bg, sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, obj->x, obj->y); break; // FIXME: Implement correct drawing of type 21 overlays. // Type 21 overlays aren't just filled rectangles, I found their drawing routine // from Operation Stealth's drawSprite routine. So they're likely some kind of sprites // and it's just a coincidence that the oxygen meter during the first arcade sequence // works even somehow currently. I tried the original under DOSBox and the oxygen gauge // is a long red bar that gets shorter as the air runs out. case 21: // A filled rectangle: case 22: // TODO: Check it this implementation really works correctly (Some things might be wrong, needs testing). assert(it->objIdx < NUM_MAX_OBJECT); obj = &g_cine->_objectTable[it->objIdx]; color = obj->part & 0x0F; width = obj->frame; height = obj->costume; drawPlainBox(obj->x, obj->y, width, height, color); debug(5, "renderOverlay: type=%d, x=%d, y=%d, width=%d, height=%d, color=%d", it->type, obj->x, obj->y, width, height, color); break; // something else default: FWRenderer::renderOverlay(it); break; } }
/** * Draw one overlay * @param it Overlay info * @todo Add handling of type 22 overlays */ void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) { int len, idx, width, height; ObjectStruct *obj; AnimData *sprite; byte color; switch (it->type) { // color sprite case 0: if (g_cine->_objectTable[it->objIdx].frame < 0) { break; } sprite = &g_cine->_animDataTable[g_cine->_objectTable[it->objIdx].frame]; drawSprite(&(*it), sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, g_cine->_objectTable[it->objIdx].x, g_cine->_objectTable[it->objIdx].y, g_cine->_objectTable[it->objIdx].part, sprite->_bpp); break; // game message case 2: if (it->objIdx >= g_cine->_messageTable.size()) { return; } _messageLen += g_cine->_messageTable[it->objIdx].size(); drawMessage(g_cine->_messageTable[it->objIdx].c_str(), it->x, it->y, it->width, it->color); if (it->color >= 0) { // This test isn't in Future Wars's implementation waitForPlayerClick = 1; } break; // action failure message case 3: idx = it->objIdx * 4 + g_cine->_rnd.getRandomNumber(3); len = strlen(failureMessages[idx]); _messageLen += len; width = 6 * len + 20; width = width > 300 ? 300 : width; // The used color here differs from Future Wars drawMessage(failureMessages[idx], (320 - width) / 2, 80, width, _messageBg); waitForPlayerClick = 1; break; // bitmap case 4: if (g_cine->_objectTable[it->objIdx].frame >= 0) { FWRenderer::renderOverlay(it); } break; // masked background case 20: assert(it->objIdx < NUM_MAX_OBJECT); var5 = it->x; // A global variable updated here! obj = &g_cine->_objectTable[it->objIdx]; sprite = &g_cine->_animDataTable[obj->frame]; if (obj->frame < 0 || it->x < 0 || it->x > 8 || !_bgTable[it->x].bg || sprite->_bpp != 1) { break; } maskBgOverlay(_bgTable[it->x].bg, sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, obj->x, obj->y); break; case 22: // TODO: Check it this implementation really works correctly (Some things might be wrong, needs testing). assert(it->objIdx < NUM_MAX_OBJECT); obj = &g_cine->_objectTable[it->objIdx]; color = obj->part & 0x0F; width = obj->frame; height = obj->costume; drawPlainBox(obj->x, obj->y, width, height, color); debug(5, "renderOverlay: type=%d, x=%d, y=%d, width=%d, height=%d, color=%d", it->type, obj->x, obj->y, width, height, color); break; // something else default: FWRenderer::renderOverlay(it); break; } }