00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00038 #include "../Include/Globals.h"
00039 #include "../Include/FlyLegacy.h"
00040 #include "../Include/CursorManager.h"
00041 #include "../Include/Utility.h"
00042 #include "../Include/Ui.h"
00043
00044 using namespace std;
00045
00046
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 CCursor::CCursor (const char* csrfilename)
00077 {
00078
00079 strcpy (csr, csrfilename);
00080 strcpy (curs, "");
00081 csid = 0;
00082 strcpy (imag, "");
00083 hots_x = hots_y = 0;
00084
00085
00086 SStream s;
00087 strcpy (s.filename, "DATA\\");
00088 strcat (s.filename, csrfilename);
00089 strcpy (s.mode, "r");
00090 if (OpenStream (&s)) {
00091 ReadFrom (this, &s);
00092 CloseStream (&s);
00093 }
00094 }
00095
00096
00097
00098
00099 CCursor::~CCursor (void)
00100 {
00101 if (texid != 0) FreeTexture();
00102 }
00103
00104
00105 void CCursor::Load (const char* pbmName)
00106 {
00107 int i, j;
00108
00109
00110 char pbmFilename[256];
00111 char actFilename[256];
00112 strcpy (pbmFilename, "Art\\");
00113 strcat (pbmFilename, pbmName);
00114
00115 strcpy (actFilename, pbmFilename);
00116 char *pExt = strrchr (actFilename, '.');
00117 if (pExt != NULL) {
00118 pExt++;
00119 strcpy (pExt, "ACT");
00120 } else {
00121 gtfo ("Invalid cursor PBM filename %s", pbmName);
00122 }
00123
00124
00125 PODFILE *act = popen (&globals->pfs, actFilename);
00126 RGB *actdata = new RGB[0x100];
00127 pread (actdata, 3, 0x100, act);
00128 pclose (act);
00129
00130
00131 PODFILE* pbm = popen (&globals->pfs, pbmFilename);
00132 SPBMHeader h;
00133 pread (&h, sizeof(SPBMHeader), 1, pbm);
00134 if (h.magic != 0x1A4D4250) {
00135 gtfo ("Invalid PBM magic value in %s", pbmName);
00136 }
00137 int width = h.width;
00138 int height = h.height;
00139
00140
00141 int texwidth = 32;
00142 int texheight = 32;
00143 if ((width > texwidth) || (height > texheight)) {
00144 gtfo ("Cursor image %s exceeds maximum size of 32x32 pixels", pbmName);
00145 }
00146
00147
00148
00149
00150 unsigned long *rowOffset = new unsigned long[height+1];
00151 pread (rowOffset, sizeof(unsigned long), height+1, pbm);
00152
00153
00154 unsigned long *rowLength = new unsigned long[height];
00155 for (i=0; i<height; i++) {
00156
00157 rowLength[i] = rowOffset[i+1] - rowOffset[i];
00158 }
00159
00160
00161 int rowDataSize = rowOffset[height];
00162 unsigned char *rowData = new unsigned char[rowDataSize];
00163 pread (rowData, 1, rowDataSize, pbm);
00164 pclose (pbm);
00165
00166
00167 GLubyte *teximage = new GLubyte[texwidth * texheight * 4];
00168 memset (teximage, 0, texwidth*texheight * 4);
00169
00170 for (i=0; i<height; i++) {
00171 unsigned char *p = &rowData[rowOffset[i]];
00172
00173
00174 unsigned long iRow = 0;
00175 while (iRow < rowLength[i]) {
00176
00177 short column;
00178 column = *((short*)p);
00179 p += sizeof(short);
00180 iRow += sizeof(short);
00181
00182
00183 short count;
00184 count = *((short*)p);
00185 p += sizeof(short);
00186 iRow += sizeof(short);
00187
00188
00189 for (j=0; j<count; j++) {
00190
00191 unsigned char iCmap = *p;
00192 p++;
00193 iRow++;
00194
00195
00196 unsigned int offset = (((texheight - i - 1) * texwidth) + column + j) * 4;
00197
00198
00199 if (iCmap == 0) {
00200
00201 teximage[offset + 0] = 0;
00202 teximage[offset + 1] = 0;
00203 teximage[offset + 2] = 0;
00204 teximage[offset + 3] = 0;
00205 } else {
00206
00207 teximage[offset + 0] = actdata[iCmap].r;
00208 teximage[offset + 1] = actdata[iCmap].g;
00209 teximage[offset + 2] = actdata[iCmap].b;
00210 teximage[offset + 3] = 0xff;
00211 }
00212 }
00213
00214
00215 while ((iRow % 4) != 0) {
00216 p++;
00217 iRow++;
00218 }
00219 }
00220 }
00221
00222
00223 delete actdata;
00224 delete rowOffset;
00225 delete rowLength;
00226 delete rowData;
00227
00228
00229 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
00230 glGenTextures (1, &texid);
00231 glBindTexture (GL_TEXTURE_2D, texid);
00232 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00233 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00234 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00235 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00236 GLenum format = GL_RGBA;
00237 glTexImage2D (GL_TEXTURE_2D, 0, format, texwidth, texheight, 0,
00238 format, GL_UNSIGNED_BYTE, teximage);
00239
00240
00241 delete teximage;
00242 }
00243
00244 void CCursor::FreeTexture (void)
00245 {
00246 glDeleteTextures (1, &texid);
00247 texid = 0;
00248 }
00249
00250 int CCursor::Read (SStream *stream, Tag tag)
00251 {
00252 int rc = TAG_IGNORED;
00253
00254 switch (tag) {
00255 case 'csid':
00256
00257 ReadTag (&csid, stream);
00258 rc = TAG_READ;
00259 break;
00260
00261 case 'imag':
00262
00263 ReadString (imag, 64, stream);
00264 rc = TAG_READ;
00265 break;
00266
00267 case 'curs':
00268
00269 ReadString (curs, 64, stream);
00270 rc = TAG_READ;
00271 break;
00272
00273 case 'hots':
00274
00275 ReadInt (&hots_x, stream);
00276 ReadInt (&hots_y, stream);
00277 rc = TAG_READ;
00278 break;
00279
00280 default:
00281 char s[16];
00282 TagToString (s, tag);
00283 globals->logWarning->Write ("CCursor::Read : Unknown tag <%s>", s);
00284 }
00285
00286 return rc;
00287 }
00288
00289
00290 void CCursor::ReadFinished (void)
00291 {
00292
00293 if (strlen (imag) > 0) {
00294 Load (imag);
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 }
00306
00307
00308
00309
00310
00311 CCursorManager::CCursorManager (void)
00312 {
00313 x = y = 0;
00314 crsrCurrent = NULL;
00315 }
00316
00317 CCursorManager::~CCursorManager (void)
00318 {
00319 map<Tag,CCursor*>::iterator iter;
00320 for (iter=cache.begin(); iter!=cache.end(); iter++) {
00321 delete iter->second;
00322 }
00323 }
00324
00325
00326
00327
00328 void CCursorManager::MouseMotion (int mouse_x, int mouse_y)
00329 {
00330 if (crsrCurrent != NULL) {
00331
00332
00333 x = mouse_x - crsrCurrent->hots_x;
00334 y = globals->screenHeight - mouse_y - 1 - 32 + crsrCurrent->hots_y;
00335 }
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 }
00348
00349
00350 CCursor *CCursorManager::FindCursor (const char *csrfilename)
00351 {
00352 CCursor *rc = NULL;
00353
00354 map<Tag,CCursor*>::iterator iter;
00355 for (iter=cache.begin(); iter!=cache.end() && (rc == NULL); iter++) {
00356 CCursor *crsr = iter->second;
00357 if (strcmp (crsr->csr, csrfilename) == 0) {
00358 rc = crsr;
00359 }
00360 }
00361
00362 return rc;
00363 }
00364
00365 CCursor *CCursorManager::FindCursor (Tag tag)
00366 {
00367 CCursor *rc = NULL;
00368
00369 map<Tag,CCursor*>::iterator iter = cache.find(tag);
00370 if (iter != cache.end()) {
00371 rc = iter->second;
00372 }
00373
00374 return rc;
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384 Tag CCursorManager::BindCursor (const char *csrfilename)
00385 {
00386 Tag rc = 0;
00387
00388 CCursor *crsr = FindCursor (csrfilename);
00389 if (crsr == NULL) {
00390
00391 crsr = new CCursor (csrfilename);
00392 cache[crsr->csid] = crsr;
00393 }
00394
00395
00396 if (crsr != NULL) {
00397 rc = crsr->csid;
00398 }
00399
00400 return rc;
00401 }
00402
00403
00404 int CCursorManager::GetNumBoundCursors (void)
00405 {
00406 return cache.size();
00407 }
00408
00409
00410 void CCursorManager::SetCursor (Tag tag)
00411 {
00412 crsrCurrent = FindCursor (tag);
00413 }
00414
00415 Tag CCursorManager::GetCursor (void)
00416 {
00417 Tag rc = 0;
00418
00419 if (crsrCurrent != NULL) {
00420 rc = crsrCurrent->csid;
00421 }
00422
00423 return rc;
00424 }
00425
00426
00427 void CCursorManager::Draw (void)
00428 {
00429 if (crsrCurrent != NULL) {
00430
00431 glMatrixMode(GL_PROJECTION);
00432 glPushMatrix();
00433 glLoadIdentity ();
00434 gluOrtho2D (0, globals->screenWidth, 0, globals->screenHeight);
00435
00436
00437 glMatrixMode (GL_MODELVIEW);
00438 glPushMatrix ();
00439 glLoadIdentity ();
00440 glTranslatef (x, y, 0);
00441
00442 glPushAttrib (GL_ENABLE_BIT);
00443 glDisable (GL_LIGHTING);
00444 glEnable (GL_ALPHA_TEST);
00445 glDisable (GL_DEPTH_TEST);
00446
00447 glEnable (GL_TEXTURE_2D);
00448 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00449 glBindTexture (GL_TEXTURE_2D, crsrCurrent->texid);
00450
00451
00452 glBegin (GL_QUADS);
00453 glTexCoord2f (0.0, 0.0);
00454 glVertex2f (0, 0);
00455
00456 glTexCoord2f (1.0, 0.0);
00457 glVertex2f (32, 0);
00458
00459 glTexCoord2f (1.0, 1.0);
00460 glVertex2f (32, 32);
00461
00462 glTexCoord2f (0.0, 1.0);
00463 glVertex2f (0, 32);
00464 glEnd ();
00465 glFlush ();
00466
00467
00468 glPopAttrib ();
00469 glMatrixMode (GL_MODELVIEW);
00470 glPopMatrix ();
00471 glMatrixMode (GL_PROJECTION);
00472 glPopMatrix ();
00473
00474
00475 GLenum e = glGetError ();
00476 if (e != GL_NO_ERROR) {
00477 gtfo ("CCursorManager::Draw : GL Error 0x%04X", e);
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 }
00490 }
00491