all repos — mgba @ 0ef07f7c26d440aa216925b1d6ad4886fa3fde50

mGBA Game Boy Advance Emulator

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

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