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#include "core/thread.h"
12#include "platform/opengl/gl.h"
13
14#define GB_GBA_CENTER ((VIDEO_HORIZONTAL_PIXELS - GB_VIDEO_HORIZONTAL_PIXELS + VIDEO_HORIZONTAL_PIXELS * (VIDEO_VERTICAL_PIXELS - GB_VIDEO_VERTICAL_PIXELS)) / 2)
15
16static void _doViewport(int w, int h, struct VideoBackend* v) {
17 v->resized(v, w, h);
18 v->clear(v);
19 v->swap(v);
20 v->clear(v);
21}
22
23#ifdef M_CORE_GBA
24#include "gba/gba.h"
25
26static bool mSDLGLInitGBA(struct mSDLRenderer* renderer);
27#endif
28#ifdef M_CORE_GB
29#include "gb/gb.h"
30
31static bool mSDLGLInitGB(struct mSDLRenderer* renderer);
32#endif
33
34static void mSDLGLRunloop(struct mSDLRenderer* renderer, void* user);
35static void mSDLGLDeinit(struct mSDLRenderer* renderer);
36
37#ifdef M_CORE_GBA
38void mSDLGLCreateGBA(struct mSDLRenderer* renderer) {
39 renderer->init = mSDLGLInitGBA;
40 renderer->deinit = mSDLGLDeinit;
41 renderer->runloop = mSDLGLRunloop;
42}
43
44bool mSDLGLInitGBA(struct mSDLRenderer* renderer) {
45 mSDLGLCommonInit(renderer);
46
47 renderer->outputBuffer = malloc(VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
48 memset(renderer->outputBuffer, 0, VIDEO_HORIZONTAL_PIXELS * VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
49 renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, VIDEO_HORIZONTAL_PIXELS);
50
51 GBAGLContextCreate(&renderer->gl);
52 renderer->gl.d.user = renderer;
53 renderer->gl.d.lockAspectRatio = renderer->lockAspectRatio;
54 renderer->gl.d.filter = renderer->filter;
55 renderer->gl.d.swap = mSDLGLCommonSwap;
56 renderer->gl.d.init(&renderer->gl.d, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 0);
57
58 _doViewport(renderer->viewportWidth, renderer->viewportHeight, &renderer->gl.d);
59 return true;
60}
61#endif
62
63#ifdef M_CORE_GB
64void mSDLGLCreateGB(struct mSDLRenderer* renderer) {
65 renderer->init = mSDLGLInitGB;
66 renderer->deinit = mSDLGLDeinit;
67 renderer->runloop = mSDLGLRunloop;
68}
69
70bool mSDLGLInitGB(struct mSDLRenderer* renderer) {
71 mSDLGLCommonInit(renderer);
72
73 // TODO: Pass texture size along
74 renderer->outputBuffer = malloc(GB_VIDEO_HORIZONTAL_PIXELS * GB_VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
75 memset(renderer->outputBuffer, 0, GB_VIDEO_HORIZONTAL_PIXELS * GB_VIDEO_VERTICAL_PIXELS * BYTES_PER_PIXEL);
76 renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, GB_VIDEO_HORIZONTAL_PIXELS);
77
78 GBAGLContextCreate(&renderer->gl);
79 renderer->gl.d.user = renderer;
80 renderer->gl.d.lockAspectRatio = renderer->lockAspectRatio;
81 renderer->gl.d.filter = renderer->filter;
82 renderer->gl.d.swap = mSDLGLCommonSwap;
83 renderer->gl.d.init(&renderer->gl.d, GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS, 0);
84
85 _doViewport(renderer->viewportWidth, renderer->viewportHeight, &renderer->gl.d);
86 return true;
87}
88#endif
89
90void mSDLGLRunloop(struct mSDLRenderer* renderer, void* user) {
91 struct mCoreThread* context = user;
92 SDL_Event event;
93 struct VideoBackend* v = &renderer->gl.d;
94
95 while (context->state < THREAD_EXITING) {
96 while (SDL_PollEvent(&event)) {
97 mSDLHandleEvent(context, &renderer->player, &event);
98#if SDL_VERSION_ATLEAST(2, 0, 0)
99 // Event handling can change the size of the screen
100 if (renderer->player.windowUpdated) {
101 SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight);
102 _doViewport(renderer->viewportWidth, renderer->viewportHeight, v);
103 renderer->player.windowUpdated = 0;
104 }
105#endif
106 }
107
108 if (mCoreSyncWaitFrameStart(&context->sync)) {
109 v->postFrame(v, renderer->outputBuffer);
110 }
111 mCoreSyncWaitFrameEnd(&context->sync);
112 v->drawFrame(v);
113 v->swap(v);
114 }
115}
116
117void mSDLGLDeinit(struct mSDLRenderer* renderer) {
118 if (renderer->gl.d.deinit) {
119 renderer->gl.d.deinit(&renderer->gl.d);
120 }
121 free(renderer->outputBuffer);
122#if SDL_VERSION_ATLEAST(2, 0, 0)
123 SDL_GL_DeleteContext(renderer->glCtx);
124#endif
125}