diff --git a/newdc/build.h b/newdc/build.h old mode 100644 new mode 100755 index 2e229816f..d3eca9a72 --- a/newdc/build.h +++ b/newdc/build.h @@ -45,7 +45,7 @@ #define COMPILER_GCC 0x30000002 /// -#if (!defined(TARGET_WIN86) && !defined(TARGET_BEAGLE) && !defined(TARGET_NACL32) && !defined(TARGET_GCW0)) +#if (!defined(TARGET_WIN86) && !defined(TARGET_BEAGLE) && !defined(TARGET_NACL32) && !defined(TARGET_GCW0) && !defined(TARGET_PANDORA)) #define TARGET_WIN86 #endif @@ -53,6 +53,10 @@ #define HOST_OS OS_WINDOWS #define HOST_CPU CPU_X86 #define BUILD_COMPILER COMPILER_VC +#elif TARGET_PANDORA + #define HOST_OS OS_LINUX + #define HOST_CPU CPU_ARM + #define BUILD_COMPILER COMPILER_GCC #elif TARGET_BEAGLE #define HOST_OS OS_LINUX #define HOST_CPU CPU_ARM diff --git a/newdc/linux-dist/main.cpp b/newdc/linux-dist/main.cpp old mode 100644 new mode 100755 index 3ce119738..648fd0aef --- a/newdc/linux-dist/main.cpp +++ b/newdc/linux-dist/main.cpp @@ -28,10 +28,18 @@ #include #endif +#ifdef TARGET_PANDORA +#include +#include +#include + +#define WINDOW_WIDTH 800 +#else #define WINDOW_WIDTH 640 +#endif #define WINDOW_HEIGHT 480 -void* x11_win,* x11_disp; +void* x11_win=0,* x11_disp=0; void* libPvr_GetRenderTarget() { return x11_win; @@ -92,6 +100,10 @@ void emit_WriteCodeCache(); static int JoyFD = -1; // Joystick file descriptor static int kbfd = -1; +#ifdef TARGET_PANDORA +static int audio_fd = -1; +#endif + #define MAP_SIZE 32 @@ -121,7 +133,11 @@ void SetupInput() } if (true) { + #ifdef TARGET_PANDORA + const char* device = "/dev/input/event4"; + #else const char* device = "/dev/event2"; + #endif char name[256]= "Unknown"; if ((kbfd = open(device, O_RDONLY)) > 0) { @@ -170,9 +186,48 @@ bool HandleKb(u32 port) { if (kbfd < 0) return false; + #ifdef TARGET_PANDORA + static int keys[13]; + while(read(kbfd,&ie,sizeof(ie))==sizeof(ie)) { + if (ie.type=EV_KEY) + //printf("type %i key %i state %i\n", ie.type, ie.code, ie.value); + switch (ie.code) { + case KEY_SPACE: keys[0]=ie.value; break; + case KEY_UP: keys[1]=ie.value; break; + case KEY_DOWN: keys[2]=ie.value; break; + case KEY_LEFT: keys[3]=ie.value; break; + case KEY_RIGHT: keys[4]=ie.value; break; + case KEY_PAGEUP:keys[5]=ie.value; break; + case KEY_PAGEDOWN:keys[6]=ie.value; break; + case KEY_END: keys[7]=ie.value; break; + case KEY_HOME: keys[8]=ie.value; break; + case KEY_MENU: keys[9]=ie.value; break; + case KEY_RIGHTSHIFT: keys[10]=ie.value; break; + case KEY_RIGHTCTRL: keys[11]=ie.value; break; + case KEY_LEFTALT: keys[12]=ie.value; 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; + #else while(read(kbfd,&ie,sizeof(ie))==sizeof(ie)) { printf("type %i key %i state %i\n", ie.type, ie.code, ie.value); } + #endif } @@ -268,16 +323,40 @@ bool HandleJoystick(u32 port) extern bool KillTex; +#ifdef TARGET_PANDORA +static Cursor CreateNullCursor(Display *display, Window root) +{ + Pixmap cursormask; + XGCValues xgc; + GC gc; + XColor dummycolour; + Cursor cursor; + + cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); + xgc.function = GXclear; + gc = XCreateGC(display, cursormask, GCFunction, &xgc); + XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); + dummycolour.pixel = 0; + dummycolour.red = 0; + dummycolour.flags = 04; + cursor = XCreatePixmapCursor(display, cursormask, cursormask, + &dummycolour,&dummycolour, 0,0); + XFreePixmap(display,cursormask); + XFreeGC(display,gc); + return cursor; +} +#endif + void UpdateInputState(u32 port) { static char key = 0; - if (HandleJoystick(port)) return; - if (HandleKb(port)) return; - kcode[port]=0xFFFF; rt[port]=0; lt[port]=0; + + if (HandleJoystick(port)) return; + if (HandleKb(port)) return; for(;;) { @@ -287,6 +366,17 @@ void UpdateInputState(u32 port) if (0 == key || EOF == key) break; if ('k' == key) KillTex=true; +#ifdef TARGET_PANDORA + if (' ' == key) { kcode[port] &= ~Btn_C; } + if ('6' == key) { kcode[port] &= ~Btn_A; } + if ('O' == key) { kcode[port] &= ~Btn_B; } + if ('5' == key) { kcode[port] &= ~Btn_Y; } + if ('H' == key) { kcode[port] &= ~Btn_X; } + if ('A' == key) { kcode[port] &= ~DPad_Up; } + if ('B' == key) { kcode[port] &= ~DPad_Down; } + if ('D' == key) { kcode[port] &= ~DPad_Left; } + if ('C' == key) { kcode[port] &= ~DPad_Right; } +#else if ('b' == key) { kcode[port] &= ~Btn_C; } if ('v' == key) { kcode[port] &= ~Btn_A; } if ('c' == key) { kcode[port] &= ~Btn_B; } @@ -296,8 +386,11 @@ void UpdateInputState(u32 port) if ('k' == key) { kcode[port] &= ~DPad_Down; } if ('j' == key) { kcode[port] &= ~DPad_Left; } if ('l' == key) { kcode[port] &= ~DPad_Right; } - +#endif if (0x0A== key) { kcode[port] &= ~Btn_Start; } +#ifdef TARGET_PANDORA + if ('q' == key){ die("death by escape key"); } +#endif //if (0x1b == key){ die("death by escape key"); } //this actually quits when i press left for some reason if ('a' == key) rt[port]=255; @@ -311,7 +404,6 @@ void UpdateInputState(u32 port) } } - void os_DoEvents() { @@ -379,8 +471,13 @@ void os_CreateWindow() sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask; ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap; + #ifdef TARGET_PANDORA + int width=800; + int height=480; + #else int width=cfgLoadInt("x11","width", WINDOW_WIDTH); int height=cfgLoadInt("x11","height", WINDOW_HEIGHT); + #endif if (width==-1) { @@ -390,9 +487,20 @@ void os_CreateWindow() // Creates the X11 window x11Window = XCreateWindow( x11Display, RootWindow(x11Display, x11Screen), (ndcid%3)*640, (ndcid/3)*480, width, height, 0, CopyFromParent, InputOutput, CopyFromParent, ui32Mask, &sWA); + #ifdef TARGET_PANDORA + // fullscreen + Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False); + Atom wmFullscreen = XInternAtom(x11Display, "_NET_WM_STATE_FULLSCREEN", False); + XChangeProperty(x11Display, x11Window, wmState, XA_ATOM, 32, PropModeReplace, (unsigned char *)&wmFullscreen, 1); + + XMapRaised(x11Display, x11Window); + #else XMapWindow(x11Display, x11Window); + #endif XFlush(x11Display); + + //(EGLNativeDisplayType)x11Display; x11_disp=(void*)x11Display; x11_win=(void*)x11Window; @@ -448,12 +556,75 @@ void common_linux_setup(); int dc_init(int argc,wchar* argv[]); void dc_run(); +#ifdef TARGET_PANDORA +void gl_term(); + +void clean_exit(int sig_num) { + void *array[10]; + size_t size; + + // close files + if (JoyFD>=0) close(JoyFD); + if (kbfd>=0) close(kbfd); + if(audio_fd>=0) close(audio_fd); + + // Close EGL context ??? + if (sig_num!=0) + gl_term(); + + // close XWindow + if (x11_win) { + XDestroyWindow(x11_disp, x11_win); + x11_win = 0; + } + if (x11_disp) { + XCloseDisplay(x11_disp); + x11_disp = 0; + } + + // 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); + } +} + +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); + } +} +#endif + int main(int argc, wchar* argv[]) { //if (argc==2) //ndcid=atoi(argv[1]); if (setup_curses() < 0) die("failed to setup curses!\n"); +#ifdef TARGET_PANDORA + signal(SIGSEGV, clean_exit); + signal(SIGKILL, clean_exit); + + init_sound(); +#endif SetHomeDir("."); printf("Home dir is: %s\n",GetPath("/").c_str()); @@ -467,12 +638,19 @@ int main(int argc, wchar* argv[]) dc_init(argc,argv); dc_run(); + +#ifdef TARGET_PANDORA + clean_exit(0); +#endif return 0; } u32 os_Push(void* frame, u32 samples, bool wait) { +#ifdef TARGET_PANDORA + write(audio_fd, frame, samples*4); +#endif return 1; } #endif diff --git a/newdc/newdc.mk b/newdc/newdc.mk old mode 100644 new mode 100755 index 8a668cce6..1ec6ae476 --- a/newdc/newdc.mk +++ b/newdc/newdc.mk @@ -37,9 +37,18 @@ RZDCY_FILES := $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(w RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.c)) RZDCY_FILES += $(foreach dir,$(addprefix $(RZDCY_SRC_DIR)/,$(RZDCY_MODULES)),$(wildcard $(dir)*.S)) +ifdef FOR_PANDORA +RZDCY_CXXFLAGS := \ + $(CFLAGS) -c -g -O3 -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps \ + -DRELEASE -DPANDORA\ + -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp \ + -frename-registers -fsingle-precision-constant -ffast-math \ + -ftree-vectorize -fomit-frame-pointer -fno-exceptions -fno-rtti -std=gnu++11 +else RZDCY_CXXFLAGS := \ $(CFLAGS) -c -g -O3 -I$(RZDCY_SRC_DIR) -I$(RZDCY_SRC_DIR)/deps \ -D_ANDROID -DRELEASE -DTARGET_BEAGLE\ -march=armv7-a -mtune=cortex-a9 -mfpu=vfpv3-d16 -mfloat-abi=softfp \ -frename-registers -fsingle-precision-constant -ffast-math \ -ftree-vectorize -fomit-frame-pointer -fno-exceptions -fno-rtti -std=gnu++11 +endif \ No newline at end of file diff --git a/newdc/nullDC.cpp b/newdc/nullDC.cpp old mode 100644 new mode 100755 index 248ce0c77..b3c7c587e --- a/newdc/nullDC.cpp +++ b/newdc/nullDC.cpp @@ -230,7 +230,7 @@ void LoadSettings() settings.pvr.ta_skip = cfgLoadInt("config","ta.skip",0); settings.pvr.rend = cfgLoadInt("config","pvr.rend",0); -#if (HOST_OS != OS_LINUX || defined(_ANDROID)) +#if (HOST_OS != OS_LINUX || defined(_ANDROID) || defined(TARGET_PANDORA)) settings.aica.BufferSize=2048; #else settings.aica.BufferSize=1024; diff --git a/newdc/rend/gles/gles.cpp b/newdc/rend/gles/gles.cpp old mode 100644 new mode 100755 index e3bc03dde..e040aeea9 --- a/newdc/rend/gles/gles.cpp +++ b/newdc/rend/gles/gles.cpp @@ -3,6 +3,18 @@ #include "rend/TexCache.h" #include "cfg/cfg.h" +#ifdef TARGET_PANDORA +#include +#include +#include +#include + +#ifndef FBIO_WAITFORVSYNC + #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) +#endif +int fbdev = -1; +#endif + /* GL|ES 2 Slower, smaller subset of gl2 @@ -304,12 +316,16 @@ int screen_height; //create a basic gles context bool gl_init(EGLNativeWindowType wind, EGLNativeDisplayType disp) { -#ifndef _ANDROID +#if !defined(_ANDROID) gl.setup.native_wind=wind; gl.setup.native_disp=disp; //try to get a display + #ifdef TARGET_PANDORA0 + gl.setup.display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + #else gl.setup.display = eglGetDisplay(gl.setup.native_disp); + #endif //if failed, get the default display (this will not happen in win32) if(gl.setup.display == EGL_NO_DISPLAY) @@ -342,7 +358,11 @@ bool gl_init(EGLNativeWindowType wind, EGLNativeDisplayType disp) return false; } + #ifdef TARGET_PANDORA0 + gl.setup.surface = eglCreateWindowSurface(gl.setup.display, config, (NativeWindowType)NULL, NULL); + #else gl.setup.surface = eglCreateWindowSurface(gl.setup.display, config, wind, NULL); + #endif if (eglCheck()) return false; @@ -384,6 +404,12 @@ void egl_stealcntx() //swap buffers void gl_swap() { + #ifdef TARGET_PANDORA0 + if (fbdev >= 0) { + int arg = 0; + ioctl(fbdev,FBIO_WAITFORVSYNC,&arg); + } + #endif eglSwapBuffers(gl.setup.display, gl.setup.surface); } @@ -393,6 +419,21 @@ void gl_term() #if HOST_OS==OS_WINDOWS ReleaseDC((HWND)gl.setup.native_wind,(HDC)gl.setup.native_disp); #endif +#ifdef TARGET_PANDORA + eglMakeCurrent( gl.setup.display, NULL, NULL, EGL_NO_CONTEXT ); + if (gl.setup.context) + eglDestroyContext(gl.setup.display, gl.setup.context); + if (gl.setup.surface) + eglDestroySurface(gl.setup.display, gl.setup.surface); + if (gl.setup.display) + eglTerminate(gl.setup.display); + if (fbdev>=0) close( fbdev ); + + fbdev=-1; + gl.setup.context=0; + gl.setup.surface=0; + gl.setup.display=0; +#endif } @@ -683,7 +724,11 @@ bool gles_init() return false; + #ifdef TARGET_PANDORA + fbdev=open("/dev/fb0", O_RDONLY); + #else eglSwapInterval(gl.setup.display,1); + #endif //clean up all buffers ... for (int i=0;i<10;i++) @@ -697,6 +742,7 @@ bool gles_init() } + float fog_coefs[]={0,0}; void tryfit(float* x,float* y) { diff --git a/newdc/rend/gles/gles.h b/newdc/rend/gles/gles.h index dea84d059..592b7b568 100644 --- a/newdc/rend/gles/gles.h +++ b/newdc/rend/gles/gles.h @@ -21,6 +21,10 @@ #define VERTEX_COL_OFFS_ARRAY 2 #define VERTEX_UV_ARRAY 3 +#ifdef TARGET_PANDORA +#define WEIRD_SLOWNESS +#endif + //vertex types extern u32 gcflip; diff --git a/reicast/pandora/Makefile b/reicast/pandora/Makefile new file mode 100755 index 000000000..d86d1677d --- /dev/null +++ b/reicast/pandora/Makefile @@ -0,0 +1,97 @@ + +LOCAL_PATH := $(call my-dir) +FOR_LINUX :=1 +FOR_ARM :=1 +FOR_PANDORA :=1 + +RZDCY_SRC_DIR = ../../newdc + +include $(RZDCY_SRC_DIR)/newdc.mk + +CC_PREFIX ?= + +CXX=${CC_PREFIX}g++ +CC=${CC_PREFIX}gcc +AS=${CC_PREFIX}as +STRIP=${CC_PREFIX}strip + +LD=${CC} + +MFLAGS := -marm -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -funroll-loops -fpermissive +ASFLAGS := -march=armv7-a -mfpu=neon -mfloat-abi=softfp + +LDFLAGS := -g -Wl,-Map,$(notdir $@).map,--gc-sections -Wl,-O3 -Wl,--sort-common + +SOURCES := cfg/ hw/arm7/ hw/aica/ hw/asic/ hw/ hw/gdrom/ hw/maple/ \ + hw/mem/ hw/pvr/ hw/sh4/ hw/sh4/rec_v2/ plugins/ profiler/ serial_ipc/ \ + hw/extdev/ hw/arm/ imgread/ linux/ linux-dist/ ./ rec-ARM/ deps/zlib/ deps/chdr/ deps/crypto/ arm_emitter/ + + +CXXFLAGS := -g -O3 -D RELEASE -c -D TARGET_PANDORA +CXXFLAGS += -frename-registers -fno-strict-aliasing -fsingle-precision-constant +CXXFLAGS += -ffast-math -ftree-vectorize -fprefetch-loop-arrays +#-std=c++0x + +CXXFLAGS += $(CFLAGS) $(MFLAGS) -fno-exceptions -fno-rtti +CXXFLAGS += -D SUPPORT_X11 + + +ifdef PGO_MAKE + CXXFLAGS += -fprofile-generate -pg + LDFLAGS += -fprofile-generate +else + CXXFLAGS += -fomit-frame-pointer +endif + +ifdef PGO_USE + CXXFLAGS += -fprofile-use +endif + + +ifdef LTO_TEST + CXXFLAGS += -flto -fwhole-program + LDFLAGS +=-flto -fwhole-program +endif + +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 + + +OBJECTS=$(RZDCY_FILES:.cpp=.build_obj) +OBJECTS:=$(OBJECTS:.c=.build_obj) +OBJECTS:=$(OBJECTS:.S=.build_obj) +OBJECTS:=$(patsubst $(RZDCY_SRC_DIR)/%,obj/%,$(OBJECTS)) + + +EXECUTABLE_STRIPPED=nosym-reicast.elf +EXECUTABLE=reicast.elf + +all: $(CPPFILES) $(EXECUTABLE) $(EXECUTABLE_STRIPPED) + echo $(RZDCY_FILES) + +$(EXECUTABLE): $(OBJECTS) + echo $(RZDCY_FILES) + $(CXX) $(MFLAGS) $(EXTRAFLAGS) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@ + +$(EXECUTABLE_STRIPPED): $(EXECUTABLE) + cp $< $@ && $(STRIP) $@ + +obj/%.build_obj : $(RZDCY_SRC_DIR)/%.cpp + mkdir -p $(dir $@) + $(CXX) $(EXTRAFLAGS) $(INCS) $(CXXFLAGS) $< -o $@ + +obj/%.build_obj : $(RZDCY_SRC_DIR)/%.c + mkdir -p $(dir $@) + $(CC) $(EXTRAFLAGS) $(INCS) $(CXXFLAGS) $< -o $@ + +obj/%.build_obj : $(RZDCY_SRC_DIR)/%.S + mkdir -p $(dir $@) + $(AS) $(ASFLAGS) $(INCS) $< -o $@ + + +clean: + rm $(OBJECTS) $(EXECUTABLE) -f