/* Called when the user clicks the 'Save As' menu. We need to allow the user to choose a file to save and then call write_file() on that file. */ void on_save_as_menu_item_activate (GtkMenuItem *menuitem, TutorialTextEditor *editor) { gchar *filename; filename = get_save_filename (editor); if (filename != NULL) write_file (editor, filename); }
bool pyjama_party_save(void) { /* Save all the pyjama party girls and stuff. */ char * buf; int bufsize; bool rv; rv = true; bufsize = globals.pyjama_party_girls_size * sizeof(globals.pyjama_party_girls[0]->name) + 1; buf = malloc(bufsize); assert(buf != NULL); strcpy(buf, ""); for(int i = 0; i < globals.pyjama_party_girls_size; i++) { if(girl_save(globals.pyjama_party_girls[i]) == true) snprintf(buf + strlen(buf), bufsize - strlen(buf), "%s\n", globals.pyjama_party_girls[i]->name); else rv = false; } if(write_file(get_save_filename("party/order"), buf, strlen(buf) + 1) == false) rv = false; free(buf); return rv; }
void MaterialItem::slot_export() { const char* project_path = m_editor_context.m_project.get_path(); const filesystem::path project_root_path = filesystem::path(project_path).parent_path(); const filesystem::path file_path = absolute("material.dmt", project_root_path); const filesystem::path file_root_path = file_path.parent_path(); QString filepath = get_save_filename( 0, "Export...", "Disney Materials (*.dmt)", m_editor_context.m_settings, SETTINGS_FILE_DIALOG_PROJECTS); if (!filepath.isEmpty()) { if (QFileInfo(filepath).suffix().isEmpty()) filepath += ".dmt"; filepath = QDir::toNativeSeparators(filepath); ParamArray parameters = m_entity->get_parameters(); parameters.insert("__name", m_entity->get_name()); parameters.insert("__model", m_entity->get_model()); SettingsFileWriter writer; if (!writer.write(filepath.toStdString().c_str(), parameters)) { show_error_message_box( "Exporting Error", "Failed to export the Disney Material file " + filepath.toStdString() + "."); } } }
void highscores_delete(struct highscorelist * list) { assert(list->filename != NULL); if(globals.read_only == false) { unlink(get_save_filename(list->filename)); for(unsigned int i = 0; i < list->highscores_size; i++) if(list->highscores[i] != NULL) { char fn[256]; snprintf(fn, sizeof fn, "%s-%d.dgp.bz2", list->filename, list->highscores[i]->playback_id); unlink(get_save_filename(fn)); } } }
G_MODULE_EXPORT void on_menu_export_activate (GtkWidget *widget, void *user) { gchar* filename = NULL; filename = get_save_filename (TYPE_PDF); if (filename) latex_export_pdffile (gummi->latex, g_active_editor, filename, TRUE); g_free (filename); }
G_MODULE_EXPORT void on_menu_projcreate_activate (GtkWidget *widget, void *user) { gchar* filename = get_save_filename (TYPE_PROJECT); if (!filename) return; if (project_create_new (filename)) { projectgui_enable (gummi->project, gui->projectgui); projectgui_list_projfiles (gummi->project->projfile); } }
G_MODULE_EXPORT void on_menu_export_activate(GtkWidget *widget, void *user) { gchar* filename = NULL; filename = get_save_filename(TYPE_PDF); if (filename){ if(strlen(filename) > 4 && STR_EQU(filename + strlen(filename) - 4, ".tex")){ latex_export_pdffile(gummi->latex, g_active_editor, filename, TRUE); } } g_free(filename); }
void PythonConsoleWidget::slot_save_file_as() { // todo: we shouldn't have to go through the Python interpreter to retrieve application settings. ParamArray& settings = PythonInterpreter::instance().get_main_window()->get_application_settings(); const QString filepath = get_save_filename( this, "Save As...", "Python Script File (*.py)", settings, SETTINGS_FILE_DIALOG_PYTHON_SCRIPTS); if (!filepath.isEmpty()) save_file(filepath.toStdString()); }
bool pyjama_party_load(void) { /* Load all the pyjama party girls and stuff. */ char * buf; int bufsize; bool rv; globals.pyjama_party_girls_size = 0; globals.pyjama_party_girls = NULL; rv = read_file(get_save_filename("party/order"), &buf, &bufsize); if(rv == true) { char * curpos, * sep; curpos = buf; do { sep = strchr(curpos, '\n'); if(sep != NULL) { *sep = '\0'; curpos = sep + 1; globals.pyjama_party_girls_size++; } } while(sep != NULL); if(globals.pyjama_party_girls_size > 0) { globals.pyjama_party_girls = malloc(sizeof(struct girl *) * globals.pyjama_party_girls_size); assert(globals.pyjama_party_girls != NULL); for(int i = 0; i < globals.pyjama_party_girls_size; i++) globals.pyjama_party_girls[i] = NULL; curpos = buf; for(int i = 0; i < globals.pyjama_party_girls_size; i++) { globals.pyjama_party_girls[i] = girl_load(curpos); curpos += strlen(curpos) + 1; } } free(buf); } return rv; }
void LightPathsTab::slot_save_light_paths() { QString filepath = get_save_filename( this, "Save Light Paths As...", "Light Paths Files (*.aspaths);;All Files (*.*)", m_settings, SETTINGS_FILE_DIALOG_LIGHT_PATHS); if (filepath.isEmpty()) return; if (QFileInfo(filepath).suffix().isEmpty()) filepath += ".aspaths"; filepath = QDir::toNativeSeparators(filepath); // Write light paths to disk. m_project.get_light_path_recorder().write(filepath.toAscii().constData()); }
void ExpressionEditorWindow::slot_save_script() { if (m_script_filepath.empty()) { QString filepath = get_save_filename( this, "Save As...", "Expression Scripts (*.se)", m_settings, SETTINGS_FILE_DIALOG_MATERIALS); if (!filepath.isEmpty()) { if (QFileInfo(filepath).suffix().isEmpty()) filepath += ".se"; filepath = QDir::toNativeSeparators(filepath); m_script_filepath = filepath.toStdString(); } } if (!m_script_filepath.empty()) { ofstream script_file(m_script_filepath.c_str()); if (!script_file.is_open()) { show_error_message_box( "Saving Error", "Failed to save the expression script file " + m_script_filepath + "."); return; } script_file << m_editor->getExpr(); script_file.close(); } }
struct playback * highscore_playback(struct highscore_entry * entry, enum GAME_MODE game_mode) { if(entry->playback == NULL) { char * fn; fn = highscore_filename(game_mode, entry->cave); if(fn != NULL) { char fnbuf[256]; snprintf(fnbuf, sizeof fnbuf, "%s-%d.dgp", fn, entry->playback_id); free(fn); entry->playback = playback_load(get_save_filename(fnbuf)); } else fprintf(stderr, "%s(): Failed to allocate memory: %s\n", __FUNCTION__, strerror(errno)); } return entry->playback; }
void settings_write(void) { /* write settings */ if(globals.write_settings == true) { FILE * fp; const char * filename; filename = get_save_filename("settings.json"); fp = fopen(filename, "w"); if(fp != NULL) { char linebuf[1024]; bool ok; ok = true; if(ok == true) { snprintf(linebuf, sizeof linebuf, "{ \"Fullscreen\": %s,\n", globals.fullscreen ? "true" : "false"); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } if(ok == true && globals.locale_save == true && globals.locale != NULL) { snprintf(linebuf, sizeof linebuf, " \"Locale\": \"%s\",\n", globals.locale); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } if(ok == true) { snprintf(linebuf, sizeof linebuf, " \"OpenGL\": %s,\n \"OpenGL_POT\": %s,\n \"OpenGL_compressed_textures\": %s,\n", globals.opengl ? "true" : "false", globals.opengl_power_of_two_textures ? "true" : "false", globals.opengl_compressed_textures ? "true" : "false"); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } if(ok == true) { snprintf(linebuf, sizeof linebuf, " \"SFX\": %s,\n \"Music\": %s,\n \"SFX_max_channels\": %d,\n \"Sound_volume\": %u,\n", globals.use_sfx ? "true" : "false", globals.use_music ? "true" : "false", globals.max_channels, globals.volume); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } if(ok == true) { snprintf(linebuf, sizeof linebuf, " \"Joysticks\": %s,\n", globals.use_joysticks ? "true" : "false"); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } if(ok == true) { snprintf(linebuf, sizeof linebuf, " \"CaveSelection\": \"%s\",\n \"CaveSelectionLevel\": %d,\n", globals.cave_selection, (int) globals.level_selection); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } if(ok == true) { snprintf(linebuf, sizeof linebuf, " \"ShowFPS\": %s,\n", globals.fps_counter_active == true ? "true" : "false"); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } if(ok == true) { char modename[32]; switch(globals.title_game_mode) { case GAME_MODE_CLASSIC: strcpy(modename, "classic"); break; case GAME_MODE_ADVENTURE: strcpy(modename, "adventure"); break; case GAME_MODE_PYJAMA_PARTY: strcpy(modename, "pyjama_party"); break; } snprintf(linebuf, sizeof linebuf, " \"GameMode\": \"%s\",\n \"IronGirlMode\": %s,\n", modename, globals.iron_girl_mode ? "true" : "false"); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } if(ok == true) { snprintf(linebuf, sizeof linebuf, " \"ActiveQuestline\": %u,\n", (unsigned int) globals.active_questline); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } if(ok == true) { snprintf(linebuf, sizeof linebuf, " \"TitleMidarea\": \"%s\",\n", globals.title_midarea == 0 ? "arcade" : "quests"); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } if(ok == true) { snprintf(linebuf, sizeof linebuf, " \"MapTilting\": %s,\n", globals.map_tilting == true ? "true" : "false"); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } if(ok == true) { snprintf(linebuf, sizeof linebuf, " \"SmoothClassicMode\": %s,\n", globals.smooth_classic_mode == true ? "true" : "false"); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } /* Bindings */ struct ui_binding ** bindings; bool first; if(ok == true) { snprintf(linebuf, sizeof linebuf, " \"Bindings\": [\n"); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } first = true; bindings = ui_get_bindings(-1); for(int i = 0; ok == true && bindings[i] != NULL; i++) if(bindings[i]->editable == true) { bool write_it; char * s_command; s_command = ui_command_name(bindings[i]->command); write_it = false; switch(bindings[i]->event.type) { case SDL_KEYDOWN: snprintf(linebuf, sizeof linebuf, " { \"Type\": \"key\", \"Command\": \"%s\", \"Key\": \"%s\", \"Modifiers\": \"%s\" }", s_command, ui_keyboard_key_name(bindings[i]->event.key.keysym.sym), ui_keyboard_modifier_name(bindings[i]->event.key.keysym.mod)); write_it = true; break; case SDL_JOYAXISMOTION: snprintf(linebuf, sizeof linebuf, " { \"Type\": \"joystick_axis\", \"Command\": \"%s\", \"Joystick\": %d, \"Axis\": %d, \"Value\": %d }", s_command, (int) bindings[i]->event.jaxis.which, (int) bindings[i]->event.jaxis.axis, (int) bindings[i]->event.jaxis.value); write_it = true; break; case SDL_JOYBUTTONDOWN: snprintf(linebuf, sizeof linebuf, " { \"Type\": \"joystick_button\", \"Command\": \"%s\", \"Joystick\": %d, \"Button\": %d }", s_command, (int) bindings[i]->event.jbutton.which, (int) bindings[i]->event.jbutton.button); write_it = true; break; default: break; } if(write_it == true) { if(first == true) first = false; else { char tmp[] = ",\n"; if(fwrite(tmp, strlen(tmp), 1, fp) != 1) ok = false; } if(ok == true) if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } } free(bindings); bindings = NULL; if(ok == true) { snprintf(linebuf, sizeof linebuf, "\n ],\n"); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } /* Themes */ struct stack * themes; if(ok == true) { snprintf(linebuf, sizeof linebuf, " \"Themes\": [\n"); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } themes = gc_get_stack(GCT_THEME); first = true; for(unsigned int i = 0; ok == true && i < themes->size; i++) { struct theme * theme; theme = themes->data[i]; if(strcmp(theme->name, "default")) { if(first == true) first = false; else { char tmp[] = ",\n"; if(fwrite(tmp, strlen(tmp), 1, fp) != 1) ok = false; } snprintf(linebuf, sizeof linebuf, " { \"Name\": \"%s\", \"Enabled\": %s }", theme->name, theme->enabled == true ? "true" : "false"); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } } if(ok == true) { snprintf(linebuf, sizeof linebuf, "\n ]\n}\n"); if(fwrite(linebuf, strlen(linebuf), 1, fp) != 1) ok = false; } if(ok == false) fprintf(stderr, "Failed to save settings into '%s': %s\n", filename, strerror(errno)); if(fclose(fp) != 0) fprintf(stderr, "Failed to save settings into '%s': %s\n", filename, strerror(errno)); } else fprintf(stderr, "Failed to save settings into '%s': %s\n", filename, strerror(errno)); } }
bool cave_save(struct cave * cave) { FILE * fp; char fn[1024]; bool success; success = true; if(cave->game_mode == GAME_MODE_PYJAMA_PARTY) snprintf(fn, sizeof fn, "party/data%s", cave_filename(cave->name)); else snprintf(fn, sizeof fn, "data%s", cave_filename(cave->name)); fp = fopen(get_save_filename(fn), "wb"); if(fp != NULL) { size_t buffer_length = 4 + sizeof cave->max_starting_level + sizeof cave->savegame.exists; if(cave->savegame.exists == true) { buffer_length += sizeof cave->savegame.game_level + sizeof cave->savegame.game_speed_modifier + sizeof cave->savegame.starting_girls + sizeof cave->savegame.girls + sizeof cave->savegame.score + sizeof cave->savegame.diamond_score + sizeof cave->savegame.diamonds + sizeof(bool) * cave->savegame.starting_girls + sizeof cave->savegame.pyjama_party_girls_passed ; } unsigned char buffer[buffer_length]; unsigned char * pos; pos = buffer; memcpy(pos, DIAMOND_GIRL_CAVEFILE_V4, 4); pos += 4; memcpy(pos, &cave->max_starting_level, sizeof cave->max_starting_level); pos += sizeof cave->max_starting_level; memcpy(pos, &cave->savegame.exists, sizeof cave->savegame.exists); pos += sizeof cave->savegame.exists; if(cave->savegame.exists) { memcpy(pos, &cave->savegame.game_level, sizeof cave->savegame.game_level); pos += sizeof cave->savegame.game_level; memcpy(pos, &cave->savegame.game_speed_modifier, sizeof cave->savegame.game_speed_modifier); pos += sizeof cave->savegame.game_speed_modifier; memcpy(pos, &cave->savegame.starting_girls, sizeof cave->savegame.starting_girls); pos += sizeof cave->savegame.starting_girls; memcpy(pos, &cave->savegame.girls, sizeof cave->savegame.girls); pos += sizeof cave->savegame.girls; memcpy(pos, &cave->savegame.score, sizeof cave->savegame.score); pos += sizeof cave->savegame.score; memcpy(pos, &cave->savegame.diamond_score, sizeof cave->savegame.diamond_score); pos += sizeof cave->savegame.diamond_score; memcpy(pos, &cave->savegame.diamonds, sizeof cave->savegame.diamonds); pos += sizeof cave->savegame.diamonds; if(cave->game_mode == GAME_MODE_PYJAMA_PARTY) { assert(cave->savegame.pyjama_party_girls != NULL); memcpy(pos, cave->savegame.pyjama_party_girls, sizeof(bool) * cave->savegame.starting_girls); pos += sizeof(bool) * cave->savegame.starting_girls; memcpy(pos, &cave->savegame.pyjama_party_girls_passed, sizeof cave->savegame.pyjama_party_girls_passed); pos += sizeof cave->savegame.pyjama_party_girls_passed; } } if(fwrite(buffer, pos - buffer, 1, fp) != 1) { fprintf(stderr, "Warning! Failed to write to '%s': %s\n", get_save_filename(fn), strerror(errno)); success = false; } if(cave->savegame.exists) if(success == true) { /* Save the treasure. */ uint16_t len; char * treasuredata; if(cave->savegame.treasure != NULL) { assert(cave->game_mode == GAME_MODE_ADVENTURE); treasuredata = treasureinfo_save(cave->savegame.treasure); } else treasuredata = NULL; if(treasuredata != NULL) len = strlen(treasuredata); else len = 0; if(fwrite(&len, sizeof len, 1, fp) == 1) { if(len > 0) if(fwrite(treasuredata, len, 1, fp) != 1) { fprintf(stderr, "Warning! Failed to write to '%s': %s\n", get_save_filename(fn), strerror(errno)); success = false; } } else { fprintf(stderr, "Warning! Failed to write to '%s': %s\n", get_save_filename(fn), strerror(errno)); success = false; } free(treasuredata); } if(fclose(fp) != 0) { fprintf(stderr, "Warning! Failed to write to '%s': %s\n", get_save_filename(fn), strerror(errno)); success = false; } if(success && cave->savegame.exists) if(cave->savegame.playback != NULL) { char tmpfn[strlen(fn) + strlen(".dgp") + 1]; snprintf(tmpfn, sizeof tmpfn, "%s.dgp", fn); success = playback_save(get_save_filename(tmpfn), cave->savegame.playback); } if(success && cave->savegame.exists) if(cave->game_mode == GAME_MODE_PYJAMA_PARTY) { char tmpfn[strlen(fn) + strlen(".dgms") + 1]; snprintf(tmpfn, sizeof tmpfn, "%s.dgms", fn); assert(cave->savegame.map != NULL); success = map_save_state(cave->savegame.map, get_save_filename(tmpfn)); } } else { fprintf(stderr, "Warning! Failed to open '%s' for writing: %s\n", get_save_filename(fn), strerror(errno)); success = false; } return success; }
bool settings_read(void) { bool rv; bool bind_defaults; bool nonexistent_ok; rv = true; bind_defaults = true; nonexistent_ok = false; /* Read and delete the old versions first if it exists. */ settings_read_v1(); if(settings_read_v2()) { bind_defaults = false; nonexistent_ok = true; // If we managed to read the old .lua file, then failing to read the new .json file should not cause any error messages. } /* Read the new version if it exists. */ char * json; int json_size; snprintf(filename, sizeof filename, "%s", get_save_filename("settings.json")); if(read_file(filename, &json, &json_size) == true) { enum json_tokener_error e; struct json_object * obj; obj = json_tokener_parse_verbose(json, &e); if(obj != NULL) { bool ok; struct json_object_iterator it; struct json_object_iterator itEnd; int active_questline; ok = true; it = json_object_iter_begin(obj); itEnd = json_object_iter_end(obj); active_questline = globals.active_questline; while(ok == true && !json_object_iter_equal(&it, &itEnd)) { const char * name; struct json_object * value; enum json_type type; bool dummy_boolean; name = json_object_iter_peek_name(&it); value = json_object_iter_peek_value(&it); type = json_object_get_type(value); struct { const char * name; enum json_type type; bool (*callback)(struct json_object * value, void * value_ptr); void * value_ptr; } stuff[] = { { "Fullscreen", json_type_boolean, cb_bool, &globals.fullscreen }, { "OpenGL", json_type_boolean, cb_bool, &globals.opengl }, { "OpenGL_POT", json_type_boolean, cb_opengl_pot, NULL }, { "OpenGL_compressed_textures", json_type_boolean, cb_bool, &globals.opengl_compressed_textures }, { "SFX", json_type_boolean, cb_bool, &globals.use_sfx }, { "Music", json_type_boolean, cb_bool, &globals.use_music }, { "SFX_max_channels", json_type_int, cb_int, &globals.max_channels }, { "Sound_volume", json_type_int, cb_sound_volume, NULL }, { "Joysticks", json_type_boolean, cb_bool, &globals.use_joysticks }, { "CaveSelection", json_type_string, cb_cave_selection, NULL }, { "CaveSelectionLevel", json_type_int, cb_cave_selection_level, NULL }, { "ShowFPS", json_type_boolean, cb_bool, &globals.fps_counter_active }, { "GameMode", json_type_string, cb_game_mode, NULL }, { "ActiveQuestline", json_type_int, cb_int, &active_questline }, { "TitleMidarea", json_type_string, cb_title_midarea, NULL }, { "IronGirlMode", json_type_boolean, cb_bool, &globals.iron_girl_mode }, { "Locale", json_type_string, cb_locale, NULL }, { "MapTilting", json_type_boolean, cb_bool, &globals.map_tilting }, { "SmoothClassicMode", json_type_boolean, cb_bool, &globals.smooth_classic_mode }, { "Bindings", json_type_array, cb_bindings, NULL }, { "Themes", json_type_array, cb_themes, NULL }, { "WriteSettings", json_type_boolean, cb_bool, &globals.write_settings }, { "TestsCompleted", json_type_boolean, cb_bool, &dummy_boolean }, // Ignored. { NULL, json_type_int, NULL, NULL } }; int ind; ind = -1; for(int i = 0; ind == -1 && stuff[i].name != NULL; i++) if(!strcmp(stuff[i].name, name)) ind = i; if(ind >= 0) { if(stuff[ind].type == type) { ok = stuff[ind].callback(value, stuff[ind].value_ptr); /* Don't bind the default keybindings if we were able to read them from the settings.json. */ if(ok == true && !strcmp(name, "Bindings")) bind_defaults = false; } else { fprintf(stderr, "%s: Incorrect value type %s for '%s', expected %s.\n", filename, json_type_to_name(type), name, json_type_to_name(stuff[ind].type)); ok = false; } } else { fprintf(stderr, "%s: Failed to parse: unknown variable '%s'.\n", filename, name); ok = false; } json_object_iter_next(&it); } if(ok == true) globals.active_questline = active_questline; else rv = false; } else { fprintf(stderr, "%s: Failed to parse: %d: %s\n", filename, (int) e, json_tokener_error_desc(e)); } free(json); } else { if(nonexistent_ok == false) fprintf(stderr, "%s: Failed to read '%s'.\n", __FUNCTION__, filename); } if(bind_defaults) ui_bindings_default(true); if(globals.iron_girl_mode) theme_set(THEME_TRAIT, "iron-girl"); return rv; }
bool questline_load(void) { bool success; success = read_file(get_save_filename("questlines"), &buf, &bufsize); if(success == true) { assert(bufsize > 0); bufpos = 0; char * version_str; uint32_t tlen; success = getstring(&version_str); if(success == true) { if(strcmp(version_str, QUESTLINE_SAVEFILE_V1)) success = false; } free(version_str); if(success == true) success = get(&globals.active_questline, sizeof globals.active_questline); unsigned int qlcount; qlcount = 0; if(success == true) { success = get(&tlen, sizeof tlen); qlcount = tlen; } for(unsigned int i = 0; success == true && i < qlcount && globals.questlines_size < MAX_QUESTLINES; i++) { struct questline * ql; ql = questline_new(QUEST_TYPE_SIZEOF_, RELATION_TYPE_SIZEOF_, RELATION_TYPE_SIZEOF_); if(ql != NULL) { globals.questlines[globals.questlines_size] = ql; globals.questlines_size++; if(success == true) success = get(&ql->type, sizeof ql->type); if(success == true) success = get(&ql->opening_weekday, sizeof ql->opening_weekday); if(success == true) success = get(&ql->opening_monthday_max, sizeof ql->opening_monthday_max); if(success == true) success = get(&ql->opening_time_hour, sizeof ql->opening_time_hour); if(success == true) success = get(&ql->opening_time_length, sizeof ql->opening_time_length); if(success == true) success = get(&ql->first_questgiver.relation_to_player, sizeof ql->first_questgiver.relation_to_player); if(success == true) success = getstring(&ql->first_questgiver.name); if(success == true) success = get(&ql->first_questgiver.gender, sizeof ql->first_questgiver.gender); if(success == true) success = get(&ql->ancient_person.relation_to_player, sizeof ql->ancient_person.relation_to_player); if(success == true) success = getstring(&ql->ancient_person.name); if(success == true) success = get(&ql->ancient_person.gender, sizeof ql->ancient_person.gender); if(success == true) success = get(&ql->reward, sizeof ql->reward); if(success == true) success = get(&ql->current_quest, sizeof ql->current_quest); if(success == true) success = get(&ql->current_phase, sizeof ql->current_phase); if(success == true) success = get(&tlen, sizeof tlen); for(unsigned int j = 0; success == true && j < tlen; j++) success = quest_load(ql); if(success == true) success = get(&tlen, sizeof tlen); for(unsigned int j = 0; success == true && j < tlen; j++) { char * str; success = getstring(&str); if(success == true) success = diary_entry_load(ql, str); free(str); } } else success = false; } if(success == true) success = get(&globals.active_trader, sizeof globals.active_trader); if(success == true) success = get(&globals.active_trader_start, sizeof globals.active_trader_start); for(int i = 0; success == true && i < MAX_TRADERS; i++) { char * str; success = getstring(&str); if(success == true) { globals.traders[i] = trader_load(str); if(globals.traders[i] == NULL) success = false; free(str); } } free(buf); assert(success == true); assert((int) bufpos == bufsize); } return success; }
void highscores_save(struct highscorelist * list, enum GAME_MODE game_mode, const char * cave) { if(list->highscores_dirty) { FILE * fp; if(list->filename == NULL) list->filename = highscore_filename(game_mode, cave); assert(list->filename != NULL); fp = fopen(get_save_filename(list->filename), "wb"); if(fp != NULL) { int ok; size_t i; ok = fwrite(FILE_HEADER_V5, 4, 1, fp); if(ok) ok = fwrite(&list->total.caves_entered, sizeof list->total.caves_entered, 1, fp); if(ok) ok = fwrite(&list->total.levels_completed, sizeof list->total.levels_completed, 1, fp); if(ok) ok = fwrite(&list->total.diamonds_collected, sizeof list->total.diamonds_collected, 1, fp); if(ok) ok = fwrite(&list->total.girls_died, sizeof list->total.girls_died, 1, fp); for(i = 0; i < list->highscores_size && ok; i++) if(list->highscores[i] != NULL) { uint8_t len; if(ok) ok = fwrite(&list->highscores[i]->timestamp, sizeof list->highscores[i]->timestamp, 1, fp); if(ok) ok = fwrite(&list->highscores[i]->score, sizeof list->highscores[i]->score, 1, fp); if(ok) ok = fwrite(&list->highscores[i]->diamonds_collected, sizeof list->highscores[i]->diamonds_collected, 1, fp); if(ok) ok = fwrite(&list->highscores[i]->level, sizeof list->highscores[i]->level, 1, fp); if(ok) ok = fwrite(&list->highscores[i]->playback_id, sizeof list->highscores[i]->playback_id, 1, fp); assert(strlen(list->highscores[i]->cave) > 0); assert(strlen(list->highscores[i]->cave) <= 0xff); len = strlen(list->highscores[i]->cave); if(ok) ok = fwrite(&len, sizeof len, 1, fp); if(ok && len > 0) ok = fwrite(list->highscores[i]->cave, len, 1, fp); assert(strlen(list->highscores[i]->notes) <= 0xff); len = strlen(list->highscores[i]->notes); if(ok) ok = fwrite(&len, sizeof len, 1, fp); if(ok && len > 0) ok = fwrite(list->highscores[i]->notes, len, 1, fp); if(ok) ok = fwrite(&list->highscores[i]->diamond_score, sizeof list->highscores[i]->diamond_score, 1, fp); if(ok) ok = fwrite(&list->highscores[i]->starting_girls, sizeof list->highscores[i]->starting_girls, 1, fp); if(ok) ok = fwrite(&list->highscores[i]->traits, sizeof list->highscores[i]->traits, 1, fp); if(!ok) fprintf(stderr, "Failed to write highscores: %s\n", strerror(errno)); if(ok && list->highscores[i]->playback_dirty == true && list->highscores[i]->playback != NULL) { char fnbuf[128]; snprintf(fnbuf, sizeof fnbuf, "%s-%d.dgp", list->filename, list->highscores[i]->playback_id); playback_save(get_save_filename(fnbuf), list->highscores[i]->playback); } } if(fclose(fp) != 0) { fprintf(stderr, "Failed to write highscores: %s\n", strerror(errno)); ok = 0; } if(ok) list->highscores_dirty = 0; } else fprintf(stderr, "Failed to open highscores file '%s': %s\n", get_save_filename(list->filename), strerror(errno)); } }
static int highscore_add(struct highscorelist * list, time_t timestamp, int score, int diamond_score, uint32_t diamonds_collected, enum GAME_MODE game_mode, char const * const cave, int level, int starting_girls, trait_t traits, bool playback_dirty, int playback_id, struct playback * playback, char * notes) { int position; struct highscore_entry * entry; assert(cave != NULL); position = -1; entry = malloc(sizeof(struct highscore_entry)); assert(entry != NULL); if(entry != NULL) { entry->timestamp = timestamp; entry->score = score; entry->diamond_score = diamond_score; entry->diamonds_collected = diamonds_collected; entry->cave = strdup(cave); entry->starting_girls = starting_girls; entry->traits = traits; entry->level = level; entry->playback_dirty = playback_dirty; entry->playback_id = playback_id; entry->playback = playback; memset(entry->notes, '\0', sizeof entry->notes); if(notes != NULL) snprintf(entry->notes, sizeof entry->notes, "%s", notes); if(list->highscores_size < 999) { /* Upper limit of the list has not yet been reached. */ struct highscore_entry ** tmplist; tmplist = realloc(list->highscores, sizeof(struct highscore_entry *) * (list->highscores_size + 1)); if(tmplist != NULL) { size_t i; size_t j, pos; i = list->highscores_size; list->highscores = tmplist; list->highscores_size++; list->highscores[i] = entry; /* put it in right position */ pos = i; switch(game_mode) { case GAME_MODE_CLASSIC: case GAME_MODE_ADVENTURE: for(j = 0; j < list->highscores_size; j++) if(list->highscores[j]->score < list->highscores[i]->score) { pos = j; break; } break; case GAME_MODE_PYJAMA_PARTY: for(j = 0; j < list->highscores_size; j++) if(list->highscores[j]->timestamp < list->highscores[i]->timestamp) { pos = j; break; } break; } if(pos != i) { struct highscore_entry * tmp; tmp = list->highscores[i]; for(j = list->highscores_size - 1; j > pos; j--) list->highscores[j] = list->highscores[j - 1]; list->highscores[pos] = tmp; } position = pos; } else fprintf(stderr, "Failed to allocate memory for a new highscore entry: %s\n", strerror(errno)); } else { /* Upper limit of the list has been reached. */ size_t j, pos; pos = list->highscores_size; switch(game_mode) { case GAME_MODE_CLASSIC: case GAME_MODE_ADVENTURE: for(j = 0; j < list->highscores_size; j++) if(list->highscores[j]->score < score) { pos = j; break; } break; case GAME_MODE_PYJAMA_PARTY: for(j = 0; j < list->highscores_size; j++) if(list->highscores[j]->timestamp < timestamp) { pos = j; break; } break; } if(pos < list->highscores_size) { if(list->filename != NULL) { assert(list->highscores[list->highscores_size - 1] != NULL); if(list->highscores[list->highscores_size - 1] != NULL) { /* Remove the 999th highscore entry. */ assert(list->total.score >= (uint64_t) list->highscores[list->highscores_size - 1]->score); list->total.score -= list->highscores[list->highscores_size - 1]->score; if(globals.read_only == false) { /* Delete the 999th playback file because it'll be purged soon enough. */ char fn[128]; snprintf(fn, sizeof fn, "%s-%d.dgp", list->filename, list->highscores[list->highscores_size - 1]->playback_id); unlink(get_save_filename(fn)); } /* Free the 999th highscore entry. */ if(list->highscores[list->highscores_size - 1]->playback != NULL) list->highscores[list->highscores_size - 1]->playback = playback_free(list->highscores[list->highscores_size - 1]->playback); free(list->highscores[list->highscores_size - 1]); list->highscores[list->highscores_size - 1] = NULL; } } /* Move the highscores to make room for this new. */ for(j = list->highscores_size - 1; j > pos; j--) list->highscores[j] = list->highscores[j - 1]; list->highscores[pos] = entry; position = pos; } } if(position < 0) { /* Cleanup upon error. */ free(entry->cave); free(entry); } } else fprintf(stderr, "Failed to allocate memory for a new highscore entry: %s\n", strerror(errno)); if(position >= 0) list->total.score += score; return position; }
void highscores_load(struct highscorelist * list, enum GAME_MODE game_mode, const char * cave) { #ifdef PROFILING if(list || cave || game_mode) { } #else FILE * fp; { /* Free the old entries. Save other variables. */ char * tmp; tmp = list->filename; list->filename = NULL; highscores_free(list); list->filename = tmp; } list->highscores_dirty = 0; if(list->filename == NULL) list->filename = highscore_filename(game_mode, cave); assert(list->filename != NULL); fp = fopen(get_save_filename(list->filename), "rb"); if(fp != NULL) { int done; int i; char header[4]; int version; int ok; version = 1; /* Version 1 did not have any header. */ if(fread(header, 4, 1, fp) == 1) /* Header will always be 4 characters. */ { if(memcmp(header, FILE_HEADER_V2, 4) == 0) version = 2; else if(memcmp(header, FILE_HEADER_V3, 4) == 0) version = 3; else if(memcmp(header, FILE_HEADER_V4, 4) == 0) version = 4; else if(memcmp(header, FILE_HEADER_V5, 4) == 0) version = 5; } if(version == 1) rewind(fp); ok = 1; if(version >= 3) { if(ok) ok = fread(&list->total.caves_entered, sizeof list->total.caves_entered, 1, fp); if(ok) ok = fread(&list->total.levels_completed, sizeof list->total.levels_completed, 1, fp); if(ok) ok = fread(&list->total.diamonds_collected, sizeof list->total.diamonds_collected, 1, fp); if(ok) ok = fread(&list->total.girls_died, sizeof list->total.girls_died, 1, fp); } done = 0; i = 0; while(ok && !done) { struct highscore_entry tmp; char tmp_cave[0xff]; if(ok) ok = fread(&tmp.timestamp, sizeof tmp.timestamp, 1, fp); if(ok) ok = fread(&tmp.score, sizeof tmp.score, 1, fp); tmp.diamonds_collected = 0; if(version >= 3) if(ok) ok = fread(&tmp.diamonds_collected, sizeof tmp.diamonds_collected, 1, fp); if(ok) ok = fread(&tmp.level, sizeof tmp.level, 1, fp); tmp.playback_id = 0; if(version >= 2) if(ok) ok = fread(&tmp.playback_id, sizeof tmp.playback_id, 1, fp); if(cave != NULL) strcpy(tmp_cave, cave); else strcpy(tmp_cave, ""); strcpy(tmp.notes, ""); if(version >= 3) { if(ok) { /* Cave name. */ uint8_t len; ok = fread(&len, sizeof len, 1, fp); if(ok) { assert(len < sizeof tmp_cave); assert(len > 0); ok = fread(tmp_cave, len, 1, fp); tmp_cave[len] = '\0'; } } if(ok) { /* Notes */ uint8_t len; ok = fread(&len, sizeof len, 1, fp); if(ok) { assert(len < sizeof tmp.notes); if(len > 0) ok = fread(tmp.notes, len, 1, fp); tmp.notes[len] = '\0'; } } } if(version >= 4) { if(ok) ok = fread(&tmp.diamond_score, sizeof tmp.diamond_score, 1, fp); if(ok) ok = fread(&tmp.starting_girls, sizeof tmp.starting_girls, 1, fp); if(ok) { if(version == 4) { uint16_t t; ok = fread(&t, sizeof t, 1, fp); tmp.traits = t; } else /* if(version >= 5) */ { ok = fread(&tmp.traits, sizeof tmp.traits, 1, fp); } } } else { tmp.diamond_score = 0; tmp.starting_girls = 3; tmp.traits = 0; } if(ok) { highscore_add(list, tmp.timestamp, tmp.score, tmp.diamond_score, tmp.diamonds_collected, game_mode, tmp_cave, tmp.level, tmp.starting_girls, tmp.traits, false, tmp.playback_id, NULL, tmp.notes); i++; } else { if(!feof(fp)) fprintf(stderr, "Failed to read highscores from %s: %s\n", get_save_filename(list->filename), strerror(errno)); done = 1; } } fclose(fp); } #endif }