mirror of
https://github.com/kichikuou/system3-sdl2.git
synced 2026-10-09 15:19:53 +03:00
Merge some changes from SysEng 0.7 (for Gakuen Senki port)
This commit is contained in:
+37
-11
@@ -38,8 +38,19 @@ static SDL_Surface* display_surface;
|
||||
|
||||
AGS::AGS(NACT* parent, const Config& config) : nact(parent), dirty(false)
|
||||
{
|
||||
SDL_RenderSetLogicalSize(g_renderer, 640, 400);
|
||||
sdlTexture = SDL_CreateTexture(g_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, 640, 400); // TOOD: pixelformat?
|
||||
// 画面サイズ
|
||||
if (nact->crc32_a == CRC32_GAKUEN || nact->crc32_a == CRC32_GAKUEN_ENG) {
|
||||
screen_width = 512;
|
||||
screen_height = 424;
|
||||
} else {
|
||||
screen_width = 640;
|
||||
screen_height = 400;
|
||||
}
|
||||
scroll = screen_height;
|
||||
|
||||
SDL_SetWindowSize(g_window, screen_width, screen_height);
|
||||
SDL_RenderSetLogicalSize(g_renderer, screen_width, screen_height);
|
||||
sdlTexture = SDL_CreateTexture(g_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, screen_width, screen_height); // TOOD: pixelformat?
|
||||
|
||||
// DIBSection 8bpp * 3 (表, 裏, メニュー)
|
||||
for(int i = 0; i < 3; i++) {
|
||||
@@ -232,9 +243,11 @@ AGS::AGS(NACT* parent, const Config& config) : nact(parent), dirty(false)
|
||||
SET_MENU(i, 452, 14, 627, 214, true);
|
||||
break;
|
||||
case CRC32_VAMPIRE:
|
||||
case CRC32_VAMPIRE_ENG:
|
||||
SET_TEXT(i, 8, 255, 615, 383, false);
|
||||
SET_MENU(i, 448, 11, 615, 224, false);
|
||||
case CRC32_VAMPIRE_ENG:
|
||||
SET_TEXT(i, 8, 255, 615, 383, false);
|
||||
SET_MENU(i, 448, 11, 615, 234, false);
|
||||
break;
|
||||
case CRC32_YAKATA:
|
||||
SET_TEXT(i, 48, 288, 594, 393, false);
|
||||
@@ -252,6 +265,15 @@ AGS::AGS(NACT* parent, const Config& config) : nact(parent), dirty(false)
|
||||
SET_TEXT(i, 104, 304, 620, 382, false);
|
||||
SET_MENU(i, 420, 28, 620, 244, true);
|
||||
break;
|
||||
case CRC32_GAKUEN:
|
||||
case CRC32_GAKUEN_ENG:
|
||||
SET_TEXT(i, 8, 260, 505, 384, false);
|
||||
if (i == 1) {
|
||||
SET_MENU(i, 128, 32, 337, 178, true);
|
||||
} else {
|
||||
SET_MENU(i, 288, 30, 433, 210, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SET_TEXT(i, 8, 311, 623, 391, true);
|
||||
SET_MENU(i, 464, 80, 623, 240, true);
|
||||
@@ -290,10 +312,6 @@ AGS::AGS(NACT* parent, const Config& config) : nact(parent), dirty(false)
|
||||
// 画面選択
|
||||
src_screen = dest_screen = 0;
|
||||
|
||||
// 画面サイズ
|
||||
screen_height = 400;
|
||||
scroll = 400;
|
||||
|
||||
// メッセージ表示
|
||||
text_dest_x = text_w[0].sx;
|
||||
text_dest_y = text_w[0].sy + 2;
|
||||
@@ -447,7 +465,7 @@ void AGS::flush_screen(bool update)
|
||||
for(int y = 0; y < screen_height; y++) {
|
||||
uint32* src = vram[0][y];
|
||||
uint32* dest = surface_line(hBmpDest, y);
|
||||
for(int x = 0; x < 640; x++) {
|
||||
for(int x = 0; x < screen_width; x++) {
|
||||
if (nact->sys_ver == 3 && src[x] & 0x80000000) {
|
||||
// あゆみちゃん物語 フルカラー実写版
|
||||
dest[x] = src[x] & 0xffffff;
|
||||
@@ -457,7 +475,7 @@ void AGS::flush_screen(bool update)
|
||||
}
|
||||
}
|
||||
}
|
||||
invalidate_screen(0, 0, 640, screen_height);
|
||||
invalidate_screen(0, 0, screen_width, screen_height);
|
||||
}
|
||||
|
||||
void AGS::draw_screen(int sx, int sy, int width, int height)
|
||||
@@ -514,8 +532,8 @@ void AGS::update_screen()
|
||||
|
||||
void AGS::save_screenshot(const char* path)
|
||||
{
|
||||
SDL_Surface* sf = SDL_CreateRGBSurface(0, 640, screen_height, 32, 0, 0, 0, 0);
|
||||
SDL_Rect r = {0, 0, 640, screen_height};
|
||||
SDL_Surface* sf = SDL_CreateRGBSurface(0, screen_width, screen_height, 32, 0, 0, 0, 0);
|
||||
SDL_Rect r = {0, 0, screen_width, screen_height};
|
||||
SDL_UnlockSurface(hBmpDest);
|
||||
SDL_BlitSurface(hBmpDest, &r, sf, NULL);
|
||||
SDL_LockSurface(hBmpDest);
|
||||
@@ -529,6 +547,14 @@ void AGS::save_screenshot(const char* path)
|
||||
SDL_FreeSurface(sf);
|
||||
}
|
||||
|
||||
int AGS::calculate_menu_max(int window) {
|
||||
if (nact->crc32_a == CRC32_INTRUDER)
|
||||
return 6;
|
||||
if (nact->crc32_a == CRC32_GAKUEN || nact->crc32_a == CRC32_GAKUEN_ENG)
|
||||
return (menu_w[window - 1].ey - menu_w[window - 1].sy) / (menu_font_size + 4);
|
||||
return 11;
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
extern "C" {
|
||||
|
||||
|
||||
+2
-1
@@ -129,6 +129,7 @@ public:
|
||||
void translate_mouse_coords(int* x, int* y);
|
||||
|
||||
void save_screenshot(const char* path);
|
||||
int calculate_menu_max(int window);
|
||||
|
||||
bool dirty;
|
||||
|
||||
@@ -140,7 +141,7 @@ public:
|
||||
int dest_screen;
|
||||
|
||||
int scroll;
|
||||
int screen_height;
|
||||
int screen_width, screen_height;
|
||||
|
||||
// メッセージ表示
|
||||
int text_dest_x;
|
||||
|
||||
@@ -37,6 +37,8 @@ void AGS::load_cg(int page, int transparent)
|
||||
case 1:
|
||||
switch (nact->crc32_a) {
|
||||
case CRC32_BUNKASAI:
|
||||
case CRC32_GAKUEN:
|
||||
case CRC32_GAKUEN_ENG:
|
||||
load_vsp(data, page, transparent);
|
||||
break;
|
||||
case CRC32_INTRUDER:
|
||||
|
||||
+21
-2
@@ -141,7 +141,13 @@ void AGS::load_vsp(uint8* data, int page, int transparent)
|
||||
c[6] = ((b0 >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4) | ((b3 << 2) & 8);
|
||||
c[7] = ((b0 ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4) | ((b3 << 3) & 8);
|
||||
|
||||
uint32* dest = &vram[dest_screen][y + sy][(x + sx) * 8];
|
||||
uint32* dest;
|
||||
// Gakuen Senki uses exact sx values rather than 8x.
|
||||
if (nact->crc32_a == CRC32_GAKUEN || nact->crc32_a == CRC32_GAKUEN_ENG)
|
||||
dest = &vram[dest_screen][y + sy][(x * 8) + sx];
|
||||
else
|
||||
dest = &vram[dest_screen][y + sy][(x + sx) * 8];
|
||||
|
||||
if(transparent == -1) {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
dest[i] = c[i] | base;
|
||||
@@ -159,7 +165,20 @@ void AGS::load_vsp(uint8* data, int page, int transparent)
|
||||
|
||||
// 画面更新
|
||||
if(dest_screen == 0 && extract_cg) {
|
||||
draw_screen(sx * 8, sy, width * 8, height);
|
||||
if (nact->crc32_a == CRC32_GAKUEN || nact->crc32_a == CRC32_GAKUEN_ENG) {
|
||||
// Gakuen Senki's images were converted to VSP for the modern port, but don't always adhere to VSP's width restrictions, which demand
|
||||
// every image width be a factor of 8. Thankfully, the exceptions are designed to fit into specific parts of the GUI, and so have
|
||||
// consistent widths for each output position.
|
||||
//
|
||||
// As above, GS also uses exact sx values rather than values that are meant to be multiplied by 8.
|
||||
if (sx == 289 && sy == 26) draw_screen(sx, sy, 188, height);
|
||||
else if (sx == 289 && sy == 92) draw_screen(sx, sy, 190, height);
|
||||
else if (sx == 278 && sy == 208) draw_screen(sx, sy, 212, height);
|
||||
else draw_screen(sx, sy, width * 8, height);
|
||||
}
|
||||
else {
|
||||
draw_screen(sx * 8, sy, width * 8, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#define CRC32_VAMPIRE 0x957bcfbf // Little Vampire
|
||||
#define CRC32_VAMPIRE_ENG 0x61985a7f // Little Vampire (English) Patch 1.5
|
||||
#define CRC32_YAKATA 0x8cef6fa6 // ALICEの館
|
||||
#define CRC32_GAKUEN 0xe4d6ec66 // 学園戦記 (unofficial system1 port) 1.0JP
|
||||
#define CRC32_GAKUEN_ENG 0x6ba8c102 // Gakuen Senki (English) 1.0
|
||||
|
||||
// SYSTEM2
|
||||
|
||||
|
||||
@@ -183,6 +183,9 @@ protected:
|
||||
// DPS
|
||||
bool text_refresh;
|
||||
|
||||
// GAKUEN
|
||||
bool enable_graphics = true;
|
||||
|
||||
bool column; // 座標モード
|
||||
bool wait_keydown; // ウェイト時のキー受付
|
||||
int text_wait_time; // テキスト表示のウェイト
|
||||
|
||||
@@ -39,6 +39,8 @@ const struct CRCTable {
|
||||
{"little_vampire", 1, "Little Vampire", JAPANESE, CRC32_VAMPIRE},
|
||||
{"little_vampire_eng", 1, "Little Vampire", ENGLISH, CRC32_VAMPIRE_ENG},
|
||||
{"yakata", 1, "ALICEの館", JAPANESE, CRC32_YAKATA},
|
||||
{"gakuen", 1, "学園戦記", JAPANESE, CRC32_GAKUEN},
|
||||
{"gakuen_eng", 1, "Gakuen Senki", ENGLISH, CRC32_GAKUEN_ENG},
|
||||
|
||||
{"ayumi_fd", 2, "あゆみちゃん物語", JAPANESE, CRC32_AYUMI_FD},
|
||||
{"ayumi_hint", 2, "あゆみちゃん物語 ヒントディスク", JAPANESE, CRC32_AYUMI_HINT},
|
||||
|
||||
@@ -52,7 +52,7 @@ void NACT::pump_events()
|
||||
case SDL_FINGERDOWN:
|
||||
case SDL_FINGERUP:
|
||||
case SDL_FINGERMOTION:
|
||||
mousex = e.tfinger.x * 640;
|
||||
mousex = e.tfinger.x * ags->screen_width;
|
||||
mousey = e.tfinger.y * ags->screen_height;
|
||||
switch (SDL_GetNumTouchFingers(e.tfinger.touchId)) {
|
||||
case 0:
|
||||
|
||||
+122
-9
@@ -20,9 +20,6 @@
|
||||
#include "encoding.h"
|
||||
#include "texthook.h"
|
||||
|
||||
// メニューの改ページ
|
||||
#define MENU_MAX (crc32_a == CRC32_INTRUDER ? 6 : 11)
|
||||
|
||||
#define WAIT(tm) \
|
||||
{ \
|
||||
Uint32 dwTime = SDL_GetTicks() + (tm); \
|
||||
@@ -112,6 +109,17 @@ void NACT_Sys1::opening()
|
||||
cmd_a();
|
||||
ags->draw_box(0);
|
||||
break;
|
||||
case CRC32_GAKUEN:
|
||||
case CRC32_GAKUEN_ENG:
|
||||
mako->set_cd_track(1, 1);
|
||||
ags->load_cg(302, -1);
|
||||
WAIT(3000);
|
||||
ags->load_cg(303, -1);
|
||||
WAIT(3000);
|
||||
mako->play_music(1);
|
||||
ags->load_cg(304, -1);
|
||||
WAIT(4000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,6 +311,9 @@ void NACT_Sys1::cmd_set_menu()
|
||||
ags->menu_dest_y += 2;
|
||||
ags->draw_menu = true;
|
||||
|
||||
if (crc32_a == CRC32_GAKUEN || crc32_a == CRC32_GAKUEN_ENG)
|
||||
menu_window = 2;
|
||||
|
||||
output_console("\n$%x,", menu_addr[menu_index - 1]);
|
||||
}
|
||||
}
|
||||
@@ -372,6 +383,10 @@ void NACT_Sys1::cmd_open_verb()
|
||||
// 表示する動詞のチェック
|
||||
int chk[MAX_VERB], page = 0, cnt = 0;
|
||||
|
||||
if (crc32_a == CRC32_GAKUEN || crc32_a == CRC32_GAKUEN_ENG)
|
||||
menu_window = 1;
|
||||
int menu_max = ags->calculate_menu_max(menu_window);
|
||||
|
||||
memset(chk, 0, sizeof(chk));
|
||||
for(int i = 0; i < menu_index; i++) {
|
||||
chk[menu_verb[i]] = 1;
|
||||
@@ -390,7 +405,7 @@ top:
|
||||
ags->menu_dest_y = 0;
|
||||
ags->draw_menu = true;
|
||||
|
||||
if(cnt <= MENU_MAX) {
|
||||
if(cnt <= menu_max) {
|
||||
// 1ページ内に全て表示できる
|
||||
for(int i = 0; i < MAX_VERB; i++) {
|
||||
if(chk[i]) {
|
||||
@@ -412,7 +427,7 @@ top2:
|
||||
ags->menu_dest_y += ags->menu_font_size + 2;
|
||||
}
|
||||
page = i + 1;
|
||||
if(index == MENU_MAX - 1) {
|
||||
if(index == menu_max - 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -446,6 +461,8 @@ top2:
|
||||
|
||||
void NACT_Sys1::cmd_open_obj(int verb)
|
||||
{
|
||||
int menu_max = ags->calculate_menu_max(menu_window);
|
||||
|
||||
// 目的語メニューの表示
|
||||
verb_obj = false;
|
||||
|
||||
@@ -481,7 +498,7 @@ top:
|
||||
ags->menu_dest_y = 0;
|
||||
ags->draw_menu = true;
|
||||
|
||||
if(cnt <= MENU_MAX - 1) {
|
||||
if(cnt <= menu_max - 1) {
|
||||
// 1ページ内に全て表示できる
|
||||
for(int i = 0; i < MAX_OBJ; i++) {
|
||||
if(chk[i]) {
|
||||
@@ -509,7 +526,7 @@ top2:
|
||||
ags->menu_dest_y += ags->menu_font_size + 2;
|
||||
}
|
||||
page = i + 1;
|
||||
if(index == MENU_MAX - 2) {
|
||||
if(index == menu_max - 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -620,11 +637,14 @@ void NACT_Sys1::cmd_g()
|
||||
|
||||
output_console("\nG %d:", page);
|
||||
|
||||
if(crc32_a == CRC32_INTRUDER) {
|
||||
if (crc32_a == CRC32_INTRUDER) {
|
||||
page = (page == 97) ? 96 : (page == 98) ? 97 : page;
|
||||
} else if (crc32_a == CRC32_GAKUEN || crc32_a == CRC32_GAKUEN_ENG) {
|
||||
page = (page == 3) ? 94 : page;
|
||||
}
|
||||
|
||||
ags->load_cg(page, -1);
|
||||
if (enable_graphics)
|
||||
ags->load_cg(page, -1);
|
||||
|
||||
if(crc32_a == CRC32_INTRUDER) {
|
||||
if(page == 94) {
|
||||
@@ -1011,6 +1031,41 @@ void NACT_Sys1::cmd_y()
|
||||
fatal_error = true;
|
||||
break;
|
||||
}
|
||||
} else if (crc32_a == CRC32_GAKUEN || crc32_a == CRC32_GAKUEN_ENG) {
|
||||
switch (cmd) {
|
||||
case 1:
|
||||
RND = (param == 0 || param == 1) ? 0 : random(param);
|
||||
break;
|
||||
case 2:
|
||||
// Clear variables up to param, though in practice param is always 21.
|
||||
for (int i = 0; i <= param; i++) {
|
||||
var[i] = 0;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
char buf[16];
|
||||
sprintf(buf, "%d", param);
|
||||
ags->draw_text(buf);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (param == 0) {
|
||||
mako->play_music(1);
|
||||
} else {
|
||||
mako->stop_music();
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
enable_graphics = (param == 0);
|
||||
break;
|
||||
case 6:
|
||||
// Dummied. 0 - "Display text slowly," 1 - disable.
|
||||
break;
|
||||
case 7:
|
||||
// Dummied. 0 - "Switch to interlace mode," 1 - disable.
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch(cmd) {
|
||||
case 0:
|
||||
@@ -1190,6 +1245,64 @@ void NACT_Sys1::cmd_z()
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CRC32_GAKUEN:
|
||||
case CRC32_GAKUEN_ENG:
|
||||
if (param != 30 && (param < 34 || param > 46)) {
|
||||
if (enable_graphics) {
|
||||
ags->load_cg(param + 250, -1);
|
||||
}
|
||||
}
|
||||
|
||||
// Display the Gakuen Senki party status bar for party members. The Z commands make the slots appear in reverse, so 39 and 45 draw
|
||||
// the box for character 1, 38 and 44 draw for character 2, and so on. Z 1, 30: draws the first character slot, which is always occupied.
|
||||
//
|
||||
// One the actual MSX, this bar was constructed in an irregular fashion. This code constructs a more consistent version, where each square
|
||||
// is 35px wide with 2px borders on each side. Since the borders are overlapped, this means each sub-sprite is placed 37px apart.
|
||||
else if (param == 46) {
|
||||
// Originally this would have loaded Image 296, the party status bar, to screen 1 for future reference. However, due to trouble with
|
||||
// the palette, I decided to load it before using each subcommand, instead.
|
||||
/*ags->dest_screen = 1;
|
||||
ags->load_cg(296, -1);
|
||||
ags->dest_screen = 0;*/
|
||||
}
|
||||
else if (param == 30) {
|
||||
// Load party status bar to screen 1.
|
||||
ags->dest_screen = 1;
|
||||
ags->load_cg(296, -1);
|
||||
ags->dest_screen = 0;
|
||||
|
||||
// Draw Wataru's icon.
|
||||
ags->src_screen = 1;
|
||||
ags->copy(10, 182, 48, 224, 7, 210);
|
||||
ags->src_screen = 0;
|
||||
}
|
||||
else if (param >= 34 && param <= 39) {
|
||||
int x = (39 - param) * 37 + 45;
|
||||
|
||||
// Load party status bar to screen 1.
|
||||
ags->dest_screen = 1;
|
||||
ags->load_cg(296, -1);
|
||||
ags->dest_screen = 0;
|
||||
|
||||
// Draw a blank party icon to init or clear the party box.
|
||||
ags->src_screen = 1;
|
||||
ags->copy(269, 182, 307, 224, x, 210);
|
||||
ags->src_screen = 0;
|
||||
}
|
||||
else {
|
||||
int x = (45 - param) * 37 + 45;
|
||||
|
||||
// Load party status bar to screen 1.
|
||||
ags->dest_screen = 1;
|
||||
ags->load_cg(296, -1);
|
||||
ags->dest_screen = 0;
|
||||
|
||||
// Draw a party member's icon to the party bar.
|
||||
ags->src_screen = 1;
|
||||
ags->copy(x + 2, 182, x + 38, 224, x, 210);
|
||||
ags->src_screen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,6 @@ void init_menu(bool mouse_move_enabled)
|
||||
HINSTANCE hinst = (HINSTANCE)GetModuleHandle(NULL);
|
||||
HMENU hmenu = LoadMenu(hinst, MAKEINTRESOURCE(IDR_MENU1));
|
||||
SetMenu(get_hwnd(g_window), hmenu);
|
||||
// Let SDL recalc the window size, taking menu height into account.
|
||||
SDL_SetWindowSize(g_window, 640, 400);
|
||||
if (mouse_move_enabled)
|
||||
CheckMenuItem(hmenu, ID_OPTION_MOUSE_MOVE, MF_BYCOMMAND | MFS_CHECKED);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user