diff --git a/config/rel_slices.yml b/config/rel_slices.yml index d1feff66..aea07383 100644 --- a/config/rel_slices.yml +++ b/config/rel_slices.yml @@ -6,6 +6,10 @@ m_debug_hayakawa.c: .text: [0x803965E4, 0x803973E8] .rodata: [0x80641D50, 0x80641D90] .data: [0x80651328, 0x80651358] +m_fbdemo.c: + .text: [0x803A0350, 0x803A0ABC] + .rodata: [0x80641F40, 0x80641F60] + .data: [0x80652AA0, 0x80652AD0] m_huusui_room.c: .text: [0x803B1908, 0x803B1968] m_home.c: diff --git a/include/libc64/sleep.h b/include/libc64/sleep.h new file mode 100644 index 00000000..68e6a0c4 --- /dev/null +++ b/include/libc64/sleep.h @@ -0,0 +1,9 @@ +#ifndef SLEEP_H +#define SLEEP_H + +#include "types.h" +#include "dolphin/os/OSTime.h" + +void csleep(OSTime c); +void msleep(int); +#endif \ No newline at end of file diff --git a/include/libultra/gu.h b/include/libultra/gu.h index 5ce54ee7..0e7fe7ef 100644 --- a/include/libultra/gu.h +++ b/include/libultra/gu.h @@ -4,6 +4,7 @@ #include "types.h" #include "libultra/ultratypes.h" +void guMtxIdentF(float mf[4][4]); inline void guTranslateF(float m[4][4], float x, float y, float z){ guMtxIdentF(m); @@ -21,7 +22,7 @@ inline void guScaleF(float mf[4][4], float x, float y, float z) { } void guMtxF2L(float mf[4][4], Mtx *m); -void guMtxIdentF(float mf[4][4]); + void guTranslate(Mtx *m, float x, float y, float z); void guScale(Mtx *m, float x, float y, float z); diff --git a/include/m_fbdemo.h b/include/m_fbdemo.h new file mode 100644 index 00000000..c9e1a5c7 --- /dev/null +++ b/include/m_fbdemo.h @@ -0,0 +1,36 @@ +#ifndef FBDEMO_H +#define FBDEMO_H + +#include "types.h" +#include "PR/mbi.h" + +typedef struct { + /* 0x0 */ f32 x; + /* 0x4 */ f32 y; +} TransitionTileVtxData; // size = 0x8 + +typedef struct { + /* 0x00 */ int cols; + /* 0x04 */ int rows; + /* 0x08 */ int frame; + /* 0x0C */ TransitionTileVtxData* vtxData; + /* 0x10 */ Vtx* vtxFrame1; + /* 0x14 */ Vtx* vtxFrame2; + /* 0x18 */ Mtx projection; + /* 0x58 */ Mtx modelView; + /* 0x98 */ Mtx unk_98; + /* 0xD8 */ Gfx* gfx; // "gfxtbl" + /* 0xDC */ u16* zBuffer; +} TransitionTile; // size = 0xE0 + + +extern void fbdemo_init_gfx(TransitionTile*); +extern void fbdemo_init_data(TransitionTile*); +extern void fbdemo_cleanup(TransitionTile*); +extern TransitionTile* fbdemo_init(TransitionTile*, int, int); +extern void fbdemo_update(TransitionTile*); +extern void fbdemo_draw(TransitionTile*, Gfx**); +extern void fbdemo_move(void); + +#endif + diff --git a/rel/m_fbdemo.c b/rel/m_fbdemo.c new file mode 100644 index 00000000..e46c7dbe --- /dev/null +++ b/rel/m_fbdemo.c @@ -0,0 +1,204 @@ +#include "m_fbdemo.h" +#include "libultra/gu.h" +#include "libc64/malloc.h" +#include "libc64/sleep.h" + +Gfx fbdemo_gfx_init[] ={ + 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), + gsDPSetCombineMode(G_CC_DECALRGB, G_CC_DECALRGB), + gsDPSetOtherMode(G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE | G_TD_CLAMP | G_TP_PERSP | G_CYC_1CYCLE | G_PM_1PRIMITIVE, G_AC_NONE | G_ZS_PIXEL | G_RM_AA_OPA_SURF | G_RM_AA_OPA_SURF2), + gsSPEndDisplayList(), +}; + +extern void fbdemo_init_gfx(TransitionTile* this) { + + int col; + int col2; + int colTex; + int rowTex; + + int row; + int frame; + + Vtx* vtx; + Gfx* gfx; + + + + guMtxIdent(&this->modelView); + guMtxIdent(&this->unk_98); + guOrtho(&this->projection, 0.0f, 320, 240, 0.0f, -1000.0f, 1000.0f, 1.0f); + + for (frame = 0; frame < 2; frame++) { + this->frame = frame; + vtx = (this->frame == 0) ? this->vtxFrame1 : this->vtxFrame2; + for (rowTex = 0, row = 0; row < (this->rows + 1);rowTex += 0x20 ,row++) { + for (colTex = 0, col = 0; col < (this->cols + 1); colTex += 0x20, col++) { + Vtx_tn* vtxn = &vtx->n; + vtx++; + vtxn->ob[0] = col * 0x20; + vtxn->ob[1] = row * 0x20; + vtxn->ob[2] = -5; + vtxn->flag = 0; + vtxn->tc[0] = colTex << 6; + vtxn->tc[1] = rowTex << 6; + vtxn->n[0] = 0; + vtxn->n[1] = 0; + vtxn->n[2] = 120; + vtxn->a = 255; + } + } + } + + gfx = this->gfx; + for (rowTex = 0, row = 0; row < this->rows; rowTex += 0x20,row++) { + gSPVertex(gfx++, SEGMENT_ADDR(0xA, (u32)row * (this->cols + 1) * sizeof(Vtx)), 2 * (this->cols + 1), 0); + + colTex = 0; + col = 0; + col2 = 0; + while (col < this->cols) { + gDPPipeSync(gfx++); + + gDPLoadTextureTile(gfx++, SEGMENT_ADDR(0xB, 0), G_IM_FMT_RGBA, G_IM_SIZ_16b, 320, 240, + colTex, rowTex, colTex + 0x20, rowTex + 0x20, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + + gSP1Quadrangle(gfx++, col2, col2 + 1, + (this->cols) + 2 + col2 , this->cols + 1 + col2, 0); + + colTex += 0x20; + col2++; + col++; + } + + } + + gDPPipeSync(gfx++); + gSPEndDisplayList(gfx++); +} + +extern void fbdemo_init_data(TransitionTile* this) { + int col; + int row; + + + for (row = 0; row < this->rows + 1; row++) { + for (col = 0; col < this->cols + 1; col++) { + (this->vtxData + col + row * (this->cols + 1))->x = col * 0x20; + (this->vtxData + col + row * (this->cols + 1))->y = row * 0x20; + } + } +} + +extern void fbdemo_cleanup(TransitionTile* this){ + msleep(100); + + if (this->vtxData != NULL) { + free(this->vtxData); + this->vtxData = NULL; + } + if (this->vtxFrame1 != NULL) { + free(this->vtxFrame1); + this->vtxFrame1 = NULL; + } + if (this->vtxFrame2 != NULL) { + free(this->vtxFrame2); + this->vtxFrame2 = NULL; + } + if (this->gfx != NULL) { + free(this->gfx); + this->gfx = NULL; + } +} + +extern TransitionTile* fbdemo_init(TransitionTile* this, int cols, int rows){ + + s32 gridsize; + + bzero(this, sizeof(TransitionTile)); + + this->cols = cols; + this->rows = rows; + + + + this->frame = 0; + this->vtxData = malloc((cols + 1) * sizeof(TransitionTileVtxData) * (rows + 1)); + + this->vtxFrame1 = malloc((cols + 1) * sizeof(Vtx) * (rows + 1)); + this->vtxFrame2 = malloc((cols + 1) * sizeof(Vtx) * (rows + 1)); + + this->gfx = malloc(((this->cols * 9 + 1) * this->rows + 2) * sizeof(Gfx)); + + if ((this->vtxData == NULL) || (this->vtxFrame1 == NULL) || + (this->vtxFrame2 == NULL) || (this->gfx == NULL)) { + + if (this->vtxData != NULL) { + free(this->vtxData); + this->vtxData = NULL; + } + + if (this->vtxFrame1 != NULL) { + free(this->vtxFrame1); + this->vtxFrame1 = NULL; + } + + if (this->vtxFrame2 != NULL) { + free(this->vtxFrame2); + this->vtxFrame2 = NULL; + } + + if (this->gfx != NULL) { + free(this->gfx); + this->gfx = NULL; + } + + return NULL; + } + + fbdemo_init_gfx(this); + fbdemo_init_data(this); + this->frame = 0; + + return this; +} + + +extern void fbdemo_update(TransitionTile* this) { + int col; + int row; + Vtx* vtx; + + for (row = 0; row < this->rows + 1; row++) { + for (col = 0; col < this->cols + 1; col++) { + vtx = (this->frame == 0) ? this->vtxFrame1 : this->vtxFrame2; + (vtx + col + row * (this->cols + 1))->n.ob[0] = (this->vtxData + col + row * (this->cols + 1))->x; + + vtx = (this->frame == 0) ? this->vtxFrame1 : this->vtxFrame2; + (vtx + col + row * (this->cols + 1))->n.ob[1] = (this->vtxData + col + row * (this->cols + 1))->y; + } + } +} + +void fbdemo_draw(TransitionTile* this, Gfx** gfxP) { + Gfx* gfx = *gfxP; + + gSPDisplayList(gfx++, fbdemo_gfx_init); + fbdemo_update(this); + gSPMatrix(gfx++, &this->projection, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + gSPMatrix(gfx++, &this->modelView, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(gfx++, 0xA, this->frame == 0 ? this->vtxFrame1 : this->vtxFrame2); + gSPSegment(gfx++, 0xB, this->zBuffer); + gSPDisplayList(gfx++, fbdemo_gfx_init); + gSPDisplayList(gfx++, this->gfx); + gDPPipeSync(gfx++); + this->frame ^= 1; + *gfxP = gfx; +} + + +extern void fbdemo_move(void){ + +} \ No newline at end of file diff --git a/src/libultra/xprintf.c b/src/libultra/xprintf.c index 74eafe05..9cdb043f 100644 --- a/src/libultra/xprintf.c +++ b/src/libultra/xprintf.c @@ -42,7 +42,7 @@ void _Putfld(_Pft*, va_list, u8, u8*); /* These functions seem to have 04,p enabled */ #pragma optimize_for_size off -s32 _Printf(void* (*pfn)(void*, const char*, int), void* arg, const char* fmt, +int _Printf(void* (*pfn)(void*, const char*, int), void* arg, const char* fmt, va_list ap) { /* Unused static variables to match position of locals */ static int unused0;