]> Shamusworld >> Repos - virtualjaguar/blob - gui.cpp
29f626dec4922bf90620e04bb9ad3da617666de5
[virtualjaguar] / gui.cpp
1 //
2 // GUI.CPP
3 //
4 // Graphical User Interface support
5 // by James L. Hammons
6 //
7
8 #include <string.h>
9 #include <dirent.h>
10 #include <SDL.h>
11 #include "types.h"
12 #include "tom.h"
13 #include "font1.h"
14 #include "gui.h"
15
16 // Private function prototypes
17
18 uint32 CountROMFiles(char * path);
19
20
21 void InitGUI(void)
22 {
23 }
24
25 void GUIDone(void)
26 {
27 }
28
29 //
30 // Render the backbuffer to the primary screen surface
31 //
32 void BlitBackbuffer(void)
33 {
34         extern SDL_Surface * surface, * mainSurface;
35         extern int16 * backbuffer;
36
37         if (SDL_MUSTLOCK(surface))
38                 while (SDL_LockSurface(surface) < 0)
39                         SDL_Delay(10);
40
41         memcpy(surface->pixels, backbuffer, tom_getVideoModeWidth() * tom_getVideoModeHeight() * 2);
42
43         if (SDL_MUSTLOCK(surface))
44                 SDL_UnlockSurface(surface);
45
46         SDL_Rect srcrect, dstrect;
47         srcrect.x = srcrect.y = 0, srcrect.w = surface->w, srcrect.h = surface->h;
48         dstrect.x = dstrect.y = 0, dstrect.w = surface->w, dstrect.h = surface->h;
49         SDL_BlitSurface(surface, &srcrect, mainSurface, &dstrect);
50     SDL_Flip(mainSurface);      
51 }
52
53 //
54 // Draw text at the given x/y coordinates. Can invert text as well.
55 //
56 void DrawText(int16 * screen, uint32 x, uint32 y, bool invert, const char * text, ...)
57 {
58         char string[4096];
59         va_list arg;
60
61         va_start(arg, text);
62         vsprintf(string, text, arg);
63         va_end(arg);
64
65         uint32 pitch = TOMGetSDLScreenPitch() / 2;              // Returns pitch in bytes but we need words...
66         uint32 length = strlen(string), address = x + (y * pitch);
67
68         for(uint32 i=0; i<length; i++)
69         {
70                 uint32 fontAddr = (uint32)string[i] * 64;
71
72                 for(uint32 yy=0; yy<8; yy++)
73                 {
74                         for(uint32 xx=0; xx<8; xx++)
75                         {
76                                 if ((font1[fontAddr] && !invert) || (!font1[fontAddr] && invert))
77                                         *(screen + address + xx + (yy * pitch)) = 0xFE00;
78                                 fontAddr++;
79                         }
80                 }
81
82                 address += 8;
83         }
84 }
85
86 //
87 // Very very crude GUI file selector
88 //
89 bool UserSelectFile(char * path, char * filename)
90 {
91         extern int16 * backbuffer;
92         uint32 numFiles = CountROMFiles(path);
93
94         if (numFiles == 0)
95                 return false;
96
97         char * names = (char *)malloc(numFiles * 2048);
98
99         if (names == NULL)
100         {
101                 WriteLog("Could not allocate memory for %u files!\nAborting!\n", numFiles);
102                 return false;
103         }
104
105         int i = 0;
106         DIR * dp = opendir(path);
107         dirent * de;
108
109         while ((de = readdir(dp)) != NULL)
110         {
111                 char * ext = strrchr(de->d_name, '.');
112                 if (ext != NULL)
113                         if (strcmpi(ext, ".zip") == 0 || strcmpi(ext, ".jag") == 0)
114                                 strcpy(&names[i++ * 2048], de->d_name);
115         }
116
117         closedir(dp);
118
119         // Main GUI selection loop
120
121         uint32 cursor = 0, startFile = 0;
122
123         if (numFiles > 1)       // Only go GUI if more than one possibility!
124         {
125                 bool done = false;
126                 uint32 limit = (numFiles > 24 ? 24 : numFiles);
127                 SDL_Event event;
128
129                 while (!done)
130                 {
131                         while (SDL_PollEvent(&event))
132                         {
133                                 // Draw the GUI...
134                                 memset(backbuffer, 0x11, tom_getVideoModeWidth() * tom_getVideoModeHeight() * 2);
135
136                                 for(uint32 i=0; i<limit; i++)
137                                 {
138                                         bool invert = (cursor == i ? true : false);
139                                         char buf[41];
140                                         // Guarantee that we clip our strings to fit in the screen...
141                                         memcpy(buf, &names[(startFile + i) * 2048], 38);
142                                         buf[38] = 0;
143                                         DrawText(backbuffer, 0, i*8, invert, " %s ", buf);
144                                 }
145
146                                 BlitBackbuffer();
147
148                                 if (event.type == SDL_KEYDOWN)
149                                 {
150                                         SDLKey key = event.key.keysym.sym;
151
152                                         if (key == SDLK_DOWN)
153                                         {
154                                                 if (cursor != limit - 1)        // Cursor is within its window
155                                                         cursor++;
156                                                 else                                            // Otherwise, scroll the window...
157                                                 {
158                                                         if (cursor + startFile != numFiles - 1)
159                                                                 startFile++;
160                                                 }
161                                         }
162                                         if (key == SDLK_UP)
163                                         {
164                                                 if (cursor != 0)
165                                                         cursor--;
166                                                 else
167                                                 {
168                                                         if (startFile != 0)
169                                                                 startFile--;
170                                                 }
171                                         }
172                                         if (key == SDLK_RETURN)
173                                                 done = true;
174                                         if (key == SDLK_ESCAPE)
175                                         {
176                                                 WriteLog("GUI: Aborting VJ by user request.\n");
177                                                 return false;                                           // Bail out!
178                                         }
179                                 }
180                         }
181                 }
182         }
183
184         strcpy(filename, path);
185         // Potential GPF here: If length of dir is zero, then this will cause a page fault!
186         if (path[strlen(path) - 1] != '/')
187                 strcat(filename, "/");
188         strcat(filename, &names[(cursor + startFile) * 2048]);
189         free(names);
190
191         return true;
192 }
193
194 //
195 // Count # of possible ROM files in the current directory
196 //
197 uint32 CountROMFiles(char * path)
198 {
199         uint32 numFiles = 0;
200         DIR * dp = opendir(path);
201
202         if (dp == NULL)
203         {
204                 WriteLog("VJ: Could not open directory \"%s\"!\nAborting!\n", path);
205                 return 0;
206         }
207         else
208         {
209                 dirent * de;
210
211                 while ((de = readdir(dp)) != NULL)
212                 {
213                         char * ext = strrchr(de->d_name, '.');
214                         if (ext != NULL)
215                                 if (strcmpi(ext, ".zip") == 0 || strcmpi(ext, ".jag") == 0)
216                                         numFiles++;
217                 }
218
219                 closedir(dp);
220         }
221
222         return numFiles;
223 }