diff options
| author | John "Lameguy" Wilbert Villamor <lameguy64@gmail.com> | 2021-08-31 13:23:20 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-31 13:23:20 +0800 |
| commit | ffa679d4d24b891cb59aba10946368f2ec00c391 (patch) | |
| tree | 0cf6061915ebf48acdedf6d77b0c1b76eec5b8c3 /examples/system/dynlink/library/cube.c | |
| parent | 317dc2b91d3afcdbaddb035f38611d12af161970 (diff) | |
| parent | f2fc18f82dd7900465d6ab3ae2080726d5589d39 (diff) | |
| download | psn00bsdk-ffa679d4d24b891cb59aba10946368f2ec00c391.tar.gz | |
Merge pull request #36 from spicyjpeg/dynlink
Dynamic linker, gp-relative addressing, ldscripts and more
Diffstat (limited to 'examples/system/dynlink/library/cube.c')
| -rw-r--r-- | examples/system/dynlink/library/cube.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/examples/system/dynlink/library/cube.c b/examples/system/dynlink/library/cube.c new file mode 100644 index 0000000..57f3e56 --- /dev/null +++ b/examples/system/dynlink/library/cube.c @@ -0,0 +1,154 @@ +/* + * PSn00bSDK dynamic linker example (DLL 1) + * (C) 2021 spicyjpeg - MPL licensed + */ + +#include <sys/types.h> +#include <stdio.h> +#include <psxgpu.h> +#include <psxgte.h> +#include <psxpad.h> +#include <inline_c.h> + +#include "dll_common.h" + +/* Cube model */ + +typedef struct { + int16_t v0, v1, v2, v3; +} INDEX; + +static SVECTOR cube_verts[] = { + { -100, -100, -100, 0 }, + { 100, -100, -100, 0 }, + { -100, 100, -100, 0 }, + { 100, 100, -100, 0 }, + { 100, -100, 100, 0 }, + { -100, -100, 100, 0 }, + { 100, 100, 100, 0 }, + { -100, 100, 100, 0 } +}; +static SVECTOR cube_norms[] = { + { 0, 0, -ONE, 0 }, + { 0, 0, ONE, 0 }, + { 0, -ONE, 0, 0 }, + { 0, ONE, 0, 0 }, + { -ONE, 0, 0, 0 }, + { ONE, 0, 0, 0 } +}; +static INDEX cube_indices[] = { + { 0, 1, 2, 3 }, + { 4, 5, 6, 7 }, + { 5, 4, 0, 1 }, + { 6, 7, 3, 2 }, + { 0, 2, 5, 7 }, + { 3, 1, 6, 4 } +}; + +#define CUBE_FACES 6 + +/* Light matrices */ + +// Each column represents the color matrix of each light source and is used as +// material color when using gte_ncs() or multiplied by a source color when +// using gte_nccs(). 4096 is 1.0 in this matrix. A column of zeroes disables +// the light source. +static MATRIX color_mtx = { + ONE, 0, 0, // R + ONE, 0, 0, // G + ONE, 0, 0 // B +}; + +// Each row represents a vector direction of each light source. An entire row +// of zeroes disables the light source. +static MATRIX light_mtx = { + -2048, -2048, -2048, + 0, 0, 0, + 0, 0, 0 +}; + +/* Functions called by the main executable */ + +// NOTE: DLLs have no main(), _start() or other defined entry point. C++ global +// objects are automatically constructed when loading the library, and their +// destructors are called when unloading it via dlclose(). Other than that, the +// main executable can freely call DLL functions in any order, however it's +// still recommended (at least for C code) to have an init() function to e.g. +// initialize variables or hardware. + +static uint32_t frame = 0; +static SVECTOR rot = { 0 }; +static VECTOR pos = { 0, 0, 400 }; +static MATRIX mtx, lmtx; + +void init(CONTEXT *ctx) { + InitGeom(); + + gte_SetGeomOffset(ctx->xres / 2, ctx->yres / 2); + gte_SetGeomScreen(ctx->xres / 2); + gte_SetBackColor(63, 63, 63); + gte_SetColorMatrix(&color_mtx); +} + +void render(CONTEXT *ctx, uint16_t buttons) { + RotMatrix(&rot, &mtx); + TransMatrix(&mtx, &pos); + MulMatrix0(&light_mtx, &mtx, &lmtx); + + gte_SetRotMatrix(&mtx); + gte_SetTransMatrix(&mtx); + gte_SetLightMatrix(&lmtx); + + // Spin the cube faster is cross is pressed. + int16_t step = !(buttons & PAD_CROSS) ? 32 : 16; + rot.vx += step; + rot.vz += step; + + DB *db = &(ctx->db[ctx->db_active]); + POLY_F4 *pol4 = (POLY_F4 *) ctx->db_nextpri; + + for (uint32_t i = 0; i < CUBE_FACES; i++) { + int32_t p; + + gte_ldv3( + &cube_verts[cube_indices[i].v0], + &cube_verts[cube_indices[i].v1], + &cube_verts[cube_indices[i].v2] + ); + + gte_rtpt(); + gte_nclip(); + gte_stopz(&p); + if (p < 0) + continue; + + gte_avsz4(); + gte_stotz(&p); + if ((p >> 2) > OT_LEN) + continue; + + setPolyF4(pol4); + + gte_stsxy0(&(pol4->x0)); + gte_stsxy1(&(pol4->x1)); + gte_stsxy2(&(pol4->x2)); + + gte_ldv0(&(cube_verts[cube_indices[i].v3])); + gte_rtps(); + gte_stsxy(&(pol4->x3)); + + gte_ldrgb(&(pol4->r0)); + gte_ldv0(&(cube_norms[i])); + gte_ncs(); + gte_strgb(&(pol4->r0)); + + addPrim(&(db->ot[p >> 2]), pol4); + pol4++; + } + + ctx->db_nextpri = (uint8_t *) pol4; + + // Due to our custom resolver, this will actually call dll_printf() in the + // main executable. + printf("DRAWING CUBE, COUNTER=%d\n", frame++); +} |
