From d14aea2a4ae48b8650b1c8afaa314e014223e2df Mon Sep 17 00:00:00 2001 From: Tau Date: Thu, 4 Apr 2019 14:28:13 -0400 Subject: [PATCH] round-trip settings load/save (ish) --- src/idz/decoder/saveSettings.ts | 20 +++++++++++--------- src/idz/encoder/loadProfile2.ts | 25 +++++++++++++++++-------- src/idz/handler/loadProfile.ts | 13 ++++++++++++- src/idz/model/settings.ts | 11 +++++++++++ src/idz/request/saveSettings.ts | 12 +++--------- src/idz/response/loadProfile2.ts | 3 +++ 6 files changed, 57 insertions(+), 27 deletions(-) create mode 100644 src/idz/model/settings.ts diff --git a/src/idz/decoder/saveSettings.ts b/src/idz/decoder/saveSettings.ts index 33bac11..2c8d807 100644 --- a/src/idz/decoder/saveSettings.ts +++ b/src/idz/decoder/saveSettings.ts @@ -11,17 +11,19 @@ export function saveSettings(buf: Buffer): SaveSettingsRequest { return { type: "save_settings_req", - bgMusic: buf.readUInt16LE(0x0002), profileId: buf.readUInt32LE(0x0004), dpoint: buf.readUInt32LE(0x0008), - forceQuitEn: ((pack >> 0) & 1) !== 0, - steeringForce: (pack >> 1) & 15, - bgVolume: (pack >> 5) & 15, - seVolume: (pack >> 9) & 15, - cornerGuide: ((pack >> 13) & 1) !== 0, - lineGuide: ((pack >> 14) & 1) !== 0, - ghostEn: ((pack >> 15) & 1) !== 0, - taResultSkip: ((pack >> 16) & 1) !== 0, + settings: { + bgMusic: buf.readUInt16LE(0x0002), + forceQuitEn: ((pack >> 0) & 1) !== 0, + steeringForce: (pack >> 1) & 15, + bgVolume: (pack >> 5) & 15, + seVolume: (pack >> 9) & 15, + cornerGuide: ((pack >> 13) & 1) !== 0, + lineGuide: ((pack >> 14) & 1) !== 0, + ghostEn: ((pack >> 15) & 1) !== 0, + taResultSkip: ((pack >> 16) & 1) !== 0, + }, field_0010: buf.readUInt8(0x0010), field_0011: buf.readUInt8(0x0011), field_0012: buf.readUInt8(0x0012), // always 5 for some reason diff --git a/src/idz/encoder/loadProfile2.ts b/src/idz/encoder/loadProfile2.ts index 52e8370..8f36c13 100644 --- a/src/idz/encoder/loadProfile2.ts +++ b/src/idz/encoder/loadProfile2.ts @@ -5,15 +5,24 @@ import { LoadProfileResponse2 } from "../response/loadProfile2"; export function loadProfile2(res: LoadProfileResponse2) { const buf = Buffer.alloc(0x0d30); - buf.writeUInt16LE(12, 0x03c8); // BGM - buf.writeUInt32LE(0x3548, 0x03d8); // Settings pack (default: max vol, force 4, corner on) - buf.writeInt16LE(0x0065, 0x0000); - buf.writeInt32LE(res.profileId, 4 + 0x3b4); - buf.writeInt16LE(res.lv, 4 + 0x03c8); - buf.writeInt32LE(res.dpoint, 4 + 0x03e4); - buf.writeInt32LE(res.fame, 4 + 0x0400); - iconv.encode(res.name + "\0", "shift_jis").copy(buf, 4 + 0x03ea); + buf.writeInt32LE(res.profileId, 0x3b8); + buf.writeUInt16LE(res.settings.bgMusic, 0x3c8); + buf.writeInt16LE(res.lv, 0x03cc); + buf.writeUInt32LE( + ((res.settings.forceQuitEn ? 1 : 0) << 0) | + (res.settings.steeringForce << 1) | + (res.settings.bgVolume << 5) | + (res.settings.seVolume << 9) | + ((res.settings.cornerGuide ? 1 : 0) << 13) | + ((res.settings.lineGuide ? 1 : 0) << 14) | + ((res.settings.ghostEn ? 1 : 0) << 15) | + ((res.settings.taResultSkip ? 1 : 0) << 16), + 0x3d8 + ); + buf.writeInt32LE(res.dpoint, 0x03e8); + buf.writeInt32LE(res.fame, 0x0404); + iconv.encode(res.name + "\0", "shift_jis").copy(buf, 0x03ee); buf.writeInt32LE(res.teamId, 0x07e0); return buf; diff --git a/src/idz/handler/loadProfile.ts b/src/idz/handler/loadProfile.ts index a156c22..6213478 100644 --- a/src/idz/handler/loadProfile.ts +++ b/src/idz/handler/loadProfile.ts @@ -10,9 +10,20 @@ export function loadProfile( type: "load_profile_v2_res", name: "てすと", profileId: 0x11223344, - lv: 69, + lv: 99, fame: 1234, dpoint: 54321, teamId: 0x22334455, + settings: { + bgMusic: 15, + forceQuitEn: false, + steeringForce: 4, + bgVolume: 10, + seVolume: 10, + cornerGuide: true, + lineGuide: false, + ghostEn: false, + taResultSkip: false, + }, }; } diff --git a/src/idz/model/settings.ts b/src/idz/model/settings.ts new file mode 100644 index 0000000..8654255 --- /dev/null +++ b/src/idz/model/settings.ts @@ -0,0 +1,11 @@ +export interface Settings { + bgMusic: number; + forceQuitEn: boolean; + steeringForce: number; + bgVolume: number; + seVolume: number; + cornerGuide: boolean; + lineGuide: boolean; + ghostEn: boolean; + taResultSkip: boolean; // TA = Time Attack presumably +} diff --git a/src/idz/request/saveSettings.ts b/src/idz/request/saveSettings.ts index be256b1..1006d87 100644 --- a/src/idz/request/saveSettings.ts +++ b/src/idz/request/saveSettings.ts @@ -1,16 +1,10 @@ +import { Settings } from "../model/settings"; + export interface SaveSettingsRequest { type: "save_settings_req"; - bgMusic: number; profileId: number; dpoint: number; // ?? why - forceQuitEn: boolean; - steeringForce: number; - bgVolume: number; - seVolume: number; - cornerGuide: boolean; - lineGuide: boolean; - ghostEn: boolean; - taResultSkip: boolean; // TA = Time Attack presumably + settings: Settings; field_0010: number; field_0011: number; field_0012: number; diff --git a/src/idz/response/loadProfile2.ts b/src/idz/response/loadProfile2.ts index 50944e5..f3800cc 100644 --- a/src/idz/response/loadProfile2.ts +++ b/src/idz/response/loadProfile2.ts @@ -1,3 +1,5 @@ +import { Settings } from "../model/settings"; + export interface LoadProfileResponse2 { type: "load_profile_v2_res"; name: string; @@ -6,5 +8,6 @@ export interface LoadProfileResponse2 { fame: number; dpoint: number; teamId: number; + settings: Settings; // giga TODO }