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
|
JOEY = /home/scott/joey
|
||||||
#CONFIG += SDL12
|
CONFIG += SDL12
|
||||||
CONFIG += SDL2
|
#CONFIG += SDL2
|
||||||
|
#CONFIG += OURLIBS
|
||||||
|
|
||||||
#BREW = /home/linuxbrew/.linuxbrew
|
#BREW = /home/linuxbrew/.linuxbrew
|
||||||
|
|
||||||
|
@ -10,6 +11,7 @@ CONFIG -= \
|
||||||
app_bundle \
|
app_bundle \
|
||||||
qt
|
qt
|
||||||
|
|
||||||
|
# Determine which libraries to link against.
|
||||||
defined(BREW,var) {
|
defined(BREW,var) {
|
||||||
# Use Homebrew libraries.
|
# Use Homebrew libraries.
|
||||||
STATICLIB = $$BREW/lib
|
STATICLIB = $$BREW/lib
|
||||||
|
@ -18,12 +20,19 @@ defined(BREW,var) {
|
||||||
-L$$STATICLIB \
|
-L$$STATICLIB \
|
||||||
-Wl,-rpath,$$STATICLIB
|
-Wl,-rpath,$$STATICLIB
|
||||||
} else {
|
} else {
|
||||||
|
OURLIBS {
|
||||||
# Use our libraries.
|
# Use our libraries.
|
||||||
#STATICLIB = $$JOEY/sdks/linux/x64/lib
|
STATICLIB = $$JOEY/sdks/linux/x64/lib
|
||||||
#INCLUDEPATH += $$JOEY/sdks/linux/x64/include
|
INCLUDEPATH += $$JOEY/sdks/linux/x64/include
|
||||||
#LIBS += \
|
LIBS += \
|
||||||
# -L$$STATICLIB \
|
-L$$STATICLIB \
|
||||||
# -Wl,-rpath,$$STATICLIB
|
-Wl,-rpath,$$STATICLIB
|
||||||
|
} else {
|
||||||
|
# System libraries.
|
||||||
|
STATICLIB = /usr/lib/x86_64-linux-gnu
|
||||||
|
LIBS += \
|
||||||
|
-Wl,-rpath,$$STATICLIB
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD/src
|
INCLUDEPATH += $$PWD/src
|
||||||
|
@ -65,9 +74,8 @@ SDL2 {
|
||||||
|
|
||||||
LIBS += \
|
LIBS += \
|
||||||
-Wl,--enable-new-dtags \
|
-Wl,--enable-new-dtags \
|
||||||
-lSDL2
|
$$STATICLIB/libSDL2.a \
|
||||||
# $$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
|
||||||
# -lm -ldl -lX11 -lXext -lXcursor -lXi -lXfixes -lXrandr -lXss -lpthread -lrt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OTHER_FILES += \
|
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 */
|
float sample; /* Current sample in tick */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef POCKETMOD_IMPLEMENTATIONx
|
#ifdef POCKETMOD_IMPLEMENTATION
|
||||||
|
|
||||||
/* Memorize a parameter unless the new value is zero */
|
/* Memorize a parameter unless the new value is zero */
|
||||||
#define POCKETMOD_MEM(dst, src) do { \
|
#define POCKETMOD_MEM(dst, src) do { \
|
||||||
|
|
|
@ -19,155 +19,747 @@
|
||||||
* 3. This notice may not be removed or altered from any source distribution.
|
* 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.h"
|
||||||
#include "SDL/SDL_mixer.h"
|
|
||||||
|
#define POCKETMOD_IMPLEMENTATION
|
||||||
|
#include "3rdparty/pocketmod/pocketmod.h"
|
||||||
|
|
||||||
#include "joey.h"
|
#include "joey.h"
|
||||||
#include "jPixBuf.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) {
|
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) {
|
jint16 jlGameGetAxis(jbyte which) {
|
||||||
(void)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) {
|
jbool jlGameGetButton(jbyte which) {
|
||||||
(void)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) {
|
jbool jlKeyPressed(void) {
|
||||||
return false;
|
jlUtilIdle();
|
||||||
|
return (_jlNumKeysDown > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char jlKeyRead(void) {
|
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 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) {
|
jbool jlSoundIsPlaying(jlSoundT *sound) {
|
||||||
(void)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;
|
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) {
|
juint16 jlUtilTimer(void) {
|
||||||
return 0;
|
return _jlTimerValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void jlUtilTitleSet(char *title) {
|
void jlUtilTitleSet(char *title) {
|
||||||
#ifdef JOEY_LINUX
|
SDL_WM_SetCaption(title, NULL); // ***TODO*** Needs icon.
|
||||||
SDL_WM_SetCaption(title, NULL);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(void) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
Uint32 vflags;
|
int joysticks;
|
||||||
int mflags;
|
int x;
|
||||||
int result;
|
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
|
||||||
// Start low-level tools
|
// Start low-level tools
|
||||||
if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {
|
if (SDL_Init(SDL_INIT_EVERYTHING) == -1) {
|
||||||
jlUtilDie(SDL_GetError());
|
jlUtilDie(SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start audio mixer & music system.
|
// Set up controllers
|
||||||
mflags = MIX_INIT_MOD;
|
joysticks = SDL_NumJoysticks();
|
||||||
result = Mix_Init(mflags);
|
_jlControllers = (SDL_Joystick **)jlMalloc(sizeof(SDL_Joystick *) * (unsigned long)joysticks);
|
||||||
if ((result & mflags) != mflags) {
|
for (x=0; x<joysticks; x++) _jlControllers[_jlControllerCount++] = SDL_JoystickOpen(x);
|
||||||
jlUtilDie(Mix_GetError());
|
|
||||||
}
|
|
||||||
if (Mix_OpenAudio(11025, AUDIO_U8, 1, 1024) == -1) {
|
|
||||||
jlUtilDie(Mix_GetError());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up video
|
// Create a window and renderer using SDL
|
||||||
vflags = SDL_HWSURFACE;
|
_jlWindow = SDL_SetVideoMode((320 + BORDER_WIDTH * 2) * _jlWindowZoom, (200 + BORDER_WIDTH * 2) * _jlWindowZoom, 16, SDL_SWSURFACE);
|
||||||
vflags |= SDL_FULLSCREEN;
|
_jlTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, 320, 200, 16, 0, 0, 0, 0);
|
||||||
_jlScreen = SDL_SetVideoMode(320, 200, 16, vflags);
|
|
||||||
if (!_jlScreen) {
|
// Set up audio device
|
||||||
jlUtilDie(SDL_GetError());
|
_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();
|
jPixBufStart();
|
||||||
|
|
||||||
// Run the main loop.
|
// Run the main loop.
|
||||||
|
if (!setjmp(_jlJumpBuffer)) {
|
||||||
joeyMain();
|
joeyMain();
|
||||||
|
|
||||||
jPixBufStop();
|
jPixBufStop();
|
||||||
|
|
||||||
SDL_FreeSurface(_jlScreen);
|
SDL_RemoveTimer(_jlTimerId);
|
||||||
jlSoundMusicStop();
|
for (x=0; x<_jlControllerCount; x++) SDL_JoystickClose(_jlControllers[x]);
|
||||||
Mix_CloseAudio();
|
_jlControllerCount = 0;
|
||||||
Mix_Quit();
|
jlFree(_jlControllers);
|
||||||
SDL_Quit();
|
SDL_PauseAudio(1);
|
||||||
|
SDL_CloseAudio();
|
||||||
|
while (_jlSoundList) jlSoundStop(_jlSoundList);
|
||||||
|
jlModStop();
|
||||||
|
SDL_FreeSurface(_jlTexture);
|
||||||
|
SDL_Quit(); // This releases _jlWindow.
|
||||||
|
|
||||||
jlUtilDie("Clean Exit.");
|
jlUtilDie("Clean Exit.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -637,7 +637,7 @@ jbool jlGameGetButton(jbyte which) {
|
||||||
|
|
||||||
|
|
||||||
#ifndef JL_HAS_IMGCOPY
|
#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;
|
jlImgT *t = NULL;
|
||||||
// Are we copying into a new image?
|
// Are we copying into a new image?
|
||||||
if (*target == NULL) {
|
if (*target == NULL) {
|
||||||
|
|
|
@ -419,8 +419,8 @@ void jlDrawSurfaceSet(jlSurfaceT target);
|
||||||
jint16 jlGameGetAxis(jbyte which);
|
jint16 jlGameGetAxis(jbyte which);
|
||||||
jbool jlGameGetButton(jbyte which);
|
jbool jlGameGetButton(jbyte which);
|
||||||
|
|
||||||
#define jlImgCopy(source, target) _jlImgCopy(source, (jlImgT **)&(target), __LINE__, (char *)__FILE__) // Syntatic Sugar
|
#define jlImgCopy(target, source) _jlImgCopy((jlImgT **)&(target), source, __LINE__, (char *)__FILE__) // Syntatic Sugar
|
||||||
jbool _jlImgCopy(jlImgT *source, jlImgT **target, jint16 line, char *file);
|
jbool _jlImgCopy(jlImgT **target, jlImgT *source, jint16 line, char *file);
|
||||||
#define jlImgCreate(img) _jlImgCreate((jlImgT **)&(img), __LINE__, (char *)__FILE__) // Syntatic Sugar
|
#define jlImgCreate(img) _jlImgCreate((jlImgT **)&(img), __LINE__, (char *)__FILE__) // Syntatic Sugar
|
||||||
jbool _jlImgCreate(jlImgT **img, jint16 line, char *file);
|
jbool _jlImgCreate(jlImgT **img, jint16 line, char *file);
|
||||||
void jlImgDisplay(jlImgT *img);
|
void jlImgDisplay(jlImgT *img);
|
||||||
|
|
Loading…
Add table
Reference in a new issue