diff options
| author | 2014-12-21 12:03:41 -0500 | |
|---|---|---|
| committer | 2014-12-21 16:39:26 -0500 | |
| commit | cdd78fa01da30a9de117ca8163f572f0dc8ffc8f (patch) | |
| tree | b13fc9948524be76840d722ccea1845fa28df322 /src | |
| parent | CFGU: Addressed some comments. (diff) | |
| download | yuzu-cdd78fa01da30a9de117ca8163f572f0dc8ffc8f.tar.gz yuzu-cdd78fa01da30a9de117ca8163f572f0dc8ffc8f.tar.xz yuzu-cdd78fa01da30a9de117ca8163f572f0dc8ffc8f.zip | |
CFGU: Addressed some issues.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/cfg_u.cpp | 98 |
1 files changed, 55 insertions, 43 deletions
diff --git a/src/core/hle/service/cfg_u.cpp b/src/core/hle/service/cfg_u.cpp index 9701e6aed..1a128a0aa 100644 --- a/src/core/hle/service/cfg_u.cpp +++ b/src/core/hle/service/cfg_u.cpp | |||
| @@ -16,25 +16,25 @@ | |||
| 16 | namespace CFG_U { | 16 | namespace CFG_U { |
| 17 | 17 | ||
| 18 | enum SystemModel { | 18 | enum SystemModel { |
| 19 | NINTENDO_3DS, | 19 | NINTENDO_3DS = 0, |
| 20 | NINTENDO_3DS_XL, | 20 | NINTENDO_3DS_XL = 1, |
| 21 | NEW_NINTENDO_3DS, | 21 | NEW_NINTENDO_3DS = 2, |
| 22 | NINTENDO_2DS, | 22 | NINTENDO_2DS = 3, |
| 23 | NEW_NINTENDO_3DS_XL | 23 | NEW_NINTENDO_3DS_XL = 4 |
| 24 | }; | 24 | }; |
| 25 | 25 | ||
| 26 | enum SystemLanguage { | 26 | enum SystemLanguage { |
| 27 | LANGUAGE_JP, | 27 | LANGUAGE_JP = 0, |
| 28 | LANGUAGE_EN, | 28 | LANGUAGE_EN = 1, |
| 29 | LANGUAGE_FR, | 29 | LANGUAGE_FR = 2, |
| 30 | LANGUAGE_DE, | 30 | LANGUAGE_DE = 3, |
| 31 | LANGUAGE_IT, | 31 | LANGUAGE_IT = 4, |
| 32 | LANGUAGE_ES, | 32 | LANGUAGE_ES = 5, |
| 33 | LANGUAGE_ZH, | 33 | LANGUAGE_ZH = 6, |
| 34 | LANGUAGE_KO, | 34 | LANGUAGE_KO = 7, |
| 35 | LANGUAGE_NL, | 35 | LANGUAGE_NL = 8, |
| 36 | LANGUAGE_PT, | 36 | LANGUAGE_PT = 9, |
| 37 | LANGUAGE_RU | 37 | LANGUAGE_RU = 10 |
| 38 | }; | 38 | }; |
| 39 | 39 | ||
| 40 | struct UsernameBlock { | 40 | struct UsernameBlock { |
| @@ -57,8 +57,11 @@ static const u8 SOUND_OUTPUT_MODE = 2; | |||
| 57 | static const u32 CONFIG_SAVEFILE_SIZE = 0x8000; | 57 | static const u32 CONFIG_SAVEFILE_SIZE = 0x8000; |
| 58 | static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer = { }; | 58 | static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer = { }; |
| 59 | 59 | ||
| 60 | /// TODO(Subv): Find out what this actually is, these values fix some NaN uniforms in some games | 60 | /** |
| 61 | /// Thanks Normmatt for providing this information | 61 | * TODO(Subv): Find out what this actually is, these values fix some NaN uniforms in some games, |
| 62 | * for example Nintendo Zone | ||
| 63 | * Thanks Normmatt for providing this information | ||
| 64 | */ | ||
| 62 | static const std::array<float, 8> STEREO_CAMERA_SETTINGS = { | 65 | static const std::array<float, 8> STEREO_CAMERA_SETTINGS = { |
| 63 | 62.0f, 289.0f, 76.80000305175781f, 46.08000183105469f, | 66 | 62.0f, 289.0f, 76.80000305175781f, 46.08000183105469f, |
| 64 | 10.0f, 5.0f, 55.58000183105469f, 21.56999969482422f | 67 | 10.0f, 5.0f, 55.58000183105469f, 21.56999969482422f |
| @@ -158,19 +161,24 @@ static void GetCountryCodeID(Service::Interface* self) { | |||
| 158 | 161 | ||
| 159 | /// Block header in the config savedata file | 162 | /// Block header in the config savedata file |
| 160 | struct SaveConfigBlockEntry { | 163 | struct SaveConfigBlockEntry { |
| 161 | u32 block_id; | 164 | u32 block_id; ///< The id of the current block |
| 162 | u32 offset_or_data; | 165 | u32 offset_or_data; ///< This is the absolute offset to the block data if the size is greater than 4 bytes, otherwise it contains the data itself |
| 163 | u16 size; | 166 | u16 size; ///< The size of the block |
| 164 | u16 flags; | 167 | u16 flags; ///< The flags of the block, possibly used for access control |
| 165 | }; | 168 | }; |
| 166 | 169 | ||
| 167 | /// The header of the config savedata file, | 170 | /// The maximum number of block entries that can exist in the config file |
| 168 | /// contains information about the blocks in the file | 171 | static const u32 CONFIG_FILE_MAX_BLOCK_ENTRIES = 1479; |
| 172 | |||
| 173 | /** | ||
| 174 | * The header of the config savedata file, | ||
| 175 | * contains information about the blocks in the file | ||
| 176 | */ | ||
| 169 | struct SaveFileConfig { | 177 | struct SaveFileConfig { |
| 170 | u16 total_entries; | 178 | u16 total_entries; ///< The total number of set entries in the config file |
| 171 | u16 data_entries_offset; | 179 | u16 data_entries_offset; ///< The offset where the data for the blocks start, this is hardcoded to 0x455C as per hardware |
| 172 | SaveConfigBlockEntry block_entries[1479]; | 180 | SaveConfigBlockEntry block_entries[CONFIG_FILE_MAX_BLOCK_ENTRIES]; ///< The block headers, the maximum possible value is 1479 as per hardware |
| 173 | u32 unknown; | 181 | u32 unknown; ///< This field is unknown, possibly padding, 0 has been observed in hardware |
| 174 | }; | 182 | }; |
| 175 | 183 | ||
| 176 | /** | 184 | /** |
| @@ -189,7 +197,7 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) { | |||
| 189 | SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); | 197 | SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); |
| 190 | 198 | ||
| 191 | auto itr = std::find_if(std::begin(config->block_entries), std::end(config->block_entries), | 199 | auto itr = std::find_if(std::begin(config->block_entries), std::end(config->block_entries), |
| 192 | [&](SaveConfigBlockEntry const& entry) { | 200 | [&](const SaveConfigBlockEntry& entry) { |
| 193 | return entry.block_id == block_id && entry.size == size && (entry.flags & flag); | 201 | return entry.block_id == block_id && entry.size == size && (entry.flags & flag); |
| 194 | }); | 202 | }); |
| 195 | 203 | ||
| @@ -217,8 +225,11 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) { | |||
| 217 | * @param data A pointer containing the data we will write to the new block | 225 | * @param data A pointer containing the data we will write to the new block |
| 218 | * @returns ResultCode indicating the result of the operation, 0 on success | 226 | * @returns ResultCode indicating the result of the operation, 0 on success |
| 219 | */ | 227 | */ |
| 220 | ResultCode CreateConfigInfoBlk(u32 block_id, u32 size, u32 flags, u8 const* data) { | 228 | ResultCode CreateConfigInfoBlk(u32 block_id, u32 size, u32 flags, const u8* data) { |
| 221 | SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); | 229 | SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); |
| 230 | if (config->total_entries >= CONFIG_FILE_MAX_BLOCK_ENTRIES) | ||
| 231 | return ResultCode(-1); // TODO(Subv): Find the right error code | ||
| 232 | |||
| 222 | // Insert the block header with offset 0 for now | 233 | // Insert the block header with offset 0 for now |
| 223 | config->block_entries[config->total_entries] = { block_id, 0, size, flags }; | 234 | config->block_entries[config->total_entries] = { block_id, 0, size, flags }; |
| 224 | if (size > 4) { | 235 | if (size > 4) { |
| @@ -268,13 +279,12 @@ ResultCode DeleteConfigNANDSaveFile() { | |||
| 268 | * @returns ResultCode indicating the result of the operation, 0 on success | 279 | * @returns ResultCode indicating the result of the operation, 0 on success |
| 269 | */ | 280 | */ |
| 270 | ResultCode UpdateConfigNANDSavegame() { | 281 | ResultCode UpdateConfigNANDSavegame() { |
| 271 | FileSys::Mode mode; | 282 | FileSys::Mode mode = {}; |
| 272 | mode.hex = 0; | ||
| 273 | mode.write_flag = 1; | 283 | mode.write_flag = 1; |
| 274 | mode.create_flag = 1; | 284 | mode.create_flag = 1; |
| 275 | FileSys::Path path("config"); | 285 | FileSys::Path path("config"); |
| 276 | auto file = cfg_system_save_data->OpenFile(path, mode); | 286 | auto file = cfg_system_save_data->OpenFile(path, mode); |
| 277 | _dbg_assert_msg_(Service_CFG, file != nullptr, "could not open file"); | 287 | _assert_msg_(Service_CFG, file != nullptr, "could not open file"); |
| 278 | file->Write(0, CONFIG_SAVEFILE_SIZE, 1, cfg_config_file_buffer.data()); | 288 | file->Write(0, CONFIG_SAVEFILE_SIZE, 1, cfg_config_file_buffer.data()); |
| 279 | return RESULT_SUCCESS; | 289 | return RESULT_SUCCESS; |
| 280 | } | 290 | } |
| @@ -292,16 +302,17 @@ ResultCode FormatConfig() { | |||
| 292 | std::fill(cfg_config_file_buffer.begin(), cfg_config_file_buffer.end(), 0); | 302 | std::fill(cfg_config_file_buffer.begin(), cfg_config_file_buffer.end(), 0); |
| 293 | // Create the header | 303 | // Create the header |
| 294 | SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); | 304 | SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); |
| 305 | // This value is hardcoded, taken from 3dbrew, verified by hardware, it's always the same value | ||
| 295 | config->data_entries_offset = 0x455C; | 306 | config->data_entries_offset = 0x455C; |
| 296 | // Insert the default blocks | 307 | // Insert the default blocks |
| 297 | res = CreateConfigInfoBlk(0x00050005, 0x20, 0xE, | 308 | res = CreateConfigInfoBlk(0x00050005, 0x20, 0xE, |
| 298 | reinterpret_cast<u8 const*>(STEREO_CAMERA_SETTINGS.data())); | 309 | reinterpret_cast<const u8*>(STEREO_CAMERA_SETTINGS.data())); |
| 299 | if (!res.IsSuccess()) | 310 | if (!res.IsSuccess()) |
| 300 | return res; | 311 | return res; |
| 301 | res = CreateConfigInfoBlk(0x00090001, 0x8, 0xE, reinterpret_cast<u8 const*>(&CONSOLE_UNIQUE_ID)); | 312 | res = CreateConfigInfoBlk(0x00090001, 0x8, 0xE, reinterpret_cast<const u8*>(&CONSOLE_UNIQUE_ID)); |
| 302 | if (!res.IsSuccess()) | 313 | if (!res.IsSuccess()) |
| 303 | return res; | 314 | return res; |
| 304 | res = CreateConfigInfoBlk(0x000F0004, 0x4, 0x8, reinterpret_cast<u8 const*>(&CONSOLE_MODEL)); | 315 | res = CreateConfigInfoBlk(0x000F0004, 0x4, 0x8, reinterpret_cast<const u8*>(&CONSOLE_MODEL)); |
| 305 | if (!res.IsSuccess()) | 316 | if (!res.IsSuccess()) |
| 306 | return res; | 317 | return res; |
| 307 | res = CreateConfigInfoBlk(0x000A0002, 0x1, 0xA, &CONSOLE_LANGUAGE); | 318 | res = CreateConfigInfoBlk(0x000A0002, 0x1, 0xA, &CONSOLE_LANGUAGE); |
| @@ -313,7 +324,7 @@ ResultCode FormatConfig() { | |||
| 313 | res = CreateConfigInfoBlk(0x000B0000, 0x4, 0xE, COUNTRY_INFO.data()); | 324 | res = CreateConfigInfoBlk(0x000B0000, 0x4, 0xE, COUNTRY_INFO.data()); |
| 314 | if (!res.IsSuccess()) | 325 | if (!res.IsSuccess()) |
| 315 | return res; | 326 | return res; |
| 316 | res = CreateConfigInfoBlk(0x000A0000, 0x1C, 0xE, reinterpret_cast<u8*>(&CONSOLE_USERNAME_BLOCK)); | 327 | res = CreateConfigInfoBlk(0x000A0000, 0x1C, 0xE, reinterpret_cast<const u8*>(&CONSOLE_USERNAME_BLOCK)); |
| 317 | if (!res.IsSuccess()) | 328 | if (!res.IsSuccess()) |
| 318 | return res; | 329 | return res; |
| 319 | // Save the buffer to the file | 330 | // Save the buffer to the file |
| @@ -357,8 +368,9 @@ static void GetSystemModel(Service::Interface* self) { | |||
| 357 | u32* cmd_buffer = Kernel::GetCommandBuffer(); | 368 | u32* cmd_buffer = Kernel::GetCommandBuffer(); |
| 358 | u32 data; | 369 | u32 data; |
| 359 | 370 | ||
| 371 | // TODO(Subv): Find out the correct error codes | ||
| 360 | cmd_buffer[1] = GetConfigInfoBlock(0x000F0004, 4, 0x8, | 372 | cmd_buffer[1] = GetConfigInfoBlock(0x000F0004, 4, 0x8, |
| 361 | reinterpret_cast<u8*>(&data)).raw; // TODO(Subv): Find out the correct error codes | 373 | reinterpret_cast<u8*>(&data)).raw; |
| 362 | cmd_buffer[2] = data & 0xFF; | 374 | cmd_buffer[2] = data & 0xFF; |
| 363 | } | 375 | } |
| 364 | 376 | ||
| @@ -372,8 +384,9 @@ static void GetModelNintendo2DS(Service::Interface* self) { | |||
| 372 | u32* cmd_buffer = Kernel::GetCommandBuffer(); | 384 | u32* cmd_buffer = Kernel::GetCommandBuffer(); |
| 373 | u32 data; | 385 | u32 data; |
| 374 | 386 | ||
| 387 | // TODO(Subv): Find out the correct error codes | ||
| 375 | cmd_buffer[1] = GetConfigInfoBlock(0x000F0004, 4, 0x8, | 388 | cmd_buffer[1] = GetConfigInfoBlock(0x000F0004, 4, 0x8, |
| 376 | reinterpret_cast<u8*>(&data)).raw; // TODO(Subv): Find out the correct error codes | 389 | reinterpret_cast<u8*>(&data)).raw; |
| 377 | 390 | ||
| 378 | u8 model = data & 0xFF; | 391 | u8 model = data & 0xFF; |
| 379 | if (model == NINTENDO_2DS) | 392 | if (model == NINTENDO_2DS) |
| @@ -412,8 +425,7 @@ Interface::Interface() { | |||
| 412 | // TODO(Subv): All this code should be moved to cfg:i, | 425 | // TODO(Subv): All this code should be moved to cfg:i, |
| 413 | // it's only here because we do not currently emulate the lower level code that uses that service | 426 | // it's only here because we do not currently emulate the lower level code that uses that service |
| 414 | // Try to open the file in read-only mode to check its existence | 427 | // Try to open the file in read-only mode to check its existence |
| 415 | FileSys::Mode mode; | 428 | FileSys::Mode mode = {}; |
| 416 | mode.hex = 0; | ||
| 417 | mode.read_flag = 1; | 429 | mode.read_flag = 1; |
| 418 | FileSys::Path path("config"); | 430 | FileSys::Path path("config"); |
| 419 | auto file = cfg_system_save_data->OpenFile(path, mode); | 431 | auto file = cfg_system_save_data->OpenFile(path, mode); |
| @@ -429,8 +441,8 @@ Interface::Interface() { | |||
| 429 | CONSOLE_USERNAME_BLOCK.ng_word = 0; | 441 | CONSOLE_USERNAME_BLOCK.ng_word = 0; |
| 430 | CONSOLE_USERNAME_BLOCK.zero = 0; | 442 | CONSOLE_USERNAME_BLOCK.zero = 0; |
| 431 | // Copy string to buffer and pad with zeros at the end | 443 | // Copy string to buffer and pad with zeros at the end |
| 432 | auto itr = Common::UTF8ToUTF16(CONSOLE_USERNAME).copy(CONSOLE_USERNAME_BLOCK.username, 0x14); | 444 | auto size = Common::UTF8ToUTF16(CONSOLE_USERNAME).copy(CONSOLE_USERNAME_BLOCK.username, 0x14); |
| 433 | std::fill(std::begin(CONSOLE_USERNAME_BLOCK.username) + itr, | 445 | std::fill(std::begin(CONSOLE_USERNAME_BLOCK.username) + size, |
| 434 | std::end(CONSOLE_USERNAME_BLOCK.username), 0); | 446 | std::end(CONSOLE_USERNAME_BLOCK.username), 0); |
| 435 | FormatConfig(); | 447 | FormatConfig(); |
| 436 | } | 448 | } |