scummvm/simon/simon.h
2005-05-10 22:56:25 +00:00

826 lines
20 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2001-2005 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#ifndef SIMON_H
#define SIMON_H
#include <stdio.h>
#include "base/engine.h"
#include "common/util.h"
#include "simon/midi.h"
#include "simon/sound.h"
class GameDetector;
namespace Simon {
/* Various other settings */
//#define DUMP_FILE_NR 8
//#define DUMP_BITMAPS_FILE_NR 8
uint fileReadItemID(Common::File *in);
#define CHECK_BOUNDS(x, y) assert((uint)(x) < ARRAYSIZE(y))
#define NUM_PALETTE_FADEOUT 32
struct Child;
struct Child2;
struct Item;
struct FillOrCopyStruct;
struct Subroutine;
struct SubroutineLine;
struct TimeEvent;
struct TextLocation {
int16 x, y, width;
TextLocation() { memset(this, 0, sizeof(*this)); }
};
struct HitArea {
uint16 x, y;
uint16 width, height;
uint16 flags;
uint16 id;
FillOrCopyStruct *fcs;
Item *item_ptr;
uint16 unk3;
uint16 layer;
HitArea() { memset(this, 0, sizeof(*this)); }
};
struct VgaPointersEntry {
byte *vgaFile1;
byte *vgaFile2;
uint32 dd;
VgaPointersEntry() { memset(this, 0, sizeof(*this)); }
};
struct VgaSprite {
uint16 id;
uint16 image;
uint16 base_color;
uint16 x, y; /* actually signed numbers */
uint16 flags;
uint16 priority;
uint16 paletteMode, fileId;
VgaSprite() { memset(this, 0, sizeof(*this)); }
};
struct VgaSleepStruct {
uint16 ident;
const byte *code_ptr;
uint16 sprite_id;
uint16 cur_vga_file;
VgaSleepStruct() { memset(this, 0, sizeof(*this)); }
};
struct VgaTimerEntry {
uint16 delay;
const byte *script_pointer;
uint16 sprite_id;
uint16 cur_vga_file;
VgaTimerEntry() { memset(this, 0, sizeof(*this)); }
};
struct GameSpecificSettings;
class Debugger;
class SimonEngine : public Engine {
friend class Debugger;
void errorString(const char *buf_input, char *buf_output);
protected:
void playSting(uint a);
const byte *_vcPtr; /* video code ptr */
uint16 _vc_get_out_of_code;
uint32 *_gameOffsetsPtr;
uint VGA_DELAY_BASE;
uint TABLE_INDEX_BASE;
uint TEXT_INDEX_BASE;
uint NUM_VIDEO_OP_CODES;
uint VGA_MEM_SIZE;
uint TABLES_MEM_SIZE;
uint MUSIC_INDEX_BASE;
uint SOUND_INDEX_BASE;
const GameSpecificSettings *gss;
byte _game;
byte _keyPressed;
typedef enum {
FORMAT_NONE,
FORMAT_MP3,
FORMAT_WAV,
FORMAT_VOC
} SoundFormat;
Common::File *_gameFile;
byte *_strippedTxtMem;
uint _textSize;
uint _stringTabNum, _stringTabPos, _stringtab_numalloc;
byte **_stringTabPtr;
Item **_itemArrayPtr;
uint _itemArraySize;
uint _itemArrayInited;
byte *_itemHeapPtr;
uint _itemHeapCurPos;
uint _itemHeapSize;
byte *_iconFilePtr;
byte *_tblList;
const byte *_codePtr;
byte **_localStringtable;
uint _stringIdLocalMin, _stringIdLocalMax;
byte *_tablesHeapPtr, *_tablesHeapPtrOrg, *_tablesheapPtrNew;
uint _tablesHeapSize, _tablesHeapCurPos, _tablesHeapCurPosOrg;
uint _tablesHeapCurPosNew;
Subroutine *_subroutineList, *_subroutineListOrg;
uint _subroutine;
uint _dxSurfacePitch;
uint _recursionDepth;
uint32 _lastVgaTick;
uint16 _op189Flags;
bool _scriptVar2;
bool _runScriptReturn1;
bool _skipVgaWait;
bool _noParentNotify;
bool _vgaRes328Loaded;
bool _hitarea_unk_3;
bool _mortalFlag;
byte _videoVar8;
bool _usePaletteDelay;
bool _syncFlag2;
bool _inCallBack;
bool _cepeFlag;
byte _copyPartialMode;
uint _speed;
bool _fastMode;
bool _dxUse3Or4ForLock;
uint16 _debugMode;
uint16 _language;
bool _pause;
bool _startMainScript;
bool _continousMainScript;
bool _startVgaScript;
bool _continousVgaScript;
bool _drawImagesDebug;
bool _dumpImages;
bool _speech;
bool _subtitles;
bool _fade;
byte _mouseCursor;
bool _vgaVar9;
int16 _scriptUnk1;
bool _vgaVar6;
int _xScroll, _vgaVar1, _vgaVar2, _xScrollStep, _spriteHeight;
const byte *_vgaVar7;
byte _vgaVar8;
int16 _scriptCondA, _scriptCondB, _scriptCondC;
uint16 _fcsUnk1;
FillOrCopyStruct *_fcsPtr1;
Item *_subjectItem, *_objectItem;
Item *_item1;
Item *_hitAreaObjectItem;
HitArea *_lastHitArea;
HitArea *_lastHitArea2Ptr;
HitArea *_lastHitArea3;
byte _leftButtonDown;
Item *_hitAreaSubjectItem;
HitArea *_hitAreaPtr5, *_hitAreaPtr7;
uint _needHitAreaRecalc;
uint _verbHitArea;
uint16 _hitAreaUnk4;
uint _lockCounter;
uint16 _videoPaletteMode;
uint _printCharUnk1, _printCharUnk2;
uint _numLettersToPrint;
uint _lastTime;
TimeEvent *_firstTimeStruct, *_pendingDeleteTimeEvent;
uint _base_time;
uint _mouseX, _mouseY;
uint _mouseXOld, _mouseYOld;
Item *_dummyItem1;
Item *_dummyItem2;
Item *_dummyItem3;
volatile uint16 _lockWord;
uint16 _scrollUpHitArea;
uint16 _scrollDownHitArea;
uint16 _videoVar7;
volatile uint16 _paletteColorCount;
byte _videoVar4;
bool _videoVar5;
bool _videoVar3;
bool _unkPalFlag;
bool _exitCutscene;
bool _skipSpeech;
byte _videoVar9;
uint _soundFileId;
int16 _lastMusicPlayed;
int16 _nextMusicToPlay;
bool _showPreposition;
bool _showMessageFlag;
uint _videoNumPalColors;
uint _vgaSpriteChanged;
byte *_vgaBufFreeStart, *_vgaBufEnd, *_vgaBufStart;
byte *_vgaFileBufOrg, *_vgaFileBufOrg2;
byte *_curVgaFile1;
byte *_curVgaFile2;
uint16 _timer1, _timer5, _timer4;
uint16 _vgaBaseDelay;
uint16 _vgaCurFile2;
uint16 _vgaWaitFor, _vgaCurFileId;
uint16 _vgaCurSpriteId;
VgaTimerEntry *_nextVgaTimerToProcess;
Item *_vcItemArray[20];
Item *_itemArray6[20];
uint16 _stringIdArray2[20];
uint16 _stringIdArray3[20];
uint16 _speechIdArray4[20];
uint16 _bitArray[32];
int16 _variableArray[256];
FillOrCopyStruct *_fcsPtrArray3[8];
byte _fcsData1[8];
bool _fcsData2[8];
TextLocation _textLocation1, _textLocation2, _textLocation3, _textLocation4;
int _freeStringSlot;
byte _stringReturnBuffer[2][180];
HitArea _hitAreas[90];
VgaPointersEntry _vgaBufferPointers[180];
VgaSprite _vgaSprites[180];
VgaSleepStruct _vgaSleepStructs[30];
const uint16 *_pathFindArray[20];
uint8 _paletteBackup[1024];
uint8 _palette[1024];
byte _videoBuf1[3000];
VgaTimerEntry _vgaTimerList[95];
FillOrCopyStruct *_fcs_list;
byte _lettersToPrintBuf[80];
MidiPlayer midi;
int _midiDriver;
int _numScreenUpdates;
int _vgaTickCounter;
Sound *_sound;
bool _effectsPaused;
bool _ambientPaused;
bool _musicPaused;
Debugger *_debugger;
FILE *_dumpFile;
int _saveLoadRowCurPos;
int _numSaveGameRows;
bool _saveDialogFlag;
bool _saveOrLoad;
bool _saveLoadFlag;
byte _saveLoadType, _saveLoadSlot;
char _saveLoadName[32];
int _sdlMouseX, _sdlMouseY;
byte *_sdl_buf_3;
byte *_sdl_buf;
byte *_sdl_buf_attached;
Common::RandomSource _rnd;
const byte *_vc10BasePtrOld;
byte _hebrew_char_widths[32];
public:
SimonEngine(GameDetector *detector, OSystem *syst);
virtual ~SimonEngine();
protected:
int allocGamePcVars(Common::File *in);
void loginPlayerHelper(Item *item, int a, int b);
void loginPlayer();
void allocateStringTable(int num);
void setupStringTable(byte *mem, int num);
void setupLocalStringTable(byte *mem, int num);
void readGamePcText(Common::File *in);
void readItemChildren(Common::File *in, Item *item, uint tmp);
void readItemFromGamePc(Common::File *in, Item *item);
void loadGamePcFile(const char *filename);
byte *allocateItem(uint size);
byte *allocateTable(uint size);
void alignTableMem();
Child *findChildOfType(Item *i, uint child);
Child *allocateChildBlock(Item *i, uint type, uint size);
void allocItemHeap();
void allocTablesHeap();
Subroutine *createSubroutine(uint a);
void readSubroutine(Common::File *in, Subroutine *sub);
SubroutineLine *createSubroutineLine(Subroutine *sub, int a);
void readSubroutineLine(Common::File *in, SubroutineLine *new_table, Subroutine *sub);
byte *readSingleOpcode(Common::File *in, byte *ptr);
void readSubroutineBlock(Common::File *in);
Subroutine *getSubroutineByID(uint subroutine_id);
/* used in debugger */
void dumpSubroutines();
void dumpSubroutine(Subroutine *sub);
void dumpSubroutineLine(SubroutineLine *sl, Subroutine *sub);
const byte *dumpOpcode(const byte *p);
int startSubroutine(Subroutine *sub);
int startSubroutineEx(Subroutine *sub);
bool checkIfToRunSubroutineLine(SubroutineLine *sl, Subroutine *sub);
int runScript();
Item *getNextItemPtr();
uint getNextItemID();
uint getItem1ID() {return 1;}
Item *getItem1Ptr();
Item *getItemPtrB();
byte getByte();
int getNextWord();
uint getNextVarContents();
uint getVarOrWord();
uint getVarOrByte();
uint readVariable(uint variable);
void writeNextVarContents(uint16 contents);
void writeVariable(uint variable, uint16 contents);
void setItemParent(Item *item, Item *parent);
uint itemPtrToID(Item *id);
Item *derefItem(uint item);
void setItemUnk3(Item *item, int value);
void showMessageFormat(const char *s, ...);
const byte *getStringPtrByID(uint string_id);
const byte *getLocalStringByID(uint string_id);
uint getNextStringID();
void addTimeEvent(uint timeout, uint subroutine_id);
void delTimeEvent(TimeEvent *te);
bool hasChildOfType1(Item *item);
bool hasChildOfType2(Item *item);
void itemChildrenChanged(Item *item);
void unlinkItem(Item *item);
void linkItem(Item *item, Item *parent);
bool o_unk_23(uint a);
void o_kill_sprite_simon1(uint a);
void o_kill_sprite_simon2(uint a, uint b);
void o_vga_reset();
void o_unk_101();
void fcs_unk_2(uint a);
void o_unk_103();
void fcs_delete(uint a);
void o_unk_108(uint a);
void clear_hitarea_bit_0x40(uint hitarea);
void set_hitarea_bit_0x40(uint hitarea);
void set_hitarea_x_y(uint hitarea, int x, int y);
bool is_hitarea_0x40_clear(uint hitarea);
void delete_hitarea(uint hitarea);
void addNewHitArea(int id, int x, int y, int width, int height, int flags, int unk3, Item *item_ptr);
HitArea *findEmptyHitArea();
void hitarea_proc_1();
void handle_verb_hitarea(HitArea * ha);
void hitarea_leave(HitArea * ha);
void leaveHitAreaById(uint hitarea_id);
void o_unk_114();
void o_wait_for_vga(uint a);
void skip_speech();
void o_unk_120(uint a);
void o_unk_126();
void o_play_music_resource();
void o_save_game();
void o_load_game();
void o_quit_if_user_presses_y();
void o_unk_137(uint a);
void o_unk_138();
void killAllTimers();
uint getOffsetOfChild2Param(Child2 *child, uint prop);
void o_unk_160(uint a);
void o_play_sound(uint a);
void o_unk_175();
void o_unk_176();
void o_pathfind(int x, int y, uint var_1, uint var_2);
void o_force_unlock();
void o_force_lock();
void o_read_vgares_328();
void o_read_vgares_23();
void o_clear_vgapointer_entry(uint a);
void o_unk_186();
void o_fade_to_black();
TextLocation *getTextLocation(uint a);
void o_print_str();
void o_setup_cond_c();
void setup_cond_c_helper();
void o_inventory_descriptions();
void lock();
void unlock();
void fcs_unk_proc_1(uint i, Item *item_ptr, int unk1, int unk2);
void loadTextIntoMem(uint string_id);
void loadTablesIntoMem(uint subr_id);
uint loadTextFile(const char *filename, byte *dst);
Common::File *openTablesFile(const char *filename);
void closeTablesFile(Common::File *in);
uint loadTextFile_simon1(const char *filename, byte *dst);
Common::File *openTablesFile_simon1(const char *filename);
uint loadTextFile_gme(const char *filename, byte *dst);
Common::File *openTablesFile_gme(const char *filename);
void invokeTimeEvent(TimeEvent *te);
bool kickoffTimeEvents();
void defocusHitarea();
void startSubroutine170();
void runSubroutine101();
void handle_uparrow_hitarea(FillOrCopyStruct *fcs);
void handle_downarrow_hitarea(FillOrCopyStruct *fcs);
void hitareaChangedHelper();
void focusVerb(uint hitarea_id);
HitArea *findHitAreaByID(uint hitarea_id);
void showActionString(uint x, const byte *string);
void video_putchar(FillOrCopyStruct *fcs, byte c, byte b = 0);
void video_fill_or_copy_from_3_to_2(FillOrCopyStruct *fcs);
void video_toggle_colors(HitArea * ha, byte a, byte b, byte c, byte d);
void read_vga_from_datfile_1(uint vga_id);
uint get_fcs_ptr_3_index(FillOrCopyStruct *fcs);
void setup_hitarea_from_pos(uint x, uint y, uint mode);
void new_current_hitarea(HitArea * ha);
bool hitarea_proc_2(uint a);
bool hitarea_proc_3(Item *item);
void f10_key();
void hitarea_stuff();
void handle_mouse_moved();
void pollMouseXY();
void draw_mouse_pointer();
void fcs_unk1(uint fcs_index);
void draw_icon_c(FillOrCopyStruct *fcs, uint icon, uint x, uint y);
bool has_item_childflag_0x10(Item *item);
uint item_get_icon_number(Item *item);
uint setup_icon_hit_area(FillOrCopyStruct *fcs, uint x, uint y, uint icon_number, Item *item_ptr);
void fcs_unk_proc_2(FillOrCopyStruct *fcs, uint fcs_index);
void loadIconFile();
void processSpecialKeys();
void hitarea_stuff_helper();
void startUp_helper_2();
void showmessage_helper_3(uint a, uint b);
void showmessage_print_char(byte chr);
void handle_verb_clicked(uint verb);
void o_set_video_mode(uint mode, uint vga_res);
void set_video_mode_internal(uint mode, uint vga_res_id);
void ensureVgaResLoadedC(uint vga_res);
void ensureVgaResLoaded(uint vga_res);
void loadSprite(uint paletteMode, uint vga_res, uint vga_sprite_id, uint x, uint y, uint base_color);
void o_unk26_helper(uint a, uint b, uint c, uint d, uint e, uint f, uint g, uint h);
void talk_with_speech(uint speech_id, uint vga_sprite_id);
void talk_with_text(uint vga_sprite_id, uint color, const char *string_ptr, int16 x, int16 y, int16 width);
FillOrCopyStruct *fcs_alloc(uint x, uint y, uint w, uint h, uint flags, uint fill_color, uint unk4);
void render_string_amiga(uint vga_sprite_id, uint color, uint width, uint height, const char *txt);
void render_string(uint vga_sprite_id, uint color, uint width, uint height, const char *txt);
void setup_hit_areas(FillOrCopyStruct *fcs, uint fcs_index);
byte *setup_vga_destination(uint32 size);
void vga_buf_unk_proc3(byte *end);
void vga_buf_unk_proc1(byte *end);
void vga_buf_unk_proc2(uint a, byte *end);
void delete_memptr_range(byte *end);
void setup_vga_file_buf_pointers();
void run_vga_script();
public:
// Simon1/Simon2 video script opcodes
void vc1_dummy_op();
void vc2_call();
void vc3_loadSprite();
void vc4_dummy_op();
void vc5_skip_if_neq();
void vc6_skip_ifn_sib_with_a();
void vc7_skip_if_sib_with_a();
void vc8_skip_if_parent_is();
void vc9_skip_if_unk3_is();
void vc10_draw();
void vc11_clearPathFinder();
void vc12_delay();
void vc13_addToSpriteX();
void vc14_addToSpriteY();
void vc15_wakeup_id();
void vc16_sleep_on_id();
void vc17_setPathfinderItem();
void vc18_jump();
void vc19_chain_to_script();
void vc20_set_code_word();
void vc21_jump_if_code_word();
void vc22_setSpritePalette();
void vc23_setSpritePriority();
void vc24_setSpriteXY();
void vc25_halt_sprite();
void vc26_setWindow();
void vc27_resetSprite();
void vc28_dummy_op();
void vc29_stopAllSounds();
void vc30_setBaseDelay();
void vc31_setPaletteMode();
void vc32_copyVar();
void vc33_forceUnlock();
void vc34_forceLock();
void vc35();
void vc36_saveLoadDialog();
void vc37_addToSpriteY();
void vc38_skipIfVarZero();
void vc39_setVar();
void vc40();
void vc41();
void vc42_delayIfNotEQ();
void vc43_skipIfBitClear();
void vc44_skipIfBitSet();
void vc45_setSpriteX();
void vc46_setSpriteY();
void vc47_addToVar();
void vc48_setPathFinder();
void vc49_setBit();
void vc50_clearBit();
void vc51_clear_hitarea_bit_0x40();
void vc52_playSound();
void vc53_no_op();
void vc54_no_op();
void vc55_offset_hit_area();
void vc56_delay();
void vc57_no_op();
void vc58();
void vc59();
void vc60_killSprite();
void vc61_changeSprite();
void vc62_fadeOut();
void vc63_palette_thing_2();
// Simon2 specific Video Script Opcodes
void vc64_skipIfNoSpeech();
void vc65_palette_thing_3();
void vc66_skipIfNotEqual();
void vc67_skipIfGE();
void vc68_skipIfLE();
void vc69_playTrack();
void vc70_queueMusic();
void vc71_checkMusicQueue();
void vc72_play_track_2();
void vc73_setOp189Flag();
void vc74_clearOp189Flag();
protected:
void delete_vga_timer(VgaTimerEntry * vte);
void vc_resume_sprite(const byte *code_ptr, uint16 cur_file, uint16 cur_sprite);
int vc_read_var_or_word();
uint vc_read_next_word();
uint vc_read_next_byte();
uint vc_read_var(uint var);
void vc_write_var(uint var, int16 value);
void vc_skip_next_instruction();
bool itemIsSiblingOf(uint16 val);
bool itemIsParentOf(uint16 a, uint16 b);
bool vc_maybe_skip_proc_1(uint16 a, int16 b);
void add_vga_timer(uint num, const byte *code_ptr, uint cur_sprite, uint cur_file);
VgaSprite *find_cur_sprite();
void vc_set_bit_to(uint bit, bool value);
void expire_vga_timers();
bool isSpriteLoaded(uint16 id, uint16 fileId);
bool vc_get_bit(uint bit);
void fcs_setTextColor(FillOrCopyStruct *fcs, uint value);
void video_copy_if_flag_0x8_c(FillOrCopyStruct *fcs);
void delete_hitarea_by_index(uint index);
void fcs_unk_5(FillOrCopyStruct *fcs, uint fcs_index);
void fcs_putchar(uint a);
void copy_img_from_3_to_2(FillOrCopyStruct *fcs);
void video_erase(FillOrCopyStruct *fcs);
void dx_copy_rgn_from_3_to_2(uint b, uint r, uint y, uint x);
byte *dx_lock_2();
void dx_unlock_2();
byte *dx_lock_attached();
void dx_unlock_attached();
byte *read_vga_from_datfile_2(uint id);
void resfile_read(void *dst, uint32 offs, uint32 size);
int init(GameDetector &detector);
int go();
void openGameFile();
static int CDECL game_thread_proc(void *param);
void timer_callback();
void timer_proc1();
void timer_vga_sprites();
void timer_vga_sprites_2();
void dx_clear_surfaces(uint num_lines);
void dx_update_screen_and_palette();
void dump_video_script(const byte *src, bool one_opcode_only);
void dump_vga_file(const byte *vga);
void dump_vga_script(const byte *ptr, uint res, uint sprite_id);
void dump_vga_script_always(const byte *ptr, uint res, uint sprite_id);
void dump_vga_bitmaps(const byte *vga, byte *vga1, int res);
void dump_single_bitmap(int file, int image, const byte *offs, int w, int h, byte base);
void dx_clear_attached_from_top(uint lines);
void dx_copy_from_attached_to_2(uint x, uint y, uint w, uint h);
void dx_copy_from_attached_to_3(uint lines);
void dx_copy_from_2_to_attached(uint x, uint y, uint w, uint h);
void print_char_helper_1(const byte *src, uint len);
void print_char_helper_5(FillOrCopyStruct *fcs);
void quick_load_or_save();
void shutdown();
byte *vc10_depack_swap(const byte *src, uint w, uint h);
byte *vc10_no_depack_swap(const byte *src, uint w, uint h);
Item *getNextItemPtrStrange();
bool save_game(uint slot, char *caption);
bool load_game(uint slot);
void showmessage_helper_2();
void print_char_helper_6(uint i);
void video_putchar_newline(FillOrCopyStruct *fcs);
void video_putchar_drawchar(FillOrCopyStruct *fcs, uint x, uint y, byte chr);
void loadMusic(uint music);
void checkTimerCallback();
void delay(uint delay);
void pause();
void o_83_helper();
void o_190_helper(uint i);
void timer_vga_sprites_helper();
void decodeStripA(byte *dst, const byte *src, int height);
void scroll_timeout();
void hitarea_stuff_helper_2();
void realizePalette();
void fadeUpPalette();
void vc_kill_sprite(uint file, uint sprite);
void set_dummy_cursor();
void set_volume(int volume);
void save_or_load_dialog(bool load);
void o_unk_132_helper_3();
int o_unk_132_helper(bool *b, char *buf);
void o_clear_character(FillOrCopyStruct *fcs, int x, byte b = 0);
void savegame_dialog(char *buf);
void o_file_error(FillOrCopyStruct *fcs, bool save_error);
int count_savegames();
int display_savegame_list(int curpos, bool load, char *dst);
void show_it(void *buf);
char *gen_savename(int slot);
};
void palette_fadeout(uint32 *pal_values, uint num);
} // End of namespace Simon
#endif