diff options
| author | John Wilbert M. Villamor <lameguy64@gmail.com> | 2020-04-24 19:01:28 +0800 |
|---|---|---|
| committer | John Wilbert M. Villamor <lameguy64@gmail.com> | 2020-04-24 19:01:28 +0800 |
| commit | 1aa0e17df7c325a41de8cf8a57f52ed853f08bf3 (patch) | |
| tree | 5ec7f69ca0104f2b0a41e2ee7d3cb0cf0c9c54c5 /examples/graphics/billboard | |
| parent | e82da2abe4c264d4b48a48d79cf9b8e4c4fb8ab6 (diff) | |
| download | psn00bsdk-1aa0e17df7c325a41de8cf8a57f52ed853f08bf3.tar.gz | |
Refined toolchain instructions, organized examples, added automatic retry for CdRead(), added FIOCSCAN ioctl in psxsio TTY driver, added tty and console examples.
Diffstat (limited to 'examples/graphics/billboard')
| -rw-r--r-- | examples/graphics/billboard/billboard.c | 260 | ||||
| -rw-r--r-- | examples/graphics/billboard/makefile | 39 | ||||
| -rw-r--r-- | examples/graphics/billboard/texture64.tim | bin | 0 -> 2112 bytes | |||
| -rw-r--r-- | examples/graphics/billboard/tim.s | 7 |
4 files changed, 306 insertions, 0 deletions
diff --git a/examples/graphics/billboard/billboard.c b/examples/graphics/billboard/billboard.c new file mode 100644 index 0000000..bba5dda --- /dev/null +++ b/examples/graphics/billboard/billboard.c @@ -0,0 +1,260 @@ +/* + * LibPSn00b Example Programs + * + * GTE Billboarding Sprites Example + * 2019 Meido-Tek Productions / PSn00bSDK Project + * + * Displays a bunch of sprites placed on the screen using 3D coordinates + * that scale according to the distance from the screen. This is a quick + * modification of the GTE cube example. + * + * Billboard sprites are useful for 2D projectiles flying across 3D space, + * particle effects such as smoke as well as characters and objects + * represented as 2D sprites. + * + * Example by Lameguy64 + * + * Changelog: + * + * Sep 24, 2019 - Initial version. + * + */ + +#include <stdio.h> +#include <psxgpu.h> +#include <psxgte.h> +#include <inline_c.h> + +/* OT and Packet Buffer sizes */ +#define OT_LEN 256 +#define PACKET_LEN 1024 + +/* Screen resolution */ +#define SCREEN_XRES 320 +#define SCREEN_YRES 240 + +/* Screen center position */ +#define CENTERX SCREEN_XRES>>1 +#define CENTERY SCREEN_YRES>>1 + + +/* Double buffer structure */ +typedef struct { + DISPENV disp; /* Display environment */ + DRAWENV draw; /* Drawing environment */ + int ot[OT_LEN]; /* Ordering table */ + char p[PACKET_LEN]; /* Packet buffer */ +} DB; + +/* Double buffer variables */ +DB db[2]; +int db_active = 0; +char *db_nextpri; + +extern int tim_image[]; +TIM_IMAGE tim; + +/* For easier handling of vertex indices */ +typedef struct { + short v0,v1,v2,v3; +} INDEX; + +/* Sprite position vertices */ +SVECTOR verts[] = { + { -50, -50, -50, 0 }, + { 50, -50, -50, 0 }, + { -50, 50, -50, 0 }, + { 50, 50, -50, 0 }, + { 50, -50, 50, 0 }, + { -50, -50, 50, 0 }, + { 50, 50, 50, 0 }, + { -50, 50, 50, 0 } +}; + + +/* Function declarations */ +void init(); +void display(); + + +/* Main function */ +int main() { + + int i,p,sz; + + SVECTOR rot = { 0 }; /* Rotation vector for Rotmatrix */ + VECTOR pos = { 0, 0, 160 }; /* Translation vector for TransMatrix */ + MATRIX mtx,lmtx; /* Rotation matrices for geometry and lighting */ + + POLY_FT4 *quad; /* Flat shaded quad primitive pointer */ + SVECTOR spos; + + /* Init graphics and GTE */ + init(); + + + /* Main loop */ + while( 1 ) { + + /* Set rotation and translation to the matrix */ + RotMatrix( &rot, &mtx ); + TransMatrix( &mtx, &pos ); + + /* Set rotation and translation matrix */ + gte_SetRotMatrix( &mtx ); + gte_SetTransMatrix( &mtx ); + + /* Make the sprites revolve around */ + rot.vy += 16; + rot.vz += 16; + + /* Draw the sprites */ + quad = (POLY_FT4*)db_nextpri; + + for( i=0; i<8; i++ ) { + + // Load the 3D coordinate of the sprite to GTE + gte_ldv0(&verts[i]); + + // Rotation, Translation and Perspective Single + gte_rtps(); + + // Store depth + gte_stsz(&p); + + // Don't sort sprite if depth is zero + // (or divide by zero will happen later) + if( p > 0 ) { + + // Store result to position vector + gte_stsxy2(&spos); + + // Calculate sprite size, the divide operation might be a + // performance killer but it's likely faster than performing + // a lookat operation between sprite and camera, which some + // billboard sprite implementations use. + sz = (16*CENTERX)/p; + + // Prepare quad primitive + setPolyFT4(quad); + + // Set quad coordinates + setXY4(quad, + spos.vx-sz, spos.vy-sz, + spos.vx+sz, spos.vy-sz, + spos.vx-sz, spos.vy+sz, + spos.vx+sz, spos.vy+sz); + + // Set color + setRGB0(quad, 128, 128, 128); + + // Set tpage + quad->tpage = getTPage(tim.mode&0x8, 0, tim.prect->x, tim.prect->y); + + // Set CLUT + setClut(quad, tim.crect->x, tim.crect->y); + + // Set texture coordinates + setUVWH(quad, 0, 0, 64, 64); + + /* Sort primitive to the ordering table */ + addPrim(db[db_active].ot+(p>>2), quad); + + /* Advance to make another primitive */ + quad++; + + } + } + + /* Update nextpri variable */ + /* (IMPORTANT if you plan to sort more primitives after this) */ + db_nextpri = (char*)quad; + + /* Swap buffers and draw the primitives */ + display(); + + } + + return 0; + +} + +void init() { + + /* Reset the GPU, also installs a VSync event handler */ + ResetGraph( 0 ); + + /* Set display and draw environment areas */ + /* (display and draw areas must be separate, otherwise hello flicker) */ + SetDefDispEnv( &db[0].disp, 0, 0, SCREEN_XRES, SCREEN_YRES ); + SetDefDrawEnv( &db[0].draw, SCREEN_XRES, 0, SCREEN_XRES, SCREEN_YRES ); + + /* Enable draw area clear and dither processing */ + setRGB0( &db[0].draw, 63, 0, 127 ); + db[0].draw.isbg = 1; + db[0].draw.dtd = 1; + + + /* Define the second set of display/draw environments */ + SetDefDispEnv( &db[1].disp, SCREEN_XRES, 0, SCREEN_XRES, SCREEN_YRES ); + SetDefDrawEnv( &db[1].draw, 0, 0, SCREEN_XRES, SCREEN_YRES ); + + setRGB0( &db[1].draw, 63, 0, 127 ); + db[1].draw.isbg = 1; + db[1].draw.dtd = 1; + + + /* Apply the drawing environment of the first double buffer */ + PutDrawEnv( &db[0].draw ); + + + /* Clear both ordering tables to make sure they are clean at the start */ + ClearOTagR( db[0].ot, OT_LEN ); + ClearOTagR( db[1].ot, OT_LEN ); + + /* Set primitive pointer address */ + db_nextpri = db[0].p; + + /* Initialize the GTE */ + InitGeom(); + + /* Set GTE offset (recommended method of centering) */ + gte_SetGeomOffset( CENTERX, CENTERY ); + + /* Set screen depth (basically FOV control, W/2 works best) */ + gte_SetGeomScreen( CENTERX ); + + GetTimInfo(tim_image, &tim); + + LoadImage(tim.prect, tim.paddr); + DrawSync(0); + + LoadImage(tim.crect, tim.caddr); + DrawSync(0); + +} + +void display() { + + /* Wait for GPU to finish drawing and vertical retrace */ + DrawSync( 0 ); + VSync( 0 ); + + /* Swap buffers */ + db_active ^= 1; + db_nextpri = db[db_active].p; + + /* Clear the OT of the next frame */ + ClearOTagR( db[db_active].ot, OT_LEN ); + + /* Apply display/drawing environments */ + PutDrawEnv( &db[db_active].draw ); + PutDispEnv( &db[db_active].disp ); + + /* Enable display */ + SetDispMask( 1 ); + + /* Start drawing the OT of the last buffer */ + DrawOTag( db[1-db_active].ot+(OT_LEN-1) ); + +}
\ No newline at end of file diff --git a/examples/graphics/billboard/makefile b/examples/graphics/billboard/makefile new file mode 100644 index 0000000..d6add7a --- /dev/null +++ b/examples/graphics/billboard/makefile @@ -0,0 +1,39 @@ +include ../../sdk-common.mk + +TARGET = billboard.elf + +CFILES = $(notdir $(wildcard *.c)) +CPPFILES = $(notdir $(wildcard *.cpp)) +AFILES = $(notdir $(wildcard *.s)) + +OFILES = $(addprefix build/,$(CFILES:.c=.o) $(CPPFILES:.cpp=.o) $(AFILES:.s=.o)) + +INCLUDE += +LIBDIRS += + +LIBS = -lpsxetc -lpsxgpu -lpsxgte -lpsxspu -lpsxapi -lc + +CFLAGS = -g -O2 -fno-builtin -fdata-sections -ffunction-sections +CPPFLAGS = $(CFLAGS) -fno-exceptions +AFLAGS = -g -msoft-float +LDFLAGS = -g -Ttext=0x80010000 -gc-sections -T $(GCC_BASE)/mipsel-unknown-elf/lib/ldscripts/elf32elmip.x + +CC = $(PREFIX)gcc +CXX = $(PREFIX)g++ +AS = $(PREFIX)as +LD = $(PREFIX)ld + +all: $(OFILES) + $(LD) $(LDFLAGS) $(LIBDIRS) $(OFILES) $(LIBS) -o $(TARGET) + elf2x -q $(TARGET) + +build/%.o: %.c + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ + +build/%.o: %.s + @mkdir -p $(dir $@) + $(CC) $(AFLAGS) $(INCLUDE) -c $< -o $@ + +clean: + rm -rf build $(TARGET) $(TARGET:.elf=.exe) diff --git a/examples/graphics/billboard/texture64.tim b/examples/graphics/billboard/texture64.tim Binary files differnew file mode 100644 index 0000000..d3aff3a --- /dev/null +++ b/examples/graphics/billboard/texture64.tim diff --git a/examples/graphics/billboard/tim.s b/examples/graphics/billboard/tim.s new file mode 100644 index 0000000..1fa8d69 --- /dev/null +++ b/examples/graphics/billboard/tim.s @@ -0,0 +1,7 @@ +.section .data + +.global tim_image +.type tim_image, @object +tim_image: + .incbin "texture64.tim" +
\ No newline at end of file |
