SDL_Surface *GetCIcon(FrameBuf *screen, short cicn_id) { char file[256]; LibPath path; SDL_Surface *cicn; SDL_RWops *cicn_src; Uint8 *pixels, *mask; Uint16 w, h; /* Open the cicn sprite file.. */ sprintf(file, "Images"DIR_SEP"Maelstrom_Icon#%hd.cicn", cicn_id); if ( (cicn_src=SDL_RWFromFile(path.Path(file), "r")) == NULL ) { error("GetCIcon(%hd): Can't open CICN %s: ", cicn_id, path.Path(file)); return(NULL); } w = SDL_ReadBE16(cicn_src); h = SDL_ReadBE16(cicn_src); pixels = new Uint8[w*h]; if ( SDL_RWread(cicn_src, pixels, 1, w*h) != (w*h) ) { error("GetCIcon(%hd): Corrupt CICN!\n", cicn_id); delete[] pixels; SDL_RWclose(cicn_src); return(NULL); } mask = new Uint8[(w/8)*h]; if ( SDL_RWread(cicn_src, mask, 1, (w/8)*h) != ((w/8)*h) ) { error("GetCIcon(%hd): Corrupt CICN!\n", cicn_id); delete[] pixels; delete[] mask; SDL_RWclose(cicn_src); return(NULL); } SDL_RWclose(cicn_src); cicn = screen->LoadImage(w, h, pixels, mask); delete[] pixels; delete[] mask; if ( cicn == NULL ) { error("GetCIcon(%hd): Couldn't convert CICN!\n", cicn_id); } return(cicn); }
static void extract_fork(SDL_RWops *fin, int req_id, const char *file_name, const char *fork_name) { long id, fork_start, fork_size; int num_entries, fork_found; SDL_RWops *fout; // Look for fork in source file SDL_RWseek(fin, 0x18, SEEK_SET); num_entries = SDL_ReadBE16(fin); while (num_entries--) { Uint32 id = SDL_ReadBE32(fin); Sint32 ofs = SDL_ReadBE32(fin); Sint32 len = SDL_ReadBE32(fin); if (id == req_id) { fork_found = 1; fork_start = ofs; fork_size = len; } } if (!fork_found) { fprintf(stderr, "Warning: source file doesn't contain a %s fork.\n", fork_name); return; } // Found, open destination file fout = SDL_RWFromFile(file_name, "wb"); if (fout == NULL) { perror("Can't open destination file"); exit(1); } // Copy fork SDL_RWseek(fin, fork_start, SEEK_SET); while (fork_size) { long length = fork_size > BUFFER_SIZE ? BUFFER_SIZE : fork_size; SDL_RWread(fin, buffer, 1, length); SDL_RWwrite(fout, buffer, 1, length); fork_size -= length; } SDL_FreeRW(fout); }
/** * @brief Tests writing and reading from file using endian aware functions. * * \sa * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile * http://wiki.libsdl.org/moin.cgi/SDL_RWClose * http://wiki.libsdl.org/moin.cgi/SDL_ReadBE16 * http://wiki.libsdl.org/moin.cgi/SDL_WriteBE16 */ int rwops_testFileWriteReadEndian(void) { SDL_RWops *rw; Sint64 result; int mode; size_t objectsWritten; Uint16 BE16value; Uint32 BE32value; Uint64 BE64value; Uint16 LE16value; Uint32 LE32value; Uint64 LE64value; Uint16 BE16test; Uint32 BE32test; Uint64 BE64test; Uint16 LE16test; Uint32 LE32test; Uint64 LE64test; int cresult; for (mode = 0; mode < 3; mode++) { /* Create test data */ switch (mode) { case 0: SDLTest_Log("All 0 values"); BE16value = 0; BE32value = 0; BE64value = 0; LE16value = 0; LE32value = 0; LE64value = 0; break; case 1: SDLTest_Log("All 1 values"); BE16value = 1; BE32value = 1; BE64value = 1; LE16value = 1; LE32value = 1; LE64value = 1; break; case 2: SDLTest_Log("Random values"); BE16value = SDLTest_RandomUint16(); BE32value = SDLTest_RandomUint32(); BE64value = SDLTest_RandomUint64(); LE16value = SDLTest_RandomUint16(); LE32value = SDLTest_RandomUint32(); LE64value = SDLTest_RandomUint64(); break; } /* Write test. */ rw = SDL_RWFromFile(RWopsWriteTestFilename, "w+"); SDLTest_AssertPass("Call to SDL_RWFromFile(..,\"w+\")"); SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFile in write mode does not return NULL"); /* Bail out if NULL */ if (rw == NULL) return TEST_ABORTED; /* Write test data */ objectsWritten = SDL_WriteBE16(rw, BE16value); SDLTest_AssertPass("Call to SDL_WriteBE16"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteBE32(rw, BE32value); SDLTest_AssertPass("Call to SDL_WriteBE32"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteBE64(rw, BE64value); SDLTest_AssertPass("Call to SDL_WriteBE64"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteLE16(rw, LE16value); SDLTest_AssertPass("Call to SDL_WriteLE16"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteLE32(rw, LE32value); SDLTest_AssertPass("Call to SDL_WriteLE32"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); objectsWritten = SDL_WriteLE64(rw, LE64value); SDLTest_AssertPass("Call to SDL_WriteLE64"); SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", objectsWritten); /* Test seek to start */ result = SDL_RWseek( rw, 0, RW_SEEK_SET ); SDLTest_AssertPass("Call to SDL_RWseek succeeded"); SDLTest_AssertCheck(result == 0, "Verify result from position 0 with SDL_RWseek, expected 0, got %i", result); /* Read test data */ BE16test = SDL_ReadBE16(rw); SDLTest_AssertPass("Call to SDL_ReadBE16"); SDLTest_AssertCheck(BE16test == BE16value, "Validate return value from SDL_ReadBE16, expected: %hu, got: %hu", BE16value, BE16test); BE32test = SDL_ReadBE32(rw); SDLTest_AssertPass("Call to SDL_ReadBE32"); SDLTest_AssertCheck(BE32test == BE32value, "Validate return value from SDL_ReadBE32, expected: %u, got: %u", BE32value, BE32test); BE64test = SDL_ReadBE64(rw); SDLTest_AssertPass("Call to SDL_ReadBE64"); SDLTest_AssertCheck(BE64test == BE64value, "Validate return value from SDL_ReadBE64, expected: %llu, got: %llu", BE64value, BE64test); LE16test = SDL_ReadLE16(rw); SDLTest_AssertPass("Call to SDL_ReadLE16"); SDLTest_AssertCheck(LE16test == LE16value, "Validate return value from SDL_ReadLE16, expected: %hu, got: %hu", LE16value, LE16test); LE32test = SDL_ReadLE32(rw); SDLTest_AssertPass("Call to SDL_ReadLE32"); SDLTest_AssertCheck(LE32test == LE32value, "Validate return value from SDL_ReadLE32, expected: %u, got: %u", LE32value, LE32test); LE64test = SDL_ReadLE64(rw); SDLTest_AssertPass("Call to SDL_ReadLE64"); SDLTest_AssertCheck(LE64test == LE64value, "Validate return value from SDL_ReadLE64, expected: %llu, got: %llu", LE64value, LE64test); /* Close handle */ cresult = SDL_RWclose(rw); SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); SDLTest_AssertCheck(cresult == 0, "Verify result value is 0; got: %d", cresult); } return TEST_COMPLETED; }
// Determine file type Typecode FileSpecifier::GetType() { // if there's an extension, assume it's correct const char *extension = strrchr(GetPath(), '.'); if (extension) { extension_mapping *mapping = extensions; while (mapping->extension) { if (( mapping->case_sensitive && (strcmp(extension + 1, mapping->extension) == 0)) || (!mapping->case_sensitive && (strcasecmp(extension + 1, mapping->extension) == 0))) { return mapping->typecode; } ++mapping; } } // Open file OpenedFile f; if (!Open(f)) return _typecode_unknown; SDL_RWops *p = f.GetRWops(); int32 file_length = 0; f.GetLength(file_length); // Check for Sounds file { f.SetPosition(0); uint32 version = SDL_ReadBE32(p); uint32 tag = SDL_ReadBE32(p); if ((version == 0 || version == 1) && tag == FOUR_CHARS_TO_INT('s', 'n', 'd', '2')) return _typecode_sounds; } // Check for Map/Physics file { f.SetPosition(0); int version = SDL_ReadBE16(p); int data_version = SDL_ReadBE16(p); if ((version == 0 || version == 1 || version == 2 || version == 4) && (data_version == 0 || data_version == 1 || data_version == 2)) { SDL_RWseek(p, 68, SEEK_CUR); int32 directory_offset = SDL_ReadBE32(p); if (directory_offset >= file_length) goto not_map; f.SetPosition(128); uint32 tag = SDL_ReadBE32(p); // ghs: I do not believe this list is comprehensive // I think it's just what we've seen so far? switch (tag) { case LINE_TAG: case POINT_TAG: case SIDE_TAG: return _typecode_scenario; break; case MONSTER_PHYSICS_TAG: return _typecode_physics; break; } } not_map: ; } // Check for Shapes file { f.SetPosition(0); for (int i=0; i<32; i++) { uint32 status_flags = SDL_ReadBE32(p); int32 offset = SDL_ReadBE32(p); int32 length = SDL_ReadBE32(p); int32 offset16 = SDL_ReadBE32(p); int32 length16 = SDL_ReadBE32(p); if (status_flags != 0 || (offset != NONE && (offset >= file_length || offset + length > file_length)) || (offset16 != NONE && (offset16 >= file_length || offset16 + length16 > file_length))) goto not_shapes; SDL_RWseek(p, 12, SEEK_CUR); } return _typecode_shapes; not_shapes: ; } // Not identified return _typecode_unknown; }