aboutsummaryrefslogtreecommitdiff
path: root/examples/graphics/billboard
diff options
context:
space:
mode:
authorJohn Wilbert M. Villamor <lameguy64@gmail.com>2020-04-24 19:01:28 +0800
committerJohn Wilbert M. Villamor <lameguy64@gmail.com>2020-04-24 19:01:28 +0800
commit1aa0e17df7c325a41de8cf8a57f52ed853f08bf3 (patch)
tree5ec7f69ca0104f2b0a41e2ee7d3cb0cf0c9c54c5 /examples/graphics/billboard
parente82da2abe4c264d4b48a48d79cf9b8e4c4fb8ab6 (diff)
downloadpsn00bsdk-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.c260
-rw-r--r--examples/graphics/billboard/makefile39
-rw-r--r--examples/graphics/billboard/texture64.timbin0 -> 2112 bytes
-rw-r--r--examples/graphics/billboard/tim.s7
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
new file mode 100644
index 0000000..d3aff3a
--- /dev/null
+++ b/examples/graphics/billboard/texture64.tim
Binary files differ
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