all repos — mgba @ 2860714714b1dd3307a4a50e8854b8eed18e43a6

mGBA Game Boy Advance Emulator

src/main.c (view raw)

  1#include "debugger.h"
  2#include "gba-thread.h"
  3#include "renderers/video-software.h"
  4
  5#include <sdl.h>
  6#include <OpenGL/gl.h>
  7
  8#include <fcntl.h>
  9#include <errno.h>
 10#include <signal.h>
 11#include <unistd.h>
 12
 13struct GLSoftwareRenderer {
 14	struct GBAVideoSoftwareRenderer d;
 15
 16	GLuint tex;
 17};
 18
 19static int _GBASDLInit(struct GLSoftwareRenderer* renderer);
 20static void _GBASDLDeinit(struct GLSoftwareRenderer* renderer);
 21static void _GBASDLRunloop(struct GBAThread* context, struct GLSoftwareRenderer* renderer);
 22
 23static const GLint _glVertices[] = {
 24	0, 0,
 25	256, 0,
 26	256, 256,
 27	0, 256
 28};
 29
 30static const GLint _glTexCoords[] = {
 31	0, 0,
 32	1, 0,
 33	1, 1,
 34	0, 1
 35};
 36
 37int main(int argc, char** argv) {
 38	int fd = open("test.rom", O_RDONLY);
 39
 40	sigset_t signals;
 41	sigaddset(&signals, SIGINT);
 42	sigaddset(&signals, SIGTRAP);
 43	pthread_sigmask(SIG_BLOCK, &signals, 0);
 44
 45	struct GBAThread context;
 46	struct GLSoftwareRenderer renderer;
 47	GBAVideoSoftwareRendererCreate(&renderer.d);
 48
 49	if (!_GBASDLInit(&renderer)) {
 50		return 1;
 51	}
 52
 53	context.fd = fd;
 54	context.renderer = &renderer.d.d;
 55	GBAThreadStart(&context);
 56
 57	_GBASDLRunloop(&context, &renderer);
 58
 59	GBAThreadJoin(&context);
 60	close(fd);
 61
 62	_GBASDLDeinit(&renderer);
 63
 64	return 0;
 65}
 66
 67static int _GBASDLInit(struct GLSoftwareRenderer* renderer) {
 68	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
 69		return 0;
 70	}
 71
 72	SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
 73	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
 74	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
 75	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
 76	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
 77	SDL_SetVideoMode(240, 160, 16, SDL_OPENGL);
 78
 79	renderer->d.outputBuffer = malloc(256 * 256 * 2);
 80	renderer->d.outputBufferStride = 256;
 81	glGenTextures(1, &renderer->tex);
 82	glBindTexture(GL_TEXTURE_2D, renderer->tex);
 83	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 84	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 85	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 86	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 87	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 88
 89	glViewport(0, 0, 240, 160);
 90
 91	return 1;
 92}
 93
 94static void _GBASDLRunloop(struct GBAThread* context, struct GLSoftwareRenderer* renderer) {
 95	SDL_Event event;
 96
 97	int err;
 98	glEnable(GL_TEXTURE_2D);
 99	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
100	glEnableClientState(GL_VERTEX_ARRAY);
101	glVertexPointer(2, GL_INT, 0, _glVertices);
102	glTexCoordPointer(2, GL_INT, 0, _glTexCoords);
103	glMatrixMode (GL_PROJECTION);
104	glLoadIdentity();
105	glOrtho(0, 240, 160, 0, 0, 1);
106	while (context->started) {
107		glBindTexture(GL_TEXTURE_2D, renderer->tex);
108		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, renderer->d.outputBuffer);
109		glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
110
111		SDL_GL_SwapBuffers();
112		pthread_mutex_lock(&renderer->d.mutex);
113		pthread_cond_broadcast(&renderer->d.cond);
114		pthread_mutex_unlock(&renderer->d.mutex);
115		while(SDL_PollEvent(&event)) {
116			
117		}
118	}
119}
120
121static void _GBASDLDeinit(struct GLSoftwareRenderer* renderer) {
122	free(renderer->d.outputBuffer);
123
124	SDL_Quit();
125}