]> Shamusworld >> Repos - apple2/blob - src/gui/diskselector.cpp
Added missing files. :-P
[apple2] / src / gui / diskselector.cpp
1 //
2 // diskselector.cpp
3 //
4 // Floppy disk selector GUI
5 // by James Hammons
6 //
7 // JLH = James Hammons <jlhamm@acm.org>
8 //
9 // WHO  WHEN        WHAT
10 // ---  ----------  ------------------------------------------------------------
11 // JLH  10/13/2013  Created this file
12 //
13 // STILL TO DO:
14 //
15 //
16
17 #include "diskselector.h"
18 #include <dirent.h>
19 #include <algorithm>
20 #include <string>
21 #include <vector>
22 #include "font14pt.h"
23 #include "log.h"
24 #include "settings.h"
25 #include "video.h"
26
27 //
28 // Case insensitve string comparison voodoo
29 //
30 struct ci_char_traits : public std::char_traits<char>
31 {
32         static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); }
33         static bool ne(char c1, char c2) { return toupper(c1) != toupper(c2); }
34         static bool lt(char c1, char c2) { return toupper(c1) <  toupper(c2); }
35         static int compare(const char * s1, const char * s2, size_t n)
36         {
37                 while (n-- != 0)
38                 {
39                         if (toupper(*s1) < toupper(*s2)) return -1;
40                         if (toupper(*s1) > toupper(*s2)) return 1;
41                         ++s1; ++s2;
42                 }
43                 return 0;
44         }
45         static const char * find(const char * s, int n, char a)
46         {
47                 while (n-- > 0 && toupper(*s) != toupper(a))
48                 {
49                         ++s;
50                 }
51                 return s;
52         }
53 };
54
55 typedef std::basic_string<char, ci_char_traits> ci_string;
56 //
57 // END Case insensitve string comparison voodoo
58 //
59
60
61 static SDL_Texture * window = NULL;
62 static SDL_Texture * charStamp = NULL;
63 static uint32_t windowPixels[400 * 300];
64 static uint32_t stamp[FONT_WIDTH * FONT_HEIGHT];
65 bool DiskSelector::showWindow = false;
66 std::vector<ci_string> imageList;
67
68
69 void DiskSelector::Init(SDL_Renderer * renderer)
70 {
71         window = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888,
72                 SDL_TEXTUREACCESS_TARGET, 400, 300);
73 //      charStamp = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888,
74         charStamp = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,
75                 SDL_TEXTUREACCESS_TARGET, FONT_WIDTH, FONT_HEIGHT);
76
77         if (!window)
78         {
79                 WriteLog("GUI (DiskSelector): Could not create window!\n");
80                 return;
81         }
82
83         if (SDL_SetTextureBlendMode(window, SDL_BLENDMODE_BLEND) == -1)
84                 WriteLog("GUI (DiskSelector): Could not set blend mode for window.\n");
85
86         if (SDL_SetTextureBlendMode(charStamp, SDL_BLENDMODE_BLEND) == -1)
87                 WriteLog("GUI (DiskSelector): Could not set blend mode for charStamp.\n");
88
89         for(uint32_t i=0; i<400*300; i++)
90                 windowPixels[i] = 0xB000FF00;
91
92         SDL_UpdateTexture(window, NULL, windowPixels, 128 * sizeof(Uint32));
93         FindDisks(NULL);
94         DrawFilenames(renderer);
95 }
96
97
98 void DiskSelector::FindDisks(const char * path)
99 {
100         DIR * dir = opendir(settings.disksPath);
101
102         if (!dir)
103         {
104                 WriteLog("GUI (DiskSelector)::FindDisks: Could not open directory \"%s\%!\n", settings.disksPath);
105                 return;
106         }
107
108         imageList.clear();
109         dirent * ent;
110
111         while ((ent = readdir(dir)) != NULL)
112         {
113                 if (HasLegalExtension(ent->d_name))
114                         imageList.push_back(ci_string(ent->d_name));
115         }
116
117         closedir(dir);
118         std::sort(imageList.begin(), imageList.end());
119 #if 0
120 {
121         std::vector<ci_string>::iterator i;
122         for(i=imageList.begin(); i!=imageList.end(); i++)
123                 printf("GUI::DS::Found \"%s\"\n", (*i).c_str());
124 }
125 #endif
126 }
127
128
129 bool DiskSelector::HasLegalExtension(const char * name)
130 {
131         const char * ext = strrchr(name, '.');
132
133         if ((strcasecmp(ext, ".dsk") == 0) || (strcasecmp(ext, ".do") == 0)
134                 || (strcasecmp(ext, ".po") == 0) || (strcasecmp(ext, ".nib") == 0))
135                 return true;
136
137         return false;
138 }
139
140
141 void DiskSelector::DrawFilenames(SDL_Renderer * renderer)
142 {
143         if (SDL_SetRenderTarget(renderer, window) < 0)
144         {
145                 WriteLog("GUI: Could not set Render Target to overlay... (%s)\n", SDL_GetError());
146                 return;
147         }
148
149         // 3 columns of 16 chars apiece (with 8X16 font), 18 rows
150
151         int count = 0;
152
153         while (count < imageList.size())
154         {
155                 int currentX = (count / 18) * 17;
156                 int currentY = (count % 18);
157
158                 for(unsigned int i=0; i<16; i++)
159                 {
160                         if (i >= imageList[count].length())
161                                 break;
162
163                         DrawCharacter(renderer, currentX + i, currentY, imageList[count][i]);
164                 }
165
166                 count++;
167
168                 if (count >= (18 * 3))
169                         break;
170         }
171
172         // Set render target back to default
173         SDL_SetRenderTarget(renderer, NULL);
174 }
175
176
177 void DiskSelector::DrawCharacter(SDL_Renderer * renderer, int x, int y, uint8_t c)
178 {
179 #if 0
180 //      uint32_t pixel = 0xFF7F0000;
181         uint8_t * ptr = (uint8_t *)&font2[(c - 0x20) * FONT_WIDTH * FONT_HEIGHT];
182
183         for(int j=0; j<FONT_HEIGHT; j++)
184         {
185                 for(int i=0; i<FONT_WIDTH; i++)
186                 {
187                         SDL_SetRenderDrawColor(renderer, 0xFF, 0x7F, 0x00, ptr[(j * FONT_WIDTH) + i]);
188                         SDL_RenderDrawPoint(renderer, (x * FONT_WIDTH) + i, (y * FONT_HEIGHT) + j);
189                 }
190         }
191
192         SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);
193 #else
194         uint32_t pixel = 0xFFCFA000;
195         uint8_t * ptr = (uint8_t *)&font2[(c - 0x20) * FONT_WIDTH * FONT_HEIGHT];
196         SDL_Rect dst;
197         dst.x = x * FONT_WIDTH, dst.y = y * FONT_HEIGHT, dst.w = FONT_WIDTH, dst.h = FONT_HEIGHT;
198
199         for(int i=0; i<FONT_WIDTH*FONT_HEIGHT; i++)
200                 stamp[i] = pixel | ptr[i];
201
202         SDL_UpdateTexture(charStamp, NULL, stamp, FONT_WIDTH * sizeof(Uint32));
203         SDL_RenderCopy(renderer, charStamp, NULL, &dst);
204 #endif
205 }
206
207 /*
208 void DiskSelector::()
209 {
210 }
211 */
212
213 void DiskSelector::MouseDown(int32_t x, int32_t y, uint32_t buttons)
214 {
215 }
216
217
218 void DiskSelector::MouseUp(int32_t x, int32_t y, uint32_t buttons)
219 {
220 }
221
222
223 void DiskSelector::MouseMove(int32_t x, int32_t y, uint32_t buttons)
224 {
225 }
226
227
228 void DiskSelector::Render(SDL_Renderer * renderer)
229 {
230         if (!(window || showWindow))
231                 return;
232
233         SDL_Rect dst;
234         dst.x = (VIRTUAL_SCREEN_WIDTH - 400) / 2, dst.y = (VIRTUAL_SCREEN_HEIGHT - 300) / 2, dst.w = 400, dst.h = 300;
235
236         SDL_RenderCopy(renderer, window, NULL, &dst);
237 }
238