// 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;
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++)
}
//
-// 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);
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;
cursor++;
else // Otherwise, scroll the window...
{
- if (cursor + startFile != numFiles - 1)
+ if (cursor + startFile != fileList.size() - 1)
startFile++;
}
}
}
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;
{
// 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)
}
}
}
- }
- }
- }
+ 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;
}