all repos — mgba @ f53f9555a26461fee86ba676e4f04d8bdecf7c40

mGBA Game Boy Advance Emulator

src/platform/sdl/gl-sdl.c (view raw)

  1/* Copyright (c) 2013-2014 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-thread.h"
  9
 10#ifdef __APPLE__
 11#include <OpenGL/gl.h>
 12#else
 13#include <GL/gl.h>
 14#endif
 15
 16#ifdef BUILD_GL
 17static const GLint _glVertices[] = {
 18	0, 0,
 19	256, 0,
 20	256, 256,
 21	0, 256
 22};
 23
 24static const GLint _glTexCoords[] = {
 25	0, 0,
 26	1, 0,
 27	1, 1,
 28	0, 1
 29};
 30#endif
 31
 32bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
 33#ifndef COLOR_16_BIT
 34	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
 35	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
 36	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
 37#else
 38	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
 39#ifdef COLOR_5_6_5
 40	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
 41#else
 42	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
 43#endif
 44	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
 45#endif
 46
 47#if SDL_VERSION_ATLEAST(2, 0, 0)
 48	renderer->window = SDL_CreateWindow(PROJECT_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->events.fullscreen));
 49	SDL_GL_CreateContext(renderer->window);
 50	SDL_GL_SetSwapInterval(1);
 51	SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight);
 52	renderer->events.window = renderer->window;
 53#else
 54	SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
 55#ifdef COLOR_16_BIT
 56	SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_OPENGL);
 57#else
 58	SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_OPENGL);
 59#endif
 60#endif
 61
 62	renderer->d.outputBuffer = malloc(256 * 256 * 4);
 63	renderer->d.outputBufferStride = 256;
 64	glGenTextures(1, &renderer->tex);
 65	glBindTexture(GL_TEXTURE_2D, renderer->tex);
 66	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 67	if (renderer->filter) {
 68		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 69		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 70	} else {
 71		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 72		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 73	}
 74#ifndef _WIN32
 75	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 76	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 77#endif
 78
 79	glViewport(0, 0, renderer->viewportWidth, renderer->viewportHeight);
 80
 81	return true;
 82}
 83
 84void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
 85	SDL_Event event;
 86
 87	glEnable(GL_TEXTURE_2D);
 88	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 89	glEnableClientState(GL_VERTEX_ARRAY);
 90	glVertexPointer(2, GL_INT, 0, _glVertices);
 91	glTexCoordPointer(2, GL_INT, 0, _glTexCoords);
 92	glMatrixMode (GL_PROJECTION);
 93	glLoadIdentity();
 94	glOrtho(0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 0, 0, 1);
 95	while (context->state < THREAD_EXITING) {
 96		while (SDL_PollEvent(&event)) {
 97			GBASDLHandleEvent(context, &renderer->events, &event);
 98#if SDL_VERSION_ATLEAST(2, 0, 0)
 99			// Event handling can change the size of the screen
100			if (renderer->events.windowUpdated) {
101				SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight);
102				glViewport(0, 0, renderer->viewportWidth, renderer->viewportHeight);
103				renderer->events.windowUpdated = 0;
104			}
105#endif
106		}
107
108		if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) {
109			glBindTexture(GL_TEXTURE_2D, renderer->tex);
110#ifdef COLOR_16_BIT
111#ifdef COLOR_5_6_5
112			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, renderer->d.outputBuffer);
113#else
114			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, renderer->d.outputBuffer);
115#endif
116#else
117			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, renderer->d.outputBuffer);
118#endif
119			if (context->sync.videoFrameWait) {
120				glFlush();
121			}
122		}
123		glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
124		GBASyncWaitFrameEnd(&context->sync);
125#if SDL_VERSION_ATLEAST(2, 0, 0)
126		SDL_GL_SwapWindow(renderer->window);
127#else
128		SDL_GL_SwapBuffers();
129#endif
130	}
131}
132
133void GBASDLDeinit(struct SDLSoftwareRenderer* renderer) {
134	UNUSED(renderer);
135}