Finished(Controller Input): Reading Joypad State

This commit is contained in:
ed
2026-07-31 15:15:51 -04:00
parent 315e1b2c5e
commit 09dde54030
9 changed files with 210 additions and 74 deletions
+2 -2
View File
@@ -61,7 +61,7 @@ WORD_COUNT(mac_gte_load_tri_verts, 18)
, load_word( R_AT, R_T1, O_(PolyTag,code)) /* AT = old_ot_head */ \ , load_word( R_AT, R_T1, O_(PolyTag,code)) /* AT = old_ot_head */ \
, load_upper_i(R_V0, (S_(Poly_F3)/S_(U4) - S_(PolyTag)/S_(U4)) << PolyTag_len_bits) /* V0 = (5 - 1) << 24 = 4 << 24 */ \ , load_upper_i(R_V0, (S_(Poly_F3)/S_(U4) - S_(PolyTag)/S_(U4)) << PolyTag_len_bits) /* V0 = (5 - 1) << 24 = 4 << 24 */ \
, mask_upper( R_AT, R_AT, S_(PolyTag_len_bits)) /* Strip upper 8 bits (length from prev cell) → keep only low 24 */ \ , mask_upper( R_AT, R_AT, S_(PolyTag_len_bits)) /* Strip upper 8 bits (length from prev cell) → keep only low 24 */ \
, or_u( R_AT, R_AT, R_V0) /* Merge length */ \ , or( R_AT, R_AT, R_V0) /* Merge length */ \
, store_word( R_AT, R_PrimCursor, O_(PolyTag,code)) /* prim->tag = packed(prim_length, old_addr) */ \ , store_word( R_AT, R_PrimCursor, O_(PolyTag,code)) /* prim->tag = packed(prim_length, old_addr) */ \
, shift_lleft( R_AT, R_PrimCursor, S_(PolyTag_len_bits)) /* AT = (prim_length << 24) | old_addr */ \ , shift_lleft( R_AT, R_PrimCursor, S_(PolyTag_len_bits)) /* AT = (prim_length << 24) | old_addr */ \
, shift_lright(R_AT, R_AT, S_(PolyTag_len_bits)) \ , shift_lright(R_AT, R_AT, S_(PolyTag_len_bits)) \
@@ -76,7 +76,7 @@ WORD_COUNT(mac_insert_ot_tag_f3, 11)
, load_word( R_AT, R_T1, O_(PolyTag,code)) /* AT = old_ot_head */ \ , load_word( R_AT, R_T1, O_(PolyTag,code)) /* AT = old_ot_head */ \
, load_upper_i(R_V0, (S_(Poly_G4)/S_(U4) - S_(PolyTag)/S_(U4)) << PolyTag_len_bits) /* V0 = (9 - 1) << 24 = 8 << 24 */ \ , load_upper_i(R_V0, (S_(Poly_G4)/S_(U4) - S_(PolyTag)/S_(U4)) << PolyTag_len_bits) /* V0 = (9 - 1) << 24 = 8 << 24 */ \
, mask_upper( R_AT, R_AT, S_(PolyTag_len_bits)) /* Strip upper 8 bits (length from prev cell) → keep only low 24 */ \ , mask_upper( R_AT, R_AT, S_(PolyTag_len_bits)) /* Strip upper 8 bits (length from prev cell) → keep only low 24 */ \
, or_u( R_AT, R_AT, R_V0) /* Merge length */ \ , or( R_AT, R_AT, R_V0) /* Merge length */ \
, store_word( R_AT, R_PrimCursor, O_(PolyTag,code)) /* prim->tag = packed(prim_length, old_addr) */ \ , store_word( R_AT, R_PrimCursor, O_(PolyTag,code)) /* prim->tag = packed(prim_length, old_addr) */ \
, shift_lleft( R_AT, R_PrimCursor, S_(PolyTag_len_bits)) /* AT = (prim_length << 24) | old_addr */ \ , shift_lleft( R_AT, R_PrimCursor, S_(PolyTag_len_bits)) /* AT = (prim_length << 24) | old_addr */ \
, shift_lright(R_AT, R_AT, S_(PolyTag_len_bits)) \ , shift_lright(R_AT, R_AT, S_(PolyTag_len_bits)) \
+7 -4
View File
@@ -60,7 +60,7 @@ enum {
atom_dbg_skip MipsAtom_(tape_exit) { jump_reg(rret_addr), nop }; atom_dbg_skip MipsAtom_(tape_exit) { jump_reg(rret_addr), nop };
/* Generalized Tape Engine Runner */ /* Generalized Tape Engine Runner */
NI_ void tape_run(Slice_MipsCode tape) { register U4* tp rgcc(R_TapePtr) = u4_r(tape.ptr); asm volatile( FI_ void tape_run(Slice_MipsCode tape) { register U4* tp rgcc(R_TapePtr) = u4_r(tape.ptr); asm volatile(
asm_words( asm_words(
add_ui( R_SP, R_SP, -MipsStackAlignment) /* Allocate stack space */ add_ui( R_SP, R_SP, -MipsStackAlignment) /* Allocate stack space */
, store_word( R_RA, R_SP, 0) /* Safely backup $ra to the stack */ , store_word( R_RA, R_SP, 0) /* Safely backup $ra to the stack */
@@ -93,7 +93,10 @@ FI_ void tb_data(TapeBuilder* tb, U4 data) { u4_r(tb->ptr)[tb->used] = u4
FI_ Slice_MipsCode tb_end (TapeBuilder* tb) { tb_emit(tb,tape_exit); return (Slice_MipsCode){ C_(U4*,tb->ptr), tb->used }; } FI_ Slice_MipsCode tb_end (TapeBuilder* tb) { tb_emit(tb,tape_exit); return (Slice_MipsCode){ C_(U4*,tb->ptr), tb->used }; }
FI_ Slice_MipsCode tb_slice(TapeBuilder tb) { return (Slice_MipsCode){ C_(U4*,tb.ptr), tb.used }; } FI_ Slice_MipsCode tb_slice(TapeBuilder tb) { return (Slice_MipsCode){ C_(U4*,tb.ptr), tb.used }; }
#define tb_scope(tb) for(U4 tbs_once=0;tbs_once==0;++tbs_once,tb_emit(tb,tape_exit)) #define tb_scope(tb) for(U4 tbs_once=0;tbs_once==0;++tbs_once,tb_emit(tb,tape_exit))
FI_ void tb_scope_run_end(TapeBuilder* tb) { tb_emit(tb,tape_exit); tape_run(tb_slice(tb[0])); }
#define tb_scope_run(tb) for(U4 tbs_once=0;tbs_once==0;++tbs_once,tb_scope_run_end(tb))
#pragma endregion Tape Drive #pragma endregion Tape Drive
@@ -132,7 +135,7 @@ MipsAtomComp_(ac_insert_ot_tag_f3) {
load_word( R_AT, R_T1, O_(PolyTag,code)), // AT = old_ot_head load_word( R_AT, R_T1, O_(PolyTag,code)), // AT = old_ot_head
load_upper_i(R_V0, (S_(Poly_F3)/S_(U4) - S_(PolyTag)/S_(U4)) << PolyTag_len_bits), // V0 = (5 - 1) << 24 = 4 << 24 load_upper_i(R_V0, (S_(Poly_F3)/S_(U4) - S_(PolyTag)/S_(U4)) << PolyTag_len_bits), // V0 = (5 - 1) << 24 = 4 << 24
mask_upper( R_AT, R_AT, S_(PolyTag_len_bits)), // Strip upper 8 bits (length from prev cell) → keep only low 24 mask_upper( R_AT, R_AT, S_(PolyTag_len_bits)), // Strip upper 8 bits (length from prev cell) → keep only low 24
or_u( R_AT, R_AT, R_V0), // Merge length or( R_AT, R_AT, R_V0), // Merge length
store_word( R_AT, R_PrimCursor, O_(PolyTag,code)), // prim->tag = packed(prim_length, old_addr) store_word( R_AT, R_PrimCursor, O_(PolyTag,code)), // prim->tag = packed(prim_length, old_addr)
shift_lleft( R_AT, R_PrimCursor, S_(PolyTag_len_bits)), // AT = (prim_length << 24) | old_addr shift_lleft( R_AT, R_PrimCursor, S_(PolyTag_len_bits)), // AT = (prim_length << 24) | old_addr
shift_lright(R_AT, R_AT, S_(PolyTag_len_bits)), shift_lright(R_AT, R_AT, S_(PolyTag_len_bits)),
@@ -147,7 +150,7 @@ MipsAtomComp_(ac_insert_ot_tag_g4) {
load_word( R_AT, R_T1, O_(PolyTag,code)), // AT = old_ot_head load_word( R_AT, R_T1, O_(PolyTag,code)), // AT = old_ot_head
load_upper_i(R_V0, (S_(Poly_G4)/S_(U4) - S_(PolyTag)/S_(U4)) << PolyTag_len_bits), // V0 = (9 - 1) << 24 = 8 << 24 load_upper_i(R_V0, (S_(Poly_G4)/S_(U4) - S_(PolyTag)/S_(U4)) << PolyTag_len_bits), // V0 = (9 - 1) << 24 = 8 << 24
mask_upper( R_AT, R_AT, S_(PolyTag_len_bits)), // Strip upper 8 bits (length from prev cell) → keep only low 24 mask_upper( R_AT, R_AT, S_(PolyTag_len_bits)), // Strip upper 8 bits (length from prev cell) → keep only low 24
or_u( R_AT, R_AT, R_V0), // Merge length or( R_AT, R_AT, R_V0), // Merge length
store_word( R_AT, R_PrimCursor, O_(PolyTag,code)), // prim->tag = packed(prim_length, old_addr) store_word( R_AT, R_PrimCursor, O_(PolyTag,code)), // prim->tag = packed(prim_length, old_addr)
shift_lleft( R_AT, R_PrimCursor, S_(PolyTag_len_bits)), // AT = (prim_length << 24) | old_addr shift_lleft( R_AT, R_PrimCursor, S_(PolyTag_len_bits)), // AT = (prim_length << 24) | old_addr
shift_lright(R_AT, R_AT, S_(PolyTag_len_bits)), shift_lright(R_AT, R_AT, S_(PolyTag_len_bits)),
+4 -4
View File
@@ -336,10 +336,10 @@ enum { _BitOffsets = 0
/* Logic Opcodes */ /* Logic Opcodes */
#define and_u(rd, rs, rt) enc_r(op_special, (rs), (rt), (rd), 0, fc_and) #define and(rd, rs, rt) enc_r(op_special, (rs), (rt), (rd), 0, fc_and)
#define or_u(rd, rs, rt) enc_r(op_special, (rs), (rt), (rd), 0, fc_or) #define or(rd, rs, rt) enc_r(op_special, (rs), (rt), (rd), 0, fc_or)
#define xor_u(rd, rs, rt) enc_r(op_special, (rs), (rt), (rd), 0, fc_xor) #define xor(rd, rs, rt) enc_r(op_special, (rs), (rt), (rd), 0, fc_xor)
#define nor_u(rd, rs, rt) enc_r(op_special, (rs), (rt), (rd), 0, fc_nor) #define nor(rd, rs, rt) enc_r(op_special, (rs), (rt), (rd), 0, fc_nor)
#define or_u_self(rd_rs, rt) enc_r(op_special, (rd_rs), (rt), (rd_rs), 0, fc_or) #define or_u_self(rd_rs, rt) enc_r(op_special, (rd_rs), (rt), (rd_rs), 0, fc_or)
+38
View File
@@ -0,0 +1,38 @@
#ifdef INTELLISENSE_DIRECTIVES
# pragma once
# include "dsl.h"
#endif
enum {
Bit_(Pad_L2, 0),
Bit_(Pad_R2, 1),
Bit_(Pad_L1, 2),
Bit_(Pad_R1, 3),
Bit_(Pad_Triangle, 4),
Bit_(Pad_Circle, 5),
Bit_(Pad_Cross, 6),
Bit_(Pad_Square, 7),
Bit_(Pad_Select, 8),
Bit_(Unused_PadI, 9),
Bit_(Unused_PadJ, 10),
Bit_(Pad_Start, 11),
Bit_(Pad_Up, 12),
Bit_(Pad_Right, 13),
Bit_(Pad_Down, 14),
Bit_(Pad_Left, 15),
};
enum {
PadId_Offset = 4,
Pad0 = 0 << PadId_Offset,
Pad1 = 1 << PadId_Offset,
};
#define pad0_(btn_id) (btn_id << Pad0)
#define pad1_(btn_id) (btn_id << Pad1)
void pad_init(U4 mode) asm("PadInit");
U4 pad_read(U4 id) asm("PadRead");
+15 -13
View File
@@ -116,20 +116,22 @@ MipsAtom_(floor_f3_face) atom_info(atom_phase(floor_f3)
/* Culling (Branch forward if Backface) */ /* Culling (Branch forward if Backface) */
gte_mv_from_data_r(R_T0, C2_MAC0), gte_mv_from_data_r(R_T0, C2_MAC0),
nop, branch_le_zero(R_T0, atom_offset(culling, floor_f3_face_exit)), nop, // required gte -> cpu load-delay slot. nop, branch_le_zero(R_T0, atom_offset(culling, floor_f3_face_exit)), nop, // required gte -> cpu load-delay slot.
/* Format Primitive */ /* Format Primitive */
mac_gte_store_f3(), mac_gte_store_f3(),
/* Calculate Depth */ /* Calculate Depth */
gte_avg_sort_z3, gte_avg_sort_z3,
gte_mv_from_data_r(R_T1, C2_OTZ), gte_mv_from_data_r(R_T1, C2_OTZ),
/* Bounds Check OTZ < 2048 (Branch forward to skip insertion) */ /* Bounds Check OTZ < 2048 (Branch forward to skip insertion) */
add_ui( R_AT, R_0, OrderingTbl_Len), add_ui( R_AT, R_0, OrderingTbl_Len),
set_lt_u( R_AT, R_T1, R_AT), set_lt_u( R_AT, R_T1, R_AT),
branch_equal(R_AT, R_0, atom_offset(bounds_chk, floor_f3_face_exit)), nop, branch_equal(R_AT, R_0, atom_offset(bounds_chk, floor_f3_face_exit)), nop,
mac_format_f3_color(0xFF, 0xFF, 0xFF), // RGB-form (R=FF, G=FF, B=FF = white) mac_format_f3_color(0xFF, 0xFF, 0xFF), // RGB-form (R=FF, G=FF, B=FF = white)
mac_insert_ot_tag_f3(), /* Insert into Ordering Table Linked List */ mac_insert_ot_tag_f3(), /* Insert into Ordering Table Linked List */
add_ui_self(R_PrimCursor, S_(Poly_F3)), /* Advance Prim Cursor (5 words) */ add_ui_self(R_PrimCursor, S_(Poly_F3)), /* Advance Prim Cursor (5 words) */
// Note(Ed): No bounds checking, should be checked before atom runs. // Note(Ed): No bounds checking, should be checked before atom runs.
// end: branch(bounds_chk)
// end: branch(culling)
/* Advance Input Cursor & Yield (Both branch targets land here) */ /* Advance Input Cursor & Yield (Both branch targets land here) */
atom_label(floor_f3_face_exit) atom_label(floor_f3_face_exit)
@@ -5,6 +5,16 @@
#pragma region hello_joypad.tape #pragma region hello_joypad.tape
// --- atom: pad_input_demo (24 words) ---
#define _atom_offset_pad_left_exit_pad_left 6
#define _atom_offset_pad_right_exit_pad_right 6
enum {
atom_offset_pad_left_exit_pad_left = _atom_offset_pad_left_exit_pad_left,
atom_offset_pad_right_exit_pad_right = _atom_offset_pad_right_exit_pad_right,
};
// --- atom: cube_g4_face (77 words) --- // --- atom: cube_g4_face (77 words) ---
#define _atom_offset_cull_cube_g4_face_exit 42 #define _atom_offset_cull_cube_g4_face_exit 42
+55 -17
View File
@@ -13,6 +13,7 @@
#include "duffle/mips.h" #include "duffle/mips.h"
#include "duffle/gp.h" #include "duffle/gp.h"
#include "duffle/gte.h" #include "duffle/gte.h"
#include "duffle/pad.h"
# include "duffle/gen/duffle.macs.h" # include "duffle/gen/duffle.macs.h"
# include "duffle/gen/duffle.offsets.h" # include "duffle/gen/duffle.offsets.h"
@@ -25,6 +26,7 @@
#include "hello_joypad.tape.c" #include "hello_joypad.tape.c"
typedef U4 OrderingTable_Buffer[OrderingTbl_Len]; typedef U4 OrderingTable_Buffer[OrderingTbl_Len];
typedef Array_(OrderingTable_Buffer, 2); typedef Array_(OrderingTable_Buffer, 2);
@@ -99,6 +101,7 @@ typedef Struct_(Ent_Floor) {
A2_V3_S2 faces; A2_V3_S2 faces;
}; };
enum { enum {
Scratchpad_Len = 1024, Scratchpad_Len = 1024,
MemTape_Len = 512, MemTape_Len = 512,
@@ -116,11 +119,17 @@ typedef Struct_(SMemory) {
Ent_Cube cube; Ent_Cube cube;
Ent_Floor floor; Ent_Floor floor;
U4 pad_state;
U4_V scratchpad; // d-cache U4_V scratchpad; // d-cache
}; };
global SMemory smem; global SMemory smem;
extern SMemory smem; extern SMemory smem;
#define pad0_signal_(btn_id) smem.pad_state & pad0_(btn_id)
#define pad1_signal_(btn_id) smem.pad_state & pad1_(btn_id)
// TODO(Ed): // TODO(Ed):
FI_ U4* spad_warm(MipsAtom atom) { FI_ U4* spad_warm(MipsAtom atom) {
return nullptr; return nullptr;
@@ -190,6 +199,31 @@ void render(void) {
GCC_OPTIMIZATION_DISABLE GCC_OPTIMIZATION_DISABLE
void update(PrimitiveArena* pa, U4* ordering_buf) void update(PrimitiveArena* pa, U4* ordering_buf)
{ {
TapeBuilder tb = tb_make(slice_ut_arr(smem.MemTape));
smem.pad_state = pad_read(0);
if (0) // Pad Input
{
if (pad0_signal_(Pad_Left)) {
smem.cube.rot.y += 30;
smem.floor.rot.y += 5;
}
if (pad0_signal_(Pad_Right)) {
smem.cube.rot.y -= 30;
smem.floor.rot.y -= 5;
}
}
if (1) // Pad Input (Tape version)
{
tb.used = 0; tb_scope_run(& tb) {
tb_emit(& tb, pad_input_demo);
tb_data(& tb, smem.pad_state);
tb_data(& tb, u4_(& smem.cube.rot));
tb_data(& tb, u4_(& smem.floor.rot));
}
}
orderingtbl_clear_reverse(ordering_buf, OrderingTbl_Len); orderingtbl_clear_reverse(ordering_buf, OrderingTbl_Len);
// Update the position based on acceleration and velocity // Update the position based on acceleration and velocity
@@ -213,7 +247,6 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
A2_S2 p; //??? A2_S2 p; //???
S4 flag; //???? S4 flag; //????
TapeBuilder tb = tb_make(slice_ut_arr(smem.MemTape));
// Draw Cube // Draw Cube
if (0) if (0)
@@ -285,7 +318,7 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
} }
tape_run(tb_slice(tb)); tape_run(tb_slice(tb));
smem.cube.rot.y += 30; // smem.cube.rot.y += 30;
} }
// Draw Floor // Draw Floor
if (0) if (0)
@@ -376,7 +409,7 @@ void update(PrimitiveArena* pa, U4* ordering_buf)
tape_run(tb_slice(tb));// Fire off the tape. tape_run(tb_slice(tb));// Fire off the tape.
// C-side state (pa->used) has already been updated by the tape! // C-side state (pa->used) has already been updated by the tape!
smem.floor.rot.y += 5; // smem.floor.rot.y += 5;
} }
// --- TAPE DIAGNOSTICS --- // --- TAPE DIAGNOSTICS ---
if (0) if (0)
@@ -402,22 +435,27 @@ int main(void)
smem = (SMemory){0}; smem = (SMemory){0};
smem.scratchpad = C_(U4_V, 0x1F800000); smem.scratchpad = C_(U4_V, 0x1F800000);
smem.primitives.used = 0; smem.primitives.used = 0;
ent_cube128_init(& smem.cube.verts, & smem.cube.faces); { {
Ent_Cube* cube = & smem.cube; ent_cube128_init(& smem.cube.verts, & smem.cube.faces); {
cube->rot = v3s2(0, 0, 0); Ent_Cube* cube = & smem.cube;
// cube->pos = v3s4(0, 0, 900); cube->rot = v3s2(0, 0, 0);
cube->scale = v3s4_fp_one(); // cube->pos = v3s4(0, 0, 900);
cube->accel = v3s4(0, 1, 0); cube->scale = v3s4_fp_one();
cube->pos = v3s4(0, -400, 1800); cube->accel = v3s4(0, 1, 0);
cube->pos = v3s4(0, -400, 1800);
}
ent_floor_init(& smem.floor.verts, & smem.floor.faces); {
Ent_Floor* floor = & smem.floor;
floor->rot = v3s2(0, 0, 0);
floor->pos = v3s4(0, 450, 1800);
floor->scale = v3s4_fp_one();
}
} }
ent_floor_init(& smem.floor.verts, & smem.floor.faces); { {
Ent_Floor* floor = & smem.floor; // gknown gp_screen_init();
floor->rot = v3s2(0, 0, 0); gp_screen_init_c11(& smem.screen_buf, & smem.active_buf_id);
floor->pos = v3s4(0, 450, 1800); pad_init(0);
floor->scale = v3s4_fp_one();
} }
// gknown gp_screen_init();
gp_screen_init_c11(& smem.screen_buf, & smem.active_buf_id);
while (1) { while (1) {
gknown S4* active_buf_id = & smem.active_buf_id; gknown S4* active_buf_id = & smem.active_buf_id;
gknown U4* ordering_buf = r_(smem.ordering_tbl)[active_buf_id[0]]; gknown U4* ordering_buf = r_(smem.ordering_tbl)[active_buf_id[0]];
+21 -21
View File
@@ -43,25 +43,25 @@ typedef Struct_(DoubleBuffer) {
#define ScreenRes_CenterX (ScreenRes_X >> 1) #define ScreenRes_CenterX (ScreenRes_X >> 1)
#define ScreenRes_CenterY (ScreenRes_Y >> 1) #define ScreenRes_CenterY (ScreenRes_Y >> 1)
DisplayEnv* displayenv_init(DisplayEnv* env, S4 x, S4 y, S4 w, S4 h) __asm__("SetDefDispEnv"); DisplayEnv* displayenv_init(DisplayEnv* env, S4 x, S4 y, S4 w, S4 h) asm("SetDefDispEnv");
DrawEnv* drawenv_init (DrawEnv* env, S4 x, S4 y, S4 w, S4 h) __asm__("SetDefDrawEnv"); DrawEnv* drawenv_init (DrawEnv* env, S4 x, S4 y, S4 w, S4 h) asm("SetDefDrawEnv");
DisplayEnv* displayenv_put(DisplayEnv* env) __asm__("PutDispEnv"); DisplayEnv* displayenv_put(DisplayEnv* env) asm("PutDispEnv");
DrawEnv* drawenv_put (DrawEnv* env) __asm__("PutDrawEnv"); DrawEnv* drawenv_put (DrawEnv* env) asm("PutDrawEnv");
U4 geom_init(void) __asm__("InitGeom"); U4 geom_init(void) asm("InitGeom");
void geom_set_offset(U4 x, U4 y) __asm__("SetGeomOffset"); void geom_set_offset(U4 x, U4 y) asm("SetGeomOffset");
void geom_set_screen(U4 h) __asm__("SetGeomScreen"); void geom_set_screen(U4 h) asm("SetGeomScreen");
U4* orderingtbl_clear_reverse(U4* ot, U4 len) __asm__("ClearOTagR"); U4* orderingtbl_clear_reverse(U4* ot, U4 len) asm("ClearOTagR");
U4 reset_graph(U4 mode) __asm__("ResetGraph"); U4 reset_graph(U4 mode) asm("ResetGraph");
void set_display_enabled(U4 mask) __asm__("SetDispMask"); void set_display_enabled(U4 mask) asm("SetDispMask");
U4 draw_sync(U4 mode) __asm__("DrawSync"); U4 draw_sync(U4 mode) asm("DrawSync");
U4 vsync(U4 mode) __asm__("VSync"); U4 vsync(U4 mode) asm("VSync");
void draw_orderingtbl(U4* buf) __asm__("DrawOTag"); void draw_orderingtbl(U4* buf) asm("DrawOTag");
typedef Struct_(Tile) { typedef Struct_(Tile) {
U4 tag; U4 tag;
@@ -74,16 +74,16 @@ typedef Struct_(Tile) {
Linear Algebra Linear Algebra
*/ */
M3_S2* m3s2_rotation (V3_S2* vec, M3_S2* mat) __asm__("RotMatrix"); M3_S2* m3s2_rotation (V3_S2* vec, M3_S2* mat) asm("RotMatrix");
M3_S2* m3s2_translation(M3_S2* mat, V3_S4* vec) __asm__("TransMatrix"); M3_S2* m3s2_translation(M3_S2* mat, V3_S4* vec) asm("TransMatrix");
M3_S2* m3s2_scale (M3_S2* mat, V3_S4* vec) __asm__("ScaleMatrix"); M3_S2* m3s2_scale (M3_S2* mat, V3_S4* vec) asm("ScaleMatrix");
// Rotation, Translation, Perspective // Rotation, Translation, Perspective
S4 rtp_v3s2_raw(V3_S2* vec, S4* xy, S4* pp, S4* flag) __asm__("RotTransPers"); S4 rtp_v3s2_raw(V3_S2* vec, S4* xy, S4* pp, S4* flag) asm("RotTransPers");
FI_ S4 rtp_v3s2(V3_S2* vec, V2_S2* xy, A2_S2* pp, S4* flag) { return rtp_v3s2_raw(vec, C_(S4*R_, & xy->x), C_(S4*R_, pp), r_(flag)); } FI_ S4 rtp_v3s2(V3_S2* vec, V2_S2* xy, A2_S2* pp, S4* flag) { return rtp_v3s2_raw(vec, C_(S4*R_, & xy->x), C_(S4*R_, pp), r_(flag)); }
S4 rtp_avg_nclip_a3_v3s2_raw(V3_S2* v0, V3_S2* v1, V3_S2* v2, S4* xy1, S4* xy2, S4* xy3, S4* pp, S4* otz, S4* flag) __asm__("RotAverageNclip3"); S4 rtp_avg_nclip_a3_v3s2_raw(V3_S2* v0, V3_S2* v1, V3_S2* v2, S4* xy1, S4* xy2, S4* xy3, S4* pp, S4* otz, S4* flag) asm("RotAverageNclip3");
FI_ S4 rtp_avg_nclip_a3_v3s2( FI_ S4 rtp_avg_nclip_a3_v3s2(
V3_S2* v0, V3_S2* v1, V3_S2* v2, V3_S2* v0, V3_S2* v1, V3_S2* v2,
V2_S2* xy0, V2_S2* xy1, V2_S2* xy2, V2_S2* xy0, V2_S2* xy1, V2_S2* xy2,
@@ -96,7 +96,7 @@ FI_ S4 rtp_avg_nclip_a3_v3s2(
); );
} }
S4 rtp_avg_nclip_a4_v3s2_raw(V3_S2* v0, V3_S2* v1, V3_S2* v2, V3_S2* v3, S4* xy1, S4* xy2, S4* xy3, S4* xy4, S4* pp, S4* otz, S4* flag) __asm__("RotAverageNclip4"); S4 rtp_avg_nclip_a4_v3s2_raw(V3_S2* v0, V3_S2* v1, V3_S2* v2, V3_S2* v3, S4* xy1, S4* xy2, S4* xy3, S4* xy4, S4* pp, S4* otz, S4* flag) asm("RotAverageNclip4");
FI_ S4 rtp_avg_nclip_a4_v3s2( FI_ S4 rtp_avg_nclip_a4_v3s2(
V3_S2* v0, V3_S2* v1, V3_S2* v2, V3_S2* v3, V3_S2* v0, V3_S2* v1, V3_S2* v2, V3_S2* v3,
V2_S2* xy0, V2_S2* xy1, V2_S2* xy2, V2_S2* xy3, V2_S2* xy0, V2_S2* xy1, V2_S2* xy2, V2_S2* xy3,
@@ -109,8 +109,8 @@ FI_ S4 rtp_avg_nclip_a4_v3s2(
); );
} }
void gte_matrix_set_rotation (M3_S2* mat) __asm__("SetRotMatrix"); void gte_matrix_set_rotation (M3_S2* mat) asm("SetRotMatrix");
void gte_matrix_set_translation(M3_S2* mat) __asm__("SetTransMatrix"); void gte_matrix_set_translation(M3_S2* mat) asm("SetTransMatrix");
enum { enum {
fp_one = (1 << 12), fp_one = (1 << 12),
+58 -13
View File
@@ -16,6 +16,49 @@
#pragma region Baked Atoms #pragma region Baked Atoms
enum {
R_PadState = R_T4 atom_reg atom_type(U4),
R_PadSignal = R_T0 atom_reg atom_type(U4),
R_CubeRot = R_T1 atom_reg atom_type(V3_S2*),
R_FloorRot = R_T2 atom_reg atom_type(V3_S2*),
};
typedef Struct_(Binds_PadInputDemo) {
U4 pad_state;
V3_S2* cube_rot;
V3_S2* floor_rot;
};
internal MipsAtom_(pad_input_demo) atom_info(atom_bind(Binds_PadInputDemo)
, atom_reads(R_PadState, R_CubeRot, R_FloorRot)
, atom_writes( R_CubeRot, R_FloorRot)
) {
load_word(R_PadState, R_TapePtr, O_(Binds_PadInputDemo,pad_state)),
load_word(R_CubeRot, R_TapePtr, O_(Binds_PadInputDemo,cube_rot)),
load_word(R_FloorRot, R_TapePtr, O_(Binds_PadInputDemo,floor_rot)),
add_ui_self( R_TapePtr, S_(Binds_PadInputDemo)),
and_i(R_PadSignal, R_PadState, pad0_(Pad_Left)),
branch_le_zero(R_PadSignal, atom_offset(pad_left, exit_pad_left)),
load_half( R_T5, R_CubeRot, O_(V3_S2,y)), // BD-Slot occupied
load_half( R_T6, R_FloorRot, O_(V3_S2,y)),
add_si( R_T5, R_T5, 30),
add_si( R_T6, R_T6, 5),
store_half(R_T5, R_CubeRot, O_(V3_S2,y)),
store_half(R_T6, R_FloorRot, O_(V3_S2,y)),
atom_label(exit_pad_left)
and_i(R_PadSignal, R_PadState, pad0_(Pad_Right)),
branch_le_zero(R_PadSignal, atom_offset(pad_right, exit_pad_right)),
load_half( R_T5, R_CubeRot, O_(V3_S2,y)), // BD-Slot occupied
load_half( R_T6, R_FloorRot, O_(V3_S2,y)),
add_si( R_T5, R_T5, -30),
add_si( R_T6, R_T6, -5),
store_half(R_T5, R_CubeRot, O_(V3_S2,y)),
store_half(R_T6, R_FloorRot, O_(V3_S2,y)),
atom_label(exit_pad_right)
mac_yield(),
};
typedef Struct_(Binds_CubeTri) { typedef Struct_(Binds_CubeTri) {
U4 PrimCursor; U4 PrimCursor;
V4_S2* FaceCursor; V4_S2* FaceCursor;
@@ -116,20 +159,22 @@ MipsAtom_(floor_f3_face) atom_info(atom_phase(floor_f3)
/* Culling (Branch forward if Backface) */ /* Culling (Branch forward if Backface) */
gte_mv_from_data_r(R_T0, C2_MAC0), gte_mv_from_data_r(R_T0, C2_MAC0),
nop, branch_le_zero(R_T0, atom_offset(culling, floor_f3_face_exit)), nop, // required gte -> cpu load-delay slot. nop, branch_le_zero(R_T0, atom_offset(culling, floor_f3_face_exit)), nop, // required gte -> cpu load-delay slot.
/* Format Primitive */ /* Format Primitive */
mac_gte_store_f3(), mac_gte_store_f3(),
/* Calculate Depth */ /* Calculate Depth */
gte_avg_sort_z3, gte_avg_sort_z3,
gte_mv_from_data_r(R_T1, C2_OTZ), gte_mv_from_data_r(R_T1, C2_OTZ),
/* Bounds Check OTZ < 2048 (Branch forward to skip insertion) */ /* Bounds Check OTZ < 2048 (Branch forward to skip insertion) */
add_ui( R_AT, R_0, OrderingTbl_Len), add_ui( R_AT, R_0, OrderingTbl_Len),
set_lt_u( R_AT, R_T1, R_AT), set_lt_u( R_AT, R_T1, R_AT),
branch_equal(R_AT, R_0, atom_offset(bounds_chk, floor_f3_face_exit)), nop, branch_equal(R_AT, R_0, atom_offset(bounds_chk, floor_f3_face_exit)), nop,
mac_format_f3_color(0xFF, 0xFF, 0xFF), // RGB-form (R=FF, G=FF, B=FF = white) mac_format_f3_color(0xFF, 0xFF, 0xFF), // RGB-form (R=FF, G=FF, B=FF = white)
mac_insert_ot_tag_f3(), /* Insert into Ordering Table Linked List */ mac_insert_ot_tag_f3(), /* Insert into Ordering Table Linked List */
add_ui_self(R_PrimCursor, S_(Poly_F3)), /* Advance Prim Cursor (5 words) */ add_ui_self(R_PrimCursor, S_(Poly_F3)), /* Advance Prim Cursor (5 words) */
// Note(Ed): No bounds checking, should be checked before atom runs. // Note(Ed): No bounds checking, should be checked before atom runs.
// end: branch(bounds_chk)
// end: branch(culling)
/* Advance Input Cursor & Yield (Both branch targets land here) */ /* Advance Input Cursor & Yield (Both branch targets land here) */
atom_label(floor_f3_face_exit) atom_label(floor_f3_face_exit)