ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/proj/trunk/RenegadeMapSelector/RenegadeMapSelector.cpp
Revision: 84
Committed: 2003-03-14T00:19:14-08:00 (22 years, 3 months ago) by douglas
File size: 15875 byte(s)
Log Message:
Need a clue-by-four?

File Contents

# Content
1 // Renegade Map Selector
2 //
3 // Douglas Thrift
4 //
5 // RenegadeMapSelector.cpp
6
7 #include "RenegadeMapSelector.h"
8 #include "RenegadeConfig.h"
9
10 #ifdef _WIN32
11 #include <io.h>
12 #include <fcntl.h>
13 #include "resource.h"
14 #else
15 #include "gtk/gtk.h"
16 #endif
17
18 bool debug = false;
19 string program;
20 RenegadeConfig* config;
21
22 #ifndef _WIN32
23 inline string fix(const string& ansi) { return ansi; }
24 inline void munge(void) { debug = true; }
25
26 void message(const string& text, const string& title, GtkMessageType type);
27 #else
28 inline string fix(const wstring& wide)
29 {
30 char* buffer = new char[wide.length() + 1];
31
32 WideCharToMultiByte(CP_ACP, 0, wide.c_str(), -1, buffer, wide.length() + 1,
33 NULL, NULL);
34
35 string ansi = buffer;
36 delete [] buffer;
37
38 return ansi;
39 }
40
41 inline void munge(void)
42 {
43 if (debug) return;
44
45 AllocConsole();
46 SetConsoleTitle("Renegade Map Selector");
47
48 int hin = _open_osfhandle(long(GetStdHandle(STD_INPUT_HANDLE)), _O_TEXT);
49 int hout = _open_osfhandle(long(GetStdHandle(STD_OUTPUT_HANDLE)), _O_TEXT);
50 int herr = _open_osfhandle(long(GetStdHandle(STD_ERROR_HANDLE)), _O_TEXT);
51
52 FILE* fin = _fdopen(hin, "r");
53 FILE* fout = _fdopen(hout, "w");
54 FILE* ferr = _fdopen(herr, "w");
55
56 *stdin = *fin;
57 *stdout = *fout;
58 *stderr = *ferr;
59
60 setvbuf(stdin, NULL, _IONBF, 0);
61 setvbuf(stdout, NULL, _IONBF, 0);
62 setvbuf(stderr, NULL, _IONBF, 0);
63
64 cin.sync_with_stdio();
65 cout.sync_with_stdio();
66 cerr.sync_with_stdio();
67
68 debug = true;
69 }
70 #endif
71
72 #ifdef _WIN32
73 int CALLBACK selector(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
74
75 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR
76 lpCmdLine, int nShowCmd)
77 {
78 int argc;
79 unsigned short** argv = CommandLineToArgvW(GetCommandLineW(), &argc);
80 #else
81 void selector(void);
82
83 int main(int argc, char* argv[])
84 {
85 if (!gtk_init_check(&argc, &argv))
86 {
87 cerr << argv[0] << ": Cannot open display, need a clue-by-four?\n";
88
89 return 1;
90 }
91 #endif
92
93 string error;
94 string file = "svrcfg_cnc.ini";
95
96 program = fix(argv[0]);
97
98 for (int index = 1; index < argc; index++)
99 {
100 string arg = fix(argv[index]);
101
102 if (arg == "-D")
103 {
104 munge();
105 }
106 else if (arg == "-file")
107 {
108 if (++index < argc)
109 {
110 file = fix(argv[index]);
111 }
112 else
113 {
114 error = "The argument -file must be followed by a filename.";
115
116 #ifdef _WIN32
117 MessageBox(NULL, error.c_str(), "Bad Arguments", MB_ICONERROR);
118 #else
119 message(error, "Bad Arguments", GTK_MESSAGE_ERROR);
120 #endif
121 return 1;
122 }
123 }
124 }
125
126 #ifdef _WIN32
127 GlobalFree(argv);
128 #endif
129
130 if (debug) cerr << "file = " << file << "\n";
131
132 config = new RenegadeConfig(file);
133 if (!config->load())
134 {
135 error = "Could not open " + file + ".";
136
137 #ifdef _WIN32
138 MessageBox(NULL, error.c_str(), "Bad File", MB_ICONERROR);
139 #else
140 message(error, "Bad File", GTK_MESSAGE_ERROR);
141 #endif
142 return 1;
143 }
144
145 #ifdef _WIN32
146 DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAP_SELECTOR), NULL, selector);
147 #else
148 selector();
149 #endif
150
151 delete config;
152
153 #ifdef _WIN32
154 if (debug)
155 {
156 cout << "Press enter key to exit . . .";
157 cin.get();
158 }
159 #endif
160
161 return 0;
162 }
163
164 #ifdef _WIN32
165 int CALLBACK selector(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
166 {
167 switch (uMsg)
168 {
169 case WM_INITDIALOG:
170 {
171 RECT rc, rcDlg, rcDesktop;
172
173 GetWindowRect(GetDesktopWindow(), &rcDesktop);
174 GetWindowRect(hwndDlg, &rcDlg);
175 CopyRect(&rc, &rcDesktop);
176
177 OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
178 OffsetRect(&rc, -rc.left, -rc.top);
179 OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
180
181 SetWindowPos(hwndDlg, HWND_TOP, rcDesktop.left + (rc.right / 2),
182 rcDesktop.top + (rc.bottom / 2), 0, 0, SWP_NOSIZE);
183 }
184 {
185 char* directory = new char[MAX_PATH + 1];
186 GetCurrentDirectory(MAX_PATH + 1, directory);
187 if (debug) cerr << "directory = " << directory << "\n";
188
189 char* data = new char[MAX_PATH + 1];
190 sprintf(data, "%s\\data\\*.mix", directory);
191 delete [] directory;
192 if (debug) cerr << "data = " << data << "\n";
193
194 DlgDirList(hwndDlg, data, IDC_AVAILABLE, 0, DDL_ARCHIVE);
195 SetCurrentDirectory("..");
196
197 delete [] data;
198 }
199 {
200 vector<string> maps = config->getMaps();
201
202 for (unsigned index = 0; index < maps.size(); index++)
203 {
204 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED), LB_ADDSTRING, 0,
205 long(maps[index].c_str()));
206 }
207 }
208 break;
209 case WM_COMMAND:
210 switch (LOWORD(wParam))
211 {
212 case IDOK:
213 if (GetListBoxInfo(GetDlgItem(hwndDlg, IDC_SELECTED)) == 0)
214 {
215 MessageBox(hwndDlg, "You need at least one map.", "No Maps",
216 MB_ICONEXCLAMATION);
217
218 return false;
219 }
220 else
221 {
222 vector<string> maps;
223
224 for (unsigned index = 0; index < GetListBoxInfo(GetDlgItem(
225 hwndDlg, IDC_SELECTED)); index++)
226 {
227 char* name = new char[SendMessage(GetDlgItem(hwndDlg,
228 IDC_SELECTED), LB_GETTEXTLEN, index, 0) + 1];
229
230 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED), LB_GETTEXT,
231 index, long(name));
232 maps.push_back(name);
233
234 delete [] name;
235 }
236
237 config->setMaps(maps);
238 }
239 config->save();
240 case IDCANCEL:
241 EndDialog(hwndDlg, wParam);
242 return true;
243 case IDC_ADD_MAP:
244 {
245 unsigned count = SendMessage(GetDlgItem(hwndDlg,
246 IDC_AVAILABLE), LB_GETSELCOUNT, 0, 0);
247 unsigned* additions = new unsigned[count];
248
249 SendMessage(GetDlgItem(hwndDlg, IDC_AVAILABLE), LB_GETSELITEMS,
250 count, long(additions));
251
252 if (debug) cerr << "additions = {\n";
253 for (unsigned index = 0; index < count; index++)
254 {
255 if (debug) cerr << " [" << index << "] = " <<
256 additions[index] << "\n";
257
258 char* name = new char[SendMessage(GetDlgItem(hwndDlg,
259 IDC_AVAILABLE), LB_GETTEXTLEN, additions[index], 0) + 1
260 ];
261
262 SendMessage(GetDlgItem(hwndDlg, IDC_AVAILABLE), LB_GETTEXT,
263 additions[index], long(name));
264 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
265 LB_ADDSTRING, 0, long(name));
266
267 delete [] name;
268 }
269 if (debug) cerr << "}\n";
270
271 delete [] additions;
272
273 SendMessage(GetDlgItem(hwndDlg, IDC_AVAILABLE), LB_SETSEL,
274 false, -1);
275 EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_MAP), false);
276 }
277 break;
278 case IDC_REMOVE_MAP:
279 {
280 unsigned count = SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
281 LB_GETSELCOUNT, 0, 0);
282 unsigned* removals = new unsigned[count];
283
284 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED), LB_GETSELITEMS,
285 count, long(removals));
286
287 if (debug) cerr << "removals = {\n";
288 for (unsigned index = count; index > 0; index--)
289 {
290 if (debug) cerr << " [" << index - 1 << "] = " <<
291 removals[index - 1] << "\n";
292
293 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
294 LB_DELETESTRING, removals[index - 1], 0);
295 }
296 if (debug) cerr << "}\n";
297
298 delete [] removals;
299
300 EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE_MAP), false);
301 EnableWindow(GetDlgItem(hwndDlg, IDC_UP_MAP), false);
302 EnableWindow(GetDlgItem(hwndDlg, IDC_DOWN_MAP), false);
303 }
304 break;
305 case IDC_UP_MAP:
306 {
307 unsigned count = SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
308 LB_GETSELCOUNT, 0, 0);
309 unsigned* ups = new unsigned[count];
310
311 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED), LB_GETSELITEMS,
312 count, long(ups));
313
314 unsigned insert = ups[0] - 1;
315
316 if (debug) cerr << "ups = {\n";
317 for (unsigned index = 0; index < count; index++)
318 {
319 if (debug) cerr << " [" << index << "] = " << ups[index]
320 << "\n";
321
322 char* up = new char[SendMessage(GetDlgItem(hwndDlg,
323 IDC_SELECTED), LB_GETTEXTLEN, ups[index], 0) + 1];
324
325 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED), LB_GETTEXT,
326 ups[index], long(up));
327 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
328 LB_DELETESTRING, ups[index], 0);
329 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
330 LB_INSERTSTRING, insert, long(up));
331 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED), LB_SETSEL,
332 true, insert++);
333 }
334 if (debug) cerr << "}\n";
335
336 delete [] ups;
337
338 if (SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
339 LB_GETSEL, 0, 0) == 0)
340 {
341 EnableWindow(GetDlgItem(hwndDlg, IDC_UP_MAP), true);
342 }
343 else
344 {
345 EnableWindow(GetDlgItem(hwndDlg, IDC_UP_MAP), false);
346 }
347
348 if (SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
349 LB_GETSEL, SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED
350 ), LB_GETCOUNT, 0, 0) - 1, 0) == 0)
351 {
352 EnableWindow(GetDlgItem(hwndDlg, IDC_DOWN_MAP), true);
353 }
354 }
355 break;
356 case IDC_DOWN_MAP:
357 {
358 unsigned count = SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
359 LB_GETSELCOUNT, 0, 0);
360 unsigned* downs = new unsigned[count];
361
362 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED), LB_GETSELITEMS,
363 count, long(downs));
364
365 unsigned insert = downs[count - 1] + 1;
366
367 if (debug) cerr << "downs = {\n";
368 for (unsigned index = count; index > 0; index--)
369 {
370 if (debug) cerr << " [" << index << "] = " << downs[index
371 - 1] << "\n";
372
373 char* down = new char[SendMessage(GetDlgItem(hwndDlg,
374 IDC_SELECTED), LB_GETTEXTLEN, downs[index - 1], 0) +
375 1];
376
377 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED), LB_GETTEXT,
378 downs[index - 1], long(down));
379 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
380 LB_DELETESTRING, downs[index - 1], 0);
381 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
382 LB_INSERTSTRING, insert, long(down));
383 SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED), LB_SETSEL,
384 true, insert--);
385 }
386 if (debug) cerr << "}\n";
387
388 delete [] downs;
389
390 if (SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
391 LB_GETSEL, 0, 0) == 0)
392 {
393 EnableWindow(GetDlgItem(hwndDlg, IDC_UP_MAP), true);
394 }
395
396 if (SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
397 LB_GETSEL, SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED
398 ), LB_GETCOUNT, 0, 0) - 1, 0) == 0)
399 {
400 EnableWindow(GetDlgItem(hwndDlg, IDC_DOWN_MAP), true);
401 }
402 else
403 {
404 EnableWindow(GetDlgItem(hwndDlg, IDC_DOWN_MAP), false);
405 }
406 }
407 break;
408 case IDC_AVAILABLE:
409 switch (HIWORD(wParam))
410 {
411 case LBN_SELCHANGE:
412 if (SendMessage(GetDlgItem(hwndDlg, IDC_AVAILABLE),
413 LB_GETSELCOUNT, 0, 0) > 0)
414 {
415 EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_MAP), true);
416 }
417 else
418 {
419 EnableWindow(GetDlgItem(hwndDlg, IDC_ADD_MAP), false);
420 }
421 break;
422 }
423 break;
424 case IDC_SELECTED:
425 switch (HIWORD(wParam))
426 {
427 case LBN_SELCHANGE:
428 if (SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
429 LB_GETSELCOUNT, 0, 0) > 0)
430 {
431 EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE_MAP), true);
432
433 if (SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
434 LB_GETSEL, 0, 0) == 0)
435 {
436 EnableWindow(GetDlgItem(hwndDlg, IDC_UP_MAP), true);
437 }
438 else
439 {
440 EnableWindow(GetDlgItem(hwndDlg, IDC_UP_MAP), false);
441 }
442
443 if (SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED),
444 LB_GETSEL, SendMessage(GetDlgItem(hwndDlg, IDC_SELECTED
445 ), LB_GETCOUNT, 0, 0) - 1, 0) == 0)
446 {
447 EnableWindow(GetDlgItem(hwndDlg, IDC_DOWN_MAP), true);
448 }
449 else
450 {
451 EnableWindow(GetDlgItem(hwndDlg, IDC_DOWN_MAP), false);
452 }
453 }
454 else
455 {
456 EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE_MAP), false);
457 EnableWindow(GetDlgItem(hwndDlg, IDC_UP_MAP), false);
458 EnableWindow(GetDlgItem(hwndDlg, IDC_DOWN_MAP), false);
459 }
460 break;
461 }
462 break;
463 }
464 break;
465 }
466
467 return false;
468 }
469 #else
470 static void destruct(GtkWidget* widget, gpointer data)
471 {
472 gtk_main_quit();
473 }
474
475 static void done(GtkWidget* widget, gpointer data)
476 {
477 if (true)
478 {
479 message("You need at least one map.", "No Maps",
480 GTK_MESSAGE_WARNING);
481 }
482 else
483 {
484 //
485
486 config->save();
487
488 gtk_main_quit();
489 }
490 }
491
492 static void mapAdd(GtkWidget* widget, gpointer data)
493 {
494 cout << "STUB: add\n\a" << flush;
495 }
496
497 static void mapRemove(GtkWidget* widget, gpointer data)
498 {
499 cout << "STUB: remove\n\a" << flush;
500 }
501
502 static void mapUp(GtkWidget* widget, gpointer data)
503 {
504 cout << "STUB: up\n\a" << flush;
505 }
506
507 static void mapDown(GtkWidget* widget, gpointer data)
508 {
509 cout << "STUB: down\n\a" << flush;
510 }
511
512 void selector(void)
513 {
514 GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
515
516 gtk_window_set_title(GTK_WINDOW(window), "Renegade Map Selector");
517 gtk_window_set_resizable(GTK_WINDOW(window), false);
518 g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(destruct),
519 NULL);
520
521 GtkWidget* vertical = gtk_vbox_new(false, 0);
522 GtkWidget* horizontal = gtk_hbox_new(false, 9);
523 GtkWidget* left = gtk_frame_new("Available Maps");
524
525 gtk_frame_set_label_align(GTK_FRAME(left), 0.5, 0.5);
526 gtk_container_set_border_width(GTK_CONTAINER(left), 6);
527
528 GtkWidget* center = gtk_vbox_new(true, 0);
529 GtkWidget* top = gtk_vbutton_box_new();
530
531 gtk_button_box_set_layout(GTK_BUTTON_BOX(top), GTK_BUTTONBOX_START);
532 gtk_box_set_spacing(GTK_BOX(top), 9);
533 gtk_container_set_border_width(GTK_CONTAINER(top), 6);
534
535 GtkWidget* add = gtk_button_new_with_mnemonic("_Add");
536
537 g_signal_connect(G_OBJECT(add), "clicked", G_CALLBACK(mapAdd), NULL);
538 gtk_widget_set_sensitive(add, false);
539
540 GtkWidget* remove = gtk_button_new_with_mnemonic("_Remove");
541
542 g_signal_connect(G_OBJECT(remove), "clicked", G_CALLBACK(mapRemove), NULL);
543 gtk_widget_set_sensitive(remove, false);
544
545 GtkWidget* middle = gtk_vbutton_box_new();
546
547 gtk_button_box_set_layout(GTK_BUTTON_BOX(middle), GTK_BUTTONBOX_END);
548 gtk_box_set_spacing(GTK_BOX(middle), 9);
549 gtk_container_set_border_width(GTK_CONTAINER(middle), 6);
550
551 GtkWidget* up = gtk_button_new_with_mnemonic("_Up");
552
553 g_signal_connect(G_OBJECT(up), "clicked", G_CALLBACK(mapUp), NULL);
554 gtk_widget_set_sensitive(up, false);
555
556 GtkWidget* down = gtk_button_new_with_mnemonic("_Down");
557
558 g_signal_connect(G_OBJECT(down), "clicked", G_CALLBACK(mapDown), NULL);
559 gtk_widget_set_sensitive(down, false);
560
561 GtkWidget* right = gtk_frame_new("Selected Maps");
562
563 gtk_frame_set_label_align(GTK_FRAME(right), 0.5, 0.5);
564 gtk_container_set_border_width(GTK_CONTAINER(right), 6);
565
566 GtkWidget* separator = gtk_hseparator_new();
567 GtkWidget* bottom = gtk_hbutton_box_new();
568
569 gtk_button_box_set_layout(GTK_BUTTON_BOX(bottom), GTK_BUTTONBOX_END);
570 gtk_box_set_spacing(GTK_BOX(bottom), 9);
571 gtk_container_set_border_width(GTK_CONTAINER(bottom), 6);
572
573 GtkWidget* ok = gtk_button_new_from_stock(GTK_STOCK_OK);
574
575 g_signal_connect(G_OBJECT(ok), "clicked", G_CALLBACK(done), NULL);
576
577 GtkWidget* cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
578
579 g_signal_connect(G_OBJECT(cancel), "clicked", G_CALLBACK(destruct), NULL);
580
581 // pack
582 gtk_container_add(GTK_CONTAINER(vertical), horizontal);
583 gtk_container_add(GTK_CONTAINER(horizontal), left);
584 gtk_container_add(GTK_CONTAINER(horizontal), center);
585 gtk_container_add(GTK_CONTAINER(center), top);
586 gtk_container_add(GTK_CONTAINER(top), add);
587 gtk_container_add(GTK_CONTAINER(top), remove);
588 gtk_container_add(GTK_CONTAINER(center), middle);
589 gtk_container_add(GTK_CONTAINER(middle), up);
590 gtk_container_add(GTK_CONTAINER(middle), down);
591 gtk_container_add(GTK_CONTAINER(horizontal), right);
592 gtk_container_add(GTK_CONTAINER(vertical), separator);
593 gtk_container_add(GTK_CONTAINER(bottom), ok);
594 gtk_container_add(GTK_CONTAINER(bottom), cancel);
595 gtk_container_add(GTK_CONTAINER(vertical), bottom);
596 gtk_container_add(GTK_CONTAINER(window), vertical);
597
598 // show
599 gtk_widget_show(left);
600 gtk_widget_show(add);
601 gtk_widget_show(remove);
602 gtk_widget_show(top);
603 gtk_widget_show(up);
604 gtk_widget_show(down);
605 gtk_widget_show(middle);
606 gtk_widget_show(center);
607 gtk_widget_show(right);
608 gtk_widget_show(horizontal);
609 gtk_widget_show(separator);
610 gtk_widget_show(ok);
611 gtk_widget_show(cancel);
612 gtk_widget_show(bottom);
613 gtk_widget_show(vertical);
614 gtk_widget_show(window);
615
616 gtk_main();
617 }
618
619 void message(const string& text, const string& title, GtkMessageType type)
620 {
621 GtkWidget* box = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, type,
622 GTK_BUTTONS_OK, text.c_str());
623
624 gtk_window_set_title(GTK_WINDOW(box), title.c_str());
625
626 gtk_dialog_run(GTK_DIALOG(box));
627 gtk_widget_destroy(box);
628 }
629 #endif