Add basic XA sound support

This commit is contained in:
ABelliqueux 2021-08-10 18:44:19 +02:00
parent f03d4e03b7
commit 9894e7d9d5
8 changed files with 168 additions and 6 deletions

View File

@ -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 \

View File

@ -16,6 +16,8 @@
<file name="SCES_313.37" type="data" source="main.ps-exe"/>
<file name="LEVEL0.bin" type="data" source="Overlay.lvl0" />
<file name="LEVEL1.bin" type="data" source="Overlay.lvl1" />
<file name="INTER8.XA" type="xa" source="xa/inter8.xa"/>
<dummy sectors="1024"/>
</directory_tree>
</track>

View File

@ -6,6 +6,7 @@
#include <libgpu.h>
#include <libapi.h>
#include <libcd.h>
#include <libspu.h>
#include <string.h>
#include <inline_n.h>
#include <gtemac.h>

27
include/sound.h Normal file
View File

@ -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);

View File

@ -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,

View File

@ -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

82
src/sound.c Normal file
View File

@ -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, &param, 0);
}
int prepareXAplayback(CdlFILTER * filter, char * channel){
u_char param = CdlModeSpeed|CdlModeRT|CdlModeSF|CdlModeSize1;
// Set the parameters above
CdControlB(CdlSetmode, &param, 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;
}
}

BIN
xa/inter8.xa Normal file

Binary file not shown.