int Android_VideoInit(_THIS) { SDL_DisplayMode mode; posix_print("Android_VideoInit------(%ix%i)\n", Android_ScreenWidth, Android_ScreenHeight); mode.format = Android_ScreenFormat; mode.w = Android_ScreenWidth; mode.h = Android_ScreenHeight; mode.refresh_rate = Android_ScreenRate; mode.driverdata = NULL; if (SDL_AddBasicVideoDisplay(&mode) < 0) { return -1; } SDL_AddDisplayMode(&_this->displays[0], &mode); posix_print("after SDL_AddDisplayMode(%ix%i)\n", mode.w, mode.h); Android_InitKeyboard(); Android_InitTouch(); Android_InitMouse(); /* We're done! */ return 0; }
void playsingle_controller::init_gui() { uint32_t start = SDL_GetTicks(); LOG_NG << "Initializing GUI... " << (SDL_GetTicks() - ticks_) << "\n"; play_controller::init_gui(); uint32_t end_parent_init_gui = SDL_GetTicks(); posix_print("playsingle_controller::init_gui, play_controller::init_gui(), used time: %u ms\n", end_parent_init_gui - start); if (human_team_ != -1) { gui_->scroll_to_tile(map_.starting_position(human_team_ + 1), game_display::WARP); } gui_->scroll_to_tile(map_.starting_position(1), game_display::WARP); if (tent::mode != TOWER_MODE) { gui_->set_current_list_type(game_display::taccess_list::TROOP); } else { gui_->set_current_list_type(game_display::taccess_list::HERO); } uint32_t end_scroll_to_tile = SDL_GetTicks(); posix_print("playsingle_controller::init_gui, scroll_to_tile, used time: %u ms\n", end_scroll_to_tile - end_parent_init_gui); update_locker lock_display(gui_->video(),recorder.is_skipping()); events::raise_draw_event(); gui_->draw(); for(std::vector<team>::iterator t = teams_.begin(); t != teams_.end(); ++t) { ::clear_shroud(t - teams_.begin() + 1); } uint32_t end_draw = SDL_GetTicks(); posix_print("playsingle_controller::init_gui, gui_->draw, used time: %u ms\n", end_draw - end_scroll_to_tile); }
// config就三个成员变量, values, children, orderer_children. orderer_child_ren可由children推出 // config被组织成一个树状结构 void wml_config_to_file(const std::string &fname, config &cfg, uint32_t nfiles, uint32_t sum_size, uint32_t modified) { posix_file_t fp = INVALID_FILE; uint32_t max_str_len, bytertd, u32n; std::vector<std::string> tdomain; posix_print("<xwml.cpp>::wml_config_to_file------fname: %s\n", fname.c_str()); posix_fopen(fname.c_str(), GENERIC_WRITE, CREATE_ALWAYS, fp); if (fp == INVALID_FILE) { posix_print("------<xwml.cpp>::wml_config_to_file, cannot create %s for wrtie\n", fname.c_str()); goto exit; } // max_str_len = posix_max(WMLBIN_MARK_CONFIG_LEN, WMLBIN_MARK_VALUE_LEN); posix_fseek(fp, 16 + sizeof(max_str_len) + sizeof(u32n), 0); // write [textdomain] BOOST_FOREACH (const config &d, cfg.child_range("textdomain")) { if (std::find(tdomain.begin(), tdomain.end(), d.get("name")->str()) != tdomain.end()) { continue; } tdomain.push_back(d.get("name")->str()); u32n = tdomain.back().size(); posix_fwrite(fp, &u32n, sizeof(u32n), bytertd); posix_fwrite(fp, tdomain.back().c_str(), u32n, bytertd); } wml_config_to_fp(fp, cfg, &max_str_len, tdomain, 0); // update max_str_len/textdomain_count posix_fseek(fp, 0, 0); // 0--15 u32n = mmioFOURCC('X', 'W', 'M', 'L'); posix_fwrite(fp, &u32n, 4, bytertd); posix_fwrite(fp, &nfiles, 4, bytertd); posix_fwrite(fp, &sum_size, 4, bytertd); posix_fwrite(fp, &modified, 4, bytertd); // 16--19(max_str_len) posix_fwrite(fp, &max_str_len, sizeof(max_str_len), bytertd); // 20--23(textdomain_count) u32n = tdomain.size(); posix_fwrite(fp, &u32n, sizeof(u32n), bytertd); posix_print("------<xwml.cpp>::wml_config_to_file, return\n"); exit: if (fp != INVALID_FILE) { posix_fclose(fp); } return; }
void playsingle_controller::init_gui() { uint32_t start = SDL_GetTicks(); LOG_NG << "Initializing GUI... " << (SDL_GetTicks() - ticks_) << "\n"; play_controller::init_gui(); uint32_t end_parent_init_gui = SDL_GetTicks(); posix_print("playsingle_controller::init_gui, play_controller::init_gui(), used time: %u ms\n", end_parent_init_gui - start); if (human_team_ != -1) { gui_->scroll_to_tile(map_.starting_position(human_team_ + 1), game_display::WARP); } gui_->scroll_to_tile(map_.starting_position(1), game_display::WARP); if (tent::mode == mode_tag::TOWER || tent::mode == mode_tag::LAYOUT) { gui_->set_current_list_type(game_display::taccess_list::HERO); } else { gui_->set_current_list_type(game_display::taccess_list::TROOP); } { int ii = 0; // gui_->set_current_list_type(game_display::taccess_list::TROOP); } uint32_t end_scroll_to_tile = SDL_GetTicks(); posix_print("playsingle_controller::init_gui, scroll_to_tile, used time: %u ms\n", end_scroll_to_tile - end_parent_init_gui); update_locker lock_display(gui_->video(),recorder.is_skipping()); events::raise_draw_event(); gui_->draw(); for(std::vector<team>::iterator t = teams_.begin(); t != teams_.end(); ++t) { ::clear_shroud(t - teams_.begin() + 1); } gui_->refresh_access_troops(human_team_, game_display::REFRESH_RELOAD); uint32_t end_draw = SDL_GetTicks(); posix_print("playsingle_controller::init_gui, gui_->draw, used time: %u ms\n", end_draw - end_scroll_to_tile); if (tent::mode == mode_tag::SIEGE) { refresh_endturn_button(*gui_, "buttons/ctrl-pause2.png"); gui_->set_theme_object_active("endturn", true); teams_[human_team_].set_objectives_changed(false); } if (lobby->chat.ready()) { refresh_chat_button(*gui_, "misc/network-disconnected.png"); } tlobby::thandler::join(); }
playsingle_controller::~playsingle_controller() { posix_print("playsingle_controller::~playsingle_controller()\n"); ai::manager::remove_observer(this) ; ai::manager::clear_ais() ; }
static jboolean nativeFillAudio(JNIEnv* env, jarray buffer, SDL_bool is16Bit) { SDL_AudioDevice* this = audioDevice; if (!require_xmit) { return JNI_FALSE; } // here, I want to reduce copy, but fail! Hope someone can do it. // jboolean isCopy = JNI_FALSE; // void* bufferPinned = (*env)->GetShortArrayElements(env, buffer, &isCopy); void* bufferPinned; int length; if (is16Bit) { bufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)buffer, NULL); length = (*env)->GetArrayLength(env, (jshortArray)buffer) * 2; } else { bufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)buffer, NULL); length = (*env)->GetArrayLength(env, (jbyteArray)buffer); } /* Only do anything if audio is enabled and not paused */ if (this->enabled && !this->paused) { static Uint32 last_ticks = 0; Uint32 now_ticks = SDL_GetTicks(); if (now_ticks - last_ticks >= 5000) { posix_print("nativeFillAudio, 1, bufferPinned: %p, length: %i, enabled: %s, paused: %s\n", bufferPinned, length, this->enabled? "true": "false", this->paused? "true": "false"); last_ticks = now_ticks; } // Generate the data SDL_LockMutex(this->mixer_lock); (*this->spec.callback)(this->spec.userdata, bufferPinned, length); SDL_UnlockMutex(this->mixer_lock); } else { posix_print("nativeFillAudio, 2, bufferPinned: %p, length: %i, enabled: %s, paused: %s\n", bufferPinned, length, this->enabled? "true": "false", this->paused? "true": "false"); SDL_memset(bufferPinned, this->spec.silence, length); } (*env)->ReleaseByteArrayElements(env, buffer, bufferPinned, 0); (*env)->DeleteLocalRef(env, buffer); return JNI_TRUE; }
std::ostream& operator<<(std::ostream& os, qi::StreamColor col) { if (&os == &(std::cout) && !qi::os::isatty(1)) return os; if (&os == &(std::cerr) && !qi::os::isatty(2)) return os; #if defined(__APPLE__) or defined(__linux__) posix_print(os, col); #endif return os; }
void Android_SetScreenResolution(int width, int height, Uint32 format, float rate) { static int times = 0; posix_print("#%i, Android_SetScreenResolution------(%ix%i), format: 0x%08x, rate: %7.2f, Android_Window: %p\n", times, width, height, format, rate, Android_Window); SDL_VideoDevice* device; SDL_VideoDisplay *display; Android_ScreenWidth = width; Android_ScreenHeight = height; Android_ScreenFormat = format; Android_ScreenRate = rate; /* Update the resolution of the desktop mode, so that the window can be properly resized. The screen resolution change can for example happen when the Activity enters or exists immersive mode, which can happen after VideoInit(). */ device = SDL_GetVideoDevice(); if (device && device->num_displays > 0) { display = &device->displays[0]; display->desktop_mode.format = Android_ScreenFormat; display->desktop_mode.w = Android_ScreenWidth; display->desktop_mode.h = Android_ScreenHeight; display->desktop_mode.refresh_rate = Android_ScreenRate; } if (Android_Window) { SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESIZED, width, height); /* Force the current mode to match the resize otherwise the SDL_WINDOWEVENT_RESTORED event * will fall back to the old mode */ display = SDL_GetDisplayForWindow(Android_Window); display->current_mode.format = format; display->current_mode.w = width; display->current_mode.h = height; display->current_mode.refresh_rate = rate; } times ++; }
static BOOL cb_walk_campaign(char* name, uint32_t flags, uint64_t len, int64_t lastWriteTime, uint32_t* ctx) { char text1[_MAX_PATH], text2[_MAX_PATH]; BOOL fok; walk_campaign_param_t* wcp = (walk_campaign_param_t*)ctx; if (flags & FILE_ATTRIBUTE_DIRECTORY ) { sprintf(text2, "%s\\%s", wcp->ins_campaign_dir.c_str(), name); MakeDirectory(std::string(text2)); // !!不要在<data>/campaigns/{campaign}下建images目录 sprintf(text1, "%s\\%s\\images", wcp->src_campaign_dir.c_str(), name); sprintf(text2, "%s\\%s\\images", wcp->ins_campaign_dir.c_str(), name); if (is_directory(text1)) { posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); return FALSE; } } } return TRUE; }
void playsingle_controller::play_ai_turn() { uint32_t start = SDL_GetTicks(); total_draw = 0; total_draws = 0; total_analyzing = 0; total_recruit = 0; total_combat = 0; total_build = 0; total_move = 0; total_diplomatism = 0; team& current_team = teams_[player_number_ - 1]; { const events::command_disabler disable_commands; if (card_mode_) { execute_card_uh(turn(), player_number_); } execute_guard_attack(player_number_); } gui_->enable_menu("play_card", false); gui_->enable_menu("undo", false); gui_->enable_menu("endturn", false); browse_ = true; gui_->recalculate_minimap(); const cursor::setter cursor_setter(cursor::WAIT); turn_info turn_data(player_number_, replay_sender_, undo_stack_); uint32_t before = SDL_GetTicks(); try { ai::manager::play_turn(player_number_); } catch (end_turn_exception&) { } uint32_t after = SDL_GetTicks(); if (!teams_[player_number_ - 1].is_human()) { recorder.end_turn(); } turn_data.sync_network(); if (!current_team.is_human()) { gui_->recalculate_minimap(); ::clear_shroud(player_number_); gui_->invalidate_unit(); gui_->invalidate_game_status(); gui_->invalidate_all(); gui_->draw(); if (card_mode_) { execute_card_bh(turn(), player_number_); } } uint32_t stop = SDL_GetTicks(); posix_print("#%i, play_ai_turn %u ms, (draw: %u(%i), analyzing: %u), [%u](%u+[%u]+%u)(recruit: %u, combat: %u, build: %u, move: %u, diplomatism: %u)\n", player_number_, stop - start, total_draw, total_draws, total_analyzing, before - start + total_recruit + total_combat + total_build + total_move + total_diplomatism + stop - after, before - start, total_recruit + total_combat + total_build + total_move + total_diplomatism, stop - after, total_recruit, total_combat, total_build, total_move, total_diplomatism); }
void playsingle_controller::play_ai_turn(turn_info* turn_data) { uint32_t start = SDL_GetTicks(); total_analyzing = 0; total_recruit = 0; total_combat = 0; total_build = 0; total_move = 0; total_diplomatism = 0; team& current_team = teams_[player_number_ - 1]; { const events::command_disabler disable_commands; if (card_mode_) { execute_card_uh(turn(), player_number_); } execute_guard_attack(player_number_); } gui_->set_theme_object_active("card", false); gui_->set_theme_object_active("undo", false); if (tent::mode == mode_tag::SIEGE) { } else { gui_->set_theme_object_active("endturn", false); } browse_ = true; gui_->recalculate_minimap(); const cursor::setter cursor_setter(cursor::WAIT); uint32_t before = SDL_GetTicks(); try { ai::manager::play_turn(); } catch (end_turn_exception&) { } uint32_t after = SDL_GetTicks(); if (turn_data) { turn_data->sync_network(); } if (unit::actor && !teams_[unit::actor->side() - 1].is_human()) { /* gui_->recalculate_minimap(); ::clear_shroud(unit::actor->side()); gui_->invalidate_unit(); gui_->invalidate_game_status(); gui_->invalidate_all(); gui_->draw(); */ if (card_mode_) { execute_card_bh(turn(), player_number_); } } // do_delay_call(true); uint32_t stop = SDL_GetTicks(); posix_print("#%i, play_ai_turn %u ms, (analyzing: %u), [%u](%u+[%u]+%u)(recruit: %u, combat: %u, build: %u, move: %u, diplomatism: %u)\n", player_number_, stop - start, total_analyzing, before - start + total_recruit + total_combat + total_build + total_move + total_diplomatism + stop - after, before - start, total_recruit + total_combat + total_build + total_move + total_diplomatism, stop - after, total_recruit, total_combat, total_build, total_move, total_diplomatism); }
void controller_base::play_slice(bool is_delay_enabled) { display& gui = get_display(); CKey key; events::pump(); events::raise_process_event(); events::raise_draw_event(); slice_before_scroll(); // const theme::menu* const m = get_display().menu_pressed(); const button_loc& loc = get_display().menu_pressed(); const theme::menu* m = loc.first; if (m && (m == gui.access_troop_menu())) { map_location pressed_loc = gui.access_unit_press(loc.second); if (pressed_loc.valid() && !get_mouse_handler_base().is_moving() && !get_mouse_handler_base().is_recalling() && !get_mouse_handler_base().is_building() && !get_mouse_handler_base().is_card_playing()) { gui.scroll_to_tile(pressed_loc, display::WARP); events::mouse_handler::get_singleton()->select_hex(map_location(), false); // gui.select_hex(pressed_loc); // sound::play_UI_sound("select-unit.wav"); resources::units->find(pressed_loc)->set_selecting(); resources::screen->invalidate_unit(); // now, selectedHex_ is invalid, hide context menu. gui.goto_main_context_menu(); } } else if (m != NULL){ const SDL_Rect& menu_loc = m->location(get_display().screen_area()); if (m->is_context()) { // Is pressed menu a father menu of context-menu? const std::string& item = m->items()[loc.second]; std::vector<std::string> item2 = utils::split(item, ':'); if (item2.size() == 1) { // item2.push_back(item2[0]) is wrong way, resulting item2[1] is null string. item2.push_back(""); } size_t pos = item2[0].rfind("_m"); if (pos == item2[0].size() - 2) { // cancel current menu, and display sub-menu gui.hide_context_menu(NULL, true); const std::string item1 = item2[0].substr(0, pos); gui.get_theme().set_current_context_menu(get_display().get_theme().context_menu(item1)); show_context_menu(NULL, get_display()); } else { // execute one menu command pos = item2[0].rfind("_c"); if (pos == item2[0].size() - 2) { const std::string item1 = item2[0].substr(0, pos); // hotkey::execute_command(gui, hotkey::get_hotkey(item1).get_id(), this, -1, item2[1]); execute_command(hotkey::get_hotkey(item1).get_id(), -1, item2[1]); gui.hide_context_menu(NULL, true); } else { // hotkey::execute_command(gui, hotkey::get_hotkey(item2[0]).get_id(), this, -1, item2[1]); execute_command(hotkey::get_hotkey(item2[0]).get_id(), -1, item2[1]); } } } else { show_menu(m->items(), menu_loc.x+1, menu_loc.y + menu_loc.h + 1, false); } return; } int mousex, mousey; Uint8 mouse_flags = SDL_GetMouseState(&mousex, &mousey); bool was_scrolling = scrolling_; scrolling_ = handle_scroll(key, mousex, mousey, mouse_flags); get_display().draw(); // be nice when window is not visible // NOTE should be handled by display instead, to only disable drawing if (is_delay_enabled && (SDL_GetAppState() & SDL_APPACTIVE) == 0) { get_display().delay(200); } if (!scrolling_ && was_scrolling) { #if (defined(__APPLE__) && TARGET_OS_IPHONE) || defined(ANDROID) // swip result to scroll, don't update mouse hex. SDL_Event new_event; while(SDL_PeepEvents(&new_event, 1, SDL_GETEVENT, SDL_FINGERMOTION, SDL_FINGERMOTION) > 0) { posix_print("SDL_FINGERMOTION(discard), (x, y): (%u, %u), (dx, dy): (%i, %i)\n", new_event.tfinger.x, new_event.tfinger.y, new_event.tfinger.dx, new_event.tfinger.dy); }; #else // scrolling ended, update the cursor and the brightened hex get_mouse_handler_base().mouse_update(browse_); #endif } slice_end(); }
LEVEL_RESULT playsingle_controller::play_scenario( const config::const_child_itors &story, bool skip_replay) { uint32_t start = SDL_GetTicks(); // level_ // save game: [snapshort] in save file // new game: [scenario] in <scenarios>.cfg // Start music. BOOST_FOREACH (const config &m, level_.child_range("music")) { sound::play_music_config(m); } sound::commit_music_changes(); if(!skip_replay) { // show_story(*gui_, level_["name"], story); // gui2::show_story(*gui_, level_["name"], story); } gui_->labels().read(level_); // Read sound sources assert(soundsources_manager_ != NULL); BOOST_FOREACH (const config &s, level_.child_range("sound_source")) { soundsource::sourcespec spec(s); soundsources_manager_->add(spec); } uint32_t end_sound_sources = SDL_GetTicks(); posix_print("playsingle_controller::play_scenario, sound sources, used time: %u ms\n", end_sound_sources - start); set_victory_when_enemy_no_city(level_["victory_when_enemy_no_city"].to_bool(true)); end_level_data &end_level = get_end_level_data(); end_level.carryover_percentage = level_["carryover_percentage"].to_int(game_config::gold_carryover_percentage); end_level.carryover_add = level_["carryover_add"].to_bool(); try { uint32_t end_entering_try = SDL_GetTicks(); posix_print("playsingle_controller::play_scenario, entering try, used time: %u ms\n", end_entering_try - end_sound_sources); fire_prestart(!loading_game_); uint32_t end_fire_prestart = SDL_GetTicks(); posix_print("playsingle_controller::play_scenario, fire_prestrt, used time: %u ms\n", end_fire_prestart - end_entering_try); init_gui(); fire_start(!loading_game_); gui_->recalculate_minimap(); // replaying_ = (recorder.at_end() == false); // Initialize countdown clock. std::vector<team>::iterator t; for(t = teams_.begin(); t != teams_.end(); ++t) { if (gamestate_.mp_settings().mp_countdown && !loading_game_ ){ t->set_countdown_time(1000 * gamestate_.mp_settings().mp_countdown_init_time); } } // if we loaded a save file in linger mode, skip to it. if (linger_) { //determine the bonus gold handling for this scenario const config end_cfg = level_.child_or_empty("endlevel"); end_level.carryover_percentage = level_["carryover_percentage"].to_int(game_config::gold_carryover_percentage); end_level.carryover_add = level_["carr`yover_add"].to_bool(); end_level.gold_bonus = end_cfg["bonus"].to_bool(true); end_level.carryover_report = false; throw end_level_exception(SKIP_TO_LINGER); } // Avoid autosaving after loading, but still // allow the first turn to have an autosave. bool save = !loading_game_; for(; ; first_player_ = 1) { play_turn(save); save = true; } //end for loop } catch(game::load_game_exception& lge) { // Loading a new game is effectively a quit. // if (lge.game != "") { gamestate_ = game_state(); } throw lge; } catch (end_level_exception &end_level_exn) { LEVEL_RESULT end_level_result = end_level_exn.result; if (!end_level.custom_endlevel_music.empty()) { if (end_level_result == DEFEAT) { set_defeat_music_list(end_level.custom_endlevel_music); } else { set_victory_music_list(end_level.custom_endlevel_music); } } if (teams_.empty()) { //store persistent teams gamestate_.snapshot = config(); return VICTORY; // this is probably only a story scenario, i.e. has its endlevel in the prestart event } const bool obs = is_observer(); if (end_level_result == DEFEAT || end_level_result == VICTORY) { gamestate_.classification().completion = (end_level_exn.result == VICTORY) ? "victory" : "defeat"; // If we're a player, and the result is victory/defeat, then send // a message to notify the server of the reason for the game ending. if (!obs) { config cfg; config& info = cfg.add_child("info"); info["type"] = "termination"; info["condition"] = "game over"; info["result"] = gamestate_.classification().completion; network::send_data(cfg, 0); } else { gui2::show_transient_message(gui_->video(),_("Game Over"), _("The game is over.")); return OBSERVER_END; } } if (end_level_result == QUIT) { return QUIT; } else if (end_level_result == DEFEAT) { gamestate_.classification().completion = "defeat"; game_events::fire("defeat"); if (!obs) { const std::string& defeat_music = select_defeat_music(); if(defeat_music.empty() != true) sound::play_music_once(defeat_music); return DEFEAT; } else { return QUIT; } } else if (end_level_result == VICTORY) { gamestate_.classification().completion = !end_level.linger_mode ? "running" : "victory"; game_events::fire("victory"); // // Play victory music once all victory events // are finished, if we aren't observers. // // Some scenario authors may use 'continue' // result for something that is not story-wise // a victory, so let them use [music] tags // instead should they want special music. // if (!obs && end_level.linger_mode) { const std::string& victory_music = select_victory_music(); if(victory_music.empty() != true) sound::play_music_once(victory_music); } // Add all the units that survived the scenario. LOG_NG << "Add units that survived the scenario to the recall list.\n"; //store all units that survived (recall list for the next scenario) in snapshot gamestate_.snapshot = config(); //store gold and report victory store_gold(obs); return VICTORY; } else if (end_level_result == SKIP_TO_LINGER) { LOG_NG << "resuming from loaded linger state...\n"; //as carryover information is stored in the snapshot, we have to re-store it after loading a linger state gamestate_.snapshot = config(); store_gold(); return VICTORY; } } // end catch catch(network::error& e) { bool disconnect = false; if(e.socket) { e.disconnect(); disconnect = true; } config snapshot; to_config(snapshot); savegame::game_savegame save(heros_, heros_start_, gamestate_, *gui_, snapshot); save.save_game_interactive(gui_->video(), _("A network disconnection has occurred, and the game cannot continue. Do you want to save the game?"), gui::YES_NO); if(disconnect) { throw network::error(); } else { return QUIT; } } return QUIT; }
int wml_config_from_data(uint8_t *data, uint32_t datalen, uint8_t *namebuf, uint8_t *valbuf, std::vector<std::string> &tdomain, config &cfg) { int retval; uint8_t *rdpos = data; uint32_t u32n, len, transcnt, tdidx; uint16_t deep; config::child_list lastcfg; retval = -1; lastcfg.push_back(&cfg); uint32_t max_str_len = 0; int debug = 0; while (rdpos < data + datalen) { // posix_print("in while, rdpos: %p, pos: %u(0x%x)", rdpos, rdpos - data + 4, rdpos - data + 4); // read {[cfg]}{len}{name} if (memcmp(rdpos, WMLBIN_MARK_CONFIG, WMLBIN_MARK_CONFIG_LEN)) { posix_print("mark is not %s\n", WMLBIN_MARK_CONFIG); goto exit; } rdpos = rdpos + WMLBIN_MARK_CONFIG_LEN; memcpy(&u32n, rdpos, sizeof(u32n)); len = posix_lo16(u32n); deep = posix_hi16(u32n); rdpos = rdpos + sizeof(u32n); memcpy(namebuf, rdpos, len); namebuf[len] = 0; rdpos = rdpos + len; // posix_print("deep: %u, name: %s\n", deep, namebuf); config &cfgtmp = lastcfg[deep]->add_child(std::string((char *)namebuf)); if (deep + 1 >= (uint16_t)lastcfg.size()) { lastcfg.push_back(&cfgtmp); } else { lastcfg[deep + 1] = &cfgtmp; } // read {[val]}{len}{name0}{len}{val0}{len}{name1}{len}{val1}{...} if (!memcmp(rdpos, WMLBIN_MARK_VALUE, WMLBIN_MARK_VALUE_LEN)) { // 存在value rdpos = rdpos + WMLBIN_MARK_VALUE_LEN; while ((rdpos < data + datalen) && memcmp(rdpos, WMLBIN_MARK_CONFIG, WMLBIN_MARK_CONFIG_LEN)) { // name memcpy(&len, rdpos, sizeof(len)); rdpos = rdpos + sizeof(len); memcpy(namebuf, rdpos, len); namebuf[len] = 0; rdpos = rdpos + len; // value memcpy(&u32n, rdpos, sizeof(u32n)); rdpos = rdpos + sizeof(u32n); transcnt = posix_hi8(posix_hi16(u32n)); tdidx = posix_lo8(posix_hi16(u32n)); memcpy(&len, rdpos, sizeof(len)); rdpos = rdpos + sizeof(len); memcpy(valbuf, rdpos, len); valbuf[len] = 0; rdpos = rdpos + len; if (transcnt) { if (tdidx) { cfgtmp[std::string((char *)namebuf)] = t_string((const char *)valbuf, tdomain[tdidx - 1]); } else { cfgtmp[std::string((char *)namebuf)] = t_string((const char *)valbuf); } transcnt --; while (transcnt != 0) { // value memcpy(&u32n, rdpos, sizeof(u32n)); rdpos = rdpos + sizeof(u32n); tdidx = posix_lo8(posix_hi16(u32n)); memcpy(&len, rdpos, sizeof(len)); rdpos = rdpos + sizeof(len); memcpy(valbuf, rdpos, len); valbuf[len] = 0; rdpos = rdpos + len; if (tdidx) { cfgtmp[std::string((char *)namebuf)] = cfgtmp[std::string((char *)namebuf)].t_str() + t_string((const char *)valbuf, tdomain[tdidx - 1]); } else { cfgtmp[std::string((char *)namebuf)] = cfgtmp[std::string((char *)namebuf)].t_str() + t_string((const char *)valbuf); } transcnt --; } } else { cfgtmp[std::string((char *)namebuf)] = t_string((const char *)valbuf); } } } } retval = 0; exit: return retval; }
void wml_config_from_file(const std::string &fname, config &cfg, uint32_t* nfiles, uint32_t* sum_size, uint32_t* modified) { posix_file_t fp = INVALID_FILE; uint32_t datalen, fsizelow, fsizehigh, max_str_len, bytertd, tdcnt, idx, len; uint8_t *data = NULL, *namebuf = NULL, *valbuf = NULL; char tdname[MAXLEN_TEXTDOMAIN + 1]; std::vector<std::string> tdomain; posix_print("<xwml.cpp>::wml_config_from_file------fname: %s\n", fname.c_str()); cfg.clear(); // 首先清空,以下是增加方式 posix_fopen(fname.c_str(), GENERIC_READ, OPEN_EXISTING, fp); if (fp == INVALID_FILE) { posix_print("------<xwml.cpp>::wml_config_from_file, cannot create %s for read\n", fname.c_str()); goto exit; } posix_fsize(fp, fsizelow, fsizehigh); if (fsizelow <= 16) { goto exit; } posix_fseek(fp, 0, 0); posix_fread(fp, &len, 4, bytertd); // 判断是不是XWML if (len != mmioFOURCC('X', 'W', 'M', 'L')) { goto exit; } posix_fread(fp, &len, 4, bytertd); if (nfiles) { *nfiles = len; } posix_fread(fp, &len, 4, bytertd); if (sum_size) { *sum_size = len; } posix_fread(fp, &len, 4, bytertd); if (modified) { *modified = len; } posix_fread(fp, &max_str_len, sizeof(max_str_len), bytertd); // 读出po posix_fread(fp, &tdcnt, sizeof(tdcnt), bytertd); datalen = fsizelow - 16 - sizeof(max_str_len) - sizeof(tdcnt); for (idx = 0; idx < tdcnt; idx ++) { posix_fread(fp, &len, sizeof(uint32_t), bytertd); posix_fread(fp, tdname, len, bytertd); tdname[len] = 0; tdomain.push_back(tdname); datalen -= sizeof(uint32_t) + len; t_string::add_textdomain(tdomain.back(), get_intl_dir()); } data = (uint8_t *)malloc(datalen); namebuf = (uint8_t *)malloc(max_str_len + 1 + 1024); valbuf = (uint8_t *)malloc(max_str_len + 1 + 1024); // 剩下数据读出sram posix_fread(fp, data, datalen, bytertd); wml_config_from_data(data, datalen, namebuf, valbuf, tdomain, cfg); exit: if (fp != INVALID_FILE) { posix_fclose(fp); } if (data) { free(data); } if (namebuf) { free(namebuf); } if (valbuf) { free(valbuf); } return; }
void wml_building_rules_to_file(const std::string& fname, terrain_builder::building_rule* rules, uint32_t rules_size, uint32_t nfiles, uint32_t sum_size, uint32_t modified) { posix_file_t fp = INVALID_FILE; uint32_t max_str_len, bytertd, u32n, idx, size, size1; posix_print("<xwml.cpp>::wml_building_rules_to_file------fname: %s, will save %u rules\n", fname.c_str(), rules_size); posix_fopen(fname.c_str(), GENERIC_WRITE, CREATE_ALWAYS, fp); if (fp == INVALID_FILE) { posix_print("------<xwml.cpp>::wml_building_rules_to_file, cannot create %s for wrtie\n", fname.c_str()); return; } // max str len max_str_len = 63; // 0--15 u32n = mmioFOURCC('X', 'W', 'M', 'L'); posix_fwrite(fp, &u32n, 4, bytertd); posix_fwrite(fp, &nfiles, 4, bytertd); posix_fwrite(fp, &sum_size, 4, bytertd); posix_fwrite(fp, &modified, 4, bytertd); posix_fseek(fp, 16 + sizeof(max_str_len), 0); // rules size posix_fwrite(fp, &rules_size, sizeof(rules_size), bytertd); uint32_t rule_index = 0; for (rule_index = 0; rule_index < rules_size; rule_index ++) { // // typedef std::multiset<building_rule> building_ruleset; // // building_rule const terrain_builder::building_rule& rule = rules[rule_index]; // *int precedence posix_fwrite(fp, &rule.precedence, sizeof(int), bytertd); // *map_location location_constraints; posix_fwrite(fp, &rule.location_constraints.x, sizeof(int), bytertd); posix_fwrite(fp, &rule.location_constraints.y, sizeof(int), bytertd); // *int probability posix_fwrite(fp, &rule.probability, sizeof(int), bytertd); // size of constraints size = rule.constraints.size(); posix_fwrite(fp, &size, sizeof(uint32_t), bytertd); // constraint_set constraints for (terrain_builder::constraint_set::const_iterator constraint = rule.constraints.begin(); constraint != rule.constraints.end(); ++constraint) { // typedef std::vector<terrain_constraint> constraint_set; posix_fwrite(fp, &constraint->loc.x, sizeof(int), bytertd); posix_fwrite(fp, &constraint->loc.y, sizeof(int), bytertd); // // terrain_constraint // // t_translation::t_match terrain_types_match; const t_translation::t_match& match = constraint->terrain_types_match; // struct t_match{ // ...... // t_list terrain; // t_list mask; // t_list masked_terrain; // bool has_wildcard; // bool is_empty; // }; // typedef std::vector<t_terrain> t_list; // terrain, mask和masked_terrain肯定一样长度, 为节省空间,只写一个长度值 size = match.terrain.size(); posix_fwrite(fp, &size, sizeof(size), bytertd); t_list_to_fp(fp, match.terrain, idx, size, bytertd); t_list_to_fp(fp, match.mask, idx, size, bytertd); t_list_to_fp(fp, match.masked_terrain, idx, size, bytertd); u32n = match.has_wildcard? 1: 0; posix_fwrite(fp, &u32n, sizeof(int), bytertd); u32n = match.is_empty? 1: 0; posix_fwrite(fp, &u32n, sizeof(int), bytertd); // std::vector<std::string> set_flag; vstr_to_fp(fp, constraint->set_flag, idx, size, u32n, bytertd, max_str_len); // std::vector<std::string> no_flag; vstr_to_fp(fp, constraint->no_flag, idx, size, u32n, bytertd, max_str_len); // std::vector<std::string> has_flag; vstr_to_fp(fp, constraint->has_flag, idx, size, u32n, bytertd, max_str_len); // (typedef std::vector<rule_image> rule_imagelist) rule_imagelist images size = constraint->images.size(); posix_fwrite(fp, &size, sizeof(size), bytertd); for (idx = 0; idx < size; idx ++) { const struct terrain_builder::rule_image& ri = constraint->images[idx]; // rule_image // struct rule_image { // ...... // int layer; // int basex, basey; // bool global_image; // int center_x, center_y; // rule_image_variantlist variants; // } posix_fwrite(fp, &ri.layer, sizeof(int), bytertd); posix_fwrite(fp, &ri.basex, sizeof(int), bytertd); posix_fwrite(fp, &ri.basey, sizeof(int), bytertd); u32n = ri.global_image? 1: 0; posix_fwrite(fp, &u32n, sizeof(int), bytertd); posix_fwrite(fp, &ri.center_x, sizeof(int), bytertd); posix_fwrite(fp, &ri.center_y, sizeof(int), bytertd); // (std::vector<rule_image_variant>) variants size1 = ri.variants.size(); posix_fwrite(fp, &size1, sizeof(size), bytertd); for (std::vector<terrain_builder::rule_image_variant>::const_iterator imgitor = ri.variants.begin(); imgitor != ri.variants.end(); ++imgitor) { // value: rule_image_variant // struct rule_image_variant { // ...... // std::string image_string; // std::string variations; // std::string tod; // animated<image::locator> image; // bool random_start; // } u32n = imgitor->image_string.size(); posix_fwrite(fp, &u32n, sizeof(u32n), bytertd); posix_fwrite(fp, imgitor->image_string.c_str(), u32n, bytertd); max_str_len = posix_max(max_str_len, u32n); u32n = imgitor->variations.size(); posix_fwrite(fp, &u32n, sizeof(u32n), bytertd); posix_fwrite(fp, imgitor->variations.c_str(), u32n, bytertd); max_str_len = posix_max(max_str_len, u32n); u32n = imgitor->random_start? 1: 0; posix_fwrite(fp, &u32n, sizeof(int), bytertd); // // 到此为止,只有rule_image_variant中的image没有生成 // image涉及到两个类class animated和class locator,类中有数据private成员数据,很难直接赋值 // 考虑到from时也会调用构造函数以构造类,这里就填上构造函数需的参数就行了。 // 如何由构造函数生成animated和locator参考:bool terrain_builder::start_animation(building_rule &rule) // // class animated // int starting_frame_time_; // bool does_not_change_; // bool started_; // bool need_first_update_; // int start_tick_; // bool cycles_; // double acceleration_; // int last_update_tick_; // int current_frame_key_; // +std::vector<frame> frames_; // int duration_; // int start_time_; // +T value_; // +class locator // static int last_index_; // int index_; // value val_; // struct value { // ...... // type type_; // std::string filename_; // map_location loc_; // std::string modifications_; // int center_x_; // int center_y_; // } } } } } // 更新最大的存储区大小 posix_fseek(fp, 16, 0); posix_fwrite(fp, &max_str_len, sizeof(max_str_len), bytertd); posix_fclose(fp); posix_print("------<xwml.cpp>::wml_building_rules_to_file, return\n"); return; }
BOOL extra_kingdom_ins_disk(char* kingdom_src, char* kingdom_ins, char* kingdom_ins_android) { char text1[_MAX_PATH], text2[_MAX_PATH]; BOOL fok; walk_campaign_param_t wcp; MakeDirectory(std::string(kingdom_ins)); // 清空目录 fok = delfile1(kingdom_ins); if (!fok) { posix_print_mb("删除目录: %s,失败", kingdom_ins); return fok; } fok = delfile1(kingdom_ins_android); if (!fok) { posix_print_mb("删除目录: %s,失败", kingdom_ins_android); // return fok; } // // <kingdom-src>\data // // 1. images in all campaigns wcp.src_campaign_dir = std::string(kingdom_src) + "\\data\\campaigns"; wcp.ins_campaign_dir = std::string(kingdom_ins) + "\\data\\campaigns"; fok = walk_dir_win32_deepen(wcp.src_campaign_dir.c_str(), 0, cb_walk_campaign, (uint32_t *)&wcp); if (!fok) { return fok; } wcp.ins_campaign_dir = std::string(kingdom_ins_android) + "\\data\\campaigns"; fok = walk_dir_win32_deepen(wcp.src_campaign_dir.c_str(), 0, cb_walk_campaign, (uint32_t *)&wcp); if (!fok) { return fok; } // 2. images in <data>\core root MakeDirectory(std::string("") + kingdom_ins + "\\data\\core"); sprintf(text1, "%s\\data\\core\\images", kingdom_src); sprintf(text2, "%s\\data\\core\\images", kingdom_ins); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // android MakeDirectory(std::string("") + kingdom_ins_android + "\\data\\core"); sprintf(text2, "%s\\data\\core\\images", kingdom_ins_android); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // 3. music in <data>\core root sprintf(text1, "%s\\data\\core\\music", kingdom_src); sprintf(text2, "%s\\data\\core\\music", kingdom_ins); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // android sprintf(text2, "%s\\data\\core\\music", kingdom_ins_android); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // 4. sounds in <data>\core root sprintf(text1, "%s\\data\\core\\sounds", kingdom_src); sprintf(text2, "%s\\data\\core\\sounds", kingdom_ins); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // android sprintf(text2, "%s\\data\\core\\sounds", kingdom_ins_android); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } sprintf(text1, "%s\\data\\hardwired", kingdom_src); sprintf(text2, "%s\\data\\hardwired", kingdom_ins); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // android sprintf(text2, "%s\\data\\hardwired", kingdom_ins_android); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } sprintf(text1, "%s\\data\\lua", kingdom_src); sprintf(text2, "%s\\data\\lua", kingdom_ins); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // android sprintf(text2, "%s\\data\\lua", kingdom_ins_android); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } sprintf(text1, "%s\\data\\tools", kingdom_src); sprintf(text2, "%s\\data\\tools", kingdom_ins); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // android sprintf(text2, "%s\\data\\tools", kingdom_ins_android); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // <kingdom-src>\data\_main_cfg sprintf(text1, "%s\\data\\_main.cfg", kingdom_src); sprintf(text2, "%s\\data\\_main.cfg", kingdom_ins); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制文件,从%s到%s,失败", text1, text2); goto exit; } // android sprintf(text2, "%s\\data\\_main.cfg", kingdom_ins_android); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制文件,从%s到%s,失败", text1, text2); goto exit; } // // <kingdom-src>\fonts // sprintf(text1, "%s\\fonts", kingdom_src); sprintf(text2, "%s\\fonts", kingdom_ins); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // android sprintf(text2, "%s\\fonts", kingdom_ins_android); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // // <kingdom-src>\images // sprintf(text1, "%s\\images", kingdom_src); sprintf(text2, "%s\\images", kingdom_ins); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // android sprintf(text2, "%s\\images", kingdom_ins_android); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // // <kingdom-src>\manual // sprintf(text1, "%s\\manual", kingdom_src); sprintf(text2, "%s\\manual", kingdom_ins); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // andorid don't copy manual // // <kingdom-src>\sounds // sprintf(text1, "%s\\sounds", kingdom_src); sprintf(text2, "%s\\sounds", kingdom_ins); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // android sprintf(text2, "%s\\sounds", kingdom_ins_android); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // // <kingdom-src>\translations // sprintf(text1, "%s\\translations", kingdom_src); sprintf(text2, "%s\\translations", kingdom_ins); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // android sprintf(text2, "%s\\translations", kingdom_ins_android); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // // <kingdom-src>\xwml // sprintf(text1, "%s\\xwml", kingdom_src); sprintf(text2, "%s\\xwml", kingdom_ins); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } // android sprintf(text2, "%s\\xwml", kingdom_ins_android); posix_print("<data>, copy %s to %s ......\n", text1, text2); fok = copyfile(text1, text2); if (!fok) { posix_print_mb("复制目录,从%s到%s,失败", text1, text2); goto exit; } fok = copy_root_files(kingdom_src, kingdom_ins); exit: if (!fok) { delfile1(kingdom_ins); } return fok; }
terrain_builder::building_rule* wml_building_rules_from_file(const std::string& fname, uint32_t* rules_size_ptr) { posix_file_t fp = INVALID_FILE; uint32_t datalen, max_str_len, rules_size, fsizelow, fsizehigh, bytertd, idx, len, size, size1, idx1, size2, idx2; uint8_t* data = NULL, *strbuf = NULL, *variations = NULL; uint8_t* rdpos; terrain_builder::building_rule * rules = NULL; map_location loc; tmp_pair tmppair; posix_print("<xwml.cpp>::wml_config_from_file------fname: %s\n", fname.c_str()); if (rules_size_ptr) { *rules_size_ptr = 0; } posix_fopen(fname.c_str(), GENERIC_READ, OPEN_EXISTING, fp); if (fp == INVALID_FILE) { posix_print("------<xwml.cpp>::wml_building_rules_from_file, cannot create %s for read\n", fname.c_str()); return NULL; } posix_fsize(fp, fsizelow, fsizehigh); if (fsizelow <= 16 + sizeof(max_str_len) + sizeof(rules_size)) { posix_fclose(fp); return NULL; } posix_fseek(fp, 16, 0); posix_fread(fp, &max_str_len, sizeof(max_str_len), bytertd); posix_fread(fp, &rules_size, sizeof(rules_size), bytertd); datalen = fsizelow - 16 - sizeof(max_str_len) - sizeof(rules_size); data = (uint8_t *)malloc(datalen); strbuf = (uint8_t *)malloc(max_str_len + 1); variations = (uint8_t *)malloc(max_str_len + 1); // 剩下数据读出sram posix_fread(fp, data, datalen, bytertd); posix_print("max_str_len: %u, fsizelow: %u, datalen: %u\n", max_str_len, fsizelow, datalen); rdpos = data; // allocate memory for rules pointer array if (rules_size) { // rules = (terrain_builder::building_rule**)malloc(rules_size * sizeof(terrain_builder::building_rule**)); rules = new terrain_builder::building_rule[rules_size]; } else { rules = NULL; } uint32_t rule_index = 0; /* uint32_t previous, current, start, stop = SDL_GetTicks(); */ while (rdpos < data + datalen) { int x, y; /* start = stop; posix_print("#%04u, (", rule_index); */ // building_ruleset::iterator // terrain_builder::building_rule& pbr = *rules.insert(terrain_builder::building_rule()); // rules.push_back(terrain_builder::building_rule()); // terrain_builder::building_rule& pbr = rules.back(); // rules[rule_index] = new terrain_builder::building_rule; terrain_builder::building_rule& pbr = rules[rule_index]; /* previous = SDL_GetTicks(); posix_print("%u", previous - start); */ // precedence memcpy(&pbr.precedence, rdpos, sizeof(int)); rdpos = rdpos + sizeof(int); // *map_location location_constraints; memcpy(&x, rdpos, sizeof(int)); memcpy(&y, rdpos + sizeof(int), sizeof(int)); rdpos = rdpos + 2 * sizeof(int); pbr.location_constraints = map_location(x, y); // *int probability memcpy(&pbr.probability, rdpos, sizeof(int)); rdpos = rdpos + sizeof(int); // local pbr.local = false; // size of constraints memcpy(&size, rdpos, sizeof(int)); rdpos = rdpos + sizeof(int); /* current = SDL_GetTicks(); posix_print(" + %u", current - previous); previous = current; */ for (idx = 0; idx < size; idx ++) { // terrain_constraint memcpy(&tmppair, rdpos, 8); rdpos = rdpos + 8; loc = map_location(tmppair.first, tmppair.second); // pbr.constraints[loc] = terrain_builder::terrain_constraint(loc); // constraint = pbr.constraints.find(loc); pbr.constraints.push_back(terrain_builder::terrain_constraint(loc)); terrain_builder::terrain_constraint& constraint = pbr.constraints.back(); // // t_mach // t_translation::t_match& match = constraint.terrain_types_match; // memcpy(&x, rdpos, sizeof(int)); // memcpy(&y, rdpos, sizeof(int)); // rdpos = rdpos + 2 * sizeof(int); // size of terrain in t_mach // constraints[loc].terrain_types_match = t_translation::t_terrain(x, y); memcpy(&size1, rdpos, sizeof(uint32_t)); rdpos = rdpos + sizeof(uint32_t); for (idx1 = 0; idx1 < size1; idx1 ++) { memcpy(&tmppair, rdpos, 8); match.terrain.push_back(t_translation::t_terrain(tmppair.first, tmppair.second)); rdpos = rdpos + 8; } for (idx1 = 0; idx1 < size1; idx1 ++) { memcpy(&tmppair, rdpos, 8); match.mask.push_back(t_translation::t_terrain(tmppair.first, tmppair.second)); rdpos = rdpos + 8; } for (idx1 = 0; idx1 < size1; idx1 ++) { memcpy(&tmppair, rdpos, 8); match.masked_terrain.push_back(t_translation::t_terrain(tmppair.first, tmppair.second)); rdpos = rdpos + 8; } memcpy(&tmppair, rdpos, 8); match.has_wildcard = tmppair.first? true: false; match.is_empty = tmppair.second? true: false; rdpos = rdpos + 8; // size of flags in set_flag memcpy(&size1, rdpos, sizeof(uint32_t)); rdpos = rdpos + sizeof(uint32_t); for (idx1 = 0; idx1 < size1; idx1 ++) { memcpy(&len, rdpos, sizeof(uint32_t)); memcpy(strbuf, rdpos + sizeof(uint32_t), len); strbuf[len] = 0; constraint.set_flag.push_back((char*)strbuf); rdpos = rdpos + sizeof(uint32_t) + len; } // size of flags in no_flag memcpy(&size1, rdpos, sizeof(uint32_t)); rdpos = rdpos + sizeof(uint32_t); for (idx1 = 0; idx1 < size1; idx1 ++) { memcpy(&len, rdpos, sizeof(uint32_t)); memcpy(strbuf, rdpos + sizeof(uint32_t), len); strbuf[len] = 0; constraint.no_flag.push_back((char*)strbuf); rdpos = rdpos + sizeof(uint32_t) + len; } // size of flags in has_flag memcpy(&size1, rdpos, sizeof(uint32_t)); rdpos = rdpos + sizeof(uint32_t); for (idx1 = 0; idx1 < size1; idx1 ++) { memcpy(&len, rdpos, sizeof(uint32_t)); memcpy(strbuf, rdpos + sizeof(uint32_t), len); strbuf[len] = 0; constraint.has_flag.push_back((char*)strbuf); rdpos = rdpos + sizeof(uint32_t) + len; } // size of rule_image in rule_imagelist memcpy(&size1, rdpos, sizeof(uint32_t)); rdpos = rdpos + sizeof(uint32_t); for (idx1 = 0; idx1 < size1; idx1 ++) { // struct terrain_builder::rule_image& ri = constraint->second.images[idx1]; // rule_image int layer, center_x, center_y; bool global_image; memcpy(&layer, rdpos, sizeof(int)); memcpy(&x, rdpos + 4, sizeof(int)); memcpy(&y, rdpos + 8, sizeof(int)); memcpy(&len, rdpos + 12, sizeof(int)); global_image = len? true: false; memcpy(¢er_x, rdpos + 16, sizeof(int)); memcpy(¢er_y, rdpos + 20, sizeof(int)); rdpos = rdpos + 24; constraint.images.push_back(terrain_builder::rule_image(layer, x, y, global_image, center_x, center_y)); // size of rule_image in rule_imagelist memcpy(&size2, rdpos, sizeof(uint32_t)); rdpos = rdpos + sizeof(uint32_t); for (idx2 = 0; idx2 < size2; idx2 ++) { bool random_start; memcpy(&len, rdpos, sizeof(uint32_t)); memcpy(strbuf, rdpos + sizeof(uint32_t), len); strbuf[len] = 0; rdpos = rdpos + sizeof(uint32_t) + len; // Adds the main (default) variant of the image, if present memcpy(&len, rdpos, sizeof(uint32_t)); memcpy(variations, rdpos + sizeof(uint32_t), len); variations[len] = 0; rdpos = rdpos + sizeof(uint32_t) + len; memcpy(&len, rdpos, sizeof(int)); random_start = len? true: false; rdpos = rdpos + sizeof(int); constraint.images.back().variants.push_back(terrain_builder::rule_image_variant((char*)strbuf, (char*)variations, random_start)); } } /* current = SDL_GetTicks(); posix_print(" + %u", current - previous); previous = current; */ } /* stop = SDL_GetTicks(); posix_print("), expend %u ms\n", stop - start); */ rule_index ++; } if (fp != INVALID_FILE) { posix_fclose(fp); } if (data) { free(data); } if (strbuf) { free(strbuf); } if (variations) { free(variations); } if (rules_size_ptr) { *rules_size_ptr = rule_index; } posix_print("------<xwml.cpp>::wml_building_rules_from_file, restore %u rules, return\n", rule_index); return rules; }