void ByteArray::append(ByteArray const& cpy) { uint64 bufsize = cpy.getSize(); uint64 pos = getSize(); std::vector<char> buf = cpy.getBuffer(); _buffer->resize(getSize() + bufsize); for (uint32 i = 0; i < bufsize; ++i) (*_buffer)[pos++] = buf[i]; }
bool ByteArray::operator!=(ByteArray const& cmp) { uint64 bufsize = cmp.getSize(); uint64 currentSize = getSize(); if (bufsize != currentSize) return true; std::vector<char> buf = cmp.getBuffer(); for (uint32 i = 0; i < bufsize; ++i) if (buf[i] != _buffer->at(i)) return true; return false; }
void Scene::processSceneResources(SceneResourceDataArray &resourceList) { ByteArray resourceData; const byte *palPointer; SAGAResourceTypes *types = 0; int typesCount = 0; SAGAResourceTypes resType; getResourceTypes(types, typesCount); // Process the scene resource list for (SceneResourceDataArray::iterator resource = resourceList.begin(); resource != resourceList.end(); ++resource) { if (resource->invalid) { continue; } _vm->_resource->loadResource(_sceneContext, resource->resourceId, resourceData); if (resourceData.size() >= 6) { if (!memcmp(resourceData.getBuffer(), "DUMMY!", 6)) { resource->invalid = true; warning("DUMMY resource %i", resource->resourceId); } } if (resource->invalid) { continue; } if (resource->resourceType >= typesCount) { error("Scene::processSceneResources() wrong resource type %i", resource->resourceType); } resType = types[resource->resourceType]; switch (resType) { case SAGA_UNKNOWN: warning("UNKNOWN resourceType %i", resource->resourceType); break; case SAGA_ACTOR: //for (a = actorsInScene; a; a = a->nextInScene) // if (a->obj.figID == glist->file_id) // if (_vm->getGameId() == GID_ITE || // ((a->obj.flags & ACTORF_FINAL_FACE) & 0xff)) // a->sprites = (xSpriteSet *)glist->offset; warning("STUB: unimplemeted handler of SAGA_ACTOR resource"); break; case SAGA_OBJECT: break; case SAGA_BG_IMAGE: // Scene background resource if (_bg.loaded) { error("Scene::processSceneResources() Multiple background resources encountered"); } debug(3, "Loading background resource."); if (!_vm->decodeBGImage(resourceData, _bg.buffer, &_bg.w, &_bg.h)) { error("Scene::processSceneResources() Error loading background resource %i", resource->resourceId); } _bg.loaded = true; palPointer = _vm->getImagePal(resourceData); memcpy(_bg.pal, palPointer, sizeof(_bg.pal)); break; case SAGA_BG_MASK: // Scene background mask resource if (_bgMask.loaded) { error("Scene::ProcessSceneResources(): Duplicate background mask resource encountered"); } debug(3, "Loading BACKGROUND MASK resource."); _vm->decodeBGImage(resourceData, _bgMask.buffer, &_bgMask.w, &_bgMask.h, true); _bgMask.loaded = true; // At least in ITE the mask needs to be clipped. _bgMask.w = MIN(_bgMask.w, _vm->getDisplayInfo().width); _bgMask.h = MIN(_bgMask.h, getHeight()); debug(4, "BACKGROUND MASK width=%d height=%d length=%d", _bgMask.w, _bgMask.h, _bgMask.buffer.size()); break; case SAGA_STRINGS: debug(3, "Loading scene strings resource..."); _vm->loadStrings(_sceneStrings, resourceData); break; case SAGA_OBJECT_MAP: debug(3, "Loading object map resource..."); _objectMap->load(resourceData); break; case SAGA_ACTION_MAP: debug(3, "Loading action map resource..."); _actionMap->load(resourceData); break; case SAGA_ISO_IMAGES: if (!(_sceneDescription.flags & kSceneFlagISO)) { error("Scene::ProcessSceneResources(): not Iso mode"); } debug(3, "Loading isometric images resource."); _vm->_isoMap->loadImages(resourceData); break; case SAGA_ISO_MAP: if (!(_sceneDescription.flags & kSceneFlagISO)) { error("Scene::ProcessSceneResources(): not Iso mode"); } debug(3, "Loading isometric map resource."); _vm->_isoMap->loadMap(resourceData); break; case SAGA_ISO_PLATFORMS: if (!(_sceneDescription.flags & kSceneFlagISO)) { error("Scene::ProcessSceneResources(): not Iso mode"); } debug(3, "Loading isometric platforms resource."); _vm->_isoMap->loadPlatforms(resourceData); break; case SAGA_ISO_METATILES: if (!(_sceneDescription.flags & kSceneFlagISO)) { error("Scene::ProcessSceneResources(): not Iso mode"); } debug(3, "Loading isometric metatiles resource."); _vm->_isoMap->loadMetaTiles(resourceData); break; case SAGA_ANIM: { uint16 animId = resource->resourceType - 14; debug(3, "Loading animation resource animId=%i", animId); _vm->_anim->load(animId, resourceData); } break; case SAGA_ENTRY: debug(3, "Loading entry list resource..."); loadSceneEntryList(resourceData); break; case SAGA_ISO_MULTI: if (!(_sceneDescription.flags & kSceneFlagISO)) { error("Scene::ProcessSceneResources(): not Iso mode"); } debug(3, "Loading isometric multi resource."); _vm->_isoMap->loadMulti(resourceData); break; case SAGA_PAL_ANIM: debug(3, "Loading palette animation resource."); _vm->_palanim->loadPalAnim(resourceData); break; case SAGA_FACES: if (_vm->getGameId() == GID_ITE) _vm->_interface->loadScenePortraits(resource->resourceId); break; case SAGA_PALETTE: { PalEntry pal[PAL_ENTRIES]; byte *palPtr = resourceData.getBuffer(); if (resourceData.size() < 3 * PAL_ENTRIES) error("Too small scene palette %i", (int)resourceData.size()); for (uint16 c = 0; c < PAL_ENTRIES; c++) { pal[c].red = *palPtr++; pal[c].green = *palPtr++; pal[c].blue = *palPtr++; } _vm->_gfx->setPalette(pal); } break; default: error("Scene::ProcessSceneResources() Encountered unknown resource type %i", resource->resourceType); break; } } }
ByteArray::ByteArray(ByteArray const& cpy) : _buffer(new std::vector<char>()) { bufcopy(cpy.getBuffer()); }
int Events::handleOneShot(Event *event) { Rect rect; if (event->time > 0) { return kEvStContinue; } // Event has been signaled switch (event->code & EVENT_MASK) { case kTextEvent: switch (event->op) { case kEventDisplay: ((TextListEntry *)event->data)->display = true; break; case kEventRemove: { TextListEntry entry = *((TextListEntry *)event->data); _vm->_scene->_textList.remove(entry); } break; default: break; } break; case kSoundEvent: _vm->_sound->stopSound(); if (event->op == kEventPlay) _vm->_sndRes->playSound(event->param, event->param2, event->param3 != 0); break; case kVoiceEvent: _vm->_sndRes->playVoice(event->param); break; case kMusicEvent: if (event->op == kEventPlay) _vm->_music->play(event->param, (MusicFlags)event->param2); break; case kBgEvent: { Surface *backGroundSurface = _vm->_render->getBackGroundSurface(); BGInfo bgInfo; if (!(_vm->_scene->getFlags() & kSceneFlagISO)) { _vm->_scene->getBGInfo(bgInfo); backGroundSurface->blit(bgInfo.bounds, bgInfo.buffer); // If it is inset scene then draw black border if (bgInfo.bounds.width() < _vm->getDisplayInfo().width || bgInfo.bounds.height() < _vm->_scene->getHeight()) { Common::Rect rect1(2, bgInfo.bounds.height() + 4); Common::Rect rect2(bgInfo.bounds.width() + 4, 2); Common::Rect rect3(2, bgInfo.bounds.height() + 4); Common::Rect rect4(bgInfo.bounds.width() + 4, 2); rect1.moveTo(bgInfo.bounds.left - 2, bgInfo.bounds.top - 2); rect2.moveTo(bgInfo.bounds.left - 2, bgInfo.bounds.top - 2); rect3.moveTo(bgInfo.bounds.right, bgInfo.bounds.top - 2); rect4.moveTo(bgInfo.bounds.left - 2, bgInfo.bounds.bottom); backGroundSurface->drawRect(rect1, kITEColorBlack); backGroundSurface->drawRect(rect2, kITEColorBlack); backGroundSurface->drawRect(rect3, kITEColorBlack); backGroundSurface->drawRect(rect4, kITEColorBlack); } if (event->param == kEvPSetPalette) { PalEntry *palPointer; #ifdef ENABLE_IHNM if (_vm->getGameId() == GID_IHNM) { PalEntry portraitBgColor = _vm->_interface->_portraitBgColor; byte portraitColor = (_vm->getLanguage() == Common::ES_ESP) ? 253 : 254; // Set the portrait bg color, in case a saved state is restored from the // launcher. In this case, sfSetPortraitBgColor is not called, thus the // portrait color will always be 0 (black). if (portraitBgColor.red == 0 && portraitBgColor.green == 0 && portraitBgColor.blue == 0) portraitBgColor.green = 255; if (_vm->_spiritualBarometer > 255) _vm->_gfx->setPaletteColor(portraitColor, 0xff, 0xff, 0xff); else _vm->_gfx->setPaletteColor(portraitColor, _vm->_spiritualBarometer * portraitBgColor.red / 256, _vm->_spiritualBarometer * portraitBgColor.green / 256, _vm->_spiritualBarometer * portraitBgColor.blue / 256); } #endif _vm->_scene->getBGPal(palPointer); _vm->_gfx->setPalette(palPointer); } } _vm->_render->clearFlag(RF_DISABLE_ACTORS); } break; case kPsychicProfileBgEvent: { ResourceContext *context = _vm->_resource->getContext(GAME_RESOURCEFILE); ByteArray resourceData; _vm->_resource->loadResource(context, _vm->getResourceDescription()->psychicProfileResourceId, resourceData); ByteArray image; int width; int height; _vm->decodeBGImage(resourceData, image, &width, &height); const PalEntry *palette = (const PalEntry *)_vm->getImagePal(resourceData); const Rect profileRect(width, height); _vm->_render->getBackGroundSurface()->blit(profileRect, image.getBuffer()); _vm->_render->addDirtyRect(profileRect); _vm->_frameCount++; _vm->_gfx->setPalette(palette); // Draw the scene. It won't be drawn by Render::drawScene(), as a placard is up _vm->_scene->draw(); } break; case kAnimEvent: switch (event->op) { case kEventPlay: _vm->_anim->play(event->param, event->time, true); break; case kEventStop: _vm->_anim->stop(event->param); break; case kEventFrame: _vm->_anim->play(event->param, event->time, false); break; case kEventSetFlag: _vm->_anim->setFlag(event->param, event->param2); break; case kEventClearFlag: _vm->_anim->clearFlag(event->param, event->param2); break; case kEventResumeAll: _vm->_anim->resumeAll(); break; default: break; } break; case kSceneEvent: switch (event->op) { case kEventDraw: { BGInfo bgInfo; _vm->_scene->getBGInfo(bgInfo); _vm->_render->getBackGroundSurface()->blit(bgInfo.bounds, bgInfo.buffer); _vm->_render->addDirtyRect(bgInfo.bounds); _vm->_scene->draw(); } break; case kEventEnd: _vm->_scene->nextScene(); return kEvStBreak; default: break; } break; case kPalAnimEvent: switch (event->op) { case kEventCycleStart: _vm->_palanim->cycleStart(); break; case kEventCycleStep: _vm->_palanim->cycleStep(event->time); break; default: break; } break; case kInterfaceEvent: switch (event->op) { case kEventActivate: _vm->_interface->activate(); break; case kEventDeactivate: _vm->_interface->deactivate(); break; case kEventSetStatus: _vm->_interface->setStatusText((const char*)event->data); _vm->_interface->drawStatusBar(); break; case kEventClearStatus: _vm->_interface->setStatusText(""); _vm->_interface->drawStatusBar(); break; case kEventSetFadeMode: _vm->_interface->setFadeMode(event->param); break; case kEventRestoreMode: _vm->_interface->restoreMode(); break; case kEventSetMode: _vm->_interface->setMode(event->param); break; default: break; } break; case kScriptEvent: switch (event->op) { case kEventExecBlocking: case kEventExecNonBlocking: { debug(6, "Exec module number %ld script entry number %ld", event->param, event->param2); ScriptThread &sthread = _vm->_script->createThread(event->param, event->param2); sthread._threadVars[kThreadVarAction] = event->param3; sthread._threadVars[kThreadVarObject] = event->param4; sthread._threadVars[kThreadVarWithObject] = event->param5; sthread._threadVars[kThreadVarActor] = event->param6; if (event->op == kEventExecBlocking) _vm->_script->completeThread(); break; } case kEventThreadWake: _vm->_script->wakeUpThreads(event->param); break; } break; case kCursorEvent: switch (event->op) { case kEventShow: _vm->_gfx->showCursor(true); break; case kEventHide: _vm->_gfx->showCursor(false); break; case kEventSetNormalCursor: // in ITE and IHNM demo there is just one cursor // ITE never makes this call if (!_vm->isIHNMDemo()) _vm->_gfx->setCursor(kCursorNormal); break; case kEventSetBusyCursor: // in ITE and IHNM demo there is just one cursor // ITE never makes this call if (!_vm->isIHNMDemo()) _vm->_gfx->setCursor(kCursorBusy); break; default: break; } break; case kGraphicsEvent: switch (event->op) { case kEventFillRect: rect.top = event->param2; rect.bottom = event->param3; rect.left = event->param4; rect.right = event->param5; _vm->_gfx->drawRect(rect, event->param); break; case kEventSetFlag: _vm->_render->setFlag(event->param); break; case kEventClearFlag: _vm->_render->clearFlag(event->param); break; default: break; } #ifdef ENABLE_IHNM case kCutawayEvent: switch (event->op) { case kEventClear: _vm->_anim->clearCutaway(); break; case kEventShowCutawayBg: _vm->_anim->showCutawayBg(event->param); break; default: break; } #endif case kActorEvent: switch (event->op) { case kEventMove: // TODO (check Actor::direct) break; default: break; } default: break; } return kEvStDelete; }
size_t TcpClient::write(const ByteArray& bytes) { return send(bytes.getBuffer(), bytes.getCapacity()); }
void Sprite::loadList(int resourceId, SpriteList &spriteList) { SpriteInfo *spriteInfo; ByteArray spriteListData; uint16 oldSpriteCount; uint16 newSpriteCount; uint16 spriteCount; uint i; int outputLength, inputLength; uint32 offset; const byte *spritePointer; const byte *spriteDataPointer; _vm->_resource->loadResource(_spriteContext, resourceId, spriteListData); if (spriteListData.empty()) { return; } ByteArrayReadStreamEndian readS(spriteListData, _spriteContext->isBigEndian()); spriteCount = readS.readUint16(); debug(9, "Sprites: %d", spriteCount); oldSpriteCount = spriteList.size(); newSpriteCount = oldSpriteCount + spriteCount; spriteList.resize(newSpriteCount); bool bigHeader = _vm->getGameId() == GID_IHNM || _vm->isMacResources(); for (i = oldSpriteCount; i < spriteList.size(); i++) { spriteInfo = &spriteList[i]; if (bigHeader) offset = readS.readUint32(); else offset = readS.readUint16(); if (offset >= spriteListData.size()) { // ITE Mac demos throw this warning warning("Sprite::loadList offset exceeded"); spriteList.resize(i); return; } spritePointer = spriteListData.getBuffer(); spritePointer += offset; if (bigHeader) { Common::MemoryReadStreamEndian readS2(spritePointer, 8, _spriteContext->isBigEndian()); spriteInfo->xAlign = readS2.readSint16(); spriteInfo->yAlign = readS2.readSint16(); spriteInfo->width = readS2.readUint16(); spriteInfo->height = readS2.readUint16(); spriteDataPointer = spritePointer + readS2.pos(); } else { Common::MemoryReadStreamEndian readS2(spritePointer, 4, false); spriteInfo->xAlign = readS2.readSByte(); spriteInfo->yAlign = readS2.readSByte(); spriteInfo->width = readS2.readByte(); spriteInfo->height = readS2.readByte(); spriteDataPointer = spritePointer + readS2.pos(); } outputLength = spriteInfo->width * spriteInfo->height; inputLength = spriteListData.size() - (spriteDataPointer - spriteListData.getBuffer()); spriteInfo->decodedBuffer.resize(outputLength); if (outputLength > 0) { decodeRLEBuffer(spriteDataPointer, inputLength, outputLength); byte *dst = &spriteInfo->decodedBuffer.front(); #ifdef ENABLE_IHNM // IHNM sprites are upside-down, for reasons which i can only // assume are perverse. To simplify things, flip them now. Not // at drawing time. if (_vm->getGameId() == GID_IHNM) { byte *src = &_decodeBuf[spriteInfo->width * (spriteInfo->height - 1)]; for (int j = 0; j < spriteInfo->height; j++) { memcpy(dst, src, spriteInfo->width); src -= spriteInfo->width; dst += spriteInfo->width; } } else #endif memcpy(dst, &_decodeBuf.front(), outputLength); } } }