/* Function: al_fopen_slice */ ALLEGRO_FILE *al_fopen_slice(ALLEGRO_FILE *fp, size_t initial_size, const char *mode) { SLICE_DATA *userdata = al_calloc(1, sizeof(*userdata)); if (!userdata) { return NULL; } if (strstr(mode, "r") || strstr(mode, "R")) { userdata->mode |= SLICE_READ; } if (strstr(mode, "w") || strstr(mode, "W")) { userdata->mode |= SLICE_WRITE; } if (strstr(mode, "e") || strstr(mode, "E")) { userdata->mode |= SLICE_EXPANDABLE; } userdata->fp = fp; userdata->anchor = al_ftell(fp); userdata->size = initial_size; return al_create_file_handle(&fi, userdata); }
static long tell_callback(void *dptr) { AL_OV_DATA *ov = (AL_OV_DATA *)dptr; int64_t ret = 0; ret = al_ftell(ov->file); if(ret == -1) return -1; return (long)ret; }
static opus_int64 tell_callback(void *stream) { AL_OP_DATA *op = (AL_OP_DATA *)stream; int64_t ret = 0; ret = al_ftell(op->file); if (ret == -1) return -1; return ret; }
static ALLEGRO_AUDIO_STREAM *modaudio_stream_init(ALLEGRO_FILE* f, size_t buffer_count, unsigned int samples #if (DUMB_MAJOR_VERSION) < 2 /* For DUMB 0.9.3, we must choose a loader function ourselves. */ , DUH *(loader)(DUMBFILE *) #endif ) { ALLEGRO_AUDIO_STREAM *stream; DUMBFILE *df; DUH_SIGRENDERER *sig = NULL; DUH *duh = NULL; DUMB_IT_SIGRENDERER *it_sig = NULL; int64_t start_pos = -1; df = lib.dumbfile_open_ex(f, &dfs_f); if (!df) { ALLEGRO_ERROR("dumbfile_open_ex failed.\n"); return NULL; } start_pos = al_ftell(f); #if (DUMB_MAJOR_VERSION) >= 2 /* * DUMB 2.0 introduces dumb_read_any. It takes two extra int arguments. * * The first int, restrict_, changes how a MOD module is interpreted. * int restrict_ is a two-bit bitfield, and 0 is a good default. * For discussion, see: https://github.com/kode54/dumb/issues/53 * * The second int, subsong, matters only for very few formats. * A5 doesn't allow to choose a subsong from the 5.2 API anyway, thus 0. */ duh = lib.dumb_read_any(df, 0, 0); #else duh = loader(df); #endif if (!duh) { ALLEGRO_ERROR("Failed to create DUH.\n"); goto Error; } sig = lib.duh_start_sigrenderer(duh, 0, 2, 0); if (!sig) { ALLEGRO_ERROR("duh_start_sigrenderer failed.\n"); goto Error; } it_sig = lib.duh_get_it_sigrenderer(sig); if (it_sig) { /* Turn off freezing for XM files. Seems completely pointless. */ lib.dumb_it_set_xm_speed_zero_callback(it_sig, lib.dumb_it_callback_terminate, NULL); } stream = al_create_audio_stream(buffer_count, samples, 44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2); if (stream) { MOD_FILE *mf = al_malloc(sizeof(MOD_FILE)); mf->duh = duh; mf->sig = sig; mf->fh = NULL; mf->length = lib.duh_get_length(duh) / 65536.0; if (mf->length < 0) mf->length = 0; mf->loop_start = -1; mf->loop_end = -1; stream->extra = mf; stream->feeder = modaudio_stream_update; stream->unload_feeder = modaudio_stream_close; stream->rewind_feeder = modaudio_stream_rewind; stream->seek_feeder = modaudio_stream_seek; stream->get_feeder_position = modaudio_stream_get_position; stream->get_feeder_length = modaudio_stream_get_length; stream->set_feeder_loop = modaudio_stream_set_loop; _al_acodec_start_feed_thread(stream); } else { ALLEGRO_ERROR("Failed to create stream.\n"); goto Error; } return stream; Error: if (sig) { lib.duh_end_sigrenderer(sig); } if (duh) { lib.unload_duh(duh); } /* try to return back to where we started to load */ if (start_pos != -1) al_fseek(f, start_pos, ALLEGRO_SEEK_SET); return NULL; }
static AL_VOC_DATA *voc_open(ALLEGRO_FILE *fp) { AL_VOC_DATA *vocdata; char hdrbuf[0x16]; size_t readcount = 0; uint8_t blocktype = 0; uint8_t x = 0; uint16_t timeconstant = 0; uint16_t format = 0; // can be 16-bit in Blocktype 9 (voc version > 1.20 uint16_t vocversion = 0; uint16_t checkver = 0; // must be 1's complement of vocversion + 0x1234 uint32_t blocklength = 0; //length is stored in 3 bites LE, gd byteorder. if (!fp) { ALLEGRO_WARN("voc_open: Failed opening ALLEGRO_FILE"); return NULL; } /* init VOC data */ vocdata = al_malloc(sizeof(AL_VOC_DATA)); memset(vocdata, 0, sizeof(*vocdata)); memset(hdrbuf, 0, sizeof(hdrbuf)); vocdata->file = fp; /* Begin checking the Header info */ readcount = al_fread(fp, hdrbuf, 0x16); if (readcount != 0x16 /*shorter header*/ || !memcmp(hdrbuf, "Creative Voice File\0x1A", 0x14) /*wrong id */ || !memcmp(hdrbuf+0x15 , "\0x00\0x1A", 0x2)) { /*wrong offset */ ALLEGRO_WARN("voc_open: File does not appear to be a valid VOC file"); return NULL; } al_fread(fp, &vocversion, 2); if (vocversion != 0x10A && vocversion != 0x114) { // known ver 1.10 -1.20 ALLEGRO_WARN("voc_open: File is of unknown version"); return NULL; } /* checksum version check */ al_fread(fp, &checkver, 2); if (checkver != ~vocversion + 0x1234) { ALLEGRO_WARN("voc_open: Bad VOC Version Identification Number"); return NULL; } /* * We're at the first datablock, we shall check type and set all the relevant * info in the vocdata structure, including finally the datapos index to the * first valid data byte. */ READNBYTES(fp, blocktype, 1, NULL); READNBYTES(fp, blocklength, 2, NULL); READNBYTES(fp, x, 1, NULL); blocklength += x<<16; switch (blocktype) { case 1: /* blocktype 1 is the most basic header with 1byte format, time * constant and length equal to (datalength + 2). */ blocklength -= 2; READNBYTES(fp, timeconstant, 1, NULL); READNBYTES(fp, format, 1, NULL); vocdata->bits = 8; /* only possible codec for Blocktype 1 */ vocdata->channels = 1; /* block 1 alone means MONO */ vocdata->samplerate = 1000000 / (256 - timeconstant); vocdata->sample_size = 1; /* or better: 1 * 8 / 8 */ /* * Expected number of samples is at LEAST what is in this block. * IIF lentgh 0xFFF there will be a following blocktype 2. * We will deal with this later in load_voc. */ vocdata->samples = blocklength / vocdata->sample_size; vocdata->datapos = al_ftell(fp); break; case 8: /* Blocktype 8 is enhanced data block (mainly for Stereo samples I * guess) that precedes a Blocktype 1, of which the sound infor have * to be ignored. * We skip to the end of the following Blocktype 1 once we get all the * required header info. */ if (blocklength != 4) { ALLEGRO_WARN("voc_open: Got opening Blocktype 8 of wrong length"); return NULL; } READNBYTES(fp, timeconstant, 2, NULL); READNBYTES(fp, format, 1, NULL); READNBYTES(fp, vocdata->channels, 1, NULL); vocdata->channels += 1; /* was 0 for mono, 1 for stereo */ vocdata->bits = 8; /* only possible codec for Blocktype 8 */ vocdata->samplerate = 1000000 / (256 - timeconstant); vocdata->samplerate /= vocdata->channels; vocdata->sample_size = vocdata->channels * vocdata->bits / 8; /* * Now following there is a blocktype 1 which tells us the length of * the data block and all other info are discarded. */ READNBYTES(fp, blocktype, 1, NULL); if (blocktype != 1) { ALLEGRO_WARN("voc_open: Blocktype following type 8 is not 1"); return NULL; } READNBYTES(fp, blocklength, 2, NULL); READNBYTES(fp, x, 1, NULL); blocklength += x<<16; blocklength -= 2; READNBYTES(fp, x, 2, NULL); vocdata->samples = blocklength / vocdata->sample_size; vocdata->datapos = al_ftell(fp); break; case 9: /* * Blocktype 9 is available only for VOC version 1.20 and above. * Deals with 16-bit codecs and stereo and is richier than blocktype 1 * or the BLocktype 8+1 combo * Length is 12 bytes more than actual data. */ blocklength -= 12; READNBYTES(fp, vocdata->samplerate, 4, NULL); // actual samplerate READNBYTES(fp, vocdata->bits, 1, NULL); // actual bits // after compression READNBYTES(fp, vocdata->channels, 1, NULL); // actual channels READNBYTES(fp, format, 2, NULL); if ((vocdata->bits != 8 && vocdata->bits != 16) || (format != 0 && format != 4)) { ALLEGRO_WARN("voc_open: unsupported CODEC in voc data"); return NULL; } READNBYTES(fp, x, 4, NULL); // just skip 4 reserved bytes vocdata->datapos = al_ftell(fp); break; case 2: // case 3: // these cases are just case 4: // ignored in this span case 5: // and wll not return a case 6: // valid VOC data. case 7: // default: ALLEGRO_WARN("voc_open: opening Block is of unsupported type"); return NULL; break; } return vocdata; }
T3F_ANIMATION * t3f_load_animation_f(ALLEGRO_FILE * fp, const char * fn) { T3F_ANIMATION * ap; int i; char header[12] = {0}; int ver; int fpos = 0; ALLEGRO_STATE old_state; ALLEGRO_BITMAP * bp; al_fread(fp, header, 12); ver = check_header(header); if(ver < 0) { return NULL; } ap = t3f_create_animation(); if(ap) { switch(ver) { case 0: { ap->bitmaps->count = al_fread16le(fp); for(i = 0; i < ap->bitmaps->count; i++) { ap->bitmaps->bitmap[i] = t3f_load_resource_f((void **)(&ap->bitmaps->bitmap[i]), T3F_RESOURCE_TYPE_BITMAP, fp, fn, 1, 0); } ap->frames = al_fread16le(fp); for(i = 0; i < ap->frames; i++) { ap->frame[i] = al_malloc(sizeof(T3F_ANIMATION_FRAME)); if(!ap->frame[i]) { return NULL; } ap->frame[i]->bitmap = al_fread16le(fp); ap->frame[i]->x = t3f_fread_float(fp); ap->frame[i]->y = t3f_fread_float(fp); ap->frame[i]->z = t3f_fread_float(fp); ap->frame[i]->width = t3f_fread_float(fp); ap->frame[i]->height = t3f_fread_float(fp); ap->frame[i]->angle = t3f_fread_float(fp); ap->frame[i]->ticks = al_fread32le(fp); ap->frame[i]->flags = al_fread32le(fp); } ap->flags = al_fread32le(fp); break; } case 1: { ap->bitmaps->count = al_fread16le(fp); for(i = 0; i < ap->bitmaps->count; i++) { fpos = al_ftell(fp); ap->bitmaps->bitmap[i] = t3f_load_resource_f((void **)(&ap->bitmaps->bitmap[i]), T3F_RESOURCE_TYPE_BITMAP, fp, fn, 0, 0); if(!ap->bitmaps->bitmap[i]) { al_fseek(fp, fpos, ALLEGRO_SEEK_SET); al_store_state(&old_state, ALLEGRO_STATE_NEW_BITMAP_PARAMETERS); al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP); bp = t3f_load_bitmap_f(fp); al_restore_state(&old_state); if(bp) { ap->bitmaps->bitmap[i] = t3f_squeeze_bitmap(bp, NULL, NULL); al_destroy_bitmap(bp); } } else if(al_get_bitmap_flags(ap->bitmaps->bitmap[i]) & ALLEGRO_MEMORY_BITMAP) { bp = t3f_squeeze_bitmap(ap->bitmaps->bitmap[i], NULL, NULL); al_destroy_bitmap(ap->bitmaps->bitmap[i]); ap->bitmaps->bitmap[i] = bp; } if(!ap->bitmaps->bitmap[i]) { return NULL; } } ap->frames = al_fread16le(fp); for(i = 0; i < ap->frames; i++) { ap->frame[i] = al_malloc(sizeof(T3F_ANIMATION_FRAME)); if(!ap->frame[i]) { return NULL; } ap->frame[i]->bitmap = al_fread16le(fp); ap->frame[i]->x = t3f_fread_float(fp); ap->frame[i]->y = t3f_fread_float(fp); ap->frame[i]->z = t3f_fread_float(fp); ap->frame[i]->width = t3f_fread_float(fp); ap->frame[i]->height = t3f_fread_float(fp); ap->frame[i]->angle = t3f_fread_float(fp); ap->frame[i]->ticks = al_fread32le(fp); ap->frame[i]->flags = al_fread32le(fp); } ap->flags = al_fread32le(fp); break; } } } t3f_animation_build_frame_list(ap); return ap; }
static ALLEGRO_AUDIO_STREAM *mod_stream_init(ALLEGRO_FILE* f, size_t buffer_count, unsigned int samples, DUH *(loader)(DUMBFILE *)) { ALLEGRO_AUDIO_STREAM *stream; DUMBFILE *df; DUH_SIGRENDERER *sig = NULL; DUH *duh = NULL; DUMB_IT_SIGRENDERER *it_sig = NULL; int64_t start_pos = -1; df = lib.dumbfile_open_ex(f, &dfs_f); if (!df) return NULL; start_pos = al_ftell(f); duh = loader(df); if (!duh) { goto Error; } sig = lib.duh_start_sigrenderer(duh, 0, 2, 0); if (!sig) { goto Error; } it_sig = lib.duh_get_it_sigrenderer(sig); if (it_sig) { /* Turn off freezing for XM files. Seems completely pointless. */ lib.dumb_it_set_xm_speed_zero_callback(it_sig, lib.dumb_it_callback_terminate, NULL); } stream = al_create_audio_stream(buffer_count, samples, 44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2); if (stream) { MOD_FILE *mf = al_malloc(sizeof(MOD_FILE)); mf->duh = duh; mf->sig = sig; mf->fh = NULL; mf->length = lib.duh_get_length(duh) / 65536.0; if (mf->length < 0) mf->length = 0; mf->loop_start = -1; mf->loop_end = -1; stream->extra = mf; stream->feeder = modaudio_stream_update; stream->unload_feeder = modaudio_stream_close; stream->rewind_feeder = modaudio_stream_rewind; stream->seek_feeder = modaudio_stream_seek; stream->get_feeder_position = modaudio_stream_get_position; stream->get_feeder_length = modaudio_stream_get_length; stream->set_feeder_loop = modaudio_stream_set_loop; _al_acodec_start_feed_thread(stream); } else { goto Error; } return stream; Error: if (sig) { lib.duh_end_sigrenderer(sig); } if (duh) { lib.unload_duh(duh); } /* try to return back to where we started to load */ if (start_pos != -1) al_fseek(f, start_pos, ALLEGRO_SEEK_SET); return NULL; }
void mapSaver::writeData(ALLEGRO_FILE* fileStream) { unsigned int offset_settings = 0; unsigned int offset_collision = 0; unsigned int offset_tile = 0; unsigned int offset_background = 0; //Reserve room for the header for (unsigned int i=0; i<4*sizeof(unsigned int); i++) { al_fputc(fileStream,0); } offset_settings = al_ftell(fileStream); //Write map dimensions al_fwrite(fileStream,&_mData.left,sizeof(int)); //Write position on map al_fwrite(fileStream,&_mData.top,sizeof(int)); //Write position on map al_fwrite(fileStream,&_mData.right,sizeof(int)); //Write position on map al_fwrite(fileStream,&_mData.bottom,sizeof(int)); //Write position on map offset_collision = al_ftell(fileStream); int collisionLineList = _mData.getCollisionLineCount(); al_fwrite(fileStream,&collisionLineList, sizeof(int)); //Write number of collision lines for (collisionLineListNode* i = _mData.getRootCollisionLine(); i!=NULL; i=i->next) { //Iterate through all the lines int buffer; buffer = i->line->p1.x; al_fwrite(fileStream,&buffer,sizeof(int)); //Line beginning buffer = i->line->p1.y; al_fwrite(fileStream,&buffer,sizeof(int)); //Line beginning buffer = i->line->p2.x; al_fwrite(fileStream,&buffer,sizeof(int)); //Line end buffer = i->line->p2.y; al_fwrite(fileStream,&buffer,sizeof(int)); //line end al_fwrite(fileStream,&i->line->jumpthrough,sizeof(bool)); //jumpthrough? } offset_tile = al_ftell(fileStream); int layerList = _mData.tileLayers.size(); al_fwrite(fileStream,&layerList, sizeof(int)); //Write number of tile Layers for (unsigned int i=0; i<_mData.tileLayers.size(); i++) { int layoutList = _mData.tileLayers[i]->layouts.size(); al_fwrite(fileStream, &layoutList, sizeof(int)); //Write number of layouts. for (unsigned int j=0; j<layoutList; j++) { int tileList = _mData.tileLayers[i]->layouts[j]->tilePositions.size(); al_fwrite(fileStream,&_mData.tileLayers[i]->layouts[j]->tilesetData->tilesetID, sizeof(short)); //Write ID of tileset al_fwrite(fileStream,&tileList, sizeof(int)); //Number of tiles for (unsigned int c=0; c<tileList; c++) { al_fwrite(fileStream,&_mData.tileLayers[i]->layouts[j]->tilePositions[c]->mapX,sizeof(int)); //Write position on map al_fwrite(fileStream,&_mData.tileLayers[i]->layouts[j]->tilePositions[c]->mapY,sizeof(int)); //Write position on map al_fwrite(fileStream,&_mData.tileLayers[i]->layouts[j]->tilePositions[c]->tileSetX,sizeof(short)); //Write position on tileset (pos*width) al_fwrite(fileStream,&_mData.tileLayers[i]->layouts[j]->tilePositions[c]->tileSetY,sizeof(short)); //Write position on tileset (pos*height) } } } offset_background = al_ftell(fileStream); //Background layers int LayerCount = _mData.backgroundLayers.size(); al_fwrite(fileStream,&LayerCount, sizeof(int)); //Write number of background layers for (int i=0; i<_mData.backgroundLayers.size(); i++) { int buffer; buffer = _mData.backgroundLayers[i]->bgHandle->id; al_fwrite(fileStream,&buffer,sizeof(int)); //BG ID buffer = _mData.backgroundLayers[i]->xPos; al_fwrite(fileStream,&buffer,sizeof(int)); //x position buffer = _mData.backgroundLayers[i]->yPos; al_fwrite(fileStream,&buffer,sizeof(int)); //Y position } al_fseek(fileStream,0,ALLEGRO_SEEK_SET); al_fwrite(fileStream,&offset_settings,sizeof(int)); //Write position on map al_fwrite(fileStream,&offset_collision,sizeof(int)); //Write position on map al_fwrite(fileStream,&offset_tile,sizeof(int)); //Write position on map al_fwrite(fileStream,&offset_background,sizeof(int)); //Write position on map }
/** Returns the file position (the 'ftell' function). @return the file position. */ int64_t getFilePosition() const { return al_ftell(get()); }