kopia lustrzana https://github.com/Jean-MarcHarvengt/MCUME
251 wiersze
5.7 KiB
C++
251 wiersze
5.7 KiB
C++
![]() |
#include "go.h"
|
||
|
|
||
|
extern "C" {
|
||
|
#include "emuapi.h"
|
||
|
#include "iopins.h"
|
||
|
}
|
||
|
|
||
|
#include "esp_event.h"
|
||
|
|
||
|
#include "keyboard_osd.h"
|
||
|
|
||
|
|
||
|
#include "ili9341_t3dma.h"
|
||
|
#ifdef HAS_SND
|
||
|
#include "AudioPlaySystem.h"
|
||
|
#include "LibFC14/fc14audiodecoder.h"
|
||
|
#include "loader.h"
|
||
|
#endif
|
||
|
|
||
|
#include <rom/rtc.h>
|
||
|
#include <string.h>
|
||
|
#include <math.h>
|
||
|
#include "mcume.h"
|
||
|
|
||
|
#define RTC_SLOW_MEM ((uint32_t*) 0x50000000) /*!< RTC slow memory, 8k size */
|
||
|
|
||
|
#define ULP_DATA_OFFSET 36
|
||
|
|
||
|
_Static_assert(ULP_DATA_OFFSET < CONFIG_ULP_COPROC_RESERVE_MEM/4 - 6,
|
||
|
"ULP_DATA_OFFSET is set too high, or CONFIG_ULP_COPROC_RESERVE_MEM is not sufficient");
|
||
|
|
||
|
static inline uint16_t ulp_data_read(size_t offset)
|
||
|
{
|
||
|
return RTC_SLOW_MEM[ULP_DATA_OFFSET + offset] & 0xffff;
|
||
|
}
|
||
|
static inline void ulp_data_write(size_t offset, uint16_t value)
|
||
|
{
|
||
|
RTC_SLOW_MEM[ULP_DATA_OFFSET + offset] = value;
|
||
|
}
|
||
|
|
||
|
|
||
|
ILI9341_t3DMA tft = ILI9341_t3DMA(PIN_NUM_CS, PIN_NUM_DC, -1, PIN_NUM_MOSI, PIN_NUM_CLK, PIN_NUM_MISO, TPIN_NUM_CS, TPIN_NUM_IRQ);
|
||
|
#ifdef HAS_SND
|
||
|
AudioPlaySystem audio;
|
||
|
static void *decoder = nullptr;
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#define MAX_FILENAME_SIZE 18
|
||
|
#define MAX_MENULINES 7
|
||
|
#define TEXT_HEIGHT 16
|
||
|
#define TEXT_WIDTH 8
|
||
|
#define MENU_FILE_XOFFSET (11*TEXT_WIDTH)
|
||
|
#define MENU_FILE_YOFFSET (7*TEXT_HEIGHT)
|
||
|
#define MENU_FILE_W (MAX_FILENAME_SIZE*TEXT_WIDTH)
|
||
|
#define MENU_FILE_H (MAX_MENULINES*TEXT_HEIGHT)
|
||
|
#define MENU_FILE_FGCOLOR RGBVAL16(0xff,0xff,0xff)
|
||
|
#define MENU_FILE_BGCOLOR RGBVAL16(0x00,0x00,0x10)
|
||
|
|
||
|
|
||
|
#define NB_APPS 8
|
||
|
|
||
|
static bool menuRedraw=false;
|
||
|
static int nbFiles=NB_APPS;
|
||
|
static int curFile=0;
|
||
|
static int topFile=0;
|
||
|
static int xOffLogo=0;
|
||
|
static int swipeAngle=0;
|
||
|
|
||
|
static char * apps[NB_APPS] = {
|
||
|
" Zx81 ",
|
||
|
" Zx Spectrum ",
|
||
|
" Atari 800 ",
|
||
|
" C64 ",
|
||
|
" Atari 2600 ",
|
||
|
//" Odyssey ",
|
||
|
" NES ",
|
||
|
" Colecovision ",
|
||
|
" Atari 5200 "
|
||
|
};
|
||
|
|
||
|
|
||
|
static void initBootMenu(void) {
|
||
|
menuRedraw=true;
|
||
|
tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
|
||
|
//tft.drawSpriteNoDma(30,10,(uint16_t*)logo);
|
||
|
//tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
static int handleBootMenu(unsigned short bClick)
|
||
|
{
|
||
|
int action = -1;
|
||
|
xOffLogo = 16*sin((2*3.14*swipeAngle)/256)+30;
|
||
|
swipeAngle = (swipeAngle + 2)&0xff;
|
||
|
//printf("xOffLogo %d %d\n",xOffLogo,swipeAngle);
|
||
|
tft.drawSpriteNoDma(xOffLogo,10,(uint16_t*)logo);
|
||
|
|
||
|
if (bClick & MASK_JOY2_UP) {
|
||
|
if (curFile!=0) {
|
||
|
menuRedraw=true;
|
||
|
curFile--;
|
||
|
}
|
||
|
}
|
||
|
else if (bClick & MASK_JOY2_DOWN) {
|
||
|
if ((curFile<(nbFiles-1)) && (nbFiles)) {
|
||
|
curFile++;
|
||
|
menuRedraw=true;
|
||
|
}
|
||
|
}
|
||
|
else if (bClick & MASK_JOY2_BTN) {
|
||
|
action = curFile;
|
||
|
}
|
||
|
|
||
|
if (menuRedraw && nbFiles) {
|
||
|
//printf("update\n");
|
||
|
int fileIndex = 0;
|
||
|
int appcnt=0;
|
||
|
tft.drawRectNoDma(MENU_FILE_XOFFSET,MENU_FILE_YOFFSET, MENU_FILE_W, MENU_FILE_H, MENU_FILE_BGCOLOR);
|
||
|
if (curFile <= (MAX_MENULINES/2-1)) topFile=0;
|
||
|
else topFile=curFile-(MAX_MENULINES/2);
|
||
|
//if (curFile <= (MAX_MENULINES-1)) topFile=0;
|
||
|
//else topFile=curFile-(MAX_MENULINES/2);
|
||
|
|
||
|
int i=0;
|
||
|
while (i<MAX_MENULINES) {
|
||
|
if (appcnt == (NB_APPS)) {
|
||
|
break;
|
||
|
}
|
||
|
char * title=apps[appcnt++];
|
||
|
if (fileIndex >= topFile) {
|
||
|
if ((i+topFile) < nbFiles ) {
|
||
|
int dx = (MAX_FILENAME_SIZE-strlen(title))*TEXT_WIDTH/2;
|
||
|
if ((i+topFile)==curFile) {
|
||
|
tft.drawTextNoDma(MENU_FILE_XOFFSET+dx,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, title, RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);
|
||
|
}
|
||
|
else {
|
||
|
tft.drawTextNoDma(MENU_FILE_XOFFSET+dx,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, title, MENU_FILE_FGCOLOR, MENU_FILE_BGCOLOR, true);
|
||
|
}
|
||
|
}
|
||
|
i++;
|
||
|
}
|
||
|
fileIndex++;
|
||
|
}
|
||
|
|
||
|
|
||
|
menuRedraw=false;
|
||
|
}
|
||
|
|
||
|
|
||
|
return (action);
|
||
|
}
|
||
|
|
||
|
|
||
|
static void spi_task(void *args)
|
||
|
{
|
||
|
while(true) {
|
||
|
tft.refresh();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void input_task(void *args)
|
||
|
{
|
||
|
while(true) {
|
||
|
if ((emu_ReadKeys() & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) {
|
||
|
printf("rebooting\n");
|
||
|
esp_restart();
|
||
|
}
|
||
|
|
||
|
uint16_t bClick = emu_DebounceLocalKeys();
|
||
|
if (bClick & MASK_KEY_USER2) {
|
||
|
printf("%d\n",emu_SwapJoysticks(1));
|
||
|
emu_SwapJoysticks(0);
|
||
|
}
|
||
|
else {
|
||
|
//emu_Input(bClick);
|
||
|
}
|
||
|
#ifdef HAS_SND
|
||
|
audio.step();
|
||
|
#endif
|
||
|
vTaskDelay(20 / portTICK_PERIOD_MS);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
static void main_step() {
|
||
|
uint16_t bClick = emu_DebounceLocalKeys();
|
||
|
int action = handleBootMenu(bClick);
|
||
|
if (action >= 0) {
|
||
|
printf("launching\n");
|
||
|
ulp_data_write(0, action);
|
||
|
esp_restart();
|
||
|
}
|
||
|
#ifdef HAS_SND
|
||
|
audio.step();
|
||
|
#endif
|
||
|
//vTaskDelay(20 / portTICK_PERIOD_MS);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void setup(void)
|
||
|
{
|
||
|
printf("App selector\n");
|
||
|
|
||
|
tft.begin();
|
||
|
tft.flipscreen(true);
|
||
|
tft.start();
|
||
|
tft.refresh();
|
||
|
|
||
|
emu_InitJoysticks();
|
||
|
initBootMenu();
|
||
|
|
||
|
xTaskCreatePinnedToCore(spi_task, "spithread", 4096, NULL, 1, NULL, 0);
|
||
|
//vTaskPrioritySet(NULL, tskIDLE_PRIORITY+1);
|
||
|
|
||
|
#ifdef HAS_SND
|
||
|
audio.begin();
|
||
|
audio.start();
|
||
|
bool haveModule = false;
|
||
|
decoder = fc14dec_new();
|
||
|
haveModule = fc14dec_init(decoder,(void*)musym,sizeof(musym));
|
||
|
if ( !haveModule ) {
|
||
|
fc14dec_delete(decoder);
|
||
|
printf("FC module not supported\n");
|
||
|
}
|
||
|
else {
|
||
|
printf("FC music loaded\n");
|
||
|
fc14dec_mixer_init(decoder,22050,16,1,0 /*32767*/);
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void loop(void)
|
||
|
{
|
||
|
unsigned long t = esp_timer_get_time();
|
||
|
main_step();
|
||
|
//printf("%d\n",(int)((esp_timer_get_time()-t)/1000));
|
||
|
}
|
||
|
|
||
|
|
||
|
void SND_Process( void* stream, int len) {
|
||
|
#ifdef HAS_SND
|
||
|
fc14dec_buffer_fill(decoder,stream,len*2);
|
||
|
#endif
|
||
|
}
|
||
|
|