diff --git a/Makefile b/Makefile index e88b4b7..0dd3df7 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,16 @@ TIM/bg_camPath_002.tim \ TIM/bg_camPath_003.tim \ TIM/bg_camPath_004.tim \ TIM/bg_camPath_005.tim \ +VAG/hello.vag \ +VAG/poly.vag \ +VAG/0_come.vag \ +VAG/1_cuek.vag \ +VAG/2_erro.vag \ +VAG/3_hehe.vag \ +VAG/4_m4a1.vag \ +VAG/5_punc.vag \ +VAG/7_wron.vag \ +VAG/8_yooo.vag \ OVERLAYSCRIPT ?= overlay.ld OVERLAYSECTION ?= .lvl0 .lvl1 diff --git a/README.md b/README.md index b57bc27..0400f31 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ cd my-project * `pcsx-redux -run -iso OverlayExample.cue` : run the disk image in the [pcsx-redux](https://github.com/grumpycoders/pcsx-redux/) emulator. On first launch, `pcsx-redux` will ask for a PSX bios. You can use your own or [the open source OpenBios](https://github.com/grumpycoders/pcsx-redux/tree/main/src/mips/openbios). - A [prebuilt binary](http://psx.arthus.net/roms/bios/openbios.bin) is available here for convenience. + A [prebuilt binary](https://psx.arthus.net/roms/bios/openbios.bin) is available here for convenience. Set it in pcsx-redux ; `Configuration > Emulation`, then reboot the emulator ; `File > Reboot`. 4. Install the [blender extension](https://github.com/ABelliqueux/blender_io_export_psx_mesh) to create your own levels. @@ -85,6 +85,33 @@ Thus, to load `Overlay.lvl1` and `main.ps-exe` in the psx ram, use : # Credits -PSX code based on [example](http://psx.arthus.net/code/primdraw.7z) by [Lameguy64](https://github.com/Lameguy64) +## Sound credits + +### XA files : + +Lobby Time by Kevin MacLeod +Link: https://incompetech.filmmusic.io/song/3986-lobby-time +License: https://filmmusic.io/standard-license + +Pixelland by Kevin MacLeod +Link: https://incompetech.filmmusic.io/song/4222-pixelland +License: https://filmmusic.io/standard-license + +### VAG files + +All the sound effects come from https://www.myinstants.com and are : + +``` +comedy_pop_finger_in_mouth_001(1).mp3 +cuek.swf.mp3 +erro.mp3 +m4a1_single-kibblesbob-8540445.mp3 +punch.mp3 +wrong-answer-sound-effect.mp3 +yooooooooooooooooooooooooo_4.mp3 +hehehehhehehehhehehheheehehe.mp3 +``` + +PSX code based on [example](https://psx.arthus.net/code/primdraw.7z) by [Lameguy64](https://github.com/Lameguy64) An incredible amount of help from the good fellows at the [psxdev discord](https://discord.com/invite/EnaNgrqJ?utm_source=Discord%20Widget&utm_medium=Connect), Including but not limited to @NicolasNoble, @Lameguy64, @Impiaa, @paul, @sickle, @danhans42... diff --git a/VAG/0_come.vag b/VAG/0_come.vag new file mode 100644 index 0000000..09cab2e Binary files /dev/null and b/VAG/0_come.vag differ diff --git a/VAG/1_cuek.vag b/VAG/1_cuek.vag new file mode 100644 index 0000000..61891c3 Binary files /dev/null and b/VAG/1_cuek.vag differ diff --git a/VAG/2_erro.vag b/VAG/2_erro.vag new file mode 100644 index 0000000..7f8c656 Binary files /dev/null and b/VAG/2_erro.vag differ diff --git a/VAG/3_hehe.vag b/VAG/3_hehe.vag new file mode 100644 index 0000000..56d3417 Binary files /dev/null and b/VAG/3_hehe.vag differ diff --git a/VAG/4_m4a1.vag b/VAG/4_m4a1.vag new file mode 100644 index 0000000..6a4dfc4 Binary files /dev/null and b/VAG/4_m4a1.vag differ diff --git a/VAG/5_punc.vag b/VAG/5_punc.vag new file mode 100644 index 0000000..89e6894 Binary files /dev/null and b/VAG/5_punc.vag differ diff --git a/VAG/7_wron.vag b/VAG/7_wron.vag new file mode 100644 index 0000000..f36e08d Binary files /dev/null and b/VAG/7_wron.vag differ diff --git a/VAG/8_yooo.vag b/VAG/8_yooo.vag new file mode 100644 index 0000000..77b90eb Binary files /dev/null and b/VAG/8_yooo.vag differ diff --git a/VAG/README.md b/VAG/README.md new file mode 100644 index 0000000..e51a251 --- /dev/null +++ b/VAG/README.md @@ -0,0 +1,3 @@ +See here for more informations about the VAG fileformat and tools : + +https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/VAG diff --git a/VAG/audio2vag b/VAG/audio2vag new file mode 100755 index 0000000..3fba8ec --- /dev/null +++ b/VAG/audio2vag @@ -0,0 +1,18 @@ +#!/bin/bash +if [ $# -eq 0 ] + then + echo "Audio to VAG conversion helper script +You need to have ffmpeg and wav2vag in your path environment. + +Usage: + ./audio2wav input.ext freq + +where freq can be 44100, 22050, 11025, 5512 +" +else + +ffmpeg -i $1 -f s16le -ac 1 -ar $2 tmp.dat -y +wav2vag tmp.dat ${1%.***}.vag -sraw16 -freq=$2 +rm tmp.dat + +fi diff --git a/VAG/hello.vag b/VAG/hello.vag new file mode 100644 index 0000000..e333b19 Binary files /dev/null and b/VAG/hello.vag differ diff --git a/VAG/hello_poly.vag b/VAG/hello_poly.vag new file mode 100644 index 0000000..fd984d8 Binary files /dev/null and b/VAG/hello_poly.vag differ diff --git a/VAG/poly.vag b/VAG/poly.vag new file mode 100644 index 0000000..74a6505 Binary files /dev/null and b/VAG/poly.vag differ diff --git a/VAG/wav/00_sile.vag b/VAG/wav/00_sile.vag new file mode 100644 index 0000000..eff2412 Binary files /dev/null and b/VAG/wav/00_sile.vag differ diff --git a/VAG/wav/00_sile.wav b/VAG/wav/00_sile.wav new file mode 100644 index 0000000..7d6749f Binary files /dev/null and b/VAG/wav/00_sile.wav differ diff --git a/VAG/wav/0_come.vag b/VAG/wav/0_come.vag new file mode 100644 index 0000000..09cab2e Binary files /dev/null and b/VAG/wav/0_come.vag differ diff --git a/VAG/wav/0_come.wav b/VAG/wav/0_come.wav new file mode 100644 index 0000000..11423eb Binary files /dev/null and b/VAG/wav/0_come.wav differ diff --git a/VAG/wav/1_cuek.vag b/VAG/wav/1_cuek.vag new file mode 100644 index 0000000..61891c3 Binary files /dev/null and b/VAG/wav/1_cuek.vag differ diff --git a/VAG/wav/1_cuek.wav b/VAG/wav/1_cuek.wav new file mode 100644 index 0000000..150a408 Binary files /dev/null and b/VAG/wav/1_cuek.wav differ diff --git a/VAG/wav/2_erro.vag b/VAG/wav/2_erro.vag new file mode 100644 index 0000000..7f8c656 Binary files /dev/null and b/VAG/wav/2_erro.vag differ diff --git a/VAG/wav/2_erro.wav b/VAG/wav/2_erro.wav new file mode 100644 index 0000000..58f66f7 Binary files /dev/null and b/VAG/wav/2_erro.wav differ diff --git a/VAG/wav/3_hehe.vag b/VAG/wav/3_hehe.vag new file mode 100644 index 0000000..56d3417 Binary files /dev/null and b/VAG/wav/3_hehe.vag differ diff --git a/VAG/wav/3_hehe.wav b/VAG/wav/3_hehe.wav new file mode 100644 index 0000000..c4f9e65 Binary files /dev/null and b/VAG/wav/3_hehe.wav differ diff --git a/VAG/wav/4_m4a1.vag b/VAG/wav/4_m4a1.vag new file mode 100644 index 0000000..6a4dfc4 Binary files /dev/null and b/VAG/wav/4_m4a1.vag differ diff --git a/VAG/wav/4_m4a1.wav b/VAG/wav/4_m4a1.wav new file mode 100644 index 0000000..f17e005 Binary files /dev/null and b/VAG/wav/4_m4a1.wav differ diff --git a/VAG/wav/5_punc.vag b/VAG/wav/5_punc.vag new file mode 100644 index 0000000..89e6894 Binary files /dev/null and b/VAG/wav/5_punc.vag differ diff --git a/VAG/wav/5_punc.wav b/VAG/wav/5_punc.wav new file mode 100644 index 0000000..15d2a96 Binary files /dev/null and b/VAG/wav/5_punc.wav differ diff --git a/VAG/wav/7_wron.vag b/VAG/wav/7_wron.vag new file mode 100644 index 0000000..f36e08d Binary files /dev/null and b/VAG/wav/7_wron.vag differ diff --git a/VAG/wav/7_wron.wav b/VAG/wav/7_wron.wav new file mode 100644 index 0000000..b8a7b44 Binary files /dev/null and b/VAG/wav/7_wron.wav differ diff --git a/VAG/wav/8_yooo.vag b/VAG/wav/8_yooo.vag new file mode 100644 index 0000000..77b90eb Binary files /dev/null and b/VAG/wav/8_yooo.vag differ diff --git a/VAG/wav/8_yooo.wav b/VAG/wav/8_yooo.wav new file mode 100644 index 0000000..c718f4a Binary files /dev/null and b/VAG/wav/8_yooo.wav differ diff --git a/include/defines.h b/include/defines.h index 7c974b8..8ce1727 100644 --- a/include/defines.h +++ b/include/defines.h @@ -1,5 +1,5 @@ #define VMODE 0 // 0 == NTSC, 1 == PAL -#define VSYNC 1 +#define VSYNC 0 #define SCREENXRES 320 #define SCREENYRES 240 #define CENTERX SCREENXRES/2 @@ -10,6 +10,15 @@ #define CLEAR_COLOR_G 0 #define CLEAR_COLOR_B 0 +// Sound +// CDDA / XA volume +#define MVOL_L 0x3fff +#define MVOL_R 0x3fff +#define CDVOL_L 0x7fff +#define CDVOL_R 0x7fff +#define VOICEVOL_L 0x3fff +#define VOICEVOL_R 0x3fff + // Debug Font #define FNT_VRAM_X 960 #define FNT_VRAM_Y 256 @@ -75,10 +84,10 @@ asm(\ #define PadDown ( 1 << 6 ) #define PadLeft ( 1 << 7 ) -#define Tri ( 1 << 12 ) -#define Circ ( 1 << 13 ) +#define Triangle ( 1 << 12 ) +#define Circle ( 1 << 13 ) #define Cross ( 1 << 14 ) -#define Squar ( 1 << 15 ) +#define Square ( 1 << 15 ) // Joysticks #define PadR3 ( 1 << 2 ) #define PadL3 ( 1 << 1 ) diff --git a/include/macros.h b/include/macros.h index 36cc485..9ee2e9d 100644 --- a/include/macros.h +++ b/include/macros.h @@ -46,3 +46,6 @@ gte_stdp(r9); \ gte_avsz4(); \ gte_stotz(r10); } + +// convert Little endian to Big endian +#define SWAP_ENDIAN32(x) (((x)>>24) | (((x)>>8) & 0xFF00) | (((x)<<8) & 0x00FF0000) | ((x)<<24)) diff --git a/include/sound.h b/include/sound.h index c6367ac..be9b9dd 100644 --- a/include/sound.h +++ b/include/sound.h @@ -1,27 +1,54 @@ #pragma once #include "../include/psx.h" - -#define CD_SECTOR_SIZE 2048 +#include "../include/macros.h" // 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) +#define XA_CHANNELS 8 +#define XA_CDSPEED (XA_CHANNELS >> VSYNC) +// Number of XA samples ( != # of XA files ) +#define XA_TRACKS 2 +// VAG +// Number of VAG files to load +#define VAG_NBR 8 +#define MALLOC_MAX VAG_NBR // Max number of time we can call SpuMalloc +// Custom struct to handle VAG files +typedef struct VAGsound { + u_char * VAGfile; // Pointer to VAG data address + u_long spu_channel; // SPU voice to playback to + u_long spu_address; // SPU address for memory freeing spu mem + } VAGsound; +// VAG header struct (see fileformat47.pdf, p.209) +typedef struct VAGhdr { // All the values in this header must be big endian + char id[4]; // VAGp 4 bytes -> 1 char * 4 + unsigned int version; // 4 bytes + unsigned int reserved; // 4 bytes + unsigned int dataSize; // (in bytes) 4 bytes + unsigned int samplingFrequency;// 4 bytes + char reserved2[12]; // 12 bytes -> 1 char * 12 + char name[16]; // 16 bytes -> 1 char * 16 + // Waveform data after that +} VAGhdr; +// XA +typedef struct XAsound { + u_int id; + u_int size; + u_char file, channel; + u_int start, end; + int cursor; +} XAsound; -// XA track struc -typedef struct { - int start; - int end; -} XA_TRACK; +typedef struct XAbank { + u_int index; + int offset; + XAsound samples[]; +} XAbank; -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); +// VAG playback +void initSnd(SpuCommonAttr * spuSettings, char * spu_malloc_rec); +u_long sendVAGtoSPU(unsigned int VAG_data_size, u_char *VAG_data); +void setVoiceAttr(SpuVoiceAttr * voiceAttributes, u_int pitch, long channel, u_long soundAddr ); +u_long setSPUtransfer(SpuVoiceAttr * voiceAttributes, VAGsound * sound); +void playSFX(SpuVoiceAttr * voiceAttributes, VAGsound * sound); +// XA playback +void XAsetup(void); +void setXAsample(XAsound * sound, CdlFILTER * filter); diff --git a/src/main.c b/src/main.c index f670df2..4175ea0 100644 --- a/src/main.c +++ b/src/main.c @@ -16,7 +16,6 @@ * eye */ // Blender debug mode // bpy. app. debug = True -#define _WCHAR_T #include "../include/psx.h" #include "../include/pad.h" #include "../include/math.h" @@ -95,8 +94,9 @@ NODE * propStartNode; // Callback function is used for pads void callback(); // variable FPS -ulong oldTime = 0; -int dt = 0; +long oldTime = 0; +long XATime = 0; +long dt = 0; // Physics/collisions short physics = 1; VECTOR col = {0}; @@ -107,26 +107,73 @@ 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 +// VAG playback +// Memory management table ; allow MALLOC_MAX calls to SpuMalloc() - libref47.pdf p.1044 +char spu_malloc_rec[SPU_MALLOC_RECSIZ * (2 + MALLOC_MAX + 1)]; +// SPU settings +SpuCommonAttr spuSettings; // structure for changing common voice attributes +SpuVoiceAttr voiceAttributes ; // structure for changing individual voice attributes +// extern VAG files +extern u_char _binary_VAG_0_come_vag_start; +extern u_char _binary_VAG_1_cuek_vag_start; +extern u_char _binary_VAG_2_erro_vag_start; +extern u_char _binary_VAG_3_hehe_vag_start; +extern u_char _binary_VAG_4_m4a1_vag_start; +extern u_char _binary_VAG_5_punc_vag_start; +extern u_char _binary_VAG_7_wron_vag_start; +extern u_char _binary_VAG_8_yooo_vag_start; +// soundBank +VAGsound VAGBank[VAG_NBR] = { + { &_binary_VAG_0_come_vag_start, + SPU_00CH, 0 }, + { &_binary_VAG_1_cuek_vag_start, + SPU_01CH, 0 }, + { &_binary_VAG_2_erro_vag_start, + SPU_02CH, 0 }, + { &_binary_VAG_3_hehe_vag_start, + SPU_03CH, 0 }, + { &_binary_VAG_4_m4a1_vag_start, + SPU_04CH, 0 }, + { &_binary_VAG_5_punc_vag_start, + SPU_05CH, 0 }, + { &_binary_VAG_7_wron_vag_start, + SPU_06CH, 0 }, + { &_binary_VAG_8_yooo_vag_start, + SPU_07CH, 0 } +}; +// XA playback +XAbank XABank = { + 8, + 0, + { + //channel 0 + { 0, 698464, 1, 0, 0, ((698464/2336)-1) * XA_CHANNELS, -1 }, + { 1, 366752, 1, 1 , 0, ((366752/2336)-1) * XA_CHANNELS, -1 }, + //~ // channel 5 + //~ // id size file channel start end cursor + //~ { 0, 18688, 0, 5, 0, 56, -1 }, + //~ { 1, 44384, 0, 5 , 144, 288, -1 }, + //~ // channel 6 + //~ { 2, 32704, 0, 6 , 0, 104, -1 }, + //~ { 3, 56064, 0, 6 , 196, 380, -1 }, + //~ { 4, 53728, 0, 6 , 468, 644, -1 }, + //~ // channel 7 + //~ { 5, 84096, 0, 7 , 0, 260, -1 }, + //~ { 6, 16352, 0, 7 , 368, 440, -1 }, + //~ // channel 8 + //~ { 7, 114464, 0, 8 , 0, 384, -1 } + } +}; +// XA file to load static char * loadXA = "\\INTER8.XA;1"; -// ADPCM Filter +// File informations : pos, size, name +CdlFILE XAPos = {0}; +// CD 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; +// File position in m/s/f +CdlLOC loc; +// Keep track of XA Sample currently playing +int sample = -1; int main() { // Set matrices pointers to scratchpad @@ -147,7 +194,12 @@ int main() { // Load overlay from cd #ifdef USECD CdInit(); + // Load level LoadLevelCD(overlayFile, &load_all_overlays_here); + // Load XA file + CdSearchFile( &XAPos, loadXA); + // Set cd head to start of file + XABank.offset = CdPosToInt(&XAPos.pos); #endif // TODO : Add switch case to get the correct pointers // Get needed pointers from level file @@ -199,21 +251,42 @@ int main() { // Time counter oldTime = GetRCnt(RCntCNT1); // Sound - setSPUsettings(&spuSettings); - #ifdef USECD - loadXAfile(loadXA, XATrack); - #endif - prepareXAplayback(&filter, &channel); - CurPos = XATrack[0].start; + SpuInit(); + // Init sound settings + initSnd(&spuSettings, spu_malloc_rec); + //~ spuCDsetup(&spuSettings); + XAsetup(); + for (u_short vag = 0; vag < VAG_NBR; vag++ ){ + VAGBank[vag].spu_address = setSPUtransfer(&voiceAttributes, &VAGBank[vag]); + } + sample = 0; + setXAsample(&XABank.samples[sample], &filter); // Main loop while ( VSync(VSYNC) ) { - - // Sound playback - playXAtrack(&CurPos, XATrack, &filter, &loc, &channel); - dt = GetRCnt(RCntCNT1) - oldTime; oldTime = GetRCnt(RCntCNT1); - + // XA playback + // if sample is set + if (sample != -1 ){ + // TODO : Fix XA playback with VSYNC = 1 + // Begin XA file playback... + // if sample's cursor is 0 + if (XABank.samples[sample].cursor == 0){ + // Convert sector number to CD position in min/second/frame and set CdlLOC accordingly. + CdIntToPos( XABank.samples[sample].start + XABank.offset , &loc); + // Send CDROM read command + CdControlF(CdlReadS, (u_char *)&loc); + XATime = VSync(-1); + // Set playing flag + } + // if sample's cursor is close to sample's end position, stop playback + if ((XABank.samples[sample].cursor += XA_CDSPEED) >= XABank.samples[sample].end - XABank.samples[sample].start ){ + //~ CdControlF(CdlStop,0); + XABank.samples[sample].cursor = -1; + //~ sample = !sample; + setXAsample(&XABank.samples[sample], &filter); + } + } // Check if level has changed // TODO : Proper level system / loader if ( levelWas != level ){ @@ -252,6 +325,14 @@ int main() { // Set level lighting setLightEnv(draw, curLvl.BGc, curLvl.BKc); levelWas = level; + // Change XA track + XAsetup(); + sample = !sample; + XABank.samples[sample].cursor = -1; + setXAsample(&XABank.samples[sample], &filter); + CdIntToPos( XABank.samples[sample].start + XABank.offset , &loc); + // Send CDROM read command + CdControlF(CdlReadS, (u_char *)&loc); } //~ FntPrint("Ovl:%s\nLvl : %x\nLvl: %d %d \n%x", overlayFile, &level, level, levelWas, loadLvl); // atime is used for animations timing @@ -263,12 +344,14 @@ int main() { // TODO : put in a function // Reset player/prop pos if(curLvl.actorPtr->pos.vy >= 200){ + playSFX(&voiceAttributes, &VAGBank[6]); copyVector(&curLvl.actorPtr->body->position, &actorStartPos ); copyVector(&curLvl.actorPtr->rot, &actorStartRot ); curLvl.curNode = actorStartNode; curLvl.levelPtr = curLvl.curNode->plane; } if(curLvl.propPtr->pos.vy >= 200){ + playSFX(&voiceAttributes, &VAGBank[3]); copyVector(&curLvl.propPtr->body->position, &propStartPos ); copyVector(&curLvl.propPtr->rot, &propStartRot ); curLvl.propPtr->node = propStartNode; @@ -392,7 +475,7 @@ int main() { //~ FntPrint("\nTime : %d\n", time); FntPrint("\n#Tri : %d\n", triCount); - FntPrint("#RCnt : %d %d\n", oldTime, dt); + FntPrint("#RCnt : %d %d %d\n", VSync(-1), XA_CDSPEED, dt); FntPrint("CamAngle : %d\n", curCamAngle); FntFlush(-1); display( &disp[db], &draw[db], otdisc[db], primbuff[db], &nextpri, &db); @@ -431,7 +514,7 @@ void callback() { if (angleCam.vy > 2048 || angleCam.vy < -2048) { angleCam.vy = 0; } - if ( PAD & PadShldR1 && !timer ) { + if ( PAD & PadShldR1 && !(lastPad & PadShldR1) ) { // Change camera angle switching mode if using pre-calculated BGs if (!curLvl.camPtr->tim_data){ if(camMode < 5){ @@ -454,46 +537,67 @@ void callback() { } } lastPad = PAD; - timer = 10; } - //~ if ( !(PAD & PadShldR1) && lastPad & PadShldR1 ) { - //pressed = 0; - //~ } + if ( !(PAD & PadShldR1) && lastPad & PadShldR1 ) { + lastPad = PAD; + } if ( PAD & PadShldL2 ) { dc_lgtangp->vy += 32; } if ( PAD & PadShldL1 ) { dc_lgtangp->vz += 32; } - if ( PAD & Tri && !timer ){ + if ( PAD & Triangle && !( lastPad & Triangle ) ){ if (curLvl.actorPtr->isPrism){ curLvl.actorPtr->isPrism = 0; } else { curLvl.actorPtr->isPrism = 1; } - timer = 10; + playSFX(&voiceAttributes, &VAGBank[0]); + //~ timer = 10; lastPad = PAD; } - if ( PAD & Cross && !timer ){ + if ( !(PAD & Triangle) && lastPad & Triangle ) { + lastPad = PAD; + } + if ( PAD & Square && !( lastPad & Square ) ){ + playSFX(&voiceAttributes, &VAGBank[7]); + //~ sample = 0; + //~ setXAsample(&XABank.samples[sample], &filter); + lastPad = PAD; + } + if ( !(PAD & Square) && lastPad & Square ) { + lastPad = PAD; + } + if ( PAD & Cross && !(lastPad & Cross) ){ if (curLvl.actorPtr->body->gForce.vy == 0 && (curLvl.actorPtr->body->position.vy - curLvl.actorPtr->body->min.vy) == curLvl.levelPtr->body->min.vy ){ // Use delta to find jump force - curLvl.actorPtr->body->gForce.vy = - ((200/((ONE/(dt<1?1:dt))<1?1:(ONE/(dt<1?1:dt))))*14); + //~ curLvl.actorPtr->body->gForce.vy = - ((200/((ONE/(dt<1?1:dt))<1?1:(ONE/(dt<1?1:dt))))*14); + curLvl.actorPtr->body->gForce.vy = -200; } - //~ cursor = div - 15; timer = 10; + playSFX(&voiceAttributes, &VAGBank[4]); lastPad = PAD; } if ( !(PAD & Cross) && lastPad & Cross ) { - //~ curLvl.actorPtr->body->gForce.vy = 0; lastPad = PAD; } - if ( PAD & PadLeft && !timer ) { + if ( PAD & Circle && !(PAD & lastPad) ){ + playSFX(&voiceAttributes, &VAGBank[5]); + lastPad = PAD; + } + if ( !(PAD & Circle) && lastPad & Circle ) { + lastPad = PAD; + } + if ( PAD & PadLeft && !(lastPad & PadLeft) ) { if (curLvl.actorPtr->anim->interpolate){ curLvl.actorPtr->anim->interpolate = 0; } else { curLvl.actorPtr->anim->interpolate = 1; } - timer = 10; + lastPad = PAD; + } + if ( !(PAD & PadLeft) && lastPad & PadLeft ) { lastPad = PAD; } if (theControllers[0].type == 0x73){ @@ -549,7 +653,7 @@ void callback() { curLvl.actorPtr->rot.vy += 64; lastPad = PAD; } - if ( PAD & PadSelect && !timer ) { + if ( PAD & PadSelect && !(lastPad & PadSelect) ) { //~ if (!levelHasChanged){ #ifndef USECD printf("load:%p:%08x:%s", &load_all_overlays_here, &level, overlayFile); @@ -563,6 +667,9 @@ void callback() { timer = 30; lastPad = PAD; } + if ( !(PAD & PadSelect) && lastPad & PadSelect ) { + lastPad = PAD; + } if( theControllers[0].type == 0x73 && camMode == ACTOR){ // Cam control - horizontal if ( theControllers[0].analog0 >= 0 && theControllers[0].analog0 < (128 - DS_DZ/2) ) { diff --git a/src/sound.c b/src/sound.c index 37b3bcc..6457311 100644 --- a/src/sound.c +++ b/src/sound.c @@ -1,82 +1,108 @@ #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; +// VAG playback +void initSnd(SpuCommonAttr * spuSettings, char * spu_malloc_rec){ + + SpuInitMalloc(MALLOC_MAX, spu_malloc_rec); // Maximum number of blocks, mem. management table address. + spuSettings->mask = (SPU_COMMON_MVOLL | SPU_COMMON_MVOLR | SPU_COMMON_CDVOLL | SPU_COMMON_CDVOLR | SPU_COMMON_CDMIX ); // Mask which attributes to set + spuSettings->mvol.left = MVOL_L; // Master volume left + spuSettings->mvol.right = MVOL_R; // see libref47.pdf, p.1058 + spuSettings->cd.volume.left = CDVOL_L; + spuSettings->cd.volume.right = CDVOL_R; // Enable CD input ON spuSettings->cd.mix = SPU_ON; - // Apply settings - SpuSetCommonAttr(spuSettings); + + SpuSetCommonAttr(spuSettings); // Set transfer mode SpuSetTransferMode(SPU_TRANSFER_BY_DMA); + SpuSetIRQ(SPU_OFF); + // Mute all voices + SpuSetKey(SpuOff, SPU_ALLCH); } - -int resetXAsettings(void){ - // Reset parameters - u_char param = CdlModeSpeed; - // Set CD mode - return CdControlB(CdlSetmode, ¶m, 0); +u_long sendVAGtoSPU(unsigned int VAG_data_size, u_char *VAG_data){ + u_long transferred; + SpuSetTransferMode(SpuTransByDMA); // DMA transfer; can do other processing during transfer + transferred = SpuWrite (VAG_data + sizeof(VAGhdr), VAG_data_size); // transfer VAG_data_size bytes from VAG_data address to sound buffer + SpuIsTransferCompleted (SPU_TRANSFER_WAIT); // Checks whether transfer is completed and waits for completion + return transferred; } -int prepareXAplayback(CdlFILTER * filter, char * channel){ - u_char param = CdlModeSpeed|CdlModeRT|CdlModeSF|CdlModeSize1; +void setVoiceAttr(SpuVoiceAttr * voiceAttributes, u_int pitch, long channel, u_long soundAddr ){ + voiceAttributes->mask= //~ Attributes (bit string, 1 bit per attribute) + ( + SPU_VOICE_VOLL | + SPU_VOICE_VOLR | + SPU_VOICE_PITCH | + SPU_VOICE_WDSA | + SPU_VOICE_ADSR_AMODE | + SPU_VOICE_ADSR_SMODE | + SPU_VOICE_ADSR_RMODE | + SPU_VOICE_ADSR_AR | + SPU_VOICE_ADSR_DR | + SPU_VOICE_ADSR_SR | + SPU_VOICE_ADSR_RR | + SPU_VOICE_ADSR_SL + ); + voiceAttributes->voice = channel; //~ Voice (low 24 bits are a bit string, 1 bit per voice ) + voiceAttributes->volume.left = 0x0; //~ Volume + voiceAttributes->volume.right = 0x0; //~ Volume + voiceAttributes->pitch = pitch; //~ Interval (set pitch) + voiceAttributes->addr = soundAddr; //~ Waveform data start address + voiceAttributes->a_mode = SPU_VOICE_LINEARIncN; //~ Attack rate mode = Linear Increase - see libref47.pdf p.1091 + voiceAttributes->s_mode = SPU_VOICE_LINEARIncN; //~ Sustain rate mode = Linear Increase + voiceAttributes->r_mode = SPU_VOICE_LINEARDecN; //~ Release rate mode = Linear Decrease + voiceAttributes->ar = 0x0; //~ Attack rate + voiceAttributes->dr = 0x0; //~ Decay rate + voiceAttributes->rr = 0x0; //~ Release rate + voiceAttributes->sr = 0x0; //~ Sustain rate + voiceAttributes->sl = 0xf; //~ Sustain level + SpuSetVoiceAttr(voiceAttributes); // set attributes +} +u_long setSPUtransfer(SpuVoiceAttr * voiceAttributes, VAGsound * sound){ + // Return spu_address + u_long transferred, spu_address; + u_int pitch; + const VAGhdr * VAGheader = (VAGhdr *) sound->VAGfile; + pitch = (SWAP_ENDIAN32(VAGheader->samplingFrequency) << 12) / 44100L; + spu_address = SpuMalloc(SWAP_ENDIAN32(VAGheader->dataSize)); // Allocate an area of dataSize bytes in the sound buffer. + SpuSetTransferStartAddr(spu_address); // Sets a starting address in the sound buffer + transferred = sendVAGtoSPU(SWAP_ENDIAN32(VAGheader->dataSize), sound->VAGfile); + setVoiceAttr(voiceAttributes, pitch, sound->spu_channel, spu_address); + // Return 1 if ok, size transferred else. + //~ if (transferred == SWAP_ENDIAN32(VAGheader->dataSize)){ + //~ return 1; + //~ } + //~ return transferred; + return spu_address; +} +void playSFX(SpuVoiceAttr * voiceAttributes, VAGsound * sound){ + // Set voice volume to max + voiceAttributes->mask= ( SPU_VOICE_VOLL | SPU_VOICE_VOLR ); + voiceAttributes->voice = sound->spu_channel; + // Range 0 - 3fff + voiceAttributes->volume.left = VOICEVOL_L; + voiceAttributes->volume.right = VOICEVOL_R; + SpuSetVoiceAttr(voiceAttributes); + // Play voice + SpuSetKey(SpuOn, sound->spu_channel); +} +void XAsetup(void){ + u_char param[4]; + // ORing the parameters we need to set ; drive speed, ADPCM play, Subheader filter, sector size + // If using CdlModeSpeed(Double speed), you need to load an XA file that has 8 channels. + // In single speed, a 4 channels XA is to be used. + param[0] = CdlModeSpeed|CdlModeRT|CdlModeSF|CdlModeSize1; + // Issue primitive command to CD-ROM system (Blocking-type) // Set the parameters above - CdControlB(CdlSetmode, ¶m, 0); + 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; +void setXAsample(XAsound * sound, CdlFILTER * filter){ + filter->chan = sound->channel; + filter->file = sound->file; // 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; - } + CdControlF(CdlSetfilter, (u_char *)filter); + // Reset sample's cursor + sound->cursor = 0; } diff --git a/xa/inter8.xa b/xa/inter8.xa index 5ea675f..1c00570 100644 Binary files a/xa/inter8.xa and b/xa/inter8.xa differ diff --git a/xa/interleave8.txt b/xa/interleave8.txt new file mode 100644 index 0000000..b491904 --- /dev/null +++ b/xa/interleave8.txt @@ -0,0 +1,8 @@ +1 xa lobby.xa 1 0 +1 xa pixel.xa 1 1 +1 null +1 null +1 null +1 null +1 null +1 null diff --git a/xa/lobby.xa b/xa/lobby.xa new file mode 100644 index 0000000..80af6e6 Binary files /dev/null and b/xa/lobby.xa differ diff --git a/xa/pixel.xa b/xa/pixel.xa new file mode 100644 index 0000000..9ec6a05 Binary files /dev/null and b/xa/pixel.xa differ