mirror of
https://github.com/kichikuou/system3-sdl2.git
synced 2026-10-14 01:59:14 +03:00
Import system3 for win32 2016-01-16, downloaded from
http://homepage3.nifty.com/takeda-toshiya/alice/index.html
This commit is contained in:
@@ -0,0 +1,575 @@
|
||||
/*
|
||||
ALICE SOFT SYSTEM 3 for Win32
|
||||
|
||||
[ NACT ]
|
||||
*/
|
||||
|
||||
#if defined(_SYSTEM1)
|
||||
#include "../res1/resource.h"
|
||||
#elif defined(_SYSTEM2)
|
||||
#include "../res2/resource.h"
|
||||
#else
|
||||
#include "../res3/resource.h"
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include "nact.h"
|
||||
#include "ags.h"
|
||||
#include "mako.h"
|
||||
#include "dri.h"
|
||||
#include "../fileio.h"
|
||||
|
||||
extern _TCHAR g_root[_MAX_PATH];
|
||||
extern HWND g_hwnd;
|
||||
|
||||
// 初期化
|
||||
|
||||
NACT::NACT()
|
||||
{
|
||||
memset(key, 0, sizeof(key));
|
||||
mouse_x = mouse_y = 0;
|
||||
|
||||
// デバッグコンソール起動
|
||||
initialize_console();
|
||||
|
||||
// SYSTEM3 初期化
|
||||
|
||||
crc32 = calc_crc32();
|
||||
fatal_error = post_quit = false;
|
||||
|
||||
// AG00.DAT読み込み
|
||||
FILEIO* fio = new FILEIO();
|
||||
_TCHAR file_path[_MAX_PATH];
|
||||
_stprintf_s(file_path, _MAX_PATH, _T("%sAG00.DAT"), g_root);
|
||||
|
||||
if(fio->Fopen(file_path, FILEIO_READ_BINARY)) {
|
||||
int d0, d1, d2, d3;
|
||||
char string[MAX_CAPTION];
|
||||
fio->Fgets(string);
|
||||
sscanf_s(string, "%d,%d,%d,%d", &d0, &d1, &d2, &d3);
|
||||
for(int i = 0; i < d1; i++) {
|
||||
// 動詞の読み込み
|
||||
fio->Fgets(string);
|
||||
memcpy(caption_verb[i], string, sizeof(string));
|
||||
}
|
||||
for(int i = 0; i < d2; i++) {
|
||||
// 目的語の読み込み
|
||||
fio->Fgets(string);
|
||||
memcpy(caption_obj[i], string, sizeof(string));
|
||||
}
|
||||
fio->Fclose();
|
||||
}
|
||||
delete fio;
|
||||
|
||||
// ADISK.DAT
|
||||
#if defined(_PROG_OMAKE)
|
||||
_tcscpy_s(adisk, 16, _T("AGAME.DAT"));
|
||||
#else
|
||||
_tcscpy_s(adisk, 16, _T("ADISK.DAT"));
|
||||
#endif
|
||||
|
||||
// シナリオ管理
|
||||
scenario_data = NULL;
|
||||
load_scenario(0);
|
||||
scenario_page = 0;
|
||||
scenario_addr = 2;
|
||||
label_depth = page_depth = 0;
|
||||
|
||||
// 変数初期化
|
||||
memset(var, 0, sizeof(var));
|
||||
memset(var_stack, 0, sizeof(var_stack));
|
||||
memset(tvar, 0, sizeof(tvar));
|
||||
memset(tvar_stack, 0, sizeof(tvar_stack));
|
||||
|
||||
// コマンド初期化
|
||||
column = true; // 座標モード
|
||||
wait_keydown = true; // ウェイト時のキー受付
|
||||
seed = timeGetTime(); // 乱数の種
|
||||
text_wait_time = 100; // メッセージ表示のウェイト
|
||||
text_wait_enb = false;
|
||||
text_skip_enb = false;
|
||||
mouse_sence = 16; // マウス移動感知
|
||||
|
||||
menu_window = text_window = 1;
|
||||
menu_index = 0;
|
||||
show_push = true;
|
||||
clear_text = true;
|
||||
|
||||
verb_obj = false;
|
||||
set_palette = false;
|
||||
|
||||
tvar_index = 0;
|
||||
|
||||
pcm_index = 0;
|
||||
memset(pcm, 0, sizeof(pcm));
|
||||
|
||||
// SYETEM1 初期化
|
||||
#if defined(_DPS)
|
||||
text_refresh = false;
|
||||
_tcscpy_s(tvar[0], 22, _T("カスタム"));
|
||||
_tcscpy_s(tvar[1], 22, _T("リーナス"));
|
||||
_tcscpy_s(tvar[2], 22, _T("かつみ"));
|
||||
_tcscpy_s(tvar[3], 22, _T("由美子"));
|
||||
_tcscpy_s(tvar[4], 22, _T("いつみ"));
|
||||
_tcscpy_s(tvar[5], 22, _T("ひとみ"));
|
||||
_tcscpy_s(tvar[6], 22, _T("真理子"));
|
||||
#elif defined(_INTRUDER)
|
||||
paint_x = paint_y = map_page = 0;
|
||||
#endif
|
||||
|
||||
// 各種クラス生成
|
||||
ags = new AGS(this);
|
||||
mako = new MAKO(this);
|
||||
|
||||
// 入力初期化
|
||||
joy_num = joyGetNumDevs();
|
||||
if(joy_num) {
|
||||
joyGetDevCaps(JOYSTICKID1, &joycaps, sizeof(JOYCAPS));
|
||||
}
|
||||
|
||||
// メインスレッド起動
|
||||
params.nact = this;
|
||||
params.terminate = false;
|
||||
hThread = (HANDLE)_beginthread(thread, 0, ¶ms);
|
||||
SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL);
|
||||
}
|
||||
|
||||
NACT::~NACT()
|
||||
{
|
||||
// メインスレッド終了
|
||||
params.terminate = true;
|
||||
if(hThread) {
|
||||
WaitForSingleObject(hThread, INFINITE);
|
||||
}
|
||||
hThread = NULL;
|
||||
|
||||
// 各種クラス開放
|
||||
if(ags) {
|
||||
delete ags;
|
||||
}
|
||||
if(mako) {
|
||||
delete mako;
|
||||
}
|
||||
|
||||
// シナリオ開放
|
||||
if(scenario_data) {
|
||||
free(scenario_data);
|
||||
}
|
||||
|
||||
// デバッグコンソール開放
|
||||
release_console();
|
||||
}
|
||||
|
||||
void NACT::thread(PVOID pvoid)
|
||||
{
|
||||
volatile PPARAMS pparams;
|
||||
pparams = (PPARAMS)pvoid;
|
||||
int sleep_cnt = 0;
|
||||
|
||||
while(!pparams->terminate) {
|
||||
pparams->nact->execute();
|
||||
// 512コマンド実行毎にSleep(10)
|
||||
if(!(sleep_cnt = (sleep_cnt + 1) & 0x1ff)) {
|
||||
Sleep(10);
|
||||
} else {
|
||||
Sleep(0);
|
||||
}
|
||||
}
|
||||
_endthread();
|
||||
}
|
||||
|
||||
// コマンドパーサ
|
||||
|
||||
void NACT::execute()
|
||||
{
|
||||
// アドレスの確認
|
||||
if(scenario_addr < 2 || scenario_addr >= scenario_size) {
|
||||
fatal_error = true;
|
||||
}
|
||||
|
||||
// 致命的なエラー発生 or 正常終了
|
||||
if(fatal_error) {
|
||||
if(!post_quit) {
|
||||
PostMessage(g_hwnd, WM_CLOSE, 0, 0);
|
||||
}
|
||||
post_quit = true;
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(_SYSTEM1)
|
||||
if(scenario_page == 0 && scenario_addr == 2) {
|
||||
opening();
|
||||
}
|
||||
#endif
|
||||
|
||||
// 1コマンド実行
|
||||
uint8 cmd = getd();
|
||||
|
||||
if(set_palette && cmd != 'P') {
|
||||
// パレット設定が終わった
|
||||
ags->flush_screen(true);
|
||||
set_palette = false;
|
||||
}
|
||||
if(verb_obj && cmd != '[' && cmd != ':') {
|
||||
// 動詞-目的語メニューの表示
|
||||
scenario_addr--;
|
||||
cmd_open_verb();
|
||||
return;
|
||||
}
|
||||
|
||||
switch(cmd) {
|
||||
case '!':
|
||||
cmd_calc();
|
||||
break;
|
||||
case '{':
|
||||
cmd_branch();
|
||||
break;
|
||||
case '}':
|
||||
break;
|
||||
case '@':
|
||||
cmd_label_jump();
|
||||
break;
|
||||
case '\\':
|
||||
cmd_label_call();
|
||||
break;
|
||||
case '&':
|
||||
cmd_page_jump();
|
||||
break;
|
||||
case '%':
|
||||
cmd_page_call();
|
||||
break;
|
||||
case '$':
|
||||
cmd_set_menu();
|
||||
break;
|
||||
case '[':
|
||||
cmd_set_verbobj();
|
||||
break;
|
||||
case ':':
|
||||
cmd_set_verbobj2();
|
||||
break;
|
||||
case ']':
|
||||
cmd_open_menu();
|
||||
break;
|
||||
case 'A':
|
||||
cmd_a();
|
||||
break;
|
||||
case 'B':
|
||||
cmd_b();
|
||||
break;
|
||||
case 'D':
|
||||
cmd_d();
|
||||
break;
|
||||
case 'E':
|
||||
cmd_e();
|
||||
break;
|
||||
case 'F':
|
||||
cmd_f();
|
||||
break;
|
||||
case 'G':
|
||||
cmd_g();
|
||||
break;
|
||||
case 'H':
|
||||
cmd_h();
|
||||
break;
|
||||
case 'I':
|
||||
cmd_i();
|
||||
break;
|
||||
case 'J':
|
||||
cmd_j();
|
||||
break;
|
||||
case 'K':
|
||||
cmd_k();
|
||||
break;
|
||||
case 'L':
|
||||
cmd_l();
|
||||
break;
|
||||
case 'M':
|
||||
cmd_m();
|
||||
break;
|
||||
case 'N':
|
||||
cmd_n();
|
||||
break;
|
||||
case 'O':
|
||||
cmd_o();
|
||||
break;
|
||||
case 'P':
|
||||
cmd_p();
|
||||
break;
|
||||
case 'Q':
|
||||
cmd_q();
|
||||
break;
|
||||
case 'R':
|
||||
cmd_r();
|
||||
break;
|
||||
case 'S':
|
||||
cmd_s();
|
||||
break;
|
||||
case 'T':
|
||||
cmd_t();
|
||||
break;
|
||||
case 'U':
|
||||
cmd_u();
|
||||
break;
|
||||
case 'V':
|
||||
cmd_v();
|
||||
break;
|
||||
case 'W':
|
||||
cmd_w();
|
||||
break;
|
||||
case 'X':
|
||||
cmd_x();
|
||||
break;
|
||||
case 'Y':
|
||||
cmd_y();
|
||||
break;
|
||||
case 'Z':
|
||||
cmd_z();
|
||||
break;
|
||||
default:
|
||||
if(cmd == 0x20 || (0xa1 <= cmd && cmd <= 0xdd)) {
|
||||
// message (1 byte)
|
||||
char string[2];
|
||||
string[0] = cmd;
|
||||
string[1] = '\0';
|
||||
ags->draw_text(string);
|
||||
#if defined(_DPS)
|
||||
if(!ags->draw_menu) {
|
||||
text_refresh = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!ags->draw_menu && text_wait_enb && cmd != 0x20) {
|
||||
DWORD dwTime = timeGetTime() + text_wait_time;
|
||||
for(;;) {
|
||||
if(params.terminate) {
|
||||
return;
|
||||
}
|
||||
RND = get_key();
|
||||
if(RND && wait_keydown) {
|
||||
break;
|
||||
}
|
||||
if(dwTime <= timeGetTime()) {
|
||||
break;
|
||||
}
|
||||
Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_DEBUG_CONSOLE)
|
||||
output_console(string);
|
||||
#endif
|
||||
} else if((0x81 <= cmd && cmd <= 0x9f) || 0xe0 <= cmd) {
|
||||
// message (2 bytes)
|
||||
char string[3];
|
||||
string[0] = cmd;
|
||||
string[1] = getd();
|
||||
string[2] = '\0';
|
||||
ags->draw_text(string);
|
||||
#if defined(_DPS)
|
||||
if(!ags->draw_menu) {
|
||||
text_refresh = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!ags->draw_menu && text_wait_enb) {
|
||||
DWORD dwTime = timeGetTime() + text_wait_time;
|
||||
for(;;) {
|
||||
if(params.terminate) {
|
||||
return;
|
||||
}
|
||||
RND = get_key();
|
||||
if(RND && wait_keydown) {
|
||||
break;
|
||||
}
|
||||
if(dwTime <= timeGetTime()) {
|
||||
break;
|
||||
}
|
||||
Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_DEBUG_CONSOLE)
|
||||
output_console(string);
|
||||
#endif
|
||||
} else {
|
||||
fatal_error = true;
|
||||
|
||||
#if defined(_DEBUG_CONSOLE)
|
||||
char log[128];
|
||||
memset(log, 0, sizeof(log));
|
||||
sprintf_s(log, 128, "\nFAILED: %2x, %d", cmd, scenario_addr);
|
||||
output_console(log);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NACT::load_scenario(int page)
|
||||
{
|
||||
if(scenario_data) {
|
||||
free(scenario_data);
|
||||
}
|
||||
DRI* dri = new DRI();
|
||||
if((scenario_data = dri->load(adisk, page + 1, &scenario_size)) == NULL) {
|
||||
fatal_error = true;
|
||||
}
|
||||
delete dri;
|
||||
}
|
||||
|
||||
// 下位関数
|
||||
|
||||
uint16 NACT::random(uint16 range)
|
||||
{
|
||||
// xorhift32
|
||||
seed = seed ^ (seed << 13);
|
||||
seed = seed ^ (seed >> 17);
|
||||
seed = seed ^ (seed << 15);
|
||||
return (uint16)(((uint32)range * (seed & 0xffff)) >> 16) + 1;
|
||||
}
|
||||
|
||||
// WinMainとのインターフェース
|
||||
|
||||
int NACT::get_screen_height()
|
||||
{
|
||||
return ags->screen_height;
|
||||
}
|
||||
|
||||
void NACT::update_screen(HDC hdc, int sx, int sy, int width, int height)
|
||||
{
|
||||
ags->update_screen(hdc, sx, sy, width, height);
|
||||
}
|
||||
|
||||
void NACT::notify_mci(int status)
|
||||
{
|
||||
mako->notify_mci(status);
|
||||
}
|
||||
|
||||
void NACT::key_down(int val)
|
||||
{
|
||||
key[val] = 1;
|
||||
}
|
||||
|
||||
void NACT::key_up(int val)
|
||||
{
|
||||
if(val == -1) {
|
||||
memset(key, 0, sizeof(key));
|
||||
} else {
|
||||
key[val] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void NACT::select_cursor()
|
||||
{
|
||||
ags->select_cursor();
|
||||
}
|
||||
|
||||
void NACT::select_sound(int dev)
|
||||
{
|
||||
// 強制的に音源を変更する
|
||||
int page = mako->current_music;
|
||||
int old_dev = (1 <= page && page <= 99 && mako->cd_track[page]) ? 1 : 0;
|
||||
|
||||
for(int i = 1; i <= 99; i++) {
|
||||
mako->cd_track[i] = dev ? i : 0;
|
||||
}
|
||||
|
||||
// デバイスが変更された場合は再演奏する
|
||||
if(dev != old_dev && page) {
|
||||
mako->stop_music();
|
||||
mako->play_music(page);
|
||||
}
|
||||
}
|
||||
|
||||
// デバッグコンソール
|
||||
|
||||
void NACT::initialize_console()
|
||||
{
|
||||
#if defined(_DEBUG_CONSOLE)
|
||||
AllocConsole();
|
||||
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
#if defined(_SYSTEM1)
|
||||
SetConsoleTitle("SYSTEM1 NACT Tracer");
|
||||
#elif defined(_SYSTEM2)
|
||||
SetConsoleTitle("SYSTEM2 NACT Tracer");
|
||||
#else
|
||||
SetConsoleTitle("SYSTEM3 NACT Tracer");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void NACT::release_console()
|
||||
{
|
||||
#if defined(_DEBUG_CONSOLE)
|
||||
FreeConsole();
|
||||
#endif
|
||||
}
|
||||
|
||||
void NACT::output_console(char log[])
|
||||
{
|
||||
#if defined(_DEBUG_CONSOLE)
|
||||
DWORD dwWritten;
|
||||
WriteConsole(hConsole, log, strlen(log), &dwWritten, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL CALLBACK NACT::TextDialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static NACT* nact;
|
||||
char string[64];
|
||||
int pnt, cnt;
|
||||
|
||||
switch(msg) {
|
||||
case WM_CLOSE:
|
||||
EndDialog(hDlg, IDCANCEL);
|
||||
break;
|
||||
case WM_INITDIALOG:
|
||||
// get this pointer
|
||||
nact = (NACT *)lParam;
|
||||
// init dialog
|
||||
sprintf_s(string, 64, "文字列を入力してください(最大%d文字)", nact->tvar_maxlen);
|
||||
Edit_SetText(GetDlgItem(hDlg, IDC_TEXT), string);
|
||||
Edit_SetText(GetDlgItem(hDlg, IDC_EDITBOX), nact->tvar[nact->tvar_index - 1]);
|
||||
if(nact->tvar[nact->tvar_index - 1][0] == '\0') {
|
||||
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
|
||||
} else {
|
||||
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch(LOWORD(wParam)) {
|
||||
case IDC_EDITBOX:
|
||||
GetDlgItemText(hDlg, IDC_EDITBOX, string, 32);
|
||||
pnt = cnt = 0;
|
||||
while(string[pnt] != '\0') {
|
||||
unsigned char dat = string[pnt];
|
||||
if((0x81 <= dat && dat <= 0x9f) || 0xe0 <= dat) {
|
||||
pnt++;
|
||||
}
|
||||
pnt++;
|
||||
cnt++;
|
||||
}
|
||||
if(cnt == 0 || cnt > nact->tvar_maxlen) {
|
||||
EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
|
||||
} else {
|
||||
EnableWindow(GetDlgItem(hDlg, IDOK), TRUE);
|
||||
}
|
||||
break;
|
||||
case IDOK:
|
||||
GetDlgItemText(hDlg, IDC_EDITBOX, string, 32);
|
||||
strcpy_s(nact->tvar[nact->tvar_index - 1], 22, string);
|
||||
EndDialog(hDlg, IDOK);
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user