mirror of
https://github.com/libretro/scummvm.git
synced 2025-03-04 09:18:38 +00:00
380 lines
7.9 KiB
C++
380 lines
7.9 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "common/error.h"
|
|
#include "common/system.h"
|
|
#include "engines/util.h"
|
|
|
|
#include "chamber/chamber.h"
|
|
#include "chamber/common.h"
|
|
#include "chamber/decompr.h"
|
|
#include "chamber/cga.h"
|
|
#include "chamber/anim.h"
|
|
#include "chamber/cursor.h"
|
|
#include "chamber/input.h"
|
|
#include "chamber/timer.h"
|
|
#include "chamber/portrait.h"
|
|
#include "chamber/room.h"
|
|
#include "chamber/savegame.h"
|
|
#include "chamber/resdata.h"
|
|
#include "chamber/script.h"
|
|
#include "chamber/print.h"
|
|
#include "chamber/dialog.h"
|
|
#include "chamber/menu.h"
|
|
#include "chamber/ifgm.h"
|
|
|
|
namespace Chamber {
|
|
|
|
uint16 cpu_speed_delay;
|
|
|
|
/*
|
|
Prompt user to insert disk #2 to any drive
|
|
*/
|
|
void askDisk2(void) {
|
|
drawMessage(seekToString(vepci_data, 179), frontbuffer);
|
|
}
|
|
|
|
void saveToFile(char *filename, void *data, uint16 size) {
|
|
warning("STUB: SaveToFile(%s, data, %d)", filename, size);
|
|
#if 0
|
|
FILE *f = fopen(filename, "wb");
|
|
fwrite(data, 1, size, f);
|
|
fclose(f);
|
|
#endif
|
|
}
|
|
|
|
int16 loadSplash(const char *filename) {
|
|
if (!loadFile(filename, scratch_mem1))
|
|
return 0;
|
|
decompress(scratch_mem1 + 8, backbuffer); /* skip compressed/decompressed size fields */
|
|
return 1;
|
|
}
|
|
|
|
uint16 benchmarkCpu(void) {
|
|
byte t;
|
|
uint16 cycles = 0;
|
|
for (t = script_byte_vars.timer_ticks; t == script_byte_vars.timer_ticks;) ;
|
|
for (t = script_byte_vars.timer_ticks; t == script_byte_vars.timer_ticks;) cycles++;
|
|
return cycles;
|
|
}
|
|
|
|
void randomize(void) {
|
|
warning("STUB: Randomize()");
|
|
#if 0
|
|
union REGS reg;
|
|
|
|
reg.h.ah = 0;
|
|
int86(0x1A, ®, ®);
|
|
rand_seed = reg.h.dl;
|
|
Rand();
|
|
#endif
|
|
}
|
|
|
|
void TRAP() {
|
|
promptWait();
|
|
for (;;) ;
|
|
}
|
|
|
|
/* Main Game Loop */
|
|
void gameLoop(byte *target) {
|
|
for (;;) {
|
|
animateSpots(target);
|
|
|
|
/* Update/check live things */
|
|
updateProtozorqs();
|
|
checkGameTimeLimit();
|
|
cleanupDroppedItems();
|
|
|
|
/* Get player input */
|
|
pollInput();
|
|
|
|
if (g_vm->_shouldQuit)
|
|
return;
|
|
|
|
the_command = 0;
|
|
if (isCursorInRect(&room_bounds_rect)) {
|
|
selectCursor(CURSOR_TARGET);
|
|
command_hint = 100;
|
|
selectSpotCursor();
|
|
} else {
|
|
selectCursor(CURSOR_FINGER);
|
|
object_hint = 117;
|
|
checkMenuCommandHover();
|
|
}
|
|
|
|
if (object_hint != last_object_hint)
|
|
drawObjectHint();
|
|
|
|
if (command_hint != last_command_hint)
|
|
drawCommandHint();
|
|
|
|
drawHintsAndCursor(target);
|
|
|
|
if (!buttons || !the_command) {
|
|
/*Pending / AI commands*/
|
|
|
|
if (script_byte_vars.check_used_commands < script_byte_vars.used_commands) {
|
|
the_command = Swap16(script_word_vars.next_aspirant_cmd);
|
|
if (the_command)
|
|
goto process;
|
|
}
|
|
|
|
if (script_byte_vars.bvar_45)
|
|
continue;
|
|
|
|
the_command = Swap16(script_word_vars.next_protozorqs_cmd);
|
|
if (the_command)
|
|
goto process;
|
|
|
|
if (Swap16(next_vorts_ticks) < script_word_vars.timer_ticks2) { /*TODO: is this ok? ticks2 is BE, ticks3 is LE*/
|
|
the_command = next_vorts_cmd;
|
|
if (the_command)
|
|
goto process;
|
|
}
|
|
|
|
if (Swap16(next_turkey_ticks) < script_word_vars.timer_ticks2) { /*TODO: is this ok? ticks2 is BE, ticks4 is LE*/
|
|
the_command = next_turkey_cmd;
|
|
if (the_command)
|
|
goto process;
|
|
}
|
|
|
|
continue;
|
|
|
|
process:
|
|
;
|
|
updateUndrawCursor(target);
|
|
refreshSpritesData();
|
|
runCommand();
|
|
if (g_vm->_shouldRestart)
|
|
return;
|
|
blitSpritesToBackBuffer();
|
|
processInput();
|
|
drawSpots(target);
|
|
} else {
|
|
/*Player action*/
|
|
|
|
updateUndrawCursor(target);
|
|
refreshSpritesData();
|
|
uint16 restart = runCommandKeepSp();
|
|
if (restart == RUNCOMMAND_RESTART && g_vm->_shouldRestart)
|
|
return;
|
|
script_byte_vars.used_commands++;
|
|
if (script_byte_vars.dead_flag) {
|
|
if (--script_byte_vars.tries_left == 0)
|
|
resetAllPersons();
|
|
}
|
|
blitSpritesToBackBuffer();
|
|
processInput();
|
|
drawSpots(target);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void exitGame(void) {
|
|
switchToTextMode();
|
|
uninitTimer();
|
|
}
|
|
|
|
#ifdef DEBUG_ENDING
|
|
extern theEnd(void);
|
|
#endif
|
|
|
|
Common::Error ChamberEngine::init() {
|
|
byte c;
|
|
|
|
// Initialize graphics using following:
|
|
initGraphics(320, 200);
|
|
initSound();
|
|
|
|
/*TODO: DetectCPU*/
|
|
|
|
IFGM_Init();
|
|
|
|
switchToGraphicsMode();
|
|
|
|
/* Install timer callback */
|
|
initTimer();
|
|
|
|
if (g_vm->getLanguage() == Common::EN_USA) {
|
|
/* Load title screen */
|
|
if (!loadSplash("PRESCGA.BIN"))
|
|
exitGame();
|
|
|
|
if (ifgm_loaded) {
|
|
/*TODO*/
|
|
}
|
|
} else {
|
|
/* Load title screen */
|
|
if (!loadSplash("PRES.BIN"))
|
|
exitGame();
|
|
}
|
|
|
|
/* Select intense cyan-mageta palette */
|
|
cga_ColorSelect(0x30);
|
|
|
|
/* Show the title screen */
|
|
cga_BackBufferToRealFull();
|
|
|
|
if (g_vm->getLanguage() == Common::EN_USA) {
|
|
if (ifgm_loaded) {
|
|
/*TODO*/
|
|
}
|
|
|
|
/* Force English language */
|
|
c = 'E';
|
|
} else {
|
|
/* Load language selection screen */
|
|
if (!loadSplash("DRAP.BIN"))
|
|
exitGame();
|
|
|
|
/* Wait for a keypress and show the language selection screen */
|
|
clearKeyboard();
|
|
readKeyboardChar();
|
|
|
|
if (_shouldQuit)
|
|
return Common::kNoError;
|
|
|
|
cga_BackBufferToRealFull();
|
|
clearKeyboard();
|
|
|
|
/* Wait for a valid language choice */
|
|
do {
|
|
c = readKeyboardChar();
|
|
if (c > 'F')
|
|
c -= ' ';
|
|
} while (c < 'D' || c > 'F');
|
|
}
|
|
|
|
if (_shouldQuit)
|
|
return Common::kNoError;
|
|
|
|
/* Patch resource names for choosen language */
|
|
res_texts[0].name[4] = c;
|
|
res_texts[1].name[4] = c;
|
|
res_desci[0].name[4] = c;
|
|
res_diali[0].name[4] = c;
|
|
|
|
if (g_vm->getLanguage() != Common::EN_USA)
|
|
cga_BackBufferToRealFull();
|
|
|
|
/* Load script and other static resources */
|
|
/* Those are normally embedded in the executable, but here we load extracted ones*/
|
|
if (!loadStaticData())
|
|
exitGame();
|
|
|
|
/* Load text resources */
|
|
if (!loadVepciData() || !loadDesciData() || !loadDialiData())
|
|
exitGame();
|
|
|
|
/* Detect/Initialize input device */
|
|
initInput();
|
|
|
|
/* Load graphics resources */
|
|
while (!loadFond() || !loadSpritesData() || !loadPersData())
|
|
askDisk2();
|
|
|
|
/*TODO: is this neccessary?*/
|
|
cga_BackBufferToRealFull();
|
|
|
|
/* Create clean game state snapshot */
|
|
saveRestartGame();
|
|
|
|
/* Detect CPU speed for delay routines */
|
|
cpu_speed_delay = benchmarkCpu() / 8;
|
|
|
|
if (g_vm->getLanguage() == Common::EN_USA) {
|
|
if (ifgm_loaded) {
|
|
/*TODO*/
|
|
}
|
|
}
|
|
|
|
return Common::kNoError;
|
|
}
|
|
|
|
Common::Error ChamberEngine::execute() {
|
|
randomize();
|
|
|
|
/* Set start zone */
|
|
script_byte_vars.zone_index = 7;
|
|
|
|
/* Begin the game */
|
|
script_byte_vars.game_paused = 0;
|
|
|
|
#ifdef DEBUG_SCRIPT
|
|
unlink(DEBUG_SCRIPT_LOG);
|
|
#endif
|
|
|
|
#ifdef DEBUG_SKIP_INTRO
|
|
/*bypass characters introduction*/
|
|
script_byte_vars.load_flag = DEBUG_SKIP_INTRO;
|
|
#endif
|
|
|
|
/* Discard all pending input */
|
|
//ResetInput();
|
|
|
|
/* Play introduction sequence and initialize game */
|
|
the_command = 0xC001;
|
|
runCommand();
|
|
|
|
if (_shouldQuit)
|
|
return Common::kNoError;
|
|
|
|
/* Sync graphics */
|
|
blitSpritesToBackBuffer();
|
|
|
|
/* Initialize cursor backup */
|
|
processInput();
|
|
|
|
#ifdef DEBUG_ENDING
|
|
script_byte_vars.game_paused = 5;
|
|
theEnd();
|
|
for (;;) ;
|
|
#endif
|
|
|
|
/* Main game loop */
|
|
gameLoop(frontbuffer);
|
|
if (g_vm->_shouldRestart)
|
|
run();
|
|
|
|
/*TODO: the following code is never executed since gameLoop is infinite (or the whole game is restarted) */
|
|
|
|
/* Release hardware */
|
|
uninitInput();
|
|
|
|
exitGame();
|
|
|
|
return Common::kNoError;
|
|
}
|
|
Common::Error ChamberEngine::run() {
|
|
if (!g_vm->_shouldRestart)
|
|
init();
|
|
|
|
do {
|
|
g_vm->_shouldRestart = false;
|
|
execute();
|
|
} while (g_vm->_shouldRestart);
|
|
|
|
return Common::kNoError;
|
|
}
|
|
|
|
} // End of namespace Chamber
|