Import 0.3.6

This commit is contained in:
Gregory Montoir 2018-01-15 00:00:00 +08:00
parent e2f30e28a0
commit e8f6b94ef8
14 changed files with 114 additions and 76 deletions

View File

@ -1,6 +1,6 @@
REminiscence README REminiscence README
Release version: 0.3.5 Release version: 0.3.6
------------------------------------------------------------------------------- -------------------------------------------------------------------------------

View File

@ -13,7 +13,7 @@
#include "unpack.h" #include "unpack.h"
#include "util.h" #include "util.h"
Game::Game(SystemStub *stub, FileSystem *fs, const char *savePath, int level, int demo, ResourceType ver, Language lang) Game::Game(SystemStub *stub, FileSystem *fs, const char *savePath, int level, ResourceType ver, Language lang)
: _cut(&_res, stub, &_vid), _menu(&_res, stub, &_vid), : _cut(&_res, stub, &_vid), _menu(&_res, stub, &_vid),
_mix(fs, stub), _res(fs, ver, lang), _seq(stub, &_mix), _vid(&_res, stub), _mix(fs, stub), _res(fs, ver, lang), _seq(stub, &_mix), _vid(&_res, stub),
_stub(stub), _fs(fs), _savePath(savePath) { _stub(stub), _fs(fs), _savePath(savePath) {
@ -21,23 +21,12 @@ Game::Game(SystemStub *stub, FileSystem *fs, const char *savePath, int level, in
_inp_demPos = 0; _inp_demPos = 0;
_skillLevel = _menu._skill = 1; _skillLevel = _menu._skill = 1;
_currentLevel = _menu._level = level; _currentLevel = _menu._level = level;
_demoBin = demo; _demoBin = -1;
} }
void Game::run() { void Game::run() {
_randSeed = time(0); _randSeed = time(0);
if (_demoBin != -1) {
if (_demoBin < ARRAYSIZE(_demoInputs)) {
const char *fn = _demoInputs[_demoBin].name;
debug(DBG_INFO, "Loading inputs from '%s'", fn);
_res.load_DEM(fn);
}
if (_res._demLen == 0) {
return;
}
}
_res.init(); _res.init();
_res.load_TEXT(); _res.load_TEXT();
@ -69,10 +58,8 @@ void Game::run() {
_mix.init(); _mix.init();
_mix._mod._isAmiga = _res.isAmiga(); _mix._mod._isAmiga = _res.isAmiga();
if (_demoBin == -1) {
playCutscene(0x40); playCutscene(0x40);
playCutscene(0x0D); playCutscene(0x0D);
}
switch (_res._type) { switch (_res._type) {
case kResourceTypeAmiga: case kResourceTypeAmiga:
@ -90,10 +77,7 @@ void Game::run() {
} }
while (!_stub->_pi.quit) { while (!_stub->_pi.quit) {
if (_demoBin != -1) { if (_res._isDemo) {
_currentLevel = _demoInputs[_demoBin].level;
_randSeed = 0;
} else if (_res._isDemo) {
// do not present title screen and menus // do not present title screen and menus
} else { } else {
_mix.playMusic(1); _mix.playMusic(1);
@ -104,6 +88,21 @@ void Game::run() {
_stub->_pi.quit = true; _stub->_pi.quit = true;
break; break;
} }
if (_menu._selectedOption == Menu::MENU_OPTION_ITEM_DEMO) {
_demoBin = (_demoBin + 1) % ARRAYSIZE(_demoInputs);
const char *fn = _demoInputs[_demoBin].name;
debug(DBG_DEMO, "Loading inputs from '%s'", fn);
_res.load_DEM(fn);
if (_res._demLen == 0) {
continue;
}
_skillLevel = 1;
_currentLevel = _demoInputs[_demoBin].level;
_randSeed = 0;
_mix.stopMusic();
break;
}
_demoBin = -1;
_skillLevel = _menu._skill; _skillLevel = _menu._skill;
_currentLevel = _menu._level; _currentLevel = _menu._level;
_mix.stopMusic(); _mix.stopMusic();
@ -135,10 +134,17 @@ void Game::run() {
while (!_stub->_pi.quit && !_endLoop) { while (!_stub->_pi.quit && !_endLoop) {
mainLoop(); mainLoop();
if (_demoBin != -1 && _inp_demPos >= _res._demLen) { if (_demoBin != -1 && _inp_demPos >= _res._demLen) {
debug(DBG_INFO, "End of demo"); debug(DBG_DEMO, "End of demo");
_stub->_pi.quit = true; // exit level
_demoBin = -1;
_endLoop = true;
} }
} }
// flush inputs
_stub->_pi.dirMask = 0;
_stub->_pi.enter = false;
_stub->_pi.space = false;
_stub->_pi.shift = false;
} }
} }
@ -149,7 +155,7 @@ void Game::run() {
void Game::displayTitleScreenAmiga() { void Game::displayTitleScreenAmiga() {
static const char *FILENAME = "present.cmp"; static const char *FILENAME = "present.cmp";
_res.load_CMP_menu(FILENAME, _res._memBuf); _res.load_CMP_menu(FILENAME, _res._scratchBuffer);
static const int kW = 320; static const int kW = 320;
static const int kH = 224; static const int kH = 224;
uint8_t *buf = (uint8_t *)calloc(kW * kH, 1); uint8_t *buf = (uint8_t *)calloc(kW * kH, 1);
@ -169,7 +175,7 @@ void Game::displayTitleScreenAmiga() {
_stub->setScreenSize(kW, kH); _stub->setScreenSize(kW, kH);
_stub->copyRect(0, 0, kW, kH, buf, kW); _stub->copyRect(0, 0, kW, kH, buf, kW);
_stub->updateScreen(0); _stub->updateScreen(0);
_vid.AMIGA_decodeCmp(_res._memBuf + 6, buf); _vid.AMIGA_decodeCmp(_res._scratchBuffer + 6, buf);
free(buf); free(buf);
for (int h = 0; h < kH / 2; h += 2) { for (int h = 0; h < kH / 2; h += 2) {
const int y = kH / 2 - h; const int y = kH / 2 - h;
@ -261,7 +267,7 @@ void Game::mainLoop() {
return; return;
} }
if (_loadMap) { if (_loadMap) {
if (_currentRoom == 0xFF) { if (_currentRoom == 0xFF || !hasLevelMap(_currentLevel, _pgeLive[0].room_location)) {
_cut._id = 6; _cut._id = 6;
_deathCutsceneCounter = 1; _deathCutsceneCounter = 1;
} else { } else {
@ -288,7 +294,7 @@ void Game::mainLoop() {
} }
if (_stub->_pi.escape) { if (_stub->_pi.escape) {
_stub->_pi.escape = false; _stub->_pi.escape = false;
if (handleConfigPanel()) { if (_demoBin != -1 || handleConfigPanel()) {
_endLoop = true; _endLoop = true;
return; return;
} }
@ -382,7 +388,7 @@ void Game::playCutscene(int id) {
bool Game::playCutsceneSeq(const char *name) { bool Game::playCutsceneSeq(const char *name) {
File f; File f;
if (f.open(name, "rb", _fs)) { if (f.open(name, "rb", _fs)) {
_seq.setBackBuffer(_res._memBuf); _seq.setBackBuffer(_res._scratchBuffer);
_seq.play(&f); _seq.play(&f);
_vid.fullRefresh(); _vid.fullRefresh();
return true; return true;
@ -967,13 +973,13 @@ void Game::drawAnimBuffer(uint8_t stateNum, AnimBufferState *state) {
} }
switch (_res._type) { switch (_res._type) {
case kResourceTypeAmiga: case kResourceTypeAmiga:
_vid.AMIGA_decodeSpm(state->dataPtr, _res._memBuf); _vid.AMIGA_decodeSpm(state->dataPtr, _res._scratchBuffer);
drawCharacter(_res._memBuf, state->x, state->y, state->h, state->w, pge->flags); drawCharacter(_res._scratchBuffer, state->x, state->y, state->h, state->w, pge->flags);
break; break;
case kResourceTypeDOS: case kResourceTypeDOS:
if (!(state->dataPtr[-2] & 0x80)) { if (!(state->dataPtr[-2] & 0x80)) {
decodeCharacterFrame(state->dataPtr, _res._memBuf); decodeCharacterFrame(state->dataPtr, _res._scratchBuffer);
drawCharacter(_res._memBuf, state->x, state->y, state->h, state->w, pge->flags); drawCharacter(_res._scratchBuffer, state->x, state->y, state->h, state->w, pge->flags);
} else { } else {
drawCharacter(state->dataPtr, state->x, state->y, state->h, state->w, pge->flags); drawCharacter(state->dataPtr, state->x, state->y, state->h, state->w, pge->flags);
} }
@ -1041,14 +1047,14 @@ void Game::drawObjectFrame(const uint8_t *bankDataPtr, const uint8_t *dataPtr, i
switch (_res._type) { switch (_res._type) {
case kResourceTypeAmiga: case kResourceTypeAmiga:
_vid.AMIGA_decodeSpc(src, sprite_w, sprite_h, _res._memBuf); _vid.AMIGA_decodeSpc(src, sprite_w, sprite_h, _res._scratchBuffer);
break; break;
case kResourceTypeDOS: case kResourceTypeDOS:
_vid.PC_decodeSpc(src, sprite_w, sprite_h, _res._memBuf); _vid.PC_decodeSpc(src, sprite_w, sprite_h, _res._scratchBuffer);
break; break;
} }
src = _res._memBuf; src = _res._scratchBuffer;
bool sprite_mirror_x = false; bool sprite_mirror_x = false;
int16_t sprite_clipped_w; int16_t sprite_clipped_w;
if (sprite_x >= 0) { if (sprite_x >= 0) {
@ -1294,6 +1300,15 @@ int Game::loadMonsterSprites(LivePGE *pge) {
return 0xFFFF; return 0xFFFF;
} }
bool Game::hasLevelMap(int level, int room) const {
if (_res._map) {
return READ_LE_UINT32(_res._map + room * 6) != 0;
} else if (_res._lev) {
return READ_BE_UINT32(_res._lev + room * 4) != 0;
}
return false;
}
void Game::loadLevelMap() { void Game::loadLevelMap() {
debug(DBG_GAME, "Game::loadLevelMap() room=%d", _currentRoom); debug(DBG_GAME, "Game::loadLevelMap() room=%d", _currentRoom);
_currentIcon = 0xFF; _currentIcon = 0xFF;
@ -1441,6 +1456,7 @@ void Game::loadLevelData() {
_pgeLive[0].room_location = _demoInputs[_demoBin].room; _pgeLive[0].room_location = _demoInputs[_demoBin].room;
_pgeLive[0].pos_x = _demoInputs[_demoBin].x; _pgeLive[0].pos_x = _demoInputs[_demoBin].x;
_pgeLive[0].pos_y = _demoInputs[_demoBin].y; _pgeLive[0].pos_y = _demoInputs[_demoBin].y;
_inp_demPos = 0;
} else { } else {
_inp_demPos = 1; _inp_demPos = 1;
} }
@ -1669,7 +1685,7 @@ void Game::handleInventory() {
void Game::inp_update() { void Game::inp_update() {
_stub->processEvents(); _stub->processEvents();
if (_inp_demPos < _res._demLen) { if (_demoBin != -1 && _inp_demPos < _res._demLen) {
const int keymask = _res._dem[_inp_demPos++]; const int keymask = _res._dem[_inp_demPos++];
_stub->_pi.dirMask = keymask & 0xF; _stub->_pi.dirMask = keymask & 0xF;
_stub->_pi.enter = (keymask & 0x10) != 0; _stub->_pi.enter = (keymask & 0x10) != 0;

3
game.h
View File

@ -87,7 +87,7 @@ struct Game {
bool _endLoop; bool _endLoop;
uint32_t _frameTimestamp; uint32_t _frameTimestamp;
Game(SystemStub *, FileSystem *, const char *savePath, int level, int demo, ResourceType ver, Language lang); Game(SystemStub *, FileSystem *, const char *savePath, int level, ResourceType ver, Language lang);
void run(); void run();
void displayTitleScreenAmiga(); void displayTitleScreenAmiga();
@ -96,6 +96,7 @@ struct Game {
void updateTiming(); void updateTiming();
void playCutscene(int id = -1); void playCutscene(int id = -1);
bool playCutsceneSeq(const char *name); bool playCutsceneSeq(const char *name);
bool hasLevelMap(int level, int room) const;
void loadLevelMap(); void loadLevelMap();
void loadLevelData(); void loadLevelData();
void drawIcon(uint8_t iconNum, int16_t x, int16_t y, uint8_t colMask); void drawIcon(uint8_t iconNum, int16_t x, int16_t y, uint8_t colMask);

View File

@ -174,7 +174,6 @@ int main(int argc, char *argv[]) {
bool fullscreen = false; bool fullscreen = false;
ScalerParameters scalerParameters = ScalerParameters::defaults(); ScalerParameters scalerParameters = ScalerParameters::defaults();
int forcedLanguage = -1; int forcedLanguage = -1;
int demoNum = -1;
if (argc == 2) { if (argc == 2) {
// data path as the only command line argument // data path as the only command line argument
struct stat st; struct stat st;
@ -190,7 +189,6 @@ int main(int argc, char *argv[]) {
{ "fullscreen", no_argument, 0, 4 }, { "fullscreen", no_argument, 0, 4 },
{ "scaler", required_argument, 0, 5 }, { "scaler", required_argument, 0, 5 },
{ "language", required_argument, 0, 6 }, { "language", required_argument, 0, 6 },
{ "playdemo", required_argument, 0, 7 },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
int index; int index;
@ -235,9 +233,6 @@ int main(int argc, char *argv[]) {
} }
} }
break; break;
case 7:
demoNum = atoi(optarg);
break;
default: default:
printf(USAGE, argv[0]); printf(USAGE, argv[0]);
return 0; return 0;
@ -253,7 +248,7 @@ int main(int argc, char *argv[]) {
} }
const Language language = (forcedLanguage == -1) ? detectLanguage(&fs) : (Language)forcedLanguage; const Language language = (forcedLanguage == -1) ? detectLanguage(&fs) : (Language)forcedLanguage;
SystemStub *stub = SystemStub_SDL_create(); SystemStub *stub = SystemStub_SDL_create();
Game *g = new Game(stub, &fs, savePath, levelNum, demoNum, (ResourceType)version, language); Game *g = new Game(stub, &fs, savePath, levelNum, (ResourceType)version, language);
stub->init(g_caption, Video::GAMESCREEN_W, Video::GAMESCREEN_H, fullscreen, &scalerParameters); stub->init(g_caption, Video::GAMESCREEN_W, Video::GAMESCREEN_H, fullscreen, &scalerParameters);
g->run(); g->run();
delete g; delete g;

View File

@ -73,16 +73,16 @@ void Menu::drawString2(const char *str, int16_t y, int16_t x) {
void Menu::loadPicture(const char *prefix) { void Menu::loadPicture(const char *prefix) {
debug(DBG_MENU, "Menu::loadPicture('%s')", prefix); debug(DBG_MENU, "Menu::loadPicture('%s')", prefix);
_res->load_MAP_menu(prefix, _res->_memBuf); _res->load_MAP_menu(prefix, _res->_scratchBuffer);
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
for (int y = 0; y < 224; ++y) { for (int y = 0; y < 224; ++y) {
for (int x = 0; x < 64; ++x) { for (int x = 0; x < 64; ++x) {
_vid->_frontLayer[i + x * 4 + 256 * y] = _res->_memBuf[0x3800 * i + x + 64 * y]; _vid->_frontLayer[i + x * 4 + 256 * y] = _res->_scratchBuffer[0x3800 * i + x + 64 * y];
} }
} }
} }
_res->load_PAL_menu(prefix, _res->_memBuf); _res->load_PAL_menu(prefix, _res->_scratchBuffer);
_stub->setPalette(_res->_memBuf, 256); _stub->setPalette(_res->_scratchBuffer, 256);
} }
void Menu::handleInfoScreen() { void Menu::handleInfoScreen() {
@ -309,7 +309,7 @@ void Menu::handleTitleScreen() {
_charVar4 = 0; _charVar4 = 0;
_charVar5 = 0; _charVar5 = 0;
static const int MAX_MENU_ITEMS = 5; static const int MAX_MENU_ITEMS = 6;
Item menuItems[MAX_MENU_ITEMS]; Item menuItems[MAX_MENU_ITEMS];
int menuItemsCount = 0; int menuItemsCount = 0;
@ -331,6 +331,9 @@ void Menu::handleTitleScreen() {
menuItems[menuItemsCount].str = LocaleData::LI_10_INFO; menuItems[menuItemsCount].str = LocaleData::LI_10_INFO;
menuItems[menuItemsCount].opt = MENU_OPTION_ITEM_INFO; menuItems[menuItemsCount].opt = MENU_OPTION_ITEM_INFO;
++menuItemsCount; ++menuItemsCount;
menuItems[menuItemsCount].str = LocaleData::LI_23_DEMO;
menuItems[menuItemsCount].opt = MENU_OPTION_ITEM_DEMO;
++menuItemsCount;
menuItems[menuItemsCount].str = LocaleData::LI_11_QUIT; menuItems[menuItemsCount].str = LocaleData::LI_11_QUIT;
menuItems[menuItemsCount].opt = MENU_OPTION_ITEM_QUIT; menuItems[menuItemsCount].opt = MENU_OPTION_ITEM_QUIT;
++menuItemsCount; ++menuItemsCount;
@ -406,6 +409,9 @@ void Menu::handleTitleScreen() {
_currentScreen = SCREEN_INFO; _currentScreen = SCREEN_INFO;
handleInfoScreen(); handleInfoScreen();
break; break;
case MENU_OPTION_ITEM_DEMO:
quitLoop = true;
break;
case MENU_OPTION_ITEM_QUIT: case MENU_OPTION_ITEM_QUIT:
quitLoop = true; quitLoop = true;
break; break;

1
menu.h
View File

@ -20,6 +20,7 @@ struct Menu {
MENU_OPTION_ITEM_PASSWORD, MENU_OPTION_ITEM_PASSWORD,
MENU_OPTION_ITEM_LEVEL, MENU_OPTION_ITEM_LEVEL,
MENU_OPTION_ITEM_INFO, MENU_OPTION_ITEM_INFO,
MENU_OPTION_ITEM_DEMO,
MENU_OPTION_ITEM_QUIT MENU_OPTION_ITEM_QUIT
}; };
enum { enum {

View File

@ -30,6 +30,7 @@ struct ModPlayer_impl {
_settings.mBits = 16; _settings.mBits = 16;
_settings.mFrequency = rate; _settings.mFrequency = rate;
_settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; _settings.mResamplingMode = MODPLUG_RESAMPLE_FIR;
_settings.mLoopCount = -1;
ModPlug_SetSettings(&_settings); ModPlug_SetSettings(&_settings);
} }
@ -58,7 +59,15 @@ struct ModPlayer_impl {
_repeatIntro = false; _repeatIntro = false;
} }
const int count = ModPlug_Read(_mf, buf, len * sizeof(int16_t)); const int count = ModPlug_Read(_mf, buf, len * sizeof(int16_t));
return count > 0; // setting mLoopCount to non-zero does not trigger any looping in
// my test and ModPlug_Read returns 0.
// looking at the libmodplug-0.8.8 tarball, it seems the variable
// m_nRepeatCount is commented in sndmix.cpp. Not sure how if this
// is a known bug, we workaround it here.
if (count == 0) {
ModPlug_SeekOrder(_mf, 0);
}
return true;
} }
return false; return false;
} }
@ -570,7 +579,8 @@ void ModPlayer_impl::handleTick() {
} }
if (_currentPatternOrder == _modInfo.numPatterns) { if (_currentPatternOrder == _modInfo.numPatterns) {
debug(DBG_MOD, "ModPlayer::handleEffect() _currentPatternOrder == _modInfo.numPatterns"); debug(DBG_MOD, "ModPlayer::handleEffect() _currentPatternOrder == _modInfo.numPatterns");
_playing = false; // _playing = false;
_currentPatternOrder = 0;
} }
} }

View File

@ -193,7 +193,7 @@ set_anim:
uint8_t _dl = pge->anim_seq; uint8_t _dl = pge->anim_seq;
const uint8_t *anim_frame = anim_data + 6 + _dl * 4; const uint8_t *anim_frame = anim_data + 6 + _dl * 4;
while (_dh > _dl) { while (_dh > _dl) {
if (READ_LE_UINT16(anim_frame) != 0xFFFF) { if (_res._readUint16(anim_frame) != 0xFFFF) {
if (_pge_currentPiegeFacingDir) { if (_pge_currentPiegeFacingDir) {
pge->pos_x -= (int8_t)anim_frame[2]; pge->pos_x -= (int8_t)anim_frame[2];
} else { } else {

View File

@ -19,8 +19,8 @@ Resource::Resource(FileSystem *fs, ResourceType ver, Language lang) {
_aba = 0; _aba = 0;
_readUint16 = (_type == kResourceTypeDOS) ? READ_LE_UINT16 : READ_BE_UINT16; _readUint16 = (_type == kResourceTypeDOS) ? READ_LE_UINT16 : READ_BE_UINT16;
_readUint32 = (_type == kResourceTypeDOS) ? READ_LE_UINT32 : READ_BE_UINT32; _readUint32 = (_type == kResourceTypeDOS) ? READ_LE_UINT32 : READ_BE_UINT32;
_memBuf = (uint8_t *)malloc(320 * 224 + 1024); _scratchBuffer = (uint8_t *)malloc(320 * 224 + 1024);
if (!_memBuf) { if (!_scratchBuffer) {
error("Unable to allocate temporary memory buffer"); error("Unable to allocate temporary memory buffer");
} }
static const int kBankDataSize = 0x7000; static const int kBankDataSize = 0x7000;
@ -40,7 +40,7 @@ Resource::~Resource() {
free(_tab); free(_tab);
free(_spc); free(_spc);
free(_spr1); free(_spr1);
free(_memBuf); free(_scratchBuffer);
free(_cmd); free(_cmd);
free(_pol); free(_pol);
free(_cine_off); free(_cine_off);

View File

@ -37,6 +37,7 @@ struct LocaleData {
LI_20_LOAD_GAME, LI_20_LOAD_GAME,
LI_21_SAVE_GAME, LI_21_SAVE_GAME,
LI_22_SAVE_SLOT, LI_22_SAVE_SLOT,
LI_23_DEMO,
LI_NUM LI_NUM
}; };
@ -144,7 +145,7 @@ struct Resource {
uint8_t *_bnq; uint8_t *_bnq;
uint16_t _numObjectNodes; uint16_t _numObjectNodes;
ObjectNode *_objectNodesMap[255]; ObjectNode *_objectNodesMap[255];
uint8_t *_memBuf; uint8_t *_scratchBuffer;
SoundFx *_sfxList; SoundFx *_sfxList;
uint8_t _numSfx; uint8_t _numSfx;
uint8_t *_cmd; uint8_t *_cmd;

View File

@ -2261,7 +2261,7 @@ const uint8_t LocaleData::_stringsTableJP[] = {
0x0a, 0x61, 0x7a, 0x73, 0x20, 0x7d, 0x73, 0x6a, 0xcf, 0x92, 0x00 0x0a, 0x61, 0x7a, 0x73, 0x20, 0x7d, 0x73, 0x6a, 0xcf, 0x92, 0x00
}; };
const char *LocaleData::_textsTableFR[] = { const char *LocaleData::_textsTableFR[LocaleData::LI_NUM] = {
"CONTINUER OU ABANDONNER ?", "CONTINUER OU ABANDONNER ?",
"TEMPS", "TEMPS",
"CONTINUER", "CONTINUER",
@ -2283,10 +2283,11 @@ const char *LocaleData::_textsTableFR[] = {
"ABANDONNER", "ABANDONNER",
"CHARGER", "CHARGER",
"SAUVEGARDER", "SAUVEGARDER",
"PARTIE" "PARTIE",
"DEMO"
}; };
const char *LocaleData::_textsTableEN[] = { const char *LocaleData::_textsTableEN[LocaleData::LI_NUM] = {
"CONTINUE OR ABORT THIS GAME ?", "CONTINUE OR ABORT THIS GAME ?",
"TIME", "TIME",
"CONTINUE", "CONTINUE",
@ -2308,10 +2309,11 @@ const char *LocaleData::_textsTableEN[] = {
"ABORT GAME", "ABORT GAME",
"LOAD GAME", "LOAD GAME",
"SAVE GAME", "SAVE GAME",
"SLOT" "SLOT",
"DEMO"
}; };
const char *LocaleData::_textsTableDE[] = { const char *LocaleData::_textsTableDE[LocaleData::LI_NUM] = {
"WEITERSPIELEN ODER ABBRECHEN ?", "WEITERSPIELEN ODER ABBRECHEN ?",
"ZEIT : ", "ZEIT : ",
"WEITERSPIELEN", "WEITERSPIELEN",
@ -2333,10 +2335,11 @@ const char *LocaleData::_textsTableDE[] = {
"SPIEL ABBRECHEN", "SPIEL ABBRECHEN",
"LADEN", "LADEN",
"SPEICHERN", "SPEICHERN",
"SPIEL" "SPIEL",
"DEMO"
}; };
const char *LocaleData::_textsTableSP[] = { const char *LocaleData::_textsTableSP[LocaleData::LI_NUM] = {
"CONTINUAR O TERMINAR JUEGO ?", "CONTINUAR O TERMINAR JUEGO ?",
"TIEMPO", "TIEMPO",
"SEGUIR", "SEGUIR",
@ -2358,10 +2361,11 @@ const char *LocaleData::_textsTableSP[] = {
"PARAR JUEGO", "PARAR JUEGO",
"CARGAR DATOS", "CARGAR DATOS",
"GUARDAR DATOS", "GUARDAR DATOS",
"JUEGO" "JUEGO",
"DEMO"
}; };
const char *LocaleData::_textsTableIT[] = { const char *LocaleData::_textsTableIT[LocaleData::LI_NUM] = {
"CONTINUA O ABBANDONA GIOCO", "CONTINUA O ABBANDONA GIOCO",
"TEMPO", "TEMPO",
"CONTINUA", "CONTINUA",
@ -2383,7 +2387,8 @@ const char *LocaleData::_textsTableIT[] = {
"ESCI DAL GIOCO", "ESCI DAL GIOCO",
"CARICA IL GIOCO", "CARICA IL GIOCO",
"SALVA IL GIOCO", "SALVA IL GIOCO",
"SLOT" "SLOT",
"DEMO"
}; };
const uint8_t LocaleData::_level1TbnJP[] = { const uint8_t LocaleData::_level1TbnJP[] = {

View File

@ -611,6 +611,8 @@ void SystemStub_SDL::prepareGraphics() {
int flags = 0; int flags = 0;
if (_fullscreen) { if (_fullscreen) {
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
} else {
flags |= SDL_WINDOW_RESIZABLE;
} }
_window = SDL_CreateWindow(_caption, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, windowW, windowH, flags); _window = SDL_CreateWindow(_caption, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, windowW, windowH, flags);
SDL_Surface *icon = SDL_LoadBMP(kIconBmp); SDL_Surface *icon = SDL_LoadBMP(kIconBmp);

3
util.h
View File

@ -22,7 +22,8 @@ enum {
DBG_CUT = 1 << 9, DBG_CUT = 1 << 9,
DBG_MOD = 1 << 10, DBG_MOD = 1 << 10,
DBG_SFX = 1 << 11, DBG_SFX = 1 << 11,
DBG_FILE = 1 << 12 DBG_FILE = 1 << 12,
DBG_DEMO = 1 << 13
}; };
extern uint16_t g_debugMask; extern uint16_t g_debugMask;

View File

@ -188,7 +188,7 @@ void Video::PC_decodeLev(int level, int room) {
_res->clearBankData(); _res->clearBankData();
} }
static void PC_decodeMapHelper(int sz, const uint8_t *src, uint8_t *dst) { static void PC_decodeMapPlane(int sz, const uint8_t *src, uint8_t *dst) {
const uint8_t *end = src + sz; const uint8_t *end = src + sz;
while (src < end) { while (src < end) {
int16_t code = (int8_t)*src++; int16_t code = (int8_t)*src++;
@ -212,6 +212,7 @@ void Video::PC_decodeMap(int level, int room) {
if (off == 0) { if (off == 0) {
error("Invalid room %d", room); error("Invalid room %d", room);
} }
// int size = READ_LE_UINT16(_res->_map + room * 6 + 4);
bool packed = true; bool packed = true;
if (off < 0) { if (off < 0) {
off = -off; off = -off;
@ -226,19 +227,18 @@ void Video::PC_decodeMap(int level, int room) {
// workaround for wrong palette colors (fire) // workaround for wrong palette colors (fire)
_mapPalSlot4 = 5; _mapPalSlot4 = 5;
} }
static const int kPlaneSize = 256 * 224 / 4;
if (packed) { if (packed) {
uint8_t *vid = _frontLayer;
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
const int sz = READ_LE_UINT16(p); p += 2; const int sz = READ_LE_UINT16(p); p += 2;
PC_decodeMapHelper(sz, p, _res->_memBuf); p += sz; PC_decodeMapPlane(sz, p, _res->_scratchBuffer); p += sz;
memcpy(vid, _res->_memBuf, 256 * 56); memcpy(_frontLayer + i * kPlaneSize, _res->_scratchBuffer, kPlaneSize);
vid += 256 * 56;
} }
} else { } else {
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
for (int y = 0; y < 224; ++y) { for (int y = 0; y < 224; ++y) {
for (int x = 0; x < 64; ++x) { for (int x = 0; x < 64; ++x) {
_frontLayer[i + x * 4 + 256 * y] = p[256 * 56 * i + x + 64 * y]; _frontLayer[i + x * 4 + 256 * y] = p[kPlaneSize * i + x + 64 * y];
} }
} }
} }
@ -601,7 +601,7 @@ static void decodeLevHelper(uint8_t *dst, const uint8_t *src, int offset10, int
} }
void Video::AMIGA_decodeLev(int level, int room) { void Video::AMIGA_decodeLev(int level, int room) {
uint8_t *tmp = _res->_memBuf; uint8_t *tmp = _res->_scratchBuffer;
const int offset = READ_BE_UINT32(_res->_lev + room * 4); const int offset = READ_BE_UINT32(_res->_lev + room * 4);
if (!delphine_unpack(tmp, _res->_lev, offset)) { if (!delphine_unpack(tmp, _res->_lev, offset)) {
error("Bad CRC for level %d room %d", level, room); error("Bad CRC for level %d room %d", level, room);
@ -835,8 +835,8 @@ void Video::PC_drawChar(uint8_t c, int16_t y, int16_t x, bool forceDefaultFont)
void Video::AMIGA_drawStringChar(uint8_t *dst, int pitch, const uint8_t *src, uint8_t color, uint8_t chr) { void Video::AMIGA_drawStringChar(uint8_t *dst, int pitch, const uint8_t *src, uint8_t color, uint8_t chr) {
assert(chr >= 32); assert(chr >= 32);
AMIGA_decodeIcn(src, chr - 32, _res->_memBuf); AMIGA_decodeIcn(src, chr - 32, _res->_scratchBuffer);
src = _res->_memBuf; src = _res->_scratchBuffer;
for (int y = 0; y < 8; ++y) { for (int y = 0; y < 8; ++y) {
for (int x = 0; x < 8; ++x) { for (int x = 0; x < 8; ++x) {
if (src[x] != 0) { if (src[x] != 0) {