From 5f0b67a38b603983c9280235997f3f544a32e2ab Mon Sep 17 00:00:00 2001 From: farisawan-2000 Date: Mon, 31 May 2021 01:32:58 -0400 Subject: [PATCH] much faster matrix pipeline, debug condition manager, and start of f3d_draw --- config.h | 2 + debug.h | 15 ++++++++ f3d_draw.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++ init.c | 11 ++++-- mtx.c | 32 ++++++++-------- s2d_draw.c | 103 ++++++++++++++++++++-------------------------------- s2d_draw.h | 1 + s2d_parse.c | 71 +++++++++++++++++++++++++++--------- s2d_print.h | 1 - 9 files changed, 229 insertions(+), 102 deletions(-) create mode 100644 debug.h create mode 100644 f3d_draw.c diff --git a/config.h b/config.h index 138209b3..3b3f4f24 100644 --- a/config.h +++ b/config.h @@ -13,6 +13,8 @@ * Helpful defines to change ***********/ +#define DRAW_F3D + #define BASE_SCALE 1.0f /****************************** diff --git a/debug.h b/debug.h new file mode 100644 index 00000000..c2649ab6 --- /dev/null +++ b/debug.h @@ -0,0 +1,15 @@ +#ifndef DEBUG_H +#define DEBUG_H + +// #define init_cond (CONTROLLER_HELD_INPUT & R_CBUTTONS) +// #define tex_cond (CONTROLLER_HELD_INPUT & D_CBUTTONS) +// #define mtx_cond (CONTROLLER_HELD_INPUT & L_TRIG) +// #define spr_cond (CONTROLLER_HELD_INPUT & U_JPAD) +// #define deinit_cond (CONTROLLER_HELD_INPUT & U_CBUTTONS) +#define tex_cond (1) +#define mtx_cond (1) +#define spr_cond (1) +#define init_cond (1) +#define deinit_cond (1) + +#endif diff --git a/f3d_draw.c b/f3d_draw.c new file mode 100644 index 00000000..aeae1463 --- /dev/null +++ b/f3d_draw.c @@ -0,0 +1,95 @@ +#include "config.h" +#ifdef DRAW_F3D + +#include +#include "mtx.h" +#include "debug.h" + +float myScale = 1.0f; +int myDegrees = 0; +uObjMtx final_mtx, rot_mtx; +int s2d_red = 255, s2d_green = 255, s2d_blue = 255, s2d_alpha = 255; +int drop_shadow = FALSE; +int drop_x = 0; +int drop_y = 0; + +Gfx s2d_text_init_dl[] = { + gsDPPipeSync(), + gsDPSetTexturePersp(G_TP_NONE), + gsDPSetTextureLOD(G_TL_TILE), + gsDPSetTextureLUT(G_TT_NONE), + gsDPSetTextureConvert(G_TC_FILT), + gsDPSetAlphaCompare(G_AC_THRESHOLD), + gsDPSetBlendColor(0, 0, 0, 0x01), + + // IA8 + // TODO: add more formats + gsDPSetCombineLERP( + 0, 0, 0, ENVIRONMENT, + 0, 0, 0, TEXEL0, + 0, 0, 0, ENVIRONMENT, + 0, 0, 0, TEXEL0 + ), + + gsSPEndDisplayList(), +}; + +void s2d_rdp_init(void) { + gDPPipeSync(gdl_head++); + gDPSetTextureFilter(gdl_head++, G_TF_POINT); + gDPSetCycleType(gdl_head++, G_CYC_1CYCLE); + gDPSetRenderMode(gdl_head++, G_RM_XLU_SPRITE, G_RM_XLU_SPRITE2); + if (init_cond) { + gSPDisplayList(gdl_head++, s2d_text_init_dl); + gSPObjRenderMode(gdl_head++, G_OBJRM_XLU); + } +} + +void setup_font_texture(int idx) { + gDPPipeSync(gdl_head++); + gDPSetEnvColor(gdl_head++, s2d_red, s2d_green, s2d_blue, s2d_alpha); + gSPObjLoadTxtr(gdl_head++, &s2d_tex[idx]); +} + +// Original Mtx Pipeline +// Distorts when rotating, but is faster +void mtx_pipeline(uObjMtx *m, int x, int y) { + // init + gDPPipeSync(gdl_head++); + mat2_ident(m, 1.0f / myScale); + mat2_translate(m, x, y); + + gSPObjSubMatrix(gdl_head++, &m->m.X); + gDPPipeSync(gdl_head++); +} + +#define CLAMP_0(x) ((x < 0) ? 0 : x) + +void draw_s2d_shadow(char c, int x, int y, uObjMtx *ds) { + if (mtx_cond) mtx_pipeline(ds, x, y); + if (tex_cond) setup_font_texture(c); + + if (s2d_red != 0 + && s2d_green != 0 + && s2d_blue != 0 + ) { + gDPPipeSync(gdl_head++); + gDPSetEnvColor(gdl_head++, + CLAMP_0(s2d_red - 100), + CLAMP_0(s2d_green - 100), + CLAMP_0(s2d_blue - 100), + s2d_alpha); + if (spr_cond) gSPObjRectangleR(gdl_head++, &s2d_font); + gDPSetEnvColor(gdl_head++, s2d_red, s2d_green, s2d_blue, s2d_alpha); + } +} + +void draw_s2d_glyph(char c, int x, int y, uObjMtx *mt) { + if (mtx_cond) mtx_pipeline(mt, x, y); + if (tex_cond) setup_font_texture(c); + // mtx_pipeline2(mt, x, y); + + if (spr_cond) gSPObjRectangleR(gdl_head++, &s2d_font); +} + +#endif diff --git a/init.c b/init.c index 9a702119..7633dcf0 100644 --- a/init.c +++ b/init.c @@ -2,17 +2,20 @@ #include #include "config.h" #include "init.h" +#include "debug.h" #include "s2d_error.h" void s2d_init(void) { s2d_error_y = TEX_HEIGHT; - gSPLoadUcode(gdl_head++, s2d_text, s2d_data); + // gSPLoadUcode(gdl_head++, s2d_text, s2d_data); } void s2d_stop(void) { - gSPLoadUcode(gdl_head++, zex_text, zex_data); - my_rdp_init(); - my_rsp_init(); + // gSPLoadUcode(gdl_head++, zex_text, zex_data); + // if deinit_cond { + // my_rdp_init(); + // my_rsp_init(); + // } s2d_reset_defer_index(); } diff --git a/mtx.c b/mtx.c index 2c420212..013cb217 100644 --- a/mtx.c +++ b/mtx.c @@ -2,9 +2,13 @@ #include #include +#include "config.h" + #define ftoq FTOFIX32 #define qtof FIX32TOF +#define qu510(n) ((u16)((n)*0x0400)) + void mat2_dst_mul(uObjMtx *dst, uObjMtx *m1, uObjMtx *m2) { dst->m.A = ftoq((qtof(m1->m.A) * qtof(m2->m.A)) + (qtof(m1->m.B) * qtof(m2->m.C))); dst->m.B = ftoq((qtof(m1->m.A) * qtof(m2->m.B)) + (qtof(m1->m.B) * qtof(m2->m.D))); @@ -26,16 +30,21 @@ void mat2_copy(uObjMtx *dst, uObjMtx *src) { dst->m.D = src->m.D; dst->m.X = src->m.X; dst->m.Y = src->m.Y; + dst->m.BaseScaleX = src->m.BaseScaleX; + dst->m.BaseScaleY = src->m.BaseScaleY; } void mat2_ident(uObjMtx *dst, float scale) { - dst->m.A = (1 << 16); + dst->m.A = FTOFIX32(scale); + dst->m.D = FTOFIX32(scale); dst->m.B = 0; dst->m.C = 0; - dst->m.D = (1 << 16); dst->m.X = 0; dst->m.Y = 0; + + dst->m.BaseScaleX = qu510(scale); + dst->m.BaseScaleY = qu510(scale); } // cos -sin sin cos void mat2_rotate(uObjMtx *dst, f32 degrees) { @@ -55,9 +64,10 @@ void mat2_add(uObjMtx *m1, uObjMtx *m2) { void mat2_scale(uObjMtx *dst, int scale) { dst->m.A *= scale; - // dst->m.B *= scale; - // dst->m.C *= scale; dst->m.D *= scale; + + dst->m.BaseScaleX *= scale; + dst->m.BaseScaleY *= scale; } #define FTOFIX16(x) (long)((x) * (float)(1 << 2)) @@ -67,27 +77,17 @@ void mat2_translate(uObjMtx *m, int x, int y) { m->m.Y = y<<2; } - void mat2_translate_vec(uObjMtx *m, f32 degrees, f32 mag) { m->m.X += FTOFIX16(mag * cosf(degrees)); m->m.Y += FTOFIX16(mag * sinf(degrees)); } -// void get_final_mat(uObjMtx *dst) { -// u32 s_temp_top = stack_top; -// if (s_isempty()) return; - -// while (s_temp_top != 0) { -// mat2_mul(dst, &stack[s_temp_top]); -// } -// } - typedef float Mat4[4][4]; void gu_to_gs2dex(uObjMtx *m1, Mat4 m2) { - m1->m.A = FTOFIX32(m2[0][0]); + m1->m.A = m1->m.BaseScaleX = FTOFIX32(m2[0][0]); m1->m.B = FTOFIX32(m2[0][1]); m1->m.C = FTOFIX32(m2[1][0]); - m1->m.D = FTOFIX32(m2[1][1]); + m1->m.D = m1->m.BaseScaleY = FTOFIX32(m2[1][1]); m1->m.X = FTOFIX16(m2[3][0]); m1->m.Y = FTOFIX16(m2[3][1]); diff --git a/s2d_draw.c b/s2d_draw.c index e8582246..47c48c31 100644 --- a/s2d_draw.c +++ b/s2d_draw.c @@ -1,6 +1,8 @@ -#include #include "config.h" +#ifdef DRAW_S2D +#include #include "mtx.h" +#include "debug.h" float myScale = 1.0f; int myDegrees = 0; @@ -32,12 +34,14 @@ Gfx s2d_text_init_dl[] = { }; void s2d_rdp_init(void) { - gDPPipeSync(gdl_head++); - gDPSetTextureFilter(gdl_head++, G_TF_POINT); - gSPDisplayList(gdl_head++, s2d_text_init_dl); - gDPSetCycleType(gdl_head++, G_CYC_1CYCLE); - gDPSetRenderMode(gdl_head++, G_RM_XLU_SPRITE, G_RM_XLU_SPRITE2); - gSPObjRenderMode(gdl_head++, G_OBJRM_XLU | G_OBJRM_BILERP); + gDPPipeSync(gdl_head++); + gDPSetTextureFilter(gdl_head++, G_TF_POINT); + gDPSetCycleType(gdl_head++, G_CYC_1CYCLE); + gDPSetRenderMode(gdl_head++, G_RM_XLU_SPRITE, G_RM_XLU_SPRITE2); + if (init_cond) { + gSPDisplayList(gdl_head++, s2d_text_init_dl); + gSPObjRenderMode(gdl_head++, G_OBJRM_XLU); + } } void setup_font_texture(int idx) { @@ -48,71 +52,42 @@ void setup_font_texture(int idx) { // Original Mtx Pipeline // Distorts when rotating, but is faster -// void mtx_pipeline(uObjMtx *m, int x, int y) { -// // init -// mat2_ident(m, 1); -// mat2_ident(&rot_mtx, 1); - -// // create rot matrix -// mat2_rotate(&rot_mtx, (myDegrees) * (M_PI / 180.0f)); -// // scale m -// mat2_scale(m, myScale); -// mat2_dst_mul(m,m, &rot_mtx); -// mat2_translate(m, x, y); - -// gSPObjMatrix(gdl_head++, m); -// } - -// New matrix pipeline -// Works with both rotation and scale, -// but is (probably not noticeably) slower -void mtx_pipeline2(uObjMtx *m, int x, int y) { +void mtx_pipeline(uObjMtx *m, int x, int y) { // init - Mat4 tmp, rot, scal, translate; - guMtxIdentF(tmp); - guScaleF(scal, BASE_SCALE * (myScale), BASE_SCALE * (myScale), 0); - guRotateF(rot, (f32) myDegrees, 0, 0, 1.0f); - guTranslateF(translate, x, y, 0); + gDPPipeSync(gdl_head++); + mat2_ident(m, 1.0f / myScale); + mat2_translate(m, x, y); - mtxf_mul(tmp, tmp, scal); - mtxf_mul(tmp, tmp, rot); - mtxf_mul(tmp, tmp, translate); - - gu_to_gs2dex(m, tmp); - - if (myDegrees != 0) { - mat2_translate_vec(m, -(myDegrees) * M_DTOR, myScale); - } - - gSPObjMatrix(gdl_head++, m); + gSPObjSubMatrix(gdl_head++, &m->m.X); } #define CLAMP_0(x) ((x < 0) ? 0 : x) -void draw_s2d_glyph(char c, int x, int y, uObjMtx *mt) { - setup_font_texture(c); +void draw_s2d_shadow(char c, int x, int y, uObjMtx *ds) { + if (mtx_cond) mtx_pipeline(ds, x, y); + if (tex_cond) setup_font_texture(c); - // mtx_pipeline(mt, x, y); - mtx_pipeline2(mt, x, y); - - if (drop_shadow) { - if (s2d_red != 0 - && s2d_green != 0 - && s2d_blue != 0 - ) { - gDPPipeSync(gdl_head++); - gDPSetEnvColor(gdl_head++, - CLAMP_0(s2d_red - 100), - CLAMP_0(s2d_green - 100), - CLAMP_0(s2d_blue - 100), - s2d_alpha); - gSPObjSprite(gdl_head++, &s2d_dropshadow); - gDPPipeSync(gdl_head++); - gDPSetEnvColor(gdl_head++, s2d_red, s2d_green, s2d_blue, s2d_alpha); - } + if (s2d_red != 0 + && s2d_green != 0 + && s2d_blue != 0 + ) { + gDPPipeSync(gdl_head++); + gDPSetEnvColor(gdl_head++, + CLAMP_0(s2d_red - 100), + CLAMP_0(s2d_green - 100), + CLAMP_0(s2d_blue - 100), + s2d_alpha); + if (spr_cond) gSPObjRectangleR(gdl_head++, &s2d_font); + gDPSetEnvColor(gdl_head++, s2d_red, s2d_green, s2d_blue, s2d_alpha); } - - gSPObjSprite(gdl_head++, &s2d_font); } +void draw_s2d_glyph(char c, int x, int y, uObjMtx *mt) { + if (mtx_cond) mtx_pipeline(mt, x, y); + if (tex_cond) setup_font_texture(c); + // mtx_pipeline2(mt, x, y); + if (spr_cond) gSPObjRectangleR(gdl_head++, &s2d_font); +} + +#endif diff --git a/s2d_draw.h b/s2d_draw.h index 0116f3cb..4cd386e3 100644 --- a/s2d_draw.h +++ b/s2d_draw.h @@ -18,5 +18,6 @@ extern void setup_font_texture(int idx); extern void mtx_pipeline(uObjMtx *m, int x, int y); extern void draw_s2d_glyph(char c, int x, int y, uObjMtx *mt); +extern void draw_s2d_shadow(char c, int x, int y, uObjMtx *ds); #endif \ No newline at end of file diff --git a/s2d_parse.c b/s2d_parse.c index 18f0e789..66572789 100644 --- a/s2d_parse.c +++ b/s2d_parse.c @@ -12,7 +12,12 @@ static int s2d_width(const char *str, int line, int len); -static int s2d_snprint(int x, int y, int align, const char *str, uObjMtx *buf, int len) { +enum S2DPrintModes { + MODE_DRAW_DROPSHADOW, + MODE_DRAW_NORMALTEXT, +}; + +static int s2d_snprint(int x, int y, int align, const char *str, uObjMtx *buf, int len, int mode) { char *p = str; int tmp_len = 0; int orig_x = x; @@ -82,18 +87,14 @@ static int s2d_snprint(int x, int y, int align, const char *str, uObjMtx *buf, i s2d_alpha = s2d_atoi(p, &p); break; case CH_DROPSHADOW: - drop_shadow ^= 1; + drop_shadow = 1; // WIP: drop shadow custom offset // TODO: unique offset per string; fix negative offsets - // CH_SKIP(p); - // drop_x = s2d_atoi(p, &p); - // CH_SKIP(p); CH_SKIP(p); - // drop_y = s2d_atoi(p, &p); - - // drop_x <<= 2; - // drop_y <<= 2; - + CH_SKIP(p); + drop_x = s2d_atoi(p, &p); + CH_SKIP(p); CH_SKIP(p); + drop_y = s2d_atoi(p, &p); break; case CH_BUTTON: if (len - tmp_len == 1) break; @@ -161,7 +162,11 @@ static int s2d_snprint(int x, int y, int align, const char *str, uObjMtx *buf, i if (current_char != '\0' && current_char != CH_SEPARATOR) { char *tbl = segmented_to_virtual(s2d_kerning_table); - draw_s2d_glyph(current_char, x, y, (buf++)); + if (drop_shadow && mode == MODE_DRAW_DROPSHADOW) { + draw_s2d_shadow(current_char, x + drop_x, y + drop_y, (buf++)); + } else if (mode == MODE_DRAW_NORMALTEXT) { + draw_s2d_glyph(current_char, x, y, (buf++)); + } (x += (tbl[(int) current_char] * (BASE_SCALE * myScale))); } } @@ -177,11 +182,23 @@ static int s2d_snprint(int x, int y, int align, const char *str, uObjMtx *buf, i return 0; } +static int s2d_string_has_dropshadow(const char *str) { + char *p = str; + + int result = FALSE; + + do {if (*p == CH_DROPSHADOW) result = TRUE;} while (*(++p) != '\0'); + + return result; +} + +// deprecated void s2d_print(int x, int y, int align, const char *str, uObjMtx *buf) { if (s2d_check_align(align) != 0) return; if (s2d_check_str(str) != 0) return; - s2d_snprint(x, y, align, str, buf, s2d_strlen(str)); + s2d_snprint(x, y, align, str, buf, s2d_strlen(str), MODE_DRAW_DROPSHADOW); + s2d_snprint(x, y, align, str, buf, s2d_strlen(str), MODE_DRAW_NORMALTEXT); } void s2d_print_alloc(int x, int y, int align, const char *str) { @@ -192,10 +209,16 @@ void s2d_print_alloc(int x, int y, int align, const char *str) { len = s2d_strlen(str); - uObjMtx *b = alloc(sizeof(uObjMtx) * len); - s2d_snprint(x, y, align, str, b, len); + if (s2d_string_has_dropshadow(str)) { + uObjMtx *b = alloc(sizeof(uObjMtx) * len); + s2d_snprint(x, y, align, str, b, len, MODE_DRAW_DROPSHADOW); + } + + uObjMtx *b2 = alloc(sizeof(uObjMtx) * len); + s2d_snprint(x, y, align, str, b2, len, MODE_DRAW_NORMALTEXT); } +// deprecated void s2d_type_print(int x, int y, int align, const char *str, uObjMtx *buf, int *pos) { int len; @@ -204,7 +227,9 @@ void s2d_type_print(int x, int y, int align, const char *str, uObjMtx *buf, int len = s2d_strlen(str); - int result = s2d_snprint(x, y, align, str, buf, *pos); + s2d_snprint(x, y, align, str, buf, *pos, MODE_DRAW_DROPSHADOW); + + int result = s2d_snprint(x, y, align, str, buf, *pos, MODE_DRAW_NORMALTEXT); if (s2d_timer % 2 == 0) { if (*pos < len && result != 1) { (*pos)++; @@ -220,10 +245,22 @@ void s2d_type_print_alloc(int x, int y, int align, const char *str, int *pos) { len = s2d_strlen(str); - uObjMtx *b = alloc(sizeof(uObjMtx) * len); - s2d_type_print(x, y, align, str, b, pos); + uObjMtx *b = alloc(sizeof(uObjMtx) * (*pos)); + + if (s2d_string_has_dropshadow(str)) { + uObjMtx *b_d = alloc(sizeof(uObjMtx) * (*pos)); + s2d_snprint(x, y, align, str, b_d, *pos, MODE_DRAW_DROPSHADOW); + } + + int result = s2d_snprint(x, y, align, str, b, *pos, MODE_DRAW_NORMALTEXT); + if (s2d_timer % 2 == 0) { + if (*pos < len && result != 1) { + (*pos)++; + } + } } +// broken atm static int s2d_width(const char *str, int line, int len) { char *p = str; int tmp_len = 0; diff --git a/s2d_print.h b/s2d_print.h index 0c100120..fb59f228 100644 --- a/s2d_print.h +++ b/s2d_print.h @@ -31,6 +31,5 @@ #define ALIGN_CENTER 1 #define ALIGN_RIGHT 2 -extern void s2d_print(int x, int y, int align, const char *str, uObjMtx *buf); extern void s2d_print_alloc(int x, int y, int align, const char *str); extern void s2d_type_print(int x, int y, int align, const char *str, uObjMtx *buf, int *pos);