SDL: Modernize software renderer

This commit is contained in:
Jeffrey Pfau 2016-06-20 21:34:06 -07:00
parent e1a4acec9f
commit ca46fedd34
2 changed files with 29 additions and 23 deletions

View File

@ -70,7 +70,6 @@ endif()
if(BUILD_PANDORA) if(BUILD_PANDORA)
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/pandora-sdl.c) list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/pandora-sdl.c)
else() else()
#list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl.c)
if(BUILD_GL) if(BUILD_GL)
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-sdl.c) list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-sdl.c)
list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gl.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c) list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gl.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c)
@ -81,6 +80,9 @@ else()
list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gles2.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c) list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gles2.c ${CMAKE_SOURCE_DIR}/src/platform/sdl/gl-common.c)
include_directories(${OPENGLES2_INCLUDE_DIR}) include_directories(${OPENGLES2_INCLUDE_DIR})
endif() endif()
if(NOT BUILD_GL AND NOT BUILD_GLES2)
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/sw-sdl.c)
endif()
endif() endif()
add_executable(${BINARY_NAME}-sdl WIN32 ${PLATFORM_SRC} ${MAIN_SRC}) add_executable(${BINARY_NAME}-sdl WIN32 ${PLATFORM_SRC} ${MAIN_SRC})

View File

@ -5,17 +5,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "main.h" #include "main.h"
#include "gba/supervisor/thread.h" #include "core/thread.h"
#include "core/version.h"
#include "util/arm-algo.h" #include "util/arm-algo.h"
static bool mSDLSWInit(struct mSDLRenderer* renderer); static bool mSDLSWInit(struct mSDLRenderer* renderer);
static void mSDLSWRunloopGBA(struct mSDLRenderer* renderer, void* user); static void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user);
static void mSDLSWDeinit(struct mSDLRenderer* renderer); static void mSDLSWDeinit(struct mSDLRenderer* renderer);
void mSDLSWCreate(struct mSDLRenderer* renderer) { void mSDLSWCreate(struct mSDLRenderer* renderer) {
renderer->init = mSDLSWInit; renderer->init = mSDLSWInit;
renderer->deinit = mSDLSWDeinit; renderer->deinit = mSDLSWDeinit;
renderer->runloop = mSDLSWRunloopGBA; renderer->runloop = mSDLSWRunloop;
} }
bool mSDLSWInit(struct mSDLRenderer* renderer) { bool mSDLSWInit(struct mSDLRenderer* renderer) {
@ -27,6 +28,8 @@ bool mSDLSWInit(struct mSDLRenderer* renderer) {
#endif #endif
#endif #endif
unsigned width, height;
renderer->core->desiredVideoDimensions(renderer->core, &width, &height);
#if SDL_VERSION_ATLEAST(2, 0, 0) #if SDL_VERSION_ATLEAST(2, 0, 0)
renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen)); renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen));
SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight); SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight);
@ -34,27 +37,27 @@ bool mSDLSWInit(struct mSDLRenderer* renderer) {
renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
#ifdef COLOR_16_BIT #ifdef COLOR_16_BIT
#ifdef COLOR_5_6_5 #ifdef COLOR_5_6_5
renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height);
#else #else
renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, width, height);
#endif #endif
#else #else
renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, width, height);
#endif #endif
SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->d.outputBuffer, &renderer->d.outputBufferStride); int stride;
renderer->d.outputBufferStride /= BYTES_PER_PIXEL; SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride);
renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL);
#else #else
SDL_Surface* surface = SDL_GetVideoSurface(); SDL_Surface* surface = SDL_GetVideoSurface();
SDL_LockSurface(surface); SDL_LockSurface(surface);
if (renderer->ratio == 1) { if (renderer->ratio == 1) {
renderer->d.outputBuffer = surface->pixels; renderer->core->setVideoBuffer(renderer->core, surface->pixels, surface->pitch / BYTES_PER_PIXEL);
renderer->d.outputBufferStride = surface->pitch / BYTES_PER_PIXEL;
} else { } else {
#ifdef USE_PIXMAN #ifdef USE_PIXMAN
renderer->d.outputBuffer = malloc(VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL); renderer->outputBuffer = malloc(width * height * BYTES_PER_PIXEL);
renderer->d.outputBufferStride = VIDEO_HORIZONTAL_PIXELS; renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, width);
#ifdef COLOR_16_BIT #ifdef COLOR_16_BIT
#ifdef COLOR_5_6_5 #ifdef COLOR_5_6_5
pixman_format_code_t format = PIXMAN_r5g6b5; pixman_format_code_t format = PIXMAN_r5g6b5;
@ -64,8 +67,8 @@ bool mSDLSWInit(struct mSDLRenderer* renderer) {
#else #else
pixman_format_code_t format = PIXMAN_x8b8g8r8; pixman_format_code_t format = PIXMAN_x8b8g8r8;
#endif #endif
renderer->pix = pixman_image_create_bits(format, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, renderer->pix = pixman_image_create_bits(format, width, height,
renderer->d.outputBuffer, renderer->d.outputBufferStride * BYTES_PER_PIXEL); renderer->outputBuffer, width * BYTES_PER_PIXEL);
renderer->screenpix = pixman_image_create_bits(format, renderer->viewportWidth, renderer->viewportHeight, surface->pixels, surface->pitch); renderer->screenpix = pixman_image_create_bits(format, renderer->viewportWidth, renderer->viewportHeight, surface->pixels, surface->pitch);
pixman_transform_t transform; pixman_transform_t transform;
@ -82,8 +85,8 @@ bool mSDLSWInit(struct mSDLRenderer* renderer) {
return true; return true;
} }
void mSDLSWRunloopGBA(struct mSDLRenderer* renderer, void* user) { void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user) {
struct GBAThread* context = user; struct mCoreThread* context = user;
SDL_Event event; SDL_Event event;
#if !SDL_VERSION_ATLEAST(2, 0, 0) #if !SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Surface* surface = SDL_GetVideoSurface(); SDL_Surface* surface = SDL_GetVideoSurface();
@ -91,7 +94,7 @@ void mSDLSWRunloopGBA(struct mSDLRenderer* renderer, void* user) {
while (context->state < THREAD_EXITING) { while (context->state < THREAD_EXITING) {
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
mSDLHandleEventGBA(context, &renderer->player, &event); mSDLHandleEvent(context, &renderer->player, &event);
} }
if (mCoreSyncWaitFrameStart(&context->sync)) { if (mCoreSyncWaitFrameStart(&context->sync)) {
@ -99,8 +102,9 @@ void mSDLSWRunloopGBA(struct mSDLRenderer* renderer, void* user) {
SDL_UnlockTexture(renderer->sdlTex); SDL_UnlockTexture(renderer->sdlTex);
SDL_RenderCopy(renderer->sdlRenderer, renderer->sdlTex, 0, 0); SDL_RenderCopy(renderer->sdlRenderer, renderer->sdlTex, 0, 0);
SDL_RenderPresent(renderer->sdlRenderer); SDL_RenderPresent(renderer->sdlRenderer);
SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->d.outputBuffer, &renderer->d.outputBufferStride); int stride;
renderer->d.outputBufferStride /= BYTES_PER_PIXEL; SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride);
renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL);
#else #else
#ifdef USE_PIXMAN #ifdef USE_PIXMAN
if (renderer->ratio > 1) { if (renderer->ratio > 1) {
@ -112,10 +116,10 @@ void mSDLSWRunloopGBA(struct mSDLRenderer* renderer, void* user) {
switch (renderer->ratio) { switch (renderer->ratio) {
#if defined(__ARM_NEON) && COLOR_16_BIT #if defined(__ARM_NEON) && COLOR_16_BIT
case 2: case 2:
_neon2x(surface->pixels, renderer->d.outputBuffer, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); _neon2x(surface->pixels, renderer->outputBuffer, width, height);
break; break;
case 4: case 4:
_neon4x(surface->pixels, renderer->d.outputBuffer, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); _neon4x(surface->pixels, renderer->outputBuffer, width, height);
break; break;
#endif #endif
case 1: case 1:
@ -135,7 +139,7 @@ void mSDLSWRunloopGBA(struct mSDLRenderer* renderer, void* user) {
void mSDLSWDeinit(struct mSDLRenderer* renderer) { void mSDLSWDeinit(struct mSDLRenderer* renderer) {
if (renderer->ratio > 1) { if (renderer->ratio > 1) {
free(renderer->d.outputBuffer); free(renderer->outputBuffer);
} }
#if !SDL_VERSION_ATLEAST(2, 0, 0) #if !SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Surface* surface = SDL_GetVideoSurface(); SDL_Surface* surface = SDL_GetVideoSurface();