mirror of https://github.com/nmlgc/ReC98.git
[Decompilation] [th02] Dialog: Face rendering
Part of P0260, funded by Yanga.
This commit is contained in:
parent
be31caeba8
commit
c4622992b5
|
@ -6,7 +6,11 @@ typedef Planar<mpn_plane_t> mpn_image_t;
|
|||
|
||||
typedef struct {
|
||||
char magic[4]; // = "MPTN"
|
||||
uint8_t count; // Stored minus 1.
|
||||
|
||||
// Stored minus 1. (Probably because MIKO_K.MPN contains 256 tiles and ZUN
|
||||
// absolutely wanted to store this value in a single byte regardless.)
|
||||
uint8_t count;
|
||||
|
||||
int8_t unused;
|
||||
} mpn_header_t;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "platform.h"
|
||||
#include "x86real.h"
|
||||
#include "pc98.h"
|
||||
#include "planar.h"
|
||||
#include "shiftjis.hpp"
|
||||
#include "master.hpp"
|
||||
extern "C" {
|
||||
|
@ -9,6 +10,8 @@ extern "C" {
|
|||
}
|
||||
#include "th02/hardware/pages.hpp"
|
||||
#include "th02/formats/dialog.hpp"
|
||||
#include "th02/formats/tile.hpp"
|
||||
#include "th02/formats/mpn.hpp"
|
||||
#include "th02/main/playfld.hpp"
|
||||
#include "th02/main/score.hpp"
|
||||
#include "th02/main/scroll.hpp"
|
||||
|
@ -18,6 +21,7 @@ extern "C" {
|
|||
#include "th02/main/player/player.hpp"
|
||||
#include "th02/main/tile/tile.hpp"
|
||||
#include "th02/sprites/main_pat.h"
|
||||
#include "th02/sprites/face.hpp"
|
||||
|
||||
// Coordinates
|
||||
// -----------
|
||||
|
@ -36,6 +40,9 @@ static const pixel_t BOX_MIDDLE_W = (
|
|||
);
|
||||
|
||||
static const pixel_t BOX_SLIDE_SPEED = (PLAYFIELD_W / 24);
|
||||
|
||||
static const screen_x_t FACE_LEFT = (BOX_LEFT + 8);
|
||||
static const screen_y_t FACE_TOP = (BOX_TOP + 8);
|
||||
// -----------
|
||||
|
||||
// State
|
||||
|
@ -267,3 +274,38 @@ void near dialog_post(void)
|
|||
|
||||
graph_accesspage(page_back);
|
||||
}
|
||||
|
||||
void pascal near dialog_face_put(
|
||||
int topleft_id // ACTUAL TYPE: face_topleft_id_t
|
||||
)
|
||||
{
|
||||
static_assert(FACE_TILES_X == 3);
|
||||
static_assert(FACE_TILES_Y == 3);
|
||||
|
||||
vram_y_t top1;
|
||||
vram_y_t top2 = 0;
|
||||
vram_y_t top3 = 0;
|
||||
|
||||
top1 = scroll_screen_y_to_vram(top1, FACE_TOP);
|
||||
scroll_add_scrolled(top2, top1, TILE_H);
|
||||
scroll_add_scrolled(top3, top2, TILE_H);
|
||||
|
||||
if(topleft_id == FACE_COL_0) {
|
||||
grcg_setcolor(GC_RMW, 0);
|
||||
grcg_boxfill(
|
||||
FACE_LEFT, top1, (FACE_LEFT + FACE_W - 1), (top1 + FACE_H - 1)
|
||||
);
|
||||
grcg_off();
|
||||
return;
|
||||
}
|
||||
|
||||
mpn_put_8((FACE_LEFT + (0 * TILE_W)), top1, face_tile_id(topleft_id, 0, 0));
|
||||
mpn_put_8((FACE_LEFT + (1 * TILE_W)), top1, face_tile_id(topleft_id, 1, 0));
|
||||
mpn_put_8((FACE_LEFT + (2 * TILE_W)), top1, face_tile_id(topleft_id, 2, 0));
|
||||
mpn_put_8((FACE_LEFT + (0 * TILE_W)), top2, face_tile_id(topleft_id, 0, 1));
|
||||
mpn_put_8((FACE_LEFT + (1 * TILE_W)), top2, face_tile_id(topleft_id, 1, 1));
|
||||
mpn_put_8((FACE_LEFT + (2 * TILE_W)), top2, face_tile_id(topleft_id, 2, 1));
|
||||
mpn_put_8((FACE_LEFT + (0 * TILE_W)), top3, face_tile_id(topleft_id, 0, 2));
|
||||
mpn_put_8((FACE_LEFT + (1 * TILE_W)), top3, face_tile_id(topleft_id, 1, 2));
|
||||
mpn_put_8((FACE_LEFT + (2 * TILE_W)), top3, face_tile_id(topleft_id, 2, 2));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
// TH02 stores its 48×48 faces for in-game dialogs as 3×3 sets of .MPN tiles in
|
||||
// MIKO_K.PTN… yup.
|
||||
|
||||
#define FACE_TILES_X (FACE_W / TILE_W)
|
||||
#define FACE_TILES_Y (FACE_H / TILE_H)
|
||||
|
||||
#define FACE_TILE_STRIDE 16
|
||||
|
||||
// The 20 faces are arranged by placing a 5×4 grid of 3×3 tiles on the left
|
||||
// side of a 16×12 grid. This results in the inner (face_col, face_row) values
|
||||
// for the outer .MPN tile IDs:
|
||||
//
|
||||
// 012 345 678 9AB CDE F
|
||||
// ┌───────────────────┐
|
||||
// 0 │0 |1 |2 |3 |4 |
|
||||
// 1 │ , | , | , | , | , |
|
||||
// 2 │ 0| 0| 0| 0| 0|
|
||||
// ├───────────────────┤
|
||||
// 3 │0 |1 |2 |3 |4 |
|
||||
// 4 │ , | , | , | , | , |
|
||||
// 5 │ 1| 1| 1| 1| 1|
|
||||
// ├───────────────────┤
|
||||
// 6 │0 |1 |2 |3 |4 |
|
||||
// 7 │ , | , | , | , | , |
|
||||
// 8 │ 2| 2| 2| 2| 2|
|
||||
// ├───────────────────┤
|
||||
// 9 │0 |1 |2 |3 |4 |
|
||||
// A │ , | , | , | , | , |
|
||||
// B │ 3| 3| 3| 3| 3|
|
||||
// └───────────────────┘
|
||||
#define topleft_id_at(face_col, face_row) ( \
|
||||
(face_row * FACE_TILES_Y * FACE_TILE_STRIDE) + (face_col * FACE_TILES_X) \
|
||||
)
|
||||
|
||||
// Only stores the top-left ID for every face; the remaining ones can be
|
||||
// calculated from the tile layout.
|
||||
typedef enum face_tile_topleft_t {
|
||||
FACE_REIMU_NEUTRAL = topleft_id_at(0, 0),
|
||||
FACE_REIMU_HUSHED = topleft_id_at(1, 0),
|
||||
FACE_REIMU_ANGRY = topleft_id_at(2, 0),
|
||||
FACE_REIMU_JOY = topleft_id_at(3, 0),
|
||||
FACE_REIMU_FROWN = topleft_id_at(4, 0),
|
||||
FACE_REIMU_FALL = topleft_id_at(0, 1),
|
||||
FACE_REIMU_CRY = topleft_id_at(1, 1),
|
||||
FACE_REIMU_QUESTION = topleft_id_at(2, 1),
|
||||
FACE_REIMU_SWEAT = topleft_id_at(3, 1),
|
||||
FACE_REIMU_FLIRTY = topleft_id_at(4, 1), // Best guess given its usage... :/
|
||||
FACE_GENJII = topleft_id_at(0, 2),
|
||||
FACE_RIKA = topleft_id_at(1, 2),
|
||||
FACE_MEIRA_NEUTRAL = topleft_id_at(2, 2),
|
||||
FACE_MIMA_SMILE = topleft_id_at(3, 2),
|
||||
FACE_MIMA_FROWN = topleft_id_at(4, 2),
|
||||
FACE_MARISA_SMILE = topleft_id_at(0, 3),
|
||||
FACE_MARISA_FROWN = topleft_id_at(1, 3),
|
||||
FACE_MEIRA_SWEAT = topleft_id_at(2, 3),
|
||||
FACE_EXRIKA_SMILE = topleft_id_at(3, 3),
|
||||
FACE_EXRIKA_FROWN = topleft_id_at(4, 3),
|
||||
|
||||
// Fills the face area with hardware color 0 and doesn't blit any tile.
|
||||
FACE_COL_0 = 0xFF,
|
||||
};
|
||||
|
||||
#undef topleft_id_at
|
||||
|
||||
inline int face_tile_id(
|
||||
int topleft, // ACTUAL TYPE: face_tile_topleft_t
|
||||
int inner_col,
|
||||
int inner_row
|
||||
) {
|
||||
return (topleft + (inner_row * FACE_TILE_STRIDE) + inner_col);
|
||||
}
|
|
@ -3,10 +3,17 @@
|
|||
/// Sprite sizes
|
||||
/// ------------
|
||||
|
||||
#define FACE_W 48
|
||||
#define FACE_H 48
|
||||
|
||||
#define DIALOG_BOX_PART_W 32
|
||||
#define DIALOG_BOX_PART_H 32
|
||||
|
||||
#define DIALOG_BOX_LEFT_W 96
|
||||
#define DIALOG_BOX_FACE_BORDER 8
|
||||
|
||||
#define DIALOG_BOX_LEFT_W ( \
|
||||
(DIALOG_BOX_FACE_BORDER * 2) + FACE_W + DIALOG_BOX_PART_W \
|
||||
)
|
||||
|
||||
#define DIALOG_BOX_LEFT_PARTS (DIALOG_BOX_LEFT_W / DIALOG_BOX_PART_W)
|
||||
/// ------------
|
||||
|
|
130
th02_main.asm
130
th02_main.asm
|
@ -43,6 +43,28 @@ DIALOG_LINE_LENGTH = 36
|
|||
DIALOG_LINE_SIZE = (DIALOG_LINE_LENGTH + 4)
|
||||
DIALOG_BOX_LINES = 2
|
||||
|
||||
FACE_REIMU_NEUTRAL = 0
|
||||
FACE_REIMU_HUSHED = 3
|
||||
FACE_REIMU_ANGRY = 6
|
||||
FACE_REIMU_JOY = 9
|
||||
FACE_REIMU_FROWN = 12
|
||||
FACE_REIMU_FALL = 48
|
||||
FACE_REIMU_CRY = 51
|
||||
FACE_REIMU_QUESTION = 54
|
||||
FACE_REIMU_SWEAT = 57
|
||||
FACE_REIMU_FLIRTY = 60
|
||||
FACE_GENJII = 96
|
||||
FACE_RIKA = 99
|
||||
FACE_MEIRA_NEUTRAL = 102
|
||||
FACE_MIMA_SMILE = 105
|
||||
FACE_MIMA_FROWN = 108
|
||||
FACE_MARISA_SMILE = 144
|
||||
FACE_MARISA_FROWN = 147
|
||||
FACE_MEIRA_SWEAT = 150
|
||||
FACE_EXRIKA_SMILE = 153
|
||||
FACE_EXRIKA_FROWN = 156
|
||||
FACE_COL_0 = 255
|
||||
|
||||
main_01 group main_01_TEXT, POINTNUM_TEXT, main_01__TEXT, ITEM_TEXT, HUD_TEXT, main_01___TEXT, PLAYER_B_TEXT, main_01____TEXT
|
||||
main_03 group main_03_TEXT, DIALOG_TEXT, main_03__TEXT
|
||||
|
||||
|
@ -12370,112 +12392,12 @@ sub_12B9E endp
|
|||
extern @dialog_load_and_init$qv:proc
|
||||
@dialog_pre$qv procdesc near
|
||||
@dialog_post$qv procdesc near
|
||||
@DIALOG_FACE_PUT$QI procdesc pascal near \
|
||||
topleft_id:word
|
||||
DIALOG_TEXT ends
|
||||
|
||||
main_03__TEXT segment byte public 'CODE' use16
|
||||
|
||||
; =============== S U B R O U T I N E =======================================
|
||||
|
||||
; Attributes: bp-based frame
|
||||
|
||||
sub_12F23 proc near
|
||||
|
||||
@@top_2 = word ptr -4
|
||||
@@top_1 = word ptr -2
|
||||
@@mpn_image = word ptr 4
|
||||
|
||||
enter 4, 0
|
||||
push si
|
||||
push di
|
||||
mov di, [bp+@@mpn_image]
|
||||
mov [bp+@@top_1], 0
|
||||
mov [bp+@@top_2], 0
|
||||
mov si, 328
|
||||
add si, _scroll_line
|
||||
cmp si, RES_Y
|
||||
jl short loc_12F47
|
||||
sub si, RES_Y
|
||||
|
||||
loc_12F47:
|
||||
lea ax, [si+TILE_H]
|
||||
add [bp+@@top_1], ax
|
||||
cmp [bp+@@top_1], RES_Y
|
||||
jl short loc_12F59
|
||||
sub [bp+@@top_1], RES_Y
|
||||
|
||||
loc_12F59:
|
||||
mov ax, [bp+@@top_1]
|
||||
add ax, TILE_H
|
||||
add [bp+@@top_2], ax
|
||||
cmp [bp+@@top_2], RES_Y
|
||||
jl short loc_12F6E
|
||||
sub [bp+@@top_2], RES_Y
|
||||
|
||||
loc_12F6E:
|
||||
cmp di, 255
|
||||
jnz short loc_12F94
|
||||
call grcg_setcolor pascal, (GC_RMW shl 16) + 0
|
||||
push 40
|
||||
push si
|
||||
push 87
|
||||
lea ax, [si+47]
|
||||
push ax
|
||||
call grcg_boxfill
|
||||
call grcg_off
|
||||
jmp short loc_13009
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_12F94:
|
||||
call @mpn_put_8$qiii pascal, 40, si, di
|
||||
push 56 ; left
|
||||
push si ; top
|
||||
lea ax, [di+1]
|
||||
push ax ; image
|
||||
call @mpn_put_8$qiii
|
||||
push 72 ; left
|
||||
push si ; top
|
||||
lea ax, [di+2]
|
||||
push ax ; image
|
||||
call @mpn_put_8$qiii
|
||||
push 40 ; left
|
||||
push [bp+@@top_1] ; top
|
||||
lea ax, [di+10h]
|
||||
push ax ; image
|
||||
call @mpn_put_8$qiii
|
||||
push 56 ; left
|
||||
push [bp+@@top_1] ; top
|
||||
lea ax, [di+11h]
|
||||
push ax ; image
|
||||
call @mpn_put_8$qiii
|
||||
push 72 ; left
|
||||
push [bp+@@top_1] ; top
|
||||
lea ax, [di+12h]
|
||||
push ax ; image
|
||||
call @mpn_put_8$qiii
|
||||
push 40 ; left
|
||||
push [bp+@@top_2] ; top
|
||||
lea ax, [di+20h]
|
||||
push ax ; image
|
||||
call @mpn_put_8$qiii
|
||||
push 56 ; left
|
||||
push [bp+@@top_2] ; top
|
||||
lea ax, [di+21h]
|
||||
push ax ; image
|
||||
call @mpn_put_8$qiii
|
||||
push 72 ; left
|
||||
push [bp+@@top_2] ; top
|
||||
lea ax, [di+22h]
|
||||
push ax ; image
|
||||
call @mpn_put_8$qiii
|
||||
|
||||
loc_13009:
|
||||
pop di
|
||||
pop si
|
||||
leave
|
||||
retn 2
|
||||
sub_12F23 endp
|
||||
|
||||
|
||||
; =============== S U B R O U T I N E =======================================
|
||||
|
||||
; Attributes: bp-based frame
|
||||
|
@ -12534,7 +12456,7 @@ sub_13055 proc near
|
|||
|
||||
var_4 = word ptr -4
|
||||
var_2 = word ptr -2
|
||||
@@mpn_image = word ptr 4
|
||||
@@topleft_id = word ptr 4
|
||||
|
||||
enter 4, 0
|
||||
push si
|
||||
|
@ -12551,7 +12473,7 @@ var_2 = word ptr -2
|
|||
|
||||
loc_13090:
|
||||
call _input_sense
|
||||
call sub_12F23 pascal, [bp+@@mpn_image]
|
||||
call @dialog_face_put$qi pascal, [bp+@@topleft_id]
|
||||
cmp si, 24h ; '$'
|
||||
jg short loc_130B3
|
||||
push 0
|
||||
|
|
Loading…
Reference in New Issue