much faster matrix pipeline, debug condition manager, and start of f3d_draw

This commit is contained in:
farisawan-2000
2021-05-31 01:32:58 -04:00
parent 36574f5455
commit 5f0b67a38b
9 changed files with 229 additions and 102 deletions

View File

@@ -13,6 +13,8 @@
* Helpful defines to change
***********/
#define DRAW_F3D
#define BASE_SCALE 1.0f
/******************************

15
debug.h Normal file
View File

@@ -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

95
f3d_draw.c Normal file
View File

@@ -0,0 +1,95 @@
#include "config.h"
#ifdef DRAW_F3D
#include <ultra64.h>
#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

11
init.c
View File

@@ -2,17 +2,20 @@
#include <PR/gs2dex.h>
#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();
}

32
mtx.c
View File

@@ -2,9 +2,13 @@
#include <PR/gs2dex.h>
#include <PR/gu.h>
#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]);

View File

@@ -1,6 +1,8 @@
#include <ultra64.h>
#include "config.h"
#ifdef DRAW_S2D
#include <ultra64.h>
#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

View File

@@ -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

View File

@@ -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;

View File

@@ -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);