In theory, we have an SDL 1.2 backend. No toolchain to test it with yet.
This commit is contained in:
parent
a67e998c28
commit
f10172d5bb
5 changed files with 706 additions and 106 deletions
|
@ -1,6 +1,7 @@
|
|||
JOEY = /home/scott/joey
|
||||
#CONFIG += SDL12
|
||||
CONFIG += SDL2
|
||||
CONFIG += SDL12
|
||||
#CONFIG += SDL2
|
||||
#CONFIG += OURLIBS
|
||||
|
||||
#BREW = /home/linuxbrew/.linuxbrew
|
||||
|
||||
|
@ -10,6 +11,7 @@ CONFIG -= \
|
|||
app_bundle \
|
||||
qt
|
||||
|
||||
# Determine which libraries to link against.
|
||||
defined(BREW,var) {
|
||||
# Use Homebrew libraries.
|
||||
STATICLIB = $$BREW/lib
|
||||
|
@ -18,12 +20,19 @@ defined(BREW,var) {
|
|||
-L$$STATICLIB \
|
||||
-Wl,-rpath,$$STATICLIB
|
||||
} else {
|
||||
# Use our libraries.
|
||||
#STATICLIB = $$JOEY/sdks/linux/x64/lib
|
||||
#INCLUDEPATH += $$JOEY/sdks/linux/x64/include
|
||||
#LIBS += \
|
||||
# -L$$STATICLIB \
|
||||
# -Wl,-rpath,$$STATICLIB
|
||||
OURLIBS {
|
||||
# Use our libraries.
|
||||
STATICLIB = $$JOEY/sdks/linux/x64/lib
|
||||
INCLUDEPATH += $$JOEY/sdks/linux/x64/include
|
||||
LIBS += \
|
||||
-L$$STATICLIB \
|
||||
-Wl,-rpath,$$STATICLIB
|
||||
} else {
|
||||
# System libraries.
|
||||
STATICLIB = /usr/lib/x86_64-linux-gnu
|
||||
LIBS += \
|
||||
-Wl,-rpath,$$STATICLIB
|
||||
}
|
||||
}
|
||||
|
||||
INCLUDEPATH += $$PWD/src
|
||||
|
@ -65,9 +74,8 @@ SDL2 {
|
|||
|
||||
LIBS += \
|
||||
-Wl,--enable-new-dtags \
|
||||
-lSDL2
|
||||
# $$STATICLIB/libSDL2.a \
|
||||
# -lm -ldl -lX11 -lXext -lXcursor -lXi -lXfixes -lXrandr -lXss -lpthread -lrt
|
||||
$$STATICLIB/libSDL2.a \
|
||||
-lm -lasound -lm -ldl -lpthread -lpulse-simple -pthread -lpulse -pthread -lX11 -lXext -lXcursor -lXinerama -lXi -lXfixes -lXrandr -lXss -lXxf86vm -ldrm -lgbm -lwayland-egl -lwayland-client -lwayland-cursor -lxkbcommon -ldecor-0 -lpthread -lrt
|
||||
}
|
||||
|
||||
OTHER_FILES += \
|
||||
|
|
2
joeylib/src/3rdparty/pocketmod/pocketmod.h
vendored
2
joeylib/src/3rdparty/pocketmod/pocketmod.h
vendored
|
@ -87,7 +87,7 @@ struct pocketmod_context
|
|||
float sample; /* Current sample in tick */
|
||||
};
|
||||
|
||||
#ifndef POCKETMOD_IMPLEMENTATIONx
|
||||
#ifdef POCKETMOD_IMPLEMENTATION
|
||||
|
||||
/* Memorize a parameter unless the new value is zero */
|
||||
#define POCKETMOD_MEM(dst, src) do { \
|
||||
|
|
|
@ -19,155 +19,747 @@
|
|||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "SDL/SDL.h"
|
||||
#include "SDL/SDL_mixer.h"
|
||||
|
||||
#define POCKETMOD_IMPLEMENTATION
|
||||
#include "3rdparty/pocketmod/pocketmod.h"
|
||||
|
||||
#include "joey.h"
|
||||
#include "jPixBuf.h"
|
||||
|
||||
|
||||
static SDL_Surface *_jlScreen = NULL;
|
||||
#define AUDIO_FORMAT AUDIO_S16
|
||||
#define AUDIO_FREQUENCY 44100
|
||||
#define AUDIO_CHANNELS 2
|
||||
|
||||
#define BORDER_WIDTH 20
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t *data;
|
||||
uint32_t len;
|
||||
} jlPlatformSoundT;
|
||||
|
||||
typedef struct jlSoundPlayingS {
|
||||
jlPlatformSoundT *sound;
|
||||
jlSoundChannelE channel; // Corresponds to IIgs 4soniq channel definitions.
|
||||
jbyte volume; // 0 = silent, 255 = loud.
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
struct jlSoundPlayingS *next;
|
||||
} jlSoundPlayingT;
|
||||
|
||||
typedef struct {
|
||||
char *data;
|
||||
size_t size;
|
||||
} jlPlatformModT;
|
||||
|
||||
|
||||
static jbyte _jlBorderRGBs[16][3] = {
|
||||
{ 0x00, 0x00, 0x00 }, // Black
|
||||
{ 0xdd, 0x00, 0x33 }, // Deep Red
|
||||
{ 0x00, 0x00, 0x99 }, // Deep Blue
|
||||
{ 0xdd, 0x22, 0xdd }, // Purple
|
||||
{ 0x00, 0x77, 0x22 }, // Dark Green
|
||||
{ 0x55, 0x55, 0x55 }, // Dark Gray
|
||||
{ 0x22, 0x22, 0xff }, // Medium Blue
|
||||
{ 0x66, 0xaa, 0xff }, // Light Blue
|
||||
{ 0x88, 0x55, 0x00 }, // Brown
|
||||
{ 0xff, 0x66, 0x00 }, // Orange
|
||||
{ 0xaa, 0xaa, 0xaa }, // Light Gray
|
||||
{ 0xff, 0x99, 0x88 }, // Pink
|
||||
{ 0x11, 0xdd, 0x00 }, // Green
|
||||
{ 0xff, 0xff, 0x00 }, // Yellow
|
||||
{ 0x44, 0xff, 0x99 }, // Acquamarine
|
||||
{ 0xff, 0xff, 0xff } // White
|
||||
};
|
||||
|
||||
static SDL_Surface *_jlWindow = NULL;
|
||||
static SDL_Surface *_jlTexture = NULL;
|
||||
static jbool _jlIsRunning = jtrue;
|
||||
static jint16 _jlNumKeysDown = 0;
|
||||
static char _jlLastKey = 0;
|
||||
static SDL_Joystick **_jlControllers = NULL;
|
||||
static jint16 _jlControllerCount = 0;
|
||||
static juint16 _jlTimerValue = 0;
|
||||
static SDL_TimerID _jlTimerId = 0;
|
||||
static pocketmod_context _jlModContext;
|
||||
static SDL_AudioSpec _jlAudioFormat;
|
||||
static jbool _jlModPlaying = jfalse;
|
||||
static jlPlatformModT *_jlModCurrent = NULL;
|
||||
static jbyte _jlModVolume = 255;
|
||||
static jlSoundPlayingT *_jlSoundList = NULL;
|
||||
static jint16 _jlWindowZoom = 2;
|
||||
|
||||
|
||||
static Uint32 _jlUtilTimer(Uint32 interval, void *param);
|
||||
static void _jlAudioCallback(void *userdata, Uint8 *buffer, int bytes);
|
||||
|
||||
|
||||
extern jbool _jlSwapChannels;
|
||||
|
||||
|
||||
/*
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
Uint32 _jlGetPixel(SDL_Surface *surface, int x, int y) {
|
||||
|
||||
int bpp = surface->format->BytesPerPixel;
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
|
||||
|
||||
switch(bpp) {
|
||||
case 1:
|
||||
return *p;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// Generates cast increases required alignment of target type [-Wcast-align] warning. Harmless on x86.
|
||||
return *(Uint16 *)p;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||
return (Uint32)(p[0] << 16 | p[1] << 8 | p[2]);
|
||||
else
|
||||
return (Uint32)(p[0] | p[1] << 8 | p[2] << 16);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// Generates cast increases required alignment of target type [-Wcast-align] warning. Harmless on x86.
|
||||
return *(Uint32 *)p;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _jlPutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel) {
|
||||
|
||||
int bpp = surface->format->BytesPerPixel;
|
||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
|
||||
|
||||
switch(bpp) {
|
||||
case 1:
|
||||
*p = (Uint8)pixel;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*(Uint16 *)p = (Uint16)pixel;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
|
||||
p[0] = (pixel >> 16) & 0xff;
|
||||
p[1] = (pixel >> 8) & 0xff;
|
||||
p[2] = pixel & 0xff;
|
||||
} else {
|
||||
p[0] = pixel & 0xff;
|
||||
p[1] = (pixel >> 8) & 0xff;
|
||||
p[2] = (pixel >> 16) & 0xff;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
*(Uint32 *)p = pixel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
*/
|
||||
|
||||
|
||||
static void _jlAudioCallback(void *userdata, Uint8 *buffer, int bytes) {
|
||||
int i = 0;
|
||||
jlSoundPlayingT *sound = NULL;
|
||||
jlSoundPlayingT *prev = NULL;
|
||||
jlSoundPlayingT *temp = NULL;
|
||||
uint32_t length = 0;
|
||||
int16_t *data = NULL;
|
||||
int16_t *out = NULL;
|
||||
float adjust = 1;
|
||||
float mod[2];
|
||||
int32_t work = 0;
|
||||
jbool isRight = jfalse;
|
||||
|
||||
|
||||
(void)userdata;
|
||||
|
||||
// Silence buffer.
|
||||
memset(buffer, 0, bytes);
|
||||
|
||||
// Load in music.
|
||||
if (_jlModPlaying) {
|
||||
// Adjust volume. Convert to S16 by multiplying rendered values by 32767.
|
||||
adjust = ((100.0 / 255.0) * (float)_jlModVolume) * 0.01 * 32767;
|
||||
out = (int16_t *)buffer;
|
||||
while (i < bytes) {
|
||||
i += pocketmod_render(&_jlModContext, mod, sizeof(float[2]));
|
||||
out[i] *= adjust;
|
||||
out[i + 1] *= adjust;
|
||||
}
|
||||
}
|
||||
|
||||
// Mix in sounds.
|
||||
// Just adding samples together seems fine for floating point data.
|
||||
// For integers, we need to clamp.
|
||||
if (_jlSoundList) {
|
||||
sound = _jlSoundList;
|
||||
while (sound) {
|
||||
// Find length of data to mix.
|
||||
length = ((uint32_t)bytes > sound->len) ? sound->len : (uint32_t)bytes;
|
||||
// Adjust volume.
|
||||
adjust = ((100.0 / 255.0) * (float)sound->volume) * 0.01;
|
||||
// Point at sample data.
|
||||
data = (int16_t *)sound->buffer;
|
||||
out = (int16_t *)buffer;
|
||||
for (i=0; i<(int)(length / sizeof(int16_t)); i+=2) {
|
||||
// Combine channels into a mono sample.
|
||||
work = (data[i] + data[i + 1]) * 0.5;
|
||||
// Determine channel.
|
||||
isRight = (sound->channel & 0x01);
|
||||
if (_jlSwapChannels) isRight = !isRight;
|
||||
if (isRight) {
|
||||
// Place sound in the right channel.
|
||||
out[i + 1] += (work * adjust);
|
||||
} else {
|
||||
// Place sound in left channel.
|
||||
out[i] += (work * adjust);
|
||||
}
|
||||
}
|
||||
sound->buffer += length;
|
||||
sound->len -= length;
|
||||
// Are we done with this sound?
|
||||
if (sound->len == 0) {
|
||||
if (prev) {
|
||||
prev->next = sound->next;
|
||||
} else {
|
||||
_jlSoundList = sound->next;
|
||||
}
|
||||
temp = sound;
|
||||
sound = sound->next;
|
||||
jlFree(temp);
|
||||
} else {
|
||||
prev = sound;
|
||||
sound = sound->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void jlDisplayPresent(void) {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
Uint16 *pixels = NULL;
|
||||
SDL_Rect r;
|
||||
|
||||
jlUtilIdle();
|
||||
|
||||
// Render 4 bit copy to proper pixel format.
|
||||
// This extra step preserves palette effects.
|
||||
SDL_LockSurface(_jlTexture);
|
||||
pixels = (Uint16 *)_jlTexture->pixels;
|
||||
for (int y=0; y<200; y++) {
|
||||
for (int x=0; x<160; x++) {
|
||||
// We decode this R/L instead of L/R for some reason. NO idea why yet. Endians?
|
||||
pixels[i++] = SDL_MapRGBA(_jlTexture->format,
|
||||
_jlBackingStore->palette[_jlBackingStore->pixels[j].r].r * 16,
|
||||
_jlBackingStore->palette[_jlBackingStore->pixels[j].r].g * 16,
|
||||
_jlBackingStore->palette[_jlBackingStore->pixels[j].r].b * 16,
|
||||
255);
|
||||
pixels[i++] = SDL_MapRGBA(_jlTexture->format,
|
||||
_jlBackingStore->palette[_jlBackingStore->pixels[j].l].r * 16,
|
||||
_jlBackingStore->palette[_jlBackingStore->pixels[j].l].g * 16,
|
||||
_jlBackingStore->palette[_jlBackingStore->pixels[j].l].b * 16,
|
||||
255);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
SDL_UnlockSurface(_jlTexture);
|
||||
|
||||
// Border.
|
||||
SDL_FillRect(_jlWindow, NULL, SDL_MapRGB(_jlWindow->format, _jlBorderRGBs[_jlBorderColor][0], _jlBorderRGBs[_jlBorderColor][1], _jlBorderRGBs[_jlBorderColor][2]));
|
||||
|
||||
// Display.
|
||||
r.x = _jlWindowZoom * BORDER_WIDTH;
|
||||
r.y = _jlWindowZoom * BORDER_WIDTH;
|
||||
r.w = 320 * _jlWindowZoom;
|
||||
r.h = 200 * _jlWindowZoom;
|
||||
SDL_BlitSurface(_jlTexture, NULL, _jlWindow, &r);
|
||||
SDL_Flip(_jlWindow);
|
||||
}
|
||||
|
||||
|
||||
jint16 jlGameGetAxis(byte which) {
|
||||
(void)which;
|
||||
jint16 jlGameGetAxis(jbyte which) {
|
||||
uint8_t axis;
|
||||
short int unscaled;
|
||||
short int max = SHRT_MIN;
|
||||
short int min = SHRT_MAX;
|
||||
int x;
|
||||
|
||||
return 0;
|
||||
jlUtilIdle();
|
||||
|
||||
if (which == 0) {
|
||||
axis = 0;
|
||||
} else {
|
||||
axis = 1;
|
||||
}
|
||||
|
||||
for (x=0; x<_jlControllerCount; x++) {
|
||||
unscaled = SDL_JoystickGetAxis(_jlControllers[x], axis);
|
||||
if (unscaled > 0) {
|
||||
if (unscaled > max) {
|
||||
max = unscaled;
|
||||
}
|
||||
} else {
|
||||
if (unscaled < min) {
|
||||
min = unscaled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (-min > max ? min : max) / 256;
|
||||
}
|
||||
|
||||
|
||||
bool jlGameGetButton(byte which) {
|
||||
(void)which;
|
||||
jbool jlGameGetButton(jbyte which) {
|
||||
uint8_t button;
|
||||
int x;
|
||||
jbool pressed = jfalse;
|
||||
|
||||
return false;
|
||||
jlUtilIdle();
|
||||
|
||||
if (which == 0) {
|
||||
button = 0;
|
||||
} else {
|
||||
button = 1;
|
||||
}
|
||||
|
||||
for (x=0; x<_jlControllerCount; x++) {
|
||||
if (SDL_JoystickGetButton(_jlControllers[x], button)) {
|
||||
pressed = jtrue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
||||
|
||||
bool jlKeyPressed(void) {
|
||||
return false;
|
||||
jbool jlKeyPressed(void) {
|
||||
jlUtilIdle();
|
||||
return (_jlNumKeysDown > 0);
|
||||
}
|
||||
|
||||
|
||||
char jlKeyRead(void) {
|
||||
return 0;
|
||||
jlUtilIdle();
|
||||
return _jlLastKey;
|
||||
}
|
||||
|
||||
|
||||
void jlModContinue(void) {
|
||||
if (_jlModCurrent) _jlModPlaying = jtrue;
|
||||
}
|
||||
|
||||
|
||||
void jlModFree(jlModT *mod) {
|
||||
jlPlatformModT *m = (jlPlatformModT *)mod;
|
||||
|
||||
// Is this the current mod?
|
||||
if (m == _jlModCurrent) {
|
||||
// Is it playing?
|
||||
if (_jlModPlaying) {
|
||||
// Lock and wait for current mod to stop playing.
|
||||
SDL_LockAudio();
|
||||
jlModStop();
|
||||
SDL_UnlockAudio();
|
||||
}
|
||||
_jlModCurrent = NULL;
|
||||
}
|
||||
|
||||
// Free loaded song.
|
||||
if (m->data) {
|
||||
jlFree(m->data);
|
||||
jlFree(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
jbool jlModIsPlaying(void) {
|
||||
return _jlModPlaying;
|
||||
}
|
||||
|
||||
|
||||
jbool _jlModLoad(jlModT **mod, char *filename) {
|
||||
FILE *in = NULL;
|
||||
jlPlatformModT *m = NULL;
|
||||
jbool result = jfalse;
|
||||
|
||||
// New MOD.
|
||||
m = (jlPlatformModT *)jlMalloc(sizeof(jlPlatformModT));
|
||||
if (m) {
|
||||
// Load MOD.
|
||||
in = fopen(jlUtilMakePathname(filename, "mod"), "rb");
|
||||
if (in) {
|
||||
fseek(in, 0, SEEK_END);
|
||||
m->size = ftell(in);
|
||||
rewind(in);
|
||||
m->data = (char *)jlMalloc(m->size);
|
||||
if (m->data) {
|
||||
fread(m->data, m->size, 1, in);
|
||||
*mod = m;
|
||||
result = jtrue;
|
||||
}
|
||||
fclose(in);
|
||||
} else {
|
||||
jlFree(m);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void jlModPause(void) {
|
||||
if (_jlModCurrent) _jlModPlaying = jfalse;
|
||||
}
|
||||
|
||||
|
||||
void jlModPlay(jlModT *mod) {
|
||||
jlPlatformModT *m = (jlPlatformModT *)mod;
|
||||
|
||||
// Stop any currently playing MOD.
|
||||
if (_jlModPlaying) jlModStop();
|
||||
|
||||
// Start playback.
|
||||
if (pocketmod_init(&_jlModContext, m->data, m->size, _jlAudioFormat.freq)) {
|
||||
_jlModPlaying = jtrue;
|
||||
_jlModCurrent = m;
|
||||
} else {
|
||||
_jlModPlaying = jfalse;
|
||||
_jlModCurrent = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void jlModStop(void) {
|
||||
_jlModPlaying = jfalse;
|
||||
_jlModCurrent = NULL;
|
||||
}
|
||||
|
||||
|
||||
void jlModVolume(jbyte volume) {
|
||||
_jlModVolume = volume;
|
||||
}
|
||||
|
||||
|
||||
void jlSoundFree(jlSoundT *sound) {
|
||||
(void)sound;
|
||||
jlPlatformSoundT *s = (jlPlatformSoundT *)sound;
|
||||
|
||||
if (s != NULL) {
|
||||
// Stop playing this sound.
|
||||
jlSoundStop(s);
|
||||
// Free it.
|
||||
if (s->data != NULL) jlFree(s->data);
|
||||
jlFree(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool jlSoundIsPlaying(jlSoundT *sound) {
|
||||
(void)sound;
|
||||
jbool jlSoundIsPlaying(jlSoundT *sound) {
|
||||
jlPlatformSoundT *s = (jlPlatformSoundT *)sound;
|
||||
jlSoundPlayingT *cur = _jlSoundList;
|
||||
|
||||
return false;
|
||||
}
|
||||
// Are we being played?
|
||||
SDL_LockAudio();
|
||||
while (cur) {
|
||||
if (cur->sound == s) {
|
||||
// Yep
|
||||
SDL_UnlockAudio();
|
||||
return jtrue;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
SDL_UnlockAudio();
|
||||
|
||||
|
||||
bool _jlSoundLoad(jlSoundT **sound, char *filename) {
|
||||
(void)sound;
|
||||
(void)filename;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void jlSoundMusicContinue(void) {
|
||||
}
|
||||
|
||||
|
||||
bool jlSoundMusicIsPlaying(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void jlSoundMusicPause(void) {
|
||||
}
|
||||
|
||||
|
||||
void jlSoundMusicPlay(char *name) {
|
||||
(void)name;
|
||||
}
|
||||
|
||||
|
||||
void jlSoundMusicStop(void) {
|
||||
}
|
||||
|
||||
|
||||
void jlSoundPlay(jlSoundT *sound, jlSoundChannelE channel, jbyte volume) {
|
||||
(void)sound;
|
||||
}
|
||||
|
||||
|
||||
void jlUtilIdle(void) {
|
||||
}
|
||||
|
||||
|
||||
jbool jlUtilMustExit(void) {
|
||||
return jfalse;
|
||||
}
|
||||
|
||||
|
||||
jbool _jlSoundLoad(jlSoundT **sound, char *filename) {
|
||||
SDL_AudioSpec wave;
|
||||
SDL_AudioCVT cvt;
|
||||
uint8_t *data;
|
||||
uint32_t len;
|
||||
jlPlatformSoundT *soundPlatform = NULL;
|
||||
jbool result = jfalse;
|
||||
|
||||
soundPlatform = (jlPlatformSoundT *)jlMalloc(sizeof(jlPlatformSoundT));
|
||||
if (soundPlatform) {
|
||||
*sound = soundPlatform;
|
||||
if (SDL_LoadWAV(jlUtilMakePathname(filename, "wav"), &wave, &data, &len)) {
|
||||
// Do we need to convert to our internal format?
|
||||
SDL_BuildAudioCVT(&cvt, wave.format, wave.channels, wave.freq, AUDIO_FORMAT, AUDIO_CHANNELS, AUDIO_FREQUENCY);
|
||||
if (cvt.needed) {
|
||||
// Yes! Convert audio.
|
||||
cvt.buf = (jbyte *)jlMalloc(len * cvt.len_mult);
|
||||
if (cvt.buf) {
|
||||
memcpy(cvt.buf, data, len);
|
||||
cvt.len = len;
|
||||
SDL_ConvertAudio(&cvt);
|
||||
SDL_FreeWAV(data);
|
||||
soundPlatform->len = cvt.len_cvt;
|
||||
soundPlatform->data = (jbyte *)jlMalloc(soundPlatform->len);
|
||||
if (soundPlatform->data) {
|
||||
memcpy(soundPlatform->data, cvt.buf, soundPlatform->len);
|
||||
result = jtrue;
|
||||
}
|
||||
data = cvt.buf; // This prevents a warning about taking the address of a packed struct.
|
||||
jlFree(data);
|
||||
}
|
||||
} else {
|
||||
// No. Use as-is.
|
||||
soundPlatform->len = len;
|
||||
soundPlatform->data = (jbyte *)jlMalloc(soundPlatform->len);
|
||||
if (soundPlatform->data) {
|
||||
memcpy(&soundPlatform->data, data, soundPlatform->len);
|
||||
result = jtrue;
|
||||
}
|
||||
SDL_FreeWAV(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!result && soundPlatform) jlFree(soundPlatform);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void jlSoundPlay(jlSoundT *sound, jlSoundChannelE channel, jbyte volume) {
|
||||
jlSoundPlayingT *sp = NULL;
|
||||
|
||||
sp = (jlSoundPlayingT *)jlMalloc(sizeof(jlSoundPlayingT));
|
||||
if (sp) {
|
||||
SDL_LockAudio();
|
||||
sp->sound = sound;
|
||||
sp->channel = channel;
|
||||
sp->volume = volume;
|
||||
sp->buffer = sp->sound->data;
|
||||
sp->len = sp->sound->len;
|
||||
sp->next = _jlSoundList;
|
||||
_jlSoundList = sp;
|
||||
SDL_UnlockAudio();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void jlSoundStop(jlSoundT *sound) {
|
||||
jlPlatformSoundT *s = (jlPlatformSoundT *)sound;
|
||||
jlSoundPlayingT *prev = NULL;
|
||||
jlSoundPlayingT *temp = NULL;
|
||||
jlSoundPlayingT *cur = _jlSoundList;
|
||||
|
||||
// Are we being played?
|
||||
SDL_LockAudio();
|
||||
while (cur) {
|
||||
if (cur->sound == s) {
|
||||
if (prev) {
|
||||
prev->next = cur->next;
|
||||
} else {
|
||||
_jlSoundList = cur->next;
|
||||
}
|
||||
temp = cur;
|
||||
cur = cur->next;
|
||||
jlFree(temp);
|
||||
} else {
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
SDL_UnlockAudio();
|
||||
}
|
||||
|
||||
|
||||
char _jlUtilIdleCheckKey(int sym) {
|
||||
|
||||
char key = 0;
|
||||
SDLMod mod = 0;
|
||||
|
||||
// Do we even care about this key?
|
||||
if ((sym < 8) || (sym > 127)) {
|
||||
key = 0;
|
||||
} else {
|
||||
mod = SDL_GetModState();
|
||||
key = (char)sym;
|
||||
// Map LF to CR
|
||||
if (key == 10) {
|
||||
key = 13;
|
||||
}
|
||||
// Map DEL to BS
|
||||
if (key == 127) {
|
||||
key = 8;
|
||||
}
|
||||
// Convert to uppercase if needed
|
||||
if ((mod == KMOD_SHIFT) && (key >= 'a') && (key <= 'z')) {
|
||||
key -= 32;
|
||||
}
|
||||
// Is this outside the range we care about?
|
||||
if ((key < ' ') || (key > '~')) {
|
||||
if ((key != 8) && (key != 13) && (key != 27)) {
|
||||
key = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
void jlUtilIdle(void) {
|
||||
SDL_Event event;
|
||||
|
||||
SDL_JoystickUpdate();
|
||||
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch(event.type) {
|
||||
case SDL_KEYDOWN:
|
||||
// Track keydown/keyup and remember last key pressed.
|
||||
switch (event.key.keysym.sym) {
|
||||
case SDLK_F1:
|
||||
_jlWindowZoom = 1;
|
||||
_jlWindow = SDL_SetVideoMode((320 + BORDER_WIDTH * 2) * _jlWindowZoom, (200 + BORDER_WIDTH * 2) * _jlWindowZoom, 16, SDL_SWSURFACE);
|
||||
break;
|
||||
|
||||
case SDLK_F2:
|
||||
_jlWindowZoom = 2;
|
||||
_jlWindow = SDL_SetVideoMode((320 + BORDER_WIDTH * 2) * _jlWindowZoom, (200 + BORDER_WIDTH * 2) * _jlWindowZoom, 16, SDL_SWSURFACE);
|
||||
break;
|
||||
|
||||
case SDLK_F3:
|
||||
_jlWindowZoom = 3;
|
||||
_jlWindow = SDL_SetVideoMode((320 + BORDER_WIDTH * 2) * _jlWindowZoom, (200 + BORDER_WIDTH * 2) * _jlWindowZoom, 16, SDL_SWSURFACE);
|
||||
break;
|
||||
|
||||
default:
|
||||
_jlLastKey = _jlUtilIdleCheckKey(event.key.keysym.sym);
|
||||
if (_jlLastKey > 0) {
|
||||
//***FIX***
|
||||
//_jlNumKeysDown++;
|
||||
_jlNumKeysDown = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_KEYUP:
|
||||
if (_jlUtilIdleCheckKey(event.key.keysym.sym) > 0) {
|
||||
//***FIX***
|
||||
//_jlNumKeysDown--;
|
||||
_jlNumKeysDown = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_QUIT:
|
||||
_jlIsRunning = jfalse;
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_Delay(1);
|
||||
}
|
||||
|
||||
//printf("Keys down: %d\n", _jlNumKeysDown);
|
||||
|
||||
SDL_Delay(1);
|
||||
}
|
||||
|
||||
|
||||
jbool jlUtilMustExit(void) {
|
||||
return !_jlIsRunning;
|
||||
}
|
||||
|
||||
|
||||
static Uint32 _jlUtilTimer(Uint32 interval, void *param) {
|
||||
(void)param;
|
||||
_jlTimerValue++;
|
||||
return(interval);
|
||||
}
|
||||
|
||||
|
||||
juint16 jlUtilTimer(void) {
|
||||
return 0;
|
||||
return _jlTimerValue;
|
||||
}
|
||||
|
||||
|
||||
void jlUtilTitleSet(char *title) {
|
||||
#ifdef JOEY_LINUX
|
||||
SDL_WM_SetCaption(title, NULL);
|
||||
#endif
|
||||
SDL_WM_SetCaption(title, NULL); // ***TODO*** Needs icon.
|
||||
}
|
||||
|
||||
|
||||
int main(void) {
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
Uint32 vflags;
|
||||
int mflags;
|
||||
int result;
|
||||
int joysticks;
|
||||
int x;
|
||||
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
// Start low-level tools
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {
|
||||
jlUtilDie(SDL_GetError());
|
||||
}
|
||||
|
||||
// Start audio mixer & music system.
|
||||
mflags = MIX_INIT_MOD;
|
||||
result = Mix_Init(mflags);
|
||||
if ((result & mflags) != mflags) {
|
||||
jlUtilDie(Mix_GetError());
|
||||
}
|
||||
if (Mix_OpenAudio(11025, AUDIO_U8, 1, 1024) == -1) {
|
||||
jlUtilDie(Mix_GetError());
|
||||
}
|
||||
// Set up controllers
|
||||
joysticks = SDL_NumJoysticks();
|
||||
_jlControllers = (SDL_Joystick **)jlMalloc(sizeof(SDL_Joystick *) * (unsigned long)joysticks);
|
||||
for (x=0; x<joysticks; x++) _jlControllers[_jlControllerCount++] = SDL_JoystickOpen(x);
|
||||
|
||||
// Set up video
|
||||
vflags = SDL_HWSURFACE;
|
||||
vflags |= SDL_FULLSCREEN;
|
||||
_jlScreen = SDL_SetVideoMode(320, 200, 16, vflags);
|
||||
if (!_jlScreen) {
|
||||
jlUtilDie(SDL_GetError());
|
||||
}
|
||||
// Create a window and renderer using SDL
|
||||
_jlWindow = SDL_SetVideoMode((320 + BORDER_WIDTH * 2) * _jlWindowZoom, (200 + BORDER_WIDTH * 2) * _jlWindowZoom, 16, SDL_SWSURFACE);
|
||||
_jlTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, 320, 200, 16, 0, 0, 0, 0);
|
||||
|
||||
// Set up audio device
|
||||
_jlAudioFormat.freq = AUDIO_FREQUENCY;
|
||||
_jlAudioFormat.format = AUDIO_FORMAT;
|
||||
_jlAudioFormat.channels = 2;
|
||||
_jlAudioFormat.samples = AUDIO_CHANNELS;
|
||||
_jlAudioFormat.callback = _jlAudioCallback;
|
||||
_jlAudioFormat.userdata = NULL;
|
||||
if (SDL_OpenAudio(&_jlAudioFormat, &_jlAudioFormat) < 0) jlUtilDie(SDL_GetError());
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
// Start 1/60th second timer
|
||||
_jlTimerId = SDL_AddTimer(1000 / 60, _jlUtilTimer, NULL);
|
||||
|
||||
jPixBufStart();
|
||||
|
||||
// Run the main loop.
|
||||
joeyMain();
|
||||
if (!setjmp(_jlJumpBuffer)) {
|
||||
joeyMain();
|
||||
|
||||
jPixBufStop();
|
||||
jPixBufStop();
|
||||
|
||||
SDL_FreeSurface(_jlScreen);
|
||||
jlSoundMusicStop();
|
||||
Mix_CloseAudio();
|
||||
Mix_Quit();
|
||||
SDL_Quit();
|
||||
jlUtilDie("Clean Exit.");
|
||||
SDL_RemoveTimer(_jlTimerId);
|
||||
for (x=0; x<_jlControllerCount; x++) SDL_JoystickClose(_jlControllers[x]);
|
||||
_jlControllerCount = 0;
|
||||
jlFree(_jlControllers);
|
||||
SDL_PauseAudio(1);
|
||||
SDL_CloseAudio();
|
||||
while (_jlSoundList) jlSoundStop(_jlSoundList);
|
||||
jlModStop();
|
||||
SDL_FreeSurface(_jlTexture);
|
||||
SDL_Quit(); // This releases _jlWindow.
|
||||
|
||||
jlUtilDie("Clean Exit.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -637,7 +637,7 @@ jbool jlGameGetButton(jbyte which) {
|
|||
|
||||
|
||||
#ifndef JL_HAS_IMGCOPY
|
||||
jbool _jlImgCopy(jlImgT *source, jlImgT **target, jint16 line, char *file) {
|
||||
jbool _jlImgCopy(jlImgT **target, jlImgT *source, jint16 line, char *file) {
|
||||
jlImgT *t = NULL;
|
||||
// Are we copying into a new image?
|
||||
if (*target == NULL) {
|
||||
|
|
|
@ -419,8 +419,8 @@ void jlDrawSurfaceSet(jlSurfaceT target);
|
|||
jint16 jlGameGetAxis(jbyte which);
|
||||
jbool jlGameGetButton(jbyte which);
|
||||
|
||||
#define jlImgCopy(source, target) _jlImgCopy(source, (jlImgT **)&(target), __LINE__, (char *)__FILE__) // Syntatic Sugar
|
||||
jbool _jlImgCopy(jlImgT *source, jlImgT **target, jint16 line, char *file);
|
||||
#define jlImgCopy(target, source) _jlImgCopy((jlImgT **)&(target), source, __LINE__, (char *)__FILE__) // Syntatic Sugar
|
||||
jbool _jlImgCopy(jlImgT **target, jlImgT *source, jint16 line, char *file);
|
||||
#define jlImgCreate(img) _jlImgCreate((jlImgT **)&(img), __LINE__, (char *)__FILE__) // Syntatic Sugar
|
||||
jbool _jlImgCreate(jlImgT **img, jint16 line, char *file);
|
||||
void jlImgDisplay(jlImgT *img);
|
||||
|
|
Loading…
Add table
Reference in a new issue