Introduce Dri class

It caches the link table.
This commit is contained in:
kichikuou
2024-12-08 13:39:23 +09:00
parent f26ce11fd9
commit 48d780add6
14 changed files with 121 additions and 110 deletions
+7 -4
View File
@@ -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<uint8_t> data = dri_load(amus, page);
std::vector<uint8_t> 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<uint8_t> wav_buffer = dri_load("AWAV.DAT", page);
std::vector<uint8_t> wav_buffer = awav.load(page);
if (wav_buffer.empty()) {
std::vector<uint8_t> buffer = dri_load("AMSE.DAT", page);
std::vector<uint8_t> buffer = amse.load(page);
if (!buffer.empty()) {
// AMSE形式 (乙女戦記)
int samples = (buffer.size() - 12) * 2;
+8 -6
View File
@@ -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<uint8_t> data = dri_load(amus, page);
std::vector<uint8_t> 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<uint8_t> buffer = dri_load("AWAV.DAT", page);
std::vector<uint8_t> 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;
+17 -2
View File
@@ -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) {
+7 -3
View File
@@ -7,9 +7,11 @@
#ifndef _AGS_H_
#define _AGS_H_
#include <memory>
#include <stdio.h>
#include "../common.h"
#include "nact.h"
#include "dri.h"
#include <SDL_ttf.h>
#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);
+6 -14
View File
@@ -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<uint8_t> data = dri_load(acg, page);
std::vector<uint8_t> data = acg.load(page);
if (data.empty())
return;
switch (nact->sys_ver) {
+27 -47
View File
@@ -5,83 +5,63 @@
*/
#include "dri.h"
#include <memory>
#include <string.h>
#include "crc32.h"
#include "../fileio.h"
std::vector<uint8> 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<FILEIO>();
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<uint8> Dri::load(int page)
{
if (static_cast<size_t>(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<FILEIO>();
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<uint8_t> buffer(size);
std::vector<uint8_t> 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<uint8> dri_load_mda(uint32_t crc32_a, uint32_t crc32_b, int page)
// static
std::vector<uint8> Dri::load_mda(uint32_t crc32_a, uint32_t crc32_b, int page)
{
// データ取得
const char* name = NULL;
+12 -2
View File
@@ -7,10 +7,20 @@
#ifndef _DRI_H_
#define _DRI_H_
#include <string>
#include <stdint.h>
#include <vector>
std::vector<uint8_t> dri_load(const char* file_name, int page);
std::vector<uint8_t> dri_load_mda(uint32_t crc32_a, uint32_t crc32_b, int page);
class Dri {
public:
void open(const char* file_name);
std::vector<uint8_t> load(int page);
static std::vector<uint8_t> load_mda(uint32_t crc32_a, uint32_t crc32_b, int page);
private:
std::string fname;
std::vector<uint8_t> link_table;
};
#endif
+7 -4
View File
@@ -7,12 +7,14 @@
#ifndef _MAKO_H_
#define _MAKO_H_
#include <memory>
#include <vector>
#include <stdio.h>
#include <limits.h>
#include <math.h>
#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<const char*> playlist;
+7 -10
View File
@@ -93,7 +93,7 @@ void stop_midi()
class Playback {
public:
static std::unique_ptr<Playback> create(NACT* nact, char* amus, int page, int loop, int seq);
static std::unique_ptr<Playback> 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<uint8_t>& data);
void load_mda(const std::vector<uint8_t>& data);
@@ -379,23 +379,20 @@ bool Playback::play_midi(SDL_atomic_t* current_loop, SDL_atomic_t* current_mark)
}
//static
std::unique_ptr<Playback> Playback::create(NACT* nact, char* amus, int page, int loop, int seq)
std::unique_ptr<Playback> Playback::create(NACT* nact, Dri& amus, Dri& mda, int page, int loop, int seq)
{
auto playback = std::make_unique<Playback>(nact->crc32_a, loop, seq);
std::vector<uint8_t> data = dri_load(amus, page);
std::vector<uint8_t> 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(&current_seq, seq);
+3 -2
View File
@@ -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; }
+3 -3
View File
@@ -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);
}
+2 -2
View File
@@ -13,6 +13,7 @@
#include <stdio.h>
#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<uint8_t> scenario_data;
+7 -5
View File
@@ -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] = ':';
+8 -6
View File
@@ -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<uint8_t> data = dri_load(amus, page);
std::vector<uint8_t> 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<uint8_t> wav_buffer = dri_load("AWAV.DAT", page);
std::vector<uint8_t> wav_buffer = awav.load(page);
if (wav_buffer.empty()) {
std::vector<uint8_t> buffer = dri_load("AMSE.DAT", page);
std::vector<uint8_t> buffer = amse.load(page);
if (!buffer.empty()) {
// AMSE形式 (乙女戦記)
int samples = (static_cast<int>(buffer.size()) - 12) * 2;