Reorganised source code of linux emulator main engine

This commit is contained in:
Silvano Seva 2022-06-09 22:48:09 +02:00
parent 763eb0c2be
commit 5c94d33b6b
5 changed files with 133 additions and 112 deletions

View File

@ -22,8 +22,7 @@
#include <stdint.h> #include <stdint.h>
#include <interfaces/keyboard.h> #include <interfaces/keyboard.h>
#include <emulator/sdl_engine.h> #include <emulator/sdl_engine.h>
#include <emulator/emulator.h>
extern keyboard_t shellkeyq_get();
void kbd_init() void kbd_init()
{ {
@ -34,7 +33,7 @@ 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 |= emulator_getKeys();
keys |= sdlEngine_getKeys(); keys |= sdlEngine_getKeys();
return keys; return keys;

View File

@ -18,25 +18,32 @@
* 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 "emulator.h"
#include "sdl_engine.h"
#include <pthread.h> #include <pthread.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <interfaces/keyboard.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <readline/readline.h> #include <readline/readline.h>
#include <readline/history.h> #include <readline/history.h>
#include "emulator.h"
#include "sdl_engine.h"
/* Custom SDL Event to request a screenshot */ /* Custom SDL Event to request a screenshot */
extern Uint32 SDL_Screenshot_Event; extern Uint32 SDL_Screenshot_Event;
radio_state Radio_State = {12, 8.2f, 3, 4, 1, false, false}; emulator_state_t emulator_state =
{
12, // RSSI
8.2f, // Vbat
3, // mic level
4, // volume level
1, // chSelector
false, // PTT status
false // power off
};
typedef int (*_climenu_fn)(void *self, int argc, char **argv); typedef int (*_climenu_fn)(void *self, int argc, char **argv);
@ -46,7 +53,8 @@ typedef struct
char *description; char *description;
void *var; void *var;
_climenu_fn fn; _climenu_fn fn;
} _climenu_option; }
_climenu_option;
enum shell_retvals enum shell_retvals
{ {
@ -56,21 +64,35 @@ enum shell_retvals
SH_EXIT_OK = 2, SH_EXIT_OK = 2,
}; };
static keyboard_t _shellkeyq[25] = {0};
static int _skq_cap = 25;
static int _skq_head;
static int _skq_tail;
static int _skq_in;
static int _skq_out;
keyboard_t _shellkeyq[25] = {0}; // NOTE: unused function
int _skq_cap = 25; // static void _dump_skq()
int _skq_head; // {
int _skq_tail; // for(int i = 0; i < _skq_cap; i++)
int _skq_in; // {
int _skq_out; // printf("skq[%d] == %d\n", i, _shellkeyq[i]);
void _dump_skq() // }
{ // }
for(int i = 0; i < _skq_cap; i++)
{ // NOTE: unused function
printf("skq[%d] == %d\n", i, _shellkeyq[i]); // static void _test_skq()
} // {
} // for(int i = 0; i < 257; i++)
void shellkeyq_put(keyboard_t keys) // {
// shellkeyq_put(i + 1);
// }
//
// //clear it out now
// while(emulator_getKeys());
// }
static void shellkeyq_put(keyboard_t keys)
{ {
// note - we must allow keys == 0 to be inserted because otherwise a queue // note - we must allow keys == 0 to be inserted because otherwise a queue
// full of [1,1,1,1,1] is simulating HOLDING 1, and we sometimes // full of [1,1,1,1,1] is simulating HOLDING 1, and we sometimes
@ -87,35 +109,8 @@ void shellkeyq_put(keyboard_t keys)
_skq_in++; _skq_in++;
_skq_tail = (_skq_tail + 1) % _skq_cap; _skq_tail = (_skq_tail + 1) % _skq_cap;
} }
keyboard_t shellkeyq_get()
{
if(_skq_in > _skq_out)
{
//only if we've fallen behind and there's data in there:
keyboard_t out = _shellkeyq[ _skq_head ];
_shellkeyq[ _skq_head ] = 0;
_skq_out++;
_skq_head = (_skq_head + 1) % _skq_cap;
return out;
}
else
{
return 0; //no keys
}
}
void _test_skq()
{
for(int i = 0; i < 257; i++)
{
shellkeyq_put(i + 1);
}
//clear it out now static int shell_ready(void *_self, int _argc, char **_argv)
while(shellkeyq_get());
}
int shell_ready(void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
(void) _argc; (void) _argc;
@ -128,7 +123,7 @@ int shell_ready(void *_self, int _argc, char **_argv)
return SH_CONTINUE; return SH_CONTINUE;
} }
keyboard_t keyname2keyboard(char *name) static keyboard_t keyname2keyboard(char *name)
{ {
/* The line noise at the end of this comment is a vim macro for taking the /* The line noise at the end of this comment is a vim macro for taking the
* keyboard.h interface and putting it into the format further below. * keyboard.h interface and putting it into the format further below.
@ -179,7 +174,7 @@ keyboard_t keyname2keyboard(char *name)
return 0; return 0;
} }
int pressKey(void *_self, int _argc, char **_argv) static int pressKey(void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
@ -215,7 +210,7 @@ int pressKey(void *_self, int _argc, char **_argv)
// pressMultiKeys allows for key combos by sending all the keys specified in // pressMultiKeys allows for key combos by sending all the keys specified in
// one keyboard_t // one keyboard_t
int pressMultiKeys(void *_self, int _argc, char **_argv) static int pressMultiKeys(void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
printf("Press Keys: [\n"); printf("Press Keys: [\n");
@ -236,23 +231,24 @@ int pressMultiKeys(void *_self, int _argc, char **_argv)
return SH_CONTINUE; // continue return SH_CONTINUE; // continue
} }
int template(void *_self, int _argc, char **_argv) // NOTE: unused function
{ // static int template(void *_self, int _argc, char **_argv)
_climenu_option *self = (_climenu_option *) _self; // {
printf("%s\n\t%s\n", self->name, self->description); // _climenu_option *self = (_climenu_option *) _self;
// printf("%s\n\t%s\n", self->name, self->description);
//
// for(int i = 0; i < _argc; i++)
// {
// if(_argv[i] != NULL)
// {
// printf("\tArgs:\t%s\n", _argv[i]);
// }
// }
//
// return SH_CONTINUE; // continue
// }
for(int i = 0; i < _argc; i++) static int screenshot(void *_self, int _argc, char **_argv)
{
if(_argv[i] != NULL)
{
printf("\tArgs:\t%s\n", _argv[i]);
}
}
return SH_CONTINUE; // continue
}
int screenshot(void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
char *filename = "screenshot.bmp"; char *filename = "screenshot.bmp";
@ -271,7 +267,7 @@ int screenshot(void *_self, int _argc, char **_argv)
return SDL_PushEvent(&e) == 1 ? SH_CONTINUE : SH_ERR; return SDL_PushEvent(&e) == 1 ? SH_CONTINUE : SH_ERR;
} }
int setFloat(void *_self, int _argc, char **_argv) static int setFloat(void *_self, int _argc, char **_argv)
{ {
_climenu_option *self = (_climenu_option *) _self; _climenu_option *self = (_climenu_option *) _self;
@ -289,7 +285,7 @@ int setFloat(void *_self, int _argc, char **_argv)
} }
int toggleVariable(void *_self, int _argc, char **_argv) static int toggleVariable(void *_self, int _argc, char **_argv)
{ {
(void) _argc; (void) _argc;
(void) _argv; (void) _argv;
@ -299,7 +295,7 @@ int toggleVariable(void *_self, int _argc, char **_argv)
return SH_CONTINUE; // continue return SH_CONTINUE; // continue
} }
int shell_sleep(void *_self, int _argc, char **_argv) static int shell_sleep(void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
@ -314,7 +310,7 @@ int shell_sleep(void *_self, int _argc, char **_argv)
return SH_CONTINUE; return SH_CONTINUE;
} }
int shell_quit( void *_self, int _argc, char **_argv) static int shell_quit( void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
(void) _argc; (void) _argc;
@ -325,22 +321,22 @@ int shell_quit( void *_self, int _argc, char **_argv)
return SH_EXIT_OK; //normal quit return SH_EXIT_OK; //normal quit
} }
int printState( void *_self, int _argc, char **_argv) static int printState( void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
(void) _argc; (void) _argc;
(void) _argv; (void) _argv;
printf("\nCurrent state\n"); printf("\nCurrent state\n");
printf("RSSI : %f\n", Radio_State.RSSI); printf("RSSI : %f\n", emulator_state.RSSI);
printf("Battery: %f\n", Radio_State.Vbat); printf("Battery: %f\n", emulator_state.vbat);
printf("Mic : %f\n", Radio_State.micLevel); printf("Mic : %f\n", emulator_state.micLevel);
printf("Volume : %f\n", Radio_State.volumeLevel); printf("Volume : %f\n", emulator_state.volumeLevel);
printf("Channel: %f\n", Radio_State.chSelector); printf("Channel: %f\n", emulator_state.chSelector);
printf("PTT : %s\n\n", Radio_State.PttStatus ? "true" : "false"); printf("PTT : %s\n\n", emulator_state.PTTstatus ? "true" : "false");
return SH_CONTINUE; return SH_CONTINUE;
} }
int shell_nop( void *_self, int _argc, char **_argv) static int shell_nop( void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
(void) _argc; (void) _argc;
@ -350,17 +346,17 @@ int shell_nop( void *_self, int _argc, char **_argv)
} }
// Forward declaration needed to include function pointer in the table below // Forward declaration needed to include function pointer in the table below
int shell_help( void *_self, int _argc, char **_argv); static int shell_help( void *_self, int _argc, char **_argv);
_climenu_option _options[] = static _climenu_option _options[] =
{ {
/* name/shortcut description var reference, if available method to call */ /* name/shortcut description var reference, if available method to call */
{"rssi", "Set rssi", (void *) &Radio_State.RSSI, setFloat }, {"rssi", "Set rssi", (void *) &emulator_state.RSSI, setFloat },
{"vbat", "Set vbat", (void *) &Radio_State.Vbat, setFloat }, {"vbat", "Set vbat", (void *) &emulator_state.vbat, setFloat },
{"mic", "Set miclevel", (void *) &Radio_State.micLevel, setFloat }, {"mic", "Set miclevel", (void *) &emulator_state.micLevel, setFloat },
{"volume", "Set volume", (void *) &Radio_State.volumeLevel, setFloat }, {"volume", "Set volume", (void *) &emulator_state.volumeLevel, setFloat },
{"channel", "Set channel", (void *) &Radio_State.chSelector, setFloat }, {"channel", "Set channel", (void *) &emulator_state.chSelector, setFloat },
{"ptt", "Toggle PTT", (void *) &Radio_State.PttStatus, toggleVariable }, {"ptt", "Toggle PTT", (void *) &emulator_state.PTTstatus, toggleVariable },
{"key", "Press keys in sequence (e.g. 'key ENTER DOWN ENTER' will descend through two menus)", {"key", "Press keys in sequence (e.g. 'key ENTER DOWN ENTER' will descend through two menus)",
NULL, pressKey NULL, pressKey
}, },
@ -378,9 +374,10 @@ _climenu_option _options[] =
/*"but is already implied by key and keycombo so there's not much direct use for it right now",*/ /*"but is already implied by key and keycombo so there's not much direct use for it right now",*/
/*NULL, shell_ready },*/ /*NULL, shell_ready },*/
}; };
int num_options = (sizeof(_options) / sizeof(_climenu_option));
int shell_help( void *_self, int _argc, char **_argv) static const int num_options = (sizeof(_options) / sizeof(_climenu_option));
static int shell_help( void *_self, int _argc, char **_argv)
{ {
(void) _self; (void) _self;
(void) _argc; (void) _argc;
@ -396,8 +393,7 @@ int shell_help( void *_self, int _argc, char **_argv)
return SH_CONTINUE; return SH_CONTINUE;
} }
static _climenu_option *findMenuOption(char *tok)
_climenu_option *findMenuOption(char *tok)
{ {
for(int i = 0; i < num_options; i++) for(int i = 0; i < num_options; i++)
{ {
@ -418,7 +414,7 @@ _climenu_option *findMenuOption(char *tok)
return NULL; return NULL;
} }
void striptoken(char *token) static void striptoken(char *token)
{ {
for(size_t i = 0; i < strlen(token); i++) for(size_t i = 0; i < strlen(token); i++)
{ {
@ -429,7 +425,7 @@ void striptoken(char *token)
} }
} }
int process_line(char *line) static int process_line(char *line)
{ {
char *token = strtok(line, " "); char *token = strtok(line, " ");
@ -490,6 +486,7 @@ void *startCLIMenu()
do do
{ {
char *r = readline(">"); char *r = readline(">");
if(r == NULL) if(r == NULL)
{ {
ret = SH_EXIT_OK; ret = SH_EXIT_OK;
@ -522,6 +519,7 @@ void *startCLIMenu()
case SH_EXIT_OK: case SH_EXIT_OK:
//normal quit //normal quit
emulator_state.powerOff = true;
break; break;
case SH_ERR: case SH_ERR:
@ -530,15 +528,19 @@ void *startCLIMenu()
ret = SH_CONTINUE; ret = SH_CONTINUE;
break; break;
} }
free(r); //free the string allocated by readline free(r); //free the string allocated by readline
} }
while(ret == SH_CONTINUE); while((ret == SH_CONTINUE) && (emulator_state.powerOff == false));
fflush(stdout); fflush(stdout);
write_history(histfile); write_history(histfile);
Radio_State.PowerOff = true;
return NULL;
} }
void emulator_start() void emulator_start()
{ {
sdlEngine_init(); sdlEngine_init();
@ -551,3 +553,20 @@ void emulator_start()
printf("An error occurred starting the emulator CLI thread: %d\n", err); printf("An error occurred starting the emulator CLI thread: %d\n", err);
} }
} }
keyboard_t emulator_getKeys()
{
if(_skq_in > _skq_out)
{
//only if we've fallen behind and there's data in there:
keyboard_t out = _shellkeyq[ _skq_head ];
_shellkeyq[ _skq_head ] = 0;
_skq_out++;
_skq_head = (_skq_head + 1) % _skq_cap;
return out;
}
else
{
return 0; //no keys
}
}

View File

@ -20,6 +20,7 @@
#ifndef EMULATOR_H #ifndef EMULATOR_H
#define EMULATOR_H #define EMULATOR_H
#include <interfaces/keyboard.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
@ -47,17 +48,19 @@ enum choices
typedef struct typedef struct
{ {
float RSSI; float RSSI;
float Vbat; float vbat;
float micLevel; float micLevel;
float volumeLevel; float volumeLevel;
float chSelector; float chSelector;
bool PttStatus; bool PTTstatus;
bool PowerOff; bool powerOff;
} radio_state; }
emulator_state_t;
extern radio_state Radio_State; extern emulator_state_t emulator_state;
void emulator_start(); void emulator_start();
void emulator_process_sdl_events();
keyboard_t emulator_getKeys();
#endif /* EMULATOR_H */ #endif /* EMULATOR_H */

View File

@ -312,7 +312,7 @@ void sdlEngine_run()
SDL_Event ev = { 0 }; SDL_Event ev = { 0 };
while (!Radio_State.PowerOff) while (!emulator_state.powerOff)
{ {
keyboard_t key = 0; keyboard_t key = 0;
@ -321,7 +321,7 @@ void sdlEngine_run()
switch (ev.type) switch (ev.type)
{ {
case SDL_QUIT: case SDL_QUIT:
Radio_State.PowerOff = true; emulator_state.powerOff = true;
break; break;
case SDL_KEYDOWN: case SDL_KEYDOWN:

View File

@ -74,7 +74,7 @@ void platform_setBacklightLevel(uint8_t level)
// Simulate a fully charged lithium battery // Simulate a fully charged lithium battery
uint16_t platform_getVbat() uint16_t platform_getVbat()
{ {
float voltage = Radio_State.Vbat; float voltage = emulator_state.vbat;
if(voltage < 0.0f) voltage = 0.0f; if(voltage < 0.0f) voltage = 0.0f;
if(voltage > 65.0f) voltage = 65.0f; if(voltage > 65.0f) voltage = 65.0f;
return ((uint16_t) voltage); return ((uint16_t) voltage);
@ -82,7 +82,7 @@ uint16_t platform_getVbat()
uint8_t platform_getMicLevel() uint8_t platform_getMicLevel()
{ {
float level = Radio_State.micLevel; float level = emulator_state.micLevel;
if(level < 0.0f) level = 0.0f; if(level < 0.0f) level = 0.0f;
if(level > 255.0f) level = 255.0f; if(level > 255.0f) level = 255.0f;
@ -91,7 +91,7 @@ uint8_t platform_getMicLevel()
uint8_t platform_getVolumeLevel() uint8_t platform_getVolumeLevel()
{ {
float level = Radio_State.volumeLevel; float level = emulator_state.volumeLevel;
if(level < 0.0f) level = 0.0f; if(level < 0.0f) level = 0.0f;
if(level > 255.0f) level = 255.0f; if(level > 255.0f) level = 255.0f;
@ -100,7 +100,7 @@ uint8_t platform_getVolumeLevel()
int8_t platform_getChSelector() int8_t platform_getChSelector()
{ {
return Radio_State.chSelector; return emulator_state.chSelector;
} }
bool platform_getPttStatus() bool platform_getPttStatus()
@ -117,7 +117,7 @@ bool platform_getPttStatus()
bool platform_pwrButtonStatus() bool platform_pwrButtonStatus()
{ {
/* Suppose radio is always on */ /* Suppose radio is always on */
return !Radio_State.PowerOff; return !emulator_state.powerOff;
} }
void platform_ledOn(led_t led) void platform_ledOn(led_t led)