//////////////////////////////////////////////////////////// // TSprite256Control // ----------------- // void TSprite256Control::LoadPictureData (const char *picname, BYTE HUGE **ppData, USHORT *pxsize, USHORT *pysize, SHORT remapPlayer) { MDirPtr dir; SHORT x, y; SHORT xofs, yofs; BYTE HUGE *lpColumnData; BYTE *lpColumn; BYTE color; LONG *lpNeededOffsets; SHORT nColumns, nCurrentColumn; LONG lCurrentOffset; SHORT i, n; BYTE bRowStart, bColored; assert (pUsedColors != NULL); TRACE ("TSprite256Control::LoadPictureData(" << dec << picname); // Search for picture name dir = FindMasterDir (MasterDir, (char *)picname); if (dir == NULL) { *ppData = NULL; // Notify ("Couldn't find sprite or picture \"%s\" (BUG!)", picname); return; } // Read picture size and offset BasicWadSeek(dir->wadfile, dir->dir.start); BasicWadRead(dir->wadfile, pxsize, 2L); BasicWadRead(dir->wadfile, pysize, 2L); // We ingnore x and y offsets BasicWadRead(dir->wadfile, &xofs, 2L); BasicWadRead(dir->wadfile, &yofs, 2L); xofs = yofs = 0; USHORT xsize = *pxsize; USHORT ysize = *pysize; nColumns = xsize; // Allocate space for bitmap data ULONG dsize = (ULONG)xsize * ysize; TRACE ("TSprite256Control::LoadPictureData: " << dec << "Datasize = " << dsize << ", xsize = " << xsize << ", ysize = " << ysize); *ppData = (BYTE *)GetMemory (dsize); #define TEX_COLUMNBUFFERSIZE (60L * 1024L) #define TEX_COLUMNSIZE 512L // dir->size - 4 shorts (size and offset) - Columns offsets * 4L #define CD_BUFFER_SIZE (dir->dir.size - 4 * 2L - nColumns * 4L) /* Note from CJS: I tried to use far memory originally, but kept getting out-of-mem errors that is really strange - I assume that the wad dir et al uses all the far mem, and there is only near memory available. NEVER seen this situation before..... I'll keep them huge pointers anyway, in case something changes later */ lpColumnData = (BYTE HUGE *)GetMemory (CD_BUFFER_SIZE); // Initialize columns offsets lpNeededOffsets = (LONG *)GetMemory (nColumns * 4L); BasicWadRead (dir->wadfile, lpNeededOffsets, nColumns * 4); // read first column data, and subsequent column data BasicWadSeek(dir->wadfile, dir->dir.start + lpNeededOffsets[0]); BasicWadRead(dir->wadfile, lpColumnData, CD_BUFFER_SIZE); for (nCurrentColumn = 0; nCurrentColumn < nColumns; nCurrentColumn++) { lCurrentOffset = lpNeededOffsets[nCurrentColumn]; assert (lCurrentOffset - lpNeededOffsets[0] < CD_BUFFER_SIZE); lpColumn = (BYTE *)&lpColumnData[lCurrentOffset - lpNeededOffsets[0]]; /* we now have the needed column data, one way or another, so write it */ n = 1; bRowStart = lpColumn[0]; x = nCurrentColumn; while (bRowStart != 255 && n < TEX_COLUMNSIZE) { bColored = lpColumn[n]; n += 2; // skip over 'null' pixel in data y = bRowStart; for (i = 0; i < bColored; i++) { assert (x >= 0 && x < xsize); assert (y >= 0 && y < ysize); color = lpColumn[i+n]; // Remap player start position color (GREEN, RED, ...) if ( (remapPlayer) && (color >= 0x70) && (color < 0x80)) color += remapPlayer; (*ppData)[(LONG)y * xsize + x] = color; pUsedColors[color] = TRUE; y++; } n += bColored + 1; // skip over written pixels, and the 'null' one bRowStart = lpColumn[n++]; } assert (bRowStart == 255); } FreeMemory (lpColumnData); FreeMemory (lpNeededOffsets); }
/* basic opening of WAD file and creation of node in Wad linked list */ WadPtr BasicWadOpen( char *filename) { WadPtr curw, prevw; /* find the WAD file in the Wad file list */ prevw = WadFileList; if (prevw) { curw = prevw->next; while (curw && strcmp( filename, curw->filename)) { prevw = curw; curw = prevw->next; } } else curw = NULL; /* if this entry doesn't exist, add it to the WadFileList */ if (! curw) { curw = (WadPtr) GetMemory( sizeof( struct WadFileInfo)); if (! prevw) WadFileList = curw; else prevw->next = curw; curw->next = NULL; curw->filename = filename; } /* open the file */ if ((curw->fileinfo = fopen( filename, "rb")) == NULL) { if (! prevw) WadFileList = NULL; else prevw->next = curw->next; FreeMemory( curw); ProgError( "error opening \"%s\"", filename); } /* read in the WAD directory info */ BasicWadRead( curw, curw->type, 4); if (strncmp( curw->type, "IWAD", 4) && strncmp( curw->type, "PWAD", 4)) ProgError( "\"%s\" is not a valid WAD file", filename); BasicWadRead( curw, &curw->dirsize, sizeof( curw->dirsize)); swaplong( &(curw->dirsize)); BasicWadRead( curw, &curw->dirstart, sizeof( curw->dirstart)); swaplong( &(curw->dirstart)); /* read in the WAD directory itself */ curw->directory = (DirPtr) GetMemory( sizeof( struct Directory) * curw->dirsize); BasicWadSeek( curw, curw->dirstart); BasicWadRead( curw, curw->directory, sizeof( struct Directory) * curw->dirsize); #ifdef BIGEND { int i; for (i = 0; i < curw->dirsize; i++) { DirPtr d = &(curw->directory[ i]); swaplong( &(d->start)); swaplong( &(d->size)); } } #endif /* all done */ return curw; }
/* dump a directory entry in hex */ void DumpDirectoryEntry( FILE *file, char *entryname) { MDirPtr entry; char dataname[ 9]; char input[ 10]; char *key; BCINT lines = 2; long n, c, i; unsigned char buf[ 16]; c = 0; entry = MasterDir; while (entry) { if (! strncmp( entry->dir.name, entryname, 8)) { strncpy( dataname, entry->dir.name, 8); dataname[ 8] = '\0'; fprintf( file, "\nContents of entry %s (size = %ld bytes):\n\n", dataname, entry->dir.size); BasicWadSeek( entry->wadfile, entry->dir.start); n = 0; for (c = 0; c < entry->dir.size; c += 16) { fprintf( file, "%04lX: ", n); for (i = 0; i < 16; i++) { BasicWadRead( entry->wadfile, &(buf[ i]), 1); fprintf( file, " %02X", buf[ i]); n++; } fprintf( file, " "); for (i = 0; i < 16; i++) { if (buf[ i] >= 32) fprintf( file, "%c", buf[ i]); else fprintf( file, " "); } fprintf( file, "\n"); if (file == stdout && lines++ > 21) { lines = 0; printf( "[ %ld%% - Q to abort, S to skip this entry, any other key to continue] ", n * 100 / entry->dir.size); gets( input); key = strtok( input, " "); if (key != NULL) { if (*key == 'S' || *key == 's') { lines = 2; break; } if (*key == 'Q' || *key == 'q') return; } } } } entry = entry->next; } if (! c) { printf( "[Entry not in master directory.]\n"); return; } }
void TViewEntryDialog::EvDrawItem (UINT ctrlId, DRAWITEMSTRUCT& drawInfo) #endif { char Buf[128]; // To be sure if ( CurrentEntry == NULL ) return; // To be sure if ( ctrlId != IDC_VE_DUMP_LIST ) return; // If there are no list box items, skip this message. if ( drawInfo.itemID == (UINT)-1 ) return; // Build string to draw strcpy (Buf, ""); if ( drawInfo.itemID == 0 ) { char entryname[9]; strncpy (entryname, CurrentEntry->dir.name, 8); entryname[8] = '\0'; sprintf(Buf, "Contents of entry %s (size = %ld bytes):", entryname, CurrentEntry->dir.size); } else { // Starting Offset in the entry ULONG EntryOffset = (ULONG)(drawInfo.itemID - 1) * NB_HEX_LINE; // Starting Offset in the wad file ULONG WadOffset = CurrentEntry->dir.start + EntryOffset; // Number of chars for this line USHORT NbChars = min(NB_HEX_LINE, (USHORT)(CurrentEntry->dir.size - EntryOffset)); // Bytes of the line unsigned char HexBuf[NB_HEX_LINE]; // Line len int len; int i; BasicWadSeek (CurrentEntry->wadfile, WadOffset); // Dump offset len = sprintf(Buf, "%06lX:\t", EntryOffset); // 16 hex values for (i = 0 ; i < NbChars ; i++) { BasicWadRead (CurrentEntry->wadfile, &(HexBuf[i]), 1); len += sprintf (&Buf[len], "%02X\t", HexBuf[i]); } // Add padding tabs for (; i < NB_HEX_LINE ; i++) len += sprintf(&Buf[len], "\t"); // len += sprintf (&Buf[len], "\t"); // 16 chars for (i = 0 ; i < NbChars ; i++) { char c = HexBuf[i]; if ( ! isprint(c) ) c = ' '; len += sprintf (&Buf[len], "%c", c); } } switch (drawInfo.itemAction) { case ODA_SELECT: case ODA_DRAWENTIRE: { // Retreive the average character width TEXTMETRIC tm; GetTextMetrics(drawInfo.hDC, &tm); // Setup tab stops in HexDump list int TabStops[NB_HEX_LINE+1]; int i; TabStops[0] = 6 * tm.tmAveCharWidth; for (i = 1 ; i < NB_HEX_LINE ; i++) TabStops[i] = TabStops[i-1] + 3 * tm.tmAveCharWidth + 2; TabStops[i] = TabStops[i-1] + 4 * tm.tmAveCharWidth; TabbedTextOut(drawInfo.hDC, drawInfo.rcItem.left, drawInfo.rcItem.top, Buf, strlen(Buf), NB_HEX_LINE+2, TabStops, 0); #if 0 /* Is the item selected? */ if (drawInfo.itemState & ODS_SELECTED) { /* Draw a rectangle around bitmap to indicate the selection. */ DrawFocusRect(drawInfo.hDC, &drawInfo.rcItem); } #endif } break; case ODA_FOCUS: /* * Do not process focus changes. The focus caret (outline * rectangle) indicates the selection. The Which one? (IDOK) * button indicates the final selection. */ break; } }