]> Shamusworld >> Repos - virtualjaguar/blobdiff - src/gui.cpp
Yet more switches!
[virtualjaguar] / src / gui.cpp
index b1ffb370a3bc7eaee05c4ae27598c0d6e708c704..404af7e4f481fbf71ebdf01686c64bc9e3bb0830 100644 (file)
@@ -5,55 +5,68 @@
 // by James L. Hammons
 //
 
-#include <string.h>
 #include <dirent.h>
 #include <SDL.h>
+#include <string>
+#include <vector>
+#include <algorithm>
 #include "types.h"
+#include "settings.h"
 #include "tom.h"
+#include "video.h"
 #include "font1.h"
 #include "gui.h"
 
-// Private function prototypes
+using namespace std;                                                           // For STL stuff
 
-uint32 CountROMFiles(char * path);
+// Private function prototypes
 
+// Local global variables
+
+int mouseX, mouseY;
+
+uint16 mousePic[] = {
+       6, 8,
+
+       0x03E0,0x0000,0x0000,0x0000,0x0000,0x0000,              // +
+       0x0300,0x03E0,0x0000,0x0000,0x0000,0x0000,              // @+
+       0x0300,0x03E0,0x03E0,0x0000,0x0000,0x0000,              // @++
+       0x0300,0x0300,0x03E0,0x03E0,0x0000,0x0000,              // @@++
+       0x0300,0x0300,0x03E0,0x03E0,0x03E0,0x0000,              // @@+++
+       0x0300,0x0300,0x0300,0x03E0,0x03E0,0x03E0,              // @@@+++
+       0x0300,0x0300,0x0300,0x0000,0x0000,0x0000,              // @@@
+       0x0300,0x0000,0x0000,0x0000,0x0000,0x0000               // @
+/*
+       0xFFFF,0x0000,0x0000,0x0000,0x0000,0x0000,              // +
+       0xE318,0xFFFF,0x0000,0x0000,0x0000,0x0000,              // @+
+       0xE318,0xFFFF,0xFFFF,0x0000,0x0000,0x0000,              // @++
+       0xE318,0xE318,0xFFFF,0xFFFF,0x0000,0x0000,              // @@++
+       0xE318,0xE318,0xFFFF,0xFFFF,0xFFFF,0x0000,              // @@+++
+       0xE318,0xE318,0xE318,0xFFFF,0xFFFF,0xFFFF,              // @@@+++
+       0xE318,0xE318,0xE318,0x0000,0x0000,0x0000,              // @@@
+       0xE318,0x0000,0x0000,0x0000,0x0000,0x0000               // @
+*/
+};
+// 1 111 00 11 100 1 1100 -> F39C
+// 1 100 00 10 000 1 0000 -> C210
+// 1 110 00 11 000 1 1000 -> E318
+// 0 000 00 11 111 0 0000 -> 03E0
+// 0 000 00 11 000 0 0000 -> 0300
 
 void InitGUI(void)
 {
+       SDL_ShowCursor(SDL_DISABLE);
+       SDL_GetMouseState(&mouseX, &mouseY);
 }
 
 void GUIDone(void)
 {
 }
 
-//
-// Render the backbuffer to the primary screen surface
-//
-void BlitBackbuffer(void)
-{
-       extern SDL_Surface * surface, * mainSurface;
-       extern int16 * backbuffer;
-
-       if (SDL_MUSTLOCK(surface))
-               while (SDL_LockSurface(surface) < 0)
-                       SDL_Delay(10);
-
-       memcpy(surface->pixels, backbuffer, tom_getVideoModeWidth() * tom_getVideoModeHeight() * 2);
-
-       if (SDL_MUSTLOCK(surface))
-               SDL_UnlockSurface(surface);
-
-       SDL_Rect srcrect, dstrect;
-       srcrect.x = srcrect.y = 0, srcrect.w = surface->w, srcrect.h = surface->h;
-       dstrect.x = dstrect.y = 0, dstrect.w = surface->w, dstrect.h = surface->h;
-       SDL_BlitSurface(surface, &srcrect, mainSurface, &dstrect);
-    SDL_Flip(mainSurface);      
-}
-
 //
 // Draw text at the given x/y coordinates. Can invert text as well.
 //
-void DrawText(int16 * screen, uint32 x, uint32 y, bool invert, const char * text, ...)
+void DrawString(int16 * screen, uint32 x, uint32 y, bool invert, const char * text, ...)
 {
        char string[4096];
        va_list arg;
@@ -62,7 +75,7 @@ void DrawText(int16 * screen, uint32 x, uint32 y, bool invert, const char * text
        vsprintf(string, text, arg);
        va_end(arg);
 
-       uint32 pitch = TOMGetSDLScreenPitch() / 2;              // Returns pitch in bytes but we need words...
+       uint32 pitch = GetSDLScreenPitch() / 2;                 // Returns pitch in bytes but we need words...
        uint32 length = strlen(string), address = x + (y * pitch);
 
        for(uint32 i=0; i<length; i++)
@@ -84,62 +97,48 @@ void DrawText(int16 * screen, uint32 x, uint32 y, bool invert, const char * text
 }
 
 //
-// Very very crude GUI file selector
+// Draw "picture"
+// Uses zero as transparent color
 //
-#ifndef FILENAME_MAX
-#define FILENAME_MAX   2048
-#endif
-bool UserSelectFile(char * path, char * filename)
+void DrawTransparentBitmap(int16 * screen, uint32 x, uint32 y, uint16 * bitmap)
 {
-       extern int16 * backbuffer;
-       uint32 numFiles = CountROMFiles(path);
-
-       if (numFiles == 0)
-               return false;
+       uint16 width = bitmap[0], height = bitmap[1];
+       bitmap += 2;
 
-       char * names = (char *)malloc(numFiles * FILENAME_MAX);
+       uint32 pitch = GetSDLScreenPitch() / 2;                 // Returns pitch in bytes but we need words...
+       uint32 address = x + (y * pitch);
 
-       if (names == NULL)
+       for(int yy=0; yy<height; yy++)
        {
-               WriteLog("Could not allocate memory for %u files!\nAborting!\n", numFiles);
-               return false;
+               for(int xx=0; xx<width; xx++)
+               {
+                               if (*bitmap && x + xx < pitch)          // NOTE: Still doesn't clip the Y val...
+                                       *(screen + address + xx + (yy * pitch)) = *bitmap;
+                               bitmap++;
+               }
        }
+}
+
+//
+// Very very crude GUI file selector
+//
+bool UserSelectFile(char * path, char * filename)
+{
+       extern int16 * backbuffer;
+       vector<string> fileList;
+
+       // Read in the candidate files from the directory pointed to by "path"
 
-       int i = 0;
        DIR * dp = opendir(path);
        dirent * de;
 
        while ((de = readdir(dp)) != NULL)
        {
                char * ext = strrchr(de->d_name, '.');
+
                if (ext != NULL)
-               {
                        if (stricmp(ext, ".zip") == 0 || stricmp(ext, ".jag") == 0)
-                       {
-                               // Do a QnD insertion sort...
-                               // (Yeah, it's n^2/2 time, but there aren't that many items...)
-                               uint32 pos = 0;
-
-                               for(int k=0; k<i; k++)
-                               {
-                                       if (stricmp(&names[k * FILENAME_MAX], de->d_name) < 0)
-                                               pos++;
-                                       else
-                                               break;
-                               }
-
-                               uint32 blockSize = (i - pos) * FILENAME_MAX;
-
-                               if (blockSize)
-//This only works on Win32 for some reason...
-//                                     memcpy(&names[(pos + 1) * FILENAME_MAX], &names[pos * FILENAME_MAX], blockSize);
-                                       for(int k=blockSize-1; k>=0; k--)
-                                               names[((pos + 1) * FILENAME_MAX) + k] = names[(pos * FILENAME_MAX) + k];
-
-                               strcpy(&names[pos * FILENAME_MAX], de->d_name);
-                               i++;
-                       }
-               }
+                               fileList.push_back(string(de->d_name));
        }
 
        closedir(dp);
@@ -148,31 +147,22 @@ bool UserSelectFile(char * path, char * filename)
 
        uint32 cursor = 0, startFile = 0;
 
-       if (numFiles > 1)       // Only go GUI if more than one possibility!
+       if (fileList.size() > 1)        // Only go GUI if more than one possibility!
        {
+               sort(fileList.begin(), fileList.end());
+
                bool done = false;
-               uint32 limit = (numFiles > 24 ? 24 : numFiles);
+               uint32 limit = (fileList.size() > 30 ? 30 : fileList.size());
                SDL_Event event;
 
+               // Ensure that the GUI is drawn before any user input...
+               event.type = SDL_USEREVENT;
+               SDL_PushEvent(&event);
+
                while (!done)
                {
                        while (SDL_PollEvent(&event))
                        {
-                               // Draw the GUI...
-                               memset(backbuffer, 0x11, tom_getVideoModeWidth() * tom_getVideoModeHeight() * 2);
-
-                               for(uint32 i=0; i<limit; i++)
-                               {
-                                       bool invert = (cursor == i ? true : false);
-                                       char buf[41];
-                                       // Guarantee that we clip our strings to fit in the screen...
-                                       memcpy(buf, &names[(startFile + i) * FILENAME_MAX], 38);
-                                       buf[38] = 0;
-                                       DrawText(backbuffer, 0, i*8, invert, " %s ", buf);
-                               }
-
-                               BlitBackbuffer();
-
                                if (event.type == SDL_KEYDOWN)
                                {
                                        SDLKey key = event.key.keysym.sym;
@@ -183,7 +173,7 @@ bool UserSelectFile(char * path, char * filename)
                                                        cursor++;
                                                else                                            // Otherwise, scroll the window...
                                                {
-                                                       if (cursor + startFile != numFiles - 1)
+                                                       if (cursor + startFile != fileList.size() - 1)
                                                                startFile++;
                                                }
                                        }
@@ -199,9 +189,26 @@ bool UserSelectFile(char * path, char * filename)
                                        }
                                        if (key == SDLK_PAGEDOWN)
                                        {
+                                               if (cursor != limit - 1)
+                                                       cursor = limit - 1;
+                                               else
+                                               {
+                                                       startFile += limit;
+                                                       if (startFile > fileList.size() - limit)
+                                                               startFile = fileList.size() - limit;
+                                               }
                                        }
                                        if (key == SDLK_PAGEUP)
                                        {
+                                               if (cursor != 0)
+                                                       cursor = 0;
+                                               else
+                                               {
+                                                       if (startFile < limit)
+                                                               startFile = 0;
+                                                       else
+                                                               startFile -= limit;
+                                               }
                                        }
                                        if (key == SDLK_RETURN)
                                                done = true;
@@ -214,9 +221,10 @@ bool UserSelectFile(char * path, char * filename)
                                        {
                                                // Advance cursor to filename with first letter pressed...
                                                uint8 which = (key - SDLK_a) + 65;      // Convert key to A-Z char
-                                               for(uint32 i=0; i<numFiles; i++)
+
+                                               for(uint32 i=0; i<fileList.size(); i++)
                                                {
-                                                       if ((names[i * FILENAME_MAX] & 0xDF) == which)
+                                                       if ((fileList[i][0] & 0xDF) == which)
                                                        {
                                                                cursor = i - startFile;
                                                                if (i > startFile + limit - 1)
@@ -230,47 +238,48 @@ bool UserSelectFile(char * path, char * filename)
                                                }
                                        }
                                }
-                       }
-               }
-       }
+                               else if (event.type == SDL_MOUSEMOTION)
+                               {
+                                       mouseX = event.motion.x, mouseY = event.motion.y;
+                                       if (vjs.useOpenGL)
+                                               mouseX /= 2, mouseY /= 2;
+                               }
+                               else if (event.type == SDL_MOUSEBUTTONDOWN)
+                               {
+                                       uint32 mx = event.button.x, my = event.button.y;
+                                       if (vjs.useOpenGL)
+                                               mx /= 2, my /= 2;
+                                       cursor = my / 8;
+                               }
 
-       strcpy(filename, path);
-       // Potential GPF here: If length of dir is zero, then this will cause a page fault!
-       if (path[strlen(path) - 1] != '/')
-               strcat(filename, "/");
-       strcat(filename, &names[(cursor + startFile) * FILENAME_MAX]);
-       free(names);
+                               // Draw the GUI...
+//                             memset(backbuffer, 0x11, tom_getVideoModeWidth() * tom_getVideoModeHeight() * 2);
+                               memset(backbuffer, 0x11, tom_getVideoModeWidth() * 240 * 2);
 
-       return true;
-}
+                               for(uint32 i=0; i<limit; i++)
+                               {
+                                       // Clip our strings to guarantee that they fit on the screen...
+                                       // (and strip off the extension too)
+                                       string s(fileList[startFile + i], 0, fileList[startFile + i].length() - 4);
+                                       if (s.length() > 38)
+                                               s[38] = 0;
+                                       DrawString(backbuffer, 0, i*8, (cursor == i ? true : false), " %s ", s.c_str());
+                               }
 
-//
-// Count # of possible ROM files in the current directory
-//
-uint32 CountROMFiles(char * path)
-{
-       uint32 numFiles = 0;
-       DIR * dp = opendir(path);
+                               DrawTransparentBitmap(backbuffer, mouseX, mouseY, mousePic);
 
-       if (dp == NULL)
-       {
-               WriteLog("VJ: Could not open directory \"%s\"!\nAborting!\n", path);
-               return 0;
+                               RenderBackbuffer();
+                       }
+               }
        }
-       else
-       {
-               dirent * de;
 
-               while ((de = readdir(dp)) != NULL)
-               {
-                       char * ext = strrchr(de->d_name, '.');
-                       if (ext != NULL)
-                               if (stricmp(ext, ".zip") == 0 || stricmp(ext, ".jag") == 0)
-                                       numFiles++;
-               }
+       strcpy(filename, path);
 
-               closedir(dp);
-       }
+       if (strlen(path) > 0)
+               if (path[strlen(path) - 1] != '/')
+                       strcat(filename, "/");
 
-       return numFiles;
+       strcat(filename, fileList[startFile + cursor].c_str());
+
+       return true;
 }