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...
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
See here for more informations about the VAG fileformat and tools :
|
||||
|
||||
https://github.com/ABelliqueux/nolibgs_hello_worlds/wiki/VAG
|
|
@ -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
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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.
|
@ -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
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue