static Mask *ase_file_read_mask_chunk(FILE *f) { int c, u, v, byte; Mask *mask; // Read chunk data int x = fgetw(f); int y = fgetw(f); int w = fgetw(f); int h = fgetw(f); ase_file_read_padding(f, 8); std::string name = ase_file_read_string(f); mask = new Mask(); mask->setName(name.c_str()); mask->replace(x, y, w, h); // Read image data for (v=0; v<h; v++) for (u=0; u<(w+7)/8; u++) { byte = fgetc(f); for (c=0; c<8; c++) image_putpixel(mask->getBitmap(), u*8+c, v, byte & (1<<(7-c))); } return mask; }
/* rle_tga_read16: * Helper for reading 16 bit RLE data from TGA files. */ static void rle_tga_read16(uint32_t* address, int w, FILE *f) { unsigned int value; uint32_t color; int count; int c = 0; do { count = fgetc(f); if (count & 0x80) { count = (count & 0x7F) + 1; c += count; value = fgetw(f); color = _rgba(_rgb_scale_5[((value >> 10) & 0x1F)], _rgb_scale_5[((value >> 5) & 0x1F)], _rgb_scale_5[(value & 0x1F)], 255); while (count--) *(address++) = color; } else { count++; c += count; while (count--) { value = fgetw(f); color = _rgba(_rgb_scale_5[((value >> 10) & 0x1F)], _rgb_scale_5[((value >> 5) & 0x1F)], _rgb_scale_5[(value & 0x1F)], 255); *(address++) = color; } } } while (c < w);
static void ase_file_read_frame_header(FILE *f, ASE_FrameHeader *frame_header) { frame_header->size = fgetl(f); frame_header->magic = fgetw(f); frame_header->chunks = fgetw(f); frame_header->duration = fgetw(f); ase_file_read_padding(f, 6); }
/** * Prepis programu wordcount z C++ do C zo zadania. */ int main(void) { htab_t *t=htab_init(HTAB_SIZE); if(!t) { fprintf(stderr, "[wordcount]\t-htable was not allocated\n"); return EXIT_FAILURE; } char word[WORD_LIMIT+1]={0}; while(fgetw(word, WORD_LIMIT, stdin)!=EOF) { if(!htab_lookup(t, word)) { fprintf(stderr, "[wordcount]\t-[htab_lookup] allocation fail\n"); htab_free(t); return EXIT_FAILURE; } } htab_foreach(t, &print_items); //htab_statistics(t); /// vypis statistiky udajov tabulky htab_free(t); return EXIT_SUCCESS; }
static Palette *ase_file_read_color2_chunk(FILE *f, Sprite *sprite, int frame) { int i, c, r, g, b, packets, skip, size; Palette* pal = new Palette(*sprite->getPalette(frame)); pal->setFrame(frame); packets = fgetw(f); // Number of packets skip = 0; // Read all packets for (i=0; i<packets; i++) { skip += fgetc(f); size = fgetc(f); if (!size) size = 256; for (c=skip; c<skip+size; c++) { r = fgetc(f); g = fgetc(f); b = fgetc(f); pal->setEntry(c, _rgba(r, g, b, 255)); } } return pal; }
static bool ase_file_read_header(FILE *f, ASE_Header *header) { header->pos = ftell(f); header->size = fgetl(f); header->magic = fgetw(f); if (header->magic != ASE_FILE_MAGIC) return false; header->frames = fgetw(f); header->width = fgetw(f); header->height = fgetw(f); header->depth = fgetw(f); header->flags = fgetl(f); header->speed = fgetw(f); header->next = fgetl(f); header->frit = fgetl(f); header->transparent_index = fgetc(f); header->ignore[0] = fgetc(f); header->ignore[1] = fgetc(f); header->ignore[2] = fgetc(f); header->ncolors = fgetw(f); if (header->ncolors == 0) // 0 means 256 (old .ase files) header->ncolors = 256; fseek(f, header->pos+128, SEEK_SET); return true; }
unsigned char z80readblock(FILE* file, char* buf) { unsigned char tmp; int adr; adr = fgetw(file); // compressed size tmp = fgetc(file); // page num if (adr == 0xffff) { fread(buf, 0x4000, 1, file); } else { z80uncompress(file, buf, 0x4000); } return tmp; }
static std::string ase_file_read_string(FILE *f) { int length = fgetw(f); if (length == EOF) return ""; std::string string; string.reserve(length+1); for (int c=0; c<length; c++) string.push_back(fgetc(f)); return string; }
t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) { int32 origin, csum, zerocnt, count, word, i; if ((*cptr != 0) || (flag != 0)) return SCPE_ARG; for (zerocnt = 1;; zerocnt = -10) { /* block loop */ for (;; zerocnt++) { /* skip 0's */ if ((count = fgetc (fileref)) == EOF) return SCPE_OK; else if (count) break; else if (zerocnt == 0) return SCPE_OK; } if (fgetc (fileref) == EOF) return SCPE_FMT; if ((origin = fgetw (fileref)) < 0) return SCPE_FMT; csum = origin; /* seed checksum */ for (i = 0; i < count; i++) { /* get data words */ if ((word = fgetw (fileref)) < 0) return SCPE_FMT; WritePW (origin, word); origin = origin + 1; csum = csum + word; } if ((word = fgetw (fileref)) < 0) return SCPE_FMT; if ((word ^ csum) & DMASK) return SCPE_CSUM; } }
static Layer *ase_file_read_layer_chunk(FILE *f, Sprite *sprite, Layer **previous_layer, int *current_level) { std::string name; Layer *layer = NULL; /* read chunk data */ int flags; int layer_type; int child_level; flags = fgetw(f); layer_type = fgetw(f); child_level = fgetw(f); fgetw(f); // default width fgetw(f); // default height fgetw(f); // blend mode ase_file_read_padding(f, 4); name = ase_file_read_string(f); /* image layer */ if (layer_type == 0) { layer = new LayerImage(sprite); } /* layer set */ else if (layer_type == 1) { layer = new LayerFolder(sprite); } if (layer) { // flags layer->setFlags(flags); // name layer->setName(name.c_str()); // child level... if (child_level == *current_level) (*previous_layer)->get_parent()->add_layer(layer); else if (child_level > *current_level) static_cast<LayerFolder*>(*previous_layer)->add_layer(layer); else if (child_level < *current_level) (*previous_layer)->get_parent()->get_parent()->add_layer(layer); *previous_layer = layer; *current_level = child_level; } return layer; }
/* * Read words from stdin and print number of occurrences * @param argc number of arguments * @param argv arguments * @return success code * */ int main(int argc, char* argv[]) { // This size is used, because it is enought for entire book (tested on Alice's Adventures in Wonderland and Pride and Prejudice) // and average number is between 0.5-2 - is used more than half and is average not more than 2 items htab_t* htab = htab_init(7000); htab_listitem* item; char word[128]; while(fgetw(word, 127,stdin) != EOF) { item = htab_lookup(htab,word); item->data++; } htab_foreach(htab, &print_word); //htab_statistics(htab); htab_free(htab); return 0; }
__editor_maybe_static int load_board_direct(struct board *cur_board, FILE *fp, int data_size, int savegame, int version) { int num_robots, num_scrolls, num_sensors, num_robots_active; int overlay_mode, size, board_width, board_height, i; int viewport_x, viewport_y, viewport_width, viewport_height; int truncated = 0; struct robot *cur_robot; struct scroll *cur_scroll; struct sensor *cur_sensor; char *test_buffer; int board_location = ftell(fp); cur_board->num_robots = 0; cur_board->num_robots_allocated = 0; cur_board->num_robots_active = 0; cur_board->num_scrolls = 0; cur_board->num_scrolls_allocated = 0; cur_board->num_sensors = 0; cur_board->num_sensors_allocated = 0; cur_board->robot_list = NULL; cur_board->robot_list_name_sorted = NULL; cur_board->sensor_list = NULL; cur_board->scroll_list = NULL; // Initialize some fields that may no longer be loaded // from the board file itself.. cur_board->last_key = '?'; cur_board->num_input = 0; cur_board->input_size = 0; cur_board->input_string[0] = 0; cur_board->player_last_dir = 0x10; cur_board->bottom_mesg[0] = 0; cur_board->b_mesg_timer = 0; cur_board->lazwall_start = 7; cur_board->b_mesg_row = 24; cur_board->b_mesg_col = -1; cur_board->scroll_x = 0; cur_board->scroll_y = 0; cur_board->locked_x = -1; cur_board->locked_y = -1; cur_board->volume = 255; cur_board->volume_inc = 0; cur_board->volume_target = 255; // board_mode, unused if(fgetc(fp) == EOF) { val_error(WORLD_BOARD_MISSING, board_location); return VAL_MISSING; } overlay_mode = fgetc(fp); if(!overlay_mode) { int overlay_width; int overlay_height; overlay_mode = fgetc(fp); overlay_width = fgetw(fp); overlay_height = fgetw(fp); size = overlay_width * overlay_height; if((size < 1) || (size > MAX_BOARD_SIZE)) goto err_invalid; cur_board->overlay = cmalloc(size); cur_board->overlay_color = cmalloc(size); if(load_RLE2_plane(cur_board->overlay, fp, size)) goto err_freeoverlay; test_buffer = cmalloc(1024); free(test_buffer); // Skip sizes if(fseek(fp, 4, SEEK_CUR) || load_RLE2_plane(cur_board->overlay_color, fp, size)) goto err_freeoverlay; test_buffer = cmalloc(1024); free(test_buffer); } else { overlay_mode = 0; // Undo that last get fseek(fp, -1, SEEK_CUR); } cur_board->overlay_mode = overlay_mode; board_width = fgetw(fp); board_height = fgetw(fp); cur_board->board_width = board_width; cur_board->board_height = board_height; size = board_width * board_height; if((size < 1) || (size > MAX_BOARD_SIZE)) goto err_freeoverlay; cur_board->level_id = cmalloc(size); cur_board->level_color = cmalloc(size); cur_board->level_param = cmalloc(size); cur_board->level_under_id = cmalloc(size); cur_board->level_under_color = cmalloc(size); cur_board->level_under_param = cmalloc(size); if(load_RLE2_plane(cur_board->level_id, fp, size)) goto err_freeboard; if(fseek(fp, 4, SEEK_CUR) || load_RLE2_plane(cur_board->level_color, fp, size)) goto err_freeboard; if(fseek(fp, 4, SEEK_CUR) || load_RLE2_plane(cur_board->level_param, fp, size)) goto err_freeboard; if(fseek(fp, 4, SEEK_CUR) || load_RLE2_plane(cur_board->level_under_id, fp, size)) goto err_freeboard; if(fseek(fp, 4, SEEK_CUR) || load_RLE2_plane(cur_board->level_under_color, fp, size)) goto err_freeboard; if(fseek(fp, 4, SEEK_CUR) || load_RLE2_plane(cur_board->level_under_param, fp, size)) goto err_freeboard; // Load board parameters if(version < 0x0253) { fread(cur_board->mod_playing, LEGACY_MOD_FILENAME_MAX, 1, fp); cur_board->mod_playing[LEGACY_MOD_FILENAME_MAX] = 0; } else { size_t len = fgetw(fp); if(len >= MAX_PATH) len = MAX_PATH - 1; fread(cur_board->mod_playing, len, 1, fp); cur_board->mod_playing[len] = 0; } viewport_x = fgetc(fp); viewport_y = fgetc(fp); viewport_width = fgetc(fp); viewport_height = fgetc(fp); if( (viewport_x < 0) || (viewport_x > 79) || (viewport_y < 0) || (viewport_y > 24) || (viewport_width < 1) || (viewport_width > 80) || (viewport_height < 1) || (viewport_height > 25)) goto err_invalid; cur_board->viewport_x = viewport_x; cur_board->viewport_y = viewport_y; cur_board->viewport_width = viewport_width; cur_board->viewport_height = viewport_height; cur_board->can_shoot = fgetc(fp); cur_board->can_bomb = fgetc(fp); cur_board->fire_burn_brown = fgetc(fp); cur_board->fire_burn_space = fgetc(fp); cur_board->fire_burn_fakes = fgetc(fp); cur_board->fire_burn_trees = fgetc(fp); cur_board->explosions_leave = fgetc(fp); cur_board->save_mode = fgetc(fp); cur_board->forest_becomes = fgetc(fp); cur_board->collect_bombs = fgetc(fp); cur_board->fire_burns = fgetc(fp); for(i = 0; i < 4; i++) { cur_board->board_dir[i] = fgetc(fp); } cur_board->restart_if_zapped = fgetc(fp); cur_board->time_limit = fgetw(fp); if(version < 0x0253) { cur_board->last_key = fgetc(fp); cur_board->num_input = fgetw(fp); cur_board->input_size = fgetc(fp); fread(cur_board->input_string, LEGACY_INPUT_STRING_MAX + 1, 1, fp); cur_board->input_string[LEGACY_INPUT_STRING_MAX] = 0; cur_board->player_last_dir = fgetc(fp); fread(cur_board->bottom_mesg, LEGACY_BOTTOM_MESG_MAX + 1, 1, fp); cur_board->bottom_mesg[LEGACY_BOTTOM_MESG_MAX] = 0; cur_board->b_mesg_timer = fgetc(fp); cur_board->lazwall_start = fgetc(fp); cur_board->b_mesg_row = fgetc(fp); cur_board->b_mesg_col = (signed char)fgetc(fp); cur_board->scroll_x = (signed short)fgetw(fp); cur_board->scroll_y = (signed short)fgetw(fp); cur_board->locked_x = (signed short)fgetw(fp); cur_board->locked_y = (signed short)fgetw(fp); } else if(savegame) { size_t len; cur_board->last_key = fgetc(fp); cur_board->num_input = fgetw(fp); cur_board->input_size = fgetw(fp); len = fgetw(fp); if(len >= ROBOT_MAX_TR) len = ROBOT_MAX_TR - 1; fread(cur_board->input_string, len, 1, fp); cur_board->input_string[len] = 0; cur_board->player_last_dir = fgetc(fp); len = fgetw(fp); if(len >= ROBOT_MAX_TR) len = ROBOT_MAX_TR - 1; fread(cur_board->bottom_mesg, len, 1, fp); cur_board->bottom_mesg[len] = 0; cur_board->b_mesg_timer = fgetc(fp); cur_board->lazwall_start = fgetc(fp); cur_board->b_mesg_row = fgetc(fp); cur_board->b_mesg_col = (signed char)fgetc(fp); cur_board->scroll_x = (signed short)fgetw(fp); cur_board->scroll_y = (signed short)fgetw(fp); cur_board->locked_x = (signed short)fgetw(fp); cur_board->locked_y = (signed short)fgetw(fp); } cur_board->player_ns_locked = fgetc(fp); cur_board->player_ew_locked = fgetc(fp); cur_board->player_attack_locked = fgetc(fp); if(version < 0x0253 || savegame) { cur_board->volume = fgetc(fp); cur_board->volume_inc = fgetc(fp); cur_board->volume_target = fgetc(fp); } /***************/ /* Load robots */ /***************/ num_robots = fgetc(fp); num_robots_active = 0; if(num_robots == EOF) truncated = 1; // EOF/crazy value check if((num_robots < 0) || (num_robots > 255) || (num_robots > size)) goto board_scan; cur_board->robot_list = ccalloc(num_robots + 1, sizeof(struct robot *)); // Also allocate for name sorted list cur_board->robot_list_name_sorted = ccalloc(num_robots, sizeof(struct robot *)); // Any null objects being placed will later be optimized out if(num_robots) { for(i = 1; i <= num_robots; i++) { // Make sure there's robots to load here int length_check = fgetw(fp); fseek(fp, -2, SEEK_CUR); if(length_check < 0) { // Send off the error and then tell validation to shut up for now val_error(WORLD_ROBOT_MISSING, ftell(fp)); set_validation_suppression(1); truncated = 1; } cur_robot = load_robot_allocate(fp, savegame, version); if(cur_robot->used) { cur_board->robot_list[i] = cur_robot; cur_board->robot_list_name_sorted[num_robots_active] = cur_robot; num_robots_active++; } else { // We don't need no null robot clear_robot(cur_robot); cur_board->robot_list[i] = NULL; } } } set_validation_suppression(-1); if(num_robots_active > 0) { if(num_robots_active != num_robots) { cur_board->robot_list_name_sorted = crealloc(cur_board->robot_list_name_sorted, sizeof(struct robot *) * num_robots_active); } qsort(cur_board->robot_list_name_sorted, num_robots_active, sizeof(struct robot *), cmp_robots); } else { free(cur_board->robot_list_name_sorted); cur_board->robot_list_name_sorted = NULL; } cur_board->num_robots = num_robots; cur_board->num_robots_allocated = num_robots; cur_board->num_robots_active = num_robots_active; /****************/ /* Load scrolls */ /****************/ num_scrolls = fgetc(fp); if(num_scrolls == EOF) truncated = 1; if((num_scrolls < 0) || (num_scrolls > 255) || (num_robots + num_scrolls > size)) goto board_scan; cur_board->scroll_list = ccalloc(num_scrolls + 1, sizeof(struct scroll *)); if(num_scrolls) { for(i = 1; i <= num_scrolls; i++) { cur_scroll = load_scroll_allocate(fp); if(cur_scroll->used) cur_board->scroll_list[i] = cur_scroll; else clear_scroll(cur_scroll); } } cur_board->num_scrolls = num_scrolls; cur_board->num_scrolls_allocated = num_scrolls; /****************/ /* Load sensors */ /****************/ num_sensors = fgetc(fp); if(num_sensors == EOF) truncated = 1; if((num_sensors < 0) || (num_sensors > 255) || (num_scrolls + num_sensors + num_robots > size)) goto board_scan; cur_board->sensor_list = ccalloc(num_sensors + 1, sizeof(struct sensor *)); if(num_sensors) { for(i = 1; i <= num_sensors; i++) { cur_sensor = load_sensor_allocate(fp); if(cur_sensor->used) cur_board->sensor_list[i] = cur_sensor; else clear_sensor(cur_sensor); } } cur_board->num_sensors = num_sensors; cur_board->num_sensors_allocated = num_sensors; board_scan: // Now do a board scan to make sure there aren't more than the data told us. { int robot_count = 0, scroll_count = 0, sensor_count = 0; char err_mesg[80] = { 0 }; for(i = 0; i < (board_width * board_height); i++) { if(cur_board->level_id[i] > 127) cur_board->level_id[i] = CUSTOM_BLOCK; if(cur_board->level_under_id[i] > 127) cur_board->level_under_id[i] = CUSTOM_FLOOR; switch(cur_board->level_id[i]) { case ROBOT: case ROBOT_PUSHABLE: { robot_count++; if(robot_count > cur_board->num_robots) { cur_board->level_id[i] = CUSTOM_BLOCK; cur_board->level_param[i] = 'R'; cur_board->level_color[i] = 0xCF; } break; } case SIGN: case SCROLL: { scroll_count++; if(scroll_count > cur_board->num_scrolls) { cur_board->level_id[i] = CUSTOM_BLOCK; cur_board->level_param[i] = 'S'; cur_board->level_color[i] = 0xCF; } } case SENSOR: { // Wait, I forgot. Nobody cares about sensors. //sensor_count++; if(sensor_count > cur_board->num_sensors) { cur_board->level_id[i] = CUSTOM_FLOOR; cur_board->level_param[i] = 'S'; cur_board->level_color[i] = 0xDF; } } } } if(robot_count > cur_board->num_robots) { snprintf(err_mesg, 80, "Board @ %Xh: found %i robots; expected %i", board_location, robot_count, cur_board->num_robots); error(err_mesg, 1, 8, 0); } if(scroll_count > cur_board->num_scrolls) { snprintf(err_mesg, 80, "Board @ %Xh: found %i scrolls/signs; expected %i", board_location, scroll_count, cur_board->num_scrolls); error(err_mesg, 1, 8, 0); } // This won't be reached but I'll leave it anyway. if(sensor_count > cur_board->num_sensors) { snprintf(err_mesg, 80, "Board @ %Xh: found %i sensors; expected %i", board_location, sensor_count, cur_board->num_sensors); error(err_mesg, 1, 8, 0); } if(err_mesg[0]) error("Any extra robots/scrolls/signs were replaced", 1, 8, 0); } if(truncated == 1) val_error(WORLD_BOARD_TRUNCATED_SAFE, board_location); return VAL_SUCCESS; err_freeboard: free(cur_board->level_id); free(cur_board->level_color); free(cur_board->level_param); free(cur_board->level_under_id); free(cur_board->level_under_color); free(cur_board->level_under_param); err_freeoverlay: if(overlay_mode) { free(cur_board->overlay); free(cur_board->overlay_color); } err_invalid: val_error(WORLD_BOARD_CORRUPT, board_location); return VAL_INVALID; }
static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, int frame, PixelFormat pixelFormat, FileOp *fop, ASE_Header *header, size_t chunk_end) { /* read chunk data */ int layer_index = fgetw(f); int x = ((short)fgetw(f)); int y = ((short)fgetw(f)); int opacity = fgetc(f); int cel_type = fgetw(f); Layer* layer; ase_file_read_padding(f, 7); layer = sprite->indexToLayer(layer_index); if (!layer) { fop_error(fop, "Frame %d didn't found layer with index %d\n", frame, layer_index); return NULL; } if (!layer->is_image()) { fop_error(fop, "Invalid .ase file (frame %d in layer %d which does not contain images\n", frame, layer_index); return NULL; } // Create the new frame. UniquePtr<Cel> cel(new Cel(frame, 0)); cel->setPosition(x, y); cel->setOpacity(opacity); switch (cel_type) { case ASE_FILE_RAW_CEL: { // Read width and height int w = fgetw(f); int h = fgetw(f); if (w > 0 && h > 0) { Image* image = Image::create(pixelFormat, w, h); // Read pixel data switch (image->getPixelFormat()) { case IMAGE_RGB: read_raw_image<RgbTraits>(f, image, fop, header); break; case IMAGE_GRAYSCALE: read_raw_image<GrayscaleTraits>(f, image, fop, header); break; case IMAGE_INDEXED: read_raw_image<IndexedTraits>(f, image, fop, header); break; } cel->setImage(sprite->getStock()->addImage(image)); } break; } case ASE_FILE_LINK_CEL: { // Read link position int link_frame = fgetw(f); Cel* link = static_cast<LayerImage*>(layer)->getCel(link_frame); if (link) { // Create a copy of the linked cel (avoid using links cel) Image* image = Image::createCopy(sprite->getStock()->getImage(link->getImage())); cel->setImage(sprite->getStock()->addImage(image)); } else { // Linked cel doesn't found return NULL; } break; } case ASE_FILE_COMPRESSED_CEL: { // Read width and height int w = fgetw(f); int h = fgetw(f); if (w > 0 && h > 0) { Image* image = Image::create(pixelFormat, w, h); // Try to read pixel data try { switch (image->getPixelFormat()) { case IMAGE_RGB: read_compressed_image<RgbTraits>(f, image, chunk_end, fop, header); break; case IMAGE_GRAYSCALE: read_compressed_image<GrayscaleTraits>(f, image, chunk_end, fop, header); break; case IMAGE_INDEXED: read_compressed_image<IndexedTraits>(f, image, chunk_end, fop, header); break; } } // OK, in case of error we can show the problem, but continue // loading more cels. catch (const std::exception& e) { fop_error(fop, e.what()); } cel->setImage(sprite->getStock()->addImage(image)); } break; } } Cel* newCel = cel.release(); static_cast<LayerImage*>(layer)->addCel(newCel); return newCel; }
bool AseFormat::onLoad(FileOp *fop) { Sprite *sprite = NULL; ASE_Header header; ASE_FrameHeader frame_header; int current_level; int frame_pos; int chunk_pos; int chunk_size; int chunk_type; int c, frame; FileHandle f(fop->filename.c_str(), "rb"); if (!f) return false; if (!ase_file_read_header(f, &header)) { fop_error(fop, "Error reading header\n"); return false; } // Create the new sprite sprite = new Sprite(header.depth == 32 ? IMAGE_RGB: header.depth == 16 ? IMAGE_GRAYSCALE: IMAGE_INDEXED, header.width, header.height, header.ncolors); if (!sprite) { fop_error(fop, "Error creating sprite with file spec\n"); return false; } // Set frames and speed sprite->setTotalFrames(header.frames); sprite->setDurationForAllFrames(header.speed); // Set transparent entry sprite->setTransparentColor(header.transparent_index); // Prepare variables for layer chunks Layer* last_layer = sprite->getFolder(); current_level = -1; /* read frame by frame to end-of-file */ for (frame=0; frame<sprite->getTotalFrames(); frame++) { /* start frame position */ frame_pos = ftell(f); fop_progress(fop, (float)frame_pos / (float)header.size); /* read frame header */ ase_file_read_frame_header(f, &frame_header); /* correct frame type */ if (frame_header.magic == ASE_FILE_FRAME_MAGIC) { /* use frame-duration field? */ if (frame_header.duration > 0) sprite->setFrameDuration(frame, frame_header.duration); /* read chunks */ for (c=0; c<frame_header.chunks; c++) { /* start chunk position */ chunk_pos = ftell(f); fop_progress(fop, (float)chunk_pos / (float)header.size); /* read chunk information */ chunk_size = fgetl(f); chunk_type = fgetw(f); switch (chunk_type) { /* only for 8 bpp images */ case ASE_FILE_CHUNK_FLI_COLOR: case ASE_FILE_CHUNK_FLI_COLOR2: /* fop_error(fop, "Color chunk\n"); */ if (sprite->getPixelFormat() == IMAGE_INDEXED) { Palette *prev_pal = sprite->getPalette(frame); Palette *pal = chunk_type == ASE_FILE_CHUNK_FLI_COLOR ? ase_file_read_color_chunk(f, sprite, frame): ase_file_read_color2_chunk(f, sprite, frame); if (prev_pal->countDiff(pal, NULL, NULL) > 0) { sprite->setPalette(pal, true); } delete pal; } else fop_error(fop, "Warning: was found a color chunk in non-8bpp file\n"); break; case ASE_FILE_CHUNK_LAYER: { /* fop_error(fop, "Layer chunk\n"); */ ase_file_read_layer_chunk(f, sprite, &last_layer, ¤t_level); break; } case ASE_FILE_CHUNK_CEL: { /* fop_error(fop, "Cel chunk\n"); */ ase_file_read_cel_chunk(f, sprite, frame, sprite->getPixelFormat(), fop, &header, chunk_pos+chunk_size); break; } case ASE_FILE_CHUNK_MASK: { Mask *mask; /* fop_error(fop, "Mask chunk\n"); */ mask = ase_file_read_mask_chunk(f); if (mask) delete mask; // TODO add the mask in some place? else fop_error(fop, "Warning: error loading a mask chunk\n"); break; } case ASE_FILE_CHUNK_PATH: /* fop_error(fop, "Path chunk\n"); */ break; default: fop_error(fop, "Warning: Unsupported chunk type %d (skipping)\n", chunk_type); break; } /* skip chunk size */ fseek(f, chunk_pos+chunk_size, SEEK_SET); } } /* skip frame size */ fseek(f, frame_pos+frame_header.size, SEEK_SET); /* just one frame? */ if (fop->oneframe) break; if (fop_is_stop(fop)) break; } fop->document = new Document(sprite); if (ferror(f)) { fop_error(fop, "Error reading file.\n"); return false; } else { return true; } }
int loadZ80_f(Computer* comp, FILE* file) { int btm; int err = ERR_OK; unsigned char tmp,tmp2,reg,lst; unsigned short adr, twrd; // CPU* cpu = comp->cpu; char pageBuf[0xc000]; z80v1Header hd; comp->p7FFD = 0x10; comp->pEFF7 = 0x00; memSetBank(comp->mem,0x00,MEM_ROM,1,MEM_16K,NULL,NULL,NULL); memSetBank(comp->mem,0xc0,MEM_RAM,0,MEM_16K,NULL,NULL,NULL); comp->vid->curscr = 5; fread((char*)&hd, sizeof(z80v1Header), 1, file); if (hd.flag12 == 0xff) hd.flag12 = 0x01; // Because of compatibility, if byte 12 is 255, it has to be regarded as being 1. comp->cpu->af = (hd.a << 8) | hd.f; comp->cpu->bc = (hd.b << 8) | hd.c; comp->cpu->de = (hd.d << 8) | hd.e; comp->cpu->hl = (hd.h << 8) | hd.l; comp->cpu->af_ = (hd._a << 8) | hd._f; comp->cpu->bc_ = (hd._b << 8) | hd._c; comp->cpu->de_ = (hd._d << 8) | hd._e; comp->cpu->hl_ = (hd._h << 8) | hd._l; comp->cpu->pc = (hd.pch << 8) | hd.pcl; comp->cpu->sp = (hd.sph << 8) | hd.spl; comp->cpu->ix = (hd.ixh << 8) | hd.ixl; comp->cpu->iy = (hd.iyh << 8) | hd.iyl; comp->cpu->i = hd.i; comp->cpu->r7 = (hd.flag12 & 1) ? 0x80 : 0; comp->cpu->r = (hd.r7 & 0x7f) | comp->cpu->r7; comp->cpu->imode = hd.flag29 & 3; comp->cpu->iff1 = hd.iff1; comp->cpu->iff2 = hd.iff2; comp->cpu->inten = Z80_NMI | (hd.iff1 ? Z80_INT : 0); comp->vid->brdcol = (hd.flag12 >> 1) & 7; comp->vid->nextbrd = comp->vid->brdcol; // unsupported things list if (hd.flag12 & 0x10) printf("...flag 12.bit 4.Basic SamRom switched in\n"); if (hd.flag29 & 0x04) printf("...flag 29.bit 2.Issue 2 emulation\n"); if (hd.flag29 & 0x08) printf("...flag 29.bit 3.Double interrupt frequency\n"); // continued if (comp->cpu->pc == 0) { adr = fgetw(file); twrd = fgetw(file); comp->cpu->pc = twrd; lst = fgetc(file); // 34: HW mode tmp = fgetc(file); // 35: 7FFD last out comp->hw->out(comp, 0x7ffd, tmp, 0); tmp = fgetc(file); // 36: skip (IF1) tmp = fgetc(file); // 37: skip (flags) TODO reg = fgetc(file); // 38: last out to fffd for (tmp2 = 0; tmp2 < 16; tmp2++) { // AY regs tmp = fgetc(file); tsOut(comp->ts, 0xfffd, tmp2); tsOut(comp->ts, 0xbffd, tmp); } comp->hw->out(comp, 0xfffd, reg, 0); if (adr > 23) { printf(".z80 version 3\n"); if (lst < 16) printf("Hardware: %s\n",v3hardware[lst]); switch (lst) { case 0: case 1: case 2: lst = 1; break; // 48K case 4: case 5: case 6: case 9: lst = 2; break; // 128K case 10: lst = 3; break; // 256K default: lst = 0; break; // undef } fseek(file, adr-23, SEEK_CUR); // skip all other bytes } else { printf(".z80 version 2\n"); if (lst < 16) printf("Hardware: %s\n",v2hardware[lst]); switch (lst) { case 0: case 1: lst = 1; break; case 3: case 4: case 9: lst = 2; break; // 128K case 10: lst = 3; break; // 256K default: lst = 0; break; // undef } } switch (lst) { case 1: btm = 1; do { tmp = z80readblock(file,pageBuf); switch (tmp) { case 4: memPutData(comp->mem,MEM_RAM,2,MEM_16K,pageBuf); break; case 5: memPutData(comp->mem,MEM_RAM,0,MEM_16K,pageBuf); break; case 8: memPutData(comp->mem,MEM_RAM,5,MEM_16K,pageBuf); break; default: btm = 0; break; } } while (btm && !feof(file)); break; case 2: btm = 1; do { tmp = z80readblock(file,pageBuf); if ((tmp > 2) && (tmp < 11)) { memPutData(comp->mem,MEM_RAM,tmp-3,MEM_16K,pageBuf); } else { btm = 0; } } while (btm && !feof(file)); break; case 3: btm = 1; do { tmp = z80readblock(file,pageBuf); if ((tmp > 2) && (tmp < 19)) { memPutData(comp->mem,MEM_RAM,tmp-3,MEM_16K,pageBuf); } else { btm = 0; } } while (btm && !feof(file)); break; default: printf("Hardware mode not supported. reset\n"); compReset(comp, RES_DEFAULT); err = ERR_Z80_HW; break; } } else { // version 1 printf(".z80 version 1\n"); if (hd.flag12 & 0x20) { printf("data is compressed\n"); z80uncompress(file,pageBuf,0xc000); memPutData(comp->mem,MEM_RAM,5,MEM_16K,pageBuf); memPutData(comp->mem,MEM_RAM,2,MEM_16K,pageBuf + MEM_16K); memPutData(comp->mem,MEM_RAM,0,MEM_16K,pageBuf + MEM_32K); } else { printf("data is not compressed\n"); fread(pageBuf, 0x4000, 1, file); memPutData(comp->mem,MEM_RAM,5,MEM_16K,pageBuf); fread(pageBuf, 0x4000, 1, file); memPutData(comp->mem,MEM_RAM,2,MEM_16K,pageBuf); fread(pageBuf, 0x4000, 1, file); memPutData(comp->mem,MEM_RAM,0,MEM_16K,pageBuf); } } tsReset(comp->ts); return err; }
/* This is a lot like try_load_world but much more thorough, and doesn't * pass data through or leave a file open. This needs to be done before * any data is ever loaded, so that Megazeux can cleanly abort if there * is an issue. */ enum val_result validate_world_file(const char *filename, int savegame, int *end_of_global_offset, int decrypt_attempted) { enum val_result result = VAL_SUCCESS; FILE *f; char magic[15]; int num_boards; int board_name_offset; int v, i; /* TEST 1: Make sure it's a readable file */ if(!(f = val_fopen(filename))) { val_error(FILE_DOES_NOT_EXIST, 0); result = VAL_MISSING; goto err_out; } /* TEST 2: Is it a save file? */ if(savegame) { int screen_mode, num_counters, num_strings, len; if(fread(magic, 5, 1, f) != 1) goto err_invalid; v = save_magic(magic); if(!v) goto err_invalid; else if (v > WORLD_VERSION) { val_error(SAVE_VERSION_TOO_RECENT, v); result = VAL_VERSION; goto err_close; } else if (v < WORLD_VERSION) { val_error(SAVE_VERSION_OLD, v); result = VAL_VERSION; goto err_close; } /* TEST 3: Check for truncation, savegame style, hope this * doesn't explode :erm: */ if( fseek(f, 8, SEEK_SET) || fseek(f, WORLD_BLOCK_1_SIZE, SEEK_CUR) || fseek(f, 71, SEEK_CUR) || fseek(f, (len = fgetw(f)), SEEK_CUR) || (len < 0) || fseek(f, WORLD_BLOCK_2_SIZE, SEEK_CUR) || fseek(f, 24, SEEK_CUR)) { debug("pre-counters\n"); goto err_invalid; } //do counters - vvvvnnnn(name) num_counters = fgetd(f); if(num_counters < 0) { debug("counter num\n"); goto err_invalid; } for(i = 0; i < num_counters; i++) { if( fseek(f, 4, SEEK_CUR) || //value fseek(f, (len = fgetd(f)), SEEK_CUR) || (len < 0)) { debug("counters\n"); goto err_invalid; } } //do strings- nnnnllll(name)(value) num_strings = fgetd(f); if(num_strings < 0) { debug("string num\n"); goto err_invalid; } for(i = 0; i < num_strings; i++) { int name_length = fgetd(f); int value_length = fgetd(f); if( (name_length < 0) || (value_length < 0) || fseek(f, name_length, SEEK_CUR) || fseek(f, value_length, SEEK_CUR)) { debug("strings\n"); goto err_invalid; } } if( fseek(f, 4612, SEEK_CUR) || //sprites fseek(f, 12, SEEK_CUR) || //misc fseek(f, fgetw(f), SEEK_CUR) || //fread_open fseek(f, 4, SEEK_CUR) || //fread_pos fseek(f, fgetw(f), SEEK_CUR) || //fwrite_open fseek(f, 4, SEEK_CUR)) //fwrite_pos { debug("post strings\n"); goto err_invalid; } screen_mode = fgetw(f); if((screen_mode > 3) || (screen_mode > 1 && fseek(f, 768, SEEK_CUR))) //smzx palette { debug("smzx palette\n"); goto err_invalid; } if( fseek(f, 4, SEEK_CUR) || //commands ((len = fgetd(f)) < 0) || //vlayer size fseek(f, 4, SEEK_CUR) || // width & height fseek(f, len, SEEK_CUR) || //chars fseek(f, len, SEEK_CUR)) //colors { debug("vlayer\n"); goto err_invalid; } /* now we should be at the global robot pointer! */ } else /* !savegame */ { int protection_method; /* TEST 3: Check for truncation */ if(fseek(f, WORLD_GLOBAL_OFFSET_OFFSET, SEEK_SET)) goto err_invalid; fseek(f, BOARD_NAME_SIZE, SEEK_SET); /* TEST 4: If we think it's locked, try to decrypt it. */ protection_method = fgetc(f); if(protection_method > 0) { if(protection_method > 3) goto err_invalid; if(decrypt_attempted) // In the unlikely event that this will happen again goto err_invalid; val_error(WORLD_PASSWORD_PROTECTED, 0); if(!confirm(NULL, "Would you like to decrypt it?")) { result = VAL_NEED_UNLOCK; goto err_close; } else { val_error(WORLD_LOCKED, 0); result = VAL_ABORTED; goto err_close; } } /* TEST 5: Make sure the magic is awwrightttt~ */ fread(magic, 1, 3, f); v = world_magic(magic); if(v == 0) goto err_invalid; else if (v < 0x0205) { val_error(WORLD_FILE_VERSION_OLD, v); result = VAL_VERSION; goto err_close; } else if (v > WORLD_VERSION) { val_error(WORLD_FILE_VERSION_TOO_RECENT, v); result = VAL_VERSION; goto err_close; } /* TEST 6: Attempt to eliminate invalid files by * testing the palette for impossible values. */ fseek(f, WORLD_GLOBAL_OFFSET_OFFSET - 48, SEEK_SET); for(i = 0; i<48; i++) { int val = fgetc(f); if((val < 0) || (val > 63)) goto err_invalid; } /* now we should be at the global robot pointer! */ } /* TEST 7: Either branch should be at the global robot pointer now. * Test for valid SFX structure, if applicable, and board information. */ fseek(f, 4, SEEK_CUR); // Do the sfx num_boards = fgetc(f); if(num_boards == 0) { int sfx_size = fgetw(f); int sfx_off = ftell(f); for (i = 0; i < NUM_SFX; i++) { if(fseek(f, fgetc(f), SEEK_CUR)) break; } if((i != NUM_SFX) || ((ftell(f) - sfx_off) != sfx_size)) goto err_invalid; num_boards = fgetc(f); } if(num_boards == 0) goto err_invalid; board_name_offset = ftell(f); //Make sure board name and pointer data exists if( fseek(f, num_boards * BOARD_NAME_SIZE, SEEK_CUR) || fseek(f, num_boards * 8, SEEK_CUR) || ((ftell(f) - board_name_offset) != num_boards * (BOARD_NAME_SIZE + 8))) goto err_invalid; /* If any of the pointers are less than this pos we probably * aren't dealing with a valid world, but it's not our job * to figure that out right now, so we'll pass it back. */ if(end_of_global_offset) *end_of_global_offset = ftell(f); //todo: maybe have a complete fail when N number of pointers fail? goto err_close; err_invalid: result = VAL_INVALID; if(savegame) val_error(SAVE_FILE_INVALID, 0); else val_error(WORLD_FILE_INVALID, 0); err_close: fclose(f); err_out: return result; }
void help_system(struct world *mzx_world) { char file[13], file2[13], label[13]; int where, offs, size, t1, t2; enum cursor_mode_types old_cmode; FILE *fp; fp = mzx_world->help_file; if(!fp) return; old_cmode = get_cursor_mode(); rewind(fp); t1 = fgetw(fp); fseek(fp, t1 * 21 + 4 + get_context() * 12, SEEK_SET); // At proper context info where = fgetd(fp); // Where file to load is size = fgetd(fp); // Size of file to load offs = fgetd(fp); // Offset within file of link // Jump to file fseek(fp, where, SEEK_SET); // Read it in fread(help, 1, size, fp); // Display it cursor_off(); labelled: help_display(mzx_world, help, offs, file, label); // File? if(file[0]) { // Yep. Search for file. fseek(fp, 2, SEEK_SET); for(t2 = 0; t2 < t1; t2++) { fread(file2, 1, 13, fp); if(!strcmp(file, file2)) break; fseek(fp, 8, SEEK_CUR); } if(t2 < t1) { // Found file. where = fgetd(fp); size = fgetd(fp); fseek(fp, where, SEEK_SET); fread(help, 1, size, fp); // Search for label for(t2 = 0; t2 < size; t2++) { if(help[t2] != 255) continue; if(help[t2 + 1] != ':') continue; if(!strcmp(help + t2 + 3, label)) break; // Found label! } if(t2 < size) { // Found label. t2 is offset. offs = t2; goto labelled; } } } set_cursor_mode(old_cmode); }
__editor_maybe_static void load_board_direct(struct board *cur_board, FILE *fp, int savegame, int version) { int num_robots, num_scrolls, num_sensors, num_robots_active; int overlay_mode, size, board_width, board_height, i; struct robot *cur_robot; struct scroll *cur_scroll; struct sensor *cur_sensor; char *test_buffer; // Initialize some fields that may no longer be loaded // from the board file itself.. cur_board->last_key = '?'; cur_board->num_input = 0; cur_board->input_size = 0; cur_board->input_string[0] = 0; cur_board->player_last_dir = 0x10; cur_board->bottom_mesg[0] = 0; cur_board->b_mesg_timer = 0; cur_board->lazwall_start = 7; cur_board->b_mesg_row = 24; cur_board->b_mesg_col = -1; cur_board->scroll_x = 0; cur_board->scroll_y = 0; cur_board->locked_x = -1; cur_board->locked_y = -1; cur_board->volume = 255; cur_board->volume_inc = 0; cur_board->volume_target = 255; // board_mode, unused fgetc(fp); overlay_mode = fgetc(fp); if(!overlay_mode) { int overlay_width; int overlay_height; overlay_mode = fgetc(fp); overlay_width = fgetw(fp); overlay_height = fgetw(fp); size = overlay_width * overlay_height; cur_board->overlay = cmalloc(size); cur_board->overlay_color = cmalloc(size); load_RLE2_plane(cur_board->overlay, fp, size); test_buffer = cmalloc(1024); free(test_buffer); // Skip sizes fseek(fp, 4, SEEK_CUR); load_RLE2_plane(cur_board->overlay_color, fp, size); test_buffer = cmalloc(1024); free(test_buffer); } else { overlay_mode = 0; // Undo that last get fseek(fp, -1, SEEK_CUR); } cur_board->overlay_mode = overlay_mode; board_width = fgetw(fp); board_height = fgetw(fp); cur_board->board_width = board_width; cur_board->board_height = board_height; size = board_width * board_height; cur_board->level_id = cmalloc(size); cur_board->level_color = cmalloc(size); cur_board->level_param = cmalloc(size); cur_board->level_under_id = cmalloc(size); cur_board->level_under_color = cmalloc(size); cur_board->level_under_param = cmalloc(size); load_RLE2_plane(cur_board->level_id, fp, size); fseek(fp, 4, SEEK_CUR); load_RLE2_plane(cur_board->level_color, fp, size); fseek(fp, 4, SEEK_CUR); load_RLE2_plane(cur_board->level_param, fp, size); fseek(fp, 4, SEEK_CUR); load_RLE2_plane(cur_board->level_under_id, fp, size); fseek(fp, 4, SEEK_CUR); load_RLE2_plane(cur_board->level_under_color, fp, size); fseek(fp, 4, SEEK_CUR); load_RLE2_plane(cur_board->level_under_param, fp, size); // Load board parameters if(version < 0x0253) { fread(cur_board->mod_playing, LEGACY_MOD_FILENAME_MAX, 1, fp); cur_board->mod_playing[LEGACY_MOD_FILENAME_MAX] = 0; } else { size_t len = fgetw(fp); if(len >= MAX_PATH) len = MAX_PATH - 1; fread(cur_board->mod_playing, len, 1, fp); cur_board->mod_playing[len] = 0; } cur_board->viewport_x = fgetc(fp); cur_board->viewport_y = fgetc(fp); cur_board->viewport_width = fgetc(fp); cur_board->viewport_height = fgetc(fp); cur_board->can_shoot = fgetc(fp); cur_board->can_bomb = fgetc(fp); cur_board->fire_burn_brown = fgetc(fp); cur_board->fire_burn_space = fgetc(fp); cur_board->fire_burn_fakes = fgetc(fp); cur_board->fire_burn_trees = fgetc(fp); cur_board->explosions_leave = fgetc(fp); cur_board->save_mode = fgetc(fp); cur_board->forest_becomes = fgetc(fp); cur_board->collect_bombs = fgetc(fp); cur_board->fire_burns = fgetc(fp); for(i = 0; i < 4; i++) { cur_board->board_dir[i] = fgetc(fp); } cur_board->restart_if_zapped = fgetc(fp); cur_board->time_limit = fgetw(fp); if(version < 0x0253) { cur_board->last_key = fgetc(fp); cur_board->num_input = fgetw(fp); cur_board->input_size = fgetc(fp); fread(cur_board->input_string, LEGACY_INPUT_STRING_MAX + 1, 1, fp); cur_board->input_string[LEGACY_INPUT_STRING_MAX] = 0; cur_board->player_last_dir = fgetc(fp); fread(cur_board->bottom_mesg, LEGACY_BOTTOM_MESG_MAX + 1, 1, fp); cur_board->bottom_mesg[LEGACY_BOTTOM_MESG_MAX] = 0; cur_board->b_mesg_timer = fgetc(fp); cur_board->lazwall_start = fgetc(fp); cur_board->b_mesg_row = fgetc(fp); cur_board->b_mesg_col = (signed char)fgetc(fp); cur_board->scroll_x = (signed short)fgetw(fp); cur_board->scroll_y = (signed short)fgetw(fp); cur_board->locked_x = (signed short)fgetw(fp); cur_board->locked_y = (signed short)fgetw(fp); } else if(savegame) { size_t len; cur_board->last_key = fgetc(fp); cur_board->num_input = fgetw(fp); cur_board->input_size = fgetw(fp); len = fgetw(fp); if(len >= ROBOT_MAX_TR) len = ROBOT_MAX_TR - 1; fread(cur_board->input_string, len, 1, fp); cur_board->input_string[len] = 0; cur_board->player_last_dir = fgetc(fp); len = fgetw(fp); if(len >= ROBOT_MAX_TR) len = ROBOT_MAX_TR - 1; fread(cur_board->bottom_mesg, len, 1, fp); cur_board->bottom_mesg[len] = 0; cur_board->b_mesg_timer = fgetc(fp); cur_board->lazwall_start = fgetc(fp); cur_board->b_mesg_row = fgetc(fp); cur_board->b_mesg_col = (signed char)fgetc(fp); cur_board->scroll_x = (signed short)fgetw(fp); cur_board->scroll_y = (signed short)fgetw(fp); cur_board->locked_x = (signed short)fgetw(fp); cur_board->locked_y = (signed short)fgetw(fp); } cur_board->player_ns_locked = fgetc(fp); cur_board->player_ew_locked = fgetc(fp); cur_board->player_attack_locked = fgetc(fp); if(version < 0x0253 || savegame) { cur_board->volume = fgetc(fp); cur_board->volume_inc = fgetc(fp); cur_board->volume_target = fgetc(fp); } // Load robots num_robots = fgetc(fp); num_robots_active = 0; cur_board->robot_list = ccalloc(num_robots + 1, sizeof(struct robot *)); // Also allocate for name sorted list cur_board->robot_list_name_sorted = ccalloc(num_robots, sizeof(struct robot *)); // Any null objects being placed will later be optimized out if(num_robots) { for(i = 1; i <= num_robots; i++) { cur_robot = load_robot_allocate(fp, savegame, version); if(cur_robot->used) { cur_board->robot_list[i] = cur_robot; cur_board->robot_list_name_sorted[num_robots_active] = cur_robot; num_robots_active++; } else { // We don't need no null robot clear_robot(cur_robot); cur_board->robot_list[i] = NULL; } } } if(num_robots_active) { if(num_robots_active != num_robots) { cur_board->robot_list_name_sorted = crealloc(cur_board->robot_list_name_sorted, sizeof(struct robot *) * num_robots_active); } qsort(cur_board->robot_list_name_sorted, num_robots_active, sizeof(struct robot *), cmp_robots); } else { free(cur_board->robot_list_name_sorted); cur_board->robot_list_name_sorted = NULL; } cur_board->num_robots = num_robots; cur_board->num_robots_allocated = num_robots; cur_board->num_robots_active = num_robots_active; // Load scrolls num_scrolls = fgetc(fp); cur_board->scroll_list = ccalloc(num_scrolls + 1, sizeof(struct scroll *)); if(num_scrolls) { for(i = 1; i <= num_scrolls; i++) { cur_scroll = load_scroll_allocate(fp); if(cur_scroll->used) cur_board->scroll_list[i] = cur_scroll; else clear_scroll(cur_scroll); } } cur_board->num_scrolls = num_scrolls; cur_board->num_scrolls_allocated = num_scrolls; // Load sensors num_sensors = fgetc(fp); cur_board->sensor_list = ccalloc(num_sensors + 1, sizeof(struct sensor *)); if(num_sensors) { for(i = 1; i <= num_sensors; i++) { cur_sensor = load_sensor_allocate(fp); if(cur_sensor->used) cur_board->sensor_list[i] = cur_sensor; else clear_sensor(cur_sensor); } } cur_board->num_sensors = num_sensors; cur_board->num_sensors_allocated = num_sensors; }
bool CMapLoaderGalaxy::loadMap(CMap &Map, Uint8 level) { // Get the MAPHEAD Location from within the Exe File or an external file std::vector<char> mapHeadContainer; const std::string &path = gKeenFiles.gameDir; // Set Map position and some flags for the freshly loaded level Map.gotoPos(0,0); Map.setLevel(level); Map.isSecret = false; Map.mNumFuses = 0; // In case no external file was read, let's use data from the embedded data byte *Maphead = gKeenFiles.exeFile.getRawData() + getMapheadOffset(); // In case there is an external file read it into the container and replace the pointer const std::string mapHeadFilename = gKeenFiles.mapheadFilename; std::ifstream MapHeadFile; if(OpenGameFileR(MapHeadFile, getResourceFilename(mapHeadFilename,path,true,false), std::ios::binary)) { // get length of file: MapHeadFile.seekg (0, std::ios::end); unsigned int length = MapHeadFile.tellg(); MapHeadFile.seekg (0, std::ios::beg); mapHeadContainer.resize(length); MapHeadFile.read(&mapHeadContainer[0],length*sizeof(char)); Maphead = reinterpret_cast<byte*>(&mapHeadContainer[0]); } word magic_word; longword level_offset; // Get the magic number of the level data from MAPHEAD Located in the EXE-File. // This is used for the decompression. magic_word = READWORD(Maphead); // Get location of the level data from MAPHEAD Located in the EXE-File. Maphead += level*sizeof(longword); level_offset = READLONGWORD(Maphead); // Open the Gamemaps file std::string gamemapfile = gKeenFiles.gamemapsFilename; std::ifstream MapFile; if(OpenGameFileR(MapFile, getResourceFilename(gamemapfile,path,true,false), std::ios::binary)) { if(level_offset == 0 && mapHeadContainer.empty()) { MapFile.close(); gLogging.textOut("This Level doesn't exist in GameMaps"); return false; } // Then jump to that location and read the level map data MapFile.seekg (level_offset, std::ios::beg); int headbegin; // Get the level plane header if(gotoNextSignature(MapFile)) { /* * Plane Offsets: Long[3] Offset within GAMEMAPS to the start of the plane. The first offset is for the background plane, the * second for the foreground plane, and the third for the info plane (see below). * Plane Lengths: Word[3] Length (in bytes) of the compressed plane data. The first length is for the background plane, the * second for the foreground plane, and the third for the info plane (see below). * Width: Word Level width (in tiles). * Height: Word Level height (in tiles). Together with Width, this can be used to calculate the uncompressed * size of plane data, by multiplying Width by Height and multiplying the result by sizeof(Word). * Name: Byte[16] Null-terminated string specifying the name of the level. This name is used only by TED5, not by Keen. * Signature: Byte[4] Marks the end of the Level Header. Always "!ID!". */ int jumpback = 3*sizeof(longword) + 3*sizeof(word) + 2*sizeof(word) + 16*sizeof(byte) + 4*sizeof(byte); headbegin = static_cast<int>(MapFile.tellg()) - jumpback; } else { MapFile.clear(); headbegin = level_offset; } MapFile.seekg( headbegin, std::ios_base::beg); // Get the header of level data longword Plane_Offset[3]; longword Plane_Length[3]; word Width, Height; char name[17]; // Get the plane offsets Plane_Offset[0] = fgetl(MapFile); Plane_Offset[1] = fgetl(MapFile); Plane_Offset[2] = fgetl(MapFile); // Get the dimensions of the level Plane_Length[0] = fgetw(MapFile); Plane_Length[1] = fgetw(MapFile); Plane_Length[2] = fgetw(MapFile); Width = fgetw(MapFile); Height = fgetw(MapFile); if(Width>1024 || Height>1024) { gLogging.textOut("Sorry, but I cannot uncompress this map and must give up." "Please report this to the developers and send that version to them in order to fix it.<br>" ); return false; } for(int c=0 ; c<16 ; c++) { name[c] = MapFile.get(); } name[16] = '\0'; // Get and check the signature gLogging.textOut("Loading the Level \"" + static_cast<std::string>(name) + "\" (Level No. "+ itoa(level) + ")<br>" ); Map.setLevelName(name); mLevelName = name; // Then decompress the level data using rlew and carmack gLogging.textOut("Decompressing the Map...<br>" ); // Start with the Background Map.createEmptyDataPlane(0, Width, Height); Map.createEmptyDataPlane(1, Width, Height); Map.createEmptyDataPlane(2, Width, Height); unpackPlaneData(MapFile, Map, 0, Plane_Offset[0], Plane_Length[0], magic_word); unpackPlaneData(MapFile, Map, 1, Plane_Offset[1], Plane_Length[1], magic_word); unpackPlaneData(MapFile, Map, 2, Plane_Offset[2], Plane_Length[2], magic_word); Map.collectBlockersCoordiantes(); MapFile.close(); // Now that we have all the 3 planes (Background, Foreground, Foes) unpacked... // We only will show the first two of them in the screen, because the Foes one // is the one which will be used for spawning the foes (Keen, platforms, enemies, etc.) spawnFoes(Map); } else { return false; } // Set Scrollbuffer Map.drawAll(); gVideoDriver.updateScrollBuffer(Map.m_scrollx, Map.m_scrolly); return true; }
/* loads a COL file (Animator and Animator Pro format) */ Palette *load_col_file(const char *filename) { #if (MAKE_VERSION(4, 2, 1) >= MAKE_VERSION(ALLEGRO_VERSION, \ ALLEGRO_SUB_VERSION, \ ALLEGRO_WIP_VERSION)) int size = file_size(filename); #else int size = file_size_ex(filename); #endif int pro = (size == 768)? false: true; /* is Animator Pro format? */ div_t d = div(size-8, 3); Palette *pal = NULL; int c, r, g, b; FILE *f; if (!(size) || (pro && d.rem)) /* invalid format */ return NULL; f = fopen(filename, "rb"); if (!f) return NULL; /* Animator format */ if (!pro) { pal = new Palette(FrameNumber(0), 256); for (c=0; c<256; c++) { r = fgetc(f); g = fgetc(f); b = fgetc(f); if (ferror(f)) break; pal->setEntry(c, _rgba(_rgb_scale_6[MID(0, r, 63)], _rgb_scale_6[MID(0, g, 63)], _rgb_scale_6[MID(0, b, 63)], 255)); } } /* Animator Pro format */ else { int magic, version; fgetl(f); /* skip file size */ magic = fgetw(f); /* file format identifier */ version = fgetw(f); /* version file */ /* unknown format */ if (magic != PROCOL_MAGIC_NUMBER || version != 0) { fclose(f); return NULL; } pal = new Palette(FrameNumber(0), MIN(d.quot, 256)); for (c=0; c<pal->size(); c++) { r = fgetc(f); g = fgetc(f); b = fgetc(f); if (ferror(f)) break; pal->setEntry(c, _rgba(MID(0, r, 255), MID(0, g, 255), MID(0, b, 255), 255)); } } fclose(f); return pal; }