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
10#if defined(__ARM_NEON)
11void _neon2x(void* dest, void* src, int width, int height);
12void _neon4x(void* dest, void* src, int width, int height);
13#endif
14
15bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
16#if !SDL_VERSION_ATLEAST(2, 0, 0)
17#ifdef COLOR_16_BIT
18 SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_DOUBLEBUF | SDL_HWSURFACE);
19#else
20 SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_DOUBLEBUF | SDL_HWSURFACE);
21#endif
22#endif
23
24#if SDL_VERSION_ATLEAST(2, 0, 0)
25 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));
26 SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight);
27 renderer->events.window = renderer->window;
28 renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
29#ifdef COLOR_16_BIT
30#ifdef COLOR_5_6_5
31 renderer->tex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
32#else
33 renderer->tex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
34#endif
35#else
36 renderer->tex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
37#endif
38
39 SDL_LockTexture(renderer->tex, 0, &renderer->d.outputBuffer, &renderer->d.outputBufferStride);
40 renderer->d.outputBufferStride /= BYTES_PER_PIXEL;
41#else
42 SDL_Surface* surface = SDL_GetVideoSurface();
43 SDL_LockSurface(surface);
44
45 if (renderer->ratio == 1) {
46 renderer->d.outputBuffer = surface->pixels;
47#ifdef COLOR_16_BIT
48 renderer->d.outputBufferStride = surface->pitch / 2;
49#else
50 renderer->d.outputBufferStride = surface->pitch / 4;
51#endif
52 } else {
53 renderer->d.outputBuffer = malloc(240 * 160 * BYTES_PER_PIXEL);
54 renderer->d.outputBufferStride = 240;
55 }
56#endif
57
58 return true;
59}
60
61void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
62 SDL_Event event;
63#if !SDL_VERSION_ATLEAST(2, 0, 0)
64 SDL_Surface* surface = SDL_GetVideoSurface();
65#endif
66
67 while (context->state < THREAD_EXITING) {
68 while (SDL_PollEvent(&event)) {
69 GBASDLHandleEvent(context, &renderer->events, &event);
70 }
71
72 if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) {
73#if SDL_VERSION_ATLEAST(2, 0, 0)
74 SDL_UnlockTexture(renderer->tex);
75 SDL_RenderCopy(renderer->sdlRenderer, renderer->tex, 0, 0);
76 SDL_RenderPresent(renderer->sdlRenderer);
77 SDL_LockTexture(renderer->tex, 0, &renderer->d.outputBuffer, &renderer->d.outputBufferStride);
78 renderer->d.outputBufferStride /= BYTES_PER_PIXEL;
79#else
80 switch (renderer->ratio) {
81#if defined(__ARM_NEON) && COLOR_16_BIT
82 case 2:
83 _neon2x(surface->pixels, renderer->d.outputBuffer, 240, 160);
84 break;
85 case 4:
86 _neon4x(surface->pixels, renderer->d.outputBuffer, 240, 160);
87 break;
88#endif
89 case 1:
90 break;
91 default:
92 abort();
93 }
94 SDL_UnlockSurface(surface);
95 SDL_Flip(surface);
96 SDL_LockSurface(surface);
97#endif
98 }
99 GBASyncWaitFrameEnd(&context->sync);
100 }
101}
102
103void GBASDLDeinit(struct SDLSoftwareRenderer* renderer) {
104 UNUSED(renderer);
105}