mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-09 06:36:59 +02:00
SDL: rewrote joystick handling and add multiple joystick support. (#170)
* SDL: rewrote joystick handling and add multiple joystick support. * SDL: Move SDL2 platform audio system to SDL2 functions * SDL: Add fullscreen toggle via ALT+ENTER. Rearrange SDL2 GL/GLES header includes.
This commit is contained in:
425
main.cpp
Normal file
425
main.cpp
Normal file
@@ -0,0 +1,425 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
|
// SDL2 include stuff
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#define GL_GLEXT_PROTOTYPES 1
|
||||||
|
#include <SDL2/SDL_opengles2.h>
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
#define WND_TITLE "OpenLara"
|
||||||
|
|
||||||
|
// timing
|
||||||
|
unsigned int startTime;
|
||||||
|
|
||||||
|
int osGetTime() {
|
||||||
|
timeval t;
|
||||||
|
gettimeofday(&t, NULL);
|
||||||
|
return int((t.tv_sec - startTime) * 1000 + t.tv_usec / 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// sound
|
||||||
|
snd_pcm_uframes_t SND_FRAMES = 512;
|
||||||
|
snd_pcm_t *sndOut;
|
||||||
|
Sound::Frame *sndData;
|
||||||
|
pthread_t sndThread;
|
||||||
|
|
||||||
|
void* sndFill(void *arg) {
|
||||||
|
while (sndOut) {
|
||||||
|
Sound::fill(sndData, SND_FRAMES);
|
||||||
|
|
||||||
|
int err = snd_pcm_writei(sndOut, sndData, SND_FRAMES);
|
||||||
|
if (err < 0) {
|
||||||
|
LOG("! sound: write %s\n", snd_strerror(err));;
|
||||||
|
if (err != -EPIPE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
err = snd_pcm_recover(sndOut, err, 0);
|
||||||
|
if (err < 0) {
|
||||||
|
LOG("! sound: failed to recover\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
snd_pcm_prepare(sndOut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sndInit() {
|
||||||
|
unsigned int freq = 44100;
|
||||||
|
|
||||||
|
int err;
|
||||||
|
if ((err = snd_pcm_open(&sndOut, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
|
||||||
|
LOG("! sound: open %s\n", snd_strerror(err));\
|
||||||
|
sndOut = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_pcm_hw_params_t *params;
|
||||||
|
|
||||||
|
snd_pcm_hw_params_alloca(¶ms);
|
||||||
|
snd_pcm_hw_params_any(sndOut, params);
|
||||||
|
snd_pcm_hw_params_set_access(sndOut, params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
||||||
|
|
||||||
|
snd_pcm_hw_params_set_channels(sndOut, params, 2);
|
||||||
|
snd_pcm_hw_params_set_format(sndOut, params, SND_PCM_FORMAT_S16_LE);
|
||||||
|
snd_pcm_hw_params_set_rate_near(sndOut, params, &freq, NULL);
|
||||||
|
|
||||||
|
snd_pcm_hw_params_set_periods(sndOut, params, 4, 0);
|
||||||
|
snd_pcm_hw_params_set_period_size_near(sndOut, params, &SND_FRAMES, NULL);
|
||||||
|
snd_pcm_hw_params_get_period_size(params, &SND_FRAMES, 0);
|
||||||
|
|
||||||
|
snd_pcm_hw_params(sndOut, params);
|
||||||
|
snd_pcm_prepare(sndOut);
|
||||||
|
|
||||||
|
sndData = new Sound::Frame[SND_FRAMES];
|
||||||
|
memset(sndData, 0, SND_FRAMES * sizeof(Sound::Frame));
|
||||||
|
if ((err = snd_pcm_writei(sndOut, sndData, SND_FRAMES)) < 0) {
|
||||||
|
LOG("! sound: write %s\n", snd_strerror(err));\
|
||||||
|
sndOut = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_pcm_start(sndOut);
|
||||||
|
pthread_create(&sndThread, NULL, sndFill, NULL);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sndFree() {
|
||||||
|
pthread_cancel(sndThread);
|
||||||
|
snd_pcm_drop(sndOut);
|
||||||
|
snd_pcm_drain(sndOut);
|
||||||
|
snd_pcm_close(sndOut);
|
||||||
|
delete[] sndData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input
|
||||||
|
|
||||||
|
#define MAX_JOYS 4
|
||||||
|
#define JOY_DEAD_ZONE_STICK 8192
|
||||||
|
|
||||||
|
struct sdl_input *sdl_inputs;
|
||||||
|
int sdl_numjoysticks, sdl_numcontrollers;
|
||||||
|
SDL_Joystick *sdl_joysticks[MAX_JOYS];
|
||||||
|
SDL_GameController *sdl_controllers[MAX_JOYS];
|
||||||
|
|
||||||
|
vec2 joyL, joyR;
|
||||||
|
|
||||||
|
bool osJoyReady(int index) {
|
||||||
|
return index == 0; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void osJoyVibrate(int index, float L, float R) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
InputKey codeToInputKey(int code) {
|
||||||
|
switch (code) {
|
||||||
|
// keyboard
|
||||||
|
case SDL_SCANCODE_LEFT : return ikLeft;
|
||||||
|
case SDL_SCANCODE_RIGHT : return ikRight;
|
||||||
|
case SDL_SCANCODE_UP : return ikUp;
|
||||||
|
case SDL_SCANCODE_DOWN : return ikDown;
|
||||||
|
case SDL_SCANCODE_SPACE : return ikSpace;
|
||||||
|
case SDL_SCANCODE_TAB : return ikTab;
|
||||||
|
case SDL_SCANCODE_RETURN : return ikEnter;
|
||||||
|
case SDL_SCANCODE_ESCAPE : return ikEscape;
|
||||||
|
case SDL_SCANCODE_LSHIFT :
|
||||||
|
case SDL_SCANCODE_RSHIFT : return ikShift;
|
||||||
|
case SDL_SCANCODE_LCTRL :
|
||||||
|
case SDL_SCANCODE_RCTRL : return ikCtrl;
|
||||||
|
case SDL_SCANCODE_LALT :
|
||||||
|
case SDL_SCANCODE_RALT : return ikAlt;
|
||||||
|
case SDL_SCANCODE_0 : return ik0;
|
||||||
|
case SDL_SCANCODE_1 : return ik1;
|
||||||
|
case SDL_SCANCODE_2 : return ik2;
|
||||||
|
case SDL_SCANCODE_3 : return ik3;
|
||||||
|
case SDL_SCANCODE_4 : return ik4;
|
||||||
|
case SDL_SCANCODE_5 : return ik5;
|
||||||
|
case SDL_SCANCODE_6 : return ik6;
|
||||||
|
case SDL_SCANCODE_7 : return ik7;
|
||||||
|
case SDL_SCANCODE_8 : return ik8;
|
||||||
|
case SDL_SCANCODE_9 : return ik9;
|
||||||
|
case SDL_SCANCODE_A : return ikA;
|
||||||
|
case SDL_SCANCODE_B : return ikB;
|
||||||
|
case SDL_SCANCODE_C : return ikC;
|
||||||
|
case SDL_SCANCODE_D : return ikD;
|
||||||
|
case SDL_SCANCODE_E : return ikE;
|
||||||
|
case SDL_SCANCODE_F : return ikF;
|
||||||
|
case SDL_SCANCODE_G : return ikG;
|
||||||
|
case SDL_SCANCODE_H : return ikH;
|
||||||
|
case SDL_SCANCODE_I : return ikI;
|
||||||
|
case SDL_SCANCODE_J : return ikJ;
|
||||||
|
case SDL_SCANCODE_K : return ikK;
|
||||||
|
case SDL_SCANCODE_L : return ikL;
|
||||||
|
case SDL_SCANCODE_M : return ikM;
|
||||||
|
case SDL_SCANCODE_N : return ikN;
|
||||||
|
case SDL_SCANCODE_O : return ikO;
|
||||||
|
case SDL_SCANCODE_P : return ikP;
|
||||||
|
case SDL_SCANCODE_Q : return ikQ;
|
||||||
|
case SDL_SCANCODE_R : return ikR;
|
||||||
|
case SDL_SCANCODE_S : return ikS;
|
||||||
|
case SDL_SCANCODE_T : return ikT;
|
||||||
|
case SDL_SCANCODE_U : return ikU;
|
||||||
|
case SDL_SCANCODE_V : return ikV;
|
||||||
|
case SDL_SCANCODE_W : return ikW;
|
||||||
|
case SDL_SCANCODE_X : return ikX;
|
||||||
|
case SDL_SCANCODE_Y : return ikY;
|
||||||
|
case SDL_SCANCODE_Z : return ikZ;
|
||||||
|
case SDL_SCANCODE_AC_HOME : return ikEscape;
|
||||||
|
}
|
||||||
|
return ikNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
JoyKey controllerCodeToJoyKey(int code) {
|
||||||
|
// joystick using the modern SDL GameController interface
|
||||||
|
switch (code) {
|
||||||
|
case SDL_CONTROLLER_BUTTON_A : return jkA;
|
||||||
|
case SDL_CONTROLLER_BUTTON_B : return jkB;
|
||||||
|
case SDL_CONTROLLER_BUTTON_X : return jkX;
|
||||||
|
case SDL_CONTROLLER_BUTTON_Y : return jkY;
|
||||||
|
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER : return jkLB;
|
||||||
|
case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER : return jkRB;
|
||||||
|
case SDL_CONTROLLER_BUTTON_BACK : return jkSelect;
|
||||||
|
case SDL_CONTROLLER_BUTTON_START : return jkStart;
|
||||||
|
case SDL_CONTROLLER_BUTTON_LEFTSTICK : return jkL;
|
||||||
|
case SDL_CONTROLLER_BUTTON_RIGHTSTICK : return jkR;
|
||||||
|
}
|
||||||
|
return jkNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
JoyKey joyCodeToJoyKey(int buttonNumber) {
|
||||||
|
// joystick using the classic SDL Joystick interface
|
||||||
|
switch (buttonNumber) {
|
||||||
|
case 0 : return jkY;
|
||||||
|
case 1 : return jkB;
|
||||||
|
case 2 : return jkA;
|
||||||
|
case 3 : return jkX;
|
||||||
|
case 4 : return jkL;
|
||||||
|
case 5 : return jkR;
|
||||||
|
case 6 : return jkLB;
|
||||||
|
case 7 : return jkRB;
|
||||||
|
case 8 : return jkSelect;
|
||||||
|
case 9 : return jkStart;
|
||||||
|
}
|
||||||
|
return jkNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool inputInit() {
|
||||||
|
int i;
|
||||||
|
joyL = joyR = vec2(0);
|
||||||
|
sdl_numjoysticks = SDL_NumJoysticks();
|
||||||
|
sdl_numjoysticks = (sdl_numjoysticks < MAX_JOYS )? sdl_numjoysticks : MAX_JOYS;
|
||||||
|
|
||||||
|
for (i = 0; i < sdl_numjoysticks; i++) {
|
||||||
|
if(SDL_IsGameController(i)) {
|
||||||
|
SDL_GameController *controller = SDL_GameControllerOpen(i);
|
||||||
|
sdl_joysticks[i] = SDL_GameControllerGetJoystick(controller);
|
||||||
|
sdl_controllers[i] = controller;
|
||||||
|
sdl_numcontrollers++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sdl_joysticks[i] = SDL_JoystickOpen(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void inputFree() {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < sdl_numcontrollers; i++) {
|
||||||
|
SDL_GameControllerClose(sdl_controllers[i]);
|
||||||
|
}
|
||||||
|
for (i = 0; i < sdl_numjoysticks; i++) {
|
||||||
|
SDL_JoystickClose(sdl_joysticks[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float joyAxisValue(int value) {
|
||||||
|
if (value > -JOY_DEAD_ZONE_STICK && value < JOY_DEAD_ZONE_STICK)
|
||||||
|
return 0.0f;
|
||||||
|
return value / 32767.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float joyTrigger(int value) {
|
||||||
|
return min(1.0f, value / 255.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 joyDir(const vec2 &value) {
|
||||||
|
float dist = min(1.0f, value.length());
|
||||||
|
return value.normal() * dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getJoyIndex(SDL_JoystickID id) {
|
||||||
|
int i;
|
||||||
|
for (i=0 ; i < sdl_numjoysticks; i++) {
|
||||||
|
if (SDL_JoystickInstanceID(sdl_joysticks[i]) == id) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void inputUpdate() {
|
||||||
|
// get input events
|
||||||
|
|
||||||
|
int joyIndex;
|
||||||
|
SDL_Event event;
|
||||||
|
|
||||||
|
while (SDL_PollEvent(&event) == 1) { // while there are still events to be processed
|
||||||
|
switch (event.type) {
|
||||||
|
case SDL_KEYDOWN: {
|
||||||
|
int scancode = event.key.keysym.scancode;
|
||||||
|
InputKey key = codeToInputKey(scancode);
|
||||||
|
if (key != ikNone) {
|
||||||
|
Input::setDown(key, 1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_KEYUP: {
|
||||||
|
int scancode = event.key.keysym.scancode;
|
||||||
|
InputKey key = codeToInputKey(scancode);
|
||||||
|
if (key != ikNone) {
|
||||||
|
Input::setDown(key, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Joystick reading using the modern GameController interface
|
||||||
|
case SDL_CONTROLLERBUTTONDOWN: {
|
||||||
|
joyIndex = getJoyIndex(event.cbutton.which);
|
||||||
|
JoyKey key = controllerCodeToJoyKey(event.cbutton.button);
|
||||||
|
Input::setJoyDown(joyIndex, key, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_CONTROLLERBUTTONUP: {
|
||||||
|
joyIndex = getJoyIndex(event.cbutton.which);
|
||||||
|
JoyKey key = controllerCodeToJoyKey(event.cbutton.button);
|
||||||
|
Input::setJoyDown(joyIndex, key, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_CONTROLLERAXISMOTION: {
|
||||||
|
joyIndex = getJoyIndex(event.caxis.which);
|
||||||
|
switch (event.caxis.axis) {
|
||||||
|
case SDL_CONTROLLER_AXIS_LEFTX: joyL.x = joyAxisValue(event.caxis.value); break;
|
||||||
|
case SDL_CONTROLLER_AXIS_LEFTY: joyL.y = joyAxisValue(event.caxis.value); break;
|
||||||
|
case SDL_CONTROLLER_AXIS_RIGHTX: joyR.x = joyAxisValue(event.caxis.value); break;
|
||||||
|
case SDL_CONTROLLER_AXIS_RIGHTY: joyR.y = joyAxisValue(event.caxis.value); break;
|
||||||
|
}
|
||||||
|
Input::setJoyPos(joyIndex, jkL, joyDir(joyL));
|
||||||
|
Input::setJoyPos(joyIndex, jkR, joyDir(joyR));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Joystick reading using the classic Joystick interface
|
||||||
|
case SDL_JOYBUTTONDOWN: {
|
||||||
|
joyIndex = getJoyIndex(event.jbutton.which);
|
||||||
|
JoyKey key = joyCodeToJoyKey(event.jbutton.button);
|
||||||
|
Input::setJoyDown(joyIndex, key, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_JOYBUTTONUP: {
|
||||||
|
joyIndex = getJoyIndex(event.jbutton.which);
|
||||||
|
JoyKey key = joyCodeToJoyKey(event.jbutton.button);
|
||||||
|
Input::setJoyDown(joyIndex, key, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_JOYAXISMOTION: {
|
||||||
|
joyIndex = getJoyIndex(event.jaxis.which);
|
||||||
|
switch (event.jaxis.axis) {
|
||||||
|
// In the classic joystick interface we know what axis changed by it's number,
|
||||||
|
// they have no names like on the fancy GameController interface.
|
||||||
|
case 0: joyL.x = joyAxisValue(event.jaxis.value); break;
|
||||||
|
case 1: joyL.y = joyAxisValue(event.jaxis.value); break;
|
||||||
|
case 2: joyR.x = joyAxisValue(event.jaxis.value); break;
|
||||||
|
case 3: joyR.y = joyAxisValue(event.jaxis.value); break;
|
||||||
|
}
|
||||||
|
Input::setJoyPos(joyIndex, jkL, joyDir(joyL));
|
||||||
|
Input::setJoyPos(joyIndex, jkR, joyDir(joyR));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
int w, h;
|
||||||
|
SDL_DisplayMode current;
|
||||||
|
|
||||||
|
|
||||||
|
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_EVENTS|SDL_INIT_GAMECONTROLLER);
|
||||||
|
|
||||||
|
SDL_GetCurrentDisplayMode(0, ¤t);
|
||||||
|
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||||
|
|
||||||
|
// We start in fullscreen mode using the vide mode currently in use, to avoid video mode changes.
|
||||||
|
SDL_Window *window = SDL_CreateWindow(WND_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||||
|
//current.w, current.h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||||
|
640, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
|
||||||
|
|
||||||
|
// We try to use the current video mode, but we inform the core of whatever mode SDL2 gave us in the end.
|
||||||
|
SDL_GetWindowSize(window, &w, &h);
|
||||||
|
|
||||||
|
Core::width = w;
|
||||||
|
Core::height = h;
|
||||||
|
|
||||||
|
SDL_GLContext context = SDL_GL_CreateContext(window);
|
||||||
|
SDL_GL_SetSwapInterval(0);
|
||||||
|
|
||||||
|
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1,
|
||||||
|
SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
|
||||||
|
|
||||||
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
|
|
||||||
|
cacheDir[0] = saveDir[0] = contentDir[0] = 0;
|
||||||
|
|
||||||
|
const char *home;
|
||||||
|
if (!(home = getenv("HOME")))
|
||||||
|
home = getpwuid(getuid())->pw_dir;
|
||||||
|
strcat(cacheDir, home);
|
||||||
|
strcat(cacheDir, "/.openlara/");
|
||||||
|
|
||||||
|
struct stat st = {0};
|
||||||
|
if (stat(cacheDir, &st) == -1 && mkdir(cacheDir, 0777) == -1)
|
||||||
|
cacheDir[0] = 0;
|
||||||
|
strcpy(saveDir, cacheDir);
|
||||||
|
|
||||||
|
timeval t;
|
||||||
|
gettimeofday(&t, NULL);
|
||||||
|
startTime = t.tv_sec;
|
||||||
|
|
||||||
|
sndInit();
|
||||||
|
|
||||||
|
inputInit();
|
||||||
|
|
||||||
|
char *lvlName = argc > 1 ? argv[1] : NULL;
|
||||||
|
|
||||||
|
Game::init(lvlName);
|
||||||
|
|
||||||
|
while (!Core::isQuit) {
|
||||||
|
inputUpdate();
|
||||||
|
|
||||||
|
if (Game::update()) {
|
||||||
|
Game::render();
|
||||||
|
Core::waitVBlank();
|
||||||
|
SDL_GL_SwapWindow(window);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sndFree();
|
||||||
|
Game::deinit();
|
||||||
|
|
||||||
|
SDL_DestroyRenderer(renderer);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -29,7 +29,7 @@
|
|||||||
extern void osToggleVR(bool enable);
|
extern void osToggleVR(bool enable);
|
||||||
#elif __SDL2__
|
#elif __SDL2__
|
||||||
#define _GAPI_GL 1
|
#define _GAPI_GL 1
|
||||||
#ifdef SDL2GLES
|
#ifdef SDL2_GLES
|
||||||
#define _GAPI_GLES 1
|
#define _GAPI_GLES 1
|
||||||
#define DYNGEOM_NO_VBO
|
#define DYNGEOM_NO_VBO
|
||||||
#endif
|
#endif
|
||||||
|
@@ -19,10 +19,11 @@
|
|||||||
|
|
||||||
#elif defined(__SDL2__)
|
#elif defined(__SDL2__)
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#if !defined(_GAPI_GLES)
|
|
||||||
#include <SDL2/SDL_opengl.h>
|
#if defined(_GAPI_GLES)
|
||||||
#else
|
#define GL_GLEXT_PROTOTYPES 1
|
||||||
#include <SDL2/SDL_opengles2.h>
|
#include <SDL2/SDL_opengles2.h>
|
||||||
|
#include <SDL2/SDL_opengles2_gl2ext.h>
|
||||||
|
|
||||||
#define GL_CLAMP_TO_BORDER 0x812D
|
#define GL_CLAMP_TO_BORDER 0x812D
|
||||||
#define GL_TEXTURE_BORDER_COLOR 0x1004
|
#define GL_TEXTURE_BORDER_COLOR 0x1004
|
||||||
@@ -45,7 +46,6 @@
|
|||||||
#define GL_RG16F GL_RGBA
|
#define GL_RG16F GL_RGBA
|
||||||
#define GL_HALF_FLOAT GL_HALF_FLOAT_OES
|
#define GL_HALF_FLOAT GL_HALF_FLOAT_OES
|
||||||
|
|
||||||
#define GL_TEXTURE_3D 0
|
|
||||||
#define GL_TEXTURE_WRAP_R 0
|
#define GL_TEXTURE_WRAP_R 0
|
||||||
#define GL_DEPTH_STENCIL GL_DEPTH_STENCIL_OES
|
#define GL_DEPTH_STENCIL GL_DEPTH_STENCIL_OES
|
||||||
#define GL_UNSIGNED_INT_24_8 GL_UNSIGNED_INT_24_8_OES
|
#define GL_UNSIGNED_INT_24_8 GL_UNSIGNED_INT_24_8_OES
|
||||||
@@ -59,6 +59,10 @@
|
|||||||
#define GL_PROGRAM_BINARY_LENGTH GL_PROGRAM_BINARY_LENGTH_OES
|
#define GL_PROGRAM_BINARY_LENGTH GL_PROGRAM_BINARY_LENGTH_OES
|
||||||
#define glGetProgramBinary(...)
|
#define glGetProgramBinary(...)
|
||||||
#define glProgramBinary(...)
|
#define glProgramBinary(...)
|
||||||
|
#else
|
||||||
|
#define GL_GLEXT_PROTOTYPES 1
|
||||||
|
#include <SDL2/SDL_opengl.h>
|
||||||
|
#include <SDL2/SDL_opengl_glext.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(_OS_RPI) || defined(_OS_CLOVER)
|
#elif defined(_OS_RPI) || defined(_OS_CLOVER)
|
||||||
@@ -501,7 +505,7 @@ namespace GAPI {
|
|||||||
sprintf(defines + strlen(defines), "#define %s\n", DefineName[def[i]]);
|
sprintf(defines + strlen(defines), "#define %s\n", DefineName[def[i]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_OS_RPI) || defined(_OS_CLOVER)
|
#if defined(_OS_RPI) || defined(_OS_CLOVER) || (defined (__SDL2__) && defined (_GAPI_GLES))
|
||||||
strcat(defines, "#define OPT_VLIGHTPROJ\n");
|
strcat(defines, "#define OPT_VLIGHTPROJ\n");
|
||||||
strcat(defines, "#define OPT_VLIGHTVEC\n");
|
strcat(defines, "#define OPT_VLIGHTVEC\n");
|
||||||
strcat(defines, "#define OPT_SHADOW_ONETAP\n");
|
strcat(defines, "#define OPT_SHADOW_ONETAP\n");
|
||||||
|
@@ -1,15 +1,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <pthread.h>
|
|
||||||
#include <alsa/asoundlib.h>
|
|
||||||
|
|
||||||
// SDL2 include stuff
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#define GL_GLEXT_PROTOTYPES 1
|
|
||||||
#include <SDL2/SDL_opengles2.h>
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
|
|
||||||
@@ -25,84 +20,78 @@ int osGetTime() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sound
|
// sound
|
||||||
snd_pcm_uframes_t SND_FRAMES = 512;
|
|
||||||
snd_pcm_t *sndOut;
|
int SND_FRAMES = 512;
|
||||||
|
// A Frame is a struct containing: int16 L, int16 R.
|
||||||
Sound::Frame *sndData;
|
Sound::Frame *sndData;
|
||||||
pthread_t sndThread;
|
SDL_AudioDeviceID sdl_audiodev;
|
||||||
|
|
||||||
void* sndFill(void *arg) {
|
void sndFill(void *udata, Uint8 *stream, int len) {
|
||||||
while (sndOut) {
|
// Let's milk the audio subsystem for SND_FRAMES frames!
|
||||||
Sound::fill(sndData, SND_FRAMES);
|
Sound::fill(sndData, SND_FRAMES);
|
||||||
|
// We have the number of samples, but each sample is sizeof(Sound::Frame) bytes long,
|
||||||
int err = snd_pcm_writei(sndOut, sndData, SND_FRAMES);
|
// and memcpy copies a number of bytes.
|
||||||
if (err < 0) {
|
memcpy (stream, sndData, SND_FRAMES * sizeof(Sound::Frame));
|
||||||
LOG("! sound: write %s\n", snd_strerror(err));;
|
|
||||||
if (err != -EPIPE)
|
|
||||||
break;
|
|
||||||
|
|
||||||
err = snd_pcm_recover(sndOut, err, 0);
|
|
||||||
if (err < 0) {
|
|
||||||
LOG("! sound: failed to recover\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
snd_pcm_prepare(sndOut);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sndInit() {
|
bool sndInit() {
|
||||||
unsigned int freq = 44100;
|
int FREQ = 44100;
|
||||||
|
|
||||||
int err;
|
SDL_AudioSpec desired, obtained;
|
||||||
if ((err = snd_pcm_open(&sndOut, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
|
|
||||||
LOG("! sound: open %s\n", snd_strerror(err));\
|
desired.freq = FREQ;
|
||||||
sndOut = NULL;
|
desired.format = AUDIO_S16SYS;
|
||||||
|
desired.channels = 2;
|
||||||
|
desired.samples = SND_FRAMES;
|
||||||
|
desired.callback = sndFill;
|
||||||
|
desired.userdata = NULL;
|
||||||
|
|
||||||
|
sdl_audiodev = SDL_OpenAudioDevice(NULL, 0, &desired, &obtained, /*SDL_AUDIO_ALLOW_FORMAT_CHANGE*/0);
|
||||||
|
if (sdl_audiodev == 0)
|
||||||
|
{
|
||||||
|
LOG ("SDL2: error opening audio device: %s\n", SDL_GetError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_pcm_hw_params_t *params;
|
if (desired.samples != obtained.samples) {
|
||||||
|
LOG ("SDL2: number of samples not supported by device. Watch out for buggy audio drivers!\n");
|
||||||
snd_pcm_hw_params_alloca(¶ms);
|
return false;
|
||||||
snd_pcm_hw_params_any(sndOut, params);
|
|
||||||
snd_pcm_hw_params_set_access(sndOut, params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
|
||||||
|
|
||||||
snd_pcm_hw_params_set_channels(sndOut, params, 2);
|
|
||||||
snd_pcm_hw_params_set_format(sndOut, params, SND_PCM_FORMAT_S16_LE);
|
|
||||||
snd_pcm_hw_params_set_rate_near(sndOut, params, &freq, NULL);
|
|
||||||
|
|
||||||
snd_pcm_hw_params_set_periods(sndOut, params, 4, 0);
|
|
||||||
snd_pcm_hw_params_set_period_size_near(sndOut, params, &SND_FRAMES, NULL);
|
|
||||||
snd_pcm_hw_params_get_period_size(params, &SND_FRAMES, 0);
|
|
||||||
|
|
||||||
snd_pcm_hw_params(sndOut, params);
|
|
||||||
snd_pcm_prepare(sndOut);
|
|
||||||
|
|
||||||
sndData = new Sound::Frame[SND_FRAMES];
|
|
||||||
memset(sndData, 0, SND_FRAMES * sizeof(Sound::Frame));
|
|
||||||
if ((err = snd_pcm_writei(sndOut, sndData, SND_FRAMES)) < 0) {
|
|
||||||
LOG("! sound: write %s\n", snd_strerror(err));\
|
|
||||||
sndOut = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_pcm_start(sndOut);
|
// Initialize audio buffer and fill it with zeros
|
||||||
pthread_create(&sndThread, NULL, sndFill, NULL);
|
sndData = new Sound::Frame[SND_FRAMES];
|
||||||
|
memset(sndData, 0, SND_FRAMES * sizeof(Sound::Frame));
|
||||||
|
|
||||||
|
SDL_PauseAudioDevice(sdl_audiodev,0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sndFree() {
|
void sndFree() {
|
||||||
pthread_cancel(sndThread);
|
SDL_PauseAudioDevice(sdl_audiodev,1);
|
||||||
snd_pcm_drop(sndOut);
|
SDL_CloseAudioDevice(sdl_audiodev);
|
||||||
snd_pcm_drain(sndOut);
|
|
||||||
snd_pcm_close(sndOut);
|
// Delete the audio buffer
|
||||||
delete[] sndData;
|
delete[] sndData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input
|
// Input
|
||||||
SDL_GameController *sdl_gamecontroller;
|
|
||||||
SDL_Joystick *sdl_joystick;
|
#define MAX_JOYS 4
|
||||||
bool using_old_joystick_interface;
|
#define JOY_DEAD_ZONE_STICK 8192
|
||||||
|
#define WIN_W 640
|
||||||
|
#define WIN_H 480
|
||||||
|
|
||||||
|
struct sdl_input *sdl_inputs;
|
||||||
|
int sdl_numjoysticks, sdl_numcontrollers;
|
||||||
|
SDL_Joystick *sdl_joysticks[MAX_JOYS];
|
||||||
|
SDL_GameController *sdl_controllers[MAX_JOYS];
|
||||||
|
SDL_Window *sdl_window;
|
||||||
|
SDL_Renderer *sdl_renderer;
|
||||||
|
SDL_DisplayMode sdl_displaymode;
|
||||||
|
|
||||||
|
bool fullscreen;
|
||||||
|
bool l_alt, k_enter; // Is left ALT pressed? (For fullscreen toggle purposes)
|
||||||
|
|
||||||
vec2 joyL, joyR;
|
vec2 joyL, joyR;
|
||||||
|
|
||||||
@@ -114,6 +103,20 @@ void osJoyVibrate(int index, float L, float R) {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void toggleFullscreen () {
|
||||||
|
Uint32 flags = 0;
|
||||||
|
|
||||||
|
fullscreen = !fullscreen;
|
||||||
|
|
||||||
|
flags = fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0;
|
||||||
|
|
||||||
|
SDL_SetWindowFullscreen (sdl_window, flags);
|
||||||
|
|
||||||
|
// Tell the engine we have changed display size!
|
||||||
|
Core::width = fullscreen ? sdl_displaymode.w : WIN_W;
|
||||||
|
Core::height = fullscreen ? sdl_displaymode.h : WIN_H;
|
||||||
|
}
|
||||||
|
|
||||||
InputKey codeToInputKey(int code) {
|
InputKey codeToInputKey(int code) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
// keyboard
|
// keyboard
|
||||||
@@ -123,13 +126,21 @@ InputKey codeToInputKey(int code) {
|
|||||||
case SDL_SCANCODE_DOWN : return ikDown;
|
case SDL_SCANCODE_DOWN : return ikDown;
|
||||||
case SDL_SCANCODE_SPACE : return ikSpace;
|
case SDL_SCANCODE_SPACE : return ikSpace;
|
||||||
case SDL_SCANCODE_TAB : return ikTab;
|
case SDL_SCANCODE_TAB : return ikTab;
|
||||||
case SDL_SCANCODE_RETURN : return ikEnter;
|
|
||||||
|
case SDL_SCANCODE_RETURN : {
|
||||||
|
k_enter = !k_enter;
|
||||||
|
if (l_alt && k_enter) {
|
||||||
|
toggleFullscreen();
|
||||||
|
}
|
||||||
|
else return ikEnter;
|
||||||
|
}
|
||||||
|
|
||||||
case SDL_SCANCODE_ESCAPE : return ikEscape;
|
case SDL_SCANCODE_ESCAPE : return ikEscape;
|
||||||
case SDL_SCANCODE_LSHIFT :
|
case SDL_SCANCODE_LSHIFT :
|
||||||
case SDL_SCANCODE_RSHIFT : return ikShift;
|
case SDL_SCANCODE_RSHIFT : return ikShift;
|
||||||
case SDL_SCANCODE_LCTRL :
|
case SDL_SCANCODE_LCTRL :
|
||||||
case SDL_SCANCODE_RCTRL : return ikCtrl;
|
case SDL_SCANCODE_RCTRL : return ikCtrl;
|
||||||
case SDL_SCANCODE_LALT :
|
case SDL_SCANCODE_LALT : { l_alt = !l_alt; } // We toggle l_alt being pushed.
|
||||||
case SDL_SCANCODE_RALT : return ikAlt;
|
case SDL_SCANCODE_RALT : return ikAlt;
|
||||||
case SDL_SCANCODE_0 : return ik0;
|
case SDL_SCANCODE_0 : return ik0;
|
||||||
case SDL_SCANCODE_1 : return ik1;
|
case SDL_SCANCODE_1 : return ik1;
|
||||||
@@ -172,9 +183,9 @@ InputKey codeToInputKey(int code) {
|
|||||||
return ikNone;
|
return ikNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
JoyKey codeToJoyKey(int code) {
|
JoyKey controllerCodeToJoyKey(int code) {
|
||||||
|
// joystick using the modern SDL GameController interface
|
||||||
switch (code) {
|
switch (code) {
|
||||||
// gamepad
|
|
||||||
case SDL_CONTROLLER_BUTTON_A : return jkA;
|
case SDL_CONTROLLER_BUTTON_A : return jkA;
|
||||||
case SDL_CONTROLLER_BUTTON_B : return jkB;
|
case SDL_CONTROLLER_BUTTON_B : return jkB;
|
||||||
case SDL_CONTROLLER_BUTTON_X : return jkX;
|
case SDL_CONTROLLER_BUTTON_X : return jkX;
|
||||||
@@ -189,34 +200,55 @@ JoyKey codeToJoyKey(int code) {
|
|||||||
return jkNone;
|
return jkNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JoyKey joyCodeToJoyKey(int buttonNumber) {
|
||||||
|
// joystick using the classic SDL Joystick interface
|
||||||
|
switch (buttonNumber) {
|
||||||
|
case 0 : return jkY;
|
||||||
|
case 1 : return jkB;
|
||||||
|
case 2 : return jkA;
|
||||||
|
case 3 : return jkX;
|
||||||
|
case 4 : return jkL;
|
||||||
|
case 5 : return jkR;
|
||||||
|
case 6 : return jkLB;
|
||||||
|
case 7 : return jkRB;
|
||||||
|
case 8 : return jkSelect;
|
||||||
|
case 9 : return jkStart;
|
||||||
|
}
|
||||||
|
return jkNone;
|
||||||
|
}
|
||||||
|
|
||||||
bool inputInit() {
|
bool inputInit() {
|
||||||
sdl_gamecontroller = NULL;
|
int i;
|
||||||
sdl_joystick = NULL;
|
joyL = joyR = vec2(0);
|
||||||
if (SDL_NumJoysticks() > 0) {
|
sdl_numjoysticks = SDL_NumJoysticks();
|
||||||
if(SDL_IsGameController(0)) {
|
sdl_numjoysticks = (sdl_numjoysticks < MAX_JOYS )? sdl_numjoysticks : MAX_JOYS;
|
||||||
sdl_gamecontroller = SDL_GameControllerOpen(0);
|
l_alt = false;
|
||||||
|
k_enter = false;
|
||||||
|
|
||||||
|
for (i = 0; i < sdl_numjoysticks; i++) {
|
||||||
|
if(SDL_IsGameController(i)) {
|
||||||
|
SDL_GameController *controller = SDL_GameControllerOpen(i);
|
||||||
|
sdl_joysticks[i] = SDL_GameControllerGetJoystick(controller);
|
||||||
|
sdl_controllers[i] = controller;
|
||||||
|
sdl_numcontrollers++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sdl_joystick = SDL_JoystickOpen(0);
|
sdl_joysticks[i] = SDL_JoystickOpen(i);
|
||||||
using_old_joystick_interface = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void inputFree() {
|
void inputFree() {
|
||||||
if (sdl_gamecontroller != NULL) {
|
int i;
|
||||||
SDL_GameControllerClose(sdl_gamecontroller);
|
for (i = 0; i < sdl_numcontrollers; i++) {
|
||||||
sdl_gamecontroller = NULL;
|
SDL_GameControllerClose(sdl_controllers[i]);
|
||||||
}
|
}
|
||||||
if (sdl_joystick != NULL) {
|
for (i = 0; i < sdl_numjoysticks; i++) {
|
||||||
SDL_JoystickClose(sdl_joystick);
|
SDL_JoystickClose(sdl_joysticks[i]);
|
||||||
sdl_joystick = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define JOY_DEAD_ZONE_STICK 8192
|
|
||||||
|
|
||||||
float joyAxisValue(int value) {
|
float joyAxisValue(int value) {
|
||||||
if (value > -JOY_DEAD_ZONE_STICK && value < JOY_DEAD_ZONE_STICK)
|
if (value > -JOY_DEAD_ZONE_STICK && value < JOY_DEAD_ZONE_STICK)
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
@@ -232,12 +264,22 @@ vec2 joyDir(const vec2 &value) {
|
|||||||
return value.normal() * dist;
|
return value.normal() * dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getJoyIndex(SDL_JoystickID id) {
|
||||||
|
int i;
|
||||||
|
for (i=0 ; i < sdl_numjoysticks; i++) {
|
||||||
|
if (SDL_JoystickInstanceID(sdl_joysticks[i]) == id) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void inputUpdate() {
|
void inputUpdate() {
|
||||||
// get input events
|
// get input events
|
||||||
|
|
||||||
int joyIndex = 0; // TODO: joy index
|
int joyIndex;
|
||||||
|
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|
||||||
while (SDL_PollEvent(&event) == 1) { // while there are still events to be processed
|
while (SDL_PollEvent(&event) == 1) { // while there are still events to be processed
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case SDL_KEYDOWN: {
|
case SDL_KEYDOWN: {
|
||||||
@@ -256,85 +298,98 @@ void inputUpdate() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Joystick reading using the modern GameController interface
|
||||||
case SDL_CONTROLLERBUTTONDOWN: {
|
case SDL_CONTROLLERBUTTONDOWN: {
|
||||||
JoyKey key = codeToJoyKey(event.cbutton.button);
|
joyIndex = getJoyIndex(event.cbutton.which);
|
||||||
|
JoyKey key = controllerCodeToJoyKey(event.cbutton.button);
|
||||||
Input::setJoyDown(joyIndex, key, 1);
|
Input::setJoyDown(joyIndex, key, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDL_CONTROLLERBUTTONUP: {
|
case SDL_CONTROLLERBUTTONUP: {
|
||||||
JoyKey key = codeToJoyKey(event.cbutton.button);
|
joyIndex = getJoyIndex(event.cbutton.which);
|
||||||
|
JoyKey key = controllerCodeToJoyKey(event.cbutton.button);
|
||||||
Input::setJoyDown(joyIndex, key, 0);
|
Input::setJoyDown(joyIndex, key, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SDL_CONTROLLERAXISMOTION: {
|
case SDL_CONTROLLERAXISMOTION: {
|
||||||
|
joyIndex = getJoyIndex(event.caxis.which);
|
||||||
switch (event.caxis.axis) {
|
switch (event.caxis.axis) {
|
||||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
case SDL_CONTROLLER_AXIS_LEFTX: joyL.x = joyAxisValue(event.caxis.value); break;
|
||||||
if (event.caxis.value < 0) {
|
case SDL_CONTROLLER_AXIS_LEFTY: joyL.y = joyAxisValue(event.caxis.value); break;
|
||||||
Input::setJoyDown(joyIndex, jkLeft, 1);
|
case SDL_CONTROLLER_AXIS_RIGHTX: joyR.x = joyAxisValue(event.caxis.value); break;
|
||||||
Input::setJoyDown(joyIndex, jkRight, 0);
|
case SDL_CONTROLLER_AXIS_RIGHTY: joyR.y = joyAxisValue(event.caxis.value); break;
|
||||||
}
|
}
|
||||||
if (event.caxis.value > 0) {
|
|
||||||
Input::setJoyDown(joyIndex, jkRight, 1);
|
|
||||||
Input::setJoyDown(joyIndex, jkLeft, 0);
|
|
||||||
}
|
|
||||||
if (event.caxis.value == 0) {
|
|
||||||
Input::setJoyDown(joyIndex, jkRight, 0);
|
|
||||||
Input::setJoyDown(joyIndex, jkLeft, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
|
||||||
if (event.caxis.value < 0) {
|
|
||||||
Input::setJoyDown(joyIndex, jkUp, 1);
|
|
||||||
Input::setJoyDown(joyIndex, jkDown, 0);
|
|
||||||
}
|
|
||||||
if (event.caxis.value > 0) {
|
|
||||||
Input::setJoyDown(joyIndex, jkUp, 0);
|
|
||||||
Input::setJoyDown(joyIndex, jkDown, 1);
|
|
||||||
}
|
|
||||||
if (event.caxis.value == 0) {
|
|
||||||
Input::setJoyDown(joyIndex, jkUp, 0);
|
|
||||||
Input::setJoyDown(joyIndex, jkDown, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Input::setJoyPos(joyIndex, jkL, joyDir(joyL));
|
Input::setJoyPos(joyIndex, jkL, joyDir(joyL));
|
||||||
Input::setJoyPos(joyIndex, jkR, joyDir(joyR));
|
Input::setJoyPos(joyIndex, jkR, joyDir(joyR));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Joystick reading using the classic Joystick interface
|
||||||
|
case SDL_JOYBUTTONDOWN: {
|
||||||
|
joyIndex = getJoyIndex(event.jbutton.which);
|
||||||
|
JoyKey key = joyCodeToJoyKey(event.jbutton.button);
|
||||||
|
Input::setJoyDown(joyIndex, key, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_JOYBUTTONUP: {
|
||||||
|
joyIndex = getJoyIndex(event.jbutton.which);
|
||||||
|
JoyKey key = joyCodeToJoyKey(event.jbutton.button);
|
||||||
|
Input::setJoyDown(joyIndex, key, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_JOYAXISMOTION: {
|
||||||
|
joyIndex = getJoyIndex(event.jaxis.which);
|
||||||
|
switch (event.jaxis.axis) {
|
||||||
|
// In the classic joystick interface we know what axis changed by it's number,
|
||||||
|
// they have no names like on the fancy GameController interface.
|
||||||
|
case 0: joyL.x = joyAxisValue(event.jaxis.value); break;
|
||||||
|
case 1: joyL.y = joyAxisValue(event.jaxis.value); break;
|
||||||
|
case 2: joyR.x = joyAxisValue(event.jaxis.value); break;
|
||||||
|
case 3: joyR.y = joyAxisValue(event.jaxis.value); break;
|
||||||
|
}
|
||||||
|
Input::setJoyPos(joyIndex, jkL, joyDir(joyL));
|
||||||
|
Input::setJoyPos(joyIndex, jkR, joyDir(joyR));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
int w, h;
|
int w, h;
|
||||||
SDL_DisplayMode current;
|
|
||||||
|
|
||||||
|
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_EVENTS|SDL_INIT_GAMECONTROLLER);
|
||||||
|
|
||||||
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_EVENTS|SDL_INIT_GAMECONTROLLER);
|
SDL_GetCurrentDisplayMode(0, &sdl_displaymode);
|
||||||
|
|
||||||
SDL_GetCurrentDisplayMode(0, ¤t);
|
#ifdef _GAPI_GLES
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||||
|
#endif
|
||||||
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||||
|
|
||||||
// We start in fullscreen mode using the vide mode currently in use, to avoid video mode changes.
|
// We start in fullscreen mode using the vide mode currently in use, to avoid video mode changes.
|
||||||
SDL_Window *window = SDL_CreateWindow(WND_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
sdl_window = SDL_CreateWindow(WND_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||||
//current.w, current.h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN_DESKTOP);
|
//sdl_displaymode.w, sdl_displaymode.h, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||||
640, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
|
WIN_W, WIN_H, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
|
||||||
|
|
||||||
// We try to use the current video mode, but we inform the core of whatever mode SDL2 gave us in the end.
|
// We try to use the current video mode, but we inform the core of whatever mode SDL2 gave us in the end.
|
||||||
SDL_GetWindowSize(window, &w, &h);
|
SDL_GetWindowSize(sdl_window, &w, &h);
|
||||||
|
|
||||||
Core::width = w;
|
Core::width = w;
|
||||||
Core::height = h;
|
Core::height = h;
|
||||||
|
|
||||||
SDL_GLContext context = SDL_GL_CreateContext(window);
|
SDL_GLContext context = SDL_GL_CreateContext(sdl_window);
|
||||||
SDL_GL_SetSwapInterval(0);
|
SDL_GL_SetSwapInterval(0);
|
||||||
|
|
||||||
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1,
|
sdl_renderer = SDL_CreateRenderer(sdl_window, -1,
|
||||||
SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
|
SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
|
||||||
|
|
||||||
SDL_ShowCursor(SDL_DISABLE);
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
@@ -370,15 +425,15 @@ int main(int argc, char **argv) {
|
|||||||
if (Game::update()) {
|
if (Game::update()) {
|
||||||
Game::render();
|
Game::render();
|
||||||
Core::waitVBlank();
|
Core::waitVBlank();
|
||||||
SDL_GL_SwapWindow(window);
|
SDL_GL_SwapWindow(sdl_window);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
sndFree();
|
sndFree();
|
||||||
Game::deinit();
|
Game::deinit();
|
||||||
|
|
||||||
SDL_DestroyRenderer(renderer);
|
SDL_DestroyRenderer(sdl_renderer);
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(sdl_window);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user