all repos — mgba @ 2770b654f5f1fe70ac5ddcf1d0742ef004345781

mGBA Game Boy Advance Emulator

src/platform/sdl/sw-sdl2.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 <mgba/core/core.h>
 9#include <mgba/core/thread.h>
10#include <mgba/core/version.h>
11#include <mgba-util/arm-algo.h>
12
13static bool mSDLSWInit(struct mSDLRenderer* renderer);
14static void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user);
15static void mSDLSWDeinit(struct mSDLRenderer* renderer);
16
17void mSDLSWCreate(struct mSDLRenderer* renderer) {
18	renderer->init = mSDLSWInit;
19	renderer->deinit = mSDLSWDeinit;
20	renderer->runloop = mSDLSWRunloop;
21}
22
23bool mSDLSWInit(struct mSDLRenderer* renderer) {
24	unsigned width, height;
25	renderer->core->desiredVideoDimensions(renderer->core, &width, &height);
26	renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen));
27	SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight);
28	renderer->player.window = renderer->window;
29	renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
30#ifdef COLOR_16_BIT
31#ifdef COLOR_5_6_5
32	renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height);
33#else
34	renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, width, height);
35#endif
36#else
37	renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, width, height);
38#endif
39
40	int stride;
41	SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride);
42	renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL);
43
44	return true;
45}
46
47void mSDLSWRunloop(struct mSDLRenderer* renderer, void* user) {
48	struct mCoreThread* context = user;
49	SDL_Event event;
50
51	while (mCoreThreadIsActive(context)) {
52		while (SDL_PollEvent(&event)) {
53			mSDLHandleEvent(context, &renderer->player, &event);
54		}
55
56		if (mCoreSyncWaitFrameStart(&context->impl->sync)) {
57			SDL_UnlockTexture(renderer->sdlTex);
58			SDL_RenderCopy(renderer->sdlRenderer, renderer->sdlTex, 0, 0);
59			SDL_RenderPresent(renderer->sdlRenderer);
60			int stride;
61			SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride);
62			renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL);
63		}
64		mCoreSyncWaitFrameEnd(&context->impl->sync);
65	}
66}
67
68void mSDLSWDeinit(struct mSDLRenderer* renderer) {
69	if (renderer->ratio > 1) {
70		free(renderer->outputBuffer);
71	}
72}