all repos — mgba @ 7149dd3102a6bbb7f73cae7da0c01dc784b0f601

mGBA Game Boy Advance Emulator

src/platform/sdl/sw-sdl.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 "gba/supervisor/thread.h"
  9
 10#if defined(__ARM_NEON)
 11void _neon2x(void* dest, void* src, int width, int height);
 12void _neon4x(void* dest, void* src, int width, int height);
 13#endif
 14
 15bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
 16#if !SDL_VERSION_ATLEAST(2, 0, 0)
 17#ifdef COLOR_16_BIT
 18	SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_DOUBLEBUF | SDL_HWSURFACE);
 19#else
 20	SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_DOUBLEBUF | SDL_HWSURFACE);
 21#endif
 22#endif
 23
 24#if SDL_VERSION_ATLEAST(2, 0, 0)
 25	renderer->window = SDL_CreateWindow(PROJECT_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->events.fullscreen));
 26	SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight);
 27	renderer->events.window = renderer->window;
 28	renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
 29#ifdef COLOR_16_BIT
 30#ifdef COLOR_5_6_5
 31	renderer->tex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
 32#else
 33	renderer->tex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
 34#endif
 35#else
 36	renderer->tex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
 37#endif
 38
 39	SDL_LockTexture(renderer->tex, 0, &renderer->d.outputBuffer, &renderer->d.outputBufferStride);
 40	renderer->d.outputBufferStride /= BYTES_PER_PIXEL;
 41#else
 42	SDL_Surface* surface = SDL_GetVideoSurface();
 43	SDL_LockSurface(surface);
 44
 45	if (renderer->ratio == 1) {
 46		renderer->d.outputBuffer = surface->pixels;
 47#ifdef COLOR_16_BIT
 48		renderer->d.outputBufferStride = surface->pitch / 2;
 49#else
 50		renderer->d.outputBufferStride = surface->pitch / 4;
 51#endif
 52	} else {
 53		renderer->d.outputBuffer = malloc(240 * 160 * BYTES_PER_PIXEL);
 54		renderer->d.outputBufferStride = 240;
 55	}
 56#endif
 57
 58	return true;
 59}
 60
 61void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
 62	SDL_Event event;
 63#if !SDL_VERSION_ATLEAST(2, 0, 0)
 64	SDL_Surface* surface = SDL_GetVideoSurface();
 65#endif
 66
 67	while (context->state < THREAD_EXITING) {
 68		while (SDL_PollEvent(&event)) {
 69			GBASDLHandleEvent(context, &renderer->events, &event);
 70		}
 71
 72		if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) {
 73#if SDL_VERSION_ATLEAST(2, 0, 0)
 74			SDL_UnlockTexture(renderer->tex);
 75			SDL_RenderCopy(renderer->sdlRenderer, renderer->tex, 0, 0);
 76			SDL_RenderPresent(renderer->sdlRenderer);
 77			SDL_LockTexture(renderer->tex, 0, &renderer->d.outputBuffer, &renderer->d.outputBufferStride);
 78			renderer->d.outputBufferStride /= BYTES_PER_PIXEL;
 79#else
 80			switch (renderer->ratio) {
 81#if defined(__ARM_NEON) && COLOR_16_BIT
 82			case 2:
 83				_neon2x(surface->pixels, renderer->d.outputBuffer, 240, 160);
 84				break;
 85			case 4:
 86				_neon4x(surface->pixels, renderer->d.outputBuffer, 240, 160);
 87				break;
 88#endif
 89			case 1:
 90				break;
 91			default:
 92				abort();
 93			}
 94			SDL_UnlockSurface(surface);
 95			SDL_Flip(surface);
 96			SDL_LockSurface(surface);
 97#endif
 98		}
 99		GBASyncWaitFrameEnd(&context->sync);
100	}
101}
102
103void GBASDLDeinit(struct SDLSoftwareRenderer* renderer) {
104	UNUSED(renderer);
105}