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_CFLAGS := `sdl2-config --cflags`
|
||||||
SDL_LIBS = `sdl-config --libs`
|
SDL_LIBS := `sdl2-config --libs`
|
||||||
MODPLUG_LIBS = -lmodplug
|
|
||||||
# TREMOR_LIBS = -lvorbisidec -logg
|
|
||||||
ZLIB_LIBS = -lz
|
|
||||||
|
|
||||||
CXX := clang++
|
MODPLUG_LIBS := -lmodplug
|
||||||
CXXFLAGS := -Wall -MMD $(SDL_CFLAGS) -DUSE_MODPLUG -DUSE_ZLIB # -DUSE_TREMOR
|
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 \
|
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 \
|
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
|
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.
|
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,
|
To have background music during polygonal cutscenes with the PC version,
|
||||||
you'll need to copy the .mod files of the Amiga version :
|
you need to copy the music/ directory of the Amiga version or use the .mod
|
||||||
|
fileset from unexotica.
|
||||||
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 hear voice during in-game dialogues, you'll need to copy the 'VOICE.VCE'
|
To hear voice during in-game dialogues, you'll need to copy the 'VOICE.VCE'
|
||||||
file from the SegaCD version to the DATA directory.
|
file from the SegaCD version to the DATA directory.
|
||||||
|
@ -87,7 +66,6 @@ Debug hotkeys :
|
||||||
Ctrl F toggle fast mode
|
Ctrl F toggle fast mode
|
||||||
Ctrl I Conrad 'infinite' life
|
Ctrl I Conrad 'infinite' life
|
||||||
Ctrl B toggle display of updated dirty blocks
|
Ctrl B toggle display of updated dirty blocks
|
||||||
Ctrl M mirror mode (right - left swapped)
|
|
||||||
|
|
||||||
|
|
||||||
Credits:
|
Credits:
|
||||||
|
|
11
cutscene.cpp
11
cutscene.cpp
|
@ -33,7 +33,7 @@ void Cutscene::sync() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cutscene::copyPalette(const uint8_t *pal, uint16_t num) {
|
void Cutscene::copyPalette(const uint8_t *pal, uint16_t num) {
|
||||||
uint8_t *dst = (uint8_t *)_palBuf;
|
uint8_t *dst = _palBuf;
|
||||||
if (num != 0) {
|
if (num != 0) {
|
||||||
dst += 0x20;
|
dst += 0x20;
|
||||||
}
|
}
|
||||||
|
@ -1091,10 +1091,11 @@ void Cutscene::play() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (g_options.use_text_cutscenes && _res->_lang == LANG_FR) {
|
if (g_options.use_text_cutscenes) {
|
||||||
for (int i = 0; _frTextsTable[i].str; ++i) {
|
const Text *textsTable = (_res->_lang == LANG_FR) ? _frTextsTable : _enTextsTable;
|
||||||
if (_id == _frTextsTable[i].num) {
|
for (int i = 0; textsTable[i].str; ++i) {
|
||||||
playText(_frTextsTable[i].str);
|
if (_id == textsTable[i].num) {
|
||||||
|
playText(textsTable[i].str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct Cutscene {
|
||||||
static const uint8_t _musicTable[];
|
static const uint8_t _musicTable[];
|
||||||
static const uint8_t _protectionShapeData[];
|
static const uint8_t _protectionShapeData[];
|
||||||
static const Text _frTextsTable[];
|
static const Text _frTextsTable[];
|
||||||
|
static const Text _enTextsTable[];
|
||||||
|
|
||||||
Graphics _gfx;
|
Graphics _gfx;
|
||||||
Resource *_res;
|
Resource *_res;
|
||||||
|
|
77
file.cpp
77
file.cpp
|
@ -11,6 +11,10 @@
|
||||||
#ifdef USE_ZLIB
|
#ifdef USE_ZLIB
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_RWOPS
|
||||||
|
#include <SDL_filesystem.h>
|
||||||
|
#include <SDL_rwops.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
struct File_impl {
|
struct File_impl {
|
||||||
bool _ioErr;
|
bool _ioErr;
|
||||||
|
@ -128,6 +132,62 @@ struct GzipFile : File_impl {
|
||||||
};
|
};
|
||||||
#endif
|
#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()
|
File::File()
|
||||||
: _impl(0) {
|
: _impl(0) {
|
||||||
|
@ -155,6 +215,23 @@ bool File::open(const char *filename, const char *mode, FileSystem *fs) {
|
||||||
free(path);
|
free(path);
|
||||||
return ret;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
31
fs.cpp
31
fs.cpp
|
@ -12,6 +12,9 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_RWOPS
|
||||||
|
#include <SDL_rwops.h>
|
||||||
|
#endif
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -47,9 +50,18 @@ struct FileSystem_impl {
|
||||||
debug(DBG_FILE, "Found %d files and %d directories", _filesCount, _dirsCount);
|
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) {
|
for (int i = 0; i < _filesCount; ++i) {
|
||||||
if (strcasecmp(_filesList[i].name, name) == 0) {
|
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 char *dir = _dirsList[_filesList[i].dir];
|
||||||
const int len = strlen(dir) + 1 + strlen(_filesList[i].name) + 1;
|
const int len = strlen(dir) + 1 + strlen(_filesList[i].name) + 1;
|
||||||
char *p = (char *)malloc(len);
|
char *p = (char *)malloc(len);
|
||||||
|
@ -58,7 +70,6 @@ struct FileSystem_impl {
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,13 +157,19 @@ FileSystem::~FileSystem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
char *FileSystem::findPath(const char *filename) const {
|
char *FileSystem::findPath(const char *filename) const {
|
||||||
return _impl->findPath(filename);
|
return _impl->getPath(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSystem::exists(const char *filename) const {
|
bool FileSystem::exists(const char *filename) const {
|
||||||
char *path = findPath(filename);
|
if (_impl->findPathIndex(filename) >= 0) {
|
||||||
if (path) {
|
return true;
|
||||||
free(path);
|
|
||||||
}
|
}
|
||||||
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);
|
_randSeed = time(0);
|
||||||
|
|
||||||
if (_demoBin != -1) {
|
if (_demoBin != -1) {
|
||||||
if (_demoBin < (int)ARRAYSIZE(_demoInputs)) {
|
if (_demoBin < ARRAYSIZE(_demoInputs)) {
|
||||||
const char *fn = _demoInputs[_demoBin].name;
|
const char *fn = _demoInputs[_demoBin].name;
|
||||||
debug(DBG_INFO, "Loading inputs from '%s'", fn);
|
debug(DBG_INFO, "Loading inputs from '%s'", fn);
|
||||||
_res.load_DEM(fn);
|
_res.load_DEM(fn);
|
||||||
|
@ -50,7 +50,9 @@ void Game::run() {
|
||||||
break;
|
break;
|
||||||
case kResourceTypeDOS:
|
case kResourceTypeDOS:
|
||||||
_res.load("FB_TXT", Resource::OT_FNT);
|
_res.load("FB_TXT", Resource::OT_FNT);
|
||||||
|
if (g_options.use_seq_cutscenes) {
|
||||||
_res._hasSeqData = _fs->exists("INTRO.SEQ");
|
_res._hasSeqData = _fs->exists("INTRO.SEQ");
|
||||||
|
}
|
||||||
if (_fs->exists("logosssi.cmd")) {
|
if (_fs->exists("logosssi.cmd")) {
|
||||||
_cut._patchedOffsetsTable = Cutscene::_ssiOffsetsTable;
|
_cut._patchedOffsetsTable = Cutscene::_ssiOffsetsTable;
|
||||||
}
|
}
|
||||||
|
@ -91,10 +93,12 @@ void Game::run() {
|
||||||
if (_demoBin != -1) {
|
if (_demoBin != -1) {
|
||||||
_currentLevel = _demoInputs[_demoBin].level;
|
_currentLevel = _demoInputs[_demoBin].level;
|
||||||
_randSeed = 0;
|
_randSeed = 0;
|
||||||
|
} else if (_res._isDemo) {
|
||||||
|
// do not present title screen and menus
|
||||||
} else {
|
} else {
|
||||||
|
_mix.playMusic(1);
|
||||||
switch (_res._type) {
|
switch (_res._type) {
|
||||||
case kResourceTypeDOS:
|
case kResourceTypeDOS:
|
||||||
_mix.playMusic(1);
|
|
||||||
_menu.handleTitleScreen();
|
_menu.handleTitleScreen();
|
||||||
if (_menu._selectedOption == Menu::MENU_OPTION_ITEM_QUIT || _stub->_pi.quit) {
|
if (_menu._selectedOption == Menu::MENU_OPTION_ITEM_QUIT || _stub->_pi.quit) {
|
||||||
_stub->_pi.quit = true;
|
_stub->_pi.quit = true;
|
||||||
|
@ -148,11 +152,10 @@ void Game::displayTitleScreenAmiga() {
|
||||||
_res.load_CMP_menu(FILENAME, _res._memBuf);
|
_res.load_CMP_menu(FILENAME, _res._memBuf);
|
||||||
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 *)malloc(kW * kH);
|
uint8_t *buf = (uint8_t *)calloc(kW * kH, 1);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
error("Failed to allocate screen buffer w=%d h=%d", kW, kH);
|
error("Failed to allocate screen buffer w=%d h=%d", kW, kH);
|
||||||
}
|
}
|
||||||
_vid.AMIGA_decodeCmp(_res._memBuf + 6, buf);
|
|
||||||
static const int kAmigaColors[] = {
|
static const int kAmigaColors[] = {
|
||||||
0x000, 0x123, 0x012, 0x134, 0x433, 0x453, 0x046, 0x245,
|
0x000, 0x123, 0x012, 0x134, 0x433, 0x453, 0x046, 0x245,
|
||||||
0x751, 0x455, 0x665, 0x268, 0x961, 0x478, 0x677, 0x786,
|
0x751, 0x455, 0x665, 0x268, 0x961, 0x478, 0x677, 0x786,
|
||||||
|
@ -166,7 +169,14 @@ 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);
|
||||||
free(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) {
|
while (1) {
|
||||||
_stub->processEvents();
|
_stub->processEvents();
|
||||||
if (_stub->_pi.quit) {
|
if (_stub->_pi.quit) {
|
||||||
|
@ -243,6 +253,9 @@ void Game::mainLoop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (oldLevel != _currentLevel) {
|
if (oldLevel != _currentLevel) {
|
||||||
|
if (_res._isDemo) {
|
||||||
|
_currentLevel = oldLevel;
|
||||||
|
}
|
||||||
changeLevel();
|
changeLevel();
|
||||||
_pge_opTempVar1 = 0;
|
_pge_opTempVar1 = 0;
|
||||||
return;
|
return;
|
||||||
|
@ -598,7 +611,9 @@ bool Game::handleContinueAbort() {
|
||||||
bool Game::handleProtectionScreen() {
|
bool Game::handleProtectionScreen() {
|
||||||
bool valid = true;
|
bool valid = true;
|
||||||
_cut.prepare();
|
_cut.prepare();
|
||||||
_cut.copyPalette(_protectionPal, 0);
|
const int palOffset = _res.isAmiga() ? 32 : 0;
|
||||||
|
_cut.copyPalette(_protectionPal + palOffset, 0);
|
||||||
|
|
||||||
_cut.updatePalette();
|
_cut.updatePalette();
|
||||||
_cut._gfx.setClippingRect(64, 48, 128, 128);
|
_cut._gfx.setClippingRect(64, 48, 128, 128);
|
||||||
|
|
||||||
|
@ -622,10 +637,10 @@ bool Game::handleProtectionScreen() {
|
||||||
do {
|
do {
|
||||||
codeText[len] = '\0';
|
codeText[len] = '\0';
|
||||||
memcpy(_vid._frontLayer, _vid._tempLayer, _vid._layerSize);
|
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];
|
char buf[20];
|
||||||
snprintf(buf, sizeof(buf), "CODE %d : %s", codeNum + 1, codeText);
|
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();
|
_vid.updateScreen();
|
||||||
_stub->sleep(50);
|
_stub->sleep(50);
|
||||||
_stub->processEvents();
|
_stub->processEvents();
|
||||||
|
@ -679,7 +694,11 @@ void Game::printLevelCode() {
|
||||||
--_printLevelCodeCounter;
|
--_printLevelCodeCounter;
|
||||||
if (_printLevelCodeCounter != 0) {
|
if (_printLevelCodeCounter != 0) {
|
||||||
char buf[32];
|
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);
|
_vid.drawString(buf, (_vid._w - strlen(buf) * 8) / 2, 16, 0xE7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1506,16 +1525,30 @@ void Game::handleInventory() {
|
||||||
int icon_h = 5;
|
int icon_h = 5;
|
||||||
int icon_y = 140;
|
int icon_y = 140;
|
||||||
int icon_num = 31;
|
int icon_num = 31;
|
||||||
|
static const int icon_spr_w = 16;
|
||||||
|
static const int icon_spr_h = 16;
|
||||||
do {
|
do {
|
||||||
int icon_x = 56;
|
int icon_x = 56;
|
||||||
int icon_w = 9;
|
int icon_w = 9;
|
||||||
do {
|
do {
|
||||||
drawIcon(icon_num, icon_x, icon_y, 0xF);
|
drawIcon(icon_num, icon_x, icon_y, 0xF);
|
||||||
++icon_num;
|
++icon_num;
|
||||||
icon_x += 16;
|
icon_x += icon_spr_w;
|
||||||
} while (--icon_w);
|
} while (--icon_w);
|
||||||
icon_y += 16;
|
icon_y += icon_spr_h;
|
||||||
} while (--icon_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) {
|
if (!display_score) {
|
||||||
int icon_x_pos = 72;
|
int icon_x_pos = 72;
|
||||||
|
|
23
intern.h
23
intern.h
|
@ -7,24 +7,20 @@
|
||||||
#ifndef INTERN_H__
|
#ifndef INTERN_H__
|
||||||
#define INTERN_H__
|
#define INTERN_H__
|
||||||
|
|
||||||
#include <cstdio>
|
#include <stdio.h>
|
||||||
#include <cstring>
|
#include <string.h>
|
||||||
#include <cstdlib>
|
#include <stdlib.h>
|
||||||
#include <cassert>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifndef ABS
|
#undef ABS
|
||||||
#define ABS(x) ((x)<0?-(x):(x))
|
#define ABS(x) ((x)<0?-(x):(x))
|
||||||
#endif
|
#undef MAX
|
||||||
#ifndef MAX
|
|
||||||
#define MAX(x,y) ((x)>(y)?(x):(y))
|
#define MAX(x,y) ((x)>(y)?(x):(y))
|
||||||
#endif
|
#undef MIN
|
||||||
#ifndef MIN
|
|
||||||
#define MIN(x,y) ((x)<(y)?(x):(y))
|
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||||
#endif
|
#undef ARRAYSIZE
|
||||||
#ifndef ARRAYSIZE
|
#define ARRAYSIZE(a) (int)(sizeof(a)/sizeof(a[0]))
|
||||||
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline uint16_t READ_BE_UINT16(const void *ptr) {
|
inline uint16_t READ_BE_UINT16(const void *ptr) {
|
||||||
const uint8_t *b = (const uint8_t *)ptr;
|
const uint8_t *b = (const uint8_t *)ptr;
|
||||||
|
@ -93,6 +89,7 @@ struct Options {
|
||||||
bool fade_out_palette;
|
bool fade_out_palette;
|
||||||
bool use_tiledata;
|
bool use_tiledata;
|
||||||
bool use_text_cutscenes;
|
bool use_text_cutscenes;
|
||||||
|
bool use_seq_cutscenes;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Color {
|
struct Color {
|
||||||
|
|
8
main.cpp
8
main.cpp
|
@ -4,6 +4,7 @@
|
||||||
* Copyright (C) 2005-2015 Gregory Montoir (cyx@users.sourceforge.net)
|
* Copyright (C) 2005-2015 Gregory Montoir (cyx@users.sourceforge.net)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -19,7 +20,7 @@ static const char *USAGE =
|
||||||
"Usage: %s [OPTIONS]...\n"
|
"Usage: %s [OPTIONS]...\n"
|
||||||
" --datapath=PATH Path to data files (default 'DATA')\n"
|
" --datapath=PATH Path to data files (default 'DATA')\n"
|
||||||
" --savepath=PATH Path to save files (default '.')\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"
|
" --fullscreen Fullscreen display\n"
|
||||||
" --scaler=INDEX Graphics scaler\n"
|
" --scaler=INDEX Graphics scaler\n"
|
||||||
" --language=LANG Language (fr,en,de,sp,it)\n"
|
" --language=LANG Language (fr,en,de,sp,it)\n"
|
||||||
|
@ -36,7 +37,7 @@ static int detectVersion(FileSystem *fs) {
|
||||||
{ "LEVEL1.MAP", kResourceTypeDOS, "DOS" },
|
{ "LEVEL1.MAP", kResourceTypeDOS, "DOS" },
|
||||||
{ "LEVEL1.LEV", kResourceTypeAmiga, "Amiga" },
|
{ "LEVEL1.LEV", kResourceTypeAmiga, "Amiga" },
|
||||||
{ "DEMO.LEV", kResourceTypeAmiga, "Amiga (Demo)" },
|
{ "DEMO.LEV", kResourceTypeAmiga, "Amiga (Demo)" },
|
||||||
{ 0, -1 }
|
{ 0, -1, 0 }
|
||||||
};
|
};
|
||||||
for (int i = 0; table[i].filename; ++i) {
|
for (int i = 0; table[i].filename; ++i) {
|
||||||
File f;
|
File f;
|
||||||
|
@ -82,6 +83,7 @@ static void initOptions() {
|
||||||
g_options.enable_password_menu = false;
|
g_options.enable_password_menu = false;
|
||||||
g_options.fade_out_palette = true;
|
g_options.fade_out_palette = true;
|
||||||
g_options.use_text_cutscenes = false;
|
g_options.use_text_cutscenes = false;
|
||||||
|
g_options.use_seq_cutscenes = true;
|
||||||
// read configuration file
|
// read configuration file
|
||||||
struct {
|
struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -93,6 +95,7 @@ static void initOptions() {
|
||||||
{ "fade_out_palette", &g_options.fade_out_palette },
|
{ "fade_out_palette", &g_options.fade_out_palette },
|
||||||
{ "use_tiledata", &g_options.use_tiledata },
|
{ "use_tiledata", &g_options.use_tiledata },
|
||||||
{ "use_text_cutscenes", &g_options.use_text_cutscenes },
|
{ "use_text_cutscenes", &g_options.use_text_cutscenes },
|
||||||
|
{ "use_seq_cutscenes", &g_options.use_seq_cutscenes },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
static const char *filename = "rs.cfg";
|
static const char *filename = "rs.cfg";
|
||||||
|
@ -126,7 +129,6 @@ static void initOptions() {
|
||||||
|
|
||||||
static const int DEFAULT_SCALER = SCALER_SCALE_3X;
|
static const int DEFAULT_SCALER = SCALER_SCALE_3X;
|
||||||
|
|
||||||
#undef main
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
const char *dataPath = "DATA";
|
const char *dataPath = "DATA";
|
||||||
const char *savePath = ".";
|
const char *savePath = ".";
|
||||||
|
|
1
menu.h
1
menu.h
|
@ -40,6 +40,7 @@ struct Menu {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *_passwords[8][3];
|
static const char *_passwords[8][3];
|
||||||
|
static const char *_passwordsFrAmiga[];
|
||||||
|
|
||||||
Resource *_res;
|
Resource *_res;
|
||||||
SystemStub *_stub;
|
SystemStub *_stub;
|
||||||
|
|
|
@ -488,9 +488,6 @@ void Game::pge_addToCurrentRoomList(LivePGE *pge, uint8_t room) {
|
||||||
void Game::pge_getInput() {
|
void Game::pge_getInput() {
|
||||||
inp_update();
|
inp_update();
|
||||||
_inp_lastKeysHit = _stub->_pi.dirMask;
|
_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)) {
|
if ((_inp_lastKeysHit & 0xC) && (_inp_lastKeysHit & 0x3)) {
|
||||||
const uint8_t mask = (_inp_lastKeysHit & 0xF0) | (_inp_lastKeysHitLeftRight & 0xF);
|
const uint8_t mask = (_inp_lastKeysHit & 0xF0) | (_inp_lastKeysHitLeftRight & 0xF);
|
||||||
_pge_inpKeysMask = mask;
|
_pge_inpKeysMask = mask;
|
||||||
|
|
|
@ -949,6 +949,7 @@ void Resource::load_PGE(File *f) {
|
||||||
_pgeNum = f->readUint16LE();
|
_pgeNum = f->readUint16LE();
|
||||||
memset(_pgeInit, 0, sizeof(_pgeInit));
|
memset(_pgeInit, 0, sizeof(_pgeInit));
|
||||||
debug(DBG_RES, "_pgeNum=%d", _pgeNum);
|
debug(DBG_RES, "_pgeNum=%d", _pgeNum);
|
||||||
|
assert(_pgeNum <= ARRAYSIZE(_pgeInit));
|
||||||
for (uint16_t i = 0; i < _pgeNum; ++i) {
|
for (uint16_t i = 0; i < _pgeNum; ++i) {
|
||||||
InitPGE *pge = &_pgeInit[i];
|
InitPGE *pge = &_pgeInit[i];
|
||||||
pge->type = f->readUint16LE();
|
pge->type = f->readUint16LE();
|
||||||
|
@ -979,6 +980,7 @@ void Resource::decodePGE(const uint8_t *p, int size) {
|
||||||
_pgeNum = _readUint16(p); p += 2;
|
_pgeNum = _readUint16(p); p += 2;
|
||||||
memset(_pgeInit, 0, sizeof(_pgeInit));
|
memset(_pgeInit, 0, sizeof(_pgeInit));
|
||||||
debug(DBG_RES, "len=%d _pgeNum=%d", size, _pgeNum);
|
debug(DBG_RES, "len=%d _pgeNum=%d", size, _pgeNum);
|
||||||
|
assert(_pgeNum <= ARRAYSIZE(_pgeInit));
|
||||||
for (uint16_t i = 0; i < _pgeNum; ++i) {
|
for (uint16_t i = 0; i < _pgeNum; ++i) {
|
||||||
InitPGE *pge = &_pgeInit[i];
|
InitPGE *pge = &_pgeInit[i];
|
||||||
pge->type = _readUint16(p); p += 2;
|
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 .BNQ & .LEV datafiles (tile based rendering) for backgrounds (instead of .MAP)
|
||||||
use_tiledata=false
|
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
|
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_SCALE_3X,
|
||||||
SCALER_POINT_4X,
|
SCALER_POINT_4X,
|
||||||
SCALER_SCALE_4X,
|
SCALER_SCALE_4X,
|
||||||
NUM_SCALERS = 7
|
NUM_SCALERS
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Scaler {
|
struct Scaler {
|
||||||
|
|
|
@ -836,6 +836,29 @@ const Cutscene::Text Cutscene::_frTextsTable[] = {
|
||||||
{ -1, 0 }
|
{ -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[] = {
|
const Demo Game::_demoInputs[] = {
|
||||||
{ "demo1.bin", 0, 0x33, 0x60, 0x46 },
|
{ "demo1.bin", 0, 0x33, 0x60, 0x46 },
|
||||||
{ "demo51.bin", 5, 0x00, 0x60, 0xD6 },
|
{ "demo51.bin", 5, 0x00, 0x60, 0xD6 },
|
||||||
|
@ -2700,8 +2723,12 @@ const uint8_t Game::_protectionCodeData[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8_t Game::_protectionPal[] = {
|
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, 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] = {
|
const char *Menu::_passwords[8][3] = {
|
||||||
|
@ -2715,6 +2742,12 @@ const char *Menu::_passwords[8][3] = {
|
||||||
{ "BELUGA", "BELUGA", "BELUGA" }
|
{ "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[] = {
|
const uint8_t Video::_conradPal1[] = {
|
||||||
0x00, 0x00, 0xCC, 0x0C, 0x8F, 0x08, 0x7E, 0x07, 0x6C, 0x06, 0x5B, 0x05, 0x4A, 0x04, 0x63, 0x09,
|
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
|
0x52, 0x07, 0x41, 0x06, 0x30, 0x06, 0x76, 0x0C, 0x14, 0x09, 0x25, 0x0B, 0x88, 0x08, 0xFF, 0x0F
|
||||||
|
|
|
@ -35,8 +35,6 @@ struct PlayerInput {
|
||||||
bool load;
|
bool load;
|
||||||
int stateSlot;
|
int stateSlot;
|
||||||
|
|
||||||
bool mirrorMode;
|
|
||||||
|
|
||||||
uint8_t dbgMask;
|
uint8_t dbgMask;
|
||||||
bool quit;
|
bool quit;
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,6 +19,7 @@ struct SystemStub_SDL : SystemStub {
|
||||||
SDL_Window *_window;
|
SDL_Window *_window;
|
||||||
SDL_Renderer *_renderer;
|
SDL_Renderer *_renderer;
|
||||||
SDL_Texture *_texture;
|
SDL_Texture *_texture;
|
||||||
|
int _texW, _texH;
|
||||||
SDL_GameController *_controller;
|
SDL_GameController *_controller;
|
||||||
#else
|
#else
|
||||||
SDL_Surface *_surface;
|
SDL_Surface *_surface;
|
||||||
|
@ -125,10 +126,7 @@ void SystemStub_SDL::setScreenSize(int w, int h) {
|
||||||
if (_screenW == w && _screenH == h) {
|
if (_screenW == w && _screenH == h) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
free(_screenBuffer);
|
cleanupGraphics();
|
||||||
_screenBuffer = 0;
|
|
||||||
free(_fadeScreenBuffer);
|
|
||||||
_fadeScreenBuffer = 0;
|
|
||||||
// allocate some extra bytes for the scaling routines
|
// allocate some extra bytes for the scaling routines
|
||||||
const int screenBufferSize = (w + 2) * (h + 2) * sizeof(uint16_t);
|
const int screenBufferSize = (w + 2) * (h + 2) * sizeof(uint16_t);
|
||||||
_screenBuffer = (uint16_t *)calloc(1, screenBufferSize);
|
_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];
|
SDL_Rect *br = &_blitRects[_numBlitRects];
|
||||||
|
|
||||||
br->x = _pi.mirrorMode ? _screenW - (x + w) : x;
|
br->x = x;
|
||||||
br->y = y;
|
br->y = y;
|
||||||
br->w = w;
|
br->w = w;
|
||||||
br->h = h;
|
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);
|
uint16_t *p = _screenBuffer + (br->y + 1) * _screenW + (br->x + 1);
|
||||||
buf += y * pitch + x;
|
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--) {
|
while (h--) {
|
||||||
for (int i = 0; i < w; ++i) {
|
for (int i = 0; i < w; ++i) {
|
||||||
p[i] = _pal[buf[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;
|
p += _screenW;
|
||||||
buf += pitch;
|
buf += pitch;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (_pi.dbgMask & PlayerInput::DF_DBLOCKS) {
|
if (_pi.dbgMask & PlayerInput::DF_DBLOCKS) {
|
||||||
drawRect(br, 0xE7, _screenBuffer + _screenW + 1, _screenW * 2);
|
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) {
|
void SystemStub_SDL::updateScreen(int shakeOffset) {
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#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_UpdateTexture(_texture, 0, _screenBuffer + _screenW + 1, _screenW * sizeof(uint16_t));
|
||||||
|
}
|
||||||
SDL_RenderClear(_renderer);
|
SDL_RenderClear(_renderer);
|
||||||
if (_fadeOnUpdateScreen) {
|
if (_fadeOnUpdateScreen) {
|
||||||
SDL_SetRenderDrawBlendMode(_renderer, SDL_BLENDMODE_BLEND);
|
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;
|
_pi.dbgMask ^= PlayerInput::DF_DBLOCKS;
|
||||||
} else if (ev.key.keysym.sym == SDLK_i) {
|
} else if (ev.key.keysym.sym == SDLK_i) {
|
||||||
_pi.dbgMask ^= PlayerInput::DF_SETLIFE;
|
_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) {
|
} else if (ev.key.keysym.sym == SDLK_s) {
|
||||||
_pi.save = true;
|
_pi.save = true;
|
||||||
} else if (ev.key.keysym.sym == SDLK_l) {
|
} else if (ev.key.keysym.sym == SDLK_l) {
|
||||||
|
@ -690,9 +684,13 @@ void SystemStub_SDL::prepareGraphics() {
|
||||||
case SCALER_SCALE_3X:
|
case SCALER_SCALE_3X:
|
||||||
case SCALER_SCALE_4X:
|
case SCALER_SCALE_4X:
|
||||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
|
||||||
|
_texW = _screenW * _scalers[_scaler].factor;
|
||||||
|
_texH = _screenH * _scalers[_scaler].factor;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); // nearest pixel sampling
|
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); // nearest pixel sampling
|
||||||
|
_texW = _screenW;
|
||||||
|
_texH = _screenH;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const int windowW = _screenW * _scalers[_scaler].factor;
|
const int windowW = _screenW * _scalers[_scaler].factor;
|
||||||
|
@ -705,7 +703,7 @@ void SystemStub_SDL::prepareGraphics() {
|
||||||
_renderer = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED);
|
_renderer = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED);
|
||||||
SDL_RenderSetLogicalSize(_renderer, windowW, windowH);
|
SDL_RenderSetLogicalSize(_renderer, windowW, windowH);
|
||||||
static const uint32_t kPixelFormat = SDL_PIXELFORMAT_RGB565;
|
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);
|
_fmt = SDL_AllocFormat(kPixelFormat);
|
||||||
#else
|
#else
|
||||||
SDL_WM_SetCaption(_caption, NULL);
|
SDL_WM_SetCaption(_caption, NULL);
|
||||||
|
|
17
util.cpp
17
util.cpp
|
@ -8,7 +8,11 @@
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <cstdarg>
|
#ifdef __ANDROID__
|
||||||
|
#define LOG_TAG "FbJni"
|
||||||
|
#include <android/log.h>
|
||||||
|
#endif
|
||||||
|
#include <stdarg.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,8 +25,11 @@ void debug(uint16_t cm, const char *msg, ...) {
|
||||||
va_start(va, msg);
|
va_start(va, msg);
|
||||||
vsprintf(buf, msg, va);
|
vsprintf(buf, msg, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
printf("%s\n", buf);
|
fprintf(stdout, "%s\n", buf);
|
||||||
fflush(stdout);
|
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);
|
fprintf(stderr, "ERROR: %s!\n", buf);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
MessageBox(0, buf, g_caption, MB_ICONERROR);
|
MessageBox(0, buf, g_caption, MB_ICONERROR);
|
||||||
|
#endif
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "%s", buf);
|
||||||
#endif
|
#endif
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
@ -46,5 +56,8 @@ void warning(const char *msg, ...) {
|
||||||
vsnprintf(buf, sizeof(buf), msg, va);
|
vsnprintf(buf, sizeof(buf), msg, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
fprintf(stderr, "WARNING: %s!\n", buf);
|
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 yflip = (d3 & (1 << 12)) != 0;
|
||||||
const bool xflip = (d3 & (1 << 11)) != 0;
|
const bool xflip = (d3 & (1 << 11)) != 0;
|
||||||
int mask = 0;
|
int mask = 0;
|
||||||
if ((d3 < (1 << 15)) == 0) {
|
if ((d3 & 0x8000) != 0) {
|
||||||
mask = 0x80;
|
mask = 0x80 + ((d3 >> 6) & 0x10);
|
||||||
}
|
}
|
||||||
if (isPC) {
|
if (isPC) {
|
||||||
PC_drawTile(dst + y * 256 + x, a2, mask, xflip, yflip, -1);
|
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;
|
int mask = 0;
|
||||||
if ((d3 & 0x6000) != 0 && sgdBuf) {
|
if ((d3 & 0x6000) != 0 && sgdBuf) {
|
||||||
mask = 0x10;
|
mask = 0x10;
|
||||||
} else if ((d3 < (1 << 15)) == 0) {
|
} else if ((d3 & 0x8000) != 0) {
|
||||||
mask = 0x80;
|
mask = 0x80 + ((d3 >> 6) & 0x10);
|
||||||
}
|
}
|
||||||
if (isPC) {
|
if (isPC) {
|
||||||
PC_drawTile(dst + y * 256 + x, a2, mask, xflip, yflip, 0);
|
PC_drawTile(dst + y * 256 + x, a2, mask, xflip, yflip, 0);
|
||||||
|
@ -663,13 +663,14 @@ void Video::AMIGA_decodeLev(int level, int room) {
|
||||||
// background
|
// background
|
||||||
setPaletteSlotBE(0x0, _mapPalSlot1);
|
setPaletteSlotBE(0x0, _mapPalSlot1);
|
||||||
// objects
|
// objects
|
||||||
setPaletteSlotBE(0x1, (level == 0 || level == 1) ? _mapPalSlot3 : _mapPalSlot2);
|
setPaletteSlotBE(0x1, (level == 0) ? _mapPalSlot3 : _mapPalSlot2);
|
||||||
setPaletteSlotBE(0x2, _mapPalSlot3);
|
setPaletteSlotBE(0x2, _mapPalSlot3);
|
||||||
setPaletteSlotBE(0x3, _mapPalSlot3);
|
setPaletteSlotBE(0x3, _mapPalSlot3);
|
||||||
// conrad
|
// conrad
|
||||||
setPaletteSlotBE(0x4, _mapPalSlot3);
|
setPaletteSlotBE(0x4, _mapPalSlot3);
|
||||||
// foreground
|
// foreground
|
||||||
setPaletteSlotBE(0x8, _mapPalSlot1);
|
setPaletteSlotBE(0x8, _mapPalSlot1);
|
||||||
|
setPaletteSlotBE(0x9, (level == 0) ? _mapPalSlot1 : _mapPalSlot3);
|
||||||
// inventory
|
// inventory
|
||||||
setPaletteSlotBE(0xA, _mapPalSlot3);
|
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;
|
const uint8_t *src = _res->_fnt + (c - 32) * 32;
|
||||||
uint8_t *dst = _frontLayer + x + 256 * y;
|
uint8_t *dst = _frontLayer + x + 256 * y;
|
||||||
for (int h = 0; h < 8; ++h) {
|
for (int h = 0; h < 8; ++h) {
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i, ++src) {
|
||||||
uint8_t c1 = (*src & 0xF0) >> 4;
|
const uint8_t c1 = *src >> 4;
|
||||||
uint8_t c2 = (*src & 0x0F) >> 0;
|
|
||||||
++src;
|
|
||||||
|
|
||||||
if (c1 != 0) {
|
if (c1 != 0) {
|
||||||
if (c1 != 2) {
|
if (c1 != 2) {
|
||||||
*dst = _charFrontColor;
|
*dst = _charFrontColor;
|
||||||
|
@ -818,7 +816,7 @@ void Video::PC_drawChar(uint8_t c, int16_t y, int16_t x) {
|
||||||
*dst = _charTransparentColor;
|
*dst = _charTransparentColor;
|
||||||
}
|
}
|
||||||
++dst;
|
++dst;
|
||||||
|
const uint8_t c2 = *src & 15;
|
||||||
if (c2 != 0) {
|
if (c2 != 0) {
|
||||||
if (c2 != 2) {
|
if (c2 != 2) {
|
||||||
*dst = _charFrontColor;
|
*dst = _charFrontColor;
|
||||||
|
|
Loading…
Reference in New Issue