From e4ff9dae97f5b0f17d92d72d6b3fccca3a651f10 Mon Sep 17 00:00:00 2001 From: nmlgc Date: Fri, 29 Mar 2024 07:11:47 +0100 Subject: [PATCH] [Maintenance] Cutscenes: Centrally define picture coordinates Part of P0278, funded by Yanga. --- th01/end/end.cpp | 2 +- th01/end/pic.cpp | 18 ++++++---- th01/end/pic.hpp | 9 ++--- th01/formats/cutscene.hpp | 9 +++++ th03/cutscene/cutscene.cpp | 70 ++++++++++++++++++++------------------ 5 files changed, 60 insertions(+), 48 deletions(-) create mode 100644 th01/formats/cutscene.hpp diff --git a/th01/end/end.cpp b/th01/end/end.cpp index 9d28dc29..1251838f 100644 --- a/th01/end/end.cpp +++ b/th01/end/end.cpp @@ -31,7 +31,7 @@ inline void pic_caption_type_n(int line, size_t len, const char str[]) { graph_type_ank_n( (((RES_X / 2) - ((len * GLYPH_HALF_W) / 2) + BYTE_MASK) & ~BYTE_MASK), - (PIC_BOTTOM + (((line * 2) + 1) * GLYPH_H)), + (CUTSCENE_PIC_TOP + CUTSCENE_PIC_H + (((line * 2) + 1) * GLYPH_H)), len, str ); diff --git a/th01/end/pic.cpp b/th01/end/pic.cpp index 716e05db..98624ee3 100644 --- a/th01/end/pic.cpp +++ b/th01/end/pic.cpp @@ -16,10 +16,12 @@ void end_pic_show(int quarter) { egc_start_copy(); - pixel_t src_left = ((quarter % 2) * PIC_W); - pixel_t src_top = ((quarter / 2) * PIC_H); + pixel_t src_left = ((quarter % 2) * CUTSCENE_PIC_W); + pixel_t src_top = ((quarter / 2) * CUTSCENE_PIC_H); uvram_offset_t vram_offset_src = vram_offset_shift(src_left, src_top); - uvram_offset_t vram_offset_dst = vram_offset_shift(PIC_LEFT, PIC_TOP); + uvram_offset_t vram_offset_dst = vram_offset_shift( + CUTSCENE_PIC_LEFT, CUTSCENE_PIC_TOP + ); vram_word_amount_t vram_x; pixel_t y; @@ -32,8 +34,9 @@ void end_pic_show(int quarter) // Optimizations aside, using the EGC can't give you a better algorithm, // as its tile registers are limited to 16 dots. Expanding to at least 32 // dots would have really been nice for ≥386 CPUs... - for(y = 0; y < PIC_H; y++) { - for(vram_x = 0; vram_x < (PIC_VRAM_W / EGC_REGISTER_SIZE); vram_x++) { + for(y = 0; y < CUTSCENE_PIC_H; y++) { + vram_x = 0; + while(vram_x < (CUTSCENE_PIC_VRAM_W / EGC_REGISTER_SIZE)) { egc_temp_t d; graph_accesspage_func(1); d = egc_chunk(vram_offset_src); @@ -41,9 +44,10 @@ void end_pic_show(int quarter) vram_offset_src += EGC_REGISTER_SIZE; vram_offset_dst += EGC_REGISTER_SIZE; + vram_x++; } - vram_offset_src += (ROW_SIZE - PIC_VRAM_W); - vram_offset_dst += (ROW_SIZE - PIC_VRAM_W); + vram_offset_src += (ROW_SIZE - CUTSCENE_PIC_VRAM_W); + vram_offset_dst += (ROW_SIZE - CUTSCENE_PIC_VRAM_W); } egc_off(); } diff --git a/th01/end/pic.hpp b/th01/end/pic.hpp index ed37fda8..819cc34c 100644 --- a/th01/end/pic.hpp +++ b/th01/end/pic.hpp @@ -1,11 +1,6 @@ -static const pixel_t PIC_W = (RES_X / 2); -static const pixel_t PIC_H = (RES_Y / 2); -static const screen_x_t PIC_LEFT = ((RES_X / 2) - (PIC_W / 2)); -static const screen_y_t PIC_TOP = ((RES_Y / 2) - (PIC_H / 2)); -static const screen_y_t PIC_RIGHT = (PIC_LEFT + PIC_W); -static const screen_y_t PIC_BOTTOM = (PIC_TOP + PIC_H); +#include "th01/formats/cutscene.hpp" -static const pixel_t PIC_VRAM_W = (PIC_W / BYTE_DOTS); +static const screen_y_t CUTSCENE_PIC_TOP = ((RES_Y / 2) - (CUTSCENE_PIC_H / 2)); // Loads the ending pictures from the .GRP file [fn] onto graphics page #1, // and sets the hardware color palette to the one in [fn]'s header. diff --git a/th01/formats/cutscene.hpp b/th01/formats/cutscene.hpp new file mode 100644 index 00000000..9bc0716c --- /dev/null +++ b/th01/formats/cutscene.hpp @@ -0,0 +1,9 @@ +// Cutscene/ending picture dimensions. Always horizontally centered, but shown +// at different vertical positions depending on the game. +static const pixel_t CUTSCENE_PIC_W = (RES_X / 2); +static const pixel_t CUTSCENE_PIC_H = (RES_Y / 2); +static const screen_x_t CUTSCENE_PIC_LEFT = ( + (RES_X / 2) - (CUTSCENE_PIC_W / 2) +); + +static const pixel_t CUTSCENE_PIC_VRAM_W = (CUTSCENE_PIC_W / BYTE_DOTS); diff --git a/th03/cutscene/cutscene.cpp b/th03/cutscene/cutscene.cpp index 4541d1b0..97e349fb 100644 --- a/th03/cutscene/cutscene.cpp +++ b/th03/cutscene/cutscene.cpp @@ -20,6 +20,7 @@ #include "shiftjis.hpp" #include "master.hpp" #include "libs/kaja/kaja.h" +#include "th01/formats/cutscene.hpp" #include "th02/v_colors.hpp" #include "th02/hardware/frmdelay.h" #if (GAME == 5) @@ -61,16 +62,8 @@ extern "C" { // Constants // --------- -static const pixel_t PIC_W = PI_QUARTER_W; -static const pixel_t PIC_H = PI_QUARTER_H; -static const screen_x_t PIC_LEFT = ((RES_X / 2) - (PIC_W / 2)); -static const screen_y_t PIC_TOP = 64; -static const screen_x_t PIC_RIGHT = (PIC_LEFT + PIC_W); -static const screen_x_t PIC_BOTTOM = (PIC_TOP + PIC_H); - -static const vram_byte_amount_t PIC_VRAM_W = (PIC_W / BYTE_DOTS); - -static const int PIC_SLOT = 0; +static const screen_y_t CUTSCENE_PIC_TOP = 64; +static const int CUTSCENE_PIC_SLOT = 0; // Note that this does not correspond to the tiled area painted into TH05's // EDBK?.PI images. @@ -253,7 +246,7 @@ bool16 pascal near cutscene_script_load(const char* fn) // everything even more complicated.) #if (GAME == 5) #define pic_copy_to_other(left, top) { \ - egc_copy_rect_1_to_0_16(left, top, PIC_W, PIC_H); \ + egc_copy_rect_1_to_0_16(left, top, CUTSCENE_PIC_W, CUTSCENE_PIC_H); \ } void pascal near pic_put_both_masked( @@ -261,7 +254,7 @@ bool16 pascal near cutscene_script_load(const char* fn) ) { graph_accesspage(1); - pi_put_quarter_masked_8(left, top, PIC_SLOT, quarter, mask_id); + pi_put_quarter_masked_8(left, top, CUTSCENE_PIC_SLOT, quarter, mask_id); pic_copy_to_other(left, top); } #else @@ -277,9 +270,9 @@ bool16 pascal near cutscene_script_load(const char* fn) // as optimal as you can get within the EGC's limited 16-dot tile // register. y = 0; - while(y < PIC_H) { + while(y < CUTSCENE_PIC_H) { vram_x = 0; - while(vram_x < PIC_VRAM_W) { + while(vram_x < CUTSCENE_PIC_VRAM_W) { egc_temp_t tmp; // ZUN bloat: Remember that the call site temporarily switched @@ -291,7 +284,7 @@ bool16 pascal near cutscene_script_load(const char* fn) vo += EGC_REGISTER_SIZE; } y++; - vo += (ROW_SIZE - PIC_VRAM_W); + vo += (ROW_SIZE - CUTSCENE_PIC_VRAM_W); } egc_off(); @@ -313,21 +306,21 @@ bool16 pascal near cutscene_script_load(const char* fn) vram_offset_t vo_temp; pi_buffer_p_t row_p; - pi_buffer_p_init_quarter(row_p, PIC_SLOT, quarter); + pi_buffer_p_init_quarter(row_p, CUTSCENE_PIC_SLOT, quarter); // ZUN bloat: See the call site. graph_showpage(1); vram_offset_t vo = vram_offset_shift(left, top); graph_accesspage(0); - for(pixel_t y = 0; y < PIC_H; y++) { + for(pixel_t y = 0; y < CUTSCENE_PIC_H; y++) { // This might actually be faster than clearing the masked pixels // using the GRCG and doing an unaccelerated 4-plane VRAM OR. - graph_pack_put_8_noclip(0, TEMP_ROW, row_p, PIC_W); + graph_pack_put_8_noclip(0, TEMP_ROW, row_p, CUTSCENE_PIC_W); egc_start_copy(); egc_setup_copy_masked(PI_MASKS[mask_id][y & (PI_MASK_COUNT - 1)]); vo_temp = vram_offset_shift(0, TEMP_ROW); vram_word = 0; - while(vram_word < (PIC_W / EGC_REGISTER_DOTS)) { + while(vram_word < (CUTSCENE_PIC_W / EGC_REGISTER_DOTS)) { egc_chunk(vo) = egc_chunk(vo_temp); vram_word++; vo += EGC_REGISTER_SIZE; @@ -335,7 +328,7 @@ bool16 pascal near cutscene_script_load(const char* fn) } egc_off(); - vo += (ROW_SIZE - PIC_VRAM_W); + vo += (ROW_SIZE - CUTSCENE_PIC_VRAM_W); pi_buffer_p_offset(row_p, PI_W, 0); pi_buffer_p_normalize(row_p); } @@ -816,9 +809,9 @@ script_ret_t pascal near script_op(unsigned char c) if((c == '=') || (c == '@')) { graph_accesspage(1); if(c == '=') { - pi_palette_apply(PIC_SLOT); + pi_palette_apply(CUTSCENE_PIC_SLOT); } - pi_put_8(0, 0, PIC_SLOT); + pi_put_8(0, 0, CUTSCENE_PIC_SLOT); graph_copy_page(0); graph_accesspage(0); #if (GAME == 5) @@ -827,19 +820,19 @@ script_ret_t pascal near script_op(unsigned char c) box_bg_allocate_and_snap(); #endif } else if(c == '-') { - pi_free(PIC_SLOT); + pi_free(CUTSCENE_PIC_SLOT); return CONTINUE; } else if(c == 'p') { - pi_palette_apply(PIC_SLOT); + pi_palette_apply(CUTSCENE_PIC_SLOT); return CONTINUE; } else if(c != ',') { script_p--; } else { script_param_read_fn(fn, p1, c); #if (GAME >= 4) - pi_free(PIC_SLOT); + pi_free(CUTSCENE_PIC_SLOT); #endif - pi_load(PIC_SLOT, fn); + pi_load(CUTSCENE_PIC_SLOT, fn); } break; @@ -890,11 +883,16 @@ script_ret_t pascal near script_op(unsigned char c) graph_accesspage(0); #endif if(p1 < PI_QUARTER_COUNT) { - pi_put_quarter_8(PIC_LEFT, PIC_TOP, PIC_SLOT, p1); + pi_put_quarter_8( + CUTSCENE_PIC_LEFT, CUTSCENE_PIC_TOP, CUTSCENE_PIC_SLOT, p1 + ); } else { grcg_setcolor(GC_RMW, 0); grcg_boxfill_8( - PIC_LEFT, PIC_TOP, (PIC_RIGHT - 1), (PIC_BOTTOM - 1) + CUTSCENE_PIC_LEFT, + CUTSCENE_PIC_TOP, + (CUTSCENE_PIC_LEFT + CUTSCENE_PIC_W - 1), + (CUTSCENE_PIC_TOP + CUTSCENE_PIC_H - 1) ); grcg_off(); } @@ -904,14 +902,16 @@ script_ret_t pascal near script_op(unsigned char c) script_param_number_default = 1; script_param_read_number_second(p2); for(i = 0; i < PI_MASK_COUNT; i++) { - pic_put_both_masked(PIC_LEFT, PIC_TOP, p1, i); + pic_put_both_masked(CUTSCENE_PIC_LEFT, CUTSCENE_PIC_TOP, p1, i); if(!fast_forward) { frame_delay(p2); } } #if (GAME == 5) graph_accesspage(1); - pi_put_quarter_8(PIC_LEFT, PIC_TOP, PIC_SLOT, p1); + pi_put_quarter_8( + CUTSCENE_PIC_LEFT, CUTSCENE_PIC_TOP, CUTSCENE_PIC_SLOT, p1 + ); frame_delay(1); // ZUN quirk #else // ZUN bloat: See above. @@ -919,13 +919,17 @@ script_ret_t pascal near script_op(unsigned char c) graph_showpage(1); graph_accesspage(0); - pi_put_quarter_8(PIC_LEFT, PIC_TOP, PIC_SLOT, p1); + pi_put_quarter_8( + CUTSCENE_PIC_LEFT, CUTSCENE_PIC_TOP, CUTSCENE_PIC_SLOT, p1 + ); #endif } #if (GAME <= 4) graph_showpage(0); // ZUN bloat: See above. #endif - pic_copy_to_other(PIC_LEFT, PIC_TOP); + static_assert(CUTSCENE_PIC_W == PI_QUARTER_W); + static_assert(CUTSCENE_PIC_H == PI_QUARTER_H); + pic_copy_to_other(CUTSCENE_PIC_LEFT, CUTSCENE_PIC_TOP); break; case 'm': @@ -1143,7 +1147,7 @@ void near cutscene_animate(void) } #if (GAME == 5) bgimage_free(); - pi_free(PIC_SLOT); + pi_free(CUTSCENE_PIC_SLOT); #else box_bg_put(); box_bg_free();