190 lines
6.9 KiB
Plaintext
190 lines
6.9 KiB
Plaintext
; ______ ____ ___
|
|
; | \/ ____| |___|
|
|
; | | | \ | |
|
|
;---------------------------
|
|
; Copyright 2020, tyra - https://github.com/h4570/tyra
|
|
; Sandro Sobczyński <sandro.sobczynski@gmail.com>
|
|
;
|
|
;---------------------------------------------------------------
|
|
; draw3D.vcl |
|
|
;---------------------------------------------------------------
|
|
; First tyra VU1 microprogram. |
|
|
; Features: |
|
|
; - Draw triangles (no strip) with STQ (textures) and 1 RGBA. |
|
|
; This program uses double buffering (xtop) |
|
|
; |
|
|
; I want to say thank you to: |
|
|
; - Dr Henry Fortuna - for teaching how things work |
|
|
; - Jesper Svennevid, Daniel Collin - for openvcl samples |
|
|
; - Guilherme Lampert - for VU1 idea for PS2 Quake and vclpp |
|
|
; - Tyler Daniel - for PS2GL source code for PS2 Linux |
|
|
;---------------------------------------------------------------
|
|
|
|
; TODO
|
|
; - Add dynamic lighting (feature)
|
|
; - Add --cont + MSCNT instead of alltime MSCAL
|
|
; - Split this program into two (RBA/STQ), so we can get better performance
|
|
|
|
#include "/repos/tyra/src/engine/vu1_progs/geometry.inc"
|
|
#include "/repos/tyra/src/engine/vu1_progs/matrix.inc"
|
|
#include "/repos/tyra/src/engine/vu1_progs/vector.inc"
|
|
|
|
#vuprog draw3D
|
|
|
|
.syntax new
|
|
.name VU1Draw3D
|
|
.vu
|
|
.init_vf_all
|
|
.init_vi_all
|
|
|
|
--enter
|
|
--endenter
|
|
|
|
;///////////// LOAD STATIC DATA /////////////
|
|
lq gif_draw_finish_tag, 0(vi00) ; GIF tag - wait
|
|
lq gif_set_tag, 1(vi00) ; GIF tag - set
|
|
;////////////////////////////////////////////
|
|
|
|
xtop double_buffer
|
|
|
|
;//////// LOAD CURRENT BUFFER DATA //////////
|
|
MatrixLoad{ matrix, 0, double_buffer }
|
|
ilw.x do_draw_finish, 4(double_buffer) ; Add draw finish tag? (sync)
|
|
ilw.y vertex_count, 4(double_buffer) ; Vertex count
|
|
ilw.z triangles_count, 4(double_buffer) ; Triangles count
|
|
ilw.w rgba_only, 4(double_buffer) ; RGBA (1) or STQ+RGBA (0)
|
|
lq tex_gif_tag_1, 5(double_buffer) ; GIF tag - texture LOD
|
|
lq tex_gif_tag_2, 6(double_buffer) ; GIF tag - texture buffer & CLUT
|
|
lq prim_tag, 7(double_buffer) ; GIF tag - tell GS how many data we will send
|
|
lq rgba, 8(double_buffer) ; Mesh RGBA
|
|
|
|
iaddiu vertex_data, double_buffer, 9 ; pointer to vertex data
|
|
iadd stq_data, vertex_data, vertex_count ; pointer to stq
|
|
iadd kick_address, stq_data, vertex_count ; pointer for XGKICK
|
|
iadd dest_address, stq_data, vertex_count ; helper pointer for data inserting
|
|
;////////////////////////////////////////////
|
|
|
|
LoadScaleConstant{ gs_scale }
|
|
fcset 0x000000 ; VCL won't let us use CLIP without first zeroing the clip flags
|
|
|
|
;/////////////// STORE TAGS /////////////////
|
|
sqi gif_set_tag, (dest_address++) ;
|
|
sqi tex_gif_tag_1, (dest_address++) ; texture LOD tag
|
|
sqi gif_set_tag, (dest_address++) ;
|
|
sqi tex_gif_tag_2, (dest_address++) ; texture buffer & CLUT tag
|
|
iblez do_draw_finish, prim_tag_l
|
|
sqi gif_set_tag, (dest_address++) ;
|
|
sqi gif_draw_finish_tag, (dest_address++) ; do draw_finish is needed
|
|
prim_tag_l:
|
|
sqi prim_tag, (dest_address++) ; prim + tell gs how many data will be
|
|
;////////////////////////////////////////////
|
|
|
|
;//////// FIX ADC BIT FOR CLIPPING //////////
|
|
iaddiu adc_bit, vi00, 0x7FFF
|
|
iaddiu adc_bit, adc_bit, 1
|
|
;////////////////////////////////////////////
|
|
|
|
;/////////// START TRIANGLE LOOP ////////////
|
|
iaddiu triangle_counter, vi00, 0 ; Reset counter
|
|
triangle_loop: --LoopCS 1,3
|
|
|
|
;//////////////// VERTEX 1 //////////////////
|
|
vec1:
|
|
VectorLoad{ vertex, vertex_data, 0 }
|
|
MatrixXForm{ xformed_vertex, matrix, vertex }
|
|
VectorClip{ gs_vertex, xformed_vertex }
|
|
VectorPerspectiveDivide{ xformed_vertex }
|
|
VectorAddGSScales{ gs_vertex, xformed_vertex, gs_scale }
|
|
|
|
ibgtz rgba_only, vec_1_rgba
|
|
|
|
vec_1_stq_rgba:
|
|
VectorLoad{ stq1, stq_data, 0 }
|
|
VectorTexturePerspectiveCorrection{ pers_stq, stq1 }
|
|
VectorStore{ pers_stq, dest_address, 0 }
|
|
VectorStore{ rgba, dest_address, 1 }
|
|
VectorStore{ gs_vertex, dest_address, 2 }
|
|
ibeq vi00, vi00, vec2
|
|
|
|
vec_1_rgba:
|
|
VectorStore{ rgba, dest_address, 0 }
|
|
VectorStore{ gs_vertex, dest_address, 1 }
|
|
|
|
;////////////////////////////////////////////
|
|
|
|
;//////////////// VERTEX 2 //////////////////
|
|
vec2:
|
|
VectorLoad{ vertex, vertex_data, 1 }
|
|
MatrixXForm{ xformed_vertex, matrix, vertex }
|
|
VectorClip{ gs_vertex, xformed_vertex }
|
|
VectorPerspectiveDivide{ xformed_vertex }
|
|
VectorAddGSScales{ gs_vertex, xformed_vertex, gs_scale }
|
|
|
|
ibgtz rgba_only, vec_2_rgba
|
|
|
|
vec_2_stq_rgba:
|
|
VectorLoad{ stq2, stq_data, 1 }
|
|
VectorTexturePerspectiveCorrection{ pers_stq, stq2 }
|
|
VectorStore{ pers_stq, dest_address, 3 }
|
|
VectorStore{ rgba, dest_address, 4 }
|
|
VectorStore{ gs_vertex, dest_address, 5 }
|
|
ibeq vi00, vi00, vec3
|
|
|
|
vec_2_rgba:
|
|
VectorStore{ rgba, dest_address, 2 }
|
|
VectorStore{ gs_vertex, dest_address, 3 }
|
|
|
|
;////////////////////////////////////////////
|
|
|
|
;//////////////// VERTEX 3 //////////////////
|
|
vec3:
|
|
VectorLoad{ vertex, vertex_data, 2 }
|
|
MatrixXForm{ xformed_vertex, matrix, vertex }
|
|
VectorClip{ gs_vertex, xformed_vertex }
|
|
VectorPerspectiveDivide{ xformed_vertex }
|
|
VectorAddGSScales{ gs_vertex, xformed_vertex, gs_scale }
|
|
|
|
fcand vi01, 0x03FFFF
|
|
iaddiu new_adc_bit, vi01, 0x7FFF
|
|
mfir.w gs_vertex, new_adc_bit
|
|
|
|
ibgtz rgba_only, vec_3_rgba
|
|
|
|
vec_3_stq_rgba:
|
|
VectorLoad{ stq3, stq_data, 2 }
|
|
VectorTexturePerspectiveCorrection{ pers_stq, stq3 }
|
|
VectorStore{ pers_stq, dest_address, 6 }
|
|
VectorStore{ rgba, dest_address, 7 }
|
|
VectorStore{ gs_vertex, dest_address, 8 }
|
|
iaddiu dest_address, dest_address, 9 // Loop control
|
|
ibeq vi00, vi00, loop_ctrl
|
|
|
|
vec_3_rgba:
|
|
VectorStore{ rgba, dest_address, 4 }
|
|
VectorStore{ gs_vertex, dest_address, 5 }
|
|
iaddiu dest_address, dest_address, 6 // Loop control
|
|
|
|
;////////////////////////////////////////////
|
|
|
|
;////////////// LOOP CONTROL ////////////////
|
|
loop_ctrl:
|
|
iaddiu vertex_data, vertex_data, 3
|
|
iaddiu stq_data, stq_data, 3
|
|
|
|
iaddiu triangle_counter, triangle_counter, 1 // Incrementing this
|
|
// by other value than 1 is causing HUGE problems, but.. why?
|
|
// My first idea was do vertex_counter and incrementing by 3
|
|
ibne triangle_counter, triangles_count, triangle_loop
|
|
;////////////////////////////////////////////
|
|
|
|
;////////////////////////////////////////////
|
|
|
|
--barrier
|
|
|
|
|
|
xgkick kick_address ; dispatch to the GS rasterizer.
|
|
|
|
--exit
|
|
--endexit
|
|
|
|
#endvuprog |