Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
CmpSelectDlg.cpp
Go to the documentation of this file.
1 /* Project Starshatter 4.5
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: CmpSelectDlg.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Mission Select Dialog Active Window class
13 */
14 
15 #include "MemDebug.h"
16 #include "CmpSelectDlg.h"
17 #include "ConfirmDlg.h"
18 #include "MenuScreen.h"
19 #include "Starshatter.h"
20 #include "Campaign.h"
21 #include "CampaignSaveGame.h"
22 #include "CombatGroup.h"
23 #include "ShipDesign.h"
24 #include "Player.h"
25 
26 #include "Game.h"
27 #include "DataLoader.h"
28 #include "Button.h"
29 #include "ListBox.h"
30 #include "Slider.h"
31 #include "Video.h"
32 #include "Keyboard.h"
33 #include "Mouse.h"
34 #include "ParseUtil.h"
35 #include "FormatUtil.h"
36 
37 // +--------------------------------------------------------------------+
38 // DECLARE MAPPING FUNCTIONS:
39 
42 DEF_MAP_CLIENT(CmpSelectDlg, OnDelete);
43 DEF_MAP_CLIENT(CmpSelectDlg, OnConfirmDelete);
44 DEF_MAP_CLIENT(CmpSelectDlg, OnAccept);
45 DEF_MAP_CLIENT(CmpSelectDlg, OnCancel);
46 DEF_MAP_CLIENT(CmpSelectDlg, OnCampaignSelect);
47 
48 // +--------------------------------------------------------------------+
49 
51 : FormWindow(s, 0, 0, s->Width(), s->Height()), manager(mgr),
52 lst_campaigns(0), btn_new(0), btn_saved(0), btn_delete(0),
53 btn_accept(0), btn_cancel(0), description(0), stars(0), campaign(0),
54 selected_mission(-1), show_saved(false), loading(false),
55 loaded(false), hproc(0)
56 {
58  select_msg = Game::GetText("CmpSelectDlg.select_msg");
59  Init(def);
60 }
61 
63 {
64  StopLoadProc();
65  images.destroy();
66 }
67 
68 // +--------------------------------------------------------------------+
69 
70 void
72 {
73  btn_new = (Button*) FindControl(100);
74  btn_saved = (Button*) FindControl(101);
75  btn_delete = (Button*) FindControl(102);
76  btn_accept = (Button*) FindControl( 1);
77  btn_cancel = (Button*) FindControl( 2);
78 
79  if (btn_new)
81 
82  if (btn_saved)
84 
85  if (btn_delete) {
86  btn_delete->SetEnabled(false);
89  }
90 
91  if (btn_accept) {
92  btn_accept->SetEnabled(false);
94  }
95 
96  if (btn_cancel) {
97  btn_cancel->SetEnabled(true);
99  }
100 
101  description = FindControl(200);
102 
104 
105  if (lst_campaigns)
107 
109 }
110 
111 // +--------------------------------------------------------------------+
112 
113 void
115 {
116  if (Keyboard::KeyDown(VK_RETURN)) {
117  if (btn_accept && btn_accept->IsEnabled())
118  OnAccept(0);
119  }
120 
121  AutoThreadSync a(sync);
122 
123  if (loaded) {
124  loaded = false;
125 
126  if (btn_cancel)
127  btn_cancel->SetEnabled(true);
128 
129  if (description && btn_accept) {
130  if (campaign) {
132 
133  if (load_index >= 0) {
134  if (lst_campaigns) {
135  images[load_index]->CopyBitmap(*campaign->GetImage(1));
137  }
138 
139  description->SetText(Text("<font Limerick12><color ffffff>") +
140  campaign->Name() +
141  Text("<font Verdana>\n\n") +
142  Text("<color ffff80>") +
143  Game::GetText("CmpSelectDlg.scenario") +
144  Text("<color ffffff>\n\t") +
145  campaign->Description());
146  }
147  else {
148  char time_buf[32];
149  char score_buf[32];
150 
151  double t = campaign->GetLoadTime() - campaign->GetStartTime();
152  FormatDayTime(time_buf, t);
153 
154  sprintf_s(score_buf, "%d", campaign->GetPlayerTeamScore());
155 
156  Text desc = Text("<font Limerick12><color ffffff>") +
157  campaign->Name() +
158  Text("<font Verdana>\n\n") +
159  Text("<color ffff80>") +
160  Game::GetText("CmpSelectDlg.scenario") +
161  Text("<color ffffff>\n\t") +
162  campaign->Description() +
163  Text("\n\n<color ffff80>") +
164  Game::GetText("CmpSelectDlg.campaign-time") +
165  Text("<color ffffff>\n\t") +
166  time_buf +
167  Text("\n\n<color ffff80>") +
168  Game::GetText("CmpSelectDlg.assignment") +
169  Text("<color ffffff>\n\t");
170 
171  if (campaign->GetPlayerGroup())
172  desc += campaign->GetPlayerGroup()->GetDescription();
173  else
174  desc += "n/a";
175 
176  desc += Text("\n\n<color ffff80>") +
177  Game::GetText("CmpSelectDlg.team-score") +
178  Text("<color ffffff>\n\t") +
179  score_buf;
180 
181  description->SetText(desc);
182  }
183 
184  btn_accept->SetEnabled(true);
185 
186  if (btn_delete)
188  }
189  else {
191  btn_accept->SetEnabled(true);
192  }
193  }
194  }
195 }
196 
197 bool
199 {
200  AutoThreadSync a(sync);
201  return !loading;
202 }
203 
204 // +--------------------------------------------------------------------+
205 
206 void
208 {
209  AutoThreadSync a(sync);
210 
211  if (loading && description) {
212  description->SetText(Game::GetText("CmpSelectDlg.already-loading"));
214  return;
215  }
216 
217  if (btn_new)
219 
220  if (btn_saved)
222 
223  if (btn_delete)
224  btn_delete->SetEnabled(false);
225 
226  if (lst_campaigns) {
227  images.destroy();
228 
233 
234  Player* player = Player::GetCurrentPlayer();
235  if (!player) return;
236 
238  while (++iter) {
239  Campaign* c = iter.value();
240 
242  Bitmap* bmp = new(__FILE__,__LINE__) Bitmap;
243  bmp->CopyBitmap(*c->GetImage(0));
244  images.append(bmp);
245 
246  int n = lst_campaigns->AddImage(bmp) - 1;
247  lst_campaigns->SetItemText(n, c->Name());
248 
249  // if campaign is not available, show the grayed-out image
250 
251  // FULL GAME CRITERIA (based on player record):
252  if (c->GetCampaignId() > 2 && c->GetCampaignId() < 10 &&
253  !player->HasCompletedCampaign(c->GetCampaignId()-1)) {
254  images[n]->CopyBitmap(*c->GetImage(2));
256  }
257 
258  // Two additional sequences of ten campaigns (10-19 and 20-29)
259  // for mod authors to use:
260  else if (c->GetCampaignId() >= 10 && c->GetCampaignId() < 30 &&
261  (c->GetCampaignId() % 10) != 0 &&
262  !player->HasCompletedCampaign(c->GetCampaignId()-1)) {
263  images[n]->CopyBitmap(*c->GetImage(2));
265  }
266 
267  // NOTE: Campaigns 10, 20, and 30-99 are always enabled if they exist!
268  }
269  }
270  }
271 
272  if (description)
274 
275  if (btn_accept)
276  btn_accept->SetEnabled(false);
277 
278  show_saved = false;
279 }
280 
281 // +--------------------------------------------------------------------+
282 
283 void
285 {
286  AutoThreadSync a(sync);
287 
288  if (loading && description) {
289  description->SetText(Game::GetText("CmpSelectDlg.already-loading"));
291  return;
292  }
293 
294  if (btn_new)
296 
297  if (btn_saved)
299 
300  if (btn_delete)
301  btn_delete->SetEnabled(false);
302 
303  if (lst_campaigns) {
308 
309  List<Text> save_list;
310 
312  save_list.sort();
313 
314  for (int i = 0; i < save_list.size(); i++)
315  lst_campaigns->AddItem(*save_list[i]);
316 
317  save_list.destroy();
318  }
319 
320  if (description)
322 
323  if (btn_accept)
324  btn_accept->SetEnabled(false);
325 
326  show_saved = true;
327 }
328 
329 // +--------------------------------------------------------------------+
330 
331 void
333 {
334  if (description && lst_campaigns) {
335  AutoThreadSync a(sync);
336 
337  if (loading) {
338  description->SetText(Game::GetText("CmpSelectDlg.already-loading"));
340  return;
341  }
342 
343  load_index = -1;
344  load_file = "";
345 
346  Player* player = Player::GetCurrentPlayer();
347  if (!player) return;
348 
349  // NEW CAMPAIGN:
350  if (btn_new && btn_new->GetButtonState()) {
352 
353  for (int i = 0; i < lst_campaigns->NumItems(); i++) {
354  Campaign* c = list[i];
355 
356  // is campaign available?
357  // FULL GAME CRITERIA (based on player record):
358  if (c->GetCampaignId() <= 2 ||
359  player->HasCompletedCampaign(c->GetCampaignId()-1))
360  {
361 
362  if (lst_campaigns->IsSelected(i)) {
363  images[i]->CopyBitmap(*c->GetImage(1));
365 
366  AutoThreadSync a(sync);
367  load_index = i;
368  }
369  else {
370  images[i]->CopyBitmap(*c->GetImage(0));
372  }
373  }
374 
375  // if not, then don't select
376  else {
377  images[i]->CopyBitmap(*c->GetImage(2));
379 
380  if (lst_campaigns->IsSelected(i)) {
382  }
383  }
384  }
385  }
386 
387  // SAVED CAMPAIGN:
388  else {
389  int seln = lst_campaigns->GetSelection();
390 
391  if (seln < 0) {
393  }
394 
395  else {
396  load_index = -1;
398  }
399  }
400 
401  if (btn_accept)
402  btn_accept->SetEnabled(false);
403  }
404 
405  if (!loading && (load_index >= 0 || load_file.length() > 0)) {
406  if (btn_cancel)
407  btn_cancel->SetEnabled(false);
408 
409  StartLoadProc();
410  }
411 }
412 
413 // +--------------------------------------------------------------------+
414 
415 void
417 {
420 }
421 
422 // +--------------------------------------------------------------------+
423 
424 void
426 {
428 }
429 
430 void
432 {
434 }
435 
436 void
438 {
439  load_file = "";
440 
441  if (lst_campaigns) {
442  int seln = lst_campaigns->GetSelection();
443 
444  if (seln < 0) {
446  btn_accept->SetEnabled(false);
447  }
448 
449  else {
450  load_index = -1;
452  }
453  }
454 
455  if (load_file.length()) {
456  ConfirmDlg* confirm = manager->GetConfirmDlg();
457  if (confirm) {
458  char msg[256];
459  sprintf_s(msg, Game::GetText("CmpSelectDlg.are-you-sure"), load_file.data());
460  confirm->SetMessage(msg);
461  confirm->SetTitle(Game::GetText("CmpSelectDlg.confirm"));
462 
464  }
465 
466  else {
467  OnConfirmDelete(event);
468  }
469  }
470 
472 }
473 
474 void
476 {
477  if (load_file.length()) {
479  }
480 
482 }
483 
484 // +--------------------------------------------------------------------+
485 
486 void
488 {
489  AutoThreadSync a(sync);
490 
491  if (loading)
492  return;
493 
494  // if this is to be a new campaign,
495  // re-instaniate the campaign object
496  if (btn_new->GetButtonState())
498  else
500 
501  Mouse::Show(false);
503 }
504 
505 void
507 {
508  manager->ShowMenuDlg();
509 }
510 
511 // +--------------------------------------------------------------------+
512 
513 DWORD WINAPI CmpSelectDlgLoadProc(LPVOID link);
514 
515 void
517 {
518  if (hproc != 0) {
519  DWORD result = 0;
520  GetExitCodeThread(hproc, &result);
521 
522  if (result != STILL_ACTIVE) {
523  CloseHandle(hproc);
524  hproc = 0;
525  }
526  else {
527  return;
528  }
529  }
530 
531  if (hproc == 0) {
532  campaign = 0;
533  loading = true;
534  loaded = false;
535 
536  if (description)
537  description->SetText(Game::GetText("CmpSelectDlg.loading"));
538 
539  DWORD thread_id = 0;
540  hproc = CreateThread(0, 4096, CmpSelectDlgLoadProc, (LPVOID) this, 0, &thread_id);
541 
542  if (hproc == 0) {
543  static int report = 10;
544  if (report > 0) {
545  ::Print("WARNING: CmpSelectDlg() failed to create thread (err=%08x)\n", GetLastError());
546  report--;
547 
548  if (report == 0)
549  ::Print(" Further warnings of this type will be supressed.\n");
550  }
551  }
552  }
553 }
554 
555 void
557 {
558  if (hproc != 0) {
559  WaitForSingleObject(hproc, 2500);
560  CloseHandle(hproc);
561  hproc = 0;
562  }
563 }
564 
565 DWORD WINAPI CmpSelectDlgLoadProc(LPVOID link)
566 {
567  CmpSelectDlg* dlg = (CmpSelectDlg*) link;
568 
569  if (dlg)
570  return dlg->LoadProc();
571 
572  return (DWORD) E_POINTER;
573 }
574 
575 DWORD
577 {
578  Campaign* c = 0;
579 
580  // NEW CAMPAIGN:
581  if (load_index >= 0) {
583 
584  if (load_index < list.size()) {
585  c = list[load_index];
586  c->Load();
587  }
588  }
589 
590  // SAVED CAMPAIGN:
591  else {
592  CampaignSaveGame savegame;
593  savegame.Load(load_file);
594  c = savegame.GetCampaign();
595  }
596 
597  sync.acquire();
598 
599  loading = false;
600  loaded = true;
601  campaign = c;
602 
603  sync.release();
604 
605  return 0;
606 }
607 
608 // +--------------------------------------------------------------------+