all repos — mgba @ 7c8f1d9726eb246aac895fe90297a0ecd1ebe13a

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	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 68	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 69#ifndef _WIN32
 70	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 71	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 72#endif
 73
 74	glViewport(0, 0, renderer->viewportWidth, renderer->viewportHeight);
 75
 76	return true;
 77}
 78
 79void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
 80	SDL_Event event;
 81
 82	glEnable(GL_TEXTURE_2D);
 83	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 84	glEnableClientState(GL_VERTEX_ARRAY);
 85	glVertexPointer(2, GL_INT, 0, _glVertices);
 86	glTexCoordPointer(2, GL_INT, 0, _glTexCoords);
 87	glMatrixMode (GL_PROJECTION);
 88	glLoadIdentity();
 89	glOrtho(0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 0, 0, 1);
 90	while (context->state < THREAD_EXITING) {
 91		while (SDL_PollEvent(&event)) {
 92			GBASDLHandleEvent(context, &renderer->events, &event);
 93#if SDL_VERSION_ATLEAST(2, 0, 0)
 94			// Event handling can change the size of the screen
 95			if (renderer->events.windowUpdated) {
 96				SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight);
 97				glViewport(0, 0, renderer->viewportWidth, renderer->viewportHeight);
 98				renderer->events.windowUpdated = 0;
 99			}
100#endif
101		}
102
103		if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) {
104			glBindTexture(GL_TEXTURE_2D, renderer->tex);
105#ifdef COLOR_16_BIT
106#ifdef COLOR_5_6_5
107			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, renderer->d.outputBuffer);
108#else
109			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, renderer->d.outputBuffer);
110#endif
111#else
112			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, renderer->d.outputBuffer);
113#endif
114			if (context->sync.videoFrameWait) {
115				glFlush();
116			}
117		}
118		glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
119		GBASyncWaitFrameEnd(&context->sync);
120#if SDL_VERSION_ATLEAST(2, 0, 0)
121		SDL_GL_SwapWindow(renderer->window);
122#else
123		SDL_GL_SwapBuffers();
124#endif
125	}
126}
127
128void GBASDLDeinit(struct SDLSoftwareRenderer* renderer) {
129	UNUSED(renderer);
130}