[Maintenance] Cutscenes: Centrally define picture coordinates

Part of P0278, funded by Yanga.
This commit is contained in:
nmlgc 2024-03-29 07:11:47 +01:00
parent 536ededecd
commit e4ff9dae97
5 changed files with 60 additions and 48 deletions

View File

@ -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
);

View File

@ -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();
}

View File

@ -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.

View File

@ -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);

View File

@ -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();