commit
57b07ae84f
9 changed files with 340 additions and 0 deletions
-
2.gitignore
-
25CMakeLists.txt
-
23CMakePresets.json
-
34iso.xml
-
252main.c
-
BINplayer128-16.tim
-
BINplayer128.tim
-
BINshambler128.tim
-
4system.cnf
@ -0,0 +1,2 @@ |
|||||
|
.vscode/ |
||||
|
build/ |
||||
@ -0,0 +1,25 @@ |
|||||
|
# PSn00bSDK example CMake script |
||||
|
# (C) 2021 spicyjpeg - MPL licensed |
||||
|
|
||||
|
cmake_minimum_required(VERSION 3.20) |
||||
|
|
||||
|
project( |
||||
|
PSn00bSDK-template |
||||
|
LANGUAGES C CXX ASM |
||||
|
VERSION 1.0.0 |
||||
|
DESCRIPTION "PSn00bSDK template" |
||||
|
HOMEPAGE_URL "http://lameguy64.net/?page=psn00bsdk" |
||||
|
) |
||||
|
|
||||
|
psn00bsdk_add_executable(template STATIC main.c) |
||||
|
|
||||
|
psn00bsdk_target_incbin(template PRIVATE tim_player128 player128.tim) |
||||
|
psn00bsdk_target_incbin(template PRIVATE tim_player16bpp player128-16.tim) |
||||
|
psn00bsdk_target_incbin(template PRIVATE tim_shambler shambler128.tim) |
||||
|
|
||||
|
psn00bsdk_add_cd_image( |
||||
|
iso # Target name |
||||
|
template # Output file name (= template.bin + template.cue) |
||||
|
iso.xml # Path to config file |
||||
|
DEPENDS template |
||||
|
) |
||||
@ -0,0 +1,23 @@ |
|||||
|
{ |
||||
|
"version": 2, |
||||
|
"cmakeMinimumRequired": { |
||||
|
"major": 3, |
||||
|
"minor": 20, |
||||
|
"patch": 0 |
||||
|
}, |
||||
|
"configurePresets": [ |
||||
|
{ |
||||
|
"name": "default", |
||||
|
"displayName": "Default configuration", |
||||
|
"description": "Use this preset to build the project using PSn00bSDK.", |
||||
|
"generator": "Ninja", |
||||
|
"binaryDir": "${sourceDir}/build", |
||||
|
"cacheVariables": { |
||||
|
"CMAKE_BUILD_TYPE": "Debug", |
||||
|
"CMAKE_TOOLCHAIN_FILE": "$env{PSN00BSDK_LIBS}/cmake/sdk.cmake", |
||||
|
"PSN00BSDK_TC": "", |
||||
|
"PSN00BSDK_TARGET": "mipsel-none-elf" |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
@ -0,0 +1,34 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- |
||||
|
This file is processed by CMake and used by mkpsxiso to build the CD image. |
||||
|
|
||||
|
NOTE: all paths are relative to the build directory; if you want to include |
||||
|
a file from the source tree, you'll have to prepend its path with |
||||
|
${PROJECT_SOURCE_DIR}. |
||||
|
--> |
||||
|
<iso_project |
||||
|
image_name="${CD_IMAGE_NAME}.bin" |
||||
|
cue_sheet="${CD_IMAGE_NAME}.cue" |
||||
|
> |
||||
|
<track type="data"> |
||||
|
<identifiers |
||||
|
system ="PLAYSTATION" |
||||
|
volume ="PSN00BSDK_TEMPLATE" |
||||
|
volume_set ="PSN00BSDK_TEMPLATE" |
||||
|
publisher ="MEIDOTEK" |
||||
|
data_preparer ="PSN00BSDK ${PSN00BSDK_VERSION}" |
||||
|
application ="PLAYSTATION" |
||||
|
copyright ="README.TXT;1" |
||||
|
/> |
||||
|
|
||||
|
<directory_tree> |
||||
|
<file name="SYSTEM.CNF" type="data" source="${PROJECT_SOURCE_DIR}/system.cnf" /> |
||||
|
<file name="TEMPLATE.EXE" type="data" source="template.exe" /> |
||||
|
<file name="TEMPLATE.MAP" type="data" source="template.map" /> |
||||
|
|
||||
|
<dummy sectors="1024"/> |
||||
|
</directory_tree> |
||||
|
</track> |
||||
|
|
||||
|
<!--<track type="audio" source="track2.wav" />--> |
||||
|
</iso_project> |
||||
@ -0,0 +1,252 @@ |
|||||
|
/* |
||||
|
* LibPSn00b Example Programs |
||||
|
* |
||||
|
* Hello World Example |
||||
|
* 2019-2020 Meido-Tek Productions / PSn00bSDK Project |
||||
|
* |
||||
|
* The obligatory hello world example normally included in nearly every |
||||
|
* SDK package. This example should also get you started in how to manage |
||||
|
* the display using psxgpu. |
||||
|
* |
||||
|
* Example by Lameguy64 |
||||
|
* |
||||
|
* |
||||
|
* Changelog: |
||||
|
* |
||||
|
* January 1, 2020 - Initial version |
||||
|
*/ |
||||
|
|
||||
|
#include <stdio.h> |
||||
|
#include <sys/types.h> |
||||
|
#include <psxetc.h> |
||||
|
#include <psxgte.h> |
||||
|
#include <psxgpu.h> |
||||
|
|
||||
|
#define OTLEN 8 |
||||
|
|
||||
|
// Define display/draw environments for double buffering |
||||
|
DISPENV disp[2]; |
||||
|
DRAWENV draw[2]; |
||||
|
int db; |
||||
|
|
||||
|
u_long ot[2][OTLEN]; // Ordering tables, two arrays for double buffering. These are basically "layers" for drawing. |
||||
|
char primbuff[2][32768]; // Primitive buffer, just a raw buffer of bytes to use as a pool for primitives |
||||
|
char *nextpri; |
||||
|
|
||||
|
extern u_long tim_player128[]; |
||||
|
extern u_long tim_player16bpp[]; |
||||
|
extern u_long tim_shambler[]; |
||||
|
|
||||
|
TIM_IMAGE playerTex; |
||||
|
TIM_IMAGE shamblerTex; |
||||
|
|
||||
|
void loadTexture(u_long* tim, TIM_IMAGE* tparam) |
||||
|
{ |
||||
|
GetTimInfo(tim, tparam); |
||||
|
|
||||
|
// This freezes up if the TIM image has weird dimensions, such as the ones from Quake... |
||||
|
LoadImage(tparam->prect, tparam->paddr); |
||||
|
|
||||
|
// Upload CLUT for palettized images |
||||
|
if (tparam->mode & 0x8) |
||||
|
{ |
||||
|
LoadImage(tparam->crect, tparam->caddr); |
||||
|
} |
||||
|
|
||||
|
DrawSync(0); |
||||
|
} |
||||
|
|
||||
|
// Init function |
||||
|
void init(void) |
||||
|
{ |
||||
|
// This not only resets the GPU but it also installs the library's |
||||
|
// ISR subsystem to the kernel |
||||
|
ResetGraph(0); |
||||
|
|
||||
|
// Define display environments, first on top and second on bottom |
||||
|
SetDefDispEnv(&disp[0], 0, 0, 320, 240); |
||||
|
SetDefDispEnv(&disp[1], 0, 240, 320, 240); |
||||
|
|
||||
|
// Define drawing environments, first on bottom and second on top |
||||
|
SetDefDrawEnv(&draw[0], 0, 240, 320, 240); |
||||
|
SetDefDrawEnv(&draw[1], 0, 0, 320, 240); |
||||
|
|
||||
|
// Set and enable clear color |
||||
|
setRGB0(&draw[0], 96, 0, 96); |
||||
|
setRGB0(&draw[1], 96, 0, 96); |
||||
|
draw[0].isbg = 1; |
||||
|
draw[1].isbg = 1; |
||||
|
|
||||
|
// Clear double buffer counter |
||||
|
db = 0; |
||||
|
|
||||
|
// Apply the GPU environments |
||||
|
PutDispEnv(&disp[db]); |
||||
|
PutDrawEnv(&draw[db]); |
||||
|
|
||||
|
// Load test font |
||||
|
FntLoad(960, 0); |
||||
|
|
||||
|
// Open up a test font text stream of 100 characters |
||||
|
FntOpen(0, 8, 320, 224, 0, 100); |
||||
|
|
||||
|
nextpri = primbuff[0]; |
||||
|
|
||||
|
loadTexture(tim_player128, &playerTex); |
||||
|
loadTexture(tim_player16bpp, &playerTex); |
||||
|
loadTexture(tim_shambler, &shamblerTex); |
||||
|
|
||||
|
// Set texture page for the entire drawing environment. Nice in some cases perhaps, but not what we need. |
||||
|
//draw[0].tpage = getTPage(playerTex.mode & 0x3, 0, playerTex.prect->x, playerTex.prect->y); |
||||
|
//draw[1].tpage = getTPage(playerTex.mode & 0x3, 0, playerTex.prect->x, playerTex.prect->y); |
||||
|
} |
||||
|
|
||||
|
// Display function |
||||
|
void display(void) |
||||
|
{ |
||||
|
// Wait for all drawing to complete |
||||
|
// TODO: this should be interleaved with the double buffered ordering table draw commands, to minimize CPU idle time while waiting for the GPU |
||||
|
DrawSync(0); |
||||
|
|
||||
|
// Wait for vertical sync to cap the logic to 60fps (or 50 in PAL mode) |
||||
|
// and prevent screen tearing |
||||
|
VSync(0); |
||||
|
|
||||
|
// Switch pages |
||||
|
PutDispEnv(&disp[db]); |
||||
|
PutDrawEnv(&draw[db]); |
||||
|
|
||||
|
// Enable display output, ResetGraph() disables it by default |
||||
|
SetDispMask(1); |
||||
|
|
||||
|
DrawOTag(ot[db] + OTLEN - 1); // This performs a DMA transfer to quickly send all the primitives off to the GPU |
||||
|
|
||||
|
// Flip buffer index |
||||
|
db = !db; |
||||
|
|
||||
|
nextpri = primbuff[db]; |
||||
|
} |
||||
|
|
||||
|
static void lerpcol(int r0, int g0, int b0, int r1, int g1, int b1, int lerp, int* rout, int* gout, int* bout) // lerp = 0-4096 |
||||
|
{ |
||||
|
int invlerp = 4096 - lerp; |
||||
|
|
||||
|
*rout = (r0 * invlerp + r1 * lerp) >> 12; |
||||
|
*gout = (g0 * invlerp + g1 * lerp) >> 12; |
||||
|
*bout = (b0 * invlerp + b1 * lerp) >> 12; |
||||
|
} |
||||
|
|
||||
|
void addTile(int x, int y, int w, int h, int r, int g, int b) |
||||
|
{ |
||||
|
// Initialize tile primitive |
||||
|
TILE *tile = (TILE*)nextpri; |
||||
|
setTile(tile); |
||||
|
setXY0(tile, x, y); |
||||
|
setWH(tile, w, h); |
||||
|
setRGB0(tile, r, g, b); |
||||
|
|
||||
|
addPrim(ot[db], tile); |
||||
|
nextpri += sizeof(TILE); |
||||
|
} |
||||
|
|
||||
|
void addColoredTriangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int rgb0, unsigned int rgb1, unsigned int rgb2) |
||||
|
{ |
||||
|
POLY_G3 *poly = (POLY_G3*)nextpri; |
||||
|
setPolyG3(poly); |
||||
|
setXY3(poly, x0, y0, x1, y1, x2, y2); |
||||
|
setRGB0(poly, (rgb0 >> 16) & 0xFF, (rgb0 >> 8) & 0xFF, rgb0 & 0xFF); |
||||
|
setRGB1(poly, (rgb1 >> 16) & 0xFF, (rgb1 >> 8) & 0xFF, rgb1 & 0xFF); |
||||
|
setRGB2(poly, (rgb2 >> 16) & 0xFF, (rgb2 >> 8) & 0xFF, rgb2 & 0xFF); |
||||
|
|
||||
|
addPrim(ot[db], poly); |
||||
|
nextpri += sizeof(POLY_G3); |
||||
|
} |
||||
|
|
||||
|
void addTexturedTriangle(int x0, int y0, int x1, int y1, int x2, int y2, short u0, short v0, short u1, short v1, short u2, short v2, TIM_IMAGE *img) |
||||
|
{ |
||||
|
short uoffs = (img->prect->x % 64) << (2 - (img->mode & 0x3)); |
||||
|
short voffs = (img->prect->y & 0xFF); |
||||
|
|
||||
|
POLY_FT3 *poly = (POLY_FT3*)nextpri; |
||||
|
setPolyFT3(poly); |
||||
|
setXY3(poly, x0, y0, x1, y1, x2, y2); |
||||
|
setUV3(poly, uoffs + u0, voffs + v0, uoffs + u1, voffs + v1, uoffs + u2, voffs + v2); |
||||
|
setRGB0(poly, 128, 128, 128); |
||||
|
setClut(poly, img->crect->x, img->crect->y); |
||||
|
setTPage(poly, img->mode & 0x3, 0, img->prect->x, img->prect->y); |
||||
|
|
||||
|
addPrim(ot[db], poly); |
||||
|
nextpri += sizeof(POLY_FT3); |
||||
|
} |
||||
|
|
||||
|
void addTexturedSprite(int x, int y, int w, int h, TIM_IMAGE *img) |
||||
|
{ |
||||
|
short uoffs = (img->prect->x % 64) << (2 - (img->mode & 0x3)); |
||||
|
short voffs = (img->prect->y & 0xFF); |
||||
|
|
||||
|
SPRT *sprite = (SPRT*)nextpri; |
||||
|
setSprt(sprite); |
||||
|
setXY0(sprite, x, y); |
||||
|
setWH(sprite, w, h); |
||||
|
setUV0(sprite, uoffs, voffs); |
||||
|
setClut(sprite, img->crect->x, img->crect->y); |
||||
|
setRGB0(sprite, 128, 128, 128); |
||||
|
addPrim(ot[db], sprite); |
||||
|
nextpri += sizeof(SPRT); |
||||
|
|
||||
|
DR_TPAGE *tpage = (DR_TPAGE*)nextpri; |
||||
|
setDrawTPage(tpage, 0, 1, getTPage(img->mode & 0x3, 0, img->prect->x, img->prect->y)); |
||||
|
addPrim(ot[db], tpage); |
||||
|
nextpri += sizeof(DR_TPAGE); |
||||
|
} |
||||
|
|
||||
|
void drawStuff(int counter) |
||||
|
{ |
||||
|
ClearOTagR(ot[db], OTLEN); |
||||
|
|
||||
|
// Print the obligatory hello world and counter to show that the |
||||
|
// program isn't locking up to the last created text stream |
||||
|
FntPrint(-1, "HELLO WORLD\n"); |
||||
|
FntPrint(-1, "COUNTER=%d, SIN=%d\n", counter, isin(counter)); |
||||
|
FntPrint(-1, "Image x %d y %d w %d h %d mode 0x%x\n", playerTex.prect->x, playerTex.prect->y, playerTex.prect->w, playerTex.prect->h, playerTex.mode); |
||||
|
|
||||
|
// Draw the last created text stream |
||||
|
FntFlush(-1); |
||||
|
|
||||
|
int r, g, b; |
||||
|
|
||||
|
lerpcol(255, 255, 0, 255, 0, 0, (icos(counter * 32) + 4096) >> 1, &r, &g, &b); |
||||
|
addTile(32, 32, 64, 64, r, g, b); |
||||
|
|
||||
|
lerpcol(0, 255, 255, 0, 255, 0, (icos(counter * 24 + 512) + 4096) >> 1, &r, &g, &b); |
||||
|
addTile(128, 160, 48, 48, r, g, b); |
||||
|
|
||||
|
addColoredTriangle(260, 140, 220, 220, 300, 220, 0xFF0000, 0x00FF00, 0x0000FF); |
||||
|
addTexturedTriangle(260, 40, 220, 120, 300, 120, 0, 94, 74, 124, 58, 1, &playerTex); |
||||
|
addTexturedSprite(20, 140, 80, 80, &playerTex); |
||||
|
addTexturedSprite(80, 40, 154, 114, &shamblerTex); |
||||
|
} |
||||
|
|
||||
|
// Main function, program entrypoint |
||||
|
int main(int argc, const char *argv[]) |
||||
|
{ |
||||
|
int counter; |
||||
|
|
||||
|
// Init stuff |
||||
|
init(); |
||||
|
|
||||
|
// Main loop |
||||
|
counter = 0; |
||||
|
while(1) |
||||
|
{ |
||||
|
drawStuff(counter); |
||||
|
|
||||
|
// Update display |
||||
|
display(); |
||||
|
|
||||
|
// Increment the counter |
||||
|
counter++; |
||||
|
} |
||||
|
|
||||
|
return 0; |
||||
|
} |
||||
@ -0,0 +1,4 @@ |
|||||
|
BOOT=cdrom:\template.exe;1 |
||||
|
TCB=4 |
||||
|
EVENT=10 |
||||
|
STACK=801FFFF0 |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue