diff options
| author | spicyjpeg <thatspicyjpeg@gmail.com> | 2023-06-20 15:13:11 +0200 |
|---|---|---|
| committer | spicyjpeg <thatspicyjpeg@gmail.com> | 2023-06-20 15:13:11 +0200 |
| commit | d23024ceeb8e7f04b0a3bde7a0db41ae5e4fd06d (patch) | |
| tree | 03342eb22041fb7343c034e376489295e2a78a19 | |
| parent | 79a966486615e60be3a37d278945dc3dd0fd933b (diff) | |
Split off libsmd from n00bdemo into separate library
| -rw-r--r-- | doc/cmake_reference.md | 3 | ||||
| -rw-r--r-- | examples/demos/n00bdemo/disp.c | 2 | ||||
| -rw-r--r-- | examples/demos/n00bdemo/lightdemo.c | 326 | ||||
| -rw-r--r-- | examples/demos/n00bdemo/logo.c | 242 | ||||
| -rw-r--r-- | examples/demos/n00bdemo/main.c | 360 | ||||
| -rw-r--r-- | examples/demos/n00bdemo/smd.h | 68 | ||||
| -rw-r--r-- | libpsn00b/cmake/internal_setup.cmake | 1 | ||||
| -rw-r--r-- | libpsn00b/include/psxapi.h | 2 | ||||
| -rw-r--r-- | libpsn00b/include/smd/smd.h | 85 | ||||
| -rw-r--r-- | libpsn00b/include/smd/smd_s.inc (renamed from examples/demos/n00bdemo/smd_s.h) | 5 | ||||
| -rw-r--r-- | libpsn00b/smd/smd.s (renamed from examples/demos/n00bdemo/smd.s) | 332 | ||||
| -rw-r--r-- | libpsn00b/smd/smd_cel.s (renamed from examples/demos/n00bdemo/smd_cel.s) | 371 | ||||
| -rw-r--r-- | libpsn00b/smd/smd_flat.s (renamed from examples/demos/n00bdemo/smd_flat.s) | 279 | ||||
| -rw-r--r-- | libpsn00b/smd/smdparser.s (renamed from examples/demos/n00bdemo/smdparser.s) | 63 |
14 files changed, 1086 insertions, 1053 deletions
diff --git a/doc/cmake_reference.md b/doc/cmake_reference.md index ef3f5dc..169a7e6 100644 --- a/doc/cmake_reference.md +++ b/doc/cmake_reference.md @@ -76,6 +76,7 @@ the following targets are defined: - `psxsio` - `psxetc` - `psxapi` +- `smd` - `lzp` - `c` @@ -394,4 +395,4 @@ CMake's `add_custom_command()` and `add_custom_target()` to convert models and generate LZP archives as part of the build pipeline. ----------------------------------------- -_Last updated on 2022-12-18 by spicyjpeg_ +_Last updated on 2023-06-20 by spicyjpeg_ diff --git a/examples/demos/n00bdemo/disp.c b/examples/demos/n00bdemo/disp.c index a43a1d6..2e02a9d 100644 --- a/examples/demos/n00bdemo/disp.c +++ b/examples/demos/n00bdemo/disp.c @@ -3,7 +3,7 @@ #include <psxgpu.h> #include <psxgte.h> #include <inline_c.h> -#include "smd.h" +#include <smd/smd.h> #include "disp.h" DISPENV disp; diff --git a/examples/demos/n00bdemo/lightdemo.c b/examples/demos/n00bdemo/lightdemo.c index 5afd5c8..26da9ef 100644 --- a/examples/demos/n00bdemo/lightdemo.c +++ b/examples/demos/n00bdemo/lightdemo.c @@ -3,8 +3,8 @@ #include <psxgte.h> #include <psxgpu.h> #include <inline_c.h> +#include <smd/smd.h> #include "disp.h" -#include "smd.h" extern MATRIX lgt_colmtx; @@ -14,227 +14,227 @@ extern SMD *o_lightbulb; void sort_overlay(int showlotl); void lightdemo() { - + /* The point lighting demo is perhaps the most impressive part of n00bDEMO. A more streamlined version of this demo where you control various attributes of the light source such as position, intensity and color might be made as a dedicated example program in the future. - + The point lighting trick is actually not that too complicated. You basically calculate the distance and direction vector of two points which are the light source and the vertex of a polygon. - + Calculating the normal whose result can later be used to calculate the distance between two points is achieved with: - + vec_dir.vx = lgt_point.vx - pri_vert.vx; vec_dir.vy = lgt_point.vy - pri_vert.vy; vec_dir.vz = lgt_point.vz - pri_vert.vz; - + The intensity is calculated with (this might not be accurate but this is faster than applying a square root): - + i = 4096 - ( ( - (vec_dir.vx*vec_dir.vx) + - (vec_dir.vy*vec_dir.vy) + + (vec_dir.vx*vec_dir.vx) + + (vec_dir.vy*vec_dir.vy) + (vec_dir.vz*vec_dir.vz) ) >> 7 ); - + // Clip minimum intensity if( i < 0 ) i = 0; - + This intensity value is then used to set the color of the light source through the light color matrix. - + col_mtx.m[0][0] = i; col_mtx.m[1][0] = i; col_mtx.m[2][0] = i; gte_SetColorMatrix( &col_mtx ); - + The direction vector can then be used as the direction of the light source. It is recommended to normalize it first to prevent possible overflow related issues. - + VectorNormalS( &vec_dir, &vec_norm ); - + lgt_mtx.m[0][0] = vec_norm.vx; lgt_mtx.m[0][1] = vec_norm.vy; lgt_mtx.m[0][2] = vec_norm.vz; - + gte_SetLightMatrix( &lgt_mtx ); - + This operation is then performed for each point of a polygon to achieve a nice smooth shaded point lighting effect. The macros used are still the same as doing light source calculation with the GTE the normal way. - + 3D geometry still requires normal data as with most lighting processing operations. 'Flat' normals (faces with a single normal vector) work best on flat surfaces while 'smooth' normals (faces with normals on each point) work best on round or curved surfaces. - + */ - + int i,p_ang; - + SC_OT s_ot; - + SVECTOR rot; VECTOR pos; SMD_PRIM s_pri; - + VECTOR l_point; SVECTOR nrm; - + MATRIX lmtx,llmtx,omtx; - + SVECTOR orot = { 0 }; - + int timeout = SCENE_TIME; - + // Set clear color to black setRGB0( &draw, 0, 0, 0 ); - + // Base values for the environment geometry setVector( &pos, 0, 0, 600 ); setVector( &rot, 512, 0, 0 ); - + // Set base tpage value for the SMD drawing routines smdSetBaseTPage( 0x200 ); - + // Set back or ambient color to black for pure darkness gte_SetBackColor( 0, 0, 0 ); - + memset( &llmtx, 0, sizeof(MATRIX) ); - - + + // demo loop while( 1 ) { - + char buff[32]; - + RotMatrix( &rot, &mtx ); TransMatrix( &mtx, &pos ); - + rot.vy += 4; - + gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); - - + + setVector( &l_point, (icos( p_ang )>>2)>>2, -350+(icos( p_ang<<1 )>>4), (isin( p_ang )>>2)>>2 ); p_ang += 16; - - + + // Begin parsing the SMD data of the environment OpenSMD( o_world ); - + // Prototype point lighting renderer while( ReadSMD( &s_pri ) ) { - + VECTOR v_dir; SVECTOR v_nrm; VECTOR v_sqr; - + int flg; - + if( s_pri.prim_id.texture ) { - + POLY_GT4 *pri; - + // Perform standard rotate, translate and perspective // transformation of the geometry pri = (POLY_GT4*)nextpri; - - gte_ldv3( + + gte_ldv3( &o_world->p_verts[s_pri.v0], &o_world->p_verts[s_pri.v1], &o_world->p_verts[s_pri.v2] ); - + gte_rtpt(); - + gte_nclip(); // Backface culling - + gte_stopz( &flg ); - + if( flg < 0 ) continue; - + gte_stsxy3( &pri->x0, &pri->x1, &pri->x2 ); - + gte_ldv0( &o_world->p_verts[s_pri.v3] ); gte_rtps(); - + gte_avsz4(); // Depth sort gte_stotz( &flg ); - + if( (flg>>2) >= OT_LEN ) continue; - + gte_stsxy( &pri->x3 ); - - + + // Load base color of polygon to GTE gte_ldrgb( &s_pri.r0 ); - + // Load normal of polygon gte_ldv0( &o_world->p_norms[s_pri.n0] ); - + // Calculate the direction between the vertex of the // polygon and the light source v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v0].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v0].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v0].vz; - + // Calculate distance and light intensity using square i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + // Clip minimum intensity if( i < 0 ) i = 0; - + // Set intensity to color matrix llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; gte_SetColorMatrix( &llmtx ); - + // Normalize light direction and set it to light matrix VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; lmtx.m[0][1] = v_nrm.vy; lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); - + // Calculate (output is retrieved through gte_strgb) gte_nccs(); - - + + // Repeat process for the next 3 vertices v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v1].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v1].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v1].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - - + + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; - + gte_strgb( &pri->r0 ); - + gte_SetColorMatrix( &llmtx ); VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; @@ -242,25 +242,25 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - + v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v2].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v2].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v2].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; - + gte_strgb( &pri->r1 ); - + gte_SetColorMatrix( &llmtx ); VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; @@ -268,25 +268,25 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - + v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v3].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v3].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v3].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; - + gte_strgb( &pri->r2 ); - + gte_SetColorMatrix( &llmtx ); VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; @@ -294,70 +294,70 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - - setUV4( pri, + + setUV4( pri, s_pri.tu0, s_pri.tv0, - s_pri.tu1, s_pri.tv1, + s_pri.tu1, s_pri.tv1, s_pri.tu2, s_pri.tv2, s_pri.tu3, s_pri.tv3 ); - + pri->tpage = s_pri.tpage; pri->clut = s_pri.clut; - + setPolyGT4( pri ); addPrim( ot[db]+(flg>>2), pri ); nextpri += sizeof(POLY_GT4); - + gte_strgb( &pri->r3 ); - + } else { - + POLY_G4 *pri; - + pri = (POLY_G4*)nextpri; - - gte_ldv3( + + gte_ldv3( &o_world->p_verts[s_pri.v0], &o_world->p_verts[s_pri.v1], &o_world->p_verts[s_pri.v2] ); - + gte_rtpt(); - + gte_nclip(); - + gte_stopz( &flg ); - + if( flg < 0 ) continue; - + gte_stsxy3( &pri->x0, &pri->x1, &pri->x2 ); - + gte_ldv0( &o_world->p_verts[s_pri.v3] ); gte_rtps(); - + gte_avsz4(); gte_stotz( &flg ); - + if( (flg>>2) >= OT_LEN ) continue; - + gte_stsxy( &pri->x3 ); - + gte_ldrgb( &s_pri.r0 ); gte_ldv0( &o_world->p_norms[s_pri.n0] ); - + v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v0].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v0].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v0].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; @@ -368,26 +368,26 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - - + + v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v1].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v1].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v1].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; - + gte_strgb( &pri->r0 ); - + gte_SetColorMatrix( &llmtx ); VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; @@ -395,25 +395,25 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - + v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v2].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v2].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v2].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; - + gte_strgb( &pri->r1 ); - + gte_SetColorMatrix( &llmtx ); VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; @@ -421,25 +421,25 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - + v_dir.vx = l_point.vx - o_world->p_verts[s_pri.v3].vx; v_dir.vy = l_point.vy - o_world->p_verts[s_pri.v3].vy; v_dir.vz = l_point.vz - o_world->p_verts[s_pri.v3].vz; - + i = 4096 - ( ( - (v_dir.vx*v_dir.vx) + - (v_dir.vy*v_dir.vy) + + (v_dir.vx*v_dir.vx) + + (v_dir.vy*v_dir.vy) + (v_dir.vz*v_dir.vz) ) >> 7 ); - + if( i < 0 ) i = 0; - + llmtx.m[0][0] = i; llmtx.m[1][0] = i; llmtx.m[2][0] = i; - + gte_strgb( &pri->r2 ); - + gte_SetColorMatrix( &llmtx ); VectorNormalS( &v_dir, &v_nrm ); lmtx.m[0][0] = v_nrm.vx; @@ -447,49 +447,49 @@ void lightdemo() { lmtx.m[0][2] = v_nrm.vz; gte_SetLightMatrix( &lmtx ); gte_nccs(); - + setPolyG4( pri ); addPrim( ot[db]+(flg>>2), pri ); - + nextpri += sizeof(POLY_G4); - + gte_strgb( &pri->r3 ); - + } - + } - - + + // Sort the light bulb to represent the position of the light source orot.vx += 32; orot.vy += 32; orot.vz += 32; - + RotMatrix( &orot, &omtx ); TransMatrix( &omtx, &l_point ); - + CompMatrixLV( &mtx, &omtx, &mtx ); gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); - + s_ot.ot = ot[db]; s_ot.otlen = OT_LEN; s_ot.zdiv = 2; s_ot.zoff = 0; - + nextpri = smdSortModel( &s_ot, nextpri, o_lightbulb ); - + // Sort overlay and display sort_overlay( 1 ); - + display(); - + timeout--; if( timeout < 0 ) break; - + } - + }
\ No newline at end of file diff --git a/examples/demos/n00bdemo/logo.c b/examples/demos/n00bdemo/logo.c index 784c9e1..c6faf51 100644 --- a/examples/demos/n00bdemo/logo.c +++ b/examples/demos/n00bdemo/logo.c @@ -5,7 +5,7 @@ #include <psxgte.h> #include <psxgpu.h> #include <inline_c.h> -#include "smd.h" +#include <smd/smd.h> #include <lzp/lzp.h> #include "disp.h" @@ -54,29 +54,29 @@ typedef struct { extern NODE _end[]; void DumpHeap() { - + NODE *n = _end; - + printf( "--\n" ); - + while( 1 ) { - - printf( "B:%08p P:%08p N:%08p SZ:%d BS:%d\n", - n, n->prev, n->next, n->size, + + printf( "B:%08p P:%08p N:%08p SZ:%d BS:%d\n", + n, n->prev, n->next, n->size, ((unsigned int)n->next - (unsigned int)n) ); - + if ( !n->next ) break; - + n = (NODE*)n->next; - + } - + } void intro() { - + SVECTOR quad_coords[] = { { -100, -100, 0, 0 }, { 100, -100, 0, 0 }, @@ -85,18 +85,18 @@ void intro() { }; PARTICLE stars[MAX_STARS]; - + VECTOR mpos; SVECTOR mrot,trot; SC_OT s_ot; - + SMD *o_disk, *o_star, *o_text, *o_psn00b, *o_n00blogo; - + int i,count = 0; - + int logo_scale; int logo_rot; - + int logo_yvel; int logo_ypos; int logo_step; @@ -104,10 +104,10 @@ void intro() { int logo_svel; int logo_count = 0; int logo_tscale; - + int logo_n00b_spin; int logo_fade = 0; - + struct { int step; int yvel; @@ -129,7 +129,7 @@ void intro() { 3072, 0 }; - + struct { VECTOR pos; int scale; @@ -139,180 +139,180 @@ void intro() { ONE, 1024 }; - - + + i = lzpSearchFile( "mtekdisk", lz_resources ); o_disk = (SMD*)malloc( lzpFileSize( lz_resources, i ) ); lzpUnpackFile( o_disk, lz_resources, i ); smdInitData( o_disk ); - + i = lzpSearchFile( "mtektext", lz_resources ); o_text = (SMD*)malloc( lzpFileSize( lz_resources, i ) ); lzpUnpackFile( o_text, lz_resources, i ); smdInitData( o_text ); - + i = lzpSearchFile( "starsprite", lz_resources ); o_star = (SMD*)malloc( lzpFileSize( lz_resources, i ) ); lzpUnpackFile( o_star, lz_resources, i ); smdInitData( o_star ); - + i = lzpSearchFile( "psn00blogo", lz_resources ); o_psn00b = (SMD*)malloc( lzpFileSize( lz_resources, i ) ); lzpUnpackFile( o_psn00b, lz_resources, i ); smdInitData( o_psn00b ); - + i = lzpSearchFile( "n00blogo", lz_resources ); o_n00blogo = (SMD*)malloc( lzpFileSize( lz_resources, i ) ); lzpUnpackFile( o_n00blogo, lz_resources, i ); smdInitData( o_n00blogo ); - + //DumpHeap(); - - + + // Set some Scarlet global parameters smdSetBaseTPage( 0x200 ); - + // Change clear color setRGB0( &draw, 255, 255, 255 ); - + setVector( &trot, 0, 0, 0 ); - - + + // Initialize stars for( i=0; i<MAX_STARS; i++ ) { - + stars[i].x = ONE*(-200+(rand()%400)); stars[i].y = ONE*(80+(rand()%100)); - + stars[i].yvel = -(rand()%32768); stars[i].xvel = -(ONE*(10-(rand()%20))); - + stars[i].scale = 2048+(rand()%2048); stars[i].rot = ONE*(rand()%4096); stars[i].rotv = ONE*(-40+(rand()%80)); - + } - + logo_n00b_spin = ONE+1024; - + while( logo_count < 1320 ) { - + if( logo_count < 700 ) { - + if( logo_count > 360 ) { mtek.spin -= mtek.spinvel; mtek.spinvel += 1280; } - + setVector( &mpos, 0, -(mtek.ypos>>12)-20, 400 ); setVector( &mrot, 0, mtek.spin>>12, mtek.rot>>12 ); - + RotMatrix( &mrot, &mtx ); TransMatrix( &mtx, &mpos ); setVector( &mpos, mtek.scale, mtek.scale, 4096 ); ScaleMatrix( &mtx, &mpos ); - + gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); - + nextpri = smdSortModelFlat( ot[db]+10, nextpri, o_disk ); - + if( mtek.step > 0 ) { - + setVector( &mpos, 0, 180, 400 ); TransMatrix( &mtx, &mpos ); gte_SetTransMatrix( &mtx ); - + nextpri = smdSortModelFlat( ot[db]+8, nextpri, o_text ); - + if( logo_count < 480 ) { - + SVECTOR srot; - + for( i=0; i<MAX_STARS; i++ ) { - + setVector( &mpos, stars[i].x>>12, stars[i].y>>12, 320 ); setVector( &srot, 0, 0, stars[i].rot>>12 ); - + stars[i].x += stars[i].xvel; stars[i].y += stars[i].yvel; - + stars[i].yvel += 512; stars[i].rot += stars[i].rotv; - + RotMatrix( &srot, &mtx ); TransMatrix( &mtx, &mpos ); - + setVector( &mpos, stars[i].scale, stars[i].scale, 4096 ); ScaleMatrix( &mtx, &mpos ); - + gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); - + nextpri = smdSortModelFlat( ot[db]+6, nextpri, o_star ); - + } - + } - + } - + if( !mtek.step ) { mtek.rot -= ONE*20; } else if( mtek.step == 1 ) { mtek.rot += ( -mtek.rot )>>4; } - - + + if( mtek.step < 2 ) { mtek.scale += (ONE-mtek.scale )>>5; mtek.yvel += 512; mtek.ypos -= mtek.yvel; } - - + + if( ( mtek.ypos <= 0 ) && ( mtek.yvel > 0 ) ) { mtek.yvel = -ONE*6; mtek.step++; } - + // Does the transition effect if( logo_count > 480 ) { - + TILE *rect = (TILE*)nextpri; - + mtek.trot += 16; - + setTile( rect ); setXY0( rect, 0, 0 ); setWH( rect, 640, 511 ); setRGB0( rect, 0, 0, 0 ); addPrim( ot[db]+4, rect ); nextpri += sizeof(TILE); - + setVector( &mrot, 0, 0, mtek.trot ); setVector( &mpos, mtek.tscale, mtek.tscale, 4096 ); - + RotMatrix( &mrot, &mtx ); ScaleMatrix( &mtx, &mpos ); - + gte_SetRotMatrix( &mtx ); - + for( i=0; i<6; i++ ) { - + MASKP_F4 *pol4 = (MASKP_F4*)nextpri; - + setVector( &mpos, -100+(100*(i%3)), -60+(120*(i/3)), 160 ); TransMatrix( &mtx, &mpos ); gte_SetTransMatrix( &mtx ); - + pol4->tag = 0x08000000; pol4->tpage = 0xe1000020; pol4->mask1 = 0xe6000001; pol4->mask2 = 0xe6000002; pol4->code = 0x2A; - + gte_ldv3( &quad_coords[0], &quad_coords[1], &quad_coords[2] ); gte_rtpt(); gte_stsxy0( &pol4->x0 ); @@ -320,111 +320,111 @@ void intro() { gte_rtps(); gte_stsxy3( &pol4->x1, &pol4->x2, &pol4->x3 ); setRGB0( pol4, 0, 0, 0 ); - + addPrim( ot[db]+4, pol4 ); nextpri += sizeof(MASKP_F4); - + } - + mtek.tscale += ( -mtek.tscale )>>6; - + } - + } else { - + setRGB0( &draw, 0, 0, 0 ); - + } - + if( logo_count >= 480 ) { - + if( logo_count > 840 ) { - + psn00b.pos.vx += ((ONE*-450)-psn00b.pos.vx)>>4; psn00b.pos.vy += ((ONE*350)-psn00b.pos.vy)>>4; - + setVector( &mpos, 0, 0, 600 ); mpos.vx = psn00b.pos.vx>>12; mpos.vy = psn00b.pos.vy>>12; - + psn00b.scale += ( 1536-psn00b.scale )>>4; - + setVector( &mrot, 0, 0, 0 ); - + RotMatrix( &mrot, &mtx ); TransMatrix( &mtx, &mpos ); - + setVector( &mpos, psn00b.scale, psn00b.scale, ONE ); - + ScaleMatrix( &mtx, &mpos ); - + } else { - + setVector( &mpos, 0, 0, 600 ); setVector( &mrot, 0, logo_n00b_spin, 0 ); - + RotMatrix( &mrot, &mtx ); TransMatrix( &mtx, &mpos ); - + logo_n00b_spin += ( -logo_n00b_spin )>>6; - + } - + gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); - + nextpri = smdSortModelFlat( ot[db]+3, nextpri, o_psn00b ); - + if( logo_count > 900 ) { - + setVector( &mpos, 0, 0, 250 ); setVector( &mrot, psn00b.scarlet_spin, 0, 0 ); - + RotMatrix( &mrot, &mtx ); TransMatrix( &mtx, &mpos ); - + gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); - + nextpri = smdSortModelFlat( ot[db]+3, nextpri, o_n00blogo ); - + psn00b.scarlet_spin += ( -psn00b.scarlet_spin )>>6; - + } - + } - + if( logo_count > 1200 ) { - + FADERECT *fade = (FADERECT*)nextpri; - + fade->tag = 0x04000000; fade->tpage = 0xe1000040; fade->code = 0x62; - + setRGB0( fade, logo_fade, logo_fade, logo_fade ); setXY0( fade, 0, 0 ); setWH( fade, 640, 480 ); addPrim( ot[db]+2, fade ); - + if( logo_fade < 250 ) { logo_fade += 4; } - + nextpri += sizeof(FADERECT); - + } - + display(); - + logo_count++; - + } - + free( o_disk ); free( o_text ); free( o_star ); free( o_psn00b ); free( o_n00blogo ); - + } diff --git a/examples/demos/n00bdemo/main.c b/examples/demos/n00bdemo/main.c index 55dbbc4..d607495 100644 --- a/examples/demos/n00bdemo/main.c +++ b/examples/demos/n00bdemo/main.c @@ -1,4 +1,4 @@ -/* +/* * LibPSn00b Example Programs * * n00bDEMO Source Code @@ -41,8 +41,8 @@ #include <string.h> #include <lzp/lzp.h> #include <lzp/lzqlp.h> +#include <smd/smd.h> -#include "smd.h" #include "data.h" #include "disp.h" #include "logo.h" @@ -119,16 +119,16 @@ void UploadTIM(TIM_IMAGE *tim) { /* Very simple texture upload function */ - + LoadImage( tim->prect, tim->paddr ); - + if( tim->mode & 0x8 ) LoadImage( tim->crect, tim->caddr ); - + } void loadTextures() { - + /* Unpack textures from an embedded LZP archive and upload them to VRAM. */ @@ -136,241 +136,241 @@ void loadTextures() { int *ttim,j; QLP_HEAD *tex_buff; TIM_IMAGE tim; - + i = lzpSearchFile( "textures", lz_resources ); tex_buff = (QLP_HEAD*)malloc( lzpFileSize( lz_resources, i ) ); lzpUnpackFile( tex_buff, lz_resources, i ); - + for( j=0; j<qlpFileCount( tex_buff )-4; j++ ) { - + if( !GetTimInfo( (u_long*)qlpFileAddr( j, tex_buff ), &tim ) ) { - + UploadTIM( &tim ); - + } - + } - - - GetTimInfo( (u_long*)qlpFileAddr( + + + GetTimInfo( (u_long*)qlpFileAddr( qlpFindFile( "n00blogo", tex_buff ), tex_buff ), &tim ); - + UploadTIM( &tim ); - + psn00b_tpage = getTPage( 0, 0, tim.prect->x, tim.prect->y )|0x200; setSprt( &psn00b_sprite ); setClut( &psn00b_sprite, tim.crect->x, tim.crect->y ); setWH( &psn00b_sprite, tim.prect->w<<2, tim.prect->h ); setUV0( &psn00b_sprite, (tim.prect->x%64)<<2, tim.prect->y ); setRGB0( &psn00b_sprite, 128, 128, 128 ); - - - GetTimInfo( (u_long*)qlpFileAddr( + + + GetTimInfo( (u_long*)qlpFileAddr( qlpFindFile( "lamelotl", tex_buff ), tex_buff ), &tim ); - + UploadTIM( &tim ); - + lamelotl_tpage = getTPage( 0, 0, tim.prect->x, tim.prect->y )|0x200; setSprt( &llotl_sprite ); setClut( &llotl_sprite, tim.crect->x, tim.crect->y ); setWH( &llotl_sprite, tim.prect->w<<2, tim.prect->h ); setUV0( &llotl_sprite, 0, 0 ); setRGB0( &llotl_sprite, 128, 128, 128 ); - - - GetTimInfo( (u_long*)qlpFileAddr( + + + GetTimInfo( (u_long*)qlpFileAddr( qlpFindFile( "celmap", tex_buff ), tex_buff ), &tim ); - + UploadTIM( &tim ); - + smdSetCelTex( getTPage( 0, 2, tim.prect->x, tim.prect->y )|0x200, getClut( tim.crect->x, tim.crect->y ) ); smdSetCelParam( 3, 3, 0x4f4f4f ); - - - GetTimInfo( (u_long*)qlpFileAddr( + + + GetTimInfo( (u_long*)qlpFileAddr( qlpFindFile( "font", tex_buff ), tex_buff ), &tim ); - + UploadTIM( &tim ); - + font_tpage = getTPage( 0, 1, tim.prect->x, tim.prect->y )|0x200; font_clut = getClut( tim.crect->x, tim.crect->y ); - + free( tex_buff ); } - + void unpackModels() { - + /* Unpack model data from an embedded LZP archive. */ - + int i; - + i = lzpSearchFile( "rbowshade", lz_resources ); o_rbowshade = (SMD*)malloc( lzpFileSize( lz_resources, i ) ); lzpUnpackFile( o_rbowshade, lz_resources, i ); smdInitData( o_rbowshade ); - + i = lzpSearchFile( "bungirl", lz_resources ); o_bungirl = (SMD*)malloc( lzpFileSize( lz_resources, i ) ); lzpUnpackFile( o_bungirl, lz_resources, i ); smdInitData( o_bungirl ); - + i = lzpSearchFile( "lightworld", lz_resources ); o_world = (SMD*)malloc( lzpFileSize( lz_resources, i ) ); lzpUnpackFile( o_world, lz_resources, i ); smdInitData( o_world ); - + i = lzpSearchFile( "lightbulb", lz_resources ); o_lightbulb = (SMD*)malloc( lzpFileSize( lz_resources, i ) ); lzpUnpackFile( o_lightbulb, lz_resources, i ); smdInitData( o_lightbulb ); - + i = lzpSearchFile( "timerift", lz_resources ); o_timerift = (SMD*)malloc( lzpFileSize( lz_resources, i ) ); lzpUnpackFile( o_timerift, lz_resources, i ); smdInitData( o_timerift ); - + i = lzpSearchFile( "starmask", lz_resources ); o_star = (SMD*)malloc( lzpFileSize( lz_resources, i ) ); lzpUnpackFile( o_star, lz_resources, i ); smdInitData( o_star ); - + i = lzpSearchFile( "hatkid", lz_resources ); o_hatkid = (SMD*)malloc( lzpFileSize( lz_resources, i ) ); lzpUnpackFile( o_hatkid, lz_resources, i ); smdInitData( o_hatkid ); - + } void init() { // Init display initDisplay(); timerSetup(); - + FntLoad( 960, 0 ); - + // Just to remove all sound SpuInit(); - + // Load all textures loadTextures(); - + } // Bungirl stuff void bungirldemo() { - + /* The bunny girl demo is just a simple demonstration of rendering a 1390 polygon 3D model of a bunny girl with lighting using SMD drawing routines from Scarlet Engine. */ - + SC_OT s_ot; - + MATRIX lmtx; - + SVECTOR rot,brot,srot; VECTOR pos; - + int timeout = SCENE_TIME; - + // Set clear color setRGB0( &draw, 63, 0, 127 ); - + // Set tpage base value for SMD drawing routines smdSetBaseTPage( 0x200 ); - + // Set initial rotation values setVector( &rot, 192, 0, 0 ); setVector( &brot, 0, 0, 128 ); setVector( &srot, 0, 0, 0 ); - + // Set lighting color matrix gte_SetColorMatrix( &lgt_colmtx ); - + // Set 'backside' or ambient light color gte_SetBackColor( 113, 113, 113 ); - - + + // Demo loop while( 1 ) { - + // Bungirl position setVector( &pos, 0, 50, 350 ); - + TransMatrix( &mtx, &pos ); RotMatrix( &brot, &mtx ); - + // Calculate light matrix lmtx.m[0][0] = isin( -brot.vy<<2 ); lmtx.m[0][1] = -2048; lmtx.m[0][2] = icos( -brot.vy<<2 ); - + MulMatrix0( &lmtx, &mtx, &lmtx ); - + // Set matrices gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); gte_SetLightMatrix( &lmtx ); - + // Sort the bungirl model s_ot.ot = ot[db]; s_ot.otlen = OT_LEN; s_ot.zdiv = 1; s_ot.zoff = 0; nextpri = smdSortModel( &s_ot, nextpri, o_bungirl ); - - + + // Sort the rotating rainbow background setVector( &pos, 0, 0, 200 ); - + TransMatrix( &mtx, &pos ); RotMatrix( &srot, &mtx ); - + gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); nextpri = smdSortModelFlat( ot[db]+(OT_LEN-1), nextpri, o_rbowshade ); - + brot.vy += 8; srot.vz += 4; - - + + // Sort overlay then display sort_overlay( 0 ); - + display(); - + timeout--; if( timeout < 0 ) break; - + } } // Stencil effect stuff void stencilstuff() { - - /* + + /* The stencil demo is achieved by utilizing the mask bit setting primitive GP0(E6h). The structure of this primitive is defined as DR_STP initialized and set by setDrawStp(). - + The DR_STP primitive controls mask bit operations for drawing primitives such as setting mask bits on every pixel drawn or mask bit test where pixels won't be drawn on pixels with the mask bit set. It applies to most graphics drawing primitives except VRAM fill. The mask bits are stored in the 16th bit of each pixel drawn. - + The semi-transparency bits of a texture always carry over as mask bits in textured primitives. The only way to clear mask bits is by using VRAM fill commands or drawing primitives with the set mask bit operation disabled. - + The stencil effect featured in this demo is achieved by enabling set mask bit with DR_STP, drawing semi-transparent primitives using additive blending but color is all zero to make it completely invisible @@ -380,96 +380,96 @@ void stencilstuff() { drawing the scene that will be 'below' the mask layer. */ int timeout = SCENE_TIME; - + int spin=0; - + DR_STP *mask; TILE *rect; - + SC_OT s_ot; - + SVECTOR rot; SVECTOR srot; VECTOR pos; - + // Set clear color setRGB0( &draw, 127, 0, 63 ); - + // Set tpage base value for SMD drawing routines smdSetBaseTPage( 0x200 ); - + // Base rotation coordinates setVector( &rot, 0, 0, 0 ); setVector( &srot, 0, 0, 0 ); - + // Set perspective gte_SetGeomScreen( 320 ); - - + + // Demo loop while( timeout > 0 ) { - - + + // Draw the timerift background setVector( &rot, 0, spin, 0 ); setVector( &pos, 0, 0, 0 ); - + TransMatrix( &mtx, &pos ); RotMatrix( &rot, &mtx ); - + gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); - + s_ot.ot = ot[db]; s_ot.otlen = 32; s_ot.zdiv = 2; s_ot.zoff = 20; - + nextpri = smdSortModelFlat( ot[db]+(OT_LEN-1), nextpri, o_timerift ); - - + + // Sort mask primitive that enables setting mask bits mask = (DR_STP*)nextpri; setDrawStp( mask, 1, 0 ); addPrim( ot[db]+20, mask ); nextpri += sizeof(DR_STP); - - + + // Sort the stars setVector( &rot, 0, 0, spin<<2 ); - setVector( &pos, - (isin(spin<<2)*icos(spin))>>16, + setVector( &pos, + (isin(spin<<2)*icos(spin))>>16, (icos(spin<<2)*isin(spin))>>16, 400 ); - + TransMatrix( &mtx, &pos ); RotMatrix( &rot, &mtx ); - + gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); - + nextpri = smdSortModelFlat( ot[db]+19, nextpri, o_star ); - + setVector( &rot, 0, 0, -spin<<2 ); - setVector( &pos, - (isin(-spin<<2)*icos(-spin))>>16, + setVector( &pos, + (isin(-spin<<2)*icos(-spin))>>16, (icos(-spin<<2)*isin(-spin))>>16, 400 ); - + TransMatrix( &mtx, &pos ); RotMatrix( &rot, &mtx ); - + gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); - + nextpri = smdSortModelFlat( ot[db]+19, nextpri, o_star ); - - + + // Sort mask primitive that enables mask bit test mask = (DR_STP*)nextpri; setDrawStp( mask, 0, 1 ); addPrim( ot[db]+18, mask ); nextpri += sizeof(DR_STP); - + // Sort rectangle that fills the screen rect = (TILE*)nextpri; setTile( rect ); @@ -478,119 +478,119 @@ void stencilstuff() { setRGB0( rect, 128, 0, 255 ); addPrim( ot[db]+17, rect ); nextpri += sizeof(TILE); - - + + // Clear all mask settings mask = (DR_STP*)nextpri; setDrawStp( mask, 0, 0 ); addPrim( ot[db]+15, mask ); nextpri += sizeof(DR_STP); - + // Sort overlay then display sort_overlay( 0 ); - + display(); - + spin += 4; timeout--; } - + } // Orbiting around cel-shaded hatkid stuff void hatkidstuff() { - + /* The cel-shading effect works in a similar manner as conventional per-vertex light source calculation except the color values are used - in a different manner. The resulting color values are divided down + in a different manner. The resulting color values are divided down using bit shifts to fit as texture coordinates (usually within the range of 0-31) which are then used to map to a shading map which is a simple texture of 3 to 4 shading levels. This technique is very similar to how cel-shading is achieved on the Gamecube except all the vertex to texture coordinate conversion is all done on the GX itself. - + To achieve this effect on untextured and textured polygons seamlessly the shading map is drawn over the original unshaded polygons of the model as semi-transparent polygons with subtractive blending. The shading map had to be inverted for this effect to work properly since blending is subtractive and not multiplicative after all. */ - + int timeout = SCENE_TIME; int spin=0; - + SC_OT s_ot; - + MATRIX lmtx; - + SVECTOR rot; VECTOR pos; - + // Set clear color setRGB0( &draw, 127, 0, 63 ); - + // Sets base TPage value for SMD drawing routines smdSetBaseTPage( 0x200 ); - + setVector( &rot, 0, 0, 0 ); - + // Set light color matrix gte_SetColorMatrix( &lgt_colmtx ); - + // Set back/ambient color to black (required for good cel-shading) gte_SetBackColor( 0, 0, 0 ); - + gte_SetGeomScreen( 320 ); - + // Demo loop while( timeout > 0 ) { - + // Sort 3D timerift background setVector( &rot, spin, spin, spin>>1 ); setVector( &pos, 0, 0, 0 ); - + TransMatrix( &mtx, &pos ); RotMatrix( &rot, &mtx ); - + // Fixed light source direction lmtx.m[0][0] = -2048; lmtx.m[0][1] = -2048; lmtx.m[0][2] = -2048; - + // Multiply by rotation matrix to make it relative to the camera rotation MulMatrix0( &lmtx, &mtx, &lmtx ); - + gte_SetLightMatrix( &lmtx ); gte_SetRotMatrix( &mtx ); gte_SetTransMatrix( &mtx ); - + nextpri = smdSortModelFlat( ot[db]+(OT_LEN-1), nextpri, o_timerift ); - - + + // Sort the cel-shaded hatkid setVector( &pos, 0, 0, 600 ); TransMatrix( &mtx, &pos ); gte_SetTransMatrix( &mtx ); - + s_ot.ot = ot[db]; s_ot.otlen = 250; s_ot.zdiv = 1; s_ot.zoff = 0; - + nextpri = smdSortModelCel( &s_ot, nextpri, o_hatkid ); - + // Sort overlay then display sort_overlay( 1 ); display(); - + spin += 8; timeout--; - + } - + } // Plasma stuff @@ -598,101 +598,101 @@ void genPlasma(char *out, int count); char *sortPlasma(u_long *ot, char *pri, char *map); void plasmastuff() { - + DR_TPAGE* tp; char plasbuff[1271]; - + int pcount = 0; int timeout = SCENE_TIME; - + while( timeout > 0 ) { - + genPlasma( plasbuff, pcount ); nextpri = sortPlasma( ot[db]+1, nextpri, plasbuff ); - + sort_overlay( 1 ); - + display(); timeout--; pcount++; - + } - + } // Simple stripe transition effect void transition() { - + int count = 0; int bheight[16] = { 0 }; - + TILE *tile = (TILE*)nextpri; draw.isbg = 0; - + while( 1 ) { - + int comp = 0; - + for( int i=0; i<16; i++ ) { - + if( bheight[i] > 0 ) { - - + + setTile( tile ); setXY0( tile, 0, 32*i ); setRGB0( tile, 0, 151, 255 ); setWH( tile, 640, bheight[i] ); addPrim( ot[db], tile ); tile++; - + if( bheight[i] < 32 ) bheight[i]++; else comp++; - + } - + } - + if( bheight[count>>1] == 0 ) bheight[count>>1] = 1; display(); count++; - + if( comp >= 16 ) break; } - + DrawSync(0); - + draw.isbg = 1; - + } int main(int argc, const char *argv[]) { - + // Init init(); - + // Do transition transition(); - + // Do Meido-Tek, PSn00bSDK and n00bDEMO logo intros intro(); - + // Unpack model data unpackModels(); - + // Demo sequence loop timer_counter = 100; while( 1 ) { - + lightdemo(); bungirldemo(); stencilstuff(); hatkidstuff(); plasmastuff(); - + } return 0; diff --git a/examples/demos/n00bdemo/smd.h b/examples/demos/n00bdemo/smd.h deleted file mode 100644 index 4306534..0000000 --- a/examples/demos/n00bdemo/smd.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef _SMD_H -#define _SMD_H - -typedef struct { - u_long *ot; - short otlen; - unsigned char zdiv,zoff; -} SC_OT; - -typedef struct { - char id[3]; - unsigned char version; - unsigned short flags; - unsigned short n_verts; - unsigned short n_norms; - unsigned short n_prims; - SVECTOR *p_verts; - SVECTOR *p_norms; - void *p_prims; -} SMD; - -typedef struct { - unsigned char type:2; - unsigned char l_type:2; - unsigned char c_type:1; - unsigned char texture:1; - unsigned char blend:2; - unsigned char zoff:4; - unsigned char nocull:1; - unsigned char mask:1; - unsigned char texwin:2; - unsigned char texoff:2; - unsigned char reserved:6; - unsigned char len; -} SMD_PRI_TYPE; - -typedef struct { - SMD_PRI_TYPE prim_id; - unsigned short v0,v1,v2,v3; // Vertex indices - unsigned short n0,n1,n2,n3; // Normal indices - unsigned char r0,g0,b0,code; // RGB0 - unsigned char r1,g1,b1,p0; // RGB1 - unsigned char r2,g2,b2,p1; // RGB2 - unsigned char r3,g3,b3,p2; // RGB3 - unsigned char tu0,tv0; - unsigned char tu1,tv1; - unsigned char tu2,tv2; - unsigned char tu3,tv3; - unsigned short tpage,clut; -} SMD_PRIM; - - -int OpenSMD(void *smd); -SMD_PRIM *ReadSMD(SMD_PRIM *pri); - -void scSetClipRect(int x0, int y0, int x1, int y1); - -SMD *smdInitData(void *data); -void smdSetBaseTPage(unsigned short tpage); - -char *smdSortModel(SC_OT *ot, char* pribuff, SMD *smd); -char *smdSortModelFlat(u_long *ot, char* pribuff, SMD *smd); - -void smdSetCelTex(unsigned short tpage, unsigned short clut); -void smdSetCelParam(int udiv, int vdiv, unsigned int col); -char *smdSortModelCel(SC_OT *ot, char* pribuff, SMD *smd); - -#endif
\ No newline at end of file diff --git a/libpsn00b/cmake/internal_setup.cmake b/libpsn00b/cmake/internal_setup.cmake index e24595a..c3bb2dc 100644 --- a/libpsn00b/cmake/internal_setup.cmake +++ b/libpsn00b/cmake/internal_setup.cmake @@ -51,6 +51,7 @@ set( psxsio psxetc psxapi + smd lzp c ) diff --git a/libpsn00b/include/psxapi.h b/libpsn00b/include/psxapi.h index 5bb2b6f..67fa51a 100644 --- a/libpsn00b/include/psxapi.h +++ b/libpsn00b/include/psxapi.h @@ -310,7 +310,7 @@ int LoadExec(const char *path, int argc, const char **argv); void FlushCache(void); void ResetEntryInt(void); -void HookEntryInt(jmp_buf buf); +void HookEntryInt(const JumpBuffer *buf); void ReturnFromException(void); int SetConf(int evcb, int tcb, uint32_t sp); diff --git a/libpsn00b/include/smd/smd.h b/libpsn00b/include/smd/smd.h new file mode 100644 index 0000000..658f7fa --- /dev/null +++ b/libpsn00b/include/smd/smd.h @@ -0,0 +1,85 @@ +/* + * PSn00bSDK .SMD model parser library + * (C) 2019-2023 Lameguy64, spicyjpeg - MPL licensed + */ + +#pragma once + +#include <stdint.h> +#include <psxgte.h> + +/* Structure definitions */ + +typedef struct { + uint32_t *ot; + int16_t otlen; + uint8_t zdiv,zoff; +} SC_OT; + +typedef struct { + char id[3]; + uint8_t version; + uint16_t flags; + uint16_t n_verts; + uint16_t n_norms; + uint16_t n_prims; + SVECTOR *p_verts; + SVECTOR *p_norms; + void *p_prims; +} SMD; + +typedef struct { + uint8_t type : 2; + uint8_t l_type : 2; + uint8_t c_type : 1; + uint8_t texture : 1; + uint8_t blend : 2; + uint8_t zoff : 4; + uint8_t nocull : 1; + uint8_t mask : 1; + uint8_t texwin : 2; + uint8_t texoff : 2; + uint8_t reserved : 6; + uint8_t len; +} SMD_PRI_TYPE; + +typedef struct { + SMD_PRI_TYPE prim_id; + + uint16_t v0,v1,v2,v3; // Vertex indices + uint16_t n0,n1,n2,n3; // Normal indices + uint8_t r0,g0,b0,code; // RGB0 + uint8_t r1,g1,b1,p0; // RGB1 + uint8_t r2,g2,b2,p1; // RGB2 + uint8_t r3,g3,b3,p2; // RGB3 + uint8_t tu0,tv0; + uint8_t tu1,tv1; + uint8_t tu2,tv2; + uint8_t tu3,tv3; + uint16_t tpage,clut; +} SMD_PRIM; + +/* API */ + +#ifdef __cplusplus +extern "C" { +#endif + +int OpenSMD(const void *smd); +SMD_PRIM *ReadSMD(SMD_PRIM *pri); + +void scSetClipRect(int x0, int y0, int x1, int y1); + +SMD *smdInitData(const void *data); +void smdSetBaseTPage(uint16_t tpage); + +uint8_t *smdSortModel(SC_OT *ot, uint8_t *pribuff, SMD *smd); +uint8_t *smdSortModelFlat(uint32_t *ot, uint8_t *pribuff, SMD *smd); + +void smdSetCelTex(uint16_t tpage, uint16_t clut); +void smdSetCelParam(int udiv, int vdiv, unsigned int col); +uint8_t *smdSortModelCel(SC_OT *ot, uint8_t *pribuff, SMD *smd); + +#ifdef __cplusplus +} +#endif diff --git a/examples/demos/n00bdemo/smd_s.h b/libpsn00b/include/smd/smd_s.inc index 4dca4dd..827e9e3 100644 --- a/examples/demos/n00bdemo/smd_s.h +++ b/libpsn00b/include/smd/smd_s.inc @@ -1,3 +1,6 @@ +# PSn00bSDK .SMD model parser library +# (C) 2019-2023 Lameguy64, spicyjpeg - MPL licensed + .set OT_ADDR, 0 .set OT_LEN, 4 .set OT_ZDIV, 8 @@ -332,5 +335,5 @@ nop ori $s3, CLIP_BOTTOM .no_clip_b_y3_q: - + .endm diff --git a/examples/demos/n00bdemo/smd.s b/libpsn00b/smd/smd.s index d25f760..3c87a5e 100644 --- a/examples/demos/n00bdemo/smd.s +++ b/libpsn00b/smd/smd.s @@ -1,35 +1,37 @@ +# PSn00bSDK .SMD model parser library +# (C) 2019-2023 Lameguy64, spicyjpeg - MPL licensed + .set noreorder .include "gtereg.inc" .include "inline_s.inc" -.include "smd_s.h" - - -.section .text +.include "smd/smd_s.inc" # Currently does not do header checks +.section .text.smdInitData, "ax", @progbits .global smdInitData .type smdInitData, @function + smdInitData: - lw $a1, SMD_HEAD_PVERTS($a0) # Initialize header pointers lw $a2, SMD_HEAD_PNORMS($a0) lw $a3, SMD_HEAD_PPRIMS($a0) - + addu $a1, $a0 addu $a2, $a0 addu $a3, $a0 - + sw $a1, SMD_HEAD_PVERTS($a0) sw $a2, SMD_HEAD_PNORMS($a0) sw $a3, SMD_HEAD_PPRIMS($a0) - + jr $ra move $v0, $a0 - - + +.section .text.scSetClipRect, "ax", @progbits .global scSetClipRect .type scSetClipRect, @function + scSetClipRect: sll $a1, 16 or $a0, $a1 @@ -39,50 +41,51 @@ scSetClipRect: sw $a0, 0( $a1 ) jr $ra sw $a2, 4( $a1 ) - - + +.section .text.smdSetBaseTPage, "ax", @progbits .global smdSetBaseTPage .type smdSetBaseTPage, @function + smdSetBaseTPage: la $v0, _smd_tpage_base jr $ra sw $a0, 0($v0) - - + +.section .text.smdSortModel, "ax", @progbits .global smdSortModel .type smdSortModel, @function + smdSortModel: - # a0 - Pointer SC_OT structure # a1 - Pointer to next primitive # a2 - Pointer to SMD data address # v0 - New pointer of primitive buffer (return) - + addiu $sp, -16 sw $s0, 0($sp) sw $s1, 4($sp) sw $s2, 8($sp) sw $s3, 12($sp) - + la $v0, _sc_clip lw $t8, 0($v0) lw $t9, 4($v0) - + lw $t0, OT_LEN($a0) lw $a0, OT_ADDR($a0) lw $t1, SMD_HEAD_PVERTS($a2) lw $t2, SMD_HEAD_PNORMS($a2) lw $t3, SMD_HEAD_PPRIMS($a2) - + .sort_loop: nop lw $a3, 0($t3) # Get primitive ID word move $t4, $t3 - + beqz $a3, .exit # Check if terminator (just zero) addiu $t4, 4 - + lhu $t5, 0( $t4 ) # Load vertices lhu $t6, 2( $t4 ) lhu $t7, 4( $t4 ) @@ -98,38 +101,38 @@ smdSortModel: lwc2 C2_VZ1 , 4( $t6 ) lwc2 C2_VXY2, 0( $t7 ) lwc2 C2_VZ2 , 4( $t7 ) - + srl $v1, $a3, 24 # Get primitive size addu $t3, $v1 # Step main pointer to next primitive - + RTPT - + cfc2 $v0, C2_FLAG # Get GTE flag value nop - + bltz $v0, .skip_prim # Skip primitive if Z overflow andi $v0, $a3, 0x3 - + NCLIP # Backface culling - + srl $v1, $a3, 12 andi $v1, 1 - + bnez $v1, .no_culling nop - + mfc2 $v1, C2_MAC0 nop bltz $v1, .skip_prim nop - + .no_culling: beq $v0, 0x1, .prim_tri # If primitive is a triangle nop beq $v0, 0x2, .prim_quad # If primitive is a quad nop - + b .skip_prim nop @@ -140,25 +143,25 @@ smdSortModel: addiu $t4, 8 # Advance from indices AVSZ3 # Calculate average Z - + srl $v0, $t0, 16 # Get Z divisor from OT_LEN value andi $v0, 0xff - + mfc2 $t5, C2_OTZ # Get AVSZ3 result - + sra $v1, $t0, 24 # Get Z offset from OT_LEN value - + srl $t5, $v0 # Apply divisor and offset sub $t5, $v1 - + blez $t5, .skip_prim # Skip primitive if less than zero andi $v1, $t0, 0xffff bge $t5, $v1, .skip_prim # Skip primitive if greater than OT length sll $t5, 2 addu $t5, $a0 # Append OTZ to OT address - + ClipTestTri - + and $v0, $s0, $s1 # v0 & v1 beqz $v0, .do_draw and $v0, $s1, $s2 # v1 & v2 @@ -168,10 +171,10 @@ smdSortModel: nop b .skip_prim nop - + .do_draw: - - + + srl $v0, $a3, 2 # Lighting enabled? andi $v0, 0x3 bnez $v0, .F3_light @@ -180,18 +183,18 @@ smdSortModel: andi $v0, $a3, 0x10 # Gouraud shaded bnez $v0, .F3_gouraud nop - + andi $v0, $a3, 0x20 # Textured triangle bnez $v0, .F3_textured nop - + lw $v0, 0( $t4 ) # Flat color, no lighting lui $v1, 0x2000 or $v0, $v1 - + b .sort_F3_pri sw $v0, POLYF3_rgbc( $a1 ) - + .F3_gouraud: lw $v0, 0($t4) @@ -213,30 +216,30 @@ smdSortModel: or $v0, $v1 sw $v0, POLYFT3_rgbc( $a1 ) addiu $t4, 4 - + lhu $v0, 0( $t4 ) # Load texture coordinates lhu $v1, 2( $t4 ) sh $v0, POLYFT3_uv0( $a1 ) lhu $v0, 4( $t4 ) sh $v1, POLYFT3_uv1( $a1 ) sh $v0, POLYFT3_uv2( $a1 ) - + lw $v0, 8( $t4 ) # Tpage + CLUT nop andi $v1, $v0, 0xffff sh $v1, POLYFT3_tpage( $a1 ) srl $v0, 16 - + b .sort_FT3_pri sh $v0, POLYFT3_clut( $a1 ) - + .F3_light: - + lhu $v0, 0( $t4 ) # Load normal 0 - + srl $v1, $a3, 2 andi $v1, $v1, 0x3 - + sll $v0, 3 addu $v0, $t2 lwc2 C2_VXY0, 0( $v0 ) @@ -244,26 +247,26 @@ smdSortModel: beq $v1, 0x2, .F3_light_smt nop - + lw $v0, 4( $t4 ) lui $v1, 0x2000 or $v0, $v1 mtc2 $v0, C2_RGB - + addiu $t4, 8 nop - + NCCS andi $v0, $a3, 0x20 # Textured triangle bnez $v0, .F3_light_tex nop - + swc2 C2_RGB2, POLYF3_rgbc( $a1 ) - + b .sort_F3_pri nop - + .F3_light_tex: lhu $v0, 0( $t4 ) # Load texture coordinates @@ -272,23 +275,23 @@ smdSortModel: lhu $v0, 4( $t4 ) sh $v1, POLYFT3_uv1( $a1 ) sh $v0, POLYFT3_uv2( $a1 ) - + lw $v1, 8( $t4 ) nop andi $v0, $v1, 0xffff sh $v0, POLYFT3_tpage( $a1 ) srl $v0, $v1, 16 sh $v0, POLYFT3_clut( $a1 ) - + mfc2 $v0, C2_RGB2 lui $v1, 0x2400 or $v0, $v1 - + b .sort_FT3_pri sw $v0, POLYFT3_rgbc( $a1 ) - + .F3_light_smt: - + lhu $v0, 2( $t4 ) # Load normals 1 and 2 lhu $v1, 4( $t4 ) sll $v0, 3 @@ -303,20 +306,20 @@ smdSortModel: lui $v1, 0x3000 # Load color or $v0, $v1 mtc2 $v0, C2_RGB - + addiu $t4, 12 nop - + NCCT - + andi $v0, $a3, 0x20 # Textured triangle bnez $v0, .F3_light_tex_smt nop - + swc2 C2_RGB0, POLYG3_rgbc0( $a1 ) swc2 C2_RGB1, POLYG3_rgbc1( $a1 ) swc2 C2_RGB2, POLYG3_rgbc2( $a1 ) - + b .sort_G3_pri nop @@ -328,21 +331,21 @@ smdSortModel: lhu $v0, 4( $t4 ) sh $v1, POLYGT3_uv1( $a1 ) sh $v0, POLYGT3_uv2( $a1 ) - + lw $v1, 8( $t4 ) nop andi $v0, $v1, 0xffff sh $v0, POLYGT3_tpage( $a1 ) srl $v0, $v1, 16 sh $v0, POLYGT3_clut( $a1 ) - + mfc2 $v0, C2_RGB0 lui $v1, 0x3400 or $v0, $v1 - + swc2 C2_RGB1, POLYGT3_rgbc1( $a1 ) swc2 C2_RGB2, POLYGT3_rgbc2( $a1 ) - + b .sort_GT3_pri sw $v0, POLYGT3_rgbc0( $a1 ) @@ -351,7 +354,7 @@ smdSortModel: swc2 C2_SXY0, POLYF3_xy0($a1) swc2 C2_SXY1, POLYF3_xy1($a1) swc2 C2_SXY2, POLYF3_xy2($a1) - + la $v0, _smd_tpage_base lhu $v0, 0($v0) srl $v1, $a3, 6 # Get blend mode @@ -361,7 +364,7 @@ smdSortModel: lui $v1, 0xe100 or $v0, $v1 sw $v0, POLYF3_tpage($a1) # Store TPage - + .set noat lui $v1, 0x0500 @@ -379,21 +382,21 @@ smdSortModel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYF3_len - + .sort_FT3_pri: swc2 C2_SXY0, POLYFT3_xy0( $a1 ) swc2 C2_SXY1, POLYFT3_xy1( $a1 ) swc2 C2_SXY2, POLYFT3_xy2( $a1 ) - + .set noat lui $v1, 0x0700 @@ -411,21 +414,21 @@ smdSortModel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYFT3_len - + .sort_G3_pri: swc2 C2_SXY0, POLYG3_xy0( $a1 ) swc2 C2_SXY1, POLYG3_xy1( $a1 ) swc2 C2_SXY2, POLYG3_xy2( $a1 ) - + la $v0, _smd_tpage_base lhu $v0, 0($v0) srl $v1, $a3, 6 # Get blend mode @@ -435,7 +438,7 @@ smdSortModel: lui $v1, 0xe100 or $v0, $v1 sw $v0, POLYG3_tpage($a1) # Store TPage - + .set noat lui $v1, 0x0700 @@ -453,21 +456,21 @@ smdSortModel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYG3_len - + .sort_GT3_pri: swc2 C2_SXY0, POLYGT3_xy0( $a1 ) swc2 C2_SXY1, POLYGT3_xy1( $a1 ) swc2 C2_SXY2, POLYGT3_xy2( $a1 ) - + .set noat lui $v1, 0x0900 @@ -485,17 +488,17 @@ smdSortModel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYGT3_len ## Quads - + .prim_quad: # Quad processing mfc2 $t6, C2_SXY0 # Retrieve first projected vertex @@ -506,38 +509,38 @@ smdSortModel: addu $t5, $t1 lwc2 C2_VXY0, 0( $t5 ) lwc2 C2_VZ0 , 4( $t5 ) - + nRTPS - + cfc2 $v1, C2_FLAG # Get GTE flag value - + srl $v0, $t0, 16 # Get Z divisor from OT_LEN value - + bltz $v1, .skip_prim nop - + AVSZ4 - + andi $v0, 0xff - + mfc2 $t5, C2_OTZ - + sra $v1, $t0, 24 # Get Z offset from OT_LEN value - + srl $t5, $v0 # Apply divisor and offset sub $t5, $v1 - + blez $t5, .skip_prim # Skip primitive if less than zero andi $v1, $t0, 0xffff bge $t5, $v1, .skip_prim # Skip primitive if greater than OT length sll $t5, 2 addu $t5, $a0 # Append OTZ to OT address - + # no touch: # a0, a1, a2, a3, t0, t1, t2, t3, t4, t5(ot), t6(sxy0) - + ClipTestQuad - + and $v0, $s0, $s1 # v0 & v1 beqz $v0, .do_draw_q and $v0, $s1, $s2 # v1 & v2 @@ -553,29 +556,29 @@ smdSortModel: nop b .skip_prim nop - + .do_draw_q: srl $v0, $a3, 2 # Lighting enabled? andi $v0, 0x3 bnez $v0, .F4_light nop - + andi $v0, $a3, 0x10 # Gouraud quad bnez $v0, .F4_gouraud nop - + andi $v0, $a3, 0x20 # Textured quad bnez $v0, .F4_textured nop - + lw $v0, 0($t4) lui $v1, 0x2800 or $v0, $v1 - + b .sort_F4_pri sw $v0, POLYF4_rgbc($a1) - + .F4_gouraud: lw $v0, 0($t4) @@ -591,15 +594,15 @@ smdSortModel: sw $v0, POLYG4_rgbc2($a1) b .sort_G4_pri sw $v1, POLYG4_rgbc3($a1) - + .F4_textured: - + lw $v0, 0($t4) lui $v1, 0x2c00 or $v0, $v1 sw $v0, POLYFT4_rgbc( $a1 ) addiu $t4, 4 - + lhu $v0, 0($t4) # Load texture coordinates lhu $v1, 2($t4) sh $v0, POLYFT4_uv0( $a1 ) @@ -608,23 +611,23 @@ smdSortModel: lhu $v1, 6( $t4 ) sh $v0, POLYFT4_uv2( $a1 ) sh $v1, POLYFT4_uv3( $a1 ) - + lw $v1, 8( $t4 ) nop andi $v0, $v1, 0xffff sh $v0, POLYFT4_tpage( $a1 ) srl $v0, $v1, 16 - + b .sort_FT4_pri sh $v0, POLYFT4_clut($a1) - + .F4_light: lhu $v0, 0( $t4 ) # Load normal 0 - + srl $v1, $a3, 2 andi $v1, $v1, 0x3 - + sll $v0, 3 addu $v0, $t2 lwc2 C2_VXY0, 0( $v0 ) @@ -632,26 +635,26 @@ smdSortModel: beq $v1, 0x2, .F4_light_smt nop - + lw $v0, 4( $t4 ) lui $v1, 0x2800 or $v0, $v1 mtc2 $v0, C2_RGB - + addiu $t4, 8 nop - + NCCS - + andi $v0, $a3, 0x20 # Textured triangle bnez $v0, .F4_light_tex nop swc2 C2_RGB2, POLYF4_rgbc( $a1 ) - + b .sort_F4_pri nop - + .F4_light_tex: lhu $v0, 0( $t4 ) # Load texture coordinates @@ -662,21 +665,21 @@ smdSortModel: lhu $v1, 6( $t4 ) sh $v0, POLYFT4_uv2( $a1 ) sh $v1, POLYFT4_uv3( $a1 ) - + lw $v1, 8( $t4 ) nop andi $v0, $v1, 0xffff sh $v0, POLYFT4_tpage( $a1 ) srl $v0, $v1, 16 sh $v0, POLYFT4_clut( $a1 ) - + mfc2 $v0, C2_RGB2 lui $v1, 0x2c00 or $v0, $v1 - + b .sort_FT4_pri sw $v0, POLYFT4_rgbc( $a1 ) - + .F4_light_smt: lhu $v0, 2( $t4 ) # Load normals 1 and 2 @@ -689,38 +692,38 @@ smdSortModel: lwc2 C2_VZ1 , 4( $v0 ) lwc2 C2_VXY2, 0( $v1 ) lwc2 C2_VZ2 , 4( $v1 ) - + lw $v0, 8( $t4 ) lui $v1, 0x3800 # Load color or $v0, $v1 mtc2 $v0, C2_RGB - + nNCCT - + lhu $v0, 6( $t4 ) # Load normal 3 - + addiu $t4, 12 - + sll $v0, 3 addu $v0, $t2 lwc2 C2_VXY0, 0( $v0 ) lwc2 C2_VZ0 , 4( $v0 ) - + andi $v0, $a3, 0x20 # Textured triangle bnez $v0, .F4_light_tex_smt nop - + swc2 C2_RGB0, POLYG4_rgbc0( $a1 ) swc2 C2_RGB1, POLYG4_rgbc1( $a1 ) swc2 C2_RGB2, POLYG4_rgbc2( $a1 ) - + nNCCS - + swc2 C2_RGB2, POLYG4_rgbc3( $a1 ) - + b .sort_G4_pri nop - + .F4_light_tex_smt: mfc2 $v0, C2_RGB0 @@ -729,9 +732,9 @@ smdSortModel: sw $v0, POLYGT4_rgbc0( $a1 ) swc2 C2_RGB1, POLYGT4_rgbc1( $a1 ) swc2 C2_RGB2, POLYGT4_rgbc2( $a1 ) - + NCCS - + lhu $v0, 0( $t4 ) # Load texture coordinates lhu $v1, 2( $t4 ) sh $v0, POLYGT4_uv0( $a1 ) @@ -743,21 +746,21 @@ smdSortModel: lw $v1, 8( $t4 ) swc2 C2_RGB2, POLYGT4_rgbc3( $a1 ) - + andi $v0, $v1, 0xffff sh $v0, POLYGT4_tpage( $a1 ) srl $v0, $v1, 16 - + b .sort_GT4_pri sh $v0, POLYGT4_clut( $a1 ) - + .sort_F4_pri: sw $t6, POLYF4_xy0($a1) swc2 C2_SXY0, POLYF4_xy1($a1) swc2 C2_SXY1, POLYF4_xy2($a1) swc2 C2_SXY2, POLYF4_xy3($a1) - + la $v0, _smd_tpage_base lhu $v0, 0($v0) srl $v1, $a3, 6 # Get blend mode @@ -767,7 +770,7 @@ smdSortModel: lui $v1, 0xe100 or $v0, $v1 sw $v0, POLYF4_tpage($a1) # Store TPage - + .set noat lui $v1, 0x0600 @@ -785,22 +788,22 @@ smdSortModel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYF4_len - + .sort_FT4_pri: sw $t6, POLYFT4_xy0($a1) swc2 C2_SXY0, POLYFT4_xy1($a1) swc2 C2_SXY1, POLYFT4_xy2($a1) swc2 C2_SXY2, POLYFT4_xy3($a1) - + .set noat lui $v1, 0x0900 @@ -818,22 +821,22 @@ smdSortModel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYFT4_len - + .sort_G4_pri: sw $t6, POLYG4_xy0($a1) swc2 C2_SXY0, POLYG4_xy1($a1) swc2 C2_SXY1, POLYG4_xy2($a1) swc2 C2_SXY2, POLYG4_xy3($a1) - + la $v0, _smd_tpage_base lhu $v0, 0($v0) srl $v1, $a3, 6 # Get blend mode @@ -843,7 +846,7 @@ smdSortModel: lui $v1, 0xe100 or $v0, $v1 sw $v0, POLYG4_tpage($a1) # Store TPage - + .set noat lui $v1, 0x0900 @@ -861,22 +864,22 @@ smdSortModel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYG4_len - + .sort_GT4_pri: sw $t6, POLYGT4_xy0($a1) swc2 C2_SXY0, POLYGT4_xy1($a1) swc2 C2_SXY1, POLYGT4_xy2($a1) swc2 C2_SXY2, POLYGT4_xy3($a1) - + .set noat lui $v1, 0x0c00 @@ -894,20 +897,20 @@ smdSortModel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYGT4_len - + .skip_prim: b .sort_loop nop - + .exit: lw $s0, 0( $sp ) @@ -917,8 +920,9 @@ smdSortModel: addiu $sp, 16 jr $ra move $v0, $a1 - - + +.section .bss._smd_tpage_base, "w" .comm _smd_tpage_base, 4, 4 +.section .bss._sc_clip, "w" .comm _sc_clip, 8, 4 diff --git a/examples/demos/n00bdemo/smd_cel.s b/libpsn00b/smd/smd_cel.s index 383f043..8a39f01 100644 --- a/examples/demos/n00bdemo/smd_cel.s +++ b/libpsn00b/smd/smd_cel.s @@ -1,14 +1,16 @@ +# PSn00bSDK .SMD model parser library +# (C) 2019-2023 Lameguy64, spicyjpeg - MPL licensed + .set noreorder .include "gtereg.inc" .include "inline_s.inc" -.include "smd_s.h" - +.include "smd/smd_s.inc" -.section .text - +.section .text.smdSetCelTex, "ax", @progbits .global smdSetCelTex .type smdSetCelTex, @function + smdSetCelTex: # a0 - TPage value # a1 - CLUT value @@ -18,11 +20,11 @@ smdSetCelTex: or $a0, $a1 jr $ra sw $a0, 0($v0) - - - + +.section .text.smdSetCelParam, "ax", @progbits .global smdSetCelParam .type smdSetCelParam, @function + smdSetCelParam: # a0 - Shading texture U offset # a1 - Shading texture V offset @@ -38,42 +40,42 @@ smdSetCelParam: or $a3, $v1 jr $ra sw $a2, 0($v0) - - + +.section .text.smdSortModelCel, "ax", @progbits .global smdSortModelCel .type smdSortModelCel, @function + smdSortModelCel: - # a0 - Pointer SC_OT structure # a1 - Pointer to next primitive # a2 - Pointer to SMD data address # v0 - New pointer of primitive buffer (return) - + addiu $sp, -16 sw $s0, 0($sp) sw $s1, 4($sp) sw $s2, 8($sp) sw $s3, 12($sp) - + la $v0, _sc_clip lw $t8, 0($v0) lw $t9, 4($v0) - + lw $t0, OT_LEN($a0) lw $a0, OT_ADDR($a0) lw $t1, SMD_HEAD_PVERTS($a2) lw $t2, SMD_HEAD_PNORMS($a2) lw $t3, SMD_HEAD_PPRIMS($a2) - + .sort_loop: nop lw $a3, 0($t3) # Get primitive ID word move $t4, $t3 - + beqz $a3, .exit # Check if terminator (just zero) addiu $t4, 4 - + lhu $t5, 0( $t4 ) # Load vertices lhu $t6, 2( $t4 ) lhu $t7, 4( $t4 ) @@ -89,38 +91,38 @@ smdSortModelCel: lwc2 C2_VZ1 , 4( $t6 ) lwc2 C2_VXY2, 0( $t7 ) lwc2 C2_VZ2 , 4( $t7 ) - + srl $v1, $a3, 24 # Get primitive size addu $t3, $v1 # Step main pointer to next primitive - + RTPT - + cfc2 $v0, C2_FLAG # Get GTE flag value nop - + bltz $v0, .skip_prim # Skip primitive if Z overflow andi $v0, $a3, 0x3 - + NCLIP # Backface culling - + srl $v1, $a3, 12 andi $v1, 1 - + bnez $v1, .no_culling nop - + mfc2 $v1, C2_MAC0 nop bltz $v1, .skip_prim nop - + .no_culling: beq $v0, 0x1, .prim_tri # If primitive is a triangle nop beq $v0, 0x2, .prim_quad # If primitive is a quad nop - + b .skip_prim nop @@ -131,25 +133,25 @@ smdSortModelCel: addiu $t4, 8 # Advance from indices AVSZ3 # Calculate average Z - + srl $v0, $t0, 16 # Get Z divisor from OT_LEN value andi $v0, 0xff - + mfc2 $t5, C2_OTZ # Get AVSZ3 result - + sra $v1, $t0, 24 # Get Z offset from OT_LEN value - + srl $t5, $v0 # Apply divisor and offset sub $t5, $v1 - + blez $t5, .skip_prim # Skip primitive if less than zero andi $v1, $t0, 0xffff bge $t5, $v1, .skip_prim # Skip primitive if greater than OT length sll $t5, 2 addu $t5, $a0 # Append OTZ to OT address - + ClipTestTri - + and $v0, $s0, $s1 # v0 & v1 beqz $v0, .do_draw and $v0, $s1, $s2 # v1 & v2 @@ -159,10 +161,10 @@ smdSortModelCel: nop b .skip_prim nop - + .do_draw: - - + + srl $v0, $a3, 2 # Lighting enabled? andi $v0, 0x3 bnez $v0, .F3_light @@ -171,18 +173,18 @@ smdSortModelCel: andi $v0, $a3, 0x10 # Gouraud shaded bnez $v0, .F3_gouraud nop - + andi $v0, $a3, 0x20 # Textured triangle bnez $v0, .F3_textured nop - + lw $v0, 0( $t4 ) # Flat color, no lighting lui $v1, 0x2000 or $v0, $v1 - + b .sort_F3_pri sw $v0, POLYF3_rgbc( $a1 ) - + .F3_gouraud: lw $v0, 0($t4) @@ -204,30 +206,30 @@ smdSortModelCel: or $v0, $v1 sw $v0, POLYFT3_rgbc( $a1 ) addiu $t4, 4 - + lhu $v0, 0( $t4 ) # Load texture coordinates lhu $v1, 2( $t4 ) sh $v0, POLYFT3_uv0( $a1 ) lhu $v0, 4( $t4 ) sh $v1, POLYFT3_uv1( $a1 ) sh $v0, POLYFT3_uv2( $a1 ) - + lw $v0, 8( $t4 ) # Tpage + CLUT nop andi $v1, $v0, 0xffff sh $v1, POLYFT3_tpage( $a1 ) srl $v0, 16 - + b .sort_FT3_pri sh $v0, POLYFT3_clut( $a1 ) - + .F3_light: - + lhu $v0, 0( $t4 ) # Load normal 0 - + srl $v1, $a3, 2 andi $v1, $v1, 0x3 - + sll $v0, 3 addu $v0, $t2 lwc2 C2_VXY0, 0( $v0 ) @@ -235,26 +237,26 @@ smdSortModelCel: beq $v1, 0x2, .F3_light_smt nop - + lw $v0, 4( $t4 ) lui $v1, 0x2000 or $v0, $v1 mtc2 $v0, C2_RGB - + addiu $t4, 8 nop - + NCCS andi $v0, $a3, 0x20 # Textured triangle bnez $v0, .F3_light_tex nop - + swc2 C2_RGB2, POLYF3_rgbc( $a1 ) - + b .sort_F3_pri nop - + .F3_light_tex: lhu $v0, 0( $t4 ) # Load texture coordinates @@ -263,23 +265,23 @@ smdSortModelCel: lhu $v0, 4( $t4 ) sh $v1, POLYFT3_uv1( $a1 ) sh $v0, POLYFT3_uv2( $a1 ) - + lw $v1, 8( $t4 ) nop andi $v0, $v1, 0xffff sh $v0, POLYFT3_tpage( $a1 ) srl $v0, $v1, 16 sh $v0, POLYFT3_clut( $a1 ) - + mfc2 $v0, C2_RGB2 lui $v1, 0x2400 or $v0, $v1 - + b .sort_FT3_pri sw $v0, POLYFT3_rgbc( $a1 ) - + .F3_light_smt: - + lhu $v0, 2($t4) # Load normals 1 and 2 lhu $v1, 4($t4) sll $v0, 3 @@ -293,32 +295,32 @@ smdSortModelCel: lwc2 C2_VXY2, 0($v1) lwc2 C2_VZ2 , 4($v1) mtc2 $v0, C2_RGB - + swc2 C2_SXY0, POLYFT3_xy0($a1) swc2 C2_SXY1, POLYFT3_xy1($a1) swc2 C2_SXY2, POLYFT3_xy2($a1) - + la $v0, _smd_cel_tpage # Load cel shader TPage and CLUT values lw $v0, 0($v0) - + NCT - + andi $v1, $v0, 0xffff sh $v1, POLYFT3_tpage($a1) srl $v1, $v0, 16 sh $v1, POLYFT3_clut($a1) - + # Usable regs: v0, v1, at, t6, t7 - + .set noat - + la $at, _smd_cel_param # Load cel shader parameters lhu $at, 0($at) - + mfc2 $t7, C2_RGB0 # Get first shaded color andi $v1, $at, 0xff # Get U divisor value andi $t7, 0xffff # Only keep R and G colors - + andi $v0, $t7, 0xff # U0 srl $v0, $v1 sb $v0, POLYFT3_uv0($a1) @@ -326,7 +328,7 @@ smdSortModelCel: srl $v1, $at, 8 srl $v0, $v1 sb $v0, POLYFT3_uv0+1($a1) - + mfc2 $t7, C2_RGB1 andi $v1, $at, 0xff andi $t7, 0xffff @@ -337,7 +339,7 @@ smdSortModelCel: srl $v1, $at, 8 srl $v0, $v1 sb $v0, POLYFT3_uv1+1($a1) - + mfc2 $t7, C2_RGB2 andi $v1, $at, 0xff andi $t7, 0xffff @@ -348,16 +350,16 @@ smdSortModelCel: srl $v1, $at, 8 srl $v0, $v1 sb $v0, POLYFT3_uv2+1($a1) - + la $v0, _smd_cel_col lw $v0, 0($v0) lui $v1, 0x2600 or $v0, $v1 sw $v0, POLYFT3_rgbc($a1) - + lw $t7, 8($t4) addiu $t4, 12 - + lui $v1, 0x0700 lw $v0, 0($t5) lui $at, 0xff00 @@ -373,21 +375,21 @@ smdSortModelCel: and $v0, $at or $v0, $v1 sw $v0, 0($t5) - + lui $v0, 0x8000 or $a1, $v0 addiu $a1, POLYFT3_len - + .set at - + andi $v0, $a3, 0x20 # Textured triangle bnez $v0, .F3_light_tex_smt nop - + #swc2 C2_RGB0, POLYG3_rgbc0( $a1 ) #swc2 C2_RGB1, POLYG3_rgbc1( $a1 ) #swc2 C2_RGB2, POLYG3_rgbc2( $a1 ) - + lui $v0, 0x2000 or $t7, $v0 b .sort_F3_pri @@ -401,17 +403,17 @@ smdSortModelCel: lhu $v0, 4( $t4 ) sh $v1, POLYFT3_uv1( $a1 ) sh $v0, POLYFT3_uv2( $a1 ) - + lw $v1, 8( $t4 ) nop andi $v0, $v1, 0xffff sh $v0, POLYFT3_tpage( $a1 ) srl $v0, $v1, 16 sh $v0, POLYFT3_clut( $a1 ) - + lui $v1, 0x2400 or $t7, $v1 - + b .sort_FT3_pri sw $t7, POLYFT3_rgbc( $a1 ) @@ -420,7 +422,7 @@ smdSortModelCel: swc2 C2_SXY0, POLYF3_xy0($a1) swc2 C2_SXY1, POLYF3_xy1($a1) swc2 C2_SXY2, POLYF3_xy2($a1) - + la $v0, _smd_tpage_base lhu $v0, 0($v0) srl $v1, $a3, 6 # Get blend mode @@ -430,7 +432,7 @@ smdSortModelCel: lui $v1, 0xe100 or $v0, $v1 sw $v0, POLYF3_tpage($a1) # Store TPage - + .set noat lui $v1, 0x0500 @@ -448,21 +450,21 @@ smdSortModelCel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYF3_len - + .sort_FT3_pri: swc2 C2_SXY0, POLYFT3_xy0( $a1 ) swc2 C2_SXY1, POLYFT3_xy1( $a1 ) swc2 C2_SXY2, POLYFT3_xy2( $a1 ) - + .set noat lui $v1, 0x0700 @@ -480,21 +482,21 @@ smdSortModelCel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYFT3_len - + .sort_G3_pri: swc2 C2_SXY0, POLYG3_xy0( $a1 ) swc2 C2_SXY1, POLYG3_xy1( $a1 ) swc2 C2_SXY2, POLYG3_xy2( $a1 ) - + la $v0, _smd_tpage_base lhu $v0, 0($v0) srl $v1, $a3, 6 # Get blend mode @@ -504,7 +506,7 @@ smdSortModelCel: lui $v1, 0xe100 or $v0, $v1 sw $v0, POLYG3_tpage($a1) # Store TPage - + .set noat lui $v1, 0x0700 @@ -522,21 +524,21 @@ smdSortModelCel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYG3_len - + .sort_GT3_pri: swc2 C2_SXY0, POLYGT3_xy0( $a1 ) swc2 C2_SXY1, POLYGT3_xy1( $a1 ) swc2 C2_SXY2, POLYGT3_xy2( $a1 ) - + .set noat lui $v1, 0x0900 @@ -554,17 +556,17 @@ smdSortModelCel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYGT3_len ## Quads - + .prim_quad: # Quad processing mfc2 $t6, C2_SXY0 # Retrieve first projected vertex @@ -575,38 +577,38 @@ smdSortModelCel: addu $t5, $t1 lwc2 C2_VXY0, 0( $t5 ) lwc2 C2_VZ0 , 4( $t5 ) - + nRTPS - + cfc2 $v1, C2_FLAG # Get GTE flag value - + srl $v0, $t0, 16 # Get Z divisor from OT_LEN value - + bltz $v1, .skip_prim nop - + AVSZ4 - + andi $v0, 0xff - + mfc2 $t5, C2_OTZ - + sra $v1, $t0, 24 # Get Z offset from OT_LEN value - + srl $t5, $v0 # Apply divisor and offset sub $t5, $v1 - + blez $t5, .skip_prim # Skip primitive if less than zero andi $v1, $t0, 0xffff bge $t5, $v1, .skip_prim # Skip primitive if greater than OT length sll $t5, 2 addu $t5, $a0 # Append OTZ to OT address - + # no touch: # a0, a1, a2, a3, t0, t1, t2, t3, t4, t5(ot), t6(sxy0) - + ClipTestQuad - + and $v0, $s0, $s1 # v0 & v1 beqz $v0, .do_draw_q and $v0, $s1, $s2 # v1 & v2 @@ -622,29 +624,29 @@ smdSortModelCel: nop b .skip_prim nop - + .do_draw_q: srl $v0, $a3, 2 # Lighting enabled? andi $v0, 0x3 bnez $v0, .F4_light nop - + andi $v0, $a3, 0x10 # Gouraud quad bnez $v0, .F4_gouraud nop - + andi $v0, $a3, 0x20 # Textured quad bnez $v0, .F4_textured nop - + lw $v0, 0($t4) lui $v1, 0x2800 or $v0, $v1 - + b .sort_F4_pri sw $v0, POLYF4_rgbc($a1) - + .F4_gouraud: lw $v0, 0($t4) @@ -660,15 +662,15 @@ smdSortModelCel: sw $v0, POLYG4_rgbc2($a1) b .sort_G4_pri sw $v1, POLYG4_rgbc3($a1) - + .F4_textured: - + lw $v0, 0($t4) lui $v1, 0x2c00 or $v0, $v1 sw $v0, POLYFT4_rgbc( $a1 ) addiu $t4, 4 - + lhu $v0, 0($t4) # Load texture coordinates lhu $v1, 2($t4) sh $v0, POLYFT4_uv0( $a1 ) @@ -677,23 +679,23 @@ smdSortModelCel: lhu $v1, 6( $t4 ) sh $v0, POLYFT4_uv2( $a1 ) sh $v1, POLYFT4_uv3( $a1 ) - + lw $v1, 8( $t4 ) nop andi $v0, $v1, 0xffff sh $v0, POLYFT4_tpage( $a1 ) srl $v0, $v1, 16 - + b .sort_FT4_pri sh $v0, POLYFT4_clut($a1) - + .F4_light: lhu $v0, 0( $t4 ) # Load normal 0 - + srl $v1, $a3, 2 andi $v1, $v1, 0x3 - + sll $v0, 3 addu $v0, $t2 lwc2 C2_VXY0, 0( $v0 ) @@ -701,26 +703,26 @@ smdSortModelCel: beq $v1, 0x2, .F4_light_smt nop - + lw $v0, 4( $t4 ) lui $v1, 0x2800 or $v0, $v1 mtc2 $v0, C2_RGB - + addiu $t4, 8 nop - + NCS - + andi $v0, $a3, 0x20 # Textured triangle bnez $v0, .F4_light_tex nop swc2 C2_RGB2, POLYF4_rgbc( $a1 ) - + b .sort_F4_pri nop - + .F4_light_tex: lhu $v0, 0( $t4 ) # Load texture coordinates @@ -731,22 +733,22 @@ smdSortModelCel: lhu $v1, 6( $t4 ) sh $v0, POLYFT4_uv2( $a1 ) sh $v1, POLYFT4_uv3( $a1 ) - + lw $v1, 8( $t4 ) nop andi $v0, $v1, 0xffff sh $v0, POLYFT4_tpage( $a1 ) srl $v0, $v1, 16 sh $v0, POLYFT4_clut( $a1 ) - + mfc2 $v0, C2_RGB2 lui $v1, 0x2c00 or $v0, $v1 - + b .sort_FT4_pri nop sw $v0, POLYFT4_rgbc( $a1 ) - + .F4_light_smt: lhu $v0, 2( $t4 ) # Load normals 1 and 2 @@ -759,33 +761,33 @@ smdSortModelCel: lwc2 C2_VZ1 , 4( $v0 ) lwc2 C2_VXY2, 0( $v1 ) lwc2 C2_VZ2 , 4( $v1 ) - + sw $t6, POLYFT4_xy0($a1) swc2 C2_SXY0, POLYFT4_xy1($a1) swc2 C2_SXY1, POLYFT4_xy2($a1) swc2 C2_SXY2, POLYFT4_xy3($a1) - + la $v0, _smd_cel_tpage # Load cel shader TPage and CLUT values lw $v0, 0($v0) - + NCT - + andi $v1, $v0, 0xffff sh $v1, POLYFT4_tpage($a1) srl $v1, $v0, 16 sh $v1, POLYFT4_clut($a1) - + # Usable regs: v0, v1, at, t7 - + .set noat - + la $at, _smd_cel_param # Load cel shader parameters lhu $at, 0($at) - + mfc2 $t7, C2_RGB0 andi $v1, $at, 0xff # Get U divisor value andi $t7, 0xffff # Only keep R and G colors - + andi $v0, $t7, 0xff # U0 srl $v0, $v1 sb $v0, POLYFT4_uv0($a1) @@ -793,7 +795,7 @@ smdSortModelCel: srl $v1, $at, 8 srl $v0, $v1 sb $v0, POLYFT4_uv0+1($a1) - + mfc2 $t7, C2_RGB1 andi $v1, $at, 0xff andi $t7, 0xffff @@ -804,7 +806,7 @@ smdSortModelCel: srl $v1, $at, 8 srl $v0, $v1 sb $v0, POLYFT4_uv1+1($a1) - + mfc2 $t7, C2_RGB2 andi $v1, $at, 0xff andi $t7, 0xffff @@ -815,24 +817,24 @@ smdSortModelCel: srl $v1, $at, 8 srl $v0, $v1 sb $v0, POLYFT4_uv2+1($a1) - + la $v0, _smd_cel_col lw $v0, 0($v0) lui $v1, 0x2E00 or $v0, $v1 sw $v0, POLYFT4_rgbc($a1) - + lw $t7, 8($t4) - + lhu $v0, 6($t4) # Load normal 3 addiu $t4, 12 sll $v0, 3 addu $v0, $t2 lwc2 C2_VXY0, 0( $v0 ) lwc2 C2_VZ0 , 4( $v0 ) - + nNCS - + mfc2 $s0, C2_RGB2 andi $v1, $at, 0xff andi $s0, 0xffff @@ -843,7 +845,7 @@ smdSortModelCel: srl $v1, $at, 8 srl $v0, $v1 sb $v0, POLYFT4_uv3+1($a1) - + lui $v1, 0x0900 lw $v0, 0($t5) lui $at, 0xff00 @@ -859,24 +861,24 @@ smdSortModelCel: and $v0, $at or $v0, $v1 sw $v0, 0($t5) - + lui $v0, 0x8000 or $a1, $v0 addiu $a1, POLYFT4_len - + .set at - + andi $v0, $a3, 0x20 # Textured quad bnez $v0, .F4_light_tex_smt nop - + lui $v0, 0x2800 or $t7, $v0 b .sort_F4_pri sw $t7, POLYF4_rgbc($a1) - + .F4_light_tex_smt: - + lhu $v0, 0($t4) # Load texture coordinates lhu $v1, 2($t4) sh $v0, POLYFT4_uv0($a1) @@ -887,25 +889,25 @@ smdSortModelCel: sh $v1, POLYFT4_uv3($a1) lw $v1, 8($t4) - + lui $v0, 0x2E00 or $t7, $v0 sw $t7, POLYFT4_rgbc($a1) - + andi $v0, $v1, 0xffff sh $v0, POLYFT4_tpage($a1) srl $v0, $v1, 16 - + b .sort_FT4_pri sh $v0, POLYFT4_clut($a1) - + .sort_F4_pri: sw $t6, POLYF4_xy0($a1) swc2 C2_SXY0, POLYF4_xy1($a1) swc2 C2_SXY1, POLYF4_xy2($a1) swc2 C2_SXY2, POLYF4_xy3($a1) - + la $v0, _smd_tpage_base lhu $v0, 0($v0) srl $v1, $a3, 6 # Get blend mode @@ -915,7 +917,7 @@ smdSortModelCel: lui $v1, 0xe100 or $v0, $v1 sw $v0, POLYF4_tpage($a1) # Store TPage - + .set noat lui $v1, 0x0600 @@ -933,22 +935,22 @@ smdSortModelCel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYF4_len - + .sort_FT4_pri: sw $t6, POLYFT4_xy0($a1) swc2 C2_SXY0, POLYFT4_xy1($a1) swc2 C2_SXY1, POLYFT4_xy2($a1) swc2 C2_SXY2, POLYFT4_xy3($a1) - + .set noat lui $v1, 0x0900 @@ -966,22 +968,22 @@ smdSortModelCel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYFT4_len - + .sort_G4_pri: sw $t6, POLYG4_xy0($a1) swc2 C2_SXY0, POLYG4_xy1($a1) swc2 C2_SXY1, POLYG4_xy2($a1) swc2 C2_SXY2, POLYG4_xy3($a1) - + la $v0, _smd_tpage_base lhu $v0, 0($v0) srl $v1, $a3, 6 # Get blend mode @@ -991,7 +993,7 @@ smdSortModelCel: lui $v1, 0xe100 or $v0, $v1 sw $v0, POLYG4_tpage($a1) # Store TPage - + .set noat lui $v1, 0x0900 @@ -1009,22 +1011,22 @@ smdSortModelCel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYG4_len - + .sort_GT4_pri: sw $t6, POLYGT4_xy0($a1) swc2 C2_SXY0, POLYGT4_xy1($a1) swc2 C2_SXY1, POLYGT4_xy2($a1) swc2 C2_SXY2, POLYGT4_xy3($a1) - + .set noat lui $v1, 0x0c00 @@ -1042,20 +1044,20 @@ smdSortModelCel: and $v0, $at or $v0, $a1 sw $v0, 0($t5) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYGT4_len - + .skip_prim: b .sort_loop nop - + .exit: lw $s0, 0( $sp ) @@ -1065,9 +1067,12 @@ smdSortModelCel: addiu $sp, 16 jr $ra move $v0, $a1 - +.section .bss._smd_cel_col, "w" .comm _smd_cel_col, 4, 4 # STP shading polygon color + +.section .bss._smd_cel_param, "w" .comm _smd_cel_param, 4, 4 # U divisor, V divisor, shading clip -.comm _smd_cel_tpage, 4, 4 # CEL shader texture page & CLUT +.section .bss._smd_cel_tpage, "w" +.comm _smd_cel_tpage, 4, 4 # CEL shader texture page & CLUT diff --git a/examples/demos/n00bdemo/smd_flat.s b/libpsn00b/smd/smd_flat.s index 4b47be4..843b8d3 100644 --- a/examples/demos/n00bdemo/smd_flat.s +++ b/libpsn00b/smd/smd_flat.s @@ -1,43 +1,45 @@ +# PSn00bSDK .SMD model parser library +# (C) 2019-2023 Lameguy64, spicyjpeg - MPL licensed + .set noreorder .include "gtereg.inc" .include "inline_s.inc" -.include "smd_s.h" - - -.section .text +.include "smd/smd_s.inc" +.section .text.smdSortModelFlat, "ax", @progbits .global smdSortModelFlat .type smdSortModelFlat, @function + smdSortModelFlat: # a0 - Pointer SC_OT structure # a1 - Pointer to next primitive # a2 - Pointer to SMD data address # v0 - New pointer of primitive buffer (return) - + addiu $sp, -16 sw $s0, 0( $sp ) sw $s1, 4( $sp ) sw $s2, 8( $sp ) sw $s3, 12( $sp ) - + la $v0, _sc_clip lw $t8, 0($v0) lw $t9, 4($v0) - + lw $t1, SMD_HEAD_PVERTS( $a2 ) lw $t2, SMD_HEAD_PNORMS( $a2 ) lw $t3, SMD_HEAD_PPRIMS( $a2 ) - + .sort_loop: nop lw $a3, 0($t3) # Get primitive ID word move $t4, $t3 - + beqz $a3, .exit # Check if terminator (just zero) addiu $t4, 4 - + lhu $t5, 0( $t4 ) # Load vertices lhu $t6, 2( $t4 ) lhu $t7, 4( $t4 ) @@ -53,32 +55,32 @@ smdSortModelFlat: lwc2 C2_VZ1 , 4( $t6 ) lwc2 C2_VXY2, 0( $t7 ) lwc2 C2_VZ2 , 4( $t7 ) - + srl $v1, $a3, 24 # Get primitive size addu $t3, $v1 # Step main pointer to next primitive - + RTPT - + cfc2 $v0, C2_FLAG # Get GTE flag value nop - + bltz $v0, .skip_prim # Skip primitive if Z overflow nop - + #NCLIP # Backface culling - + #mfc2 $v1, C2_MAC0 - + andi $v0, $a3, 0x3 - + #bltz $v1, .skip_prim #nop - + beq $v0, 0x1, .prim_tri # If primitive is a triangle nop beq $v0, 0x2, .prim_quad # If primitive is a quad nop - + b .skip_prim nop @@ -89,9 +91,9 @@ smdSortModelFlat: addiu $t4, 8 # Advance from indices #AVSZ3 # Calculate average Z - + ClipTestTri - + and $v0, $s0, $s1 # v0 & v1 beqz $v0, .do_draw and $v0, $s1, $s2 # v1 & v2 @@ -101,9 +103,9 @@ smdSortModelFlat: nop b .skip_prim nop - + .do_draw: - + #srl $v0, $a3, 2 # Lighting enabled? #andi $v0, 0x3 #bnez $v0, .F3_light @@ -112,18 +114,18 @@ smdSortModelFlat: andi $v0, $a3, 0x20 # Textured triangle bnez $v0, .F3_textured nop - + andi $v0, $a3, 0x10 # Gouraud shaded bnez $v0, .F3_gouraud nop - + lw $v0, 0( $t4 ) # Flat color, no lighting lui $v1, 0x2000 or $v0, $v1 - + b .sort_F3_pri sw $v0, POLYF3_rgbc( $a1 ) - + .F3_textured: lw $v0, 0( $t4 ) # Flat color, no lighting @@ -131,23 +133,23 @@ smdSortModelFlat: or $v0, $v1 sw $v0, POLYFT3_rgbc( $a1 ) addiu $t4, 4 - + lhu $v0, 0( $t4 ) # Load texture coordinates lhu $v1, 2( $t4 ) sh $v0, POLYFT3_uv0( $a1 ) lhu $v0, 4( $t4 ) sh $v1, POLYFT3_uv1( $a1 ) sh $v0, POLYFT3_uv2( $a1 ) - + lw $v0, 8( $t4 ) # Tpage + CLUT nop andi $v1, $v0, 0xffff sh $v1, POLYFT3_tpage( $a1 ) srl $v0, 16 - + b .sort_FT3_pri sh $v0, POLYFT3_clut( $a1 ) - + .F3_gouraud: lw $v0, 0($t4) lw $v1, 4($t4) @@ -160,14 +162,14 @@ smdSortModelFlat: sw $v1, POLYG3_rgbc1($a1) b .sort_G3_pri sw $v0, POLYG3_rgbc2($a1) - + #.F3_light: - + #lhu $v0, 0( $t4 ) # Load normal 0 - + #srl $v1, $a3, 2 #andi $v1, $v1, 0x3 - + #sll $v0, 3 #addu $v0, $t2 #lwc2 C2_VXY0, 0( $v0 ) @@ -175,26 +177,26 @@ smdSortModelFlat: #beq $v1, 0x2, .F3_light_smt #nop - + #lw $v0, 4( $t4 ) #lui $v1, 0x2000 #or $v0, $v1 #mtc2 $v0, C2_RGB - + #addiu $t4, 8 #nop - + #NCCS #andi $v0, $a3, 0x20 # Textured triangle #bnez $v0, .F3_light_tex #nop - + #swc2 C2_RGB2, POLYF3_rgbc( $a1 ) - + #b .sort_F3_pri #nop - + #.F3_light_tex: #lhu $v0, 0( $t4 ) # Load texture coordinates @@ -203,23 +205,23 @@ smdSortModelFlat: #lhu $v0, 4( $t4 ) #sh $v1, POLYFT3_uv1( $a1 ) #sh $v0, POLYFT3_uv2( $a1 ) - + #lw $v1, 8( $t4 ) #nop #andi $v0, $v1, 0xffff #sh $v0, POLYFT3_tpage( $a1 ) #srl $v0, $v1, 16 #sh $v0, POLYFT3_clut( $a1 ) - + #mfc2 $v0, C2_RGB2 #lui $v1, 0x2400 #or $v0, $v1 - + #b .sort_FT3_pri #sw $v0, POLYFT3_rgbc( $a1 ) - + #.F3_light_smt: - + #lhu $v0, 2( $t4 ) # Load normals 1 and 2 #lhu $v1, 4( $t4 ) #sll $v0, 3 @@ -234,20 +236,20 @@ smdSortModelFlat: #lui $v1, 0x3000 # Load color #or $v0, $v1 #mtc2 $v0, C2_RGB - + #addiu $t4, 12 #nop - + #NCCT - + #andi $v0, $a3, 0x20 # Textured triangle #bnez $v0, .F3_light_tex_smt #nop - + #swc2 C2_RGB0, POLYG3_rgbc0( $a1 ) #swc2 C2_RGB1, POLYG3_rgbc1( $a1 ) #swc2 C2_RGB2, POLYG3_rgbc2( $a1 ) - + #b .sort_G3_pri #nop @@ -259,21 +261,21 @@ smdSortModelFlat: # lhu $v0, 4( $t4 ) # sh $v1, POLYGT3_uv1( $a1 ) # sh $v0, POLYGT3_uv2( $a1 ) - + # lw $v1, 8( $t4 ) # nop # andi $v0, $v1, 0xffff # sh $v0, POLYGT3_tpage( $a1 ) # srl $v0, $v1, 16 # sh $v0, POLYGT3_clut( $a1 ) - + # mfc2 $v0, C2_RGB0 # lui $v1, 0x3400 # or $v0, $v1 - + # swc2 C2_RGB1, POLYGT3_rgbc1( $a1 ) # swc2 C2_RGB2, POLYGT3_rgbc2( $a1 ) - + # b .sort_GT3_pri # sw $v0, POLYGT3_rgbc0( $a1 ) @@ -282,7 +284,7 @@ smdSortModelFlat: swc2 C2_SXY0, POLYF3_xy0($a1) swc2 C2_SXY1, POLYF3_xy1($a1) swc2 C2_SXY2, POLYF3_xy2($a1) - + la $v0, _smd_tpage_base lhu $v0, 0($v0) srl $v1, $a3, 6 # Get blend mode @@ -292,7 +294,7 @@ smdSortModelFlat: lui $v1, 0xe100 or $v0, $v1 sw $v0, POLYF3_tpage($a1) # Store TPage - + .set noat lui $v1, 0x0500 @@ -310,21 +312,21 @@ smdSortModelFlat: and $v0, $at or $v0, $a1 sw $v0, 0($a0) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYF3_len - + .sort_FT3_pri: swc2 C2_SXY0, POLYFT3_xy0( $a1 ) swc2 C2_SXY1, POLYFT3_xy1( $a1 ) swc2 C2_SXY2, POLYFT3_xy2( $a1 ) - + .set noat lui $v1, 0x0700 @@ -342,21 +344,21 @@ smdSortModelFlat: and $v0, $at or $v0, $a1 sw $v0, 0($a0) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYFT3_len - + .sort_G3_pri: swc2 C2_SXY0, POLYG3_xy0( $a1 ) swc2 C2_SXY1, POLYG3_xy1( $a1 ) swc2 C2_SXY2, POLYG3_xy2( $a1 ) - + la $v0, _smd_tpage_base lhu $v0, 0($v0) srl $v1, $a3, 6 # Get blend mode @@ -366,7 +368,7 @@ smdSortModelFlat: lui $v1, 0xe100 or $v0, $v1 sw $v0, POLYG3_tpage($a1) # Store TPage - + .set noat lui $v1, 0x0700 @@ -384,21 +386,21 @@ smdSortModelFlat: and $v0, $at or $v0, $a1 sw $v0, 0($a0) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYG3_len - + .sort_GT3_pri: swc2 C2_SXY0, POLYGT3_xy0( $a1 ) swc2 C2_SXY1, POLYGT3_xy1( $a1 ) swc2 C2_SXY2, POLYGT3_xy2( $a1 ) - + .set noat lui $v1, 0x0900 @@ -416,17 +418,17 @@ smdSortModelFlat: and $v0, $at or $v0, $a1 sw $v0, 0($a0) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYGT3_len ## Quads - + .prim_quad: # Quad processing mfc2 $t6, C2_SXY0 # Retrieve first projected vertex @@ -437,18 +439,18 @@ smdSortModelFlat: addu $t5, $t1 lwc2 C2_VXY0, 0( $t5 ) lwc2 C2_VZ0 , 4( $t5 ) - + nRTPS - + cfc2 $v1, C2_FLAG # Get GTE flag value - + nop - + bltz $v1, .skip_prim nop - + ClipTestQuad - + and $v0, $s0, $s1 # v0 & v1 beqz $v0, .do_draw_q and $v0, $s1, $s2 # v1 & v2 @@ -464,37 +466,37 @@ smdSortModelFlat: nop b .skip_prim nop - + .do_draw_q: srl $v0, $a3, 2 # Lighting enabled? andi $v0, 0x3 bnez $v0, .F4_light nop - + andi $v0, $a3, 0x10 # Gouraud quad bnez $v0, .F4_gouraud nop - + andi $v0, $a3, 0x20 # Textured quad bnez $v0, .F4_textured nop - + lw $v0, 0($t4) lui $v1, 0x2800 or $v0, $v1 - + b .sort_F4_pri sw $v0, POLYF4_rgbc($a1) .F4_textured: - + lw $v0, 0($t4) lui $v1, 0x2c00 or $v0, $v1 sw $v0, POLYFT4_rgbc( $a1 ) addiu $t4, 4 - + lhu $v0, 0($t4) # Load texture coordinates lhu $v1, 2($t4) sh $v0, POLYFT4_uv0( $a1 ) @@ -503,16 +505,16 @@ smdSortModelFlat: lhu $v1, 6( $t4 ) sh $v0, POLYFT4_uv2( $a1 ) sh $v1, POLYFT4_uv3( $a1 ) - + lw $v1, 8( $t4 ) nop andi $v0, $v1, 0xffff sh $v0, POLYFT4_tpage( $a1 ) srl $v0, $v1, 16 - + b .sort_FT4_pri sh $v0, POLYFT4_clut($a1) - + .F4_gouraud: lw $v0, 0($t4) @@ -528,15 +530,15 @@ smdSortModelFlat: sw $v0, POLYG4_rgbc2($a1) b .sort_G4_pri sw $v1, POLYG4_rgbc3($a1) - + .F4_light: lhu $v0, 0( $t4 ) # Load normal 0 - + srl $v1, $a3, 2 andi $v1, $v1, 0x3 - + sll $v0, 3 addu $v0, $t2 lwc2 C2_VXY0, 0( $v0 ) @@ -544,26 +546,26 @@ smdSortModelFlat: beq $v1, 0x2, .F4_light_smt nop - + lw $v0, 4( $t4 ) lui $v1, 0x2800 or $v0, $v1 mtc2 $v0, C2_RGB - + addiu $t4, 8 nop - + NCCS - + andi $v0, $a3, 0x20 # Textured triangle bnez $v0, .F4_light_tex nop swc2 C2_RGB2, POLYF4_rgbc( $a1 ) - + b .sort_F4_pri nop - + .F4_light_tex: lhu $v0, 0( $t4 ) # Load texture coordinates @@ -574,21 +576,21 @@ smdSortModelFlat: lhu $v1, 6( $t4 ) sh $v0, POLYFT4_uv2( $a1 ) sh $v1, POLYFT4_uv3( $a1 ) - + lw $v1, 8( $t4 ) nop andi $v0, $v1, 0xffff sh $v0, POLYFT4_tpage( $a1 ) srl $v0, $v1, 16 sh $v0, POLYFT4_clut( $a1 ) - + mfc2 $v0, C2_RGB2 lui $v1, 0x2c00 or $v0, $v1 - + b .sort_FT4_pri sw $v0, POLYFT4_rgbc( $a1 ) - + .F4_light_smt: lhu $v0, 2( $t4 ) # Load normals 1 and 2 @@ -601,38 +603,38 @@ smdSortModelFlat: lwc2 C2_VZ1 , 4( $v0 ) lwc2 C2_VXY2, 0( $v1 ) lwc2 C2_VZ2 , 4( $v1 ) - + lw $v0, 8( $t4 ) lui $v1, 0x3800 # Load color or $v0, $v1 mtc2 $v0, C2_RGB - + nNCCT - + lhu $v0, 6( $t4 ) # Load normal 3 - + addiu $t4, 12 - + sll $v0, 3 addu $v0, $t2 lwc2 C2_VXY0, 0( $v0 ) lwc2 C2_VZ0 , 4( $v0 ) - + andi $v0, $a3, 0x20 # Textured triangle bnez $v0, .F4_light_tex_smt nop - + swc2 C2_RGB0, POLYG4_rgbc0( $a1 ) swc2 C2_RGB1, POLYG4_rgbc1( $a1 ) swc2 C2_RGB2, POLYG4_rgbc2( $a1 ) - + nNCCS - + swc2 C2_RGB2, POLYG4_rgbc3( $a1 ) - + b .sort_G4_pri nop - + .F4_light_tex_smt: mfc2 $v0, C2_RGB0 @@ -641,9 +643,9 @@ smdSortModelFlat: sw $v0, POLYGT4_rgbc0( $a1 ) swc2 C2_RGB1, POLYGT4_rgbc1( $a1 ) swc2 C2_RGB2, POLYGT4_rgbc2( $a1 ) - + NCCS - + lhu $v0, 0( $t4 ) # Load texture coordinates lhu $v1, 2( $t4 ) sh $v0, POLYGT4_uv0( $a1 ) @@ -655,21 +657,21 @@ smdSortModelFlat: lw $v1, 8( $t4 ) swc2 C2_RGB2, POLYGT4_rgbc3( $a1 ) - + andi $v0, $v1, 0xffff sh $v0, POLYGT4_tpage( $a1 ) srl $v0, $v1, 16 - + b .sort_GT4_pri sh $v0, POLYGT4_clut( $a1 ) - + .sort_F4_pri: sw $t6, POLYF4_xy0($a1) swc2 C2_SXY0, POLYF4_xy1($a1) swc2 C2_SXY1, POLYF4_xy2($a1) swc2 C2_SXY2, POLYF4_xy3($a1) - + la $v0, _smd_tpage_base lhu $v0, 0($v0) srl $v1, $a3, 6 # Get blend mode @@ -679,7 +681,7 @@ smdSortModelFlat: lui $v1, 0xe100 or $v0, $v1 sw $v0, POLYF4_tpage($a1) # Store TPage - + .set noat lui $v1, 0x0600 @@ -697,22 +699,22 @@ smdSortModelFlat: and $v0, $at or $v0, $a1 sw $v0, 0($a0) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYF4_len - + .sort_FT4_pri: sw $t6, POLYFT4_xy0($a1) swc2 C2_SXY0, POLYFT4_xy1($a1) swc2 C2_SXY1, POLYFT4_xy2($a1) swc2 C2_SXY2, POLYFT4_xy3($a1) - + .set noat lui $v1, 0x0900 @@ -730,22 +732,22 @@ smdSortModelFlat: and $v0, $at or $v0, $a1 sw $v0, 0($a0) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYFT4_len - + .sort_G4_pri: sw $t6, POLYG4_xy0($a1) swc2 C2_SXY0, POLYG4_xy1($a1) swc2 C2_SXY1, POLYG4_xy2($a1) swc2 C2_SXY2, POLYG4_xy3($a1) - + la $v0, _smd_tpage_base lhu $v0, 0($v0) srl $v1, $a3, 6 # Get blend mode @@ -755,7 +757,7 @@ smdSortModelFlat: lui $v1, 0xe100 or $v0, $v1 sw $v0, POLYG4_tpage($a1) # Store TPage - + .set noat lui $v1, 0x0900 @@ -773,22 +775,22 @@ smdSortModelFlat: and $v0, $at or $v0, $a1 sw $v0, 0($a0) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYG4_len - + .sort_GT4_pri: sw $t6, POLYGT4_xy0($a1) swc2 C2_SXY0, POLYGT4_xy1($a1) swc2 C2_SXY1, POLYGT4_xy2($a1) swc2 C2_SXY2, POLYGT4_xy3($a1) - + .set noat lui $v1, 0x0c00 @@ -806,20 +808,20 @@ smdSortModelFlat: and $v0, $at or $v0, $a1 sw $v0, 0($a0) - + .set at lui $v0, 0x8000 or $a1, $v0 - + b .sort_loop addiu $a1, POLYGT4_len - + .skip_prim: b .sort_loop nop - + .exit: lw $s0, 0( $sp ) @@ -829,4 +831,3 @@ smdSortModelFlat: addiu $sp, 16 jr $ra move $v0, $a1 -
\ No newline at end of file diff --git a/examples/demos/n00bdemo/smdparser.s b/libpsn00b/smd/smdparser.s index 379690f..656e509 100644 --- a/examples/demos/n00bdemo/smdparser.s +++ b/libpsn00b/smd/smdparser.s @@ -1,6 +1,9 @@ +# PSn00bSDK .SMD model parser library +# (C) 2019-2023 Lameguy64, spicyjpeg - MPL licensed + .set noreorder -.include "smd_s.h" +.include "smd/smd_s.inc" .set SMD_PRI_ID, 0 .set SMD_PRI_v0, 4 @@ -22,108 +25,106 @@ .set SMD_PRI_tpage, 44 .set SMD_PRI_clut, 46 -.section .text - - -.comm _smd_parse_addr, 4, 4 - - +.section .text.OpenSMD, "ax", @progbits .global OpenSMD .type OpenSMD, @function + OpenSMD: lw $v0, SMD_HEAD_ID($a0) li $v1, 0x01444d53 - + bne $v0, $v1, .not_smd nop - + lw $v0, SMD_HEAD_PPRIMS($a0) la $v1, _smd_parse_addr sw $v0, 0($v1) - + jr $ra lhu $v0, SMD_HEAD_NPRIMS($a0) - + .not_smd: jr $ra move $v0, $0 - - + +.section .text.ReadSMD, "ax", @progbits .global ReadSMD .type ReadSMD, @function -ReadSMD: +ReadSMD: la $v0, _smd_parse_addr lw $v0, 0($v0) nop - + lw $a2, 0($v0) # Load primitive ID addiu $a1, $v0, 4 - + sw $a2, SMD_PRI_ID($a0) - + beqz $a2, $end_prim nop - + srl $v1, $a2, 24 # Get primitive size addu $v0, $v1 la $v1, _smd_parse_addr sw $v0, 0($v1) - + lw $v0, 0($a1) # Copy vertex coords lw $v1, 4($a1) sw $v0, SMD_PRI_v0($a0) sw $v1, SMD_PRI_v2($a0) addiu $a1, 8 - + srl $v0, $a2, 2 # Lighting enabled? andi $v0, 0x3 bnez $v0, $light nop - + b $no_light nop - + $light: srl $v1, $a2, 2 lw $v0, 0($a1) # Copy vertex coords andi $v1, 0x3 sw $v0, SMD_PRI_n0($a0) - + bne $v1, 0x2, $light_flat addiu $a1, 4 - + lw $v1, 0($a1) addiu $a1, 4 sw $v1, SMD_PRI_n2($a0) $light_flat: $no_light: - + lw $v0, 0($a1) nop sw $v0, SMD_PRI_rgbc0($a0) addiu $a1, 4 - + srl $v0, $a2, 5 andi $v0, 0x1 beqz $v0, $not_textured nop - + lw $v0, 0($a1) lw $v1, 4($a1) sw $v0, SMD_PRI_tuv0($a0) lw $v0, 8($a1) sw $v1, SMD_PRI_tuv2($a0) sw $v0, SMD_PRI_tpage($a0) - + $not_textured: - + jr $ra move $v0, $a0 - + $end_prim: jr $ra move $v0, $0 -
\ No newline at end of file + +.section .bss._smd_parse_addr, "w" +.comm _smd_parse_addr, 4, 4 |
