roo_e/roo-e/src/platform/sdl2.c
2022-06-28 16:00:42 -05:00

230 lines
6.3 KiB
C

/*
* Roo/E, the Kangaroo Punch Portable GUI Toolkit
* Copyright (C) 2022 Scott Duensing
*
* http://kangaroopunch.com
*
*
* This file is part of Roo/E.
*
* Roo/E is free software: you can redistribute it and/or modify it under the
* terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* Roo/E is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Roo/E. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef BACKEND_SDL2
#include <SDL2/SDL.h>
#include "platform.h"
static SDL_Window *_window = NULL;
static SDL_Renderer *_renderer = NULL;
static SDL_Texture *_texture = NULL;
static uint16_t _width = 0;
static uint16_t _height = 0;
static uint8_t _windowScale = 1;
void platformEventGet(EventT *event) {
SDL_Event e;
static uint8_t ASCII = 0;
static uint8_t debounce = 0;
static uint8_t buttons = 0;
static int16_t x = 0;
static int16_t y = 0;
memset(event, 0, sizeof(EventT));
while (SDL_PollEvent(&e)) {
switch (e.type) {
case SDL_MOUSEMOTION:
x = e.motion.x;
y = e.motion.y;
break;
case SDL_MOUSEBUTTONUP:
if (e.button.button == SDL_BUTTON_LEFT) {
buttons &= ~BUTTON_LEFT;
event->flags |= EVENT_FLAG_LEFT_UP;
}
if (e.button.button == SDL_BUTTON_RIGHT) {
buttons &= ~BUTTON_RIGHT;
event->flags |= EVENT_FLAG_RIGHT_UP;
}
break;
case SDL_MOUSEBUTTONDOWN:
if (e.button.button == SDL_BUTTON_LEFT) {
buttons |= BUTTON_LEFT;
event->flags |= EVENT_FLAG_LEFT_DOWN;
}
if (e.button.button == SDL_BUTTON_RIGHT) {
buttons |= BUTTON_RIGHT;
event->flags |= EVENT_FLAG_RIGHT_DOWN;
}
break;
case SDL_KEYUP:
ASCII = 0;
debounce = 0;
break;
case SDL_KEYDOWN:
if (debounce == 0) {
if (e.key.keysym.scancode != 0) {
// Not a meta key
debounce = 1;
ASCII = e.key.keysym.sym;
//if (e.key.keysym.scancode == SDL_SCANCODE_ESCAPE) ASCII = 27;
event->key = ASCII;
event->flags |= EVENT_FLAG_KEYPRESS;
}
}
break;
}
}
event->x = x;
event->y = y;
event->buttons = buttons;
if ((SDL_GetModState() & KMOD_ALT) != 0) event->kbstat |= META_ALT;
if ((SDL_GetModState() & KMOD_CTRL) != 0) event->kbstat |= META_CTRL;
if ((SDL_GetModState() & KMOD_SHIFT) != 0) event->kbstat |= META_SHIFT;
}
void platformShutdown(void) {
SDL_ShowCursor(SDL_ENABLE);
surfaceShutdown();
if (_texture) {
SDL_DestroyTexture(_texture);
_texture = NULL;
}
if (_renderer) {
SDL_DestroyRenderer(_renderer);
_renderer = NULL;
}
if (_window) {
SDL_DestroyWindow(_window);
_window = NULL;
}
SDL_Quit();
}
uint8_t platformStartup(int16_t width, int16_t height, int16_t depth) {
SDL_PixelFormatEnum pixelFormat;
(void)depth;
/*
SDL_Surface *bits8 = SDL_CreateRGBSurfaceWithFormat(0, 320, 200, 8, SDL_PIXELFORMAT_RGB332);
SDL_Surface *bits16 = SDL_CreateRGBSurfaceWithFormat(0, 320, 200, 8, SDL_PIXELFORMAT_RGB565);
SDL_Surface *bits32 = SDL_CreateRGBSurfaceWithFormat(0, 320, 200, 8, SDL_PIXELFORMAT_ARGB8888);
logWrite("8 Red Mask %u Shift %u Loss %u\n", bits8->format->Rmask, bits8->format->Rshift, bits8->format->Rloss);
logWrite("8 Green Mask %u Shift %u Loss %u\n", bits8->format->Gmask, bits8->format->Gshift, bits8->format->Gloss);
logWrite("8 Blue Mask %u Shift %u Loss %u\n", bits8->format->Bmask, bits8->format->Bshift, bits8->format->Bloss);
logWrite("8 Alpha Mask %u Shift %u Loss %u\n\n", bits8->format->Amask, bits8->format->Ashift, bits8->format->Aloss);
logWrite("16 Red Mask %u Shift %u Loss %u\n", bits16->format->Rmask, bits16->format->Rshift, bits16->format->Rloss);
logWrite("16 Green Mask %u Shift %u Loss %u\n", bits16->format->Gmask, bits16->format->Gshift, bits16->format->Gloss);
logWrite("16 Blue Mask %u Shift %u Loss %u\n", bits16->format->Bmask, bits16->format->Bshift, bits16->format->Bloss);
logWrite("16 Alpha Mask %u Shift %u Loss %u\n\n", bits16->format->Amask, bits16->format->Ashift, bits16->format->Aloss);
logWrite("32 Red Mask %u Shift %u Loss %u\n", bits32->format->Rmask, bits32->format->Rshift, bits32->format->Rloss);
logWrite("32 Green Mask %u Shift %u Loss %u\n", bits32->format->Gmask, bits32->format->Gshift, bits32->format->Gloss);
logWrite("32 Blue Mask %u Shift %u Loss %u\n", bits32->format->Bmask, bits32->format->Bshift, bits32->format->Bloss);
logWrite("32 Alpha Mask %u Shift %u Loss %u\n\n", bits32->format->Amask, bits32->format->Ashift, bits32->format->Aloss);
*/
switch (depth) {
case 8:
pixelFormat = SDL_PIXELFORMAT_RGB332;
break;
case 16:
pixelFormat = SDL_PIXELFORMAT_RGB565;
break;
case 32:
pixelFormat = SDL_PIXELFORMAT_ARGB8888;
break;
}
SDL_Init(SDL_INIT_EVERYTHING);
_windowScale = 3;
_window = SDL_CreateWindow("GUI Debug", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_ALLOW_HIGHDPI);
_renderer = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED);
_texture = SDL_CreateTexture(_renderer, pixelFormat, SDL_TEXTUREACCESS_STREAMING, width, height);
SDL_RenderSetLogicalSize(_renderer, width, height);
SDL_SetWindowSize(_window, width * _windowScale, height * _windowScale);
SDL_ShowCursor(SDL_DISABLE);
_width = width;
_height = height;
surfaceStartup(depth);
return SUCCESS;
}
void videoBlit(int16_t targetX, int16_t targetY, SurfaceT *source) {
void *pixels;
int temp;
//***TODO*** Does not handle partial blits at this time.
(void)targetX;
(void)targetY;
SDL_LockTexture(_texture, NULL, &pixels, &temp);
memcpy(pixels, source->buffer.bits8, source->bytes);
SDL_UnlockTexture(_texture);
SDL_RenderCopy(_renderer, _texture, NULL, NULL);
SDL_RenderPresent(_renderer);
// Throttle this to some sane frame rate.
SDL_Delay(32);
}
uint16_t videoDisplayHeightGet(void) {
return _height;
}
uint16_t videoDisplayWidthGet(void) {
return _width;
}
void videoModesShow(void) {
// Nada
}
#endif // BACKEND_SDL2