Implement game specific commands for Gakuen KING

This commit is contained in:
kichikuou
2026-08-24 16:29:09 +09:00
parent 64f8e7bf9f
commit 6bd5baf7c2
19 changed files with 2933 additions and 161 deletions
+10 -1
View File
@@ -109,6 +109,11 @@ public:
void update_screen();
void load_cg(int page, int transparent);
// Decodes a CG without drawing it, but still updates the palette.
CG load_cg_surface(int page, int transparent = -1);
// Returns an ACG page bytes, without decoding it.
std::vector<uint8_t> load_cg_data(int page) { return acg.load(page); }
void blit_cg(int dest, CG& cg, const SDL_Rect* src, int dx, int dy);
void set_cg_file(const char *file_name);
void load_censor_list(const char* fname);
@@ -121,7 +126,11 @@ public:
void fade_out(int duration_ms, bool white);
void fade_in(int duration_ms);
void copy(int sx, int sy, int ex, int ey, int dx, int dy);
void copy(int sx, int sy, int ex, int ey, int dx, int dy) {
copy_screen(src_screen, dest_screen, sx, sy, ex, ey, dx, dy);
}
void copy_screen(int src, int dest, int sx, int sy, int ex, int ey, int dx, int dy,
int transparent_color = -1);
void gcopy(int gsc, int gde, int glx, int gly, int gsw);
void paint(int x, int y, uint8 color);
void draw_box(int index);
+45 -24
View File
@@ -31,15 +31,15 @@ void mosaic(SDL_Surface* sf) {
} // namespace
void AGS::load_cg(int page, int transparent)
CG AGS::load_cg_surface(int page, int transparent)
{
if (bmp_prefix) {
WARNING("not implemented");
return;
return CG();
}
std::vector<uint8_t> data = acg.load(page);
if (data.empty())
return;
return CG();
bool set_palette = extract_palette && !ignore_palette.count(page);
CG cg;
@@ -92,24 +92,12 @@ void AGS::load_cg(int page, int transparent)
break;
}
// J command
if (cg_dest.has_value()) {
cg.x = cg_dest->x;
cg.y = cg_dest->y;
cg_dest = std::nullopt;
if (cg.surface()) {
SDL_SetSurfacePalette(cg.surface(), screen_palette);
if (censor_list.count(page))
mosaic(cg.surface());
}
if (extract_cg && cg.surface()) {
SDL_SetSurfacePalette(cg.surface(), screen_palette);
if (censor_list.count(page)) {
mosaic(cg.surface());
}
SDL_Rect dstrect = { cg.x, cg.y, cg.width(), cg.height() };
SDL_BlitSurface(cg.surface(), NULL, hBmpScreen[dest_screen], &dstrect);
if (dest_screen == 0) {
draw_screen(dstrect.x, dstrect.y, dstrect.w, dstrect.h);
}
}
if (set_palette) {
dirty_rect = {0, 0, screen_width, screen_height};
#ifdef ENABLE_DEBUGGER
@@ -117,20 +105,53 @@ void AGS::load_cg(int page, int transparent)
g_debugger->on_palette_change();
#endif
}
return cg;
}
void AGS::copy(int sx, int sy, int ex, int ey, int dx, int dy)
void AGS::blit_cg(int dest, CG& cg, const SDL_Rect* src, int dx, int dy)
{
if (!cg.surface())
return;
SDL_Rect dstrect = { dx, dy, src ? src->w : cg.width(), src ? src->h : cg.height() };
SDL_BlitSurface(cg.surface(), src, hBmpScreen[dest], &dstrect);
if (dest == 0) {
draw_screen(dstrect.x, dstrect.y, dstrect.w, dstrect.h);
}
}
void AGS::load_cg(int page, int transparent)
{
CG cg = load_cg_surface(page, transparent);
if (!cg)
return;
// J command
if (cg_dest.has_value()) {
cg.x = cg_dest->x;
cg.y = cg_dest->y;
cg_dest = std::nullopt;
}
if (extract_cg)
blit_cg(dest_screen, cg, NULL, cg.x, cg.y);
}
void AGS::copy_screen(int src, int dest, int sx, int sy, int ex, int ey, int dx, int dy, int transparent_color)
{
int width = ex - sx + 1;
int height = ey - sy + 1;
SDL_Rect srcrect = {sx, sy, width, height};
SDL_Rect destrect = {dx, dy, width, height};
SDL_BlitSurface(hBmpScreen[src_screen], &srcrect, hBmpScreen[dest_screen], &destrect);
SDL_Surface* src_surface = hBmpScreen[src];
if (transparent_color >= 0)
SDL_SetColorKey(src_surface, SDL_TRUE, transparent_color);
SDL_BlitSurface(src_surface, &srcrect, hBmpScreen[dest], &destrect);
if (transparent_color >= 0)
SDL_SetColorKey(src_surface, SDL_FALSE, 0);
if(dest_screen == 0) {
draw_screen(dx, dy, ex - sx + 1, ey - sy + 1);
}
if (dest == 0)
draw_screen(dx, dy, width, height);
}
void AGS::gcopy(int gsc, int gde, int glx, int gly, int gsw)
+8 -1
View File
@@ -104,7 +104,14 @@ void AGS::init_windows()
case 3: text_w[i].reset(24, 310, 183, 391, false, false); break;
case 4: text_w[i].reset(464, 310, 623, 391, false, false); break;
}
menu_w[i].reset(416, 24, 591, 248, true, true);
switch (i) {
default:
case 0: menu_w[i].reset(416, 24, 591, 248, true, true); break;
case 1: menu_w[i].reset(32, 16, 191, 216, true, true); break;
case 2: menu_w[i].reset(448, 16, 607, 216, true, true); break;
case 3: menu_w[i].reset(32, 223, 191, 383, true, true); break;
case 4: menu_w[i].reset(448, 223, 607, 383, true, true); break;
}
break;
default:
text_w[i].reset(8, 311, 623, 391, true, false);
+6 -9
View File
@@ -513,18 +513,15 @@ void NACT::message(uint8_t first_byte)
void NACT::text_wait()
{
if (msgskip->skipping())
return;
Uint32 dwTime = SDL_GetTicks() + text_wait_time;
for(;;) {
if(terminate) {
return;
}
RND = get_key();
if(RND && wait_keydown) {
while (!terminate) {
if (get_key(false) && wait_keydown)
break;
}
if(dwTime <= SDL_GetTicks()) {
if (dwTime <= SDL_GetTicks())
break;
}
sys_sleep(16);
}
}
+4 -4
View File
@@ -22,11 +22,11 @@
#define MAX_VERB 128
#define MAX_OBJ 256
#define MAX_VAR 512
#define MAX_VAR 768 // Gakuen KING uses up to VAR737.
#define MAX_STRVAR 10
#define TRACE(fmt, ...) if (config.trace) trace(fmt "\n", ##__VA_ARGS__)
#define TRACE_UNIMPLEMENTED(fmt, ...) trace("Unimplemented command " fmt "\n", ##__VA_ARGS__)
#define TRACE_UNIMPLEMENTED(fmt, ...) trace("Unimplemented command at %d:%04x " fmt "\n", sco.page(), sco.cmd_addr(), ##__VA_ARGS__)
class AGS;
class MAKO;
@@ -80,7 +80,7 @@ protected:
void cmd_set_verbobj2();
virtual void cmd_open_verb() = 0;
void cmd_a();
virtual void cmd_a();
virtual void cmd_b() { sco.unknown_command('B'); }
virtual void cmd_d() { sco.unknown_command('D'); }
virtual void cmd_e() { sco.unknown_command('E'); }
@@ -146,7 +146,7 @@ protected:
int menu_select(int num_items);
void wait_after_open_menu();
uint8 get_key();
uint8 get_key(bool notify_texthook = true);
void wait_key_release(uint8_t mask = 0xff);
void get_cursor(int* x, int* y);
+1790 -109
View File
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -106,11 +106,12 @@ void NACT::process_next_event()
handle_event(std::move(e));
}
uint8 NACT::get_key()
uint8 NACT::get_key(bool notify_texthook)
{
uint8 val = 0;
texthook_keywait();
if (notify_texthook)
texthook_keywait();
pump_events();
+1
View File
@@ -58,6 +58,7 @@ public:
: is_page_call(is_page_call), page(page), addr(addr) {}
};
const std::vector<StackFrame>& get_call_stack() const { return call_stack; }
void set_call_stack(std::vector<StackFrame> frames) { call_stack = std::move(frames); }
int write_instruction(int page, int addr, uint8_t op);
private: