From d5f43751a91d2720fdef4426316c14fee42cc273 Mon Sep 17 00:00:00 2001 From: farisawan-2000 Date: Sat, 12 Dec 2020 15:33:14 -0500 Subject: [PATCH] save state --- fixed_point_math.c | 26 +++++++++++++++--- fixedpoint.h | 5 ++++ fonts/impact.c | 4 +-- mtx.c | 66 ++++++++++++++++++++++++++++++++++------------ mtx.h | 2 ++ s2d_draw.c | 56 ++++++++++++++++++++++++++++++++++++--- s2d_draw.h | 2 +- s2d_parse.c | 11 ++++++-- s2d_print.h | 6 ++--- 9 files changed, 145 insertions(+), 33 deletions(-) create mode 100644 fixedpoint.h diff --git a/fixed_point_math.c b/fixed_point_math.c index 7f0e7e01..bff61c74 100644 --- a/fixed_point_math.c +++ b/fixed_point_math.c @@ -1,13 +1,31 @@ +#include // jk i dont think this file is needed lol // update: it was needed :( +// update 2: gu.h already has macros for this :( // hopefully I'll only need s15.16 // ^ clueless +// Q to float + +// To convert a number from Qm.n format to floating point: + +// Convert the number to floating point as if it were an integer, in other words remove the binary point +// Multiply by 2^−n + f32 qtof(int q) { - f32 lit = (float) ((q >> 16) & 0x7FFF); - if (q < 0) lit = -lit; - f32 dec = (float) ((float)(q & 0xFFFF) / (float)2^16); - return lit + dec; + return ((float)q) * 0.00001525878f; } +// Float to Q + +// To convert a number from floating point to Qm.n format: + +// Multiply the floating point number by 2^n +// Round to the nearest integer +int ftoq(f32 f) { + f *= (65536.0f); + return (int)f; +} + + diff --git a/fixedpoint.h b/fixedpoint.h new file mode 100644 index 00000000..69ba4298 --- /dev/null +++ b/fixedpoint.h @@ -0,0 +1,5 @@ +#include + +extern f32 qtof(int q); + +extern int ftoq(f32 f); diff --git a/fonts/impact.c b/fonts/impact.c index a19b1720..aa2525b2 100644 --- a/fonts/impact.c +++ b/fonts/impact.c @@ -1673,8 +1673,8 @@ uObjMtx impact_mtx = { 1<<10, 1<<10 /* BaseScaleX, BaseScaleY */ }; uObjSprite impact_obj = { - 0<<2, 1<<10, 16<<5, 0, /* objX, scaleX, imageW, unused */ - 0<<2, 1<<10, 16<<5, 0, /* objY, scaleY, imageH, unused */ + -8<<2, 1<<10, 16<<5, 0, /* objX, scaleX, imageW, unused */ + -8<<2, 1<<10, 16<<5, 0, /* objY, scaleY, imageH, unused */ GS_PIX2TMEM(16, G_IM_SIZ_8b), /* imageStride */ GS_PIX2TMEM(0, G_IM_SIZ_8b), /* imageAdrs */ G_IM_FMT_IA, /* imageFmt */ diff --git a/mtx.c b/mtx.c index fb513625..a3d706ad 100644 --- a/mtx.c +++ b/mtx.c @@ -1,21 +1,17 @@ #include #include #include "stack.h" +// #include "fixedpoint.h" +#include + +#define ftoq FTOFIX32 +#define qtof FIX32TOF -// TODO: implement fixed point math instead of... this... void mat2_dst_mul(uObjMtx *dst, uObjMtx *m1, uObjMtx *m2) { - int m1A = m1->m.A >> 16; - int m1B = m1->m.B >> 16; - int m1C = m1->m.C >> 16; - int m1D = m1->m.D >> 16; - int m2A = m2->m.A >> 16; - int m2B = m2->m.B >> 16; - int m2C = m2->m.C >> 16; - int m2D = m2->m.D >> 16; - dst->m.A = ((m1A * m2A) * (m1B * m2C)) << 16; - dst->m.B = ((m1A * m2B) * (m1B * m2D)) << 16; - dst->m.C = ((m1C * m2A) * (m1D * m2C)) << 16; - dst->m.D = ((m1C * m2B) * (m1D * m2D)) << 16; + 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))); + dst->m.C = ftoq((qtof(m1->m.C) * qtof(m2->m.A)) + (qtof(m1->m.D) * qtof(m2->m.C))); + dst->m.D = ftoq((qtof(m1->m.C) * qtof(m2->m.B)) + (qtof(m1->m.D) * qtof(m2->m.D))); } void mat2_dst_add(uObjMtx *dst, uObjMtx *m1, uObjMtx *m2) { @@ -25,6 +21,15 @@ void mat2_dst_add(uObjMtx *dst, uObjMtx *m1, uObjMtx *m2) { dst->m.D = (m1->m.D + m2->m.D); } +void mat2_copy(uObjMtx *dst, uObjMtx *src) { + dst->m.A = src->m.A; + dst->m.B = src->m.B; + dst->m.C = src->m.C; + dst->m.D = src->m.D; + dst->m.X = src->m.X; + dst->m.Y = src->m.Y; +} + void mat2_ident(uObjMtx *dst, int scale) { dst->m.A = scale << 16; dst->m.B = 0; @@ -34,6 +39,13 @@ void mat2_ident(uObjMtx *dst, int scale) { dst->m.X = 0; dst->m.Y = 0; } +// cos -sin sin cos +void mat2_rotate(uObjMtx *dst, f32 degrees) { + dst->m.A = ftoq(cosf(degrees)); + dst->m.B = ftoq(-sinf(degrees)); + dst->m.C = ftoq(sinf(degrees)); + dst->m.D = ftoq(cosf(degrees)); +} void mat2_mul(uObjMtx *m1, uObjMtx *m2) { mat2_dst_mul(m1, m1, m2); @@ -45,14 +57,22 @@ 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.B *= scale; + // dst->m.C *= scale; dst->m.D *= scale; } +#define FTOFIX16(x) (long)((x) * (float)(1 << 2)) +#define FIX16TOF(x) ((float)(x) * (1.0f / (float)(1 << 2))) void mat2_translate(uObjMtx *m, int x, int y) { - m->m.X = x; - m->m.Y = y; + m->m.X = x<<2; + 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) { @@ -63,3 +83,15 @@ void get_final_mat(uObjMtx *dst) { 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.B = FTOFIX32(m2[0][1]); + m1->m.C = FTOFIX32(m2[1][0]); + m1->m.D = FTOFIX32(m2[1][1]); + + m1->m.X = FTOFIX16(m2[3][0]); + m1->m.Y = FTOFIX16(m2[3][1]); +} + diff --git a/mtx.h b/mtx.h index c0f5e7de..cd124c9d 100644 --- a/mtx.h +++ b/mtx.h @@ -17,3 +17,5 @@ extern void mat2_scale(uObjMtx *dst, int scale); extern void get_final_mat(uObjMtx *dst); extern void mat2_translate(uObjMtx *m, int x, int y); + +extern void mat2_rotate(uObjMtx *dst, f32 degrees); diff --git a/s2d_draw.c b/s2d_draw.c index 96536ff0..91621ca3 100644 --- a/s2d_draw.c +++ b/s2d_draw.c @@ -3,9 +3,12 @@ #include "mtx.h" int myScale = 1; -int degrees = 0; +int myDegrees = 0; uObjMtx final_mtx, rot_mtx; +#define TEX_X -8 +#define TEX_Y -8 + static Gfx s2d_init_dl[] = { gsDPPipeSync(), gsDPSetTexturePersp(G_TP_NONE), @@ -26,15 +29,58 @@ void setup_font(int idx) { gDPSetRenderMode(gDisplayListHead++, G_RM_XLU_SPRITE, G_RM_XLU_SPRITE2); gSPObjRenderMode(gDisplayListHead++, G_OBJRM_XLU | G_OBJRM_BILERP); gSPObjLoadTxtr(gDisplayListHead++, &s2d_tex[idx]); -}// 32 32 +} + +extern void mat2_translate_vec(uObjMtx *m, f32 degrees, f32 mag); void mtx_pipeline(uObjMtx *m, int x, int y) { + // init mat2_ident(m, 1); mat2_ident(&rot_mtx, 1); - // mat2_translate(&rot_mtx, 50, 50); + + // create rot matrix + mat2_rotate(&rot_mtx, (myDegrees) * (M_PI / 180.0f)); + + + // mat2_translate_with_rotation(m, &rot_mtx, x, y); + // scale m mat2_scale(m, myScale); - // mat2_mul(m, &rot_mtx); + // m = rot_mtx * m + // bypass the above by just copying the rot matrix + // mat2_copy(m, &rot_mtx); + mat2_dst_mul(m,m, &rot_mtx); mat2_translate(m, x, y); + // mat2_translate_vec(m, (-myDegrees) * (M_PI / 180.0f), 1.0f); + + + // testing a stackoverflow answer + // mat2_translate(m, -TEX_X * myScale, -TEX_Y * myScale); + // mat2_dst_mul(m, m, &rot_mtx); + // mat2_translate(m, TEX_X * myScale, TEX_Y * myScale); + + + // yeah + gSPObjMatrix(gDisplayListHead++, m); +} + +#include +typedef float Mat4[4][4]; + +void mtx_pipeline2(uObjMtx *m, int x, int y) { + // init + Mat4 tmp, rot, scal, translate; + guMtxIdentF(tmp); + guScaleF(scal, myScale, myScale, 0); + guRotateF(rot, (f32) myDegrees, 0, 0, 1.0f); + guTranslateF(translate, x, y, 0); + + mtxf_mul(tmp, tmp, scal); + mtxf_mul(tmp, tmp, rot); + mtxf_mul(tmp, tmp, translate); + + gu_to_gs2dex(m, tmp); + + // yeah gSPObjMatrix(gDisplayListHead++, m); } @@ -44,3 +90,5 @@ void draw_s2d_glyph(char c, int x, int y, uObjMtx *mt) { // gSPObjMatrix(gDisplayListHead++, &s2d_mat); gSPObjSprite(gDisplayListHead++, &s2d_font); } + + diff --git a/s2d_draw.h b/s2d_draw.h index 835c2bfc..a988859b 100644 --- a/s2d_draw.h +++ b/s2d_draw.h @@ -3,7 +3,7 @@ #include extern int myScale; -extern int degrees; +extern int myDegrees; extern uObjMtx final_mtx, rot_mtx; extern void setup_font(int idx); diff --git a/s2d_parse.c b/s2d_parse.c index c332ca15..5bc30b91 100644 --- a/s2d_parse.c +++ b/s2d_parse.c @@ -4,12 +4,14 @@ #include "s2d_draw.h" #include "s2d_print.h" +int saved_degrees = 0; + void s2d_print(int x, int y, const char *str, uObjMtx *buf) { char *p = str; + if (*p == '\0') return; do { char r = *p; char s, rd, tx, ty; - if (*p == '\0') break; switch (r) { case CH_SCALE: s = CH_GET_NEXT(p); @@ -17,16 +19,21 @@ void s2d_print(int x, int y, const char *str, uObjMtx *buf) { break; case CH_ROT: rd = CH_GET_NEXT(p); - degrees = rd; + saved_degrees = rd; + myDegrees = rd; break; case CH_TRANSLATE: tx = CH_GET_NEXT(p); ty = CH_GET_NEXT(p); + break; default: draw_s2d_glyph(r, x += (29 * myScale), y, (buf++)); } + myDegrees += saved_degrees; } while (*(p++) != '\0'); myScale = 1; + myDegrees = 0; + saved_degrees = 0; } diff --git a/s2d_print.h b/s2d_print.h index 97ce74b8..d26e771c 100644 --- a/s2d_print.h +++ b/s2d_print.h @@ -1,9 +1,9 @@ #include #include -#define SCALE "\x80" -#define ROT "\x81" -#define TRANSLATE "\x82" +#define SCALE "\x80" // SCALE (some scale) +#define ROTATE "\x81" // ROTATE (degrees) // TODO: maybe add axis? +#define TRANSLATE "\x82" // TRANSLATE (x) (y) #define CH_SCALE '\x80' #define CH_ROT '\x81'