src/platform/sdl/gl-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 "gl-common.h"
9
10#include "core/core.h"
11#ifdef M_CORE_GBA
12#include "gba/supervisor/thread.h"
13#endif
14#ifdef M_CORE_GB
15#include "gb/core.h"
16#include "gb/gb.h"
17#endif
18#include "platform/opengl/gl.h"
19
20#define GB_GBA_CENTER ((VIDEO_HORIZONTAL_PIXELS - GB_VIDEO_HORIZONTAL_PIXELS + VIDEO_HORIZONTAL_PIXELS * (VIDEO_VERTICAL_PIXELS - GB_VIDEO_VERTICAL_PIXELS)) / 2)
21
22static void _doViewport(int w, int h, struct VideoBackend* v) {
23 v->resized(v, w, h);
24 v->clear(v);
25 v->swap(v);
26 v->clear(v);
27}
28
29#ifdef M_CORE_GBA
30static bool mSDLGLInitGBA(struct mSDLRenderer* renderer);
31static void mSDLGLRunloopGBA(struct mSDLRenderer* renderer, void* user);
32static void mSDLGLDeinitGBA(struct mSDLRenderer* renderer);
33#endif
34#ifdef M_CORE_GB
35static bool mSDLGLInitGB(struct mSDLRenderer* renderer);
36static void mSDLGLRunloopGB(struct mSDLRenderer* renderer, void* user);
37static void mSDLGLDeinitGB(struct mSDLRenderer* renderer);
38#endif
39
40#ifdef M_CORE_GBA
41void mSDLGLCreate(struct mSDLRenderer* renderer) {
42 renderer->init = mSDLGLInitGBA;
43 renderer->deinit = mSDLGLDeinitGBA;
44 renderer->runloop = mSDLGLRunloopGBA;
45}
46
47bool mSDLGLInitGBA(struct mSDLRenderer* renderer) {
48 mSDLGLCommonInit(renderer);
49
50 renderer->d.outputBuffer = malloc(VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
51 renderer->d.outputBufferStride = VIDEO_HORIZONTAL_PIXELS;
52
53 GBAGLContextCreate(&renderer->gl);
54 renderer->gl.d.user = renderer;
55 renderer->gl.d.lockAspectRatio = renderer->lockAspectRatio;
56 renderer->gl.d.filter = renderer->filter;
57 renderer->gl.d.swap = mSDLGLCommonSwap;
58 renderer->gl.d.init(&renderer->gl.d, 0);
59
60 _doViewport(renderer->viewportWidth, renderer->viewportHeight, &renderer->gl.d);
61 return true;
62}
63
64void mSDLGLRunloopGBA(struct mSDLRenderer* renderer, void* user) {
65 struct GBAThread* context = user;
66 SDL_Event event;
67 struct VideoBackend* v = &renderer->gl.d;
68 renderer->audio.psg = &context->gba->audio.psg;
69
70 while (context->state < THREAD_EXITING) {
71 while (SDL_PollEvent(&event)) {
72 GBASDLHandleEvent(context, &renderer->player, &event);
73#if SDL_VERSION_ATLEAST(2, 0, 0)
74 // Event handling can change the size of the screen
75 if (renderer->player.windowUpdated) {
76 SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight);
77 _doViewport(renderer->viewportWidth, renderer->viewportHeight, v);
78 renderer->player.windowUpdated = 0;
79 }
80#endif
81 }
82
83 if (mCoreSyncWaitFrameStart(&context->sync)) {
84 v->postFrame(v, renderer->d.outputBuffer);
85 }
86 mCoreSyncWaitFrameEnd(&context->sync);
87 v->drawFrame(v);
88 v->swap(v);
89 }
90
91 renderer->audio.psg = 0;
92}
93
94void mSDLGLDeinitGBA(struct mSDLRenderer* renderer) {
95 if (renderer->gl.d.deinit) {
96 renderer->gl.d.deinit(&renderer->gl.d);
97 }
98 free(renderer->d.outputBuffer);
99#if SDL_VERSION_ATLEAST(2, 0, 0)
100 SDL_GL_DeleteContext(renderer->glCtx);
101#endif
102}
103#endif
104
105#ifdef M_CORE_GB
106void mSDLGLCreateGB(struct mSDLRenderer* renderer) {
107 renderer->init = mSDLGLInitGB;
108 renderer->deinit = mSDLGLDeinitGB;
109 renderer->runloop = mSDLGLRunloopGB;
110}
111
112bool mSDLGLInitGB(struct mSDLRenderer* renderer) {
113 mSDLGLCommonInit(renderer);
114
115 // TODO: Pass texture size along
116 renderer->outputBuffer = malloc(VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
117 memset(renderer->outputBuffer, 0, VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
118 renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer + GB_GBA_CENTER, VIDEO_HORIZONTAL_PIXELS);
119
120 GBAGLContextCreate(&renderer->gl);
121 renderer->gl.d.user = renderer;
122 renderer->gl.d.lockAspectRatio = renderer->lockAspectRatio;
123 renderer->gl.d.filter = renderer->filter;
124 renderer->gl.d.swap = mSDLGLCommonSwap;
125 renderer->gl.d.init(&renderer->gl.d, 0);
126
127 _doViewport(renderer->viewportWidth, renderer->viewportHeight, &renderer->gl.d);
128 return true;
129}
130
131void mSDLGLRunloopGB(struct mSDLRenderer* renderer, void* user) {
132 UNUSED(user);
133 SDL_Event event;
134 struct VideoBackend* v = &renderer->gl.d;
135 int activeKeys = 0;
136 renderer->audio.psg = &((struct GB*) renderer->core->board)->audio;
137
138 while (true) {
139 renderer->core->runFrame(renderer->core);
140 while (SDL_PollEvent(&event)) {
141 // TODO: Refactor out
142 if (event.type == SDL_KEYUP || event.type == SDL_KEYDOWN) {
143 int key;
144#if !defined(BUILD_PANDORA) && SDL_VERSION_ATLEAST(2, 0, 0)
145 key = mInputMapKey(renderer->player.bindings, SDL_BINDING_KEY, event.key.keysym.scancode);
146#else
147 key = mInputMapKey(renderer->player.bindings, SDL_BINDING_KEY, event.key.keysym.sym);
148#endif
149 if (key != GBA_KEY_NONE) {
150 if (event.type == SDL_KEYDOWN) {
151 activeKeys |= 1 << key;
152 } else {
153 activeKeys &= ~(1 << key);
154 }
155 }
156 }
157 if (event.type == SDL_QUIT) {
158 return;
159 }
160
161#if SDL_VERSION_ATLEAST(2, 0, 0)
162 // Event handling can change the size of the screen
163 if (renderer->player.windowUpdated) {
164 SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight);
165 _doViewport(renderer->viewportWidth, renderer->viewportHeight, v);
166 renderer->player.windowUpdated = 0;
167 }
168#endif
169 }
170 renderer->core->setKeys(renderer->core, activeKeys);
171
172 v->postFrame(v, renderer->outputBuffer);
173 v->drawFrame(v);
174 v->swap(v);
175 }
176 renderer->audio.psg = 0;
177}
178
179void mSDLGLDeinitGB(struct mSDLRenderer* renderer) {
180 if (renderer->gl.d.deinit) {
181 renderer->gl.d.deinit(&renderer->gl.d);
182 }
183 free(renderer->outputBuffer);
184#if SDL_VERSION_ATLEAST(2, 0, 0)
185 SDL_GL_DeleteContext(renderer->glCtx);
186#endif
187}
188#endif