static int _mm_RWopsReader_Get(MREADER* reader) { char buf; if ( SDL_RWread(((MRWOPSREADER*)reader)->rw, &buf, 1, 1) != 1 ) return EOF; else return (int)buf; }
/* Open an SDL_RWops for reading */ LDAT *ldat_open_rw (SDL_RWops * rw) { char header[LDAT_MAGIC_LEN]; LDAT *newldat; LDAT_Block *newblock; Uint16 i, itemcount; Uint8 idlen; newldat = ldat_create (); newldat->data = rw; /* Read header */ SDL_RWread (newldat->data, header, 1, LDAT_MAGIC_LEN); if (strncmp (header, "LDAT", 4)) { fprintf (stderr,"Error: this is not an LDAT archive !\n"); return NULL; } if (header[4] != LDAT_MAJOR) { fprintf (stderr, "Error: Unsupported version (%d.%d) !\n", header[4], header[5]); fprintf (stderr, "Latest supported version is %d.%d\n", LDAT_MAJOR, LDAT_MINOR); return NULL; } /* Read catalog */ if(Luola_ReadLE16 (newldat->data,&itemcount) == -1) { fprintf(stderr,"Error occured while reading itemcount!\n"); } for (i = 0; i < itemcount; i++) { newblock = malloc (sizeof (LDAT_Block)); memset (newblock, 0, sizeof (LDAT_Block)); if (SDL_RWread (newldat->data, &idlen, 1, 1) == -1) { fprintf (stderr, "(%d) Error occured while reading idlen!\n", i); return NULL; } newblock->ID = malloc (idlen + 1); if (SDL_RWread (newldat->data, newblock->ID, 1, idlen) == -1) { fprintf (stderr, "(%d) Error occured while reading ID string!\n", i); return NULL; } newblock->ID[idlen] = '\0'; if (Luola_ReadLE16(newldat->data, &newblock->index) == -1) { fprintf (stderr, "(%d) Error occured while reading index number!\n", i); return NULL; } if (Luola_ReadLE32(newldat->data, &newblock->pos) == -1) { fprintf (stderr, "(%d) Error occured while reading position!\n", i); return NULL; } if (Luola_ReadLE32(newldat->data, &newblock->size) == -1) { fprintf (stderr, "(%d) Error occured while reading size!\n", i); return NULL; } if (newldat->catalog == NULL) newldat->catalog = newblock; else { newblock->prev = newldat->catalog; newldat->catalog->next = newblock; newldat->catalog = newblock; } } newldat->catalog_size = SDL_RWtell (newldat->data) - LDAT_HEADER_LEN; /* Rewing catalog */ while (newldat->catalog->prev) newldat->catalog = newldat->catalog->prev; return newldat; }
static size_t sdl_read_func(void *ptr, size_t size, size_t nmemb, void *datasource) { return SDL_RWread((SDL_RWops*)datasource, ptr, size, nmemb); }
SDL_Surface *IMG_LoadPNM_RW(SDL_RWops *src) { SDL_Surface *surface = NULL; int width, height; int maxval, y, bpl; Uint8 *row; Uint8 *buf = NULL; char *error = NULL; Uint8 magic[2]; int ascii; enum { PBM, PGM, PPM } kind; #define ERROR(s) do { error = (s); goto done; } while(0) if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } SDL_RWread(src, magic, 2, 1); kind = magic[1] - '1'; ascii = 1; if(kind >= 3) { ascii = 0; kind -= 3; } width = ReadNumber(src); height = ReadNumber(src); if(width <= 0 || height <= 0) ERROR("Unable to read image width and height"); if(kind != PBM) { maxval = ReadNumber(src); if(maxval <= 0 || maxval > 255) ERROR("unsupported PNM format"); } else maxval = 255; /* never scale PBMs */ /* binary PNM allows just a single character of whitespace after the last parameter, and we've already consumed it */ if(kind == PPM) { /* 24-bit surface in R,G,B byte order */ surface = SDL_AllocSurface(SDL_SWSURFACE, width, height, 24, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x000000ff, 0x0000ff00, 0x00ff0000, #else 0x00ff0000, 0x0000ff00, 0x000000ff, #endif 0); } else { /* load PBM/PGM as 8-bit indexed images */ surface = SDL_AllocSurface(SDL_SWSURFACE, width, height, 8, 0, 0, 0, 0); } if ( surface == NULL ) ERROR("Out of memory"); bpl = width * surface->format->BytesPerPixel; if(kind == PGM) { SDL_Color *c = surface->format->palette->colors; int i; for(i = 0; i < 256; i++) c[i].r = c[i].g = c[i].b = i; surface->format->palette->ncolors = 256; } else if(kind == PBM) { /* for some reason PBM has 1=black, 0=white */ SDL_Color *c = surface->format->palette->colors; c[0].r = c[0].g = c[0].b = 255; c[1].r = c[1].g = c[1].b = 0; surface->format->palette->ncolors = 2; bpl = (width + 7) >> 3; buf = malloc(bpl); if(buf == NULL) ERROR("Out of memory"); }
size_t SDLRWops::read(void *ptr, size_t size, size_t num) { return SDL_RWread(rwops_, ptr, num, size); }
NativeMidiSong *native_midi_loadsong_RW(SDL_RWops *rw) { NativeMidiSong *retval = NULL; void *buf = NULL; int len = 0; CFDataRef data = NULL; if (SDL_RWseek(rw, 0, RW_SEEK_END) < 0) goto fail; len = SDL_RWtell(rw); if (len < 0) goto fail; if (SDL_RWseek(rw, 0, RW_SEEK_SET) < 0) goto fail; buf = malloc(len); if (buf == NULL) goto fail; if (SDL_RWread(rw, buf, len, 1) != 1) goto fail; retval = malloc(sizeof(NativeMidiSong)); if (retval == NULL) goto fail; memset(retval, '\0', sizeof (*retval)); if (NewMusicPlayer(&retval->player) != noErr) goto fail; if (NewMusicSequence(&retval->sequence) != noErr) goto fail; data = CFDataCreate(NULL, (const UInt8 *) buf, len); if (data == NULL) goto fail; free(buf); buf = NULL; #if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 /* this is deprecated, but works back to 10.3 */ if (MusicSequenceLoadSMFDataWithFlags(retval->sequence, data, 0) != noErr) goto fail; #else /* not deprecated, but requires 10.5 or later */ if (MusicSequenceFileLoadData(retval->sequence, data, 0, 0) != noErr) goto fail; #endif CFRelease(data); data = NULL; if (GetSequenceLength(retval->sequence, &retval->endTime) != noErr) goto fail; if (MusicPlayerSetSequence(retval->player, retval->sequence) != noErr) goto fail; return retval; fail: if (retval) { if (retval->sequence) DisposeMusicSequence(retval->sequence); if (retval->player) DisposeMusicPlayer(retval->player); free(retval); } if (data) CFRelease(data); if (buf) free(buf); return NULL; }
size_t THSoundArchive::getSoundDuration(size_t iIndex) { SDL_RWops *pFile = loadSound(iIndex); if(!pFile) return 0; uint16_t iWaveAudioFormat = 0; uint16_t iWaveChannelCount = 0; uint32_t iWaveSampleRate = 0; uint32_t iWaveByteRate = 0; uint16_t iWaveBlockAlign = 0; uint16_t iWaveBitsPerSample = 0; uint32_t iWaveDataLength = 0; // This is a very crude RIFF parser, but it does the job. uint32_t iFourCC; uint32_t iChunkLength; for(;;) { if(SDL_RWread(pFile, &iFourCC, 4, 1) != 1) break; if(SDL_RWread(pFile, &iChunkLength, 4, 1) != 1) break; if(iFourCC == FOURCC('R','I','F','F') || iFourCC == FOURCC('L','I','S','T')) { if(iChunkLength >= 4) { if(SDL_RWread(pFile, &iFourCC, 4, 1) != 1) break; else continue; } } if(iFourCC == FOURCC('f','m','t',' ') && iChunkLength >= 16) { if(SDL_RWread(pFile, &iWaveAudioFormat, 2, 1) != 1) break; if(SDL_RWread(pFile, &iWaveChannelCount, 2, 1) != 1) break; if(SDL_RWread(pFile, &iWaveSampleRate, 4, 1) != 1) break; if(SDL_RWread(pFile, &iWaveByteRate, 4, 1) != 1) break; if(SDL_RWread(pFile, &iWaveBlockAlign, 2, 1) != 1) break; if(SDL_RWread(pFile, &iWaveBitsPerSample, 2, 1) != 1) break; iChunkLength -= 16; } //Finally: if(iFourCC == FOURCC('d','a','t','a')) { iWaveDataLength = iChunkLength; break; } if(SDL_RWseek(pFile, iChunkLength + (iChunkLength & 1), RW_SEEK_CUR) == -1) { break; } } SDL_RWclose(pFile); if(iWaveAudioFormat != 1 || iWaveChannelCount == 0 || iWaveSampleRate == 0 || iWaveDataLength == 0 || iWaveBitsPerSample == 0) { return 0; } #define mul64(a, b) (static_cast<uint64_t>(a) * static_cast<uint64_t>(b)) return static_cast<size_t>(mul64(iWaveDataLength, 8000) / mul64(mul64(iWaveBitsPerSample, iWaveChannelCount), iWaveSampleRate)); #undef mul64 }
void TR_Level::read_tr5_room(SDL_RWops * const src, tr5_room_t & room) { uint32_t room_data_size; //uint32_t portal_offset; uint32_t sector_data_offset; uint32_t static_meshes_offset; uint32_t layer_offset; uint32_t vertices_offset; uint32_t poly_offset; uint32_t poly_offset2; uint32_t vertices_size; //uint32_t light_size; SDL_RWops *newsrc = NULL; uint32_t temp; uint32_t i; uint8_t *buffer; if (read_bitu32(src) != 0x414C4558) Sys_extError("read_tr5_room: 'XELA' not found"); room_data_size = read_bitu32(src); buffer = new uint8_t[room_data_size]; if (SDL_RWread(src, buffer, 1, room_data_size) < room_data_size) Sys_extError("read_tr5_room: room_data"); if ((newsrc = SDL_RWFromMem(buffer, room_data_size)) == NULL) Sys_extError("read_tr5_room: SDL_RWFromMem"); room.intensity1 = 32767; room.intensity2 = 32767; room.light_mode = 0; if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator1 has wrong value"); /*portal_offset = */read_bit32(newsrc); // StartPortalOffset? // endSDOffset sector_data_offset = read_bitu32(newsrc); // StartSDOffset temp = read_bitu32(newsrc); if ((temp != 0) && (temp != 0xCDCDCDCD)) Sys_extWarn("read_tr5_room: seperator2 has wrong value"); static_meshes_offset = read_bitu32(newsrc); // endPortalOffset // static_meshes_offset or room_layer_offset // read and change coordinate system room.offset.x = (float)read_bit32(newsrc); room.offset.y = read_bitu32(newsrc); room.offset.z = (float)-read_bit32(newsrc); room.y_bottom = (float)-read_bit32(newsrc); room.y_top = (float)-read_bit32(newsrc); room.num_zsectors = read_bitu16(newsrc); room.num_xsectors = read_bitu16(newsrc); room.light_colour.b = read_bitu8(newsrc) / 255.0f; room.light_colour.g = read_bitu8(newsrc) / 255.0f; room.light_colour.r = read_bitu8(newsrc) / 255.0f; room.light_colour.a = read_bitu8(newsrc) / 255.0f; room.num_lights = read_bitu16(newsrc); if (room.num_lights > 512) Sys_extWarn("read_tr5_room: num_lights > 512"); room.num_static_meshes = read_bitu16(newsrc); if (room.num_static_meshes > 512) Sys_extWarn("read_tr5_room: num_static_meshes > 512"); room.reverb_info = read_bitu8(newsrc); room.alternate_group = read_bitu8(newsrc); room.water_scheme = read_bitu16(newsrc); if (read_bitu32(newsrc) != 0x00007FFF) Sys_extWarn("read_tr5_room: filler1 has wrong value"); if (read_bitu32(newsrc) != 0x00007FFF) Sys_extWarn("read_tr5_room: filler2 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator4 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator5 has wrong value"); if (read_bitu32(newsrc) != 0xFFFFFFFF) Sys_extWarn("read_tr5_room: seperator6 has wrong value"); room.alternate_room = read_bit16(newsrc); room.flags = read_bitu16(newsrc); room.unknown_r1 = read_bitu32(newsrc); room.unknown_r2 = read_bitu32(newsrc); room.unknown_r3 = read_bitu32(newsrc); temp = read_bitu32(newsrc); if ((temp != 0) && (temp != 0xCDCDCDCD)) Sys_extWarn("read_tr5_room: seperator7 has wrong value"); room.unknown_r4a = read_bitu16(newsrc); room.unknown_r4b = read_bitu16(newsrc); room.room_x = read_float(newsrc); room.unknown_r5 = read_bitu32(newsrc); room.room_z = -read_float(newsrc); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator8 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator9 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator10 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator11 has wrong value"); temp = read_bitu32(newsrc); if ((temp != 0) && (temp != 0xCDCDCDCD)) Sys_extWarn("read_tr5_room: seperator12 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator13 has wrong value"); room.num_triangles = read_bitu32(newsrc); if (room.num_triangles == 0xCDCDCDCD) room.num_triangles = 0; if (room.num_triangles > 512) Sys_extWarn("read_tr5_room: num_triangles > 512"); room.num_rectangles = read_bitu32(newsrc); if (room.num_rectangles == 0xCDCDCDCD) room.num_rectangles = 0; if (room.num_rectangles > 1024) Sys_extWarn("read_tr5_room: num_rectangles > 1024"); if (read_bitu32(newsrc) != 0) Sys_extWarn("read_tr5_room: seperator14 has wrong value"); /*light_size = */read_bitu32(newsrc); if (read_bitu32(newsrc) != room.num_lights) Sys_extError("read_tr5_room: room.num_lights2 != room.num_lights"); room.unknown_r6 = read_bitu32(newsrc); room.room_y_top = -read_float(newsrc); room.room_y_bottom = -read_float(newsrc); room.num_layers = read_bitu32(newsrc); /* if (room.num_layers != 0) { if (room.x != room.room_x) throw TR_ReadError("read_tr5_room: x != room_x"); if (room.z != room.room_z) throw TR_ReadError("read_tr5_room: z != room_z"); if (room.y_top != room.room_y_top) throw TR_ReadError("read_tr5_room: y_top != room_y_top"); if (room.y_bottom != room.room_y_bottom) throw TR_ReadError("read_tr5_room: y_bottom != room_y_bottom"); } */ layer_offset = read_bitu32(newsrc); vertices_offset = read_bitu32(newsrc); poly_offset = read_bitu32(newsrc); poly_offset2 = read_bitu32(newsrc); if (poly_offset != poly_offset2) Sys_extError("read_tr5_room: poly_offset != poly_offset2"); vertices_size = read_bitu32(newsrc); if ((vertices_size % 28) != 0) Sys_extError("read_tr5_room: vertices_size has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator15 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator16 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator17 has wrong value"); if (read_bitu32(newsrc) != 0xCDCDCDCD) Sys_extWarn("read_tr5_room: seperator18 has wrong value"); room.lights = (tr5_room_light_t*)malloc(room.num_lights * sizeof(tr5_room_light_t)); for (i = 0; i < room.num_lights; i++) read_tr5_room_light(newsrc, room.lights[i]); SDL_RWseek(newsrc, 208 + sector_data_offset, SEEK_SET); room.sector_list = (tr_room_sector_t*)malloc(room.num_zsectors * room.num_xsectors * sizeof(tr_room_sector_t)); for (i = 0; i < (uint32_t)(room.num_zsectors * room.num_xsectors); i++) read_tr_room_sector(newsrc, room.sector_list[i]); /* if (room.portal_offset != 0xFFFFFFFF) { if (room.portal_offset != (room.sector_data_offset + (room.num_zsectors * room.num_xsectors * 8))) throw TR_ReadError("read_tr5_room: portal_offset has wrong value"); SDL_RWseek(newsrc, 208 + room.portal_offset, SEEK_SET); } */ room.num_portals = read_bit16(newsrc); room.portals = (tr_room_portal_t*)malloc(room.num_portals * sizeof(tr_room_portal_t)); for (i = 0; i < room.num_portals; i++) read_tr_room_portal(newsrc, room.portals[i]); SDL_RWseek(newsrc, 208 + static_meshes_offset, SEEK_SET); room.static_meshes = (tr2_room_staticmesh_t*)malloc(room.num_static_meshes * sizeof(tr2_room_staticmesh_t)); for (i = 0; i < room.num_static_meshes; i++) read_tr4_room_staticmesh(newsrc, room.static_meshes[i]); SDL_RWseek(newsrc, 208 + layer_offset, SEEK_SET); room.layers = (tr5_room_layer_t*)malloc(room.num_layers * sizeof(tr5_room_layer_t)); for (i = 0; i < room.num_layers; i++) read_tr5_room_layer(newsrc, room.layers[i]); SDL_RWseek(newsrc, 208 + poly_offset, SEEK_SET); { uint32_t vertex_index = 0; uint32_t rectangle_index = 0; uint32_t triangle_index = 0; room.rectangles = (tr4_face4_t*)malloc(room.num_rectangles * sizeof(tr4_face4_t)); room.triangles = (tr4_face3_t*)malloc(room.num_triangles * sizeof(tr4_face3_t)); for (i = 0; i < room.num_layers; i++) { uint32_t j; for (j = 0; j < room.layers[i].num_rectangles; j++) { read_tr4_face4(newsrc, room.rectangles[rectangle_index]); room.rectangles[rectangle_index].vertices[0] += vertex_index; room.rectangles[rectangle_index].vertices[1] += vertex_index; room.rectangles[rectangle_index].vertices[2] += vertex_index; room.rectangles[rectangle_index].vertices[3] += vertex_index; rectangle_index++; } for (j = 0; j < room.layers[i].num_triangles; j++) { read_tr4_face3(newsrc, room.triangles[triangle_index]); room.triangles[triangle_index].vertices[0] += vertex_index; room.triangles[triangle_index].vertices[1] += vertex_index; room.triangles[triangle_index].vertices[2] += vertex_index; triangle_index++; } vertex_index += room.layers[i].num_vertices; } } SDL_RWseek(newsrc, 208 + vertices_offset, SEEK_SET); { uint32_t vertex_index = 0; room.num_vertices = vertices_size / 28; //int temp1 = room_data_size - (208 + vertices_offset + vertices_size); room.vertices = (tr5_room_vertex_t*)calloc(room.num_vertices, sizeof(tr5_room_vertex_t)); for (i = 0; i < room.num_layers; i++) { uint32_t j; for (j = 0; j < room.layers[i].num_vertices; j++) read_tr5_room_vertex(newsrc, room.vertices[vertex_index++]); } } SDL_RWseek(newsrc, room_data_size, SEEK_SET); SDL_RWclose(newsrc); newsrc = NULL; delete [] buffer; }
void TR_Level::read_tr5_level(SDL_RWops * const src) { uint32_t i; uint8_t *comp_buffer = NULL; uint8_t *uncomp_buffer = NULL; SDL_RWops *newsrc = NULL; // Version uint32_t file_version = read_bitu32(src); if (file_version != 0x00345254) Sys_extError("Wrong level version"); this->num_textiles = 0; this->num_room_textiles = 0; this->num_obj_textiles = 0; this->num_bump_textiles = 0; this->num_misc_textiles = 0; this->read_32bit_textiles = false; uint32_t uncomp_size; uint32_t comp_size; unsigned long size; this->num_room_textiles = read_bitu16(src); this->num_obj_textiles = read_bitu16(src); this->num_bump_textiles = read_bitu16(src); this->num_misc_textiles = 3; this->num_textiles = this->num_room_textiles + this->num_obj_textiles + this->num_bump_textiles + this->num_misc_textiles; uncomp_size = read_bitu32(src); if (uncomp_size == 0) Sys_extError("read_tr5_level: textiles32 uncomp_size == 0"); comp_size = read_bitu32(src); if (comp_size > 0) { uncomp_buffer = new uint8_t[uncomp_size]; this->textile32.resize( this->num_textiles ); comp_buffer = new uint8_t[comp_size]; if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size) Sys_extError("read_tr5_level: textiles32"); size = uncomp_size; if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK) Sys_extError("read_tr5_level: uncompress"); if (size != uncomp_size) Sys_extError("read_tr5_level: uncompress size mismatch"); delete [] comp_buffer; comp_buffer = NULL; if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL) Sys_extError("read_tr5_level: SDL_RWFromMem"); for (i = 0; i < (this->num_textiles - this->num_misc_textiles); i++) read_tr4_textile32(newsrc, this->textile32[i]); SDL_RWclose(newsrc); newsrc = NULL; delete [] uncomp_buffer; uncomp_buffer = NULL; this->read_32bit_textiles = true; } uncomp_size = read_bitu32(src); if (uncomp_size == 0) Sys_extError("read_tr5_level: textiles16 uncomp_size == 0"); comp_size = read_bitu32(src); if (comp_size > 0) { if (this->textile32.empty()) { uncomp_buffer = new uint8_t[uncomp_size]; this->textile16_count = this->num_textiles; this->textile16 = (tr2_textile16_t*)malloc(this->textile16_count * sizeof(tr2_textile16_t)); comp_buffer = new uint8_t[comp_size]; if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size) Sys_extError("read_tr5_level: textiles16"); size = uncomp_size; if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK) Sys_extError("read_tr5_level: uncompress"); if (size != uncomp_size) Sys_extError("read_tr5_level: uncompress size mismatch"); delete [] comp_buffer; comp_buffer = NULL; if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL) Sys_extError("read_tr5_level: SDL_RWFromMem"); for (i = 0; i < (this->num_textiles - this->num_misc_textiles); i++) read_tr2_textile16(newsrc, this->textile16[i]); SDL_RWclose(newsrc); newsrc = NULL; delete [] uncomp_buffer; uncomp_buffer = NULL; } else { SDL_RWseek(src, comp_size, SEEK_CUR); } } uncomp_size = read_bitu32(src); if (uncomp_size == 0) Sys_extError("read_tr5_level: textiles32d uncomp_size == 0"); comp_size = read_bitu32(src); if (comp_size > 0) { uncomp_buffer = new uint8_t[uncomp_size]; if ((uncomp_size / (256 * 256 * 4)) > 3) Sys_extWarn("read_tr5_level: num_misc_textiles > 3"); if (this->textile32.empty()) { this->textile32.resize( this->num_misc_textiles ); } comp_buffer = new uint8_t[comp_size]; if (SDL_RWread(src, comp_buffer, 1, comp_size) < comp_size) Sys_extError("read_tr5_level: misc_textiles"); size = uncomp_size; if (uncompress(uncomp_buffer, &size, comp_buffer, comp_size) != Z_OK) Sys_extError("read_tr5_level: uncompress"); if (size != uncomp_size) Sys_extError("read_tr5_level: uncompress size mismatch"); delete [] comp_buffer; comp_buffer = NULL; if ((newsrc = SDL_RWFromMem(uncomp_buffer, uncomp_size)) == NULL) Sys_extError("read_tr5_level: SDL_RWFromMem"); for (i = (this->num_textiles - this->num_misc_textiles); i < this->num_textiles; i++) read_tr4_textile32(newsrc, this->textile32[i]); SDL_RWclose(newsrc); newsrc = NULL; delete [] uncomp_buffer; uncomp_buffer = NULL; } // flags? /* I found 2 flags in the TR5 file format. Directly after the sprite textures are 2 ints as a flag. The first one is the lara type: 0 Normal 3 Catsuit 4 Divesuit 6 Invisible The second one is the weather type (effects all outside rooms): 0 No weather 1 Rain 2 Snow (in title.trc these are red triangles falling from the sky). */ i = read_bitu16(src); i = read_bitu16(src); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[1]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[2]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[3]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[4]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[5]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[6]"); if (read_bitu32(src) != 0) Sys_extWarn("Bad value for flags[7]"); // LevelDataSize1 read_bitu32(src); // LevelDataSize2 read_bitu32(src); // Unused if (read_bitu32(src) != 0) Sys_extWarn("Bad value for 'unused'"); this->rooms_count = read_bitu32(src); this->rooms = (tr5_room_t*)calloc(this->rooms_count, sizeof(tr5_room_t)); for (i = 0; i < this->rooms_count; i++) read_tr5_room(src, this->rooms[i]); this->floor_data_size = read_bitu32(src); this->floor_data = (uint16_t*)malloc(this->floor_data_size * sizeof(uint16_t)); for(i = 0; i < this->floor_data_size; i++) this->floor_data[i] = read_bitu16(src); read_mesh_data(src); this->animations_count = read_bitu32(src); this->animations = (tr_animation_t*)malloc(this->animations_count * sizeof(tr_animation_t)); for (i = 0; i < this->animations_count; i++) { read_tr4_animation(src, this->animations[i]); } this->state_changes_count = read_bitu32(src); this->state_changes = (tr_state_change_t*)malloc(this->state_changes_count * sizeof(tr_state_change_t)); for (i = 0; i < this->state_changes_count; i++) read_tr_state_changes(src, this->state_changes[i]); this->anim_dispatches_count = read_bitu32(src); this->anim_dispatches = (tr_anim_dispatch_t*)malloc(this->anim_dispatches_count * sizeof(tr_anim_dispatch_t)); for (i = 0; i < this->anim_dispatches_count; i++) read_tr_anim_dispatches(src, this->anim_dispatches[i]); this->anim_commands_count = read_bitu32(src); this->anim_commands = (int16_t*)malloc(this->anim_commands_count * sizeof(int16_t)); for (i = 0; i < this->anim_commands_count; i++) this->anim_commands[i] = read_bit16(src); this->mesh_tree_data_size = read_bitu32(src); this->mesh_tree_data = (uint32_t*)malloc(this->mesh_tree_data_size * sizeof(uint32_t)); for (i = 0; i < this->mesh_tree_data_size; i++) this->mesh_tree_data[i] = read_bitu32(src); // 4 bytes read_frame_moveable_data(src); this->static_meshes_count = read_bitu32(src); this->static_meshes = (tr_staticmesh_t*)malloc(this->static_meshes_count * sizeof(tr_staticmesh_t)); for (i = 0; i < this->static_meshes_count; i++) read_tr_staticmesh(src, this->static_meshes[i]); if (read_bit8(src) != 'S') Sys_extError("read_tr5_level: 'SPR' not found"); if (read_bit8(src) != 'P') Sys_extError("read_tr5_level: 'SPR' not found"); if (read_bit8(src) != 'R') Sys_extError("read_tr5_level: 'SPR' not found"); if (read_bit8(src) != 0) Sys_extError("read_tr5_level: 'SPR' not found"); this->sprite_textures.resize( read_bitu32(src) ); for (i = 0; i < this->sprite_textures.size(); i++) read_tr4_sprite_texture(src, this->sprite_textures[i]); this->sprite_sequences_count = read_bitu32(src); this->sprite_sequences = (tr_sprite_sequence_t*)malloc(this->sprite_sequences_count * sizeof(tr_sprite_sequence_t)); for (i = 0; i < this->sprite_sequences_count; i++) read_tr_sprite_sequence(src, this->sprite_sequences[i]); this->cameras_count = read_bitu32(src); this->cameras = (tr_camera_t*)malloc(this->cameras_count * sizeof(tr_camera_t)); for (i = 0; i < this->cameras_count; i++) { this->cameras[i].x = read_bit32(src); this->cameras[i].y = read_bit32(src); this->cameras[i].z = read_bit32(src); this->cameras[i].room = read_bit16(src); this->cameras[i].unknown1 = read_bitu16(src); } this->flyby_cameras_count = read_bitu32(src); this->flyby_cameras = (tr4_flyby_camera_t*)malloc(this->flyby_cameras_count * sizeof(tr4_flyby_camera_t)); for (i = 0; i < this->flyby_cameras_count; i++) { this->flyby_cameras[i].cam_x = read_bit32(src); this->flyby_cameras[i].cam_y = read_bit32(src); this->flyby_cameras[i].cam_z = read_bit32(src); this->flyby_cameras[i].target_x = read_bit32(src); this->flyby_cameras[i].target_y = read_bit32(src); this->flyby_cameras[i].target_z = read_bit32(src); this->flyby_cameras[i].sequence = read_bit8(src); this->flyby_cameras[i].index = read_bit8(src); this->flyby_cameras[i].fov = read_bitu16(src); this->flyby_cameras[i].roll = read_bitu16(src); this->flyby_cameras[i].timer = read_bitu16(src); this->flyby_cameras[i].speed = read_bitu16(src); this->flyby_cameras[i].flags = read_bitu16(src); this->flyby_cameras[i].room_id = read_bitu32(src); } this->sound_sources_count = read_bitu32(src); this->sound_sources = (tr_sound_source_t*)malloc(this->sound_sources_count * sizeof(tr_sound_source_t)); for(i = 0; i < this->sound_sources_count; i++) { this->sound_sources[i].x = read_bit32(src); this->sound_sources[i].y = read_bit32(src); this->sound_sources[i].z = read_bit32(src); this->sound_sources[i].sound_id = read_bitu16(src); this->sound_sources[i].flags = read_bitu16(src); } this->boxes_count = read_bitu32(src); this->boxes = (tr_box_t*)malloc(this->boxes_count * sizeof(tr_box_t)); for (i = 0; i < this->boxes_count; i++) read_tr2_box(src, this->boxes[i]); this->overlaps_count = read_bitu32(src); this->overlaps = (uint16_t*)malloc(this->overlaps_count * sizeof(uint16_t)); for (i = 0; i < this->overlaps_count; i++) this->overlaps[i] = read_bitu16(src); // Zones SDL_RWseek(src, this->boxes_count * 20, SEEK_CUR); this->animated_textures_count = read_bitu32(src); this->animated_textures = (uint16_t*)malloc(this->animated_textures_count * sizeof(uint16_t)); for (i = 0; i < this->animated_textures_count; i++) { this->animated_textures[i] = read_bitu16(src); } this->animated_textures_uv_count = read_bitu8(src); if (read_bit8(src) != 'T') Sys_extError("read_tr5_level: '\\0TEX' not found"); if (read_bit8(src) != 'E') Sys_extError("read_tr5_level: '\\0TEX' not found"); if (read_bit8(src) != 'X') Sys_extError("read_tr5_level: '\\0TEX' not found"); if (read_bit8(src) != 0) Sys_extError("read_tr5_level: '\\0TEX' not found"); this->object_textures.resize( read_bitu32(src) ); for (i = 0; i < this->object_textures.size(); i++) { read_tr4_object_texture(src, this->object_textures[i]); if (read_bitu16(src) != 0) Sys_extWarn("read_tr5_level: obj_tex trailing bitu16 != 0"); } this->items_count = read_bitu32(src); this->items = (tr2_item_t*)malloc(this->items_count * sizeof(tr2_item_t)); for (i = 0; i < this->items_count; i++) read_tr4_item(src, this->items[i]); this->ai_objects_count = read_bitu32(src); this->ai_objects = (tr4_ai_object_t*)malloc(this->ai_objects_count * sizeof(tr4_ai_object_t)); for(i=0; i < this->ai_objects_count; i++) { this->ai_objects[i].object_id = read_bitu16(src); this->ai_objects[i].room = read_bitu16(src); this->ai_objects[i].x = read_bit32(src); this->ai_objects[i].y = read_bit32(src); this->ai_objects[i].z = read_bit32(src); // 16 this->ai_objects[i].ocb = read_bitu16(src); this->ai_objects[i].flags = read_bitu16(src); // 20 this->ai_objects[i].angle = read_bit32(src); // 24 } this->demo_data_count = read_bitu16(src); this->demo_data = (uint8_t*)malloc(this->demo_data_count * sizeof(uint8_t)); for(i=0; i < this->demo_data_count; i++) this->demo_data[i] = read_bitu8(src); // Soundmap this->soundmap = (int16_t*)malloc(TR_AUDIO_MAP_SIZE_TR5 * sizeof(int16_t)); for(i=0; i < TR_AUDIO_MAP_SIZE_TR5; i++) this->soundmap[i] = read_bit16(src); this->sound_details_count = read_bitu32(src); this->sound_details = (tr_sound_details_t*)malloc(this->sound_details_count * sizeof(tr_sound_details_t)); for(i=0; i < this->sound_details_count; i++) { this->sound_details[i].sample = read_bitu16(src); this->sound_details[i].volume = (uint16_t)read_bitu8(src); // n x 2.6 this->sound_details[i].sound_range = (uint16_t)read_bitu8(src); // n as is this->sound_details[i].chance = (uint16_t)read_bitu8(src); // If n = 99, n = 0 (max. chance) this->sound_details[i].pitch = (int16_t)read_bit8(src); // n as is this->sound_details[i].num_samples_and_flags_1 = read_bitu8(src); this->sound_details[i].flags_2 = read_bitu8(src); } this->sample_indices_count = read_bitu32(src); this->sample_indices = (uint32_t*)malloc(this->sample_indices_count * sizeof(uint32_t)); for(i=0; i < this->sample_indices_count; i++) this->sample_indices[i] = read_bitu32(src); SDL_RWseek(src, 6, SEEK_CUR); // In TR5, sample indices are followed by 6 0xCD bytes. - correct - really 0xCDCDCDCDCDCD // LOAD SAMPLES i = read_bitu32(src); // Read num samples if(i) { this->samples_count = i; // Since sample data is the last part, we simply load whole last // block of file as single array. this->samples_data.resize( SDL_RWsize(src) - SDL_RWtell(src) ); for(i = 0; i < this->samples_data.size(); i++) this->samples_data[i] = read_bitu8(src); } }
SDL_Surface * SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) { SDL_bool was_error; Sint64 fp_offset = 0; int bmpPitch; int i, pad; SDL_Surface *surface; Uint32 Rmask = 0; Uint32 Gmask = 0; Uint32 Bmask = 0; Uint32 Amask = 0; SDL_Palette *palette; Uint8 *bits; Uint8 *top, *end; SDL_bool topDown; int ExpandBMP; SDL_bool haveRGBMasks = SDL_FALSE; SDL_bool haveAlphaMask = SDL_FALSE; SDL_bool correctAlpha = SDL_FALSE; /* The Win32 BMP file header (14 bytes) */ char magic[2]; /* Uint32 bfSize = 0; */ /* Uint16 bfReserved1 = 0; */ /* Uint16 bfReserved2 = 0; */ Uint32 bfOffBits = 0; /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ Uint32 biSize = 0; Sint32 biWidth = 0; Sint32 biHeight = 0; /* Uint16 biPlanes = 0; */ Uint16 biBitCount = 0; Uint32 biCompression = 0; /* Uint32 biSizeImage = 0; */ /* Sint32 biXPelsPerMeter = 0; */ /* Sint32 biYPelsPerMeter = 0; */ Uint32 biClrUsed = 0; /* Uint32 biClrImportant = 0; */ /* Make sure we are passed a valid data source */ surface = NULL; was_error = SDL_FALSE; if (src == NULL) { was_error = SDL_TRUE; goto done; } /* Read in the BMP file header */ fp_offset = SDL_RWtell(src); SDL_ClearError(); if (SDL_RWread(src, magic, 1, 2) != 2) { SDL_Error(SDL_EFREAD); was_error = SDL_TRUE; goto done; } if (SDL_strncmp(magic, "BM", 2) != 0) { SDL_SetError("File is not a Windows BMP file"); was_error = SDL_TRUE; goto done; } /* bfSize = */ SDL_ReadLE32(src); /* bfReserved1 = */ SDL_ReadLE16(src); /* bfReserved2 = */ SDL_ReadLE16(src); bfOffBits = SDL_ReadLE32(src); /* Read the Win32 BITMAPINFOHEADER */ biSize = SDL_ReadLE32(src); if (biSize == 12) { /* really old BITMAPCOREHEADER */ biWidth = (Uint32) SDL_ReadLE16(src); biHeight = (Uint32) SDL_ReadLE16(src); /* biPlanes = */ SDL_ReadLE16(src); biBitCount = SDL_ReadLE16(src); biCompression = BI_RGB; } else if (biSize >= 40) { /* some version of BITMAPINFOHEADER */ Uint32 headerSize; biWidth = SDL_ReadLE32(src); biHeight = SDL_ReadLE32(src); /* biPlanes = */ SDL_ReadLE16(src); biBitCount = SDL_ReadLE16(src); biCompression = SDL_ReadLE32(src); /* biSizeImage = */ SDL_ReadLE32(src); /* biXPelsPerMeter = */ SDL_ReadLE32(src); /* biYPelsPerMeter = */ SDL_ReadLE32(src); biClrUsed = SDL_ReadLE32(src); /* biClrImportant = */ SDL_ReadLE32(src); /* 64 == BITMAPCOREHEADER2, an incompatible OS/2 2.x extension. Skip this stuff for now. */ if (biSize == 64) { /* ignore these extra fields. */ if (biCompression == BI_BITFIELDS) { /* this value is actually huffman compression in this variant. */ SDL_SetError("Compressed BMP files not supported"); was_error = SDL_TRUE; goto done; } } else { /* This is complicated. If compression is BI_BITFIELDS, then we have 3 DWORDS that specify the RGB masks. This is either stored here in an BITMAPV2INFOHEADER (which only differs in that it adds these RGB masks) and biSize >= 52, or we've got these masks stored in the exact same place, but strictly speaking, this is the bmiColors field in BITMAPINFO immediately following the legacy v1 info header, just past biSize. */ if (biCompression == BI_BITFIELDS) { haveRGBMasks = SDL_TRUE; Rmask = SDL_ReadLE32(src); Gmask = SDL_ReadLE32(src); Bmask = SDL_ReadLE32(src); /* ...v3 adds an alpha mask. */ if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */ haveAlphaMask = SDL_TRUE; Amask = SDL_ReadLE32(src); } } else { /* the mask fields are ignored for v2+ headers if not BI_BITFIELD. */ if (biSize >= 52) { /* BITMAPV2INFOHEADER; adds RGB masks */ /*Rmask = */ SDL_ReadLE32(src); /*Gmask = */ SDL_ReadLE32(src); /*Bmask = */ SDL_ReadLE32(src); } if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */ /*Amask = */ SDL_ReadLE32(src); } } /* Insert other fields here; Wikipedia and MSDN say we're up to v5 of this header, but we ignore those for now (they add gamma, color spaces, etc). Ignoring the weird OS/2 2.x format, we currently parse up to v3 correctly (hopefully!). */ } /* skip any header bytes we didn't handle... */ headerSize = (Uint32) (SDL_RWtell(src) - (fp_offset + 14)); if (biSize > headerSize) { SDL_RWseek(src, (biSize - headerSize), RW_SEEK_CUR); } } if (biHeight < 0) { topDown = SDL_TRUE; biHeight = -biHeight; } else { topDown = SDL_FALSE; } /* Check for read error */ if (SDL_strcmp(SDL_GetError(), "") != 0) { was_error = SDL_TRUE; goto done; } /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */ switch (biBitCount) { case 1: case 4: ExpandBMP = biBitCount; biBitCount = 8; break; default: ExpandBMP = 0; break; } /* We don't support any BMP compression right now */ switch (biCompression) { case BI_RGB: /* If there are no masks, use the defaults */ SDL_assert(!haveRGBMasks); SDL_assert(!haveAlphaMask); /* Default values for the BMP format */ switch (biBitCount) { case 15: case 16: Rmask = 0x7C00; Gmask = 0x03E0; Bmask = 0x001F; break; case 24: #if SDL_BYTEORDER == SDL_BIG_ENDIAN Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; #else Rmask = 0x00FF0000; Gmask = 0x0000FF00; Bmask = 0x000000FF; #endif break; case 32: /* We don't know if this has alpha channel or not */ correctAlpha = SDL_TRUE; Amask = 0xFF000000; Rmask = 0x00FF0000; Gmask = 0x0000FF00; Bmask = 0x000000FF; break; default: break; } break; case BI_BITFIELDS: break; /* we handled this in the info header. */ default: SDL_SetError("Compressed BMP files not supported"); was_error = SDL_TRUE; goto done; } /* Create a compatible surface, note that the colors are RGB ordered */ surface = SDL_CreateRGBSurface(0, biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, Amask); if (surface == NULL) { was_error = SDL_TRUE; goto done; } /* Load the palette, if any */ palette = (surface->format)->palette; if (palette) { SDL_assert(biBitCount <= 8); if (biClrUsed == 0) { biClrUsed = 1 << biBitCount; } if ((int) biClrUsed > palette->ncolors) { SDL_Color *colors; int ncolors = biClrUsed; colors = (SDL_Color *) SDL_realloc(palette->colors, ncolors * sizeof(*palette->colors)); if (!colors) { SDL_OutOfMemory(); was_error = SDL_TRUE; goto done; } palette->ncolors = ncolors; palette->colors = colors; } else if ((int) biClrUsed < palette->ncolors) { palette->ncolors = biClrUsed; } if (biSize == 12) { for (i = 0; i < (int) biClrUsed; ++i) { SDL_RWread(src, &palette->colors[i].b, 1, 1); SDL_RWread(src, &palette->colors[i].g, 1, 1); SDL_RWread(src, &palette->colors[i].r, 1, 1); palette->colors[i].a = SDL_ALPHA_OPAQUE; } } else { for (i = 0; i < (int) biClrUsed; ++i) { SDL_RWread(src, &palette->colors[i].b, 1, 1); SDL_RWread(src, &palette->colors[i].g, 1, 1); SDL_RWread(src, &palette->colors[i].r, 1, 1); SDL_RWread(src, &palette->colors[i].a, 1, 1); /* According to Microsoft documentation, the fourth element is reserved and must be zero, so we shouldn't treat it as alpha. */ palette->colors[i].a = SDL_ALPHA_OPAQUE; } } } /* Read the surface pixels. Note that the bmp image is upside down */ if (SDL_RWseek(src, fp_offset + bfOffBits, RW_SEEK_SET) < 0) { SDL_Error(SDL_EFSEEK); was_error = SDL_TRUE; goto done; } top = (Uint8 *)surface->pixels; end = (Uint8 *)surface->pixels+(surface->h*surface->pitch); switch (ExpandBMP) { case 1: bmpPitch = (biWidth + 7) >> 3; pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0); break; case 4: bmpPitch = (biWidth + 1) >> 1; pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0); break; default: pad = ((surface->pitch % 4) ? (4 - (surface->pitch % 4)) : 0); break; } if (topDown) { bits = top; } else { bits = end - surface->pitch; } while (bits >= top && bits < end) { switch (ExpandBMP) { case 1: case 4: { Uint8 pixel = 0; int shift = (8 - ExpandBMP); for (i = 0; i < surface->w; ++i) { if (i % (8 / ExpandBMP) == 0) { if (!SDL_RWread(src, &pixel, 1, 1)) { SDL_SetError("Error reading from BMP"); was_error = SDL_TRUE; goto done; } } *(bits + i) = (pixel >> shift); pixel <<= ExpandBMP; } } break; default: if (SDL_RWread(src, bits, 1, surface->pitch) != surface->pitch) { SDL_Error(SDL_EFREAD); was_error = SDL_TRUE; goto done; } #if SDL_BYTEORDER == SDL_BIG_ENDIAN /* Byte-swap the pixels if needed. Note that the 24bpp case has already been taken care of above. */ switch (biBitCount) { case 15: case 16: { Uint16 *pix = (Uint16 *) bits; for (i = 0; i < surface->w; i++) pix[i] = SDL_Swap16(pix[i]); break; } case 32: { Uint32 *pix = (Uint32 *) bits; for (i = 0; i < surface->w; i++) pix[i] = SDL_Swap32(pix[i]); break; } } #endif break; } /* Skip padding bytes, ugh */ if (pad) { Uint8 padbyte; for (i = 0; i < pad; ++i) { SDL_RWread(src, &padbyte, 1, 1); } } if (topDown) { bits += surface->pitch; } else { bits -= surface->pitch; } } if (correctAlpha) { CorrectAlphaChannel(surface); } done: if (was_error) { if (src) { SDL_RWseek(src, fp_offset, RW_SEEK_SET); } SDL_FreeSurface(surface); surface = NULL; } if (freesrc && src) { SDL_RWclose(src); } return (surface); }
/* Initialize the music players with a certain desired audio format */ int open_music(SDL_AudioSpec *mixer) { int music_error; music_error = 0; #ifdef WAV_MUSIC if ( WAVStream_Init(mixer) < 0 ) { ++music_error; } #endif #ifdef MOD_MUSIC /* Set the MikMod music format */ music_swap8 = 0; music_swap16 = 0; switch (mixer->format) { case AUDIO_U8: case AUDIO_S8: { if ( mixer->format == AUDIO_S8 ) { music_swap8 = 1; } md_mode = 0; } break; case AUDIO_S16LSB: case AUDIO_S16MSB: { /* See if we need to correct MikMod mixing */ #if SDL_BYTEORDER == SDL_LIL_ENDIAN if ( mixer->format == AUDIO_S16MSB ) { #else if ( mixer->format == AUDIO_S16LSB ) { #endif music_swap16 = 1; } md_mode = DMODE_16BITS; } break; default: { Mix_SetError("Unknown hardware audio format"); ++music_error; } } if ( mixer->channels > 1 ) { if ( mixer->channels > 2 ) { Mix_SetError("Hardware uses more channels than mixer"); ++music_error; } md_mode |= DMODE_STEREO; } md_mixfreq = mixer->freq; md_device = 0; md_volume = 96; md_musicvolume = 128; md_sndfxvolume = 128; md_pansep = 128; md_reverb = 0; MikMod_RegisterAllLoaders(); MikMod_RegisterAllDrivers(); if ( MikMod_Init() ) { Mix_SetError("%s", MikMod_strerror(MikMod_errno)); ++music_error; } #endif #ifdef MID_MUSIC #ifdef USE_TIMIDITY_MIDI samplesize = mixer->size / mixer->samples; if ( Timidity_Init(mixer->freq, mixer->format, mixer->channels, mixer->samples) == 0 ) { timidity_ok = 1; } else { timidity_ok = 0; } #endif #ifdef USE_NATIVE_MIDI #ifdef USE_TIMIDITY_MIDI native_midi_ok = !timidity_ok; if ( native_midi_ok ) #endif native_midi_ok = native_midi_detect(); #endif #endif #ifdef OGG_MUSIC if ( OGG_init(mixer) < 0 ) { ++music_error; } #endif #ifdef MP3_MUSIC /* Keep a copy of the mixer */ used_mixer = *mixer; #endif music_playing = NULL; music_stopped = 0; if ( music_error ) { return(-1); } Mix_VolumeMusic(SDL_MIX_MAXVOLUME); /* Calculate the number of ms for each callback */ ms_per_step = (int) (((float)mixer->samples * 1000.0) / mixer->freq); return(0); } /* Portable case-insensitive string compare function */ int MIX_string_equals(const char *str1, const char *str2) { while ( *str1 && *str2 ) { if ( toupper((unsigned char)*str1) != toupper((unsigned char)*str2) ) break; ++str1; ++str2; } return (!*str1 && !*str2); } /* Load a music file */ Mix_Music *Mix_LoadMUS(const char *file) { char *ext; Uint8 magic[5]; Mix_Music *music; SDL_RWops *src; //maks /* Figure out what kind of file this is */ /*fp = fopen(file, "rb"); //maks if ( (fp == NULL) || !fread(magic, 4, 1, fp) ) { if ( fp != NULL ) { fclose(fp); } Mix_SetError("Couldn't read from '%s'", file); return(NULL); } magic[4] = '\0'; fclose(fp);*/ src = SDL_RWFromFile(file, "rb"); //maks if ( (src == NULL) || !SDL_RWread(src, magic, 4, 1) ) { if ( src != NULL ) { SDL_RWclose(src); } Mix_SetError("Couldn't read from '%s'", file); return(NULL); } magic[4] = '\0'; SDL_RWclose(src); /* Figure out the file extension, so we can determine the type */ ext = strrchr(file, '.'); if ( ext ) ++ext; /* skip the dot in the extension */ /* Allocate memory for the music structure */ music = (Mix_Music *)malloc(sizeof(Mix_Music)); if ( music == NULL ) { Mix_SetError("Out of memory"); return(NULL); } music->error = 0; #ifdef CMD_MUSIC if ( music_cmd ) { music->type = MUS_CMD; music->data.cmd = MusicCMD_LoadSong(music_cmd, file); if ( music->data.cmd == NULL ) { music->error = 1; } } else #endif #ifdef WAV_MUSIC /* WAVE files have the magic four bytes "RIFF" AIFF files have the magic 12 bytes "FORM" XXXX "AIFF" */ if ( (ext && MIX_string_equals(ext, "WAV")) || (strcmp((char *)magic, "RIFF") == 0) || (strcmp((char *)magic, "FORM") == 0) ) { music->type = MUS_WAV; music->data.wave = WAVStream_LoadSong(file, (char *)magic); if ( music->data.wave == NULL ) { Mix_SetError("Unable to load WAV file"); music->error = 1; } } else #endif #ifndef _WIN32_WCE #ifdef MID_MUSIC /* MIDI files have the magic four bytes "MThd" */ if ( (ext && MIX_string_equals(ext, "MID")) || (ext && MIX_string_equals(ext, "MIDI")) || strcmp((char *)magic, "MThd") == 0 ) { music->type = MUS_MID; #ifdef USE_NATIVE_MIDI if ( native_midi_ok ) { music->data.nativemidi = native_midi_loadsong((char *)file); if ( music->data.nativemidi == NULL ) { Mix_SetError("%s", native_midi_error()); music->error = 1; } } MIDI_ELSE #endif #ifdef USE_TIMIDITY_MIDI if ( timidity_ok ) { music->data.midi = Timidity_LoadSong((char *)file); if ( music->data.midi == NULL ) { Mix_SetError("%s", Timidity_Error()); music->error = 1; } } else { Mix_SetError("%s", Timidity_Error()); music->error = 1; } #endif } else
// opens the file, returns NULL if it fails. void* cfg_OpenFile( const char* fileName ) { if( SDL_strlen( fileName ) >= ( FILE_PATH_LEN - 1 ) ) { llog( LOG_ERROR, "Configuration file path too long" ); return NULL; } CFGFile* newFile = (CFGFile*)mem_Allocate( sizeof( CFGFile ) ); if( newFile == NULL ) { llog( LOG_INFO, "Unable to open configuration file." ); return NULL; } newFile->sbAttributes = NULL; SDL_strlcpy( newFile->filePath, fileName, FILE_PATH_LEN - 1 ); newFile->filePath[FILE_PATH_LEN-1] = 0; SDL_RWops* rwopsFile = SDL_RWFromFile( fileName, "r" ); if( rwopsFile == NULL ) { // file doesn't exist, just create a new empty configuration file to use return newFile; } // TODO: change this so everything is happening in place and there are no allocations // parse what this configuration file currently has in it char buffer[READ_BUFFER_SIZE]; size_t numRead; char* fileText = NULL; llog( LOG_INFO, "Stream size: %i", (int)SDL_RWsize( rwopsFile ) ); while( ( numRead = SDL_RWread( rwopsFile, (void*)buffer, sizeof( char ), sizeof( buffer ) ) ) != 0 ) { char* c = sb_Add( fileText, (int)numRead ); for( size_t i = 0; i < numRead; ++i ) { *c++ = buffer[i]; } } sb_Push( fileText, 0 ); // make this c-string compatible // got the entire file text, now tokenize and parse // only tokens we're worried about are '=' and '/r/n' // everything before the '=' is the attribute name, everything // after is the attribute value, all white space should be cut // off of each end int gettingAttrName = 1; const char* delimiters = "\f\v\t =\r\n"; char* token = strtok( fileText, delimiters ); CFGAttribute attr; while( token != NULL ) { // cut off white space, don't care about preserving memory if( gettingAttrName ) { SDL_strlcpy( attr.fileName, token, sizeof( attr.fileName ) - 1 ); attr.fileName[sizeof( attr.fileName ) - 1] = 0; gettingAttrName = 0; } else { attr.value = SDL_atoi( token ); sb_Push( newFile->sbAttributes, attr ); llog( LOG_INFO, "New attribute: %s %i", attr.fileName, attr.value ); gettingAttrName = 1; } token = strtok( NULL, delimiters ); } sb_Release( fileText ); SDL_RWclose( rwopsFile ); return newFile; }
int main(int argc, char **argv) { Uint8* RawMooseData; SDL_RWops* handle; SDL_Surface* screen; SDL_Surface* MooseFrame[MOOSEFRAMES_COUNT]; SDL_Overlay* overlay; SDL_Rect overlayrect; SDL_Event event; Uint32 lastftick; int paused=0; int resized=0; int i; int fps=12; int fpsdelay; int overlay_format=SDL_YUY2_OVERLAY; int scale=5; while ( argc > 1 ) { if (strcmp(argv[1], "-fps")== 0) { if (argv[2]) { fps = atoi(argv[2]); if (fps==0) { fprintf(stderr, "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); return -1; } if ((fps<0) || (fps>1000)) { fprintf(stderr, "The -fps option must be in range from 1 to 1000, default is 12.\n"); return -1; } argv += 2; argc -= 2; } else { fprintf(stderr, "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); return -1; } } else if (strcmp(argv[1], "-format") == 0) { if (argv[2]) { if (!strcmp(argv[2],"YV12")) overlay_format = SDL_YV12_OVERLAY; else if(!strcmp(argv[2],"IYUV")) overlay_format = SDL_IYUV_OVERLAY; else if(!strcmp(argv[2],"YUY2")) overlay_format = SDL_YUY2_OVERLAY; else if(!strcmp(argv[2],"UYVY")) overlay_format = SDL_UYVY_OVERLAY; else if(!strcmp(argv[2],"YVYU")) overlay_format = SDL_YVYU_OVERLAY; else { fprintf(stderr, "The -format option %s is not recognized, see help for info.\n", argv[2]); return -1; } argv += 2; argc -= 2; } else { fprintf(stderr, "The -format option requires an argument, default is YUY2.\n"); return -1; } } else if (strcmp(argv[1], "-scale") == 0) { if (argv[2]) { scale = atoi(argv[2]); if (scale==0) { fprintf(stderr, "The -scale option requires an argument [from 1 to 50], default is 5.\n"); return -1; } if ((scale<0) || (scale>50)) { fprintf(stderr, "The -scale option must be in range from 1 to 50, default is 5.\n"); return -1; } argv += 2; argc -= 2; } else { fprintf(stderr, "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); return -1; } } else if ((strcmp(argv[1], "-help") == 0 ) || (strcmp(argv[1], "-h") == 0)) { PrintUsage(argv[0]); return 0; } else { fprintf(stderr, "Unrecognized option: %s.\n", argv[1]); return -1; } break; } RawMooseData=(Uint8*)malloc(MOOSEFRAME_SIZE * MOOSEFRAMES_COUNT); if (RawMooseData==NULL) { fprintf(stderr, "Can't allocate memory for movie !\n"); free(RawMooseData); return 1; } /* load the trojan moose images */ handle=SDL_RWFromFile("moose.dat", "rb"); if (handle==NULL) { fprintf(stderr, "Can't find the file moose.dat !\n"); free(RawMooseData); return 2; } SDL_RWread(handle, RawMooseData, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT); SDL_RWclose(handle); if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); free(RawMooseData); return 3; } atexit(SDL_Quit); /* Set video mode */ if ( (screen=SDL_SetVideoMode(MOOSEPIC_W*scale, MOOSEPIC_H*scale, 0, SDL_RESIZABLE | SDL_SWSURFACE)) == NULL ) { fprintf(stderr, "Couldn't set video mode: %s\n", 0, SDL_GetError()); free(RawMooseData); return 4; } /* Set the window manager title bar */ SDL_WM_SetCaption("SDL test overlay: running moose", "testoverlay2"); for (i=0; i<MOOSEFRAMES_COUNT; i++) { MooseFrame[i]=SDL_CreateRGBSurfaceFrom(RawMooseData+i*MOOSEFRAME_SIZE, MOOSEPIC_W, MOOSEPIC_H, 8, MOOSEPIC_W, 0, 0, 0, 0); if (MooseFrame[i]==NULL) { fprintf(stderr, "Couldn't create SDL_Surfaces:%s\n", 0, SDL_GetError()); free(RawMooseData); return 5; } SDL_SetColors(MooseFrame[i], MooseColors, 0, 84); { SDL_Surface *newsurf; SDL_PixelFormat format; format.palette=NULL; format.BitsPerPixel=32; format.BytesPerPixel=4; #if SDL_BYTEORDER == SDL_LIL_ENDIAN format.Rshift=0; format.Gshift=8; format.Bshift=16; #else format.Rshift=24; format.Gshift=16; format.Bshift=8; #endif format.Ashift=0; format.Rmask=0xff<<format.Rshift; format.Gmask=0xff<<format.Gshift; format.Bmask=0xff<<format.Bshift; format.Amask=0; format.Rloss=0; format.Gloss=0; format.Bloss=0; format.Aloss=8; format.colorkey=0; format.alpha=0; newsurf=SDL_ConvertSurface(MooseFrame[i], &format, SDL_SWSURFACE); if(!newsurf) { fprintf(stderr, "Couldn't convert picture to 32bits RGB: %s\n", SDL_GetError()); return 6; } SDL_FreeSurface(MooseFrame[i]); MooseFrame[i]=newsurf; } } free(RawMooseData); overlay=SDL_CreateYUVOverlay(MOOSEPIC_W, MOOSEPIC_H, overlay_format, screen); if (!overlay) { fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError()); return 7; } printf("Created %dx%dx%d %s %s overlay\n",overlay->w,overlay->h,overlay->planes, overlay->hw_overlay?"hardware":"software", overlay->format==SDL_YV12_OVERLAY?"YV12": overlay->format==SDL_IYUV_OVERLAY?"IYUV": overlay->format==SDL_YUY2_OVERLAY?"YUY2": overlay->format==SDL_UYVY_OVERLAY?"UYVY": overlay->format==SDL_YVYU_OVERLAY?"YVYU": "Unknown"); for(i=0; i<overlay->planes; i++) { printf(" plane %d: pitch=%d\n", i, overlay->pitches[i]); } overlayrect.x=0; overlayrect.y=0; overlayrect.w=MOOSEPIC_W*scale; overlayrect.h=MOOSEPIC_H*scale; /* set the start frame */ i=0; fpsdelay=1000/fps; /* Ignore key up events, they don't even get filtered */ SDL_EventState(SDL_KEYUP, SDL_IGNORE); lastftick=SDL_GetTicks(); /* Loop, waiting for QUIT or RESIZE */ while (1) { if (SDL_PollEvent(&event)) { switch (event.type) { case SDL_VIDEORESIZE: screen=SDL_SetVideoMode(event.resize.w, event.resize.h, 0, SDL_RESIZABLE | SDL_SWSURFACE); overlayrect.w=event.resize.w; overlayrect.h=event.resize.h; if (paused) { resized=1; } break; case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_SPACE) { paused=!paused; break; } if (event.key.keysym.sym != SDLK_ESCAPE) { break; } case SDL_QUIT: SDL_FreeYUVOverlay(overlay); for (i=0; i<MOOSEFRAMES_COUNT; i++) { SDL_FreeSurface(MooseFrame[i]); } return 0; } } if ((!paused)||(resized)) { if (((SDL_GetTicks()-lastftick)>fpsdelay)||(resized)) { lastftick=SDL_GetTicks(); switch (overlay_format) { case SDL_YUY2_OVERLAY: ConvertRGBtoYUY2(MooseFrame[i], overlay, 0, 100); break; case SDL_YV12_OVERLAY: ConvertRGBtoYV12(MooseFrame[i], overlay, 0, 100); break; case SDL_UYVY_OVERLAY: ConvertRGBtoUYVY(MooseFrame[i], overlay, 0, 100); break; case SDL_YVYU_OVERLAY: ConvertRGBtoYVYU(MooseFrame[i], overlay, 0, 100); break; case SDL_IYUV_OVERLAY: ConvertRGBtoIYUV(MooseFrame[i], overlay, 0, 100); break; } SDL_DisplayYUVOverlay(overlay, &overlayrect); if (!resized) { i++; if (i==10) { i=0; } } else { resized=0; } } } /* kind of timeslice to OS */ SDL_Delay(1); } return 0; }
/* Reads the next frame from the file. Returns true on success or false on failure. */ static int read_next_frame(mad_data *mp3_mad) { if (mp3_mad->stream.buffer == NULL || mp3_mad->stream.error == MAD_ERROR_BUFLEN) { size_t read_size; size_t remaining; unsigned char *read_start; /* There might be some bytes in the buffer left over from last time. If so, move them down and read more bytes following them. */ if (mp3_mad->stream.next_frame != NULL) { remaining = mp3_mad->stream.bufend - mp3_mad->stream.next_frame; memmove(mp3_mad->input_buffer, mp3_mad->stream.next_frame, remaining); read_start = mp3_mad->input_buffer + remaining; read_size = MAD_INPUT_BUFFER_SIZE - remaining; } else { read_size = MAD_INPUT_BUFFER_SIZE; read_start = mp3_mad->input_buffer; remaining = 0; } /* Now read additional bytes from the input file. */ read_size = SDL_RWread(mp3_mad->rw, read_start, 1, read_size); if (read_size <= 0) { if ((mp3_mad->status & (MS_input_eof | MS_input_error)) == 0) { if (read_size == 0) { mp3_mad->status |= MS_input_eof; } else { mp3_mad->status |= MS_input_error; } /* At the end of the file, we must stuff MAD_BUFFER_GUARD number of 0 bytes. */ memset(read_start + read_size, 0, MAD_BUFFER_GUARD); read_size += MAD_BUFFER_GUARD; } } /* Now feed those bytes into the libmad stream. */ mad_stream_buffer(&mp3_mad->stream, mp3_mad->input_buffer, read_size + remaining); mp3_mad->stream.error = MAD_ERROR_NONE; } /* Now ask libmad to extract a frame from the data we just put in its buffer. */ if (mad_frame_decode(&mp3_mad->frame, &mp3_mad->stream)) { if (MAD_RECOVERABLE(mp3_mad->stream.error)) { return 0; } else if (mp3_mad->stream.error == MAD_ERROR_BUFLEN) { return 0; } else { mp3_mad->status |= MS_decode_error; return 0; } } mp3_mad->frames_read++; mad_timer_add(&mp3_mad->next_frame_start, mp3_mad->frame.header.duration); return 1; }
/* * Add or update an entry into the Mappings Database */ int SDL_GameControllerAddMappingsFromRW(SDL_RWops * rw, int freerw) { const char *platform = SDL_GetPlatform(); int controllers = 0; char *buf, *line, *line_end, *tmp, *comma, line_platform[64]; size_t db_size, platform_len; if (rw == NULL) { return SDL_SetError("Invalid RWops"); } db_size = (size_t)SDL_RWsize(rw); buf = (char *)SDL_malloc(db_size + 1); if (buf == NULL) { if (freerw) { SDL_RWclose(rw); } return SDL_SetError("Could not allocate space to read DB into memory"); } if (SDL_RWread(rw, buf, db_size, 1) != 1) { if (freerw) { SDL_RWclose(rw); } SDL_free(buf); return SDL_SetError("Could not read DB"); } if (freerw) { SDL_RWclose(rw); } buf[db_size] = '\0'; line = buf; while (line < buf + db_size) { line_end = SDL_strchr(line, '\n'); if (line_end != NULL) { *line_end = '\0'; } else { line_end = buf + db_size; } /* Extract and verify the platform */ tmp = SDL_strstr(line, SDL_CONTROLLER_PLATFORM_FIELD); if (tmp != NULL) { tmp += SDL_strlen(SDL_CONTROLLER_PLATFORM_FIELD); comma = SDL_strchr(tmp, ','); if (comma != NULL) { platform_len = comma - tmp + 1; if (platform_len + 1 < SDL_arraysize(line_platform)) { SDL_strlcpy(line_platform, tmp, platform_len); if (SDL_strncasecmp(line_platform, platform, platform_len) == 0 && SDL_GameControllerAddMapping(line) > 0) { controllers++; } } } } line = line_end + 1; } SDL_free(buf); return controllers; }
/* * Vorbis stuff. */ static size_t ovpack_read( void *ptr, size_t size, size_t nmemb, void *datasource ) { SDL_RWops *rw = datasource; return (size_t) SDL_RWread( rw, ptr, size, nmemb ); }
/* Load a PCX type image from an SDL datasource */ SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) { Sint64 start; struct PCXheader pcxh; Uint32 Rmask; Uint32 Gmask; Uint32 Bmask; Uint32 Amask; SDL_Surface *surface = NULL; int width, height; int y, bpl; Uint8 *row, *buf = NULL; char *error = NULL; int bits, src_bits; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } start = SDL_RWtell(src); if ( ! SDL_RWread(src, &pcxh, sizeof(pcxh), 1) ) { error = "file truncated"; goto done; } pcxh.Xmin = SDL_SwapLE16(pcxh.Xmin); pcxh.Ymin = SDL_SwapLE16(pcxh.Ymin); pcxh.Xmax = SDL_SwapLE16(pcxh.Xmax); pcxh.Ymax = SDL_SwapLE16(pcxh.Ymax); pcxh.BytesPerLine = SDL_SwapLE16(pcxh.BytesPerLine); /* Create the surface of the appropriate type */ width = (pcxh.Xmax - pcxh.Xmin) + 1; height = (pcxh.Ymax - pcxh.Ymin) + 1; Rmask = Gmask = Bmask = Amask = 0; src_bits = pcxh.BitsPerPixel * pcxh.NPlanes; if((pcxh.BitsPerPixel == 1 && pcxh.NPlanes >= 1 && pcxh.NPlanes <= 4) || (pcxh.BitsPerPixel == 8 && pcxh.NPlanes == 1)) { bits = 8; } else if(pcxh.BitsPerPixel == 8 && pcxh.NPlanes == 3) { bits = 24; #if SDL_BYTEORDER == SDL_LIL_ENDIAN Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; #else Rmask = 0xFF0000; Gmask = 0x00FF00; Bmask = 0x0000FF; #endif } else { error = "unsupported PCX format"; goto done; } surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, bits, Rmask, Gmask, Bmask, Amask); if ( surface == NULL ) goto done; bpl = pcxh.NPlanes * pcxh.BytesPerLine; if (bpl > surface->pitch) { error = "bytes per line is too large (corrupt?)"; } buf = (Uint8 *)SDL_malloc(bpl); row = (Uint8 *)surface->pixels; for ( y=0; y<surface->h; ++y ) { /* decode a scan line to a temporary buffer first */ int i, count = 0; Uint8 ch; Uint8 *dst = (src_bits == 8) ? row : buf; if ( pcxh.Encoding == 0 ) { if(!SDL_RWread(src, dst, bpl, 1)) { error = "file truncated"; goto done; } } else { for(i = 0; i < bpl; i++) { if(!count) { if(!SDL_RWread(src, &ch, 1, 1)) { error = "file truncated"; goto done; } if( (ch & 0xc0) == 0xc0) { count = ch & 0x3f; if(!SDL_RWread(src, &ch, 1, 1)) { error = "file truncated"; goto done; } } else count = 1; } dst[i] = ch; count--; } } if(src_bits <= 4) { /* expand planes to 1 byte/pixel */ Uint8 *innerSrc = buf; int plane; for(plane = 0; plane < pcxh.NPlanes; plane++) { int j, k, x = 0; for(j = 0; j < pcxh.BytesPerLine; j++) { Uint8 byte = *innerSrc++; for(k = 7; k >= 0; k--) { unsigned bit = (byte >> k) & 1; /* skip padding bits */ if (j * 8 + k >= width) continue; row[x++] |= bit << plane; } } } } else if(src_bits == 24) {
/** * @brief Loads a wav file from the rw if possible. * * @note Closes the rw. * * @param snd Sound to load wav into. * @param rw Data for the wave. */ static int sound_al_loadWav( alSound *snd, SDL_RWops *rw ) { int len; uint32_t i; char magic[4], *buf; ALenum format; uint32_t filelen, chunklen, rate, unused32; uint16_t compressed, channels, align, unused16; /* Some initialization. */ compressed = 0; channels = 0; /* Seek to start. */ SDL_RWseek( rw, 0, SEEK_SET ); /* Check RIFF header. */ if (sound_al_wavReadCmp( rw, "RIFF", 4 )) { WARN("RIFF header not found."); goto wav_err; } /* Get file length. */ if (sound_al_wavGetLen32( rw, &filelen )) { WARN("Unable to get WAVE length."); goto wav_err; } /* Check WAVE header. */ if (sound_al_wavReadCmp( rw, "WAVE", 4 )) { WARN("WAVE header not found."); goto wav_err; } /* * Chunk information header. */ /* Check chunk header. */ if (sound_al_wavReadCmp( rw, "fmt ", 4 )) { WARN("Chunk header 'fmt ' header not found."); goto wav_err; } /* Get chunk length. */ if (sound_al_wavGetLen32( rw, &chunklen )) { WARN("Unable to get WAVE chunk length."); goto wav_err; } i = 0; /* Get compression. */ if (sound_al_wavGetLen16( rw, &compressed )) { WARN("Unable to get WAVE chunk compression type."); goto wav_err; } if (compressed != 0x0001) { WARN("Unsupported WAVE chunk compression '0x%04x'.", compressed); goto wav_err; } i += 2; /* Get channels. */ if (sound_al_wavGetLen16( rw, &channels )) { WARN("Unable to get WAVE chunk channels."); goto wav_err; } i += 2; /* Get sample rate. */ if (sound_al_wavGetLen32( rw, &rate )) { WARN("Unable to get WAVE chunk sample rate."); goto wav_err; } i += 4; /* Get average bytes. */ if (sound_al_wavGetLen32( rw, &unused32 )) { WARN("Unable to get WAVE chunk average byte rate."); goto wav_err; } i += 4; /* Get block align. */ if (sound_al_wavGetLen16( rw, &unused16 )) { WARN("Unable to get WAVE chunk block align."); goto wav_err; } i += 2; /* Get significant bits. */ if (sound_al_wavGetLen16( rw, &align )) { WARN("Unable to get WAVE chunk significant bits."); goto wav_err; } align /= channels; i += 2; /* Seek to end. */ SDL_RWseek( rw, chunklen-i, SEEK_CUR ); /* Read new header. */ len = SDL_RWread( rw, magic, 4, 1 ); if (len != 1) { WARN("Unable to read chunk header."); goto wav_err; } /* Skip fact. */ if (memcmp( magic, "fact", 4)==0) { /* Get chunk length. */ if (sound_al_wavGetLen32( rw, &chunklen )) { WARN("Unable to get WAVE chunk data length."); goto wav_err; } /* Seek to end of chunk. */ SDL_RWseek( rw, chunklen, SEEK_CUR ); /* Read new header. */ len = SDL_RWread( rw, magic, 4, 1 ); if (len != 1) { WARN("Unable to read chunk header."); goto wav_err; } } /* Should be chunk header now. */ if (memcmp( magic, "data", 4)) { WARN("Unable to find WAVE 'data' chunk header."); goto wav_err; } /* * Chunk data header. */ /* Get chunk length. */ if (sound_al_wavGetLen32( rw, &chunklen )) { WARN("Unable to get WAVE chunk data length."); goto wav_err; } /* Load the chunk data. */ buf = malloc( chunklen ); i = 0; while (i < chunklen) { i += SDL_RWread( rw, &buf[i], 1, chunklen-i ); } /* Calculate format. */ if (channels == 2) { if (align == 16) format = AL_FORMAT_STEREO16; else if (align == 8) format = AL_FORMAT_STEREO8; else { WARN("Unsupported byte alignment (%d) in WAVE file.", align); goto chunk_err; } } else if (channels == 1) { if (align == 16) format = AL_FORMAT_MONO16; else if (align == 8) format = AL_FORMAT_MONO8; else { WARN("Unsupported byte alignment (%d) in WAVE file.", align); goto chunk_err; } } else { WARN("Unsupported number of channels (%d) in WAVE file.", channels); goto chunk_err; } soundLock(); /* Create new buffer. */ alGenBuffers( 1, &snd->u.al.buf ); /* Put into the buffer. */ alBufferData( snd->u.al.buf, format, buf, chunklen, rate ); soundUnlock(); free(buf); return 0; chunk_err: free(buf); wav_err: return -1; }
SDL_Surface *IMG_LoadWEBP_RW(SDL_RWops *src) { Sint64 start; const char *error = NULL; SDL_Surface *volatile surface = NULL; Uint32 Rmask; Uint32 Gmask; Uint32 Bmask; Uint32 Amask; WebPBitstreamFeatures features; int raw_data_size; uint8_t *raw_data = NULL; int r; uint8_t *ret; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } start = SDL_RWtell(src); if ( !IMG_Init(IMG_INIT_WEBP) ) { goto error; } raw_data_size = -1; if ( !webp_getinfo( src, &raw_data_size ) ) { error = "Invalid WEBP"; goto error; } // seek to start of file SDL_RWseek(src, 0, RW_SEEK_SET ); raw_data = (uint8_t*) SDL_malloc( raw_data_size ); if ( raw_data == NULL ) { error = "Failed to allocate enought buffer for WEBP"; goto error; } r = SDL_RWread(src, raw_data, 1, raw_data_size ); if ( r != raw_data_size ) { error = "Failed to read WEBP"; goto error; } #if 0 // extract size of picture, not interesting since we don't know about alpha channel int width = -1, height = -1; if ( !WebPGetInfo( raw_data, raw_data_size, &width, &height ) ) { printf("WebPGetInfo has failed\n" ); return NULL; } #endif if ( lib.webp_get_features_internal( raw_data, raw_data_size, &features, WEBP_DECODER_ABI_VERSION ) != VP8_STATUS_OK ) { error = "WebPGetFeatures has failed"; goto error; } /* Check if it's ok !*/ #if SDL_BYTEORDER == SDL_LIL_ENDIAN Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; Amask = (features.has_alpha) ? 0xFF000000 : 0; #else s = (features.has_alpha) ? 0 : 8; Rmask = 0xFF000000 >> s; Gmask = 0x00FF0000 >> s; Bmask = 0x0000FF00 >> s; Amask = 0x000000FF >> s; #endif surface = SDL_CreateRGBSurface(SDL_SWSURFACE, features.width, features.height, features.has_alpha?32:24, Rmask,Gmask,Bmask,Amask); if ( surface == NULL ) { error = "Failed to allocate SDL_Surface"; goto error; } if ( features.has_alpha ) { ret = lib.webp_decode_rgba_into( raw_data, raw_data_size, (uint8_t *)surface->pixels, surface->pitch * surface->h, surface->pitch ); } else { ret = lib.webp_decode_rgb_into( raw_data, raw_data_size, (uint8_t *)surface->pixels, surface->pitch * surface->h, surface->pitch ); } if ( !ret ) { error = "Failed to decode WEBP"; goto error; } return surface; error: if ( surface ) { SDL_FreeSurface( surface ); } if ( raw_data ) { SDL_free( raw_data ); } if ( error ) { IMG_SetError( error ); } SDL_RWseek(src, start, RW_SEEK_SET); return(NULL); }
MentatTextFile::MentatTextFile(SDL_RWops* rwop) { unsigned char* pFiledata; if(rwop == NULL) { throw std::invalid_argument("MentatTextFile:MentatTextFile(): rwop == NULL!"); } int mentatTextFilesize = SDL_RWseek(rwop,0,SEEK_END); if(mentatTextFilesize <= 0) { throw std::runtime_error("MentatTextFile:MentatTextFile(): Cannot determine size of this file!"); } if(mentatTextFilesize < 20) { throw std::runtime_error("MentatTextFile:MentatTextFile(): No valid mentat textfile: File too small!"); } if(SDL_RWseek(rwop,0,SEEK_SET) != 0) { throw std::runtime_error("MentatTextFile:MentatTextFile(): Seeking in this mentat textfile failed!"); } if( (pFiledata = (unsigned char*) malloc(mentatTextFilesize)) == NULL) { throw std::bad_alloc(); } if(SDL_RWread(rwop, pFiledata, mentatTextFilesize, 1) != 1) { free(pFiledata); throw std::runtime_error("MentatTextFile:MentatTextFile(): Reading this mentat textfile failed!"); } if((pFiledata[0] != 'F') || (pFiledata[1] != 'O') || (pFiledata[2] != 'R') || (pFiledata[3] != 'M')) { free(pFiledata); throw std::runtime_error("MentatTextFile:MentatTextFile(): Invalid mentat textfile! Must start with 'FORM'"); } Uint32 formSectionSize = SDL_SwapBE32(*((Uint32*) (pFiledata+4))); if((int) formSectionSize + 8 != mentatTextFilesize) { free(pFiledata); throw std::runtime_error("MentatTextFile:MentatTextFile(): Invalid mentat textfile!"); } if((pFiledata[8] != 'M') || (pFiledata[9] != 'E') || (pFiledata[10] != 'N') || (pFiledata[11] != 'T') || (pFiledata[12] != 'N') || (pFiledata[13] != 'A') || (pFiledata[14] != 'M') || (pFiledata[15] != 'E')) { free(pFiledata); throw std::runtime_error("MentatTextFile:MentatTextFile(): Invalid mentat textfile!"); } Uint32 mentnameSectionSize = SDL_SwapBE32(*((Uint32*) (pFiledata+16))); unsigned char* pMentNameSection = pFiledata + 20; unsigned char* pCurrentPos = pMentNameSection; unsigned char* pMentNameSectionEnd = pMentNameSection + mentnameSectionSize; while(pCurrentPos < pMentNameSectionEnd) { unsigned int entryLength = *pCurrentPos; Uint32 entryContentOffset = SDL_SwapBE32(*((Uint32*) (pCurrentPos+1))); unsigned int numMenuEntry = *((char*) pCurrentPos + 5) - '0'; unsigned int menuLevel = *((char*) pCurrentPos + 6) - '0'; std::string entryTitle((char*) pCurrentPos + 7); int techLevel = *((char*) pCurrentPos + entryLength - 1); if((int) entryContentOffset >= mentatTextFilesize) { free(pFiledata); fprintf(stderr, "0x%x\n", entryContentOffset); throw std::runtime_error("MentatTextFile:MentatTextFile(): Entry offset beyond file end!"); } std::string compressedEntryContent((char*) pFiledata + entryContentOffset); std::string entryContent = convertCP850ToISO8859_1(decodeString(compressedEntryContent)); size_t delimPos = entryContent.find_first_of('*'); std::string filename = entryContent.substr(0,delimPos); std::string nameAndContent = (delimPos == std::string::npos) ? "" : entryContent.substr(delimPos + 1); size_t delimPos2 = nameAndContent.find(" \n"); std::string name = nameAndContent.substr(0,delimPos2); std::string content = (delimPos2 == std::string::npos) ? "" : nameAndContent.substr(delimPos2 + 2); mentatEntries.push_back( MentatEntry( convertCP850ToISO8859_1(entryTitle), numMenuEntry, menuLevel, techLevel, filename, name, content) ); pCurrentPos += entryLength; } free(pFiledata); }
size_t ex_os_fread ( ex_file_t *_file, void *_buf, uint64 _size ) { return SDL_RWread( (SDL_RWops *)_file, _buf, 1, (size_t)_size ); }
static void model_parseDoc (char *docname) { xmlDocPtr doc; xmlNodePtr cur; xmlChar *key; if (strncmp(docname, "./", 2) == 0) { docname += 2; } char *buffer = NULL; int len = 0; SDL_RWops *ops_file = SDL_RWFromFile(docname, "r"); if (ops_file == NULL) { SDL_Log("map: Document open failed: %s\n", docname); return; } len = SDL_RWseek(ops_file, 0, SEEK_END); SDL_RWseek(ops_file, 0, SEEK_SET); buffer = malloc(len); SDL_RWread(ops_file, buffer, 1, len); doc = xmlParseMemory(buffer, len); SDL_RWclose(ops_file); free(buffer); if (doc == NULL) { SDL_Log("Document parsing failed: %s\n", docname); return; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { xmlFreeDoc(doc); die("Document is Empty!!!\n"); return; } strncpy(ModelData[ModelActive].name, basename(docname), 199); cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"name"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if ((char *)key != NULL) { strncpy(ModelData[ModelActive].name, (char *)key, 199); if (strstr(ModelData[ModelActive].name, ".xml\0") <= 0) { strcat(ModelData[ModelActive].name, ".xml"); } } xmlFree(key); } else if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"image"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if ((char *)key != NULL) { strncpy(ModelData[ModelActive].image, (char *)key, 511); } xmlFree(key); } else if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"type"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); if ((char *)key != NULL) { ModelData[ModelActive].dronetype = model_get_dronetype_by_name((char *)key); } xmlFree(key); } else if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"telemetry"))) { model_parseTelemetry(doc, cur); } else if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"mavlink"))) { mavlink_xml_load(ModelActive, doc, cur); } else if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"mwi21"))) { mwi21_xml_load(ModelActive, doc, cur); } else if ((!xmlStrcasecmp(cur->name, (const xmlChar *)"OpenPilot"))) { openpilot_xml_load(doc, cur); } cur = cur->next; } xmlFreeDoc(doc); return; }
bool SaveData::load(const std::string& filename) { char filler[50] = "GTLGTLGTLGTLGTLGTLGTLGTLGTLGTLGTLGTLGTLGTL"; // for RESERVED SDL_RWops *infile; char temp_filename[80]; char temptext[10] = "GTL"; char savedgame[40]; char temp_campaign[41]; strcpy(temp_campaign, "org.openglad.gladiator"); temp_campaign[40] = '\0'; char temp_version = 9; Uint32 newcash; Uint32 newscore = 0; // short numguys; short listsize; short i; char tempname[12] = "FRED"; char guyname[12] = "JOE"; char temp_order, temp_family; short temp_str, temp_dex, temp_con; short temp_short, temp_arm, temp_lev; unsigned char temp_numplayers; Uint32 temp_exp; short temp_kills; Sint32 temp_level_kills; Sint32 temp_td, temp_th, temp_ts; short temp_teamnum; // version 5+ short temp_allied; // v.7+ short temp_registered; // v.7+ // Format of a team list file is: // 3-byte header: 'GTL' // 1-byte version number // 2-bytes registered mark // Versions 7+ // 40-bytes saved game name, version 2 and up // 40-bytes current campaign ID // Version 8+ // 2-bytes (short) = scenario number // 4-bytes (Sint32)= cash (unsigned) // 4-bytes (Sint32)= score (unsigned) // 4-bytes (Sint32)= cash-B (unsigned) // All alternate scores // 4-bytes (Sint32)= score-B (unsigned) // version 6+ // 4-bytes (Sint32)= cash-C (unsigned) // 4-bytes (Sint32)= score-C (unsigned) // 4-bytes (Sint32)= cash-D (unsigned) // 4-bytes (Sint32)= score-D (unsigned) // 2-bytes Allied mode // Versions 7+ // 2-bytes (short) = # of team members in list // 1-byte number of players // 31-bytes RESERVED // List of n objects, each of 58-bytes of form: // 1-byte ORDER // 1-byte FAMILY // 12-byte name // 2-bytes strength // 2-bytes dexterity // 2-bytes constitution // 2-bytes intelligence // 2-bytes armor // 2-bytes level // Does not include upgraded stats in version 8 or lower // 4-bytes unsigned experience // 2-bytes # kills, v.3 // 4-bytes # total levels killed, v.3 // 4-bytes total damage dealt, v.4+ // 4-bytes total hits inflicted, v.4+ // 4-bytes total shots made, v.4+ // 2-bytes team number // 2*4 = 8 bytes RESERVED // List of 200 or 500 (max levels) 1-byte scenario-level status // Versions 1-7 // 2-bytes Number of campaigns in list // Version 8+ // List of n campaigns // Version 8+ // 40-bytes Campaign ID string // 2-bytes Current level in this campaign // 2-bytes Number of level indices in list // List of n level indices // 2-bytes Level index Log("Loading save: %s\n", filename.c_str()); strcpy(temp_filename, filename.c_str()); strcat(temp_filename, ".gtl"); // gladiator team list if ( (infile = open_read_file("save/", temp_filename)) == NULL ) { Log("Failed to open save file: %s\n", filename.c_str()); return 0; } completed_levels.clear(); current_levels.clear(); for(int i = 0; i < team_size; i++) { delete team_list[i]; team_list[i] = NULL; } team_size = 0; // Read id header SDL_RWread(infile, temptext, 3, 1); if ( strcmp(temptext,"GTL")) { SDL_RWclose(infile); Log("Error, selected file is not a GTL file: %s\n", filename.c_str()); return 0; //not a gtl file } // Read version number SDL_RWread(infile, &temp_version, 1, 1); // Versions 7+ have a registered mark .. if (temp_version >= 7) { SDL_RWread(infile, &temp_registered, 2, 1); } // Do other stuff based on version .. if (temp_version != 1) { if (temp_version >= 2) SDL_RWread(infile, savedgame, 40, 1); // read and ignore the name else { SDL_RWclose(infile); Log("Error, selected files is not version one: %s\n", filename.c_str()); return 0; } } save_name = savedgame; // Read campaign ID if (temp_version >= 8) { SDL_RWread(infile, temp_campaign, 1, 40); temp_campaign[40] = '\0'; if(strlen(temp_campaign) > 3) current_campaign = temp_campaign; else current_campaign = "org.openglad.gladiator"; } // Read scenario number short temp_scenario; SDL_RWread(infile, &temp_scenario, 2, 1); scen_num = temp_scenario; // Read cash SDL_RWread(infile, &newcash, 4, 1); totalcash = newcash; // Read score SDL_RWread(infile, &newscore, 4, 1); totalscore = newscore; // Versions 6+ have a score for each possible team, 0-3 if (temp_version >= 6) { for (i=0; i < 4; i++) { SDL_RWread(infile, &newcash, 4, 1); m_totalcash[i] = newcash; SDL_RWread(infile, &newscore, 4, 1); m_totalscore[i] = newscore; } } // Versions 7+ have the allied information .. if (temp_version >= 7) { SDL_RWread(infile, &temp_allied, 2, 1); allied_mode = temp_allied; } // Get # of guys to read SDL_RWread(infile, &listsize, 2, 1); // Read the # of players SDL_RWread(infile, &temp_numplayers, 1, 1); #ifdef DISABLE_MULTIPLAYER temp_numplayers = 1; #endif numplayers = temp_numplayers; // Read the reserved area, 31 bytes SDL_RWread(infile, filler, 31, 1); // Okay, we've read header .. now read the team list data .. for(int i = 0; i < listsize; i++) { guy* temp_guy = new guy; team_list[i] = temp_guy; team_size++; // Get temp values to be read temp_order = ORDER_LIVING; // may be changed later // Read name of current guy... memset(guyname, 0, 12); strcpy(guyname, tempname); // Now write all those values SDL_RWread(infile, &temp_order, 1, 1); SDL_RWread(infile, &temp_family,1, 1); SDL_RWread(infile, guyname, 12, 1); SDL_RWread(infile, &temp_str, 2, 1); SDL_RWread(infile, &temp_dex, 2, 1); SDL_RWread(infile, &temp_con, 2, 1); SDL_RWread(infile, &temp_short, 2, 1); SDL_RWread(infile, &temp_arm, 2, 1); SDL_RWread(infile, &temp_lev, 2, 1); SDL_RWread(infile, &temp_exp, 4, 1); // Below here is version 3 and up.. SDL_RWread(infile, &temp_kills, 2, 1); // how many kills we have SDL_RWread(infile, &temp_level_kills, 4, 1); // levels of kills // Below here is version 4 and up .. SDL_RWread(infile, &temp_td, 4, 1); // total damage SDL_RWread(infile, &temp_th, 4, 1); // total hits SDL_RWread(infile, &temp_ts, 4, 1); // total shots SDL_RWread(infile, &temp_teamnum, 2, 1); // team number // And the filler SDL_RWread(infile, filler, 8, 1); // Now set the values .. temp_guy->family = temp_family; strcpy(temp_guy->name,guyname); temp_guy->strength = temp_str; temp_guy->dexterity = temp_dex; temp_guy->constitution = temp_con; temp_guy->intelligence = temp_short; temp_guy->armor = temp_arm; if(temp_version >= 9) temp_guy->set_level_number(temp_lev); else temp_guy->upgrade_to_level(temp_lev); temp_guy->exp = temp_exp; if (temp_version >=3) { temp_guy->kills = temp_kills; temp_guy->level_kills= temp_level_kills; } else // version 2 or earlier { temp_guy->kills = 0; temp_guy->level_kills= 0; } if (temp_version >= 4) { temp_guy->total_damage = temp_td; temp_guy->total_hits = temp_th; temp_guy->total_shots = temp_ts; } else { temp_guy->total_damage = 0; temp_guy->total_hits = 0; temp_guy->total_shots = 0; } if (temp_version >= 5) { temp_guy->teamnum = temp_teamnum; } else { temp_guy->teamnum = 0; } } // Make sure the default campaign is included completed_levels.insert(std::make_pair("org.openglad.gladiator", std::set<int>())); current_levels.insert(std::make_pair("org.openglad.gladiator", 1)); if(temp_version < 8) { char levelstatus[MAX_LEVELS]; memset(levelstatus, 0, 500); if (temp_version >= 5) SDL_RWread(infile, levelstatus, 500, 1); else SDL_RWread(infile, levelstatus, 200, 1); // Guaranteed to be the default campaign if version < 8 for(int i = 0; i < 500; i++) { if(levelstatus[i]) add_level_completed(current_campaign, i); } } else { short num_campaigns = 0; char campaign[41]; short num_levels = 0; // How many campaigns are stored? SDL_RWread(infile, &num_campaigns, 2, 1); for(int i = 0; i < num_campaigns; i++) { // Get the campaign ID (40 chars) SDL_RWread(infile, campaign, 1, 40); campaign[40] = '\0'; short index = 1; // Get the current level for this campaign SDL_RWread(infile, &index, 2, 1); current_levels[campaign] = index; // Get the number of cleared levels SDL_RWread(infile, &num_levels, 2, 1); for(int j = 0; j < num_levels; j++) { // Get the level index SDL_RWread(infile, &index, 2, 1); // Add it to our list add_level_completed(campaign, index); } } } Log("Loading campaign: %s\n", current_campaign.c_str()); int current_level = load_campaign(current_campaign, current_levels); if(current_level >= 0) { if(scen_num != current_level) Log("Error: Loaded scen_num %d, but found current_level %d\n", scen_num, current_level); //scen_num = current_level; } SDL_RWclose(infile); return 1; }
unsigned File::Read(void* dest, unsigned size) { #ifdef ANDROID if (!handle_ && !assetHandle_) #else if (!handle_) #endif { // Do not log the error further here to prevent spamming the stderr stream return 0; } if (mode_ == FILE_WRITE) { LOGERROR("File not opened for reading"); return 0; } if (size + position_ > size_) size = size_ - position_; if (!size) return 0; #ifdef ANDROID if (assetHandle_) { unsigned sizeLeft = size; unsigned char* destPtr = (unsigned char*)dest; while (sizeLeft) { if (readBufferOffset_ >= readBufferSize_) { readBufferSize_ = Min((int)size_ - position_, (int)READ_BUFFER_SIZE); readBufferOffset_ = 0; SDL_RWread(assetHandle_, readBuffer_.Get(), readBufferSize_, 1); } unsigned copySize = Min((int)(readBufferSize_ - readBufferOffset_), (int)sizeLeft); memcpy(destPtr, readBuffer_.Get() + readBufferOffset_, copySize); destPtr += copySize; sizeLeft -= copySize; readBufferOffset_ += copySize; position_ += copySize; } return size; } #endif if (compressed_) { unsigned sizeLeft = size; unsigned char* destPtr = (unsigned char*)dest; while (sizeLeft) { if (!readBuffer_ || readBufferOffset_ >= readBufferSize_) { unsigned char blockHeaderBytes[4]; fread(blockHeaderBytes, sizeof blockHeaderBytes, 1, (FILE*)handle_); MemoryBuffer blockHeader(&blockHeaderBytes[0], sizeof blockHeaderBytes); unsigned unpackedSize = blockHeader.ReadUShort(); unsigned packedSize = blockHeader.ReadUShort(); if (!readBuffer_) { readBuffer_ = new unsigned char[unpackedSize]; inputBuffer_ = new unsigned char[LZ4_compressBound(unpackedSize)]; } /// \todo Handle errors fread(inputBuffer_.Get(), packedSize, 1, (FILE*)handle_); LZ4_decompress_fast((const char*)inputBuffer_.Get(), (char *)readBuffer_.Get(), unpackedSize); readBufferSize_ = unpackedSize; readBufferOffset_ = 0; } unsigned copySize = Min((int)(readBufferSize_ - readBufferOffset_), (int)sizeLeft); memcpy(destPtr, readBuffer_.Get() + readBufferOffset_, copySize); destPtr += copySize; sizeLeft -= copySize; readBufferOffset_ += copySize; position_ += copySize; } return size; } size_t ret = fread(dest, size, 1, (FILE*)handle_); if (ret != 1) { // Return to the position where the read began fseek((FILE*)handle_, position_ + offset_, SEEK_SET); LOGERROR("Error while reading from file " + GetName()); return 0; } position_ += size; return size; }
/** * @brief Makes sure parameters work properly. Local helper function. * * \sa * http://wiki.libsdl.org/moin.cgi/SDL_RWseek * http://wiki.libsdl.org/moin.cgi/SDL_RWread */ void _testGenericRWopsValidations(SDL_RWops *rw, int write) { char buf[sizeof(RWopsHelloWorldTestString)]; Sint64 i; size_t s; int seekPos = SDLTest_RandomIntegerInRange(4, 8); /* Clear buffer */ SDL_zero(buf); /* Set to start. */ i = SDL_RWseek(rw, 0, RW_SEEK_SET ); SDLTest_AssertPass("Call to SDL_RWseek succeeded"); SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (RW_SEEK_SET), expected 0, got %"SDL_PRIs64, i); /* Test write. */ s = SDL_RWwrite(rw, RWopsHelloWorldTestString, sizeof(RWopsHelloWorldTestString)-1, 1); SDLTest_AssertPass("Call to SDL_RWwrite succeeded"); if (write) { SDLTest_AssertCheck(s == (size_t)1, "Verify result of writing one byte with SDL_RWwrite, expected 1, got %i", (int) s); } else { SDLTest_AssertCheck(s == (size_t)0, "Verify result of writing with SDL_RWwrite, expected: 0, got %i", (int) s); } /* Test seek to random position */ i = SDL_RWseek( rw, seekPos, RW_SEEK_SET ); SDLTest_AssertPass("Call to SDL_RWseek succeeded"); SDLTest_AssertCheck(i == (Sint64)seekPos, "Verify seek to %i with SDL_RWseek (RW_SEEK_SET), expected %i, got %"SDL_PRIs64, seekPos, seekPos, i); /* Test seek back to start */ i = SDL_RWseek(rw, 0, RW_SEEK_SET ); SDLTest_AssertPass("Call to SDL_RWseek succeeded"); SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (RW_SEEK_SET), expected 0, got %"SDL_PRIs64, i); /* Test read */ s = SDL_RWread( rw, buf, 1, sizeof(RWopsHelloWorldTestString)-1 ); SDLTest_AssertPass("Call to SDL_RWread succeeded"); SDLTest_AssertCheck( s == (size_t)(sizeof(RWopsHelloWorldTestString)-1), "Verify result from SDL_RWread, expected %i, got %i", (int) (sizeof(RWopsHelloWorldTestString)-1), (int) s); SDLTest_AssertCheck( SDL_memcmp(buf, RWopsHelloWorldTestString, sizeof(RWopsHelloWorldTestString)-1 ) == 0, "Verify read bytes match expected string, expected '%s', got '%s'", RWopsHelloWorldTestString, buf); /* More seek tests. */ i = SDL_RWseek( rw, -4, RW_SEEK_CUR ); SDLTest_AssertPass("Call to SDL_RWseek(...,-4,RW_SEEK_CUR) succeeded"); SDLTest_AssertCheck( i == (Sint64)(sizeof(RWopsHelloWorldTestString)-5), "Verify seek to -4 with SDL_RWseek (RW_SEEK_CUR), expected %i, got %i", (int) (sizeof(RWopsHelloWorldTestString)-5), (int) i); i = SDL_RWseek( rw, -1, RW_SEEK_END ); SDLTest_AssertPass("Call to SDL_RWseek(...,-1,RW_SEEK_END) succeeded"); SDLTest_AssertCheck( i == (Sint64)(sizeof(RWopsHelloWorldTestString)-2), "Verify seek to -1 with SDL_RWseek (RW_SEEK_END), expected %i, got %i", (int) (sizeof(RWopsHelloWorldTestString)-2), (int) i); /* Invalid whence seek */ i = SDL_RWseek( rw, 0, 999 ); SDLTest_AssertPass("Call to SDL_RWseek(...,0,invalid_whence) succeeded"); SDLTest_AssertCheck( i == (Sint64)(-1), "Verify seek with SDL_RWseek (invalid_whence); expected: -1, got %i", (int) i); }
SDL_Surface *IMG_LoadLBM_RW( SDL_RWops *src ) { int start; SDL_Surface *Image; Uint8 id[4], pbm, colormap[MAXCOLORS*3], *MiniBuf, *ptr, count, color, msk; Uint32 size, bytesloaded, nbcolors; Uint32 i, j, bytesperline, nbplanes, stencil, plane, h; Uint32 remainingbytes; Uint32 width; BMHD bmhd; char *error; Uint8 flagHAM,flagEHB; Image = NULL; error = NULL; MiniBuf = NULL; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } start = SDL_RWtell(src); if ( !SDL_RWread( src, id, 4, 1 ) ) { error="error reading IFF chunk"; goto done; } /* Should be the size of the file minus 4+4 ( 'FORM'+size ) */ if ( !SDL_RWread( src, &size, 4, 1 ) ) { error="error reading IFF chunk size"; goto done; } /* As size is not used here, no need to swap it */ if ( memcmp( id, "FORM", 4 ) != 0 ) { error="not a IFF file"; goto done; } if ( !SDL_RWread( src, id, 4, 1 ) ) { error="error reading IFF chunk"; goto done; } pbm = 0; /* File format : PBM=Packed Bitmap, ILBM=Interleaved Bitmap */ if ( !memcmp( id, "PBM ", 4 ) ) pbm = 1; else if ( memcmp( id, "ILBM", 4 ) ) { error="not a IFF picture"; goto done; } nbcolors = 0; memset( &bmhd, 0, sizeof( BMHD ) ); flagHAM = 0; flagEHB = 0; while ( memcmp( id, "BODY", 4 ) != 0 ) { if ( !SDL_RWread( src, id, 4, 1 ) ) { error="error reading IFF chunk"; goto done; } if ( !SDL_RWread( src, &size, 4, 1 ) ) { error="error reading IFF chunk size"; goto done; } bytesloaded = 0; size = SDL_SwapBE32( size ); if ( !memcmp( id, "BMHD", 4 ) ) /* Bitmap header */ { if ( !SDL_RWread( src, &bmhd, sizeof( BMHD ), 1 ) ) { error="error reading BMHD chunk"; goto done; } bytesloaded = sizeof( BMHD ); bmhd.w = SDL_SwapBE16( bmhd.w ); bmhd.h = SDL_SwapBE16( bmhd.h ); bmhd.x = SDL_SwapBE16( bmhd.x ); bmhd.y = SDL_SwapBE16( bmhd.y ); bmhd.tcolor = SDL_SwapBE16( bmhd.tcolor ); bmhd.Lpage = SDL_SwapBE16( bmhd.Lpage ); bmhd.Hpage = SDL_SwapBE16( bmhd.Hpage ); } if ( !memcmp( id, "CMAP", 4 ) ) /* palette ( Color Map ) */ { if ( !SDL_RWread( src, &colormap, size, 1 ) ) { error="error reading CMAP chunk"; goto done; } bytesloaded = size; nbcolors = size / 3; } if ( !memcmp( id, "CAMG", 4 ) ) /* Amiga ViewMode */ { Uint32 viewmodes; if ( !SDL_RWread( src, &viewmodes, sizeof(viewmodes), 1 ) ) { error="error reading CAMG chunk"; goto done; } bytesloaded = size; viewmodes = SDL_SwapBE32( viewmodes ); if ( viewmodes & 0x0800 ) flagHAM = 1; if ( viewmodes & 0x0080 ) flagEHB = 1; } if ( memcmp( id, "BODY", 4 ) ) { if ( size & 1 ) ++size; /* padding ! */ size -= bytesloaded; /* skip the remaining bytes of this chunk */ if ( size ) SDL_RWseek( src, size, RW_SEEK_CUR ); } } /* compute some usefull values, based on the bitmap header */ width = ( bmhd.w + 15 ) & 0xFFFFFFF0; /* Width in pixels modulo 16 */ bytesperline = ( ( bmhd.w + 15 ) / 16 ) * 2; nbplanes = bmhd.planes; if ( pbm ) /* File format : 'Packed Bitmap' */ { bytesperline *= 8; nbplanes = 1; } stencil = (bmhd.mask & 1); /* There is a mask ( 'stencil' ) */ /* Allocate memory for a temporary buffer ( used for decompression/deinterleaving ) */ MiniBuf = (void *)malloc( bytesperline * (nbplanes + stencil) ); if ( MiniBuf == NULL ) { error="no enough memory for temporary buffer"; goto done; } if ( ( Image = SDL_CreateRGBSurface( SDL_SWSURFACE, width, bmhd.h, (bmhd.planes==24 || flagHAM==1)?24:8, 0, 0, 0, 0 ) ) == NULL ) goto done; if ( bmhd.mask & 2 ) /* There is a transparent color */ #if (SDL_VERSION_ATLEAST(1,3,0)) SDL_SetColorKey( Image, SDL_TRUE, bmhd.tcolor ); #else SDL_SetColorKey( Image, SDL_SRCCOLORKEY, bmhd.tcolor ); #endif /* Update palette informations */ /* There is no palette in 24 bits ILBM file */ if ( nbcolors>0 && flagHAM==0 ) { /* FIXME: Should this include the stencil? See comment below */ int nbrcolorsfinal = 1 << (nbplanes + stencil); ptr = &colormap[0]; for ( i=0; i<nbcolors; i++ ) { Image->format->palette->colors[i].r = *ptr++; Image->format->palette->colors[i].g = *ptr++; Image->format->palette->colors[i].b = *ptr++; } /* Amiga EHB mode (Extra-Half-Bright) */ /* 6 bitplanes mode with a 32 colors palette */ /* The 32 last colors are the same but divided by 2 */ /* Some Amiga pictures save 64 colors with 32 last wrong colors, */ /* they shouldn't !, and here we overwrite these 32 bad colors. */ if ( (nbcolors==32 || flagEHB ) && (1<<bmhd.planes)==64 ) { nbcolors = 64; ptr = &colormap[0]; for ( i=32; i<64; i++ ) { Image->format->palette->colors[i].r = (*ptr++)/2; Image->format->palette->colors[i].g = (*ptr++)/2; Image->format->palette->colors[i].b = (*ptr++)/2; } } /* If nbcolors < 2^nbplanes, repeat the colormap */ /* This happens when pictures have a stencil mask */ if ( nbrcolorsfinal > (1<<bmhd.planes) ) { nbrcolorsfinal = (1<<bmhd.planes); } for ( i=nbcolors; i < (Uint32)nbrcolorsfinal; i++ ) { Image->format->palette->colors[i].r = Image->format->palette->colors[i%nbcolors].r; Image->format->palette->colors[i].g = Image->format->palette->colors[i%nbcolors].g; Image->format->palette->colors[i].b = Image->format->palette->colors[i%nbcolors].b; } if ( !pbm ) Image->format->palette->ncolors = nbrcolorsfinal; } /* Get the bitmap */ for ( h=0; h < bmhd.h; h++ ) { /* uncompress the datas of each planes */ for ( plane=0; plane < (nbplanes+stencil); plane++ ) { ptr = MiniBuf + ( plane * bytesperline ); remainingbytes = bytesperline; if ( bmhd.tcomp == 1 ) /* Datas are compressed */ { do { if ( !SDL_RWread( src, &count, 1, 1 ) ) { error="error reading BODY chunk"; goto done; } if ( count & 0x80 ) { count ^= 0xFF; count += 2; /* now it */ if ( ( count > remainingbytes ) || !SDL_RWread( src, &color, 1, 1 ) ) { error="error reading BODY chunk"; goto done; } memset( ptr, color, count ); } else { ++count; if ( ( count > remainingbytes ) || !SDL_RWread( src, ptr, count, 1 ) ) { error="error reading BODY chunk"; goto done; } } ptr += count; remainingbytes -= count; } while ( remainingbytes > 0 ); } else { if ( !SDL_RWread( src, ptr, bytesperline, 1 ) ) { error="error reading BODY chunk"; goto done; } } } /* One line has been read, store it ! */ ptr = Image->pixels; if ( nbplanes==24 || flagHAM==1 ) ptr += h * width * 3; else ptr += h * width; if ( pbm ) /* File format : 'Packed Bitmap' */ { memcpy( ptr, MiniBuf, width ); } else /* We have to un-interlace the bits ! */ { if ( nbplanes!=24 && flagHAM==0 ) { size = ( width + 7 ) / 8; for ( i=0; i < size; i++ ) { memset( ptr, 0, 8 ); for ( plane=0; plane < (nbplanes + stencil); plane++ ) { color = *( MiniBuf + i + ( plane * bytesperline ) ); msk = 0x80; for ( j=0; j<8; j++ ) { if ( ( plane + j ) <= 7 ) ptr[j] |= (Uint8)( color & msk ) >> ( 7 - plane - j ); else ptr[j] |= (Uint8)( color & msk ) << ( plane + j - 7 ); msk >>= 1; } } ptr += 8; } } else {
static tsize_t tiff_read(thandle_t fd, tdata_t buf, tsize_t size) { return SDL_RWread((SDL_RWops*)fd, buf, 1, size); }
struct MUSIC_GME *GME_LoadSongRW(SDL_RWops *src, int trackNum) { if(src != NULL) { void *bytes=0; long spcsize; Sint64 length=0; length = SDL_RWseek(src, 0, RW_SEEK_END); if (length < 0) { Mix_SetError("GAME-EMU: wrong file\n"); return NULL; } SDL_RWseek(src, 0, RW_SEEK_SET); bytes = malloc(length); long bytes_l; unsigned char byte[1]; spcsize=0; while( (bytes_l=SDL_RWread(src, &byte, sizeof(unsigned char), 1))!=0) { ((unsigned char*)bytes)[spcsize] = byte[0]; spcsize++; } if (spcsize == 0) { Mix_SetError("GAME-EMU: wrong file\n"); return NULL; } Music_Emu* game_emu; char *err = (char*)gme_open_data( bytes, spcsize, &game_emu, gme_t_sample_rate ); //spc_load_spc( snes_spc, bytes, spcsize ); free(bytes); if(err!=0) { Mix_SetError("GAME-EMU: %s", err); return NULL; } if((trackNum<0)||(trackNum >= gme_track_count(game_emu))) trackNum = gme_track_count(game_emu)-1; err = (char*)gme_start_track( game_emu, trackNum ); if(err!=0) { Mix_SetError("GAME-EMU: %s", err); return NULL; } struct MUSIC_GME *spcSpec = (struct MUSIC_GME*)malloc(sizeof(struct MUSIC_GME)); spcSpec->game_emu=game_emu; spcSpec->playing=0; spcSpec->gme_t_sample_rate=mixer.freq; spcSpec->volume=MIX_MAX_VOLUME; spcSpec->mus_title=NULL; spcSpec->mus_artist=NULL; spcSpec->mus_album=NULL; spcSpec->mus_copyright=NULL; gme_info_t *musInfo; err = (char*)gme_track_info(spcSpec->game_emu, &musInfo, trackNum); if(err!=0) { gme_delete(spcSpec->game_emu); free(spcSpec); Mix_SetError("GAME-EMU: %s", err); return NULL; } spcSpec->mus_title = (char *)SDL_malloc(sizeof(char)*strlen(musInfo->song)+1); strcpy(spcSpec->mus_title, musInfo->song); spcSpec->mus_artist = (char *)SDL_malloc(sizeof(char)*strlen(musInfo->author)+1); strcpy(spcSpec->mus_artist, musInfo->author); spcSpec->mus_album = (char *)SDL_malloc(sizeof(char)*strlen(musInfo->game)+1); strcpy(spcSpec->mus_album, musInfo->game); spcSpec->mus_copyright = (char *)SDL_malloc(sizeof(char)*strlen(musInfo->copyright)+1); strcpy(spcSpec->mus_copyright, musInfo->copyright); gme_free_info( musInfo ); SDL_BuildAudioCVT(&spcSpec->cvt, AUDIO_S16, 2, mixer.freq, mixer.format, mixer.channels, mixer.freq); return spcSpec; } return NULL; }
// This callback reads some bytes from an SDL_rwops and copies it // to a Quartz buffer (supplied by Apple framework). static size_t MyProviderGetBytesCallback(void* rwops_userdata, void* quartz_buffer, size_t the_count) { return (size_t)SDL_RWread((struct SDL_RWops *)rwops_userdata, quartz_buffer, 1, the_count); }
static BOOL _mm_RWopsReader_Read(MREADER* reader,void* ptr,size_t size) { return SDL_RWread(((MRWOPSREADER*)reader)->rw, ptr, size, 1); }