diff --git a/include/MSL_C/w_math.h b/include/MSL_C/w_math.h index 5f8cb11e..521d39b1 100644 --- a/include/MSL_C/w_math.h +++ b/include/MSL_C/w_math.h @@ -19,6 +19,15 @@ inline float sqrtf(float x) return x; } +extern inline double fabs(double x) +{ + return __fabs(x) ; +} + +inline float fabsf(float x) { + return (float)fabs((double)x); +} + f64 atan2(f64, f64); f64 acos(f32); diff --git a/include/audio.h b/include/audio.h index 7b9cab7b..a5837c3f 100644 --- a/include/audio.h +++ b/include/audio.h @@ -10,6 +10,9 @@ extern "C" { extern void sAdo_GameFrame(); extern void sAdo_SoftReset(); +/* Not sure about the last param name */ +extern void sAdo_VoiceSe(u8 num, u8 num2, u8 num3, s16 character_idx, u8 scale, u8 mode); + #ifdef __cplusplus } #endif diff --git a/include/dataobject.h b/include/dataobject.h new file mode 100644 index 00000000..bf0f15e2 --- /dev/null +++ b/include/dataobject.h @@ -0,0 +1,23 @@ +#ifndef DATAOBJECT_H +#define DATAOBJECT_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// TODO: This file should be autogenerated. + +extern u8 FONT_nes_tex_font1[]; +extern u8 FONT_nes_tex_jyouge[]; +extern u8 FONT_nes_tex_sayuu[]; +extern u8 FONT_nes_tex_cursor[]; +extern u8 FONT_nes_tex_next[]; +extern u8 FONT_nes_tex_choice[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/dolphin/gx.h b/include/dolphin/gx.h new file mode 100644 index 00000000..6b9feaba --- /dev/null +++ b/include/dolphin/gx.h @@ -0,0 +1,16 @@ +#ifndef DOLPHIN_GX_H +#define DOLPHIN_GX_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/graph.h b/include/graph.h index 3395576a..cc107358 100644 --- a/include/graph.h +++ b/include/graph.h @@ -39,36 +39,37 @@ typedef enum { #define GRAPH_MSG_BUF_COUNT 8 typedef struct graph_s { - /* 0x0000 */ Gfx* Gfx_list00; /* line translucent */ - /* 0x0004 */ Gfx* Gfx_list01; /* overlay */ + /* 0x0000 */ Gfx* Gfx_list00; /* polygon opaque */ + /* 0x0004 */ Gfx* Gfx_list01; /* polygon translucent */ /* 0x0008 */ void* DepthBuffer; /* 0x000C */ Gfx* Gfx_list03; /* unused */ - /* 0x0010 */ Gfx* Gfx_list04; /* line opaque */ - /* 0x0014 */ Gfx* Gfx_list07; /* polygon opaque */ - /* 0x0018 */ Gfx* Gfx_list08; /* polygon translucent */ - /* 0x001C */ Gfx* Gfx_list09; /* font */ + /* 0x0010 */ Gfx* Gfx_list04; /* overlay */ + /* 0x0014 */ Gfx* Gfx_list07; /* font */ + /* 0x0018 */ Gfx* Gfx_list08; /* shadow */ + /* 0x001C */ Gfx* Gfx_list09; /* light */ /* 0x0020 */ Gfx* gfxsave; /* 0x0024 */ u8 _unk24[32]; /* 0x0044 */ OSMessage graphReplyMesgBuf[GRAPH_MSG_BUF_COUNT]; /* 0x0064 */ OSMessageQueue* schedMesgQueue; /* 0x0068 */ OSMessageQueue graphReplyMesgQueue; - /* 0x0088 */ u8 _unused_ossctask00p[0x50]; /* real type = OSScTask */ - /* 0x00D8 */ u8 _unused_ossctask01p[0x50]; /* real type = OSScTask */ - /* 0x0128 */ u8 _unused_ossctask02p[0x50]; /* real type = OSScTask */ - /* 0x0178 */ u8 _unk178[0x48]; /* If graphReplyMesgQueue is N64 type, this may be another OSScTask */ + /* 0x0088 */ u8 _unused_ossctask00p[0x68]; /* real type = OSScTask */ + /* 0x00F0 */ u8 _unused_ossctask01p[0x68]; /* real type = OSScTask */ + /* 0x0158 */ u8 _unused_ossctask02p[0x68]; /* real type = OSScTask */ /* 0x01C0 */ Gfx* Gfx_list05; /* work */ /* 0x01C4 */ THA_GA work_thaga; - /* 0x01D4 */ u8 _unk1D4[0xDC]; /* Maybe related to more OSScTask stuff? */ - /* 0x02B0 */ void* scheduler; /* Actually points to OSSched struct, only used in DnM? */ - /* 0x02B4 */ void* vimode; /* Actually points to OSViMode struct, not used in AC. */ - /* 0x02B8 */ THA_GA line_opaque_thaga; - /* 0x02C8 */ THA_GA line_translucent_thaga; - /* 0x02D8 */ THA_GA overlay_thaga; - /* 0x02E8 */ THA_GA polygon_opaque_thaga; - /* 0x02F8 */ THA_GA polygon_translucent_thaga; - /* 0x0308 */ THA_GA font_thaga; - /* 0x0318 */ THA_GA shadow_thaga; - /* 0x0328 */ THA_GA light_thaga; + /* 0x01D4 */ u8 _unk1D4[0xBC]; /* Maybe related to more OSScTask stuff? */ + /* 0x0290 */ void* scheduler; /* Actually points to OSSched struct, only used in DnM? */ + /* 0x0294 */ void* vimode; /* Actually points to OSViMode struct, not used in AC. */ + /* 0x0298 */ THA_GA line_opaque_thaga; + /* 0x02A8 */ THA_GA line_translucent_thaga; + /* 0x02B8 */ THA_GA overlay_thaga; + /* 0x02C8 */ THA_GA polygon_opaque_thaga; + /* 0x02D8 */ THA_GA polygon_translucent_thaga; + /* 0x02E8 */ THA_GA font_thaga; + /* 0x02F8 */ THA_GA shadow_thaga; + /* 0x0308 */ THA_GA light_thaga; + /* 0x0318 */ THA_GA new0_thaga; + /* 0x0328 */ THA_GA new1_thaga; /* 0x0338 */ int frame_counter; /* 0x033C */ u16* frameBuffer; /* 0x0340 */ u16* renderBuffer; @@ -82,8 +83,8 @@ typedef struct graph_s { /* 0x0354 */ f32 vixscale; /* 0x0358 */ f32 viyscale; /* 0x035C */ Gfx* last_dl; - /* 0x0360 */ Gfx* Gfx_list10; /* shadow */ - /* 0x0364 */ Gfx* Gfx_list11; /* light */ + /* 0x0360 */ Gfx* Gfx_list10; /* new0 (highlight/reflections?) */ + /* 0x0364 */ Gfx* Gfx_list11; /* new1 (highlight/reflections?) */ } GRAPH ATTRIBUTE_ALIGN(8); // one of the missing structs is likely aligned to 8 bytes. extern void graph_proc(void* arg); @@ -107,9 +108,8 @@ extern void graph_dt(GRAPH* this); #define NEXT_DISP(thaga) ((thaga)->thaGfx.head_p++) #define NOW_DISP(thaga) ((thaga)->thaGfx.head_p) +#define SET_DISP(thaga, p) ((thaga)->tha.head_p = (char*)(p)) -#define NEXT_LINE_XLU_DISP NEXT_DISP(&__graph->line_translucent_thaga) -#define NEXT_LINE_OPA_DISP NEXT_DISP(&__graph->line_opaque_thaga) #define NEXT_POLY_OPA_DISP NEXT_DISP(&__graph->polygon_opaque_thaga) #define NEXT_POLY_XLU_DISP NEXT_DISP(&__graph->polygon_translucent_thaga) #define NEXT_OVERLAY_DISP NEXT_DISP(&__graph->overlay_thaga) @@ -117,9 +117,9 @@ extern void graph_dt(GRAPH* this); #define NEXT_FONT_DISP NEXT_DISP(&__graph->font_thaga) #define NEXT_SHADOW_DISP NEXT_DISP(&__graph->shadow_thaga) #define NEXT_LIGHT_DISP NEXT_DISP(&__graph->light_thaga) +#define NEXT_NEW0_DISP NEXT_DISP(&__graph->new0_thaga) +#define NEXT_NEW1_DISP NEXT_DISP(&__graph->new1_thaga) -#define NOW_LINE_XLU_DISP (Gfx*)NOW_DISP(&__graph->line_translucent_thaga) -#define NOW_LINE_OPA_DISP (Gfx*)NOW_DISP(&__graph->line_opaque_thaga) #define NOW_POLY_OPA_DISP (Gfx*)NOW_DISP(&__graph->polygon_opaque_thaga) #define NOW_POLY_XLU_DISP (Gfx*)NOW_DISP(&__graph->polygon_translucent_thaga) #define NOW_OVERLAY_DISP (Gfx*)NOW_DISP(&__graph->overlay_thaga) @@ -127,6 +127,21 @@ extern void graph_dt(GRAPH* this); #define NOW_FONT_DISP (Gfx*)NOW_DISP(&__graph->font_thaga) #define NOW_SHADOW_DISP (Gfx*)NOW_DISP(&__graph->shadow_thaga) #define NOW_LIGHT_DISP (Gfx*)NOW_DISP(&__graph->light_thaga) +#define NOW_NEW0_DISP (Gfx*)NOW_DISP(&__graph->new0_thaga) +#define NOW_NEW1_DISP (Gfx*)NOW_DISP(&__graph->new1_thaga) + +#define SET_POLY_OPA_DISP(p) SET_DISP(&__graph->polygon_opaque_thaga, p) +#define SET_POLY_XLU_DISP(p) SET_DISP(&__graph->polygon_translucent_thaga, p) +#define SET_OVERLAY_DISP(p) SET_DISP(&__graph->overlay_thaga, p) +#define SET_WORK_DISP(p) SET_DISP(&__graph->work_thaga, p) +#define SET_FONT_DISP(p) SET_DISP(&__graph->font_thaga, p) +#define SET_SHADOW_DISP(p) SET_DISP(&__graph->shadow_thaga, p) +#define SET_LIGHT_DISP(p) SET_DISP(&__graph->light_thaga, p) +#define SET_NEW0_DISP(p) SET_DISP(&__graph->new0_thaga, p) +#define SET_NEW1_DISP(p) SET_DISP(&__graph->new1_thaga, p) + +#define GRAPH_ALLOC(graph, size) ((void*)((graph)->polygon_opaque_thaga.tha.tail_p = (char*)((int)(graph)->polygon_opaque_thaga.tha.tail_p - (int)(size)))) +#define GRAPH_ALLOC_TYPE(graph, type, num) (GRAPH_ALLOC(graph, sizeof(type) * (num))) extern u8 SoftResetEnable; extern GRAPH graph_class; diff --git a/include/libc/math.h b/include/libc/math.h index 6f3bce9e..cacd313e 100644 --- a/include/libc/math.h +++ b/include/libc/math.h @@ -2,6 +2,9 @@ #define MATH_H #include "types.h" + +#define SQRT_OF_2_F 1.41421356237309504880f + s16 sins(u16); f32 fatan2(f32, f32); diff --git a/include/libc64/__osMalloc.h b/include/libc64/__osMalloc.h index 5af16449..5b8dd744 100644 --- a/include/libc64/__osMalloc.h +++ b/include/libc64/__osMalloc.h @@ -5,7 +5,7 @@ #include "dolphin/os/OSTime.h" #include "libultra/osThread.h" #include "libultra/osMesg.h" -#include "libultra/u64types.h" +#include "libultra/ultratypes.h" struct ArenaNode; diff --git a/include/libforest/gbi_extensions.h b/include/libforest/gbi_extensions.h new file mode 100644 index 00000000..51fd1723 --- /dev/null +++ b/include/libforest/gbi_extensions.h @@ -0,0 +1,561 @@ +#ifndef __GBI_EXTENSIONS_H__ +#define __GBI_EXTENSIONS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "types.h" +#include +#include "dolphin/gx.h" + +/* New Microcode Command Ids */ +#define G_TRIN 0x09 +#define G_TRIN_INDEPEND 0x0A + +#define G_SETTEXEDGEALPHA 0xCE +#define G_SETCOMBINE_NOTEV 0xCF +#define G_SETCOMBINE_TEV 0xD0 +#define G_SETTILE_DOLPHIN 0xD2 + +#define G_OFF 0 +#define G_ON 1 + +#define G_FIRST_CMD G_SETTEXEDGEALPHA + +/* Triangle/Quad vertex bit size */ +#define POLY_5b 0 /* 5 bits per vertex index (0 - 31) */ +#define POLY_7b 1 /* 7 bits per vertex index (0 - 127) */ +#define POLY_BITMASK 1 + +/* First face, 5 bits */ +#define POLY_GET_V0_5b(g)((g->words.w1 >> 4) & 0x1F) +#define POLY_GET_V1_5b(g)((g->words.w1 >> 9) & 0x1F) +#define POLY_GET_V2_5b(g)((g->words.w1 >> 14) & 0x1F) + +/* Second face, 5 bits */ +#define POLY_GET_V3_5b(g)((g->words.w1 >> 19) & 0x1F) +#define POLY_GET_V4_5b(g)((g->words.w1 >> 24) & 0x1F) +#define POLY_GET_V5_5b(g)((((g->words.w1 >> 29) & 7) | ((g->words.w0 & 3) << 3)) & 0x1F) + +/* Third face, 5 bits */ +#define POLY_GET_V6_5b(g)((g->words.w0 >> 2) & 0x1F) +#define POLY_GET_V7_5b(g)((g->words.w0 >> 7) & 0x1F) +#define POLY_GET_V8_5b(g)((g->words.w0 >> 12) & 0x1F) + +/* Fourth face, 5 bits */ +#define POLY_GET_V9_5b(g)((g->words.w0 >> 17) & 0x1F) +#define POLY_GET_V10_5b(g)((g->words.w0 >> 22) & 0x1F) +#define POLY_GET_V11_5b(g)((g->words.w0 >> 27) & 0x1F) + +/* First face, 7 bits */ +#define POLY_GET_V0_7b(g)((g->words.w1 >> 1) & 0x7F) +#define POLY_GET_V1_7b(g)((g->words.w1 >> 8) & 0x7F) +#define POLY_GET_V2_7b(g)((g->words.w1 >> 15) & 0x7F) + +/* Second face, 7 bits */ +#define POLY_GET_V3_7b(g)((g->words.w1 >> 22) & 0x7F) +#define POLY_GET_V4_7b(g)((((g->words.w1 >> 29) & 7) | ((g->words.w0 & 0xF) << 3)) & 0x7F) +#define POLY_GET_V5_7b(g)((g->words.w0 >> 4) & 0x7F) + +/* Third face, 7 bits */ +#define POLY_GET_V6_7b(g)((g->words.w0 >> 11) & 0x7F) +#define POLY_GET_V7_7b(g)((g->words.w0 >> 18) & 0x7F) +#define POLY_GET_V8_7b(g)((g->words.w0 >> 25) & 0x7F) + +/* Vertex matrix types */ +#define SHARED_MTX GX_PNMTX0 +#define NONSHARED_MTX GX_PNMTX1 + +#define MTX_SHARED 0 +#define MTX_NONSHARED 1 + +/* NOOP Debug Tags */ +#define G_TAG_NONE 0 +#define G_TAG_HERE 1 +#define G_TAG_STRING 2 +#define G_TAG_WORD 3 +#define G_TAG_FLOAT 4 +#define G_TAG_INFO 5 +#define G_TAG_CALLBACK 6 +#define G_TAG_OPENDISP 7 +#define G_TAG_CLOSEDISP 8 +#define G_TAG_FILL 9 + +/* Vertex Culling Flags */ +#define G_CULL_X_LESSTHAN 0x100 /* x component left of culling plane */ +#define G_CULL_X_GREATERTHAN 0x200 /* x component right of culling plane */ +#define G_CULL_Y_LESSTHAN 0x400 /* y component below culling plane */ +#define G_CULL_Y_GREATERTHAN 0x800 /* y component above culling plane */ +#define G_CULL_Z_LESSTHAN 0x1000 /* z component behind culling plane */ +#define G_CULL_Z_GREATERTHAN 0x2000 /* z component farther than culling plane */ + +/* Extra Geometry Mode Flags */ +#define G_LIGHTING_POSITIONAL 0x400000 +#define G_DECAL_LEQUAL 0x00 +#define G_DECAL_GEQUAL 0x10 +#define G_DECAL_EQUAL 0x20 +#define G_DECAL_ALWAYS 0x30 +#define G_DECAL_SPECIAL 0x40 +#define G_DECAL_ALL G_DECAL_ALWAYS | G_DECAL_SPECIAL + +/* Indicies for G_SPECIAL_1 */ +#define G_SPECIAL_NONE 0 +#define G_SPECIAL_UNKNOWN 1 +#define G_SPECIAL_TA_MODE 2 + +/* Texture Adjust Modes (used in G_SPECIAL1) */ +#define G_TA_N64 0 +#define G_TA_DOLPHIN 1 + +/* Combiner Param Ids */ +#define COMBINER_PARAM_A 1 +#define COMBINER_PARAM_B 2 +#define COMBINER_PARAM_C 3 +#define COMBINER_PARAM_D 4 + +/* TEV Combiner Settings */ + +#define TEV_COMBINED 0 +#define TEV_COMBINED_ALPHA 1 +#define TEV_FILL 2 +#define TEV_PRIM_LOD_FRAC 3 +#define TEV_PRIMITIVE 4 +#define TEV_PRIMITIVE_ALPHA 5 +#define TEV_ENVIRONMENT 6 +#define TEV_ENV_ALPHA 7 +#define TEV_TEXEL0 8 +#define TEV_TEXEL0_ALPHA 9 +#define TEV_SHADE 10 +#define TEV_SHADE_ALPHA 11 +#define TEV_ONE 12 +#define TEV_HALF 13 +#define TEV_KONST 14 +#define TEV_ZERO 15 + +#define TEV_ALPHA_COMBINED 0 +#define TEV_ALPHA_PRIM_LOD_FRAC 1 +#define TEV_ALPHA_PRIMITIVE 2 +#define TEV_ALPHA_ENVIRONMENT 3 +#define TEV_ALPHA_TEXEL0 4 +#define TEV_ALPHA_SHADE 5 +#define TEV_ALPHA_ONE 6 +#define TEV_ALPHA_ZERO 7 + +/* Macro to expand packed image/tile width and height */ +#define EXPAND_WIDTH(wd)(wd + 1) +#define EXPAND_HEIGHT(ht)((ht + 1) * 4) + +/* Combiner Macros */ + +#define COMBINER_GET_a0(words)((words.w0 >> 20) & 0xF) +#define COMBINER_GET_b0(words)((words.w1 >> 28) & 0xF) +#define COMBINER_GET_c0(words)((words.w0 >> 15) & 0x1F) +#define COMBINER_GET_d0(words)((words.w1 >> 15) & 7) + +#define COMBINER_GET_Aa0(words)((words.w0 >> 12) & 7) +#define COMBINER_GET_Ab0(words)((words.w1 >> 12) & 7) +#define COMBINER_GET_Ac0(words)((words.w0 >> 9) & 7) +#define COMBINER_GET_Ad0(words)((words.w1 >> 9) & 7) + +#define COMBINER_GET_a1(words)((words.w0 >> 5) & 0xF) +#define COMBINER_GET_b1(words)((words.w1 >> 24) & 0xF) +#define COMBINER_GET_c1(words)(words.w0 & 0x1F) +#define COMBINER_GET_d1(words)((words.w1 >> 6) & 7) + +#define COMBINER_GET_Aa1(words)((words.w1 >> 21) & 7) +#define COMBINER_GET_Ab1(words)((words.w1 >> 3) & 7) +#define COMBINER_GET_Ac1(words)((words.w1 >> 18) & 7) +#define COMBINER_GET_Ad1(words)(words.w1 & 7) + +/* TEV Combiner Macros */ + +#define COMBINER_TEV_GET_a0(words)((words.w1 >> 28) & 0xF) +#define COMBINER_TEV_GET_b0(words)((words.w1 >> 24) & 0xF) +#define COMBINER_TEV_GET_c0(words)((words.w1 >> 20) & 0xF) +#define COMBINER_TEV_GET_d0(words)((words.w1 >> 16) & 0xF) + +#define COMBINER_TEV_GET_Aa0(words)((words.w0 >> 21) & 7) +#define COMBINER_TEV_GET_Ab0(words)((words.w0 >> 18) & 7) +#define COMBINER_TEV_GET_Ac0(words)((words.w0 >> 15) & 7) +#define COMBINER_TEV_GET_Ad0(words)((words.w0 >> 12) & 7) + +#define COMBINER_TEV_GET_a1(words)((words.w1 >> 12) & 0xF) +#define COMBINER_TEV_GET_b1(words)((words.w1 >> 8) & 0xF) +#define COMBINER_TEV_GET_c1(words)((words.w1 >> 4) & 0xF) +#define COMBINER_TEV_GET_d1(words)((words.w1 >> 0) & 0xF) + +#define COMBINER_TEV_GET_Aa1(words)((words.w0 >> 9) & 7) +#define COMBINER_TEV_GET_Ab1(words)((words.w0 >> 6) & 7) +#define COMBINER_TEV_GET_Ac1(words)((words.w0 >> 3) & 7) +#define COMBINER_TEV_GET_Ad1(words)((words.w0 >> 0) & 7) + +typedef struct { + int cmd:8; + unsigned int a0:4; + unsigned int c0:5; + unsigned int Aa0:3; + unsigned int Ac0:3; + unsigned int a1:4; + unsigned int c1:5; + + unsigned int b0:4; + unsigned int b1:4; + unsigned int Aa1:3; + unsigned int Ac1:3; + unsigned int d0:3; + unsigned int Ab0:3; + unsigned int Ad0:3; + unsigned int d1:3; + unsigned int Ab1:3; + unsigned int Ad1:3; +} Gsetcombine; + +typedef struct { + int cmd:8; /* 0xCF */ + unsigned int Aa0:3; + unsigned int Ab0:3; + unsigned int Ac0:3; + unsigned int Ad0:3; + + unsigned int Aa1:3; + unsigned int Ab1:3; + unsigned int Ac1:3; + unsigned int Ad1:3; + + unsigned int a0:4; + unsigned int b0:4; + unsigned int c0:4; + unsigned int d0:4; + + unsigned int a1:4; + unsigned int b1:4; + unsigned int c1:4; + unsigned int d1:4; +} Gsetcombine_tev; + +typedef struct { + unsigned int cmd:8; + unsigned int xl:12; /* Top-left x coord */ + unsigned int yl:12; /* Top-left y coord */ + unsigned int pad1:5; + unsigned int tile:3; /* Tile descriptor index */ + unsigned int xh:12; /* Lower-right x coord */ + unsigned int yh:12; /* Lower-right y coord */ + + unsigned int pad2:32; + + unsigned int s:16; /* S (X) texture coord at top left */ + unsigned int t:16; /* T (Y) texture coord at top left */ + + unsigned int pad3:32; + + unsigned int dsdx:16; /* Change in S (X) per change in X */ + unsigned int dtdy:16; /* Change in T (Y) per change in Y */ +} Gtexrect2; + +typedef struct { + int cmd:8; + unsigned int dol_fmt:4; + unsigned int pad0:1; + unsigned int tile:3; + unsigned int tlut_name:4; + unsigned int wrap_s:2; + unsigned int wrap_t:2; + unsigned int shift_s:4; + unsigned int shift_t:4; + unsigned int pad1:32; +} Gsettile_dolphin; + +typedef struct { + int cmd:8; + unsigned int sl:14; /* Start of S coordinate */ + unsigned int slen:10; /* Length of S coordinate */ + + unsigned int isDolphin:1; /* If true, format is Gsettilesize_dolphin. If false, format is Gsettilesize2 */ + unsigned int pad:4; + unsigned int tile:3; /* Tile descriptor */ + unsigned int tl:14; /* Start of T coordinate */ + unsigned int tlen:10; /* Length of T coordinate */ +} Gsettilesize_dolphin; + +typedef struct { + int cmd:8; /* Command */ + unsigned int fmt:3; /* Image format */ + unsigned int siz:2; /* Image format texel size */ + unsigned int isDolphin:1; /* Is this Gsetimg2 or Gsetimg */ + unsigned int ht:8; /* Height, packed: (height / 4) - 1 */ + unsigned int wd:10; /* Width, packed: width - 1 */ + + unsigned int imgaddr:32; /* Image RAM address */ +} Gsetimg2; + +typedef union { + Gsetimg setimg; + Gsetimg2 setimg2; +} Gsetimg_new; + +typedef struct { + int cmd:8; + unsigned int type:2; /* Type - if 2, is Gloadtlut_dolphin. Otherwise is Gloadtlut. */ + unsigned int pad0:2; + unsigned int tlut_name:4; /* GC Palette/TLUT name(index). */ + unsigned int pad1:2; + unsigned int count:14; /* Number of entries in the TLUT. Max by GC spec is 0x4000. */ + + unsigned int tlut_addr:32; +} Gloadtlut_dolphin; + +typedef struct { + unsigned char cmd:8; + unsigned char xparam:8; + unsigned int pad:2; + unsigned char level:3; + unsigned char tile:3; + unsigned char on:8; /* Should be 7 bits w/ 1 bit padding, but emulator doesn't do this */ + unsigned short s:16; + unsigned short t:16; +} Gtexture_internal; + +typedef struct { + unsigned char cmd:8; + unsigned int index:8; + unsigned int offset:16; + unsigned int data; +} Gmoveword; + +typedef struct { + unsigned char cmd:8; + unsigned int length:8; + unsigned int offset:8; + unsigned int index:8; + + unsigned int data; +} Gmovemem; + +typedef struct { + unsigned char col[3]; + unsigned char kc; + unsigned char colc[3]; + unsigned char k1; + signed short pos[3]; /* position of light */ + unsigned char kq; +} Light_pos_t; + +typedef union { + Light_t l; + Light_pos_t p; + long long int force_align[2]; +} Light_new; + +/* Combiner Structs */ +typedef struct { + unsigned int pad0:4; + unsigned int color0:4; + unsigned int pad1:4; + unsigned int color1:4; + unsigned int pad2:4; + unsigned int color2:4; + unsigned int pad3:4; + unsigned int color3:4; +} combiner_tev_color; + +typedef struct { + unsigned int pad0:5; + unsigned int alpha0:3; + unsigned int pad1:5; + unsigned int alpha1:3; +} combiner_tev_alpha; + +static combiner_tev_alpha tbla[8] = { + { 0, TEV_ALPHA_COMBINED, 0, TEV_ALPHA_ONE }, + { 0, TEV_ALPHA_TEXEL0, 0, TEV_ALPHA_TEXEL0 }, + { 0, TEV_ALPHA_TEXEL0, 0, TEV_ALPHA_TEXEL0 }, + { 0, TEV_ALPHA_PRIMITIVE, 0, TEV_ALPHA_PRIMITIVE }, + { 0, TEV_ALPHA_SHADE, 0, TEV_ALPHA_SHADE }, + { 0, TEV_ALPHA_ENVIRONMENT, 0, TEV_ALPHA_ENVIRONMENT }, + { 0, TEV_ALPHA_ONE, 0, TEV_ALPHA_PRIM_LOD_FRAC }, + { 0, TEV_ALPHA_ZERO, 0, TEV_ALPHA_ZERO } +}; + +static combiner_tev_color tblc[32] = { + { 0, TEV_COMBINED, 0, TEV_COMBINED, 0, TEV_COMBINED, 0, TEV_COMBINED }, + { 0, TEV_TEXEL0, 0, TEV_TEXEL0, 0, TEV_TEXEL0, 0, TEV_TEXEL0 }, + { 0, TEV_TEXEL0, 0, TEV_TEXEL0, 0, TEV_TEXEL0, 0, TEV_TEXEL0 }, + { 0, TEV_PRIMITIVE, 0, TEV_PRIMITIVE, 0, TEV_PRIMITIVE, 0, TEV_PRIMITIVE }, + { 0, TEV_SHADE, 0, TEV_SHADE, 0, TEV_SHADE, 0, TEV_SHADE }, + { 0, TEV_ENVIRONMENT, 0, TEV_ENVIRONMENT, 0, TEV_ENVIRONMENT, 0, TEV_ENVIRONMENT }, + { 0, TEV_ONE, 0, TEV_HALF, 0, TEV_HALF, 0, TEV_ONE }, + { 0, TEV_HALF, 0, TEV_HALF, 0, TEV_COMBINED_ALPHA, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_TEXEL0_ALPHA, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_TEXEL0_ALPHA, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_PRIMITIVE_ALPHA, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_SHADE_ALPHA, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ENV_ALPHA, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_HALF, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_PRIM_LOD_FRAC, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_HALF, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO }, + { 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO, 0, TEV_ZERO } +}; + +/* New Command Macros */ +#define gsDPParam2(cmd, tag, param, extra) \ +{{ \ + _SHIFTL(cmd, 24, 8) | _SHIFTL(tag, 16, 8) | _SHIFTL(param, 0, 16), extra \ +}} + +#define gsDPNoOpTag2(tag, param, extra) gsDPParam2(G_NOOP, tag, param, extra) +#define gsDPNoOpHere() gsDPNoOpTag2(G_TAG_HERE, __LINE__, __FILE__) +#define gsDPNoOpString(str, param) gsDPNoOpTag2(G_TAG_STRING, param, str) +#define gsDPNoOpWord(word, param) gsDPNoOpTag2(G_TAG_WORD, param, word) +#define gsDPNoOpFloat(float, param) gsDPNoOpTag2(G_TAG_FLOAT, param, float) +#define gsDPNoOpQuiet() gsDPNoOpTag2(G_TAG_INFO, 0, 0) +#define gsDPNoOpVerbose() gsDPNoOpTag2(G_TAG_INFO, 0xF, 0) +#define gsDPNoOpCallBack(callback, param) gsDPNoOpTag2(G_TAG_CALLBACK, param, callback) +#define gsDPNoOpOpenDisp() gsDPNoOpTag2(G_TAG_OPENDISP, __LINE__, __FILE__) +#define gsDPNoOpCloseDisp() gsDPNoOpTag2(G_TAG_CLOSEDISP, __LINE__, __FILE__) +#define gsDPNoOpFill() gsDPNoOpTag2(G_TAG_FILL, 0, 0) +#define gsDPNoOpTag3(tag, extra, param) gsDPNoOpTag2(tag, param, extra) + +#define G_TLUT_DOLPHIN 2 +#define gDPLoadTLUT_Dolphin(pkt, name, count, unk, addr) \ +do { \ + Gfx* _g = (Gfx*)(pkt); \ + _g->words.w0 = _SHIFTL(G_LOADTLUT, 24, 8) | _SHIFTL(G_TLUT_DOLPHIN, 22, 2) | _SHIFTL(name, 16, 4) | _SHIFTL(unk, 14, 2) | _SHIFTL(count, 0, 14); \ + _g->words.w1 = (unsigned int)addr; \ +} while (0) + +#define gsDPLoadTLUT_Dolphin(name, count, unk, addr) \ +{{ \ + _SHIFTL(G_LOADTLUT, 24, 8) | _SHIFTL(G_TLUT_DOLPHIN, 22, 2) | _SHIFTL(name, 16, 4) | _SHIFTL(unk, 14, 2) | _SHIFTL(count, 0, 14), (unsigned int)addr \ +}} + +#define gsDPSetTextureImage_Dolphin(fmt, siz, h, w, img) \ +{{ \ + _SHIFTL(G_SETTIMG, 24, 8) | _SHIFTL(fmt, 21, 3) | _SHIFTL(siz, 19, 2) | _SHIFTL(1, 18, 1) | \ + _SHIFTL((h/4)-1, 10, 8) | _SHIFTL((w-1), 0, 10), img \ +}} + +#define gsDPSetTile_Dolphin(d_fmt, tile, tlut_name, wrap_s, wrap_t, shift_s, shift_t) \ +{{ \ + _SHIFTL(G_SETTILE_DOLPHIN, 24, 8) | _SHIFTL(d_fmt, 20, 4) | _SHIFTL(tile, 16, 3) | \ + _SHIFTL(tlut_name, 12, 4) | _SHIFTL(wrap_s, 10, 2) | _SHIFTL(wrap_t, 8, 2) | \ + _SHIFTL(shift_s, 4, 4) | _SHIFTL(shift_t, 0, 4), 0 \ +}} + +#define gDPSetTextureImage_Dolphin(pkt, fmt, siz, h, w, img) \ +{{ \ + Gfx* _gfx = (Gfx*)(pkt); \ + _gfx->words.w0 = _SHIFTL(G_SETTIMG, 24, 8) | _SHIFTL(fmt, 21, 3) | _SHIFTL(siz, 19, 2) | _SHIFTL(1, 18, 1) | \ + _SHIFTL((h/4)-1, 10, 8) | _SHIFTL((w-1), 0, 10); \ + _gfx->words.w1 = (unsigned int)img; \ +}} + +#define gDPSetTile_Dolphin(pkt, d_fmt, tile, tlut_name, wrap_s, wrap_t, shift_s, shift_t) \ +{{ \ + Gfx* _gfx = (Gfx*)(pkt); \ + _gfx->words.w0 = _SHIFTL(G_SETTILE_DOLPHIN, 24, 8) | _SHIFTL(d_fmt, 20, 4) | _SHIFTL(tile, 16, 3) | \ + _SHIFTL(tlut_name, 12, 4) | _SHIFTL(wrap_s, 10, 2) | _SHIFTL(wrap_t, 8, 2) | \ + _SHIFTL(shift_s, 4, 4) | _SHIFTL(shift_t, 0, 4); \ + /*_gfx->words.w1 = 0;*/ /* bug? they don't set the second word */ \ +}} + +#define G_DOLPHIN_TLUT_DEFAULT_MODE 15 // used almost always? CI palettes are forced to GX_TF_RGB5A3 +#define gsDPLoadTextureBlock_4b_Dolphin(timg, fmt, w, h, pal, ws, wt, ss, st) \ + gsDPSetTextureImage_Dolphin(fmt, G_IM_SIZ_4b, h, w, timg), \ + gsDPSetTile_Dolphin(G_DOLPHIN_TLUT_DEFAULT_MODE, 0, pal, ws, wt, ss, st) + +#define gDPLoadTextureTile_4b_Dolphin(pkt, timg, fmt, w, h) \ +do { \ + gDPSetTextureImage_Dolphin(pkt, fmt, G_IM_SIZ_4b, h, w, timg); \ + gDPSetTile_Dolphin(pkt, G_DOLPHIN_TLUT_DEFAULT_MODE, 0, 0, 0, 0, 0, 0) \ +} while (0); + +#define gsSPNTriangles(n) \ +{{ \ + _SHIFTL(G_TRIN_INDEPEND, 24, 8) | _SHIFTL(n-1, 17, 7), 0 \ +}} + +/* 5 bits per vertex id (32) */ +#define gsSPNTriangleData1(v0, v1, v2, flag) (_SHIFTL(v2, 10, 5) | _SHIFTL(v1, 5, 5) | _SHIFTL(v0, 0, 5)) + +/* 7 bits per vertex id (128) */ +#define gsSPNTriangleData2(v0, v1, v2, flag) \ +{{ \ + (unsigned long long)(_SHIFTL(v2, 14, 7) | _SHIFTL(v1, 7, 7) | _SHIFTL(v0, 0, 7)) \ +}} + +#define G_VTX_MODE_5bit 0 +#define G_VTX_MODE_7bit 1 + +#define gSPNTriangles_5b(pkt, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) \ +{{ \ + Gfx* _g = (Gfx*)(pkt); \ + _g->words.w0 = (u32)((gsSPNTriangleData1(v9, v10, v11) << 17) | (gsSPNTriangleData1(v6, v7, v8) << 2) | ((gsSPNTriangleData1(v3, v4, v5) >> 13) & 3)); \ + _g->words.w1 = (u32)(((gsSPNTriangleData1(v3, v4, v5) & 7) << 19) | (gsSPNTriangleData1(v0, v1, v2) << 4) | G_VTX_MODE_5bit); \ +}} + +#define gSPNTrianglesInit_5b(pkt, n, v0, v1, v2, v3, v4, v5, v6, v7, v8) \ +{{ \ + Gfx* _g = (Gfx*)(pkt); \ + _g->words.w0 = (u32)(_SHIFTL(G_TRIN_INDEPEND, 24, 8) | _SHIFTL(n-1, 17, 7) | _SHIFTL(gsSPNTriangleData1(v6, v7, v8, 0), 2, 15) | _SHIFTL(_SHIFTR(gsSPNTriangleData1(v3, v4, v5, 0), 2, 13), 0, 2)); \ + _g->words.w1 = (u32)(_SHIFTL(gsSPNTriangleData1(v3, v4, v5, 0), 19, 13) | _SHIFTL(gsSPNTriangleData1(v0, v1, v2, 0), 4, 15) | _SHIFTL(G_VTX_MODE_5bit, 0, 1)); \ +}} + +// TODO: convert +#define gSPNTriangles_7b(v0, v1, v2, v3, v4, v5, v6, v7, v8) \ +{{ \ + (unsigned long long)((gsSPNTriangleData2(v6, v7, v8) << 43) | (gsSPNTriangleData2(v3, v4, v5) << 22) | \ + (gsSPNTriangleData2(v0, v1, v2) << 1)) | G_VTX_MODE_7bit \ +}} + +#define gSPNTrianglesInit_7b(n, v0, v1, v2, v3, v4, v5) \ +{{ \ + (unsigned long long)((((unsigned long long)gsSPNTriangles(n)) << 32) | (gsSPNWTriangleData2(v3, v4, v5) << 22) | \ + (gsSPNTriangleData2(v0, v1, v2) << 1)) | G_VTX_MODE_7bit \ +}} + +#define gsSPNTriangles_5b(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) \ +{{ \ + (unsigned long long)((gsSPNTriangleData1(v9, v10, v11) << 49) | (gsSPNTriangleData1(v6, v7, v8) << 34) | \ + (gsSPNTriangleData1(v3, v4, v5) << 19) | (gsSPNTriangleData1(v0, v1, v2) << 4)) | G_VTX_MODE_5bit \ +}} + +#define gsSPNTrianglesInit_5b(n, v0, v1, v2, v3, v4, v5, v6, v7, v8) \ +{{ \ + _SHIFTL(G_TRIN_INDEPEND, 24, 8) | _SHIFTL(n-1, 17, 7) | _SHIFTL(gsSPNTriangleData1(v6, v7, v8, 0), 2, 15) | _SHIFTL(_SHIFTR(gsSPNTriangleData1(v3, v4, v5, 0), 2, 13), 0, 2), \ + _SHIFTL(gsSPNTriangleData1(v3, v4, v5, 0), 19, 13) | _SHIFTL(gsSPNTriangleData1(v0, v1, v2, 0), 4, 15) | _SHIFTL(G_VTX_MODE_5bit, 0, 1) \ +}} + +#define gsSPNTriangles_7b(v0, v1, v2, v3, v4, v5, v6, v7, v8) \ +{{ \ + (unsigned long long)((gsSPNTriangleData2(v6, v7, v8) << 43) | (gsSPNTriangleData2(v3, v4, v5) << 22) | \ + (gsSPNTriangleData2(v0, v1, v2) << 1)) | G_VTX_MODE_7bit \ +}} + +#define gsSPNTrianglesInit_7b(n, v0, v1, v2, v3, v4, v5) \ +{{ \ + (unsigned long long)((((unsigned long long)gsSPNTriangles(n)) << 32) | (gsSPNWTriangleData2(v3, v4, v5) << 22) | \ + (gsSPNTriangleData2(v0, v1, v2) << 1)) | G_VTX_MODE_7bit \ +}} + +#ifdef __cplusplus +} +#endif + +#endif /* __GBI_EXTENSIONS_H__ */ diff --git a/include/libu64/gfxprint.h b/include/libu64/gfxprint.h index f23f4e13..60a620e5 100644 --- a/include/libu64/gfxprint.h +++ b/include/libu64/gfxprint.h @@ -2,7 +2,7 @@ #define GFXPRINT_H #include "types.h" -#include "libultra/u64types.h" +#include "libu64/u64types.h" #include "PR/mbi.h" #include "va_args.h" diff --git a/include/libu64/u64types.h b/include/libu64/u64types.h index 089ac015..24ed70cd 100644 --- a/include/libu64/u64types.h +++ b/include/libu64/u64types.h @@ -7,4 +7,16 @@ typedef struct xyz_s { f32 x, y, z; } xyz_t; +typedef struct { + u32 r:8; + u32 g:8; + u32 b:8; + u32 a:8; +} rgba8888_t; + +typedef union { + u32 rgba8888; + rgba8888_t c; +} rgba8888; + #endif diff --git a/include/libultra/gu.h b/include/libultra/gu.h index 49ee20fa..5ce54ee7 100644 --- a/include/libultra/gu.h +++ b/include/libultra/gu.h @@ -2,7 +2,7 @@ #define GU_H #include "PR/mbi.h" #include "types.h" -#include "libultra/u64types.h" +#include "libultra/ultratypes.h" inline void guTranslateF(float m[4][4], float x, float y, float z){ diff --git a/include/libultra/u64types.h b/include/libultra/ultratypes.h similarity index 72% rename from include/libultra/u64types.h rename to include/libultra/ultratypes.h index 09fa9428..cb22866b 100644 --- a/include/libultra/u64types.h +++ b/include/libultra/ultratypes.h @@ -3,18 +3,6 @@ #include "types.h" -typedef struct { - u32 r:8; - u32 g:8; - u32 b:8; - u32 a:8; -} rgba8888_t; - -typedef union { - u32 rgba8888; - rgba8888_t c; -} rgba8888; - /* typedef struct { float m[4][4]; diff --git a/include/m_common_data.h b/include/m_common_data.h index 46394876..0a46a9e9 100644 --- a/include/m_common_data.h +++ b/include/m_common_data.h @@ -3,6 +3,7 @@ #include "types.h" #include "m_actor_type.h" +#include "m_land_h.h" #include "lb_rtc.h" #ifdef __cplusplus @@ -28,11 +29,13 @@ typedef struct time_s { } Time_c; typedef struct Save_s { - u8 _tmp0[0x20F14]; + u8 _tmp0[0x9120]; + /* 0x009120 */ mLd_land_info_c land_info; + u8 _tmp1[0x17DE8]; /* 0x020F14 */ lbRTC_ymd_t renew_time; - u8 _tmp1[0x1610]; + u8 _tmp2[0x1610]; /* 0x022528 */ OSTime time_delta; - u8 _tmp2[0x3AD0]; + u8 _tmp3[0x3AD0]; } Save_t; typedef union save_u { diff --git a/include/m_font.h b/include/m_font.h new file mode 100644 index 00000000..4c104126 --- /dev/null +++ b/include/m_font.h @@ -0,0 +1,534 @@ +#ifndef M_FONT_H +#define M_FONT_H + +#include "types.h" +#include "m_lib.h" +#include "graph.h" +#include "game.h" +#include "gbi_extensions.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CHAR_INVERT_EXCLAMATION 0 +#define CHAR_INVERT_QUESTIONMARK 1 +#define CHAR_DIAERESIS_A 2 +#define CHAR_GRAVE_A 3 +#define CHAR_ACUTE_A 4 +#define CHAR_CIRCUMFLEX_A 5 +#define CHAR_TILDE_A 6 +#define CHAR_ANGSTROM_A 7 +#define CHAR_CEDILLA 8 +#define CHAR_GRAVE_E 9 +#define CHAR_ACUTE_E 10 +#define CHAR_CIRCUMFLEX_E 11 +#define CHAR_DIARESIS_E 12 +#define CHAR_GRAVE_I 13 +#define CHAR_ACUTE_I 14 +#define CHAR_CIRCUMFLEX_I 15 +#define CHAR_DIARESIS_I 16 +#define CHAR_ETH 17 /* Đ */ +#define CHAR_TILDE_N 18 +#define CHAR_GRAVE_O 19 +#define CHAR_ACUTE_O 20 +#define CHAR_CIRCUMFLEX_O 21 +#define CHAR_TILDE_O 22 +#define CHAR_DIARESIS_O 23 +#define CHAR_OE 24 /* Ø */ +#define CHAR_GRAVE_U 25 +#define CHAR_ACUTE_U 26 +#define CHAR_CIRCUMFLEX_U 27 +#define CHAR_DIARESIS_U 28 +#define CHAR_LOWER_BETA 29 /* β */ +#define CHAR_THORN 30 /* Þ */ +#define CHAR_GRAVE_a 31 +#define CHAR_SPACE 32 /* ' ' */ +#define CHAR_EXCLAMATION 33 +#define CHAR_QUOTATION 34 +#define CHAR_ACUTE_a 35 +#define CHAR_CIRCUMFLEX_a 36 +#define CHAR_PERCENT 37 +#define CHAR_AMPERSAND 38 +#define CHAR_APOSTROPHE 39 +#define CHAR_OPEN_PARENTHESIS 40 +#define CHAR_CLOSE_PARENTHESIS 41 +#define CHAR_TILDE 42 +#define CHAR_SYMBOL_HEART 43 +#define CHAR_COMMA 44 +#define CHAR_DASH 45 +#define CHAR_PERIOD 46 +#define CHAR_SYMBOL_MUSIC_NOTE 47 +#define CHAR_ZERO 48 +#define CHAR_ONE 49 +#define CHAR_TWO 50 +#define CHAR_THREE 51 +#define CHAR_FOUR 52 +#define CHAR_FIVE 53 +#define CHAR_SIX 54 +#define CHAR_SEVEN 55 +#define CHAR_EIGHT 56 +#define CHAR_NINE 57 +#define CHAR_COLON 58 +#define CHAR_SYMBOL_DROPLET 59 +#define CHAR_LESS_THAN 60 +#define CHAR_EQUALS 61 +#define CHAR_GREATER_THAN 62 +#define CHAR_QUESTIONMARK 63 +#define CHAR_AT_SIGN 64 +#define CHAR_A 65 +#define CHAR_B 66 +#define CHAR_C 67 +#define CHAR_D 68 +#define CHAR_E 69 +#define CHAR_F 70 +#define CHAR_G 71 +#define CHAR_H 72 +#define CHAR_I 73 +#define CHAR_J 74 +#define CHAR_K 75 +#define CHAR_L 76 +#define CHAR_M 77 +#define CHAR_N 78 +#define CHAR_O 79 +#define CHAR_P 80 +#define CHAR_Q 81 +#define CHAR_R 82 +#define CHAR_S 83 +#define CHAR_T 84 +#define CHAR_U 85 +#define CHAR_V 86 +#define CHAR_W 87 +#define CHAR_X 88 +#define CHAR_Y 89 +#define CHAR_Z 90 +#define CHAR_TILDE_a 91 +#define CHAR_SYMBOL_ANNOYED 92 +#define CHAR_DIARESIS_a 93 +#define CHAR_ANGSTROM_a 94 +#define CHAR_UNDERSCORE 95 +#define CHAR_LOWER_CEDILLA 96 +#define CHAR_a 97 +#define CHAR_b 98 +#define CHAR_c 99 +#define CHAR_d 100 +#define CHAR_e 101 +#define CHAR_f 102 +#define CHAR_g 103 +#define CHAR_h 104 +#define CHAR_i 105 +#define CHAR_j 106 +#define CHAR_k 107 +#define CHAR_l 108 +#define CHAR_m 109 +#define CHAR_n 110 +#define CHAR_o 111 +#define CHAR_p 112 +#define CHAR_q 113 +#define CHAR_r 114 +#define CHAR_s 115 +#define CHAR_t 116 +#define CHAR_u 117 +#define CHAR_v 118 +#define CHAR_w 119 +#define CHAR_x 120 +#define CHAR_y 121 +#define CHAR_z 122 +#define CHAR_GRAVE_e 123 +#define CHAR_ACUTE_e 124 +#define CHAR_CIRCUMFLEX_e 125 +#define CHAR_DIARESIS_e 126 +#define CHAR_CONTROL_CODE 127 +#define CHAR_MESSAGE_TAG 128 +#define CHAR_GRAVE_i 129 +#define CHAR_ACUTE_i 130 +#define CHAR_CIRCUMFLEX_i 131 +#define CHAR_DIARESIS_i 132 +#define CHAR_INTERPUNCT 133 /* · */ +#define CHAR_LOWER_ETH 134 /* đ */ +#define CHAR_TILDE_n 135 +#define CHAR_GRAVE_o 136 +#define CHAR_ACUTE_o 137 +#define CHAR_CIRCUMFLEX_o 138 +#define CHAR_TILDE_o 139 +#define CHAR_DIARESIS_o 140 +#define CHAR_oe 141 +#define CHAR_GRAVE_u 142 +#define CHAR_ACUTE_u 143 +#define CHAR_HYPHEN 144 +#define CHAR_CIRCUMFLEX_u 145 +#define CHAR_DIARESIS_u 146 +#define CHAR_ACUTE_y 147 +#define CHAR_DIARESIS_y 148 +#define CHAR_LOWER_THORN 149 +#define CHAR_ACUTE_Y 150 +#define CHAR_BROKEN_BAR 151 /* ¦ */ +#define CHAR_SILCROW 152 /* § */ +#define CHAR_FEMININE_ORDINAL 153 +#define CHAR_MASCULINE_ORDINAL 154 /* ° */ +#define CHAR_DOUBLE_VERTICAL_BAR 155 +#define CHAR_LATIN_MU 156 +#define CHAR_SUPERSCRIPT_THREE 157 +#define CHAR_SUPERSCRIPT_TWO 158 +#define CHAR_SUPRESCRIPT_ONE 159 +#define CHAR_MACRON_SYMBOL 160 +#define CHAR_LOGICAL_NEGATION 161 +#define CHAR_ASH 162 +#define CHAR_LOWER_ASH 163 +#define CHAR_INVERT_QUOTATION 164 +#define CHAR_GUILLEMET_OPEN 165 +#define CHAR_GUILLEMET_CLOSE 166 +#define CHAR_SYMBOL_SUN 167 +#define CHAR_SYMBOL_CLOUD 168 +#define CHAR_SYMBOL_UMBRELLA 169 +#define CHAR_SYMBOL_WIND 170 +#define CHAR_SYMBOL_SNOWMAN 171 +#define CHAR_LINES_CONVERGE_RIGHT 172 +#define CHAR_LINES_CONVERGE_LEFT 173 +#define CHAR_FORWARD_SLASH 174 +#define CHAR_INFINITY 175 +#define CHAR_CIRCLE 176 +#define CHAR_CROSS 177 +#define CHAR_SQUARE 178 +#define CHAR_TRIANGLE 179 +#define CHAR_PLUS 180 +#define CHAR_SYMBOL_LIGTNING 181 // ?? maybe electric also? +#define CHAR_MARS_SYMBOL 182 // aka male symbol +#define CHAR_VENUS_SYMBOL 183 // aka female symbol +#define CHAR_SYMBOL_FLOWER 184 +#define CHAR_SYMBOL_STAR 185 +#define CHAR_SYMBOL_SKULL 186 +#define CHAR_SYMBOL_SURPRISE 187 +#define CHAR_SYMBOL_HAPPY 188 +#define CHAR_SYMBOL_SAD 189 +#define CHAR_SYMBOL_ANGRY 190 +#define CHAR_SYMBOL_SMILE 191 +#define CHAR_DIMENSION_SIGN 192 // multiplication character +#define CHAR_OBELUS_SIGN 193 // division character +#define CHAR_SYMBOL_HAMMER 194 +#define CHAR_SYMBOL_RIBBON 195 +#define CHAR_SYMBOL_MAIL 196 +#define CHAR_SYMBOL_MONEY 197 +#define CHAR_SYMBOL_PAW 198 +#define CHAR_SYMBOL_SQUIRREL 199 // might be dog? would make a bit more sense ig +#define CHAR_SYMBOL_CAT 200 +#define CHAR_SYMBOL_RABBIT 201 +#define CHAR_SYMBOL_OCTOPUS 202 // could also be bird...? +#define CHAR_SYMBOL_COW 203 +#define CHAR_SYMBOL_PIG 204 +#define CHAR_NEW_LINE 205 +#define CHAR_SYMBOL_FISH 206 +#define CHAR_SYMBOL_BUG 207 +#define CHAR_SEMICOLON 208 +#define CHAR_HASHTAG 209 +#define CHAR_SPACE_2 210 // Short space +#define CHAR_SPACE_3 211 // Wide space +#define CHAR_SYMBOL_KEY 212 +/* Begin EU-only symbols, unused in AC */ +#define CHAR_LEFT_QUOTATION 213 +#define CHAR_RIGHT_QUOTATION 214 +#define CHAR_LEFT_APOSTROPHE 215 +#define CHAR_RIGHT_APOSTROPHE 216 +#define CHAR_ETHEL 217 +#define CHAR_LOWER_ETHEL 218 +#define CHAR_ORDINAL_e 219 +#define CHAR_ORDINAL_er 220 +#define CHAR_ORDINAL_re 221 +#define CHAR_BACKSLASH 222 +/* Unused characters */ +#define CHAR_223 223 +#define CHAR_224 224 +#define CHAR_225 225 +#define CHAR_226 226 +#define CHAR_227 227 +#define CHAR_228 228 +#define CHAR_229 229 +#define CHAR_230 230 +#define CHAR_231 231 +#define CHAR_232 232 +#define CHAR_233 233 +#define CHAR_234 234 +#define CHAR_235 235 +#define CHAR_236 236 +#define CHAR_237 237 +#define CHAR_238 238 +#define CHAR_239 239 +#define CHAR_240 240 +#define CHAR_241 241 +#define CHAR_242 242 +#define CHAR_243 243 +#define CHAR_244 244 +#define CHAR_245 245 +#define CHAR_246 246 +#define CHAR_247 247 +#define CHAR_248 248 +#define CHAR_249 249 +#define CHAR_250 250 +#define CHAR_251 251 +#define CHAR_252 252 +#define CHAR_253 253 +#define CHAR_254 254 +#define CHAR_255 255 + +#define TOTAL_CHARS 256 + +#define mFont_MARKTYPE_VERT_ARROW 0 +#define mFont_MARKTYPE_HORI_ARROW 1 +#define mFont_MARKTYPE_CURSOR 2 +#define mFont_MARKTYPE_NEXT 3 +#define mFont_MARKTYPE_CHOICE 4 +#define mFont_MARKTYPE_TOTAL 5 + +enum { + mFont_CONT_CODE_BEGIN = 0, + mFont_CONT_CODE_LAST = mFont_CONT_CODE_BEGIN, + mFont_CONT_CODE_CONINTUE, + mFont_CONT_CODE_CLEAR, + mFont_CONT_CODE_CURSOR_SET_TIME, + mFont_CONT_CODE_BUTTON, + mFont_CONT_CODE_COLOR, + mFont_CONT_CODE_ABLE_CANCEL, + mFont_CONT_CODE_UNABLE_CANCEL, + mFont_CONT_CODE_SET_DEMO_ORDER_PLAYER, + mFont_CONT_CODE_SET_DEMO_ORDER_NPC0, + mFont_CONT_CODE_SET_DEMO_ORDER_NPC1, + mFont_CONT_CODE_SET_DEMO_ORDER_NPC2, + mFont_CONT_CODE_SET_DEMO_ORDER_QUEST, + mFont_CONT_CODE_SET_SELECT_WINDOW, + mFont_CONT_CODE_SET_NEXT_MESSAGE_F, + mFont_CONT_CODE_SET_NEXT_MESSAGE_0, + mFont_CONT_CODE_SET_NEXT_MESSAGE_1, + mFont_CONT_CODE_SET_NEXT_MESSAGE_2, + mFont_CONT_CODE_SET_NEXT_MESSAGE_3, + mFont_CONT_CODE_SET_NEXT_MESSAGE_RANDOM_2, + mFont_CONT_CODE_SET_NEXT_MESSAGE_RANDOM_3, + mFont_CONT_CODE_SET_NEXT_MESSAGE_RANDOM_4, + mFont_CONT_CODE_SET_SELECT_STRING_2, + mFont_CONT_CODE_SET_SELECT_STRING_3, + mFont_CONT_CODE_SET_SELECT_STRING_4, + mFont_CONT_CODE_SET_FORCE_NEXT, + mFont_CONT_CODE_PUT_STRING_PLAYER_NAME, + mFont_CONT_CODE_PUT_STRING_TALK_NAME, + mFont_CONT_CODE_PUT_STRING_TAIL, + mFont_CONT_CODE_PUT_STRING_YEAR, + mFont_CONT_CODE_PUT_STRING_MONTH, + mFont_CONT_CODE_PUT_STRING_WEEK, + mFont_CONT_CODE_PUT_STRING_DAY, + mFont_CONT_CODE_PUT_STRING_HOUR, + mFont_CONT_CODE_PUT_STRING_MIN, + mFont_CONT_CODE_PUT_STRING_SEC, + mFont_CONT_CODE_PUT_STRING_FREE0, + mFont_CONT_CODE_PUT_STRING_FREE1, + mFont_CONT_CODE_PUT_STRING_FREE2, + mFont_CONT_CODE_PUT_STRING_FREE3, + mFont_CONT_CODE_PUT_STRING_FREE4, + mFont_CONT_CODE_PUT_STRING_FREE5, + mFont_CONT_CODE_PUT_STRING_FREE6, + mFont_CONT_CODE_PUT_STRING_FREE7, + mFont_CONT_CODE_PUT_STRING_FREE8, + mFont_CONT_CODE_PUT_STRING_FREE9, + mFont_CONT_CODE_PUT_STRING_DETERMINATION, + mFont_CONT_CODE_PUT_STRING_COUNTRY_NAME, + mFont_CONT_CODE_PUT_STRING_RANDOM_NUMBER_2, + mFont_CONT_CODE_PUT_STRING_ITEM0, + mFont_CONT_CODE_PUT_STRING_ITEM1, + mFont_CONT_CODE_PUT_STRING_ITEM2, + mFont_CONT_CODE_PUT_STRING_ITEM3, + mFont_CONT_CODE_PUT_STRING_ITEM4, + mFont_CONT_CODE_PUT_STRING_FREE10, + mFont_CONT_CODE_PUT_STRING_FREE11, + mFont_CONT_CODE_PUT_STRING_FREE12, + mFont_CONT_CODE_PUT_STRING_FREE13, + mFont_CONT_CODE_PUT_STRING_FREE14, + mFont_CONT_CODE_PUT_STRING_FREE15, + mFont_CONT_CODE_PUT_STRING_FREE16, + mFont_CONT_CODE_PUT_STRING_FREE17, + mFont_CONT_CODE_PUT_STRING_FREE18, + mFont_CONT_CODE_PUT_STRING_FREE19, + mFont_CONT_CODE_PUT_STRING_MAIL, + mFont_CONT_CODE_SET_PLAYER_DESTINY0, + mFont_CONT_CODE_SET_PLAYER_DESTINY1, + mFont_CONT_CODE_SET_PLAYER_DESTINY2, + mFont_CONT_CODE_SET_PLAYER_DESTINY3, + mFont_CONT_CODE_SET_PLAYER_DESTINY4, + mFont_CONT_CODE_SET_PLAYER_DESTINY5, + mFont_CONT_CODE_SET_PLAYER_DESTINY6, + mFont_CONT_CODE_SET_PLAYER_DESTINY7, + mFont_CONT_CODE_SET_PLAYER_DESTINY8, + mFont_CONT_CODE_SET_PLAYER_DESTINY9, + mFont_CONT_CODE_SET_MESSAGE_CONTENTS_NORMAL, + mFont_CONT_CODE_SET_MESSAGE_CONTENTS_ANGRY, + mFont_CONT_CODE_SET_MESSAGE_CONTENTS_SAD, + mFont_CONT_CODE_SET_MESSAGE_CONTENTS_FUN, + mFont_CONT_CODE_SET_MESSAGE_CONTENTS_SLEEPY, + mFont_CONT_CODE_SET_COLOR_CHAR, + mFont_CONT_CODE_SOUND_CUT, + mFont_CONT_CODE_SET_LINE_OFFSET, + mFont_CONT_CODE_SET_LINE_TYPE, + mFont_CONT_CODE_SET_CHAR_SCALE, + mFont_CONT_CODE_BUTTON2, + mFont_CONT_CODE_BGM_MAKE, + mFont_CONT_CODE_BGM_DELETE, + mFont_CONT_CODE_MSG_TIME_END, + mFont_CONT_CODE_SOUND_TRG_SYS, + mFont_CONT_CODE_SET_LINE_SCALE, + mFont_CONT_CODE_SOUND_NO_PAGE, + mFont_CONT_CODE_VOICE_TRUE, + mFont_CONT_CODE_VOICE_FALSE, + mFont_CONT_CODE_SELECT_NO_B, + mFont_CONT_CODE_GIVE_OPEN, + mFont_CONT_CODE_GIVE_CLOSE, + mFont_CONT_CODE_SET_MESSAGE_CONTENTS_GLOOMY, + mFont_CONT_CODE_SELECT_NO_B_CLOSE, + mFont_CONT_CODE_SET_NEXT_MESSAGE_RANDOM_SECTION, + mFont_CONT_CODE_AGB_DUMMY0, + mFont_CONT_CODE_AGB_DUMMY1, + mFont_CONT_CODE_AGB_DUMMY2, + mFont_CONT_CODE_SPACE, + mFont_CONT_CODE_AGB_DUMMY3, + mFont_CONT_CODE_AGB_DUMMY4, + mFont_CONT_CODE_AGB_MALE_FEMALE_CHECK, + mFont_CONT_CODE_AGB_DUMMY5, + mFont_CONT_CODE_AGB_DUMMY6, + mFont_CONT_CODE_AGB_DUMMY7, + mFont_CONT_CODE_AGB_DUMMY8, + mFont_CONT_CODE_AGB_DUMMY9, + mFont_CONT_CODE_AGB_DUMMY10, + mFont_CONT_CODE_PUT_STRING_ISLAND_NAME, + mFont_CONT_CODE_SET_CURSOR_JUST, + mFont_CONT_CODE_CLR_CURSOR_JUST, + mFont_CONT_CODE_CUT_ARTICLE, + mFont_CONT_CODE_CAPITAL_LETTER, + mFont_CONT_CODE_PUT_STRING_AM_PM, + mFont_CONT_CODE_SET_NEXT_MESSAGE_4, + mFont_CONT_CODE_SET_NEXT_MESSAGE_5, + mFont_CONT_CODE_SET_SELECT_STRING_5, + mFont_CONT_CODE_SET_SELECT_STRING_6, + + mFont_CONT_CODE_NUM, + mFont_CONT_CODE_END = 256 +}; + +// TODO: figure out the other values for this +enum { + mFont_CONT_ATTRIBUTE_0, + mFont_CONT_ATTRIBUTE_DEMO, + mFont_CONT_ATTRIBUTE_STRING, + mFont_CONT_ATTRIBUTE_3, + mFont_CONT_ATTRIBUTE_SENTENCE, + mFont_CONT_ATTRIBUTE_CHARACTER, + mFont_CONT_ATTRIBUTE_BGM, + mFont_CONT_ATTRIBUTE_SE, + mFont_CONT_ATTRIBUTE_AGB_DUMMY, + + mFont_CONT_ATTRIBUTE_END +}; + +enum { + mFont_LineType_Top, + mFont_LineType_Center, + mFont_LineType_Bottom, + + mFont_LineType_End +}; + +#define mFont_CHAR_FLAG_CUT 1 +#define mFont_CHAR_FLAG_USE_POLY 2 +#define mFont_CHAR_FLAG_SCALE 4 +#define mFont_CHAR_FLAG_SCALE_RESET 8 + +/* sizeof(struct font_char_s) == 0x40 */ +typedef struct font_char_s { + /* 0x00 */ u8* char_p; + /* 0x04 */ s8 len; + /* 0x05 */ u8 flags; + /* 0x06 */ u8 pad0[2]; + /* 0x08 */ xy_t position; + /* 0x10 */ xy_t scale; + /* 0x18 */ xy_t inv_scale; + /* 0x20 */ xy_t scaled_size; + /* 0x28 */ xy_t inv_scaled_size; + /* 0x30 */ f32 ofs_y; + /* 0x34 */ rgba_t color; + /* 0x38 */ u8 color_ctr; + /* 0x39 */ u8 pad1[3]; + /* 0x3C */ f32 width; +} mFontChar; + +#define mFont_SENTENCE_FLAG_CUT 1 +#define mFont_SENTENCE_FLAG_REVERT 2 +#define mFont_SENTENCE_FLAG_USE_POLY 4 +#define mFont_SENTENCE_FLAG_3 8 +#define mFont_SENTENCE_FLAG_NO_COMBINE 16 +#define mFont_SENTENCE_FLAG_NO_COLOR 32 +#define mFont_SENTENCE_SKIP_DRAW_NEW_LINE 64 +#define mFont_SENTENCE_FLAG_VOICE_SE 128 +#define mFont_SENTENCE_FLAG_8 256 + +typedef struct font_sentence_s { + u8* sentence_p; + int len; + u32 flags; + xy_t position; + int line_type; + rgba_t color; + xy_t scale; + xy_t inv_scale; + int now_idx; + f32 offset; + f32 width; + f32 line_scale; + f32 inv_line_scale; + int se_pos; + s16 se_character_id; + u8 voice_idx; + u8 voice2_idx; + u8 voice3_idx; + u8 pad[3]; + mFontChar character; +} mFontSentence; + +#define mFont_TEX_CHAR_WIDTH 12 +#define mFont_TEX_CHAR_HEIGHT 16 + +#define mFont_TEX_CHAR_WIDTH_F32 12.0f +#define mFont_TEX_CHAR_HEIGHT_F32 16.0f + +#define mFont_SCALE_F 16.0f + +typedef void (*mFont_ControlCodeCharFunc)(mFontChar*, Gfx**); +typedef void (*mFont_ControlCodeSentenceFunc)(mFontSentence*, Gfx**); + +extern void mFont_ct(); +extern int mFont_UnintToString(u8* str, int figure, u32 num, int figure_start, int left_cut, int fill_zero, int separator); +extern int mFont_char_save_data_check(u8 c); +extern u8 mFont_small_to_capital(u8 small); +extern int mFont_GetCodeWidth(int c, int cut); +extern int mFont_GetStringWidth(u8* str, int len, int cut); +extern int mFont_GetStringWidth2(u8* str, int len, int cut); +extern int mFont_CodeSize_get(u8* str); +extern int mFont_CodeSize_idx_get(u8* str, int idx); +extern int mFont_cont_attr_get(int cont_code); +extern void mFont_gppSetMode(Gfx** gfx_pp); +extern void mFont_SetMode(GRAPH* graph, int mode); +extern void mFont_SetPrimColor(GRAPH* graph, int r, int g, int b, int a, int mode); +extern void mFont_SetCombineMode(GRAPH* graph, int revert_flag, int mode); +extern f32 mFont_SetVertexRectangle(GAME* game, f32 x, f32 y, int s, int t, f32 scale_x, f32 scale_y, int mode); +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); +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); +extern void mFont_CulcOrthoMatrix(Mtx* m); +extern void mFont_SetMatrix(GRAPH* graph, int mode); +extern void mFont_UnSetMatrix(GRAPH* graph, int mode); +extern void mFont_Main_start(GRAPH* graph); +extern f32 mFont_Get_NextCharRectX(int c, f32 x, f32 ofs_r, f32 ofs_l, int cut, f32 scale_x); +extern f32 mFont_Get_NextCharRectY(int c, f32 y, f32 ofs_t, f32 ofs_b, f32 scale_y); +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); +extern void mFontSentence_gppDraw(mFontSentence* this, GAME* game, Gfx** gfx_pp); +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); +extern void mFont_gppSetRectMode(Gfx** gfx_pp); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_home.h b/include/m_home.h new file mode 100644 index 00000000..13e1a058 --- /dev/null +++ b/include/m_home.h @@ -0,0 +1,16 @@ +#ifndef M_HOME_H +#define M_HOME_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mHm_ClearAllHomeInfo(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_land.h b/include/m_land.h new file mode 100644 index 00000000..25d79beb --- /dev/null +++ b/include/m_land.h @@ -0,0 +1,23 @@ +#ifndef M_LAND_H +#define M_LAND_H + +#include "types.h" +#include "m_land_h.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define mLd_BITMASK 0x3000 +#define mLd_CHECK_ID(id) (((id) & mLd_BITMASK) == mLd_BITMASK) + +#define NATIVE 0 +#define FOREIGN 1 + +extern u8* mLd_GetLandName(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_land_h.h b/include/m_land_h.h new file mode 100644 index 00000000..1330a653 --- /dev/null +++ b/include/m_land_h.h @@ -0,0 +1,24 @@ +#ifndef M_LAND_H_H +#define M_LAND_H_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Town name character count +#define LAND_NAME_SIZE 8 +#define LAND_NAME_MURA_SIZE (LAND_NAME_SIZE + 2) + +typedef struct land_info_s { + u8 name[LAND_NAME_SIZE]; + s8 exists; + u16 id; +} mLd_land_info_c; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_lib.h b/include/m_lib.h index 2f6e86c2..7fc4d46f 100644 --- a/include/m_lib.h +++ b/include/m_lib.h @@ -6,6 +6,10 @@ #define ABS(x) ((x) >= 0) ? (x) : -(x) #define SQ(x) ((x)*(x)) +typedef struct xy_s { + f32 x, y; +} xy_t; + typedef struct xyz_t { f32 x, y, z; } xyz_t; @@ -18,49 +22,49 @@ typedef struct rgba_t { //can be put in other place u8 r, g, b, a; } rgba_t; -void mem_copy(u8*, u8*, u32); -void mem_clear(u8*, u32, u8); -s32 mem_cmp(u8*, u8*, u32); +extern void mem_copy(u8*, u8*, u32); +extern void mem_clear(u8*, u32, u8); +extern s32 mem_cmp(u8*, u8*, u32); -f32 sin_s(s16); -f32 cos_s(s16); +extern f32 sin_s(s16); +extern f32 cos_s(s16); -s32 chase_angle(s16*, s16, s16); -s32 chase_s(s16*, s16, s16); -s32 chase_f(f32*, f32, f32); -f32 chase_xyz_t(xyz_t*, xyz_t*, f32); -s32 chase_angle2(s16*, s16, s16); +extern s32 chase_angle(s16*, s16, s16); +extern s32 chase_s(s16*, s16, s16); +extern s32 chase_f(f32*, f32, f32); +extern f32 chase_xyz_t(xyz_t*, xyz_t*, f32); +extern s32 chase_angle2(s16*, s16, s16); -void inter_float(f32*, f32, s32); -s16 get_random_timer(s16, s16); +extern void inter_float(f32*, f32, s32); +extern s16 get_random_timer(s16, s16); -void xyz_t_move(xyz_t*, xyz_t*); -void xyz_t_move_s_xyz(xyz_t*, s_xyz*); -void xyz_t_add(xyz_t*, xyz_t*, xyz_t*); -void xyz_t_sub(xyz_t*, xyz_t*, xyz_t*); -void xyz_t_mult_v(xyz_t*, f32); +extern void xyz_t_move(xyz_t*, xyz_t*); +extern void xyz_t_move_s_xyz(xyz_t*, s_xyz*); +extern void xyz_t_add(xyz_t*, xyz_t*, xyz_t*); +extern void xyz_t_sub(xyz_t*, xyz_t*, xyz_t*); +extern void xyz_t_mult_v(xyz_t*, f32); -f32 search_position_distance(xyz_t*, xyz_t*); -f32 search_position_distanceXZ(xyz_t*, xyz_t*); -s16 search_position_angleY(xyz_t*, xyz_t*); -s16 search_position_angleX(xyz_t*, xyz_t*); +extern f32 search_position_distance(xyz_t*, xyz_t*); +extern f32 search_position_distanceXZ(xyz_t*, xyz_t*); +extern s16 search_position_angleY(xyz_t*, xyz_t*); +extern s16 search_position_angleX(xyz_t*, xyz_t*); -void add_calc2(f32*, f32, f32, f32); -void add_calc0(f32*, f32, f32); +extern void add_calc2(f32*, f32, f32, f32); +extern void add_calc0(f32*, f32, f32); -s16 add_calc_short_angle2(s16*, s16, f32, s16, s16); -s16 add_calc_short_angle3(s16*, s16, f32, s16, s16); +extern s16 add_calc_short_angle2(s16*, s16, f32, s16, s16); +extern s16 add_calc_short_angle3(s16*, s16, f32, s16, s16); -void rgba_t_move(rgba_t*, rgba_t*); +extern void rgba_t_move(rgba_t*, rgba_t*); -u32 none_proc1(void); -void none_proc2(void); +extern u32 none_proc1(void); +extern void none_proc2(void); -void _Game_play_isPause(u32); //IDK +extern void _Game_play_isPause(u32); //IDK //Unsure //?? check_percent_abs(); //?? get_percent_forAccelBrake(); //void Game_play_Projection_Trans(game_play*, Vec3f*, Vec3f); -f32 get_percent(s32, s32, s32); +extern f32 get_percent(s32, s32, s32); #endif \ No newline at end of file diff --git a/include/m_msg.h b/include/m_msg.h new file mode 100644 index 00000000..d036e5d5 --- /dev/null +++ b/include/m_msg.h @@ -0,0 +1,23 @@ +#ifndef M_MSG_H +#define M_MSG_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* TODO: fill out message struct */ +typedef struct message_window_s M_MSG_WINDOW; + +extern int mMsg_Get_Length_String(u8* buf, size_t buf_size); + +extern M_MSG_WINDOW* mMsg_Get_base_window_p(); + +extern void mMsg_Set_free_str(M_MSG_WINDOW* msg, int free_str_no, u8* str, size_t str_size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_private.h b/include/m_private.h new file mode 100644 index 00000000..8836f1b4 --- /dev/null +++ b/include/m_private.h @@ -0,0 +1,16 @@ +#ifndef M_PRIVATE_H +#define M_PRIVATE_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PLAYER_NUM 4 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_rcp.h b/include/m_rcp.h new file mode 100644 index 00000000..3cd41a26 --- /dev/null +++ b/include/m_rcp.h @@ -0,0 +1,17 @@ +#ifndef M_RCP_H +#define M_RCP_H + +#include "types.h" +#include "PR/mbi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern Gfx* gfx_gSPTextureRectangle1(Gfx* gfx, u32 ulx, u32 uly, u32 lrx, u32 lry, int tile, int s, int t, int dsdx, int dtdy); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/m_skin_matrix.h b/include/m_skin_matrix.h index 7ff77ec4..f8caaf74 100644 --- a/include/m_skin_matrix.h +++ b/include/m_skin_matrix.h @@ -1,7 +1,7 @@ #ifndef SKIN_MATRIX_H #define SKIN_MATRIX_H -#include "libultra/u64types.h" +#include "libultra/ultratypes.h" #ifdef __cplusplus extern "C"{ diff --git a/include/m_string.h b/include/m_string.h new file mode 100644 index 00000000..26b3ae2a --- /dev/null +++ b/include/m_string.h @@ -0,0 +1,16 @@ +#ifndef M_STRING_H +#define M_STRING_H + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void mString_Load_StringFromRom(u8* buf, size_t buf_size, u32 str_no); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/sys_dynamic.h b/include/sys_dynamic.h index 8b657d98..fb9aec19 100644 --- a/include/sys_dynamic.h +++ b/include/sys_dynamic.h @@ -11,6 +11,7 @@ extern "C" { #define SYSDYNAMIC_START_MAGIC 0x1234 #define SYSDYNAMIC_END_MAGIC 0x5678 +/* #define SHADOW_SIZE 512 #define LIGHT_SIZE 256 #define LINE_XLU_SIZE 9952 @@ -21,22 +22,34 @@ extern "C" { #define POLY_OPA_SIZE 1792 #define POLY_XLU_SIZE 512 #define FONT_SIZE 256 +*/ + +#define POLY_OPA_SIZE 9952 +#define POLY_XLU_SIZE 2048 +#define OVERLAY_SIZE 1024 +#define WORK_SIZE 128 +#define UNK_BUF0_SIZE 32 +#define FONT_SIZE 1792 +#define SHADOW_SIZE 512 +#define LIGHT_SIZE 256 +#define NEW0_SIZE 512 +#define NEW1_SIZE 256 typedef struct dynamic_s { u16 start_magic; - Gfx line_xlu[LINE_XLU_SIZE]; + Gfx poly_opa[POLY_OPA_SIZE]; + Gfx poly_xlu[POLY_XLU_SIZE]; Gfx overlay[OVERLAY_SIZE]; - Gfx line_opa[LINE_OPA_SIZE]; Gfx work[WORK_SIZE]; Gfx unused[UNK_BUF0_SIZE]; - Gfx poly_opa[POLY_OPA_SIZE]; - Gfx poly_xlu[POLY_XLU_SIZE]; Gfx font[FONT_SIZE]; Gfx shadow[SHADOW_SIZE]; Gfx light[LIGHT_SIZE]; + Gfx new0[NEW0_SIZE]; + Gfx new1[NEW1_SIZE]; + u16 end_magic; - } dynamic_t; extern dynamic_t sys_dynamic; diff --git a/include/sys_matrix.h b/include/sys_matrix.h new file mode 100644 index 00000000..bd878d86 --- /dev/null +++ b/include/sys_matrix.h @@ -0,0 +1,24 @@ +#ifndef SYS_MATRIX_H +#define SYS_MATRIX_H + +#include "types.h" +#include "libultra/ultratypes.h" +#include "PR/mbi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern MtxF MtxF_clear; +extern Mtx Mtx_clear; + +extern void Matrix_push(); +extern void Matrix_pull(); +extern void Matrix_get(MtxF* m); +extern void Matrix_put(MtxF* m); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rel/graph.c b/rel/graph.c index db353837..c71d6c81 100644 --- a/rel/graph.c +++ b/rel/graph.c @@ -40,25 +40,25 @@ static void graph_setup_double_buffer(GRAPH* this) { sys_dynamic.start_magic = SYSDYNAMIC_START_MAGIC; sys_dynamic.end_magic = SYSDYNAMIC_END_MAGIC; - CONSTRUCT_THA_GA(&this->shadow_thaga, shadow, SHADOW); - CONSTRUCT_THA_GA(&this->light_thaga, light, LIGHT); - CONSTRUCT_THA_GA(&this->line_translucent_thaga, line_xlu, LINE_XLU); - CONSTRUCT_THA_GA(&this->overlay_thaga, overlay, OVERLAY); - CONSTRUCT_THA_GA(&this->line_opaque_thaga, line_opa, LINE_OPA); - CONSTRUCT_THA_GA(&this->work_thaga, work, WORK); + CONSTRUCT_THA_GA(&this->new0_thaga, new0, NEW0); + CONSTRUCT_THA_GA(&this->new1_thaga, new1, NEW1); CONSTRUCT_THA_GA(&this->polygon_opaque_thaga, poly_opa, POLY_OPA); CONSTRUCT_THA_GA(&this->polygon_translucent_thaga, poly_xlu, POLY_XLU); + CONSTRUCT_THA_GA(&this->overlay_thaga, overlay, OVERLAY); + CONSTRUCT_THA_GA(&this->work_thaga, work, WORK); CONSTRUCT_THA_GA(&this->font_thaga, font, FONT); + CONSTRUCT_THA_GA(&this->shadow_thaga, shadow, SHADOW); + CONSTRUCT_THA_GA(&this->light_thaga, light, LIGHT); - this->Gfx_list10 = sys_dynamic.shadow; - this->Gfx_list11 = sys_dynamic.light; - this->Gfx_list00 = sys_dynamic.line_xlu; - this->Gfx_list01 = sys_dynamic.overlay; - this->Gfx_list04 = sys_dynamic.line_opa; + this->Gfx_list10 = sys_dynamic.new0; + this->Gfx_list11 = sys_dynamic.new1; + this->Gfx_list00 = sys_dynamic.poly_opa; + this->Gfx_list01 = sys_dynamic.poly_xlu; + this->Gfx_list04 = sys_dynamic.overlay; this->Gfx_list05 = sys_dynamic.work; - this->Gfx_list07 = sys_dynamic.poly_opa; - this->Gfx_list08 = sys_dynamic.poly_xlu; - this->Gfx_list09 = sys_dynamic.font; + this->Gfx_list07 = sys_dynamic.font; + this->Gfx_list08 = sys_dynamic.shadow; + this->Gfx_list09 = sys_dynamic.light; this->gfxsave = NULL; } @@ -139,16 +139,16 @@ static int graph_draw_finish(GRAPH* this) { OPEN_DISP(this); gSPBranchList(NOW_WORK_DISP++, this->Gfx_list10); - gSPBranchList(NOW_SHADOW_DISP++, this->Gfx_list08); - gSPBranchList(NOW_POLY_XLU_DISP++, this->Gfx_list11); - gSPBranchList(NOW_LIGHT_DISP++, this->Gfx_list00); - gSPBranchList(NOW_LINE_XLU_DISP++, this->Gfx_list01); - gSPBranchList(NOW_OVERLAY_DISP++, this->Gfx_list09); - gSPBranchList(NOW_FONT_DISP++, this->Gfx_list07); - gSPBranchList(NOW_POLY_OPA_DISP++, this->Gfx_list04); - gDPPipeSync(NOW_LINE_OPA_DISP++); - gDPFullSync(NOW_LINE_OPA_DISP++); - gSPEndDisplayList(NOW_LINE_OPA_DISP++); + gSPBranchList(NOW_NEW0_DISP++, this->Gfx_list08); + gSPBranchList(NOW_SHADOW_DISP++, this->Gfx_list11); + gSPBranchList(NOW_NEW1_DISP++, this->Gfx_list00); + gSPBranchList(NOW_POLY_OPA_DISP++, this->Gfx_list01); + gSPBranchList(NOW_POLY_XLU_DISP++, this->Gfx_list09); + gSPBranchList(NOW_LIGHT_DISP++, this->Gfx_list07); + gSPBranchList(NOW_FONT_DISP++, this->Gfx_list04); + gDPPipeSync(NOW_OVERLAY_DISP++); + gDPFullSync(NOW_OVERLAY_DISP++); + gSPEndDisplayList(NOW_OVERLAY_DISP++); CLOSE_DISP(this); err = FALSE; @@ -164,35 +164,35 @@ static int graph_draw_finish(GRAPH* this) { } SYSDYNAMIC_CLOSE(); - if (THA_GA_isCrash(&this->line_translucent_thaga)) { + if (THA_GA_isCrash(&this->polygon_opaque_thaga)) { err = TRUE; } - if (THA_GA_isCrash(&this->overlay_thaga)) { + if (THA_GA_isCrash(&this->polygon_translucent_thaga)) { err = TRUE; } - if (THA_GA_isCrash(&this->line_opaque_thaga)) { + if (THA_GA_isCrash(&this->overlay_thaga)) { err = TRUE; } - if (THA_GA_isCrash(&this->polygon_opaque_thaga)) { + if (THA_GA_isCrash(&this->font_thaga)) { err = TRUE; } - if (THA_GA_isCrash(&this->polygon_translucent_thaga)) { + if (THA_GA_isCrash(&this->shadow_thaga)) { err = TRUE; } - if (THA_GA_isCrash(&this->font_thaga)) { + if (THA_GA_isCrash(&this->light_thaga)) { err = TRUE; } - if (THA_GA_isCrash(&this->shadow_thaga)) { + if (THA_GA_isCrash(&this->new0_thaga)) { err = TRUE; } - if (THA_GA_isCrash(&this->light_thaga)) { + if (THA_GA_isCrash(&this->new1_thaga)) { err = TRUE; } diff --git a/rel/m_font.c b/rel/m_font.c new file mode 100644 index 00000000..0ba7b71e --- /dev/null +++ b/rel/m_font.c @@ -0,0 +1,1434 @@ +#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); +} diff --git a/rel/m_land.c b/rel/m_land.c new file mode 100644 index 00000000..d30c458f --- /dev/null +++ b/rel/m_land.c @@ -0,0 +1,269 @@ +/** + * @file m_land.c + * @brief Functions and definitions for handling town name, town ID, and + * determining if a player is a foreigner or not. + * + * This file contains functions for manipulating town names and IDs, checking + * if a player is a foreigner, and initializing land and home data. + * + * Note: "Mura" (むら/村) is the Japanese word for village. Functions which contain that + * word were used to concatenate the town name with it. Since this does not happen + * in inernational releases, these functions essentially do nothing. + * + * Functions: + * - mLd_StartFlagOn(): Turns on the start flag. + * - mLd_CheckStartFlag(): Checks the start flag. + * - mLd_NullCheckLandName(): Checks if a given town name is empty or filled with spaces. + * - mLd_CheckId(): Checks if a given land ID has the correct bitmask. + * - mLd_CheckCmpLandName(): Compares two town names for equality. + * - mLd_CheckCmpLand(): Compares two town names and their IDs for equality. + * - mLd_ClearLandName(): Clears the town name by filling it with spaces. + * - mLd_CopyLandName(): Copies a source town name to a destination. + * - mLd_AddMuraString(): Adds the "Mura" (むら/村) string to the town name. + * - mLd_GetLandNameStringAddMura(): Gets the town name with "Mura" (むら/村) added. + * - mLd_SetFreeStrLandMuraName(): Sets the town name with "Mura" (むら/村) added as a free string. + * - mLd_GetLandName(): Retrieves the town name from the save data. + * - mLd_MakeLandId(): Generates a new land ID with the correct bitmask. + * - mLd_PlayerManKindCheckNo(): Checks if a player is a foreigner based on their player number. + * - mLd_PlayerManKindCheck(): Checks if the current player is a foreigner. + * - mLd_CheckThisLand(): Checks if a given town name and ID match the current town. + * - mLd_LandInfoInit(): Initializes the land information in the save data. + * - mLd_LandDataInit(): Initializes the land data and clears all home information. + */ + +#include "m_land.h" + +#include "libc64/qrand.h" +#include "m_common_data.h" +#include "m_font.h" +#include "m_home.h" +#include "m_lib.h" +#include "m_msg.h" +#include "m_private.h" +#include "m_string.h" +#include "types.h" + +static int l_mld_start_flag; + +/** + * @brief Turns on the start flag. + */ +extern void mLd_StartFlagOn() { + l_mld_start_flag = TRUE; +} + +/** + * @brief Checks the start flag. + * @return The value of l_mld_start_flag. + */ +extern int mLd_CheckStartFlag() { + return l_mld_start_flag; +} + +/** + * @brief Checks if the given town name is empty or filled with spaces. + * @param land_name Pointer to the town name. + * @return TRUE if the town name is empty, FALSE otherwise. + */ +extern int mLd_NullCheckLandName(const u8* land_name) { + int null_name = FALSE; + int i; + + for (i = 0; i < LAND_NAME_SIZE; i++) { + if (*land_name != CHAR_SPACE) { + break; + } + land_name++; + } + + if (i == LAND_NAME_SIZE) { + null_name = TRUE; + } + return null_name; +} + +/** + * @brief Checks if the given land ID has the correct bitmask. + * @param land_id Land ID to be checked. + * @return TRUE if the land ID has the correct bitmask, FALSE otherwise. + */ +extern int mLd_CheckId(u16 land_id) { + int res = FALSE; + if (mLd_CHECK_ID(land_id)) { + res = TRUE; + } + + return res; +} + +/** + * @brief Compares two town names for equality. + * @param name_a First town name. + * @param name_b Second town name. + * @return TRUE if both town names are equal, FALSE otherwise. + */ +extern int mLd_CheckCmpLandName(u8* name_a, u8* name_b) { + int equal = FALSE; + + if (mLd_NullCheckLandName(name_a) == FALSE && mLd_NullCheckLandName(name_b) == FALSE) { + equal = mem_cmp(name_a, name_b, LAND_NAME_SIZE); + } + + return equal; +} + +/** + * @brief Compares two town names and their IDs for equality. + * @param name_a First town name. + * @param id_a First town ID. + * @param name_b Second town name. + * @param id_b Second town ID. + * @return TRUE if both town names and IDs are equal, FALSE otherwise. + */ +extern int mLd_CheckCmpLand(u8* name_a, u16 id_a, u8* name_b, u16 id_b) { + int equal = FALSE; + + if (id_a == id_b && mLd_CheckCmpLandName(name_a, name_b) == TRUE) { + equal = TRUE; + } + + return equal; +} + +/** + * @brief Clears the town name by filling it with spaces. + * @param name Pointer to the town name. + */ +extern void mLd_ClearLandName(u8* name) { + mem_clear(name, LAND_NAME_SIZE, CHAR_SPACE); +} + +/** + * @brief Copies the source town name to the destination. + * @param dst Pointer to the destination town name. + * @param src Pointer to the source town name. + */ +extern void mLd_CopyLandName(u8* dst, u8* src) { + mem_copy(dst, src, LAND_NAME_SIZE); +} + +/** + * @brief Adds the "Mura" (むら/村) string to the town name. + * @param name Pointer to the town name. + * @param name_len Length of the town name. + * @return The length of the new town name with "Mura" (むら/村) added. + */ +extern int mLd_AddMuraString(u8* name, int name_len) { + u8 buf[16]; + int size; + + mString_Load_StringFromRom(buf, 16, 484); /* TODO: str_no should probably be enum or something */ + size = mMsg_Get_Length_String(buf, 16); + mem_copy(name + name_len, buf, size); + + return size + name_len; +} + +/** + * @brief Gets the town name with "Mura" (むら/村) added. + * @param buf Buffer to store the town name with "Mura" (むら/村) added. + */ +extern void mLd_GetLandNameStringAddMura(u8* buf) { + int mura_size; + + u8* name = mLd_GetLandName(); + int size = mMsg_Get_Length_String(name, LAND_NAME_SIZE); + mem_copy(buf, name, size); + mura_size = mLd_AddMuraString(buf, size); + + for (mura_size; mura_size < LAND_NAME_MURA_SIZE; mura_size++) { + buf[mura_size] = CHAR_SPACE; + } +} + +/** + * @brief Sets the town name with "Mura" (むら/村) added as a free string. + * @param name Pointer to the town name. + * @param free_str_no The number of the free string. + */ +extern void mLd_SetFreeStrLandMuraName(u8* name, int free_str_no) { + u8 str[16]; + int name_len; + int mura_len; + int i; + + for (i = 0; i < LAND_NAME_MURA_SIZE; i++) { + str[i] = CHAR_SPACE; + } + + name_len = mMsg_Get_Length_String(name, LAND_NAME_SIZE); + mem_copy(str, name, name_len); + mura_len = mLd_AddMuraString(str, name_len); + mMsg_Set_free_str(mMsg_Get_base_window_p(), free_str_no, str, mura_len); +} + +/** + * @brief Retrieves the town name from the save data. + * @return Pointer to the town name. + */ +extern u8* mLd_GetLandName() { + return Save_Get(land_info.name); +} + +/** + * @brief Generates a new land ID with the correct bitmask. + * @return The newly generated land ID. + */ +extern u16 mLd_MakeLandId() { + return (int)(fqrand() * 256.0f) | mLd_BITMASK; +} + +/** + * @brief Checks if a player is a foreigner based on their player number. + * @param player_no The player number. + * @return FOREIGN if the player is a foreigner, NATIVE otherwise. + */ +extern int mLd_PlayerManKindCheckNo(u8 player_no) { + int foreigner = TRUE; + if (player_no < PLAYER_NUM) { + foreigner = FALSE; + } + + return foreigner; +} + +/** + * @brief Checks if the current player is a foreigner. + * @return FOREIGN if the current player is a foreigner, NATIVE otherwise. + */ +extern int mLd_PlayerManKindCheck() { + return mLd_PlayerManKindCheckNo(Common_Get(player_no)); +} + +/* + * @brief Checks if the given town name and ID match the current town. + * @param other_name Pointer to the town name to be checked. + * @param other_id Town ID to be checked. + * @return TRUE if the town name and ID match the current town, FALSE otherwise. + */ +extern int mLd_CheckThisLand(u8* other_name, u16 other_id) { + return mLd_CheckCmpLand(other_name, other_id, Save_Get(land_info.name), Save_Get(land_info.id)); +} + +/** + * @brief Initializes the land information in the save data. + */ +extern void mLd_LandInfoInit() { + mLd_land_info_c* land_info = Save_GetPointer(land_info); + + land_info->id = mLd_MakeLandId(); + land_info->exists = TRUE; +} + +/** + * @brief Initializes the land data and clears all home information. + */ +extern void mLd_LandDataInit() { + mLd_LandInfoInit(); + mHm_ClearAllHomeInfo(); +} diff --git a/rel/m_time.c b/rel/m_time.c index e7999093..39a30389 100644 --- a/rel/m_time.c +++ b/rel/m_time.c @@ -308,7 +308,7 @@ static void mTM_disp_time(int unused) { if (Common_Get(time.disp) == TRUE) { gfxprint_t gfxprint; GRAPH* g; - Gfx* line_xlu; + Gfx* poly_opaque; Gfx* line_opa; Gfx* gfx_temp; @@ -317,10 +317,10 @@ static void mTM_disp_time(int unused) { OPEN_DISP(g); - line_xlu = NOW_LINE_XLU_DISP; - gfx_temp = gfxopen(line_xlu); + poly_opaque = NOW_POLY_OPA_DISP; + gfx_temp = gfxopen(poly_opaque); - gSPDisplayList(NOW_LINE_OPA_DISP++, gfx_temp); + gSPDisplayList(NOW_OVERLAY_DISP++, gfx_temp); /* Debug mode draw time in format: YYYY MM/DD hh:mm ss */ gfxprint_open(&gfxprint, gfx_temp); @@ -340,8 +340,8 @@ static void mTM_disp_time(int unused) { gfx_temp = gfxprint_close(&gfxprint); gSPEndDisplayList(gfx_temp++); - gfxclose(line_xlu, gfx_temp); - NOW_LINE_XLU_DISP = gfx_temp; + gfxclose(poly_opaque, gfx_temp); + SET_POLY_OPA_DISP(gfx_temp); gfxprint_cleanup(&gfxprint); CLOSE_DISP(g);