src/platform/sdl/sw-sdl.c (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "main.h"
7
8#include "gba/supervisor/thread.h"
9#include "util/arm-algo.h"
10
11bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
12#if !SDL_VERSION_ATLEAST(2, 0, 0)
13#ifdef COLOR_16_BIT
14 SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_DOUBLEBUF | SDL_HWSURFACE);
15#else
16 SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_DOUBLEBUF | SDL_HWSURFACE);
17#endif
18#endif
19
20#if SDL_VERSION_ATLEAST(2, 0, 0)
21 renderer->window = SDL_CreateWindow(PROJECT_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->events.fullscreen));
22 SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight);
23 renderer->events.window = renderer->window;
24 renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
25#ifdef COLOR_16_BIT
26#ifdef COLOR_5_6_5
27 renderer->tex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
28#else
29 renderer->tex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
30#endif
31#else
32 renderer->tex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
33#endif
34
35 SDL_LockTexture(renderer->tex, 0, (void**) &renderer->d.outputBuffer, &renderer->d.outputBufferStride);
36 renderer->d.outputBufferStride /= BYTES_PER_PIXEL;
37#else
38 SDL_Surface* surface = SDL_GetVideoSurface();
39 SDL_LockSurface(surface);
40
41 if (renderer->ratio == 1) {
42 renderer->d.outputBuffer = surface->pixels;
43#ifdef COLOR_16_BIT
44 renderer->d.outputBufferStride = surface->pitch / 2;
45#else
46 renderer->d.outputBufferStride = surface->pitch / 4;
47#endif
48 } else {
49 renderer->d.outputBuffer = malloc(240 * 160 * BYTES_PER_PIXEL);
50 renderer->d.outputBufferStride = 240;
51 }
52#endif
53
54 return true;
55}
56
57void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
58 SDL_Event event;
59#if !SDL_VERSION_ATLEAST(2, 0, 0)
60 SDL_Surface* surface = SDL_GetVideoSurface();
61#endif
62
63 while (context->state < THREAD_EXITING) {
64 while (SDL_PollEvent(&event)) {
65 GBASDLHandleEvent(context, &renderer->events, &event);
66 }
67
68 if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) {
69#if SDL_VERSION_ATLEAST(2, 0, 0)
70 SDL_UnlockTexture(renderer->tex);
71 SDL_RenderCopy(renderer->sdlRenderer, renderer->tex, 0, 0);
72 SDL_RenderPresent(renderer->sdlRenderer);
73 SDL_LockTexture(renderer->tex, 0, (void**) &renderer->d.outputBuffer, &renderer->d.outputBufferStride);
74 renderer->d.outputBufferStride /= BYTES_PER_PIXEL;
75#else
76 switch (renderer->ratio) {
77#if defined(__ARM_NEON) && COLOR_16_BIT
78 case 2:
79 _neon2x(surface->pixels, renderer->d.outputBuffer, 240, 160);
80 break;
81 case 4:
82 _neon4x(surface->pixels, renderer->d.outputBuffer, 240, 160);
83 break;
84#endif
85 case 1:
86 break;
87 default:
88 abort();
89 }
90 SDL_UnlockSurface(surface);
91 SDL_Flip(surface);
92 SDL_LockSurface(surface);
93#endif
94 }
95 GBASyncWaitFrameEnd(&context->sync);
96 }
97}
98
99void GBASDLDeinit(struct SDLSoftwareRenderer* renderer) {
100 UNUSED(renderer);
101}