Removed old iOS-only project and demos
This commit is contained in:
parent
3a3aaac221
commit
dc60b975f3
48 changed files with 0 additions and 12068 deletions
|
@ -1,344 +0,0 @@
|
|||
/*
|
||||
* mixer.c
|
||||
* written by Holmes Futrell
|
||||
* use however you want
|
||||
*/
|
||||
|
||||
#include "SDL.h"
|
||||
#include "common.h"
|
||||
|
||||
#define NUM_CHANNELS 8 /* max number of sounds we can play at once */
|
||||
#define NUM_DRUMS 4 /* number of drums in our set */
|
||||
|
||||
static struct
|
||||
{
|
||||
SDL_Rect rect; /* where the button is drawn */
|
||||
SDL_Color upColor; /* color when button is not active */
|
||||
SDL_Color downColor; /* color when button is active */
|
||||
int isPressed; /* is the button being pressed ? */
|
||||
int touchIndex; /* what mouse (touch) index pressed the button ? */
|
||||
} buttons[NUM_DRUMS];
|
||||
|
||||
struct sound
|
||||
{
|
||||
Uint8 *buffer; /* audio buffer for sound file */
|
||||
Uint32 length; /* length of the buffer (in bytes) */
|
||||
};
|
||||
|
||||
/* this array holds the audio for the drum noises */
|
||||
static struct sound drums[NUM_DRUMS];
|
||||
|
||||
/* function declarations */
|
||||
void handleMouseButtonDown(SDL_Event * event);
|
||||
void handleMouseButtonUp(SDL_Event * event);
|
||||
int playSound(struct sound *);
|
||||
void initializeButtons(SDL_Renderer *);
|
||||
void audioCallback(void *userdata, Uint8 * stream, int len);
|
||||
void loadSound(const char *file, struct sound *s);
|
||||
|
||||
struct
|
||||
{
|
||||
/* channel array holds information about currently playing sounds */
|
||||
struct
|
||||
{
|
||||
Uint8 *position; /* what is the current position in the buffer of this sound ? */
|
||||
Uint32 remaining; /* how many bytes remaining before we're done playing the sound ? */
|
||||
Uint32 timestamp; /* when did this sound start playing ? */
|
||||
} channels[NUM_CHANNELS];
|
||||
SDL_AudioSpec outputSpec; /* what audio format are we using for output? */
|
||||
int numSoundsPlaying; /* how many sounds are currently playing */
|
||||
} mixer;
|
||||
|
||||
/* sets up the buttons (color, position, state) */
|
||||
void
|
||||
initializeButtons(SDL_Renderer *renderer)
|
||||
{
|
||||
int i;
|
||||
int spacing = 10; /* gap between drum buttons */
|
||||
SDL_Rect buttonRect; /* keeps track of where to position drum */
|
||||
SDL_Color upColor = { 86, 86, 140, 255 }; /* color of drum when not pressed */
|
||||
SDL_Color downColor = { 191, 191, 221, 255 }; /* color of drum when pressed */
|
||||
int renderW, renderH;
|
||||
|
||||
SDL_RenderGetLogicalSize(renderer, &renderW, &renderH);
|
||||
|
||||
buttonRect.x = spacing;
|
||||
buttonRect.y = spacing;
|
||||
buttonRect.w = renderW - 2 * spacing;
|
||||
buttonRect.h = (renderH - (NUM_DRUMS + 1) * spacing) / NUM_DRUMS;
|
||||
|
||||
/* setup each button */
|
||||
for (i = 0; i < NUM_DRUMS; i++) {
|
||||
|
||||
buttons[i].rect = buttonRect;
|
||||
buttons[i].isPressed = 0;
|
||||
buttons[i].upColor = upColor;
|
||||
buttons[i].downColor = downColor;
|
||||
|
||||
buttonRect.y += spacing + buttonRect.h; /* setup y coordinate for next drum */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
loads a wav file (stored in 'file'), converts it to the mixer's output format,
|
||||
and stores the resulting buffer and length in the sound structure
|
||||
*/
|
||||
void
|
||||
loadSound(const char *file, struct sound *s)
|
||||
{
|
||||
SDL_AudioSpec spec; /* the audio format of the .wav file */
|
||||
SDL_AudioCVT cvt; /* used to convert .wav to output format when formats differ */
|
||||
int result;
|
||||
if (SDL_LoadWAV(file, &spec, &s->buffer, &s->length) == NULL) {
|
||||
fatalError("could not load .wav");
|
||||
}
|
||||
/* build the audio converter */
|
||||
result = SDL_BuildAudioCVT(&cvt, spec.format, spec.channels, spec.freq,
|
||||
mixer.outputSpec.format,
|
||||
mixer.outputSpec.channels,
|
||||
mixer.outputSpec.freq);
|
||||
if (result == -1) {
|
||||
fatalError("could not build audio CVT");
|
||||
} else if (result != 0) {
|
||||
/*
|
||||
this happens when the .wav format differs from the output format.
|
||||
we convert the .wav buffer here
|
||||
*/
|
||||
cvt.buf = (Uint8 *) SDL_malloc(s->length * cvt.len_mult); /* allocate conversion buffer */
|
||||
cvt.len = s->length; /* set conversion buffer length */
|
||||
SDL_memcpy(cvt.buf, s->buffer, s->length); /* copy sound to conversion buffer */
|
||||
if (SDL_ConvertAudio(&cvt) == -1) { /* convert the sound */
|
||||
fatalError("could not convert .wav");
|
||||
}
|
||||
SDL_free(s->buffer); /* free the original (unconverted) buffer */
|
||||
s->buffer = cvt.buf; /* point sound buffer to converted buffer */
|
||||
s->length = cvt.len_cvt; /* set sound buffer's new length */
|
||||
}
|
||||
}
|
||||
|
||||
/* called from main event loop */
|
||||
void
|
||||
handleMouseButtonDown(SDL_Event * event)
|
||||
{
|
||||
|
||||
int x, y, mouseIndex, i, drumIndex;
|
||||
|
||||
mouseIndex = 0;
|
||||
drumIndex = -1;
|
||||
|
||||
SDL_GetMouseState(&x, &y);
|
||||
/* check if we hit any of the drum buttons */
|
||||
for (i = 0; i < NUM_DRUMS; i++) {
|
||||
if (x >= buttons[i].rect.x
|
||||
&& x < buttons[i].rect.x + buttons[i].rect.w
|
||||
&& y >= buttons[i].rect.y
|
||||
&& y < buttons[i].rect.y + buttons[i].rect.h) {
|
||||
drumIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (drumIndex != -1) {
|
||||
/* if we hit a button */
|
||||
buttons[drumIndex].touchIndex = mouseIndex;
|
||||
buttons[drumIndex].isPressed = 1;
|
||||
playSound(&drums[drumIndex]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* called from main event loop */
|
||||
void
|
||||
handleMouseButtonUp(SDL_Event * event)
|
||||
{
|
||||
int i;
|
||||
int mouseIndex = 0;
|
||||
/* check if this should cause any of the buttons to become unpressed */
|
||||
for (i = 0; i < NUM_DRUMS; i++) {
|
||||
if (buttons[i].touchIndex == mouseIndex) {
|
||||
buttons[i].isPressed = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* draws buttons to screen */
|
||||
void
|
||||
render(SDL_Renderer *renderer)
|
||||
{
|
||||
int i;
|
||||
SDL_SetRenderDrawColor(renderer, 50, 50, 50, 255);
|
||||
SDL_RenderClear(renderer); /* draw background (gray) */
|
||||
/* draw the drum buttons */
|
||||
for (i = 0; i < NUM_DRUMS; i++) {
|
||||
SDL_Color color =
|
||||
buttons[i].isPressed ? buttons[i].downColor : buttons[i].upColor;
|
||||
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
|
||||
SDL_RenderFillRect(renderer, &buttons[i].rect);
|
||||
}
|
||||
/* update the screen */
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
/*
|
||||
finds a sound channel in the mixer for a sound
|
||||
and sets it up to start playing
|
||||
*/
|
||||
int
|
||||
playSound(struct sound *s)
|
||||
{
|
||||
/*
|
||||
find an empty channel to play on.
|
||||
if no channel is available, use oldest channel
|
||||
*/
|
||||
int i;
|
||||
int selected_channel = -1;
|
||||
int oldest_channel = 0;
|
||||
|
||||
if (mixer.numSoundsPlaying == 0) {
|
||||
/* we're playing a sound now, so start audio callback back up */
|
||||
SDL_PauseAudio(0);
|
||||
}
|
||||
|
||||
/* find a sound channel to play the sound on */
|
||||
for (i = 0; i < NUM_CHANNELS; i++) {
|
||||
if (mixer.channels[i].position == NULL) {
|
||||
/* if no sound on this channel, select it */
|
||||
selected_channel = i;
|
||||
break;
|
||||
}
|
||||
/* if this channel's sound is older than the oldest so far, set it to oldest */
|
||||
if (mixer.channels[i].timestamp <
|
||||
mixer.channels[oldest_channel].timestamp)
|
||||
oldest_channel = i;
|
||||
}
|
||||
|
||||
/* no empty channels, take the oldest one */
|
||||
if (selected_channel == -1)
|
||||
selected_channel = oldest_channel;
|
||||
else
|
||||
mixer.numSoundsPlaying++;
|
||||
|
||||
/* point channel data to wav data */
|
||||
mixer.channels[selected_channel].position = s->buffer;
|
||||
mixer.channels[selected_channel].remaining = s->length;
|
||||
mixer.channels[selected_channel].timestamp = SDL_GetTicks();
|
||||
|
||||
return selected_channel;
|
||||
}
|
||||
|
||||
/*
|
||||
Called from SDL's audio system. Supplies sound input with data by mixing together all
|
||||
currently playing sound effects.
|
||||
*/
|
||||
void
|
||||
audioCallback(void *userdata, Uint8 * stream, int len)
|
||||
{
|
||||
int i;
|
||||
int copy_amt;
|
||||
SDL_memset(stream, mixer.outputSpec.silence, len); /* initialize buffer to silence */
|
||||
/* for each channel, mix in whatever is playing on that channel */
|
||||
for (i = 0; i < NUM_CHANNELS; i++) {
|
||||
if (mixer.channels[i].position == NULL) {
|
||||
/* if no sound is playing on this channel */
|
||||
continue; /* nothing to do for this channel */
|
||||
}
|
||||
|
||||
/* copy len bytes to the buffer, unless we have fewer than len bytes remaining */
|
||||
copy_amt =
|
||||
mixer.channels[i].remaining <
|
||||
len ? mixer.channels[i].remaining : len;
|
||||
|
||||
/* mix this sound effect with the output */
|
||||
SDL_MixAudioFormat(stream, mixer.channels[i].position,
|
||||
mixer.outputSpec.format, copy_amt, SDL_MIX_MAXVOLUME);
|
||||
|
||||
/* update buffer position in sound effect and the number of bytes left */
|
||||
mixer.channels[i].position += copy_amt;
|
||||
mixer.channels[i].remaining -= copy_amt;
|
||||
|
||||
/* did we finish playing the sound effect ? */
|
||||
if (mixer.channels[i].remaining == 0) {
|
||||
mixer.channels[i].position = NULL; /* indicates no sound playing on channel anymore */
|
||||
mixer.numSoundsPlaying--;
|
||||
if (mixer.numSoundsPlaying == 0) {
|
||||
/* if no sounds left playing, pause audio callback */
|
||||
SDL_PauseAudio(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int done; /* has user tried to quit ? */
|
||||
SDL_Window *window; /* main window */
|
||||
SDL_Renderer *renderer;
|
||||
SDL_Event event;
|
||||
int i;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
|
||||
fatalError("could not initialize SDL");
|
||||
}
|
||||
window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
renderer = SDL_CreateRenderer(window, 0, 0);
|
||||
|
||||
SDL_GetWindowSize(window, &width, &height);
|
||||
SDL_RenderSetLogicalSize(renderer, width, height);
|
||||
|
||||
/* initialize the mixer */
|
||||
SDL_memset(&mixer, 0, sizeof(mixer));
|
||||
/* setup output format */
|
||||
mixer.outputSpec.freq = 44100;
|
||||
mixer.outputSpec.format = AUDIO_S16LSB;
|
||||
mixer.outputSpec.channels = 2;
|
||||
mixer.outputSpec.samples = 256;
|
||||
mixer.outputSpec.callback = audioCallback;
|
||||
mixer.outputSpec.userdata = NULL;
|
||||
|
||||
/* open audio for output */
|
||||
if (SDL_OpenAudio(&mixer.outputSpec, NULL) != 0) {
|
||||
fatalError("Opening audio failed");
|
||||
}
|
||||
|
||||
/* load our drum noises */
|
||||
loadSound("ds_kick_big_amb.wav", &drums[3]);
|
||||
loadSound("ds_brush_snare.wav", &drums[2]);
|
||||
loadSound("ds_loose_skin_mute.wav", &drums[1]);
|
||||
loadSound("ds_china.wav", &drums[0]);
|
||||
|
||||
/* setup positions, colors, and state of buttons */
|
||||
initializeButtons(renderer);
|
||||
|
||||
/* enter main loop */
|
||||
done = 0;
|
||||
while (!done) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
handleMouseButtonDown(&event);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
handleMouseButtonUp(&event);
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
render(renderer); /* draw buttons */
|
||||
|
||||
SDL_Delay(1);
|
||||
}
|
||||
|
||||
/* cleanup code, let's free up those sound buffers */
|
||||
for (i = 0; i < NUM_DRUMS; i++) {
|
||||
SDL_free(drums[i].buffer);
|
||||
}
|
||||
/* let SDL do its exit code */
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue