diff options
-rw-r--r-- | gameDetector.cpp | 3 | ||||
-rw-r--r-- | gfx.cpp | 25 | ||||
-rw-r--r-- | main.cpp | 1 | ||||
-rw-r--r-- | morphos/morphos.cpp | 4 | ||||
-rw-r--r-- | morphos/morphos.h | 2 | ||||
-rw-r--r-- | resource.cpp | 2 | ||||
-rw-r--r-- | scumm.h | 8 | ||||
-rw-r--r-- | scummvm.cpp | 12 | ||||
-rw-r--r-- | sdl.cpp | 13 | ||||
-rw-r--r-- | simon/simon.cpp | 375 | ||||
-rw-r--r-- | simon/simon.h | 27 | ||||
-rw-r--r-- | sound/mixer.cpp | 4 | ||||
-rw-r--r-- | sound/mixer.h | 2 | ||||
-rw-r--r-- | system.h | 2 |
14 files changed, 410 insertions, 70 deletions
diff --git a/gameDetector.cpp b/gameDetector.cpp index 273fd112f3..5c395cbd4d 100644 --- a/gameDetector.cpp +++ b/gameDetector.cpp @@ -380,8 +380,7 @@ int GameDetector::detectMain(int argc, char **argv) if (!_gameDataPath) { warning("No path was provided. Assuming that data file are in the current directory"); - _gameDataPath = (char *)malloc(sizeof(char) * 2); - strcpy(_gameDataPath, ""); + _gameDataPath = strdup(""); } return (0); @@ -157,31 +157,6 @@ void Scumm::drawDirtyScreenParts() } } -void Scumm::redrawLines(int from, int to) -{ - VirtScreen *vs = virtscr; - int i, j; - - if (to <= from) - return; - - for (i = 0; i != ARRAYSIZE(virtscr); i++, vs++) { - if (to > vs->topline && from < vs->topline + vs->height) { - int min = from - vs->topline; - int max = to - vs->topline; - if (min < 0) - min = 0; - if (max > vs->height) - max = vs->height; - for (j = 0; j != 40; j++) { - vs->tdirty[j] = min; - vs->bdirty[j] = max; - } - gdi.updateDirtyScreen(vs); - } - } -} - void Scumm::updateDirtyScreen(int slot) { gdi.updateDirtyScreen(&virtscr[slot]); @@ -70,6 +70,7 @@ int main(int argc, char *argv[]) SimonState *simon = SimonState::create(system, midi); simon->_game = detector._gameId - GID_SIMON_FIRST; simon->set_volume(detector._sfx_volume); + simon->_game_path = detector._gameDataPath; simon->go(); } else { diff --git a/morphos/morphos.cpp b/morphos/morphos.cpp index 8887db05d2..10b8fbda12 100644 --- a/morphos/morphos.cpp +++ b/morphos/morphos.cpp @@ -1562,7 +1562,7 @@ void OSystem_MorphOS::set_mouse_cursor(const byte *buf, uint w, uint h, int hots undraw_mouse(); } -void OSystem_MorphOS::set_sound_proc( void *param, OSystem::SoundProc *proc, byte format ) +bool OSystem_MorphOS::set_sound_proc( void *param, OSystem::SoundProc *proc, byte format ) { static EmulFunc MySoundEmulFunc; @@ -1587,6 +1587,8 @@ void OSystem_MorphOS::set_sound_proc( void *param, OSystem::SoundProc *proc, byt puts( "Failed to create sound thread" ); exit( 1 ); } + + return true; } void OSystem_MorphOS::fill_sound( byte *stream, int len ) diff --git a/morphos/morphos.h b/morphos/morphos.h index be198f4715..c720a990ae 100644 --- a/morphos/morphos.h +++ b/morphos/morphos.h @@ -72,7 +72,7 @@ class OSystem_MorphOS : public OSystem virtual bool poll_event(Event *event); // Set the function to be invoked whenever samples need to be generated - virtual void set_sound_proc(void *param, SoundProc *proc, byte format); + virtual bool set_sound_proc(void *param, SoundProc *proc, byte format); void fill_sound (byte * stream, int len); virtual uint32 property(int param, uint32 value); diff --git a/resource.cpp b/resource.cpp index 0cb921879b..5edf1e1776 100644 --- a/resource.cpp +++ b/resource.cpp @@ -737,7 +737,7 @@ int Scumm::getResourceDataSize(byte *ptr) if (_features & GF_SMALL_HEADER) return READ_LE_UINT32(ptr) - 6; else - return READ_BE_UINT32(ptr - 4) - 8; + return READ_BE_UINT32_UNALIGNED(ptr - 4) - 8; } struct FindResourceState { @@ -82,7 +82,7 @@ struct ResHdr { } GCC_PACK; #define RES_DATA(x) (((byte*)x) + sizeof(ResHdr)) -#define RES_SIZE(x) ( READ_BE_UINT32(&((ResHdr*)x)->size) ) +#define RES_SIZE(x) ( READ_BE_UINT32_UNALIGNED(&((ResHdr*)x)->size) ) struct RoomHeader { @@ -594,10 +594,7 @@ public: char *getGameName(); Scumm(); // constructor - /* video buffer */ - byte _videoBuffer[328*200]; // main video buffer - - /* system call object */ + byte *_videoBuffer; /* Scumm main loop */ @@ -1122,7 +1119,6 @@ public: void restoreBG(int left, int top, int right, int bottom); void redrawBGStrip(int start, int num); void redrawBGAreas(); - void redrawLines(int from, int to); void moveCamera(); void cameraMoved(); diff --git a/scummvm.cpp b/scummvm.cpp index 808cde2a5b..727e98fc64 100644 --- a/scummvm.cpp +++ b/scummvm.cpp @@ -63,6 +63,7 @@ void Scumm::scummInit() if (!(_features & GF_SMALL_NAMES)) loadCharset(1); + initScreens(0, 16, 320, 144); setShake(0); @@ -1211,6 +1212,7 @@ void Scumm::launch() _minHeapThreshold = 400000; /* Create a primary virtual screen */ + _videoBuffer = (byte*)malloc(328*200); allocResTypeData(rtBuffer, MKID('NONE'), 10, "buffer", 0); initVirtScreen(0, 0, 200, false, false); @@ -1286,7 +1288,15 @@ Scumm *Scumm::createFromDetector(GameDetector *detector, OSystem *syst) /* bind the mixer to the system => mixer will be invoked * automatically when samples need to be generated */ - scumm->_mixer->bind_to_system(syst); + if (!scumm->_mixer->bind_to_system(syst)) { + warning("Sound initialization failed"); + if (detector->_use_adlib) { + detector->_use_adlib = false; + detector->_midi_driver = MD_NULL; + warning("Adlib music was selected, switching to midi null driver"); + } + } + scumm->_mixer->set_volume(128); scumm->_fullScreen = detector->_fullScreen; @@ -52,7 +52,7 @@ public: bool poll_event(Event *event); // Set function that generates samples - void set_sound_proc(void *param, SoundProc *proc, byte sound); + bool set_sound_proc(void *param, SoundProc *proc, byte sound); // Quit void quit(); @@ -458,6 +458,8 @@ void OSystem_SDL::mk_checksums(const byte *buf) { void OSystem_SDL::add_dirty_rgn_auto(const byte *buf) { + assert( ((uint32)buf & 3) == 0); + /* generate a table of the checksums */ mk_checksums(buf); @@ -713,7 +715,7 @@ bool OSystem_SDL::poll_event(Event *event) { } } -void OSystem_SDL::set_sound_proc(void *param, SoundProc *proc, byte format) { +bool OSystem_SDL::set_sound_proc(void *param, SoundProc *proc, byte format) { SDL_AudioSpec desired; /* only one format supported at the moment */ @@ -724,8 +726,11 @@ void OSystem_SDL::set_sound_proc(void *param, SoundProc *proc, byte format) { desired.samples = 2048; desired.callback = proc; desired.userdata = param; - SDL_OpenAudio(&desired, NULL); + if (SDL_OpenAudio(&desired, NULL) != 0) { + return false; + } SDL_PauseAudio(0); + return true; } @@ -1031,7 +1036,7 @@ public: void delay_msecs(uint msecs); void *create_thread(ThreadProc *proc, void *param) { return NULL; } bool poll_event(Event *event) { return false; } - void set_sound_proc(void *param, SoundProc *proc, byte sound) {} + bool set_sound_proc(void *param, SoundProc *proc, byte sound) {} void quit() { exit(1); } uint32 property(int param, uint32 value) { return 0; } static OSystem *create(int gfx_mode, bool full_screen); 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); }; diff --git a/sound/mixer.cpp b/sound/mixer.cpp index add23d9e91..084dced7d8 100644 --- a/sound/mixer.cpp +++ b/sound/mixer.cpp @@ -55,7 +55,7 @@ void SoundMixer::on_generate_samples(void *s, byte *samples, int len) { ((SoundMixer*)s)->mix((int16*)samples, len>>1); } -void SoundMixer::bind_to_system(OSystem *syst) { +bool SoundMixer::bind_to_system(OSystem *syst) { _volume_table = (int16*)calloc(256*sizeof(int16),1); uint rate = (uint)syst->property(OSystem::PROP_GET_SAMPLE_RATE, 0); @@ -65,7 +65,7 @@ void SoundMixer::bind_to_system(OSystem *syst) { if (rate == 0) error("OSystem returned invalid sample rate"); - syst->set_sound_proc(this, on_generate_samples, OSystem::SOUND_16BIT); + return syst->set_sound_proc(this, on_generate_samples, OSystem::SOUND_16BIT); } void SoundMixer::stop_all() { diff --git a/sound/mixer.h b/sound/mixer.h index e2002a9e87..9894d20a87 100644 --- a/sound/mixer.h +++ b/sound/mixer.h @@ -90,7 +90,7 @@ public: /* bind to the OSystem object => mixer will be * invoked automatically when samples need * to be generated */ - void bind_to_system(OSystem *syst); + bool bind_to_system(OSystem *syst); /* set the volume, 0-256 */ void set_volume(int volume); @@ -89,7 +89,7 @@ public: // Set the function to be invoked whenever samples need to be generated // Format is the sample type format. // Only 16-bit signed mode is needed for simon & scumm - virtual void set_sound_proc(void *param, SoundProc *proc, byte format) = 0; + virtual bool set_sound_proc(void *param, SoundProc *proc, byte format) = 0; // Get or set a property virtual uint32 property(int param, uint32 value) = 0; |