static bool replay_write_stage(ReplayStage *stg, SDL_RWops *file, uint16_t version) { if(version >= REPLAY_STRUCT_VERSION_TS102000_REV1) { SDL_WriteLE32(file, stg->flags); } SDL_WriteLE16(file, stg->stage); SDL_WriteLE32(file, stg->seed); SDL_WriteU8(file, stg->diff); SDL_WriteLE32(file, stg->plr_points); if(version >= REPLAY_STRUCT_VERSION_TS102000_REV1) { SDL_WriteU8(file, stg->plr_continues_used); } SDL_WriteU8(file, stg->plr_char); SDL_WriteU8(file, stg->plr_shot); SDL_WriteLE16(file, stg->plr_pos_x); SDL_WriteLE16(file, stg->plr_pos_y); SDL_WriteU8(file, stg->plr_focus); SDL_WriteLE16(file, stg->plr_power); SDL_WriteU8(file, stg->plr_lives); SDL_WriteU8(file, stg->plr_life_fragments); SDL_WriteU8(file, stg->plr_bombs); SDL_WriteU8(file, stg->plr_bomb_fragments); SDL_WriteU8(file, stg->plr_inputflags); SDL_WriteLE16(file, stg->numevents); SDL_WriteLE32(file, 1 + ~replay_calc_stageinfo_checksum(stg, version)); return true; }
bool Serializer::writeHeader() { // Write magic number if (!SDL_RWwrite(_rw, SAVIdent, sizeof(SAVIdent), 1)) return false; // Write version information { const size_t len = UCHAR_MAX > strlen(DAGON_VERSION_STRING) ? strlen(DAGON_VERSION_STRING) : UCHAR_MAX; if (!SDL_WriteU8(_rw, len)) return false; if (!SDL_RWwrite(_rw, DAGON_VERSION_STRING, len, 1)) return false; } // Write preview { const std::string desc = Control::instance().currentNode()->description(); const size_t len = UCHAR_MAX > desc.length() ? desc.length() : UCHAR_MAX; if (!SDL_WriteU8(_rw, len)) return false; if (len > 0 && !SDL_RWwrite(_rw, desc.c_str(), len, 1)) return false; } // Write current room name const std::string name = Control::instance().currentRoom()->name(); if (!SDL_WriteU8(_rw, name.length())) return false; if (!SDL_RWwrite(_rw, name.c_str(), name.length(), 1)) return false; return true; }
static bool replay_write_stage_event(ReplayEvent *evt, SDL_RWops *file) { SDL_WriteLE32(file, evt->frame); SDL_WriteU8(file, evt->type); SDL_WriteLE16(file, evt->value); return true; }
static void replay_write_string(SDL_RWops *file, char *str, uint16_t version) { if(version >= REPLAY_STRUCT_VERSION_TS102000_REV1) { SDL_WriteU8(file, strlen(str)); } else { SDL_WriteLE16(file, strlen(str)); } SDL_RWwrite(file, str, 1, strlen(str)); }
void dmx_device_store_to_disc(void) { char *file_name = "device"; char *base_path = SDL_GetPrefPath("net.exse", "untel"); char *file_path = calloc((strlen(base_path)+strlen(file_name)+1),sizeof(char)); strcat(file_path,base_path); strcat(file_path,file_name); free(base_path); SDL_RWops *file = SDL_RWFromFile(file_path, "w"); free(file_path); SDL_WriteBE32(file,devices_inuse); for(unsigned int i=0;i<devices_inuse;i++) { SDL_WriteBE32(file,dmx_device_list[i].type); SDL_WriteBE32(file,dmx_device_list[i].addr); SDL_WriteU8(file,strnlen(dmx_device_list[i].name,DMX_NAME_LENGTH)); SDL_RWwrite(file,dmx_device_list[i].name,1,1+strnlen(dmx_device_list[i].name,DMX_NAME_LENGTH)); } SDL_RWclose(file); }
bool Serializer::writeField(const std::string &key, const std::string &val) { return SDL_WriteBE16(_rw, key.length() + val.length() + 1) && // +1 because of = SDL_RWwrite(_rw, key.c_str(), key.length(), 1) && SDL_WriteU8(_rw, '=') && SDL_RWwrite(_rw, val.c_str(), val.length(), 1); }
bool Serializer::writeRoomData() { // Write the enable status for the spots of all nodes of all rooms if (!SDL_WriteBE16(_rw, Control::instance().numRooms())) return false; for (Room *room : Control::instance().rooms()) { if (!SDL_WriteBE16(_rw, room->numNodes())) return false; if (room->hasNodes()) { room->beginIteratingNodes(); do { Node *node = room->iterator(); if (!SDL_WriteBE16(_rw, node->numSpots())) return false; if (node->hasSpots()) { node->beginIteratingSpots(); do { if (!SDL_WriteU8(_rw, node->currentSpot()->isEnabled())) return false; } while (node->iterateSpots()); } } while (room->iterateNodes()); } } Room *room = Control::instance().currentRoom(); // Write node number uint16_t nodeIdx = 0; if (room->hasNodes()) { room->beginIteratingNodes(); do { if (room->iterator() == room->currentNode()) break; nodeIdx++; } while (room->iterateNodes()); } if (!SDL_WriteBE16(_rw, nodeIdx)) return false; // Write camera angles int hAngle = CameraManager::instance().angleHorizontal(); const std::string hAngleStr = std::to_string(hAngle); if (!SDL_WriteU8(_rw, hAngleStr.length())) return false; if (!SDL_RWwrite(_rw, hAngleStr.c_str(), hAngleStr.length(), 1)) return false; int vAngle = CameraManager::instance().angleVertical(); const std::string vAngleStr = std::to_string(vAngle); if (!SDL_WriteU8(_rw, vAngleStr.length())) return false; if (!SDL_RWwrite(_rw, vAngleStr.c_str(), vAngleStr.length(), 1)) return false; float fov = CameraManager::instance().fieldOfView(); const std::string fovStr = std::to_string(fov); if (!SDL_WriteU8(_rw, fovStr.length())) return false; if (!SDL_RWwrite(_rw, fovStr.c_str(), fovStr.length(), 1)) return false; // Write audio states if (!SDL_WriteBE16(_rw, room->arrayOfAudios().size())) return false; for (Audio *audio : room->arrayOfAudios()) { if (!SDL_WriteU8(_rw, audio->state())) return false; } // Write timers int64_t timersPtr = SDL_RWtell(_rw); if (timersPtr < 0) return false; if (!SDL_WriteBE16(_rw, 0)) // 2 placeholder bytes for the actual number of timers return false; uint16_t numTimers = 0; for (const auto &timer : TimerManager::instance().timers()) { if (timer.type != DGTimerNormal || !timer.isEnabled || (!timer.isLoopable && timer.hasTriggered)) continue; double elapsed = TimerManager::instance().timeElapsed(timer); if (timer.trigger - elapsed > 0) { const std::string triggerStr = std::to_string(timer.trigger); if (!SDL_WriteU8(_rw, timer.isLoopable)) return false; if (!SDL_WriteU8(_rw, triggerStr.length())) return false; if (!SDL_RWwrite(_rw, triggerStr.c_str(), triggerStr.length(), 1)) return false; const std::string elapsedStr = std::to_string(elapsed); if (!SDL_WriteU8(_rw, elapsedStr.length())) return false; if (!SDL_RWwrite(_rw, elapsedStr.c_str(), elapsedStr.length(), 1)) return false; lua_rawgeti(_L, LUA_REGISTRYINDEX, timer.luaHandler); // Push timer function to top of stack int64_t funcSizePtr = SDL_RWtell(_rw); if (funcSizePtr < 0) return false; if (!SDL_WriteBE16(_rw, 0)) // 2 placeholder bytes for the actual function size return false; int64_t beforeFuncPtr = SDL_RWtell(_rw); if (beforeFuncPtr < 0) return false; int errCode = lua_dump(_L, writeFunction, _rw); if (errCode != 0) return false; int64_t afterFuncPtr = SDL_RWtell(_rw); if (afterFuncPtr < 0) return false; uint16_t numBytesWritten = afterFuncPtr - beforeFuncPtr; if (SDL_RWseek(_rw, funcSizePtr, RW_SEEK_SET) < 0) return false; if (!SDL_WriteBE16(_rw, numBytesWritten)) return false; if (SDL_RWseek(_rw, 0, RW_SEEK_END) < 0) // Restore file pointer to end return false; numTimers++; } } if (SDL_RWseek(_rw, timersPtr, RW_SEEK_SET) < 0) return false; if (!SDL_WriteBE16(_rw, numTimers)) return false; if (SDL_RWseek(_rw, 0, RW_SEEK_END) < 0) // Restore file pointer to end return false; // Write control mode if (!SDL_WriteU8(_rw, Config::instance().controlMode)) return false; return true; }
CAMLprim value caml_SDL_WriteU8(value rwo, Uint8 d) { return Val_size_t( SDL_WriteU8(SDL_RWops_val(rwo), Uint8_val(d))); }
bool replay_write(Replay *rpy, SDL_RWops *file, uint16_t version) { uint16_t base_version = (version & ~REPLAY_VERSION_COMPRESSION_BIT); bool compression = (version & REPLAY_VERSION_COMPRESSION_BIT); int i, j; SDL_RWwrite(file, replay_magic_header, sizeof(replay_magic_header), 1); SDL_WriteLE16(file, version); if(base_version >= REPLAY_STRUCT_VERSION_TS102000_REV0) { TaiseiVersion v; TAISEI_VERSION_GET_CURRENT(&v); if(taisei_version_write(file, &v) != TAISEI_VERSION_SIZE) { log_warn("Failed to write game version: %s", SDL_GetError()); return false; } } void *buf; SDL_RWops *abuf = NULL; SDL_RWops *vfile = file; if(compression) { abuf = SDL_RWAutoBuffer(&buf, 64); vfile = SDL_RWWrapZWriter(abuf, REPLAY_COMPRESSION_CHUNK_SIZE, false); } replay_write_string(vfile, config_get_str(CONFIG_PLAYERNAME), base_version); fix_flags(rpy); if(base_version >= REPLAY_STRUCT_VERSION_TS102000_REV1) { SDL_WriteLE32(vfile, rpy->flags); } SDL_WriteLE16(vfile, rpy->numstages); for(i = 0; i < rpy->numstages; ++i) { if(!replay_write_stage(rpy->stages + i, vfile, base_version)) { if(compression) { SDL_RWclose(vfile); SDL_RWclose(abuf); } return false; } } if(compression) { SDL_RWclose(vfile); SDL_WriteLE32(file, SDL_RWtell(file) + SDL_RWtell(abuf) + 4); SDL_RWwrite(file, buf, SDL_RWtell(abuf), 1); SDL_RWclose(abuf); vfile = SDL_RWWrapZWriter(file, REPLAY_COMPRESSION_CHUNK_SIZE, false); } for(i = 0; i < rpy->numstages; ++i) { ReplayStage *stg = rpy->stages + i; for(j = 0; j < stg->numevents; ++j) { if(!replay_write_stage_event(stg->events + j, vfile)) { if(compression) { SDL_RWclose(vfile); } return false; } } } if(compression) { SDL_RWclose(vfile); } // useless byte to simplify the premature EOF check, can be anything SDL_WriteU8(file, REPLAY_USELESS_BYTE); return true; }