convert line ends
[canaan.git] / prj / cam / src / shock / shkutils.cpp
blob8c8debb37dc8ba200de659ea2c535b24d22f3d12
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 // $Header: r:/t2repos/thief2/src/shock/shkutils.cpp,v 1.36 2000/02/19 13:26:33 toml Exp $
8 #include <appagg.h>
9 #include <string.h>
11 #include <shkutils.h>
12 #include <string.h>
13 #include <dev2d.h>
14 #include <mprintf.h>
16 #include <resapi.h>
17 #include <resistr.h>
18 #include <imgrstyp.h>
19 #include <palrstyp.h>
20 #include <strrstyp.h>
21 #include <fonrstyp.h>
23 #include <objtype.h>
24 #include <shkgame.h>
25 #include <shkcurm.h>
26 #include <shkfsys.h>
27 #include <shkinv.h>
29 #include <palmgr.h>
30 #include <memall.h>
31 #include <dbmem.h> // must be last header!
33 grs_font *gShockFont = NULL;
34 IRes *gShockFontRes = NULL;
36 grs_font *gShockFontAA = NULL;
37 IRes *gShockFontAARes = NULL;
39 grs_font *gShockFontMono = NULL;
40 IRes *gShockFontMonoRes = NULL;
42 grs_font *gShockFontDimmed = NULL;
43 IRes *gShockFontDimmedRes = NULL;
45 grs_font *gShockFontBlue = NULL;
46 IRes *gShockFontBlueRes = NULL;
48 uint gShockTextColor = 0;
50 // For the DrawCursor methods:
51 static IRes *gPendingHnd = NULL;
53 //--------------------------------------------------------------------------------------
54 void ShockUtilsInit(void)
56 AutoAppIPtr(ResMan);
57 IRes *fontpal;
58 grs_bitmap *fontpalbmp;
60 fontpal = LoadPCX("fontpal");
61 fontpalbmp = (grs_bitmap *) fontpal->Lock();
63 gShockFontMonoRes = pResMan->Bind("mainfont",RESTYPE_FONT, NULL, "fonts\\");
64 if (gShockFontMonoRes != NULL)
65 gShockFontMono = (grs_font *)gShockFontMonoRes->Lock();
67 //gShockFontAA = gShockFont;
68 //gShockBoldFontAA = gShockFont;
70 gShockFontAARes = pResMan->Bind("mainaa",RESTYPE_FONT, NULL, "fonts\\");
71 if (gShockFontAARes != NULL)
73 gShockFontAA = (grs_font *)gShockFontAARes->Lock();
74 gShockFontAA->pal_id = fontpalbmp->align;
77 gShockFontDimmedRes = pResMan->Bind("Dimmed",RESTYPE_FONT, NULL, "fonts\\");
78 if (gShockFontDimmedRes != NULL)
80 gShockFontDimmed = (grs_font *)gShockFontDimmedRes->Lock();
81 gShockFontDimmed->pal_id = fontpalbmp->align;
84 gShockFontBlueRes = pResMan->Bind("BlueAA",RESTYPE_FONT, NULL, "fonts\\");
85 if (gShockFontBlueRes != NULL)
87 gShockFontBlue = (grs_font *)gShockFontBlueRes->Lock();
88 gShockFontBlue->pal_id = fontpalbmp->align;
91 // what is our default font?
92 gShockFont = gShockFontAA;
94 fontpal->Unlock();
95 SafeFreeHnd(&fontpal);
97 gPendingHnd = LoadPCX("hourglas", SHK_INTERFACE_PATH);
100 //--------------------------------------------------------------------------------------
101 void ShockUtilInitColor()
103 int color[3] = {0,255,190}; // { 0, 255, 0};
104 gShockTextColor = FindColor(color);
108 //--------------------------------------------------------------------------------------
109 void ShockUtilsTerm(void)
111 gShockFontMonoRes->Unlock();
112 gShockFontMonoRes->Release();
113 gShockFontAARes->Unlock();
114 gShockFontAARes->Release();
115 gShockFontDimmedRes->Unlock();
116 gShockFontDimmedRes->Release();
117 gShockFontBlueRes->Unlock();
118 gShockFontBlueRes->Release();
119 SafeFreeHnd(&gPendingHnd);
122 //--------------------------------------------------------------------------------------
123 // Utility routine to load correct .PCX bitmap (based on current res).
124 // Ideally, in the long run, this should take an ISearchPath instead of
125 // the current char *path; it'll be more efficient.
127 // For the moment, this is doing a global Lock(), since we have a couple
128 // of DataPeeks around the system. If we can rid ourselves of the DataPeeks,
129 // then we can eliminate this Lock, and the Unlock in SafeFreeHnd.
131 // The returned resource should be freed with SafeFreeHnd().
132 //--------------------------------------------------------------------------------------
133 IRes *LoadPCX(const char *name, char *path, eShockLoadFlags flags)
136 char hires[16], lores[16], name[16];
138 sscanf(str, "%s %s", hires, lores);
139 if (gHires)
140 strcpy(name, hires);
141 else
142 strcpy(name, lores);
144 // We are not currently assuming that image files are .pcx. This is more
145 // flexible, but possibly slower. We should keep an eye on the time
146 // impact of this:
147 // strcat(name, ".PCX");
149 AutoAppIPtr(ResMan);
150 IRes *pRes = pResMan->Bind(name, RESTYPE_IMAGE, NULL, path);
151 if (!pRes) {
152 return NULL;
154 // @NOTE: We are holding a permanent Lock on all images here (which is
155 // eventually Unlocked by SafeFreeHnd). This *may* want to go away later,
156 // but we need to think about the Palette ramifications...
157 grs_bitmap *pbm = (grs_bitmap *) pRes->Lock();
159 // Now that we have the Image, load the Palette as well.
160 // @TBD: We should create an ImageAndPalette resource type, which will
161 // load both of them at a shot, instead of having to do two disk hits.
162 if ((pbm->align == 0) && !(flags & ShockLoadNoPalette))
164 IRes *pPallRes = pResMan->Retype(pRes, RESTYPE_PALETTE, 0);
165 if (pPallRes) {
166 uchar *pPall = (uchar *) pPallRes->Lock();
167 pbm->align = palmgr_alloc_pal(pPall);
168 pPallRes->Unlock();
169 // keep it in memory, so don't drop it.
170 //pPallRes->Drop();
171 SafeRelease(pPallRes);
175 return pRes;
178 //--------------------------------------------------------------------------------------
179 // Draw some art, specified by handle
180 //--------------------------------------------------------------------------------------
181 BOOL DrawByHandle(IRes *drawhand, Point pt)
183 grs_bitmap *bm;
184 if (drawhand != NULL)
186 bm = (grs_bitmap *) drawhand->Lock();
187 gr_bitmap(bm, pt.x, pt.y);
188 drawhand->Unlock();
189 return(TRUE);
191 return(FALSE);
194 BOOL DrawByHandleCenter(IRes *drawhand, Point pt)
196 grs_bitmap *bm;
197 if (drawhand != NULL)
199 bm = (grs_bitmap *) drawhand->Lock();
200 gr_bitmap(bm, pt.x - (bm->w / 2), pt.y - (bm->h / 2));
201 drawhand->Unlock();
202 return(TRUE);
204 return(FALSE);
207 BOOL DrawByHandleCenterRotate(IRes *drawhand, Point pt, fixang theta)
209 grs_bitmap *bm;
210 if (drawhand != NULL)
212 bm = (grs_bitmap *) drawhand->Lock();
213 gr_rotate_bitmap(bm, theta, fix_make(pt.x,0), fix_make(pt.y,0));
214 drawhand->Unlock();
216 return(TRUE);
218 return(FALSE);
220 //--------------------------------------------------------------------------------------
221 // Similar to the above, but will do any additional manipulation appropriate
222 // for all cursors. At the moment, this just means that it will tack on the
223 // "pending" icon if a frob request is pending.
224 // This may be getting a little high-level for shkutils; should we break
225 // it out?
226 //--------------------------------------------------------------------------------------
227 BOOL DrawCursorByHandle(IRes *drawhand, Point pt)
229 grs_bitmap *bm;
230 if (drawhand != NULL)
232 bm = (grs_bitmap *) drawhand->Lock();
233 gr_bitmap(bm, pt.x, pt.y);
234 if (ShockFrobPending() && gPendingHnd) {
235 grs_bitmap *bm2;
236 bm2 = (grs_bitmap *) gPendingHnd->Lock();
237 gr_bitmap(bm2, pt.x + bm->w, pt.y + bm->h);
238 gPendingHnd->Unlock();
240 drawhand->Unlock();
241 return(TRUE);
243 return(FALSE);
246 BOOL DrawCursorByHandleCenter(IRes *drawhand, Point pt)
248 grs_bitmap *bm;
249 int dx,dy;
250 if (drawhand != NULL)
252 bm = (grs_bitmap *) drawhand->Lock();
253 dx = pt.x - (bm->w / 2);
254 dy = pt.y - (bm->h / 2);
255 gr_bitmap(bm, dx, dy);
256 if (ShockFrobPending() && gPendingHnd) {
257 grs_bitmap *bm2;
258 bm2 = (grs_bitmap *) gPendingHnd->Lock();
259 gr_bitmap(bm2, pt.x + (bm->w / 2), pt.y + (bm->h / 2));
260 gPendingHnd->Unlock();
262 drawhand->Unlock();
264 // add in a stack count, potentially
265 if (shock_cursor_mode == SCM_DRAGOBJ)
267 char temp[32];
268 if (ShockObjGetQuantity(drag_obj,temp))
270 gr_set_fcolor(gShockTextColor);
271 gr_font_string(gShockFontMono, temp, dx + 3 , dy + 3);
274 return(TRUE);
276 return(FALSE);
279 //--------------------------------------------------------------------------------------
280 // Free a IRes *, making sure not to free a NULL, and clearing the value afterwards
281 //--------------------------------------------------------------------------------------
282 void SafeFreeHnd(IRes **hndPtr)
284 if (*hndPtr != NULL)
286 (*hndPtr)->Unlock();
287 (*hndPtr)->Release();
288 *hndPtr = NULL;
292 //--------------------------------------------------------------------------------------
293 // Return the pixel value at x,y within the bitmap specified by the handle
294 //--------------------------------------------------------------------------------------
295 DWORD HandleGetPix(IRes *handle, Point loc)
297 DWORD retval = 0;
298 grs_bitmap *bm;
299 if (handle != NULL)
301 bm = (grs_bitmap *) handle->Lock();
302 if ((loc.x >= bm->w) || (loc.y >= bm->h) || (loc.x < 0) || (loc.y < 0))
303 retval = 0;
304 else
305 retval = gr_get_pixel_bm(bm,loc.x,loc.y);
306 handle->Unlock();
308 return(retval);
311 //--------------------------------------------------------------------------------------
312 // just does the mechanical UI elements, no state changes
313 IRes *gCursorHnd = NULL;
314 extern IRes *gDefaultHnd;
316 void RemoveCursor()
318 gCursorHnd = gDefaultHnd;
321 //--------------------------------------------------------------------------------------
322 // Returns the cursor to it's default state
323 //--------------------------------------------------------------------------------------
324 // hmm, should this check to make sure that isn't going to pop down to nothing?
325 void ClearCursor(void)
327 if (shock_cursor_mode != SCM_NORMAL)
329 //mprintf("Clearing cursor\n");
331 RemoveCursor();
332 shock_cursor_mode = SCM_NORMAL;
333 drag_obj = OBJ_NULL;
337 //--------------------------------------------------------------------------------------
338 // Given a bitmap handle, makes that bitmap the current cursor
339 //--------------------------------------------------------------------------------------
340 // do we also want a grs_bitmap version of this?
341 bool SetCursorByHandle(IRes *hnd) // , Cursor *cursorp)
343 RemoveCursor();
345 if (hnd != NULL)
347 gCursorHnd = hnd;
348 return(TRUE);
350 return(FALSE);
352 //--------------------------------------------------------------------------------------
353 // takes in a color triplet
354 int FindColor(int *color)
356 // Lookup the correct color
357 int icol = 0;
358 for (int i = 2; i >= 0; i--)
360 icol <<= 8;
361 icol |= color[i] & 0xFF;
363 return(gr_make_screen_fcolor(icol));
365 //--------------------------------------------------------------------------------------
366 char *string_basepath = "strings/";
367 BOOL ShockStringFetch(char *temp,int bufsize, const char *name, const char *table,int offset)
369 AutoAppIPtr(ResMan);
370 char usename[255];
371 if (strlen(name) == 0)
372 return(FALSE);
374 if (offset == -1)
375 strcpy(usename,name);
376 else
377 sprintf(usename,"%s%d",name,offset);
379 cAutoIPtr<IRes> res = pResMan->Bind(table,
380 RESTYPE_STRING,
381 NULL,
382 string_basepath);
383 cAutoIPtr<IStringRes> strres (IID_IStringRes,res);
384 if (strres == NULL)
385 return(FALSE);
386 const char* s = strres->StringLock(usename);
388 if (s)
390 strncpy(temp,s,bufsize);
391 strres->StringUnlock(usename);
392 return(TRUE);
394 else
396 strcpy(temp,"");
397 return(FALSE);
400 //--------------------------------------------------------------------------------------
401 void DrawVerticalString(char *text, int x, int y, int dy)
403 int j;
404 char s[2];
405 Point drawpt;
406 //int w;
408 drawpt.x = x;
409 drawpt.y = y;
411 s[1] = '\0';
413 gr_set_fcolor(gShockTextColor);
415 for (j=0; j < strlen(text); j++)
417 s[0] = text[j];
418 //w = gr_font_string_width(gShockFont, s);
419 gr_font_string(gShockFont, s, drawpt.x, drawpt.y);
420 drawpt.y = drawpt.y + dy;
423 //--------------------------------------------------------------------------------------