2020-12-24 20:03:45 +01:00
// With help from Nicolas Noble, Jaby smoll Seamonstah
// Based on Lameguy64's tutorial series : http://lameguy64.net/svn/pstutorials/chapter1/2-graphics.html
//
2020-12-27 19:30:21 +01:00
// From ../psyq/addons/graphics/MESH/RMESH/TUTO0.C :
//
/* PSX screen coordinate system
*
* Z +
* /
* /
* + - - - - - - X +
* / |
* / |
* / Y +
* eye */
2020-12-24 20:03:45 +01:00
# include <sys/types.h>
# include <stdio.h>
# include <libgte.h>
# include <libetc.h>
# include <libgpu.h>
# define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL
# define SCREENXRES 320 // Screen width
# define SCREENYRES 240 // Screen height
# define CENTERX SCREENXRES / 2 // Center of screen on x
# define CENTERY SCREENYRES / 2 // Center of screen on y
# define MARGINX 32 // margins for text display
# define MARGINY 32
# define FONTSIZE 8 * 5 // Text Field Height
# define OTLEN 8 // Ordering Table Length
DISPENV disp [ 2 ] ; // Double buffered DISPENV and DRAWENV
DRAWENV draw [ 2 ] ;
u_long ot [ 2 ] [ OTLEN ] ; // double ordering table of length 8 * 32 = 256 bits / 32 bytes
char primbuff [ 2 ] [ 32768 ] = { 1 } ; // double primitive buffer of length 32768 * 8 = 262.144 bits / 32,768 Kbytes
char * nextpri = primbuff [ 0 ] ; // pointer to the next primitive in primbuff. Initially, points to the first bit of primbuff[0]
short db = 0 ; // index of which buffer is used, values 0, 1
// 16bpp TIM
extern unsigned long _binary_TIM_bousai_tim_start [ ] ;
extern unsigned long _binary_TIM_bousai_tim_end [ ] ;
extern unsigned long _binary_TIM_bousai_tim_length ;
TIM_IMAGE bousai ;
MATRIX identity ( int num ) // generate num x num matrix
{
int row , col ;
MATRIX matrix ;
for ( row = 0 ; row < num ; row + + )
{
for ( col = 0 ; col < num ; col + + )
{
if ( row = = col )
matrix . m [ row ] [ col ] = 4096 ;
else
matrix . m [ row ] [ col ] = 0 ;
}
}
return matrix ;
}
void LoadTexture ( u_long * tim , TIM_IMAGE * tparam ) { // This part is from Lameguy64's tutorial series : lameguy64.net/svn/pstutorials/chapter1/3-textures.html login/pw: annoyingmous
OpenTIM ( tim ) ; // Open the tim binary data, feed it the address of the data in memory
ReadTIM ( tparam ) ; // This read the header of the TIM data and sets the corresponding members of the TIM_IMAGE structure
LoadImage ( tparam - > prect , tparam - > paddr ) ; // Transfer the data from memory to VRAM at position prect.x, prect.y
DrawSync ( 0 ) ; // Wait for the drawing to end
if ( tparam - > mode & 0x8 ) { // check 4th bit // If 4th bit == 1, TIM has a CLUT
LoadImage ( tparam - > crect , tparam - > caddr ) ; // Load it to VRAM at position crect.x, crect.y
DrawSync ( 0 ) ; // Wait for drawing to end
}
}
void init ( void )
{
ResetGraph ( 0 ) ;
// Initialize and setup the GTE
InitGeom ( ) ;
2020-12-27 19:30:21 +01:00
SetGeomOffset ( CENTERX , CENTERY ) ;
SetGeomScreen ( CENTERX ) ;
2020-12-24 20:03:45 +01:00
SetDefDispEnv ( & disp [ 0 ] , 0 , 0 , SCREENXRES , SCREENYRES ) ;
SetDefDispEnv ( & disp [ 1 ] , 0 , SCREENYRES , SCREENXRES , SCREENYRES ) ;
SetDefDrawEnv ( & draw [ 0 ] , 0 , SCREENYRES , SCREENXRES , SCREENYRES ) ;
SetDefDrawEnv ( & draw [ 1 ] , 0 , 0 , SCREENXRES , SCREENYRES ) ;
if ( VMODE )
{
SetVideoMode ( MODE_PAL ) ;
disp [ 0 ] . screen . y + = 8 ;
disp [ 1 ] . screen . y + = 8 ;
}
setRGB0 ( & draw [ 0 ] , 128 , 128 , 128 ) ;
setRGB0 ( & draw [ 1 ] , 128 , 128 , 128 ) ;
draw [ 0 ] . isbg = 1 ;
draw [ 1 ] . isbg = 1 ;
PutDispEnv ( & disp [ db ] ) ;
PutDrawEnv ( & draw [ db ] ) ;
FntLoad ( 960 , 0 ) ;
FntOpen ( MARGINX , SCREENYRES - MARGINY - FONTSIZE , SCREENXRES - MARGINX * 2 , FONTSIZE , 0 , 280 ) ;
}
void display ( void )
{
DrawSync ( 0 ) ;
VSync ( 0 ) ;
PutDispEnv ( & disp [ db ] ) ;
PutDrawEnv ( & draw [ db ] ) ;
SetDispMask ( 1 ) ;
DrawOTag ( ot [ db ] + OTLEN - 1 ) ;
db = ! db ;
nextpri = primbuff [ db ] ;
}
int main ( void )
{
MATRIX IDMATRIX = identity ( 3 ) ; // Generate 3x3 identity matrix
2020-12-27 19:30:21 +01:00
POLY_FT4 * poly = { 0 } ; // pointer to a POLY_G4
2020-12-24 20:03:45 +01:00
SVECTOR RotVector = { 0 , 0 , 0 } ; // Initialize rotation vector {x, y, z}
2020-12-27 19:30:21 +01:00
VECTOR MovVector = { 0 , 0 , CENTERX / 2 , 0 } ; // Initialize translation vector {x, y, z, pad}
VECTOR ScaleVector = { ONE , ONE , ONE } ; // ONE is define as 4096 in libgte.h
2020-12-24 20:03:45 +01:00
SVECTOR VertPos [ 4 ] = { // Set initial vertices position relative to 0,0 - see here : https://psx.arthus.net/docs/poly_f4.jpg
{ - 32 , - 32 , 1 } , // Vert 1
{ - 32 , 32 , 1 } , // Vert 2
{ 32 , - 32 , 1 } , // Vert 3
{ 32 , 32 , 1 } // Vert 4
} ;
MATRIX PolyMatrix = IDMATRIX ;
long polydepth ;
long polyflag ;
2020-12-27 19:30:21 +01:00
int ping = 0 ;
2020-12-24 20:03:45 +01:00
init ( ) ;
LoadTexture ( _binary_TIM_bousai_tim_start , & bousai ) ;
while ( 1 )
{
ClearOTagR ( ot [ db ] , OTLEN ) ;
poly = ( POLY_FT4 * ) nextpri ; // Set poly to point to the address of the next primitiv in the buffer
// Set transform matrices for this polygon
RotMatrix ( & RotVector , & PolyMatrix ) ; // Apply rotation matrix
TransMatrix ( & PolyMatrix , & MovVector ) ; // Apply translation matrix
2020-12-27 19:30:21 +01:00
ScaleMatrix ( & PolyMatrix , & ScaleVector ) ; // Apply scale matrix
2020-12-24 20:03:45 +01:00
SetRotMatrix ( & PolyMatrix ) ; // Set default rotation matrix
SetTransMatrix ( & PolyMatrix ) ; // Set default transformation matrix
setPolyFT4 ( poly ) ; // Initialize poly as a POLY_F4
poly - > tpage = getTPage ( bousai . mode & 0x3 , 0 , bousai . prect - > x , bousai . prect - > y ) ; // Get Tpage coordinates from the TIM_IMAGE mode and prect members.
setRGB0 ( poly , 128 , 128 , 128 ) ; // Set poly color (neutra here)
RotTransPers4 (
& VertPos [ 0 ] , & VertPos [ 1 ] , & VertPos [ 2 ] , & VertPos [ 3 ] ,
( long * ) & poly - > x0 , ( long * ) & poly - > x1 , ( long * ) & poly - > x2 , ( long * ) & poly - > x3 ,
& polydepth ,
& polyflag
) ; // Perform coordinate and perspective transformation for 4 vertices
setUV4 ( poly , 0 , 0 , 0 , 144 , 144 , 0 , 144 , 144 ) ; // Set UV coordinates in order Top Left, Bottom Left, Top Right, Bottom Right
2020-12-27 19:30:21 +01:00
// Let's have some fun on the Z axis
if ( ! ping ) {
if ( MovVector . vz < CENTERX ) { // While Poly position on Z axis is < 160, push it
MovVector . vz + = 1 ; // Push on Z axis
} else {
ping = ! ping ; // Switch ping value
}
}
if ( ping ) {
if ( MovVector . vz > CENTERX / 2 ) { // While Poly position on Z axis is > 80, pull it
MovVector . vz - = 1 ; // Pull on Z axis
} else {
ping = ! ping ; // Switch ping value
}
}
2020-12-24 20:03:45 +01:00
addPrim ( ot [ db ] , poly ) ; // add poly to the Ordering table
nextpri + = sizeof ( POLY_FT4 ) ; // increment nextpri address with size of a POLY_F4 struct
FntPrint ( " Hello textured poly ! " ) ;
FntFlush ( - 1 ) ;
display ( ) ;
}
return 0 ;
}