test

Dependencies:   SDFileSystem mbed-dev

Fork of Nucleo_Ex06_EMU by woodstock .

Revision:
4:53ef91c87d74
diff -r 8d6e6aec9b01 -r 53ef91c87d74 pNesX_Filer.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pNesX_Filer.cpp	Sat May 27 02:17:37 2017 +0000
@@ -0,0 +1,377 @@
+/*===================================================================*/
+/*                                                                   */
+/*  pNesX_Filer.cpp : ROM selection screen                           */
+/*                                                                   */
+/*  2016/1/20  Racoon                                                */
+/*                                                                   */
+/*===================================================================*/
+
+#include "mbed.h"
+#include "SDFileSystem.h"
+#include "tft.h"
+
+#include "pNesX_Types.h"
+
+extern void pNesX_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem );
+extern const unsigned char pNesX_logo[];
+extern const unsigned char Racoon_logo[];
+
+#define LOGO_BACKCOLOR 0x86fd
+
+#define FOLDER_FILE_MAX 100
+#define LIST_ROWS 20
+#define LIST_TOP 40
+#define LIST_LEFT 4
+
+static int DispTop; // Top of the list
+static int SelIdx; // Cursor index
+static int FileCount; // Number of files in the folder
+
+// file information
+typedef struct tagLISTITEM{
+    char filename[33];
+    bool isDir;
+    long size;
+} LISTITEM;
+
+// folder file list
+LISTITEM *flist;
+
+char szRomFolder[32];
+char szPrevFolder[32];
+char szRomFilename[33];
+char szRomPath[256];
+
+/*-------------------------------------------------------------------*/
+/*  Get file extension                                               */
+/*-------------------------------------------------------------------*/
+char *get_ext(char *filename)
+{
+    int i;
+    for (i = strlen(filename) - 1; i >= 0; --i) {
+        if (filename[i] == '.') {
+            return &filename[i + 1];
+        }
+    }
+    return NULL;
+}
+
+/*-------------------------------------------------------------------*/
+/*  Get file path                                                    */
+/*-------------------------------------------------------------------*/
+char *get_filepath(char *path, char *filename)
+{
+    static char filepath[256];
+
+    if (strncmp(path, "/sd", 3) != 0)
+    {
+        filepath[0] = 0;
+        return filepath;
+    }
+    
+    int len = strlen(path);
+    if (len < 4) {
+        strcpy(filepath, filename);
+    } else {
+        sprintf(filepath, "%s/%s", &path[4], filename);
+    }
+
+    return filepath;
+}
+
+/*-------------------------------------------------------------------*/
+/*  Get file list in the folder                                     */
+/*-------------------------------------------------------------------*/
+int get_filelist(char *path)
+{
+    DIR *dir = opendir(path);
+    if ( dir == NULL ) {
+        return 0;
+    }
+
+    dirent *entry;
+    FILINFO fi;
+    fi.lfname = NULL;
+    fi.lfsize = 0;
+    int i = 0;
+
+    // not root
+    if (strcmp(path, "/sd") != 0) {
+        strcpy(flist[i].filename, "..");
+        flist[i].isDir = true;
+        i++;
+    }
+
+    // folder
+    while ((entry = readdir(dir)) != NULL && i < FOLDER_FILE_MAX) {
+        if (f_stat(get_filepath(path, entry->d_name), &fi) == FR_OK) {
+            int len = strlen(entry->d_name);
+            len = len > 32 ? 32 : len;
+            if (entry->d_name[0] == '.') continue;
+
+            memcpy(flist[i].filename, entry->d_name, len);
+            flist[i].filename[len] = 0;
+            flist[i].isDir = fi.fattrib & AM_DIR;
+            flist[i].size = fi.fsize;
+            ++i;
+        }
+    }
+
+    closedir(dir);
+
+    return i;
+}
+
+
+/*-------------------------------------------------------------------*/
+/*  Get file information string                                      */
+/*-------------------------------------------------------------------*/
+char* filedata(int idx)
+{
+    static char disptext[41];
+    
+    if (flist[idx].isDir) {
+        sprintf(disptext, "%-32s  <DIR>", flist[idx].filename);
+    } else {
+        sprintf(disptext, "%-32s %6d", flist[idx].filename, flist[idx].size);
+    }
+
+    return disptext;
+}
+
+/*-------------------------------------------------------------------*/
+/*  Draw file list                                                   */
+/*-------------------------------------------------------------------*/
+void draw_list()
+{
+    int i,y;
+
+    for (y = 0, i = DispTop; y < LIST_ROWS && i < FileCount; ++y, ++i) {
+        tft_text( LIST_LEFT, LIST_TOP + y * 8, filedata(i), TFT_WHITE, TFT_BLACK );
+    }
+
+    if (y < LIST_ROWS) {
+        tft_boxfill( 0, LIST_TOP + y * 8, 319, LIST_TOP + LIST_ROWS * 8 - 1, TFT_BLACK);
+    }
+}
+
+/*-------------------------------------------------------------------*/
+/*  Draw cursor                                                      */
+/*-------------------------------------------------------------------*/
+void draw_cursor(bool clear = false)
+{
+    int y = SelIdx - DispTop;
+    if (clear) {
+        tft_box( LIST_LEFT - 1, LIST_TOP + y * 8 - 1, LIST_LEFT + 39 * 8, LIST_TOP + y * 8 + 7, TFT_BLACK);
+        tft_text( LIST_LEFT, LIST_TOP + y * 8, filedata(SelIdx), TFT_WHITE, TFT_BLACK );
+    } else {
+        tft_box( LIST_LEFT - 1, LIST_TOP + y * 8 - 1, LIST_LEFT + 39 * 8, LIST_TOP + y * 8 + 7, TFT_YELLOW);
+        tft_text( LIST_LEFT, LIST_TOP + y * 8, filedata(SelIdx), TFT_BLACK, TFT_YELLOW );
+    }
+}
+
+/*-------------------------------------------------------------------*/
+/*  Draw back ground                                                 */
+/*-------------------------------------------------------------------*/
+void draw_frame()
+{
+        tft_boxfill( 0, 0, 319, 31, LOGO_BACKCOLOR);
+        tft_boxfill(0, 32, 319, 223, TFT_BLACK);
+        tft_boxfill( 0, 224, 319, 239, LOGO_BACKCOLOR);
+        
+       draw_bmp_4bpp(pNesX_logo, 8, 6);
+       tft_text( 100, 225, "layerOne 2017", TFT_BLACK, LOGO_BACKCOLOR );
+        //tft_text( 200, 233, "R1+R2:Reset", TFT_BLACK, LOGO_BACKCOLOR );
+       // draw_bmp_4bpp(Racoon_logo, 0, 224);
+}
+
+/*-------------------------------------------------------------------*/
+/*  Dialog window                                                    */
+/*-------------------------------------------------------------------*/
+void dialog(char *msg)
+{
+    if (msg)
+    {
+        tft_boxfill(0, 100, 319, 139, TFT_NAVY);
+        int len = strlen(msg);
+        len = len > 38 ? 38 : len;
+        msg[len] = 0;
+        int x = (40 - len) * 4;
+        tft_text(x, 116, msg, TFT_WHITE, TFT_NAVY);
+    }
+    else
+    {
+        tft_boxfill(0, 100, 319, 139, TFT_BLACK);
+    }
+}
+
+
+/*-------------------------------------------------------------------*/
+/*  Rom selection                                                    */
+/*-------------------------------------------------------------------*/
+//  return code:
+//   0 : File selected
+//   1 : Return to Emu
+//   2 : Reset
+//   -1: Error
+int pNesX_Filer()
+{
+    DWORD dwPad1=0, dwPad2=0, dwSystem=0;
+    DWORD prev_dwPad1 = 0;
+    
+    bool loadFolder;
+    int keyrepeat = 1;
+
+    // Draw back ground
+    draw_frame();
+    
+    // init
+    flist = (LISTITEM *)malloc(sizeof(LISTITEM) * FOLDER_FILE_MAX);
+    if (flist == NULL) {
+        return -1;
+    }
+    
+    loadFolder = true;
+    int ret;
+    
+    while(1) {
+        if (loadFolder) {
+            // Drawing of the files in the folder
+            FileCount = get_filelist(szRomFolder);
+            
+            if (FileCount > 0) {
+                if (strcmp(szRomFolder, szPrevFolder) != 0)
+                {
+                    DispTop = 0;
+                    SelIdx = 0;
+                    strcpy( szPrevFolder, szRomFolder);
+                }
+                draw_list();
+                draw_cursor();
+            }
+            loadFolder = false;
+        }
+
+        pNesX_PadState( &dwPad1, &dwPad2, &dwSystem );
+        
+        if (dwPad1 != prev_dwPad1) {
+            keyrepeat = 0;
+        }
+
+        if (keyrepeat == 0 || keyrepeat >= 10) {
+            // Down
+            if (dwPad1 & KEYPAD_DOWN) {
+                if (SelIdx < FileCount - 1) {
+                    // clear cursor
+                    draw_cursor(true);
+                    
+                    if (SelIdx - DispTop == LIST_ROWS - 1) {
+                        DispTop++;
+                        draw_list();
+                    }
+    
+                    // draw new cursor
+                    SelIdx++;
+                    draw_cursor();
+                }                
+            }
+
+            // Up
+            if (dwPad1 & KEYPAD_UP) {
+                if (SelIdx > 0) {
+                    // clear cursor
+                    draw_cursor(true);
+                    
+                    if (SelIdx - DispTop == 0) {
+                        DispTop--;
+                        draw_list();
+                    }
+
+                    // draw new cursor
+                    SelIdx--;
+                    draw_cursor();
+                }
+            }
+
+            // Select
+            if (dwPad1 == KEYPAD_SELECT) {
+                // clear cursor
+                draw_cursor(true);
+
+                if (flist[SelIdx].isDir) {
+                    // folder
+                    if (strcmp(flist[SelIdx].filename, "..") != 0) {
+                        sprintf(szRomFolder, "%s/%s", szRomFolder, flist[SelIdx].filename);
+                    } else {
+                        // upper folder
+                        char *upper = strrchr(szRomFolder, '/');
+                        if (upper) {
+                            *upper = 0;
+                        }
+                    }
+
+                    loadFolder = true;
+                } else {
+                    char *ext = get_ext(flist[SelIdx].filename);
+                    if (ext != NULL && strcasecmp(ext, "nes") == 0)
+                    {
+                        strcpy(szRomFilename, flist[SelIdx].filename);
+    
+
+                        strcpy(szRomPath, get_filepath(szRomFolder, szRomFilename));
+                        
+                        ret = 0;
+                        break;
+                    }
+                    else
+                    {
+                        dialog("not a rom file!!");
+                        wait(1);
+                        dialog(NULL);
+                        draw_list();
+                        draw_cursor();
+                    }
+                }
+            }
+            
+            // Return to Emu
+            if (dwSystem & 0x01) {
+                if ( szRomFilename[0] != 0 ) {
+                    do {
+                        wait(0.08);
+                        pNesX_PadState( &dwPad1, &dwPad2, &dwSystem );
+
+                    } while (dwSystem & 0x01);
+            
+                    ret = 1;
+                    break;
+                }
+            }
+
+            // Reset
+            if (dwSystem & 0x02) {
+                if ( szRomFilename[0] != 0 ) {
+                    do {
+                        wait(0.08);
+                        pNesX_PadState( &dwPad1, &dwPad2, &dwSystem );
+                    } while (dwSystem & 0x02);
+
+                    ret = 2;
+                    break;
+                }
+            }
+        }
+
+        keyrepeat++;
+
+        prev_dwPad1 = dwPad1;
+
+        wait(0.08);
+    }
+    
+    // release memory
+    free(flist);
+
+    return ret;
+}
+