In theory, we have an SDL 1.2 backend. No toolchain to test it with yet.

This commit is contained in:
Scott Duensing 2022-09-17 17:41:24 -05:00
parent a67e998c28
commit f10172d5bb
5 changed files with 706 additions and 106 deletions

View file

@ -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 += \

View file

@ -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 { \

View file

@ -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;
}

View file

@ -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) {

View file

@ -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);