diff --git a/src/emscripten/mako.cpp b/src/emscripten/mako.cpp index 1a71362..252f1d5 100644 --- a/src/emscripten/mako.cpp +++ b/src/emscripten/mako.cpp @@ -27,7 +27,10 @@ MAKO::MAKO(NACT* parent, const Config& config) : nact(parent) { g_mako = this; - strcpy(amus, "AMUS.DAT"); + amus.open("AMUS.DAT"); + awav.open("AWAV.DAT"); + amse.open("AMSE.DAT"); + mda.open("AMUS.MDA"); for (int i = 1; i <= 99; i++) cd_track[i] = 0; } @@ -50,7 +53,7 @@ void MAKO::play_music(int page) EM_ASM_ARGS({ xsystem35.cdPlayer.play($0, $1); }, cd_track[page] + 1, next_loop ? 0 : 1); } else { - std::vector data = dri_load(amus, page); + std::vector data = amus.load(page); if (data.empty()) return; int rate = EM_ASM_INT({ return xsystem35.audio.enable_audio_hook(); }); @@ -109,9 +112,9 @@ void MAKO::play_pcm(int page, bool loop) }; // WAV形式 (Only You) - std::vector wav_buffer = dri_load("AWAV.DAT", page); + std::vector wav_buffer = awav.load(page); if (wav_buffer.empty()) { - std::vector buffer = dri_load("AMSE.DAT", page); + std::vector buffer = amse.load(page); if (!buffer.empty()) { // AMSE形式 (乙女戦記) int samples = (buffer.size() - 12) * 2; diff --git a/src/generic/mako.cpp b/src/generic/mako.cpp index 856539c..7c99029 100644 --- a/src/generic/mako.cpp +++ b/src/generic/mako.cpp @@ -43,8 +43,10 @@ MAKO::MAKO(NACT* parent, const Config& config) : if (!config.playlist.empty() && load_playlist(config.playlist.c_str())) mix_init_flags |= MIX_INIT_MP3 | MIX_INIT_OGG; - strcpy(amus, "AMUS.DAT"); - strcpy(amse, "AMSE.DAT"); // unused + amus.open("AMUS.DAT"); + awav.open("AWAV.DAT"); + amse.open("AMSE.DAT"); + mda.open("AMUS.MDA"); for (int i = 1; i <= 99; i++) cd_track[i] = 0; @@ -117,7 +119,7 @@ void MAKO::play_music(int page) } } } else if (use_fm) { - std::vector data = dri_load(amus, page); + std::vector data = amus.load(page); if (data.empty()) return; if (!fm_mutex) @@ -128,7 +130,7 @@ void MAKO::play_music(int page) SDL_UnlockMutex(fm_mutex); Mix_HookMusic(&FMHook, this); } else if (midi->is_available()) { - if (!midi->play(nact, amus, page, next_loop)) + if (!midi->play(nact, amus, mda, page, next_loop)) return; } @@ -193,14 +195,14 @@ void MAKO::play_pcm(int page, bool loop) stop_pcm(); - std::vector buffer = dri_load("AWAV.DAT", page); + std::vector buffer = awav.load(page); if (!buffer.empty()) { // WAV形式 (Only You) mix_chunk = Mix_LoadWAV_RW(SDL_RWFromConstMem(buffer.data(), buffer.size()), 1 /* freesrc */); Mix_PlayChannel(-1, mix_chunk, loop ? -1 : 0); return; } - buffer = dri_load("AMSE.DAT", page); + buffer = amse.load(page); if (!buffer.empty()) { // AMSE形式 (乙女戦記) int samples = (buffer.size() - 12) * 2; diff --git a/src/sys/ags.cpp b/src/sys/ags.cpp index 5311494..2c85843 100644 --- a/src/sys/ags.cpp +++ b/src/sys/ags.cpp @@ -159,8 +159,7 @@ AGS::AGS(NACT* parent, const Config& config) : nact(parent), dirty(false) // SYSTEM3 初期化 - // ACG.DAT - strcpy_s(acg, 16, "ACG.DAT"); + acg.open("ACG.DAT"); // パレット memset(program_palette, 0, sizeof(program_palette)); @@ -429,6 +428,22 @@ AGS::~AGS() SDL_DestroyTexture(sdlTexture); } +void AGS::set_cg_file(const char *file_name) +{ + bmp_prefix = NULL; + if (nact->sys_ver == 3) { + // あゆみちゃん物語 フルカラー実写版 + if (!strcmp(file_name, "CGA000.BMP")) { + bmp_prefix = "CGA"; + return; + } else if (!strcmp(file_name, "CGB000.BMP")) { + bmp_prefix = "CGB"; + return; + } + } + acg.open(file_name); +} + void AGS::set_palette(int index, int r, int g, int b) { if(index < 16) { diff --git a/src/sys/ags.h b/src/sys/ags.h index 8ca0bfa..fa893a2 100644 --- a/src/sys/ags.h +++ b/src/sys/ags.h @@ -7,9 +7,11 @@ #ifndef _AGS_H_ #define _AGS_H_ +#include #include #include "../common.h" #include "nact.h" +#include "dri.h" #include #define MAX_CG 10000 @@ -95,6 +97,7 @@ public: void flush_screen(bool update); void load_cg(int page, int transparent); + void set_cg_file(const char *file_name); void set_palette(int index, int r, int g, int b); uint8 get_pixel(int dest, int x, int y); @@ -136,9 +139,6 @@ public: bool dirty; - // ACG.DAT - char acg[16]; - // 画面選択 int src_screen; int dest_screen; @@ -216,6 +216,10 @@ public: // マウスカーソル uint8 cursor_color; int cursor_index; + +private: + Dri acg; + const char* bmp_prefix = NULL; }; extern "C" void ags_setAntialiasedStringMode(int on); diff --git a/src/sys/ags_draw.cpp b/src/sys/ags_draw.cpp index 90b5a0d..81c9885 100644 --- a/src/sys/ags_draw.cpp +++ b/src/sys/ags_draw.cpp @@ -15,21 +15,13 @@ void AGS::load_cg(int page, int transparent) { - if (nact->sys_ver == 3) { - // あゆみちゃん物語 フルカラー実写版 - if(strncmp(acg, "CGA000.BMP", 10) == 0) { - char file_name[16]; - snprintf(file_name, sizeof(file_name), "CGA%03d.BMP", page); - load_bmp(file_name); - return; - } else if(strncmp(acg, "CGB000.BMP", 10) == 0) { - char file_name[16]; - snprintf(file_name, sizeof(file_name), "CGB%03d.BMP", page); - load_bmp(file_name); - return; - } + if (bmp_prefix) { + char file_name[16]; + snprintf(file_name, sizeof(file_name), "%s%03d.BMP", bmp_prefix, page); + load_bmp(file_name); + return; } - std::vector data = dri_load(acg, page); + std::vector data = acg.load(page); if (data.empty()) return; switch (nact->sys_ver) { diff --git a/src/sys/dri.cpp b/src/sys/dri.cpp index 7c4873f..0c45391 100644 --- a/src/sys/dri.cpp +++ b/src/sys/dri.cpp @@ -5,83 +5,63 @@ */ #include "dri.h" +#include #include #include "crc32.h" #include "../fileio.h" -std::vector dri_load(const char* file_name, int page) +void Dri::open(const char* file_name) { - char tmp_name[20]; - strcpy_s(tmp_name, sizeof(tmp_name), file_name); + link_table.clear(); + fname = file_name; + fname[0] = 'A'; - FILEIO* fio = new FILEIO(); - - // ページの位置を取得 - tmp_name[0] = 'A'; - if(!fio->Fopen(tmp_name, FILEIO_READ_BINARY)) { - delete fio; - return {}; - } + auto fio = std::make_unique(); + if (!fio->Fopen(fname.c_str(), FILEIO_READ_BINARY)) + return; int link_sector = fio->Fgetc(); link_sector |= fio->Fgetc() << 8; int data_sector = fio->Fgetc(); data_sector |= fio->Fgetc() << 8; - if(page > (data_sector - link_sector) * 128 - 1) { - // ページ番号不正 - fio->Fclose(); - delete fio; + link_table.resize((data_sector - link_sector) * 256); + fio->Fseek((link_sector - 1) * 256, FILEIO_SEEK_SET); + fio->Fread(link_table.data(), 256, data_sector - link_sector); +} + +std::vector Dri::load(int page) +{ + if (static_cast(page) >= link_table.size() / 2) return {}; - } - fio->Fseek((link_sector - 1) * 256 + (page - 1) * 2, FILEIO_SEEK_SET); - int disk_index = fio->Fgetc(); - int link_index = fio->Fgetc(); - - if(disk_index == 0 || disk_index == 0x1a) { - // 欠番 - fio->Fclose(); - delete fio; + int disk_index = link_table[(page - 1) * 2]; + int link_index = link_table[(page - 1) * 2 + 1]; + if (disk_index == 0 || disk_index == 0x1a) return {}; - } - // A??.DAT以外にリンクされている場合はファイルを開き直す - if(disk_index != 1) { - tmp_name[0] = 'A' + disk_index - 1; - fio->Fclose(); - if(!fio->Fopen(tmp_name, FILEIO_READ_BINARY)) { - delete fio; - return {}; - } - } + auto fio = std::make_unique(); + fname[0] = 'A' + disk_index - 1; + if (!fio->Fopen(fname.c_str(), FILEIO_READ_BINARY)) + return {}; - // データ取得 fio->Fseek(link_index * 2, FILEIO_SEEK_SET); int start_sector = fio->Fgetc(); start_sector |= fio->Fgetc() << 8; int end_sector = fio->Fgetc(); end_sector |= fio->Fgetc() << 8; - - int size = (end_sector - start_sector) * 256; - if (size == 0) { - // サイズ不正 - fio->Fclose(); - delete fio; + if (end_sector <= start_sector) return {}; - } - std::vector buffer(size); + std::vector buffer((end_sector - start_sector) * 256); fio->Fseek((start_sector - 1) * 256, FILEIO_SEEK_SET); fio->Fread(buffer.data(), 256, end_sector - start_sector); - fio->Fclose(); - delete fio; - return buffer; } -std::vector dri_load_mda(uint32_t crc32_a, uint32_t crc32_b, int page) +// static +std::vector Dri::load_mda(uint32_t crc32_a, uint32_t crc32_b, int page) { // データ取得 const char* name = NULL; diff --git a/src/sys/dri.h b/src/sys/dri.h index a2e814b..b60c461 100644 --- a/src/sys/dri.h +++ b/src/sys/dri.h @@ -7,10 +7,20 @@ #ifndef _DRI_H_ #define _DRI_H_ +#include #include #include -std::vector dri_load(const char* file_name, int page); -std::vector dri_load_mda(uint32_t crc32_a, uint32_t crc32_b, int page); +class Dri { +public: + void open(const char* file_name); + std::vector load(int page); + + static std::vector load_mda(uint32_t crc32_a, uint32_t crc32_b, int page); + +private: + std::string fname; + std::vector link_table; +}; #endif diff --git a/src/sys/mako.h b/src/sys/mako.h index 0847c1e..cda2a3a 100644 --- a/src/sys/mako.h +++ b/src/sys/mako.h @@ -7,12 +7,14 @@ #ifndef _MAKO_H_ #define _MAKO_H_ +#include #include #include #include #include #include "../common.h" #include "nact.h" +#include "dri.h" enum BGMDevice { BGM_FM, @@ -46,9 +48,10 @@ public: bool use_fm; - // AMUS.DAT, AMSE.DAT - char amus[16]; - char amse[16]; + Dri amus; + Dri awav; + Dri amse; + Dri mda; int current_music; int next_loop; // Y19 @@ -57,7 +60,7 @@ private: NACT* nact; int cd_track[100]; // Z -#if !defined(__EMSCRIPTEN__) +#ifndef __EMSCRIPTEN__ bool load_playlist(const char* path); std::vector playlist; diff --git a/src/sys/mako_midi.cpp b/src/sys/mako_midi.cpp index 9b3dba5..14b5c16 100644 --- a/src/sys/mako_midi.cpp +++ b/src/sys/mako_midi.cpp @@ -93,7 +93,7 @@ void stop_midi() class Playback { public: - static std::unique_ptr create(NACT* nact, char* amus, int page, int loop, int seq); + static std::unique_ptr create(NACT* nact, Dri& amus, Dri& mda, int page, int loop, int seq); Playback(uint32_t crc32_a, int loop, int seq) : crc32_a(crc32_a), loop_(loop), seq_(seq) {} bool load_mml(const std::vector& data); void load_mda(const std::vector& data); @@ -379,23 +379,20 @@ bool Playback::play_midi(SDL_atomic_t* current_loop, SDL_atomic_t* current_mark) } //static -std::unique_ptr Playback::create(NACT* nact, char* amus, int page, int loop, int seq) +std::unique_ptr Playback::create(NACT* nact, Dri& amus, Dri& mda, int page, int loop, int seq) { auto playback = std::make_unique(nact->crc32_a, loop, seq); - std::vector data = dri_load(amus, page); + std::vector data = amus.load(page); if (data.empty()) return nullptr; if (!playback->load_mml(data)) return nullptr; // Load MDA - char path[16]; - strcpy_s(path, 16, amus); - strcpy(path + strlen(path) - 3, "MDA"); - data = dri_load(path, page); + data = mda.load(page); if (data.empty()) - data = dri_load_mda(nact->crc32_a, nact->crc32_b, page); + data = Dri::load_mda(nact->crc32_a, nact->crc32_b, page); playback->load_mda(data); return playback; @@ -663,10 +660,10 @@ bool MAKOMidi::is_available() return !!midiout; } -bool MAKOMidi::play(NACT* nact, char* amus, int page, int loop) +bool MAKOMidi::play(NACT* nact, Dri& amus, Dri& mda, int page, int loop) { int seq = ++next_seq; - auto playback = Playback::create(nact, amus, page, loop, seq); + auto playback = Playback::create(nact, amus, mda, page, loop, seq); if (!playback) return false; SDL_AtomicSet(¤t_seq, seq); diff --git a/src/sys/mako_midi.h b/src/sys/mako_midi.h index 87c6c82..41a0712 100644 --- a/src/sys/mako_midi.h +++ b/src/sys/mako_midi.h @@ -7,6 +7,7 @@ #include "../common.h" class NACT; +class Dri; #ifdef USE_MIDI @@ -15,7 +16,7 @@ public: explicit MAKOMidi(int device); ~MAKOMidi(); bool is_available(); - bool play(NACT* nact, char* amus, int page, int loop); + bool play(NACT* nact, Dri& amus, Dri& mda, int page, int loop); void stop(); bool is_playing(); void get_mark(int* mark, int* loop); @@ -40,7 +41,7 @@ class MAKOMidi { public: explicit MAKOMidi(int device) {} bool is_available() { return false; } - bool play(NACT* nact, char* amus, int page, int loop) { return false; } + bool play(NACT* nact, Dri& amus, Dri& mda, int page, int loop) { return false; } void stop() {} bool is_playing() { return false; } void get_mark(int* mark, int* loop) { *mark = *loop = 0; } diff --git a/src/sys/nact.cpp b/src/sys/nact.cpp index 265c603..dd7695a 100644 --- a/src/sys/nact.cpp +++ b/src/sys/nact.cpp @@ -54,9 +54,9 @@ NACT::NACT(int sys_ver, uint32 crc32_a, uint32 crc32_b, const Config& config) // ADISK.DAT if (crc32_a == CRC32_PROG_OMAKE) - strcpy_s(adisk, 16, "AGAME.DAT"); + adisk.open("AGAME.DAT"); else - strcpy_s(adisk, 16, "ADISK.DAT"); + adisk.open("ADISK.DAT"); // シナリオ管理 load_scenario(0); @@ -387,7 +387,7 @@ void NACT::text_wait() void NACT::load_scenario(int page) { - scenario_data = dri_load(adisk, page + 1); + scenario_data = adisk.load(page + 1); if (scenario_data.empty()) { fatal("Cannot load scenario %d", page); } diff --git a/src/sys/nact.h b/src/sys/nact.h index c87b66b..dd73504 100644 --- a/src/sys/nact.h +++ b/src/sys/nact.h @@ -13,6 +13,7 @@ #include #include "../common.h" #include "config.h" +#include "dri.h" #define RND var[ 0] #define D01 var[ 1] @@ -111,8 +112,7 @@ protected: void execute(); void load_scenario(int page); - // ADISK.DAT, ASLEEP.DAT - char adisk[16]; + Dri adisk; // シナリオデータ std::vector scenario_data; diff --git a/src/sys/nact_sys3.cpp b/src/sys/nact_sys3.cpp index acfe978..f641b93 100644 --- a/src/sys/nact_sys3.cpp +++ b/src/sys/nact_sys3.cpp @@ -744,13 +744,15 @@ void NACT_Sys3::cmd_m() if(1 <= tvar_index && tvar_index <= 10) { memcpy(tvar[tvar_index - 1], string, 22); } else if(tvar_index == 31) { - strcpy_s(adisk, 16, string); + adisk.open(string); } else if(tvar_index == 32) { - strcpy_s(ags->acg, 16, string); + ags->set_cg_file(string); } else if(tvar_index == 33) { - strcpy_s(mako->amus, 16, string); + mako->amus.open(string); + strcpy(string + strlen(string) - 3, "MDA"); + mako->mda.open(string); } else if(tvar_index == 34) { - strcpy_s(mako->amse, 16, string); + // mako->amse.open(string); } } @@ -1370,7 +1372,7 @@ void NACT_Sys3::cmd_y() break; case 250: #if 0 - if(FILEIO::GetRootPath()[1] == ':') { + if(FILEIO::GetRootPath()[1] == ':') { _TCHAR root_path[4]; root_path[0] = FILEIO::GetRootPath()[0]; root_path[1] = ':'; diff --git a/src/win/mako.cpp b/src/win/mako.cpp index 62be19d..ca72cd5 100644 --- a/src/win/mako.cpp +++ b/src/win/mako.cpp @@ -209,8 +209,10 @@ MAKO::MAKO(NACT* parent, const Config& config) : if (!config.playlist.empty()) load_playlist(config.playlist.c_str()); - strcpy_s(amus, 16, "AMUS.DAT"); - strcpy_s(amse, 16, "AMSE.DAT"); // 実際には使わない + amus.open("AMUS.DAT"); + awav.open("AWAV.DAT"); + amse.open("AMSE.DAT"); + mda.open("AMUS.MDA"); for(int i = 1; i <= 99; i++) { cd_track[i] = 0; @@ -288,7 +290,7 @@ void MAKO::play_music(int page) return; music = new Music(playlist[track], next_loop); } else if (use_fm) { - std::vector data = dri_load(amus, page); + std::vector data = amus.load(page); if (data.empty()) return; @@ -297,7 +299,7 @@ void MAKO::play_music(int page) SDL_UnlockMutex(fm_mutex); SDL_PauseAudio(0); } else if (midi->is_available()) { - if (!midi->play(nact, amus, page, next_loop)) + if (!midi->play(nact, amus, mda, page, next_loop)) return; } current_music = page; @@ -419,9 +421,9 @@ void MAKO::play_pcm(int page, bool loop) stop_pcm(); // WAV形式 (Only You) - std::vector wav_buffer = dri_load("AWAV.DAT", page); + std::vector wav_buffer = awav.load(page); if (wav_buffer.empty()) { - std::vector buffer = dri_load("AMSE.DAT", page); + std::vector buffer = amse.load(page); if (!buffer.empty()) { // AMSE形式 (乙女戦記) int samples = (static_cast(buffer.size()) - 12) * 2;