aboutsummaryrefslogtreecommitdiff
path: root/simon
diff options
context:
space:
mode:
Diffstat (limited to 'simon')
-rw-r--r--simon/simon.cpp375
-rw-r--r--simon/simon.h27
2 files changed, 377 insertions, 25 deletions
diff --git a/simon/simon.cpp b/simon/simon.cpp
index 107970863d..9292edb3ab 100644
--- a/simon/simon.cpp
+++ b/simon/simon.cpp
@@ -111,20 +111,33 @@ uint fileReadItemID(FILE *in) {
return val + 2;
}
-FILE *fopen_maybe_lowercase(const char *filename) {
+
+/* debug code */
+void SimonState::show_it(void *buf) {
+ _system->copy_rect((byte*)buf, 320, 0, 0, 320, 200);
+ _system->update_screen();
+}
+
+FILE *SimonState::fopen_maybe_lowercase(const char *filename) {
+ char buf[256], *e;
+
+ const char *s = _game_path;
+
+ strcpy(buf, s);
+ e = strchr(buf, 0);
+ strcpy(e, filename);
+
#ifdef WIN32
/* win32 is not case sensitive */
- return fopen(filename, "rb");
+ return fopen(buf, "rb");
#else
/* first try with the original filename */
- FILE *in = fopen(filename, "rb");
- char buf[50], *s;
+ FILE *in = fopen(buf, "rb");
if (in) return in;
/* if that fails, convert the filename into lowercase and retry */
-
- s=buf;
- do *s++ = tolower(*filename++); while (filename[-1]);
+
+ do *e = tolower(*e); while(*e++);
return fopen(buf, "rb");
#endif
@@ -5762,14 +5775,299 @@ void SimonState::o_force_lock() {
}
void SimonState::o_save_game() {
- if (!save_game(123, "TEST"))
- error("save failed");
-// error("o_save_game: not implemented yet");
+ save_or_load_dialog(false);
}
void SimonState::o_load_game() {
- if (!load_game(123))
- error("load failed");
+ save_or_load_dialog(true);
+}
+
+
+int SimonState::o_unk_132_helper(bool *b, char *buf) {
+ HitArea *ha;
+
+ *b = true;
+
+
+ if (!_saveload_flag) {
+strange_jump:;
+ _saveload_flag = false;
+ savegame_dialog(buf);
+ }
+
+start_over:;
+ _key_pressed = 0;
+
+start_over_2:;
+ _last_hitarea = _last_hitarea_3 = 0;
+
+ do {
+ if (_key_pressed != 0) {
+ if (_saveload_flag) {
+ *b = false;
+ return _key_pressed;
+ }
+ goto start_over;
+ }
+ delay(100);
+ } while (_last_hitarea_3 == 0);
+
+ ha = _last_hitarea;
+
+ if (ha == NULL || ha->id < 205) goto start_over_2;
+
+ if (ha->id == 205) return ha->id;
+
+ if (ha->id == 206) {
+ if (_saveload_row_curpos == 1) goto start_over_2;
+ if (_saveload_row_curpos < 7) _saveload_row_curpos = 1;
+ else _saveload_row_curpos -= 6;
+
+ goto strange_jump;
+ }
+
+ if (ha->id == 207) {
+ if (!_savedialog_flag) goto start_over_2;
+ _saveload_row_curpos += 6;
+// if (_saveload_row_curpos >= _num_savegame_rows)
+// _saveload_row_curpos = _num_savegame_rows;
+ goto strange_jump;
+ }
+
+ if (ha->id >= 214) goto start_over_2;
+ return ha->id - 208;
+}
+
+void SimonState::o_unk_132_helper_3() {
+ for(int i=208; i!=208+6; i++)
+ set_hitarea_bit_0x40(i);
+}
+
+
+int SimonState::display_savegame_list(int curpos, bool load, char *dst) {
+ int slot, last_slot;
+ FILE *in;
+
+ showMessageFormat("\xC");
+
+ memset(dst, 0, 18*6);
+
+ slot = curpos;
+
+ while (curpos + 6 > slot) {
+ in = fopen(gen_savename(slot), "rb");
+ if (!in) break;
+
+ fread(dst, 1, 18, in);
+ fclose(in);
+ last_slot = slot;
+ if (slot < 10)
+ showMessageFormat(" ");
+ showMessageFormat("%d", slot);
+ showMessageFormat(".%s\n", dst);
+ dst+=18 ;
+ slot++;
+ }
+ /* while_break */
+ if (!load) {
+ if (curpos + 6 == slot)
+ slot++;
+ else {
+ if (slot < 10)
+ showMessageFormat(" ");
+ showMessageFormat("%d.\n", slot);
+ }
+ } else {
+ if (curpos +6 == slot) {
+ in = fopen(gen_savename(slot), "rb");
+ if (in != NULL) {
+ slot++;
+ fclose(in);
+ }
+ }
+ }
+
+ return slot - curpos;
+}
+
+
+void SimonState::savegame_dialog(char *buf) {
+ int i;
+
+ o_unk_132_helper_3();
+
+ i = display_savegame_list(_saveload_row_curpos, _save_or_load, buf);
+
+ _savedialog_flag = true;
+
+ if (i != 7) {
+ i++;
+ if (!_save_or_load)
+ i++;
+ _savedialog_flag = false;
+ }
+
+ if (!--i)
+ return;
+
+ do {
+ clear_hitarea_bit_0x40(0xd0 + i - 1);
+ } while (--i);
+}
+
+void SimonState::o_unk_132_helper_2(FillOrCopyStruct *fcs, int x) {
+ byte old_text;
+
+ video_putchar(fcs, x);
+ old_text = fcs->text_color;
+ fcs->text_color = fcs->fill_color;
+
+ x += 120;
+ if (x != 128) x=129;
+ video_putchar(fcs, x);
+
+ fcs->text_color = old_text;
+ video_putchar(fcs, 8);
+}
+
+void SimonState::save_or_load_dialog(bool load) {
+ time_t save_time;
+ int num = _number_of_savegames;
+ int i;
+ int unk132_result;
+ FillOrCopyStruct *fcs;
+ char *name;
+ int name_len;
+ bool b;
+ char buf[108];
+
+ _save_or_load = load;
+
+ save_time = time(NULL);
+
+ _copy_partial_mode = 1;
+
+ num = _number_of_savegames;
+ if (!load) num++;
+ num -= 6;
+ if (num<0) num = 0;
+ num++;
+ _num_savegame_rows = num;
+
+ _saveload_row_curpos = 1;
+ if (!load)
+ _saveload_row_curpos = num;
+
+ _saveload_flag = false;
+
+restart:;
+ do {
+ i = o_unk_132_helper(&b, buf);
+ } while (!b);
+
+ if (i == 205) goto get_out;
+ if (!load) {
+ /* if_1 */
+if_1:;
+ unk132_result = i;
+
+ set_hitarea_bit_0x40(0xd0 + i);
+ leaveHitAreaById(0xd0 + i);
+
+ /* some code here */
+
+ fcs = _fcs_ptr_array_3[5];
+
+ fcs->unk2 = unk132_result;
+ fcs->unk1 = 2;
+ fcs->unk3 = 2;
+ fcs->unk6 = 3;
+
+ name = buf + i * 18;
+
+ name_len = 0;
+ while (name[name_len]) {
+ fcs->unk6++;
+ fcs->unk3 += 4;
+ if (name[name_len] == 'i' || name[name_len] == 'l')
+ fcs->unk3 += 2;
+ if (fcs->unk3 >= 8) {
+ fcs->unk3 -= 8;
+ fcs->unk1++;
+ }
+ name_len++;
+ }
+ /* while_1_end */
+
+ /* do_3_start */
+ for(;;) {
+ video_putchar(fcs, 0x7f);
+
+ _saveload_flag = true;
+
+ /* do_2 */
+ do {
+ i = o_unk_132_helper(&b, buf);
+
+ if (b) {
+ if (i == 205) goto get_out;
+ clear_hitarea_bit_0x40(0xd0 + unk132_result);
+ if (_saveload_flag) {
+ o_unk_132_helper_2(_fcs_ptr_array_3[5], 8);
+ /* move code */
+ } goto if_1;
+ }
+
+ /* is_not_b */
+ if (!_saveload_flag) {
+ clear_hitarea_bit_0x40(0xd0 + unk132_result);
+ goto restart;
+ }
+ } while (i >= 0x80 || i == 0);
+
+ /* after_do_2 */
+ o_unk_132_helper_2(_fcs_ptr_array_3[5], 8);
+ if (i==10 || i==13) break;
+ if (i==8) {
+ /* do_backspace */
+ if (name_len != 0) {
+ int x;
+
+ name_len--;
+
+ x = (name[name_len] == 'i' || name[name_len]=='l') ? 1 : 8;
+ name[name_len] = 0;
+
+ o_unk_132_helper_2(_fcs_ptr_array_3[5], x);
+ }
+ } else if (i>=32 && name_len!=17) {
+ name[name_len++] = i;
+
+ video_putchar(_fcs_ptr_array_3[5], i);
+ }
+ }
+
+ /* do_save */
+ if (!save_game(_saveload_row_curpos + unk132_result, buf + unk132_result * 18))
+ warning("Save failed");
+ } else {
+ if (!load_game(_saveload_row_curpos + i))
+ warning("Load failed");
+ }
+
+get_out:;
+ o_unk_132_helper_3();
+// clear_keydowns();
+
+ _base_time = time(NULL) - save_time + _base_time;
+ _copy_partial_mode = 0;
+
+ dx_copy_rgn_from_3_to_2(94, 208, 46, 80);
+
+ i = _timer_4;
+ do {
+ delay(10);
+ } while (i == _timer_4);
}
void SimonState::o_unk_127() {
@@ -5998,10 +6296,16 @@ void SimonState::timer_proc1() {
timer_vga_sprites_2();
#endif
- if (!(_game&GAME_SIMON2) && _copy_partial_mode==2) {
- /* copy partial from attached to 2 */
- dx_copy_from_attached_to_2(176, 61, 320-176, 134-61);
- _copy_partial_mode = 0;
+ if (!(_game&GAME_SIMON2)) {
+ if (_copy_partial_mode == 1) {
+ dx_copy_from_2_to_attached(80, 46, 208-80, 94-46);
+ }
+
+ if (_copy_partial_mode==2) {
+ /* copy partial from attached to 2 */
+ dx_copy_from_attached_to_2(176, 61, 320-176, 134-61);
+ _copy_partial_mode = 0;
+ }
}
/* XXX: more stuff here */
@@ -6213,6 +6517,10 @@ void SimonState::o_pathfind(int x,int y,uint var_1,uint var_2) {
uint x_diff, y_diff;
uint best_i=0, best_j=0, best_dist = 0xFFFFFFFF;
+ if (_game & GAME_SIMON2) {
+ x += _x_scroll * 8;
+ }
+
prev_i = 21 - _variableArray[12];
for(i=20; i!=0; --i) {
p = (uint16*)_pathfind_array[20-i];
@@ -6798,6 +7106,7 @@ void SimonState::video_putchar_helper_2(FillOrCopyStruct *fcs, uint x, uint y, b
} while (--h);
dx_unlock_2();
+
_lock_word &= ~0x8000;
}
@@ -7504,6 +7813,19 @@ void SimonState::dx_copy_from_attached_to_2(uint x, uint y, uint w, uint h) {
} while(--h);
}
+void SimonState::dx_copy_from_2_to_attached(uint x, uint y, uint w, uint h) {
+ uint offs = x + y*320;
+ byte *s = sdl_buf + offs;
+ byte *d = sdl_buf_attached + offs;
+
+ do {
+ memcpy(d,s,w);
+ d+=320;
+ s+=320;
+ } while(--h);
+}
+
+
void SimonState::dx_copy_from_attached_to_3(uint lines) {
memcpy(sdl_buf_3, sdl_buf_attached, lines*320);
@@ -7633,6 +7955,7 @@ void SimonState::delay(uint delay) {
_fast_mode^=1;
}
}
+ _key_pressed = (byte)event.kbd.ascii;
break;
case OSystem::EVENT_MOUSEMOVE:
sdl_mouse_x = event.mouse.x;
@@ -7663,18 +7986,15 @@ void SimonState::delay(uint delay) {
bool SimonState::save_game(uint slot, const char *caption) {
- char filename[32];
FILE *f;
uint item_index, num_item, i;
TimeEvent *te;
_lock_word |= 0x100;
-
- sprintf(filename, "SAVE.%.3d", slot);
errno = 0;
- f = fopen(filename, "wb");
+ f = fopen(gen_savename(slot), "wb");
if (f==NULL)
return false;
@@ -7759,19 +8079,22 @@ bool SimonState::save_game(uint slot, const char *caption) {
return true;
}
+char *SimonState::gen_savename(int slot) {
+ static char buf[128];
+ sprintf(buf, "SAVE.%.3d", slot);
+ return buf;
+}
+
bool SimonState::load_game(uint slot) {
- char filename[32];
char ident[18];
FILE *f;
uint num, item_index, i;
_lock_word |= 0x100;
-
- sprintf(filename, "SAVE.%.3d", slot);
errno = 0;
- f = fopen_maybe_lowercase(filename);
+ f = fopen_maybe_lowercase(gen_savename(slot));
if (f==NULL)
return false;
@@ -8785,7 +9108,9 @@ SimonState *SimonState::create(OSystem *syst, MidiDriver *driver) {
s->midi.set_driver(driver);
/* Setup mixer */
- s->_mixer->bind_to_system(syst);
+ if (!s->_mixer->bind_to_system(syst))
+ warning("Sound initialization failed. "
+ "Features of the game that depend on sound synchronization will most likely break");
return s;
diff --git a/simon/simon.h b/simon/simon.h
index 9709ace991..a534beba90 100644
--- a/simon/simon.h
+++ b/simon/simon.h
@@ -350,6 +350,8 @@ class SimonState {
public:
OSystem *_system;
+ char *_game_path;
+
byte *_vc_ptr; /* video code ptr */
uint32 *_game_offsets_ptr;
@@ -357,6 +359,7 @@ public:
const GameSpecificSettings *gss;
byte _game;
+ byte _key_pressed;
enum {
GAME_SIMON2 = 1,
@@ -391,6 +394,7 @@ public:
byte *_tbl_list;
byte *_code_ptr;
+
byte **_local_stringtable;
uint _string_id_local_min, _string_id_local_max;
@@ -593,6 +597,14 @@ public:
FILE *_dump_file;
+ int _number_of_savegames;
+
+ int _saveload_row_curpos;
+ int _num_savegame_rows;
+ bool _savedialog_flag;
+ bool _save_or_load;
+ bool _saveload_flag;
+
int allocGamePcVars(FILE *in);
Item *allocItem1();
void loginPlayerHelper(Item *item, int a, int b);
@@ -983,6 +995,7 @@ public:
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);
@@ -1036,6 +1049,20 @@ public:
void set_dummy_cursor();
void set_volume(byte volume);
+
+ FILE *fopen_maybe_lowercase(const char *filename);
+
+ void save_or_load_dialog(bool load);
+ void o_unk_132_helper_3();
+ int o_unk_132_helper(bool *b, char *buf);
+ void o_unk_132_helper_2(FillOrCopyStruct *fcs, int x);
+ void savegame_dialog(char *buf);
+
+ int display_savegame_list(int curpos, bool load, char *dst);
+
+ void show_it(void *buf);
+
+ char *gen_savename(int slot);
};