예제 #1
0
파일: Music.cpp 프로젝트: Aerospyke/solarus
/**
 * @brief Creates a new music.
 * @param music_id id of the music (a file name)
 */
Music::Music(const MusicId& music_id):
  id(music_id) {

  if (!is_initialized() || music_id == none) {
    return;
  }

  // compute the file name
  file_name = (std::string) "musics/" + music_id;

  // get the format
  size_t index = music_id.find_last_of(".");
  Debug::check_assertion(index != std::string::npos && index != music_id.size(),
    StringConcat() << "Invalid music file name: " << music_id);
  std::string extension = music_id.substr(index + 1);

  if (extension == "spc" || extension == "SPC" || extension == "Spc") {
    format = SPC;
  }
  else if (extension == "it" || extension == "IT" || extension == "It") {
    format = IT;
  }
  else if (extension == "ogg" || extension == "OGG" || extension == "Ogg") {
    format = OGG;
  }
  else {
    Debug::die(StringConcat() << "Unrecognized music file format: " << music_id);
  }

  for (int i = 0; i < nb_buffers; i++) {
    buffers[i] = AL_NONE;
  }
  source = AL_NONE;
}
예제 #2
0
/*
=================
UI_CreateGame_GetMapsList
=================
*/
static void UI_CreateGame_GetMapsList( void )
{
	char *afile;

	if( !CHECK_MAP_LIST( FALSE ) || (afile = (char *)LOAD_FILE( "maps.lst", NULL )) == NULL )
	{
		uiCreateGame.done.generic.flags |= QMF_GRAYED;
		uiCreateGame.mapsList.itemNames = (const char **)uiCreateGame.mapsDescriptionPtr;
		Con_Printf( "Cmd_GetMapsList: can't open maps.lst\n" );
		return;
	}

	char *pfile = afile;
	char token[1024];
	int numMaps = 0;
	
	while(( pfile = COM_ParseFile( pfile, token )) != NULL )
	{
		if( numMaps >= UI_MAXGAMES ) break;
		StringConcat( uiCreateGame.mapName[numMaps], token, sizeof( uiCreateGame.mapName[0] ));
		StringConcat( uiCreateGame.mapsDescription[numMaps], token, MAPNAME_LENGTH );
		StringConcat( uiCreateGame.mapsDescription[numMaps], uiEmptyString, MAPNAME_LENGTH );
		if(( pfile = COM_ParseFile( pfile, token )) == NULL ) break; // unexpected end of file
		StringConcat( uiCreateGame.mapsDescription[numMaps], token, TITLE_LENGTH );
		StringConcat( uiCreateGame.mapsDescription[numMaps], uiEmptyString, TITLE_LENGTH );
		uiCreateGame.mapsDescriptionPtr[numMaps] = uiCreateGame.mapsDescription[numMaps];
		numMaps++;
	}

	if( !numMaps ) uiCreateGame.done.generic.flags |= QMF_GRAYED;

	for( ; numMaps < UI_MAXGAMES; numMaps++ ) uiCreateGame.mapsDescriptionPtr[numMaps] = NULL;
	uiCreateGame.mapsList.itemNames = (const char **)uiCreateGame.mapsDescriptionPtr;
	FREE_FILE( afile );
}
예제 #3
0
/**
 * \brief Loads the fonts.
 */
void TextSurface::load_fonts() {

    // Load the list of available fonts.
    static const std::string file_name = "text/fonts.dat";

    lua_State* l = luaL_newstate();
    size_t size;
    char* buffer;
    FileTools::data_file_open_buffer(file_name, &buffer, &size);
    int load_result = luaL_loadbuffer(l, buffer, size, file_name.c_str());
    FileTools::data_file_close_buffer(buffer);

    if (load_result != 0) {
        Debug::die(StringConcat() << "Failed to load the fonts file '"
                   << file_name << "': " << lua_tostring(l, -1));
        lua_pop(l, 1);
    }
    else {
        lua_register(l, "font", l_font);
        if (lua_pcall(l, 0, 0, 0) != 0) {
            Debug::die(StringConcat() << "Failed to load the fonts file '"
                       << file_name << "': " << lua_tostring(l, -1));
            lua_pop(l, 1);
        }
    }

    lua_close(l);
    fonts_loaded = true;
}
예제 #4
0
/**
 * @brief Initializes the font system.
 */
void TextSurface::initialize() {

  TTF_Init();

  // first determine the available fonts
  IniFile ini("text/fonts.dat", IniFile::READ);
  for (ini.start_group_iteration(); ini.has_more_groups(); ini.next_group()) {

    // get the font metadata
    std::string font_id = ini.get_group();
    std::string file_name = ini.get_string_value("file", "");
    Debug::check_assertion(file_name.size() > 0, StringConcat() << "Missing font file name in file 'text/fonts.dat' for group '" << font_id << "'");
    int font_size = ini.get_integer_value("size", 0);
    Debug::check_assertion(font_size > 0, StringConcat() << "Missing font size in file 'text/fonts.dat' for group '" << font_id << "'");
    fonts[font_id].file_name = file_name;
    fonts[font_id].font_size = font_size;

    if (ini.get_boolean_value("default", false)) {
      default_font_id = font_id;
    }

    // load the font
    size_t size;
    FileTools::data_file_open_buffer(file_name, &fonts[font_id].buffer, &size);
    fonts[font_id].rw = SDL_RWFromMem(fonts[font_id].buffer, int(size));
    fonts[font_id].internal_font = TTF_OpenFontRW(fonts[font_id].rw, 0, font_size);
    Debug::check_assertion(fonts[font_id].internal_font != NULL, StringConcat() << "Cannot load font from file '" << file_name << "': " << TTF_GetError());
  }

  Debug::check_assertion(default_font_id.size() > 0, "No default font set in file 'text/fonts.dat'");
}
예제 #5
0
파일: Script.cpp 프로젝트: AlanTR/solarus
/**
 * @brief Calls a Lua function of the current script, possibly with arguments and return values of various types.
 *
 * This is just a convenient method to push the parameters and pop the results for you
 * in addition to calling the Lua function.
 * However, this function uses the variable number of parameters mechanism of cstdarg, which
 * is inherently C and not C++.
 * This means you have to use C-style strings instead of std::string.
 *
 * The arguments and results of the Lua function are passed thanks to the variable number of
 * parameters (possibly of different types) of this C++ method.
 * The format parameter of this C++ method specifies the type of each
 * argument and each result of the Lua function to call.
 * The types of the arguments should be described in the format string as a sequence of characters
 * where each character represents a type ('i': int, 'b': bool, 's': const char*).
 * If you expect some results to get returned by the Lua function,
 * the format string should then take a space character,
 * and the types of the results are then specified in the same way,
 * except that results of type string are not accepted.
 * The space character is optional if no result is returned.
 * This means an empty format string can be used when the Lua function has no argument
 * and no return value.
 *
 * The remaining parameters of this C++ method (of variable number)
 * must match the specified format,
 * passing values for the arguments and pointers for the results.
 *
 * Let's take an example:
 * assuming that the Lua function you want to call takes as arguments
 * a string plus two integers and returns a boolean,
 * the format string you should specify is: "sii b".
 * You should then give four parameters of types const char*, int, int and bool*.
 *
 * If the Lua function does not exists in the script,
 * nothing happens and this C++ function returns false.
 * It just means that the function corresponds to an event that
 * the script does not want to handle.
 * If the Lua function exists, the arguments are pushed onto the stack, the function is executed,
 * the results (if any) are popped from the stack and stored into your pointed areas,
 * and this C++ method returns true.
 * In both cases, the Lua stack is left unchanged.
 *
 * This function does not support results of type string because it would cause some
 * complications and we want to keep its usage simple.
 * If you need to call a function with a result of type string, you can still do it,
 * but not with this C++ method.
 * I explain now what the problem is with string results.
 * If a Lua function returns a string, the memory used by the const char* pointer is discarded
 * when the C++ code pops it from the stack.
 * And this C++ method is supposed to to the job for you, so it pops the results
 * from the stack before returning them to you.
 * As a consequence, allowing string results
 * would require that you pop the results yourself, after having read them.
 * Another solution would be to return a copy of the string,
 * but because the variable number of parameters mechanism cannot use std::string,
 * the copy would be a const char* that you would have to free yourself.
 * As this function wants to simplify your code by doing the job for you,
 * both solutions are bad ideas.
 * However, in Solarus, calling Lua from C++ is used only to notify a script that something
 * happened (recall the name of this C++ method), not to ask strings to them.
 *
 * @param function_name name of the function to call
 * (may be prefixed by the name of several Lua tables, typically sol.main.some_function)
 * @param format a string describing the types of arguments to pass to the Lua function
 * and the types of return values to get (see above)
 * @return true if the function was called successfully, false if it does not exist
 */
bool Script::notify_script(const std::string& function_name, const char* format, ...) {

  // find the function and push it onto the stack
  bool exists = find_lua_function(function_name);

  if (exists) {

    va_list args;
    va_start(args, format);

    // push the arguments
    unsigned int i;
    unsigned int nb_arguments = 0;
    bool end_arguments = false;
    for (i = 0; i < strlen(format) && !end_arguments; i++) {
      switch (format[i]) {
        case 'i':	lua_pushinteger(l, va_arg(args, int));	break;
        case 'b':	lua_pushboolean(l, va_arg(args, int));	break; 		// cstdarg refuses bool
        case 's':	lua_pushstring(l, va_arg(args, const char*));	break;	// and std::string
        case ' ':	end_arguments = true;	break;
        default:	Debug::die(StringConcat() << "Invalid character '" << format[i] << "' in format string '" << format);
      }

      if (format[i] != ' ') {
        nb_arguments++;
      }
    }

    // call the function
    int nb_results = strlen(format) - i;
    if (lua_pcall(l, nb_arguments, nb_results, 0) != 0) {
      Debug::print(StringConcat() << "Error in " << function_name << "(): "
          << lua_tostring(l, -1));
      lua_pop(l, 1);
      nb_results = 0;
    }

    // get the results
    for (int i = 0; i < nb_results; i++) {
      char type = format[nb_arguments + i + 1];
      int stack_index = -nb_results + i;
      switch (type) {
        case 'i':	*va_arg(args, int*) = lua_tointeger(l, stack_index);	break;
        case 'b':	*va_arg(args, int*) = lua_toboolean(l, stack_index);	break;
        case 's':	Debug::die("String results are not supported by Script::notify_script(), please make the call yourself");
        default:	Debug::die(StringConcat() << "Invalid character '" << type << "' in format string '" << format);
      }
    }
    lua_pop(l, nb_results);
    va_end(args);
  }

  return exists;
}
예제 #6
0
/**
 * \brief Returns a boolean value saved.
 * \param key Name of the value to get.
 * \return The boolean value associated with this key or false.
 */
bool Savegame::get_boolean(const std::string& key) {

  Debug::check_assertion(LuaContext::is_valid_lua_identifier(key), StringConcat() <<
      "Savegame variable '" << key << "' is not a valid key");

  bool result = false;
  if (saved_values.count(key) > 0) {
    const SavedValue& value = saved_values[key];
    Debug::check_assertion(value.type == SavedValue::VALUE_BOOLEAN, StringConcat() <<
        "Value '" << key << "' is not a boolean");
    result = value.int_data != 0;
  }
  return result;
}
예제 #7
0
/**
 * \brief Returns a integer value saved.
 * \param key Name of the value to get.
 * \return The integer value associated with this key or 0.
 */
int Savegame::get_integer(const std::string& key) {

  Debug::check_assertion(LuaContext::is_valid_lua_identifier(key), StringConcat() <<
      "Savegame variable '" << key << "' is not a valid key");

  int result = 0;
  if (saved_values.count(key) > 0) {
    const SavedValue& value = saved_values[key];
    Debug::check_assertion(value.type == SavedValue::VALUE_INTEGER, StringConcat() <<
        "Value '" << key << "' is not an integer");
    result = value.int_data;
  }
  return result;
}
예제 #8
0
/*
=================
UI_PlayDemo_GetDemoList
=================
*/
static void UI_PlayDemo_GetDemoList( void )
{
	char	comment[256];
	char	**filenames;
	int	i, numFiles;

	filenames = FS_SEARCH( "demos/*.dem", &numFiles, TRUE );

	for( i = 0; i < numFiles; i++ )
	{
		if( i >= UI_MAXGAMES ) break;
		
		if( !GET_DEMO_COMMENT( filenames[i], comment ))
		{
			if( strlen( comment ))
			{
				// get name string even if not found - CL_GetComment can be mark demos
				// as <CORRUPTED> <OLD VERSION> etc
				StringConcat( uiPlayDemo.demoDescription[i], uiEmptyString, TITLE_LENGTH );
				StringConcat( uiPlayDemo.demoDescription[i], comment, MAPNAME_LENGTH );
				StringConcat( uiPlayDemo.demoDescription[i], uiEmptyString, MAXCLIENTS_LENGTH );
				uiPlayDemo.demoDescriptionPtr[i] = uiPlayDemo.demoDescription[i];
				COM_FileBase( filenames[i], uiPlayDemo.delName[i] );
			}
			else uiPlayDemo.demoDescriptionPtr[i] = NULL;
			continue;
		}

		// strip path, leave only filename (empty slots doesn't have savename)
		COM_FileBase( filenames[i], uiPlayDemo.demoName[i] );
		COM_FileBase( filenames[i], uiPlayDemo.delName[i] );

		// fill demo desc
		StringConcat( uiPlayDemo.demoDescription[i], comment + CS_SIZE, TITLE_LENGTH );
		StringConcat( uiPlayDemo.demoDescription[i], uiEmptyString, TITLE_LENGTH );
		StringConcat( uiPlayDemo.demoDescription[i], comment, MAPNAME_LENGTH );
		StringConcat( uiPlayDemo.demoDescription[i], uiEmptyString, MAPNAME_LENGTH ); // fill remaining entries
		StringConcat( uiPlayDemo.demoDescription[i], comment + CS_SIZE * 2, MAXCLIENTS_LENGTH );
		StringConcat( uiPlayDemo.demoDescription[i], uiEmptyString, MAXCLIENTS_LENGTH );
		uiPlayDemo.demoDescriptionPtr[i] = uiPlayDemo.demoDescription[i];
	}

	for ( ; i < UI_MAXGAMES; i++ )
		uiPlayDemo.demoDescriptionPtr[i] = NULL;
	uiPlayDemo.demosList.itemNames = (const char **)uiPlayDemo.demoDescriptionPtr;

	if( strlen( uiPlayDemo.demoName[0] ) == 0 )
		uiPlayDemo.play.generic.flags |= QMF_GRAYED;
	else uiPlayDemo.play.generic.flags &= ~QMF_GRAYED;

	if( strlen( uiPlayDemo.delName[0] ) == 0 || !stricmp( gpGlobals->demoname, uiPlayDemo.delName[uiPlayDemo.demosList.curItem] ))
		uiPlayDemo.remove.generic.flags |= QMF_GRAYED;
	else uiPlayDemo.remove.generic.flags &= ~QMF_GRAYED;
}
예제 #9
0
/**
 * \brief Returns a string value saved.
 * \param key Name of the value to get.
 * \return The string value associated with this key or an empty string.
 */
const std::string& Savegame::get_string(const std::string& key) {

  Debug::check_assertion(LuaContext::is_valid_lua_identifier(key), StringConcat() <<
      "Savegame variable '" << key << "' is not a valid key");

  if (saved_values.count(key) > 0) {
    const SavedValue& value = saved_values[key];
    Debug::check_assertion(value.type == SavedValue::VALUE_STRING, StringConcat() <<
        "Value '" << key << "' is not a string");
    return value.string_data;
  }

  static const std::string empty_string = "";
  return empty_string;
}
예제 #10
0
/**
 * @brief Returns the value of a property of this movement.
 *
 * Accepted keys:
 * - path
 * - speed
 * - loop
 * - ignore_obstacles
 * - snap_to_grid
 *
 * @param key key of the property to get
 * @return the corresponding value as a string
 */
const std::string PathMovement::get_property(const std::string &key) {

  std::ostringstream oss;

  if (key == "path") {
    oss << initial_path;
  }
  else if (key == "speed") {
    oss << speed;
  }
  else if (key == "loop") {
    oss << loop;
  }
  else if (key == "ignore_obstacles") {
    oss << are_obstacles_ignored();
  }
  else if (key == "snap_to_grid") {
    oss << snap_to_grid;
  }
  else {
    Debug::die(StringConcat() << "Unknown property of PathMovement: '" << key << "'");
  }

  return oss.str();
}
예제 #11
0
/**
 * \brief Returns the index of the savegame variable that stores the specified ability.
 * \param ability_name Name of the ability.
 * \return Name of the boolean savegame variable that stores this ability.
 */
std::string Equipment::get_ability_savegame_variable(
    const std::string& ability_name) const {

  std::string savegame_variable;

  if (ability_name == "tunic") {
    savegame_variable = Savegame::KEY_ABILITY_TUNIC;
  }
  else if (ability_name == "sword") {
    savegame_variable = Savegame::KEY_ABILITY_SWORD;
  }
  else if (ability_name == "sword_knowledge") {
    savegame_variable = Savegame::KEY_ABILITY_SWORD_KNOWLEDGE;
  }
  else if (ability_name == "shield") {
    savegame_variable = Savegame::KEY_ABILITY_SHIELD;
  }
  else if (ability_name == "lift") {
    savegame_variable = Savegame::KEY_ABILITY_LIFT;
  }
  else if (ability_name == "swim") {
    savegame_variable = Savegame::KEY_ABILITY_SWIM;
  }
  else if (ability_name == "run") {
    savegame_variable = Savegame::KEY_ABILITY_RUN;
  }
  else if (ability_name == "detect_weak_walls") {
    savegame_variable = Savegame::KEY_ABILITY_DETECT_WEAK_WALLS;
  }
  else {
    Debug::die(StringConcat() << "Unknown ability '" << ability_name << "'");
  }

  return savegame_variable;
}
예제 #12
0
파일: Script.cpp 프로젝트: AlanTR/solarus
/**
 * @brief Updates the script.
 */
void Script::update() {

  // update the timers
  std::map<int, Timer*>::iterator it;

  for (it = timers.begin(); it != timers.end(); it++) {

    int ref = it->first;
    Timer* timer = it->second;

    timer->update();
    if (timer->is_finished()) {

      // delete the C++ timer
      timers.erase(it);
      delete timer;

      // retrieve the Lua function and call it
      lua_rawgeti(l, LUA_REGISTRYINDEX, ref);
      if (lua_pcall(l, 0, 0, 0) != 0) {
        Debug::print(StringConcat() << "Error in the function of the timer: "
            << lua_tostring(l, -1));
        lua_pop(l, 1);
      }

      // delete the Lua function
      luaL_unref(l, LUA_REGISTRYINDEX, ref);

      break;
    }
  }
}
예제 #13
0
파일: Script.cpp 프로젝트: AlanTR/solarus
/**
 * @brief Returns a sprite handled by this script.
 * @param sprite_handle handle of the sprite to get
 * @return the corresponding sprite
 */
Sprite& Script::get_sprite(int sprite_handle) {

  Debug::check_assertion(sprites.count(sprite_handle) > 0,
    StringConcat() << "No sprite with handle '" << sprite_handle << "'");

  return *sprites[sprite_handle];
}
예제 #14
0
파일: Script.cpp 프로젝트: AlanTR/solarus
/**
 * @brief Initializes the Lua context and loads the script from a file.
 *
 * If the script file does not exist, the field context is NULL.
 *
 * @param script_name name of a Lua script file (without extension)
 */
void Script::load_if_exists(const std::string& script_name) {

  if (l == NULL) {
    initialize_lua_context();
  }

  // determine the file name (.lua)
  std::ostringstream oss;
  oss << script_name << ".lua";
  std::string file_name = oss.str();

  if (FileTools::data_file_exists(file_name)) {
    // load the file
    size_t size;
    char* buffer;
    FileTools::data_file_open_buffer(file_name, &buffer, &size);
    luaL_loadbuffer(l, buffer, size, file_name.c_str());
    FileTools::data_file_close_buffer(buffer);
    if (lua_pcall(l, 0, 0, 0) != 0) {
      Debug::die(StringConcat() << "Error: failed to load script '" << script_name
          << "': " << lua_tostring(l, -1));
      lua_pop(l, 1);
    }
  }
  else {
    // uninitialize Lua
    lua_close(l);
    l = NULL;
  }
}
예제 #15
0
/**
 * @brief Sets the number of rotations of the movement.
 *
 * When this number of rotations is reached, the movement stops.
 * Note that is the radius changes gradually, the movement will continue
 * for a while until the radius reaches zero.
 *
 * @param max_rotations number of rotations to make (0 for infinite rotations)
 */
void CircleMovement::set_max_rotations(int max_rotations) {

  Debug::check_assertion(max_rotations >= 0, StringConcat() << "Invalid maximum rotations number: " << max_rotations);

  this->max_rotations = max_rotations;
  this->nb_rotations = 0;
}
예제 #16
0
/**
 * \brief Unsets a value saved.
 * \param key Name of the value to unset.
 */
void Savegame::unset(const std::string& key) {

  Debug::check_assertion(LuaContext::is_valid_lua_identifier(key), StringConcat() <<
      "Savegame variable '" << key << "' is not a valid key");

  saved_values.erase(key);
}
예제 #17
0
/**
 * @brief Sets the map.
 *
 * Warning: as this function is called when initializing the map,
 * the current map of the game is still the old one.
 *
 * @param map the map
 */
void Teletransporter::set_map(Map &map) {

  MapEntity::set_map(map);

  if (destination_point_name == "_side") {

    int x = get_x();
    int y = get_y();

    if (get_width() == 16 && x == -16) {
      destination_side = 0;
    }
    else if (get_width() == 16 && x == map.get_width()) {
      destination_side = 2;
    }
    else if (get_height() == 16 && y == -16) {
      destination_side = 3;
    }
    else if (get_height() == 16 && y == map.get_height()) {
      destination_side = 1;
    }
    else {
      Debug::die(StringConcat() << "Bad position of teletransporter '" << get_name() << "'"); 
    }
  }

  transition_direction = (destination_side + 2) % 4;
}
예제 #18
0
int main(int argc, char** argv)
{
    FLAGS_alsologtostderr = true;
    google::ParseCommandLineFlags(&argc, &argv, true);
    google::InitGoogleLogging(argv[0]);

    HttpServer server(FLAGS_threads_num);
    ChineseYangHandler handler;
    HttpClosure* task = NewPermanentClosure(
        &handler, &ChineseYangHandler::HandleGet);
    server.RegisterPrefixSimpleHandler("/yang", task);

    std::string address = StringConcat(
        FLAGS_server_ip, ":", FLAGS_server_port);
    if (!server.Start(address)) {
        LOG(ERROR) << "start failed. address " << address;
        return 1;
    }

    LOG(INFO) << "listen on " << address;

    int ret = server.Run();
    LOG(INFO) << "server finish. ret " << ret;

    return ret;
}
예제 #19
0
/**
 * @brief Blits a surface on the screen with the current video mode.
 * @param src_surface the source surface to display on the screen
 */
void VideoManager::display(Surface *src_surface) {

  if (disable_window) {
    return;
  }

  switch (video_mode) {

    case WINDOWED_NORMAL:
      blit(src_surface, screen_surface);
      break;

    case WINDOWED_STRETCHED:
    case FULLSCREEN_NORMAL:
    case FULLSCREEN_WIDE:
      blit_stretched(src_surface, screen_surface);
      break;

    case WINDOWED_SCALE2X:
    case FULLSCREEN_SCALE2X:
    case FULLSCREEN_SCALE2X_WIDE:
      blit_scale2x(src_surface, screen_surface);
      break;

    default:
      Debug::die(StringConcat() << "Unknown video mode " << video_mode);
      break;
  }

  SDL_Flip(screen_surface->get_internal_surface());
}
예제 #20
0
/**
 * \brief Implementation of game:get_value().
 * \param l The Lua context that is calling this function.
 * \return Number of values to return to Lua.
 */
int LuaContext::game_api_get_value(lua_State* l) {

  Savegame& savegame = check_game(l, 1);
  const std::string& key = luaL_checkstring(l, 2);

  if (!is_valid_lua_identifier(key)) {
    arg_error(l, 3, StringConcat() <<
        "Invalid savegame variable '" << key <<
        "': the name should only contain alphanumeric characters or '_'" <<
        " and cannot start with a digit");
  }

  if (savegame.is_boolean(key)) {
    lua_pushboolean(l, savegame.get_boolean(key));
  }
  else if (savegame.is_integer(key)) {
    lua_pushinteger(l, savegame.get_integer(key));
  }
  else if (savegame.is_string(key)) {
    lua_pushstring(l, savegame.get_string(key).c_str());
  }
  else {
    lua_pushnil(l);
  }

  return 1;
}
예제 #21
0
/**
 * @brief Initializes the text resource by loading all strings.
 *
 * The strings are loaded from the language-specific file "text/strings.dat"
 * and stored into memory for future access by get_string().
 */
void StringResource::initialize() {

  strings.clear();
  std::istream &file = FileTools::data_file_open("text/strings.dat", true);
  std::string line;

  // read each line
  int i = 0;
  while (std::getline(file, line)) {

    i++;

    // ignore empty lines or lines starting with '#'
    if (line.size() == 0 || line[0] == '#') {
      continue;
    }
 
    // get the key
    std::string key = line.substr(0, line.find_first_of(" \t"));

    // get the value
    size_t index = line.find_last_of("\t");
    Debug::check_assertion(index != std::string::npos && index + 1 < line.size(),
      StringConcat() << "strings.dat, line " << i << ": cannot read string value for key '" << key << "'");
    strings[key] = line.substr(index + 1);
  }

  FileTools::data_file_close(file);
}
예제 #22
0
파일: Sound.cpp 프로젝트: ziz/solarus
/**
 * @brief Sets the volume of sound effects.
 * @param volume the new volume (0 to 100)
 */
void Sound::set_volume(int volume) {

  Debug::check_assertion(volume >= 0 && volume <= 100, StringConcat() << "Illegal volume for sound effects:" << volume);

  Configuration::set_value("sound_volume", volume);
  Sound::volume = volume / 100.0;
}
예제 #23
0
파일: Surface.cpp 프로젝트: Arvek/SOLARME
/**
 * \brief Creates a surface from the specified image file name.
 *
 * An assertion error occurs if the file cannot be loaded.
 *
 * \param file_name Name of the image file to load, relative to the base directory specified.
 * \param base_directory The base directory to use.
 */
Surface::Surface(const std::string& file_name, ImageDirectory base_directory):
  Drawable(),
  internal_surface(NULL),
  owns_internal_surface(true),
  with_colorkey(false),
  colorkey(0) {

  std::string prefix = "";
  bool language_specific = false;

  if (base_directory == DIR_SPRITES) {
    prefix = "sprites/";
  }
  else if (base_directory == DIR_LANGUAGE) {
    language_specific = true;
    prefix = "images/";
  }
  std::string prefixed_file_name = prefix + file_name;

  size_t size;
  char* buffer;
  FileTools::data_file_open_buffer(prefixed_file_name, &buffer, &size, language_specific);
  SDL_RWops* rw = SDL_RWFromMem(buffer, int(size));
  this->internal_surface = IMG_Load_RW(rw, 0);
  FileTools::data_file_close_buffer(buffer);
  SDL_RWclose(rw);

  Debug::check_assertion(internal_surface != NULL, StringConcat() <<
      "Cannot load image '" << prefixed_file_name << "'");
    
  with_colorkey = SDL_GetColorKey(internal_surface, &colorkey) == 0;
}
예제 #24
0
/**
 * @brief Returns the point located just outside the hookshot's collision box,
 * in its current direction.
 */
const Rectangle Hookshot::get_facing_point() {

  Rectangle facing_point = get_center_point();

  switch (get_sprite().get_current_direction()) {

    // right
    case 0:
      facing_point.add_x(8);
      break;

      // up
    case 1:
      facing_point.add_y(-9);
      break;

      // left
    case 2:
      facing_point.add_x(-9);
      break;

      // down
    case 3:
      facing_point.add_y(8);
      break;

    default:
      Debug::die(StringConcat() << "Invalid direction for Hookshot::get_facing_point(): "
          << get_sprite().get_current_direction());
  }

  return facing_point;
}
예제 #25
0
/**
 * \brief Sets the maximum amount of money of the player.
 * \param max_money the player's maximum amount number of money
 */
void Equipment::set_max_money(int max_money) {

  Debug::check_assertion(max_money > 0, StringConcat()
      << "Illegal maximum amount of money: " << max_money);

  savegame.set_integer(Savegame::KEY_MAX_MONEY, max_money);
}
예제 #26
0
/**
 * \brief Sets the maximum level of life of the player.
 *
 * The program exits with an error message if the specified maximum
 * life is not valid.
 * 
 * \param max_life the player's maximum life
 */
void Equipment::set_max_life(int max_life) {

  Debug::check_assertion(max_life > 0, StringConcat()
      << "Illegal maximum life: " << max_life);

  savegame.set_integer(Savegame::KEY_MAX_LIFE, max_life);
}
예제 #27
0
파일: Script.cpp 프로젝트: AlanTR/solarus
/**
 * @brief Starts a timer to run a Lua function after the delay.
 *
 * The Lua function must be on the top of the stack and will be popped.
 * If the duration is set to zero, the function is executed immediately.
 *
 * @param l a Lua state
 * @param duration the timer duration in milliseconds
 * @param with_sound true to play a clock sound until the timer expires
 */
void Script::add_timer(lua_State* l, uint32_t duration, bool with_sound) {

  if (duration == 0) {
    // directly call the function
    if (lua_pcall(l, 0, 0, 0) != 0) {
      Debug::print(StringConcat() << "Error in the function of the timer: "
          << lua_tostring(l, -1));
      lua_pop(l, 1);
    }
  }
  else {
    // store the function into the Lua registry
    int ref = luaL_ref(l, LUA_REGISTRYINDEX);

    // retrieve the script
    lua_getfield(l, LUA_REGISTRYINDEX, "sol.cpp_object");
    Script* script = (Script*) lua_touserdata(l, -1);
    lua_pop(l, 1);

    // create the timer
    Timer* timer = new Timer(duration, with_sound);
    if (script->is_new_timer_suspended()) {
      timer->set_suspended(true);
    }
    script->timers[ref] = timer;
  }
}
예제 #28
0
/**
 * \brief Returns an equipment item.
 * \param item_name Name of the item to get.
 * \return The corresponding item.
 */
const EquipmentItem& Equipment::get_item(const std::string& item_name) const {

  Debug::check_assertion(item_exists(item_name),
      StringConcat() << "Cannot find item with name '" << item_name << "'");

  return *items.find(item_name)->second;
}
예제 #29
0
파일: Script.cpp 프로젝트: AlanTR/solarus
/**
 * @brief Returns a movement handled by this script.
 * @param movement_handle handle of the movement to get
 * @return the corresponding movement
 */
Movement& Script::get_movement(int movement_handle) {

  Debug::check_assertion(movements.count(movement_handle) > 0,
    StringConcat() << "No movement with handle '" << movement_handle << "'");

  return *movements[movement_handle];
}
예제 #30
0
파일: Treasure.cpp 프로젝트: Arvek/SOLARME
/**
 * \brief Raises an assertion error if the player cannot obtain this treasure.
 */
void Treasure::check_obtainable() const {

  Debug::check_assertion(item_name.empty()
      || game->get_equipment().get_item(item_name).is_obtainable(),
      StringConcat() << "Treasure '" << item_name
      << "' is not allowed, did you call ensure_obtainable()?");
}