mirror of
https://github.com/stevenhowes/CTheEscape.git
synced 2026-05-27 20:13:31 +01:00
Proper sound for phasers and explosions. Multi-channel audio.
This commit is contained in:
Binary file not shown.
+10
-4
@@ -5,7 +5,7 @@
|
|||||||
#include "Sound.h"
|
#include "Sound.h"
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
|
|
||||||
#define SKIP_INTRO
|
//#define SKIP_INTRO
|
||||||
//#define SKIP_MISSION1
|
//#define SKIP_MISSION1
|
||||||
//#define SKIP_MISSION2
|
//#define SKIP_MISSION2
|
||||||
|
|
||||||
@@ -52,9 +52,10 @@ void exitfunc () {
|
|||||||
free(fontbuffer);
|
free(fontbuffer);
|
||||||
free(tilebuffer);
|
free(tilebuffer);
|
||||||
|
|
||||||
inreg.r[0] = 4;
|
sound_pcm_unset(5);
|
||||||
inreg.r[1] = 0;
|
sound_pcm_unset(6);
|
||||||
_kernel_swi (DataVox_Unset, &inreg, &outreg);
|
sound_pcm_unset(7);
|
||||||
|
sound_pcm_unset(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@@ -65,6 +66,11 @@ int main(int argc, char *argv[])
|
|||||||
atexit(exitfunc);
|
atexit(exitfunc);
|
||||||
|
|
||||||
sound_on();
|
sound_on();
|
||||||
|
sound_voices(8);
|
||||||
|
sound_set_voice(5,"DataVox-Voice");
|
||||||
|
sound_set_voice(6,"DataVox-Voice");
|
||||||
|
sound_set_voice(7,"DataVox-Voice");
|
||||||
|
sound_set_voice(8,"DataVox-Voice");
|
||||||
|
|
||||||
// Set initial display mode
|
// Set initial display mode
|
||||||
display_mode(DISPLAY_MODE);
|
display_mode(DISPLAY_MODE);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ void intro()
|
|||||||
{
|
{
|
||||||
int currentstart = 0;
|
int currentstart = 0;
|
||||||
int introframe = 0;
|
int introframe = 0;
|
||||||
sound_voices(4);
|
|
||||||
|
|
||||||
sound_set_voice(1,"WaveSynth-Beep");
|
sound_set_voice(1,"WaveSynth-Beep");
|
||||||
sound_set_voice(2,"WaveSynth-Beep");
|
sound_set_voice(2,"WaveSynth-Beep");
|
||||||
|
|||||||
+17
-40
@@ -22,6 +22,8 @@ char *sprites[] = {"player_ship","durno_ship","ship_trgt","durno_ship2","ship2_t
|
|||||||
|
|
||||||
char hudbuffer[63];
|
char hudbuffer[63];
|
||||||
|
|
||||||
|
unsigned char lastnpcchannel = PCMCHANNEL_NPC1;
|
||||||
|
|
||||||
struct EntityLocation_s {
|
struct EntityLocation_s {
|
||||||
short signed int X,Y;
|
short signed int X,Y;
|
||||||
};
|
};
|
||||||
@@ -146,12 +148,14 @@ void game_spawn_projectile(int id, int Px, int Py, int Vx, int Vy, enum sprite_e
|
|||||||
Projectiles[id].nextframe = tick + 10;
|
Projectiles[id].nextframe = tick + 10;
|
||||||
Projectiles[id].damage = damage;
|
Projectiles[id].damage = damage;
|
||||||
Projectiles[id].collidable = 1;
|
Projectiles[id].collidable = 1;
|
||||||
// Play it
|
|
||||||
inreg.r[0] = 4;
|
// Alternate between channels
|
||||||
inreg.r[1] = -15;
|
if(lastnpcchannel == PCMCHANNEL_NPC1)
|
||||||
inreg.r[2] = 1;
|
lastnpcchannel = PCMCHANNEL_NPC2;
|
||||||
inreg.r[3] = 1;
|
else
|
||||||
_kernel_swi (Sound_Control, &inreg, &outreg);
|
lastnpcchannel = PCMCHANNEL_NPC1;
|
||||||
|
|
||||||
|
sound_pcm_playsample(lastnpcchannel,PCMSAMPLE_DURNOTORPEDO);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -195,6 +199,7 @@ void game_draw_player()
|
|||||||
NPCS[Player.targetleft].location.X + ((NPCS[Player.targetleft].hitbox_bl.X + NPCS[Player.targetleft].hitbox_tr.X)/2) - 1,
|
NPCS[Player.targetleft].location.X + ((NPCS[Player.targetleft].hitbox_bl.X + NPCS[Player.targetleft].hitbox_tr.X)/2) - 1,
|
||||||
NPCS[Player.targetleft].location.Y + NPCS[Player.targetleft].hitbox_bl.Y
|
NPCS[Player.targetleft].location.Y + NPCS[Player.targetleft].hitbox_bl.Y
|
||||||
);
|
);
|
||||||
|
sound_pcm_playsample_ifidle(PCMCHANNEL_PLAYER,PCMSAMPLE_PHASER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((Player.firingright) && (Player.targetright >= 0))
|
if((Player.firingright) && (Player.targetright >= 0))
|
||||||
@@ -219,6 +224,7 @@ void game_draw_player()
|
|||||||
NPCS[Player.targetright].location.X + ((NPCS[Player.targetright].hitbox_bl.X + NPCS[Player.targetright].hitbox_tr.X)/2) - 1,
|
NPCS[Player.targetright].location.X + ((NPCS[Player.targetright].hitbox_bl.X + NPCS[Player.targetright].hitbox_tr.X)/2) - 1,
|
||||||
NPCS[Player.targetright].location.Y + NPCS[Player.targetright].hitbox_bl.Y
|
NPCS[Player.targetright].location.Y + NPCS[Player.targetright].hitbox_bl.Y
|
||||||
);
|
);
|
||||||
|
sound_pcm_playsample_ifidle(PCMCHANNEL_PLAYER,PCMSAMPLE_PHASER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debugs[dbweapons])
|
if(debugs[dbweapons])
|
||||||
@@ -502,9 +508,7 @@ void game_tick_npcs()
|
|||||||
NPCS[i].collidable = 0;
|
NPCS[i].collidable = 0;
|
||||||
NPCS[i].sprite = explode_start;
|
NPCS[i].sprite = explode_start;
|
||||||
NPCS[i].explodenextframe = tick + 4;
|
NPCS[i].explodenextframe = tick + 4;
|
||||||
sound_play(1,-5,0,100);
|
sound_pcm_playsample(PCMCHANNEL_AMBIENT,PCMSAMPLE_SHIPEXPLODE);
|
||||||
sound_play(3,-15,0,1000);
|
|
||||||
sound_play(2,-10,1,100);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -792,38 +796,14 @@ void game_tick_input()
|
|||||||
|
|
||||||
void game_setup_audio()
|
void game_setup_audio()
|
||||||
{
|
{
|
||||||
sound_voices(4);
|
|
||||||
|
|
||||||
sound_set_voice(1,"WaveSynth-Beep");
|
sound_set_voice(1,"WaveSynth-Beep");
|
||||||
sound_set_voice(2,"Percussion-Noise");
|
sound_set_voice(2,"Percussion-Noise");
|
||||||
sound_set_voice(3,"Percussion-Soft");
|
sound_set_voice(3,"Percussion-Soft");
|
||||||
sound_set_voice(4,"DataVox-Voice");
|
|
||||||
sound_pcm_loadsample("sounds.torpedo");
|
|
||||||
|
|
||||||
|
|
||||||
inreg.r[0] = 4;
|
|
||||||
inreg.r[1] = (int) audiobuffer;
|
|
||||||
inreg.r[2] = (int) audiobuffer + 20000;
|
|
||||||
_kernel_swi (DataVox_SetMemory, &inreg, &outreg);
|
|
||||||
|
|
||||||
// Unsigned 8-bit PCM
|
|
||||||
inreg.r[0] = 4;
|
|
||||||
inreg.r[1] = 1;
|
|
||||||
_kernel_swi (DataVox_Type, &inreg, &outreg);
|
|
||||||
|
|
||||||
// Not timed
|
|
||||||
inreg.r[0] = 4;
|
|
||||||
inreg.r[1] = 0;
|
|
||||||
_kernel_swi (DataVox_Timed, &inreg, &outreg);
|
|
||||||
|
|
||||||
// Bitrate
|
|
||||||
inreg.r[0] = 4;
|
|
||||||
inreg.r[1] = 4000; // I was expecting this to be 125 to 8KHz but.... No idea
|
|
||||||
_kernel_swi (DataVox_Pitch, &inreg, &outreg);
|
|
||||||
|
|
||||||
|
|
||||||
|
sound_pcm_loadsample(PCMSAMPLE_DURNOTORPEDO,"sounds.torpedo");
|
||||||
|
sound_pcm_loadsample(PCMSAMPLE_PHASER,"sounds.phaser");
|
||||||
|
sound_pcm_loadsample(PCMSAMPLE_SHIPEXPLODE,"sounds.shpexp");
|
||||||
}
|
}
|
||||||
|
|
||||||
void game_draw_hud()
|
void game_draw_hud()
|
||||||
{
|
{
|
||||||
draw_sprite("lcars",4,DISPLAY_Y-164);
|
draw_sprite("lcars",4,DISPLAY_Y-164);
|
||||||
@@ -873,7 +853,6 @@ void game1_death()
|
|||||||
{
|
{
|
||||||
int currentstart = 0;
|
int currentstart = 0;
|
||||||
int introframe = 0;
|
int introframe = 0;
|
||||||
sound_voices(4);
|
|
||||||
|
|
||||||
sound_set_voice(1,"WaveSynth-Beep");
|
sound_set_voice(1,"WaveSynth-Beep");
|
||||||
sound_set_voice(2,"WaveSynth-Beep");
|
sound_set_voice(2,"WaveSynth-Beep");
|
||||||
@@ -926,9 +905,7 @@ void game_tick_npcs_scatter()
|
|||||||
NPCS[i].collidable = 0;
|
NPCS[i].collidable = 0;
|
||||||
NPCS[i].sprite = explode_start;
|
NPCS[i].sprite = explode_start;
|
||||||
NPCS[i].explodenextframe = tick + 4;
|
NPCS[i].explodenextframe = tick + 4;
|
||||||
sound_play(1,-5,0,100);
|
sound_pcm_playsample_ifidle(PCMCHANNEL_AMBIENT,PCMSAMPLE_SHIPEXPLODE);
|
||||||
sound_play(3,-15,0,1000);
|
|
||||||
sound_play(2,-10,1,100);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,8 +165,6 @@ void game2_death()
|
|||||||
int currentstart = 0;
|
int currentstart = 0;
|
||||||
int introframe = 0;
|
int introframe = 0;
|
||||||
|
|
||||||
sound_voices(4);
|
|
||||||
|
|
||||||
sound_set_voice(1,"WaveSynth-Beep");
|
sound_set_voice(1,"WaveSynth-Beep");
|
||||||
sound_set_voice(2,"WaveSynth-Beep");
|
sound_set_voice(2,"WaveSynth-Beep");
|
||||||
sound_set_voice(3,"WaveSynth-Beep");
|
sound_set_voice(3,"WaveSynth-Beep");
|
||||||
|
|||||||
+56
-13
@@ -13,7 +13,7 @@ int composition_startcent = -1;
|
|||||||
|
|
||||||
struct CompositionElement composition[COMPOSITION_MAX];
|
struct CompositionElement composition[COMPOSITION_MAX];
|
||||||
|
|
||||||
unsigned char audiobuffer[20000];
|
struct pcmsample_s pcmsamples[PCMSAMPLE_MAX];
|
||||||
|
|
||||||
char *notes[] = {"AX","A#","BX","CX","C#","DX","D#","EX","FX","F#","GX","G#"};
|
char *notes[] = {"AX","A#","BX","CX","C#","DX","D#","EX","FX","F#","GX","G#"};
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ void sound_composition_load(char* filename)
|
|||||||
int length;
|
int length;
|
||||||
|
|
||||||
// Attempt to get file info
|
// Attempt to get file info
|
||||||
inreg.r[0] = 13;
|
inreg.r[0] = 5;
|
||||||
inreg.r[1] = (int) filename;
|
inreg.r[1] = (int) filename;
|
||||||
_kernel_swi(OS_File,&inreg,&outreg);
|
_kernel_swi(OS_File,&inreg,&outreg);
|
||||||
|
|
||||||
@@ -38,8 +38,8 @@ void sound_composition_load(char* filename)
|
|||||||
if(length > sizeof(composition))
|
if(length > sizeof(composition))
|
||||||
{
|
{
|
||||||
screen_nobuffer();
|
screen_nobuffer();
|
||||||
printf("Composition exceeds %d bytes (%d bytes)",sizeof(composition),length);
|
while(1)
|
||||||
exit(0);
|
printf("Composition exceeds %d bytes (%d bytes)\n",sizeof(composition),length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to get file info
|
// Attempt to get file info
|
||||||
@@ -198,12 +198,55 @@ int sound_composition_incomplete()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sound_pcm_loadsample(char* filename)
|
void sound_pcm_unset(enum pcmchannel_e channel)
|
||||||
|
{
|
||||||
|
inreg.r[0] = channel;
|
||||||
|
inreg.r[1] = 0;
|
||||||
|
_kernel_swi (DataVox_Unset, &inreg, &outreg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_pcm_playsample(enum pcmchannel_e channel, enum pcmsample_e sample)
|
||||||
|
{
|
||||||
|
inreg.r[0] = channel;
|
||||||
|
inreg.r[1] = pcmsamples[sample].data;
|
||||||
|
inreg.r[2] = pcmsamples[sample].data + pcmsamples[sample].length;
|
||||||
|
_kernel_swi (DataVox_SetMemory, &inreg, &outreg);
|
||||||
|
|
||||||
|
// Unsigned 8-bit PCM
|
||||||
|
inreg.r[0] = channel;
|
||||||
|
inreg.r[1] = 1;
|
||||||
|
_kernel_swi (DataVox_Type, &inreg, &outreg);
|
||||||
|
|
||||||
|
// Not timed
|
||||||
|
inreg.r[0] = channel;
|
||||||
|
inreg.r[1] = 0;
|
||||||
|
_kernel_swi (DataVox_Timed, &inreg, &outreg);
|
||||||
|
|
||||||
|
// Bitrate
|
||||||
|
inreg.r[0] = channel;
|
||||||
|
inreg.r[1] = 4000; // I was expecting this to be 125 to 8KHz but.... No idea
|
||||||
|
_kernel_swi (DataVox_Pitch, &inreg, &outreg);
|
||||||
|
|
||||||
|
// Play it
|
||||||
|
inreg.r[0] = channel;
|
||||||
|
inreg.r[1] = -15;
|
||||||
|
inreg.r[2] = 1;
|
||||||
|
inreg.r[3] = 1;
|
||||||
|
_kernel_swi (Sound_Control, &inreg, &outreg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_pcm_playsample_ifidle(enum pcmchannel_e channel, enum pcmsample_e sample)
|
||||||
|
{
|
||||||
|
inreg.r[0] = channel;
|
||||||
|
_kernel_swi (DataVox_ReadAddress, &inreg, &outreg);
|
||||||
|
if(!outreg.r[1])
|
||||||
|
sound_pcm_playsample(channel, sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_pcm_loadsample(enum pcmsample_e sample, char* filename)
|
||||||
{
|
{
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
memset(audiobuffer,0x00,20000);
|
|
||||||
|
|
||||||
// Attempt to get file info
|
// Attempt to get file info
|
||||||
inreg.r[0] = 5;
|
inreg.r[0] = 5;
|
||||||
inreg.r[1] = (int) filename;
|
inreg.r[1] = (int) filename;
|
||||||
@@ -212,21 +255,21 @@ void sound_pcm_loadsample(char* filename)
|
|||||||
// Length will be in R4 if it exists
|
// Length will be in R4 if it exists
|
||||||
length = outreg.r[4];
|
length = outreg.r[4];
|
||||||
|
|
||||||
if(length > sizeof(audiobuffer))
|
if(length > 100000)
|
||||||
{
|
{
|
||||||
screen_nobuffer();
|
screen_nobuffer();
|
||||||
while (1)
|
while (1)
|
||||||
printf("Sample exceeds %d bytes (%d bytes) object type is %d\n",sizeof(audiobuffer),length,outreg.r[0]);
|
printf("Sample exceeds %d bytes (%d bytes) object type is %d\n",100000,length,outreg.r[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pcmsamples[sample].length = length;
|
||||||
|
pcmsamples[sample].data = malloc(length);
|
||||||
|
|
||||||
// Attempt to get file info
|
// Attempt to get file info
|
||||||
inreg.r[0] = 16;
|
inreg.r[0] = 16;
|
||||||
inreg.r[1] = (int) filename;
|
inreg.r[1] = (int) filename;
|
||||||
inreg.r[2] = (int) audiobuffer;
|
inreg.r[2] = (int) pcmsamples[sample].data;
|
||||||
inreg.r[3] = 0;
|
inreg.r[3] = 0;
|
||||||
|
|
||||||
_kernel_swi(OS_File,&inreg,&outreg);
|
_kernel_swi(OS_File,&inreg,&outreg);
|
||||||
|
|
||||||
// Fill remainder of array with final byte
|
|
||||||
memset(audiobuffer + length,audiobuffer[length-1],sizeof(audiobuffer)-length);
|
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-1
@@ -37,6 +37,15 @@
|
|||||||
#define DataVox_AdjustMemory 0x443A2
|
#define DataVox_AdjustMemory 0x443A2
|
||||||
#define DataVox_SetInternalPitch 0x443A3
|
#define DataVox_SetInternalPitch 0x443A3
|
||||||
|
|
||||||
|
enum pcmchannel_e{
|
||||||
|
PCMCHANNEL_UI = 5,
|
||||||
|
PCMCHANNEL_PLAYER = 5,
|
||||||
|
PCMCHANNEL_NPC1 = 6,
|
||||||
|
PCMCHANNEL_NPC2 = 7,
|
||||||
|
PCMCHANNEL_AMBIENT = 8
|
||||||
|
};
|
||||||
|
enum pcmsample_e{PCMSAMPLE_DURNOTORPEDO, PCMSAMPLE_PHASER, PCMSAMPLE_SHIPEXPLODE, PCMSAMPLE_MAX};
|
||||||
|
|
||||||
struct CompositionElement {
|
struct CompositionElement {
|
||||||
signed short int Start;
|
signed short int Start;
|
||||||
unsigned char Note;
|
unsigned char Note;
|
||||||
@@ -46,4 +55,9 @@ struct CompositionElement {
|
|||||||
unsigned short int Length;
|
unsigned short int Length;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern unsigned char audiobuffer[20000];
|
struct pcmsample_s {
|
||||||
|
int data;
|
||||||
|
unsigned int length;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct pcmsample_s pcmsamples[PCMSAMPLE_MAX];
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user