1 #include "Directories.h"
2 #include "Font.h"
3 #include "HImage.h"
4 #include "Laptop.h"
5 #include "BobbyRGuns.h"
6 #include "BobbyR.h"
7 #include "MessageBoxScreen.h"
8 #include "VObject.h"
9 #include "WordWrap.h"
10 #include "Cursors.h"
11 #include "Interface_Items.h"
12 #include "Text.h"
13 #include "Store_Inventory.h"
14 #include "LaptopSave.h"
15 #include "Finances.h"
16 #include "AIMMembers.h"
17 #include "Overhead.h"
18 #include "Weapons.h"
19 #include "Button_System.h"
20 #include "Video.h"
21 #include "VSurface.h"
22 #include "ScreenIDs.h"
23 #include "Font_Control.h"
24 
25 #include "CalibreModel.h"
26 #include "ContentManager.h"
27 #include "GameInstance.h"
28 #include "MagazineModel.h"
29 #include "WeaponModels.h"
30 
31 #include "ContentManager.h"
32 #include "GameInstance.h"
33 #include "policy/GamePolicy.h"
34 #include "Logger.h"
35 
36 #include <string_theory/format>
37 #include <string_theory/string>
38 
39 #include <algorithm>
40 #include <iterator>
41 
42 #define BOBBYR_GRID_PIC_WIDTH		118
43 #define BOBBYR_GRID_PIC_HEIGHT		69
44 
45 #define BOBBYR_GRID_PIC_X		BOBBYR_GRIDLOC_X + 3
46 #define BOBBYR_GRID_PIC_Y		BOBBYR_GRIDLOC_Y + 3
47 
48 #define BOBBYR_GRID_OFFSET		72
49 
50 #define BOBBYR_ORDER_TITLE_FONT		FONT14ARIAL
51 #define BOBBYR_ORDER_TEXT_FONT		FONT10ARIAL
52 #define BOBBYR_ORDER_TEXT_COLOR		75
53 
54 #define BOBBYR_STATIC_TEXT_COLOR	75
55 #define   BOBBYR_ITEM_DESC_TEXT_FONT	FONT10ARIAL
56 #define   BOBBYR_ITEM_DESC_TEXT_COLOR	FONT_MCOLOR_WHITE
57 #define   BOBBYR_ITEM_NAME_TEXT_FONT	FONT10ARIAL
58 #define   BOBBYR_ITEM_NAME_TEXT_COLOR	FONT_MCOLOR_WHITE
59 
60 #define NUM_BOBBYRPAGE_MENU		6
61 #define NUM_CATALOGUE_BUTTONS		5
62 #define BOBBYR_NUM_WEAPONS_ON_PAGE	4
63 
64 #define BOBBYR_BRTITLE_X		LAPTOP_SCREEN_UL_X + 4
65 #define BOBBYR_BRTITLE_Y		LAPTOP_SCREEN_WEB_UL_Y + 3
66 #define BOBBYR_BRTITLE_WIDTH		46
67 #define BOBBYR_BRTITLE_HEIGHT		42
68 
69 #define BOBBYR_TO_ORDER_TITLE_X		(STD_SCREEN_X + 195)
70 #define BOBBYR_TO_ORDER_TITLE_Y		(STD_SCREEN_Y + 42 + LAPTOP_SCREEN_WEB_DELTA_Y)
71 
72 #define BOBBYR_TO_ORDER_TEXT_X		BOBBYR_TO_ORDER_TITLE_X + 75
73 #define BOBBYR_TO_ORDER_TEXT_Y		(STD_SCREEN_Y + 33 + LAPTOP_SCREEN_WEB_DELTA_Y)
74 #define BOBBYR_TO_ORDER_TEXT_WIDTH	330
75 
76 #define BOBBYR_PREVIOUS_BUTTON_X	LAPTOP_SCREEN_UL_X + 5	//BOBBYR_HOME_BUTTON_X + BOBBYR_CATALOGUE_BUTTON_WIDTH + 5
77 #define BOBBYR_PREVIOUS_BUTTON_Y	LAPTOP_SCREEN_WEB_UL_Y + 340	//BOBBYR_HOME_BUTTON_Y
78 
79 #define BOBBYR_NEXT_BUTTON_X		LAPTOP_SCREEN_UL_X + 412	//BOBBYR_ORDER_FORM_X + BOBBYR_ORDER_FORM_WIDTH + 5
80 #define BOBBYR_NEXT_BUTTON_Y		BOBBYR_PREVIOUS_BUTTON_Y	//BOBBYR_PREVIOUS_BUTTON_Y
81 
82 #define BOBBYR_CATALOGUE_BUTTON_START_X	BOBBYR_PREVIOUS_BUTTON_X + 92 	//LAPTOP_SCREEN_UL_X + 93 - BOBBYR_CATALOGUE_BUTTON_WIDTH/2
83 #define BOBBYR_CATALOGUE_BUTTON_GAP	( 318 - NUM_CATALOGUE_BUTTONS * BOBBYR_CATALOGUE_BUTTON_WIDTH) / (NUM_CATALOGUE_BUTTONS + 1) + BOBBYR_CATALOGUE_BUTTON_WIDTH + 1//80
84 #define BOBBYR_CATALOGUE_BUTTON_Y	LAPTOP_SCREEN_WEB_UL_Y + 340
85 #define BOBBYR_CATALOGUE_BUTTON_WIDTH	56//75
86 
87 #define   BOBBYR_HOME_BUTTON_X		(STD_SCREEN_X + 120)
88 #define   BOBBYR_HOME_BUTTON_Y		(STD_SCREEN_Y + 400 + LAPTOP_SCREEN_WEB_DELTA_Y)
89 
90 #define BOBBYR_CATALOGUE_BUTTON_TEXT_Y	BOBBYR_CATALOGUE_BUTTON_Y + 5
91 
92 #define BOBBYR_ITEM_DESC_START_X	BOBBYR_GRIDLOC_X + 172 + 5
93 #define BOBBYR_ITEM_DESC_START_Y	BOBBYR_GRIDLOC_Y + 6
94 #define BOBBYR_ITEM_DESC_START_WIDTH	214 - 10 + 20
95 
96 #define BOBBYR_ITEM_NAME_X		BOBBYR_GRIDLOC_X + 6
97 #define BOBBYR_ITEM_NAME_Y_OFFSET	54
98 
99 #define BOBBYR_ORDER_NUM_WIDTH		15
100 #define BOBBYR_ORDER_NUM_X		BOBBYR_GRIDLOC_X + 120 - BOBBYR_ORDER_NUM_WIDTH	//BOBBYR_ITEM_STOCK_TEXT_X
101 #define BOBBYR_ORDER_NUM_Y_OFFSET	1
102 
103 #define BOBBYR_ITEM_WEIGHT_TEXT_X	BOBBYR_GRIDLOC_X + 409 + 3
104 #define BOBBYR_ITEM_WEIGHT_TEXT_Y	3
105 
106 #define BOBBYR_ITEM_WEIGHT_NUM_X	BOBBYR_GRIDLOC_X + 429 - 2
107 #define BOBBYR_ITEM_WEIGHT_NUM_Y	3
108 #define BOBBYR_ITEM_WEIGHT_NUM_WIDTH	60
109 
110 #define BOBBYR_ITEM_SPEC_GAP		2
111 
112 #define BOBBYR_ITEM_COST_TEXT_X		BOBBYR_GRIDLOC_X + 125
113 #define BOBBYR_ITEM_COST_TEXT_Y		BOBBYR_GRIDLOC_Y + 6
114 #define BOBBYR_ITEM_COST_TEXT_WIDTH	42
115 
116 #define BOBBYR_ITEM_COST_NUM_X		BOBBYR_ITEM_COST_TEXT_X
117 #define BOBBYR_ITEM_COST_NUM_Y		BOBBYR_ITEM_COST_TEXT_Y + 10
118 
119 #define BOBBYR_ITEM_STOCK_TEXT_X	BOBBYR_ITEM_COST_TEXT_X
120 
121 #define BOBBYR_ITEM_QTY_TEXT_X		BOBBYR_GRIDLOC_X + 5//BOBBYR_ITEM_COST_TEXT_X
122 #define BOBBYR_ITEM_QTY_TEXT_Y		BOBBYR_ITEM_COST_TEXT_Y + 28
123 #define BOBBYR_ITEM_QTY_WIDTH		95
124 
125 #define BOBBYR_ITEM_QTY_NUM_X		BOBBYR_GRIDLOC_X + 105//BOBBYR_ITEM_COST_TEXT_X + 1
126 #define BOBBYR_ITEM_QTY_NUM_Y		BOBBYR_ITEM_QTY_TEXT_Y//BOBBYR_ITEM_COST_TEXT_Y + 40
127 
128 #define BOBBYR_ITEMS_BOUGHT_X		BOBBYR_GRIDLOC_X + 105 - BOBBYR_ORDER_NUM_WIDTH//BOBBYR_ITEM_QTY_NUM_X
129 
130 #define BOBBY_RAY_NOT_PURCHASED		255
131 #define BOBBY_RAY_MAX_AMOUNT_OF_ITEMS_TO_PURCHASE	200
132 
133 #define BOBBYR_ORDER_FORM_X		LAPTOP_SCREEN_UL_X + 200//204
134 #define BOBBYR_ORDER_FORM_Y		LAPTOP_SCREEN_WEB_UL_Y + 367
135 #define BOBBYR_ORDER_FORM_WIDTH		95
136 
137 #define BOBBYR_ORDER_SUBTOTAL_X		STD_SCREEN_X + 490
138 #define BOBBYR_ORDER_SUBTOTAL_Y		BOBBYR_ORDER_FORM_Y+2//BOBBYR_HOME_BUTTON_Y
139 
140 #define BOBBYR_PERCENT_FUNTCIONAL_X	BOBBYR_ORDER_SUBTOTAL_X
141 #define BOBBYR_PERCENT_FUNTCIONAL_Y	BOBBYR_ORDER_SUBTOTAL_Y + 15
142 
143 
144 BobbyRayPurchaseStruct BobbyRayPurchases[ MAX_PURCHASE_AMOUNT ];
145 
146 
147 extern	BOOLEAN fExitingLaptopFlag;
148 
149 static SGPVObject* guiGunBackground;
150 static SGPVObject* guiGunsGrid;
151 static SGPVObject* guiBrTitle;
152 
153 UINT16 gusCurWeaponIndex;
154 static UINT8 gubCurPage;
155 static LaptopMode const ubCatalogueButtonValues[] =
156 {
157 	LAPTOP_MODE_BOBBY_R_GUNS,
158 	LAPTOP_MODE_BOBBY_R_AMMO,
159 	LAPTOP_MODE_BOBBY_R_ARMOR,
160 	LAPTOP_MODE_BOBBY_R_MISC,
161 	LAPTOP_MODE_BOBBY_R_USED
162 };
163 
164 static UINT16 gusLastItemIndex  = 0;
165 static UINT16 gusFirstItemIndex = 0;
166 static UINT8  gubNumItemsOnScreen;
167 static UINT8  gubNumPages;
168 
169 static BOOLEAN gfBigImageMouseRegionCreated;
170 static UINT16  gusItemNumberForItemsOnScreen[ BOBBYR_NUM_WEAPONS_ON_PAGE ];
171 
172 
173 static BOOLEAN gfOnUsedPage;
174 
175 static UINT16 gusOldItemNumOnTopOfPage = 65535;
176 
177 //The menu bar at the bottom that changes to different pages
178 static void BtnBobbyRPageMenuCallback(GUI_BUTTON* btn, INT32 reason);
179 static BUTTON_PICS* guiBobbyRPageMenuImage;
180 static GUIButtonRef guiBobbyRPageMenu[NUM_CATALOGUE_BUTTONS];
181 
182 //The next and previous buttons
183 static BUTTON_PICS* guiBobbyRPreviousPageImage;
184 static GUIButtonRef guiBobbyRPreviousPage;
185 
186 static BUTTON_PICS* guiBobbyRNextPageImage;
187 static GUIButtonRef guiBobbyRNextPage;
188 
189 
190 static MOUSE_REGION g_scroll_region;
191 
192 // Big Image Mouse region
193 static MOUSE_REGION gSelectedBigImageRegion[BOBBYR_NUM_WEAPONS_ON_PAGE];
194 
195 // The order form button
196 static void BtnBobbyROrderFormCallback(GUI_BUTTON* btn, INT32 reason);
197 static BUTTON_PICS* guiBobbyROrderFormImage;
198 static GUIButtonRef guiBobbyROrderForm;
199 
200 // The Home button
201 static void BtnBobbyRHomeButtonCallback(GUI_BUTTON* btn, INT32 reason);
202 static BUTTON_PICS* guiBobbyRHomeImage;
203 static GUIButtonRef guiBobbyRHome;
204 
205 
206 // Link from the title
207 static MOUSE_REGION gSelectedTitleImageLinkRegion;
208 
209 
GameInitBobbyRGuns()210 void GameInitBobbyRGuns()
211 {
212 	std::fill_n(BobbyRayPurchases, MAX_PURCHASE_AMOUNT, BobbyRayPurchaseStruct{});
213 }
214 
215 
EnterBobbyRGuns()216 void EnterBobbyRGuns()
217 {
218 	gfBigImageMouseRegionCreated = FALSE;
219 
220 	// load the background graphic and add it
221 	guiGunBackground = AddVideoObjectFromFile(LAPTOPDIR "/gunbackground.sti");
222 
223 	// load the gunsgrid graphic and add it
224 	guiGunsGrid = AddVideoObjectFromFile(LAPTOPDIR "/gunsgrid.sti");
225 
226 	InitBobbyBrTitle();
227 
228 
229 	SetFirstLastPagesForNew( IC_BOBBY_GUN );
230 	//Draw menu bar
231 	InitBobbyMenuBar();
232 
233 	// render once
234 	RenderBobbyRGuns( );
235 
236 	//RenderBobbyRGuns();
237 }
238 
239 
ExitBobbyRGuns()240 void ExitBobbyRGuns()
241 {
242 	DeleteVideoObject(guiGunBackground);
243 	DeleteVideoObject(guiGunsGrid);
244 	DeleteBobbyBrTitle();
245 	DeleteBobbyMenuBar();
246 
247 	DeleteMouseRegionForBigImage();
248 
249 	giCurrentSubPage = gusCurWeaponIndex;
250 	guiLastBobbyRayPage = LAPTOP_MODE_BOBBY_R_GUNS;
251 }
252 
253 
RenderBobbyRGuns()254 void RenderBobbyRGuns()
255 {
256 	WebPageTileBackground(BOBBYR_NUM_HORIZONTAL_TILES, BOBBYR_NUM_VERTICAL_TILES, BOBBYR_BACKGROUND_WIDTH, BOBBYR_BACKGROUND_HEIGHT, guiGunBackground);
257 
258 	//Display title at top of page
259 	DisplayBobbyRBrTitle();
260 
261 	BltVideoObject(FRAME_BUFFER, guiGunsGrid, 0, BOBBYR_GRIDLOC_X, BOBBYR_GRIDLOC_Y);
262 
263 	//DeleteMouseRegionForBigImage();
264 	DisplayItemInfo( IC_BOBBY_GUN );
265 	UpdateButtonText(guiCurrentLaptopMode);
266 	MarkButtonsDirty( );
267 	RenderWWWProgramTitleBar( );
268 	InvalidateScreen();
269 }
270 
271 
DisplayBobbyRBrTitle()272 void DisplayBobbyRBrTitle()
273 {
274 	BltVideoObject(FRAME_BUFFER, guiBrTitle, 0, BOBBYR_BRTITLE_X, BOBBYR_BRTITLE_Y);
275 
276 	// To Order Text
277 	DrawTextToScreen(BobbyRText[BOBBYR_GUNS_TO_ORDER], BOBBYR_TO_ORDER_TITLE_X, BOBBYR_TO_ORDER_TITLE_Y, 0, BOBBYR_ORDER_TITLE_FONT, BOBBYR_ORDER_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
278 
279 	//First put a shadow behind the image
280 	FRAME_BUFFER->ShadowRect(BOBBYR_TO_ORDER_TEXT_X - 2, BOBBYR_TO_ORDER_TEXT_Y - 2, BOBBYR_TO_ORDER_TEXT_X + BOBBYR_TO_ORDER_TEXT_WIDTH, BOBBYR_TO_ORDER_TEXT_Y + 31);
281 
282 	//To Order text
283 	DisplayWrappedString(BOBBYR_TO_ORDER_TEXT_X, BOBBYR_TO_ORDER_TEXT_Y, BOBBYR_TO_ORDER_TEXT_WIDTH, 2, BOBBYR_ORDER_TEXT_FONT, BOBBYR_ORDER_TEXT_COLOR, BobbyRText[BOBBYR_GUNS_CLICK_ON_ITEMS], FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
284 }
285 
286 
287 static void SelectTitleImageLinkRegionCallBack(MOUSE_REGION* pRegion, INT32 iReason);
288 
289 
InitBobbyBrTitle()290 void InitBobbyBrTitle()
291 {
292 	// load the br title graphic and add it
293 	guiBrTitle = AddVideoObjectFromFile(LAPTOPDIR "/br.sti");
294 
295 	//initialize the link to the homepage by clicking on the title
296 	MSYS_DefineRegion(&gSelectedTitleImageLinkRegion, BOBBYR_BRTITLE_X, BOBBYR_BRTITLE_Y,
297 				(BOBBYR_BRTITLE_X + BOBBYR_BRTITLE_WIDTH),
298 				(UINT16)(BOBBYR_BRTITLE_Y + BOBBYR_BRTITLE_HEIGHT),
299 				MSYS_PRIORITY_HIGH,
300 				CURSOR_WWW, MSYS_NO_CALLBACK, SelectTitleImageLinkRegionCallBack);
301 
302 	gusOldItemNumOnTopOfPage=65535;
303 }
304 
305 
DeleteBobbyBrTitle()306 void DeleteBobbyBrTitle()
307 {
308 	DeleteVideoObject(guiBrTitle);
309 	MSYS_RemoveRegion(&gSelectedTitleImageLinkRegion);
310 	DeleteMouseRegionForBigImage();
311 }
312 
313 
SelectTitleImageLinkRegionCallBack(MOUSE_REGION * pRegion,INT32 iReason)314 static void SelectTitleImageLinkRegionCallBack(MOUSE_REGION* pRegion, INT32 iReason)
315 {
316 	if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP)
317 	{
318 		guiCurrentLaptopMode = LAPTOP_MODE_BOBBY_R;
319 	}
320 }
321 
322 
MakeButton(BUTTON_PICS * img,const ST::string & text,INT16 x,INT16 y,GUI_CALLBACK click)323 static GUIButtonRef MakeButton(BUTTON_PICS* img, const ST::string& text, INT16 x, INT16 y, GUI_CALLBACK click)
324 {
325 	const INT16 shadow_col = BOBBYR_GUNS_SHADOW_COLOR;
326 	GUIButtonRef const btn = CreateIconAndTextButton(img, text, BOBBYR_GUNS_BUTTON_FONT, BOBBYR_GUNS_TEXT_COLOR_ON, shadow_col, BOBBYR_GUNS_TEXT_COLOR_OFF, shadow_col, x, y, MSYS_PRIORITY_HIGH, click);
327 	btn->SetCursor(CURSOR_LAPTOP_SCREEN);
328 	return btn;
329 }
330 
331 
332 static void BtnBobbyRNextPageCallback(GUI_BUTTON*, INT32 reason);
333 static void BtnBobbyRPreviousPageCallback(GUI_BUTTON*, INT32 reason);
334 
335 
InitBobbyMenuBar()336 void InitBobbyMenuBar()
337 {
338 	// Previous button
339 	guiBobbyRPreviousPageImage = LoadButtonImage(LAPTOPDIR "/previousbutton.sti", 0, 1);
340 	guiBobbyRPreviousPage      = MakeButton(guiBobbyRPreviousPageImage, BobbyRText[BOBBYR_GUNS_PREVIOUS_ITEMS], BOBBYR_PREVIOUS_BUTTON_X, BOBBYR_PREVIOUS_BUTTON_Y, BtnBobbyRPreviousPageCallback);
341 	guiBobbyRPreviousPage->SpecifyDisabledStyle(GUI_BUTTON::DISABLED_STYLE_SHADED);
342 
343 	// Next button
344 	guiBobbyRNextPageImage = LoadButtonImage(LAPTOPDIR "/nextbutton.sti", 0, 1);
345 	guiBobbyRNextPage      = MakeButton(guiBobbyRNextPageImage, BobbyRText[BOBBYR_GUNS_MORE_ITEMS], BOBBYR_NEXT_BUTTON_X, BOBBYR_NEXT_BUTTON_Y, BtnBobbyRNextPageCallback);
346 	guiBobbyRNextPage->SpecifyDisabledStyle(GUI_BUTTON::DISABLED_STYLE_SHADED);
347 
348 	BUTTON_PICS* const gfx = LoadButtonImage(LAPTOPDIR "/cataloguebutton1.sti", 0, 1);
349 	guiBobbyRPageMenuImage = gfx;
350 
351 	UINT16             x    = BOBBYR_CATALOGUE_BUTTON_START_X;
352 	UINT16     const   y    = BOBBYR_CATALOGUE_BUTTON_Y;
353 	const ST::string* text = BobbyRText + BOBBYR_GUNS_GUNS;
354 	LaptopMode const*  mode = ubCatalogueButtonValues;
355 	FOR_EACHX(GUIButtonRef, i, guiBobbyRPageMenu, x += BOBBYR_CATALOGUE_BUTTON_GAP)
356 	{
357 		// Catalogue buttons
358 		GUIButtonRef const b = MakeButton(gfx, *text++, x, y, BtnBobbyRPageMenuCallback);
359 		b->SetUserData(*mode++);
360 		*i = b;
361 	}
362 
363 	// Order Form button
364 	guiBobbyROrderFormImage = LoadButtonImage(LAPTOPDIR "/orderformbutton.sti", 0, 1);
365 	guiBobbyROrderForm      = MakeButton(guiBobbyROrderFormImage, BobbyRText[BOBBYR_GUNS_ORDER_FORM], BOBBYR_ORDER_FORM_X, BOBBYR_ORDER_FORM_Y, BtnBobbyROrderFormCallback);
366 
367 	// Home button
368 	guiBobbyRHomeImage = LoadButtonImage(LAPTOPDIR "/cataloguebutton.sti", 0, 1);
369 	guiBobbyRHome      = MakeButton(guiBobbyRHomeImage, BobbyRText[BOBBYR_GUNS_HOME], BOBBYR_HOME_BUTTON_X, BOBBYR_HOME_BUTTON_Y, BtnBobbyRHomeButtonCallback);
370 }
371 
372 
DeleteBobbyMenuBar()373 void DeleteBobbyMenuBar()
374 {
375 	RemoveButton(guiBobbyRPreviousPage);
376 	UnloadButtonImage(guiBobbyRPreviousPageImage);
377 
378 	RemoveButton(guiBobbyRNextPage);
379 	UnloadButtonImage(guiBobbyRNextPageImage);
380 
381 	FOR_EACH(GUIButtonRef, i, guiBobbyRPageMenu) RemoveButton(*i);
382 	UnloadButtonImage(guiBobbyRPageMenuImage);
383 
384 	RemoveButton(guiBobbyROrderForm);
385 	UnloadButtonImage(guiBobbyROrderFormImage);
386 
387 	RemoveButton(guiBobbyRHome);
388 	UnloadButtonImage(guiBobbyRHomeImage);
389 }
390 
391 
BtnBobbyRPageMenuCallback(GUI_BUTTON * btn,INT32 reason)392 static void BtnBobbyRPageMenuCallback(GUI_BUTTON* btn, INT32 reason)
393 {
394 	if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
395 	{
396 		UpdateButtonText(guiCurrentLaptopMode);
397 		guiCurrentLaptopMode = static_cast<LaptopMode>(btn->GetUserData());
398 	}
399 }
400 
401 
NextPage()402 static void NextPage()
403 {
404 	if (gubCurPage == gubNumPages - 1) return;
405 	++gubCurPage;
406 	DeleteMouseRegionForBigImage();
407 	fReDrawScreenFlag       = TRUE;
408 	fPausedReDrawScreenFlag = TRUE;
409 }
410 
411 
BtnBobbyRNextPageCallback(GUI_BUTTON * const btn,INT32 const reason)412 static void BtnBobbyRNextPageCallback(GUI_BUTTON* const btn, INT32 const reason)
413 {
414 	if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
415 	{
416 		NextPage();
417 	}
418 }
419 
420 
PrevPage()421 static void PrevPage()
422 {
423 	if (gubCurPage == 0) return;
424 	--gubCurPage;
425 	DeleteMouseRegionForBigImage();
426 	fReDrawScreenFlag       = TRUE;
427 	fPausedReDrawScreenFlag = TRUE;
428 }
429 
430 
BtnBobbyRPreviousPageCallback(GUI_BUTTON * const btn,INT32 const reason)431 static void BtnBobbyRPreviousPageCallback(GUI_BUTTON* const btn, INT32 const reason)
432 {
433 	if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
434 	{
435 		PrevPage();
436 	}
437 }
438 
439 
440 static void CalcFirstIndexForPage(STORE_INVENTORY* pInv, UINT32 uiItemClass);
441 static UINT32 CalculateTotalPurchasePrice();
442 static void CreateMouseRegionForBigImage(UINT16 usPosY, UINT8 ubCount, const ItemModel* const items[]);
443 static void DisableBobbyRButtons(void);
444 static void DisplayAmmoInfo(UINT16 usIndex, UINT16 usTextPosY, BOOLEAN fUsed, UINT16 usBobbyIndex);
445 static void DisplayArmourInfo(UINT16 usIndex, UINT16 usTextPosY, BOOLEAN fUsed, UINT16 usBobbyIndex);
446 static void DisplayBigItemImage(const ItemModel* item, UINT16 PosY);
447 static void DisplayGunInfo(UINT16 usIndex, UINT16 usTextPosY, BOOLEAN fUsed, UINT16 usBobbyIndex);
448 static void DisplayItemNameAndInfo(UINT16 usPosY, UINT16 usIndex, UINT16 usBobbyIndex, BOOLEAN fUsed);
449 static void DisplayMiscInfo(UINT16 usIndex, UINT16 usTextPosY, BOOLEAN fUsed, UINT16 usBobbyIndex);
450 static void DisplayNonGunWeaponInfo(UINT16 usIndex, UINT16 usTextPosY, BOOLEAN fUsed, UINT16 usBobbyIndex);
451 
452 
DisplayItemInfo(UINT32 uiItemClass)453 void DisplayItemInfo(UINT32 uiItemClass)
454 {
455 	UINT16  i;
456 	UINT8   ubCount=0;
457 	UINT16  PosY, usTextPosY;
458 	UINT16  usItemIndex;
459 	ST::string sDollarTemp;
460 	ST::string sTemp;
461 
462 	PosY = BOBBYR_GRID_PIC_Y;
463 	usTextPosY = BOBBYR_ITEM_DESC_START_Y;
464 
465 	//if there are no items then return
466 	if( gusFirstItemIndex == BOBBYR_NO_ITEMS )
467 	{
468 		if (fExitingLaptopFlag) return;
469 		if (gfShowBookmarks)	return;
470 		if (fLoadPendingFlag)	return;
471 
472 		DisableBobbyRButtons();
473 
474 		//Display a popup saying we are out of stock
475 		DoLapTopMessageBox(MSG_BOX_LAPTOP_DEFAULT, BobbyRText[BOBBYR_NO_MORE_STOCK], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, 0);
476 		return;
477 	}
478 
479 
480 	if( uiItemClass == BOBBYR_USED_ITEMS )
481 		CalcFirstIndexForPage(LaptopSaveInfo.BobbyRayUsedInventory, IC_ALL);
482 	else
483 		CalcFirstIndexForPage( LaptopSaveInfo.BobbyRayInventory, uiItemClass );
484 
485 	DisableBobbyRButtons();
486 
487 	if( gusOldItemNumOnTopOfPage != gusCurWeaponIndex )
488 	{
489 		DeleteMouseRegionForBigImage();
490 
491 	}
492 
493 	const ItemModel* items[BOBBYR_NUM_WEAPONS_ON_PAGE];
494 	std::fill(std::begin(items), std::end(items), nullptr);
495 	for(i=gusCurWeaponIndex; ((i<=gusLastItemIndex) && (ubCount < 4)); i++)
496 	{
497 		if( uiItemClass == BOBBYR_USED_ITEMS )
498 		{
499 			//If there is not items in stock
500 			if( LaptopSaveInfo.BobbyRayUsedInventory[ i ].ubQtyOnHand == 0 )
501 				continue;
502 
503 			usItemIndex = LaptopSaveInfo.BobbyRayUsedInventory[ i ].usItemIndex;
504 			gfOnUsedPage = TRUE;
505 		}
506 		else
507 		{
508 			//If there is not items in stock
509 			if( LaptopSaveInfo.BobbyRayInventory[ i ].ubQtyOnHand == 0 )
510 				continue;
511 
512 			usItemIndex = LaptopSaveInfo.BobbyRayInventory[ i ].usItemIndex;
513 			gfOnUsedPage = FALSE;
514 		}
515 
516 		// skip items that aren't of the right item class
517 		const ItemModel * item = GCM->getItem(usItemIndex);
518 		if (!(item->getItemClass() & uiItemClass)) continue;
519 
520 		items[ubCount] = item;
521 
522 		switch (item->getItemClass())
523 		{
524 			case IC_GUN:
525 			case IC_LAUNCHER:
526 				gusItemNumberForItemsOnScreen[ ubCount ] = i;
527 
528 				DisplayBigItemImage(item, PosY);
529 
530 				//Display Items Name
531 				DisplayItemNameAndInfo(usTextPosY, usItemIndex, i, gfOnUsedPage);
532 
533 				DisplayGunInfo(usItemIndex, usTextPosY, gfOnUsedPage, i);
534 
535 				PosY += BOBBYR_GRID_OFFSET;
536 				usTextPosY += BOBBYR_GRID_OFFSET;
537 				ubCount++;
538 				break;
539 
540 			case IC_AMMO:
541 				gusItemNumberForItemsOnScreen[ ubCount ] = i;
542 
543 				DisplayBigItemImage(item, PosY);
544 
545 				//Display Items Name
546 				DisplayItemNameAndInfo(usTextPosY, usItemIndex, i, gfOnUsedPage);
547 
548 				DisplayAmmoInfo( usItemIndex, usTextPosY, gfOnUsedPage, i);
549 
550 				PosY += BOBBYR_GRID_OFFSET;
551 				usTextPosY += BOBBYR_GRID_OFFSET;
552 				ubCount++;
553 				break;
554 
555 			case IC_ARMOUR:
556 				gusItemNumberForItemsOnScreen[ ubCount ] = i;
557 
558 				DisplayBigItemImage(item, PosY);
559 
560 				//Display Items Name
561 				DisplayItemNameAndInfo(usTextPosY, usItemIndex, i, gfOnUsedPage);
562 
563 				DisplayArmourInfo( usItemIndex, usTextPosY, gfOnUsedPage, i);
564 
565 				PosY += BOBBYR_GRID_OFFSET;
566 				usTextPosY += BOBBYR_GRID_OFFSET;
567 				ubCount++;
568 				break;
569 
570 			case IC_BLADE:
571 			case IC_THROWING_KNIFE:
572 			case IC_PUNCH:
573 				gusItemNumberForItemsOnScreen[ ubCount ] = i;
574 
575 				DisplayBigItemImage(item, PosY);
576 
577 				//Display Items Name
578 				DisplayItemNameAndInfo(usTextPosY, usItemIndex, i, gfOnUsedPage);
579 
580 				DisplayNonGunWeaponInfo(usItemIndex, usTextPosY, gfOnUsedPage, i);
581 
582 				PosY += BOBBYR_GRID_OFFSET;
583 				usTextPosY += BOBBYR_GRID_OFFSET;
584 				ubCount++;
585 				break;
586 
587 			case IC_GRENADE:
588 			case IC_BOMB:
589 			case IC_MISC:
590 			case IC_MEDKIT:
591 			case IC_KIT:
592 			case IC_FACE:
593 				gusItemNumberForItemsOnScreen[ ubCount ] = i;
594 
595 				DisplayBigItemImage(item, PosY);
596 
597 				//Display Items Name
598 				DisplayItemNameAndInfo(usTextPosY, usItemIndex, i, gfOnUsedPage);
599 
600 				DisplayMiscInfo( usItemIndex, usTextPosY, gfOnUsedPage, i);
601 
602 				PosY += BOBBYR_GRID_OFFSET;
603 				usTextPosY += BOBBYR_GRID_OFFSET;
604 				ubCount++;
605 				break;
606 		}
607 	}
608 
609 	if( gusOldItemNumOnTopOfPage != gusCurWeaponIndex )
610 	{
611 		CreateMouseRegionForBigImage(BOBBYR_GRID_PIC_Y, ubCount, items);
612 		gusOldItemNumOnTopOfPage = gusCurWeaponIndex;
613 	}
614 
615 	//Display the subtotal at the bottom of the screen
616 	sDollarTemp = SPrintMoney(CalculateTotalPurchasePrice());
617 	sTemp = ST::format("{} {}", BobbyRText[BOBBYR_GUNS_SUB_TOTAL], sDollarTemp);
618 	DrawTextToScreen(sTemp, BOBBYR_ORDER_SUBTOTAL_X, BOBBYR_ORDER_SUBTOTAL_Y, 0, BOBBYR_ORDER_TITLE_FONT, BOBBYR_ORDER_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED | TEXT_SHADOWED);
619 
620 	//Display the Used item disclaimer
621 	if( gfOnUsedPage )
622 	{
623 		DrawTextToScreen(BobbyRText[BOBBYR_GUNS_PERCENT_FUNCTIONAL], BOBBYR_PERCENT_FUNTCIONAL_X, BOBBYR_PERCENT_FUNTCIONAL_Y, 0, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_ORDER_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED | TEXT_SHADOWED);
624 	}
625 }
626 
627 
628 static UINT16 DisplayCaliber(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight);
629 static UINT16 DisplayCostAndQty(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight, UINT16 usBobbyIndex, BOOLEAN fUsed);
630 static UINT16 DisplayDamage(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight);
631 static UINT16 DisplayMagazine(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight);
632 static UINT16 DisplayRange(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight);
633 static UINT16 DisplayRof(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight);
634 
635 
DisplayGunInfo(UINT16 usIndex,UINT16 usTextPosY,BOOLEAN fUsed,UINT16 usBobbyIndex)636 static void DisplayGunInfo(UINT16 usIndex, UINT16 usTextPosY, BOOLEAN fUsed, UINT16 usBobbyIndex)
637 {
638 	UINT16	usHeight;
639 	UINT16 usFontHeight;
640 	usFontHeight = GetFontHeight(BOBBYR_ITEM_DESC_TEXT_FONT);
641 
642 	//Display Items Name
643 	//DisplayItemNameAndInfo(usTextPosY, usIndex, fUsed);
644 
645 	usHeight = usTextPosY;
646 	//Display the weight, caliber, mag, rng, dam, rof text
647 
648 	//Caliber
649 	usHeight = DisplayCaliber(usHeight, usIndex, usFontHeight);
650 
651 	//Magazine
652 	usHeight = DisplayMagazine(usHeight, usIndex, usFontHeight);
653 
654 	//Range
655 	usHeight = DisplayRange(usHeight, usIndex, usFontHeight);
656 
657 	//Damage
658 	usHeight = DisplayDamage(usHeight, usIndex, usFontHeight);
659 
660 	//ROF
661 	usHeight = DisplayRof(usHeight, usIndex, usFontHeight);
662 
663 	//Display the Cost and the qty bought and on hand
664 	usHeight = DisplayCostAndQty(usTextPosY, usIndex, usFontHeight, usBobbyIndex, fUsed);
665 }
666 
667 
DisplayNonGunWeaponInfo(UINT16 usIndex,UINT16 usTextPosY,BOOLEAN fUsed,UINT16 usBobbyIndex)668 static void DisplayNonGunWeaponInfo(UINT16 usIndex, UINT16 usTextPosY, BOOLEAN fUsed, UINT16 usBobbyIndex)
669 {
670 	UINT16	usHeight;
671 	UINT16 usFontHeight;
672 	usFontHeight = GetFontHeight(BOBBYR_ITEM_DESC_TEXT_FONT);
673 
674 	//Display Items Name
675 	//DisplayItemNameAndInfo(usTextPosY, usIndex, fUsed);
676 
677 	usHeight = usTextPosY;
678 	//Display the weight, caliber, mag, rng, dam, rof text
679 
680 	//Damage
681 	usHeight = DisplayDamage(usHeight, usIndex, usFontHeight);
682 
683 	//Display the Cost and the qty bought and on hand
684 	usHeight = DisplayCostAndQty(usTextPosY, usIndex, usFontHeight, usBobbyIndex, fUsed);
685 }
686 
687 
DisplayAmmoInfo(UINT16 usIndex,UINT16 usTextPosY,BOOLEAN fUsed,UINT16 usBobbyIndex)688 static void DisplayAmmoInfo(UINT16 usIndex, UINT16 usTextPosY, BOOLEAN fUsed, UINT16 usBobbyIndex)
689 {
690 	UINT16	usHeight;
691 	UINT16 usFontHeight;
692 	usFontHeight = GetFontHeight(BOBBYR_ITEM_DESC_TEXT_FONT);
693 
694 	//Display Items Name
695 	//DisplayItemNameAndInfo(usTextPosY, usIndex, fUsed);
696 
697 	usHeight = usTextPosY;
698 	//Display the weight, caliber, mag, rng, dam, rof text
699 
700 	//Caliber
701 	usHeight = DisplayCaliber(usHeight, usIndex, usFontHeight);
702 
703 	//Magazine
704 	//usHeight = DisplayMagazine(usHeight, usIndex, usFontHeight);
705 
706 	//Display the Cost and the qty bought and on hand
707 	usHeight = DisplayCostAndQty(usTextPosY, usIndex, usFontHeight, usBobbyIndex, fUsed);
708 }
709 
710 
DisplayBigItemImage(const ItemModel * item,const UINT16 PosY)711 static void DisplayBigItemImage(const ItemModel* item, const UINT16 PosY)
712 {
713 	INT16 PosX = BOBBYR_GRID_PIC_X;
714 
715 	AutoSGPVObject uiImage(LoadTileGraphicForItem(item));
716 
717 	//center picture in frame
718 	ETRLEObject const& pTrav   = uiImage->SubregionProperties(0);
719 	UINT32      const  usWidth = pTrav.usWidth;
720 	INT16       const  sCenX   = PosX + ABS(BOBBYR_GRID_PIC_WIDTH - usWidth) / 2 - pTrav.sOffsetX;
721 	INT16       const  sCenY   = PosY + 8;
722 
723 	if (gamepolicy(f_draw_item_shadow))
724 	{
725 		//blt the shadow of the item
726 		BltVideoObjectOutlineShadow(FRAME_BUFFER, uiImage.get(), 0, sCenX - 2, sCenY + 2);
727 	}
728 
729 	BltVideoObject(FRAME_BUFFER, uiImage.get(), 0, sCenX, sCenY);
730 }
731 
732 
DisplayArmourInfo(UINT16 usIndex,UINT16 usTextPosY,BOOLEAN fUsed,UINT16 usBobbyIndex)733 static void DisplayArmourInfo(UINT16 usIndex, UINT16 usTextPosY, BOOLEAN fUsed, UINT16 usBobbyIndex)
734 {
735 	UINT16 usFontHeight = GetFontHeight(BOBBYR_ITEM_DESC_TEXT_FONT);
736 
737 	//Display the Cost and the qty bought and on hand
738 	DisplayCostAndQty(usTextPosY, usIndex, usFontHeight, usBobbyIndex, fUsed);
739 }
740 
741 
DisplayMiscInfo(UINT16 usIndex,UINT16 usTextPosY,BOOLEAN fUsed,UINT16 usBobbyIndex)742 static void DisplayMiscInfo(UINT16 usIndex, UINT16 usTextPosY, BOOLEAN fUsed, UINT16 usBobbyIndex)
743 {
744 	UINT16 usFontHeight;
745 	usFontHeight = GetFontHeight(BOBBYR_ITEM_DESC_TEXT_FONT);
746 
747 	//Display Items Name
748 	//DisplayItemNameAndInfo(usTextPosY, usIndex, fUsed);
749 
750 	//Display the Cost and the qty bought and on hand
751 	DisplayCostAndQty(usTextPosY, usIndex, usFontHeight, usBobbyIndex, fUsed);
752 }
753 
754 
755 static UINT8 CheckIfItemIsPurchased(UINT16 usItemNumber);
756 
757 
DisplayCostAndQty(UINT16 usPosY,UINT16 usIndex,UINT16 usFontHeight,UINT16 usBobbyIndex,BOOLEAN fUsed)758 static UINT16 DisplayCostAndQty(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight, UINT16 usBobbyIndex, BOOLEAN fUsed)
759 {
760 	ST::string sTemp;
761 	//UINT8	ubPurchaseNumber;
762 
763 	//
764 	//Display the cost and the qty
765 	//
766 
767 	//Display the cost
768 	DrawTextToScreen(BobbyRText[BOBBYR_GUNS_COST], BOBBYR_ITEM_COST_TEXT_X, usPosY, BOBBYR_ITEM_COST_TEXT_WIDTH, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_STATIC_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
769 	usPosY += usFontHeight + 2;
770 
771 	DrawTextToScreen(SPrintMoney(CalcBobbyRayCost(usIndex, usBobbyIndex, fUsed)), BOBBYR_ITEM_COST_NUM_X, usPosY, BOBBYR_ITEM_COST_TEXT_WIDTH, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_ITEM_DESC_TEXT_COLOR, FONT_MCOLOR_BLACK, RIGHT_JUSTIFIED);
772 	usPosY += usFontHeight + 2;
773 
774 
775 	//Display Weight Number
776 	DrawTextToScreen(BobbyRText[BOBBYR_GUNS_WGHT], BOBBYR_ITEM_STOCK_TEXT_X, usPosY, BOBBYR_ITEM_COST_TEXT_WIDTH, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_STATIC_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
777 	usPosY += usFontHeight + 2;
778 
779 
780 	sTemp = ST::format("{3.2f} {}", GetWeightBasedOnMetricOption(GCM->getItem(usIndex)->getWeight()) / 10.0f, GetWeightUnitString());
781 	DrawTextToScreen(sTemp, BOBBYR_ITEM_STOCK_TEXT_X, usPosY, BOBBYR_ITEM_COST_TEXT_WIDTH, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_ITEM_DESC_TEXT_COLOR, FONT_MCOLOR_BLACK, RIGHT_JUSTIFIED);
782 	usPosY += usFontHeight + 2;
783 
784 
785 	//Display the # In Stock
786 	DrawTextToScreen(BobbyRText[BOBBYR_GUNS_IN_STOCK], BOBBYR_ITEM_STOCK_TEXT_X, usPosY, BOBBYR_ITEM_COST_TEXT_WIDTH, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_STATIC_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
787 	usPosY += usFontHeight + 2;
788 
789 	if( fUsed )
790 		sTemp = ST::format("{_ 4d}", LaptopSaveInfo.BobbyRayUsedInventory[ usBobbyIndex ].ubQtyOnHand);
791 	else
792 		sTemp = ST::format("{_ 4d}", LaptopSaveInfo.BobbyRayInventory[ usBobbyIndex ].ubQtyOnHand);
793 
794 	DrawTextToScreen(sTemp, BOBBYR_ITEM_STOCK_TEXT_X, usPosY, BOBBYR_ITEM_COST_TEXT_WIDTH, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_ITEM_DESC_TEXT_COLOR, FONT_MCOLOR_BLACK, RIGHT_JUSTIFIED);
795 	usPosY += usFontHeight + 2;
796 
797 
798 	return(usPosY);
799 }
800 
801 
DisplayRof(UINT16 usPosY,UINT16 usIndex,UINT16 usFontHeight)802 static UINT16 DisplayRof(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight)
803 {
804 	ST::string sTemp;
805 
806 	DrawTextToScreen(BobbyRText[BOBBYR_GUNS_ROF], BOBBYR_ITEM_WEIGHT_TEXT_X, usPosY, 0, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_STATIC_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
807 
808 	sTemp = ST::format("{3d}/{}", GCM->getWeapon(usIndex)->getRateOfFire(), pMessageStrings[ MSG_MINUTE_ABBREVIATION ]);
809 
810 
811 	DrawTextToScreen(sTemp, BOBBYR_ITEM_WEIGHT_NUM_X, usPosY, BOBBYR_ITEM_WEIGHT_NUM_WIDTH, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_ITEM_DESC_TEXT_COLOR, FONT_MCOLOR_BLACK, RIGHT_JUSTIFIED);
812 	usPosY += usFontHeight + 2;
813 	return(usPosY);
814 }
815 
816 
DisplayDamage(UINT16 usPosY,UINT16 usIndex,UINT16 usFontHeight)817 static UINT16 DisplayDamage(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight)
818 {
819 	ST::string sTemp;
820 
821 	DrawTextToScreen(BobbyRText[BOBBYR_GUNS_DAMAGE], BOBBYR_ITEM_WEIGHT_TEXT_X, usPosY, 0, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_STATIC_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
822 	sTemp = ST::format("{4d}", GCM->getWeapon( usIndex )->ubImpact);
823 	DrawTextToScreen(sTemp, BOBBYR_ITEM_WEIGHT_NUM_X, usPosY, BOBBYR_ITEM_WEIGHT_NUM_WIDTH, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_ITEM_DESC_TEXT_COLOR, FONT_MCOLOR_BLACK, RIGHT_JUSTIFIED);
824 	usPosY += usFontHeight + 2;
825 	return(usPosY);
826 }
827 
828 
DisplayRange(UINT16 usPosY,UINT16 usIndex,UINT16 usFontHeight)829 static UINT16 DisplayRange(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight)
830 {
831 	ST::string sTemp;
832 
833 	DrawTextToScreen(BobbyRText[BOBBYR_GUNS_RANGE], BOBBYR_ITEM_WEIGHT_TEXT_X, usPosY, 0, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_STATIC_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
834 	sTemp = ST::format("{3d} {}", GCM->getWeapon( usIndex )->usRange, pMessageStrings[ MSG_METER_ABBREVIATION ]);
835 	DrawTextToScreen(sTemp, BOBBYR_ITEM_WEIGHT_NUM_X, usPosY, BOBBYR_ITEM_WEIGHT_NUM_WIDTH, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_ITEM_DESC_TEXT_COLOR, FONT_MCOLOR_BLACK, RIGHT_JUSTIFIED);
836 	usPosY += usFontHeight + 2;
837 	return(usPosY);
838 }
839 
840 
DisplayMagazine(UINT16 usPosY,UINT16 usIndex,UINT16 usFontHeight)841 static UINT16 DisplayMagazine(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight)
842 {
843 	ST::string sTemp;
844 
845 	DrawTextToScreen(BobbyRText[BOBBYR_GUNS_MAGAZINE], BOBBYR_ITEM_WEIGHT_TEXT_X, usPosY, 0, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_STATIC_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
846 	sTemp = ST::format("{3d} {}", GCM->getWeapon(usIndex)->ubMagSize, pMessageStrings[ MSG_ROUNDS_ABBREVIATION ]);
847 	DrawTextToScreen(sTemp, BOBBYR_ITEM_WEIGHT_NUM_X, usPosY, BOBBYR_ITEM_WEIGHT_NUM_WIDTH, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_ITEM_DESC_TEXT_COLOR, FONT_MCOLOR_BLACK, RIGHT_JUSTIFIED);
848 	usPosY += usFontHeight + 2;
849 	return(usPosY);
850 }
851 
852 
DisplayCaliber(UINT16 usPosY,UINT16 usIndex,UINT16 usFontHeight)853 static UINT16 DisplayCaliber(UINT16 usPosY, UINT16 usIndex, UINT16 usFontHeight)
854 {
855 	const ItemModel * item = GCM->getItem(usIndex);
856 	ST::string zTemp;
857 	DrawTextToScreen(BobbyRText[BOBBYR_GUNS_CALIBRE], BOBBYR_ITEM_WEIGHT_TEXT_X, usPosY, 0, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_STATIC_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
858 
859 	// ammo or gun?
860 	const CalibreModel *calibre = item->getItemClass() == IC_AMMO ? item->asAmmo()->calibre : item->asWeapon()->calibre;
861 	zTemp = *GCM->getCalibreNameForBobbyRay(calibre->index);
862 
863 	zTemp = ReduceStringLength(zTemp, BOBBYR_GRID_PIC_WIDTH, BOBBYR_ITEM_NAME_TEXT_FONT);
864 	DrawTextToScreen(zTemp, BOBBYR_ITEM_WEIGHT_NUM_X, usPosY, BOBBYR_ITEM_WEIGHT_NUM_WIDTH, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_ITEM_DESC_TEXT_COLOR, FONT_MCOLOR_BLACK, RIGHT_JUSTIFIED);
865 
866 	usPosY += usFontHeight + 2;
867 	return(usPosY);
868 }
869 
870 
DisplayItemNameAndInfo(UINT16 usPosY,UINT16 usIndex,UINT16 usBobbyIndex,BOOLEAN fUsed)871 static void DisplayItemNameAndInfo(UINT16 usPosY, UINT16 usIndex, UINT16 usBobbyIndex, BOOLEAN fUsed)
872 {
873 	ST::string sTemp;
874 	UINT32 uiStartLoc;
875 	UINT8	ubPurchaseNumber;
876 
877 	{
878 		//Display Items Name
879 		uiStartLoc = BOBBYR_ITEM_DESC_FILE_SIZE * usIndex;
880 		ST::string sText = GCM->loadEncryptedString(BOBBYRDESCFILE, uiStartLoc, BOBBYR_ITEM_DESC_NAME_SIZE);
881 		sText = ReduceStringLength(sText, BOBBYR_GRID_PIC_WIDTH - 6, BOBBYR_ITEM_NAME_TEXT_FONT);
882 		DrawTextToScreen(sText, BOBBYR_ITEM_NAME_X, usPosY + BOBBYR_ITEM_NAME_Y_OFFSET, 0, BOBBYR_ITEM_NAME_TEXT_FONT, BOBBYR_ITEM_NAME_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
883 	}
884 
885 	//number bought
886 	//Display the # bought
887 	ubPurchaseNumber = CheckIfItemIsPurchased(usBobbyIndex);
888 	if( ubPurchaseNumber != BOBBY_RAY_NOT_PURCHASED)
889 	{
890 		DrawTextToScreen(BobbyRText[BOBBYR_GUNS_QTY_ON_ORDER], BOBBYR_ITEM_QTY_TEXT_X, usPosY, BOBBYR_ITEM_QTY_WIDTH, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_STATIC_TEXT_COLOR, FONT_MCOLOR_BLACK, RIGHT_JUSTIFIED);
891 
892 		if( ubPurchaseNumber != BOBBY_RAY_NOT_PURCHASED)
893 		{
894 			sTemp = ST::format("{_ 4d}", BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased);
895 			DrawTextToScreen(sTemp, BOBBYR_ITEMS_BOUGHT_X, usPosY, 0, FONT14ARIAL, BOBBYR_ITEM_DESC_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
896 		}
897 	}
898 
899 
900 
901 
902 	//if it's a used item, display how damaged the item is
903 	if( fUsed )
904 	{
905 		sTemp = ST::format("*{3d}%", LaptopSaveInfo.BobbyRayUsedInventory[usBobbyIndex].ubItemQuality);
906 		DrawTextToScreen(sTemp, BOBBYR_ITEM_NAME_X - 2, usPosY - BOBBYR_ORDER_NUM_Y_OFFSET, BOBBYR_ORDER_NUM_WIDTH, BOBBYR_ITEM_NAME_TEXT_FONT, BOBBYR_ITEM_NAME_TEXT_COLOR, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
907 	}
908 
909 	{
910 		//Display Items description
911 		uiStartLoc += BOBBYR_ITEM_DESC_NAME_SIZE;
912 		ST::string sText = GCM->loadEncryptedString(BOBBYRDESCFILE, uiStartLoc, BOBBYR_ITEM_DESC_INFO_SIZE);
913 		DisplayWrappedString(BOBBYR_ITEM_DESC_START_X, usPosY, BOBBYR_ITEM_DESC_START_WIDTH, 2, BOBBYR_ITEM_DESC_TEXT_FONT, BOBBYR_ITEM_DESC_TEXT_COLOR, sText, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
914 	}
915 }
916 
917 
918 //Loops through Bobby Rays Inventory to find the first and last index
SetFirstLastPagesForNew(UINT32 uiClassMask)919 void SetFirstLastPagesForNew( UINT32 uiClassMask )
920 {
921 	UINT16 i;
922 	INT16	sFirst = -1;
923 	INT16	sLast = -1;
924 	UINT8	ubNumItems=0;
925 
926 	gubCurPage = 0;
927 
928 	//First loop through to get the first and last index indexs
929 	for(i=0; i<MAXITEMS; i++)
930 	{
931 		//If we have some of the inventory on hand
932 		if( LaptopSaveInfo.BobbyRayInventory[ i ].ubQtyOnHand != 0 )
933 		{
934 			if( GCM->getItem(LaptopSaveInfo.BobbyRayInventory[ i ].usItemIndex)->getItemClass() & uiClassMask )
935 			{
936 				ubNumItems++;
937 
938 				if( sFirst == -1 )
939 					sFirst = i;
940 				sLast = i;
941 			}
942 		}
943 	}
944 
945 	if( ubNumItems == 0 )
946 	{
947 		gusFirstItemIndex = BOBBYR_NO_ITEMS;
948 		gusLastItemIndex = BOBBYR_NO_ITEMS;
949 		gubNumPages = 0;
950 		return;
951 	}
952 
953 	gusFirstItemIndex = (UINT16)sFirst;
954 	gusLastItemIndex = (UINT16)sLast;
955 	gubNumPages = (UINT8)( ubNumItems / (FLOAT)BOBBYR_NUM_WEAPONS_ON_PAGE );
956 	if( (ubNumItems % BOBBYR_NUM_WEAPONS_ON_PAGE ) != 0 )
957 		gubNumPages += 1;
958 }
959 
960 //Loops through Bobby Rays Used Inventory to find the first and last index
SetFirstLastPagesForUsed()961 void SetFirstLastPagesForUsed()
962 {
963 	UINT16 i;
964 	INT16	sFirst = -1;
965 	INT16	sLast = -1;
966 	UINT8	ubNumItems=0;
967 
968 	gubCurPage = 0;
969 
970 	//First loop through to get the first and last index indexs
971 	for(i=0; i<MAXITEMS; i++)
972 	{
973 		//If we have some of the inventory on hand
974 		if( LaptopSaveInfo.BobbyRayUsedInventory[ i ].ubQtyOnHand != 0 )
975 		{
976 			ubNumItems++;
977 
978 			if( sFirst == -1 )
979 				sFirst = i;
980 			sLast = i;
981 		}
982 	}
983 	if( sFirst == -1 )
984 	{
985 		gusFirstItemIndex = BOBBYR_NO_ITEMS;
986 		gusLastItemIndex = BOBBYR_NO_ITEMS;
987 		gubNumPages = 0;
988 		return;
989 	}
990 
991 	gusFirstItemIndex = (UINT16)sFirst;
992 	gusLastItemIndex = (UINT16)sLast;
993 	gubNumPages = (UINT8)( ubNumItems / (FLOAT)BOBBYR_NUM_WEAPONS_ON_PAGE );
994 	if( (ubNumItems % BOBBYR_NUM_WEAPONS_ON_PAGE ) != 0 )
995 		gubNumPages += 1;
996 }
997 
998 
ScrollRegionCallback(MOUSE_REGION * const,INT32 const reason)999 static void ScrollRegionCallback(MOUSE_REGION* const, INT32 const reason)
1000 {
1001 	if (reason & MSYS_CALLBACK_REASON_WHEEL_UP)
1002 	{
1003 		PrevPage();
1004 	}
1005 	else if (reason & MSYS_CALLBACK_REASON_WHEEL_DOWN)
1006 	{
1007 		NextPage();
1008 	}
1009 }
1010 
1011 
1012 static UINT8 CheckPlayersInventoryForGunMatchingGivenAmmoID(const ItemModel* ammo);
1013 static void SelectBigImageRegionCallBack(MOUSE_REGION* pRegion, INT32 iReason);
1014 
1015 
CreateMouseRegionForBigImage(UINT16 y,const UINT8 n_regions,const ItemModel * const items[])1016 static void CreateMouseRegionForBigImage(UINT16 y, const UINT8 n_regions, const ItemModel* const items[])
1017 {
1018 	if (gfBigImageMouseRegionCreated) return;
1019 
1020 	{
1021 		UINT16 const x = BOBBYR_GRIDLOC_X;
1022 		UINT16 const y = BOBBYR_GRIDLOC_Y;
1023 		UINT16 const w = 493;
1024 		UINT16 const h = 290;
1025 		MSYS_DefineRegion(&g_scroll_region, x, y, x + w, y + h, MSYS_PRIORITY_HIGH, MSYS_NO_CURSOR, MSYS_NO_CALLBACK, ScrollRegionCallback);
1026 	}
1027 
1028 	UINT16 const x = BOBBYR_GRID_PIC_X;
1029 	UINT16 const w = BOBBYR_GRID_PIC_WIDTH;
1030 	UINT16 const h = BOBBYR_GRID_PIC_HEIGHT;
1031 	for (UINT8 i = 0; i != n_regions; y += BOBBYR_GRID_OFFSET, ++i)
1032 	{
1033 		// Mouse region for the Big Item Image
1034 		MOUSE_REGION& r = gSelectedBigImageRegion[i];
1035 		MSYS_DefineRegion(&r, x, y, x + w, y + h, MSYS_PRIORITY_HIGH, CURSOR_WWW, MSYS_NO_CALLBACK, SelectBigImageRegionCallBack);
1036 		MSYS_SetRegionUserData(&r, 0, i);
1037 
1038 		// Specify the help text only if the items is ammo
1039 		ItemModel const* const item = items[i];
1040 		if (item->getItemClass() != IC_AMMO) continue;
1041 		// And only if the user has an item that can use the particular type of ammo
1042 		UINT8 const n_guns = CheckPlayersInventoryForGunMatchingGivenAmmoID(item);
1043 		if (n_guns == 0) continue;
1044 
1045 		ST::string buf = st_format_printf(str_bobbyr_guns_num_guns_that_use_ammo, n_guns);
1046 		r.SetFastHelpText(buf);
1047 	}
1048 
1049 	gubNumItemsOnScreen          = n_regions;
1050 	gfBigImageMouseRegionCreated = TRUE;
1051 }
1052 
1053 
DeleteMouseRegionForBigImage()1054 void DeleteMouseRegionForBigImage()
1055 {
1056 	if (!gfBigImageMouseRegionCreated) return;
1057 
1058 	MSYS_RemoveRegion(&g_scroll_region);
1059 
1060 	for (UINT8 i = 0; i != gubNumItemsOnScreen; ++i)
1061 	{
1062 		MSYS_RemoveRegion(&gSelectedBigImageRegion[i]);
1063 	}
1064 
1065 	gfBigImageMouseRegionCreated = FALSE;
1066 	gusOldItemNumOnTopOfPage     = 65535;
1067 	gubNumItemsOnScreen          = 0;
1068 }
1069 
1070 
1071 static void PurchaseBobbyRayItem(UINT16 usItemNumber);
1072 static void UnPurchaseBobbyRayItem(UINT16 usItemNumber);
1073 
1074 
SelectBigImageRegionCallBack(MOUSE_REGION * pRegion,INT32 iReason)1075 static void SelectBigImageRegionCallBack(MOUSE_REGION* pRegion, INT32 iReason)
1076 {
1077 	if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP)
1078 	{
1079 		UINT16 usItemNum = (UINT16)MSYS_GetRegionUserData( pRegion, 0 );
1080 
1081 		PurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum] );
1082 
1083 		fReDrawScreenFlag = TRUE;
1084 		fPausedReDrawScreenFlag = TRUE;
1085 	}
1086 	else if (iReason & MSYS_CALLBACK_REASON_RBUTTON_UP)
1087 	{
1088 		UINT16 usItemNum = (UINT16)MSYS_GetRegionUserData( pRegion, 0 );
1089 
1090 		UnPurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum] );
1091 		fReDrawScreenFlag = TRUE;
1092 		fPausedReDrawScreenFlag = TRUE;
1093 	}
1094 	else if(iReason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT)
1095 	{
1096 		UINT16 usItemNum = (UINT16)MSYS_GetRegionUserData( pRegion, 0 );
1097 
1098 		PurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum] );
1099 		fReDrawScreenFlag = TRUE;
1100 		fPausedReDrawScreenFlag = TRUE;
1101 	}
1102 	else if (iReason & MSYS_CALLBACK_REASON_RBUTTON_REPEAT)
1103 	{
1104 		UINT16 usItemNum = (UINT16)MSYS_GetRegionUserData( pRegion, 0 );
1105 
1106 		UnPurchaseBobbyRayItem( gusItemNumberForItemsOnScreen[ usItemNum] );
1107 		fReDrawScreenFlag = TRUE;
1108 		fPausedReDrawScreenFlag = TRUE;
1109 	}
1110 	else if (iReason & MSYS_CALLBACK_REASON_WHEEL_UP)
1111 	{
1112 		PrevPage();
1113 	}
1114 	else if (iReason & MSYS_CALLBACK_REASON_WHEEL_DOWN)
1115 	{
1116 		NextPage();
1117 	}
1118 }
1119 
1120 
1121 static UINT8 GetNextPurchaseNumber(void);
1122 
PurchaseBobbyRayItem(UINT16 usItemNumber)1123 static void PurchaseBobbyRayItem(UINT16 usItemNumber)
1124 {
1125 	UINT8	ubPurchaseNumber;
1126 
1127 	ubPurchaseNumber = CheckIfItemIsPurchased(usItemNumber);
1128 
1129 	//if we are in the used page
1130 	if( guiCurrentLaptopMode == LAPTOP_MODE_BOBBY_R_USED )
1131 	{
1132 		//if there is enough inventory in stock to cover the purchase
1133 		if( ubPurchaseNumber == BOBBY_RAY_NOT_PURCHASED || LaptopSaveInfo.BobbyRayUsedInventory[ usItemNumber ].ubQtyOnHand >= ( BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased + 1) )
1134 		{
1135 			// If the item has not yet been purchased
1136 			if( ubPurchaseNumber == BOBBY_RAY_NOT_PURCHASED )
1137 			{
1138 				ubPurchaseNumber = GetNextPurchaseNumber();
1139 
1140 				if( ubPurchaseNumber != BOBBY_RAY_NOT_PURCHASED )
1141 				{
1142 					BobbyRayPurchases[ ubPurchaseNumber ].usItemIndex = LaptopSaveInfo.BobbyRayUsedInventory[ usItemNumber ].usItemIndex;
1143 					BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased = 1;
1144 					BobbyRayPurchases[ ubPurchaseNumber ].bItemQuality = LaptopSaveInfo.BobbyRayUsedInventory[ usItemNumber ].ubItemQuality;
1145 					BobbyRayPurchases[ ubPurchaseNumber ].usBobbyItemIndex = usItemNumber;
1146 					BobbyRayPurchases[ ubPurchaseNumber ].fUsed = TRUE;
1147 				}
1148 				else
1149 				{
1150 					//display error popup because the player is trying to purchase more thenn 10 items
1151 					DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, BobbyRText[ BOBBYR_MORE_THEN_10_PURCHASES ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
1152 
1153 				}
1154 			}
1155 			// Else If the item is already purchased increment purchase amount.  Only if ordering less then the max amount!
1156 			else
1157 			{
1158 				if( BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased <= BOBBY_RAY_MAX_AMOUNT_OF_ITEMS_TO_PURCHASE)
1159 					BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased++;
1160 			}
1161 		}
1162 		else
1163 		{
1164 			DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, BobbyRText[ BOBBYR_MORE_NO_MORE_IN_STOCK ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
1165 		}
1166 	}
1167 	//else the player is on a any other page except the used page
1168 	else
1169 	{
1170 		//if there is enough inventory in stock to cover the purchase
1171 		if( ubPurchaseNumber == BOBBY_RAY_NOT_PURCHASED || LaptopSaveInfo.BobbyRayInventory[ usItemNumber ].ubQtyOnHand >= ( BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased + 1) )
1172 		{
1173 			// If the item has not yet been purchased
1174 			if( ubPurchaseNumber == BOBBY_RAY_NOT_PURCHASED )
1175 			{
1176 				ubPurchaseNumber = GetNextPurchaseNumber();
1177 
1178 				if( ubPurchaseNumber != BOBBY_RAY_NOT_PURCHASED )
1179 				{
1180 					BobbyRayPurchases[ ubPurchaseNumber ].usItemIndex = LaptopSaveInfo.BobbyRayInventory[ usItemNumber ].usItemIndex;
1181 					BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased = 1;
1182 					BobbyRayPurchases[ ubPurchaseNumber ].bItemQuality = 100;
1183 					BobbyRayPurchases[ ubPurchaseNumber ].usBobbyItemIndex = usItemNumber;
1184 					BobbyRayPurchases[ ubPurchaseNumber ].fUsed = FALSE;
1185 				}
1186 				else
1187 				{
1188 					//display error popup because the player is trying to purchase more thenn 10 items
1189 					DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, BobbyRText[ BOBBYR_MORE_THEN_10_PURCHASES ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
1190 				}
1191 			}
1192 			// Else If the item is already purchased increment purchase amount.  Only if ordering less then the max amount!
1193 			else
1194 			{
1195 				if( BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased <= BOBBY_RAY_MAX_AMOUNT_OF_ITEMS_TO_PURCHASE)
1196 					BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased++;
1197 			}
1198 		}
1199 		else
1200 		{
1201 			DoLapTopMessageBox( MSG_BOX_LAPTOP_DEFAULT, BobbyRText[ BOBBYR_MORE_NO_MORE_IN_STOCK ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
1202 		}
1203 	}
1204 }
1205 
1206 
1207 // Checks to see if the clicked item is already bought or not.
CheckIfItemIsPurchased(UINT16 usItemNumber)1208 static UINT8 CheckIfItemIsPurchased(UINT16 usItemNumber)
1209 {
1210 	UINT8	i;
1211 
1212 	for(i=0; i<MAX_PURCHASE_AMOUNT; i++)
1213 	{
1214 		if( ( usItemNumber == BobbyRayPurchases[i].usBobbyItemIndex ) && ( BobbyRayPurchases[i].ubNumberPurchased != 0 ) && ( BobbyRayPurchases[i].fUsed == gfOnUsedPage ) )
1215 			return(i);
1216 	}
1217 	return(BOBBY_RAY_NOT_PURCHASED);
1218 }
1219 
1220 
GetNextPurchaseNumber(void)1221 static UINT8 GetNextPurchaseNumber(void)
1222 {
1223 	UINT8	i;
1224 
1225 	for(i=0; i<MAX_PURCHASE_AMOUNT; i++)
1226 	{
1227 		if( ( BobbyRayPurchases[i].usBobbyItemIndex == 0) && ( BobbyRayPurchases[i].ubNumberPurchased == 0 ) )
1228 			return(i);
1229 	}
1230 	return(BOBBY_RAY_NOT_PURCHASED);
1231 }
1232 
1233 
UnPurchaseBobbyRayItem(UINT16 usItemNumber)1234 static void UnPurchaseBobbyRayItem(UINT16 usItemNumber)
1235 {
1236 	UINT8	ubPurchaseNumber;
1237 
1238 	ubPurchaseNumber = CheckIfItemIsPurchased(usItemNumber);
1239 
1240 	if( ubPurchaseNumber != BOBBY_RAY_NOT_PURCHASED )
1241 	{
1242 		if( BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased > 1)
1243 			BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased--;
1244 		else
1245 		{
1246 			BobbyRayPurchases[ ubPurchaseNumber ].ubNumberPurchased = 0;
1247 			BobbyRayPurchases[ ubPurchaseNumber ].usBobbyItemIndex = 0;
1248 		}
1249 	}
1250 }
1251 
1252 
BtnBobbyROrderFormCallback(GUI_BUTTON * btn,INT32 reason)1253 static void BtnBobbyROrderFormCallback(GUI_BUTTON* btn, INT32 reason)
1254 {
1255 	if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
1256 	{
1257 		guiCurrentLaptopMode = LAPTOP_MODE_BOBBY_R_MAILORDER;
1258 	}
1259 }
1260 
1261 
BtnBobbyRHomeButtonCallback(GUI_BUTTON * btn,INT32 reason)1262 static void BtnBobbyRHomeButtonCallback(GUI_BUTTON* btn, INT32 reason)
1263 {
1264 	if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
1265 	{
1266 		guiCurrentLaptopMode = LAPTOP_MODE_BOBBY_R;
1267 	}
1268 }
1269 
1270 
UpdateButtonText(UINT32 uiCurPage)1271 void UpdateButtonText(UINT32	uiCurPage)
1272 {
1273 	switch( uiCurPage )
1274 	{
1275 		case LAPTOP_MODE_BOBBY_R_GUNS:
1276 			DisableButton( guiBobbyRPageMenu[0] );
1277 			break;
1278 
1279 		case LAPTOP_MODE_BOBBY_R_AMMO:
1280 			DisableButton( guiBobbyRPageMenu[1] );
1281 			break;
1282 
1283 		case LAPTOP_MODE_BOBBY_R_ARMOR:
1284 			DisableButton( guiBobbyRPageMenu[2] );
1285 			break;
1286 
1287 		case LAPTOP_MODE_BOBBY_R_MISC:
1288 			DisableButton( guiBobbyRPageMenu[3] );
1289 			break;
1290 
1291 		case LAPTOP_MODE_BOBBY_R_USED:
1292 			DisableButton( guiBobbyRPageMenu[4] );
1293 			break;
1294 	}
1295 }
1296 
1297 
CalcBobbyRayCost(UINT16 usIndex,UINT16 usBobbyIndex,BOOLEAN fUsed)1298 UINT16 CalcBobbyRayCost( UINT16 usIndex, UINT16 usBobbyIndex, BOOLEAN fUsed)
1299 {
1300 	DOUBLE value;
1301 	if( fUsed )
1302 		value = GCM->getItem(LaptopSaveInfo.BobbyRayUsedInventory[ usBobbyIndex ].usItemIndex)->getPrice() *
1303 								( .5 + .5 * ( LaptopSaveInfo.BobbyRayUsedInventory[ usBobbyIndex ].ubItemQuality ) / 100 ) + .5;
1304 	else
1305 		value = GCM->getItem(LaptopSaveInfo.BobbyRayInventory[ usBobbyIndex ].usItemIndex)->getPrice();
1306 
1307 	return( (UINT16) value);
1308 }
1309 
1310 
CalculateTotalPurchasePrice()1311 static UINT32 CalculateTotalPurchasePrice()
1312 {
1313 	UINT32 total = 0;
1314 	FOR_EACH(BobbyRayPurchaseStruct const, i, BobbyRayPurchases)
1315 	{
1316 		BobbyRayPurchaseStruct const& p = *i;
1317 		if (p.ubNumberPurchased == 0) continue;
1318 		total += CalcBobbyRayCost(p.usItemIndex, p.usBobbyItemIndex, p.fUsed) * p.ubNumberPurchased;
1319 	}
1320 	return total;
1321 }
1322 
1323 
DisableBobbyRButtons(void)1324 static void DisableBobbyRButtons(void)
1325 {
1326 	//if it is the last page, disable the next page button
1327 	EnableButton(guiBobbyRNextPage, gubNumPages != 0 && gubCurPage < gubNumPages - 1);
1328 
1329 	// if it is the first page, disable the prev page buitton
1330 	EnableButton(guiBobbyRPreviousPage, gubCurPage != 0);
1331 }
1332 
1333 
CalcFirstIndexForPage(STORE_INVENTORY * const pInv,UINT32 const item_class)1334 static void CalcFirstIndexForPage(STORE_INVENTORY* const pInv, UINT32 const item_class)
1335 {
1336 	// Reset the Current weapon Index
1337 	gusCurWeaponIndex = 0;
1338 
1339 	// Get to the first index on the page
1340 	UINT16 inv_idx = 0;
1341 	for (UINT16 i = gusFirstItemIndex; i <= gusLastItemIndex; ++i)
1342 	{
1343 		if (!(GCM->getItem(pInv[i].usItemIndex)->getItemClass() & item_class)) continue;
1344 		// If we have some of the inventory on hand
1345 		if (pInv[i].ubQtyOnHand == 0) continue;
1346 
1347 		gusCurWeaponIndex = i;
1348 		if (inv_idx++ == gubCurPage * 4) break;
1349 	}
1350 }
1351 
1352 
CheckPlayersInventoryForGunMatchingGivenAmmoID(ItemModel const * const ammo)1353 static UINT8 CheckPlayersInventoryForGunMatchingGivenAmmoID(ItemModel const* const ammo)
1354 {
1355 	UINT8 n_items = 0;
1356 	const CalibreModel *calibre = ammo->asAmmo()->calibre;
1357 	CFOR_EACH_IN_TEAM(s, OUR_TEAM)
1358 	{
1359 		// Loop through all the pockets on the merc
1360 		CFOR_EACH_SOLDIER_INV_SLOT(i, *s)
1361 		{
1362 			OBJECTTYPE const& o = *i;
1363 			// If there is a weapon here
1364 			if (GCM->getItem(o.usItem)->getItemClass() != IC_GUN) continue;
1365 			// If the weapon uses the same kind of ammo as the one passed in
1366 			if (!GCM->getWeapon(o.usItem)->matches(calibre)) continue;
1367 
1368 			++n_items;
1369 		}
1370 	}
1371 	return n_items;
1372 }
1373