Reorganised source code of linux emulator SDL engine

This commit is contained in:
Silvano Seva 2022-06-09 22:17:20 +02:00
parent d2e0b7d940
commit 980fa32e73
6 changed files with 83 additions and 96 deletions

View File

@ -52,7 +52,7 @@ int main(void)
pthread_t openrtx_thread; pthread_t openrtx_thread;
pthread_create(&openrtx_thread, NULL, openrtx_run, NULL); pthread_create(&openrtx_thread, NULL, openrtx_run, NULL);
sdl_task(); sdlEngine_run();
pthread_join(openrtx_thread, NULL); pthread_join(openrtx_thread, NULL);
#endif #endif
} }

View File

@ -129,7 +129,7 @@ void display_renderRows(uint8_t startRow, uint8_t endRow)
inProgress = true; inProgress = true;
if(!sdl_ready) if(!sdl_ready)
{ {
sdl_ready = sdl_main_loop_ready(); sdl_ready = sdlEngine_ready();
} }
if(sdl_ready) if(sdl_ready)

View File

@ -21,20 +21,21 @@
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <interfaces/keyboard.h> #include <interfaces/keyboard.h>
#include <emulator/sdl_engine.h>
extern keyboard_t shellkeyq_get(); extern keyboard_t shellkeyq_get();
extern keyboard_t sdl_getKeys();
void kbd_init() void kbd_init()
{ {
} }
keyboard_t kbd_getKeys() { keyboard_t kbd_getKeys()
{
keyboard_t keys = 0; keyboard_t keys = 0;
//this pulls in emulated keypresses from the command shell //this pulls in emulated keypresses from the command shell
keys |= shellkeyq_get(); keys |= shellkeyq_get();
keys |= sdl_getKeys(); keys |= sdlEngine_getKeys();
return keys; return keys;
} }

View File

@ -541,7 +541,7 @@ void *startCLIMenu()
void emulator_start() void emulator_start()
{ {
init_sdl(); sdlEngine_init();
pthread_t cli_thread; pthread_t cli_thread;
int err = pthread_create(&cli_thread, NULL, startCLIMenu, NULL); int err = pthread_create(&cli_thread, NULL, startCLIMenu, NULL);

View File

@ -14,37 +14,26 @@
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> * * along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/ ***************************************************************************/
#include "sdl_engine.h"
#include "emulator.h"
#include <stdlib.h> #include <stdlib.h>
#include <pthread.h> #include <pthread.h>
#include <state.h> #include <state.h>
#include <interfaces/keyboard.h> #include "sdl_engine.h"
#include <SDL2/SDL.h> #include "emulator.h"
/* Shared channel to receive frame buffer updates */ chan_t fb_sync; // Shared channel to receive frame buffer updates
chan_t fb_sync; Uint32 SDL_Screenshot_Event; // Shared custom SDL event to request a screenshot
Uint32 SDL_Backlight_Event; // Shared custom SDL event to change backlight
SDL_Window *window; static SDL_Window *window;
SDL_Renderer *renderer; static SDL_Renderer *renderer;
SDL_Texture *displayTexture; static SDL_Texture *displayTexture;
/* Custom SDL Event to request a screenshot */ static bool ready = false; // Signal if the main loop is ready
Uint32 SDL_Screenshot_Event; static keyboard_t sdl_keys; // Store the keyboard status
/* Custom SDL Event to change backlight */
Uint32 SDL_Backlight_Event;
/*
* Mutex protected variables
*/
pthread_mutex_t mu;
bool ready = false; /* Signal if the main loop is ready */
keyboard_t sdl_keys; /* Store the keyboard status */
extern state_t state; static bool sdk_key_code_to_key(SDL_Keycode sym, keyboard_t *key)
bool sdk_key_code_to_key(SDL_Keycode sym, keyboard_t *key)
{ {
switch (sym) switch (sym)
{ {
@ -141,7 +130,7 @@ bool sdk_key_code_to_key(SDL_Keycode sym, keyboard_t *key)
} }
} }
int screenshot_display(const char *filename) static int screenshot_display(const char *filename)
{ {
/* /*
* https://stackoverflow.com/a/48176678 * https://stackoverflow.com/a/48176678
@ -259,25 +248,7 @@ cleanup:
return err; return err;
} }
bool sdl_main_loop_ready() static bool set_brightness(uint8_t brightness)
{
pthread_mutex_lock(&mu);
bool is_ready = ready;
pthread_mutex_unlock(&mu);
return is_ready;
}
keyboard_t sdl_getKeys()
{
pthread_mutex_lock(&mu);
keyboard_t keys = sdl_keys;
pthread_mutex_unlock(&mu);
return keys;
}
bool set_brightness(uint8_t brightness)
{ {
/* /*
* When this texture is rendered, during the copy operation each source * When this texture is rendered, during the copy operation each source
@ -294,20 +265,52 @@ bool set_brightness(uint8_t brightness)
brightness) == 0; brightness) == 0;
} }
void sdlEngine_init()
{
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0)
{
printf("SDL video init error!!\n");
exit(1);
}
// Register SDL custom events to handle screenshot requests and backlight
SDL_Screenshot_Event = SDL_RegisterEvents(2);
SDL_Backlight_Event = SDL_Screenshot_Event+1;
chan_init(&fb_sync);
window = SDL_CreateWindow("OpenRTX",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH * 3, SCREEN_HEIGHT * 3,
SDL_WINDOW_SHOWN );
renderer = SDL_CreateRenderer(window, -1, 0);
SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT);
displayTexture = SDL_CreateTexture(renderer,
PIXEL_FORMAT,
SDL_TEXTUREACCESS_STREAMING,
SCREEN_WIDTH,
SCREEN_HEIGHT);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
}
/* /*
* SDL main loop. Due to macOS restrictions, this must run on the Main Thread. * SDL main loop. Due to macOS restrictions, this must run on the Main Thread.
*/ */
void sdl_task() void sdlEngine_run()
{ {
pthread_mutex_lock(&mu);
ready = true; ready = true;
pthread_mutex_unlock(&mu);
SDL_Event ev = { 0 }; SDL_Event ev = { 0 };
while (!Radio_State.PowerOff) while (!Radio_State.PowerOff)
{ {
keyboard_t key = 0; keyboard_t key = 0;
if (SDL_PollEvent(&ev) == 1) if (SDL_PollEvent(&ev) == 1)
{ {
switch (ev.type) switch (ev.type)
@ -319,21 +322,18 @@ void sdl_task()
case SDL_KEYDOWN: case SDL_KEYDOWN:
if (sdk_key_code_to_key(ev.key.keysym.sym, &key)) if (sdk_key_code_to_key(ev.key.keysym.sym, &key))
{ {
pthread_mutex_lock(&mu);
sdl_keys |= key; sdl_keys |= key;
pthread_mutex_unlock(&mu);
} }
break; break;
case SDL_KEYUP: case SDL_KEYUP:
if (sdk_key_code_to_key(ev.key.keysym.sym, &key)) if (sdk_key_code_to_key(ev.key.keysym.sym, &key))
{ {
pthread_mutex_lock(&mu);
sdl_keys ^= key; sdl_keys ^= key;
pthread_mutex_unlock(&mu);
} }
break; break;
} }
if (ev.type == SDL_Screenshot_Event) if (ev.type == SDL_Screenshot_Event)
{ {
char *filename = (char *)ev.user.data1; char *filename = (char *)ev.user.data1;
@ -372,42 +372,20 @@ void sdl_task()
SDL_Quit(); SDL_Quit();
} }
void init_sdl() bool sdlEngine_ready()
{ {
pthread_mutex_init(&mu, NULL); /*
* bool is an atomic data type for x86 and it can be returned safely without
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) * incurring in data races between threads.
{ */
printf("SDL video init error!!\n"); return ready;
exit(1); }
}
keyboard_t sdlEngine_getKeys()
// Register SDL custom events to handle screenshot requests and backlight {
SDL_Screenshot_Event = SDL_RegisterEvents(2); /*
SDL_Backlight_Event = SDL_Screenshot_Event+1; * keyboard_t is an atomic data type for x86 and it can be returned safely
* without incurring in data races between threads.
chan_init(&fb_sync); */
return sdl_keys;
window = SDL_CreateWindow("OpenRTX",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH * 3, SCREEN_HEIGHT * 3,
SDL_WINDOW_SHOWN );
renderer = SDL_CreateRenderer(window, -1, 0);
SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT);
displayTexture = SDL_CreateTexture(renderer,
PIXEL_FORMAT,
SDL_TEXTUREACCESS_STREAMING,
SCREEN_WIDTH,
SCREEN_HEIGHT);
SDL_RenderClear(renderer);
if(!set_brightness(state.settings.brightness))
{
SDL_Log("Cannot apply brightness: %s", SDL_GetError());
}
SDL_RenderCopy(renderer, displayTexture, NULL, NULL);
SDL_RenderPresent(renderer);
} }

View File

@ -17,9 +17,10 @@
#ifndef SDL_ENGINE_H #ifndef SDL_ENGINE_H
#define SDL_ENGINE_H #define SDL_ENGINE_H
#include "chan.h" #include <interfaces/keyboard.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <stdbool.h> #include <stdbool.h>
#include <chan.h>
/* /*
* Screen dimensions, adjust basing on the size of the screen you need to * Screen dimensions, adjust basing on the size of the screen you need to
@ -44,18 +45,25 @@
/** /**
* Initialize the SDL engine. Must be called in the Main Thread. * Initialize the SDL engine. Must be called in the Main Thread.
*/ */
void init_sdl(); void sdlEngine_init();
/** /**
* SDL main loop. Must be called in the Main Thread. * SDL main loop. Must be called in the Main Thread.
*/ */
void sdl_task(); void sdlEngine_run();
/** /**
* Thread-safe check to verify if the application entered the SDL main loop. * Thread-safe check to verify if the application entered the SDL main loop.
* *
* @return true after sdl_task() started. * @return true after sdl_task() started.
*/ */
bool sdl_main_loop_ready(); bool sdlEngine_ready();
/**
* Thread-safe function returning the keys currently being pressed.
*
* @return a keyboard_t bit field with the keys currently being pressed.
*/
keyboard_t sdlEngine_getKeys();
#endif /* SDL_ENGINE_H */ #endif /* SDL_ENGINE_H */