Add XA/VAG playback support, progress on blender_io_export_psx_mesh#4
This commit is contained in:
parent
6c82310a3d
commit
17d30079ca
10
Makefile
10
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
|
||||
|
31
README.md
31
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...
|
||||
|
BIN
VAG/0_come.vag
Normal file
BIN
VAG/0_come.vag
Normal file
Binary file not shown.
BIN
VAG/1_cuek.vag
Normal file
BIN
VAG/1_cuek.vag
Normal file
Binary file not shown.
BIN
VAG/2_erro.vag
Normal file
BIN
VAG/2_erro.vag
Normal file
Binary file not shown.
BIN
VAG/3_hehe.vag
Normal file
BIN
VAG/3_hehe.vag
Normal file
Binary file not shown.
BIN
VAG/4_m4a1.vag
Normal file
BIN
VAG/4_m4a1.vag
Normal file
Binary file not shown.
BIN
VAG/5_punc.vag
Normal file
BIN
VAG/5_punc.vag
Normal file
Binary file not shown.
BIN
VAG/7_wron.vag
Normal file
BIN
VAG/7_wron.vag
Normal file
Binary file not shown.
BIN
VAG/8_yooo.vag
Normal file
BIN
VAG/8_yooo.vag
Normal file
Binary file not shown.
3
VAG/README.md
Normal file
3
VAG/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
See here for more informations about the VAG fileformat and tools :
|
||||
|
||||
https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/VAG
|
18
VAG/audio2vag
Executable file
18
VAG/audio2vag
Executable file
@ -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
|
BIN
VAG/hello.vag
Normal file
BIN
VAG/hello.vag
Normal file
Binary file not shown.
BIN
VAG/hello_poly.vag
Normal file
BIN
VAG/hello_poly.vag
Normal file
Binary file not shown.
BIN
VAG/poly.vag
Normal file
BIN
VAG/poly.vag
Normal file
Binary file not shown.
BIN
VAG/wav/00_sile.vag
Normal file
BIN
VAG/wav/00_sile.vag
Normal file
Binary file not shown.
BIN
VAG/wav/00_sile.wav
Normal file
BIN
VAG/wav/00_sile.wav
Normal file
Binary file not shown.
BIN
VAG/wav/0_come.vag
Normal file
BIN
VAG/wav/0_come.vag
Normal file
Binary file not shown.
BIN
VAG/wav/0_come.wav
Normal file
BIN
VAG/wav/0_come.wav
Normal file
Binary file not shown.
BIN
VAG/wav/1_cuek.vag
Normal file
BIN
VAG/wav/1_cuek.vag
Normal file
Binary file not shown.
BIN
VAG/wav/1_cuek.wav
Normal file
BIN
VAG/wav/1_cuek.wav
Normal file
Binary file not shown.
BIN
VAG/wav/2_erro.vag
Normal file
BIN
VAG/wav/2_erro.vag
Normal file
Binary file not shown.
BIN
VAG/wav/2_erro.wav
Normal file
BIN
VAG/wav/2_erro.wav
Normal file
Binary file not shown.
BIN
VAG/wav/3_hehe.vag
Normal file
BIN
VAG/wav/3_hehe.vag
Normal file
Binary file not shown.
BIN
VAG/wav/3_hehe.wav
Normal file
BIN
VAG/wav/3_hehe.wav
Normal file
Binary file not shown.
BIN
VAG/wav/4_m4a1.vag
Normal file
BIN
VAG/wav/4_m4a1.vag
Normal file
Binary file not shown.
BIN
VAG/wav/4_m4a1.wav
Normal file
BIN
VAG/wav/4_m4a1.wav
Normal file
Binary file not shown.
BIN
VAG/wav/5_punc.vag
Normal file
BIN
VAG/wav/5_punc.vag
Normal file
Binary file not shown.
BIN
VAG/wav/5_punc.wav
Normal file
BIN
VAG/wav/5_punc.wav
Normal file
Binary file not shown.
BIN
VAG/wav/7_wron.vag
Normal file
BIN
VAG/wav/7_wron.vag
Normal file
Binary file not shown.
BIN
VAG/wav/7_wron.wav
Normal file
BIN
VAG/wav/7_wron.wav
Normal file
Binary file not shown.
BIN
VAG/wav/8_yooo.vag
Normal file
BIN
VAG/wav/8_yooo.vag
Normal file
Binary file not shown.
BIN
VAG/wav/8_yooo.wav
Normal file
BIN
VAG/wav/8_yooo.wav
Normal file
Binary file not shown.
@ -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 )
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
201
src/main.c
201
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) ) {
|
||||
|
160
src/sound.c
160
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;
|
||||
}
|
||||
|
BIN
xa/inter8.xa
BIN
xa/inter8.xa
Binary file not shown.
8
xa/interleave8.txt
Normal file
8
xa/interleave8.txt
Normal file
@ -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
|
BIN
xa/lobby.xa
Normal file
BIN
xa/lobby.xa
Normal file
Binary file not shown.
BIN
xa/pixel.xa
Normal file
BIN
xa/pixel.xa
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user