all repos — mgba @ 22245617f434049f4646916d1b2930d376503b0d

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