boost::shared_ptr<const Surface> GraphicsSystem::GetEmojiSurface() { GameexeFilteringIterator it = system().gameexe().filtering_begin("E_MOJI."); GameexeFilteringIterator end = system().gameexe().filtering_end(); for (; it != end; ++it) { // Try to interpret each key as a filename. std::string file_name = it->to_string(""); boost::shared_ptr<const Surface> surface = getSurfaceNamed(file_name); if (surface) return surface; } return boost::shared_ptr<const Surface>(); }
TEST(GameexeUnit, FilteringIterators) { Gameexe ini(locateTestCase("Gameexe_data/Gameexe.ini")); GameexeFilteringIterator it = ini.filtering_begin("IMAGINE"); GameexeFilteringIterator end = ini.filtering_end(); for (; it != end; ++it) { if (it->key() != "IMAGINE.ONE" && it->key() != "IMAGINE.TWO" && it->key() != "IMAGINE.THREE") { FAIL() << "Failed to filter keys in GameexeFilteringIterator. Has key " << it->key(); } } }
RLMachine::RLMachine(System& in_system, Archive& in_archive) : memory_(new Memory(*this, in_system.gameexe())), halted_(false), print_undefined_opcodes_(false), halt_on_exception_(true), archive_(in_archive), line_(0), system_(in_system), mark_savepoints_(true), delay_stack_modifications_(false), replaying_graphics_stack_(false) { // Search in the Gameexe for #SEEN_START and place us there Gameexe& gameexe = in_system.gameexe(); libReallive::Scenario* scenario = NULL; if (gameexe.exists("SEEN_START")) { int first_seen = gameexe("SEEN_START").to_int(); scenario = in_archive.scenario(first_seen); if (scenario == NULL) cerr << "WARNING: Invalid #SEEN_START in Gameexe" << endl; } if (scenario == NULL) { // if SEEN_START is undefined, then just grab the first SEEN. scenario = in_archive.scenario(archive_.begin()->first); } if (scenario == 0) throw rlvm::Exception("Invalid scenario file"); pushStackFrame(StackFrame(scenario, scenario->begin(), StackFrame::TYPE_ROOT)); // Initial value of the savepoint markSavepoint(); // Load the "DLLs" required GameexeFilteringIterator it = gameexe.filtering_begin("DLL."); GameexeFilteringIterator end = gameexe.filtering_end(); for (; it != end; ++it) { string index_str = it->key().substr(it->key().find_first_of(".") + 1); int index = lexical_cast<int>(index_str); const string& name = it->to_string(""); try { loadDLL(index, name); } catch(rlvm::Exception& e) { cerr << "WARNING: Don't know what to do with DLL '" << name << "'" << endl; } } }
GraphicsSystem::GraphicsObjectSettings::GraphicsObjectSettings( Gameexe& gameexe) { if (gameexe.exists("OBJECT_MAX")) objects_in_a_layer = gameexe("OBJECT_MAX"); else objects_in_a_layer = 256; // First we populate everything with the special value position.reset(new unsigned char[objects_in_a_layer]); fill(position.get(), position.get() + objects_in_a_layer, 0); if (gameexe.exists("OBJECT.999")) data.push_back(ObjectSettings(gameexe("OBJECT.999"))); else data.push_back(ObjectSettings()); // Read the #OBJECT.xxx entries from the Gameexe GameexeFilteringIterator it = gameexe.filtering_begin("OBJECT."); GameexeFilteringIterator end = gameexe.filtering_end(); for (; it != end; ++it) { string s = it->key().substr(it->key().find_first_of(".") + 1); std::list<int> object_nums; string::size_type poscolon = s.find_first_of(":"); if ( poscolon != string::npos ) { int obj_num_first = lexical_cast<int>(s.substr(0, poscolon)); int obj_num_last = lexical_cast<int>(s.substr(poscolon + 1)); while ( obj_num_first <= obj_num_last ) { object_nums.push_back(obj_num_first++); } } else { object_nums.push_back(lexical_cast<int>(s)); } for ( std::list<int>::const_iterator intit = object_nums.begin(); intit != object_nums.end(); ++intit ) { int obj_num = *intit; if (obj_num != 999 && obj_num < objects_in_a_layer) { position[obj_num] = data.size(); data.push_back(ObjectSettings(*it)); } } } }
void Memory::initializeDefaultValues(Gameexe& gameexe) { // Note: We ignore the \#NAME_MAXLEN variable because manual allocation is // error prone and for losers. GameexeFilteringIterator end = gameexe.filtering_end(); for (GameexeFilteringIterator it = gameexe.filtering_begin("NAME."); it != end; ++it) { try { setName(ConvertLetterIndexToInt(it->key_parts().at(1)), removeQuotes(it->to_string())); } catch(...) { cerr << "WARNING: Invalid format for key " << it->key() << endl; } } for (GameexeFilteringIterator it = gameexe.filtering_begin("LOCALNAME."); it != end; ++it) { try { setLocalName(ConvertLetterIndexToInt(it->key_parts().at(1)), removeQuotes(it->to_string())); } catch(...) { cerr << "WARNING: Invalid format for key " << it->key() << endl; } } }
TextWindow::TextWindow(System& system, int window_num) : window_num_(window_num), text_insertion_point_x_(0), text_insertion_point_y_(0), ruby_begin_point_(-1), current_line_number_(0), current_indentation_in_pixels_(0), last_token_was_name_(false), use_indentation_(0), colour_(), filter_(0), is_visible_(0), in_selection_mode_(0), system_(system), text_system_(system.text()) { Gameexe& gexe = system.gameexe(); // POINT Size size = getScreenSize(gexe); screen_width_ = size.width(); screen_height_ = size.height(); // Base form for everything to follow. GameexeInterpretObject window(gexe("WINDOW", window_num)); // Handle: #WINDOW.index.ATTR_MOD, #WINDOW_ATTR, #WINDOW.index.ATTR window_attr_mod_ = window("ATTR_MOD"); if (window_attr_mod_ == 0) setRGBAF(system.text().windowAttr()); else setRGBAF(window("ATTR")); default_font_size_in_pixels_ = window("MOJI_SIZE").to_int(25); setFontSizeInPixels(default_font_size_in_pixels_); setWindowSizeInCharacters(window("MOJI_CNT")); setSpacingBetweenCharacters(window("MOJI_REP")); setRubyTextSize(window("LUBY_SIZE").to_int(0)); setTextboxPadding(window("MOJI_POS")); setWindowPosition(window("POS")); setDefaultTextColor(gexe("COLOR_TABLE", 0)); // INDENT_USE appears to default to on. See the first scene in the // game with Nagisa, paying attention to indentation; then check the // Gameexe.ini. setUseIndentation(window("INDENT_USE").to_int(1)); setKeycurMod(window("KEYCUR_MOD")); setActionOnPause(window("R_COMMAND_MOD").to_int(0)); // Main textbox waku waku_set_ = window("WAKU_SETNO").to_int(0); textbox_waku_.reset(TextWaku::Create(system_, *this, waku_set_, 0)); // Name textbox if that setting has been enabled. setNameMod(window("NAME_MOD").to_int(0)); if (name_mod_ == 1 && window("NAME_WAKU_SETNO").exists()) { name_waku_set_ = window("NAME_WAKU_SETNO"); namebox_waku_.reset(TextWaku::Create(system_, *this, name_waku_set_, 0)); setNameSpacingBetweenCharacters(window("NAME_MOJI_REP")); setNameboxPadding(window("NAME_MOJI_POS")); // Ignoring NAME_WAKU_MIN for now setNameboxPosition(window("NAME_POS")); name_waku_dir_set_ = window("NAME_WAKU_DIR").to_int(0); namebox_centering_ = window("NAME_CENTERING").to_int(0); minimum_namebox_size_ = window("NAME_MOJI_MIN").to_int(4); name_size_ = window("NAME_MOJI_SIZE"); } // Load #FACE information. GameexeFilteringIterator it = gexe.filtering_begin(window.key() + ".FACE"); GameexeFilteringIterator end = gexe.filtering_end(); for (; it != end; ++it) { // Retrieve the face slot number std::vector<std::string> key_parts = it->key_parts(); try { int slot = boost::lexical_cast<int>(key_parts.at(3)); if (slot < kNumFaceSlots) { face_slot_[slot].reset(new FaceSlot(it->to_intVector())); } } catch (...) { // Parsing failure. Ignore this key. } } }