Add PSX code

This commit is contained in:
ABelliqueux 2020-12-27 17:36:47 +01:00
parent cb20a1c247
commit 51515c7b02
4 changed files with 392 additions and 48 deletions

35
Makefile Normal file
View File

@ -0,0 +1,35 @@
TARGET = primdrawG
TYPE = ps-exe
SRCS = primdrawG.c \
../common/crt0/crt0.s \
#~ trisamp.c \
CPPFLAGS += -I../psyq/include
LDFLAGS += -L../psyq/lib
LDFLAGS += -Wl,--start-group
LDFLAGS += -lapi
LDFLAGS += -lc
LDFLAGS += -lc2
LDFLAGS += -lcard
LDFLAGS += -lcomb
LDFLAGS += -lds
LDFLAGS += -letc
LDFLAGS += -lgpu
LDFLAGS += -lgs
LDFLAGS += -lgte
LDFLAGS += -lgun
LDFLAGS += -lhmd
LDFLAGS += -lmath
LDFLAGS += -lmcrd
LDFLAGS += -lmcx
LDFLAGS += -lpad
LDFLAGS += -lpress
LDFLAGS += -lsio
LDFLAGS += -lsnd
LDFLAGS += -lspu
LDFLAGS += -ltap
LDFLAGS += -Wl,--end-group
include ../common.mk \

View File

@ -1,12 +1,12 @@
# blender_io_export_psx_mesh # blender_io_export_psx_tmesh
Blender <= 2.79c plugin to export a PSX mesh to a C file. Blender <= 2.79c plugin to export a gouraud shaded PSX mesh to a C file.
Specifically, it generates a C file containing : Specifically, it generates a C file containing :
* an array of SVECTOR containing the vertices coordinates * an array of SVECTOR containing the vertices coordinates
* an array of SVECTOR containing the normals * an array of SVECTOR containing the normals
* an array of CVECTOR containg the color of each vertex * an array of CVECTOR containing the color of each vertex
* an array of int that describe the relation between the tri meshes * an array of int that describe the relation between the tri meshes
* a TMESH struct to ease access to those arrays * a TMESH struct to ease access to those arrays
@ -23,9 +23,9 @@ typedef struct {
``` ```
# Install # Install the plugin
Put the `io_export_psx_mesh.py` file in the addons folder of blender 2.79 : Put the `io_export_psx_tmesh.py` file in the addons folder of blender 2.79 :
On Linux, that's : On Linux, that's :
@ -38,59 +38,23 @@ On Linux, that's :
2. When your model is ready, you can then vertex paint it. If you don't, the vertices colors will default to white. 2. When your model is ready, you can then vertex paint it. If you don't, the vertices colors will default to white.
* If you modify your geometry *after* vertex painting, the plugin will faile to export the mesh. This is because the vertex color data is set to 0 each time you modify your geometry. * If you modify your geometry *after* vertex painting, the plugin will faile to export the mesh. This is because the vertex color data is set to 0 each time you modify your geometry.
3. Get the example code by Lameguy64 from [here](http://psx.arthus.net/code/primdraw.7z)
4. Edit the `primdraw.c` file 3. If needed, edit the `primdraw.c` file , lines 29 and 30, to reflect the number of tris you want to be able to draw ( seems like the PSX is happy with max 1800 )
* lines 29 and 30 to reflect the number of tris you want to be able to draw
```c ```c
#define OT_LENGTH 2048 // Maximum number of OT entries #define OT_LENGTH 2048 // Maximum number of OT entries
#define MAX_PRIMS 1024 // Maximum number of POLY_FT3 primitives #define MAX_PRIMS 1024 // Maximum number of POLY_GT3 primitives
``` ```
seem to be safe values. seem to be safe values.
* to reflect the values in your exported .c file :
For example, if you export the start cube after vertex painting and triangulation : # Compiling
lines 190 to 199 of the original file : The provided `Makefile` uses the [Nugget+PsyQ setup](https://github.com/ABelliqueux/nolibgs_hello_worlds#setting-up-the-sdk--modern-gcc--psyq-aka-nuggetpsyq).
```c Create a folder in `(...)/pcsx-redux/src/mips/`, put the `Makefile`, `cube.c` and `primdrawG.c` in it, then in a terminal, just type `make` to build the ps-exe.
for (i=0; i<vec.len; i++) {
// Initialize the primitive and set its color values
SetPolyF3(&myPrims[ActivePage][myPrimNum]);
setRGB0(&myPrims[ActivePage][myPrimNum], vec_color[i].r, vec_color[i].g, vec_color[i].b);
// Rotate, translate, and project the vectors and output the results into a primitive
OTz = RotTransPers(&vec_mesh[t], (long*)&myPrims[ActivePage][myPrimNum].x0, &p, &Flag);
OTz += RotTransPers(&vec_mesh[t+1], (long*)&myPrims[ActivePage][myPrimNum].x1, &p, &Flag);
OTz += RotTransPers(&vec_mesh[t+2], (long*)&myPrims[ActivePage][myPrimNum].x2, &p, &Flag);
```
become :
```c
for (i=0; i<modelCube.len; i++) {
// Initialize the primitive and set its color values
SetPolyF3(&myPrims[ActivePage][myPrimNum]);
setRGB0(&myPrims[ActivePage][myPrimNum], modelCube_color[i].r, modelCube_color[i].g, modelCube_color[i].b);
// Rotate, translate, and project the vectors and output the results into a primitive
OTz = RotTransPers(&modelCube_mesh[modelCube_index[t]], (long*)&myPrims[ActivePage][myPrimNum].x0, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[modelCube_index[t+1]], (long*)&myPrims[ActivePage][myPrimNum].x1, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[modelCube_index[t+2]], (long*)&myPrims[ActivePage][myPrimNum].x2, &p, &Flag);
```
# Credits # Credits
Author of the code example is [Lameguy64](https://github.com/Lameguy64) Based on the [code](https://pastebin.com/suU9DigB) provided by TheDukeOfZill, 04-2014, on http://www.psxdev.net/forum/viewtopic.php?f=64&t=537#p4088
Original author of the plugin is TheDukeOfZill, 04-2014
Original post : http://www.psxdev.net/forum/viewtopic.php?f=64&t=537&sid=f5d30dcfdef34bc9f4d644033ba93a98 PSX code based on [example](http://psx.arthus.net/code/primdraw.7z) by [Lameguy64](https://github.com/Lameguy64)

87
cube.c Normal file
View File

@ -0,0 +1,87 @@
SVECTOR modelCube_mesh[] = {
{20.0,19.999998807907104,-20.0},
{20.0,-20.0,-20.0},
{-20.00000238418579,-19.999996423721313,-20.0},
{-19.999992847442627,20.000007152557373,-20.0},
{20.000009536743164,19.99998927116394,20.0},
{19.99998688697815,-20.000011920928955,20.0},
{-20.000007152557373,-19.999992847442627,20.0},
{-19.999998807907104,20.0,20.0}
};
SVECTOR modelCube_normal[] = {
0.0,-0.0,-1.0,0,
0.0,0.0,1.0,0,
1.0,0.0,-2.384185791015625e-07,0,
-8.940696716308594e-08,-1.0,-2.9802325229866256e-07,0,
-1.0,2.384185791015625e-07,-1.4901158351676713e-07,0,
2.6822084464583895e-07,1.0,2.3841852225814364e-07,0,
0.0,0.0,-1.0,0,
0.0,-0.0,1.0,0,
1.0,-5.662441253662109e-07,3.2782537573439186e-07,0,
-4.768372150465439e-07,-1.0,8.940690321423972e-08,0,
-1.0,2.0861631355728605e-07,-1.1920931797249068e-07,0,
2.0861631355728605e-07,1.0,1.7881397695873602e-07,0
};
CVECTOR modelCube_color[] = {
255,255,255, 0,
255,255,255, 0,
54,65,255, 0,
255,255,255, 0,
255,5,7, 0,
255,255,255, 0,
255,255,255, 0,
255,255,255, 0,
4,18,255, 0,
255,5,7, 0,
255,255,255, 0,
255,255,255, 0,
254,255,23, 0,
122,255,107, 0,
255,255,255, 0,
255,255,255, 0,
255,255,255, 0,
254,255,94, 0,
255,255,255, 0,
35,255,11, 0,
255,255,255, 0,
255,255,255, 0,
255,255,255, 0,
255,5,7, 0,
255,255,255, 0,
255,5,7, 0,
255,255,255, 0,
255,5,7, 0,
255,255,255, 0,
255,255,255, 0,
254,255,23, 0,
255,255,255, 0,
122,255,107, 0,
255,255,255, 0,
54,65,255, 0,
255,255,255, 0
};
int modelCube_index[] = {
0,2,3,
7,5,4,
4,1,0,
5,2,1,
2,7,3,
0,7,4,
0,1,2,
7,6,5,
4,5,1,
5,6,2,
2,6,7,
0,3,7
};
TMESH modelCube = {
modelCube_mesh,
modelCube_normal,
0,
modelCube_color,
12
};

258
primdrawG.c Normal file
View File

@ -0,0 +1,258 @@
/* primdrawG.c, by Schnappy, 12-2020
- Draw a gouraud shaded mesh exported as a TMESH by the blender <= 2.79b plugin io_export_psx_tmesh.py
based on primdraw.c by Lameguy64 (http://www.psxdev.net/forum/viewtopic.php?f=64&t=537)
2014 Meido-Tek Productions.
Demonstrates:
- Using a primitive OT to draw triangles without libgs.
- Using the GTE to rotate, translate, and project 3D primitives.
Controls:
Start - Toggle interactive/non-interactive mode.
Select - Reset object's position and angles.
L1/L2 - Move object closer/farther.
L2/R2 - Rotate object (XY).
Up/Down/Left/Right - Rotate object (XZ/YZ).
Triangle/Cross/Square/Circle - Move object up/down/left/right.
*/
#include <sys/types.h>
#include <libgte.h>
#include <libgpu.h>
#include <libetc.h>
#include <stdio.h>
// Sample vector model
#include "cube.c"
#define HI_RES 0 // 0: 320x240, 1: 640x480
#define OT_LENGTH 3072 // Maximum number of OT entries
#define MAX_PRIMS 2048 // Maximum number of POLY_GT3 primitives
// Center screen coordinates
#if HI_RES
#define CENTERX 320
#define CENTERY 240
#else
#define CENTERX 160
#define CENTERY 120
#endif
// Display and draw environments
DISPENV disp;
DRAWENV draw;
u_long ot[2][OT_LENGTH]; // Ordering table (contains addresses to primitives)
POLY_G3 primbuff[2][MAX_PRIMS]; // Primitive list // That's our prim buffer
int primcnt=0; // Primitive counter
// Prototypes
int main();
int main() {
int db = 0; // That's db
#if HI_RES == 0
RECT ClearRect ={0,0,320,240};
#else
RECT ClearRect ={0,0,640,480};
#endif
int i;
int PadStatus;
int TPressed=0;
int AutoRotate=1;
long t, p, OTz, Flag; // t == vertex count, p == depth cueing interpolation value, OTz == value to create Z-ordered OT, Flag == see LibOver47.pdf, p.143
SVECTOR Rotate={ 0 }; // Rotation coordinates
VECTOR Trans={ 0, 0, CENTERX, 0 }; // Translation coordinates
// Scaling coordinates
VECTOR Scale={ ONE*(1+HI_RES), ONE*(1+HI_RES), ONE*(1+HI_RES), 0 }; // ONE == 4096, is * 2 if HI_RES == 1
MATRIX Matrix={0}; // Matrix data for the GTE
// Reset the GPU before doing anything and the controller
PadInit(0);
ResetGraph(0);
// Initialize and setup the GTE
InitGeom();
SetGeomOffset(CENTERX, CENTERY); // x, y offset
SetGeomScreen(CENTERX); // Distance between eye and screen
// Init font system
FntLoad(960, 0);
FntOpen(0, 0, 640, 480, 0, 512);
// Set the display and draw environments
#if HI_RES == 0 // 320x240
SetDefDispEnv(&disp, 0, 0, 320, 240);
SetDefDrawEnv(&draw, 0, 240, 320, 240);
#else // 640x480
SetDefDispEnv(&disp, 0, 0, 640, 480);
SetDefDrawEnv(&draw, 0, 0, 640, 480);
#endif
// Set the new display/drawing environments
VSync(0);
PutDispEnv(&disp);
PutDrawEnv(&draw);
ClearImage(&ClearRect, 0, 0, 127); // Clear FB
// Main loop
while (1) {
// Render the banner (FntPrint is always on top because it is not part of the OT)
#if HI_RES
FntPrint("\n\n");
#endif
FntPrint("\n\nGOURAUD SHADED TMESH EXAMPLE\n");
FntPrint("SCHNAPPY, 2020 \n");
FntPrint("BASED ON PRIMDRAW BY LAMEGUY64, 2014 \n");
// Read pad status
PadStatus = PadRead(0);
if (AutoRotate == 0) {
if (PadStatus & PADL1) Trans.vz -= 4;
if (PadStatus & PADR1) Trans.vz += 4;
if (PadStatus & PADL2) Rotate.vz -= 8;
if (PadStatus & PADR2) Rotate.vz += 8;
if (PadStatus & PADLup) Rotate.vx -= 8;
if (PadStatus & PADLdown) Rotate.vx += 8;
if (PadStatus & PADLleft) Rotate.vy -= 8;
if (PadStatus & PADLright) Rotate.vy += 8;
if (PadStatus & PADRup) Trans.vy -= 2;
if (PadStatus & PADRdown) Trans.vy += 2;
if (PadStatus & PADRleft) Trans.vx -= 2;
if (PadStatus & PADRright) Trans.vx += 2;
if (PadStatus & PADselect) {
Rotate.vx = Rotate.vy = Rotate.vz = 0;
Scale.vx = Scale.vy = Scale.vz = ONE*(1+HI_RES);
Trans.vx = Trans.vy = 0;
Trans.vz = CENTERX;
}
}
if (PadStatus & PADstart) {
if (TPressed == 0) {
AutoRotate = (AutoRotate + 1) & 1;
Rotate.vx = Rotate.vy = Rotate.vz = 0;
Scale.vx = Scale.vy = Scale.vz = ONE*(1+HI_RES);
Trans.vx = Trans.vy = 0;
Trans.vz = CENTERX;
}
TPressed = 1;
} else {
TPressed = 0;
}
if (AutoRotate) {
Rotate.vy += 8; // Pan
Rotate.vx += 8; // Tilt
//~ Rotate.vz += 8; // Roll
}
// Clear the current OT
ClearOTagR(&ot[db][0], OT_LENGTH);
primcnt = 0;
// Convert and set the matrixes
RotMatrix(&Rotate, &Matrix);
TransMatrix(&Matrix, &Trans);
ScaleMatrix(&Matrix, &Scale);
SetRotMatrix(&Matrix);
SetTransMatrix(&Matrix);
// Render the sample vector model
t=0;
// modelCube is a TMESH, len member == # vertices, but here it's # of triangle... So, for each tri * 3 vertices ...
for (i = 0; i < (modelCube.len*3); i += 3) {
// Initialize the primitive and set its color values
SetPolyG3(&primbuff[db][primcnt]);
setRGB0(&primbuff[db][primcnt], modelCube_color[i].r, modelCube_color[i].g, modelCube_color[i].b);
setRGB1(&primbuff[db][primcnt], modelCube_color[i+1].r, modelCube_color[i+1].g, modelCube_color[i+1].b);
setRGB2(&primbuff[db][primcnt], modelCube_color[i+2].r, modelCube_color[i+2].g, modelCube_color[i+2].b);
// Rotate, translate, and project the vectors and output the results into a primitive
// RotTransPers(*vertex coordinate vector, *screen coordinates, *p (see line 69), * flag)
OTz = RotTransPers(&modelCube_mesh[modelCube_index[t]], (long*)&primbuff[db][primcnt].x0, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[modelCube_index[t+1]], (long*)&primbuff[db][primcnt].x1, &p, &Flag);
OTz += RotTransPers(&modelCube_mesh[modelCube_index[t+2]], (long*)&primbuff[db][primcnt].x2, &p, &Flag);
// Sort the primitive into the OT
OTz /= 3;
if ((OTz > 0) && (OTz < OT_LENGTH))
AddPrim(&ot[db][OTz-2], &primbuff[db][primcnt]);
primcnt++;
t+=3;
}
// Prepare to switch buffers
#if HI_RES == 0
SetDefDispEnv(&disp, 0, 240*db, 320, 240);
SetDefDrawEnv(&draw, 0, 240*(1-db), 320, 240);
#endif
// Wait for all drawing to finish
DrawSync(0);
// Clear the current buffer before rendering the next frame
#if HI_RES == 0
ClearRect.y = 240*db;
#endif
ClearImage(&ClearRect, 0, 0, 127);
// Begin rendering the next frame
DrawOTag(&ot[db][OT_LENGTH-1]);
FntFlush(0);
// Wait for VSync and then switch buffers
VSync(0);
#if HI_RES == 0
PutDispEnv(&disp);
PutDrawEnv(&draw);
#endif
SetDispMask(1);
// Toggle buffer index
#if HI_RES == 0
db = !db;
#endif
}
}