diff options
author | Gregory Montoir | 2005-10-03 20:21:18 +0000 |
---|---|---|
committer | Gregory Montoir | 2005-10-03 20:21:18 +0000 |
commit | 3bcb098fd31a0f68171fd4053f2600bb84814a5a (patch) | |
tree | f62249c1ee390eccf590de2b15ef22db509a5838 | |
parent | efa1c130640f4588ccdbba060448d53b51b26a86 (diff) | |
download | scummvm-rg350-3bcb098fd31a0f68171fd4053f2600bb84814a5a.tar.gz scummvm-rg350-3bcb098fd31a0f68171fd4053f2600bb84814a5a.tar.bz2 scummvm-rg350-3bcb098fd31a0f68171fd4053f2600bb84814a5a.zip |
committed patch #1312156 'Various sprite-related things'. Thanks Oystein Eftevaag/vinterstum
svn-id: r18930
-rw-r--r-- | kyra/kyra.cpp | 154 | ||||
-rw-r--r-- | kyra/kyra.h | 28 | ||||
-rw-r--r-- | kyra/module.mk | 1 | ||||
-rw-r--r-- | kyra/screen.cpp | 8 | ||||
-rw-r--r-- | kyra/screen.h | 3 | ||||
-rw-r--r-- | kyra/script.h | 4 | ||||
-rw-r--r-- | kyra/sprites.cpp | 440 | ||||
-rw-r--r-- | kyra/sprites.h | 76 | ||||
-rw-r--r-- | kyra/staticres.cpp | 11 |
9 files changed, 717 insertions, 8 deletions
diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp index 428cc70d77..5159955397 100644 --- a/kyra/kyra.cpp +++ b/kyra/kyra.cpp @@ -38,8 +38,11 @@ #include "kyra/screen.h" #include "kyra/script.h" #include "kyra/sound.h" +#include "kyra/sprites.h" #include "kyra/wsamovie.h" +#define TEST_SPRITES 1 + using namespace Kyra; struct KyraGameSettings { @@ -164,6 +167,8 @@ int KyraEngine::init(GameDetector &detector) { assert(_res); _screen = new Screen(this, _system); assert(_screen); + _sprites = new Sprites(this, _system); + assert(_sprites); _fastMode = false; _talkCoords.y = 0x88; @@ -177,6 +182,7 @@ int KyraEngine::init(GameDetector &detector) { } KyraEngine::~KyraEngine() { + delete _sprites; delete _screen; delete _res; delete _midi; @@ -196,6 +202,8 @@ int KyraEngine::go() { _screen->loadFont(Screen::FID_8_FNT, _res->fileData("8FAT.FNT", &sz)); _screen->setScreenDim(0); + _abortIntroFlag = false; + if (_game == KYRA1DEMO) { seq_demo(); } else { @@ -203,7 +211,6 @@ int KyraEngine::go() { startup(); mainLoop(); } - return 0; } @@ -213,13 +220,149 @@ void KyraEngine::startup() { _screen->setTextColorMap(colorMap); // _screen->setFont(Screen::FID_6_FNT); _screen->setAnimBlockPtr(3750); + _gameSpeed = 50; memset(_flagsTable, 0, sizeof(_flagsTable)); + setupRooms(); // XXX } +void KyraEngine::delay(uint32 amount) { + OSystem::Event event; + uint32 start = _system->getMillis(); + do { + while (_system->pollEvent(event)) { + switch (event.type) { + case OSystem::EVENT_KEYDOWN: + if (event.kbd.keycode == 'q' || event.kbd.keycode == 27) { + _quitFlag = true; + } else if (event.kbd.keycode == ' ') { + loadRoom((++_currentRoom) % MAX_NUM_ROOMS); + } + break; + // XXX + case OSystem::EVENT_LBUTTONDOWN: + loadRoom((++_currentRoom) % MAX_NUM_ROOMS); + break; + case OSystem::EVENT_RBUTTONDOWN: + loadRoom((--_currentRoom) % MAX_NUM_ROOMS); + break; + case OSystem::EVENT_QUIT: + _quitFlag = true; + break; + default: + break; + } + } + if (amount > 0) { + _system->delayMillis((amount > 10) ? 10 : amount); + } + } while (_system->getMillis() < start + amount); +} + +void KyraEngine::drawRoom() { + //_screen->clearPage(0); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 10, 0); + _screen->copyRegion(4, 4, 4, 4, 308, 132, 14, 0); + _sprites->doAnims(); + _sprites->drawSprites(14, 0); +} + +void KyraEngine::setCursor(uint8 cursorID) { + debug(9, "KyraEngine::setCursor(%i)", cursorID); + assert(cursorID < _cursorsCount); + + loadBitmap("mouse.cps", 2, 2, _screen->_currentPalette); + uint8 *cursor = new uint8[_cursors[cursorID].w * _cursors[cursorID].h]; + + _screen->copyRegionToBuffer(2, _cursors[cursorID].x, _cursors[cursorID].y, _cursors[cursorID].w, _cursors[cursorID].h, cursor); + _system->setMouseCursor(cursor, _cursors[cursorID].w, _cursors[cursorID].h, 0, 0, 0); + _system->showMouse(true); + + delete[] cursor; +} + +void KyraEngine::setupRooms() { + // XXX + // Just a few sample rooms, most with sprite anims. + memset(_rooms, 0, sizeof(_rooms)); + _rooms[0].filename = "gemcut"; + _rooms[1].filename = "arch"; + _rooms[2].filename = "sorrow"; + _rooms[3].filename = "emcav"; + _rooms[4].filename = "extpot"; + _rooms[5].filename = "spell"; + _rooms[6].filename = "song"; + _rooms[7].filename = "belroom"; + _rooms[8].filename = "kyragem"; + _rooms[9].filename = "lephole"; + _rooms[10].filename = "sickwil"; + _rooms[11].filename = "temple"; +} + +void KyraEngine::loadRoom(uint16 roomID) { + debug(9, "KyraEngine::loadRoom(%i)", roomID); + char buf[12]; + + loadPalette("palette.col", _screen->_currentPalette); + + //loadPalette(_rooms[roomID].palFilename, _screen->_currentPalette); + //_screen->setScreenPalette(_screen->_currentPalette); + + _screen->clearPage(14); + _screen->clearPage(0); + _screen->clearPage(10); + + // Loading GUI bitmap + if (_game == KYRA1CD) { + loadBitmap("MAIN_ENG.CPS", 10, 10, 0); + } else { + loadBitmap("MAIN15.CPS", 10, 10, 0); + } + + // Loading main room background + strncpy(buf, _rooms[roomID].filename, 8); + strcat(buf, ".cps"); + loadBitmap( buf, 14, 14, 0); + + // Loading the room mask + strncpy(buf, _rooms[roomID].filename, 8); + strcat(buf, ".msc"); + loadBitmap( buf, 12, 12, 0); + + // Loading room data + strncpy(buf, _rooms[roomID].filename, 8); + strcat(buf, ".dat"); + _sprites->loadDAT(buf); + + setCursor(0); +} + void KyraEngine::mainLoop() { debug(9, "KyraEngine::mainLoop()"); - // XXX +#ifdef TEST_SPRITES + _currentRoom = 0; + loadRoom(_currentRoom); + + while (!_quitFlag) { + int32 frameTime = (int32)_system->getMillis(); + + drawRoom(); + _screen->updateScreen(); + + delay((frameTime + _gameSpeed) - _system->getMillis()); + } +#endif +} + +void KyraEngine::loadPalette(const char *filename, uint8 *palData) { + debug(9, "KyraEngine::loadPalette('%s' 0x%X)", filename, palData); + uint32 fileSize = 0; + uint8 *srcData = _res->fileData(filename, &fileSize); + + if (palData && fileSize) { + debug(9, "Loading a palette of size %i from %s", fileSize, filename); + memcpy(palData, srcData, fileSize); + } } void KyraEngine::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData) { @@ -230,6 +373,7 @@ void KyraEngine::loadBitmap(const char *filename, int tempPage, int dstPage, uin uint32 imgSize = READ_LE_UINT32(srcData + 4); uint16 palSize = READ_LE_UINT16(srcData + 8); if (palData && palSize) { + debug(9, "Loading a palette of size %i from %s", palSize, filename); memcpy(palData, srcData + 10, palSize); } uint8 *srcPtr = srcData + 10 + palSize; @@ -446,6 +590,8 @@ void KyraEngine::waitTicks(int ticks) { if (event.kbd.keycode == 'f') { _fastMode = !_fastMode; } + } else if (event.kbd.keycode == 13 || event.kbd.keycode == 32 || event.kbd.keycode == 27) { + _abortIntroFlag = true; } break; default: @@ -504,6 +650,7 @@ void KyraEngine::seq_demo() { _screen->fadeFromBlack(); waitTicks(60); _screen->fadeToBlack(); + _midi->stopMusic(); } void KyraEngine::seq_intro() { @@ -527,6 +674,7 @@ void KyraEngine::seq_intro() { setTalkCoords(136); waitTicks(30); _seq_copyViewOffs = false; + _midi->stopMusic(); } void KyraEngine::seq_introLogos() { @@ -658,7 +806,7 @@ void KyraEngine::seq_copyView() { bool KyraEngine::seq_skipSequence() const { debug(9, "KyraEngine::seq_skipSequence()"); - return _quitFlag; + return _quitFlag || _abortIntroFlag; } bool KyraEngine::seq_playSpecialSequence(const uint8 *seqData, bool skipSeq) { diff --git a/kyra/kyra.h b/kyra/kyra.h index 4463a5e517..e170ce06e4 100644 --- a/kyra/kyra.h +++ b/kyra/kyra.h @@ -27,6 +27,8 @@ namespace Kyra { +#define MAX_NUM_ROOMS 12 + enum { GF_FLOPPY = 1 << 0, GF_TALKIE = 1 << 1, @@ -64,12 +66,18 @@ struct Shape { }; struct Room { - uint8 id; +// uint8 id; uint16 northExit; uint16 eastExit; uint16 southExit; uint16 westExit; uint8 itemsTable[12]; + const char *filename; +}; + +struct Cursor { + int x, y; + int w, h; }; struct TalkCoords { @@ -86,6 +94,7 @@ struct WSAMovieV1; class MusicPlayer; class Resource; class Screen; +class Sprites; class KyraEngine : public Engine { friend class MusicPlayer; @@ -162,11 +171,19 @@ protected: void snd_setSoundEffectFile(int file); void snd_playSoundEffect(int track); void snd_seqMessage(int msg); - + + void loadRoom(uint16 roomID); + void drawRoom(); + void delay(uint32 millis); + void loadPalette(const char *filename, uint8 *palData); + void setCursor(uint8 cursorID); + void setupRooms(); + uint8 _game; bool _fastMode; bool _quitFlag; bool _skipIntroFlag; + bool _abortIntroFlag; char _talkBuffer[300]; char _talkSubstrings[TALK_SUBSTRING_LEN * TALK_SUBSTRING_NUM]; TalkCoords _talkCoords; @@ -174,14 +191,21 @@ protected: uint16 _talkMessageH; bool _talkMessagePrinted; uint8 _flagsTable[51]; + uint16 _gameSpeed; + uint16 _currentRoom; bool _seq_copyViewOffs; uint8 *_seq_handShapes[3]; Resource *_res; Screen *_screen; MusicPlayer *_midi; + Sprites *_sprites; + Room _rooms[MAX_NUM_ROOMS]; + static const Cursor _cursors[]; + static const int _cursorsCount; + // these tables are specific to the demo version static const uint8 _seq_demoData_WestwoodLogo[]; static const uint8 _seq_demoData_KyrandiaLogo[]; diff --git a/kyra/module.mk b/kyra/module.mk index fb5e0dd487..4c0f4996f9 100644 --- a/kyra/module.mk +++ b/kyra/module.mk @@ -8,6 +8,7 @@ MODULE_OBJS := \ kyra/script.o \ kyra/sound.o \ kyra/staticres.o \ + kyra/sprites.o \ kyra/wsamovie.o MODULE_DIRS += \ diff --git a/kyra/screen.cpp b/kyra/screen.cpp index 28f61bfbd7..2bb2759663 100644 --- a/kyra/screen.cpp +++ b/kyra/screen.cpp @@ -224,6 +224,14 @@ void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPag } } +void Screen::copyRegionToBuffer(int pageNum, int x, int y, int w, int h, uint8 *dest) { + assert(x >= 0 && x < Screen::SCREEN_W && y >= 0 && y < Screen::SCREEN_H && dest); + uint8 *pagePtr = getPagePtr(pageNum); + for (int i = y; i < y + h; i++) { + memcpy(dest + (i - y) * w, pagePtr + i * SCREEN_W + x, w); + } +} + void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint8 *src) { debug(9, "Screen::copyBlockToPage(%d, %d, %d, %d, %d, 0x%X)", pageNum, x, y, w, h, src); assert(x >= 0 && x < Screen::SCREEN_W && y >= 0 && y < Screen::SCREEN_H); diff --git a/kyra/screen.h b/kyra/screen.h index e044c8a75e..600725a424 100644 --- a/kyra/screen.h +++ b/kyra/screen.h @@ -110,7 +110,8 @@ public: static void decodeFrame4(const uint8 *src, uint8 *dst, uint32 dstSize); static void decodeFrameDelta(uint8 *dst, const uint8 *src); static void decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitch); - + void copyRegionToBuffer(int pageNum, int x, int y, int w, int h, uint8 *dest); + int _charWidth; int _charOffset; int _curPage; diff --git a/kyra/script.h b/kyra/script.h index 5820a10a08..ed6d36ac83 100644 --- a/kyra/script.h +++ b/kyra/script.h @@ -19,8 +19,8 @@ * */ -#ifndef SCRIPT_H -#define SCRIPT_H +#ifndef KYRASCRIPT_H +#define KYRASCRIPT_H namespace Kyra { // TODO: diff --git a/kyra/sprites.cpp b/kyra/sprites.cpp new file mode 100644 index 0000000000..14823abee2 --- /dev/null +++ b/kyra/sprites.cpp @@ -0,0 +1,440 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004-2005 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#include "common/stdafx.h" +#include "common/stream.h" +#include "common/util.h" +#include "common/system.h" +#include "kyra/screen.h" +#include "kyra/kyra.h" +#include "kyra/sprites.h" +#include "kyra/resource.h" + +namespace Kyra { + +Sprites::Sprites(KyraEngine *engine, OSystem *system) { + _engine = engine; + _res = engine->resource(); + _screen = engine->screen(); + _system = system; + _dat = 0; + memset(_anims, 0, sizeof(_anims)); + _animDelay = 16; +} + +Sprites::~Sprites() { + delete[] _dat; +} + +Sprite Sprites::getSprite(uint8 spriteID) { + assert( spriteID < MAX_NUM_SPRITES); + return _sprites[spriteID]; +} + +void Sprites::drawSprites(uint8 srcPage, uint8 dstPage) { + for (int i = 0; i < MAX_NUM_ANIMS; i++) { + if (_anims[i].script == 0) + break; + if (_anims[i].sprite >= 0) { + assert( _anims[i].sprite < MAX_NUM_SPRITES); + Sprite sprite = _sprites[_anims[i].sprite]; + + //debug(1, "Drawing from X %i, Y %i, to X %i, Y %i, width %i, height %i, srcPage %i, dstPage %i", + // sprite.x, sprite.y, _anims[i].x, _anims[i].y, sprite.width, sprite.height, srcPage, dstPage); + + _screen->copyRegion(sprite.x, sprite.y, _anims[i].x, _anims[i].y, sprite.width, sprite.height, srcPage, dstPage); + } + } +} + +void Sprites::doAnims() { + uint32 currTime = _system->getMillis(); + for (int i = 0; i < MAX_NUM_ANIMS; i++) { + if (_anims[i].script == 0) + break; + + if (!_anims[i].play || _anims[i].nextRun != 0 && _anims[i].nextRun > currTime) + continue; + + uint8 *data; + + if (_anims[i].reentry == 0) { + data = _anims[i].script; + + //debug(1, "---Start of anim script---"); + assert( READ_LE_UINT16(data) == 0xFF86 ); + data += 2; + + //debug(1, "Default X of sprite: %i", READ_LE_UINT16(data + 0x12) ); + _anims[i].x = READ_LE_UINT16(data + 0x12); + //debug(1, "Default Y of sprite: %i", READ_LE_UINT16(data + 0x16) ); + _anims[i].y = READ_LE_UINT16(data + 0x16); + + //debug(1, "Anim %i data: 0h: %i, 2h: %i,4h: %i,6h: %i,8h: %i,ah: %i,ch: %i", i, READ_LE_UINT16(data + 0x0), + //READ_LE_UINT16(data + 0x2), READ_LE_UINT16(data + 0x4),READ_LE_UINT16(data + 0x6),READ_LE_UINT16(data + 0x8), + //READ_LE_UINT16(data + 0xa),READ_LE_UINT16(data + 0xc)); + + //debug(1, "Anim %i data: eh: %i, 10h: %i,12h: %i,14h: %i,16h: %i,18h: %i,1ah: %i", i, READ_LE_UINT16(data + 0xe), + //READ_LE_UINT16(data + 0x10), READ_LE_UINT16(data + 0x12),READ_LE_UINT16(data + 0x14),READ_LE_UINT16(data + 0x16), + //READ_LE_UINT16(data + 0x18),READ_LE_UINT16(data + 0x1a)); + + //debug(1, "Anim %i data: 1ch: %i, 1fh: %i,22h: %i,24h: %i,26h: %i,28h: %i,2ah: %i", i, READ_LE_UINT16(data + 0x1c), + //READ_LE_UINT16(data + 0x1f), READ_LE_UINT16(data + 0x22),READ_LE_UINT16(data + 0x24),READ_LE_UINT16(data + 0x26), + //READ_LE_UINT16(data + 0x28),READ_LE_UINT16(data + 0x2a)); + + // TODO: Find out what the rest of this data (next 38h bytes) does. + data += 0x38; + } else { + data = _anims[i].reentry; + _anims[i].reentry = 0; + } + + bool endLoop = false; + + while (READ_LE_UINT16(data) != 0xFF87 && !endLoop) { + uint16 rndNr; + assert((data - _anims[i].script) < _anims[i].length); + switch (READ_LE_UINT16(data)) { + case 0xFF88: + data += 2; + debug(9, "func: Set sprite image, and set flag0"); + debug(9, "Sprite index %i", READ_LE_UINT16(data)); + _anims[i].sprite = READ_LE_UINT16(data); + data += 2; + debug(9, "Unused %i", READ_LE_UINT16(data)); + data += 2; + debug(9, "X %i", READ_LE_UINT16(data)); + _anims[i].x = READ_LE_UINT16(data); + data += 2; + debug(9, "Y %i", READ_LE_UINT16(data)); + _anims[i].y = READ_LE_UINT16(data); + data += 2; + _anims[i].flag0 = true; + break; + case 0xFF8D: + data += 2; + debug(9, "func: Set sprite image, and reset flag0"); + _anims[i].sprite = READ_LE_UINT16(data); + data += 2; + //debug(9, "Unused %i", READ_LE_UINT16(data)); + data += 2; + debug(9, "X %i", READ_LE_UINT16(data)); + _anims[i].x = READ_LE_UINT16(data); + data += 2; + debug(9, "Y %i", READ_LE_UINT16(data)); + _anims[i].y = READ_LE_UINT16(data); + data += 2; + _anims[i].flag0 = false; + break; + case 0xFF8A: + data += 2; + debug(9, "func: Set time to wait"); + debug(9, "Time %i", READ_LE_UINT16(data)); + _anims[i].nextRun = _system->getMillis() + READ_LE_UINT16(data) * _animDelay; + data += 2; + break; + case 0xFFB3: + data += 2; + debug(9, "func: Set time to wait to random value"); + rndNr = READ_LE_UINT16(data) + _rnd.getRandomNumber( READ_LE_UINT16(data) + 2); + debug(9, "Minimum time %i", READ_LE_UINT16(data)); + data += 2; + debug(9, "Maximum time %i", READ_LE_UINT16(data)); + data += 2; + _anims[i].nextRun = _system->getMillis() + rndNr * _animDelay; + break; + case 0xFF8C: + data += 2; + debug(9, "func: Wait until wait time has elapsed"); + _anims[i].reentry = data; + endLoop = true; + //assert( _anims[i].nextRun > _system->getMillis()); + break; + case 0xFF99: + data += 2; + debug(1, "TODO func: Set value of animation property 32h to 1"); + break; + case 0xFF9A: + data += 2; + debug(1, "TODO func: Set value of animation property 32h to 0"); + break; + case 0xFF97: + data += 2; + debug(9, "func: Set default X coordinate of sprite"); + debug(9, "X %i", READ_LE_UINT16(data)); + _anims[i].x = READ_LE_UINT16(data); + data += 2; + break; + case 0xFF98: + data += 2; + debug(9, "func: Set default Y coordinate of sprite"); + debug(9, "Y %i", READ_LE_UINT16(data)); + _anims[i].y = READ_LE_UINT16(data); + data += 2; + break; + case 0xFF8B: + debug(9, "func: Jump to start of script section"); + //data = scriptStart; + _anims[i].nextRun = _system->getMillis(); + endLoop = true; + break; + case 0xFF8E: + data += 2; + debug(9, "func: Begin for () loop"); + debug(9, "Iterations: %i", READ_LE_UINT16(data)); + _anims[i].loopsLeft = READ_LE_UINT16(data); + data += 2; + _anims[i].loopStart = data; + break; + case 0xFF8F: + data += 2; + debug(9, "func: End for () loop"); + if (_anims[i].loopsLeft > 0) { + _anims[i].loopsLeft--; + data = _anims[i].loopStart; + } + break; + case 0xFF90: + data += 2; + debug(9, "func: Set sprite image using default X and Y (and set flag0)"); + debug(9, "Sprite index %i", READ_LE_UINT16(data)); + _anims[i].sprite = READ_LE_UINT16(data); + _anims[i].flag0 = true; + data += 2; + break; + case 0xFF91: + data += 2; + debug(9, "func: Set sprite image using default X and Y (and reset flag0)"); + debug(9, "Sprite index %i", READ_LE_UINT16(data)); + _anims[i].sprite = READ_LE_UINT16(data); + _anims[i].flag0 = false; + data += 2; + break; + case 0xFF92: + data += 2; + debug(9, "func: Increase value of default X-coordinate"); + debug(9, "Increment %i", READ_LE_UINT16(data)); + _anims[i].x += READ_LE_UINT16(data); + data += 2; + break; + case 0xFF93: + data += 2; + debug(9, "func: Increase value of default Y-coordinate"); + debug(9, "Increment %i", READ_LE_UINT16(data)); + _anims[i].y += READ_LE_UINT16(data); + data += 2; + break; + case 0xFF94: + data += 2; + debug(9, "func: Decrease value of default X-coordinate"); + debug(9, "Decrement %i", READ_LE_UINT16(data)); + _anims[i].x -= READ_LE_UINT16(data); + data += 2; + break; + case 0xFF95: + data += 2; + debug(9, "func: Decrease value of default Y-coordinate"); + debug(9, "Decrement %i", READ_LE_UINT16(data)); + _anims[i].y -= READ_LE_UINT16(data); + data += 2; + break; + case 0xFF96: + data += 2; + debug(1, "TODO func: Set value of animation property 34h to 1(?)"); + debug(1, "Arg1 %i", READ_LE_UINT16(data)); + data += 2; + debug(1, "Arg2 %i", READ_LE_UINT16(data)); + data += 2; + break; +/* case 0xFF97: + data += 2; + debug(1, "func: Set value of animation property 34h to 0"); + break;*/ + case 0xFFAD: + data += 2; + debug(1, "TODO func: Set Brandon's X coordinate"); + debug(1, "X %i", READ_LE_UINT16(data)); + data += 2; + break; + case 0xFFAE: + data += 2; + debug(1, "TODO func: Set Brandon's Y coordinate"); + debug(1, "Y %i", READ_LE_UINT16(data)); + data += 2; + break; + case 0xFFAF: + data += 2; + debug(1, "TODO func: Set Brandon's X sprite"); + debug(1, "Sprite %i", READ_LE_UINT16(data)); + data += 2; + break; + case 0xFFAA: + data += 2; + debug(1, "TODO func: Reset Brandon's sprite"); + break; + case 0xFFAB: + data += 2; + debug(1, "TODO func: Update Brandon's sprite"); + break; + case 0xFFB0: + data += 2; + debug(1, "TODO func: Play sound"); + debug(1, "Sound index %i", READ_LE_UINT16(data)); + data += 2; + break; + case 0xFFB1: + data += 2; + debug(1, "TODO func: Set unknown global bit"); + break; + case 0xFFB2: + data += 2; + debug(1, "TODO func: Reset unknown global bit"); + break; + case 0xFFB4: + data += 2; + debug(1, "TODO func: Play (at random) a certain sound at a certain percentage of time"); + debug(1, "Sound index %i", READ_LE_UINT16(data)); + data += 2; + debug(1, "Percentage %i", READ_LE_UINT16(data)); + data += 2; + break; + default: + debug(1, "Unsupported anim command %X", READ_LE_UINT16(data)); + //endLoop = true; + data += 1; + break; + } + } + + if (READ_LE_UINT16(data) == 0xFF87) + _anims[i].play = false; + + //debug(1, "---End of anim script---"); + } +} + +void Sprites::loadDAT(const char *filename) { + debug(9, "Sprites::loadDat('%s')", filename); + uint32 fileSize; + uint8 spritesLoaded = 0; + + delete[] _dat; + + _dat = _res->fileData(filename, &fileSize); + + memset(_anims, 0, sizeof(Anim) * MAX_NUM_ANIMS); + uint8 nextAnim = 0; + + assert(fileSize > 0x6D); + + memcpy(_screen->_currentPalette + 745 - 0x3D, _dat + 0x17, 0x3D); + _screen->setScreenPalette(_screen->_currentPalette); + uint8 *data = _dat + 0x6B; + + uint16 length = READ_LE_UINT16(data); + data += 2; + + //debug(1, "DAT body length: %i, filesize %i, current spot %i", length, fileSize, data - _dat); + + if (length > 2) { + assert( length < fileSize); + uint8 *animstart; + uint8 *start = data; + + while (1) { + if (((uint16)(data - _dat) >= fileSize) || (data - start) >= length) + break; + + if (READ_LE_UINT16(data) == 0xFF83) { + //debug(1, "Body section end."); + data += 2; + break; + } + + switch (READ_LE_UINT16(data)) { + case 0xFF81: + data += 2; + //debug(1, "Body section start"); + break; + case 0xFF82: + data += 2; + //debug(1, "Unknown 0xFF82 section"); + break; + case 0xFF84: + data += 2; + while (READ_LE_UINT16(data) != 0xFF85) { + uint16 spriteNum = READ_LE_UINT16(data); + //debug(1, "Spritenum: %i", spriteNum); + assert(spriteNum < MAX_NUM_SPRITES); + data += 2; + _sprites[spriteNum].x = READ_LE_UINT16(data) * 8; + data += 2; + _sprites[spriteNum].y = READ_LE_UINT16(data); + data += 2; + _sprites[spriteNum].width = READ_LE_UINT16(data) * 8; + data += 2; + _sprites[spriteNum].height = READ_LE_UINT16(data); + data += 2; + spritesLoaded++; + //debug(1, "Got sprite index: %i", spriteNum); + //debug(1, "X: %i", _sprites[spriteNum].x); + //debug(1, "Y: %i", _sprites[spriteNum].y); + //debug(1, "Width: %i", _sprites[spriteNum].width); + //debug(1, "Height: %i", _sprites[spriteNum].height); + } + //debug(1, "End of sprite images."); + data += 2; + break; + case 0xFF86: + assert(nextAnim < MAX_NUM_ANIMS); + _anims[nextAnim].script = data; + _anims[nextAnim].sprite = -1; + _anims[nextAnim].play = true; + animstart = data; + data += 2; + while (READ_LE_UINT16(data) != 0xFF87) { + assert((uint16)(data - _dat) < fileSize); + data += 2; + } + _anims[nextAnim].length = data - animstart; + //debug(1, "Found an anim script of length %i!", _anims[nextAnim].length); + nextAnim++; + data += 2; + break; + default: + debug(1, "Unknown code in DAT file: %x", READ_LE_UINT16(data)); + data += 2; + break; + } + } + } else { + data += 2; + } + + debug(1, "Room DAT file loaded. Found %i sprite and %i animation scripts.", spritesLoaded, nextAnim); + + //debug(1, "Remainder after script: %i", fileSize - (data - _dat)); + assert(fileSize - (data - _dat) == 0xC); + + //TODO: Read in character entry coords here +} + +} // end of namespace Kyra diff --git a/kyra/sprites.h b/kyra/sprites.h new file mode 100644 index 0000000000..3a87b05153 --- /dev/null +++ b/kyra/sprites.h @@ -0,0 +1,76 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004-2005 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Header$ + * + */ + +#ifndef KYRASPRITES_H +#define KYRASPRITES_H + +namespace Kyra { + +#define MAX_NUM_SPRITES 50 +#define MAX_NUM_ANIMS 11 + +struct Sprite { + uint16 x; + uint16 y; + uint16 width; + uint16 height; +}; + +struct Anim { + uint8 *script; + uint16 length; + uint16 x; + uint16 y; + bool flag0; + int8 sprite; + uint8 *loopStart; + uint16 loopsLeft; + uint8 *reentry; + uint32 nextRun; + bool play; +}; + +class Sprites { +public: + + Sprites(KyraEngine *engine, OSystem *system); + ~Sprites(); + + void doAnims(); + void loadDAT(const char* filename); + Sprite getSprite(uint8 spriteID); + void drawSprites(uint8 srcPage, uint8 dstPage); + +protected: + KyraEngine *_engine; + Resource *_res; + OSystem *_system; + Screen *_screen; + Sprite _sprites[MAX_NUM_SPRITES]; + uint8 *_dat; + Anim _anims[MAX_NUM_ANIMS]; + Common::RandomSource _rnd; + uint8 _animDelay; +}; + +} // End of namespace Kyra + +#endif diff --git a/kyra/staticres.cpp b/kyra/staticres.cpp index d11323a025..c0cbd5b42e 100644 --- a/kyra/staticres.cpp +++ b/kyra/staticres.cpp @@ -467,4 +467,15 @@ const char *KyraEngine::_xmidiFiles[] = { const int KyraEngine::_xmidiFilesCount = ARRAYSIZE(_xmidiFiles); +const Cursor KyraEngine::_cursors[] = { + { 0, 0, 8, 10 }, // 0: Regular cursor + { 80, 18, 15, 10 }, // 1: Up arrow + { 95, 18, 15, 10 }, // 2: Right arrow + { 110, 18, 15, 10 }, // 3: Down arrow + { 125, 18, 15, 10 }, // 4: Left arrow + { 140, 18, 15, 10 } // 5: Stopsign +}; + +const int KyraEngine::_cursorsCount = ARRAYSIZE(_cursors); + } // End of namespace Kyra |