diff --git a/hello_bs/Makefile b/hello_bs/Makefile new file mode 100644 index 0000000..d46c7a2 --- /dev/null +++ b/hello_bs/Makefile @@ -0,0 +1,12 @@ +.PHONY: all cleansub +all: + mkpsxiso -y ./isoconfig.xml +cleansub: + $(MAKE) clean + rm -f hello_bs.cue hello_bs.bin + +TARGET = hello_bs + +SRCS = hello_bs.c \ + +include ../common.mk diff --git a/hello_bs/README.md b/hello_bs/README.md new file mode 100644 index 0000000..3a7d42e --- /dev/null +++ b/hello_bs/README.md @@ -0,0 +1,58 @@ +# Loading a BS still image + +You need [mkpsxiso](https://github.com/Lameguy64/mkpsxiso) in your $PATH to generate a PSX disk image. + +## Compile + +```bash +make all +``` + +## Clean directory + +```bash +make cleansub +``` + +## Converting a still image to BS + +`MC32` can convert these formats to BS : TIM, RGB, YUV. + +### Image > TIM with img2tim + +Convert your image to a 24bpp TIM with [`img2tim`](https://github.com/Lameguy64/img2tim): + +```bash +img2tim -bpp 24 -o bs.tim bs.png +``` + +Then use `MC32` as instructed below. + +### Image > RGB ppm with imagemagick + +You can convert any image to PPM, then change the file's extension to .rgb, and convert it with MC32. + +```bash +mogrify -format ppm image.xxx +``` + +### TIM/RGB > BS conversion + +Use the [`MC32` tool](http://psx.arthus.net/tools/pimp-psx.zip) conversion tool to import the image, specifying the right dimensions, and convert to `bs` with those settings : + +**Note that a BS image must have a width and height that is a multiple of 16** + +``` +Input: RGB, Output: bs +MDEC version : 2 +Custom: Size in sectors or (2048 * sector number) bytes, Variable frame size +``` + +![MC32 bs conversion](https://wiki.arthus.net/assets/mc32-bs-conv.png) + +## Sources & Refs + +img2tim : https://github.com/Lameguy64/img2tim +MC32 : http://psx.arthus.net/tools/pimp-psx.zip + +mdecnote : http://psx.arthus.net/sdk/Psy-Q/DOCS/TECHNOTE/mdecnote.pdf diff --git a/hello_bs/bs/bace.bs b/hello_bs/bs/bace.bs new file mode 100644 index 0000000..6b63163 Binary files /dev/null and b/hello_bs/bs/bace.bs differ diff --git a/hello_bs/bs/bace.tim b/hello_bs/bs/bace.tim new file mode 100644 index 0000000..07a5aa8 Binary files /dev/null and b/hello_bs/bs/bace.tim differ diff --git a/hello_bs/hello_bs.c b/hello_bs/hello_bs.c new file mode 100644 index 0000000..9154d1f --- /dev/null +++ b/hello_bs/hello_bs.c @@ -0,0 +1,153 @@ +// Load a BS file from CD, decompress and display it. +// Schnappy 07-2021 +// based on Lameguy64's tutorial : http://lameguy64.net/svn/pstutorials/chapter1/1-display.html +#include +#include +#include +#include +#include +#include +// CD library +#include +// CODEC library +#include +#include + + +#define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL +#define SCREENXRES 320 // Screen width +#define SCREENYRES 240 + (VMODE << 4) // Screen height : If VMODE is 0 = 240, if VMODE is 1 = 256 +#define CENTERX SCREENXRES/2 // Center of screen on x +#define CENTERY SCREENYRES/2 // Center of screen on y +#define MARGINX 8 // margins for text display +#define MARGINY 16 +#define FONTSIZE 8 * 7 // Text Field Height +DISPENV disp[2]; // Double buffered DISPENV and DRAWENV +DRAWENV draw[2]; +short db = 0; // index of which buffer is used, values 0, 1 + +// CD specifics +#define CD_SECTOR_SIZE 2048 +// Converting bytes to sectors SECTOR_SIZE is defined in words, aka int +#define BtoS(len) ( ( len + CD_SECTOR_SIZE - 1 ) / CD_SECTOR_SIZE ) +// Name of file to load +static char * loadFile; +// libcd's CD file structure contains size, location and filename +CdlFILE filePos = {0}; +//~ struct EXEC * exeStruct; +// Define start address of allocated memory +// Let's use an array so we don't have to worry about using a memory segment that's already in use. +static unsigned char ramAddr[0x40000]; // https://discord.com/channels/642647820683444236/663664210525290507/864936962199781387 +// We could also set a memory address manually, but we have to make sure this won't get in the way of other routines. +// void * ramAddr = (void *)0x80030D40; +// Load data to this buffer +u_long * dataBuffer; +// Those are not strictly needed, but we'll use them to see the commands results. +// They could be replaced by a 0 in the various functions they're used with. +u_char CtrlResult[8]; +// Value returned by CDread() - 1 is good, 0 is bad +int CDreadOK = 0; +// Value returned by CDsync() - Returns remaining sectors to load. 0 is good. +int CDreadResult = 0; +// BS decompression +// Store size of uncompressed data +long bsBufferSize; +// Allocated memory address +void * bsWorkBuffer; +// Define image draw area +RECT bsDrawArea = { 0, 0, 16, SCREENYRES}; +// Used to store a 16x240 image strip +u_long bsStrip[16*240]; + +void init(void) +{ + ResetGraph(0); // Initialize drawing engine with a complete reset (0) + SetDefDispEnv(&disp[0], 0, 0 , SCREENXRES, SCREENYRES); // Set display area for both &disp[0] and &disp[1] + SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES); // &disp[0] is on top of &disp[1] + SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES); // Set draw for both &draw[0] and &draw[1] + SetDefDrawEnv(&draw[1], 0, 0 , SCREENXRES, SCREENYRES); // &draw[0] is below &draw[1] + // Set video mode + if (VMODE){ SetVideoMode(MODE_PAL);} + SetDispMask(1); // Display on screen + setRGB0(&draw[0], 155, 0, 150); // set color for first draw area + setRGB0(&draw[1], 155, 0, 150); // set color for second draw area + draw[0].isbg = 0; // set mask for draw areas. 1 means repainting the area with the RGB color each frame + draw[1].isbg = 0; + PutDispEnv(&disp[db]); // set the disp and draw environnments + PutDrawEnv(&draw[db]); + FntLoad(960, 0); // Load font to vram at 960,0(+128) + FntOpen(MARGINX, MARGINY, SCREENXRES - MARGINX * 2, FONTSIZE, 0, 280 ); // FntOpen(x, y, width, height, black_bg, max. nbr. chars +} +void display(void) +{ + DrawSync(0); // Wait for all drawing to terminate + VSync(0); // Wait for the next vertical blank + PutDispEnv(&disp[db]); // set alternate disp and draw environnments + PutDrawEnv(&draw[db]); + db = !db; // flip db value (0 or 1) +} +int main(void) +{ + // Init display + init(); + // Init CD system + CdInit(); + // Init heap + InitHeap((u_long *)ramAddr, sizeof(ramAddr)); + // If the other method was chosen at l.39 + // InitHeap((void *)0x80030D40, 0x40000); + // Set name of file to load + loadFile = "\\BACE.BS;1"; + // Get file position from filename + CdSearchFile( &filePos, loadFile); + // Allocate memory + dataBuffer = malloc( BtoS(filePos.size) * CD_SECTOR_SIZE ); + // Issue CdlSetloc CDROM command : Set the seek target position + // Beware of a misnomed 'sector' member in the CdlLOC struct that should really be named 'frame'. + // https://discord.com/channels/642647820683444236/663664210525290507/864912470996942910 + CdControl(CdlSetloc, (u_char *)&filePos.pos, CtrlResult); + // Read data and load it to dataBuffer + CDreadOK = CdRead( (int)BtoS(filePos.size), (u_long *)dataBuffer, CdlModeSpeed ); + // Wait for operation to complete + CDreadResult = CdReadSync(0, 0); + + // Image Decompression + // Initialize image processing subsystem + DecDCTReset(0); + // Find the needed buffer size + bsBufferSize = DecDCTBufSize(dataBuffer); + // Allocate buffer size at &bsWorkBuffer + bsWorkBuffer = malloc( bsBufferSize ); + // Decode Huffman (also called VLC: variable length coding ) compressed image + DecDCTvlc( dataBuffer, (u_long *) bsWorkBuffer ); + // Send decoded data to MDEC for RLE decoding. + DecDCTin( (u_long*) bsWorkBuffer, 0); + // Fetch decoded image in 16x240 strips + for( bsDrawArea.x = 0; bsDrawArea.x < SCREENXRES; bsDrawArea.x += 16 ){ + // Request decoded data from MDEC + // Request 16 * 240 pixel high lines. + // But size is in long words (4B), so divide by 2 to get words (2B) ? + DecDCTout( bsStrip, (16*SCREENYRES)/2); + // Wait for transfer to complete + DecDCToutSync(0); + // Load image data to fb + LoadImage( &bsDrawArea, bsStrip ); + } + free( bsWorkBuffer ); + while (1) // infinite loop + { + // Copy BS image to the other buffer + MoveImage2(&disp[db].disp, 0, disp[!db].disp.y ); + DrawSync(0); + FntPrint("Hello BS! \n"); + // Print filesize in bytes/sectors + FntPrint("Bs Size: %dB sectors: %d\n", filePos.size, BtoS(filePos.size)); + // Print heap and buffer addresses + FntPrint("Heap: %x - Buf: %x\n", ramAddr, dataBuffer); + FntPrint("bsWork: %x\nbsBufSize: %dB\n", bsWorkBuffer, bsBufferSize); + + FntFlush(-1); // Draw print stream + display(); // Execute display() + } + return 0; + } diff --git a/hello_bs/isoconfig.xml b/hello_bs/isoconfig.xml new file mode 100644 index 0000000..5d6b44b --- /dev/null +++ b/hello_bs/isoconfig.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hello_bs/system.cnf b/hello_bs/system.cnf new file mode 100644 index 0000000..ae2db18 --- /dev/null +++ b/hello_bs/system.cnf @@ -0,0 +1,4 @@ +BOOT=cdrom:\SCES_313.37;1 +TCB=4 +EVENT=10 +STACK=801FFFF0 diff --git a/hello_cd/hello_cd.c b/hello_cd/hello_cd.c index fc2362f..b82c851 100644 --- a/hello_cd/hello_cd.c +++ b/hello_cd/hello_cd.c @@ -29,7 +29,7 @@ short db = 0; // index of which buffer is used, values 0, 1 // Converting bytes to sectors SECTOR_SIZE is defined in words, aka int #define BtoS(len) ( ( len + CD_SECTOR_SIZE - 1 ) / CD_SECTOR_SIZE ) // Name of file to load -static char * exeFile; +static char * loadFile; // libcd's CD file structure contains size, location and filename CdlFILE filePos = {0}; //~ struct EXEC * exeStruct; @@ -86,9 +86,9 @@ int main(void) // If the other method was chosen at l.39 // InitHeap((void *)0x80030D40, 0x40000); // Set name of file to load - exeFile = "\\HELO.DAT;1"; + loadFile = "\\HELO.DAT;1"; // Get file position from filename - CdSearchFile( &filePos, exeFile); + CdSearchFile( &filePos, loadFile); // Allocate memory dataBuffer = malloc( BtoS(filePos.size) * CD_SECTOR_SIZE ); // Issue CdlSetloc CDROM command : Set the seek target position diff --git a/hello_str/Makefile b/hello_str/Makefile new file mode 100644 index 0000000..b4ed2ca --- /dev/null +++ b/hello_str/Makefile @@ -0,0 +1,12 @@ +.PHONY: all cleansub +all: + mkpsxiso -y ./isoconfig.xml +cleansub: + $(MAKE) clean + rm -f hello_str.cue hello_str.bin + +TARGET = hello_str + +SRCS = hello_str.c \ + +include ../common.mk diff --git a/hello_str/isoconfig.xml b/hello_str/isoconfig.xml new file mode 100644 index 0000000..30b7d11 --- /dev/null +++ b/hello_str/isoconfig.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hello_str/str/copyings.str b/hello_str/str/copyings.str new file mode 100644 index 0000000..153d209 Binary files /dev/null and b/hello_str/str/copyings.str differ diff --git a/hello_str/system.cnf b/hello_str/system.cnf new file mode 100644 index 0000000..ae2db18 --- /dev/null +++ b/hello_str/system.cnf @@ -0,0 +1,4 @@ +BOOT=cdrom:\SCES_313.37;1 +TCB=4 +EVENT=10 +STACK=801FFFF0