Files
ac-decomp/rel/m_font.c
T
2023-05-09 20:28:40 -04:00

1435 lines
36 KiB
C

#include "m_font.h"
#include "audio.h"
#include "m_lib.h"
#include "gbi_extensions.h"
#include "dataobject.h"
#include "game.h"
#include "graph.h"
#include "types.h"
#include "libultra/gu.h"
#include "sys_matrix.h"
#include "MSL_C/w_math.h"
#include "m_rcp.h"
#include "libc/math.h"
#define mFont_CC_FONT 0, 0, 0, PRIMITIVE, PRIMITIVE, 0, TEXEL0, 0
#define mFont_CC_NOFONT 0, 0, 0, PRIMITIVE, 0, PRIMITIVE, TEXEL0, PRIMITIVE
/* @unused static u8* mFont_Get_end_load_texture() */
extern void mFont_ct() {
// code removed probably
}
static int mMsg_CutLeftSpace(u8* str, int str_len) {
// This should've been renamed or moved to m_message.h
u8* dst;
u8* src;
int i, j;
for (i = 0; i < str_len; i++) {
if (str[i] != CHAR_SPACE) {
break;
}
}
if (i == str_len) {
return 0;
}
else if (i == 0) {
return str_len;
}
dst = str;
src = str + i;
for (j = i; j < str_len; j++) {
*dst++ = *src++;
}
for (j = 0; j < i; j++) {
*dst++ = CHAR_SPACE;
}
return str_len - i;
}
static u8 mFont_suji_data[] = "0123456789";
static int mFont_suji_check(u8 c) {
u8* suji = mFont_suji_data;
int i;
for (i = 0; i < 10; i++) {
if (c == suji[i]) {
return TRUE;
}
}
return FALSE;
}
extern int mFont_UnintToString(
u8* str,
int figure,
u32 num,
int figure_start,
int left_cut,
int fill_zero,
int separator
) {
int i;
int j;
u32 cur_num;
int next;
int temp2;
int last_figure;
int l = figure - figure_start;
u8 fill_char = fill_zero ? CHAR_ZERO : CHAR_SPACE;
u8 left_fill_char = fill_zero && !left_cut ? CHAR_ZERO : CHAR_SPACE;
cur_num = num;
for (last_figure = figure - 1; last_figure >= l; last_figure--) {
next = cur_num / 10;
temp2 = cur_num - next * 10;
if (cur_num == 0) {
if (num == 0 && last_figure == figure - 1) {
str[last_figure] = CHAR_ZERO;
}
else {
str[last_figure] = fill_char;
}
}
else {
str[last_figure] = mFont_suji_data[temp2];
}
cur_num = next;
}
for (i = last_figure; i >= 0; i--) {
str[i] = left_fill_char;
}
if (separator) {
int count = 0;
for (i = figure - 1; i >= 0; i--) {
if (mFont_suji_check(str[i])) {
count++;
if (count > 3) {
for (j = 0; j < i; j++) {
str[j] = str[j + 1];
}
str[i] = CHAR_COMMA;
count = 0;
}
}
}
}
if (left_cut) {
return mMsg_CutLeftSpace(str, figure);
}
return figure;
}
extern int mFont_char_save_data_check(u8 c) {
return c == CHAR_CONTROL_CODE || c == CHAR_MESSAGE_TAG;
}
// TODO: Match
extern u8 mFont_small_to_capital(u8 small) {
static const u8 tbl[56][2] = {
{ CHAR_a, CHAR_A },
{ CHAR_b, CHAR_B },
{ CHAR_c, CHAR_C },
{ CHAR_d, CHAR_D },
{ CHAR_e, CHAR_E },
{ CHAR_f, CHAR_F },
{ CHAR_g, CHAR_G },
{ CHAR_h, CHAR_H },
{ CHAR_i, CHAR_I },
{ CHAR_j, CHAR_J },
{ CHAR_k, CHAR_K },
{ CHAR_l, CHAR_L },
{ CHAR_m, CHAR_M },
{ CHAR_n, CHAR_N },
{ CHAR_o, CHAR_O },
{ CHAR_p, CHAR_P },
{ CHAR_q, CHAR_Q },
{ CHAR_r, CHAR_R },
{ CHAR_s, CHAR_S },
{ CHAR_t, CHAR_T },
{ CHAR_u, CHAR_U },
{ CHAR_v, CHAR_V },
{ CHAR_w, CHAR_W },
{ CHAR_x, CHAR_X },
{ CHAR_y, CHAR_Y },
{ CHAR_z, CHAR_Z },
{ CHAR_DIARESIS_a, CHAR_DIAERESIS_A },
{ CHAR_GRAVE_a, CHAR_GRAVE_A },
{ CHAR_ACUTE_a, CHAR_ACUTE_A },
{ CHAR_CIRCUMFLEX_a, CHAR_CIRCUMFLEX_A },
{ CHAR_TILDE_a, CHAR_TILDE_A },
{ CHAR_ANGSTROM_a, CHAR_ANGSTROM_A },
{ CHAR_LOWER_CEDILLA, CHAR_CEDILLA },
{ CHAR_GRAVE_e, CHAR_GRAVE_E },
{ CHAR_ACUTE_e, CHAR_ACUTE_E },
{ CHAR_CIRCUMFLEX_e, CHAR_CIRCUMFLEX_E },
{ CHAR_DIARESIS_e, CHAR_DIARESIS_E },
{ CHAR_GRAVE_i, CHAR_GRAVE_I },
{ CHAR_ACUTE_i, CHAR_ACUTE_I },
{ CHAR_CIRCUMFLEX_i, CHAR_CIRCUMFLEX_I },
{ CHAR_DIARESIS_i, CHAR_DIARESIS_I },
{ CHAR_LOWER_ETH, CHAR_ETH },
{ CHAR_TILDE_n, CHAR_TILDE_N },
{ CHAR_GRAVE_o, CHAR_GRAVE_O },
{ CHAR_ACUTE_o, CHAR_ACUTE_O },
{ CHAR_CIRCUMFLEX_o, CHAR_CIRCUMFLEX_O },
{ CHAR_TILDE_o, CHAR_TILDE_O },
{ CHAR_DIARESIS_o, CHAR_DIARESIS_O },
{ CHAR_oe, CHAR_OE },
{ CHAR_GRAVE_u, CHAR_GRAVE_U },
{ CHAR_ACUTE_u, CHAR_ACUTE_U },
{ CHAR_CIRCUMFLEX_u, CHAR_CIRCUMFLEX_U },
{ CHAR_DIARESIS_u, CHAR_DIARESIS_U },
{ CHAR_ACUTE_y, CHAR_ACUTE_Y },
{ CHAR_LOWER_THORN, CHAR_THORN },
{ CHAR_LOWER_ASH, CHAR_ASH }
};
int i;
for (i = 0; i < 56; i++) {
if (tbl[i][0] == small) {
return tbl[i][1];
}
}
return small;
}
static int mFont_Get_FontOffset(int c) {
static u8 offset_data[256] = {
6, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6,
6, 4, 4, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5,
7, 6, 5, 5, 5, 1, 4, 8, 6, 6, 1, 0, 8, 4, 8, 0,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 1, 4, 3, 4, 4,
2, 3, 5, 4, 4, 5, 5, 4, 4, 6, 6, 5, 5, 2, 4, 4,
5, 3, 5, 5, 5, 4, 4, 2, 5, 5, 6, 5, 0, 5, 5, 3,
5, 5, 5, 5, 5, 6, 7, 5, 4, 7, 7, 6, 7, 3, 5, 5,
5, 4, 6, 6, 7, 5, 6, 3, 6, 6, 7, 5, 5, 5, 5, 0,
0, 6, 6, 6, 6, 8, 4, 5, 5, 5, 5, 5, 5, 3, 5, 5,
0, 5, 5, 5, 5, 5, 5, 6, 6, 5, 5, 4, 5, 6, 6, 6,
3, 4, 2, 3, 5, 2, 2, 0, 0, 0, 0, 0, 5, 5, 5, 0,
1, 1, 1, 0, 3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
4, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4,
8, 3, 8, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2
};
return offset_data[c];
}
static u8* mFont_Get_FontTex_p() {
return FONT_nes_tex_font1;
}
extern int mFont_GetCodeWidth(int c, int cut) {
return mFont_TEX_CHAR_WIDTH - (cut ? mFont_Get_FontOffset(c) : 0);
}
extern int mFont_GetStringWidth(u8* str, int len, int cut) {
int width = 0;
int i;
for (i = 0; i < len; i++) {
width += mFont_GetCodeWidth(str[i], cut);
}
return width;
}
extern int mFont_GetStringWidth2(u8* str, int len, int cut) {
int width = 0;
int i;
int skip_size;
for (i = 0; i < len; i += skip_size) {
u8 c = str[i];
if (c != CHAR_CONTROL_CODE) {
width += mFont_GetCodeWidth(c, cut);
}
skip_size = mFont_CodeSize_get(str + i);
}
return width;
}
typedef struct control_code_s {
s8 size;
s8 attribute;
} mFont_ControlCodeInfo_t;
static mFont_ControlCodeInfo_t mFont_cont_info_tbl[mFont_CONT_CODE_NUM] = {
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 3, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 5, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 5, mFont_CONT_ATTRIBUTE_DEMO },
{ 5, mFont_CONT_ATTRIBUTE_DEMO },
{ 5, mFont_CONT_ATTRIBUTE_DEMO },
{ 5, mFont_CONT_ATTRIBUTE_DEMO },
{ 5, mFont_CONT_ATTRIBUTE_DEMO },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 4, mFont_CONT_ATTRIBUTE_0 },
{ 4, mFont_CONT_ATTRIBUTE_0 },
{ 4, mFont_CONT_ATTRIBUTE_0 },
{ 4, mFont_CONT_ATTRIBUTE_0 },
{ 4, mFont_CONT_ATTRIBUTE_0 },
{ 6, mFont_CONT_ATTRIBUTE_0 },
{ 8, mFont_CONT_ATTRIBUTE_0 },
{ 10, mFont_CONT_ATTRIBUTE_0 },
{ 6, mFont_CONT_ATTRIBUTE_0 },
{ 8, mFont_CONT_ATTRIBUTE_0 },
{ 10, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 6, mFont_CONT_ATTRIBUTE_CHARACTER },
{ 3, mFont_CONT_ATTRIBUTE_0 },
{ 3, mFont_CONT_ATTRIBUTE_SENTENCE },
{ 3, mFont_CONT_ATTRIBUTE_SENTENCE },
{ 3, mFont_CONT_ATTRIBUTE_CHARACTER },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 4, mFont_CONT_ATTRIBUTE_BGM },
{ 4, mFont_CONT_ATTRIBUTE_BGM },
{ 3, mFont_CONT_ATTRIBUTE_0 },
{ 3, mFont_CONT_ATTRIBUTE_SE },
{ 3, mFont_CONT_ATTRIBUTE_SENTENCE },
{ 2, mFont_CONT_ATTRIBUTE_SE },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_3 },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 6, mFont_CONT_ATTRIBUTE_0 },
{ 3, mFont_CONT_ATTRIBUTE_AGB_DUMMY },
{ 3, mFont_CONT_ATTRIBUTE_AGB_DUMMY },
{ 4, mFont_CONT_ATTRIBUTE_AGB_DUMMY },
{ 3, mFont_CONT_ATTRIBUTE_SENTENCE },
{ 2, mFont_CONT_ATTRIBUTE_AGB_DUMMY },
{ 2, mFont_CONT_ATTRIBUTE_AGB_DUMMY },
{ 6, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_AGB_DUMMY },
{ 2, mFont_CONT_ATTRIBUTE_AGB_DUMMY },
{ 3, mFont_CONT_ATTRIBUTE_AGB_DUMMY },
{ 3, mFont_CONT_ATTRIBUTE_AGB_DUMMY },
{ 3, mFont_CONT_ATTRIBUTE_AGB_DUMMY },
{ 3, mFont_CONT_ATTRIBUTE_AGB_DUMMY },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_0 },
{ 2, mFont_CONT_ATTRIBUTE_STRING },
{ 4, mFont_CONT_ATTRIBUTE_0 },
{ 4, mFont_CONT_ATTRIBUTE_0 },
{ 12, mFont_CONT_ATTRIBUTE_0 },
{ 14, mFont_CONT_ATTRIBUTE_0 }
};
extern int mFont_CodeSize_get(u8* str) {
int size = 1;
int c0 = *str;
int c1;
if (c0 == CHAR_CONTROL_CODE) {
c1 = *(str + 1);
if (c1 >= 0 && c1 < mFont_CONT_CODE_NUM) {
size = mFont_cont_info_tbl[c1].size;
}
else {
size = 2;
}
}
else if (c0 == CHAR_MESSAGE_TAG) {
size = 2;
}
return size;
}
extern int mFont_CodeSize_idx_get(u8* str, int idx) {
return mFont_CodeSize_get(str + idx);
}
extern int mFont_cont_attr_get(int cont_code) {
return mFont_cont_info_tbl[cont_code].attribute;
}
extern void mFont_gppSetMode(Gfx** gfx_pp) {
static Gfx disp[] = {
gsDPPipeSync(),
gsSPTexture(0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON),
gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
gsDPSetTextureLOD(G_TL_TILE),
gsDPSetTextureConvert(G_TC_FILT),
gsDPSetTextureLUT(G_TT_NONE),
gsDPSetTextureFilter(G_TF_BILERP),
gsDPSetCycleType(G_CYC_1CYCLE),
gsDPSetTexturePersp(G_TP_PERSP),
gsDPSetCombineMode(mFont_CC_FONT, mFont_CC_FONT),
gsDPSetRenderMode(G_RM_XLU_SURF, G_RM_XLU_SURF2),
gsDPSetPrimColor(0, 0, 255, 255, 255, 255),
gsSPEndDisplayList()
};
gSPDisplayList((*gfx_pp)++, disp);
}
extern void mFont_SetMode(GRAPH* graph, int mode) {
Gfx* g;
OPEN_DISP(graph);
if (mode == 0) {
g = NOW_POLY_OPA_DISP;
mFont_gppSetMode(&g);
SET_POLY_OPA_DISP(g);
}
else {
g = NOW_FONT_DISP;
mFont_gppSetMode(&g);
SET_FONT_DISP(g);
}
CLOSE_DISP(graph);
}
static Gfx* mFont_gfxSetPrimColor(Gfx* gfx, int r, int g, int b, int a) {
gDPSetPrimColor(gfx++, 0, 0, r, g, b, a);
return gfx;
}
static Gfx* mFont_gppSetPrimColor(Gfx** gpp, rgba_t* color) {
Gfx* g = *gpp;
gDPSetPrimColor(
g++,
0, 0,
color->r,
color->g,
color->b,
color->a
);
*gpp = g;
}
extern void mFont_SetPrimColor(GRAPH* graph, int r, int g, int b, int a, int mode) {
Gfx* gfx;
OPEN_DISP(graph);
if (mode == 0) {
gfx = NOW_POLY_OPA_DISP;
gfx = mFont_gfxSetPrimColor(gfx, r, g, b, a);
SET_POLY_OPA_DISP(gfx);
}
else {
gfx = NOW_FONT_DISP;
gfx = mFont_gfxSetPrimColor(gfx, r, g, b, a);
SET_FONT_DISP(gfx);
}
CLOSE_DISP(graph);
}
static Gfx* mFont_gfxSetCombineMode(Gfx* gfx, int no_font, int sync) {
if (sync) {
gDPPipeSync(gfx++);
}
if (no_font) {
gDPSetCombineMode(gfx++, mFont_CC_FONT, mFont_CC_NOFONT);
}
else {
gDPSetCombineMode(gfx++, mFont_CC_FONT, mFont_CC_FONT);
}
return gfx;
}
static void mFont_gppSetCombineMode(Gfx** gpp, int no_font, int sync) {
Gfx* g = *gpp;
if (sync) {
gDPPipeSync(g++);
}
if (no_font) {
gDPSetCombineMode(g++, mFont_CC_FONT, mFont_CC_NOFONT);
}
else {
gDPSetCombineMode(g++, mFont_CC_FONT, mFont_CC_FONT);
}
*gpp = g;
}
extern void mFont_SetCombineMode(GRAPH* graph, int revert_flag, int mode) {
Gfx* g;
OPEN_DISP(graph);
if (mode == 0) {
g = NOW_POLY_OPA_DISP;
g = mFont_gfxSetCombineMode(g, revert_flag, TRUE);
SET_POLY_OPA_DISP(g);
}
else {
g = NOW_FONT_DISP;
g = mFont_gfxSetCombineMode(g, revert_flag, TRUE);
SET_FONT_DISP(g);
}
CLOSE_DISP(graph);
}
static void mFont_gppLoadTexture(Gfx** gpp, int c, int* uls, int* ult, int* lrs, int* lrt) {
Gfx* g = *gpp;
u8* font_tex = mFont_Get_FontTex_p();
int t = c >> 4;
int n_ult = t << 4;
int n_uls = (c - n_ult) * mFont_TEX_CHAR_WIDTH;
int n_lrs = n_uls + (mFont_TEX_CHAR_WIDTH - 1);
int n_lrt = n_ult + (mFont_TEX_CHAR_HEIGHT - 1);
gDPLoadTextureTile_4b_Dolphin(
g++,
font_tex,
G_IM_FMT_I,
mFont_TEX_CHAR_WIDTH * 16, mFont_TEX_CHAR_HEIGHT * 16
);
*gpp = g;
*uls = n_uls;
*ult = n_ult;
*lrs = n_lrs;
*lrt = n_lrt;
}
static void mFont_SetVertex_dol(Vtx* vtx, int x, int y, int s, int t) {
vtx->v.ob[0] = x;
vtx->v.ob[1] = y;
vtx->v.ob[2] = 0;
vtx->v.flag = 1;
vtx->v.tc[0] = s;
vtx->v.tc[1] = t;
vtx->v.cn[0] = 0;
vtx->v.cn[1] = 0;
vtx->v.cn[2] = 0;
vtx->v.cn[3] = 0;
}
// TEMP
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240
#define HALF_SCR_WIDTH ((f32)(SCREEN_WIDTH / 2))
#define HALF_SCR_HEIGHT ((f32)(SCREEN_HEIGHT / 2))
#define NHALF_SCR_WIDTH ((f32)(-SCREEN_WIDTH / 2))
#define NHALF_SCR_HEIGHT ((f32)(-SCREEN_HEIGHT / 2))
extern f32 mFont_SetVertexRectangle(
GAME* game,
f32 x, f32 y,
int s, int t,
f32 scale_x, f32 scale_y,
int mode
) {
f32 sS = ((f32)s) * scale_x;
f32 sT = ((f32)t) * scale_y;
f32 n = x + sS;
f32 pos_x = x - HALF_SCR_WIDTH;
f32 pos_y = -y + HALF_SCR_HEIGHT;
f32 start_x = pos_x;
f32 start_y = pos_y;
f32 end_x = start_x + sS;
f32 end_y = start_y - sT;
f32 l_ofs = 0.0f;
f32 r_ofs = 0.0f;
f32 t_ofs = 0.0f;
f32 b_ofs = 0.0f;
if (start_x > HALF_SCR_WIDTH ||
start_y < NHALF_SCR_HEIGHT ||
end_x < NHALF_SCR_WIDTH ||
end_y > HALF_SCR_HEIGHT)
{
return n;
}
{
f32 dist_l = start_x - NHALF_SCR_WIDTH;
f32 dist_t = start_y - HALF_SCR_HEIGHT;
f32 dist_r = end_x - HALF_SCR_WIDTH;
f32 dist_b = end_y - NHALF_SCR_HEIGHT;
if (dist_l < 0.0f) {
start_x = NHALF_SCR_WIDTH;
l_ofs -= dist_l;
}
if (dist_t > 0.0f) {
start_y = HALF_SCR_HEIGHT;
t_ofs += dist_t;
}
if (dist_r > 0.0f) {
end_x = HALF_SCR_WIDTH;
r_ofs += dist_r;
}
if (dist_b < 0.0f) {
end_y = NHALF_SCR_HEIGHT;
b_ofs -= dist_b;
}
}
{
f32 inv_scale_x = 1.0f / scale_x;
f32 inv_scale_y = 1.0f / scale_y;
int vert_left_s = (int)(l_ofs * inv_scale_x) << 6;
int vert_top_t = (int)(t_ofs * inv_scale_y) << 6;
int vert_right_s = (int)(((f32)s) - r_ofs * inv_scale_x) << 6;
int vert_bot_t = (int)(((f32)t) - b_ofs * inv_scale_y) << 6;
int vert_left_x = (int)(start_x * mFont_SCALE_F);
int vert_top_y = (int)(start_y * mFont_SCALE_F);
int vert_right_x = (int)(end_x * mFont_SCALE_F);
int vert_bot_y = (int)(end_y * mFont_SCALE_F);
Vtx* vtx = GRAPH_ALLOC_TYPE(game->graph, Vtx, 4);
Gfx* gfx = GRAPH_ALLOC_TYPE(game->graph, Gfx, 3);
if (vtx != NULL && gfx != NULL) {
mFont_SetVertex_dol(vtx++, vert_left_x, vert_top_y, vert_left_s, vert_top_t);
mFont_SetVertex_dol(vtx++, vert_right_x, vert_top_y, vert_right_s, vert_top_t);
mFont_SetVertex_dol(vtx++, vert_right_x, vert_bot_y, vert_right_s, vert_bot_t);
mFont_SetVertex_dol(vtx, vert_left_x, vert_bot_y, vert_left_s, vert_bot_t);
OPEN_DISP(game->graph);
if (mode == 1) {
gSPDisplayList(NOW_FONT_DISP++, gfx);
}
else {
gSPDisplayList(NOW_POLY_OPA_DISP++, gfx);
}
CLOSE_DISP(game->graph);
gSPVertex(gfx++, vtx - 3, 4, 0);
gSPNTrianglesInit_5b(
gfx++,
2, // 2 triangles
0, 2, 1, // 0 -> 2 -> 1
0, 3, 2, // 0 -> 3 -> 2
0, 0, 0 // unused
);
gSPEndDisplayList(gfx);
}
}
return n;
}
static f32 mFont_SetLineStrings_AndSpace_new(
GAME* game,
u8* str,
int len,
f32 x, f32 y,
int r, int g, int b, int a,
int flag_revert, int flag_cut,
int unused,
f32 scale_x, f32 scale_y,
int mode
) {
Gfx* g;
mFontSentence sentence;
int use_polygon_opaque = mode == 0;
u32 flag;
xy_t pos;
xy_t scale;
rgba_t color;
if (fabsf(scale_x) < 0.001f || fabsf(scale_y) < 0.001f) {
return 0.0f;
}
if (len <= 0) {
return 0.0f;
}
OPEN_DISP(game->graph);
if (use_polygon_opaque) {
g = NOW_POLY_OPA_DISP;
}
else {
g = NOW_FONT_DISP;
}
flag = mFont_SENTENCE_FLAG_USE_POLY;
if (flag_revert) {
flag |= mFont_SENTENCE_FLAG_REVERT;
}
if (flag_cut) {
flag |= mFont_SENTENCE_FLAG_CUT;
}
pos.x = x;
pos.y = y;
scale.x = scale_x;
scale.y = scale_y;
color.r = r;
color.g = g;
color.b = b;
color.a = a;
mFontSentence_set(&sentence, str, len, flag, &pos, mFont_LineType_Top, &scale, &color, 0, 0, 0, 0, 0);
mFontSentence_gppDraw(&sentence, game, &g);
if (use_polygon_opaque) {
SET_POLY_OPA_DISP(g);
}
else {
SET_FONT_DISP(g);
}
CLOSE_DISP(game->graph);
return sentence.width;
}
extern f32 mFont_SetLineStrings_AndSpace(
GAME* game,
u8* str,
int len,
f32 x, f32 y,
int r, int g, int b, int a,
int flag_revert, int flag_cut,
int unused,
f32 scale_x, f32 scale_y,
int mode
) {
return mFont_SetLineStrings_AndSpace_new(
game,
str,
len,
x, y,
r, g, b, a,
flag_revert, flag_cut,
unused,
scale_x, scale_y,
mode
);
}
extern f32 mFont_SetLineStrings(
GAME* game,
u8* str,
int len,
f32 x, f32 y,
int r, int g, int b, int a,
int flag_revert, int flag_cut,
f32 scale_x, f32 scale_y,
int mode
) {
return mFont_SetLineStrings_AndSpace(
game,
str,
len,
x, y,
r, g, b, a,
flag_revert, flag_cut,
0,
scale_x, scale_y,
mode
);
}
extern void mFont_CulcOrthoMatrix(Mtx* m) {
guOrtho(
m,
NHALF_SCR_WIDTH * mFont_SCALE_F, HALF_SCR_WIDTH * mFont_SCALE_F,
NHALF_SCR_HEIGHT * mFont_SCALE_F, HALF_SCR_HEIGHT * mFont_SCALE_F,
-800.0f, 800.0f,
1.0f
);
}
extern void mFont_SetMatrix(GRAPH* graph, int mode) {
static Mtx mtx_projection;
static int first = TRUE;
if (first) {
mFont_CulcOrthoMatrix(&mtx_projection);
first = FALSE;
}
Matrix_push();
Matrix_put(&MtxF_clear);
OPEN_DISP(graph);
if (mode == 1) {
gSPMatrix(NOW_FONT_DISP++, &mtx_projection, G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
gSPMatrix(NOW_FONT_DISP++, &Mtx_clear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
}
else {
gSPMatrix(NOW_POLY_OPA_DISP++, &mtx_projection, G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
gSPMatrix(NOW_POLY_OPA_DISP++, &Mtx_clear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);
}
CLOSE_DISP(graph);
}
extern void mFont_UnSetMatrix(GRAPH* graph, int mode) {
Matrix_pull();
}
extern void mFont_Main_start(GRAPH* graph) {
mFont_SetMode(graph, 1);
}
/* @unused f32 mFont_Get_NextCharRectX(???) */
/* @unused f32 mFont_Get_NextCharRectY(???) */
static void mFont_gppDrawCharRect(
GRAPH* graph,
Gfx** gfx_pp,
int c,
u32 ulx, u32 uly,
u32 lrx, u32 lry,
int dsdx, int dtdy
) {
Gfx* g = *gfx_pp;
int uls;
int ult;
int lrs;
int lrt;
mFont_gppLoadTexture(&g, c, &uls, &ult, &lrs, &lrt);
// Convert to signed 10.5 format
uls <<= 5;
ult <<= 5;
g = gfx_gSPTextureRectangle1(g, ulx, uly, lrx, lry, G_TX_RENDERTILE, (int)uls, (int)ult, dsdx, dtdy);
*gfx_pp = g;
}
// TODO: Non-matching
static void mFont_gppDrawCharPoly(
GRAPH* graph,
Gfx** gfx_pp,
int c,
xy_t* pos_tl, xy_t* pos_br,
int s, int t
) {
Gfx* g = *gfx_pp;
Vtx* vtx = GRAPH_ALLOC_TYPE(graph, Vtx, 4);
int uls, ult, lrs, lrt;
int ulx, uly, lrx, lry;
xy_t vert_tl, vert_br;
f32 inv_half_s, inv_half_t;
mFont_gppLoadTexture(&g, c, &uls, &ult, &lrs, &lrt);
vert_tl.x = pos_tl->x - ((f32)SCREEN_WIDTH * 0.5f);
vert_tl.y = -(pos_tl->y - ((f32)SCREEN_HEIGHT * 0.5f));
vert_br.x = pos_br->x - ((f32)SCREEN_WIDTH * 0.5f) - vert_tl.x;
vert_br.y = -(pos_br->y - ((f32)SCREEN_HEIGHT * 0.5f)) - vert_tl.y;
inv_half_s = 0.5f / (f32)s;
inv_half_t = 0.5f / (f32)t;
ulx = (vert_tl.x + vert_br.x * inv_half_s) * mFont_SCALE_F;
uly = (vert_tl.y + vert_br.y * inv_half_t) * mFont_SCALE_F;
lrx = (vert_tl.x + vert_br.x * (1.0f - inv_half_s)) * mFont_SCALE_F;
lry = (vert_tl.y + vert_br.y * (1.0f - inv_half_t)) * mFont_SCALE_F;
lrs = ((uls + s) << 6) - 32;
lrt = ((ult + t) << 6) - 32;
uls = (uls << 6) + 32;
ult = (ult << 6) + 32;
mFont_SetVertex_dol(vtx + 0, ulx, uly, uls, ult);
mFont_SetVertex_dol(vtx + 1, ulx, lry, uls, lrt);
mFont_SetVertex_dol(vtx + 2, lrx, lry, lrs, lrt);
mFont_SetVertex_dol(vtx + 3, lrx, uly, lrs, ult);
gSPVertex(g++, vtx, 4, 0);
gSPNTrianglesInit_5b(
g++,
2, // 2 tris
0, 1, 2, // tri 1
0, 2, 3, // tri 2
0, 0, 0 // unused
);
*gfx_pp = g;
}
static void mFontChar_gppDraw_sentence_restore(mFontChar* this, mFontSentence* sentence, Gfx** gfx_pp) {
if (this->color_ctr > 0) {
this->color_ctr--;
if (this->color_ctr == 0) {
rgba_t_move(&this->color, &sentence->color);
mFont_gppSetPrimColor(gfx_pp, &this->color);
}
}
if ((this->flags & mFont_CHAR_FLAG_SCALE)) {
this->scale.x = 1.0f;
this->scale.y = 1.0f;
this->inv_scale.x = 1.0f;
this->inv_scale.y = 1.0f;
this->flags &= ~mFont_CHAR_FLAG_SCALE;
this->flags |= mFont_CHAR_FLAG_SCALE_RESET;
}
}
static void mFontChar_total_scale_reset(mFontChar* this, mFontSentence* sentence) {
if ((this->flags & mFont_CHAR_FLAG_SCALE_RESET)) {
this->scaled_size.x = this->scale.x * sentence->scale.x * sentence->line_scale;
this->scaled_size.y = this->scale.y * sentence->scale.y * sentence->line_scale;
this->inv_scaled_size.x = this->inv_scale.x * sentence->inv_scale.x * sentence->inv_line_scale;
this->inv_scaled_size.y = this->inv_scale.y * sentence->inv_scale.y * sentence->inv_line_scale;
this->flags &= ~mFont_CHAR_FLAG_SCALE_RESET;
}
}
static void mFontChar_ContProc_set_color_char(mFontChar* this, Gfx** gfx_pp) {
this->color.r = this->char_p[2];
this->color.g = this->char_p[3];
this->color.b = this->char_p[4];
this->color.a = 255;
this->color_ctr = this->char_p[5];
mFont_gppSetPrimColor(gfx_pp, &this->color);
}
static void mFontChar_ContProc_set_char_scale(mFontChar* this, Gfx** gfx_pp) {
int scale_val = this->char_p[2];
f32 scale = (f32)scale_val * (1.0f / 32.0f);
f32 inv_scale = 1.0f / scale;
this->scale.x = scale;
this->scale.y = scale;
this->inv_scale.x = inv_scale;
this->inv_scale.y = inv_scale;
this->flags |= (mFont_CHAR_FLAG_SCALE | mFont_CHAR_FLAG_SCALE_RESET);
}
static mFont_ControlCodeCharFunc mFontChar_cont_proc_get(int control_code) {
if (control_code == mFont_CONT_CODE_SET_COLOR_CHAR) {
return mFontChar_ContProc_set_color_char;
}
else if (control_code == mFont_CONT_CODE_SET_CHAR_SCALE) {
return mFontChar_ContProc_set_char_scale;
}
else {
return NULL;
}
}
static void mFontChar_set(
mFontChar* this,
u8* char_p, int len,
u8 flags,
xy_t* pos,
xy_t* scale, xy_t* inv_scale,
f32 ofs_y,
rgba_t* color
) {
bzero(this, sizeof(mFontChar));
this->char_p = char_p;
this->len = len;
this->flags = flags;
this->position = *pos;
this->scale = *scale;
this->inv_scale = *inv_scale;
this->ofs_y = ofs_y;
rgba_t_move(&this->color, color);
}
static void mFontChar_gppDrawRect(mFontChar* this, GRAPH* graph, Gfx** gfx_pp) {
u32 ulx, uly, lrx, lry;
int dsdx, dtdy;
f32 t;
f32 width;
t = -this->ofs_y;
uly = (int)((t * this->scaled_size.y - t + this->position.y) * 4.0f);
t = mFont_TEX_CHAR_HEIGHT_F32 - this->ofs_y;
lry = (int)((t * this->scaled_size.y - t + this->position.y + mFont_TEX_CHAR_HEIGHT_F32) * 4.0f);
ulx = (int)(this->position.x * 4.0f);
width = (f32)mFont_GetCodeWidth(*this->char_p, this->flags & mFont_CHAR_FLAG_CUT) * this->scaled_size.x;
lrx = (int)((width + this->position.x) * 4.0f);
dsdx = (1024.0f * this->inv_scaled_size.x); /* 1 << 10 for correct s5.10 format? */
dtdy = (1024.0f * this->inv_scaled_size.y); /* 1 << 10 for correct s5.10 format? */
this->width = width;
mFont_gppDrawCharRect(graph, gfx_pp, *this->char_p, ulx, uly, lrx, lry, dsdx, dtdy);
}
// TODO: match
static void mFontChar_gppDrawPoly(mFontChar* this, GRAPH* graph, Gfx** gfx_pp) {
xy_t top_left;
xy_t bottom_right;
f32 t;
f32 width;
int s;
int c = *this->char_p;
t = -this->ofs_y;
top_left.y = (t * this->scaled_size.y) - t + this->position.y;
t = mFont_TEX_CHAR_HEIGHT_F32 - this->ofs_y;
bottom_right.y = (t * this->scaled_size.y) - t + this->position.y + mFont_TEX_CHAR_HEIGHT_F32;
top_left.x = this->position.x;
s = mFont_GetCodeWidth(c, this->flags & mFont_CHAR_FLAG_CUT);
width = s * this->scaled_size.x;
bottom_right.x = width + this->position.x;
this->width = width;
mFont_gppDrawCharPoly(graph, gfx_pp, c, &top_left, &bottom_right, s, mFont_TEX_CHAR_HEIGHT);
}
static void mFontChar_gppDraw(mFontChar* this, GRAPH* graph, Gfx** gfx_pp) {
if (this->flags & mFont_CHAR_FLAG_USE_POLY) {
mFontChar_gppDrawPoly(this, graph, gfx_pp);
}
else {
mFontChar_gppDrawRect(this, graph, gfx_pp);
}
}
static f32 mFontSentence_line_offset_calc(int line_type) {
static f32 offset_value[mFont_LineType_End] = {
mFont_TEX_CHAR_HEIGHT_F32 * 0.0f,
mFont_TEX_CHAR_HEIGHT_F32 * 0.5f,
mFont_TEX_CHAR_HEIGHT_F32 * 1.0f
};
return offset_value[line_type];
}
static void mFontSentence_ContProc_set_line_offset(mFontSentence* this, Gfx** gfx_pp) {
mFontChar* character = &this->character;
int t = (u8)(*(this->sentence_p + this->now_idx + 2)) - 128;
this->offset = t;
character->position.y = this->position.y + this->offset;
}
static void mFontSentence_ContProc_set_line_type(mFontSentence* this, Gfx** gfx_pp) {
mFontChar* character = &this->character;
int type = *(this->sentence_p + this->now_idx + 2);
this->line_type = type;
character->ofs_y = mFontSentence_line_offset_calc(this->line_type);
}
static void mFontSentence_ContProc_set_line_scale(mFontSentence* this, Gfx** gfx_pp) {
mFontChar* character = &this->character;
int scale = *(this->sentence_p + this->now_idx + 2);
f32 f_scale = (f32)scale * (1.0f / 32.0f);
f32 f_inv_scale = 1.0f / f_scale;
this->line_scale = f_scale;
this->inv_line_scale = f_inv_scale;
character->flags |= mFont_CHAR_FLAG_SCALE_RESET;
}
static void mFontSentence_ContProc_space(mFontSentence* this, Gfx** gfx_pp) {
mFontChar* character = &this->character;
int c = *(this->sentence_p + this->now_idx + 2);
this->width += c * character->scaled_size.x;
}
static mFont_ControlCodeSentenceFunc mFontSentence_cont_proc_get(int control_code) {
if (control_code == mFont_CONT_CODE_SET_LINE_OFFSET) {
return mFontSentence_ContProc_set_line_offset;
}
else if (control_code == mFont_CONT_CODE_SET_LINE_TYPE) {
return mFontSentence_ContProc_set_line_type;
}
else if (control_code == mFont_CONT_CODE_SET_LINE_SCALE) {
return mFontSentence_ContProc_set_line_scale;
}
else if (control_code == mFont_CONT_CODE_SPACE) {
return mFontSentence_ContProc_space;
}
else {
return NULL;
}
}
static void mFontSentence_animal_voice_se(mFontSentence* this) {
mFontChar* character = &this->character;
f32 f_scale;
int scale;
f_scale = character->scale.x * character->scale.x + character->scale.y * character->scale.y;
f_scale = sqrtf(f_scale);
scale = this->line_scale * f_scale * (32.0f / SQRT_OF_2_F) + 0.5f;
scale = scale < 0 ? 0 : (scale > 255 ? 255 : scale);
// TODO: these definitely deserve to be promoted to defines or enums in the future.
// Unsure which sfx & case this is referring to.
if (this->voice_idx == 0x80 && this->se_character_id != 0 && scale == 32 &&
character->color.r == 50 && character->color.g == 60 && character->color.b == 50 && character->color.a == 255) {
this->se_character_id = 0;
}
sAdo_VoiceSe(this->voice_idx, this->voice2_idx, this->voice3_idx, this->se_character_id, (u8)scale, 0);
}
extern void mFontSentence_set(
mFontSentence* this,
u8* sentence_p, int len,
u32 flags,
xy_t* pos,
int line_type,
xy_t* scale,
rgba_t* color,
int se_voice_pos,
u8 voice_idx, u8 voice2_idx, u8 voice3_idx,
s16 voice_se_character_idx
) {
static xy_t unit_vec_xy = { 1.0f, 1.0f };
u8 character_flags = 0;
bzero(this, sizeof(mFontSentence));
this->sentence_p = sentence_p;
this->len = len;
this->flags = flags;
this->position = *pos;
this->line_type = line_type;
this->scale = *scale;
this->inv_scale.x = 1.0f / scale->x;
this->inv_scale.y = 1.0f / scale->y;
this->line_scale = 1.0f;
this->inv_line_scale = 1.0f;
rgba_t_move(&this->color, color);
this->se_pos = se_voice_pos;
this->voice_idx = voice_idx;
this->voice2_idx = voice2_idx;
this->voice3_idx = voice3_idx;
this->se_character_id = voice_se_character_idx;
if (this->flags & mFont_SENTENCE_FLAG_CUT) {
character_flags |= mFont_CHAR_FLAG_CUT;
}
if (this->flags & mFont_SENTENCE_FLAG_USE_POLY) {
character_flags |= mFont_CHAR_FLAG_USE_POLY;
}
character_flags |= mFont_CHAR_FLAG_SCALE_RESET;
mFontChar_set(
&this->character,
this->sentence_p,
1,
character_flags,
&this->position,
&unit_vec_xy,
&unit_vec_xy,
mFontSentence_line_offset_calc(this->line_type),
&this->color
);
}
static void mFontSentence_gppDraw_before(mFontSentence* this, Gfx** gfx_pp) {
if (!(this->flags & mFont_SENTENCE_FLAG_3)) {
if (this->flags & mFont_SENTENCE_FLAG_USE_POLY) {
mFont_gppSetMode(gfx_pp);
}
else {
mFont_gppSetRectMode(gfx_pp);
}
}
if (!(this->flags & mFont_SENTENCE_FLAG_NO_COMBINE)) {
mFont_gppSetCombineMode(gfx_pp, this->flags & mFont_SENTENCE_FLAG_REVERT, FALSE);
}
if (!(this->flags & mFont_SENTENCE_FLAG_NO_COLOR)) {
mFont_gppSetPrimColor(gfx_pp, &this->color);
}
}
static void mFontSentence_gppDraw_main(mFontSentence* this, GAME* game, Gfx** gfx_pp) {
GRAPH* graph = game->graph;
u8* char_p = this->sentence_p + this->now_idx;
int c = *char_p;
int char_size = mFont_CodeSize_get(char_p);
this->character.char_p = char_p;
this->character.len = char_size;
if (c == CHAR_CONTROL_CODE) {
int next = *(char_p + 1);
int type = mFont_cont_attr_get(next);
if (type == mFont_CONT_ATTRIBUTE_SENTENCE) {
(mFontSentence_cont_proc_get(next))(this, gfx_pp);
}
else if (type == mFont_CONT_ATTRIBUTE_CHARACTER) {
(mFontChar_cont_proc_get(next))(&this->character, gfx_pp);
}
}
else {
if (!((this->flags & mFont_SENTENCE_SKIP_DRAW_NEW_LINE) && c == CHAR_NEW_LINE)) {
this->character.position.x = this->position.x + this->width;
mFontChar_total_scale_reset(&this->character, this);
mFontChar_gppDraw(&this->character, graph, gfx_pp);
if ((this->flags & mFont_SENTENCE_FLAG_VOICE_SE) && this->now_idx == this->se_pos) {
mFontSentence_animal_voice_se(this);
}
this->width += this->character.width;
mFontChar_gppDraw_sentence_restore(&this->character, this, gfx_pp);
}
}
this->now_idx += char_size;
}
static void mFontSentence_gppDraw_after(mFontSentence* this, Gfx** gfx_pp) {
}
extern void mFontSentence_gppDraw(mFontSentence* this, GAME* game, Gfx** gfx_pp) {
mFontSentence_gppDraw_before(this, gfx_pp);
while (this->now_idx < this->len) {
mFontSentence_gppDraw_main(this, game, gfx_pp);
}
mFontSentence_gppDraw_after(this, gfx_pp);
}
static u8* mFont_Get_MarkTex_p(int mark_type) {
static u8* tex_p_array[mFont_MARKTYPE_TOTAL] = {
FONT_nes_tex_jyouge,
FONT_nes_tex_sayuu,
FONT_nes_tex_cursor,
FONT_nes_tex_next,
FONT_nes_tex_choice
};
if (0 <= mark_type && mark_type < mFont_MARKTYPE_TOTAL && tex_p_array[mark_type] != NULL) {
return tex_p_array[mark_type];
}
return NULL;
}
static int mFont_Get_MarkTex_sizeW(int mark_type) {
static int size_array[mFont_MARKTYPE_TOTAL] = { 16, 16, 16, 16, 16 };
if (0 <= mark_type && mark_type < mFont_MARKTYPE_TOTAL && size_array[mark_type] != 0) {
return size_array[mark_type];
}
return 0;
}
static int mFont_Get_MarkTex_sizeH(int mark_type) {
static int size_array[mFont_MARKTYPE_TOTAL] = { 16, 16, 16, 16, 16 };
if (0 <= mark_type && mark_type < mFont_MARKTYPE_TOTAL && size_array[mark_type] != 0) {
return size_array[mark_type];
}
return 0;
}
// TODO: match
extern f32 mFont_SetMarkChar(
GAME* game,
u8 mark_type,
f32 x, f32 y,
int r, int g, int b, int a,
int revert_flag,
f32 scale_x, f32 scale_y,
int mode
) {
f32 next_x = x;
if ((int)mark_type < mFont_MARKTYPE_TOTAL) {
u8* tex = mFont_Get_MarkTex_p(mark_type);
int w = mFont_Get_MarkTex_sizeW(mark_type);
int h = mFont_Get_MarkTex_sizeH(mark_type);
GRAPH* graph = game->graph;
Gfx* gfx = GRAPH_ALLOC_TYPE(graph, Gfx, 9);
if (tex != NULL && w != 0 && h != 0 && gfx != NULL) {
mFont_SetMode(graph, mode);
mFont_SetPrimColor(graph, r, g, b, a, mode);
mFont_SetCombineMode(graph, revert_flag, mode);
OPEN_DISP(graph);
if (mode == 1) {
gSPDisplayList(NOW_FONT_DISP++, gfx);
}
else {
gSPDisplayList(NOW_POLY_OPA_DISP++, gfx);
}
CLOSE_DISP(graph);
/* TODO: they seem to have a secondary macro that does the operations directly */
gDPLoadTextureTile_4b_Dolphin(
gfx++,
tex,
G_IM_FMT_I,
w, h + mFont_TEX_CHAR_HEIGHT
);
gSPEndDisplayList(gfx);
next_x = mFont_SetVertexRectangle(game, x, y, w, h, scale_x, scale_y, mode);
}
}
return next_x;
}
extern void mFont_gppSetRectMode(Gfx** gfx_pp) {
static Gfx disp[] = {
gsDPPipeSync(),
gsSPTexture(0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON),
gsSPClearGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR | G_LOD | G_SHADING_SMOOTH),
gsDPSetTextureLOD(G_TL_TILE),
gsDPSetTextureConvert(G_TC_FILT),
gsDPSetTextureLUT(G_TT_NONE),
gsDPSetTextureFilter(G_TF_BILERP),
gsDPSetCycleType(G_CYC_1CYCLE),
gsDPSetTexturePersp(G_TP_NONE),
gsDPSetCombineMode(mFont_CC_FONT, mFont_CC_FONT),
gsDPSetRenderMode(G_RM_AA_DEC_LINE, G_RM_AA_DEC_LINE2),
gsDPSetPrimColor(0, 0, 255, 255, 255, 255),
gsSPEndDisplayList(),
};
gSPDisplayList((*gfx_pp)++, disp);
}