1 #include "Directories.h"
2 #include "FileMan.h"
3 #include "Font.h"
4 #include "Font_Control.h"
5 #include "Input.h"
6 #include "Interface.h"
7 #include "LoadSaveData.h"
8 #include "Local.h"
9 #include "Timer.h"
10 #include "Timer_Control.h"
11 #include "VObject.h"
12 #include "VSurface.h"
13 #include "Render_Dirty.h"
14 #include "SysUtil.h"
15 #include "Screens.h"
16 #include "Cursors.h"
17 #include "Event_Pump.h"
18 #include "Laptop.h"
19 #include "AIM.h"
20 #include "AIMMembers.h"
21 #include "AIMFacialIndex.h"
22 #include "AIMSort.h"
23 #include "AIMArchives.h"
24 #include "AIMHistory.h"
25 #include "AIMLinks.h"
26 #include "AIMPolicies.h"
27 #include "Mercs.h"
28 #include "Mercs_Files.h"
29 #include "Mercs_Account.h"
30 #include "Mercs_No_Account.h"
31 #include "BobbyR.h"
32 #include "BobbyRGuns.h"
33 #include "BobbyRAmmo.h"
34 #include "BobbyRArmour.h"
35 #include "BobbyRMisc.h"
36 #include "BobbyRUsed.h"
37 #include "BobbyRMailOrder.h"
38 #include "CharProfile.h"
39 #include "Florist.h"
40 #include "Florist_Cards.h"
41 #include "Florist_Gallery.h"
42 #include "Florist_Order_Form.h"
43 #include "Insurance.h"
44 #include "Insurance_Contract.h"
45 #include "Insurance_Info.h"
46 #include "Insurance_Comments.h"
47 #include "Funeral.h"
48 #include "Finances.h"
49 #include "Personnel.h"
50 #include "History.h"
51 #include "Files.h"
52 #include "EMail.h"
53 #include "Interface_Control.h"
54 #include "Game_Event_Hook.h"
55 #include "WordWrap.h"
56 #include "Game_Init.h"
57 #include "Game_Clock.h"
58 #include "Soldier_Control.h"
59 #include "Soldier_Profile.h"
60 #include "Overhead.h"
61 #include "Environment.h"
62 #include "Music_Control.h"
63 #include "ContentMusic.h"
64 #include "LaptopSave.h"
65 #include "RenderWorld.h"
66 #include "GameLoop.h"
67 #include "English.h"
68 #include "Random.h"
69 #include "Merc_Hiring.h"
70 #include "Map_Screen_Interface.h"
71 #include "Ambient_Control.h"
72 #include "Sound_Control.h"
73 #include "Text.h"
74 #include "Message.h"
75 #include "Map_Screen_Interface_Bottom.h"
76 #include "Cursor_Control.h"
77 #include "Quests.h"
78 #include "Multi_Language_Graphic_Utils.h"
79 #include "BrokenLink.h"
80 #include "BobbyRShipments.h"
81 #include "Dialogue_Control.h"
82 #include "HelpScreen.h"
83 #include "Cheats.h"
84 #include "Video.h"
85 #include "MemMan.h"
86 #include "Debug.h"
87 #include "Button_System.h"
88 #include "JAScreens.h"
89 #include "UILayout.h"
90
91 #include <string_theory/format>
92 #include <string_theory/string>
93
94 #include <algorithm>
95 #include <iterator>
96
97 // laptop programs
98 enum
99 {
100 LAPTOP_PROGRAM_MAILER,
101 LAPTOP_PROGRAM_WEB_BROWSER,
102 LAPTOP_PROGRAM_FILES,
103 LAPTOP_PROGRAM_PERSONNEL,
104 LAPTOP_PROGRAM_FINANCES,
105 LAPTOP_PROGRAM_HISTORY
106 };
107
108 // laptop program states
109 enum
110 {
111 LAPTOP_PROGRAM_MINIMIZED,
112 LAPTOP_PROGRAM_OPEN
113 };
114
115 #define BOOK_FONT FONT10ARIAL
116 #define DOWNLOAD_FONT FONT12ARIAL
117
118
119 #define BOOK_X (111 + STD_SCREEN_X)
120 #define BOOK_TOP_Y ( 79 + STD_SCREEN_Y)
121 #define BOOK_HEIGHT 12
122 #define DOWN_HEIGHT 19
123 #define BOOK_WIDTH 100
124
125
126 #define LONG_UNIT_TIME 120
127 #define UNIT_TIME 40
128 #define FAST_UNIT_TIME 3
129 #define FASTEST_UNIT_TIME 2
130 #define ALMOST_FAST_UNIT_TIME 25
131 #define DOWNLOAD_X (300 + STD_SCREEN_X)
132 #define DOWNLOAD_Y (200 + STD_SCREEN_Y)
133 #define LAPTOP_WINDOW_X DOWNLOAD_X + 12
134 #define LAPTOP_WINDOW_Y DOWNLOAD_Y + 25
135 #define LAPTOP_BAR_Y LAPTOP_WINDOW_Y + 2
136 #define LAPTOP_BAR_X LAPTOP_WINDOW_X + 1
137 #define UNIT_WIDTH 4
138 #define DOWN_STRING_X DOWNLOAD_X + 47
139 #define DOWN_STRING_Y DOWNLOAD_Y + 5
140 #define LAPTOP_TITLE_ICONS_X (113 + STD_SCREEN_X)
141 #define LAPTOP_TITLE_ICONS_Y ( 27 + STD_SCREEN_Y)
142
143 // HD flicker times
144 #define HD_FLICKER_TIME 3000
145 #define FLICKER_TIME 50
146
147
148 #define NUMBER_OF_LAPTOP_TITLEBAR_ITERATIONS 18
149 #define LAPTOP_TITLE_BAR_WIDTH 500
150 #define LAPTOP_TITLE_BAR_HEIGHT 24
151
152 #define LAPTOP_TITLE_BAR_TOP_LEFT_X (111 + STD_SCREEN_X)
153 #define LAPTOP_TITLE_BAR_TOP_LEFT_Y ( 25 + STD_SCREEN_Y)
154 #define LAPTOP_TITLE_BAR_TOP_RIGHT_X (610 + STD_SCREEN_X)
155
156 #define LAPTOP_TITLE_BAR_ICON_OFFSET_X (5 + STD_SCREEN_X)
157 #define LAPTOP_TITLE_BAR_ICON_OFFSET_Y (2 + STD_SCREEN_Y)
158 #define LAPTOP_TITLE_BAR_TEXT_OFFSET_X (29 + STD_SCREEN_X)
159 #define LAPTOP_TITLE_BAR_TEXT_OFFSET_Y (8 + STD_SCREEN_Y)
160
161 #define LAPTOP_PROGRAM_ICON_X LAPTOP_TITLE_BAR_TOP_LEFT_X
162 #define LAPTOP_PROGRAM_ICON_Y LAPTOP_TITLE_BAR_TOP_LEFT_Y
163 #define LAPTOP_PROGRAM_ICON_WIDTH 20
164 #define LAPTOP_PROGRAM_ICON_HEIGHT 20
165 #define DISPLAY_TIME_FOR_WEB_BOOKMARK_NOTIFY 2000
166
167 // the wait time for closing of laptop animation/delay
168 #define EXIT_LAPTOP_DELAY_TIME 100
169
170 static SGPVSurface* guiTitleBarSurface;
171 static BOOLEAN gfTitleBarSurfaceAlreadyActive = FALSE;
172
173 #define LAPTOP__NEW_FILE_ICON_X (83 + STD_SCREEN_X)
174 #define LAPTOP__NEW_FILE_ICON_Y (412 + STD_SCREEN_Y)
175
176 #define LAPTOP__NEW_EMAIL_ICON_X ((83 - 16) + STD_SCREEN_X)
177 #define LAPTOP__NEW_EMAIL_ICON_Y LAPTOP__NEW_FILE_ICON_Y
178
179
180 // Mode values
181 LaptopMode guiCurrentLaptopMode;
182 LaptopMode guiPreviousLaptopMode;
183 // Used to prevent double free problems. Fixes Stracciatella issue #68:
184 LaptopMode guiLastExitedLaptopMode = LAPTOP_MODE_NONE;
185 static LaptopMode guiCurrentWWWMode = LAPTOP_MODE_NONE;
186 INT32 giCurrentSubPage;
187
188
189 static INT32 iHighLightBookLine = -1;
190 BOOLEAN fFastLoadFlag = FALSE;
191 static BOOLEAN gfEnterLapTop=TRUE;
192 BOOLEAN gfShowBookmarks=FALSE;
193
194 // in progress of loading a page?
195 BOOLEAN fLoadPendingFlag=FALSE;
196
197 // mark buttons dirty?
198 static BOOLEAN fMarkButtonsDirtyFlag = TRUE;
199
200 // redraw afer rendering buttons?
201 BOOLEAN fReDrawPostButtonRender = FALSE;
202
203 // in laptop right now?
204 BOOLEAN fCurrentlyInLaptop = FALSE;
205
206 // exit due to a message box pop up?..don't really leave LAPTOP
207 BOOLEAN fExitDueToMessageBox = FALSE;
208
209 // exit laptop during a load?
210 static BOOLEAN fExitDuringLoad = FALSE;
211
212 // done loading?
213 BOOLEAN fDoneLoadPending = FALSE;
214
215 // going a subpage of a web page?..faster access time
216 BOOLEAN fConnectingToSubPage = FALSE;
217
218 // is this our first time in laptop?
219 static BOOLEAN fFirstTimeInLaptop = TRUE;
220
221 // redraw the book mark info panel .. for blitting on top of animations
222 BOOLEAN fReDrawBookMarkInfo = FALSE;
223
224 // show the 2 second info about bookmarks being accessed by clicking on web
225 BOOLEAN fShowBookmarkInfo = FALSE;
226
227 //GLOBAL FOR WHICH SCREEN TO EXIT TO FOR LAPTOP
228 static ScreenID guiExitScreen = MAP_SCREEN;
229
230 // Laptop screen graphic handle
231 static SGPVObject* guiLAPTOP;
232
233 static BOOLEAN fNewWWW = TRUE;
234
235 //Used to store the site to go to after the 'rain delay' message
236 extern UINT32 guiRainLoop;
237
238
239 static INT32 giRainDelayInternetSite = -1;
240
241
242 // the laptop icons
243 static SGPVObject* guiBOOKHIGH;
244 static SGPVObject* guiBOOKMARK;
245 static SGPVObject* guiGRAPHWINDOW;
246 static SGPVObject* guiGRAPHBAR;
247 SGPVObject* guiLaptopBACKGROUND;
248 static SGPVObject* guiDOWNLOADTOP;
249 static SGPVObject* guiDOWNLOADMID;
250 static SGPVObject* guiDOWNLOADBOT;
251 static SGPVObject* guiTITLEBARLAPTOP;
252 static SGPVObject* guiLIGHTS;
253 SGPVObject* guiTITLEBARICONS;
254 static SGPVSurface* guiDESKTOP;
255
256 // enter new laptop mode due to sliding bars
257 static BOOLEAN fEnteredNewLapTopDueToHandleSlidingBars = FALSE;
258
259
260 // whether or not we are initing the slide in title bar
261 static BOOLEAN fInitTitle = TRUE;
262
263 // tab handled
264 static BOOLEAN fTabHandled = FALSE;
265
266 static GUIButtonRef gLaptopButton[7];
267
268 // minimize button
269 static GUIButtonRef gLaptopMinButton;
270
271
272 static INT32 gLaptopProgramStates[LAPTOP_PROGRAM_HISTORY + 1];
273
274 // process of mazimizing
275 static BOOLEAN fMaximizingProgram = FALSE;
276
277 // program we are maximizing
278 static INT8 bProgramBeingMaximized = -1;
279
280 // are we minimizing
281 static BOOLEAN fMinizingProgram = FALSE;
282
283
284 // process openned queue
285 static INT32 gLaptopProgramQueueList[6];
286
287
288 BOOLEAN fExitingLaptopFlag = FALSE;
289
290 // HD and power lights on
291 static BOOLEAN fPowerLightOn = TRUE;
292 static BOOLEAN fHardDriveLightOn = FALSE;
293
294 // HD flicker
295 static BOOLEAN fFlickerHD = FALSE;
296
297 // the screens limiting rect
298 static const SGPRect LaptopScreenRect = { LAPTOP_UL_X, (UINT16)(LAPTOP_UL_Y - 5), (UINT16)(LAPTOP_SCREEN_LR_X + 2), (UINT16)(LAPTOP_SCREEN_LR_Y + 5 + 19) };
299
300
301 // the sub pages vistsed or not status within the web browser
302 static bool gfWWWaitSubSitesVisitedFlags[LAPTOP_MODE_END - (LAPTOP_MODE_WWW + 1)];
303
304 // mouse regions
305 static MOUSE_REGION gLapTopScreenRegion;
306 static MOUSE_REGION gBookmarkMouseRegions[MAX_BOOKMARKS];
307 static MOUSE_REGION gLapTopProgramMinIcon;
308 static MOUSE_REGION gNewMailIconRegion;
309 static MOUSE_REGION gNewFileIconRegion;
310
311
312 //used for global variables that need to be saved
313 LaptopSaveInfoStruct LaptopSaveInfo;
314
315
316 BOOLEAN fReDrawScreenFlag=FALSE;
317 BOOLEAN fPausedReDrawScreenFlag=FALSE; //used in the handler functions to redraw the screen, after the current frame
318 void PrintBalance(void);
319
320
321 void PrintDate(void);
322 void PrintNumberOnTeam(void);
323
324 extern void ClearHistoryList(void);
325
326
SetLaptopExitScreen(ScreenID const uiExitScreen)327 void SetLaptopExitScreen(ScreenID const uiExitScreen)
328 {
329 guiExitScreen = uiExitScreen;
330 }
331
332
SetLaptopNewGameFlag(void)333 void SetLaptopNewGameFlag(void)
334 {
335 LaptopSaveInfo.gfNewGameLaptop = TRUE;
336 }
337
338
GetLaptopKeyboardInput(void)339 static void GetLaptopKeyboardInput(void)
340 {
341 SGPPoint MousePos;
342 GetMousePos(&MousePos);
343
344 fTabHandled = FALSE;
345
346 InputAtom InputEvent;
347 while (DequeueEvent(&InputEvent))
348 {
349 MouseSystemHook(InputEvent.usEvent, MousePos.iX, MousePos.iY);
350 HandleKeyBoardShortCutsForLapTop(InputEvent.usEvent, InputEvent.usParam, InputEvent.usKeyState);
351 }
352 }
353
354
355 static void InitBookMarkList(void);
356
357
358 //This is called only once at game initialization.
LaptopScreenInit(void)359 void LaptopScreenInit(void)
360 {
361 //Memset the whole structure, to make sure of no 'JUNK'
362 LaptopSaveInfo = LaptopSaveInfoStruct{};
363
364 LaptopSaveInfo.gfNewGameLaptop = TRUE;
365
366 //reset the id of the last hired merc
367 LaptopSaveInfo.sLastHiredMerc.iIdOfMerc = -1;
368
369 //reset the flag that enables the 'just hired merc' popup
370 LaptopSaveInfo.sLastHiredMerc.fHaveDisplayedPopUpInLaptop = FALSE;
371
372 //Initialize all vars
373 guiCurrentLaptopMode = LAPTOP_MODE_EMAIL;
374 guiPreviousLaptopMode = LAPTOP_MODE_NONE;
375 guiCurrentWWWMode = LAPTOP_MODE_NONE;
376
377 gfShowBookmarks = FALSE;
378 InitBookMarkList();
379 GameInitAIM();
380 GameInitAimSort();
381 GameInitMercs();
382 GameInitBobbyRGuns();
383 GameInitBobbyRMailOrder();
384 GameInitEmail();
385 GameInitCharProfile();
386 GameInitFiles();
387 GameInitPersonnel();
388
389 // init program states
390 std::fill(std::begin(gLaptopProgramStates), std::end(gLaptopProgramStates), LAPTOP_PROGRAM_MINIMIZED);
391
392 gfAtLeastOneMercWasHired = FALSE;
393
394 //No longer inits the laptop screens, now InitLaptopAndLaptopScreens() does
395 }
396
397
InitLaptopAndLaptopScreens(void)398 void InitLaptopAndLaptopScreens(void)
399 {
400 GameInitFinances();
401 GameInitHistory();
402
403 //Reset the flag so we can create a new IMP character
404 LaptopSaveInfo.fIMPCompletedFlag = FALSE;
405
406 //Reset the flag so that BOBBYR's isnt available at the begining of the game
407 LaptopSaveInfo.fBobbyRSiteCanBeAccessed = FALSE;
408 }
409
410
411 //This is only called once at game shutdown.
LaptopScreenShutdown(void)412 void LaptopScreenShutdown(void)
413 {
414 InsuranceContractEndGameShutDown();
415 BobbyRayMailOrderEndGameShutDown();
416 ShutDownEmailList();
417 ClearHistoryList();
418 }
419
420
421 static void CreateDestroyMouseRegionForNewMailIcon(void);
422 static void CreateLapTopMouseRegions(void);
423 static void DrawDeskTopBackground(void);
424 static void EnterLaptopInitLaptopPages(void);
425 static void InitLaptopOpenQueue(void);
426 static void InitalizeSubSitesList(void);
427 static BOOLEAN IsItRaining(void);
428 static void LoadBookmark(void);
429 static void LoadDesktopBackground(void);
430 static void LoadLoadPending(void);
431 static void RenderLapTopImage(void);
432
433
EnterLaptop(void)434 static void EnterLaptop(void)
435 {
436 //Create, load, initialize data -- just entered the laptop.
437
438 // we are re entering due to message box, leave NOW!
439 if (fExitDueToMessageBox) return;
440
441 //if the radar map mouse region is still active, disable it.
442 if (gRadarRegion.uiFlags & MSYS_REGION_ENABLED)
443 {
444 gRadarRegion.Disable();
445 }
446
447 gfDontStartTransitionFromLaptop = FALSE;
448
449 // ATE: Disable messages....
450 DisableScrollMessages();
451
452 // Stop any person from saying anything
453 StopAnyCurrentlyTalkingSpeech();
454
455 // Don't play music....
456 SetMusicMode(MUSIC_LAPTOP);
457
458 // Stop ambients...
459 StopAmbients();
460
461 //if its raining, start the rain showers
462 if (IsItRaining())
463 {
464 //Enable the rain delay warning
465 giRainDelayInternetSite = -1;
466
467 //lower the volume
468 guiRainLoop = PlayJA2Ambient(RAIN_1, LOWVOLUME, 0);
469 }
470
471 //pause the game because we dont want time to advance in the laptop
472 PauseGame();
473
474 // set the fact we are currently in laptop, for rendering purposes
475 fCurrentlyInLaptop = TRUE;
476
477 // reset redraw flag and redraw new mail
478 fReDrawScreenFlag = FALSE;
479 fReDrawNewMailFlag = TRUE;
480
481 // sub page
482 giCurrentSubPage = 0;
483
484 // load the laptop graphic and add it
485 guiLAPTOP = AddVideoObjectFromFile(LAPTOPDIR "/laptop3.sti");
486
487 // background for panel
488 guiLaptopBACKGROUND = AddVideoObjectFromFile(LAPTOPDIR "/taskbar.sti");
489
490 // background for panel
491 guiTITLEBARLAPTOP = AddVideoObjectFromFile(LAPTOPDIR "/programtitlebar.sti");
492
493 // lights for power and HD
494 guiLIGHTS = AddVideoObjectFromFile(LAPTOPDIR "/lights.sti");
495
496 // icons for title bars
497 guiTITLEBARICONS = AddVideoObjectFromFile(LAPTOPDIR "/icons.sti");
498
499 // load, blt and delete graphics
500 guiEmailWarning = AddVideoObjectFromFile(LAPTOPDIR "/newmailwarning.sti");
501 // load background
502 LoadDesktopBackground();
503
504 guiCurrentLaptopMode = LAPTOP_MODE_NONE;
505 guiPreviousLaptopMode = LAPTOP_MODE_NONE;
506 guiCurrentWWWMode = LAPTOP_MODE_NONE;
507 CreateLapTopMouseRegions();
508 RenderLapTopImage();
509
510 // reset bookmarks flags
511 fFirstTimeInLaptop = TRUE;
512
513 // reset all bookmark visits
514 std::fill(std::begin(LaptopSaveInfo.fVisitedBookmarkAlready), std::end(LaptopSaveInfo.fVisitedBookmarkAlready), 0);
515
516 // init program states
517 std::fill(std::begin(gLaptopProgramStates), std::end(gLaptopProgramStates), LAPTOP_PROGRAM_MINIMIZED);
518
519 // turn the power on
520 fPowerLightOn = TRUE;
521
522 // we are not exiting laptop right now, we just got here
523 fExitingLaptopFlag = FALSE;
524
525 // reset program we are maximizing
526 bProgramBeingMaximized = -1;
527
528 // reset fact we are maximizing/ mining
529 fMaximizingProgram = FALSE;
530 fMinizingProgram = FALSE;
531
532
533 // initialize open queue
534 InitLaptopOpenQueue();
535
536
537 gfShowBookmarks = FALSE;
538 LoadBookmark();
539 SetBookMark(AIM_BOOKMARK);
540 LoadLoadPending();
541
542 DrawDeskTopBackground();
543
544 // create region for new mail icon
545 CreateDestroyMouseRegionForNewMailIcon();
546
547 //DEF: Added to Init things in various laptop pages
548 EnterLaptopInitLaptopPages();
549 InitalizeSubSitesList();
550
551 InvalidateScreen();
552 }
553
554
555 static void CreateDestoryBookMarkRegions(void);
556 static void CreateDestroyMinimizeButtonForCurrentMode(void);
557 static void DeleteBookmark(void);
558 static void DeleteDesktopBackground(void);
559 static void DeleteLapTopButtons(void);
560 static void DeleteLapTopMouseRegions(void);
561 static void DeleteLoadPending(void);
562 static void ExitLaptopMode(LaptopMode uiMode);
563
564
ExitLaptop(void)565 void ExitLaptop(void)
566 {
567 // exit is called due to message box, leave
568 if (fExitDueToMessageBox)
569 {
570 fExitDueToMessageBox = FALSE;
571 return;
572 }
573
574 if (DidGameJustStart())
575 {
576 SetMusicMode(MUSIC_LAPTOP);
577 }
578 else
579 {
580 // Restore to old stuff...
581 SetMusicMode(MUSIC_RESTORE);
582 }
583
584 // Start ambients...
585 BuildDayAmbientSounds();
586
587 //if its raining, start the rain showers
588 if (IsItRaining())
589 {
590 //Raise the volume to where it was
591 guiRainLoop = PlayJA2Ambient(RAIN_1, MIDVOLUME, 0);
592 }
593
594 // release cursor
595 FreeMouseCursor();
596
597 // set the fact we are currently not in laptop, for rendering purposes
598 fCurrentlyInLaptop = FALSE;
599
600 //Deallocate, save data -- leaving laptop.
601 SetRenderFlags(RENDER_FLAG_FULL);
602
603 ExitLaptopMode(fExitDuringLoad ? guiPreviousLaptopMode : guiCurrentLaptopMode);
604
605 fExitDuringLoad = FALSE;
606 fLoadPendingFlag = FALSE;
607
608
609 DeleteVideoObject(guiLAPTOP);
610 DeleteVideoObject(guiLaptopBACKGROUND);
611 DeleteVideoObject(guiTITLEBARLAPTOP);
612 DeleteVideoObject(guiLIGHTS);
613 DeleteVideoObject(guiTITLEBARICONS);
614 DeleteVideoObject(guiEmailWarning);
615
616 // destroy region for new mail icon
617 CreateDestroyMouseRegionForNewMailIcon();
618
619 // get rid of desktop
620 DeleteDesktopBackground();
621
622 if (MailToDelete != NULL)
623 {
624 MailToDelete = NULL;
625 CreateDestroyDeleteNoticeMailButton();
626 }
627 if (fNewMailFlag)
628 {
629 fNewMailFlag = FALSE;
630 CreateDestroyNewMailButton();
631 }
632
633 // get rid of minize button
634 CreateDestroyMinimizeButtonForCurrentMode();
635
636 //MSYS_SetCurrentCursor(CURSOR_NORMAL);
637 gfEnterLapTop=TRUE;
638 DeleteLapTopButtons();
639 DeleteLapTopMouseRegions();
640 gfShowBookmarks = FALSE;
641 CreateDestoryBookMarkRegions();
642
643 fNewWWW = TRUE;
644 DeleteBookmark();
645 DeleteLoadPending();
646 fReDrawNewMailFlag = FALSE;
647
648 //pause the game because we dont want time to advance in the laptop
649 UnPauseGame();
650 }
651
652
RenderLapTopImage(void)653 static void RenderLapTopImage(void)
654 {
655 if (fMaximizingProgram || fMinizingProgram) return;
656
657 BltVideoObject(FRAME_BUFFER, guiLAPTOP, 0, LAPTOP_X, LAPTOP_Y);
658 BltVideoObject(FRAME_BUFFER, guiLaptopBACKGROUND, 1, LAPTOP_X + 25, LAPTOP_Y + 23);
659
660 MarkButtonsDirty();
661 }
662
663
RenderLaptop(void)664 static void RenderLaptop(void)
665 {
666 if (fMaximizingProgram || fMinizingProgram)
667 {
668 gfShowBookmarks = FALSE;
669 return;
670 }
671
672 LaptopMode uiTempMode = LAPTOP_MODE_NONE;
673 if (fLoadPendingFlag || fExitDuringLoad)
674 {
675 uiTempMode = guiCurrentLaptopMode;
676 guiCurrentLaptopMode = guiPreviousLaptopMode;
677 }
678
679 switch (guiCurrentLaptopMode)
680 {
681 case LAPTOP_MODE_NONE: DrawDeskTopBackground(); break;
682
683 case LAPTOP_MODE_AIM: RenderAIM(); break;
684 case LAPTOP_MODE_AIM_MEMBERS: RenderAIMMembers(); break;
685 case LAPTOP_MODE_AIM_MEMBERS_FACIAL_INDEX: RenderAimFacialIndex(); break;
686 case LAPTOP_MODE_AIM_MEMBERS_SORTED_FILES: RenderAimSort(); break;
687 case LAPTOP_MODE_AIM_MEMBERS_ARCHIVES: RenderAimArchives(); break;
688 case LAPTOP_MODE_AIM_POLICIES: RenderAimPolicies(); break;
689 case LAPTOP_MODE_AIM_LINKS: RenderAimLinks(); break;
690 case LAPTOP_MODE_AIM_HISTORY: RenderAimHistory(); break;
691
692 case LAPTOP_MODE_MERC: RenderMercs(); break;
693 case LAPTOP_MODE_MERC_FILES: RenderMercsFiles(); break;
694 case LAPTOP_MODE_MERC_ACCOUNT: RenderMercsAccount(); break;
695 case LAPTOP_MODE_MERC_NO_ACCOUNT: RenderMercsNoAccount(); break;
696
697 case LAPTOP_MODE_BOBBY_R: RenderBobbyR(); break;
698 case LAPTOP_MODE_BOBBY_R_GUNS: RenderBobbyRGuns(); break;
699 case LAPTOP_MODE_BOBBY_R_AMMO: RenderBobbyRAmmo(); break;
700 case LAPTOP_MODE_BOBBY_R_ARMOR: RenderBobbyRArmour(); break;
701 case LAPTOP_MODE_BOBBY_R_MISC: RenderBobbyRMisc(); break;
702 case LAPTOP_MODE_BOBBY_R_USED: RenderBobbyRUsed(); break;
703 case LAPTOP_MODE_BOBBY_R_MAILORDER: RenderBobbyRMailOrder(); break;
704 case LAPTOP_MODE_BOBBYR_SHIPMENTS: RenderBobbyRShipments(); break;
705
706 case LAPTOP_MODE_CHAR_PROFILE: RenderCharProfile(); break;
707
708 case LAPTOP_MODE_FLORIST: RenderFlorist(); break;
709 case LAPTOP_MODE_FLORIST_FLOWER_GALLERY: RenderFloristGallery(); break;
710 case LAPTOP_MODE_FLORIST_ORDERFORM: RenderFloristOrderForm(); break;
711 case LAPTOP_MODE_FLORIST_CARD_GALLERY: RenderFloristCards(); break;
712
713 case LAPTOP_MODE_INSURANCE: RenderInsurance(); break;
714 case LAPTOP_MODE_INSURANCE_INFO: RenderInsuranceInfo(); break;
715 case LAPTOP_MODE_INSURANCE_CONTRACT: RenderInsuranceContract(); break;
716 case LAPTOP_MODE_INSURANCE_COMMENTS: RenderInsuranceComments(); break;
717
718 case LAPTOP_MODE_FUNERAL: RenderFuneral(); break;
719
720 case LAPTOP_MODE_FINANCES: RenderFinances(); break;
721 case LAPTOP_MODE_PERSONNEL: RenderPersonnel(); break;
722 case LAPTOP_MODE_HISTORY: RenderHistory(); break;
723 case LAPTOP_MODE_FILES: RenderFiles(); break;
724 case LAPTOP_MODE_EMAIL: RenderEmail(); break;
725
726 case LAPTOP_MODE_WWW: DrawDeskTopBackground(); break;
727
728 case LAPTOP_MODE_BROKEN_LINK: RenderBrokenLink(); break;
729 default:
730 break;
731 }
732
733 if (guiCurrentLaptopMode >= LAPTOP_MODE_WWW)
734 {
735 // render program bar for www program
736 RenderWWWProgramTitleBar();
737 }
738
739 if (fLoadPendingFlag)
740 {
741 guiCurrentLaptopMode = uiTempMode;
742 return;
743 }
744
745 DisplayProgramBoundingBox(FALSE);
746
747 // mark the buttons dirty at this point
748 MarkButtonsDirty();
749 }
750
751
752 static void InitTitleBarMaximizeGraphics(const SGPVObject* uiBackgroundGraphic, const ST::string& str, const SGPVObject* uiIconGraphic, UINT16 usIconGraphicIndex);
753 static void SetSubSiteAsVisted(void);
754
755
EnterNewLaptopMode(void)756 static void EnterNewLaptopMode(void)
757 {
758 static BOOLEAN fOldLoadFlag = FALSE;
759
760 if (fExitingLaptopFlag) return;
761 // cause flicker, as we are going to a new program/WEB page
762 fFlickerHD = TRUE;
763
764 // handle maximizing of programs
765 UINT prog;
766 ST::string title;
767 UINT16 gfx_idx;
768 switch (guiCurrentLaptopMode)
769 {
770 case LAPTOP_MODE_EMAIL:
771 prog = LAPTOP_PROGRAM_MAILER;
772 title = pLaptopTitles[0];
773 gfx_idx = 0;
774 break;
775
776 case LAPTOP_MODE_FILES:
777 prog = LAPTOP_PROGRAM_FILES;
778 title = pLaptopTitles[1];
779 gfx_idx = 2;
780 break;
781
782 case LAPTOP_MODE_PERSONNEL:
783 prog = LAPTOP_PROGRAM_PERSONNEL;
784 title = pLaptopTitles[2];
785 gfx_idx = 3;
786 break;
787
788 case LAPTOP_MODE_FINANCES:
789 prog = LAPTOP_PROGRAM_FINANCES;
790 title = pLaptopTitles[3];
791 gfx_idx = 5;
792 break;
793
794 case LAPTOP_MODE_HISTORY:
795 prog = LAPTOP_PROGRAM_HISTORY;
796 title = pLaptopTitles[4];
797 gfx_idx = 4;
798 break;
799
800 case LAPTOP_MODE_NONE: goto do_nothing;
801
802 default:
803 prog = LAPTOP_PROGRAM_WEB_BROWSER;
804 title = pWebTitle;
805 gfx_idx = 1;
806 break;
807 }
808
809 if (gLaptopProgramStates[prog] == LAPTOP_PROGRAM_MINIMIZED)
810 {
811 if (!fMaximizingProgram)
812 {
813 fInitTitle = TRUE;
814 InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, title, guiTITLEBARICONS, gfx_idx);
815 ExitLaptopMode(guiPreviousLaptopMode);
816 }
817 fMaximizingProgram = TRUE;
818 bProgramBeingMaximized = prog;
819 gLaptopProgramStates[prog] = LAPTOP_PROGRAM_OPEN;
820 return;
821 }
822
823 do_nothing:
824 if (fMaximizingProgram || fMinizingProgram) return;
825
826 if (fOldLoadFlag && !fLoadPendingFlag)
827 {
828 fOldLoadFlag = FALSE;
829 }
830 else if (fLoadPendingFlag && !fOldLoadFlag)
831 {
832 ExitLaptopMode(guiPreviousLaptopMode);
833 fOldLoadFlag = TRUE;
834 return;
835 }
836 else if (fOldLoadFlag && fLoadPendingFlag)
837 {
838 return;
839 }
840 else
841 {
842 // do not exit previous mode if coming from sliding bar handler
843 if (!fEnteredNewLapTopDueToHandleSlidingBars)
844 {
845 ExitLaptopMode(guiPreviousLaptopMode);
846 }
847 }
848
849 if (guiCurrentWWWMode == LAPTOP_MODE_NONE && guiCurrentLaptopMode >= LAPTOP_MODE_WWW)
850 {
851 RenderLapTopImage();
852 guiCurrentLaptopMode = LAPTOP_MODE_WWW;
853 }
854 else if (guiCurrentLaptopMode > LAPTOP_MODE_WWW)
855 {
856 if (guiPreviousLaptopMode < LAPTOP_MODE_WWW)
857 {
858 guiCurrentLaptopMode = guiCurrentWWWMode;
859 }
860 else
861 {
862 guiCurrentWWWMode = guiCurrentLaptopMode;
863 giCurrentSubPage = 0;
864 }
865 }
866
867 if (guiCurrentLaptopMode >= LAPTOP_MODE_WWW)
868 {
869 RenderWWWProgramTitleBar();
870 if (guiPreviousLaptopMode >= LAPTOP_MODE_WWW) gfShowBookmarks = FALSE;
871 }
872
873 guiLastExitedLaptopMode = LAPTOP_MODE_NONE;
874
875 //Initialize the new mode.
876 switch (guiCurrentLaptopMode)
877 {
878 case LAPTOP_MODE_AIM: EnterAIM(); break;
879 case LAPTOP_MODE_AIM_MEMBERS: EnterAIMMembers(); break;
880 case LAPTOP_MODE_AIM_MEMBERS_FACIAL_INDEX: EnterAimFacialIndex(); break;
881 case LAPTOP_MODE_AIM_MEMBERS_SORTED_FILES: EnterAimSort(); break;
882 case LAPTOP_MODE_AIM_MEMBERS_ARCHIVES: EnterAimArchives(); break;
883 case LAPTOP_MODE_AIM_POLICIES: EnterAimPolicies(); break;
884 case LAPTOP_MODE_AIM_LINKS: EnterAimLinks(); break;
885 case LAPTOP_MODE_AIM_HISTORY: EnterAimHistory(); break;
886
887 case LAPTOP_MODE_MERC: EnterMercs(); break;
888 case LAPTOP_MODE_MERC_FILES: EnterMercsFiles(); break;
889 case LAPTOP_MODE_MERC_ACCOUNT: EnterMercsAccount(); break;
890 case LAPTOP_MODE_MERC_NO_ACCOUNT: EnterMercsNoAccount(); break;
891
892 case LAPTOP_MODE_BOBBY_R: EnterBobbyR(); break;
893 case LAPTOP_MODE_BOBBY_R_GUNS: EnterBobbyRGuns(); break;
894 case LAPTOP_MODE_BOBBY_R_AMMO: EnterBobbyRAmmo(); break;
895 case LAPTOP_MODE_BOBBY_R_ARMOR: EnterBobbyRArmour(); break;
896 case LAPTOP_MODE_BOBBY_R_MISC: EnterBobbyRMisc(); break;
897 case LAPTOP_MODE_BOBBY_R_USED: EnterBobbyRUsed(); break;
898 case LAPTOP_MODE_BOBBY_R_MAILORDER: EnterBobbyRMailOrder(); break;
899 case LAPTOP_MODE_BOBBYR_SHIPMENTS: EnterBobbyRShipments(); break;
900
901 case LAPTOP_MODE_CHAR_PROFILE: EnterCharProfile(); break;
902
903 case LAPTOP_MODE_FLORIST: EnterFlorist(); break;
904 case LAPTOP_MODE_FLORIST_FLOWER_GALLERY: EnterFloristGallery(); break;
905 case LAPTOP_MODE_FLORIST_ORDERFORM: EnterFloristOrderForm(); break;
906 case LAPTOP_MODE_FLORIST_CARD_GALLERY: EnterFloristCards(); break;
907
908 case LAPTOP_MODE_INSURANCE: EnterInsurance(); break;
909 case LAPTOP_MODE_INSURANCE_INFO: EnterInsuranceInfo(); break;
910 case LAPTOP_MODE_INSURANCE_CONTRACT: EnterInsuranceContract(); break;
911 case LAPTOP_MODE_INSURANCE_COMMENTS: EnterInsuranceComments(); break;
912
913 case LAPTOP_MODE_FUNERAL: EnterFuneral(); break;
914
915 case LAPTOP_MODE_FINANCES: EnterFinances(); break;
916 case LAPTOP_MODE_PERSONNEL: EnterPersonnel(); break;
917 case LAPTOP_MODE_HISTORY: EnterHistory(); break;
918 case LAPTOP_MODE_FILES: EnterFiles(); break;
919 case LAPTOP_MODE_EMAIL: EnterEmail(); break;
920
921 case LAPTOP_MODE_BROKEN_LINK: EnterBrokenLink(); break;
922 default:
923 break;
924 }
925
926 // first time using webbrowser in this laptop session
927 if (fFirstTimeInLaptop && guiCurrentLaptopMode >= LAPTOP_MODE_WWW)
928 {
929 gfShowBookmarks = TRUE;
930 fFirstTimeInLaptop = FALSE;
931 }
932
933 if (!fLoadPendingFlag)
934 {
935 CreateDestroyMinimizeButtonForCurrentMode();
936 guiPreviousLaptopMode = guiCurrentLaptopMode;
937 SetSubSiteAsVisted();
938 }
939
940 DisplayProgramBoundingBox(TRUE);
941 }
942
943
HandleLapTopHandles(void)944 static void HandleLapTopHandles(void)
945 {
946 if (fLoadPendingFlag) return;
947
948 if (fMaximizingProgram || fMinizingProgram) return;
949
950 switch (guiCurrentLaptopMode)
951 {
952 case LAPTOP_MODE_AIM: HandleAIM(); break;
953 case LAPTOP_MODE_AIM_MEMBERS: HandleAIMMembers(); break;
954 case LAPTOP_MODE_AIM_MEMBERS_ARCHIVES: HandleAimArchives(); break;
955 case LAPTOP_MODE_AIM_POLICIES: HandleAimPolicies(); break;
956
957 case LAPTOP_MODE_MERC: HandleMercs(); break;
958 case LAPTOP_MODE_MERC_ACCOUNT: HandleMercsAccount(); break;
959
960 case LAPTOP_MODE_BOBBY_R: HandleBobbyR(); break;
961 case LAPTOP_MODE_BOBBY_R_MAILORDER: HandleBobbyRMailOrder(); break;
962 case LAPTOP_MODE_BOBBYR_SHIPMENTS: HandleBobbyRShipments(); break;
963
964 case LAPTOP_MODE_CHAR_PROFILE: HandleCharProfile(); break;
965
966 case LAPTOP_MODE_FLORIST_FLOWER_GALLERY: HandleFloristGallery(); break;
967 case LAPTOP_MODE_FLORIST_ORDERFORM: HandleFloristOrderForm(); break;
968
969 case LAPTOP_MODE_INSURANCE_CONTRACT: HandleInsuranceContract(); break;
970
971 case LAPTOP_MODE_PERSONNEL: HandlePersonnel(); break;
972 case LAPTOP_MODE_FILES: HandleFiles(); break;
973 case LAPTOP_MODE_EMAIL: HandleEmail(); break;
974 default:
975 break;
976 }
977 }
978
979
980 static void CheckIfNewWWWW(void);
981 static void CheckMarkButtonsDirtyFlag(void);
982 static void CreateLaptopButtons(void);
983 static void DisplayBookMarks(void);
984 static void DisplayLoadPending(void);
985 static void DisplayTaskBarIcons(void);
986 static void DisplayWebBookMarkNotify(void);
987 static void FlickerHDLight(void);
988 static void HandleSlidingTitleBar(void);
989 static void HandleWWWSubSites(void);
990 static void LeaveLapTopScreen(void);
991 static void PostButtonRendering(void);
992 static void ShouldNewMailBeDisplayed(void);
993 static void ShowLights(void);
994 static void UpdateStatusOfDisplayingBookMarks(void);
995
996
LaptopScreenHandle()997 ScreenID LaptopScreenHandle()
998 {
999 //User just changed modes. This is determined by the button callbacks
1000 //created in LaptopScreenInit()
1001
1002 // just entered
1003 if (gfEnterLapTop)
1004 {
1005 EnterLaptop();
1006 CreateLaptopButtons();
1007 gfEnterLapTop = FALSE;
1008 }
1009
1010 if (gfStartMapScreenToLaptopTransition)
1011 { //Everything is set up to start the transition animation.
1012 SetCurrentCursorFromDatabase(VIDEO_NO_CURSOR);
1013 //Step 1: Build the laptop image into the save buffer.
1014 gfStartMapScreenToLaptopTransition = FALSE;
1015 RestoreBackgroundRects();
1016 RenderLapTopImage();
1017 RenderLaptop();
1018 RenderButtons();
1019 PrintDate();
1020 PrintBalance();
1021 PrintNumberOnTeam();
1022 ShowLights();
1023
1024 //Step 2: The mapscreen image is in the EXTRABUFFER, and laptop is in the SAVEBUFFER
1025 // Start transitioning the screen.
1026 SGPBox const DstRect = { STD_SCREEN_X, STD_SCREEN_Y, MAP_SCREEN_WIDTH, MAP_SCREEN_HEIGHT };
1027 const UINT32 uiTimeRange = 1000;
1028 INT32 iPercentage = 0;
1029 INT32 iRealPercentage = 0;
1030 const UINT32 uiStartTime = GetClock();
1031 BltVideoSurface(guiSAVEBUFFER, FRAME_BUFFER, 0, 0, NULL);
1032 BltVideoSurface(FRAME_BUFFER, guiEXTRABUFFER, 0, 0, NULL);
1033 PlayJA2SampleFromFile(SOUNDSDIR "/laptop power up (8-11).wav", HIGHVOLUME, 1, MIDDLEPAN);
1034 while (iRealPercentage < 100)
1035 {
1036 const UINT32 uiCurrTime = GetClock();
1037 iPercentage = (uiCurrTime-uiStartTime) * 100 / uiTimeRange;
1038 iPercentage = MIN(iPercentage, 100);
1039
1040 iRealPercentage = iPercentage;
1041
1042 //Factor the percentage so that it is modified by a gravity falling acceleration effect.
1043 const INT32 iFactor = (iPercentage - 50) * 2;
1044 if (iPercentage < 50)
1045 {
1046 iPercentage += iPercentage * iFactor * 0.01 + 0.5;
1047 }
1048 else
1049 {
1050 iPercentage += (100 - iPercentage) * iFactor * 0.01 + 0.5;
1051 }
1052
1053 INT32 iScalePercentage;
1054 if (iPercentage < 99)
1055 {
1056 iScalePercentage = 10000 / (100 - iPercentage);
1057 }
1058 else
1059 {
1060 iScalePercentage = 5333;
1061 }
1062 const UINT16 uWidth = 12 * iScalePercentage / 100;
1063 const UINT16 uHeight = 9 * iScalePercentage / 100;
1064 const UINT16 uX = 472 - (472 - 320) * iScalePercentage / 5333;
1065 const UINT16 uY = 424 - (424 - 240) * iScalePercentage / 5333;
1066
1067 SGPBox const SrcRect2 = { (UINT16)(STD_SCREEN_X + uX - uWidth / 2), (UINT16)(STD_SCREEN_Y + uY - uHeight / 2), uWidth, uHeight };
1068
1069 BltStretchVideoSurface(FRAME_BUFFER, guiSAVEBUFFER, &DstRect, &SrcRect2);
1070 InvalidateScreen();
1071 RefreshScreen();
1072 }
1073 fReDrawScreenFlag = TRUE;
1074 }
1075
1076 //DO NOT MOVE THIS FUNCTION CALL!!!
1077
1078 //This determines if the help screen should be active
1079 if (ShouldTheHelpScreenComeUp(HELP_SCREEN_LAPTOP, FALSE))
1080 {
1081 // handle the help screen
1082 HelpScreenHandler();
1083 return LAPTOP_SCREEN;
1084 }
1085
1086 RestoreBackgroundRects();
1087
1088 // lock cursor to screen
1089 RestrictMouseCursor(&LaptopScreenRect);
1090
1091 // handle animated cursors
1092 HandleAnimatedCursors();
1093 // Deque all game events
1094 DequeAllGameEvents();
1095
1096 // handle sub sites..like BR Guns, BR Ammo, Armour, Misc...for WW Wait..since they are not true sub pages
1097 // and are not individual sites
1098 HandleWWWSubSites();
1099 UpdateStatusOfDisplayingBookMarks();
1100
1101 // check if we need to reset new WWW mode
1102 CheckIfNewWWWW();
1103
1104 if (guiCurrentLaptopMode != guiPreviousLaptopMode)
1105 {
1106 if (guiCurrentLaptopMode <=LAPTOP_MODE_WWW) fLoadPendingFlag = FALSE;
1107
1108 if (!fMaximizingProgram && !fMinizingProgram)
1109 {
1110 if (guiCurrentLaptopMode <= LAPTOP_MODE_WWW)
1111 {
1112 EnterNewLaptopMode();
1113 if (!fMaximizingProgram && !fMinizingProgram)
1114 {
1115 guiPreviousLaptopMode = guiCurrentLaptopMode;
1116 }
1117 }
1118 else
1119 {
1120 if (!fLoadPendingFlag)
1121 {
1122 EnterNewLaptopMode();
1123 guiPreviousLaptopMode = guiCurrentLaptopMode;
1124 }
1125 }
1126 }
1127 }
1128 if (fPausedReDrawScreenFlag)
1129 {
1130 fReDrawScreenFlag = TRUE;
1131 fPausedReDrawScreenFlag = FALSE;
1132 }
1133
1134 if (fReDrawScreenFlag)
1135 {
1136 RenderLapTopImage();
1137 RenderLaptop();
1138 }
1139
1140 // are we about to leave laptop
1141 if (fExitingLaptopFlag)
1142 {
1143 if (fLoadPendingFlag)
1144 {
1145 fLoadPendingFlag = FALSE;
1146 fExitDuringLoad = TRUE;
1147 }
1148 LeaveLapTopScreen();
1149 }
1150
1151 if (!fExitingLaptopFlag)
1152 {
1153 // handle handles for laptop input stream
1154 HandleLapTopHandles();
1155 }
1156
1157 // get keyboard input, handle it
1158 GetLaptopKeyboardInput();
1159
1160 // check to see if new mail box needs to be displayed
1161 CreateDestroyNewMailButton();
1162 DisplayNewMailBox();
1163
1164 // create various mouse regions that are global to laptop system
1165 CreateDestoryBookMarkRegions();
1166
1167 // check to see if buttons marked dirty
1168 CheckMarkButtonsDirtyFlag();
1169
1170 // check to see if new mail box needs to be displayed
1171 ShouldNewMailBeDisplayed();
1172
1173 // check to see if new mail box needs to be displayed
1174 ReDrawNewMailBox();
1175
1176 // look for unread email
1177 LookForUnread();
1178 //Handle keyboard shortcuts...
1179
1180 if (!fLoadPendingFlag || fNewMailFlag)
1181 {
1182 // render buttons marked dirty
1183 RenderButtons();
1184 }
1185
1186 // check to see if bookmarks need to be displayed
1187 if (gfShowBookmarks)
1188 {
1189 if (fExitingLaptopFlag)
1190 {
1191 gfShowBookmarks = FALSE;
1192 }
1193 else
1194 {
1195 DisplayBookMarks();
1196 }
1197 }
1198
1199 // check to see if laod pending flag is set
1200 DisplayLoadPending();
1201
1202 // check if we are showing message?
1203 DisplayWebBookMarkNotify();
1204
1205 if (fReDrawPostButtonRender)
1206 {
1207 // rendering AFTER buttons and button text
1208 if (!fMaximizingProgram && !fMinizingProgram)
1209 {
1210 PostButtonRendering();
1211 }
1212 }
1213
1214 PrintDate();
1215 PrintBalance();
1216 PrintNumberOnTeam();
1217 DisplayTaskBarIcons();
1218
1219 // handle if we are maximizing a program from a minimized state or vice versa
1220 HandleSlidingTitleBar();
1221
1222 // flicker HD light as nessacary
1223 FlickerHDLight();
1224
1225 // display power and HD lights
1226 ShowLights();
1227
1228 // render frame rate
1229 DisplayFrameRate();
1230
1231 // invalidate screen if redrawn
1232 if (fReDrawScreenFlag)
1233 {
1234 InvalidateScreen();
1235 fReDrawScreenFlag = FALSE;
1236 }
1237
1238 ExecuteVideoOverlays();
1239
1240 SaveBackgroundRects();
1241 RenderFastHelp();
1242
1243 // ex SAVEBUFFER queue
1244 ExecuteBaseDirtyRectQueue();
1245 ResetInterface();
1246 EndFrameBufferRender();
1247 return (LAPTOP_SCREEN);
1248 }
1249
1250
ExitLaptopMode(LaptopMode uiMode)1251 static void ExitLaptopMode(LaptopMode uiMode)
1252 {
1253 if (guiLastExitedLaptopMode == uiMode) {
1254 return;
1255 }
1256
1257 // Deallocate the previous mode that you were in.
1258 switch (uiMode)
1259 {
1260 case LAPTOP_MODE_AIM: ExitAIM(); break;
1261 case LAPTOP_MODE_AIM_MEMBERS: ExitAIMMembers(); break;
1262 case LAPTOP_MODE_AIM_MEMBERS_FACIAL_INDEX: ExitAimFacialIndex(); break;
1263 case LAPTOP_MODE_AIM_MEMBERS_SORTED_FILES: ExitAimSort(); break;
1264 case LAPTOP_MODE_AIM_MEMBERS_ARCHIVES: ExitAimArchives(); break;
1265 case LAPTOP_MODE_AIM_POLICIES: ExitAimPolicies(); break;
1266 case LAPTOP_MODE_AIM_LINKS: ExitAimLinks(); break;
1267 case LAPTOP_MODE_AIM_HISTORY: ExitAimHistory(); break;
1268
1269 case LAPTOP_MODE_MERC: ExitMercs(); break;
1270 case LAPTOP_MODE_MERC_FILES: ExitMercsFiles(); break;
1271 case LAPTOP_MODE_MERC_ACCOUNT: ExitMercsAccount(); break;
1272 case LAPTOP_MODE_MERC_NO_ACCOUNT: ExitMercsNoAccount(); break;
1273
1274 case LAPTOP_MODE_BOBBY_R: ExitBobbyR(); break;
1275 case LAPTOP_MODE_BOBBY_R_GUNS: ExitBobbyRGuns(); break;
1276 case LAPTOP_MODE_BOBBY_R_AMMO: ExitBobbyRAmmo(); break;
1277 case LAPTOP_MODE_BOBBY_R_ARMOR: ExitBobbyRArmour(); break;
1278 case LAPTOP_MODE_BOBBY_R_MISC: ExitBobbyRMisc(); break;
1279 case LAPTOP_MODE_BOBBY_R_USED: ExitBobbyRUsed(); break;
1280 case LAPTOP_MODE_BOBBY_R_MAILORDER: ExitBobbyRMailOrder(); break;
1281 case LAPTOP_MODE_BOBBYR_SHIPMENTS: ExitBobbyRShipments(); break;
1282
1283 case LAPTOP_MODE_CHAR_PROFILE: ExitCharProfile(); break;
1284
1285 case LAPTOP_MODE_FLORIST: ExitFlorist(); break;
1286 case LAPTOP_MODE_FLORIST_FLOWER_GALLERY: ExitFloristGallery(); break;
1287 case LAPTOP_MODE_FLORIST_ORDERFORM: ExitFloristOrderForm(); break;
1288 case LAPTOP_MODE_FLORIST_CARD_GALLERY: ExitFloristCards(); break;
1289
1290 case LAPTOP_MODE_INSURANCE: ExitInsurance(); break;
1291 case LAPTOP_MODE_INSURANCE_INFO: ExitInsuranceInfo(); break;
1292 case LAPTOP_MODE_INSURANCE_CONTRACT: ExitInsuranceContract(); break;
1293 case LAPTOP_MODE_INSURANCE_COMMENTS: ExitInsuranceComments(); break;
1294
1295 case LAPTOP_MODE_FUNERAL: ExitFuneral(); break;
1296
1297 case LAPTOP_MODE_FINANCES: ExitFinances(); break;
1298 case LAPTOP_MODE_PERSONNEL: ExitPersonnel(); break;
1299 case LAPTOP_MODE_HISTORY: ExitHistory(); break;
1300 case LAPTOP_MODE_FILES: ExitFiles(); break;
1301 case LAPTOP_MODE_EMAIL: ExitEmail(); break;
1302 case LAPTOP_MODE_BROKEN_LINK: ExitBrokenLink(); break;
1303
1304 // nothing to do for other subwindows
1305 default: break;
1306 }
1307
1308 if (uiMode != LAPTOP_MODE_NONE && uiMode < LAPTOP_MODE_WWW)
1309 {
1310 CreateDestroyMinimizeButtonForCurrentMode();
1311 }
1312
1313 guiLastExitedLaptopMode = uiMode;
1314 }
1315
1316
MakeButton(UINT idx,INT16 y,GUI_CALLBACK click,INT8 off_x,const ST::string & text,const ST::string & help_text)1317 static void MakeButton(UINT idx, INT16 y, GUI_CALLBACK click, INT8 off_x, const ST::string& text, const ST::string& help_text)
1318 {
1319 GUIButtonRef const btn = QuickCreateButtonImg(LAPTOPDIR "/buttonsforlaptop.sti", idx, idx + 8, (29 + STD_SCREEN_X), (y + STD_SCREEN_Y), MSYS_PRIORITY_HIGH, click);
1320 gLaptopButton[idx] = btn;
1321 btn->SetFastHelpText(help_text);
1322 btn->SpecifyTextOffsets(off_x, 11, TRUE);
1323 btn->SpecifyGeneralTextAttributes(text, FONT10ARIAL, 2, 0);
1324 btn->SetCursor(CURSOR_LAPTOP_SCREEN);
1325 }
1326
1327
1328 static void BtnOnCallback( GUI_BUTTON* btn, INT32 reason);
1329 static void EmailRegionButtonCallback( GUI_BUTTON* btn, INT32 reason);
1330 static void FilesRegionButtonCallback( GUI_BUTTON* btn, INT32 reason);
1331 static void FinancialRegionButtonCallback(GUI_BUTTON* btn, INT32 reason);
1332 static void HistoryRegionButtonCallback( GUI_BUTTON* btn, INT32 reason);
1333 static void PersonnelRegionButtonCallback(GUI_BUTTON* btn, INT32 reason);
1334 static void WWWRegionButtonCallback( GUI_BUTTON* btn, INT32 reason);
1335
1336
CreateLaptopButtons(void)1337 static void CreateLaptopButtons(void)
1338 {
1339 MakeButton(0, 66, EmailRegionButtonCallback, 30, pLaptopIcons[0], gzLaptopHelpText[LAPTOP_BN_HLP_TXT_VIEW_EMAIL]);
1340 MakeButton(1, 98, WWWRegionButtonCallback, 30, pLaptopIcons[1], gzLaptopHelpText[LAPTOP_BN_HLP_TXT_BROWSE_VARIOUS_WEB_SITES]);
1341 MakeButton(2, 130, FilesRegionButtonCallback, 30, pLaptopIcons[5], gzLaptopHelpText[LAPTOP_BN_HLP_TXT_VIEW_FILES_AND_EMAIL_ATTACHMENTS]);
1342 MakeButton(3, 194, PersonnelRegionButtonCallback, 30, pLaptopIcons[3], gzLaptopHelpText[LAPTOP_BN_HLP_TXT_VIEW_TEAM_INFO]);
1343 MakeButton(4, 162, HistoryRegionButtonCallback, 30, pLaptopIcons[4], gzLaptopHelpText[LAPTOP_BN_HLP_TXT_READ_LOG_OF_EVENTS]);
1344 MakeButton(5, 241, FinancialRegionButtonCallback, 30, pLaptopIcons[2], gzLaptopHelpText[LAPTOP_BN_HLP_TXT_VIEW_FINANCIAL_SUMMARY_AND_HISTORY]);
1345 MakeButton(6, 378, BtnOnCallback, 25, pLaptopIcons[6], gzLaptopHelpText[LAPTOP_BN_HLP_TXT_CLOSE_LAPTOP]);
1346 }
1347
1348
DeleteLapTopButtons(void)1349 static void DeleteLapTopButtons(void)
1350 {
1351 for (UINT32 i = 0; i < 7; ++i) RemoveButton(gLaptopButton[i]);
1352 }
1353
1354
1355 static BOOLEAN HandleExit(void);
1356
1357
BtnOnCallback(GUI_BUTTON * btn,INT32 reason)1358 static void BtnOnCallback(GUI_BUTTON *btn, INT32 reason)
1359 {
1360 if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
1361 {
1362 if (HandleExit()) fExitingLaptopFlag = TRUE;
1363 }
1364 }
1365
1366
1367 static BOOLEAN ExitLaptopDone(void);
1368
1369
LeaveLapTopScreen(void)1370 static void LeaveLapTopScreen(void)
1371 {
1372 if (ExitLaptopDone())
1373 {
1374 SetLaptopExitScreen(MAP_SCREEN);
1375
1376 if (gfAtLeastOneMercWasHired)
1377 {
1378 if (LaptopSaveInfo.gfNewGameLaptop)
1379 {
1380 LaptopSaveInfo.gfNewGameLaptop = FALSE;
1381 fExitingLaptopFlag = TRUE;
1382 InitNewGame();
1383 gfDontStartTransitionFromLaptop = TRUE;
1384 return;
1385 }
1386 }
1387 else
1388 {
1389 gfDontStartTransitionFromLaptop = TRUE;
1390 }
1391
1392 SetPendingNewScreen(guiExitScreen);
1393
1394 if (!gfDontStartTransitionFromLaptop)
1395 {
1396 gfDontStartTransitionFromLaptop = TRUE;
1397 SetCurrentCursorFromDatabase(VIDEO_NO_CURSOR);
1398 //Step 1: Build the laptop image into the save buffer.
1399 RestoreBackgroundRects();
1400 RenderLapTopImage();
1401 RenderLaptop();
1402 RenderButtons();
1403 PrintDate();
1404 PrintBalance();
1405 PrintNumberOnTeam();
1406 ShowLights();
1407
1408 //Step 2: The mapscreen image is in the EXTRABUFFER, and laptop is in the SAVEBUFFER
1409 // Start transitioning the screen.
1410 SGPBox const SrcRect = { STD_SCREEN_X, STD_SCREEN_Y, MAP_SCREEN_WIDTH, MAP_SCREEN_HEIGHT };
1411 const UINT32 uiTimeRange = 1000;
1412 INT32 iPercentage = 100;
1413 INT32 iRealPercentage = 100;
1414 const UINT32 uiStartTime = GetClock();
1415 BltVideoSurface(guiSAVEBUFFER, FRAME_BUFFER, 0, 0, NULL);
1416 PlayJA2SampleFromFile(SOUNDSDIR "/laptop power down (8-11).wav", HIGHVOLUME, 1, MIDDLEPAN);
1417 while (iRealPercentage > 0)
1418 {
1419 BltVideoSurface(FRAME_BUFFER, guiEXTRABUFFER, 0, 0, NULL);
1420
1421 const UINT32 uiCurrTime = GetClock();
1422 iPercentage = (uiCurrTime-uiStartTime) * 100 / uiTimeRange;
1423 iPercentage = MIN(iPercentage, 100);
1424 iPercentage = 100 - iPercentage;
1425
1426 iRealPercentage = iPercentage;
1427
1428 //Factor the percentage so that it is modified by a gravity falling acceleration effect.
1429 const INT32 iFactor = (iPercentage - 50) * 2;
1430 if (iPercentage < 50)
1431 {
1432 iPercentage += iPercentage * iFactor * 0.01 + 0.5;
1433 }
1434 else
1435 {
1436 iPercentage += (100-iPercentage) * iFactor * 0.01 + 0.5;
1437 }
1438
1439 //Scaled laptop
1440 INT32 iScalePercentage;
1441 if (iPercentage < 99)
1442 {
1443 iScalePercentage = 10000 / (100-iPercentage);
1444 }
1445 else
1446 {
1447 iScalePercentage = 5333;
1448 }
1449 const UINT16 uWidth = 12 * iScalePercentage / 100;
1450 const UINT16 uHeight = 9 * iScalePercentage / 100;
1451 const UINT16 uX = 472 - (472 - 320) * iScalePercentage / 5333;
1452 const UINT16 uY = 424 - (424 - 240) * iScalePercentage / 5333;
1453
1454 SGPBox const DstRect = { (UINT16)(STD_SCREEN_X + uX - uWidth / 2), (UINT16)(STD_SCREEN_Y + uY - uHeight / 2), uWidth, uHeight };
1455
1456 BltStretchVideoSurface(FRAME_BUFFER, guiSAVEBUFFER, &SrcRect, &DstRect);
1457 InvalidateScreen();
1458 RefreshScreen();
1459 }
1460 }
1461 }
1462 }
1463
1464
HandleExit(void)1465 static BOOLEAN HandleExit(void)
1466 {
1467 // new game, send email
1468 if (LaptopSaveInfo.gfNewGameLaptop)
1469 {
1470 // Set an event to send this email (day 2 8:00-12:00)
1471 if (!LaptopSaveInfo.fIMPCompletedFlag && !LaptopSaveInfo.fSentImpWarningAlready)
1472 {
1473 AddFutureDayStrategicEvent(EVENT_HAVENT_MADE_IMP_CHARACTER_EMAIL, (8 + Random(4)) * 60, 0, 1);
1474 fExitingLaptopFlag = TRUE;
1475 return FALSE;
1476 }
1477 }
1478
1479 return TRUE;
1480 }
1481
HaventMadeImpMercEmailCallBack()1482 void HaventMadeImpMercEmailCallBack()
1483 {
1484 //if the player STILL hasnt made an imp merc yet
1485 if (!LaptopSaveInfo.fIMPCompletedFlag && !LaptopSaveInfo.fSentImpWarningAlready)
1486 {
1487 LaptopSaveInfo.fSentImpWarningAlready = TRUE;
1488 AddEmail(IMP_EMAIL_AGAIN,IMP_EMAIL_AGAIN_LENGTH, 1, GetWorldTotalMin());
1489 }
1490 }
1491
1492
CreateLapTopMouseRegions(void)1493 static void CreateLapTopMouseRegions(void)
1494 {
1495 // the entire laptop display region
1496 MSYS_DefineRegion(&gLapTopScreenRegion, LaptopScreenRect.iLeft, LaptopScreenRect.iTop, LaptopScreenRect.iRight, LaptopScreenRect.iBottom, MSYS_PRIORITY_NORMAL + 1, CURSOR_LAPTOP_SCREEN, MSYS_NO_CALLBACK, LapTopScreenCallBack);
1497 }
1498
1499
DeleteLapTopMouseRegions(void)1500 static void DeleteLapTopMouseRegions(void)
1501 {
1502 MSYS_RemoveRegion(&gLapTopScreenRegion);
1503 }
1504
1505
1506 static void UpdateListToReflectNewProgramOpened(INT32 iOpenedProgram);
1507
1508
FinancialRegionButtonCallback(GUI_BUTTON * btn,INT32 reason)1509 static void FinancialRegionButtonCallback(GUI_BUTTON* btn, INT32 reason)
1510 {
1511 if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
1512 {
1513 if (gfShowBookmarks)
1514 {
1515 gfShowBookmarks = FALSE;
1516 fReDrawScreenFlag = TRUE;
1517 }
1518 guiCurrentLaptopMode = LAPTOP_MODE_FINANCES;
1519
1520 UpdateListToReflectNewProgramOpened(LAPTOP_PROGRAM_FINANCES);
1521 }
1522 }
1523
1524
PersonnelRegionButtonCallback(GUI_BUTTON * btn,INT32 reason)1525 static void PersonnelRegionButtonCallback(GUI_BUTTON *btn, INT32 reason)
1526 {
1527 if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
1528 {
1529 guiCurrentLaptopMode = LAPTOP_MODE_PERSONNEL;
1530 if (gfShowBookmarks)
1531 {
1532 gfShowBookmarks = FALSE;
1533 fReDrawScreenFlag = TRUE;
1534 }
1535 gfShowBookmarks = FALSE;
1536
1537 UpdateListToReflectNewProgramOpened(LAPTOP_PROGRAM_PERSONNEL);
1538 }
1539 }
1540
1541
EmailRegionButtonCallback(GUI_BUTTON * btn,INT32 reason)1542 static void EmailRegionButtonCallback(GUI_BUTTON *btn, INT32 reason)
1543 {
1544 if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
1545 {
1546 guiCurrentLaptopMode = LAPTOP_MODE_EMAIL;
1547 gfShowBookmarks = FALSE;
1548 UpdateListToReflectNewProgramOpened(LAPTOP_PROGRAM_MAILER);
1549 fReDrawScreenFlag = TRUE;
1550 }
1551 }
1552
1553
WWWRegionButtonCallback(GUI_BUTTON * btn,INT32 reason)1554 static void WWWRegionButtonCallback(GUI_BUTTON *btn, INT32 reason)
1555 {
1556 if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
1557 {
1558 // reset show bookmarks
1559 if (guiCurrentLaptopMode < LAPTOP_MODE_WWW)
1560 {
1561 gfShowBookmarks = FALSE;
1562 fShowBookmarkInfo = TRUE;
1563 }
1564 else
1565 {
1566 gfShowBookmarks = !gfShowBookmarks;
1567 }
1568
1569 if (fNewWWW)
1570 {
1571 // no longer a new WWW mode
1572 fNewWWW = FALSE;
1573
1574 // make sure program is maximized
1575 if (gLaptopProgramStates[LAPTOP_PROGRAM_WEB_BROWSER] == LAPTOP_PROGRAM_OPEN)
1576 {
1577 RenderLapTopImage();
1578 DrawDeskTopBackground();
1579 }
1580 }
1581
1582 guiCurrentLaptopMode = (guiCurrentWWWMode == LAPTOP_MODE_NONE ? LAPTOP_MODE_WWW : guiCurrentWWWMode);
1583
1584 UpdateListToReflectNewProgramOpened(LAPTOP_PROGRAM_WEB_BROWSER);
1585 fReDrawScreenFlag = TRUE;
1586 }
1587 else if (reason & MSYS_CALLBACK_REASON_RBUTTON_UP)
1588 {
1589 guiCurrentLaptopMode = (guiCurrentWWWMode == LAPTOP_MODE_NONE ? LAPTOP_MODE_WWW : guiCurrentWWWMode);
1590 fReDrawScreenFlag = TRUE;
1591 }
1592 }
1593
1594
HistoryRegionButtonCallback(GUI_BUTTON * btn,INT32 reason)1595 static void HistoryRegionButtonCallback(GUI_BUTTON *btn, INT32 reason)
1596 {
1597 if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
1598 {
1599 if (gfShowBookmarks)
1600 {
1601 gfShowBookmarks = FALSE;
1602 }
1603 guiCurrentLaptopMode = LAPTOP_MODE_HISTORY;
1604 UpdateListToReflectNewProgramOpened(LAPTOP_PROGRAM_HISTORY);
1605 gfShowBookmarks = FALSE;
1606 fReDrawScreenFlag = TRUE;
1607 }
1608 }
1609
1610
FilesRegionButtonCallback(GUI_BUTTON * btn,INT32 reason)1611 static void FilesRegionButtonCallback(GUI_BUTTON *btn, INT32 reason)
1612 {
1613 if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
1614 {
1615 if (gfShowBookmarks)
1616 {
1617 gfShowBookmarks = FALSE;
1618 }
1619 guiCurrentLaptopMode = LAPTOP_MODE_FILES;
1620 UpdateListToReflectNewProgramOpened(LAPTOP_PROGRAM_FILES);
1621 fReDrawScreenFlag = TRUE;
1622 }
1623 }
1624
1625
InitBookMarkList(void)1626 static void InitBookMarkList(void)
1627 {
1628 // sets bookmark list to -1
1629 std::fill(std::begin(LaptopSaveInfo.iBookMarkList), std::end(LaptopSaveInfo.iBookMarkList), -1);
1630 }
1631
1632
SetBookMark(INT32 iBookId)1633 void SetBookMark(INT32 iBookId)
1634 {
1635 // find first empty spot, set to iBookId
1636 INT32 i;
1637 for (i = 0; LaptopSaveInfo.iBookMarkList[i] != -1; ++i)
1638 {
1639 // move through list until empty
1640 if (LaptopSaveInfo.iBookMarkList[i] == iBookId)
1641 {
1642 // found it, return
1643 return;
1644 }
1645 }
1646 LaptopSaveInfo.iBookMarkList[i] = iBookId;
1647 }
1648
1649
LoadBookmark(void)1650 static void LoadBookmark(void)
1651 {
1652 // grab download bars too
1653 guiDOWNLOADTOP = AddVideoObjectFromFile(LAPTOPDIR "/downloadtop.sti");
1654 guiDOWNLOADMID = AddVideoObjectFromFile(LAPTOPDIR "/downloadmid.sti");
1655 guiDOWNLOADBOT = AddVideoObjectFromFile(LAPTOPDIR "/downloadbot.sti");
1656 guiBOOKMARK = AddVideoObjectFromFile(LAPTOPDIR "/webpages.sti");
1657 guiBOOKHIGH = AddVideoObjectFromFile(LAPTOPDIR "/hilite.sti");
1658 }
1659
1660
DisplayBookMarks(void)1661 static void DisplayBookMarks(void)
1662 {
1663 // check if we are maximizing or minimizing.. if so, do not display
1664 if (fMaximizingProgram || fMinizingProgram) return;
1665
1666 SetFont(BOOK_FONT);
1667 SetFontBackground(FONT_BLACK);
1668 SetFontShadow(NO_SHADOW);
1669
1670 SetFontDestBuffer(FRAME_BUFFER, BOOK_X, BOOK_TOP_Y, BOOK_X + BOOK_WIDTH - 10, SCREEN_HEIGHT);
1671
1672 // blt in book mark background
1673 INT32 const h = BOOK_HEIGHT + 6;
1674 INT32 const sy = BOOK_TOP_Y + 6 + h;
1675 INT32 y = sy;
1676 for (INT32 i = 0;; ++i)
1677 {
1678 bool const highlighted = iHighLightBookLine == i;
1679 SGPVObject const* const vo = highlighted ? guiBOOKHIGH : guiBOOKMARK;
1680 BltVideoObject(FRAME_BUFFER, vo, 0, BOOK_X, y);
1681
1682 SetFontForeground(highlighted ? FONT_WHITE : FONT_BLACK);
1683 INT32 const idx = LaptopSaveInfo.iBookMarkList[i];
1684 ST::string txt = pBookMarkStrings[idx != -1 ? idx : CANCEL_STRING];
1685 INT16 sX;
1686 INT16 sY;
1687 FindFontCenterCoordinates(BOOK_X + 3, y + 2, BOOK_WIDTH - 3, h, txt, BOOK_FONT, &sX, &sY);
1688 MPrint(sX, sY, txt);
1689 y += h;
1690 if (idx == -1) break;
1691 }
1692
1693 SetFontDestBuffer(FRAME_BUFFER);
1694 SetFontShadow(DEFAULT_SHADOW);
1695
1696 InvalidateRegion(BOOK_X, sy, BOOK_X + BOOK_WIDTH, y);
1697 }
1698
1699
DeleteBookmark(void)1700 static void DeleteBookmark(void)
1701 {
1702 DeleteVideoObject(guiBOOKHIGH);
1703 DeleteVideoObject(guiBOOKMARK);
1704 DeleteVideoObject(guiDOWNLOADTOP);
1705 DeleteVideoObject(guiDOWNLOADMID);
1706 DeleteVideoObject(guiDOWNLOADBOT);
1707 }
1708
1709
1710 static void BookmarkCallBack(MOUSE_REGION* pRegion, INT32 iReason);
1711 static void BookmarkMvtCallBack(MOUSE_REGION* pRegion, INT32 iReason);
1712
1713
CreateBookMarkMouseRegions(void)1714 static void CreateBookMarkMouseRegions(void)
1715 {
1716 // creates regions based on number of entries
1717 for (INT32 i = 0;; ++i)
1718 {
1719 UINT16 const y = BOOK_TOP_Y + (i + 1) * (BOOK_HEIGHT + 6) + 6;
1720 MOUSE_REGION* const r = &gBookmarkMouseRegions[i];
1721 MSYS_DefineRegion(r, BOOK_X, y, BOOK_X + BOOK_WIDTH, y + BOOK_HEIGHT + 6, MSYS_PRIORITY_HIGHEST - 2, CURSOR_LAPTOP_SCREEN, BookmarkMvtCallBack, BookmarkCallBack);
1722 MSYS_SetRegionUserData(r, 0, i);
1723 INT32 const idx = LaptopSaveInfo.iBookMarkList[i];
1724 if (idx == -1) break; // just added region for cancel
1725 r->SetFastHelpText(gzLaptopHelpText[BOOKMARK_TEXT_ASSOCIATION_OF_INTERNATION_MERCENARIES + idx]);
1726 }
1727 }
1728
1729
DeleteBookmarkRegions(void)1730 static void DeleteBookmarkRegions(void)
1731 {
1732 INT32 i;
1733 // deletes bookmark regions
1734 for (i = 0; LaptopSaveInfo.iBookMarkList[i] != -1; ++i)
1735 {
1736 MSYS_RemoveRegion(&gBookmarkMouseRegions[i]);
1737 }
1738
1739 // now one for the cancel
1740 MSYS_RemoveRegion(&gBookmarkMouseRegions[i]);
1741 }
1742
1743
CreateDestoryBookMarkRegions(void)1744 static void CreateDestoryBookMarkRegions(void)
1745 {
1746 // checks to see if a bookmark needs to be created or destroyed
1747 static BOOLEAN fOldShowBookmarks = FALSE;
1748
1749 if (gfShowBookmarks && !fOldShowBookmarks)
1750 {
1751 CreateBookMarkMouseRegions();
1752 fOldShowBookmarks = TRUE;
1753 }
1754 else if (!gfShowBookmarks && fOldShowBookmarks)
1755 {
1756 DeleteBookmarkRegions();
1757 fOldShowBookmarks = FALSE;
1758 }
1759 }
1760
1761
BookmarkCallBack(MOUSE_REGION * pRegion,INT32 iReason)1762 static void BookmarkCallBack(MOUSE_REGION* pRegion, INT32 iReason)
1763 {
1764 // we are in process of loading
1765 if (fLoadPendingFlag) return;
1766
1767 if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP)
1768 {
1769 INT32 const i = MSYS_GetRegionUserData(pRegion, 0);
1770 INT32 const idx = LaptopSaveInfo.iBookMarkList[i];
1771 if (idx != -1)
1772 {
1773 GoToWebPage(idx);
1774 }
1775 else
1776 {
1777 gfShowBookmarks = FALSE;
1778 fReDrawScreenFlag = TRUE;
1779 }
1780 }
1781 }
1782
1783
1784 static void InternetRainDelayMessageBoxCallBack(MessageBoxReturnValue);
1785
1786
GoToWebPage(INT32 iPageId)1787 void GoToWebPage(INT32 iPageId)
1788 {
1789 //if it is raining, popup a warning first saying connection time may be slow
1790 if (IsItRaining())
1791 {
1792 if (giRainDelayInternetSite == -1)
1793 {
1794 DoLapTopMessageBox(MSG_BOX_LAPTOP_DEFAULT, pErrorStrings, LAPTOP_SCREEN, MSG_BOX_FLAG_OK, InternetRainDelayMessageBoxCallBack);
1795 giRainDelayInternetSite = iPageId;
1796 return;
1797 }
1798 }
1799 else
1800 {
1801 giRainDelayInternetSite = -1;
1802 }
1803
1804 gfShowBookmarks = FALSE;
1805 fReDrawScreenFlag = TRUE;
1806
1807 switch (iPageId)
1808 {
1809 case AIM_BOOKMARK:
1810 guiCurrentWWWMode = LAPTOP_MODE_AIM;
1811 guiCurrentLaptopMode = LAPTOP_MODE_AIM;
1812 break;
1813
1814 case BOBBYR_BOOKMARK:
1815 guiCurrentWWWMode = LAPTOP_MODE_BOBBY_R;
1816 guiCurrentLaptopMode = LAPTOP_MODE_BOBBY_R;
1817 break;
1818
1819 case IMP_BOOKMARK:
1820 guiCurrentWWWMode = LAPTOP_MODE_CHAR_PROFILE;
1821 guiCurrentLaptopMode = LAPTOP_MODE_CHAR_PROFILE;
1822 iCurrentImpPage = IMP_HOME_PAGE;
1823 break;
1824
1825 case MERC_BOOKMARK:
1826 //if the mercs server has gone down, but hasnt come up yet
1827 if (LaptopSaveInfo.fMercSiteHasGoneDownYet &&
1828 LaptopSaveInfo.fFirstVisitSinceServerWentDown == FALSE)
1829 {
1830 guiCurrentWWWMode = LAPTOP_MODE_BROKEN_LINK;
1831 guiCurrentLaptopMode = LAPTOP_MODE_BROKEN_LINK;
1832 }
1833 else
1834 {
1835 guiCurrentWWWMode = LAPTOP_MODE_MERC;
1836 guiCurrentLaptopMode = LAPTOP_MODE_MERC;
1837 }
1838 break;
1839
1840 case FUNERAL_BOOKMARK:
1841 guiCurrentWWWMode = LAPTOP_MODE_FUNERAL;
1842 guiCurrentLaptopMode = LAPTOP_MODE_FUNERAL;
1843 break;
1844
1845 case FLORIST_BOOKMARK:
1846 guiCurrentWWWMode = LAPTOP_MODE_FLORIST;
1847 guiCurrentLaptopMode = LAPTOP_MODE_FLORIST;
1848 break;
1849
1850 case INSURANCE_BOOKMARK:
1851 guiCurrentWWWMode = LAPTOP_MODE_INSURANCE;
1852 guiCurrentLaptopMode = LAPTOP_MODE_INSURANCE;
1853 break;
1854
1855 default: return;
1856 }
1857
1858 // do we have to have a World Wide Wait
1859 fFastLoadFlag = LaptopSaveInfo.fVisitedBookmarkAlready[iPageId];
1860 LaptopSaveInfo.fVisitedBookmarkAlready[iPageId] = TRUE;
1861 fLoadPendingFlag = TRUE;
1862 }
1863
1864
BookmarkMvtCallBack(MOUSE_REGION * pRegion,INT32 iReason)1865 static void BookmarkMvtCallBack(MOUSE_REGION* pRegion, INT32 iReason)
1866 {
1867 if (iReason == MSYS_CALLBACK_REASON_MOVE)
1868 {
1869 iHighLightBookLine=MSYS_GetRegionUserData(pRegion, 0);
1870 }
1871 if (iReason == MSYS_CALLBACK_REASON_LOST_MOUSE)
1872 {
1873 iHighLightBookLine = -1;
1874 }
1875 }
1876
1877
LoadLoadPending(void)1878 static void LoadLoadPending(void)
1879 {
1880 // function will load the load pending graphics
1881 // reuse bookmark
1882 // load graph window and bar
1883 guiGRAPHWINDOW = AddVideoObjectFromFile(LAPTOPDIR "/graphwindow.sti");
1884 guiGRAPHBAR = AddVideoObjectFromFile(LAPTOPDIR "/graphsegment.sti");
1885 }
1886
1887
1888 static INT32 WWaitDelayIncreasedIfRaining(INT32 iUnitTime);
1889
1890
DisplayLoadPending(void)1891 static void DisplayLoadPending(void)
1892 {
1893 // this function will display the load pending and return if the load is done
1894 static INT32 iBaseTime = 0;
1895 static INT32 iTotalTime = 0;
1896
1897 // if merc webpage, make it longer
1898 // TEMP disables the loadpending
1899 INT32 iLoadTime;
1900 INT32 iUnitTime;
1901
1902 if (fFastLoadFlag)
1903 {
1904 iUnitTime = (fConnectingToSubPage ? FASTEST_UNIT_TIME : FAST_UNIT_TIME);
1905 }
1906 else if (fConnectingToSubPage)
1907 {
1908 iUnitTime = ALMOST_FAST_UNIT_TIME;
1909 }
1910 else if (guiCurrentLaptopMode == LAPTOP_MODE_MERC && !LaptopSaveInfo.fMercSiteHasGoneDownYet)
1911 {
1912 // if we are connecting the MERC site, and the MERC site hasnt yet moved
1913 // to their new site, have the sloooww wait
1914 iUnitTime = LONG_UNIT_TIME;
1915 }
1916 else
1917 {
1918 iUnitTime = UNIT_TIME;
1919 }
1920
1921 iUnitTime += WWaitDelayIncreasedIfRaining(iUnitTime);
1922 iLoadTime = iUnitTime * 30;
1923
1924 // we are now waiting on a web page to download, reset counter
1925 if (!fLoadPendingFlag)
1926 {
1927 fDoneLoadPending = FALSE;
1928 fFastLoadFlag = FALSE;
1929 fConnectingToSubPage = FALSE;
1930 iBaseTime = 0;
1931 iTotalTime = 0;
1932 return;
1933 }
1934 if (iBaseTime == 0) iBaseTime = GetJA2Clock();
1935
1936 // if total time is exceeded, return
1937 if (iTotalTime >= iLoadTime)
1938 {
1939 // done loading, redraw screen
1940 fLoadPendingFlag = FALSE;
1941 fFastLoadFlag = FALSE;
1942 iTotalTime = 0;
1943 iBaseTime = 0;
1944 fDoneLoadPending = TRUE;
1945 fConnectingToSubPage = FALSE;
1946 fPausedReDrawScreenFlag = TRUE;
1947 return;
1948 }
1949
1950 const INT32 iDifference = GetJA2Clock() - iBaseTime;
1951
1952 // difference has been long enough or we are redrawing the screen
1953 if (iDifference > iUnitTime)
1954 {
1955 // LONG ENOUGH TIME PASSED
1956 iBaseTime = GetJA2Clock();
1957 iTotalTime += iDifference;
1958 }
1959
1960 // new mail, don't redraw
1961 if (fNewMailFlag) return;
1962
1963 RenderButtons();
1964
1965 // display top middle and bottom of box
1966 BltVideoObject(FRAME_BUFFER, guiDOWNLOADTOP, 0, DOWNLOAD_X, DOWNLOAD_Y);
1967 BltVideoObject(FRAME_BUFFER, guiDOWNLOADMID, 0, DOWNLOAD_X, DOWNLOAD_Y + DOWN_HEIGHT);
1968 BltVideoObject(FRAME_BUFFER, guiDOWNLOADBOT, 0, DOWNLOAD_X, DOWNLOAD_Y + DOWN_HEIGHT * 2);
1969 BltVideoObject(FRAME_BUFFER, guiTITLEBARICONS, 1, DOWNLOAD_X + 4, DOWNLOAD_Y + 1);
1970
1971 SetFontAttributes(DOWNLOAD_FONT, FONT_WHITE, NO_SHADOW);
1972
1973 // reload or download?
1974 ST::string str = (fFastLoadFlag ? pDownloadString[1] : pDownloadString[0]);
1975 INT16 sXPosition = 0;
1976 INT16 sYPosition = 0;
1977 FindFontCenterCoordinates(328, 0, 446 - 328, 0, str, DOWNLOAD_FONT, &sXPosition, &sYPosition);
1978 MPrint(STD_SCREEN_X + sXPosition, DOWN_STRING_Y, str);
1979
1980 BltVideoObject(FRAME_BUFFER, guiGRAPHWINDOW, 0, LAPTOP_WINDOW_X, LAPTOP_WINDOW_Y);
1981
1982 // check to see if we are only updating screen, but not passed a new element in the load pending display
1983
1984 // decide how many time units are to be displayed, based on amount of time passed
1985 for (INT32 i = 0, iTempTime = iTotalTime; i <= 30 && iTempTime > 0; ++i, iTempTime -= iUnitTime)
1986 {
1987 BltVideoObject(FRAME_BUFFER, guiGRAPHBAR, 0, LAPTOP_BAR_X + UNIT_WIDTH * i, LAPTOP_BAR_Y);
1988 }
1989
1990 InvalidateRegion(DOWNLOAD_X, DOWNLOAD_Y, DOWNLOAD_X + 150, DOWNLOAD_Y + 100);
1991
1992 // re draw screen and new mail warning box
1993 SetFontShadow(DEFAULT_SHADOW);
1994
1995 MarkButtonsDirty();
1996
1997 DisableMercSiteButton();
1998 }
1999
2000
DeleteLoadPending(void)2001 static void DeleteLoadPending(void)
2002 {
2003 // this funtion will delete the load pending graphics
2004 // reuse bookmark
2005 DeleteVideoObject(guiGRAPHBAR);
2006 DeleteVideoObject(guiGRAPHWINDOW);
2007 }
2008
2009
2010 // This function is called every time the laptop is FIRST initialized, ie whenever the laptop is loaded. It calls
2011 // various init function in the laptop pages that need to be inited when the laptop is just loaded.
EnterLaptopInitLaptopPages(void)2012 static void EnterLaptopInitLaptopPages(void)
2013 {
2014 EnterInitAimMembers();
2015 EnterInitAimArchives();
2016 EnterInitAimPolicies();
2017 EnterInitAimHistory();
2018 EnterInitFloristGallery();
2019 EnterInitInsuranceInfo();
2020 EnterInitBobbyRayOrder();
2021 EnterInitMercSite();
2022
2023 // init sub pages for WW Wait
2024 InitIMPSubPageList();
2025 }
2026
2027
CheckMarkButtonsDirtyFlag(void)2028 static void CheckMarkButtonsDirtyFlag(void)
2029 {
2030 // this function checks the fMarkButtonsDirtyFlag, if true, mark buttons dirty
2031 if (fMarkButtonsDirtyFlag)
2032 {
2033 // flag set, mark buttons and reset
2034 MarkButtonsDirty();
2035 fMarkButtonsDirtyFlag = FALSE;
2036 }
2037 }
2038
2039
PostButtonRendering(void)2040 static void PostButtonRendering(void)
2041 {
2042 // this function is in place to allow for post button rendering
2043 switch (guiCurrentLaptopMode)
2044 {
2045 case LAPTOP_MODE_AIM_MEMBERS: RenderAIMMembersTopLevel(); break;
2046 default:
2047 break;
2048 }
2049 }
2050
2051
ShouldNewMailBeDisplayed(void)2052 static void ShouldNewMailBeDisplayed(void)
2053 {
2054 switch (guiCurrentLaptopMode)
2055 {
2056 case LAPTOP_MODE_AIM_MEMBERS: DisableNewMailMessage(); break;
2057 default:
2058 break;
2059 }
2060 }
2061
2062
CheckIfNewWWWW(void)2063 static void CheckIfNewWWWW(void)
2064 {
2065 // if no www mode, set new www flag..until new www mode that is not 0
2066 fNewWWW = (guiCurrentWWWMode == LAPTOP_MODE_NONE);
2067 }
2068
2069
HandleLapTopESCKey(void)2070 void HandleLapTopESCKey(void)
2071 {
2072 // will handle esc key events, since handling depends on state of laptop
2073 if (fNewMailFlag)
2074 {
2075 // get rid of new mail warning box
2076 fNewMailFlag = FALSE;
2077 CreateDestroyNewMailButton();
2078 }
2079 else if (MailToDelete != NULL)
2080 {
2081 // get rid of delete mail box
2082 MailToDelete = NULL;
2083 CreateDestroyDeleteNoticeMailButton();
2084 }
2085 else if (gfShowBookmarks)
2086 {
2087 // get rid of bookmarks
2088 gfShowBookmarks = FALSE;
2089 RenderLapTopImage();
2090 }
2091 else
2092 {
2093 // leave
2094 fExitingLaptopFlag = TRUE;
2095 HandleExit();
2096 return;
2097 }
2098
2099 // force redraw
2100 fReDrawScreenFlag = TRUE;
2101 RenderLaptop();
2102 }
2103
2104
HandleRightButtonUpEvent(void)2105 void HandleRightButtonUpEvent(void)
2106 {
2107 // will handle the right button up event
2108 if (fNewMailFlag)
2109 {
2110 // get rid of new mail warning box
2111 fNewMailFlag = FALSE;
2112 CreateDestroyNewMailButton();
2113 }
2114 else if (MailToDelete != NULL)
2115 {
2116 // get rid of delete mail box
2117 MailToDelete = NULL;
2118 CreateDestroyDeleteNoticeMailButton();
2119 }
2120 else if (gfShowBookmarks)
2121 {
2122 // get rid of bookmarks
2123 gfShowBookmarks = FALSE;
2124 RenderLapTopImage();
2125 }
2126 else if (fDisplayMessageFlag)
2127 {
2128 fDisplayMessageFlag = FALSE;
2129 RenderLapTopImage();
2130 }
2131 else
2132 {
2133 fShowBookmarkInfo = FALSE;
2134 return;
2135 }
2136
2137 // force redraw
2138 fReDrawScreenFlag = TRUE;
2139 RenderLaptop();
2140 }
2141
2142
HandleLeftButtonUpEvent(void)2143 static void HandleLeftButtonUpEvent(void)
2144 {
2145 // will handle the left button up event
2146 if (gfShowBookmarks)
2147 {
2148 // get rid of bookmarks
2149 gfShowBookmarks = FALSE;
2150
2151 // force redraw
2152 fReDrawScreenFlag = TRUE;
2153 RenderLapTopImage();
2154 RenderLaptop();
2155 }
2156 else if (fShowBookmarkInfo)
2157 {
2158 fShowBookmarkInfo = FALSE;
2159 }
2160 }
2161
LapTopScreenCallBack(MOUSE_REGION * pRegion,INT32 iReason)2162 void LapTopScreenCallBack(MOUSE_REGION* pRegion, INT32 iReason)
2163 {
2164 if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP)
2165 {
2166 HandleLeftButtonUpEvent();
2167 }
2168 if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP)
2169 {
2170 HandleRightButtonUpEvent();
2171 }
2172 }
2173
2174
DoLapTopMessageBox(MessageBoxStyleID ubStyle,const ST::string & str,ScreenID uiExitScreen,MessageBoxFlags ubFlags,MSGBOX_CALLBACK ReturnCallback)2175 void DoLapTopMessageBox(MessageBoxStyleID ubStyle, const ST::string& str, ScreenID uiExitScreen, MessageBoxFlags ubFlags, MSGBOX_CALLBACK ReturnCallback)
2176 {
2177 SGPBox const centering_rect = { LAPTOP_SCREEN_UL_X, LAPTOP_SCREEN_UL_Y, LAPTOP_SCREEN_WIDTH, LAPTOP_SCREEN_HEIGHT };
2178 DoLapTopSystemMessageBoxWithRect(ubStyle, str, uiExitScreen, ubFlags, ReturnCallback, ¢ering_rect);
2179 }
2180
2181
DoLapTopSystemMessageBoxWithRect(MessageBoxStyleID ubStyle,const ST::string & str,ScreenID uiExitScreen,MessageBoxFlags usFlags,MSGBOX_CALLBACK ReturnCallback,SGPBox const * centering_rect)2182 void DoLapTopSystemMessageBoxWithRect(MessageBoxStyleID ubStyle, const ST::string& str, ScreenID uiExitScreen, MessageBoxFlags usFlags, MSGBOX_CALLBACK ReturnCallback, SGPBox const* centering_rect)
2183 {
2184 // reset exit mode
2185 fExitDueToMessageBox = TRUE;
2186
2187 // do message box and return
2188 DoMessageBox(ubStyle, str, uiExitScreen, usFlags, ReturnCallback, centering_rect);
2189 }
2190
2191
DoLapTopSystemMessageBox(const ST::string & str,ScreenID uiExitScreen,MessageBoxFlags usFlags,MSGBOX_CALLBACK ReturnCallback)2192 void DoLapTopSystemMessageBox(const ST::string& str, ScreenID uiExitScreen, MessageBoxFlags usFlags, MSGBOX_CALLBACK ReturnCallback)
2193 {
2194 SGPBox const centering_rect = { 0, 0, SCREEN_WIDTH, INV_INTERFACE_START_Y };
2195 DoLapTopSystemMessageBoxWithRect(MSG_BOX_LAPTOP_DEFAULT, str, uiExitScreen, usFlags, ReturnCallback, ¢ering_rect);
2196 }
2197
2198
2199 //places a tileable pattern down
WebPageTileBackground(const UINT8 ubNumX,const UINT8 ubNumY,const UINT16 usWidth,const UINT16 usHeight,const SGPVObject * const background)2200 void WebPageTileBackground(const UINT8 ubNumX, const UINT8 ubNumY, const UINT16 usWidth, const UINT16 usHeight, const SGPVObject* const background)
2201 {
2202 UINT16 uiPosY = LAPTOP_SCREEN_WEB_UL_Y;
2203 for (UINT16 y = 0; y < ubNumY; ++y)
2204 {
2205 UINT16 uiPosX = LAPTOP_SCREEN_UL_X;
2206 for (UINT16 x = 0; x < ubNumX; ++x)
2207 {
2208 BltVideoObject(FRAME_BUFFER, background, 0, uiPosX, uiPosY);
2209 uiPosX += usWidth;
2210 }
2211 uiPosY += usHeight;
2212 }
2213 }
2214
2215
InitTitleBarMaximizeGraphics(const SGPVObject * uiBackgroundGraphic,const ST::string & str,const SGPVObject * uiIconGraphic,UINT16 usIconGraphicIndex)2216 static void InitTitleBarMaximizeGraphics(const SGPVObject* uiBackgroundGraphic, const ST::string& str, const SGPVObject* uiIconGraphic, UINT16 usIconGraphicIndex)
2217 {
2218 Assert(uiBackgroundGraphic);
2219
2220 // Create a background video surface to blt the title bar onto
2221 guiTitleBarSurface = AddVideoSurface(LAPTOP_TITLE_BAR_WIDTH + LAPTOP_TITLE_BAR_ICON_OFFSET_X,
2222 LAPTOP_TITLE_BAR_HEIGHT + LAPTOP_TITLE_BAR_ICON_OFFSET_Y, PIXEL_DEPTH);
2223
2224 BltVideoObject(guiTitleBarSurface, uiBackgroundGraphic, 0, 0, 0);
2225 BltVideoObject(guiTitleBarSurface, uiIconGraphic, usIconGraphicIndex, LAPTOP_TITLE_BAR_ICON_OFFSET_X, LAPTOP_TITLE_BAR_ICON_OFFSET_Y);
2226
2227 SetFontDestBuffer(guiTitleBarSurface);
2228 DrawTextToScreen(str, LAPTOP_TITLE_BAR_TEXT_OFFSET_X, LAPTOP_TITLE_BAR_TEXT_OFFSET_Y, 0, FONT14ARIAL, FONT_MCOLOR_WHITE, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
2229 SetFontDestBuffer(FRAME_BUFFER);
2230 }
2231
2232
DisplayTitleBarMaximizeGraphic(BOOLEAN fForward,BOOLEAN fInit,UINT16 usTopLeftX,UINT16 usTopLeftY,UINT16 usTopRightX)2233 static BOOLEAN DisplayTitleBarMaximizeGraphic(BOOLEAN fForward, BOOLEAN fInit, UINT16 usTopLeftX, UINT16 usTopLeftY, UINT16 usTopRightX)
2234 {
2235 static INT8 ubCount;
2236 static SGPBox LastRect;
2237
2238 if (fInit)
2239 {
2240 if (gfTitleBarSurfaceAlreadyActive) return FALSE;
2241 gfTitleBarSurfaceAlreadyActive = TRUE;
2242 if (fForward)
2243 {
2244 ubCount = 1;
2245 }
2246 else
2247 {
2248 ubCount = NUMBER_OF_LAPTOP_TITLEBAR_ITERATIONS - 1;
2249 }
2250 }
2251
2252 FLOAT dTemp;
2253 dTemp = (LAPTOP_TITLE_BAR_TOP_LEFT_X - usTopLeftX) / (FLOAT)NUMBER_OF_LAPTOP_TITLEBAR_ITERATIONS;
2254 const INT16 sPosX = usTopLeftX + dTemp * ubCount;
2255
2256 dTemp = (LAPTOP_TITLE_BAR_TOP_RIGHT_X - usTopRightX) / (FLOAT)NUMBER_OF_LAPTOP_TITLEBAR_ITERATIONS;
2257 const INT16 sPosRightX = usTopRightX + dTemp * ubCount;
2258
2259 dTemp = (LAPTOP_TITLE_BAR_TOP_LEFT_Y - usTopLeftY) / (FLOAT)NUMBER_OF_LAPTOP_TITLEBAR_ITERATIONS;
2260 const INT16 sPosY = usTopLeftY + dTemp * ubCount;
2261
2262 const INT16 sPosBottomY = LAPTOP_TITLE_BAR_HEIGHT;
2263
2264 SGPBox const SrcRect = { 0, 0, LAPTOP_TITLE_BAR_WIDTH, LAPTOP_TITLE_BAR_HEIGHT };
2265
2266 //if its the last fram, bit the tittle bar to the final position
2267 SGPBox DestRect;
2268 if (ubCount == NUMBER_OF_LAPTOP_TITLEBAR_ITERATIONS)
2269 {
2270 DestRect.x = LAPTOP_TITLE_BAR_TOP_LEFT_X;
2271 DestRect.y = LAPTOP_TITLE_BAR_TOP_LEFT_Y;
2272 DestRect.w = LAPTOP_TITLE_BAR_TOP_RIGHT_X - LAPTOP_TITLE_BAR_TOP_LEFT_X;
2273 DestRect.h = sPosBottomY;
2274 }
2275 else
2276 {
2277 DestRect.x = sPosX;
2278 DestRect.y = sPosY;
2279 DestRect.w = sPosRightX - sPosX;
2280 DestRect.h = sPosBottomY;
2281 }
2282
2283 if (fForward)
2284 {
2285 //Restore the old rect
2286 if (ubCount > 1)
2287 {
2288 BlitBufferToBuffer(guiSAVEBUFFER, FRAME_BUFFER, LastRect.x, LastRect.y, LastRect.w, LastRect.h);
2289 }
2290
2291 //Save rectangle
2292 if (ubCount > 0)
2293 {
2294 BlitBufferToBuffer(FRAME_BUFFER, guiSAVEBUFFER, DestRect.x, DestRect.y, DestRect.w, DestRect.h);
2295 }
2296 }
2297 else
2298 {
2299 //Restore the old rect
2300 if (ubCount < NUMBER_OF_LAPTOP_TITLEBAR_ITERATIONS - 1)
2301 {
2302 BlitBufferToBuffer(guiSAVEBUFFER, FRAME_BUFFER, LastRect.x, LastRect.y, LastRect.w, LastRect.h);
2303 }
2304
2305 //Save rectangle
2306 if (ubCount < NUMBER_OF_LAPTOP_TITLEBAR_ITERATIONS)
2307 {
2308 BlitBufferToBuffer(FRAME_BUFFER, guiSAVEBUFFER, DestRect.x, DestRect.y, DestRect.w, DestRect.h);
2309 }
2310 }
2311
2312 BltStretchVideoSurface(FRAME_BUFFER, guiTitleBarSurface, &SrcRect, &DestRect);
2313
2314 InvalidateRegion(DestRect.x, DestRect.y, DestRect.x + DestRect.w, DestRect.y + DestRect.h);
2315 InvalidateRegion(LastRect.x, LastRect.y, LastRect.x + LastRect.w, LastRect.y + LastRect.h);
2316
2317 LastRect = DestRect;
2318
2319 if (fForward)
2320 {
2321 if (ubCount == NUMBER_OF_LAPTOP_TITLEBAR_ITERATIONS)
2322 {
2323 gfTitleBarSurfaceAlreadyActive = FALSE;
2324 return TRUE;
2325 }
2326 else
2327 {
2328 ubCount++;
2329 return FALSE;
2330 }
2331 }
2332 else
2333 {
2334 if (ubCount == 0)
2335 {
2336 gfTitleBarSurfaceAlreadyActive = FALSE;
2337 return TRUE;
2338 }
2339 else
2340 {
2341 ubCount--;
2342 return FALSE;
2343 }
2344 }
2345 }
2346
2347
RemoveTitleBarMaximizeGraphics(void)2348 static void RemoveTitleBarMaximizeGraphics(void)
2349 {
2350 DeleteVideoSurface(guiTitleBarSurface);
2351 }
2352
2353
HandleSlidingTitleBar(void)2354 static void HandleSlidingTitleBar(void)
2355 {
2356 if (fExitingLaptopFlag) return;
2357
2358 if (fMaximizingProgram)
2359 {
2360 UINT16 y;
2361 switch (bProgramBeingMaximized)
2362 {
2363 case LAPTOP_PROGRAM_MAILER: y = STD_SCREEN_Y + 66; break;
2364 case LAPTOP_PROGRAM_FILES: y = STD_SCREEN_Y + 120; break;
2365 case LAPTOP_PROGRAM_FINANCES: y = STD_SCREEN_Y + 226; break;
2366 case LAPTOP_PROGRAM_PERSONNEL: y = STD_SCREEN_Y + 194; break;
2367 case LAPTOP_PROGRAM_HISTORY: y = STD_SCREEN_Y + 162; break;
2368 case LAPTOP_PROGRAM_WEB_BROWSER: y = STD_SCREEN_Y + 99; break;
2369 default: goto no_display_max;
2370 }
2371
2372 fMaximizingProgram = !DisplayTitleBarMaximizeGraphic(TRUE, fInitTitle, STD_SCREEN_X + 29, y, STD_SCREEN_X + 29 + 20);
2373 if (!fMaximizingProgram)
2374 {
2375 RemoveTitleBarMaximizeGraphics();
2376 fEnteredNewLapTopDueToHandleSlidingBars = TRUE;
2377 EnterNewLaptopMode();
2378 fEnteredNewLapTopDueToHandleSlidingBars = FALSE;
2379 fPausedReDrawScreenFlag = TRUE;
2380 }
2381
2382 no_display_max:
2383 MarkButtonsDirty();
2384 }
2385 else if (fMinizingProgram)
2386 {
2387 // minimizing
2388 UINT16 y;
2389 switch (bProgramBeingMaximized)
2390 {
2391 case LAPTOP_PROGRAM_MAILER: y = STD_SCREEN_Y + 66; break;
2392 case LAPTOP_PROGRAM_FILES: y = STD_SCREEN_Y + 130; break; // XXX only difference to max case
2393 case LAPTOP_PROGRAM_FINANCES: y = STD_SCREEN_Y + 226; break;
2394 case LAPTOP_PROGRAM_PERSONNEL: y = STD_SCREEN_Y + 194; break;
2395 case LAPTOP_PROGRAM_HISTORY: y = STD_SCREEN_Y + 162; break;
2396 case LAPTOP_PROGRAM_WEB_BROWSER: y = STD_SCREEN_Y + 99; break;
2397 default: goto no_display_min;
2398 }
2399
2400 fMinizingProgram = !DisplayTitleBarMaximizeGraphic(FALSE, fInitTitle, STD_SCREEN_X + 29, y, STD_SCREEN_X + 29 + 20);
2401 if (!fMinizingProgram)
2402 {
2403 RemoveTitleBarMaximizeGraphics();
2404 EnterNewLaptopMode();
2405 fEnteredNewLapTopDueToHandleSlidingBars = FALSE;
2406 fPausedReDrawScreenFlag = TRUE;
2407 }
2408
2409 no_display_min:;
2410 }
2411 else
2412 {
2413 return;
2414 }
2415
2416 // reset init
2417 fInitTitle = FALSE;
2418 }
2419
2420
ShowLights(void)2421 static void ShowLights(void)
2422 {
2423 // will show lights depending on state
2424 BltVideoObject(FRAME_BUFFER, guiLIGHTS, fPowerLightOn ? 0 : 1, STD_SCREEN_X + 44, STD_SCREEN_Y + 466);
2425 BltVideoObject(FRAME_BUFFER, guiLIGHTS, fHardDriveLightOn ? 0 : 1, STD_SCREEN_X + 88, STD_SCREEN_Y + 466);
2426 }
2427
2428
FlickerHDLight(void)2429 static void FlickerHDLight(void)
2430 {
2431 static INT32 iBaseTime = 0;
2432 static INT32 iTotalDifference = 0;
2433
2434 if (fLoadPendingFlag) fFlickerHD = TRUE;
2435 if (!fFlickerHD) return;
2436
2437 if (iBaseTime == 0) iBaseTime = GetJA2Clock();
2438
2439 const INT32 iDifference = GetJA2Clock() - iBaseTime;
2440
2441 if (iTotalDifference > HD_FLICKER_TIME && !fLoadPendingFlag)
2442 {
2443 iBaseTime = GetJA2Clock();
2444 fHardDriveLightOn = FALSE;
2445 iBaseTime = 0;
2446 iTotalDifference = 0;
2447 fFlickerHD = FALSE;
2448 InvalidateRegion(88, 466, 102, 477);
2449 return;
2450 }
2451
2452 if (iDifference > FLICKER_TIME)
2453 {
2454 iTotalDifference += iDifference;
2455
2456 if (fLoadPendingFlag) iTotalDifference = 0;
2457
2458 fHardDriveLightOn = (Random(2) == 0);
2459 InvalidateRegion(88, 466, 102, 477);
2460 }
2461 }
2462
2463
ExitLaptopDone(void)2464 static BOOLEAN ExitLaptopDone(void)
2465 {
2466 // check if this is the first time, to reset counter
2467 static BOOLEAN fOldLeaveLaptopState = FALSE;
2468 static INT32 iBaseTime = 0;
2469
2470 if (!fOldLeaveLaptopState)
2471 {
2472 fOldLeaveLaptopState = TRUE;
2473 iBaseTime = GetJA2Clock();
2474 }
2475
2476 fPowerLightOn = FALSE;
2477
2478 InvalidateRegion(44, 466, 58, 477);
2479 // get the current difference
2480 const INT32 iDifference = GetJA2Clock() - iBaseTime;
2481
2482 // did we wait long enough?
2483 if (iDifference > EXIT_LAPTOP_DELAY_TIME)
2484 {
2485 iBaseTime = 0;
2486 fOldLeaveLaptopState = FALSE;
2487 return TRUE;
2488 }
2489 else
2490 {
2491 return FALSE;
2492 }
2493 }
2494
2495
2496 static void CreateMinimizeButtonForCurrentMode(void);
2497 static void CreateMinimizeRegionsForLaptopProgramIcons(void);
2498 static void DestroyMinimizeButtonForCurrentMode(void);
2499 static void DestroyMinimizeRegionsForLaptopProgramIcons(void);
2500
2501
CreateDestroyMinimizeButtonForCurrentMode(void)2502 static void CreateDestroyMinimizeButtonForCurrentMode(void)
2503 {
2504 // will create the minimize button
2505 static BOOLEAN fAlreadyCreated = FALSE;
2506 // state of creation of minimize button
2507 BOOLEAN fCreateMinimizeButton = FALSE;
2508 // check to see if created, if so, do nothing
2509
2510 // check current mode
2511 if (guiCurrentLaptopMode == LAPTOP_MODE_NONE && guiPreviousLaptopMode != LAPTOP_MODE_NONE)
2512 {
2513 fCreateMinimizeButton = FALSE;
2514 }
2515 else if (guiCurrentLaptopMode != LAPTOP_MODE_NONE)
2516 {
2517 fCreateMinimizeButton = TRUE;
2518 }
2519 else if (guiPreviousLaptopMode != LAPTOP_MODE_NONE)
2520 {
2521 fCreateMinimizeButton = FALSE;
2522 }
2523
2524 // leaving laptop, get rid of the button
2525 if (fExitingLaptopFlag)
2526 {
2527 fCreateMinimizeButton = FALSE;
2528 }
2529
2530 if (!fAlreadyCreated && fCreateMinimizeButton)
2531 {
2532 // not created, create
2533 fAlreadyCreated = TRUE;
2534 CreateMinimizeButtonForCurrentMode();
2535 CreateMinimizeRegionsForLaptopProgramIcons();
2536 }
2537 else if (fAlreadyCreated && !fCreateMinimizeButton)
2538 {
2539 // created and must be destroyed
2540 fAlreadyCreated = FALSE;
2541 DestroyMinimizeButtonForCurrentMode();
2542 DestroyMinimizeRegionsForLaptopProgramIcons();
2543 }
2544 }
2545
2546
2547 static void LaptopMinimizeProgramButtonCallback(GUI_BUTTON* btn, INT32 reason);
2548
2549
CreateMinimizeButtonForCurrentMode(void)2550 static void CreateMinimizeButtonForCurrentMode(void)
2551 {
2552 // create minimize button
2553 gLaptopMinButton = QuickCreateButtonImg(LAPTOPDIR "/x.sti", 0, 1, STD_SCREEN_X + 590, STD_SCREEN_Y + 30, MSYS_PRIORITY_HIGH, LaptopMinimizeProgramButtonCallback);
2554 gLaptopMinButton->SetCursor(CURSOR_LAPTOP_SCREEN);
2555 }
2556
2557
DestroyMinimizeButtonForCurrentMode(void)2558 static void DestroyMinimizeButtonForCurrentMode(void)
2559 {
2560 // destroy minimize button
2561 RemoveButton(gLaptopMinButton);
2562 }
2563
2564
2565 static void SetCurrentToLastProgramOpened(void);
2566
2567
LaptopMinimizeProgramButtonCallback(GUI_BUTTON * btn,INT32 reason)2568 static void LaptopMinimizeProgramButtonCallback(GUI_BUTTON* btn, INT32 reason)
2569 {
2570 if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
2571 {
2572 UINT prog;
2573 ST::string title;
2574 UINT16 gfx_idx;
2575 switch (guiCurrentLaptopMode)
2576 {
2577 case LAPTOP_MODE_EMAIL:
2578 prog = LAPTOP_PROGRAM_MAILER;
2579 title = pLaptopIcons[0];
2580 gfx_idx = 0;
2581 break;
2582
2583 case LAPTOP_MODE_FILES:
2584 prog = LAPTOP_PROGRAM_FILES;
2585 title = pLaptopIcons[5];
2586 gfx_idx = 2;
2587 break;
2588
2589 case LAPTOP_MODE_FINANCES:
2590 prog = LAPTOP_PROGRAM_FINANCES;
2591 title = pLaptopIcons[2];
2592 gfx_idx = 5;
2593 break;
2594
2595 case LAPTOP_MODE_HISTORY:
2596 prog = LAPTOP_PROGRAM_HISTORY;
2597 title = pLaptopIcons[4];
2598 gfx_idx = 4;
2599 break;
2600
2601 case LAPTOP_MODE_PERSONNEL:
2602 prog = LAPTOP_PROGRAM_PERSONNEL;
2603 title = pLaptopIcons[3];
2604 gfx_idx = 3;
2605 break;
2606
2607 case LAPTOP_MODE_NONE: return; // nothing
2608
2609 default:
2610 gfShowBookmarks = FALSE;
2611 prog = LAPTOP_PROGRAM_WEB_BROWSER;
2612 title = pLaptopIcons[7];
2613 gfx_idx = 1;
2614 break;
2615 }
2616 gLaptopProgramStates[prog] = LAPTOP_PROGRAM_MINIMIZED;
2617 InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, title, guiTITLEBARICONS, gfx_idx);
2618 SetCurrentToLastProgramOpened();
2619 fMinizingProgram = TRUE;
2620 fInitTitle = TRUE;
2621 }
2622 }
2623
2624
FindLastProgramStillOpen(void)2625 static INT32 FindLastProgramStillOpen(void)
2626 {
2627 INT32 iLowestValue = 6;
2628 INT32 iLowestValueProgram = 6;
2629
2630 // returns ID of last program open and not minimized
2631 for (INT32 i = 0; i < 6; ++i)
2632 {
2633 if (gLaptopProgramStates[i] != LAPTOP_PROGRAM_MINIMIZED)
2634 {
2635 if (gLaptopProgramQueueList[i] < iLowestValue)
2636 {
2637 iLowestValue = gLaptopProgramQueueList[i];
2638 iLowestValueProgram = i;
2639 }
2640 }
2641 }
2642
2643 return iLowestValueProgram;
2644 }
2645
2646
UpdateListToReflectNewProgramOpened(INT32 iOpenedProgram)2647 static void UpdateListToReflectNewProgramOpened(INT32 iOpenedProgram)
2648 {
2649 // will update queue of opened programs to show thier states
2650 // set iOpenedProgram to 1, and update others
2651
2652 // increment everyone
2653 for (INT32 i = 0; i < 6; ++i)
2654 {
2655 gLaptopProgramQueueList[i]++;
2656 }
2657
2658 gLaptopProgramQueueList[iOpenedProgram] = 1;
2659 }
2660
2661
InitLaptopOpenQueue(void)2662 static void InitLaptopOpenQueue(void)
2663 {
2664 // set evereyone to 1
2665 for (INT32 i = 0; i < 6; ++i)
2666 {
2667 gLaptopProgramQueueList[i] = 1;
2668 }
2669 }
2670
2671
SetCurrentToLastProgramOpened(void)2672 static void SetCurrentToLastProgramOpened(void)
2673 {
2674 guiCurrentLaptopMode = LAPTOP_MODE_NONE;
2675
2676 switch (FindLastProgramStillOpen())
2677 {
2678 case LAPTOP_PROGRAM_HISTORY: guiCurrentLaptopMode = LAPTOP_MODE_HISTORY; break;
2679 case LAPTOP_PROGRAM_MAILER: guiCurrentLaptopMode = LAPTOP_MODE_EMAIL; break;
2680 case LAPTOP_PROGRAM_PERSONNEL: guiCurrentLaptopMode = LAPTOP_MODE_PERSONNEL; break;
2681 case LAPTOP_PROGRAM_FINANCES: guiCurrentLaptopMode = LAPTOP_MODE_FINANCES; break;
2682 case LAPTOP_PROGRAM_FILES: guiCurrentLaptopMode = LAPTOP_MODE_FILES; break;
2683
2684 case LAPTOP_PROGRAM_WEB_BROWSER:
2685 // last www mode
2686 guiCurrentLaptopMode = (guiCurrentWWWMode == 0 ? LAPTOP_MODE_WWW : guiCurrentWWWMode);
2687 fShowBookmarkInfo = TRUE;
2688 break;
2689 }
2690 }
2691
2692
BlitTitleBarIcons(void)2693 void BlitTitleBarIcons(void)
2694 {
2695 // will blit the icons for the title bar of the program we are in
2696 UINT32 Index;
2697 switch (guiCurrentLaptopMode)
2698 {
2699 case LAPTOP_MODE_HISTORY: Index = 4; break;
2700 case LAPTOP_MODE_EMAIL: Index = 0; break;
2701 case LAPTOP_MODE_PERSONNEL: Index = 3; break;
2702 case LAPTOP_MODE_FINANCES: Index = 5; break;
2703 case LAPTOP_MODE_FILES: Index = 2; break;
2704 case LAPTOP_MODE_NONE: return; // do nothing
2705 default: Index = 1; break; // www pages
2706 }
2707 BltVideoObject(FRAME_BUFFER, guiTITLEBARICONS, Index, LAPTOP_TITLE_ICONS_X, LAPTOP_TITLE_ICONS_Y);
2708 }
2709
2710
DrawDeskTopBackground(void)2711 static void DrawDeskTopBackground(void)
2712 {
2713 BltVideoSurface(FRAME_BUFFER, guiDESKTOP, LAPTOP_SCREEN_UL_X - 2, LAPTOP_SCREEN_UL_Y - 4, NULL);
2714 }
2715
2716
LoadDesktopBackground(void)2717 static void LoadDesktopBackground(void)
2718 {
2719 const char* const ImageFile = GetMLGFilename(MLG_DESKTOP);
2720 guiDESKTOP = AddVideoSurfaceFromFile(ImageFile);
2721 }
2722
2723
DeleteDesktopBackground(void)2724 static void DeleteDesktopBackground(void)
2725 {
2726 DeleteVideoSurface(guiDESKTOP);
2727 }
2728
2729
PrintBalance(void)2730 void PrintBalance(void)
2731 {
2732 SetFontAttributes(FONT10ARIAL, FONT_BLACK, NO_SHADOW);
2733
2734 ST::string pString = SPrintMoney(LaptopSaveInfo.iCurrentBalance);
2735
2736 INT32 x = STD_SCREEN_X + 47;
2737 INT32 y = STD_SCREEN_Y + 257 + 15;
2738 if (gLaptopButton[5]->Clicked())
2739 {
2740 ++x;
2741 ++y;
2742 }
2743 MPrint(x, y, pString);
2744
2745 SetFontShadow(DEFAULT_SHADOW);
2746 }
2747
2748
PrintNumberOnTeam(void)2749 void PrintNumberOnTeam(void)
2750 {
2751 SetFontAttributes(FONT10ARIAL, FONT_BLACK, NO_SHADOW);
2752
2753 const INT32 iCounter = NumberOfMercsOnPlayerTeam();
2754
2755 UINT16 usPosX = STD_SCREEN_X + 47;
2756 UINT16 usPosY = STD_SCREEN_Y + 194 + 30;
2757 if (gLaptopButton[3]->Clicked())
2758 {
2759 ++usPosX;
2760 ++usPosY;
2761 }
2762 MPrint(usPosX, usPosY, ST::format("{} {}", pPersonnelString, iCounter));
2763
2764 SetFontShadow(DEFAULT_SHADOW);
2765 }
2766
2767
PrintDate(void)2768 void PrintDate(void)
2769 {
2770 SetFontAttributes(FONT10ARIAL, FONT_BLACK, NO_SHADOW);
2771 MPrint(STD_SCREEN_X + 30 + (70 - StringPixLength(WORLDTIMESTR, FONT10ARIAL)) / 2, (433 + STD_SCREEN_Y), WORLDTIMESTR);
2772 SetFontShadow(DEFAULT_SHADOW);
2773 }
2774
2775
DisplayTaskBarIcons(void)2776 static void DisplayTaskBarIcons(void)
2777 {
2778 // display the files icon, if there is any
2779 if (fNewFilesInFileViewer)
2780 {
2781 BltVideoObject(FRAME_BUFFER, guiTITLEBARICONS, 7, LAPTOP__NEW_FILE_ICON_X, LAPTOP__NEW_FILE_ICON_Y);
2782 }
2783
2784 // display the email icon, if there is email
2785 if (fUnReadMailFlag)
2786 {
2787 BltVideoObject(FRAME_BUFFER, guiTITLEBARICONS, 6, LAPTOP__NEW_EMAIL_ICON_X, LAPTOP__NEW_EMAIL_ICON_Y);
2788 }
2789 }
2790
2791
2792 static void HandleAltTabKeyInLaptop(void);
2793 static void HandleShiftAltTabKeyInLaptop(void);
2794
2795
HandleKeyBoardShortCutsForLapTop(UINT16 usEvent,UINT32 usParam,UINT16 usKeyState)2796 void HandleKeyBoardShortCutsForLapTop(UINT16 usEvent, UINT32 usParam, UINT16 usKeyState)
2797 {
2798 // will handle keyboard shortcuts for the laptop ... to be added to later
2799 if (fExitingLaptopFlag || fTabHandled) return;
2800
2801 if (usEvent != KEY_DOWN) return;
2802
2803 switch (usParam)
2804 {
2805 case SDLK_ESCAPE:
2806 // esc hit, check to see if boomark list is shown, if so, get rid of it, otherwise, leave
2807 HandleLapTopESCKey();
2808 break;
2809
2810 case SDLK_TAB:
2811 if (usKeyState & CTRL_DOWN)
2812 {
2813 HandleShiftAltTabKeyInLaptop();
2814 }
2815 else
2816 {
2817 HandleAltTabKeyInLaptop();
2818 }
2819 fTabHandled = TRUE;
2820 break;
2821
2822 case 'b':
2823 if (CHEATER_CHEAT_LEVEL())
2824 {
2825 if (usKeyState & ALT_DOWN)
2826 {
2827 LaptopSaveInfo.fBobbyRSiteCanBeAccessed = TRUE;
2828 }
2829 else if (usKeyState & CTRL_DOWN)
2830 {
2831 guiCurrentLaptopMode = LAPTOP_MODE_BROKEN_LINK;
2832 }
2833 }
2834 break;
2835
2836 case 'x':
2837 if (usKeyState & ALT_DOWN) HandleShortCutExitState();
2838 break;
2839
2840 case SDLK_h:
2841 ShouldTheHelpScreenComeUp(HELP_SCREEN_LAPTOP, TRUE);
2842 break;
2843
2844 case '=':
2845 case '+':
2846 if (CHEATER_CHEAT_LEVEL())
2847 {
2848 // adding money
2849 AddTransactionToPlayersBook(ANONYMOUS_DEPOSIT, 0, GetWorldTotalMin(), 100000);
2850 MarkButtonsDirty();
2851 }
2852 break;
2853
2854 case '-':
2855 if (CHEATER_CHEAT_LEVEL())
2856 {
2857 // subtracting money
2858 AddTransactionToPlayersBook(ANONYMOUS_DEPOSIT, 0, GetWorldTotalMin(), -10000);
2859 MarkButtonsDirty();
2860 }
2861 break;
2862 }
2863 }
2864
2865
RenderWWWProgramTitleBar(void)2866 void RenderWWWProgramTitleBar(void)
2867 {
2868 // will render the title bar for the www program
2869 BltVideoObjectOnce(FRAME_BUFFER, LAPTOPDIR "/programtitlebar.sti", 0, LAPTOP_SCREEN_UL_X, LAPTOP_SCREEN_UL_Y - 2);
2870
2871 // now slapdown text
2872 SetFontAttributes(FONT14ARIAL, FONT_WHITE);
2873
2874 // display title
2875
2876 // no page loaded yet, do not handle yet
2877
2878 if (guiCurrentLaptopMode == LAPTOP_MODE_WWW)
2879 {
2880 MPrint(STD_SCREEN_X + 140, STD_SCREEN_Y + 33, pWebTitle);
2881 }
2882 else
2883 {
2884 const INT32 iIndex = guiCurrentLaptopMode - LAPTOP_MODE_WWW-1;
2885 MPrint(STD_SCREEN_X + 140, STD_SCREEN_Y + 33, ST::format("{} - {}", pWebTitle, pWebPagesTitles[iIndex]));
2886 }
2887
2888 BlitTitleBarIcons();
2889 DisplayProgramBoundingBox(FALSE);
2890 }
2891
2892
2893 static void LaptopProgramIconMinimizeCallback(MOUSE_REGION* pRegion, INT32 iReason);
2894
2895
CreateMinimizeRegionsForLaptopProgramIcons(void)2896 static void CreateMinimizeRegionsForLaptopProgramIcons(void)
2897 {
2898 // will create the minizing region to lie over the icon for this particular laptop program
2899 const UINT16 x = LAPTOP_PROGRAM_ICON_X;
2900 const UINT16 y = LAPTOP_PROGRAM_ICON_Y;
2901 const UINT16 w = LAPTOP_PROGRAM_ICON_WIDTH;
2902 const UINT16 h = LAPTOP_PROGRAM_ICON_HEIGHT;
2903 MSYS_DefineRegion(&gLapTopProgramMinIcon, x, y, x + w, y + h, MSYS_PRIORITY_NORMAL + 1, CURSOR_LAPTOP_SCREEN, MSYS_NO_CALLBACK, LaptopProgramIconMinimizeCallback);
2904 }
2905
2906
DestroyMinimizeRegionsForLaptopProgramIcons(void)2907 static void DestroyMinimizeRegionsForLaptopProgramIcons(void)
2908 {
2909 // will destroy the minizmize regions to be placed over the laptop icons that will be
2910 // displayed on the top of the laptop program bar
2911 MSYS_RemoveRegion(&gLapTopProgramMinIcon);
2912 }
2913
2914
LaptopProgramIconMinimizeCallback(MOUSE_REGION * pRegion,INT32 iReason)2915 static void LaptopProgramIconMinimizeCallback(MOUSE_REGION* pRegion, INT32 iReason)
2916 {
2917 // callback handler for the minize region that is attatched to the laptop program icon
2918 if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP)
2919 {
2920 switch (guiCurrentLaptopMode)
2921 {
2922 case LAPTOP_MODE_EMAIL:
2923 gLaptopProgramStates[LAPTOP_PROGRAM_MAILER] = LAPTOP_PROGRAM_MINIMIZED;
2924 InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[0], guiTITLEBARICONS, 0);
2925 SetCurrentToLastProgramOpened();
2926 break;
2927
2928 case LAPTOP_MODE_FILES:
2929 gLaptopProgramStates[LAPTOP_PROGRAM_FILES] = LAPTOP_PROGRAM_MINIMIZED;
2930 InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[5], guiTITLEBARICONS, 2);
2931 SetCurrentToLastProgramOpened();
2932 break;
2933
2934 case LAPTOP_MODE_FINANCES:
2935 gLaptopProgramStates[LAPTOP_PROGRAM_FINANCES] = LAPTOP_PROGRAM_MINIMIZED;
2936 InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[2], guiTITLEBARICONS, 5);
2937 SetCurrentToLastProgramOpened();
2938 break;
2939
2940 case LAPTOP_MODE_HISTORY:
2941 gLaptopProgramStates[LAPTOP_PROGRAM_HISTORY] = LAPTOP_PROGRAM_MINIMIZED;
2942 InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[4], guiTITLEBARICONS, 4);
2943 SetCurrentToLastProgramOpened();
2944 break;
2945
2946 case LAPTOP_MODE_PERSONNEL:
2947 gLaptopProgramStates[LAPTOP_PROGRAM_PERSONNEL] = LAPTOP_PROGRAM_MINIMIZED;
2948 InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[3], guiTITLEBARICONS, 3);
2949 SetCurrentToLastProgramOpened();
2950 break;
2951
2952 case LAPTOP_MODE_NONE: return; // nothing
2953
2954 default:
2955 gLaptopProgramStates[LAPTOP_PROGRAM_WEB_BROWSER] = LAPTOP_PROGRAM_MINIMIZED;
2956 InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pWebTitle, guiTITLEBARICONS, 1);
2957 SetCurrentToLastProgramOpened();
2958 gfShowBookmarks = FALSE;
2959 fShowBookmarkInfo = FALSE;
2960 break;
2961 }
2962 fMinizingProgram = TRUE;
2963 fInitTitle = TRUE;
2964 }
2965 }
2966
2967
DisplayProgramBoundingBox(BOOLEAN fMarkButtons)2968 void DisplayProgramBoundingBox(BOOLEAN fMarkButtons)
2969 {
2970 // the border for the program
2971 BltVideoObject(FRAME_BUFFER, guiLaptopBACKGROUND, 1, STD_SCREEN_X + 25, STD_SCREEN_Y + 23);
2972
2973 // no laptop mode, no border around the program
2974 if (guiCurrentLaptopMode != LAPTOP_MODE_NONE)
2975 {
2976 BltVideoObject(FRAME_BUFFER, guiLaptopBACKGROUND, 0, STD_SCREEN_X + 108, STD_SCREEN_Y + 23);
2977 }
2978
2979 if (fMarkButtons || fLoadPendingFlag)
2980 {
2981 MarkButtonsDirty();
2982 RenderButtons();
2983 }
2984
2985 PrintDate();
2986 PrintBalance();
2987 PrintNumberOnTeam();
2988 DisplayTaskBarIcons();
2989 }
2990
2991
2992 static void NewEmailIconCallback(MOUSE_REGION* pRegion, INT32 iReason);
2993 static void NewFileIconCallback(MOUSE_REGION* pRegion, INT32 iReason);
2994
2995
CreateDestroyMouseRegionForNewMailIcon(void)2996 static void CreateDestroyMouseRegionForNewMailIcon(void)
2997 {
2998 static BOOLEAN fCreated = FALSE;
2999
3000 // will toggle creation/destruction of the mouse regions used by the new mail icon
3001 if (!fCreated)
3002 {
3003 fCreated = TRUE;
3004 {
3005 const UINT16 x = LAPTOP__NEW_EMAIL_ICON_X;
3006 const UINT16 y = LAPTOP__NEW_EMAIL_ICON_Y;
3007 MSYS_DefineRegion(&gNewMailIconRegion, x, y + 5, x + 16, y + 16, MSYS_PRIORITY_HIGHEST - 3, CURSOR_LAPTOP_SCREEN, MSYS_NO_CALLBACK, NewEmailIconCallback);
3008 CreateFileAndNewEmailIconFastHelpText(LAPTOP_BN_HLP_TXT_YOU_HAVE_NEW_MAIL, fUnReadMailFlag == 0);
3009 }
3010
3011 {
3012 const UINT16 x = LAPTOP__NEW_FILE_ICON_X;
3013 const UINT16 y = LAPTOP__NEW_FILE_ICON_Y;
3014 MSYS_DefineRegion(&gNewFileIconRegion, x, y + 5, x + 16, y + 16, MSYS_PRIORITY_HIGHEST - 3, CURSOR_LAPTOP_SCREEN, MSYS_NO_CALLBACK, NewFileIconCallback);
3015 CreateFileAndNewEmailIconFastHelpText(LAPTOP_BN_HLP_TXT_YOU_HAVE_NEW_FILE, fNewFilesInFileViewer == 0);
3016 }
3017 }
3018 else
3019 {
3020 fCreated = FALSE;
3021 MSYS_RemoveRegion(&gNewMailIconRegion);
3022 MSYS_RemoveRegion(&gNewFileIconRegion);
3023 }
3024 }
3025
3026
NewEmailIconCallback(MOUSE_REGION * pRegion,INT32 iReason)3027 static void NewEmailIconCallback(MOUSE_REGION* pRegion, INT32 iReason)
3028 {
3029 if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP)
3030 {
3031 if (fUnReadMailFlag)
3032 {
3033 fOpenMostRecentUnReadFlag = TRUE;
3034 guiCurrentLaptopMode = LAPTOP_MODE_EMAIL;
3035 }
3036 }
3037 }
3038
3039
NewFileIconCallback(MOUSE_REGION * pRegion,INT32 iReason)3040 static void NewFileIconCallback(MOUSE_REGION* pRegion, INT32 iReason)
3041 {
3042 if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP)
3043 {
3044 if (fNewFilesInFileViewer)
3045 {
3046 fEnteredFileViewerFromNewFileIcon = TRUE;
3047 guiCurrentLaptopMode = LAPTOP_MODE_FILES;
3048 }
3049 }
3050 }
3051
3052
HandleWWWSubSites(void)3053 static void HandleWWWSubSites(void)
3054 {
3055 // check to see if WW Wait is needed for a sub site within the Web Browser
3056 if (guiCurrentLaptopMode == guiPreviousLaptopMode ||
3057 guiCurrentLaptopMode < LAPTOP_MODE_WWW ||
3058 fLoadPendingFlag ||
3059 fDoneLoadPending ||
3060 guiPreviousLaptopMode < LAPTOP_MODE_WWW)
3061 {
3062 // no go, leave
3063 return;
3064 }
3065
3066 fLoadPendingFlag = TRUE;
3067 fConnectingToSubPage = TRUE;
3068
3069 // fast or slow load?
3070 bool& visited = gfWWWaitSubSitesVisitedFlags[guiCurrentLaptopMode - (LAPTOP_MODE_WWW + 1)];
3071 if (visited) fFastLoadFlag = TRUE;
3072 visited = true; // Set fact we were here
3073
3074 //Dont show the dlownload screen when switching between these pages
3075 if ((guiCurrentLaptopMode == LAPTOP_MODE_AIM_MEMBERS && guiPreviousLaptopMode == LAPTOP_MODE_AIM_MEMBERS_FACIAL_INDEX) ||
3076 (guiCurrentLaptopMode == LAPTOP_MODE_AIM_MEMBERS_FACIAL_INDEX && guiPreviousLaptopMode == LAPTOP_MODE_AIM_MEMBERS))
3077 {
3078 fFastLoadFlag = FALSE;
3079 fLoadPendingFlag = FALSE;
3080
3081 // set fact we were here
3082 gfWWWaitSubSitesVisitedFlags[LAPTOP_MODE_AIM_MEMBERS_FACIAL_INDEX - (LAPTOP_MODE_WWW + 1)] = true;
3083 gfWWWaitSubSitesVisitedFlags[LAPTOP_MODE_AIM_MEMBERS - (LAPTOP_MODE_WWW + 1)] = true;
3084 }
3085 }
3086
3087
UpdateStatusOfDisplayingBookMarks(void)3088 static void UpdateStatusOfDisplayingBookMarks(void)
3089 {
3090 // this function will disable showing of bookmarks if in process of download or if we miniming web browser
3091 if (fLoadPendingFlag || guiCurrentLaptopMode < LAPTOP_MODE_WWW)
3092 {
3093 gfShowBookmarks = FALSE;
3094 }
3095 }
3096
3097
InitalizeSubSitesList(void)3098 static void InitalizeSubSitesList(void)
3099 {
3100 // init all subsites list to not visited
3101 FOR_EACH(bool, i, gfWWWaitSubSitesVisitedFlags)
3102 {
3103 *i = false;
3104 }
3105 }
3106
3107
SetSubSiteAsVisted(void)3108 static void SetSubSiteAsVisted(void)
3109 {
3110 // sets a www sub site as visited
3111 // not at a web page yet?
3112 if (guiCurrentLaptopMode <= LAPTOP_MODE_WWW) return;
3113
3114 gfWWWaitSubSitesVisitedFlags[guiCurrentLaptopMode - (LAPTOP_MODE_WWW + 1)] = true;
3115 }
3116
3117
HandleShiftAltTabKeyInLaptop(void)3118 static void HandleShiftAltTabKeyInLaptop(void)
3119 {
3120 // will handle the alt tab keying in laptop
3121
3122 // move to next program
3123 if (fMaximizingProgram) return;
3124
3125 switch (guiCurrentLaptopMode)
3126 {
3127 case LAPTOP_MODE_FINANCES: guiCurrentLaptopMode = LAPTOP_MODE_PERSONNEL; break;
3128 case LAPTOP_MODE_PERSONNEL: guiCurrentLaptopMode = LAPTOP_MODE_HISTORY; break;
3129 case LAPTOP_MODE_HISTORY: guiCurrentLaptopMode = LAPTOP_MODE_FILES; break;
3130 case LAPTOP_MODE_EMAIL: guiCurrentLaptopMode = LAPTOP_MODE_FINANCES; break;
3131 case LAPTOP_MODE_FILES: guiCurrentLaptopMode = LAPTOP_MODE_WWW; break;
3132 case LAPTOP_MODE_NONE: guiCurrentLaptopMode = LAPTOP_MODE_FINANCES; break;
3133 case LAPTOP_MODE_WWW: guiCurrentLaptopMode = LAPTOP_MODE_EMAIL; break;
3134 default: guiCurrentLaptopMode = LAPTOP_MODE_EMAIL; break;
3135 }
3136
3137 fPausedReDrawScreenFlag = TRUE;
3138 }
3139
3140
HandleAltTabKeyInLaptop(void)3141 static void HandleAltTabKeyInLaptop(void)
3142 {
3143 // will handle the alt tab keying in laptop
3144
3145 // move to next program
3146 if (fMaximizingProgram) return;
3147
3148 switch (guiCurrentLaptopMode)
3149 {
3150 case LAPTOP_MODE_FINANCES: guiCurrentLaptopMode = LAPTOP_MODE_EMAIL; break;
3151 case LAPTOP_MODE_PERSONNEL: guiCurrentLaptopMode = LAPTOP_MODE_FINANCES; break;
3152 case LAPTOP_MODE_HISTORY: guiCurrentLaptopMode = LAPTOP_MODE_PERSONNEL; break;
3153 case LAPTOP_MODE_EMAIL: guiCurrentLaptopMode = LAPTOP_MODE_WWW; break;
3154 case LAPTOP_MODE_FILES: guiCurrentLaptopMode = LAPTOP_MODE_HISTORY; break;
3155 case LAPTOP_MODE_NONE: guiCurrentLaptopMode = LAPTOP_MODE_EMAIL; break;
3156 default: guiCurrentLaptopMode = LAPTOP_MODE_FILES; break;
3157 }
3158
3159 fPausedReDrawScreenFlag = TRUE;
3160 }
3161
3162
3163 static void HandleWebBookMarkNotifyTimer(void);
3164
3165
3166 // display the 2 second book mark instruction
DisplayWebBookMarkNotify(void)3167 static void DisplayWebBookMarkNotify(void)
3168 {
3169 static BOOLEAN fOldShow = FALSE;
3170
3171 // handle the timer for this thing
3172 HandleWebBookMarkNotifyTimer();
3173
3174 // are we about to start showing box? or did we just stop?
3175 if ((!fOldShow || fReDrawBookMarkInfo) && fShowBookmarkInfo)
3176 {
3177 fOldShow = TRUE;
3178 fReDrawBookMarkInfo = FALSE;
3179
3180 // show background objects
3181 BltVideoObject(FRAME_BUFFER, guiDOWNLOADTOP, 0,DOWNLOAD_X, DOWNLOAD_Y);
3182 BltVideoObject(FRAME_BUFFER, guiDOWNLOADMID, 0,DOWNLOAD_X, DOWNLOAD_Y + DOWN_HEIGHT);
3183 BltVideoObject(FRAME_BUFFER, guiDOWNLOADBOT, 0,DOWNLOAD_X, DOWNLOAD_Y + 2 * DOWN_HEIGHT);
3184 BltVideoObject(FRAME_BUFFER, guiTITLEBARICONS, 1,DOWNLOAD_X + 4, DOWNLOAD_Y + 1);
3185
3186 SetFontAttributes(DOWNLOAD_FONT, FONT_WHITE, NO_SHADOW);
3187
3188 // display download string
3189 MPrint(DOWN_STRING_X, DOWN_STRING_Y, pShowBookmarkString[0]);
3190
3191 // now draw the message
3192 DisplayWrappedString(DOWN_STRING_X - 42, DOWN_STRING_Y + 20, BOOK_WIDTH + 45, 2, BOOK_FONT, FONT_BLACK, pShowBookmarkString[1], FONT_BLACK, CENTER_JUSTIFIED);
3193
3194 // invalidate region
3195 InvalidateRegion(DOWNLOAD_X, DOWNLOAD_Y, DOWNLOAD_X + 150, DOWNLOAD_Y + 100);
3196
3197 SetFontShadow(DEFAULT_SHADOW);
3198 }
3199 else if (fOldShow && !fShowBookmarkInfo)
3200 {
3201 fOldShow = FALSE;
3202 fPausedReDrawScreenFlag = TRUE;
3203 }
3204 }
3205
3206
3207 // handle timer for bookmark notify
HandleWebBookMarkNotifyTimer(void)3208 static void HandleWebBookMarkNotifyTimer(void)
3209 {
3210 static INT32 iBaseTime = 0;
3211 static BOOLEAN fOldShowBookMarkInfo = FALSE;
3212
3213 // check if maxing or mining?
3214 if (fMaximizingProgram || fMinizingProgram)
3215 {
3216 fOldShowBookMarkInfo |= fShowBookmarkInfo;
3217 fShowBookmarkInfo = FALSE;
3218 return;
3219 }
3220
3221 // if we were going to show this pop up, but were delayed, then do so now
3222 fShowBookmarkInfo |= fOldShowBookMarkInfo;
3223
3224 // reset old flag
3225 fOldShowBookMarkInfo = FALSE;
3226
3227 // if current mode is too low, then reset
3228 if (guiCurrentLaptopMode < LAPTOP_MODE_WWW)
3229 {
3230 fShowBookmarkInfo = FALSE;
3231 }
3232
3233 // if showing bookmarks, don't show help
3234 if (gfShowBookmarks) fShowBookmarkInfo = FALSE;
3235
3236 // check if flag false, is so, leave
3237 if (!fShowBookmarkInfo)
3238 {
3239 iBaseTime = 0;
3240 return;
3241 }
3242
3243 // check if this is the first time in here
3244 if (iBaseTime == 0)
3245 {
3246 iBaseTime = GetJA2Clock();
3247 return;
3248 }
3249
3250 const INT32 iDifference = GetJA2Clock() - iBaseTime;
3251
3252 fReDrawBookMarkInfo = TRUE;
3253
3254 if (iDifference > DISPLAY_TIME_FOR_WEB_BOOKMARK_NOTIFY)
3255 {
3256 // waited long enough, stop showing
3257 iBaseTime = 0;
3258 fShowBookmarkInfo = FALSE;
3259 }
3260 }
3261
3262
ClearOutTempLaptopFiles(void)3263 void ClearOutTempLaptopFiles(void)
3264 {
3265 // clear out all temp files from laptop
3266 FileDelete("files.dat");
3267 FileDelete("finances.dat");
3268 FileDelete("email.dat");
3269 FileDelete("history.dat");
3270 }
3271
3272
InjectStoreInvetory(DataWriter & d,STORE_INVENTORY const & i)3273 static void InjectStoreInvetory(DataWriter& d, STORE_INVENTORY const& i)
3274 {
3275 size_t start = d.getConsumed();
3276 INJ_U16( d, i.usItemIndex)
3277 INJ_U8( d, i.ubQtyOnHand)
3278 INJ_U8( d, i.ubQtyOnOrder)
3279 INJ_U8( d, i.ubItemQuality)
3280 INJ_BOOL(d, i.fPreviouslyEligible)
3281 INJ_SKIP(d, 2)
3282 Assert(d.getConsumed() == start + 8);
3283 }
3284
3285
ExtractStoreInvetory(DataReader & d,STORE_INVENTORY & i)3286 static void ExtractStoreInvetory(DataReader& d, STORE_INVENTORY& i)
3287 {
3288 size_t start = d.getConsumed();
3289 EXTR_U16( d, i.usItemIndex)
3290 EXTR_U8( d, i.ubQtyOnHand)
3291 EXTR_U8( d, i.ubQtyOnOrder)
3292 EXTR_U8( d, i.ubItemQuality)
3293 EXTR_BOOL(d, i.fPreviouslyEligible)
3294 EXTR_SKIP(d, 2)
3295 Assert(d.getConsumed() == start + 8);
3296 }
3297
3298
SaveLaptopInfoToSavedGame(HWFILE const f)3299 void SaveLaptopInfoToSavedGame(HWFILE const f)
3300 {
3301 LaptopSaveInfoStruct const& l = LaptopSaveInfo;
3302
3303 BYTE data[7440];
3304 DataWriter d{data};
3305 INJ_BOOL( d, l.gfNewGameLaptop)
3306 INJ_BOOLA(d, l.fVisitedBookmarkAlready, lengthof(l.fVisitedBookmarkAlready))
3307 INJ_SKIP( d, 3)
3308 INJ_I32A( d, l.iBookMarkList, lengthof(l.iBookMarkList))
3309 INJ_I32( d, l.iCurrentBalance)
3310 INJ_BOOL( d, l.fIMPCompletedFlag)
3311 INJ_BOOL( d, l.fSentImpWarningAlready)
3312 INJ_I16A( d, l.ubDeadCharactersList, lengthof(l.ubDeadCharactersList))
3313 INJ_I16A( d, l.ubLeftCharactersList, lengthof(l.ubLeftCharactersList))
3314 INJ_I16A( d, l.ubOtherCharactersList, lengthof(l.ubOtherCharactersList))
3315 INJ_U8( d, l.gubPlayersMercAccountStatus)
3316 INJ_SKIP( d, 1)
3317 INJ_U32( d, l.guiPlayersMercAccountNumber)
3318 INJ_U8( d, l.gubLastMercIndex)
3319 INJ_SKIP( d, 1)
3320 FOR_EACH(STORE_INVENTORY const, i, l.BobbyRayInventory)
3321 {
3322 InjectStoreInvetory(d, *i);
3323 }
3324 FOR_EACH(STORE_INVENTORY const, i, l.BobbyRayUsedInventory)
3325 {
3326 InjectStoreInvetory(d, *i);
3327 }
3328 INJ_SKIP( d, 6)
3329 Assert(l.BobbyRayOrdersOnDeliveryArray.size() <= UINT8_MAX);
3330 INJ_U8( d, static_cast<UINT8>(l.BobbyRayOrdersOnDeliveryArray.size()))
3331 INJ_U8( d, l.usNumberOfBobbyRayOrderUsed)
3332 INJ_SKIP( d, 6)
3333 Assert(l.pLifeInsurancePayouts.size() <= UINT8_MAX);
3334 INJ_U8( d, static_cast<UINT8>(l.pLifeInsurancePayouts.size()))
3335 Assert(l.ubNumberLifeInsurancePayoutUsed <= l.pLifeInsurancePayouts.size());
3336 INJ_U8( d, l.ubNumberLifeInsurancePayoutUsed)
3337 INJ_BOOL( d, l.fBobbyRSiteCanBeAccessed)
3338 INJ_U8( d, l.ubPlayerBeenToMercSiteStatus)
3339 INJ_BOOL( d, l.fFirstVisitSinceServerWentDown)
3340 INJ_BOOL( d, l.fNewMercsAvailableAtMercSite)
3341 INJ_BOOL( d, l.fSaidGenericOpeningInMercSite)
3342 INJ_BOOL( d, l.fSpeckSaidFloMarriedCousinQuote)
3343 INJ_BOOL( d, l.fHasAMercDiedAtMercSite)
3344 INJ_SKIP( d, 11)
3345 INJ_U16A( d, l.usInventoryListLength, lengthof(l.usInventoryListLength))
3346 INJ_I32( d, l.iVoiceId)
3347 INJ_U8( d, l.ubHaveBeenToBobbyRaysAtLeastOnceWhileUnderConstruction)
3348 INJ_BOOL( d, l.fMercSiteHasGoneDownYet)
3349 INJ_U8( d, l.ubSpeckCanSayPlayersLostQuote)
3350 INJ_SKIP( d, 1)
3351 INJ_BOOL( d, l.sLastHiredMerc.fHaveDisplayedPopUpInLaptop)
3352 INJ_SKIP( d, 3)
3353 INJ_I32( d, l.sLastHiredMerc.iIdOfMerc)
3354 INJ_U32( d, l.sLastHiredMerc.uiArrivalTime)
3355 INJ_I32( d, l.iCurrentHistoryPage)
3356 INJ_I32( d, l.iCurrentFinancesPage)
3357 INJ_I32( d, l.iCurrentEmailPage)
3358 INJ_U32( d, l.uiSpeckQuoteFlags)
3359 INJ_U32( d, l.uiFlowerOrderNumber)
3360 INJ_U32( d, l.uiTotalMoneyPaidToSpeck)
3361 INJ_U8( d, l.ubLastMercAvailableId)
3362 INJ_SKIP( d, 87)
3363 Assert(d.getConsumed() == lengthof(data));
3364
3365 FileWrite(f, data, sizeof(data));
3366
3367 if (l.usNumberOfBobbyRayOrderUsed != 0)
3368 { // There is anything in the Bobby Ray Orders on delivery
3369 size_t const size = sizeof(*l.BobbyRayOrdersOnDeliveryArray.data()) * l.BobbyRayOrdersOnDeliveryArray.size();
3370 FileWrite(f, l.BobbyRayOrdersOnDeliveryArray.data(), size);
3371 }
3372
3373 if (l.ubNumberLifeInsurancePayoutUsed != 0)
3374 { // There are any insurance payouts in progress
3375 FileWrite(f, l.pLifeInsurancePayouts.data(), sizeof(LIFE_INSURANCE_PAYOUT) * l.pLifeInsurancePayouts.size());
3376 }
3377 }
3378
3379
LoadLaptopInfoFromSavedGame(HWFILE const f)3380 void LoadLaptopInfoFromSavedGame(HWFILE const f)
3381 {
3382 LaptopSaveInfoStruct& l = LaptopSaveInfo;
3383
3384 l.BobbyRayOrdersOnDeliveryArray.clear();
3385
3386 l.pLifeInsurancePayouts.clear();
3387
3388 BYTE data[7440];
3389 FileRead(f, data, sizeof(data));
3390
3391 DataReader d{data};
3392 EXTR_BOOL( d, l.gfNewGameLaptop)
3393 EXTR_BOOLA(d, l.fVisitedBookmarkAlready, lengthof(l.fVisitedBookmarkAlready))
3394 EXTR_SKIP( d, 3)
3395 EXTR_I32A( d, l.iBookMarkList, lengthof(l.iBookMarkList))
3396 EXTR_I32( d, l.iCurrentBalance)
3397 EXTR_BOOL( d, l.fIMPCompletedFlag)
3398 EXTR_BOOL( d, l.fSentImpWarningAlready)
3399 EXTR_I16A( d, l.ubDeadCharactersList, lengthof(l.ubDeadCharactersList))
3400 EXTR_I16A( d, l.ubLeftCharactersList, lengthof(l.ubLeftCharactersList))
3401 EXTR_I16A( d, l.ubOtherCharactersList, lengthof(l.ubOtherCharactersList))
3402 EXTR_U8( d, l.gubPlayersMercAccountStatus)
3403 EXTR_SKIP( d, 1)
3404 EXTR_U32( d, l.guiPlayersMercAccountNumber)
3405 EXTR_U8( d, l.gubLastMercIndex)
3406 EXTR_SKIP( d, 1)
3407 FOR_EACH(STORE_INVENTORY, i, l.BobbyRayInventory)
3408 {
3409 ExtractStoreInvetory(d, *i);
3410 }
3411 FOR_EACH(STORE_INVENTORY, i, l.BobbyRayUsedInventory)
3412 {
3413 ExtractStoreInvetory(d, *i);
3414 }
3415 EXTR_SKIP( d, 6)
3416 UINT8 BobbyRayOrdersOnDeliveryArraySize;
3417 EXTR_U8( d, BobbyRayOrdersOnDeliveryArraySize)
3418 EXTR_U8( d, l.usNumberOfBobbyRayOrderUsed)
3419 EXTR_SKIP( d, 6)
3420 UINT8 numLifeInsurancePayouts;
3421 EXTR_U8( d, numLifeInsurancePayouts)
3422 EXTR_U8( d, l.ubNumberLifeInsurancePayoutUsed)
3423 Assert(l.ubNumberLifeInsurancePayoutUsed <= numLifeInsurancePayouts);
3424 EXTR_BOOL( d, l.fBobbyRSiteCanBeAccessed)
3425 EXTR_U8( d, l.ubPlayerBeenToMercSiteStatus)
3426 EXTR_BOOL( d, l.fFirstVisitSinceServerWentDown)
3427 EXTR_BOOL( d, l.fNewMercsAvailableAtMercSite)
3428 EXTR_BOOL( d, l.fSaidGenericOpeningInMercSite)
3429 EXTR_BOOL( d, l.fSpeckSaidFloMarriedCousinQuote)
3430 EXTR_BOOL( d, l.fHasAMercDiedAtMercSite)
3431 EXTR_SKIP( d, 11)
3432 EXTR_U16A( d, l.usInventoryListLength, lengthof(l.usInventoryListLength))
3433 EXTR_I32( d, l.iVoiceId)
3434 EXTR_U8( d, l.ubHaveBeenToBobbyRaysAtLeastOnceWhileUnderConstruction)
3435 EXTR_BOOL( d, l.fMercSiteHasGoneDownYet)
3436 EXTR_U8( d, l.ubSpeckCanSayPlayersLostQuote)
3437 EXTR_SKIP( d, 1)
3438 EXTR_BOOL( d, l.sLastHiredMerc.fHaveDisplayedPopUpInLaptop)
3439 EXTR_SKIP( d, 3)
3440 EXTR_I32( d, l.sLastHiredMerc.iIdOfMerc)
3441 EXTR_U32( d, l.sLastHiredMerc.uiArrivalTime)
3442 EXTR_I32( d, l.iCurrentHistoryPage)
3443 EXTR_I32( d, l.iCurrentFinancesPage)
3444 EXTR_I32( d, l.iCurrentEmailPage)
3445 EXTR_U32( d, l.uiSpeckQuoteFlags)
3446 EXTR_U32( d, l.uiFlowerOrderNumber)
3447 EXTR_U32( d, l.uiTotalMoneyPaidToSpeck)
3448 EXTR_U8( d, l.ubLastMercAvailableId)
3449 EXTR_SKIP( d, 87)
3450 Assert(d.getConsumed() == lengthof(data));
3451
3452 // Handle old saves in M.E.R.C. module
3453 SyncLastMercFromSaveGame();
3454
3455 if (l.usNumberOfBobbyRayOrderUsed != 0)
3456 { // There is anything in the Bobby Ray Orders on Delivery
3457 l.BobbyRayOrdersOnDeliveryArray.resize(BobbyRayOrdersOnDeliveryArraySize);
3458 size_t const size = sizeof(*l.BobbyRayOrdersOnDeliveryArray.data()) * BobbyRayOrdersOnDeliveryArraySize;
3459 FileRead(f, l.BobbyRayOrdersOnDeliveryArray.data(), size);
3460 }
3461 else
3462 {
3463 l.BobbyRayOrdersOnDeliveryArray.clear();
3464 }
3465
3466 if (l.ubNumberLifeInsurancePayoutUsed != 0)
3467 { // There are any Insurance Payouts in progress
3468 l.pLifeInsurancePayouts.assign(numLifeInsurancePayouts, LIFE_INSURANCE_PAYOUT{});
3469 FileRead(f, l.pLifeInsurancePayouts.data(), sizeof(LIFE_INSURANCE_PAYOUT) * numLifeInsurancePayouts);
3470 }
3471 else
3472 {
3473 l.pLifeInsurancePayouts.clear();
3474 }
3475 }
3476
3477
WWaitDelayIncreasedIfRaining(INT32 iUnitTime)3478 static INT32 WWaitDelayIncreasedIfRaining(INT32 iUnitTime)
3479 {
3480 INT32 iRetVal = 0;
3481 if (guiEnvWeather & WEATHER_FORECAST_THUNDERSHOWERS)
3482 {
3483 iRetVal = iUnitTime * 0.8f;
3484 }
3485 else if (guiEnvWeather & WEATHER_FORECAST_SHOWERS)
3486 {
3487 iRetVal = iUnitTime * 0.6f;
3488 }
3489 return iRetVal;
3490 }
3491
3492
3493 // Used to determine delay if its raining
IsItRaining(void)3494 static BOOLEAN IsItRaining(void)
3495 {
3496 return
3497 guiEnvWeather & WEATHER_FORECAST_SHOWERS ||
3498 guiEnvWeather & WEATHER_FORECAST_THUNDERSHOWERS;
3499 }
3500
3501
InternetRainDelayMessageBoxCallBack(MessageBoxReturnValue const bExitValue)3502 static void InternetRainDelayMessageBoxCallBack(MessageBoxReturnValue const bExitValue)
3503 {
3504 GoToWebPage(giRainDelayInternetSite);
3505
3506 //Set to -2 so we dont due the message for this occurence of laptop
3507 giRainDelayInternetSite = -2;
3508 }
3509
3510
CreateFileAndNewEmailIconFastHelpText(UINT32 uiHelpTextID,BOOLEAN fClearHelpText)3511 void CreateFileAndNewEmailIconFastHelpText(UINT32 uiHelpTextID, BOOLEAN fClearHelpText)
3512 {
3513 MOUSE_REGION* pRegion;
3514 switch (uiHelpTextID)
3515 {
3516 case LAPTOP_BN_HLP_TXT_YOU_HAVE_NEW_MAIL: pRegion = &gNewMailIconRegion; break;
3517 case LAPTOP_BN_HLP_TXT_YOU_HAVE_NEW_FILE: pRegion = &gNewFileIconRegion; break;
3518
3519 default:
3520 SLOGA("CreateFileAndNewEmailIconFastHelpText: invalid HelpTextID");
3521 return;
3522 }
3523
3524 ST::string help = (fClearHelpText ? ST::null : gzLaptopHelpText[uiHelpTextID]);
3525 pRegion->SetFastHelpText(help);
3526 }
3527
3528
3529 #ifdef WITH_UNITTESTS
3530 #include "gtest/gtest.h"
3531
TEST(Laptop,asserts)3532 TEST(Laptop, asserts)
3533 {
3534 EXPECT_EQ(sizeof(LIFE_INSURANCE_PAYOUT), 8u);
3535 EXPECT_EQ(sizeof(BobbyRayPurchaseStruct), 8u);
3536 EXPECT_EQ(sizeof(BobbyRayOrderStruct), 84u);
3537 }
3538
3539 #endif
3540