Import 0.3.3
This commit is contained in:
parent
5addfc699a
commit
1cd2866af7
14
Makefile
14
Makefile
|
@ -1,12 +1,12 @@
|
|||
|
||||
SDL_CFLAGS = `sdl-config --cflags`
|
||||
SDL_LIBS = `sdl-config --libs`
|
||||
MODPLUG_LIBS = -lmodplug
|
||||
# TREMOR_LIBS = -lvorbisidec -logg
|
||||
ZLIB_LIBS = -lz
|
||||
SDL_CFLAGS := `sdl2-config --cflags`
|
||||
SDL_LIBS := `sdl2-config --libs`
|
||||
|
||||
CXX := clang++
|
||||
CXXFLAGS := -Wall -MMD $(SDL_CFLAGS) -DUSE_MODPLUG -DUSE_ZLIB # -DUSE_TREMOR
|
||||
MODPLUG_LIBS := -lmodplug
|
||||
TREMOR_LIBS := -lvorbisidec -logg
|
||||
ZLIB_LIBS := -lz
|
||||
|
||||
CXXFLAGS += -Wall -MMD $(SDL_CFLAGS) -DUSE_MODPLUG -DUSE_TREMOR -DUSE_ZLIB
|
||||
|
||||
SRCS = collision.cpp cutscene.cpp file.cpp fs.cpp game.cpp graphics.cpp main.cpp menu.cpp \
|
||||
mixer.cpp mod_player.cpp ogg_player.cpp piege.cpp resource.cpp resource_aba.cpp \
|
||||
|
|
30
README.txt
30
README.txt
|
@ -1,6 +1,6 @@
|
|||
|
||||
REminiscence README
|
||||
Release version: 0.3.2
|
||||
Release version: 0.3.3
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
@ -24,30 +24,9 @@ Data Files:
|
|||
|
||||
You will need the original files of the PC (DOS or CD) or Amiga release.
|
||||
|
||||
To hear background music during polygonal cutscenes with the PC version,
|
||||
you'll need to copy the .mod files of the Amiga version :
|
||||
|
||||
mod.flashback-ascenseur
|
||||
mod.flashback-ceinturea
|
||||
mod.flashback-chute
|
||||
mod.flashback-desintegr
|
||||
mod.flashback-donneobjt
|
||||
mod.flashback-fin
|
||||
mod.flashback-fin2
|
||||
mod.flashback-game_over
|
||||
mod.flashback-holocube
|
||||
mod.flashback-introb
|
||||
mod.flashback-jungle
|
||||
mod.flashback-logo
|
||||
mod.flashback-memoire
|
||||
mod.flashback-missionca
|
||||
mod.flashback-options1
|
||||
mod.flashback-options2
|
||||
mod.flashback-reunion
|
||||
mod.flashback-taxi
|
||||
mod.flashback-teleport2
|
||||
mod.flashback-teleporta
|
||||
mod.flashback-voyage
|
||||
To have background music during polygonal cutscenes with the PC version,
|
||||
you need to copy the music/ directory of the Amiga version or use the .mod
|
||||
fileset from unexotica.
|
||||
|
||||
To hear voice during in-game dialogues, you'll need to copy the 'VOICE.VCE'
|
||||
file from the SegaCD version to the DATA directory.
|
||||
|
@ -87,7 +66,6 @@ Debug hotkeys :
|
|||
Ctrl F toggle fast mode
|
||||
Ctrl I Conrad 'infinite' life
|
||||
Ctrl B toggle display of updated dirty blocks
|
||||
Ctrl M mirror mode (right - left swapped)
|
||||
|
||||
|
||||
Credits:
|
||||
|
|
11
cutscene.cpp
11
cutscene.cpp
|
@ -33,7 +33,7 @@ void Cutscene::sync() {
|
|||
}
|
||||
|
||||
void Cutscene::copyPalette(const uint8_t *pal, uint16_t num) {
|
||||
uint8_t *dst = (uint8_t *)_palBuf;
|
||||
uint8_t *dst = _palBuf;
|
||||
if (num != 0) {
|
||||
dst += 0x20;
|
||||
}
|
||||
|
@ -1091,10 +1091,11 @@ void Cutscene::play() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (g_options.use_text_cutscenes && _res->_lang == LANG_FR) {
|
||||
for (int i = 0; _frTextsTable[i].str; ++i) {
|
||||
if (_id == _frTextsTable[i].num) {
|
||||
playText(_frTextsTable[i].str);
|
||||
if (g_options.use_text_cutscenes) {
|
||||
const Text *textsTable = (_res->_lang == LANG_FR) ? _frTextsTable : _enTextsTable;
|
||||
for (int i = 0; textsTable[i].str; ++i) {
|
||||
if (_id == textsTable[i].num) {
|
||||
playText(textsTable[i].str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ struct Cutscene {
|
|||
static const uint8_t _musicTable[];
|
||||
static const uint8_t _protectionShapeData[];
|
||||
static const Text _frTextsTable[];
|
||||
static const Text _enTextsTable[];
|
||||
|
||||
Graphics _gfx;
|
||||
Resource *_res;
|
||||
|
|
77
file.cpp
77
file.cpp
|
@ -11,6 +11,10 @@
|
|||
#ifdef USE_ZLIB
|
||||
#include "zlib.h"
|
||||
#endif
|
||||
#ifdef USE_RWOPS
|
||||
#include <SDL_filesystem.h>
|
||||
#include <SDL_rwops.h>
|
||||
#endif
|
||||
|
||||
struct File_impl {
|
||||
bool _ioErr;
|
||||
|
@ -128,6 +132,62 @@ struct GzipFile : File_impl {
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifdef USE_RWOPS
|
||||
struct AssetFile: File_impl {
|
||||
SDL_RWops *_rw;
|
||||
AssetFile() : _rw(0) {}
|
||||
bool open(const char *path, const char *mode) {
|
||||
_ioErr = false;
|
||||
_rw = SDL_RWFromFile(path, "rb");
|
||||
if (!_rw) {
|
||||
// try uppercase
|
||||
char fixedPath[MAXPATHLEN];
|
||||
{
|
||||
int i = 0;
|
||||
for (; path[i] && i < MAXPATHLEN - 1; ++i) {
|
||||
fixedPath[i] = path[i];
|
||||
if (fixedPath[i] >= 'a' && fixedPath[i] <= 'z') {
|
||||
fixedPath[i] += 'A' - 'a';
|
||||
}
|
||||
}
|
||||
fixedPath[i] = 0;
|
||||
}
|
||||
_rw = SDL_RWFromFile(fixedPath, "rb");
|
||||
}
|
||||
return _rw != 0;
|
||||
}
|
||||
void close() {
|
||||
if (_rw) {
|
||||
SDL_RWclose(_rw);
|
||||
_rw = 0;
|
||||
}
|
||||
}
|
||||
uint32_t size() {
|
||||
if (_rw) {
|
||||
return SDL_RWsize(_rw);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void seek(int32_t off) {
|
||||
if (_rw) {
|
||||
SDL_RWseek(_rw, off, RW_SEEK_SET);
|
||||
}
|
||||
}
|
||||
uint32_t read(void *ptr, uint32_t len) {
|
||||
if (_rw) {
|
||||
const int count = SDL_RWread(_rw, ptr, 1, len);
|
||||
if (count != len) {
|
||||
_ioErr = true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
uint32_t write(void *ptr, uint32_t len) {
|
||||
_ioErr = true;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
File::File()
|
||||
: _impl(0) {
|
||||
|
@ -155,6 +215,23 @@ bool File::open(const char *filename, const char *mode, FileSystem *fs) {
|
|||
free(path);
|
||||
return ret;
|
||||
}
|
||||
#ifdef USE_RWOPS
|
||||
if (mode[0] == 'r') {
|
||||
_impl = new AssetFile;
|
||||
return _impl->open(filename, mode);
|
||||
} else if (mode[0] == 'w') {
|
||||
bool ret = false;
|
||||
char *prefPath = SDL_GetPrefPath("org.cyxdown", "fb");
|
||||
if (prefPath) {
|
||||
char path[MAXPATHLEN];
|
||||
snprintf(path, sizeof(path), "%s/%s", prefPath, filename);
|
||||
_impl = new StdioFile;
|
||||
ret = _impl->open(path, mode);
|
||||
SDL_free(prefPath);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
31
fs.cpp
31
fs.cpp
|
@ -12,6 +12,9 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#ifdef USE_RWOPS
|
||||
#include <SDL_rwops.h>
|
||||
#endif
|
||||
#include "fs.h"
|
||||
#include "util.h"
|
||||
|
||||
|
@ -47,9 +50,18 @@ struct FileSystem_impl {
|
|||
debug(DBG_FILE, "Found %d files and %d directories", _filesCount, _dirsCount);
|
||||
}
|
||||
|
||||
char *findPath(const char *name) const {
|
||||
int findPathIndex(const char *name) const {
|
||||
for (int i = 0; i < _filesCount; ++i) {
|
||||
if (strcasecmp(_filesList[i].name, name) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *getPath(const char *name) const {
|
||||
const int i = findPathIndex(name);
|
||||
if (i >= 0) {
|
||||
const char *dir = _dirsList[_filesList[i].dir];
|
||||
const int len = strlen(dir) + 1 + strlen(_filesList[i].name) + 1;
|
||||
char *p = (char *)malloc(len);
|
||||
|
@ -58,7 +70,6 @@ struct FileSystem_impl {
|
|||
}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -146,13 +157,19 @@ FileSystem::~FileSystem() {
|
|||
}
|
||||
|
||||
char *FileSystem::findPath(const char *filename) const {
|
||||
return _impl->findPath(filename);
|
||||
return _impl->getPath(filename);
|
||||
}
|
||||
|
||||
bool FileSystem::exists(const char *filename) const {
|
||||
char *path = findPath(filename);
|
||||
if (path) {
|
||||
free(path);
|
||||
if (_impl->findPathIndex(filename) >= 0) {
|
||||
return true;
|
||||
}
|
||||
return path != 0;
|
||||
#ifdef USE_RWOPS
|
||||
SDL_RWops *rw = SDL_RWFromFile(filename, "rb");
|
||||
if (rw) {
|
||||
SDL_RWclose(rw);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
|
53
game.cpp
53
game.cpp
|
@ -28,7 +28,7 @@ void Game::run() {
|
|||
_randSeed = time(0);
|
||||
|
||||
if (_demoBin != -1) {
|
||||
if (_demoBin < (int)ARRAYSIZE(_demoInputs)) {
|
||||
if (_demoBin < ARRAYSIZE(_demoInputs)) {
|
||||
const char *fn = _demoInputs[_demoBin].name;
|
||||
debug(DBG_INFO, "Loading inputs from '%s'", fn);
|
||||
_res.load_DEM(fn);
|
||||
|
@ -50,7 +50,9 @@ void Game::run() {
|
|||
break;
|
||||
case kResourceTypeDOS:
|
||||
_res.load("FB_TXT", Resource::OT_FNT);
|
||||
if (g_options.use_seq_cutscenes) {
|
||||
_res._hasSeqData = _fs->exists("INTRO.SEQ");
|
||||
}
|
||||
if (_fs->exists("logosssi.cmd")) {
|
||||
_cut._patchedOffsetsTable = Cutscene::_ssiOffsetsTable;
|
||||
}
|
||||
|
@ -91,10 +93,12 @@ void Game::run() {
|
|||
if (_demoBin != -1) {
|
||||
_currentLevel = _demoInputs[_demoBin].level;
|
||||
_randSeed = 0;
|
||||
} else if (_res._isDemo) {
|
||||
// do not present title screen and menus
|
||||
} else {
|
||||
_mix.playMusic(1);
|
||||
switch (_res._type) {
|
||||
case kResourceTypeDOS:
|
||||
_mix.playMusic(1);
|
||||
_menu.handleTitleScreen();
|
||||
if (_menu._selectedOption == Menu::MENU_OPTION_ITEM_QUIT || _stub->_pi.quit) {
|
||||
_stub->_pi.quit = true;
|
||||
|
@ -148,11 +152,10 @@ void Game::displayTitleScreenAmiga() {
|
|||
_res.load_CMP_menu(FILENAME, _res._memBuf);
|
||||
static const int kW = 320;
|
||||
static const int kH = 224;
|
||||
uint8_t *buf = (uint8_t *)malloc(kW * kH);
|
||||
uint8_t *buf = (uint8_t *)calloc(kW * kH, 1);
|
||||
if (!buf) {
|
||||
error("Failed to allocate screen buffer w=%d h=%d", kW, kH);
|
||||
}
|
||||
_vid.AMIGA_decodeCmp(_res._memBuf + 6, buf);
|
||||
static const int kAmigaColors[] = {
|
||||
0x000, 0x123, 0x012, 0x134, 0x433, 0x453, 0x046, 0x245,
|
||||
0x751, 0x455, 0x665, 0x268, 0x961, 0x478, 0x677, 0x786,
|
||||
|
@ -166,7 +169,14 @@ void Game::displayTitleScreenAmiga() {
|
|||
_stub->setScreenSize(kW, kH);
|
||||
_stub->copyRect(0, 0, kW, kH, buf, kW);
|
||||
_stub->updateScreen(0);
|
||||
_vid.AMIGA_decodeCmp(_res._memBuf + 6, buf);
|
||||
free(buf);
|
||||
for (int h = 0; h < kH / 2; h += 2) {
|
||||
const int y = kH / 2 - h;
|
||||
_stub->copyRect(0, y, kW, h * 2, buf, kW);
|
||||
_stub->updateScreen(0);
|
||||
_stub->sleep(30);
|
||||
}
|
||||
while (1) {
|
||||
_stub->processEvents();
|
||||
if (_stub->_pi.quit) {
|
||||
|
@ -243,6 +253,9 @@ void Game::mainLoop() {
|
|||
}
|
||||
}
|
||||
if (oldLevel != _currentLevel) {
|
||||
if (_res._isDemo) {
|
||||
_currentLevel = oldLevel;
|
||||
}
|
||||
changeLevel();
|
||||
_pge_opTempVar1 = 0;
|
||||
return;
|
||||
|
@ -598,7 +611,9 @@ bool Game::handleContinueAbort() {
|
|||
bool Game::handleProtectionScreen() {
|
||||
bool valid = true;
|
||||
_cut.prepare();
|
||||
_cut.copyPalette(_protectionPal, 0);
|
||||
const int palOffset = _res.isAmiga() ? 32 : 0;
|
||||
_cut.copyPalette(_protectionPal + palOffset, 0);
|
||||
|
||||
_cut.updatePalette();
|
||||
_cut._gfx.setClippingRect(64, 48, 128, 128);
|
||||
|
||||
|
@ -622,10 +637,10 @@ bool Game::handleProtectionScreen() {
|
|||
do {
|
||||
codeText[len] = '\0';
|
||||
memcpy(_vid._frontLayer, _vid._tempLayer, _vid._layerSize);
|
||||
_menu.drawString("PROTECTION", 2, 11, 5);
|
||||
_vid.drawString("PROTECTION", 11 * 8, 2 * 8, _menu._charVar2);
|
||||
char buf[20];
|
||||
snprintf(buf, sizeof(buf), "CODE %d : %s", codeNum + 1, codeText);
|
||||
_menu.drawString(buf, 23, 8, 5);
|
||||
_vid.drawString(buf, 8 * 8, 23 * 8, _menu._charVar2);
|
||||
_vid.updateScreen();
|
||||
_stub->sleep(50);
|
||||
_stub->processEvents();
|
||||
|
@ -679,7 +694,11 @@ void Game::printLevelCode() {
|
|||
--_printLevelCodeCounter;
|
||||
if (_printLevelCodeCounter != 0) {
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "CODE: %s", _menu._passwords[_currentLevel][_skillLevel]);
|
||||
const char *code = Menu::_passwords[_currentLevel][_skillLevel];
|
||||
if (_res.isAmiga() && _res._lang == LANG_FR) {
|
||||
code = Menu::_passwordsFrAmiga[_skillLevel * 7 + _currentLevel];
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "CODE: %s", code);
|
||||
_vid.drawString(buf, (_vid._w - strlen(buf) * 8) / 2, 16, 0xE7);
|
||||
}
|
||||
}
|
||||
|
@ -1506,16 +1525,30 @@ void Game::handleInventory() {
|
|||
int icon_h = 5;
|
||||
int icon_y = 140;
|
||||
int icon_num = 31;
|
||||
static const int icon_spr_w = 16;
|
||||
static const int icon_spr_h = 16;
|
||||
do {
|
||||
int icon_x = 56;
|
||||
int icon_w = 9;
|
||||
do {
|
||||
drawIcon(icon_num, icon_x, icon_y, 0xF);
|
||||
++icon_num;
|
||||
icon_x += 16;
|
||||
icon_x += icon_spr_w;
|
||||
} while (--icon_w);
|
||||
icon_y += 16;
|
||||
icon_y += icon_spr_h;
|
||||
} while (--icon_h);
|
||||
if (_res._type == kResourceTypeAmiga) {
|
||||
// draw outline rectangle
|
||||
static const uint8_t outline_color = 0xE7;
|
||||
uint8_t *p = _vid._frontLayer + 140 * Video::GAMESCREEN_W + 56;
|
||||
memset(p + 1, outline_color, 9 * icon_spr_w - 2);
|
||||
p += Video::GAMESCREEN_W;
|
||||
for (int y = 1; y < 5 * icon_spr_h - 1; ++y) {
|
||||
p[0] = p[9 * icon_spr_w - 1] = outline_color;
|
||||
p += Video::GAMESCREEN_W;
|
||||
}
|
||||
memset(p + 1, outline_color, 9 * icon_spr_w - 2);
|
||||
}
|
||||
|
||||
if (!display_score) {
|
||||
int icon_x_pos = 72;
|
||||
|
|
23
intern.h
23
intern.h
|
@ -7,24 +7,20 @@
|
|||
#ifndef INTERN_H__
|
||||
#define INTERN_H__
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef ABS
|
||||
#undef ABS
|
||||
#define ABS(x) ((x)<0?-(x):(x))
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#undef MAX
|
||||
#define MAX(x,y) ((x)>(y)?(x):(y))
|
||||
#endif
|
||||
#ifndef MIN
|
||||
#undef MIN
|
||||
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||
#endif
|
||||
#ifndef ARRAYSIZE
|
||||
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
|
||||
#endif
|
||||
#undef ARRAYSIZE
|
||||
#define ARRAYSIZE(a) (int)(sizeof(a)/sizeof(a[0]))
|
||||
|
||||
inline uint16_t READ_BE_UINT16(const void *ptr) {
|
||||
const uint8_t *b = (const uint8_t *)ptr;
|
||||
|
@ -93,6 +89,7 @@ struct Options {
|
|||
bool fade_out_palette;
|
||||
bool use_tiledata;
|
||||
bool use_text_cutscenes;
|
||||
bool use_seq_cutscenes;
|
||||
};
|
||||
|
||||
struct Color {
|
||||
|
|
8
main.cpp
8
main.cpp
|
@ -4,6 +4,7 @@
|
|||
* Copyright (C) 2005-2015 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include <SDL.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -19,7 +20,7 @@ static const char *USAGE =
|
|||
"Usage: %s [OPTIONS]...\n"
|
||||
" --datapath=PATH Path to data files (default 'DATA')\n"
|
||||
" --savepath=PATH Path to save files (default '.')\n"
|
||||
" --levelnum=NUM Level to start from (default '0')\n"
|
||||
" --levelnum=NUM Start to level, bypass introduction\n"
|
||||
" --fullscreen Fullscreen display\n"
|
||||
" --scaler=INDEX Graphics scaler\n"
|
||||
" --language=LANG Language (fr,en,de,sp,it)\n"
|
||||
|
@ -36,7 +37,7 @@ static int detectVersion(FileSystem *fs) {
|
|||
{ "LEVEL1.MAP", kResourceTypeDOS, "DOS" },
|
||||
{ "LEVEL1.LEV", kResourceTypeAmiga, "Amiga" },
|
||||
{ "DEMO.LEV", kResourceTypeAmiga, "Amiga (Demo)" },
|
||||
{ 0, -1 }
|
||||
{ 0, -1, 0 }
|
||||
};
|
||||
for (int i = 0; table[i].filename; ++i) {
|
||||
File f;
|
||||
|
@ -82,6 +83,7 @@ static void initOptions() {
|
|||
g_options.enable_password_menu = false;
|
||||
g_options.fade_out_palette = true;
|
||||
g_options.use_text_cutscenes = false;
|
||||
g_options.use_seq_cutscenes = true;
|
||||
// read configuration file
|
||||
struct {
|
||||
const char *name;
|
||||
|
@ -93,6 +95,7 @@ static void initOptions() {
|
|||
{ "fade_out_palette", &g_options.fade_out_palette },
|
||||
{ "use_tiledata", &g_options.use_tiledata },
|
||||
{ "use_text_cutscenes", &g_options.use_text_cutscenes },
|
||||
{ "use_seq_cutscenes", &g_options.use_seq_cutscenes },
|
||||
{ 0, 0 }
|
||||
};
|
||||
static const char *filename = "rs.cfg";
|
||||
|
@ -126,7 +129,6 @@ static void initOptions() {
|
|||
|
||||
static const int DEFAULT_SCALER = SCALER_SCALE_3X;
|
||||
|
||||
#undef main
|
||||
int main(int argc, char *argv[]) {
|
||||
const char *dataPath = "DATA";
|
||||
const char *savePath = ".";
|
||||
|
|
1
menu.h
1
menu.h
|
@ -40,6 +40,7 @@ struct Menu {
|
|||
};
|
||||
|
||||
static const char *_passwords[8][3];
|
||||
static const char *_passwordsFrAmiga[];
|
||||
|
||||
Resource *_res;
|
||||
SystemStub *_stub;
|
||||
|
|
|
@ -488,9 +488,6 @@ void Game::pge_addToCurrentRoomList(LivePGE *pge, uint8_t room) {
|
|||
void Game::pge_getInput() {
|
||||
inp_update();
|
||||
_inp_lastKeysHit = _stub->_pi.dirMask;
|
||||
if (_stub->_pi.mirrorMode && (_inp_lastKeysHit & 0xC)) {
|
||||
_inp_lastKeysHit ^= 0xC; // invert left/right
|
||||
}
|
||||
if ((_inp_lastKeysHit & 0xC) && (_inp_lastKeysHit & 0x3)) {
|
||||
const uint8_t mask = (_inp_lastKeysHit & 0xF0) | (_inp_lastKeysHitLeftRight & 0xF);
|
||||
_pge_inpKeysMask = mask;
|
||||
|
|
|
@ -949,6 +949,7 @@ void Resource::load_PGE(File *f) {
|
|||
_pgeNum = f->readUint16LE();
|
||||
memset(_pgeInit, 0, sizeof(_pgeInit));
|
||||
debug(DBG_RES, "_pgeNum=%d", _pgeNum);
|
||||
assert(_pgeNum <= ARRAYSIZE(_pgeInit));
|
||||
for (uint16_t i = 0; i < _pgeNum; ++i) {
|
||||
InitPGE *pge = &_pgeInit[i];
|
||||
pge->type = f->readUint16LE();
|
||||
|
@ -979,6 +980,7 @@ void Resource::decodePGE(const uint8_t *p, int size) {
|
|||
_pgeNum = _readUint16(p); p += 2;
|
||||
memset(_pgeInit, 0, sizeof(_pgeInit));
|
||||
debug(DBG_RES, "len=%d _pgeNum=%d", size, _pgeNum);
|
||||
assert(_pgeNum <= ARRAYSIZE(_pgeInit));
|
||||
for (uint16_t i = 0; i < _pgeNum; ++i) {
|
||||
InitPGE *pge = &_pgeInit[i];
|
||||
pge->type = _readUint16(p); p += 2;
|
||||
|
|
5
rs.cfg
5
rs.cfg
|
@ -13,5 +13,8 @@ fade_out_palette=true
|
|||
# use .BNQ & .LEV datafiles (tile based rendering) for backgrounds (instead of .MAP)
|
||||
use_tiledata=false
|
||||
|
||||
# display text instead of playing the polygon cutscenes (french only)
|
||||
# display text instead of playing the polygon cutscenes
|
||||
use_text_cutscenes=false
|
||||
|
||||
# enable playback of .SEQ cutscenes (use polygonal if false)
|
||||
use_seq_cutscenes=true
|
||||
|
|
2
scaler.h
2
scaler.h
|
@ -19,7 +19,7 @@ enum {
|
|||
SCALER_SCALE_3X,
|
||||
SCALER_POINT_4X,
|
||||
SCALER_SCALE_4X,
|
||||
NUM_SCALERS = 7
|
||||
NUM_SCALERS
|
||||
};
|
||||
|
||||
struct Scaler {
|
||||
|
|
|
@ -836,6 +836,29 @@ const Cutscene::Text Cutscene::_frTextsTable[] = {
|
|||
{ -1, 0 }
|
||||
};
|
||||
|
||||
const Cutscene::Text Cutscene::_enTextsTable[] = {
|
||||
{ 1, "YOU PICK UP THE HOLOCUBE" },
|
||||
{ 2, "YOU PICK UP THE KEY" },
|
||||
{ 3, "YOU PICK UP THE GUN" },
|
||||
{ 5, "YOUR SHIELD IS RECHARGED" },
|
||||
{ 10, "YOU PICK UP THE CREDIT CARD" },
|
||||
{ 14, "THE CARTRIDGE IS RECHARGED" },
|
||||
{ 15, "YOU PICK UP THE CARTRIDGE" },
|
||||
{ 16, "YOU PICK UP THE TELEPORTER" },
|
||||
{ 18, "YOU PICK UP THE I.D. CARD" },
|
||||
{ 21, "YOU GIVE HIM THE TELEPORTER" },
|
||||
{ 32, "THE RECEPTIONIST GIVES YOU||A PACKAGE" },
|
||||
{ 33, "YOU GIVE THE PARCEL" },
|
||||
{ 34, "THE GOVERNOR GIVES YOU||A WORKING PERMIT" },
|
||||
{ 35, "THE FORGER GIVES YOU||A FAKE I.D. CARD" },
|
||||
{ 36, "YOU PICK UP THE FUSE" },
|
||||
{ 43, "YOU GIVE HIM||YOUR PAPERS" },
|
||||
{ 44, "YOU GIVE HIM MONEY" },
|
||||
{ 49, "HE GIVES YOU||AN ANTI-G BELT" },
|
||||
{ 60, "YOU PICK UP THE TELE RECEPTER" },
|
||||
{ -1, 0}
|
||||
};
|
||||
|
||||
const Demo Game::_demoInputs[] = {
|
||||
{ "demo1.bin", 0, 0x33, 0x60, 0x46 },
|
||||
{ "demo51.bin", 5, 0x00, 0x60, 0xD6 },
|
||||
|
@ -2700,8 +2723,12 @@ const uint8_t Game::_protectionCodeData[] = {
|
|||
};
|
||||
|
||||
const uint8_t Game::_protectionPal[] = {
|
||||
// DOS
|
||||
0x00, 0x00, 0x00, 0x42, 0x00, 0x63, 0x00, 0x00, 0x0F, 0xFF, 0x0F, 0xF0, 0x07, 0x77, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
// Amiga
|
||||
0x00, 0x00, 0x03, 0x04, 0x06, 0x05, 0x00, 0x00, 0x04, 0x44, 0x05, 0x55, 0x06, 0x66, 0x07, 0x77,
|
||||
0x08, 0x88, 0x09, 0x99, 0x0A, 0xAA, 0x0B, 0xBB, 0x0C, 0xCC, 0x0D, 0xDD, 0x0E, 0xEE, 0x0F, 0xFF
|
||||
};
|
||||
|
||||
const char *Menu::_passwords[8][3] = {
|
||||
|
@ -2715,6 +2742,12 @@ const char *Menu::_passwords[8][3] = {
|
|||
{ "BELUGA", "BELUGA", "BELUGA" }
|
||||
};
|
||||
|
||||
const char *Menu::_passwordsFrAmiga[] = {
|
||||
"BACK", "LOUP", "CINE", "GOOD", "SPIZ", "BIOS", "HALL", // easy
|
||||
"PLAY", "TOIT", "ZAPP", "LYNX", "SCSI", "GARY", "PONT", // normal
|
||||
"CLOP", "CARA", "CALE", "FONT", "HASH", "FIBO", "TIPS", // hard
|
||||
};
|
||||
|
||||
const uint8_t Video::_conradPal1[] = {
|
||||
0x00, 0x00, 0xCC, 0x0C, 0x8F, 0x08, 0x7E, 0x07, 0x6C, 0x06, 0x5B, 0x05, 0x4A, 0x04, 0x63, 0x09,
|
||||
0x52, 0x07, 0x41, 0x06, 0x30, 0x06, 0x76, 0x0C, 0x14, 0x09, 0x25, 0x0B, 0x88, 0x08, 0xFF, 0x0F
|
||||
|
|
|
@ -35,8 +35,6 @@ struct PlayerInput {
|
|||
bool load;
|
||||
int stateSlot;
|
||||
|
||||
bool mirrorMode;
|
||||
|
||||
uint8_t dbgMask;
|
||||
bool quit;
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@ struct SystemStub_SDL : SystemStub {
|
|||
SDL_Window *_window;
|
||||
SDL_Renderer *_renderer;
|
||||
SDL_Texture *_texture;
|
||||
int _texW, _texH;
|
||||
SDL_GameController *_controller;
|
||||
#else
|
||||
SDL_Surface *_surface;
|
||||
|
@ -125,10 +126,7 @@ void SystemStub_SDL::setScreenSize(int w, int h) {
|
|||
if (_screenW == w && _screenH == h) {
|
||||
return;
|
||||
}
|
||||
free(_screenBuffer);
|
||||
_screenBuffer = 0;
|
||||
free(_fadeScreenBuffer);
|
||||
_fadeScreenBuffer = 0;
|
||||
cleanupGraphics();
|
||||
// allocate some extra bytes for the scaling routines
|
||||
const int screenBufferSize = (w + 2) * (h + 2) * sizeof(uint16_t);
|
||||
_screenBuffer = (uint16_t *)calloc(1, screenBufferSize);
|
||||
|
@ -190,7 +188,7 @@ void SystemStub_SDL::copyRect(int x, int y, int w, int h, const uint8_t *buf, in
|
|||
}
|
||||
SDL_Rect *br = &_blitRects[_numBlitRects];
|
||||
|
||||
br->x = _pi.mirrorMode ? _screenW - (x + w) : x;
|
||||
br->x = x;
|
||||
br->y = y;
|
||||
br->w = w;
|
||||
br->h = h;
|
||||
|
@ -199,15 +197,6 @@ void SystemStub_SDL::copyRect(int x, int y, int w, int h, const uint8_t *buf, in
|
|||
uint16_t *p = _screenBuffer + (br->y + 1) * _screenW + (br->x + 1);
|
||||
buf += y * pitch + x;
|
||||
|
||||
if (_pi.mirrorMode) {
|
||||
while (h--) {
|
||||
for (int i = 0; i < w; ++i) {
|
||||
p[i] = _pal[buf[w - 1 - i]];
|
||||
}
|
||||
p += _screenW;
|
||||
buf += pitch;
|
||||
}
|
||||
} else {
|
||||
while (h--) {
|
||||
for (int i = 0; i < w; ++i) {
|
||||
p[i] = _pal[buf[i]];
|
||||
|
@ -215,7 +204,6 @@ void SystemStub_SDL::copyRect(int x, int y, int w, int h, const uint8_t *buf, in
|
|||
p += _screenW;
|
||||
buf += pitch;
|
||||
}
|
||||
}
|
||||
if (_pi.dbgMask & PlayerInput::DF_DBLOCKS) {
|
||||
drawRect(br, 0xE7, _screenBuffer + _screenW + 1, _screenW * 2);
|
||||
}
|
||||
|
@ -244,7 +232,16 @@ static uint16_t blendPixel16(uint16_t colorSrc, uint16_t colorDst, uint32_t mask
|
|||
|
||||
void SystemStub_SDL::updateScreen(int shakeOffset) {
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||
if (_texW != _screenW || _texH != _screenH) {
|
||||
void *dst = 0;
|
||||
int pitch = 0;
|
||||
if (SDL_LockTexture(_texture, 0, &dst, &pitch) == 0) {
|
||||
(*_scalers[_scaler].proc)((uint16_t *)dst, pitch, _screenBuffer + _screenW + 1, _screenW, _screenW, _screenH);
|
||||
SDL_UnlockTexture(_texture);
|
||||
}
|
||||
} else {
|
||||
SDL_UpdateTexture(_texture, 0, _screenBuffer + _screenW + 1, _screenW * sizeof(uint16_t));
|
||||
}
|
||||
SDL_RenderClear(_renderer);
|
||||
if (_fadeOnUpdateScreen) {
|
||||
SDL_SetRenderDrawBlendMode(_renderer, SDL_BLENDMODE_BLEND);
|
||||
|
@ -582,9 +579,6 @@ void SystemStub_SDL::processEvent(const SDL_Event &ev, bool &paused) {
|
|||
_pi.dbgMask ^= PlayerInput::DF_DBLOCKS;
|
||||
} else if (ev.key.keysym.sym == SDLK_i) {
|
||||
_pi.dbgMask ^= PlayerInput::DF_SETLIFE;
|
||||
} else if (ev.key.keysym.sym == SDLK_m) {
|
||||
_pi.mirrorMode = !_pi.mirrorMode;
|
||||
flipGraphics();
|
||||
} else if (ev.key.keysym.sym == SDLK_s) {
|
||||
_pi.save = true;
|
||||
} else if (ev.key.keysym.sym == SDLK_l) {
|
||||
|
@ -690,9 +684,13 @@ void SystemStub_SDL::prepareGraphics() {
|
|||
case SCALER_SCALE_3X:
|
||||
case SCALER_SCALE_4X:
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
|
||||
_texW = _screenW * _scalers[_scaler].factor;
|
||||
_texH = _screenH * _scalers[_scaler].factor;
|
||||
break;
|
||||
default:
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); // nearest pixel sampling
|
||||
_texW = _screenW;
|
||||
_texH = _screenH;
|
||||
break;
|
||||
}
|
||||
const int windowW = _screenW * _scalers[_scaler].factor;
|
||||
|
@ -705,7 +703,7 @@ void SystemStub_SDL::prepareGraphics() {
|
|||
_renderer = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED);
|
||||
SDL_RenderSetLogicalSize(_renderer, windowW, windowH);
|
||||
static const uint32_t kPixelFormat = SDL_PIXELFORMAT_RGB565;
|
||||
_texture = SDL_CreateTexture(_renderer, kPixelFormat, SDL_TEXTUREACCESS_STREAMING, _screenW, _screenH);
|
||||
_texture = SDL_CreateTexture(_renderer, kPixelFormat, SDL_TEXTUREACCESS_STREAMING, _texW, _texH);
|
||||
_fmt = SDL_AllocFormat(kPixelFormat);
|
||||
#else
|
||||
SDL_WM_SetCaption(_caption, NULL);
|
||||
|
|
17
util.cpp
17
util.cpp
|
@ -8,7 +8,11 @@
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <cstdarg>
|
||||
#ifdef __ANDROID__
|
||||
#define LOG_TAG "FbJni"
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include "util.h"
|
||||
|
||||
|
||||
|
@ -21,8 +25,11 @@ void debug(uint16_t cm, const char *msg, ...) {
|
|||
va_start(va, msg);
|
||||
vsprintf(buf, msg, va);
|
||||
va_end(va);
|
||||
printf("%s\n", buf);
|
||||
fprintf(stdout, "%s\n", buf);
|
||||
fflush(stdout);
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "%s", buf);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +42,9 @@ void error(const char *msg, ...) {
|
|||
fprintf(stderr, "ERROR: %s!\n", buf);
|
||||
#ifdef _WIN32
|
||||
MessageBox(0, buf, g_caption, MB_ICONERROR);
|
||||
#endif
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "%s", buf);
|
||||
#endif
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -46,5 +56,8 @@ void warning(const char *msg, ...) {
|
|||
vsnprintf(buf, sizeof(buf), msg, va);
|
||||
va_end(va);
|
||||
fprintf(stderr, "WARNING: %s!\n", buf);
|
||||
#ifdef __ANDROID__
|
||||
__android_log_print(ANDROID_LOG_WARN, LOG_TAG, "%s", buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
20
video.cpp
20
video.cpp
|
@ -558,8 +558,8 @@ static void decodeLevHelper(uint8_t *dst, const uint8_t *src, int offset10, int
|
|||
const bool yflip = (d3 & (1 << 12)) != 0;
|
||||
const bool xflip = (d3 & (1 << 11)) != 0;
|
||||
int mask = 0;
|
||||
if ((d3 < (1 << 15)) == 0) {
|
||||
mask = 0x80;
|
||||
if ((d3 & 0x8000) != 0) {
|
||||
mask = 0x80 + ((d3 >> 6) & 0x10);
|
||||
}
|
||||
if (isPC) {
|
||||
PC_drawTile(dst + y * 256 + x, a2, mask, xflip, yflip, -1);
|
||||
|
@ -586,8 +586,8 @@ static void decodeLevHelper(uint8_t *dst, const uint8_t *src, int offset10, int
|
|||
int mask = 0;
|
||||
if ((d3 & 0x6000) != 0 && sgdBuf) {
|
||||
mask = 0x10;
|
||||
} else if ((d3 < (1 << 15)) == 0) {
|
||||
mask = 0x80;
|
||||
} else if ((d3 & 0x8000) != 0) {
|
||||
mask = 0x80 + ((d3 >> 6) & 0x10);
|
||||
}
|
||||
if (isPC) {
|
||||
PC_drawTile(dst + y * 256 + x, a2, mask, xflip, yflip, 0);
|
||||
|
@ -663,13 +663,14 @@ void Video::AMIGA_decodeLev(int level, int room) {
|
|||
// background
|
||||
setPaletteSlotBE(0x0, _mapPalSlot1);
|
||||
// objects
|
||||
setPaletteSlotBE(0x1, (level == 0 || level == 1) ? _mapPalSlot3 : _mapPalSlot2);
|
||||
setPaletteSlotBE(0x1, (level == 0) ? _mapPalSlot3 : _mapPalSlot2);
|
||||
setPaletteSlotBE(0x2, _mapPalSlot3);
|
||||
setPaletteSlotBE(0x3, _mapPalSlot3);
|
||||
// conrad
|
||||
setPaletteSlotBE(0x4, _mapPalSlot3);
|
||||
// foreground
|
||||
setPaletteSlotBE(0x8, _mapPalSlot1);
|
||||
setPaletteSlotBE(0x9, (level == 0) ? _mapPalSlot1 : _mapPalSlot3);
|
||||
// inventory
|
||||
setPaletteSlotBE(0xA, _mapPalSlot3);
|
||||
}
|
||||
|
@ -803,11 +804,8 @@ void Video::PC_drawChar(uint8_t c, int16_t y, int16_t x) {
|
|||
const uint8_t *src = _res->_fnt + (c - 32) * 32;
|
||||
uint8_t *dst = _frontLayer + x + 256 * y;
|
||||
for (int h = 0; h < 8; ++h) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
uint8_t c1 = (*src & 0xF0) >> 4;
|
||||
uint8_t c2 = (*src & 0x0F) >> 0;
|
||||
++src;
|
||||
|
||||
for (int i = 0; i < 4; ++i, ++src) {
|
||||
const uint8_t c1 = *src >> 4;
|
||||
if (c1 != 0) {
|
||||
if (c1 != 2) {
|
||||
*dst = _charFrontColor;
|
||||
|
@ -818,7 +816,7 @@ void Video::PC_drawChar(uint8_t c, int16_t y, int16_t x) {
|
|||
*dst = _charTransparentColor;
|
||||
}
|
||||
++dst;
|
||||
|
||||
const uint8_t c2 = *src & 15;
|
||||
if (c2 != 0) {
|
||||
if (c2 != 2) {
|
||||
*dst = _charFrontColor;
|
||||
|
|
Loading…
Reference in New Issue