diff --git a/Makefile b/Makefile index fe7ceb1..e88b4b7 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ src/physics.c \ src/graphics.c \ src/psx.c \ src/space.c \ +src/sound.c \ levels/level0.c \ levels/level1.c \ TIM/home.tim \ diff --git a/config/OverlayExample.xml b/config/OverlayExample.xml index 6f69d7e..13a70ab 100644 --- a/config/OverlayExample.xml +++ b/config/OverlayExample.xml @@ -16,6 +16,8 @@ + + diff --git a/include/psx.h b/include/psx.h index 5399d67..5a8d158 100644 --- a/include/psx.h +++ b/include/psx.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include diff --git a/include/sound.h b/include/sound.h new file mode 100644 index 0000000..c6367ac --- /dev/null +++ b/include/sound.h @@ -0,0 +1,27 @@ +#pragma once +#include "../include/psx.h" + +#define CD_SECTOR_SIZE 2048 +// XA +// Sector offset for XA data 4: simple speed, 8: double speed +#define XA_SECTOR_OFFSET 4 +// Number of XA files +#define XA_TRACKS 1 +// Number of populated XA streams/channels in each XA file +#define INDEXES_IN_XA 1 +#define TOTAL_TRACKS (XA_TRACKS*INDEXES_IN_XA) + +// XA track struc +typedef struct { + int start; + int end; +} XA_TRACK; + +void setSPUsettings(SpuCommonAttr * spuSettings); +int prepareXAplayback(CdlFILTER * filter, char * channel); +int resetXAsettings(void); +void loadXAfile( char * XAfile, XA_TRACK * XATrack); +u_char startXAPlayback(int * sectorPos, CdlLOC * loc); +int stopXAPlayback(void); +int setXAchannel(CdlFILTER * filter, char * channel); +int playXAtrack(int * CurPos, XA_TRACK * XATrack, CdlFILTER * filter, CdlLOC * loc, char * channel); diff --git a/src/main.c b/src/main.c index bbe9f3a..f670df2 100644 --- a/src/main.c +++ b/src/main.c @@ -24,6 +24,7 @@ #include "../include/physics.h" #include "../include/graphics.h" #include "../include/space.h" +#include "../include/sound.h" #define USECD @@ -105,6 +106,28 @@ VECTOR col = {0}; short timediv = 1; // Animation time, see l.206 int atime = 0; +// Sound +// SPU attributes +SpuCommonAttr spuSettings; +// Declare an array of XA_TRACK +XA_TRACK XATrack[XA_TRACKS]; +// Name of file to load +static char * loadXA = "\\INTER8.XA;1"; +// ADPCM Filter +CdlFILTER filter; +// Position of file on CD +CdlLOC loc; +// XA settings +u_char param[4]; +// Start and end position of XA data, in sectors +//~ static int StartPos, EndPos; +// Current pos in file +static int CurPos = -1; +// Playback status : 0 not playing, 1 playing +//~ static int gPlaying = 0; +// Current XA channel +static char channel = 0; + int main() { // Set matrices pointers to scratchpad camera.mat = dc_camMat; @@ -175,9 +198,19 @@ int main() { setCameraPos(&camera, &curLvl.camPtr->campos->pos, &curLvl.camPtr->campos->rot); // Time counter oldTime = GetRCnt(RCntCNT1); + // Sound + setSPUsettings(&spuSettings); + #ifdef USECD + loadXAfile(loadXA, XATrack); + #endif + prepareXAplayback(&filter, &channel); + CurPos = XATrack[0].start; // Main loop while ( VSync(VSYNC) ) { + // Sound playback + playXAtrack(&CurPos, XATrack, &filter, &loc, &channel); + dt = GetRCnt(RCntCNT1) - oldTime; oldTime = GetRCnt(RCntCNT1); @@ -265,11 +298,28 @@ int main() { } // Physics if ( physics ) { + u_char canMove = 1; for ( int k = 0; k < *curLvl.meshes_length; k ++ ) { if ( curLvl.meshes[k]->isRigidBody == 1 ) { applyAcceleration( curLvl.meshes[k]->body, dt); + // Get col between props and level + if ( curLvl.meshes[k]->isProp ){ + checkBodyCol( curLvl.meshes[k]->body , curLvl.meshes[k]->node->plane->body ); + for (short obj=0; obj < curLvl.curNode->objects->index; obj++){ + // If isWall, check collision + if ( curLvl.curNode->objects->list[obj]->isWall ){ + if( getExtCollision( *curLvl.meshes[k]->body, *curLvl.curNode->objects->list[obj]->body ).vz && + getExtCollision( *curLvl.meshes[k]->body, *curLvl.curNode->objects->list[obj]->body ).vx) { + curLvl.meshes[k]->body->position.vz = curLvl.meshes[k]->body->position.vz - curLvl.meshes[k]->body->velocity.vz ; + curLvl.meshes[k]->body->position.vx = curLvl.meshes[k]->body->position.vx - curLvl.meshes[k]->body->velocity.vx ; + canMove = 0; + } + } + } + } + // Get col between actor and level if ( curLvl.meshes[k]->isActor ){ - // Get col between actor and level + // Check col checkBodyCol( curLvl.meshes[k]->body , curLvl.levelPtr->body ); // Get col between actor and current node's walls // Loop on current node's objects @@ -284,15 +334,12 @@ int main() { } } } - // Get col between props and level - if ( curLvl.meshes[k]->isProp ){ - checkBodyCol( curLvl.meshes[k]->body , curLvl.meshes[k]->node->plane->body ); - } + // Only evaluate collision if actor is on same plane as prop if ( curLvl.curNode == curLvl.propPtr->node ){ // Get col between actor and props col = getExtCollision( *curLvl.meshes[k]->body, *curLvl.propPtr->body ); - if (col.vx && col.vz ) { + if (col.vx && col.vz && canMove == 1 ) { setVector( &curLvl.propPtr->body->velocity, curLvl.meshes[k]->body->velocity.vx, 0, diff --git a/src/psx.c b/src/psx.c index 62fc198..cbb4b87 100644 --- a/src/psx.c +++ b/src/psx.c @@ -25,6 +25,8 @@ void init(DISPENV disp[2], DRAWENV draw[2], short db, CVECTOR * BGc, VECTOR * BK //~ PadInit(0); //~ InitPAD(controllers[0].pad, 34, controllers[1].pad, 34); //~ StartPAD(); + // Init SPU + SpuInit(); // Reset the GPU ResetGraph( 0 ); // Initialize and setup the GTE diff --git a/src/sound.c b/src/sound.c new file mode 100644 index 0000000..37b3bcc --- /dev/null +++ b/src/sound.c @@ -0,0 +1,82 @@ +#include "../include/sound.h" +#include "../include/space.h" + +void setSPUsettings(SpuCommonAttr * spuSettings){ + // 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); +} + +int resetXAsettings(void){ + // Reset parameters + u_char param = CdlModeSpeed; + // Set CD mode + return CdControlB(CdlSetmode, ¶m, 0); +} +int prepareXAplayback(CdlFILTER * filter, char * channel){ + u_char param = CdlModeSpeed|CdlModeRT|CdlModeSF|CdlModeSize1; + // Set the parameters above + CdControlB(CdlSetmode, ¶m, 0); + // Pause at current pos + CdControlF(CdlPause,0); + // Set filter + // Use file 1, channel 0 + filter->file = 1; + filter->chan = *channel; + return CdControlF(CdlSetfilter, (u_char *)filter); +} +void loadXAfile( char * XAfile, XA_TRACK * XATrack){ + CdlFILE XAPos; + CdSearchFile( &XAPos, XAfile); + XATrack[0].start = CdPosToInt(&XAPos.pos); + XATrack[0].end = XATrack[0].start + (XAPos.size/CD_SECTOR_SIZE) - 1; +} + +u_char startXAPlayback(int * sectorPos, CdlLOC * loc){ + // Convert sector number to CD position in min/second/frame and set CdlLOC accordingly. + CdIntToPos( *sectorPos, loc); + // Send CDROM read command + CdControlF(CdlReadS, (u_char *)loc); + return 1; +} +int stopXAPlayback(void){ + // stop CD + return CdControlF(CdlStop,0); +} +int setXAchannel(CdlFILTER * filter, char * channel){ + filter->chan = *channel; + // Set filter + return CdControlF(CdlSetfilter, (u_char *)filter); +} +int playXAtrack(int * CurPos, XA_TRACK * XATrack, CdlFILTER * filter, CdlLOC * loc, char * channel){ + static int gPlaying = 0; + // Sound playback + // Begin XA file playback + if (gPlaying == 0 && *CurPos == XATrack[0].start){ + gPlaying = startXAPlayback(&XATrack[0].start, loc); + } + // When endPos is reached, set playing flag to 0 + if ((*CurPos += XA_SECTOR_OFFSET) >= XATrack[0].end){ + gPlaying = 0; + } + // If XA file end is reached, stop playback + if ( gPlaying == 0 && *CurPos >= XATrack[0].end ){ + // Stop CD playback + stopXAPlayback(); + // Optional + //~ resetXAsettings(); + // Switch to next channel and start play back + *channel = !*channel; + setXAchannel(filter, channel); + *CurPos = XATrack[0].start; + } +} diff --git a/xa/inter8.xa b/xa/inter8.xa new file mode 100644 index 0000000..5ea675f Binary files /dev/null and b/xa/inter8.xa differ