1 #include "Directories.h"
2 #include "Font.h"
3 #include "HImage.h"
4 #include "Local.h"
5 #include "MercTextBox.h"
6 #include "PODObj.h"
7 #include "VObject.h"
8 #include "VSurface.h"
9 #include "Font_Control.h"
10 #include "WordWrap.h"
11 #include "Render_Dirty.h"
12 #include "Video.h"
13 #include "MemMan.h"
14 #include "UILayout.h"
15
16 #include <string_theory/string>
17
18 #include <stdexcept>
19
20
21 #define TEXT_POPUP_GAP_BN_LINES 10
22 #define TEXT_POPUP_FONT FONT12ARIAL
23 #define TEXT_POPUP_COLOR FONT_MCOLOR_WHITE
24
25 #define MERC_TEXT_FONT FONT12ARIAL
26 #define MERC_TEXT_COLOR FONT_MCOLOR_WHITE
27
28 #define MERC_TEXT_MIN_WIDTH 10
29 #define MERC_TEXT_POPUP_WINDOW_TEXT_OFFSET_X 10
30 #define MERC_TEXT_POPUP_WINDOW_TEXT_OFFSET_Y 10
31
32 #define MERC_BACKGROUND_WIDTH 350
33 #define MERC_BACKGROUND_HEIGHT 200
34
35
36 // both of the below are index by the enum for thier types - background and border in
37 // MercTextBox.h
38
39 // filenames for border popup .sti's
40 static char const* const zMercBorderPopupFilenames[] =
41 {
42 INTERFACEDIR "/tactpopup.sti",
43 INTERFACEDIR "/tactredpopup.sti",
44 INTERFACEDIR "/tactbluepopup.sti",
45 INTERFACEDIR "/tactpopupmain.sti",
46 INTERFACEDIR "/laptoppopup.sti"
47 };
48
49 // filenames for background popup .pcx's
50 static char const* const zMercBackgroundPopupFilenames[] =
51 {
52 INTERFACEDIR "/tactpopupbackground.pcx",
53 INTERFACEDIR "/tactpopupwhitebackground.pcx",
54 INTERFACEDIR "/tactpopupgreybackground.pcx",
55 INTERFACEDIR "/tactpopupbackgroundmain.pcx",
56 INTERFACEDIR "/laptoppopupbackground.pcx",
57 INTERFACEDIR "/imp_popup_background.pcx"
58 };
59
60
61 struct MercPopUpBox
62 {
63 SGPVSurface* uiSourceBufferIndex;
64 UINT8 ubBackgroundIndex;
65 UINT8 ubBorderIndex;
66 SGPVSurface* uiMercTextPopUpBackground;
67 SGPVObject* uiMercTextPopUpBorder;
68 };
69
70
71 // the flags
72 static SGPVObject* guiBoxIcons;
73 static SGPVObject* guiSkullIcons;
74
75
InitMercPopupBox()76 void InitMercPopupBox()
77 {
78 guiBoxIcons = AddVideoObjectFromFile(INTERFACEDIR "/msgboxicons.sti"); // stop icon
79 guiSkullIcons = AddVideoObjectFromFile(INTERFACEDIR "/msgboxiconskull.sti"); // skull icon
80 }
81
82
83 // Tactical Popup
LoadTextMercPopupImages(MercPopUpBox * const box,MercPopUpBackground const ubBackgroundIndex,MercPopUpBorder const ubBorderIndex)84 static void LoadTextMercPopupImages(MercPopUpBox* const box, MercPopUpBackground const ubBackgroundIndex, MercPopUpBorder const ubBorderIndex)
85 {
86 // this function will load the graphics associated with the background and border index values
87 box->uiMercTextPopUpBackground = AddVideoSurfaceFromFile(zMercBackgroundPopupFilenames[ubBackgroundIndex]);
88 box->uiMercTextPopUpBorder = AddVideoObjectFromFile(zMercBorderPopupFilenames[ubBorderIndex]);
89
90 // so far so good, return successful
91 box->ubBackgroundIndex = ubBackgroundIndex;
92 box->ubBorderIndex = ubBorderIndex;
93 }
94
95
RemoveTextMercPopupImages(MercPopUpBox * const box)96 static void RemoveTextMercPopupImages(MercPopUpBox* const box)
97 {
98 DeleteVideoSurface(box->uiMercTextPopUpBackground);
99 DeleteVideoObject(box->uiMercTextPopUpBorder);
100 }
101
102
RenderMercPopUpBox(MercPopUpBox const * const box,INT16 const sDestX,INT16 const sDestY,SGPVSurface * const buffer)103 void RenderMercPopUpBox(MercPopUpBox const* const box, INT16 const sDestX, INT16 const sDestY, SGPVSurface* const buffer)
104 {
105 if (!box) return;
106
107 // will render/transfer the image from the buffer in the data structure to the buffer specified by user
108 SGPVSurface* const vs = box->uiSourceBufferIndex;
109 BltVideoSurface(buffer, vs, sDestX, sDestY, NULL);
110
111 //Invalidate!
112 if (buffer == FRAME_BUFFER)
113 {
114 InvalidateRegion(sDestX, sDestY, sDestX + vs->Width(), sDestY + vs->Height());
115 }
116 }
117
118
119 static void GetMercPopupBoxFontColor(UINT8 ubBackgroundIndex, UINT8* pubFontColor, UINT8* pubFontShadowColor);
120
121
PrepareMercPopupBox(MercPopUpBox * box,MercPopUpBackground ubBackgroundIndex,MercPopUpBorder ubBorderIndex,const ST::utf32_buffer & codepoints,UINT16 usWidth,UINT16 usMarginX,UINT16 usMarginTopY,UINT16 usMarginBottomY,UINT16 * pActualWidth,UINT16 * pActualHeight,MercPopupBoxFlags flags)122 MercPopUpBox* PrepareMercPopupBox(MercPopUpBox* box, MercPopUpBackground ubBackgroundIndex, MercPopUpBorder ubBorderIndex, const ST::utf32_buffer& codepoints, UINT16 usWidth, UINT16 usMarginX, UINT16 usMarginTopY, UINT16 usMarginBottomY, UINT16* pActualWidth, UINT16* pActualHeight, MercPopupBoxFlags flags)
123 {
124 if (usWidth >= SCREEN_WIDTH)
125 {
126 throw std::logic_error("Tried to create too wide merc popup box");
127 }
128
129 if (usWidth <= MERC_TEXT_MIN_WIDTH) usWidth = MERC_TEXT_MIN_WIDTH;
130
131 SGP::PODObj<MercPopUpBox> new_box(0);
132 // check id value, if -1, box has not been inited yet
133 if (!box)
134 {
135 // no box yet
136 box = new_box.Allocate();
137 LoadTextMercPopupImages(box, ubBackgroundIndex, ubBorderIndex);
138 }
139 else
140 {
141 // has been created already,
142 // Check if these images are different
143 if (ubBackgroundIndex != box->ubBackgroundIndex ||
144 ubBorderIndex != box->ubBorderIndex)
145 {
146 //Remove old, set new
147 RemoveTextMercPopupImages(box);
148 LoadTextMercPopupImages(box, ubBackgroundIndex, ubBorderIndex);
149 }
150 }
151
152 UINT16 const usStringPixLength = StringPixLength(codepoints, TEXT_POPUP_FONT);
153 UINT16 usTextWidth;
154 if (usStringPixLength < usWidth - MERC_TEXT_POPUP_WINDOW_TEXT_OFFSET_X * 2)
155 {
156 usWidth = usStringPixLength + MERC_TEXT_POPUP_WINDOW_TEXT_OFFSET_X * 2;
157 usTextWidth = usWidth - MERC_TEXT_POPUP_WINDOW_TEXT_OFFSET_X * 2 + 1;
158 }
159 else
160 {
161 usTextWidth = usWidth - MERC_TEXT_POPUP_WINDOW_TEXT_OFFSET_X * 2 + 1 - usMarginX;
162 }
163
164 UINT16 const usNumberVerticalPixels = IanWrappedStringHeight(usTextWidth, 2, TEXT_POPUP_FONT, codepoints);
165 UINT16 usHeight = usNumberVerticalPixels + MERC_TEXT_POPUP_WINDOW_TEXT_OFFSET_Y * 2;
166
167 // Add height for margins
168 usHeight += usMarginTopY + usMarginBottomY;
169
170 // Add width for margins
171 usWidth += usMarginX * 2;
172
173 // Add width for iconic...
174 if (flags & (MERC_POPUP_PREPARE_FLAGS_STOPICON | MERC_POPUP_PREPARE_FLAGS_SKULLICON))
175 {
176 // Make minimun height for box...
177 if (usHeight < 45) usHeight = 45;
178 usWidth += 35;
179 }
180
181 if (usWidth >= MERC_BACKGROUND_WIDTH) usWidth = MERC_BACKGROUND_WIDTH - 1;
182
183 // make sure the area isnt bigger than the background texture
184 if (usHeight >= MERC_BACKGROUND_HEIGHT)
185 {
186 throw std::logic_error("Tried to create too high merc popup box");
187 }
188
189 // Create a background video surface to blt the face onto
190 SGPVSurface* const vs = AddVideoSurface(usWidth, usHeight, PIXEL_DEPTH);
191 box->uiSourceBufferIndex = vs;
192
193 *pActualWidth = usWidth;
194 *pActualHeight = usHeight;
195
196 if (flags & MERC_POPUP_PREPARE_FLAGS_TRANS_BACK)
197 {
198 // Zero with yellow,
199 // Set source transparcenty
200 vs->SetTransparency(FROMRGB(255, 255, 0));
201 vs->Fill(Get16BPPColor(FROMRGB(255, 255, 0)));
202 }
203 else
204 {
205 SGPBox const DestRect = { 0, 0, usWidth, usHeight };
206 BltVideoSurface(vs, box->uiMercTextPopUpBackground, 0, 0, &DestRect);
207 }
208
209 const SGPVObject* const hImageHandle = box->uiMercTextPopUpBorder;
210
211 UINT16 usPosY = 0;
212 //blit top row of images
213 for (UINT16 i = TEXT_POPUP_GAP_BN_LINES; i < usWidth - TEXT_POPUP_GAP_BN_LINES; i += TEXT_POPUP_GAP_BN_LINES)
214 {
215 //TOP ROW
216 BltVideoObject(vs, hImageHandle, 1, i, usPosY);
217 //BOTTOM ROW
218 BltVideoObject(vs, hImageHandle, 6, i, usHeight - TEXT_POPUP_GAP_BN_LINES + 6);
219 }
220
221 //blit the left and right row of images
222 UINT16 usPosX = 0;
223 for (UINT16 i= TEXT_POPUP_GAP_BN_LINES; i < usHeight - TEXT_POPUP_GAP_BN_LINES; i += TEXT_POPUP_GAP_BN_LINES)
224 {
225 BltVideoObject(vs, hImageHandle, 3, usPosX, i);
226 BltVideoObject(vs, hImageHandle, 4, usPosX + usWidth - 4, i);
227 }
228
229 //blt the corner images for the row
230 //top left
231 BltVideoObject(vs, hImageHandle, 0, 0, usPosY);
232 //top right
233 BltVideoObject(vs, hImageHandle, 2, usWidth - TEXT_POPUP_GAP_BN_LINES, usPosY);
234 //bottom left
235 BltVideoObject(vs, hImageHandle, 5, 0, usHeight - TEXT_POPUP_GAP_BN_LINES);
236 //bottom right
237 BltVideoObject(vs, hImageHandle, 7, usWidth - TEXT_POPUP_GAP_BN_LINES, usHeight - TEXT_POPUP_GAP_BN_LINES);
238
239 // Icon if ness....
240 if (flags & MERC_POPUP_PREPARE_FLAGS_STOPICON)
241 {
242 BltVideoObject(vs, guiBoxIcons, 0, 5, 4);
243 }
244 if (flags & MERC_POPUP_PREPARE_FLAGS_SKULLICON)
245 {
246 BltVideoObject(vs, guiSkullIcons, 0, 9, 4);
247 }
248
249 //Get the font and shadow colors
250 UINT8 ubFontColor;
251 UINT8 ubFontShadowColor;
252 GetMercPopupBoxFontColor(ubBackgroundIndex, &ubFontColor, &ubFontShadowColor);
253
254 SetFontShadow(ubFontShadowColor);
255 SetFontDestBuffer(vs);
256
257 //Display the text
258 INT16 sDispTextXPos = MERC_TEXT_POPUP_WINDOW_TEXT_OFFSET_X + usMarginX;
259
260 if (flags & (MERC_POPUP_PREPARE_FLAGS_STOPICON | MERC_POPUP_PREPARE_FLAGS_SKULLICON))
261 {
262 sDispTextXPos += 30;
263 }
264
265 DisplayWrappedString(sDispTextXPos, MERC_TEXT_POPUP_WINDOW_TEXT_OFFSET_Y + usMarginTopY, usTextWidth, 2, MERC_TEXT_FONT, ubFontColor, codepoints, FONT_MCOLOR_BLACK, LEFT_JUSTIFIED);
266
267 SetFontDestBuffer(FRAME_BUFFER);
268 SetFontShadow(DEFAULT_SHADOW);
269
270 new_box.Release();
271 return box;
272 }
273
274
275 //Deletes the surface thats contains the border, background and the text.
RemoveMercPopupBox(MercPopUpBox * const box)276 void RemoveMercPopupBox(MercPopUpBox* const box)
277 {
278 if (!box) return;
279
280 DeleteVideoSurface(box->uiSourceBufferIndex);
281
282 //DEF Added 5/26
283 //Delete the background and the border
284 RemoveTextMercPopupImages(box);
285
286 delete box;
287 }
288
289
290 //Pass in the background index, and pointers to the font and shadow color
GetMercPopupBoxFontColor(UINT8 ubBackgroundIndex,UINT8 * pubFontColor,UINT8 * pubFontShadowColor)291 static void GetMercPopupBoxFontColor(UINT8 ubBackgroundIndex, UINT8* pubFontColor, UINT8* pubFontShadowColor)
292 {
293 switch( ubBackgroundIndex )
294 {
295 case BASIC_MERC_POPUP_BACKGROUND:
296 *pubFontColor = TEXT_POPUP_COLOR;
297 *pubFontShadowColor = DEFAULT_SHADOW;
298 break;
299
300 case WHITE_MERC_POPUP_BACKGROUND:
301 *pubFontColor = 2;
302 *pubFontShadowColor = FONT_MCOLOR_WHITE;
303 break;
304
305 case GREY_MERC_POPUP_BACKGROUND:
306 *pubFontColor = 2;
307 *pubFontShadowColor = NO_SHADOW;
308 break;
309
310 case LAPTOP_POPUP_BACKGROUND:
311 *pubFontColor = TEXT_POPUP_COLOR;
312 *pubFontShadowColor = DEFAULT_SHADOW;
313 break;
314
315 default:
316 *pubFontColor = TEXT_POPUP_COLOR;
317 *pubFontShadowColor = DEFAULT_SHADOW;
318 break;
319 }
320 }
321