SDL: Add Pandora-specific main file
Jeffrey Pfau jeffrey@endrift.com
Wed, 18 Mar 2015 23:40:18 -0700
3 files changed,
118 insertions(+),
1 deletions(-)
M
src/platform/sdl/CMakeLists.txt
→
src/platform/sdl/CMakeLists.txt
@@ -53,7 +53,9 @@ target_link_libraries(${BINARY_NAME}-rpi ${BINARY_NAME} ${PLATFORM_LIBRARY} ${EGL_LIBRARY})
install(TARGETS ${BINARY_NAME}-rpi DESTINATION bin COMPONENT ${BINARY_NAME}-rpi) endif() -if(BUILD_BBB OR BUILD_RASPI OR NOT BUILD_GL) +if(BUILD_PANDORA) + list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/pandora-sdl.c) +elseif(BUILD_BBB OR BUILD_RASPI OR NOT BUILD_GL) list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl.c) else() list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-sdl.c)
M
src/platform/sdl/main.h
→
src/platform/sdl/main.h
@@ -77,6 +77,12 @@ GLuint bufferObject;
GLuint texLocation; GLuint positionLocation; #endif + +#ifdef BUILD_PANDORA + int fb; + int odd; + void* base[2]; +#endif }; bool GBASDLInit(struct SDLSoftwareRenderer* renderer);
A
src/platform/sdl/pandora-sdl.c
@@ -0,0 +1,109 @@
+/* Copyright (c) 2013-2015 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "main.h" + +#include "gba/supervisor/thread.h" + +#include <linux/omapfb.h> +#include <linux/fb.h> +#include <sys/ioctl.h> +#include <sys/mman.h> + +bool GBASDLInit(struct SDLSoftwareRenderer* renderer) { + SDL_SetVideoMode(800, 480, 16, SDL_FULLSCREEN); + + renderer->odd = 0; + renderer->fb = open("/dev/fb1", O_RDWR); + if (renderer->fb < 0) { + return false; + } + + struct omapfb_plane_info plane; + struct omapfb_mem_info mem; + if (ioctl(renderer->fb, OMAPFB_QUERY_PLANE, &plane) < 0) { + return false; + } + if (ioctl(renderer->fb, OMAPFB_QUERY_MEM, &mem) < 0) { + return false; + } + + if (plane.enabled) { + plane.enabled = 0; + ioctl(renderer->fb, OMAPFB_SETUP_PLANE, &plane); + } + + mem.size = VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * 4; + ioctl(renderer->fb, OMAPFB_SETUP_MEM, &mem); + + plane.enabled = 1; + plane.pos_x = 40; + plane.pos_y = 0; + plane.out_width = 720; + plane.out_height = 480; + ioctl(renderer->fb, OMAPFB_SETUP_PLANE, &plane); + + struct fb_var_screeninfo info; + ioctl(renderer->fb, FBIOGET_VSCREENINFO, &info); + info.xres = VIDEO_HORIZONTAL_PIXELS; + info.yres = VIDEO_VERTICAL_PIXELS; + info.xres_virtual = VIDEO_HORIZONTAL_PIXELS; + info.yres_virtual = VIDEO_VERTICAL_PIXELS * 2; + info.bits_per_pixel = 16; + ioctl(renderer->fb, FBIOPUT_VSCREENINFO, &info); + + renderer->odd = 0; + renderer->base[0] = mmap(0, VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * 4, PROT_READ | PROT_WRITE, MAP_SHARED, renderer->fb, 0); + renderer->base[1] = (uint16_t*) renderer->base[0] + VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS; + + renderer->d.outputBuffer = renderer->base[0]; + renderer->d.outputBufferStride = VIDEO_HORIZONTAL_PIXELS; + return true; +} + +void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) { + SDL_Event event; + + while (context->state < THREAD_EXITING) { + while (SDL_PollEvent(&event)) { + GBASDLHandleEvent(context, &renderer->events, &event); + } + + if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) { + int arg = 0; + ioctl(renderer->fb, FBIO_WAITFORVSYNC, &arg); + + struct fb_var_screeninfo info; + ioctl(renderer->fb, FBIOGET_VSCREENINFO, &info); + info.yoffset = VIDEO_VERTICAL_PIXELS * renderer->odd; + ioctl(renderer->fb, FBIOPAN_DISPLAY, &info); + + renderer->odd = !renderer->odd; + renderer->d.outputBuffer = renderer->base[renderer->odd]; + } + GBASyncWaitFrameEnd(&context->sync); + } +} + +void GBASDLDeinit(struct SDLSoftwareRenderer* renderer) { + munmap(renderer->base[0], VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * 4); + + struct omapfb_plane_info plane; + struct omapfb_mem_info mem; + ioctl(renderer->fb, OMAPFB_QUERY_PLANE, &plane); + ioctl(renderer->fb, OMAPFB_QUERY_MEM, &mem); + + mem.size = 0; + ioctl(renderer->fb, OMAPFB_SETUP_MEM, &mem); + + plane.enabled = 0; + plane.pos_x = 0; + plane.pos_y = 0; + plane.out_width = 0; + plane.out_height = 0; + ioctl(renderer->fb, OMAPFB_SETUP_PLANE, &plane); + + close(renderer->fb); +}