Better syntax for ot access, as per @nicolasnoble suggestion

This commit is contained in:
ABelliqueux 2021-07-23 17:24:06 +02:00
parent 1db9b31747
commit bcffa5b2ca
21 changed files with 852 additions and 16 deletions

View File

@ -126,7 +126,7 @@ void display(void)
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;

View File

@ -6,7 +6,6 @@
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
#include <libapi.h>
// CD library
#include <libcd.h>
// CODEC library

113
hello_cd_exec/hello_cd.c Normal file
View File

@ -0,0 +1,113 @@
// Load files from CD and execute them
// Schnappy 07-2021
// based on Lameguy64's tutorial : http://lameguy64.net/svn/pstutorials/chapter1/1-display.html
#include <sys/types.h>
#include <stdio.h>
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
#include <libapi.h>
#include <malloc.h>
// CD library
#include <libcd.h>
#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 0 // margins for text display
#define MARGINY 32
#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
#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 * exeFile;
CdlFILE filePos = {0};
struct EXEC * exeStruct;
void * ramAddr = (void *)0x80030D40; // https://discord.com/channels/642647820683444236/663664210525290507/864936962199781387
//~ static unsigned char gHeapBuffer[0x40000];
u_long * buffer;
u_char CtrlResult[8];
int CDreadOK = 0;
int CDreadResult = 0;
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], 255, 50, 50); // set color for first draw area
setRGB0(&draw[1], 255, 50, 50); // set color for second draw area
draw[0].isbg = 1; // set mask for draw areas. 1 means repainting the area with the RGB color each frame
draw[1].isbg = 1;
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, SCREENYRES - MARGINY - FONTSIZE, 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)
{
int i = 0;
// init() display
init();
// Init CD system
CdInit();
// Init heap
InitHeap((void *)0x80030D40, 0x40000);
//~ InitHeap((u_long *)gHeapBuffer, sizeof(gHeapBuffer));
// Set name of file to load
exeFile = "\\POLY.EXE;1";
// Get file position from filename
CdSearchFile( &filePos, exeFile);
// Allocate memory
//~ EnterCriticalSection();
buffer = malloc( BtoS(filePos.size)*CD_SECTOR_SIZE);
//~ ExitCriticalSection();
// 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
CDreadOK = CdRead( (int)BtoS(filePos.size), (u_long *)buffer, CdlModeSpeed);
// Wait for operation to complete
CDreadResult = CdReadSync(0, 0);
while (1) // infinite loop
{
// Load file from CD
//~ CdReadExec(exeFile);
// Execute file
//~ StopCallback();
//~ ResetGraph(3);
//~ Exec(exeStruct,0,0);
i++;
FntPrint("Hello CD! %d\n", i); // Send string to print stream
FntPrint("Heap: - Buf: %x\n", buffer); // Send string to print stream
FntPrint("CdCtrl : %d\nRead : %d %d\n", CtrlResult[0], CDreadOK, CDreadResult);
FntPrint("Size B: %d S: %d", filePos.size, BtoS(filePos.size)); // Send string to print stream
FntFlush(-1); // Draw printe stream
display(); // Execute display()
}
return 0;
}

View File

@ -83,7 +83,7 @@ void display(void){
VSync(0);
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;
nextpri = primbuff[db];
}

View File

@ -117,7 +117,7 @@ void display(void){
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;

View File

@ -83,7 +83,7 @@ void display(void)
// Flip DISP and DRAW env
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
// Flip db index
db = !db;
// Get next primitive in buffer

View File

@ -120,7 +120,7 @@ void display(void){
VSync(0);
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;
nextpri = primbuff[db];
}

View File

@ -75,7 +75,7 @@ void display(void)
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;

View File

@ -111,7 +111,7 @@ void display(void)
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;

View File

@ -131,7 +131,7 @@ void display(void)
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;

View File

@ -107,7 +107,7 @@ void display(void)
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;

View File

@ -131,7 +131,7 @@ void display(void)
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;

View File

@ -132,7 +132,7 @@ void display(void)
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;

View File

@ -79,7 +79,7 @@ void display(void)
// Flip DISP and DRAW env
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
// Flip db index
db = !db;
// Get next primitive in buffer

View File

@ -81,7 +81,7 @@ void display(void)
// Flip DISP and DRAW env
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
// Flip db index
db = !db;
// Get next primitive in buffer

154
hello_rsd/hello_rsd.c Normal file
View File

@ -0,0 +1,154 @@
#include <sys/types.h>
#include <stdio.h>
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
#include <kernel.h>
#include <libgs.h>
#include <libapi.h>
#include <malloc.h>
#define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL
#define SCREENXRES 320
#define SCREENYRES 240
#define CENTERX SCREENXRES/2
#define CENTERY SCREENYRES/2
#define MARGINX 0 // margins for text display
#define MARGINY 32
#define FONTSIZE 8 * 7 // Text Field Height
#define OTLEN 8 // Ordering Table Length
DISPENV disp[2]; // Double buffered DISPENV and DRAWENV
DRAWENV draw[2];
u_long ot[2][OTLEN]; // double ordering table of length 8 * 32 = 256 bits / 32 bytes
char primbuff[2][32768] = {1}; // double primitive buffer of length 32768 * 8 = 262.144 bits / 32,768 Kbytes
char *nextpri = primbuff[0]; // pointer to the next primitive in primbuff. Initially, points to the first bit of primbuff[0]
short db = 0; // index of which buffer is used, values 0, 1
//~ short BgColor[3] = {0,0,0};
void init(void)
{
ResetGraph(0);
GsInitGraph(320, 240, 0, 0, 0);
// Initialize and setup the GTE : Not needed ?
InitGeom();
SetGeomOffset(0,0);
SetGeomScreen(1);
SetDefDispEnv(&disp[0], 0, 0, SCREENXRES, SCREENYRES);
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[1], 0, 0, SCREENXRES, SCREENYRES);
if (VMODE)
{
SetVideoMode(MODE_PAL);
disp[0].screen.y += 8;
disp[1].screen.y += 8;
}
SetDispMask(1); // Display on screen
setRGB0(&draw[0], 50, 50, 50);
setRGB0(&draw[1], 50, 50, 50);
draw[0].isbg = 1;
draw[1].isbg = 1;
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
FntLoad(960, 0);
FntOpen(MARGINX, SCREENYRES - MARGINY - FONTSIZE, SCREENXRES - MARGINX * 2, FONTSIZE, 0, 280 );
}
void display(void)
{
DrawSync(0);
VSync(0);
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;
nextpri = primbuff[db];
}
int main(void)
{
POLY_F4 *poly = {0};
SVECTOR RotVector = {0, 0, 0};
VECTOR MovVector = {CENTERX, CENTERY, 0};
SVECTOR VertPos[4] = {
{-32, -32, 1},
{-32, 32, 1 },
{32, -32, 1 },
{32, 32, 1 }
};
MATRIX PolyMatrix = GsIDMATRIX;
long polydepth;
long polyflag;
init();
while (1)
{
ClearOTagR(ot[db], OTLEN);
poly = (POLY_F4 *)nextpri;
// Set transform matrices for this polygon
RotMatrix(&RotVector, &PolyMatrix);
TransMatrix(&PolyMatrix, &MovVector);
SetRotMatrix(&PolyMatrix);
SetTransMatrix(&PolyMatrix);
setPolyF4(poly);
setRGB0(poly, 255, 0, 255);
//~ setXY4(poly, 0, 0, 0, 32, 32, 0, 32, 32);
RotTransPers4(
&VertPos[0], &VertPos[1], &VertPos[2], &VertPos[3],
(long*)&poly->x0, (long*)&poly->x1, (long*)&poly->x2, (long*)&poly->x3,
&polydepth,
&polyflag
);
RotVector.vz+=16;
addPrim(ot[db], poly);
nextpri += sizeof(POLY_F4);
FntPrint("Hello world !");
FntFlush(-1);
display();
}
return 0;
}

View File

@ -110,7 +110,7 @@ void display(void)
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;

View File

@ -0,0 +1,204 @@
// Stream a STR file from CD, decompress and play it.
// Schnappy 07-2021
// based on Lameguy64 strplay library : http://www.psxdev.net/forum/viewtopic.php?t=507
// Original PsyQ sample code : /psyq/addons/cd/MOVIE
// Video to STR conversion : https://github.com/ABelliqueux/nolibgs_hello_worlds/tree/main/hello_str
#include <sys/types.h>
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
#include <libapi.h>
#include <stddef.h>
#include <stdio.h>
// CD library
#include <libcd.h>
// CODEC library
#include <libpress.h>
#include <malloc.h>
#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
#define BPP 16
#define RING_SIZE 32
// 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};
// Load data to this buffer - Use an array to reserve memory
u_long cdDataBuffer[RING_SIZE * CD_SECTOR_SIZE];
// 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;
// STR playback
// Display area for the str file
RECT strDispArea = { 0, 0, SCREENXRES, SCREENYRES };
// Number of frame in video file - 1
u_int strFrameCnt = 893;
// Flag set when playback has reached end of file
u_int strEndReached = 0;
// STR decompression
// Store size of uncompressed data
long strBufferSize[2];
// Allocated memory address
u_long strWorkBuffer[2][SCREENXRES/2*SCREENYRES];
// Define first slice draw area
RECT strDrawArea[2] = {
{0, 0, BPP, SCREENYRES},
{0, SCREENYRES, BPP, SCREENYRES}
};
// Used to store a 16x240 image strip
u_long strStrip[2][ BPP * SCREENYRES ];
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 = 1; // set mask for draw areas. 1 means repainting the area with the RGB color each frame
draw[1].isbg = 1;
PutDispEnv(&disp[0]); // set the disp and draw environnments
PutDrawEnv(&draw[0]);
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)
{
u_char cdSpeed = {CdlModeSpeed};
// Init display
init();
// Init CD system
CdInit();
// Initialize image processing subsystem
DecDCTReset(0);
// Streaming
// Init CD ring buffer
StSetRing(cdDataBuffer, RING_SIZE);
// Set streaming parameters
StSetStream(0, 0, 0xffffffff, 0, 0);
// Set name of file to load
loadFile = "\\COPY.STR;1";
// Get file position from filename
CdSearchFile( &filePos, loadFile);
// Issue CdlSetloc CDROM command : Set the seek target position
CdControl(CdlSetloc, (u_char *)&filePos.pos, 0);
// Set CD parameters
CdControl(CdlSetmode, &cdSpeed, 0);
CdSync(0,0);
// Start streaming
CdRead2(CdlModeStream|CdlModeSpeed|CdlModeRT);
u_long * cdDataBufferFrameAddr;
StHEADER * cdDataBufferSector;
int cnt = WAIT_TIME;
//Get frame's address
while (StGetNext((u_long **)cdDataBufferFrameAddr, (u_long **)cdDataBufferSector) == 1){
cnt--;
if (cnt == 0){
FntPrint("Time out !");
}
}
//~ // Decode the VLC
DecDCTvlc(cdDataBufferFrameAddr, strWorkBuffer[0]);
// Free the ring buffer's address
StFreeRing(cdDataBufferFrameAddr);
DecDCTin( (u_long*) strWorkBuffer[0], 2);
// Fetch decoded image in 16x240 strips
for( strDrawArea[0].x = 0; strDrawArea[0].x < SCREENXRES; strDrawArea[0].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( strStrip[0], (16*SCREENYRES)/2 );
// Wait for transfer to complete
DecDCToutSync(0);
// Load image data to fb
LoadImage( &strDrawArea[0], strStrip[0] );
DrawSync(0);
}
while (1) // infinite loop
{
if(!strEndReached){
if(cdDataBufferSector->frameCount < strFrameCnt){
// Send decoded data to MDEC for RLE decoding.
DecDCTin( (u_long*) strWorkBuffer[0], 2);
// Fetch decoded image in 16x240 strips
for( strDrawArea[0].x = 0; strDrawArea[0].x < SCREENXRES; strDrawArea[0].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( strStrip[0], (16*SCREENYRES)/2);
// Wait for transfer to complete
DecDCToutSync(0);
// Load image data to fb
LoadImage( &strDrawArea[0], strStrip[0] );
}
//Get frame's address
cnt = WAIT_TIME;
while (StGetNext((u_long **)cdDataBufferFrameAddr, (u_long **)cdDataBufferSector)){
cnt--;
if (cnt == 0){
FntPrint("Time out !");
}
}
//~ // Reset timeout counter
cnt = WAIT_TIME;
//~ // Decode the VLC
DecDCTvlc(cdDataBufferFrameAddr, strWorkBuffer[0]);
// Free the ring buffer
StFreeRing(cdDataBufferFrameAddr);
} else {
strEndReached = 1;
}
} else {
StUnSetRing();
CdControlB(CdlPause, 0, 0);
}
FntPrint("Hello STR! %d\n", VSync(-1));
FntPrint("cdDataBuf: %x %x\n", &cdDataBufferFrameAddr, &cdDataBufferSector);
FntPrint("Cnt: %d \n", cnt);
FntFlush(-1); // Draw print stream
display(); // Execute display()
}
return 0;
}

239
hello_str/hello_str.c Normal file
View File

@ -0,0 +1,239 @@
// Stream a STR file from CD, decompress and play it.
// Schnappy 07-2021
// based on Lameguy64 strplay library : http://www.psxdev.net/forum/viewtopic.php?t=507
// Original PsyQ sample code : /psyq/addons/cd/MOVIE
// Video to STR conversion : https://github.com/ABelliqueux/nolibgs_hello_worlds/tree/main/hello_str
#include <sys/types.h>
#include <stdio.h>
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
// CD library
#include <libcd.h>
// CODEC library
#include <libpress.h>
#define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL
#define TRUECOL 0
#define SCREENXRES 320 // Screen width
//~ #define SCREENYRES 240 + (VMODE << 4) // Screen height : If VMODE is 0 = 240, if VMODE is 1 = 256
#define SCREENYRES 240 // 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
#define STR_POS_X 0
#define STR_POS_Y 0
#define RING_SIZE 32 // Ring Buffer size (32 sectors seems good enough)
#if TRUECOL
#define PPW 3/2 // pixels per short word => (RGB24 needs 24b/3B per pixel, so 2B(short) store 3/2 pixels)
// DCT mode - bit 0 : depth (0 = 16b, 1 = 24b), bit 1: in 16b mode, set bit 15.
// 24bpp = 01b => 1
#define DCT_MODE 1
#else
// 16bpp = 11b => 3
#define PPW 1
#define DCT_MODE 2
#endif
//~ static int strFrameX=0,strFrameY=0;
static int strNumFrames=0;
// Stop playback if set
static int endPlayback = 0;
// When using RGB24, a special routine has to be setup to avoid MDEC/CDROM conflict
// See http://psx.arthus.net/sdk/Psy-Q/DOCS/LibRef47.pdf , p.713
static void strCheckRGB24();
// STR file infos : Filename on CD, Width, Height, Length in frames
static char * StrFileName = "\\COPY.STR;1";
static int StrFileX = 320;
static int StrFileY = 240;
static int StrFileLength = 893;
void init(void)
{
ResetCallback();
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);
#endif
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;
#if TRUECOL
disp[0].isrgb24 = 1;
disp[1].isrgb24 = 1;
#endif
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() {
int id; // Display buffer ID
CdlFILE file; // File info of video file
u_char param=CdlModeSpeed;
// Buffers total ~110KB in memory
// SECTOR_SIZE is defined in words : 512 * 4 == 2048 Bytes/sector
// Ring buffer : 32 * 2048 = 65536 Bytes
u_long RingBuff[ RING_SIZE * SECTOR_SIZE ];
// VLC buffers : display area in words (hence /2), 160*320 == 38400 Bytes
u_long VlcBuff[2][ SCREENXRES / 2 * SCREENYRES ];
// If using 16bpp, fetch 16xYres strips, if 24bpp, fetch 24xYres strips, 5120*PPW Bytes
u_short ImgBuff[2][ 16 * PPW * SCREENYRES];
u_long * curVLCptr = VlcBuff[db];
// Reset and initialize stuff
init();
CdInit();
//~ ResetGraph(0);
// Set display mask so we won't see garbage while the stream is being prepared
//~ SetDispMask(0);
// Reset the MDEC
DecDCTReset(0);
// Set callback routine
DecDCToutCallback(strCheckRGB24);
// Set ring buffer
StSetRing(RingBuff, RING_SIZE);
// Set streaming parameters
StSetStream(TRUECOL, 1, 0xffffffff, 0, 0);
strNumFrames = StrFileLength;
// Get the CD location of the STR file to play
if ( CdSearchFile(&file, StrFileName) == 0 ) {
printf("File not found :%s\n", StrFileName);
//~ SetDispMask(1);
}
// Set the seek target position
CdControl(CdlSetloc, (u_char *)&file.pos, 0);
// Set CD mode to CdlModeSpeed
CdControl(CdlSetmode, &param, 0);
// Read from CD at position &file.pos
// Enable streaming, double speed and ADPCM playback
CdRead2(CdlModeStream|CdlModeSpeed|CdlModeRT);
// Use a counter to avoid deadlocks
int wait = WAIT_TIME;
// Next Ring Buffer Frame address
u_long * nextFrame = 0;
// Ring buffer frame address
u_long * frameAddr = 0;
// Ring buffer frame header
StHEADER * sectorHeader;
// Main loop
while (1) {
u_long * curVLCptr = &VlcBuff[db][0];
u_short * curIMGptr = &ImgBuff[db][0];
// While end of str is not reached, play it
while (!endPlayback) {
// Use this area to draw the slices
RECT curSlice = {0, db * SCREENYRES, 16 * PPW , SCREENYRES};
int frameDone = 0;
wait = WAIT_TIME;
// Dont try decoding if not data has been loaded from ring buffer
if ( frameAddr ){
// Begin decoding RLE-encoded MDEC image data
DecDCTin( &VlcBuff[db][0] , DCT_MODE);
// Prepare to receive the decoded image data from the MDEC
while (curSlice.x < STR_POS_X + SCREENXRES * PPW) {
// Receive decoded data : a 16*ppw*240 px slice
DecDCTout( (u_long *) &ImgBuff[db][0], curSlice.w * curSlice.h / 2);
// Wait for transfer end
DecDCToutSync(1);
// Transfer data from main memory to VRAM
LoadImage(&curSlice, (u_long *) &ImgBuff[db][0]);
// Increment drawArea's X with slice width (16 or 24 pix)
curSlice.x += 16 * PPW;
}
// Set frameDone flag to 1
frameDone = 1;
curSlice.x = STR_POS_X;
curSlice.y = db * SCREENYRES;
}
// Get one frame of ring buffer data
// StGetNext is non-blocking, so we wait for it to return 0.
// StGetNext will lock the region at &frameAddr until StFreeRing() is called.
while ( StGetNext((u_long **)&frameAddr,(u_long **)&sectorHeader) ) {
wait--;
if (wait == 0)
break;
}
// If the current frame's number is bigger than the number of frames in STR,
// set the endPlayback flag.
if (sectorHeader->frameCount >= strNumFrames)
endPlayback = 1;
// Grab a frame from the stream
wait = WAIT_TIME;
while ((nextFrame = frameAddr) == 0) {
wait--;
if ( wait == 0 ){
break;
}
}
// Decode the VLC
DecDCTvlc(nextFrame, &VlcBuff[!db][0]);
// Unlock area obtained by StGetNext()
StFreeRing(nextFrame);
// Reset counter
wait = WAIT_TIME;
// Wait until the whole frame is loaded to VRAM
while ( frameDone == 0 ) {
wait--;
if ( wait == 0 ) {
// If a timeout occurs, force switching buffers
frameDone = 1;
curSlice.x = STR_POS_X;
curSlice.y = db * SCREENYRES;
}
}
FntFlush(-1);
display();
}
// Disable callback
DecDCToutCallback(0);
// Release two interrupt functions CdDataCallback() and CdReadyCallback() hooked by CDRead2()
StUnSetRing();
// Put CDROM on pause at current position
CdControlB(CdlPause, 0, 0);
}
return 0;
};
static void strCheckRGB24() {
/* From http://psx.arthus.net/sdk/Psy-Q/DOCS/, p.713
* When playing a movie in 24-bit mode, there is a potential hardware conflict between the CD subsystem
* and the MDEC image decompression system which can result in corrupted data. To avoid this,
* StCdInterrupt() may defer transferring a sector and instead set a flag variable called StCdInterFlag to
* indicate that a CD sector is ready to be transferred. Once the MDEC is finished transferring data, your
* application should check StCdIntrFlag and call StCdInterrupt() directly if it is set.
*/
#if TRUECOL
extern int StCdIntrFlag;
if (StCdIntrFlag) {
StCdInterrupt();
StCdIntrFlag = 0;
}
#endif
}

View File

@ -71,7 +71,7 @@ void display(void)
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
// We're using a reverse OT, so we want to display the last item first. See PsyQ's LibRef47.pdf, p.277
DrawOTag(ot[db] + OTLEN - 1);
DrawOTag(&ot[db][OTLEN - 1]);
// Uncomment the following line to use a regular oredered OT. Uncomment l.100 accordingly
//~ DrawOTag(ot[db]);

View File

@ -0,0 +1,127 @@
// This is stolen from Lameguy64 tutorial : http://lameguy64.net/svn/pstutorials/chapter1/1-display.html
#include <sys/types.h>
#include <stdio.h>
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
// CD library
#include <libcd.h>
// SPU library
#include <libspu.h>
#define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL
#define SCREENXRES 320 // Screen width
#define SCREENYRES 240 // Screen height
#define CENTERX SCREENXRES/2 // Center of screen on x
#define CENTERY SCREENYRES/2 // Center of screen on y
#define MARGINX 0 // margins for text display
#define MARGINY 32
#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
SpuCommonAttr spuSettings;
// CD specifics
#define CD_SECTOR_SIZE 2048
#define RING_SIZE 32
// 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};
// Load data to this buffer - Use an array to reserve memory
u_long cdDataBuffer[RING_SIZE * CD_SECTOR_SIZE];
// 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;
// XA playback
// Number of frame in video file - 1
u_int strFrameCnt = 893;
// Flag set when playback has reached end of file
u_int strEndReached = 0;
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]
if (VMODE) // PAL
{
SetVideoMode(MODE_PAL);
disp[0].screen.y += 8; // add offset : 240 + 8 + 8 = 256
disp[1].screen.y += 8;
}
SetDispMask(1); // Display on screen
setRGB0(&draw[0], 150, 200, 50); // set color for first draw area
setRGB0(&draw[1], 150, 200, 50); // set color for second draw area
draw[0].isbg = 1; // set mask for draw areas. 1 means repainting the area with the RGB color each frame
draw[1].isbg = 1;
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, SCREENYRES - MARGINY - FONTSIZE, 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)
{
u_char cdSpeed = {CdlModeSpeed};
// Init display
init();
// SPU setup
// Init Spu
SpuInit();
// Set master & CD volume to max
spuSettings.mask = (SPU_COMMON_MVOLL | SPU_COMMON_MVOLR | SPU_COMMON_CDVOLL | SPU_COMMON_CDVOLR | SPU_COMMON_CDMIX);
spuSettings.mvol.left = 0x6000;
spuSettings.mvol.right = 0x6000;
spuSettings.cd.volume.left = 0x6000;
spuSettings.cd.volume.right = 0x6000;
// Enable CD input ON
spuSettings.cd.mix = SPU_ON;
// Apply settings
SpuSetCommonAttr(&spuSettings);
// Set transfer mode
SpuSetTransferMode(SPU_TRANSFER_BY_DMA);
// Init CD system
CdInit();
// Streaming
// Init CD ring buffer
StSetRing(cdDataBuffer, RING_SIZE);
// Set name of file to load
loadFile = "\\COPY.STR;1";
// Get file position from filename
CdSearchFile( &filePos, loadFile);
// Issue CdlSetloc CDROM command : Set the seek target position
CdControl(CdlSetloc, (u_char *)&filePos.pos, 0);
// Set streaming parameters
StSetStream(0, 200, 0xffffffff, 0, 0);
// Set CD parameters
CdControl(CdlSetmode, &cdSpeed, 0);
CdSync(0,0);
// Start streaming
CdRead2(CdlModeStream|CdlModeSpeed|CdlModeRT);
while (1) // infinite loop
{
FntPrint("Hello XA streaming !"); // Send string to print stream
FntFlush(-1); // Draw printe stream
display(); // Execute display()
}
return 0;
}