diff options
| author | John Wilbert M. Villamor <lameguy64@gmail.com> | 2020-02-28 11:41:30 +0800 |
|---|---|---|
| committer | John Wilbert M. Villamor <lameguy64@gmail.com> | 2020-02-28 11:41:30 +0800 |
| commit | 84422eceb3ecaa325f814b306665e58b0c3be647 (patch) | |
| tree | 40abe71be412ee2845a66d46fe1146a073c04c52 /examples | |
| parent | e14a2a4cde7fa2518df2cb0ed7063962bd52a46e (diff) | |
| download | psn00bsdk-84422eceb3ecaa325f814b306665e58b0c3be647.tar.gz | |
Added CdOpenDir(), CdReadDir() and CdCloseDir(). Fixed SpuKeyOn() bug and added cdbrowse example.
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/cdbrowse/ball16c.h | 16 | ||||
| -rw-r--r-- | examples/cdbrowse/iso.xml | 33 | ||||
| -rw-r--r-- | examples/cdbrowse/main.c | 517 | ||||
| -rw-r--r-- | examples/cdbrowse/makefile | 59 | ||||
| -rw-r--r-- | examples/cdbrowse/system.cnf | 4 | ||||
| -rw-r--r-- | examples/cdxa/makefile | 1 |
6 files changed, 629 insertions, 1 deletions
diff --git a/examples/cdbrowse/ball16c.h b/examples/cdbrowse/ball16c.h new file mode 100644 index 0000000..c79f273 --- /dev/null +++ b/examples/cdbrowse/ball16c.h @@ -0,0 +1,16 @@ +unsigned int ball16c_size=192; +unsigned char ball16c[] = { +0x10,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0xc0,0x03,0x10, +0x01,0x10,0x00,0x01,0x00,0x00,0x00,0x31,0xc6,0x73,0xce,0x94,0xd2,0x07,0x9d, +0xd6,0xda,0x38,0xe3,0xef,0xbd,0x9b,0xef,0x8c,0xb1,0xc6,0x98,0xde,0xfb,0x4a, +0xa9,0xa4,0x90,0xad,0xb5,0x00,0x00,0x8c,0x00,0x00,0x00,0xc0,0x03,0x00,0x01, +0x04,0x00,0x10,0x00,0x00,0x00,0x10,0x22,0x12,0x02,0x00,0x00,0x00,0x10,0x32, +0x33,0x23,0x11,0x04,0x00,0x00,0x23,0x55,0x66,0x35,0x72,0x47,0x00,0x20,0x52, +0x86,0x68,0x36,0x12,0x97,0x0a,0x20,0x65,0xbb,0x8b,0x36,0x12,0x91,0x04,0x31, +0x85,0xbb,0x68,0x35,0x12,0x97,0xdc,0x32,0x86,0x8b,0x56,0x35,0x73,0x97,0xa4, +0x32,0x66,0x68,0x55,0x23,0x71,0x9e,0xac,0x32,0x65,0x56,0x33,0x13,0x71,0xce, +0xa4,0x21,0x33,0x33,0x23,0x11,0xe7,0xc9,0xd4,0x12,0x22,0x22,0x13,0x71,0xe7, +0xc9,0xda,0x10,0x17,0x11,0x77,0x77,0x9e,0x4c,0x0d,0x40,0x77,0x71,0xe7,0x9e, +0xc9,0xd4,0x0d,0x00,0x94,0x99,0x99,0xcc,0x4c,0xda,0x00,0x00,0xa0,0xc4,0xc4, +0x44,0xda,0x0d,0x00,0x00,0x00,0xd0,0xaa,0xda,0x0d,0x00,0x00 +}; diff --git a/examples/cdbrowse/iso.xml b/examples/cdbrowse/iso.xml new file mode 100644 index 0000000..a828df1 --- /dev/null +++ b/examples/cdbrowse/iso.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<iso_project image_name="cdbrowse.iso"> + + <track type="data"> + + <identifiers + system ="PLAYSTATION" + application ="PLAYSTATION" + volume ="PSN00BSDK" + volume_set ="PSN00BSDK" + publisher ="MEIDOTEK" + /> + + <directory_tree> + + <file name="system.cnf" type="data" source="system.cnf"/> + <file name="cdbrowse.exe" type="data" source="cdbrowse.exe"/> + + <dir name="dira"> + <dir name="diraa"> + </dir> + </dir> + <dir name="dirb"> + </dir> + + <dummy sectors="1024"/> + + </directory_tree> + + </track> + +</iso_project> diff --git a/examples/cdbrowse/main.c b/examples/cdbrowse/main.c new file mode 100644 index 0000000..7f91b44 --- /dev/null +++ b/examples/cdbrowse/main.c @@ -0,0 +1,517 @@ +/* + * LibPSn00b Example Programs + * + * CD File Browser Example + * 2020 Meido-Tek Productions / PSn00bSDK Project + * + * Demonstrates listing and browsing directory contents of a CD-ROM containing + * an ISO9660 file system, using the directory query functions of the libpsxcd + * library. + * + * The ISO9660 support in libpsxcd only supports the original ISO9660 + * version 1 file system specification, meaning it cannot query Rock Ridge + * or Joliet extensions that allow for long file names and unicode, despite + * the ISO9660 version 1 specification supporting names longer than 8.3 to + * begin with. However, discs written with such extensions should still be + * readable as the ISO9660 version should still be present for compatibility, + * with file names truncated to 8.3. + * + * + * Directory querying with libpsxcd is accomplished by using functions + * CdOpenDir(), CdReadDir() and CdCloseDir(). These functions work more or + * less the same as opendir(), readdir() and closedir() in *nix-like + * environments. While the library can support directories containing + * any number of files, the file browser in this example is limited to 40 + * entries, but this can be easily extended if need be. + * + * Differentiating file and directory entries is easily determined by whether + * or not the file has a version number suffix (ie. MYFILE.DAT;1). Directory + * records do not have a version number suffix. + * + * Currently, the only way to signal the isofs routines of libpsxcd that a + * disc change has occured is by simply issuing a CdlNop command. In a file + * browser that is aware of a disc change occuring at any moment a CdlNop + * command shall be issued at regular intervals of at least once a second. + * This also keeps CdStatus() up to date with disc presence. + * + * + * Controls: + * + * Up/Down - Move selection cursor. + * Cross - Enter directory. + * Circle - Go back to root directory. + * + * + * Example by Lameguy64 + * + * + * Changelog: + * + * February 25, 2020: Initial version. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <psxetc.h> +#include <psxgte.h> +#include <psxgpu.h> +#include <psxapi.h> +#include <psxpad.h> +#include <psxsio.h> +#include <psxspu.h> +#include <psxcd.h> + +#include <malloc.h> +#include "ball16c.h" + + +#define MAX_BALLS 1536 /* Number of balls to display */ + +#define OT_LEN 8 /* Ordering table length */ + + +/* Screen coordinates */ +#define SCREEN_XRES 320 +#define SCREEN_YRES 240 + +#define CENTER_X SCREEN_XRES/2 +#define CENTER_Y SCREEN_YRES/2 + + +/* Display and drawing environments */ +DISPENV disp[2]; +DRAWENV draw[2]; + +char pribuff[2][65536]; /* Primitive packet buffers */ +unsigned int ot[2][OT_LEN]; /* Ordering tables */ +char *nextpri; /* Pointer to next packet buffer offset */ +int db = 0; /* Double buffer index */ + + +/* Ball struct and array */ +typedef struct BALL_TYPE +{ + short x,y; + short xdir,ydir; + unsigned char r,g,b,p; +} BALL_TYPE; + +BALL_TYPE balls[MAX_BALLS]; + + +/* TIM image parameters for loading the ball texture and drawing sprites */ +TIM_IMAGE tim; + +/* Pad input buffer*/ +char padbuff[2][34]; + + +int query_dir(const char* path, CdlFILE* files, int max) +{ + CdlDIR* dir; + int files_found; + + printf( "Querying directory %s... ", path ); + files_found = 0; + + /* Open the directory */ + dir = CdOpenDir( path ); + if( dir ) + { + /* Read entries */ + while( CdReadDir( dir, &files[files_found] ) ) + { + files_found++; + if( files_found >= max ) + break; + } + + /* Close directory after query */ + CdCloseDir( dir ); + } + else + { + /* If directory path does not exist */ + printf( "Directory not found.\n" ); + return 0; + } + + printf( "Done.\n" ); + return files_found; +} + + +void init() +{ + int i; + + /* Reset GPU (also installs event handler for VSync) */ + printf("Init GPU... "); + ResetGraph( 0 ); + printf("Done.\n"); + + + /* Uncomment to direct tty messages to serial */ + //AddSIO(115200); + + + /* Initialize SPU and CD-ROM */ + printf("Initializing CD-ROM... "); + SpuInit(); + CdInit(0); + printf("Done.\n"); + + + /* Set display and draw environment parameters */ + SetDefDispEnv(&disp[0], 0, 0, SCREEN_XRES, SCREEN_YRES); + SetDefDispEnv(&disp[1], 0, SCREEN_YRES, SCREEN_XRES, SCREEN_YRES); + + SetDefDrawEnv(&draw[0], 0, SCREEN_YRES, SCREEN_XRES, SCREEN_YRES); + SetDefDrawEnv(&draw[1], 0, 0, SCREEN_XRES, SCREEN_YRES); + + + /* Set clear color, area clear and dither processing */ + setRGB0(&draw[0], 63, 0, 127); + draw[0].isbg = 1; + draw[0].dtd = 1; + setRGB0(&draw[1], 63, 0, 127); + draw[1].isbg = 1; + draw[1].dtd = 1; + + + /* Load and open font stream */ + FntLoad(960, 0); + FntOpen(32, 32, 256, 176, 2, 400); + + + /* Upload the ball texture */ + GetTimInfo((unsigned int*)ball16c, &tim); /* Get TIM parameters */ + LoadImage(tim.prect, tim.paddr); /* Upload texture to VRAM */ + if( tim.mode & 0x8 ) + { + LoadImage(tim.crect, tim.caddr); /* Upload CLUT if present */ + } + + + /* Calculate ball positions */ + printf("Calculating balls... "); + + for(i=0; i<MAX_BALLS; i++) + { + balls[i].x = (rand()%304); + balls[i].y = (rand()%224); + balls[i].xdir = 1-(rand()%3); + balls[i].ydir = 1-(rand()%3); + if( !balls[i].xdir ) + balls[i].xdir = 1; + if( !balls[i].ydir ) + balls[i].ydir = 1; + balls[i].xdir *= 2; + balls[i].ydir *= 2; + balls[i].r = (rand()%256); + balls[i].g = (rand()%256); + balls[i].b = (rand()%256); + } + + printf("Done.\n"); + + + /* Initialize pad */ + InitPAD(padbuff[0], 34, padbuff[1], 34); + StartPAD(); + ChangeClearPAD(0); + +} + + +int main(int argc, const char* argv[]) +{ + + SPRT* spr; // Primitive stuff + SPRT_16* sprt; + DR_TPAGE* tpri; + + PADTYPE* pad; // Pad stuff + + CdlFILE files[40]; // To store file/directory entries + char path[128]; // Directory path buffer + char disc_label[32]; // Disc label + + int i,counter=0; + int files_found; + int sel_channel=0; + int list_scroll; + int p_up=0,p_down=0,p_cross=0,p_circle=0; + int disc_present,update_listing; + + /* Init graphics and stuff before doing anything else */ + init(); + + /* Updates CdStatus() */ + CdControl( CdlNop, 0, 0 ); + + /* Main loop */ + printf("Entering loop...\n"); + + list_scroll = 0; + disc_present = false; + update_listing = true; + + while(1) { + + /* Set flag if disc has been removed */ + if( (CdStatus()&0x12) != 0x2 ) + { + disc_present = false; + } + + + /* Get pad stats */ + pad = ((PADTYPE*)padbuff[0]); + + if( pad->stat == 0 ) + { + if(( pad->type == 0x4 )||( pad->type == 0x5 )||( pad->type == 0x7 )) + { + /* Menu controls */ + if( disc_present ) + { + if( !(pad->btn&PAD_UP) ) + { + if( !p_up ) + { + if( sel_channel > 0 ) + { + sel_channel--; + + if( (sel_channel-list_scroll) < 0 ) + { + list_scroll = sel_channel; + } + } + p_up = 1; + } + } + else + { + p_up = 0; + } + + if( !(pad->btn&PAD_DOWN) ) + { + if( !p_down ) + { + if( sel_channel < files_found-1 ) + { + sel_channel++; + + if( (sel_channel-list_scroll) > 15 ) + { + list_scroll = sel_channel-15; + } + } + p_down = 1; + } + } + else + { + p_down = 0; + } + } + + /* Enter a selected directory */ + if( !(pad->btn&PAD_CROSS) ) + { + if( !p_cross ) + { + if( disc_present ) + { + if( strchr( files[sel_channel].name, ';' ) == 0 ) + { + if( strcmp( files[sel_channel].name, ".." ) + == 0 ) + { + *(strrchr( path, '\\' )+1) = 0x0; + if( strlen( path ) > 1 ) + { + path[strlen( path )-1] = 0x0; + } + } + else if( strcmp( files[sel_channel].name, "." ) ) + { + if( strlen( path ) > 1 ) + { + strcat( path, "\\" ); + } + strcat( path, files[sel_channel].name ); + } + update_listing = true; + } + } + else + { + strcpy( path, "\\" ); + update_listing = true; + } + p_cross = 1; + } + } + else + { + p_cross = 0; + } + + /* Return to root directory */ + if( !(pad->btn&PAD_CIRCLE) ) + { + if( !p_circle ) + { + strcpy( path, "\\ ); + update_listing = true; + p_circle = 1; + } + } + else + { + p_circle = 0; + } + } + } + + + /* Updates directory listing */ + if( update_listing ) + { + if ( (CdStatus()&0x12) == 0x2 ) + { + + /* Reset path and update label if new disc inserted */ + if( !disc_present ) + { + strcpy( path, "\\" ); + CdGetVolumeLabel(disc_label); + disc_present = true; + } + + /* Query directory */ + files_found = query_dir( path, files, 40 ); + sel_channel = 0; + list_scroll = 0; + + } + update_listing = false; + } + + + /* Display information */ + FntPrint( -1, "\n PSN00BSDK CD BROWSER EXAMPLE\n\n" ); + + if( disc_present ) + { + FntPrint( -1, " FILES:%d LABEL:%s\n", files_found, disc_label ); + FntPrint( -1, " %s\n", path ); + + for(i=0; i<16; i++) + { + if( (i+list_scroll) > (files_found-1) ) + break; + + if( (i+list_scroll) == sel_channel ) + { + FntPrint( -1, " ->%s\n", files[i+list_scroll].name ); + } + else + { + FntPrint( -1, " %s\n", files[i+list_scroll].name ); + } + + } + } + else + { + if( (CdStatus()&0x12) == 0x2 ) + { + FntPrint( -1, "\n PRESS <X> TO LIST CONTENTS %x\n", + CdStatus() ); + } + else + { + FntPrint( -1, "\n NO DISC INSERTED %x\n", + CdStatus() ); + } + } + + /* Clear ordering table and set start address of primitive buffer */ + ClearOTagR(ot[db], OT_LEN); + nextpri = pribuff[db]; + + + /* Sort the balls */ + sprt = (SPRT_16*)nextpri; + for( i=0; i<MAX_BALLS; i++ ) { + + setSprt16(sprt); + setXY0(sprt, balls[i].x, balls[i].y); + setRGB0(sprt, balls[i].r, balls[i].g, balls[i].b); + setUV0(sprt, 0, 0); + setClut(sprt, tim.crect->x, tim.crect->y); + + addPrim(ot[db]+(OT_LEN-1), sprt); + sprt++; + + balls[i].x += balls[i].xdir; + balls[i].y += balls[i].ydir; + + if( ( balls[i].x+16 ) > SCREEN_XRES ) { + balls[i].xdir = -2; + } else if( balls[i].x < 0 ) { + balls[i].xdir = 2; + } + + if( ( balls[i].y+16 ) > SCREEN_YRES ) { + balls[i].ydir = -2; + } else if( balls[i].y < 0 ) { + balls[i].ydir = 2; + } + + } + nextpri = (char*)sprt; + + + /* Sort a TPage primitive so the sprites will draw pixels from */ + /* the correct texture page in VRAM */ + tpri = (DR_TPAGE*)nextpri; + setDrawTPage(tpri, 0, 0, getTPage(0, 0, tim.prect->x, tim.prect->y)); + addPrim(ot[db]+(OT_LEN-1), tpri); + nextpri += sizeof(DR_TPAGE); + + /* Draw font */ + FntFlush(-1); + + /* Wait for GPU and VSync */ + DrawSync(0); + VSync(0); + + /* Since draw.isbg is non-zero this clears the screen */ + PutDispEnv(&disp[db]); + PutDrawEnv(&draw[db]); + SetDispMask(1); + + /* Begin drawing the new frame */ + DrawOTag( ot[db]+(OT_LEN-1) ); + + /* Alternate to the next buffer */ + db = !db; + + /* Periodically issue a CdlNop to keep CdStatus() updated */ + counter++; + if( (counter%60) == 59 ) + { + CdControl(CdlNop, 0, 0); + } + } + + return 0; + +} diff --git a/examples/cdbrowse/makefile b/examples/cdbrowse/makefile new file mode 100644 index 0000000..7e90b3c --- /dev/null +++ b/examples/cdbrowse/makefile @@ -0,0 +1,59 @@ +include ../sdk-common.mk + +TARGET = cdbrowse.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)) + +PREFIX = mipsel-unknown-elf- + +# Include directories +INCLUDE = -I../../libpsn00b/include + +# Library directories, last entry must point toolchain libraries +LIBDIRS = -L../../libpsn00b + +LIBDIRS += -L$(GCC_BASE)/lib/gcc/mipsel-unknown-elf/$(GCC_VERSION) +INCLUDE += -I$(GCC_BASE)/lib/gcc/mipsel-unknown-elf/$(GCC_VERSION)/include + +LIBS = -lpsxcd -lpsxetc -lpsxgpu -lpsxgte -lpsxspu -lpsxsio -lpsxapi -lc + +CFLAGS = -g -O2 -fno-builtin -fdata-sections -ffunction-sections +CPPFLAGS = $(CFLAGS) \ + -fno-exceptions \ + -fno-rtti \ + -fno-unwind-tables \ + -fno-threadsafe-statics \ + -fno-use-cxa-atexit + +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) + mkpsxiso -y -q iso.xml + +build/%.o: %.c + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@ + +build/%.o: %.cpp + @mkdir -p $(dir $@) + $(CXX) $(CPPFLAGS) $(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/cdbrowse/system.cnf b/examples/cdbrowse/system.cnf new file mode 100644 index 0000000..9cf5593 --- /dev/null +++ b/examples/cdbrowse/system.cnf @@ -0,0 +1,4 @@ +BOOT=cdrom:\cdbrowse.exe;1 +TCB=4 +EVENT=10 +STACK=801FFFF0 diff --git a/examples/cdxa/makefile b/examples/cdxa/makefile index c94f48c..57f1959 100644 --- a/examples/cdxa/makefile +++ b/examples/cdxa/makefile @@ -56,5 +56,4 @@ build/%.o: %.s $(CC) $(AFLAGS) $(INCLUDE) -c $< -o $@ clean: - make -C libpsxcd clean rm -rf build $(TARGET) $(TARGET:.elf=.exe) |
