diff --git a/core/hw/arm7/arm7.cpp b/core/hw/arm7/arm7.cpp index 3d8dcc84a..e625bf0d4 100644 --- a/core/hw/arm7/arm7.cpp +++ b/core/hw/arm7/arm7.cpp @@ -512,8 +512,16 @@ void update_armintc() reg[INTR_PEND].I=e68k_out && armFiqEnable; } +void libAICA_TimeStep(); + #ifdef HOST_NO_AREC -void arm_Run(u32 CycleCount) { arm_Run_(CycleCount); } +void arm_Run(u32 CycleCount) { + for (int i=0;i<32;i++) + { + arm_Run_(CycleCount/32); + libAICA_TimeStep(); + } +} #else extern "C" void CompileCode(); @@ -1594,7 +1602,6 @@ void armv_MOV32(eReg regn, u32 imm) #endif // HOST_CPU -void libAICA_TimeStep(); //Run a timeslice for ARMREC //CycleCount is pretty much fixed to (512*32) for now (might change to a diff constant, but will be constant) void arm_Run(u32 CycleCount) diff --git a/core/hw/pvr/Renderer_if.cpp b/core/hw/pvr/Renderer_if.cpp index f10547b81..a08d7f97d 100644 --- a/core/hw/pvr/Renderer_if.cpp +++ b/core/hw/pvr/Renderer_if.cpp @@ -244,7 +244,8 @@ void* rend_thread(void* p) if (!renderer->Init()) die("rend->init() failed\n"); - renderer->Resize(640, 480); + //we don't know if this is true, so let's not speculate here + //renderer->Resize(640, 480); for(;;) { @@ -258,6 +259,11 @@ cThread rthd(rend_thread,0); bool pend_rend = false; +void rend_resize(int width, int height) { + renderer->Resize(width, height); +} + + void rend_start_render() { pend_rend = false; @@ -311,7 +317,9 @@ void rend_end_render() { #if 1 //also disabled the printf, it takes quite some time ... #if HOST_OS!=OS_WINDOWS && !(defined(_ANDROID) || defined(TARGET_PANDORA)) - if (!re.state) printf("Render > Extended time slice ...\n"); + //too much console spam. + //TODO: how about a counter? + //if (!re.state) printf("Render > Extended time slice ...\n"); #endif #endif diff --git a/core/hw/pvr/Renderer_if.h b/core/hw/pvr/Renderer_if.h index d95fcecb3..f27f5c57a 100644 --- a/core/hw/pvr/Renderer_if.h +++ b/core/hw/pvr/Renderer_if.h @@ -14,7 +14,7 @@ void rend_end_render(); void rend_end_wait(); void rend_set_fb_scale(float x,float y); - +void rend_resize(int width, int height); void rend_text_invl(vram_block* bl); diff --git a/core/linux-dist/main.cpp b/core/linux-dist/main.cpp index 2bd594b6a..5f821ed88 100755 --- a/core/linux-dist/main.cpp +++ b/core/linux-dist/main.cpp @@ -27,7 +27,9 @@ #include #include #endif - + + #include + map x11_keymap; #endif #if !defined(ANDROID) @@ -403,11 +405,13 @@ static Cursor CreateNullCursor(Display *display, Window root) } #endif +int x11_dc_buttons = 0xFFFF; + void UpdateInputState(u32 port) { static char key = 0; - kcode[port]=0xFFFF; + kcode[port]= x11_dc_buttons; rt[port]=0; lt[port]=0; @@ -464,7 +468,39 @@ return; void os_DoEvents() { + #if defined(SUPPORT_X11) + if (x11_win) { + //Handle X11 + XEvent e; + if(XCheckWindowEvent((Display*)x11_disp, (Window)x11_win, KeyPressMask | KeyReleaseMask, &e)) + { + switch(e.type) + { + case KeyPress: + case KeyRelease: + { + int dc_key = x11_keymap[e.xkey.keycode]; + + if (e.type == KeyPress) + x11_dc_buttons &= ~dc_key; + else + x11_dc_buttons |= dc_key; + + //printf("KEY: %d -> %d: %d\n",e.xkey.keycode, dc_key, x11_dc_buttons ); + } + break; + + + { + printf("KEYRELEASE\n"); + } + break; + + } + } + } + #endif } void os_SetWindowText(const char * text) @@ -472,7 +508,7 @@ void os_SetWindowText(const char * text) if (0==x11_win || 0==x11_disp || 1) printf("%s\n",text); #if defined(SUPPORT_X11) - else { + else if (x11_win) { XChangeProperty((Display*)x11_disp, (Window)x11_win, XInternAtom((Display*)x11_disp, "WM_NAME", False), //WM_NAME, XInternAtom((Display*)x11_disp, "UTF8_STRING", False), //UTF8_STRING, @@ -490,6 +526,7 @@ void os_CreateWindow() #if defined(SUPPORT_X11) if (cfgLoadInt("pvr","nox11",0)==0) { + XInitThreads(); // X11 variables Window x11Window = 0; Display* x11Display = 0; @@ -520,15 +557,51 @@ void os_CreateWindow() int depth = CopyFromParent; #if !defined(GLES) - int attr32[] = { GLX_RGBA, GLX_DEPTH_SIZE, 32, GLX_DOUBLEBUFFER, GLX_STENCIL_SIZE, 8, None }; - int attr24[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, GLX_STENCIL_SIZE, 8, None }; + // Get a matching FB config + static int visual_attribs[] = + { + GLX_X_RENDERABLE , True, + GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, + GLX_RENDER_TYPE , GLX_RGBA_BIT, + GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, + GLX_RED_SIZE , 8, + GLX_GREEN_SIZE , 8, + GLX_BLUE_SIZE , 8, + GLX_ALPHA_SIZE , 8, + GLX_DEPTH_SIZE , 24, + GLX_STENCIL_SIZE , 8, + GLX_DOUBLEBUFFER , True, + //GLX_SAMPLE_BUFFERS , 1, + //GLX_SAMPLES , 4, + None + }; + + int glx_major, glx_minor; + + // FBConfigs were added in GLX version 1.3. + if ( !glXQueryVersion( x11Display, &glx_major, &glx_minor ) || + ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) ) + { + printf("Invalid GLX version"); + exit(1); + } + + int fbcount; + GLXFBConfig* fbc = glXChooseFBConfig(x11Display, x11Screen, visual_attribs, &fbcount); + if (!fbc) + { + printf( "Failed to retrieve a framebuffer config\n" ); + exit(1); + } + printf( "Found %d matching FB configs.\n", fbcount ); + + GLXFBConfig bestFbc = fbc[ 0 ]; + XFree( fbc ); + + // Get a visual + XVisualInfo *vi = glXGetVisualFromFBConfig( x11Display, bestFbc ); + printf( "Chosen visual ID = 0x%x\n", vi->visualid ); - XVisualInfo* vi = glXChooseVisual(x11Display, 0, attr32); - if (!vi) - vi = glXChooseVisual(x11Display, 0, attr24); - - if (!vi) - die("Failed to glXChooseVisual"); depth = vi->depth; x11Visual = vi; @@ -580,8 +653,31 @@ void os_CreateWindow() XMapWindow(x11Display, x11Window); #if !defined(GLES) - x11_glc = glXCreateContext(x11Display, x11Visual, NULL, GL_TRUE); - //glXMakeCurrent(x11Display, x11Window, glc); + + #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 + #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 + typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*); + + glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; + glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) + glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); + + verify( glXCreateContextAttribsARB != 0 ); + + int context_attribs[] = { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 1, + GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + None + }; + + x11_glc = glXCreateContextAttribsARB( x11Display, bestFbc, 0, True, context_attribs); + XSync( x11Display, False ); + + if (!x11_glc) { + die("Failed to create GL3.1 context\n"); + } #endif #endif XFlush(x11Display); @@ -681,8 +777,9 @@ void clean_exit(int sig_num) { void init_sound() { - if((audio_fd=open("/dev/dsp",O_WRONLY))<0) + 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"); @@ -711,6 +808,9 @@ int main(int argc, wchar* argv[]) signal(SIGKILL, clean_exit); init_sound(); +#else + void os_InitAudio(); + os_InitAudio(); #endif #if defined(USES_HOMEDIR) @@ -727,6 +827,27 @@ int main(int argc, wchar* argv[]) SetHomeDir("."); #endif + #if defined(SUPPORT_X11) + x11_keymap[113] = DPad_Left; + x11_keymap[114] = DPad_Right; + + x11_keymap[111] = DPad_Up; + x11_keymap[116] = DPad_Down; + + x11_keymap[52] = Btn_Y; + x11_keymap[53] = Btn_X; + x11_keymap[54] = Btn_B; + x11_keymap[55] = Btn_A; + + /* + //TODO: Fix sliders + x11_keymap[38] = DPad_Down; + x11_keymap[39] = DPad_Down; + */ + + x11_keymap[36] = Btn_Start; + #endif + printf("Home dir is: %s\n",GetPath("/").c_str()); common_linux_setup(); @@ -746,12 +867,20 @@ int main(int argc, wchar* argv[]) return 0; } +u32 alsa_Push(void* frame, u32 samples, bool wait); u32 os_Push(void* frame, u32 samples, bool wait) { -#ifdef TARGET_PANDORA - write(audio_fd, frame, samples*4); -#endif -return 1; + #ifndef TARGET_PANDORA + int audio_fd = -1; + #endif + + if (audio_fd > 0) { + write(audio_fd, frame, samples*4); + } else { + return alsa_Push(frame, samples, wait); + } + + return 1; } #endif diff --git a/core/oslib/alsa_audiostream.cpp b/core/oslib/alsa_audiostream.cpp index 055fe778d..801d6bc7b 100644 --- a/core/oslib/alsa_audiostream.cpp +++ b/core/oslib/alsa_audiostream.cpp @@ -4,14 +4,37 @@ #include "cfg/cfg.h" -#if 0 && HOST_OS==OS_LINUX && !defined(TARGET_NACL32) +#if HOST_OS==OS_LINUX && !defined(TARGET_NACL32) && !defined(ANDROID) -#if !defined(ANDROID) +#if 1 #include #include snd_pcm_t *handle; +u32 alsa_Push(void* frame, u32 samples, bool wait) { + + snd_pcm_nonblock(handle, wait ? 0 : 1); + + int rc = snd_pcm_writei(handle, frame, samples); + if (rc == -EPIPE) + { + /* EPIPE means underrun */ + fprintf(stderr, "ALSA: underrun occurred\n"); + snd_pcm_prepare(handle); + alsa_Push(frame, samples * 8, wait); + } + else if (rc < 0) + { + fprintf(stderr, "ALSA: error from writei: %s\n", snd_strerror(rc)); + } + else if (rc != samples) + { + fprintf(stderr, "ALSA: short write, wrote %d frames of %d\n", rc, samples); + } + return 1; +} +#if 0 u8 Tempbuffer[8192*4]; void* AudioThread(void*) { @@ -44,6 +67,7 @@ void* AudioThread(void*) } cThread aud_thread(AudioThread,0); +#endif void os_InitAudio() { @@ -123,7 +147,7 @@ void os_InitAudio() } /* Set period size to settings.aica.BufferSize frames. */ - frames = settings.aica.BufferSize; + frames = 2 * 1024;//settings.aica.BufferSize; rc=snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); if (rc < 0) { @@ -145,8 +169,6 @@ void os_InitAudio() fprintf(stderr, "Unable to set hw parameters: %s\n", snd_strerror(rc)); return; } - - aud_thread.Start(); } void os_TermAudio() diff --git a/core/rend/gles/gles.cpp b/core/rend/gles/gles.cpp index a0b079d68..97235ae9b 100755 --- a/core/rend/gles/gles.cpp +++ b/core/rend/gles/gles.cpp @@ -617,12 +617,39 @@ int screen_height; (GLXDrawable)libPvr_GetRenderTarget(), (GLXContext)x11_glc); + screen_width = 640; + screen_height = 480; return gl3wInit() != -1 && gl3wIsSupported(3, 1); } void gl_swap() { glXSwapBuffers((Display*)libPvr_GetRenderSurface(), (GLXDrawable)libPvr_GetRenderTarget()); + + Window win; + int temp; + unsigned int tempu, new_w, new_h; + XGetGeometry((Display*)libPvr_GetRenderSurface(), (GLXDrawable)libPvr_GetRenderTarget(), + &win, &temp, &temp, &new_w, &new_h,&tempu,&tempu); + + //if resized, clear up the draw buffers, to avoid out-of-draw-area junk data + if (new_w != screen_width || new_h != screen_height) { + screen_width = new_w; + screen_height = new_h; + } + + #if 0 + //handy to debug really stupid render-not-working issues ... + + glClearColor( 0, 0.5, 1, 1 ); + glClear( GL_COLOR_BUFFER_BIT ); + glXSwapBuffers((Display*)libPvr_GetRenderSurface(), (GLXDrawable)libPvr_GetRenderTarget()); + + + glClearColor ( 1, 0.5, 0, 1 ); + glClear ( GL_COLOR_BUFFER_BIT ); + glXSwapBuffers((Display*)libPvr_GetRenderSurface(), (GLXDrawable)libPvr_GetRenderTarget()); + #endif } #endif #endif @@ -1411,6 +1438,7 @@ bool RenderFrame() bool is_rtt=pvrrc.isRTT; + OSD_HOOK(); //if (FrameCount&7) return; @@ -1745,6 +1773,14 @@ bool RenderFrame() //not all scaling affects pixel operations, scale to adjust for that scale_x *= scissoring_scale_x; + + #if 0 + //handy to debug really stupid render-not-working issues ... + printf("SS: %dx%d\n", screen_width, screen_height); + printf("SCI: %d, %f\n", pvrrc.fb_X_CLIP.max, dc2s_scale_h); + printf("SCI: %f, %f, %f, %f\n", offs_x+pvrrc.fb_X_CLIP.min/scale_x,(pvrrc.fb_Y_CLIP.min/scale_y)*dc2s_scale_h,(pvrrc.fb_X_CLIP.max-pvrrc.fb_X_CLIP.min+1)/scale_x*dc2s_scale_h,(pvrrc.fb_Y_CLIP.max-pvrrc.fb_Y_CLIP.min+1)/scale_y*dc2s_scale_h); + #endif + glScissor(offs_x+pvrrc.fb_X_CLIP.min/scale_x,(pvrrc.fb_Y_CLIP.min/scale_y)*dc2s_scale_h,(pvrrc.fb_X_CLIP.max-pvrrc.fb_X_CLIP.min+1)/scale_x*dc2s_scale_h,(pvrrc.fb_Y_CLIP.max-pvrrc.fb_Y_CLIP.min+1)/scale_y*dc2s_scale_h); if (settings.rend.WideScreen && pvrrc.fb_X_CLIP.min==0 && ((pvrrc.fb_X_CLIP.max+1)/scale_x==640) && (pvrrc.fb_Y_CLIP.min==0) && ((pvrrc.fb_Y_CLIP.max+1)/scale_y==480 ) ) { @@ -1753,6 +1789,7 @@ bool RenderFrame() else glEnable(GL_SCISSOR_TEST); + //restore scale_x scale_x /= scissoring_scale_x; @@ -1812,7 +1849,7 @@ void rend_set_fb_scale(float x,float y) struct glesrend : Renderer { bool Init() { return gles_init(); } - void Resize(int w, int h) { } + void Resize(int w, int h) { screen_width=w; screen_height=h; } void Term() { } bool Process(TA_context* ctx) { return ProcessFrame(ctx); } diff --git a/core/stdclass.h b/core/stdclass.h index f7f351bbc..529927e33 100644 --- a/core/stdclass.h +++ b/core/stdclass.h @@ -220,7 +220,7 @@ public : #if HOST_OS==OS_WINDOWS InitializeCriticalSection(&cs); #else - mutx=PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_init ( &mutx, NULL); #endif } ~cMutex()