all repos — mgba @ 25f5520b0b59a5235dae0c9c476baa9e2753269f

mGBA Game Boy Advance Emulator

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

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