PANDORA: Port to SDL

This commit is contained in:
ptitSeb 2013-12-21 13:30:28 +01:00
parent 0142a93a5f
commit 0e83f2a6e3
3 changed files with 564 additions and 3 deletions

View File

@ -30,7 +30,11 @@ ifdef FOR_ANDROID
endif
ifdef FOR_LINUX
ifdef USE_SDL
RZDCY_MODULES += sdl/
else
RZDCY_MODULES += linux-dist/
endif
endif
RZDCY_FILES := $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.cpp))

539
newdc/sdl/main.cpp Executable file
View File

@ -0,0 +1,539 @@
#include "types.h"
#include "cfg/cfg.h"
#include <poll.h>
#include <termios.h>
//#include <curses.h>
#include <fcntl.h>
#include <semaphore.h>
#include <stdarg.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/mman.h>
#include <sys/time.h>
#include "hw/sh4/dyna/blockmanager.h"
#include <unistd.h>
#include <SDL/SDL.h>
#include <EGL/egl.h>
#ifdef USE_OSS
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#endif
#include <signal.h>
#include <execinfo.h>
#ifdef TARGET_PANDORA
#define WINDOW_WIDTH 800
#else
#define WINDOW_WIDTH 640
#endif
#define WINDOW_HEIGHT 480
void* x11_win=(NativeWindowType)NULL,* x11_disp=EGL_DEFAULT_DISPLAY;
SDL_Surface *screen=NULL;
void* libPvr_GetRenderTarget()
{
return x11_win;
}
void* libPvr_GetRenderSurface()
{
return x11_disp;
}
int msgboxf(const wchar* text,unsigned int type,...)
{
va_list args;
wchar temp[2048];
va_start(args, type);
vsprintf(temp, text, args);
va_end(args);
//printf(NULL,temp,VER_SHORTNAME,type | MB_TASKMODAL);
puts(temp);
return MBX_OK;
}
u16 kcode[4];
u32 vks[4];
s8 joyx[4],joyy[4];
u8 rt[4],lt[4];
enum DCPad {
Btn_C = 1,
Btn_B = 1<<1,
Btn_A = 1<<2,
Btn_Start = 1<<3,
DPad_Up = 1<<4,
DPad_Down = 1<<5,
DPad_Left = 1<<6,
DPad_Right = 1<<7,
Btn_Z = 1<<8,
Btn_Y = 1<<9,
Btn_X = 1<<10,
Btn_D = 1<<11,
DPad2_Up = 1<<12,
DPad2_Down = 1<<13,
DPad2_Left = 1<<14,
DPad2_Right = 1<<15,
Axis_LT= 0x10000,
Axis_RT= 0x10001,
Axis_X= 0x20000,
Axis_Y= 0x20001,
};
void emit_WriteCodeCache();
static SDL_Joystick *JoySDL = 0;
#ifdef USE_OSS
static int audio_fd = -1;
#endif
#define MAP_SIZE 32
const u32 JMapBtn_USB[MAP_SIZE] =
{ Btn_Y,Btn_B,Btn_A,Btn_X,0,0,0,0,0,Btn_Start };
const u32 JMapAxis_USB[MAP_SIZE] =
{ Axis_X,Axis_Y,0,0,0,0,0,0,0,0 };
const u32 JMapBtn_360[MAP_SIZE] =
{ Btn_A,Btn_B,Btn_X,Btn_Y,0,0,0,Btn_Start,0,0 };
const u32 JMapAxis_360[MAP_SIZE] =
{ Axis_X,Axis_Y,Axis_LT,0,0,Axis_RT,DPad_Left,DPad_Up,0,0 };
const u32* JMapBtn=JMapBtn_USB;
const u32* JMapAxis=JMapAxis_USB;
void SetupInput()
{
for (int port=0;port<4;port++)
{
kcode[port]=0xFFFF;
rt[port]=0;
lt[port]=0;
}
// Open joystick device
int numjoys = SDL_NumJoysticks();
if (numjoys > 0)
JoySDL = SDL_JoystickOpen(0);
if(JoySDL)
{
int AxisCount,ButtonCount;
char* Name;
AxisCount = 0;
ButtonCount = 0;
Name[0] = '\0';
AxisCount = SDL_JoystickNumAxes(JoySDL);
ButtonCount = SDL_JoystickNumButtons(JoySDL);
Name = SDL_JoystickName(JoySDL);
printf("SDK: Found '%s' joystick with %d axis and %d buttons\n",Name,AxisCount,ButtonCount);
if (strcmp(Name,"Microsoft X-Box 360 pad")==0)
{
JMapBtn=JMapBtn_360;
JMapAxis=JMapAxis_360;
printf("Using Xbox 360 map\n");
}
}
}
bool HandleEvents(u32 port) {
static int keys[13];
SDL_Event event;
int k, value;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
die("death by SDL request");
break;
case SDL_KEYDOWN:
case SDL_KEYUP:
k = event.key.keysym.sym;
value = (event.type==SDL_KEYDOWN)?1:0;
//printf("type %i key %i \n", event.type, k);
switch (k) {
#if defined(TARGET_PANDORA)
case SDLK_SPACE: keys[0]=value; break;
case SDLK_UP: keys[1]=value; break;
case SDLK_DOWN: keys[2]=value; break;
case SDLK_LEFT: keys[3]=value; break;
case SDLK_RIGHT: keys[4]=value; break;
case SDLK_PAGEUP: keys[5]=value; break;
case SDLK_PAGEDOWN: keys[6]=value; break;
case SDLK_END: keys[7]=value; break;
case SDLK_HOME: keys[8]=value; break;
case SDLK_MENU:
case SDLK_ESCAPE: keys[9]=value; break;
case SDLK_RSHIFT: keys[10]=value; break;
case SDLK_RCTRL: keys[11]=value; break;
case SDLK_LALT: keys[12]=value; break;
#else
#error *TODO*
#endif
}
break;
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
value = (event.type==SDL_JOYBUTTONDOWN)?1:0;
k = event.jbutton.button;
{
u32 mt=JMapBtn[k]>>16;
u32 mo=JMapBtn[k]&0xFFFF;
// printf("BUTTON %d,%d\n",JE.number,JE.value);
if (mt==0)
{
// printf("Mapped to %d\n",mo);
if (value)
kcode[port]&=~mo;
else
kcode[port]|=mo;
}
else if (mt==1)
{
// printf("Mapped to %d %d\n",mo,JE.value?255:0);
if (mo==0)
lt[port]=value?255:0;
else if (mo==1)
rt[port]=value?255:0;
}
}
break;
case SDL_JOYAXISMOTION:
k = event.jaxis.axis;
value = event.jaxis.value;
{
u32 mt=JMapAxis[k]>>16;
u32 mo=JMapAxis[k]&0xFFFF;
//printf("AXIS %d,%d\n",JE.number,JE.value);
s8 v=(s8)(value/256); //-127 ... + 127 range
if (mt==0)
{
kcode[port]|=mo;
kcode[port]|=mo*2;
if (v<-64)
{
kcode[port]&=~mo;
}
else if (v>64)
{
kcode[port]&=~(mo*2);
}
// printf("Mapped to %d %d %d\n",mo,kcode[port]&mo,kcode[port]&(mo*2));
}
else if (mt==1)
{
if (v>=0) v++; //up to 255
// printf("AXIS %d,%d Mapped to %d %d %d\n",JE.number,JE.value,mo,v,v+127);
if (mo==0)
lt[port]=v+127;
else if (mo==1)
rt[port]=v+127;
}
else if (mt==2)
{
// printf("AXIS %d,%d Mapped to %d %d [%d]",JE.number,JE.value,mo,v);
if (mo==0)
joyx[port]=v;
else if (mo==1)
joyy[port]=v;
}
}
break;
}
}
if (keys[0]) { kcode[port] &= ~Btn_C; }
if (keys[6]) { kcode[port] &= ~Btn_A; }
if (keys[7]) { kcode[port] &= ~Btn_B; }
if (keys[5]) { kcode[port] &= ~Btn_Y; }
if (keys[8]) { kcode[port] &= ~Btn_X; }
if (keys[1]) { kcode[port] &= ~DPad_Up; }
if (keys[2]) { kcode[port] &= ~DPad_Down; }
if (keys[3]) { kcode[port] &= ~DPad_Left; }
if (keys[4]) { kcode[port] &= ~DPad_Right; }
if (keys[12]){ kcode[port] &= ~Btn_Start; }
if (keys[9]){ die("death by escape key"); }
if (keys[10]) rt[port]=255;
if (keys[11]) lt[port]=255;
return true;
}
/*
bool HandleJoystick(u32 port)
{
struct js_event JE;
// Joystick must be connected
if(JoyFD<0) return false;
while(read(JoyFD,&JE,sizeof(JE))==sizeof(JE))
if (JE.number<MAP_SIZE)
{
switch(JE.type & ~JS_EVENT_INIT)
{
case JS_EVENT_AXIS:
{
u32 mt=JMapAxis[JE.number]>>16;
u32 mo=JMapAxis[JE.number]&0xFFFF;
//printf("AXIS %d,%d\n",JE.number,JE.value);
s8 v=(s8)(JE.value/256); //-127 ... + 127 range
if (mt==0)
{
kcode[port]|=mo;
kcode[port]|=mo*2;
if (v<-64)
{
kcode[port]&=~mo;
}
else if (v>64)
{
kcode[port]&=~(mo*2);
}
// printf("Mapped to %d %d %d\n",mo,kcode[port]&mo,kcode[port]&(mo*2));
}
else if (mt==1)
{
if (v>=0) v++; //up to 255
// printf("AXIS %d,%d Mapped to %d %d %d\n",JE.number,JE.value,mo,v,v+127);
if (mo==0)
lt[port]=v+127;
else if (mo==1)
rt[port]=v+127;
}
else if (mt==2)
{
// printf("AXIS %d,%d Mapped to %d %d [%d]",JE.number,JE.value,mo,v);
if (mo==0)
joyx[port]=v;
else if (mo==1)
joyy[port]=v;
}
}
break;
case JS_EVENT_BUTTON:
{
u32 mt=JMapBtn[JE.number]>>16;
u32 mo=JMapBtn[JE.number]&0xFFFF;
// printf("BUTTON %d,%d\n",JE.number,JE.value);
if (mt==0)
{
// printf("Mapped to %d\n",mo);
if (JE.value)
kcode[port]&=~mo;
else
kcode[port]|=mo;
}
else if (mt==1)
{
// printf("Mapped to %d %d\n",mo,JE.value?255:0);
if (mo==0)
lt[port]=JE.value?255:0;
else if (mo==1)
rt[port]=JE.value?255:0;
}
}
break;
}
}
return true;
}
*/
extern bool KillTex;
void UpdateInputState(u32 port)
{
static char key = 0;
kcode[port]=0xFFFF;
rt[port]=0;
lt[port]=0;
HandleEvents(port);
}
void os_DoEvents()
{
}
void os_SetWindowText(const char * text)
{
SDL_WM_SetCaption(text, NULL); // *TODO* Set Icon also...
}
int ndcid=0;
void os_CreateWindow()
{
#ifdef TARGET_PANDORA
int width=800;
int height=480;
int flags=SDL_FULLSCREEN;
#else
int width=cfgLoadInt("x11","width", WINDOW_WIDTH);
int height=cfgLoadInt("x11","height", WINDOW_HEIGHT);
int flags=SDL_SWSURFACE;
#endif
screen = SDL_SetVideoMode(width, height, 0, flags);
if (!screen)
die("error creating SDL screen");
printf("Created SDL Windows (%ix%i) successfully\n", width, height);
}
void common_linux_setup();
int dc_init(int argc,wchar* argv[]);
void dc_run();
void gl_term();
void clean_exit(int sig_num) {
void *array[10];
size_t size;
// close files
if (JoySDL) SDL_JoystickClose(JoySDL);
#ifdef USE_OSS
if (audio_fd>=0) close(audio_fd);
#endif
// Close EGL context ???
if (sig_num!=0)
gl_term();
SDL_Quit();
// finish cleaning
if (sig_num!=0) {
write(2, "\nSignal received\n", sizeof("\nSignal received\n"));
size = backtrace(array, 10);
backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(1);
}
}
#ifdef USE_OSS
void init_sound()
{
if((audio_fd=open("/dev/dsp",O_WRONLY))<0)
printf("Couldn't open /dev/dsp.\n");
else
{
printf("sound enabled, dsp openned for write\n");
int tmp=44100;
int err_ret;
err_ret=ioctl(audio_fd,SNDCTL_DSP_SPEED,&tmp);
printf("set Frequency to %i, return %i (rate=%i)\n", 44100, err_ret, tmp);
int channels=2;
err_ret=ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels);
printf("set dsp to stereo (%i => %i)\n", channels, err_ret);
int format=AFMT_S16_LE;
err_ret=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format);
printf("set dsp to %s audio (%i/%i => %i)\n", "16bits signed" ,AFMT_S16_LE, format, err_ret);
/*
// this doesn't help stutering, and the emu goes too fast after that
err_ret=ioctl(audio_fd, SNDCTL_DSP_NONBLOCK, NULL);
printf("set dsp to non-blocking ( => %i)\n", err_ret);
*/
}
}
#endif
int main(int argc, wchar* argv[])
{
//if (argc==2)
//ndcid=atoi(argv[1]);
signal(SIGSEGV, clean_exit);
signal(SIGKILL, clean_exit);
#ifdef USE_OSS
init_sound();
#endif
#if defined(USES_HOMEDIR)
string home = (string)getenv("HOME");
if(home.c_str())
{
home += "/.reicast";
mkdir(home.c_str(), 0755); // create the directory if missing
SetHomeDir(home);
}
else
SetHomeDir(".");
#else
SetHomeDir(".");
#endif
printf("Home dir is: %s\n",GetPath("/").c_str());
common_linux_setup();
printf("common linux setup done\n");
/*
// The SDL_Init prevent mprotect from working correctly ?!!!
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK|SDL_INIT_NOPARACHUTE)==-1)
die("error initializing SDL");
*/
SetupInput();
settings.profile.run_counts=0;
dc_init(argc,argv);
dc_run();
clean_exit(0);
return 0;
}
u32 os_Push(void* frame, u32 samples, bool wait)
{
#ifdef USE_OSS
write(audio_fd, frame, samples*4);
#endif
return 1;
}

View File

@ -3,6 +3,8 @@ LOCAL_PATH := $(call my-dir)
FOR_LINUX :=1
FOR_ARM :=1
FOR_PANDORA :=1
USE_SDL :=1
USE_OSS :=1
RZDCY_SRC_DIR = ../../newdc
@ -35,6 +37,9 @@ CXXFLAGS += -ffast-math -ftree-vectorize -fprefetch-loop-arrays
CXXFLAGS += $(CFLAGS) $(MFLAGS) -fno-exceptions -fno-rtti
CXXFLAGS += -D SUPPORT_X11
ifdef USE_SDL
CXXFLAGS += `sdl-config --cflags`
endif
ifdef PGO_MAKE
CXXFLAGS += -fprofile-generate -pg
@ -57,8 +62,21 @@ INCS := -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps -I$(RZDCY_SRC_DIR)/khronos
#-I../linux-deps/include
LIBS := -L../linux-deps/lib
LIBS += -lm -lrt -lEGL -lGLESv2 #-lglslcompiler -lIMGegl -lpvr2d -lsrv_um
LIBS += -lpthread -lasound -lX11 -lXdmcp -lXau
LIBS += -lm -lrt -lEGL -lGLESv2
#-lglslcompiler -lIMGegl -lpvr2d -lsrv_um
LIBS += -lpthread
ifdef USE_OSS
CXXFLAGS += -DUSE_OSS
else
LIBS += -lasound
endif
ifdef USE_SDL
LIBS += `sdl-config --libs`
else
LIBS += -lX11 -lXdmcp -lXau
endif
OBJECTS=$(RZDCY_FILES:.cpp=.build_obj)