mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-05 01:38:36 +00:00
committed patch #1312156 'Various sprite-related things'. Thanks Oystein Eftevaag/vinterstum
svn-id: r18930
This commit is contained in:
parent
efa1c13064
commit
3bcb098fd3
154
kyra/kyra.cpp
154
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) {
|
||||
|
28
kyra/kyra.h
28
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[];
|
||||
|
@ -8,6 +8,7 @@ MODULE_OBJS := \
|
||||
kyra/script.o \
|
||||
kyra/sound.o \
|
||||
kyra/staticres.o \
|
||||
kyra/sprites.o \
|
||||
kyra/wsamovie.o
|
||||
|
||||
MODULE_DIRS += \
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -19,8 +19,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SCRIPT_H
|
||||
#define SCRIPT_H
|
||||
#ifndef KYRASCRIPT_H
|
||||
#define KYRASCRIPT_H
|
||||
|
||||
namespace Kyra {
|
||||
// TODO:
|
||||
|
440
kyra/sprites.cpp
Normal file
440
kyra/sprites.cpp
Normal file
@ -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
|
76
kyra/sprites.h
Normal file
76
kyra/sprites.h
Normal file
@ -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
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user