]> Shamusworld >> Repos - apple2/blobdiff - src/gui/diskselector.cpp
First steps towards making config window/settings stick.
[apple2] / src / gui / diskselector.cpp
index 80595ee82e372fda31aaa2db345c05b1c2faddcf..ac3ec44682f8b3993bc8137f13491bc3b71a0cab 100644 (file)
@@ -23,6 +23,7 @@
 #include <string>
 #include <vector>
 #include "crc32.h"
+#include "fileio.h"
 #include "floppydrive.h"
 #include "font10pt.h"
 #include "gui.h"
@@ -51,19 +52,19 @@ enum { DSS_SHOWING, DSS_HIDING, DSS_SHOWN, DSS_HIDDEN, DSS_LSB_SHOWING, DSS_LSB_
 #define DS_YPOS        ((VIRTUAL_SCREEN_HEIGHT - DS_HEIGHT) / 2)
 
 
-bool entered = false;
-int driveNumber;
-int diskSelectorState = DSS_HIDDEN;
-int diskSelected = -1;
-int lastDiskSelected = -1;
-int numColumns;
-int colStart = 0;
-int dxLeft = 0;
-int dxRight = 0;
-int rsbPos = DS_WIDTH;
-int lsbPos = -40;
-int textScrollCount = 0;
-bool refresh = false;
+static bool entered = false;
+static int driveNumber;
+static int diskSelectorState = DSS_HIDDEN;
+static int diskSelected = -1;
+static int lastDiskSelected = -1;
+static int numColumns;
+static int colStart = 0;
+static int dxLeft = 0;
+static int dxRight = 0;
+static int rsbPos = DS_WIDTH;
+static int lsbPos = -40;
+static int textScrollCount = 0;
+static bool refresh = false;
 
 /*
 So, how this will work for multiple columns, where the number of columns is greater than 3, is to have an arrow button pop up on the left or right hand side (putting the mouse on the left or right side of the disk selector activates (shows) the button, if such a move can be made. Button hides when the mouse moves out of the hot zone or when it has no more effect.
@@ -109,21 +110,18 @@ struct FileStruct
 
 
 static SDL_Texture * window = NULL;
-static SDL_Texture * charStamp = NULL;
 static uint32_t windowPixels[DS_WIDTH * DS_HEIGHT];
-static uint32_t stamp[FONT_WIDTH * FONT_HEIGHT];
 SDL_Texture * scrollLeftIcon = NULL;
 SDL_Texture * scrollRightIcon = NULL;
 bool DiskSelector::showWindow = false;
 std::vector<FileStruct> fsList;
+std::vector<FileStruct> hdList;
 
 
 void DiskSelector::Init(SDL_Renderer * renderer)
 {
        window = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888,
                SDL_TEXTUREACCESS_TARGET, DS_WIDTH, DS_HEIGHT);
-       charStamp = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
-               SDL_TEXTUREACCESS_TARGET, FONT_WIDTH, FONT_HEIGHT);
 
        if (!window)
        {
@@ -134,17 +132,15 @@ void DiskSelector::Init(SDL_Renderer * renderer)
        if (SDL_SetTextureBlendMode(window, SDL_BLENDMODE_BLEND) == -1)
                WriteLog("GUI (DiskSelector): Could not set blend mode for window.\n");
 
-       if (SDL_SetTextureBlendMode(charStamp, SDL_BLENDMODE_BLEND) == -1)
-               WriteLog("GUI (DiskSelector): Could not set blend mode for charStamp.\n");
-
        scrollLeftIcon  = GUI::CreateTexture(renderer, &scroll_left);
        scrollRightIcon = GUI::CreateTexture(renderer, &scroll_right);
 
        for(uint32_t i=0; i<DS_WIDTH*DS_HEIGHT; i++)
                windowPixels[i] = 0xEF007F00;
 
-       SDL_UpdateTexture(window, NULL, windowPixels, 128 * sizeof(Uint32));
+       SDL_UpdateTexture(window, NULL, windowPixels, DS_WIDTH * sizeof(Uint32));
        FindDisks();
+       FindHardDisks();
        DrawFilenames(renderer);
 }
 
@@ -162,8 +158,12 @@ void DiskSelector::FindDisks(void)
        WriteLog("GUI (DiskSelector)::FindDisks(): # of columns is %i (%i files)\n", numColumns, fsList.size());
 }
 
+
 /*
-OK, so the way that you can determine if a file is a directory in a cross-platform way is to do an opendir() call on a discovered filename.  If it returns NULL, then it's a regular file and not a directory.  Though I think the Linux method is more elegant.  :-P
+OK, so the way that you can determine if a file is a directory in a cross-
+platform way is to do an opendir() call on a discovered filename.  If it
+returns NULL, then it's a regular file and not a directory.  Though I think the
+Linux method is more elegant.  :-P
 */
 //
 // Find all disks images within path (recursive call does depth first search)
@@ -341,25 +341,6 @@ bool DiskSelector::CheckManifest(const char * path, DiskSet * ds)
 }
 
 
-uint8_t * DiskSelector::ReadFile(const char * filename, uint32_t * size)
-{
-       FILE * fp = fopen(filename, "r");
-
-       if (!fp)
-               return NULL;
-
-       fseek(fp, 0, SEEK_END);
-       *size = ftell(fp);
-       fseek(fp, 0, SEEK_SET);
-
-       uint8_t * buffer = (uint8_t *)malloc(*size);
-       fread(buffer, 1, *size, fp);
-       fclose(fp);
-
-       return buffer;
-}
-
-
 bool DiskSelector::HasLegalExtension(const char * name)
 {
        // Find the file's extension, if any
@@ -381,6 +362,71 @@ bool DiskSelector::HasLegalExtension(const char * name)
 }
 
 
+//
+// Find all disks images top level call
+//
+void DiskSelector::FindHardDisks(void)
+{
+       hdList.clear();
+       FindHardDisks(settings.disksPath);
+       std::sort(hdList.begin(), hdList.end(), FileStruct());
+       WriteLog("GUI (DiskSelector)::FindHardDisks(): # of HDs is %i\n", hdList.size());
+}
+
+
+//
+// Find all hard disk images within path (recursive call does depth first search)
+//
+void DiskSelector::FindHardDisks(const char * path)
+{
+       DIR * dir = opendir(path);
+
+       if (!dir)
+       {
+               WriteLog("GUI (DiskSelector)::FindHardDisks: Could not open directory \"%s\%!\n", path);
+               return;
+       }
+
+       dirent * ent;
+
+       while ((ent = readdir(dir)) != NULL)
+       {
+               char buf[0x10000];
+               sprintf(buf, "%s/%s", path, ent->d_name);
+
+               // Cross-platform way to test if it's a directory (test = NULL -> file)
+               DIR * test = opendir(buf);
+
+               if (test == NULL)
+               {
+                       const char * ext = strrchr(ent->d_name, '.');
+
+                       if ((ext != NULL) && (strcasecmp(ext, ".2mg") == 0))
+                       {
+                               FileStruct fs;
+                               fs.image = ent->d_name;
+                               fs.fullPath = buf;
+                               hdList.push_back(fs);
+                       }
+               }
+               else
+               {
+                       // Make sure we close the thing, since it's a bona-fide dir!
+                       closedir(test);
+
+                       // Only recurse if the directory is not one of the special ones...
+                       if ((strcmp(ent->d_name, "..") != 0)
+                               && (strcmp(ent->d_name, ".") != 0))
+                       {
+                               FindHardDisks(buf);
+                       }
+               }
+       }
+
+       closedir(dir);
+}
+
+
 void DiskSelector::DrawFilenames(SDL_Renderer * renderer)
 {
        if (SDL_SetRenderTarget(renderer, window) < 0)
@@ -411,7 +457,7 @@ void DiskSelector::DrawFilenames(SDL_Renderer * renderer)
                                if (i >= fsList[partialColStart + y].image.length())
                                        break;
 
-                               DrawCharacter(renderer, x + 1, y + 1, fsList[partialColStart + y].image[i], false);
+                               GUI::DrawCharacter(renderer, x + 1, y + 1, fsList[partialColStart + y].image[i], false);
                        }
                }
        }
@@ -426,7 +472,7 @@ void DiskSelector::DrawFilenames(SDL_Renderer * renderer)
                                if (i >= fsList[fsStart + y].image.length())
                                        break;
 
-                               DrawCharacter(renderer, x + 1, y + 1, fsList[fsStart + y].image[i], false);
+                               GUI::DrawCharacter(renderer, x + 1, y + 1, fsList[fsStart + y].image[i], false);
                        }
                }
 
@@ -450,7 +496,7 @@ void DiskSelector::DrawFilenames(SDL_Renderer * renderer)
                                break;
 
                        bool invert = (diskSelected == (int)fsStart ? true : false);
-                       DrawCharacter(renderer, currentX + i + 1 + offset, currentY + 1, fsList[fsStart].image[i], invert);
+                       GUI::DrawCharacter(renderer, currentX + i + 1 + offset, currentY + 1, fsList[fsStart].image[i], invert);
                }
 
                count++;
@@ -470,7 +516,7 @@ void DiskSelector::DrawFilenames(SDL_Renderer * renderer)
                        if (i >= fsList[diskSelected].image.length())
                                break;
 
-                       DrawCharacter(renderer, i + 1, 0, fsList[diskSelected].image[i], true);
+                       GUI::DrawCharacter(renderer, i + 1, 0, fsList[diskSelected].image[i], true);
                }
        }
 
@@ -479,22 +525,6 @@ void DiskSelector::DrawFilenames(SDL_Renderer * renderer)
 }
 
 
-void DiskSelector::DrawCharacter(SDL_Renderer * renderer, int x, int y, uint8_t c, bool invert/*=false*/)
-{
-       uint32_t inv = (invert ? 0x000000FF : 0x00000000);
-       uint32_t pixel = 0xFFFFC000;    // RRGGBBAA
-       uint8_t * ptr = (uint8_t *)&font10pt[(c - 0x20) * FONT_WIDTH * FONT_HEIGHT];
-       SDL_Rect dst;
-       dst.x = x * FONT_WIDTH, dst.y = y * FONT_HEIGHT, dst.w = FONT_WIDTH, dst.h = FONT_HEIGHT;
-
-       for(int i=0; i<FONT_WIDTH*FONT_HEIGHT; i++)
-               stamp[i] = (pixel | ptr[i]) ^ inv;
-
-       SDL_UpdateTexture(charStamp, NULL, stamp, FONT_WIDTH * sizeof(Uint32));
-       SDL_RenderCopy(renderer, charStamp, NULL, &dst);
-}
-
-
 void DiskSelector::ShowWindow(int drive)
 {
        diskSelectorState = DSS_SHOWN;
@@ -504,6 +534,18 @@ void DiskSelector::ShowWindow(int drive)
 }
 
 
+void DiskSelector::HideWindow(void)
+{
+       diskSelectorState = DSS_HIDDEN;
+       dxLeft = 0;
+       dxRight = 0;
+       rsbPos = DS_WIDTH;
+       lsbPos = -40;
+       showWindow = false;
+       refresh = true;
+}
+
+
 void DiskSelector::MouseDown(int32_t x, int32_t y, uint32_t buttons)
 {
        if (!showWindow || !entered)
@@ -707,7 +749,7 @@ void DiskSelector::HandleGUIState(void)
 
 void DiskSelector::HandleSelection(SDL_Renderer * renderer)
 {
-       SDL_UpdateTexture(window, NULL, windowPixels, 128 * sizeof(Uint32));
+       SDL_UpdateTexture(window, NULL, windowPixels, DS_WIDTH * sizeof(Uint32));
        DrawFilenames(renderer);
        refresh = false;
 }