/ MCUME_esp32 / espboot / main / go.cpp
go.cpp
  1  #include "go.h"
  2  
  3  extern "C" {
  4    #include "emuapi.h"
  5    #include "iopins.h"
  6  }
  7  
  8  #include "esp_event.h"
  9  
 10  #include "keyboard_osd.h"
 11  
 12  
 13  #include "ili9341_t3dma.h"
 14  #ifdef HAS_SND
 15  #include "AudioPlaySystem.h"
 16  #include "LibFC14/fc14audiodecoder.h"
 17  #include "loader.h"
 18  #endif
 19  
 20  #include <rom/rtc.h>
 21  #include <string.h>
 22  #include <math.h>
 23  #include "mcume.h"
 24  
 25  #define RTC_SLOW_MEM ((uint32_t*) 0x50000000)       /*!< RTC slow memory, 8k size */
 26  
 27  #define ULP_DATA_OFFSET     36
 28  
 29  _Static_assert(ULP_DATA_OFFSET < CONFIG_ULP_COPROC_RESERVE_MEM/4 - 6,
 30          "ULP_DATA_OFFSET is set too high, or CONFIG_ULP_COPROC_RESERVE_MEM is not sufficient");
 31  
 32  static inline uint16_t ulp_data_read(size_t offset)
 33  {
 34      return RTC_SLOW_MEM[ULP_DATA_OFFSET + offset] & 0xffff;
 35  }
 36  static inline void ulp_data_write(size_t offset, uint16_t value)
 37  {
 38      RTC_SLOW_MEM[ULP_DATA_OFFSET + offset] = value;
 39  }
 40  
 41  
 42  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);
 43  #ifdef HAS_SND
 44  AudioPlaySystem audio;
 45  static void *decoder = nullptr;  
 46  #endif
 47  
 48  
 49  #define MAX_FILENAME_SIZE   18
 50  #define MAX_MENULINES       7
 51  #define TEXT_HEIGHT         16
 52  #define TEXT_WIDTH          8
 53  #define MENU_FILE_XOFFSET   (11*TEXT_WIDTH)
 54  #define MENU_FILE_YOFFSET   (7*TEXT_HEIGHT)
 55  #define MENU_FILE_W         (MAX_FILENAME_SIZE*TEXT_WIDTH)
 56  #define MENU_FILE_H         (MAX_MENULINES*TEXT_HEIGHT)
 57  #define MENU_FILE_FGCOLOR   RGBVAL16(0xff,0xff,0xff)
 58  #define MENU_FILE_BGCOLOR   RGBVAL16(0x00,0x00,0x10)
 59  
 60  
 61  #define NB_APPS 8
 62  
 63  static bool menuRedraw=false;
 64  static int nbFiles=NB_APPS;
 65  static int curFile=0;
 66  static int topFile=0;
 67  static int xOffLogo=0;
 68  static int swipeAngle=0;
 69  
 70  static char * apps[NB_APPS] = {
 71  "       Zx81       ",
 72  "   Zx Spectrum    ",
 73  "    Atari 800     ",
 74  "       C64        ",
 75  "    Atari 2600    ",
 76  //"     Odyssey      ",
 77  "       NES        ",
 78  "   Colecovision   ",
 79  "    Atari 5200    "
 80  };
 81  
 82  
 83  static void initBootMenu(void) {
 84    menuRedraw=true;  
 85    tft.fillScreenNoDma(RGBVAL16(0x00,0x00,0x00));
 86    //tft.drawSpriteNoDma(30,10,(uint16_t*)logo);
 87    //tft.drawTextNoDma(0,0, TITLE, RGBVAL16(0x00,0xff,0xff), RGBVAL16(0x00,0x00,0xff), true);  
 88  }
 89  
 90  
 91  
 92  static int handleBootMenu(unsigned short bClick)
 93  {
 94    int action = -1;
 95    xOffLogo = 16*sin((2*3.14*swipeAngle)/256)+30;
 96    swipeAngle = (swipeAngle + 2)&0xff;
 97  //printf("xOffLogo %d %d\n",xOffLogo,swipeAngle);
 98    tft.drawSpriteNoDma(xOffLogo,10,(uint16_t*)logo);
 99  
100    if (bClick & MASK_JOY2_UP) {
101      if (curFile!=0) {
102        menuRedraw=true;
103        curFile--;
104      }
105    } 
106    else if (bClick & MASK_JOY2_DOWN)  {
107      if ((curFile<(nbFiles-1)) && (nbFiles)) {
108        curFile++;
109        menuRedraw=true;
110      }
111    }   
112    else if (bClick & MASK_JOY2_BTN)  {
113      action = curFile;
114    }
115   
116    if (menuRedraw && nbFiles) {
117      //printf("update\n");
118      int fileIndex = 0;
119      int appcnt=0;
120      tft.drawRectNoDma(MENU_FILE_XOFFSET,MENU_FILE_YOFFSET, MENU_FILE_W, MENU_FILE_H, MENU_FILE_BGCOLOR);
121      if (curFile <= (MAX_MENULINES/2-1)) topFile=0;
122      else topFile=curFile-(MAX_MENULINES/2);
123      //if (curFile <= (MAX_MENULINES-1)) topFile=0;
124      //else topFile=curFile-(MAX_MENULINES/2);
125      
126      int i=0;
127      while (i<MAX_MENULINES) {
128        if (appcnt == (NB_APPS)) {
129          break;
130        }     
131        char * title=apps[appcnt++];
132        if (fileIndex >= topFile) {              
133          if ((i+topFile) < nbFiles ) {
134            int dx = (MAX_FILENAME_SIZE-strlen(title))*TEXT_WIDTH/2;
135            if ((i+topFile)==curFile) {
136              tft.drawTextNoDma(MENU_FILE_XOFFSET+dx,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, title, RGBVAL16(0xff,0xff,0x00), RGBVAL16(0xff,0x00,0x00), true);          
137            }
138            else {
139              tft.drawTextNoDma(MENU_FILE_XOFFSET+dx,i*TEXT_HEIGHT+MENU_FILE_YOFFSET, title, MENU_FILE_FGCOLOR, MENU_FILE_BGCOLOR, true);      
140            }
141          }
142          i++; 
143        }
144        fileIndex++;    
145      }
146      
147      
148      menuRedraw=false;     
149    }
150  
151  
152    return (action);  
153  }
154  
155  
156  static void spi_task(void *args)
157  {
158    while(true) {
159      tft.refresh();
160    } 
161  }
162  
163  static void input_task(void *args)
164  {
165    while(true) {
166      if ((emu_ReadKeys() & (MASK_KEY_USER1+MASK_KEY_USER2)) == (MASK_KEY_USER1+MASK_KEY_USER2)) {  
167        printf("rebooting\n");
168        esp_restart();    
169      }
170  
171      uint16_t bClick = emu_DebounceLocalKeys();
172      if (bClick & MASK_KEY_USER2) { 
173        printf("%d\n",emu_SwapJoysticks(1)); 
174        emu_SwapJoysticks(0);
175      }
176      else {
177        //emu_Input(bClick);
178      }
179  #ifdef HAS_SND      
180      audio.step();
181  #endif  
182      vTaskDelay(20 / portTICK_PERIOD_MS);
183    } 
184  }
185  
186  
187  static void main_step() {
188    uint16_t bClick = emu_DebounceLocalKeys();
189    int action = handleBootMenu(bClick);
190    if (action >= 0) {  
191      printf("launching\n");
192      ulp_data_write(0, action); 
193      esp_restart();       
194    }
195  #ifdef HAS_SND      
196    audio.step();
197  #endif     
198    //vTaskDelay(20 / portTICK_PERIOD_MS); 
199  }
200  
201  
202  
203  
204  void setup(void)
205  {
206    printf("App selector\n");   
207  	
208    tft.begin();
209  	tft.flipscreen(true);  
210  	tft.start();
211  	tft.refresh();
212   
213    emu_InitJoysticks();
214    initBootMenu();
215  
216    xTaskCreatePinnedToCore(spi_task, "spithread", 4096, NULL, 1, NULL, 0);
217    //vTaskPrioritySet(NULL, tskIDLE_PRIORITY+1);     
218  
219  #ifdef HAS_SND      
220    audio.begin();
221    audio.start();
222    bool haveModule = false;  
223    decoder = fc14dec_new();
224    haveModule = fc14dec_init(decoder,(void*)musym,sizeof(musym));
225    if ( !haveModule ) {
226      fc14dec_delete(decoder);
227      printf("FC module not supported\n");
228    }
229    else {
230      printf("FC music loaded\n");
231      fc14dec_mixer_init(decoder,22050,16,1,0 /*32767*/);
232  
233    }     
234  #endif  
235  }
236  
237  void loop(void)
238  {
239    unsigned long t = esp_timer_get_time();
240    main_step();
241    //printf("%d\n",(int)((esp_timer_get_time()-t)/1000));  
242  } 
243  
244  
245  void SND_Process( void* stream, int len) {
246  #ifdef HAS_SND      
247    fc14dec_buffer_fill(decoder,stream,len*2);  
248  #endif  
249  }
250