/* * Actually read the savefile */ static int rd_savefile_new_aux(void) { u32b n_x_check, n_v_check; u32b o_x_check, o_v_check; /* Mention the savefile version */ note(format("Loading a %d.%d.%d savefile...", sf_major, sf_minor, sf_patch)); /* Strip the version bytes */ strip_bytes(4); /* Hack -- decrypt */ xor_byte = sf_extra; /* Clear the checksums */ v_check = 0L; x_check = 0L; /* Strip old data */ strip_bytes(20); if (!get_check("If you import this savefile, object memory will be lost. Is that OK? [y/n]")) return -1; if (rd_randomizer()) return -1; if (rd_options()) return -1; if (rd_messages()) return -1; if (rd_monster_memory()) return -1; if (rd_object_memory()) return -1; if (rd_quests()) return -1; if (rd_artifacts()) return -1; if (rd_player()) return -1; if (rd_squelch()) return -1; if (rd_misc()) return -1; if (rd_player_hp()) return -1; if (rd_player_spells()) return -1; if (rd_randarts()) return -1; if (rd_inventory()) return -1; if (rd_stores()) return -1; if (rd_dungeon()) return -1; if (rd_objects()) return -1; if (rd_monsters()) return -1; if (rd_ghost()) return -1; if (rd_history()) return -1; /* Save the checksum */ n_v_check = v_check; /* Read the old checksum */ rd_u32b(&o_v_check); /* Verify */ if (o_v_check != n_v_check) { note("Invalid checksum"); return (-1); } /* Save the encoded checksum */ n_x_check = x_check; /* Read the checksum */ rd_u32b(&o_x_check); /* Verify */ if (o_x_check != n_x_check) { note("Invalid encoded checksum"); return (-1); } /* Hack -- no ghosts */ r_info[z_info->r_max-1].max_num = 0; /* Success */ return (0); }
/* * Actually read the savefile */ static errr rd_savefile_new_aux(void) { int i, j; int town_count; s32b wild_x_size; s32b wild_y_size; byte tmp8u; u16b tmp16u; u32b tmp32u; u16b tmp_k_idx; #ifdef VERIFY_CHECKSUMS u32b n_x_check, n_v_check; u32b o_x_check, o_v_check; #endif /* Mention the savefile version */ #ifdef JP note(format("バージョン %d.%d.%d のセーブ・ファイルをロード中...", #else note(format("Loading a %d.%d.%d savefile...", #endif sf_major, sf_minor, sf_patch)); /* Strip the version bytes */ strip_bytes(4); /* Hack -- decrypt */ xor_byte = sf_extra; /* Clear the checksums */ v_check = 0L; x_check = 0L; #if SAVEFILE_VERSION /* Read the version number of the savefile */ rd_u32b(&sf_version); #endif /* SAVEFILE_VERSION */ /* Operating system info */ rd_u32b(&sf_xtra); /* Time of savefile creation */ rd_u32b(&sf_when); /* Number of resurrections */ rd_u16b(&sf_lives); /* Number of times played */ rd_u16b(&sf_saves); /* Later use (always zero) */ rd_u32b(&tmp32u); /* Later use (always zero) */ rd_u16b(&tmp16u); /* Later use (always zero) */ rd_byte(&tmp8u); /* Kanji code */ rd_byte(&kanji_code); /* Read RNG state */ rd_randomizer(); #ifdef JP if (arg_fiddle) note("乱数情報をロードしました"); #else if (arg_fiddle) note("Loaded Randomizer Info"); #endif /* Then the options */ rd_options(); #ifdef JP if (arg_fiddle) note("オプションをロードしました"); #else if (arg_fiddle) note("Loaded Option Flags"); #endif /* * Munchkin players are marked * * XXX - should be replaced with a better method, * after the new scorefile-handling is implemented. */ if (munchkin_death) { /* Mark savefile */ noscore |= 0x0001; } /* Then the "messages" */ rd_messages(); #ifdef JP if (arg_fiddle) note("メッセージをロードしました"); #else if (arg_fiddle) note("Loaded Messages"); #endif /* Monster Memory */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > max_r_idx) { #ifdef JP note(format("モンスターの種族が多すぎる(%u)!", tmp16u)); #else note(format("Too many (%u) monster races!", tmp16u)); #endif return (21); } /* Read the available records */ for (i = 0; i < tmp16u; i++) { /* Read the lore */ rd_lore(i); } #ifdef JP if (arg_fiddle) note("モンスターの思い出をロードしました"); #else if (arg_fiddle) note("Loaded Monster Memory"); #endif /* Object Memory */ rd_u16b(&tmp_k_idx); /* Incompatible save files */ if (tmp_k_idx > max_k_idx) { #ifdef JP note(format("アイテムの種類が多すぎる(%u)!", tmp16u)); #else note(format("Too many (%u) object kinds!", tmp16u)); #endif return (22); } /* Make array for object memory */ C_MAKE(obj_mem, tmp_k_idx, byte); /* Read the object memory */ for (i = 0; i < tmp_k_idx; i++) { #if 0 byte tmp8u; object_kind *k_ptr = &k_info[i]; rd_byte(&tmp8u); k_ptr->aware = (tmp8u & 0x01) ? TRUE: FALSE; k_ptr->tried = (tmp8u & 0x02) ? TRUE: FALSE; #else rd_byte(&obj_mem[i]); #endif } #ifdef JP if (arg_fiddle) note("アイテムの記録をロードしました"); #else if (arg_fiddle) note("Loaded Object Memory"); #endif #if 0 /* * Initialize arena and rewards information */ p_ptr->arena_number = 0; p_ptr->inside_arena = 0; p_ptr->inside_quest = 0; p_ptr->exit_bldg = TRUE; /* Start in town 1 */ p_ptr->town_num = 1; p_ptr->wilderness_x = 4; p_ptr->wilderness_y = 4; #endif /* Init the wilderness seeds */ for (i = 0; i < max_wild_x; i++) { for (j = 0; j < max_wild_y; j++) { wilderness[j][i].seed = randint0(0x10000000); } } /* 2.1.3 or newer version */ { u16b max_towns_load; u16b max_quests_load; byte max_rquests_load; /* Number of towns */ rd_u16b(&max_towns_load); /* Incompatible save files */ if (max_towns_load > max_towns) { #ifdef JP note(format("町が多すぎる(%u)!", max_towns_load)); #else note(format("Too many (%u) towns!", max_towns_load)); #endif return (23); } /* Number of quests */ rd_u16b(&max_quests_load); rd_byte(&max_rquests_load); /* Incompatible save files */ if (max_quests_load > max_quests) { #ifdef JP note(format("クエストが多すぎる(%u)!", max_quests_load)); #else note(format("Too many (%u) quests!", max_quests_load)); #endif return (23); } for (i = 0; i < max_quests_load; i++) { if (i < max_quests) { rd_s16b(&quest[i].status); rd_s16b(&quest[i].level); rd_byte(&quest[i].complev); /* Load quest status if quest is running */ if ((quest[i].status == QUEST_STATUS_TAKEN) || (quest[i].status == QUEST_STATUS_COMPLETED) || ((i >= MIN_RANDOM_QUEST) && (i <= (MIN_RANDOM_QUEST + max_rquests_load)))) { rd_s16b(&quest[i].cur_num); rd_s16b(&quest[i].max_num); rd_s16b(&quest[i].type); /* Load quest monster index */ rd_s16b(&quest[i].r_idx); if ((quest[i].type == QUEST_TYPE_RANDOM) && (!quest[i].r_idx)) { int r_idx; while (1) { monster_race *r_ptr; /* * Random monster 5 - 10 levels out of depth * (depending on level) */ r_idx = get_mon_num(quest[i].level + 10); r_ptr = &r_info[r_idx]; if(!(r_ptr->flags1 & RF1_UNIQUE)) continue; if (r_ptr->flags1 & RF1_QUESTOR) continue; if (r_ptr->level >= quest[i].level + 5) continue; if (r_ptr->level >= quest[i].level) break; } quest[i].r_idx = r_idx; } /* Load quest item index */ rd_s16b(&quest[i].k_idx); if (quest[i].k_idx) a_info[quest[i].k_idx].gen_flags |= TRG_QUESTITEM; /* Load quest flags */ rd_byte(&quest[i].flags); } } /* Ignore the empty quests from old versions */ else { /* Ignore quest status */ strip_bytes(2); /* Ignore quest level */ strip_bytes(2); /* * We don't have to care about the other info, * since status should be 0 for these quests anyway */ } } /* Position in the wilderness */ rd_s32b(&p_ptr->wilderness_x); rd_s32b(&p_ptr->wilderness_y); /* Size of the wilderness */ rd_s32b(&wild_x_size); rd_s32b(&wild_y_size); /* Incompatible save files */ if ((wild_x_size > max_wild_x) || (wild_y_size > max_wild_y)) { #ifdef JP note(format("荒野が大きすぎる(%u/%u)!", wild_x_size, wild_y_size)); #else note(format("Wilderness is too big (%u/%u)!", wild_x_size, wild_y_size)); #endif return (23); } /* Load the wilderness seeds */ for (i = 0; i < wild_x_size; i++) { for (j = 0; j < wild_y_size; j++) { rd_u32b(&wilderness[j][i].seed); } } } #ifdef JP if (arg_fiddle) note("クエスト情報をロードしました"); #else if (arg_fiddle) note("Loaded Quests"); #endif /* Load the Artifacts */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > max_a_idx) { #ifdef JP note(format("伝説のアイテムが多すぎる(%u)!", tmp16u)); #else note(format("Too many (%u) artifacts!", tmp16u)); #endif return (24); } /* Read the artifact flags */ for (i = 0; i < tmp16u; i++) { rd_byte(&tmp8u); a_info[i].cur_num = tmp8u; rd_byte(&tmp8u); rd_byte(&tmp8u); rd_byte(&tmp8u); } #ifdef JP if (arg_fiddle) note("伝説のアイテムをロードしました"); #else if (arg_fiddle) note("Loaded Artifacts"); #endif /* Read the extra stuff */ rd_extra(); #ifdef JP if (arg_fiddle) note("特別情報をロードしました"); #else if (arg_fiddle) note("Loaded extra information"); #endif /* Read the player_hp array */ rd_u16b(&tmp16u); /* Remark questor flag on random quester */ if (!death) { for (i = MIN_RANDOM_QUEST; i <= MAX_RANDOM_QUEST; i++) { r_info[quest[i].r_idx].flags1 |= RF1_QUESTOR; } } /* Incompatible save files */ if (tmp16u > PY_MAX_LEVEL) { #ifdef JP note(format("ヒットポイント配列が大きすぎる(%u)!", tmp16u)); #else note(format("Too many (%u) hitpoint entries!", tmp16u)); #endif return (25); } /* Read the player_hp array */ for (i = 0; i < tmp16u; i++) { rd_s16b(&player_hp[i]); } /* Important -- Initialize the sex */ sp_ptr = &sex_info[p_ptr->psex]; /* Important -- Initialize the race/class */ rp_ptr = &race_info[p_ptr->prace]; cp_ptr = &class_info[p_ptr->pclass]; /* Important -- Initialize the magic */ mp_ptr = &m_info[p_ptr->pclass]; /* Read spell info */ rd_u32b(&spell_learned1); rd_u32b(&spell_learned2); rd_u32b(&spell_worked1); rd_u32b(&spell_worked2); rd_u32b(&spell_forgotten1); rd_u32b(&spell_forgotten2); for (i = 0; i < 64; i++) { rd_byte(&spell_order[i]); } /* Read the inventory */ if (rd_inventory()) { #ifdef JP note("持ち物情報を読み込むことができません"); #else note("Unable to read inventory"); #endif return (21); } /* Read number of towns */ rd_u16b(&tmp16u); town_count = tmp16u; /* Read the stores */ rd_u16b(&tmp16u); for (i = 1; i < town_count; i++) { for (j = 0; j < tmp16u; j++) { if (rd_store(i, j)) return (22); } } for (i = 0; i < tmp_k_idx; i++) { byte tmp8u = obj_mem[i]; object_kind *k_ptr = &k_info[i]; k_ptr->aware = (tmp8u & 0x01) ? TRUE: FALSE; k_ptr->tried = (tmp8u & 0x02) ? TRUE: FALSE; } /* Free array for object memories */ C_KILL(obj_mem, tmp_k_idx, byte); /* Read the pet command settings */ if (sf_version > 2) { rd_s16b(&p_ptr->pet_follow_distance); rd_byte(&p_ptr->pet_open_doors); rd_byte(&p_ptr->pet_pickup_items); } else { rd_byte(&tmp8u); p_ptr->pet_follow_distance = tmp8u; rd_byte(&p_ptr->pet_open_doors); rd_byte(&p_ptr->pet_pickup_items); } /* I'm not dead yet... */ if (!death) { /* Dead players have no dungeon */ #ifdef JP note("ダンジョン復元中..."); #else note("Restoring Dungeon..."); #endif if (rd_dungeon()) { #ifdef JP note("ダンジョンデータ読み込み失敗"); #else note("Error reading dungeon data"); #endif return (34); } /* Read the ghost info */ rd_ghost(); { s32b tmp32s; rd_s32b(&tmp32s); strip_bytes(tmp32s); } } #ifdef VERIFY_CHECKSUMS /* Save the checksum */ n_v_check = v_check; /* Read the old checksum */ rd_u32b(&o_v_check); /* Verify */ if (o_v_check != n_v_check) { #ifdef JP note("チェックサムがおかしい"); #else note("Invalid checksum"); #endif return (11); } /* Save the encoded checksum */ n_x_check = x_check; /* Read the checksum */ rd_u32b(&o_x_check); /* Verify */ if (o_x_check != n_x_check) { #ifdef JP note("エンコードされたチェックサムがおかしい"); #else note("Invalid encoded checksum"); #endif return (11); } #endif /* Success */ return (0); }
/* * Actually read the savefile */ static errr rd_savefile_new_aux(void) { int i; byte tmp8u; u16b tmp16u; u32b tmp32u; int a_max; artifact_type *a_info_new; object_lore *a_list_new; #ifdef VERIFY_CHECKSUMS u32b n_x_check, n_v_check; u32b o_x_check, o_v_check; #endif /* Mention the savefile version */ note(format("Loading a %d.%d.%d savefile...", sf_major, sf_minor, sf_patch)); /* Strip the version bytes */ strip_bytes(4); /* Hack -- decrypt */ xor_byte = sf_extra; /* Clear the checksums */ v_check = 0L; x_check = 0L; /* Operating system info */ rd_u32b(&sf_xtra); /* Time of savefile creation */ rd_u32b(&sf_when); /* Number of resurrections */ rd_u16b(&sf_lives); /* Number of times played */ rd_u16b(&sf_saves); /* Later use (always zero) */ rd_u32b(&tmp32u); /* Later use (always zero) */ rd_u32b(&tmp32u); /* Read RNG state */ rd_randomizer(); if (arg_fiddle) note("Loaded Randomizer Info"); /* Then the options */ rd_options(); if (arg_fiddle) note("Loaded Option Flags"); /* Then the "messages" */ rd_messages(); if (arg_fiddle) note("Loaded Messages"); /* Monster Memory */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->r_max) { note(format("Too many (%u) monster races!", tmp16u)); return (-1); } /* Read the available records */ for (i = 0; i < tmp16u; i++) { /* Read the lore */ rd_lore(i); } if (arg_fiddle) note("Loaded Monster Memory"); /* Object Memory */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->k_max) { note(format("Too many (%u) object kinds!", tmp16u)); return (-1); } /* Read the object memory */ for (i = 0; i < tmp16u; i++) { byte tmp8u; object_kind *k_ptr = &k_info[i]; rd_byte(&tmp8u); k_ptr->aware = (tmp8u == 1) ? TRUE: FALSE; k_ptr->tried = (tmp8u >= 2) ? TRUE: FALSE; if ((variant_guess_id) && (tmp8u > 2)) k_ptr->guess = (tmp8u - 2); /* Activations */ if ((variant_usage_id) && !(older_than(2,9,6))) rd_s16b(&k_ptr->used); } if (arg_fiddle) note("Loaded Object Memory"); /* Load the Quests */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > MAX_Q_IDX) { note(format("Too many (%u) quests!", tmp16u)); return (-1); } /* Load the Quests */ for (i = 0; i < tmp16u; i++) { rd_byte(&tmp8u); q_list[i].level = tmp8u; rd_byte(&tmp8u); rd_byte(&tmp8u); rd_byte(&tmp8u); } if (arg_fiddle) note("Loaded Quests"); /* Load the Artifacts */ rd_u16b(&tmp16u); a_max = tmp16u; /* Incompatible save files */ if (a_max > 256) { note(format("Too many (%u) artifacts!", tmp16u)); return (-1); } /* Allocate the new artifact range */ C_MAKE(a_info_new, a_max, artifact_type); /* Allocate the new artifact range */ C_MAKE(a_list_new, a_max, object_lore); /* Read the artifact flags */ for (i = 0; i < a_max; i++) { object_lore *n_ptr = &a_list_new[i]; rd_byte(&tmp8u); a_info_new[i].cur_num = (tmp8u != 0); rd_byte(&tmp8u); rd_byte(&tmp8u); rd_byte(&tmp8u); if (variant_learn_id) { /* Knowledge */ rd_u32b(&n_ptr->can_flags1); rd_u32b(&n_ptr->can_flags2); rd_u32b(&n_ptr->can_flags3); rd_u32b(&n_ptr->not_flags1); rd_u32b(&n_ptr->not_flags2); rd_u32b(&n_ptr->not_flags3); } /* Activations */ if (variant_usage_id) rd_s16b(&a_info_new[i].activated); /* Oops */ if (variant_learn_id) rd_byte(&tmp8u); if (variant_learn_id) rd_byte(&tmp8u); } if (arg_fiddle) note("Loaded Artifacts"); if (variant_learn_id || variant_usage_id) { /* Load the Ego items */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->e_max) { note(format("Too many (%u) ego items!", tmp16u)); return (24); } /* Read the ego item flags */ for (i = 0; i < tmp16u; i++) { object_lore *n_ptr = &e_list[i]; /* Knowledge */ if (variant_learn_id) { rd_u32b(&n_ptr->can_flags1); rd_u32b(&n_ptr->can_flags2); rd_u32b(&n_ptr->can_flags3); rd_u32b(&n_ptr->may_flags1); rd_u32b(&n_ptr->may_flags2); rd_u32b(&n_ptr->may_flags3); rd_u32b(&n_ptr->not_flags1); rd_u32b(&n_ptr->not_flags2); rd_u32b(&n_ptr->not_flags3); } /* Oops */ if (variant_usage_id) rd_byte(&e_info[i].aware); if (variant_usage_id) rd_byte(&tmp8u); /* Oops */ if (variant_learn_id) rd_byte(&tmp8u); if (variant_learn_id) rd_byte(&tmp8u); } } if (arg_fiddle) note("Loaded Ego Items"); /* Read the extra stuff */ if (rd_extra()) return (-1); if (arg_fiddle) note("Loaded extra information"); /* Read random artifacts */ if ((adult_rand_artifacts) || (a_max == 256)) { if (rd_randarts()) return (-1); if (arg_fiddle) note("Loaded Random Artifacts"); } /* Only restore fixed arts if dead */ if (a_max > z_info->a_max) a_max = z_info->a_max; /* Don't restore fixed art knowledge if all random */ else if (p_ptr->is_dead) a_max = 0; /* Copy over the artifact flags */ for (i = 0; i < a_max; i++) { object_lore *n_ptr = &a_list[i]; object_lore *n2_ptr = &a_list_new[i]; a_info[i].cur_num = a_info_new[i].cur_num; if (variant_learn_id) { /* Knowledge */ n_ptr->can_flags1 = n2_ptr->can_flags1; n_ptr->can_flags2 = n2_ptr->can_flags2; n_ptr->can_flags3 = n2_ptr->can_flags3; n_ptr->not_flags1 = n2_ptr->not_flags1; n_ptr->not_flags2 = n2_ptr->not_flags2; n_ptr->not_flags3 = n2_ptr->not_flags3; } /* Activations */ if (variant_usage_id) a_info[i].activated = a_info_new[i].activated; } FREE(a_info_new); FREE(a_list_new); /* Important -- Initialize the sex */ sp_ptr = &sex_info[p_ptr->psex]; /* Important -- Initialize the race/class */ rp_ptr = &p_info[p_ptr->prace]; cp_ptr = &c_info[p_ptr->pclass]; /* Read the inventory */ if (rd_inventory()) { note("Unable to read inventory"); return (-1); } /* Read the stores */ rd_u16b(&tmp16u); for (i = 0; i < tmp16u; i++) { if (rd_store(i)) return (-1); } /* I'm not dead yet... */ if (!p_ptr->is_dead) { /* Dead players have no dungeon */ note("Restoring Dungeon..."); if (rd_dungeon()) { note("Error reading dungeon data"); return (-1); } /* Read the ghost info */ rd_ghost(); } #ifdef VERIFY_CHECKSUMS /* Save the checksum */ n_v_check = v_check; /* Read the old checksum */ rd_u32b(&o_v_check); /* Verify */ if (o_v_check != n_v_check) { note("Invalid checksum"); return (-1); } /* Save the encoded checksum */ n_x_check = x_check; /* Read the checksum */ rd_u32b(&o_x_check); /* Verify */ if (o_x_check != n_x_check) { note("Invalid encoded checksum"); return (-1); } #endif /* Hack -- no ghosts */ r_info[z_info->r_max-1].max_num = 0; /* Set important Save-File Option */ variant_save_feats = TRUE; /* Success */ return (0); }
/* * Actually read the savefile */ static errr rd_savefile_new_aux(void) { int i; byte tmp8u; u16b tmp16u; u32b tmp32u; u32b n_x_check, n_v_check; u32b o_x_check, o_v_check; /* Mention the savefile version */ note(format("Loading a %d.%d.%d savefile...", sf_major, sf_minor, sf_patch)); /* Strip the version bytes, and the game_mode byte */ strip_bytes(5); /* Hack -- decrypt */ xor_byte = sf_extra; /* Clear the checksums */ v_check = 0L; x_check = 0L; /* Operating system info */ rd_u32b(&sf_xtra); /* Time of savefile creation */ rd_u32b(&sf_when); /* Number of resurrections */ rd_u16b(&sf_lives); /* Number of times played */ rd_u16b(&sf_saves); /* Later use (always zero) */ rd_u32b(&tmp32u); /* Later use (always zero) */ rd_u32b(&tmp32u); /* Read RNG state */ rd_randomizer(); if (arg_fiddle) note("Loaded Randomizer Info"); /* Then the options */ rd_options(); if (arg_fiddle) note("Loaded Option Flags"); /* Then the "messages" */ rd_messages(); if (arg_fiddle) note("Loaded Messages"); /* Monster Memory */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->r_max) { note(format("Too many (%u) monster races!", tmp16u)); return (-1); } /* Read the available records */ for (i = 0; i < tmp16u; i++) { /* Read the lore */ rd_monster_lore(i); } if (arg_fiddle) note("Loaded Monster Memory"); /* Object Memory */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->k_max) { note(format("Too many (%u) object kinds!", tmp16u)); return (-1); } /* Read the object memory */ for (i = 0; i < tmp16u; i++) { byte tmp8u; object_kind *k_ptr = &k_info[i]; rd_byte(&tmp8u); k_ptr->aware = (tmp8u & 0x01) ? TRUE: FALSE; k_ptr->tried = (tmp8u & 0x02) ? TRUE: FALSE; k_ptr->everseen = (tmp8u & 0x08) ? TRUE: FALSE; rd_byte(&k_ptr->squelch); /* Hack - Repair the savefile */ if (!k_ptr->everseen) k_ptr->squelch = SQUELCH_NEVER; } if (arg_fiddle) note("Loaded Object Memory"); /* Load the Quests */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->q_max) { note(format("Too many (%u) quests!", tmp16u)); return (23); } /* Load the Quests */ for (i = 0; i < tmp16u; i++) { quest_type *q_ptr = &q_info[i]; rd_byte(&q_ptr->q_type); /* Only limited info for permanent quests. The rest is detailed in quest.txt */ if (q_ptr->q_type == QUEST_PERMANENT) { rd_byte(&q_ptr->q_flags); rd_s16b(&q_ptr->q_num_killed); continue; } rd_u16b(&q_ptr->q_reward); rd_u16b(&q_ptr->q_fame_inc); rd_byte(&q_ptr->base_level); rd_byte(&q_ptr->q_theme); rd_s16b(&q_ptr->mon_idx); rd_s32b(&q_ptr->turn_counter); rd_s16b(&q_ptr->q_num_killed); rd_s16b(&q_ptr->q_max_num); rd_byte(&q_ptr->q_flags); } if (arg_fiddle) note("Loaded Quests"); /* Load the Artifacts */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->art_max) { note(format("Too many (%u) artifacts!", tmp16u)); return (-1); } /* Read the artifact flags */ for (i = 0; i < tmp16u; i++) { rd_byte(&tmp8u); a_info[i].a_cur_num = tmp8u; rd_byte(&tmp8u); rd_byte(&tmp8u); rd_byte(&tmp8u); } if (arg_fiddle) note("Loaded Artifacts"); /* Read the extra stuff */ if (rd_extra()) return (-1); if (arg_fiddle) note("Loaded extra information"); if (rd_randarts()) return (-1); if (arg_fiddle) note("Loaded Random Artifacts"); if (rd_notes()) return (-1); if (arg_fiddle) note("Loaded Notes"); if (rd_extensions()) return (-1); if (arg_fiddle) note("Loaded Extensions"); /* Important -- Initialize the sex */ sp_ptr = &sex_info[p_ptr->psex]; /* Important -- Initialize the race/class */ rp_ptr = &p_info[p_ptr->prace]; cp_ptr = &c_info[p_ptr->pclass]; /* Important -- Initialize the magic */ mp_ptr = &cp_ptr->spells; /* Hack - In NPP 050, we moved a spell out of ironman book.*/ if (cp_ptr->spell_book == TV_MAGIC_BOOK) p_ptr->spell_flags[SPELL_FLIGHT] &= ~(PY_SPELL_IRONMAN); /* Read the inventory */ if (rd_inventory()) { note("Unable to read inventory"); return (-1); } /* Read the stores */ rd_u16b(&tmp16u); for (i = 0; i < tmp16u; i++) { if (rd_store(i)) return (-1); } /* Read the stored number of terrain features */ rd_u16b(&tmp16u); /* Check bounds */ if (tmp16u > z_info->f_max) { note(format("Too many (%u) terrain features!", tmp16u)); return (-1); } /* Read terrain lore */ for (i = 0; i < tmp16u; i++) { if (rd_feature_lore(i)) return (-1); } /* Artifact lore */ /* Read the stored number of artifacts (normal + special) */ rd_u16b(&tmp16u); /* Check bounds */ if (tmp16u > z_info->art_norm_max) { note(format("Too many (%u) artifacts!", tmp16u)); return (-1); } /* Read artifact lore */ for (i = 0; i < tmp16u; i++) { if (rd_artifact_lore(i)) return (-1); } /* I'm not dead yet... */ if (!p_ptr->is_dead) { /* Dead players have no dungeon */ note("Restoring Dungeon..."); if (rd_dungeon()) { note("Error reading dungeon data"); return (-1); } } /* Save the checksum */ n_v_check = v_check; /* Read the old checksum */ rd_u32b(&o_v_check); /* Verify */ if (o_v_check != n_v_check) { note("Invalid checksum"); return (-1); } /* Save the encoded checksum */ n_x_check = x_check; /* Read the checksum */ rd_u32b(&o_x_check); /* Verify */ if (o_x_check != n_x_check) { note("Invalid encoded checksum"); return (-1); } /* Success */ return (0); }
/* * Actually read the savefile */ static errr rd_savefile_new_aux(void) { int i; byte tmp8u; u16b tmp16u; u32b n_x_check, n_v_check; u32b o_x_check, o_v_check; /* Mention the savefile version */ note(format("Loading a %d.%d.%d savefile...", sf_major, sf_minor, sf_patch)); /* Strip the version bytes */ strip_bytes(4); /* Hack -- decrypt */ xor_byte = sf_extra; /* Clear the checksums */ v_check = 0L; x_check = 0L; /* Operating system info */ rd_u32b(&sf_xtra); /* Time of savefile creation */ rd_u32b(&sf_when); /* Number of resurrections */ rd_u16b(&sf_lives); /* Number of times played */ rd_u16b(&sf_saves); // 8 spare bytes strip_bytes(8); /* Read RNG state */ rd_randomizer(); if (arg_fiddle) note("Loaded Randomizer Info"); /* Then the options */ rd_options(); if (arg_fiddle) note("Loaded Option Flags"); /* Then the "messages" */ rd_messages(); if (arg_fiddle) note("Loaded Messages"); /* Monster Memory */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->r_max) { note(format("Too many (%u) monster races!", tmp16u)); return (-1); } /* Read the available records */ for (i = 0; i < tmp16u; i++) { /* Read the lore */ rd_lore(i); } if (arg_fiddle) note("Loaded Monster Memory"); /* Object Memory */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->k_max) { note(format("Too many (%u) object kinds!", tmp16u)); return (-1); } /* Read the object memory */ for (i = 0; i < tmp16u; i++) { byte tmp8u; object_kind *k_ptr = &k_info[i]; rd_byte(&tmp8u); k_ptr->aware = (tmp8u & 0x01) ? TRUE: FALSE; k_ptr->tried = (tmp8u & 0x02) ? TRUE: FALSE; k_ptr->everseen = (tmp8u & 0x08) ? TRUE: FALSE; rd_byte(&k_ptr->squelch); } if (arg_fiddle) note("Loaded Object Memory"); /* Load the Artefacts */ rd_u16b(&tmp16u); /* Incompatible save files */ if (tmp16u > z_info->art_max) { note(format("Too many (%u) artefacts!", tmp16u)); return (-1); } /* Read the artefact flags */ for (i = 0; i < tmp16u; i++) { rd_byte(&tmp8u); a_info[i].cur_num = tmp8u; rd_byte(&tmp8u); a_info[i].found_num = tmp8u; } if (arg_fiddle) note("Loaded Artefacts"); /* Read the extra stuff */ if (rd_extra()) return (-1); if (arg_fiddle) note("Loaded extra information"); if (rd_randarts()) return (-1); if (arg_fiddle) note("Loaded Random Artefacts"); if (rd_notes()) return (-1); if (arg_fiddle) note("Loaded Notes"); /* Important -- Initialize the sex */ sp_ptr = &sex_info[p_ptr->psex]; /* Important -- Initialize the race/house */ rp_ptr = &p_info[p_ptr->prace]; hp_ptr = &c_info[p_ptr->phouse]; /* Read the inventory */ if (rd_inventory()) { note("Unable to read inventory"); return (-1); } /* I'm not dead yet... */ if (!p_ptr->is_dead) { /* Dead players have no dungeon */ note("Restoring Dungeon..."); if (rd_dungeon()) { note("Error reading dungeon data"); return (-1); } } /* Save the checksum */ n_v_check = v_check; /* Read the old checksum */ rd_u32b(&o_v_check); /* Verify */ if (o_v_check != n_v_check) { note("Invalid checksum"); return (-1); } /* Save the encoded checksum */ n_x_check = x_check; /* Read the checksum */ rd_u32b(&o_x_check); /* Verify */ if (o_x_check != n_x_check) { note("Invalid encoded checksum"); return (-1); } /* Success */ return (0); }
int main(int argc, char **argv) { FILE *in; unsigned char *msg, *sec[9]; long int last_pos; struct stat stat_buf; /* for type of grib input file */ int file_arg, i, j, num_submsgs; int n_arg; unsigned int k, ndata; float *data; double *ddata, ref; #ifdef USE_G2CLIB float missing_c_val_1, missing_c_val_2; g2int *bitmap, has_bitmap; g2float *g2_data; int ii; #endif struct ARGLIST arglist[N_ARGLIST]; int narglist = 0; const char *new_argv[N_ARGLIST]; void *local[N_ARGLIST]; int has_inv_option, last_submsg; int err, new_GDS, gdt, pdt, center; unsigned char dscale[2] = {0,0}; inv_file = stdout; // jas_init(); // gctpc initialiation init(-1,-1,"gctpc_1,txt", "gctpc_2.txt"); data = NULL; ndata = 0; /* no arguments .. help screen */ if (argc == 1) { // f_help(-1,NULL,NULL,0,inv_out,local,"most"); mode = -1; data = NULL; ndata = 0; *inv_out = 0; f_h(call_ARG0(inv_out,NULL)); fprintf(inv_file, "%s\n", inv_out); eof_bin(); eof_string(); exit(8); } setup_user_gribtable(); /* copy argv */ for (i = 0; i < argc; i++) { new_argv[i] = argv[i]; } /* scan for "inv" and input file */ has_inv_option = 0; file_arg = 0; for (i = 1; i < argc; i++) { if (new_argv[i][0] != '-') { /* must be filename */ file_arg = i; continue; } /* must be an option */ for (j = 0; j < nfunctions; j++) { if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) { if (functions[j].type == inv) has_inv_option = 1; i += functions[j].nargs; break; } } } /* if no inv option, use default inventory .. put it at end */ if (has_inv_option == 0) { for (i = 0; i < argc; i++) { new_argv[i] = new_argv[i]; } new_argv[argc++] = "-s"; } /* parse parameters */ file_arg = 0; for (i = 1; i < argc; i++) { if (new_argv[i][0] != '-' || (strcmp(new_argv[i],"-") == 0) ) { /* must be filename */ if (file_arg == 0) { file_arg = i; continue; } else { fatal_error("too many grib files .. 2nd=%s", new_argv[i]); } } /* must be an option */ for (j = 0; j < nfunctions; j++) { if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) { #ifdef DEBUG fprintf(stderr,"match .. -%s %d args\n", functions[j].name, functions[j].nargs); #endif /* add to function argument list */ arglist[narglist].fn = j; arglist[narglist].i_argc = i+1; if (functions[j].type == inv) has_inv_option = 1; i += functions[j].nargs; if (i >= argc) fatal_error("missing arguments option=%s",functions[j].name); narglist++; break; } } if (j == nfunctions) { fatal_error("unknown option %s", new_argv[i]); } } if (has_inv_option == 0) { fatal_error("missing arguments on last option",""); } /* initialize options mode = -1 */ #ifdef DEBUG fprintf(stderr,"init options narglist %d\n",narglist); #endif for (j = 0; j < narglist; j++) { inv_out[0] = 0; n_arg = functions[arglist[j].fn].nargs; err = 0; if (n_arg == 0) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j); else if (n_arg == 1) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc]); else if (n_arg == 2) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1]); else if (n_arg == 3) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],new_argv[arglist[j].i_argc+2]); else if (n_arg == 4) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]); else if (n_arg == 5) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4]); else if (n_arg == 6) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]); else if (n_arg == 7) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6]); else if (n_arg == 8) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]); if(inv_out[0] != 0) fprintf(inv_file, "%s", inv_out); if (err) { err_bin(); err_string(); exit(8); } } if (file_arg == 0 && argc > 1) fatal_error("no input file", ""); if (latlon == 1 && output_order_wanted != wesn) fatal_error("latitude-longitude information is only available with -order we:sn",""); /* open input file */ seq_input = 0; if (strcmp(new_argv[file_arg],"-") == 0) { seq_input = 1; in = stdin; if (mode == 98) fprintf(stderr, "grib input is stdin\n"); } else { if (stat(new_argv[file_arg], &stat_buf) != -1) { if (S_ISREG(stat_buf.st_mode)) { if (mode == 98) fprintf(stderr, "grib input is a regular file\n"); } else if (S_ISDIR(stat_buf.st_mode)) { fatal_error("grib input is a directory: %s",new_argv[file_arg]); } else if (S_ISCHR(stat_buf.st_mode)) { seq_input = 1; if (mode == 98) fprintf(stderr, "grib input is a char device\n"); } else if (S_ISBLK(stat_buf.st_mode)) { seq_input = 1; if (mode == 98) fprintf(stderr, "grib input is a block device\n"); } else if (S_ISFIFO(stat_buf.st_mode)) { seq_input = 1; if (mode == 98) fprintf(stderr, "grib input is a fifo device\n"); } else { if (mode == 98) fprintf(stderr, "grib input has an unknown type\n"); } } if ((in = fopen(new_argv[file_arg],"rb")) == NULL) { fatal_error("could not open file: %s", new_argv[file_arg]); } } /* sequential input - can not do random access */ if (seq_input && input == inv_mode) fatal_error("wgrib2 cannot random access grib input file",""); ndata = 0; data = NULL; ddata = NULL; msg_no = 1; inv_no = 0; len = pos = 0; submsg = 0; msg = NULL; if ((old_gds = (unsigned char *) malloc(GDS_max_size * sizeof(char)) ) == NULL) { fatal_error("memory allocation problem old_gds in wgrib2.main",""); } last_pos = -1; last_submsg = -1; /* if dump mode .. position io stream */ if (input == dump_mode) { while (msg_no < dump_msg) { msg = seq_input ? rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) : rd_grib2_msg(in, &pos, &len, &num_submsgs); if (msg == NULL) fatal_error_i("record %d not found", dump_msg); last_pos = pos; pos += len; msg_no++; } #ifdef DEBUG printf("dump mode msg=%d\n", msg_no); #endif } /* * submsg = 0 .. beginning of unread record * submsg = i .. start at ith submsg * num_submsgs = number of submessages in grib message */ /* inventory loop */ for (;last_message == 0;) { /* need position and submessage number of message */ if (input == inv_mode || input == dump_mode) { if (input == inv_mode) { if (rd_inventory(&msg_no,&submsg, &pos)) break; } else if (input == dump_mode) { if (dump_msg == -1) break; submsg = dump_submsg; dump_msg = -1; } if (pos != last_pos) { msg = seq_input ? rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) : rd_grib2_msg(in, &pos, &len, &num_submsgs); if (msg == NULL) { fatal_error_i("grib message #%d not found", msg_no); break; } last_pos = pos; last_submsg = -1; } if (pos == last_pos && submsg == last_submsg + 1) { /* read previous submessage */ if (parse_next_msg(sec) != 0) { fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, submsg); break; } } else { /* need to get desired submessage into sec */ if (parse_1st_msg(sec) != 0) { fprintf(stderr,"\n*** grib message #%d.1 not found ***\n\n", msg_no); break; } for (i = 2; i <= submsg; i++) { if (parse_next_msg(sec) != 0) { fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, i); break; } } } last_submsg = submsg; } else if (input == all_mode) { if (submsg == 0) { msg = seq_input ? rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) : rd_grib2_msg(in, &pos, &len, &num_submsgs); if (msg == NULL) break; submsg = 1; } else if (submsg > num_submsgs) { pos += len; msg_no++; msg = seq_input ? rd_grib2_msg_seq(in, &pos, &len, &num_submsgs) : rd_grib2_msg(in, &pos, &len, &num_submsgs); if (msg == NULL) break; submsg = 1; } if (submsg == 1) { if (parse_1st_msg(sec) != 0) { fprintf(stderr,"illegal format: parsing 1st submessage\n"); } } else { if (parse_next_msg(sec) != 0) { fprintf(stderr,"illegal format: parsing submessages\n"); } } } if (only_submsg > 0 && only_submsg != submsg) { submsg++; continue; } if (for_mode) { if (msg_no < for_start || msg_no > for_end || ((msg_no - for_start) % for_step) != 0) { if (msg_no > for_end && input != inv_mode) last_message = 1; submsg++; continue; } } #ifdef USE_REGEX /* move inv_no++ before match_inv is made */ inv_no++; if (match) { inv_out[0] = 0; if (num_submsgs > 1) { sprintf(inv_out,"%d.%d:", msg_no, submsg); } else { sprintf(inv_out,"%d:", msg_no); } // f_match_inv(0, sec, NULL, 0, inv_out+strlen(inv_out), NULL); f_match_inv(call_ARG0(inv_out+strlen(inv_out), NULL)); if (is_match(inv_out) != 0) { submsg++; inv_no--; continue; } } #endif match_flag = 0; if (for_n_mode) { if (inv_no < for_n_start || inv_no > for_n_end || ((inv_no - for_n_start) % for_n_step) != 0) { if (inv_no > for_n_end) last_message = 1; submsg++; continue; } } /* see if new GDS */ if ((i = GB2_Sec3_size(sec)) != old_GDS_size) { new_GDS = 1; } else { new_GDS = 0; for (j = 0; j < i; j++) { if (old_gds[j] != sec[3][j]) new_GDS = 1; } } if (new_GDS) { GDS_change_no++; if (i > GDS_max_size) { free(old_gds); GDS_max_size = i; if ((old_gds = (unsigned char *) malloc(GDS_max_size) ) == NULL) { fatal_error("memory allocation problem old_gds in wgrib2.main",""); } } for (j = 0; j < i; j++) { old_gds[j] = sec[3][j]; } old_GDS_size = i; /* update grid information */ get_nxny(sec, &nx, &ny, &npnts, &res, &scan); /* get nx, ny, and scan mode of grid */ output_order = (nx == -1 || ny == -1) ? raw : output_order_wanted; if (latlon) { i = 1; if (use_gctpc && output_order == wesn) { /* use gctpc to get lat lon values */ i = gctpc_get_latlon(sec, &lon, &lat); } if (i) get_latlon(sec, &lon, &lat); /* get lat lon of grid points */ } } /* Decode NDFD WxText */ if (WxText) mk_WxKeys(sec); // any fixes to raw grib message before decode need to be placed here if (fix_ncep_2_flag) fix_ncep_2(sec); if (fix_ncep_3_flag) fix_ncep_3(sec); if (fix_ncep_4_flag) fix_ncep_4(sec); #ifdef CHECK j = code_table_5_0(sec); // type of compression /* yes this can be simplified but want to split it up in case other decoders have problems */ if (j == 0 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib/grib-api simple decode may differ from WMO standard, use -g2clib 0 for WMO standard\n"); if ((j == 2 || j == 3) && int2(sec[5]+17) != 0 && int4(sec[5] + 31) == 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib complex decode may differ from WMO standard, use -g2clib 0 for WMO standard\n"); if (j == 40 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib jpeg deocde may differ from WMO standard, use use -g2clib 0 for WMO standard\n"); if (j == 41 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib/grib-api png decode may differ from WMO standard, use -g2clib 0 for WMO standard\n"); #endif #ifdef CHECK /* check the size of Section 7 */ /* code to check the other sizes needs to be placed in decode routines */ j = code_table_5_0(sec); // type of compression if (j == 0) { /* simple */ /* to avoid overflow on 32 bit machines */ /* old: k = (GB2_Sec5_nval(sec) * sec[5][19] + 7) / 8 + 5; */ k = 5 + (GB2_Sec5_nval(sec)/8) * sec[5][19] + (GB2_Sec5_nval(sec)%8) * (sec[5][19]/8) + ( (GB2_Sec5_nval(sec)%8) * (sec[5][19]%8) + 7) / 8; if (k != GB2_Sec7_size(sec)) { fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec)); if (decode) fatal_error("Section 7 size, mismatch, simple packing",""); } } else if (j == 4) { /* IEEE */ k = GB2_Sec5_nval(sec) * 4 + 5; if (k != GB2_Sec7_size(sec)) { fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec)); if (decode) fatal_error("Section 7 size, mismatch, IEEE packing",""); } } #endif if (decode) { #ifdef CHECK if (code_table_6_0(sec) == 0) { // has bitmap k = GB2_Sec3_npts(sec) - GB2_Sec5_nval(sec); if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec))) fatal_error_ii("inconsistent number of bitmap points sec3-sec5: %d sec6: %d", k, missing_points(sec[6]+6, GB2_Sec3_npts(sec))); } else if (code_table_6_0(sec) == 255) { // no bitmap if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec)) fatal_error_ii("inconsistent number of data points sec3: %d sec5: %d", GB2_Sec3_npts(sec), GB2_Sec5_nval(sec)); } #endif /* allocate data */ if (GB2_Sec3_npts(sec) != ndata) { if (ndata) free(data); ndata = GB2_Sec3_npts(sec); if (ndata) { data = (float *) malloc(ndata * sizeof(float)); if (data == NULL) fatal_error("main: memory allocation failed data",""); } else { data = NULL; } } j = code_table_5_0(sec); // type of compression gdt = code_table_3_1(sec); // grid type pdt = GB2_ProdDefTemplateNo(sec); // product defintion template /* USE G2CLIB */ #ifdef USE_G2CLIB if (use_g2clib == 2) { err = g2_getfld(msg,submsg,1,1,&grib_data); if (err != 0) fatal_error_ii("Fatal g2clib decode err=%d msg=%d", err, msg_no); free_gribfield = 1; has_bitmap = grib_data->ibmap; g2_data = &(grib_data->fld[0]); if (has_bitmap == 0 || has_bitmap == 254) { bitmap = grib_data->bmap; for (i = 0; i < ndata; i++) { data[i] = (bitmap[i] == 0) ? UNDEFINED : g2_data[i]; } } else { for (i = 0; i < ndata; i++) { data[i] = g2_data[i]; } } /* complex packing uses special values for undefined */ ii = sub_missing_values(sec, &missing_c_val_1, &missing_c_val_2); if (ii == 1) { for (i = 0; i < ndata; i++) { if (data[i] == missing_c_val_1) data[i] = UNDEFINED; } } else if (ii == 2) { for (i = 0; i < ndata; i++) { if (data[i] == missing_c_val_1) data[i] = UNDEFINED; if (data[i] == missing_c_val_2) data[i] = UNDEFINED; } } } #endif /* USE INTERNAL DECODER */ if (use_g2clib != 2) { center = GB2_Center(sec); if (use_g2clib == 1) { // introduce g2clib constant field error /* g2clib ignores decimal scaling for constant fields make internal decoders look like g2clib*/ if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) || (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19] == 0) || (center == NCEP && j == 40000 && sec[5][19] == 0) || (center == NCEP && j == 40010 && sec[5][19] == 0) ) { dscale[0] = sec[5][17]; dscale[1] = sec[5][18]; sec[5][17] = sec[5][18] = 0; } } err = unpk_grib(sec, data); if (err != 0) fatal_error_i("Fatal decode packing type %d",err); if (use_g2clib == 1) { // fix up data /* restore decimal scaling */ if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) || (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19]) || (center == NCEP && j == 40000 && sec[5][19] == 0) || (center == NCEP && j == 40010 && sec[5][19] == 0) ) { sec[5][17] = dscale[0]; sec[5][18] = dscale[1]; } } } /* convert to standard output order we:sn */ if (output_order_wanted == wesn) to_we_sn_scan(data); else if (output_order_wanted == wens) to_we_ns_scan(data); } else { if (ndata) free(data); ndata = 0; data = NULL; } /* get scaling parameters */ use_scale = scaling(sec, &ref, &dec_scale, &bin_scale, &i) == 0; if (num_submsgs > 1) { fprintf(inv_file, "%d.%d%s%ld", msg_no, submsg, ":", pos); } else { fprintf(inv_file, "%d%s%ld", msg_no, ":", pos); } for (j = 0; j < narglist; j++) { /* skip execution if match_flag == 1 */ /* an output option acts as endif for match_flag */ if (match_flag == 1) { if (functions[arglist[j].fn].type == output) match_flag = 0; continue; } // if (functions[arglist[j].fn].type == inv) fprintf(inv_file, item_deliminator); if (functions[arglist[j].fn].type == inv) fprintf(inv_file, "%s", item_deliminator); if (functions[arglist[j].fn].type != setup) { inv_out[0] = 0; n_arg = functions[arglist[j].fn].nargs; if (n_arg == 0) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j); else if (n_arg == 1) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc]); else if (n_arg == 2) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]); else if (n_arg == 3) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2]); else if (n_arg == 4) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]); else if (n_arg == 5) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4]); else if (n_arg == 6) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]); else if (n_arg == 7) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6]); else if (n_arg == 8) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]); if(inv_out[0] != 0) fprintf(inv_file, "%s", inv_out); } } #ifdef CHECK if (!decode) { if (code_table_6_0(sec) == 0) { // has bitmap k = GB2_Sec3_npts(sec) - GB2_Sec5_nval(sec); if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec))) fatal_error_ii("inconsistent number of bitmap points sec3-sec5: %d sec6: %d", k, missing_points(sec[6]+6, GB2_Sec3_npts(sec))); } else if (code_table_6_0(sec) == 255) { // no bitmap if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec)) fatal_error_ii("inconsistent number of data points sec3: %d sec5: %d", GB2_Sec3_npts(sec), GB2_Sec5_nval(sec)); } } #endif submsg++; #ifdef USE_G2CLIB if (free_gribfield) { g2_free(grib_data); free_gribfield = 0;} #endif // fprintf(inv_file, "\n"); fprintf(inv_file, "%s",end_inv); if (flush_mode) fflush(inv_file); if (dump_msg > 0) break; } /* finalize all functions, call with mode = -2 */ for (j = 0; j < narglist; j++) { if (functions[arglist[j].fn].type != setup) { n_arg = functions[arglist[j].fn].nargs; inv_out[0] = 0; if (n_arg == 0) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j); else if (n_arg == 1) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc]); else if (n_arg == 2) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]); else if (n_arg == 3) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2]); else if (n_arg == 4) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]); else if (n_arg == 5) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4]); else if (n_arg == 6) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]); else if (n_arg == 7) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6]); else if (n_arg == 8) functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]); // if (inv_out[0]) fprintf(stderr, "%s\n", inv_out); if (inv_out[0]) fprintf(stderr, "%s%s", inv_out, end_inv); } } eof_bin(); eof_string(); exit(0); }
/* * Actually read the savefile * */ static errr rd_savefile_new_aux(player_type *p_ptr) { int i; u16b tmp16u; u32b tmp32u; bool clear = FALSE; bool had_header = FALSE; char stat_order_hack[6]; start_section_read("mangband_player_save"); start_section_read("version"); read_int("major"); read_int("minor"); read_int("patch"); end_section_read("version"); if (section_exists("header")) { start_section_read("header"); had_header = TRUE; read_str("playername",p_ptr->name); /* 32 */ skip_value("pass"); p_ptr->prace = read_int("prace"); p_ptr->pclass = read_int("pclass"); p_ptr->male = read_int("male"); read_binary("stat_order", stat_order_hack, 6); for (i = 0; i < 6; i++) p_ptr->stat_order[i] = stat_order_hack[i]; end_section_read("header"); } /* Operating system info */ sf_xtra = read_uint("sf_xtra"); /* Time of savefile creation */ sf_when = read_uint("sf_when"); /* Number of resurrections */ sf_lives = read_int("sf_lives"); /* Number of times played */ sf_saves = read_int("sf_saves"); /* Skip the turn info - if present */ skip_value("turn"); /* Turn this character was born on */ if(value_exists("birth_turn")) read_hturn("birth_turn", &p_ptr->birth_turn); else /* Disable character event logging if no birth turn */ ht_clr(&p_ptr->birth_turn); /* Player turns (actually time spent playing) */ if(value_exists("player_turn")) read_hturn("player_turn", &p_ptr->turn); else ht_clr(&p_ptr->turn); /* Read birth options */ if (rd_birthoptions(p_ptr)) { return (28); } /* Monster Memory */ if (section_exists("monster_lore")) { start_section_read("monster_lore"); tmp16u = read_int("max_r_idx"); /* Incompatible save files */ if (tmp16u > z_info->r_max) { note(format("Too many (%u) monster races!", tmp16u)); return (21); } /* Read the available records */ for (i = 0; i < tmp16u; i++) { /* Read the lore */ rd_lore(p_ptr, i); } end_section_read("monster_lore"); } /* Object Memory */ start_section_read("object_memory"); tmp16u = read_int("max_k_idx"); /* Incompatible save files */ if (tmp16u > z_info->k_max) { note(format("Too many (%u) object kinds!", tmp16u)); return (22); } /* Read the object memory */ for (i = 0; i < tmp16u; i++) { byte tmp8u; tmp8u = read_int("flags"); p_ptr->obj_aware[i] = (tmp8u & 0x01) ? TRUE : FALSE; p_ptr->obj_tried[i] = (tmp8u & 0x02) ? TRUE : FALSE; } end_section_read("object_memory"); /*if (arg_fiddle) note("Loaded Object Memory");*/ /* Read the extra stuff */ rd_extra(p_ptr, had_header); /*if (arg_fiddle) note("Loaded extra information");*/ /* Read the player_hp array */ start_section_read("hp"); tmp16u = read_int("py_max_level"); /* Read the player_hp array */ for (i = 0; i < tmp16u; i++) { p_ptr->player_hp[i] = read_int("hp"); } end_section_read("hp"); /* Important -- Initialize the race/class */ p_ptr->rp_ptr = &p_info[p_ptr->prace]; p_ptr->cp_ptr = &c_info[p_ptr->pclass]; /* Important -- Choose the magic info */ p_ptr->mp_ptr = &c_info[p_ptr->pclass].spells; /* Read spell info */ if (section_exists("spell_flags")) { start_section_read("spell_flags"); for (i = 0; i < PY_MAX_SPELLS; i++) { p_ptr->spell_flags[i] = read_int("flag"); } end_section_read("spell_flags"); } else { /* Port spell flags from old format */ u32b spell_learned1, spell_learned2; u32b spell_worked1, spell_worked2; u32b spell_forgotten1, spell_forgotten2; spell_learned1 = read_uint("spell_learned1"); spell_learned2 = read_uint("spell_learned2"); spell_worked1 = read_uint("spell_worked1"); spell_worked2 = read_uint("spell_worked2"); spell_forgotten1 = read_uint("spell_forgotten1"); spell_forgotten2 = read_uint("spell_forgotten2"); for (i = 0; i < PY_MAX_SPELLS; i++) { if ((i < 32) ? (spell_forgotten1 & (1L << i)) : (spell_forgotten2 & (1L << (i - 32)))) { p_ptr->spell_flags[i] |= PY_SPELL_FORGOTTEN; } if ((i < 32) ? (spell_learned1 & (1L << i)) : (spell_learned2 & (1L << (i - 32)))) { p_ptr->spell_flags[i] |= PY_SPELL_LEARNED; } if ((i < 32) ? (spell_worked1 & (1L << i)) : (spell_worked2 & (1L << (i - 32)))) { p_ptr->spell_flags[i] |= PY_SPELL_WORKED; } } } start_section_read("spell_order"); for (i = 0; i < PY_MAX_SPELLS; i++) { p_ptr->spell_order[i] = read_int("order"); } end_section_read("spell_order"); /* Read the inventory */ if (rd_inventory(p_ptr)) { /*note("Unable to read inventory");*/ return (21); } /* Read hostility information if new enough */ if (rd_hostilities(p_ptr)) { return (22); } rd_cave_memory(p_ptr); /* read the wilderness map */ start_section_read("wilderness"); /* get the map size */ tmp32u = read_int("max_wild"); /* if too many map entries */ if (tmp32u > MAX_WILD) { return 23; } /* read in the map */ for (i = 0; i < tmp32u; i++) { p_ptr->wild_map[i] = read_int("wild_map"); } end_section_read("wilderness"); /* Read the character event history */ if(section_exists("event_history")) { char buf[160]; cptr msg; history_event evt; history_event *last = NULL; start_section_read("event_history"); while(value_exists("hist")) { int depth, level; history_event *n_evt = NULL; read_str("hist", buf); if (sscanf(buf, "%02i:%02i:%02i %4ift %2i ", &evt.days, &evt.hours, &evt.mins, &depth, &level) == 5) { msg = &buf[25];/* skip 25 characters ^ */ evt.depth = depth / 50; evt.message = quark_add(msg); } /* Allocate */ MAKE(n_evt, history_event); n_evt->days = evt.days; n_evt->hours = evt.hours; n_evt->mins = evt.mins; n_evt->depth = evt.depth; n_evt->level = level; n_evt->message = evt.message; /* Add to chain */ if (!last) { p_ptr->charhist = n_evt; last = n_evt; } else { last->next = n_evt; last = n_evt; } } end_section_read("event_history"); } /* Read the characters quest list */ if(section_exists("quests")) { start_section_read("quests"); tmp16u = read_int("max_q_idx"); for(i = 0; i < MAX_Q_IDX; i++) { tmp16u = read_int("level"); p_ptr->q_list[i].level = tmp16u; } end_section_read("quests"); } /* Read the characters sold artifact list */ if(section_exists("found_artifacts")) { start_section_read("found_artifacts"); tmp16u = read_int("max_a_idx"); tmp32u = tmp16u; /* If we have an unexpected number of arts, just reset our list * of sold artifacts. It's not so important we want to break * save file compatability for it. */ if( tmp16u != z_info->a_max ) { clear = TRUE; tmp16u = 0; } for(i = 0; i < z_info->a_max; i++) { if(i < tmp32u) { if(!clear) tmp16u = read_int("a_info"); } p_ptr->a_info[i] = tmp16u; } end_section_read("found_artifacts"); } /* Hack -- no ghosts */ /* r_info[z_info->r_max - 1].max_num = 0; */ end_section_read("mangband_player_save"); /* Success */ return (0); }
int main(int argc, char **argv) { #else int wgrib2(int argc, const char **argv) { #endif //WNE FILE *in; struct seq_file in_file; unsigned char *msg, *sec[10]; /* sec[9] = last valid bitmap */ long int last_pos; int file_arg, i, j, num_submsgs; int n_arg; unsigned int k, ndata; int err_4_3_count; float *data; double ref; // double *ddata, ref; #ifdef USE_G2CLIB float missing_c_val_1, missing_c_val_2; g2int *bitmap, has_bitmap; g2float *g2_data; int ii; #endif struct ARGLIST arglist[N_ARGLIST]; int narglist; const char *new_argv[N_ARGLIST]; void *local[N_ARGLIST]; int has_inv_option, last_submsg; int err, new_GDS, center; unsigned char dscale[2]; init_globals(); init_inv_out(); ndata = 0; err_4_3_count = 0; if (initial_call) { /* only done 1st time */ setup_user_gribtable(); // jas_init(); // gctpc initialiation init(-1,-1,"gctpc_error,txt", "gctpc_param.txt"); initial_call = 0; } narglist = 0; dscale[0] = dscale[1] = 0; mode = 0; if (fopen_file(&(rd_inventory_input), "-", "r")) fatal_error("opening stdin for rd_inventory",""); data = NULL; // ddata = NULL; #ifdef CALLABLE_WGRIB2 if (setjmp(fatal_err)) { fprintf(stderr,"*** arg list to wgrib2:"); for (i=0; i < argc; i++) { fprintf(stderr," %s", argv[i]); } fprintf(stderr,"\n\n"); if (ndata && data != NULL) free(data); ndata=0; return 1; } #endif /* no arguments .. help screen */ if (argc == 1) { mode = -1; inv_out[0] = 0; f_h(call_ARG0(inv_out,NULL)); // fprintf(inv_file, "%s\n", inv_out); i = strlen(inv_out); inv_out[i++] = '\n'; inv_out[i] = '\0'; fwrite_file(inv_out, 1, i, &inv_file); err_bin(1); err_string(1); return 8; } /* copy argv */ for (i = 0; i < argc; i++) { new_argv[i] = argv[i]; } /* scan for "inv" and input file */ has_inv_option = 0; file_arg = 0; for (i = 1; i < argc; i++) { if (new_argv[i][0] != '-' || (strcmp(new_argv[i],"-") == 0) ) { /* must be filename */ if (file_arg == 0) { file_arg = i; continue; } else { fatal_error_ss("too many grib files .. 1st=%s 2nd=%s", new_argv[file_arg], new_argv[i]); } } /* must be an option */ for (j = 0; j < nfunctions; j++) { if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) { if (functions[j].type == inv) has_inv_option = 1; i += functions[j].nargs; break; } } if (j == nfunctions) { fatal_error("undefined option: %s", new_argv[i]); } } /* if no inv option, use default inventory .. put it at end */ if (has_inv_option == 0) new_argv[argc++] = "-s"; /* try opening the input file */ in_file.file_type = NOT_OPEN; if (file_arg != 0) { fopen_file(&in_file, new_argv[file_arg],"rb"); } /* "compile" options */ #ifdef DEBUG fprintf(stderr,"going to compile phase\n"); #endif for (i = 1; i < argc; i++) { /* if filename skip */ if (new_argv[i][0] != '-' || (strcmp(new_argv[i],"-") == 0)) continue; /* must be an option */ for (j = 0; j < nfunctions; j++) { if (strcmp(&(new_argv[i][1]),functions[j].name) == 0) break; } if (j == nfunctions) fatal_error("unknown option %s", new_argv[i]); /* add to function argument list */ arglist[narglist].fn = j; arglist[narglist].i_argc = i+1; if (functions[j].type == inv) has_inv_option = 1; i += functions[j].nargs; if (i >= argc) fatal_error("missing arguments option=%s",functions[j].name); narglist++; } if (has_inv_option == 0) fatal_error("missing arguments on last option",""); /* initialize options, mode = -1 */ #ifdef DEBUG fprintf(stderr,"going to init options, narglist %d\n",narglist); #endif for (j = 0; j < narglist; j++) { new_inv_out(); /* inv_out[0] = 0; */ n_arg = functions[arglist[j].fn].nargs; err = 0; #ifdef DEBUG fprintf(stderr,"going to init option %s\n", functions[arglist[j].fn].name); #endif if (n_arg == 0) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j); else if (n_arg == 1) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc]); else if (n_arg == 2) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1]); else if (n_arg == 3) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1],new_argv[arglist[j].i_argc+2]); else if (n_arg == 4) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]); else if (n_arg == 5) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4]); else if (n_arg == 6) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]); else if (n_arg == 7) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6]); else if (n_arg == 8) err = functions[arglist[j].fn].fn(-1,NULL,NULL,0, inv_out,local+j, new_argv[arglist[j].i_argc],new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]); // if(inv_out[0] != 0) fprintf(inv_file, "%s", inv_out); if(inv_out[0] != 0) fwrite_file(inv_out, 1, strnlen(inv_out,INV_BUFFER), &inv_file); if (err) { err_bin(1); err_string(1); // cleanup return 8; } } /* error and EOF handlers have been initialized */ #ifdef DEBUG fprintf(stderr,"initial error and EOF handlers\n"); #endif if (has_inv_option == 0) fatal_error("missing arguments on last option",""); if (in_file.file_type == NOT_OPEN) { if (file_arg == 0) fatal_error("no input file defined",""); else fatal_error("missing input file %s", new_argv[file_arg]); } if (latlon == 1 && output_order_wanted != wesn) fatal_error("latitude-longitude information is only available with -order we:sn",""); if (input == inv_mode && (in_file.file_type != DISK && in_file.file_type != MEM)) fatal_error("wgrib2 cannot random access grib input file",""); #ifdef DEBUG fprintf(stderr,"going to process data\n"); #endif msg_no = 1; inv_no = 0; len = pos = 0; submsg = 0; msg = NULL; last_pos = -1; last_submsg = -1; /* if dump mode .. position io stream */ if (input == dump_mode) { while (msg_no < dump_msg) { // // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs); // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); // else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs); msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); if (msg == NULL) fatal_error_i("record %d not found", dump_msg); last_pos = pos; pos += len; msg_no++; } #ifdef DEBUG printf("dump mode msg=%d\n", msg_no); #endif } /* * submsg = 0 .. beginning of unread record * submsg = i .. start at ith submsg * num_submsgs = number of submessages in grib message */ /* inventory loop */ for (;last_message == 0;) { /* need position and submessage number of message */ if (input == inv_mode || input == dump_mode) { if (input == inv_mode) { if (rd_inventory(&msg_no,&submsg, &pos, &rd_inventory_input)) break; if (fseek_file(&in_file, pos,SEEK_SET) != 0) fatal_error("fseek_file failed",""); } else if (input == dump_mode) { if (dump_msg == -1) break; submsg = dump_submsg; dump_msg = -1; } if (pos != last_pos) { // // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs); // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); // else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs); msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); if (msg == NULL) { fatal_error_i("grib message #%d not found", msg_no); break; } last_pos = pos; last_submsg = -1; } if (pos == last_pos && submsg == last_submsg + 1) { /* read previous submessage */ if (parse_next_msg(sec) != 0) { fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, submsg); break; } } else { /* need to get desired submessage into sec */ if (parse_1st_msg(sec) != 0) { fprintf(stderr,"\n*** grib message #%d.1 not found ***\n\n", msg_no); break; } for (i = 2; i <= submsg; i++) { if (parse_next_msg(sec) != 0) { fprintf(stderr,"\n*** grib message #%d.%d not found ***\n\n", msg_no, i); break; } } } last_submsg = submsg; } else if (input == all_mode) { if (submsg == 0) { // // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs); // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); // else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs); msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); if (msg == NULL) break; submsg = 1; } else if (submsg > num_submsgs) { pos += len; msg_no++; // // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq(sec, in, &pos, &len, &num_submsgs); // if (in_file.file_type == PIPE) msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); // else if (in_file.file_type == DISK) msg = rd_grib2_msg(sec, in, &pos, &len, &num_submsgs); msg = rd_grib2_msg_seq_file(sec, &in_file, &pos, &len, &num_submsgs); if (msg == NULL) break; submsg = 1; } if (submsg == 1) { if (parse_1st_msg(sec) != 0) { fprintf(stderr,"illegal format: parsing 1st submessage\n"); } } else { if (parse_next_msg(sec) != 0) { fprintf(stderr,"illegal format: parsing submessages\n"); } } } if (only_submsg > 0 && only_submsg != submsg) { submsg++; continue; } if (for_mode) { if (msg_no < for_start || msg_no > for_end || ((msg_no - for_start) % for_step) != 0) { if (msg_no > for_end && input != inv_mode) last_message = 1; submsg++; continue; } } /* move inv_no++ before match_inv is made */ inv_no++; if (match || match_fs) { inv_out[0] = 0; if (num_submsgs > 1) { sprintf(inv_out,"%d.%d:", msg_no, submsg); } else { sprintf(inv_out,"%d:", msg_no); } f_match_inv(call_ARG0(inv_out+strlen(inv_out), NULL)); if (is_match_fs(inv_out) != 0) { submsg++; inv_no--; continue; } #ifdef USE_REGEX if (is_match(inv_out) != 0) { submsg++; inv_no--; continue; } #endif } match_flag = 0; if (for_n_mode) { if (inv_no < for_n_start || inv_no > for_n_end || ((inv_no - for_n_start) % for_n_step) != 0) { if (inv_no > for_n_end) last_message = 1; submsg++; continue; } } /* see if new GDS */ if ((i = (int) GB2_Sec3_size(sec)) != old_GDS_size) { new_GDS = 1; } else { new_GDS = 0; for (j = 0; j < i; j++) { if (old_gds[j] != sec[3][j]) new_GDS = 1; } } if (new_GDS) { GDS_change_no++; if (i > GDS_max_size) { if (GDS_max_size) free(old_gds); GDS_max_size = i + 100; /* add 100 just to avoid excessive memory allocations */ if ((old_gds = (unsigned char *) malloc(GDS_max_size) ) == NULL) { fatal_error("memory allocation problem old_gds in wgrib2.main",""); } } for (j = 0; j < i; j++) { old_gds[j] = sec[3][j]; } old_GDS_size = i; /* update grid information */ get_nxny(sec, &nx, &ny, &npnts, &res, &scan); /* get nx, ny, and scan mode of grid */ get_nxny_(sec, &nx_, &ny_, &npnts, &res, &scan); /* get nx, ny, and scan mode of grid */ output_order = (nx_ < 1 || ny_ < 1) ? raw : output_order_wanted; if (latlon) { i = 1; #ifdef USE_PROJ4 if (use_proj4 && i != 0) { /* use Proj4 to get lat lon values */ i = proj4_get_latlon(sec, &lon, &lat); // if (i == 0) fprintf(stderr,"proj4_get_lat used\n"); } #endif if (use_gctpc && i != 0) { /* use gctpc to get lat lon values */ i = gctpc_get_latlon(sec, &lon, &lat); // if (i == 0) fprintf(stderr,"gctpc_get_lat used\n"); } if (i != 0) get_latlon(sec, &lon, &lat); /* get lat lon of grid points using built-in code */ } } /* Decode NDFD WxText */ if (WxText) mk_WxKeys(sec); // any fixes to raw grib message before decode need to be placed here if (fix_ncep_2_flag) fix_ncep_2(sec); if (fix_ncep_3_flag) fix_ncep_3(sec); if (fix_ncep_4_flag) fix_ncep_4(sec); #ifdef CHECK j = code_table_5_0(sec); // type of compression /* yes this can be simplified but want to split it up in case other decoders have problems */ if (j == 0 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib/grib-api simple encode/decode may differ from WMO standard, use -g2clib 0 for WMO standard\n"); if ((j == 2 || j == 3) && int2(sec[5]+17) != 0 && int4(sec[5] + 31) == 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib complex encode/decode may differ from WMO standard, use -g2clib 0 for WMO standard\n"); if (j == 40 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib jpeg encode/deocde may differ from WMO standard, use -g2clib 0 for WMO standard\n"); if (j == 41 && sec[5][19] == 0 && int2(sec[5] + 17) != 0 && ieee2flt(sec[5]+11) != 0.0) fprintf(stderr,"Warning: g2lib/g2clib/grib-api png encode/decode may differ from WMO standard, use -g2clib 0 for WMO standard\n"); /* check the size of Section 7 */ /* code to check the other sizes needs to be placed in decode routines */ j = code_table_5_0(sec); // type of compression if (j == 0) { /* simple */ /* to avoid overflow on 32 bit machines */ /* old: k = (GB2_Sec5_nval(sec) * sec[5][19] + 7) / 8 + 5; */ k = 5 + (GB2_Sec5_nval(sec)/8) * sec[5][19] + (GB2_Sec5_nval(sec)%8) * (sec[5][19]/8) + ( (GB2_Sec5_nval(sec)%8) * (sec[5][19]%8) + 7) / 8; if (k != GB2_Sec7_size(sec)) { fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec)); if (decode) fatal_error("Section 7 size, mismatch, simple packing",""); } } else if (j == 4) { /* IEEE */ k = GB2_Sec5_nval(sec) * 4 + 5; if (k != GB2_Sec7_size(sec)) { fprintf(stderr,"Detected a size mismatch, Section 7, wanted %d found %d\n", k, GB2_Sec7_size(sec)); if (decode) fatal_error("Section 7 size, mismatch, IEEE packing",""); } } /* code table 4.3 can change units, warn if undefined */ if (err_4_3_count < 2) { if (code_table_4_3(sec) == 255) { fprintf(stderr,"** WARNING input Code Table 4.3 = 255 (undefined) **\n"); err_4_3_count++; } } #endif if (decode) { #ifdef CHECK if (code_table_6_0(sec) == 0) { // has bitmap k = GB2_Sec3_npts(sec) - GB2_Sec5_nval(sec); if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec))) fatal_error_uu("inconsistent number of bitmap points sec3-sec5: %u sec6: %u", k, missing_points(sec[6]+6, GB2_Sec3_npts(sec))); } else if (code_table_6_0(sec) == 255) { // no bitmap if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec)) fatal_error_uu("inconsistent number of data points sec3: %u sec5: %u", GB2_Sec3_npts(sec), GB2_Sec5_nval(sec)); } #endif /* allocate data */ if (GB2_Sec3_npts(sec) != ndata) { if (ndata) free(data); ndata = GB2_Sec3_npts(sec); if (ndata) { data = (float *) malloc(sizeof(float) * (size_t) ndata); if (data == NULL) { ndata = 0; fatal_error("main: memory allocation failed data",""); } } else { data = NULL; } } j = code_table_5_0(sec); // type of compression /* USE G2CLIB */ #ifdef USE_G2CLIB if (use_g2clib == 2) { err = g2_getfld(msg,submsg,1,1,&grib_data); if (err != 0) fatal_error_ii("Fatal g2clib decode err=%d msg=%d", err, msg_no); free_gribfield = 1; has_bitmap = grib_data->ibmap; g2_data = &(grib_data->fld[0]); if (has_bitmap == 0 || has_bitmap == 254) { bitmap = grib_data->bmap; for (k = 0; k < ndata; k++) { data[k] = (bitmap[k] == 0) ? UNDEFINED : g2_data[k]; } } else { for (k = 0; k < ndata; k++) { data[k] = g2_data[k]; } } /* complex packing uses special values for undefined */ ii = sub_missing_values(sec, &missing_c_val_1, &missing_c_val_2); if (ii == 1) { for (k = 0; k < ndata; k++) { if (data[k] == missing_c_val_1) data[k] = UNDEFINED; } } else if (ii == 2) { for (k = 0; k < ndata; k++) { if (data[k] == missing_c_val_1) data[k] = UNDEFINED; if (data[k] == missing_c_val_2) data[k] = UNDEFINED; } } } #endif /* USE INTERNAL DECODER */ if (use_g2clib != 2) { center = GB2_Center(sec); if (use_g2clib == 1) { // introduce g2clib constant field error /* g2clib ignores decimal scaling for constant fields make internal decoders look like g2clib*/ if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) || (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19] == 0) || (center == NCEP && j == 40000 && sec[5][19] == 0) || (center == NCEP && j == 40010 && sec[5][19] == 0) ) { dscale[0] = sec[5][17]; dscale[1] = sec[5][18]; sec[5][17] = sec[5][18] = 0; } } err = unpk_grib(sec, data); if (err != 0) fatal_error_i("Fatal decode packing type %d",err); if (use_g2clib == 1) { // fix up data /* restore decimal scaling */ if ( (j == 0 && sec[5][19] == 0) || ((j == 2 || j == 3) && int4(sec[5] + 31) == 0) || (j == 40 && sec[5][19] == 0) || (j == 41 && sec[5][19]) || (center == NCEP && j == 40000 && sec[5][19] == 0) || (center == NCEP && j == 40010 && sec[5][19] == 0) ) { sec[5][17] = dscale[0]; sec[5][18] = dscale[1]; } } } /* convert to standard output order we:sn */ if (output_order_wanted == wesn) to_we_sn_scan(data, scan, npnts, nx, ny, save_translation); else if (output_order_wanted == wens) to_we_ns_scan(data, scan, npnts, nx, ny, save_translation); } else { if (ndata) free(data); ndata = 0; data = NULL; } /* get scaling parameters */ use_scale = input_scale = scaling(sec, &ref, &dec_scale, &bin_scale, &i) == 0; /* make sure msg_no:pos is put in inv_out so that -last will work */ new_inv_out(); // inv_out[0] = 0; if (num_submsgs > 1) { sprintf(inv_out, "%d.%d%s%ld", msg_no, submsg, ":", pos); } else { sprintf(inv_out, "%d%s%ld", msg_no, ":", pos); } // fprintf(inv_file, "%s", inv_out); fwrite_file(inv_out, 1, strnlen(inv_out,INV_BUFFER), &inv_file); for (j = 0; j < narglist; j++) { /* skip execution if match_flag == 1 */ /* an output option acts as endif for match_flag */ if (match_flag == 1) { if (functions[arglist[j].fn].type == output) match_flag = 0; continue; } // if (functions[arglist[j].fn].type == inv) fprintf(inv_file, "%s", item_deliminator); if (functions[arglist[j].fn].type == inv) fwrite_file(item_deliminator, 1, strlen(item_deliminator), &inv_file); if (functions[arglist[j].fn].type != setup) { new_inv_out(); // inv_out[0] = 0; n_arg = functions[arglist[j].fn].nargs; if (n_arg == 0) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j); else if (n_arg == 1) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc]); else if (n_arg == 2) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]); else if (n_arg == 3) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2]); else if (n_arg == 4) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]); else if (n_arg == 5) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4]); else if (n_arg == 6) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]); else if (n_arg == 7) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6]); else if (n_arg == 8) functions[arglist[j].fn].fn(mode, sec, data, ndata, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]); // if(inv_out[0] != 0) fprintf(inv_file, "%s", inv_out); if(inv_out[0] != 0) fwrite_file(inv_out, 1, strnlen(inv_out,INV_BUFFER), &inv_file); } } #ifdef CHECK if (!decode) { if (code_table_6_0(sec) == 0) { // has bitmap k = GB2_Sec3_npts(sec) - GB2_Sec5_nval(sec); if (k != missing_points(sec[6]+6, GB2_Sec3_npts(sec))) fatal_error_uu("inconsistent number of bitmap points sec3-sec5: %u sec6: %u", k, missing_points(sec[6]+6, GB2_Sec3_npts(sec))); } else if (code_table_6_0(sec) == 255) { // no bitmap if (GB2_Sec3_npts(sec) != GB2_Sec5_nval(sec)) fatal_error_ii("inconsistent number of data points sec3: %d sec5: %d", (int) GB2_Sec3_npts(sec), (int) GB2_Sec5_nval(sec)); } } #endif submsg++; #ifdef USE_G2CLIB if (free_gribfield) { g2_free(grib_data); free_gribfield = 0;} #endif // fprintf(inv_file, "%s",end_inv); fwrite_file(end_inv, 1, strlen(end_inv), &inv_file); if (flush_mode) fflush_file(&inv_file); if (dump_msg > 0) break; } /* finalize all functions, call with mode = -2 */ err = 0; for (j = 0; j < narglist; j++) { // if (functions[arglist[j].fn].type != setup) { n_arg = functions[arglist[j].fn].nargs; new_inv_out(); // inv_out[0] = 0; if (n_arg == 0) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j); else if (n_arg == 1) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc]); else if (n_arg == 2) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1]); else if (n_arg == 3) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2]); else if (n_arg == 4) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3]); else if (n_arg == 5) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4]); else if (n_arg == 6) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5]); else if (n_arg == 7) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6]); else if (n_arg == 8) err |= functions[arglist[j].fn].fn(-2, NULL, NULL, 0, inv_out, local+j, new_argv[arglist[j].i_argc], new_argv[arglist[j].i_argc+1], new_argv[arglist[j].i_argc+2], new_argv[arglist[j].i_argc+3], new_argv[arglist[j].i_argc+4], new_argv[arglist[j].i_argc+5], new_argv[arglist[j].i_argc+6], new_argv[arglist[j].i_argc+7]); // if (inv_out[0]) fprintf(stderr, "%s\n", inv_out); if (inv_out[0]) fprintf(stderr, "%s%s", inv_out, end_inv); // } } err_bin(0); err_string(0); fclose_file(&in_file); if (ndata) { ndata = 0; free(data); } // return 0; return err; } void set_mode(int new_mode) { mode = new_mode; }