diff --git a/bin/segment2.c b/bin/segment2.c index 1211249c..7265be0e 100644 --- a/bin/segment2.c +++ b/bin/segment2.c @@ -3853,6 +3853,9 @@ ALIGNED8 static const u8 texture_font_normal_char_punc_sp_qu[] = { #include "textures/segment2/custom_font_normal_char_punc_sp_qu.ia4.inc.c" }; +ALIGNED8 const u8 texture_font_normal[] = { +#include "textures/custom_font_title/custom_font_normal.rgba32.inc.c" +}; const u8* const font_normal_chars[] = { texture_font_char_us_exclamation, // ! diff --git a/src/pc/djui/djui_font.c b/src/pc/djui/djui_font.c index 01bb024f..bd1177ba 100644 --- a/src/pc/djui/djui_font.c +++ b/src/pc/djui/djui_font.c @@ -27,9 +27,9 @@ const Gfx dl_font_normal_display_list_begin[] = { const Gfx dl_font_normal_display_list[] = { gsDPLoadBlock(G_TX_LOADTILE, 0, 0, ((16 * 8 + G_IM_SIZ_4b_INCR) >> G_IM_SIZ_4b_SHIFT) - 1, CALC_DXT(16, G_IM_SIZ_4b_BYTES)), - gsSPVertex(djui_font_normal_vertices, 4, 0), + gsSPVertexDjui(djui_font_normal_vertices, 4, 0), gsSPExecuteDjui(G_TEXCLIP_DJUI), - gsSP2Triangles(0, 1, 2, 0x0, 0, 2, 3, 0x0), + gsSP2TrianglesDjui(0, 1, 2, 0x0, 0, 2, 3, 0x0), gsSPEndDisplayList(), }; @@ -39,11 +39,19 @@ static void djui_font_normal_render_char(char* c) { u32 index = djui_unicode_get_sprite_index(c); - extern const u8* const font_normal_chars[]; - void* fontChar = (void*)font_normal_chars[index]; + //extern const u8* const font_normal_chars[]; + //void* fontChar = (void*)font_normal_chars[index]; + extern ALIGNED8 const u8 texture_font_normal[]; + void* fontChar = texture_font_normal; - gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, (void*)fontChar); - gSPDisplayList(gDisplayListHead++, dl_font_normal_display_list); + //djui_gfx_render_texture(texture_font_normal, 256, 128, 32); + //djui_gfx_render_texture_tile(texture_font_normal, 8, 16, 32, 0, 0, 256, 128); + u32 tx = index % 32; + u32 ty = index / 32; + djui_gfx_render_texture_tile(texture_font_normal, 256, 128, 32, tx * 8, ty * 16, 8, 16); + + //gDPSetTextureImage(gDisplayListHead++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, (void*)fontChar); + //gSPDisplayList(gDisplayListHead++, dl_font_normal_display_list); } static f32 djui_font_normal_char_width(char* c) { @@ -57,8 +65,8 @@ static const struct DjuiFont sDjuiFontNormal = { .charHeight = 1.0f, .lineHeight = 0.8125f, .defaultFontScale = 32.0f, - .rotatedUV = true, - .textBeginDisplayList = dl_font_normal_display_list_begin, + .rotatedUV = false, + .textBeginDisplayList = NULL, //dl_font_normal_display_list_begin, .render_char = djui_font_normal_render_char, .char_width = djui_font_normal_char_width, }; diff --git a/src/pc/djui/djui_gbi.h b/src/pc/djui/djui_gbi.h index d718f929..e16adf83 100644 --- a/src/pc/djui/djui_gbi.h +++ b/src/pc/djui/djui_gbi.h @@ -2,6 +2,8 @@ #define G_TEXCLIP_DJUI 0xe1 #define G_TEXOVERRIDE_DJUI 0xe0 +#define G_DJUI_SIMPLE_VERT 0x11 +#define G_DJUI_SIMPLE_TRI2 0x12 #define G_EXECUTE_DJUI 0xdd #define gSetClippingDjui(pkt, cmd, rot, x1, y1, x2, y2) \ @@ -20,10 +22,64 @@ _g->words.w1 = (uintptr_t)(texture); \ } +# define gSPVertexDjui(pkt, v, n, v0) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + _g->words.w0 = \ + _SHIFTL(G_DJUI_SIMPLE_VERT,24,8)|_SHIFTL((n),12,8)|_SHIFTL((v0)+(n),1,7); \ + _g->words.w1 = (uintptr_t)(v); \ +} + +#define gSP2TrianglesDjui(pkt, v00, v01, v02, flag0, v10, v11, v12, flag1) \ +{ \ + Gfx *_g = (Gfx *)(pkt); \ + \ + _g->words.w0 = (_SHIFTL(G_DJUI_SIMPLE_TRI2, 24, 8)| \ + __gsSP1Triangle_w1f(v00, v01, v02, flag0)); \ + _g->words.w1 = __gsSP1Triangle_w1f(v10, v11, v12, flag1); \ +} + #define gsSPExecuteDjui(word) \ {{ \ _SHIFTL(G_EXECUTE_DJUI, 24, 8), (unsigned int)(word) \ }} +#define gDPLoadTextureBlockWithoutTexture(pkt, timg, fmt, siz, width, height, \ + pal, cms, cmt, masks, maskt, shifts, shiftt) \ +{ \ + gDPSetTile(pkt, fmt, siz##_LOAD_BLOCK, 0, 0, G_TX_LOADTILE, \ + 0 , cmt, maskt, shiftt, cms, masks, shifts); \ + gDPLoadSync(pkt); \ + gDPLoadBlock(pkt, G_TX_LOADTILE, 0, 0, \ + (((width)*(height) + siz##_INCR) >> siz##_SHIFT) -1, \ + CALC_DXT(width, siz##_BYTES)); \ + gDPPipeSync(pkt); \ + gDPSetTile(pkt, fmt, siz, \ + (((width) * siz##_LINE_BYTES)+7)>>3, 0, \ + G_TX_RENDERTILE, pal, cmt, maskt, shiftt, cms, masks, \ + shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, \ + ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC) \ +} + #define gDPSetTextureClippingDjui(pkt, rot, x1, y1, x2, y2) gSetClippingDjui(pkt, G_TEXCLIP_DJUI, rot, x1, y1, x2, y2) #define gDPSetTextureOverrideDjui(pkt, texture, w, h, bitSize) gSetOverrideDjui(pkt, G_TEXOVERRIDE_DJUI, texture, w, h, bitSize) + + +// DO NOT COMMIT // + +# define gsSPVertexDjui(v, n, v0) \ +{{ \ + (_SHIFTL(G_DJUI_SIMPLE_VERT,24,8)|_SHIFTL((n),12,8)|_SHIFTL((v0)+(n),1,7)), \ + (uintptr_t)(v) \ +}} + +#define gsSP2TrianglesDjui(v00, v01, v02, flag0, v10, v11, v12, flag1) \ +{{ \ + (_SHIFTL(G_DJUI_SIMPLE_TRI2, 24, 8)| \ + __gsSP1Triangle_w1f(v00, v01, v02, flag0)), \ + __gsSP1Triangle_w1f(v10, v11, v12, flag1) \ +}} + +// DO NOT COMMIT // diff --git a/src/pc/djui/djui_gfx.c b/src/pc/djui/djui_gfx.c index 49f68b85..85b9bb55 100644 --- a/src/pc/djui/djui_gfx.c +++ b/src/pc/djui/djui_gfx.c @@ -84,21 +84,25 @@ void djui_gfx_render_texture(const u8* texture, u32 w, u32 h, u32 bitSize) { void djui_gfx_render_texture_tile(const u8* texture, u32 w, u32 h, u32 bitSize, u32 tileX, u32 tileY, u32 tileW, u32 tileH) { Vtx *vtx = alloc_display_list(sizeof(Vtx) * 4); - vtx[0] = (Vtx) {{{ 0, -1, 0 }, 0, { ( tileX * 512) / w, ((tileY + tileH) * 512) / h }, { 0xff, 0xff, 0xff, 0xff }}}; - vtx[1] = (Vtx) {{{ 1, -1, 0 }, 0, { ((tileX + tileW) * 512) / w, ((tileY + tileH) * 512) / h }, { 0xff, 0xff, 0xff, 0xff }}}; - vtx[2] = (Vtx) {{{ 1, 0, 0 }, 0, { ((tileX + tileW) * 512) / w, ( tileY * 512) / h }, { 0xff, 0xff, 0xff, 0xff }}}; - vtx[3] = (Vtx) {{{ 0, 0, 0 }, 0, { ( tileX * 512) / w, ( tileY * 512) / h }, { 0xff, 0xff, 0xff, 0xff }}}; - gDPSetTextureOverrideDjui(gDisplayListHead++, texture, djui_gfx_power_of_two(w), djui_gfx_power_of_two(h), bitSize); + f32 aspect = w ? ((f32)h / (f32)w) : 1; + vtx[0] = (Vtx) {{{ 0, -1, 0 }, 0, { ( tileX * 512) / w, ((tileY + tileH) * 512) / h }, { 0xff, 0xff, 0xff, 0xff }}}; + vtx[1] = (Vtx) {{{ 1 * aspect, -1, 0 }, 0, { ((tileX + tileW) * 512) / w, ((tileY + tileH) * 512) / h }, { 0xff, 0xff, 0xff, 0xff }}}; + vtx[2] = (Vtx) {{{ 1 * aspect, 0, 0 }, 0, { ((tileX + tileW) * 512) / w, ( tileY * 512) / h }, { 0xff, 0xff, 0xff, 0xff }}}; + vtx[3] = (Vtx) {{{ 0, 0, 0 }, 0, { ( tileX * 512) / w, ( tileY * 512) / h }, { 0xff, 0xff, 0xff, 0xff }}}; + gSPClearGeometryMode(gDisplayListHead++, G_LIGHTING); gDPSetCombineMode(gDisplayListHead++, G_CC_FADEA, G_CC_FADEA); gDPSetRenderMode(gDisplayListHead++, G_RM_XLU_SURF, G_RM_XLU_SURF2); gDPSetTextureFilter(gDisplayListHead++, G_TF_POINT); gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); - gDPLoadTextureBlock(gDisplayListHead++, NULL, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 16, 0, G_TX_CLAMP, G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD); + + gDPSetTextureOverrideDjui(gDisplayListHead++, texture, djui_gfx_power_of_two(w), djui_gfx_power_of_two(h), bitSize); + gDPLoadTextureBlockWithoutTexture(gDisplayListHead++, NULL, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 16, 0, G_TX_CLAMP, G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD); + *(gDisplayListHead++) = (Gfx) gsSPExecuteDjui(G_TEXOVERRIDE_DJUI); - gSPVertex(gDisplayListHead++, vtx, 4, 0); + gSPVertexDjui(gDisplayListHead++, vtx, 4, 0); *(gDisplayListHead++) = (Gfx) gsSPExecuteDjui(G_TEXCLIP_DJUI); - gSP2Triangles(gDisplayListHead++, 0, 1, 2, 0x0, 0, 2, 3, 0x0); + gSP2TrianglesDjui(gDisplayListHead++, 0, 1, 2, 0x0, 0, 2, 3, 0x0); gSPTexture(gDisplayListHead++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_OFF); gDPSetCombineMode(gDisplayListHead++, G_CC_SHADE, G_CC_SHADE); } diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index f249077a..4651cc68 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -900,9 +900,7 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t struct LoadedVertex *v2 = &rsp.loaded_vertices[vtx2_idx]; struct LoadedVertex *v3 = &rsp.loaded_vertices[vtx3_idx]; struct LoadedVertex *v_arr[3] = {v1, v2, v3}; - - //if (rand()%2) return; - + if (v1->clip_rej & v2->clip_rej & v3->clip_rej) { // The whole triangle lies outside the visible area return; @@ -1293,9 +1291,9 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t } uint32_t size_bytes = (lrs + 1) << word_size_shift; rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes; + rdp.textures_changed[rdp.texture_to_load.tile_number] = rdp.loaded_texture[rdp.texture_to_load.tile_number].addr != rdp.texture_to_load.addr; rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr; - rdp.textures_changed[rdp.texture_to_load.tile_number] = true; } static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, uint32_t lrt) { @@ -1997,8 +1995,9 @@ static void OPTIMIZE_O3 djui_gfx_dp_execute_override(void) { uint32_t lrs = (sDjuiOverrideW * sDjuiOverrideH) - 1; uint32_t sizeBytes = (lrs + 1) << wordSizeShift; rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = sizeBytes; + rdp.textures_changed[rdp.texture_to_load.tile_number] = rdp.loaded_texture[rdp.texture_to_load.tile_number].addr != rdp.texture_to_load.addr; rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr; - rdp.textures_changed[rdp.texture_to_load.tile_number] = true; + //rdp.textures_changed[rdp.texture_to_load.tile_number] = true; // gsDPSetTile uint32_t line = (((sDjuiOverrideW * 2) + 7) >> 3); @@ -2009,8 +2008,6 @@ static void OPTIMIZE_O3 djui_gfx_dp_execute_override(void) { rdp.texture_tile.ult = 0; rdp.texture_tile.lrs = (sDjuiOverrideW - 1) << G_TEXTURE_IMAGE_FRAC; rdp.texture_tile.lrt = (sDjuiOverrideH - 1) << G_TEXTURE_IMAGE_FRAC;*/ - rdp.textures_changed[0] = true; - rdp.textures_changed[1] = true; } static void OPTIMIZE_O3 djui_gfx_dp_execute_djui(uint32_t opcode) { @@ -2037,6 +2034,99 @@ static void OPTIMIZE_O3 djui_gfx_dp_set_override(void* texture, uint32_t w, uint sDjuiOverride = (texture != NULL); } +static void OPTIMIZE_O3 djui_gfx_sp_simple_vertex(size_t n_vertices, size_t dest_index, const Vtx *vertices) { + for (size_t i = 0; i < n_vertices; i++, dest_index++) { + const Vtx_t *v = &vertices[i].v; + struct LoadedVertex *d = &rsp.loaded_vertices[dest_index]; + + float x = v->ob[0] * rsp.MP_matrix[0][0] + v->ob[1] * rsp.MP_matrix[1][0] + v->ob[2] * rsp.MP_matrix[2][0] + rsp.MP_matrix[3][0]; + float y = v->ob[0] * rsp.MP_matrix[0][1] + v->ob[1] * rsp.MP_matrix[1][1] + v->ob[2] * rsp.MP_matrix[2][1] + rsp.MP_matrix[3][1]; + float z = v->ob[0] * rsp.MP_matrix[0][2] + v->ob[1] * rsp.MP_matrix[1][2] + v->ob[2] * rsp.MP_matrix[2][2] + rsp.MP_matrix[3][2]; + float w = v->ob[0] * rsp.MP_matrix[0][3] + v->ob[1] * rsp.MP_matrix[1][3] + v->ob[2] * rsp.MP_matrix[2][3] + rsp.MP_matrix[3][3]; + + x = gfx_adjust_x_for_aspect_ratio(x); + + short U = v->tc[0] * rsp.texture_scaling_factor.s >> 16; + short V = v->tc[1] * rsp.texture_scaling_factor.t >> 16; + + d->color.r = v->cn[0]; + d->color.g = v->cn[1]; + d->color.b = v->cn[2]; + + d->u = U; + d->v = V; + + d->x = x; + d->y = y; + d->z = z; + d->w = w; + + d->color.a = v->cn[3]; + } +} + +static void OPTIMIZE_O3 djui_gfx_sp_simple_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) { + struct LoadedVertex *v1 = &rsp.loaded_vertices[vtx1_idx]; + struct LoadedVertex *v2 = &rsp.loaded_vertices[vtx2_idx]; + struct LoadedVertex *v3 = &rsp.loaded_vertices[vtx3_idx]; + struct LoadedVertex *v_arr[3] = {v1, v2, v3}; + + uint32_t cc_id = rdp.combine_mode; + + bool use_alpha = true; + cc_id |= SHADER_OPT_ALPHA; + + if (!use_alpha) { + cc_id &= ~0xfff000; + } + + struct ColorCombiner *comb = gfx_lookup_or_create_color_combiner(cc_id); + struct ShaderProgram *prg = comb->prg; + if (prg != rendering_state.shader_program) { + gfx_flush(); + gfx_rapi->unload_shader(rendering_state.shader_program); + gfx_rapi->load_shader(prg); + rendering_state.shader_program = prg; + } + + if (rdp.textures_changed[0]) { + gfx_flush(); + import_texture(0); + rdp.textures_changed[0] = false; + } + + uint32_t tex_width = (rdp.texture_tile.lrs - rdp.texture_tile.uls + 4) / 4; + uint32_t tex_height = (rdp.texture_tile.lrt - rdp.texture_tile.ult + 4) / 4; + + bool z_is_from_0_to_1 = gfx_rapi->z_is_from_0_to_1(); + + for (int32_t i = 0; i < 3; i++) { + float z = v_arr[i]->z, w = v_arr[i]->w; + if (z_is_from_0_to_1) { + z = (z + w) / 2.0f; + } + buf_vbo[buf_vbo_len++] = v_arr[i]->x; + buf_vbo[buf_vbo_len++] = v_arr[i]->y; + buf_vbo[buf_vbo_len++] = z; + buf_vbo[buf_vbo_len++] = w; + + float u = (v_arr[i]->u - rdp.texture_tile.uls * 8) / 32.0f; + float v = (v_arr[i]->v - rdp.texture_tile.ult * 8) / 32.0f; + buf_vbo[buf_vbo_len++] = u / tex_width; + buf_vbo[buf_vbo_len++] = v / tex_height; + + struct RGBA *color; + color = &rdp.env_color; + buf_vbo[buf_vbo_len++] = color->r / 255.0f; + buf_vbo[buf_vbo_len++] = color->g / 255.0f; + buf_vbo[buf_vbo_len++] = color->b / 255.0f; + buf_vbo[buf_vbo_len++] = color->a / 255.0f; + } + if (++buf_vbo_num_tris == MAX_BUFFERED) { + gfx_flush(); + } +} + void OPTIMIZE_O3 djui_gfx_run_dl(Gfx* cmd) { uint32_t opcode = cmd->words.w0 >> 24; switch (opcode) { @@ -2046,6 +2136,13 @@ void OPTIMIZE_O3 djui_gfx_run_dl(Gfx* cmd) { case G_TEXOVERRIDE_DJUI: djui_gfx_dp_set_override(seg_addr(cmd->words.w1), 1 << C0(16, 8), 1 << C0(8, 8), C0(0, 8)); break; + case G_DJUI_SIMPLE_VERT: + djui_gfx_sp_simple_vertex(C0(12, 8), C0(1, 7) - C0(12, 8), seg_addr(cmd->words.w1)); + break; + case G_DJUI_SIMPLE_TRI2: + djui_gfx_sp_simple_tri1(C0(16, 8) / 2, C0(8, 8) / 2, C0(0, 8) / 2); + djui_gfx_sp_simple_tri1(C1(16, 8) / 2, C1(8, 8) / 2, C1(0, 8) / 2); + break; case G_EXECUTE_DJUI: djui_gfx_dp_execute_djui(cmd->words.w1); break; diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index a1ce19f8..7f0a14a0 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -202,7 +202,7 @@ void produce_interpolation_frames_and_delay(void) { sFrameTargetTime += sFrameTime * gGameSpeed; gRenderingInterpolated = false; - //printf(">>> fpt: %llu, fps: %f :: %f\n", frames, sAvgFps, fps); + printf(">>> fpt: %llu, fps: %f :: %f\n", frames, sAvgFps, fps); } void produce_one_frame(void) { diff --git a/textures/custom_font_title/custom_font_normal.rgba32.png b/textures/custom_font_title/custom_font_normal.rgba32.png new file mode 100644 index 00000000..43e8a70f Binary files /dev/null and b/textures/custom_font_title/custom_font_normal.rgba32.png differ