diff options
| -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 | 
