diff --git a/iidx/2dx_gst_ver0.5/2dx_gst.exe b/iidx/2dx_gst_ver0.5/2dx_gst.exe new file mode 100644 index 0000000..c79f8ae Binary files /dev/null and b/iidx/2dx_gst_ver0.5/2dx_gst.exe differ diff --git a/iidx/2dx_gst_ver0.5/readme b/iidx/2dx_gst_ver0.5/readme new file mode 100644 index 0000000..a3ce272 --- /dev/null +++ b/iidx/2dx_gst_ver0.5/readme @@ -0,0 +1,45 @@ +looks like i forget to post this here lol +also dunno if anyone post something like this yet +this thing can "render" gst file for iidx songs + +DL: https://www.dropbox.com/s/l0nepgb50x0zz51/2dx_gst_ver0.5.zip?dl=0 +oof, i posted the old version(0.2), fixed + +usage: +1. place the exe into the same place of .1 and .2dx/.s3p file +2. run this line in cmd + + 2dx_gst [music_id] + + +3. you should see the output wave file in the same folder + +QA: +1. What's that "render" mean? +Because I just simply add all the samples to the final track without processing them like this: + + static int32_t mixing_function(int32_t buf, int16_t input) + { + return buf + input; + } + + +Maybe there's a better way to do the sample mixing, but this way is simple and also working so I just leave it like this. +If anyone has better solution rather than just adding all tracks into the final one, please feel free to leave a comment here. + +2. What's the "mixing level" mean? +Since I use int32 rather than int16 for temp buffer(so it won't rape your ear if too much sample is added in the same time period), this will show how much the scale is when converting it back to int16 in the final step. It's kinda like normalizing the final track by the max volume of original track. + +3. Why sometimes there will be more than one wave file? +The chart files are different sometimes(like 1ms differ for only one sample sound, or totally completly different music), so the final track will also be different. I use hash for each output track to check this, so even if it's only some 1ms differs the program will still just treat them as different tracks. You can just ignore/delete other outputs if it sounds the same. + +4. How to generate files for multi tracks like crew? + + 2dx_gst 24084 --snd-string 51253400 + + +The suffix string is in music_data.bin if needed. + +There're still some things to fix such as temp file for s3p decoding and the same output checking, but i think it should be ready to post a build here. + +Feel free to report any issue, I havn't tested it for all songs so there may be some bugs I can't find by now. diff --git a/iidx/BMSto1/BMSto1.exe b/iidx/BMSto1/BMSto1.exe new file mode 100644 index 0000000..676fcf9 Binary files /dev/null and b/iidx/BMSto1/BMSto1.exe differ diff --git a/iidx/BMSto1/BMSto1.txt b/iidx/BMSto1/BMSto1.txt new file mode 100644 index 0000000..4ae893d --- /dev/null +++ b/iidx/BMSto1/BMSto1.txt @@ -0,0 +1,40 @@ + ============================ + BMSto1 v0.06 + Created 2007.04.04 and (Y) + Updated 2007.04.07 by ('-') + (")_(") + ---------------------------- + + BMSto1 is a Be-Music Source conversion utility. It opens a BMS file, then + saves the converted data to .1 format. Sound data is converted and saved + to un-encrypted .2dx format. + + Written in Delphi 7. Source is included. + + Although BMSto1 is a console application, File Drag and Drop is supported. + Output files will be saved in the input file's folder. + + + To use: BMSto1 [/RANDOM] [/MIRROR] [/VMIRROR] InputFile1 InputFile2 ... + + InputFile - The BMS file(s) to convert. Wildcards ? and * can be used in + any InputFile name parameter. All Output file(s) will have .1 + as their new file extension. + /RANDOM - Applies the Random Modifier effect to the note-chart. + /MIRROR - Applies the Mirror Modifier effect to the note-chart. + /VMIRROR - Vertically flips the note-chart. Last note becomes first! + + This version of BMSto1 currently isn't able to combine multiple BMS files of + the same song. Instead, each BMS will be converted to its own .1 file. + + + ------------------------------------------------------------------------------- + + =============== + Version History + --------------- + v0.06 released 2007.04.07 - Added in .2dx file creation. + Removed the useless /RAW option. + v0.05 released 2007.04.06 - Fixed the "Song-Stop appears in wrong location" bug. + v0.04 released 2007.04.06 - Fixed the "No song-stop event" bug. + v0.01 released 2007.04.04 - First release! \ No newline at end of file diff --git a/iidx/BMSto1/src/BMS.pas b/iidx/BMSto1/src/BMS.pas new file mode 100644 index 0000000..cf15465 --- /dev/null +++ b/iidx/BMSto1/src/BMS.pas @@ -0,0 +1,735 @@ +unit BMS; +// ================================================ +// BMS.PAS +// Created 2007.02.18 +// +// Supports reading *.bms, *.bme and related files. +// +// Based on the 'BMS_Open' procedure from earlier +// versions of Be-Pachi Music. +// +// Contains functions and procedures for dealing +// with converting data inside a Be-Music Source +// file into a useable format. +// +// Output data can be found in the DB.pas arrays. +// ------------------------------------------------ + +interface + +uses + SysUtils, Base36, DB_Main; + +function CountEvents(Path_File: String): Integer; +function CountTempoChanges(Path_File: String): Word; +function FindFirstSpace(Data: String): Word; +function FindHighestReference(Path_File, Reference_Type: String): Word; +function OpenBMS(Path_File: String): Boolean; + +procedure AddMeasuresToEventList; +procedure AddTempoChangesToEventList; +procedure AdjustMeasureTimes; +procedure ApplyTempoChanges; +procedure CollectCustomTempoChanges(Path_File: String); +procedure CollectWavBmpAssigns(Path_File: String); +procedure ConvertDataLine(BMS_Measure: Word; BMS_Function: Byte; BMS_DataLine: String); +procedure ConvertPositionsIntoTime; +procedure ConvertTempoChangesIntoTime; +procedure ParseMainDataField(Path_File: String); +procedure ReadHeader(Path_File: String); +procedure SetMeasureStartTimes; + +implementation + + + +// ---------------------------------------------------------- + + + +function CountEvents(Path_File: String): Integer; +// ========================================================= +// Returns the total number of objects (not just notes but +// other events and also measure lines) in a BMS file. +// +// This also retrieves the total number of measures as well, +// which is placed in Measure_Count for reference. +// --------------------------------------------------------- +var + BMS_Measure: word; + BMS_File: TextFile; + Data: string; +begin + + Result := 0; + Measure_Count := 0; + + if not FileExists(Path_File) then + begin + Result := -1; + exit; + end; + + AssignFile(BMS_File, Path_File); + Reset(BMS_File); + + while not EOF(BMS_File) do + begin + ReadLn(BMS_File, Data); + Data := TrimRight(UpperCase(Data)); + + if Length(Data) > 1 then + if Data[1] = '#' then + if Data[2] in ['0'..'9'] then + begin + BMS_Measure := StrToInt(copy(Data, 2, 3)); + Data := copy(Data, 8, Length(Data) - 7); + + if BMS_Measure > Measure_Count then + Measure_Count := BMS_Measure; + + if Length(Data) > 1 then + repeat + if (Data[1] <> '0') or (Data[2] <> '0') then inc(Result); + Data := copy(Data, 3, Length(Data) - 2); + until Data = ''; + + end; + end; + + CloseFile(BMS_File); + + inc(Result, Result); // Double the amount to allow for the sound change events + + inc(Measure_Count); // Include the measure immediately after the song ends + + inc(Result, Measure_Count); // Make room for the Measure lines, which will be + // converted into events, and added to the note + // arrays + + inc(Result, 218); // Make room for the end-of-song line graph + + inc(Result, 100); // And some over-flow space, just to be safe! + +end; + + + +// ---------------------------------------------------------------------------- + + + +function CountTempoChanges(Path_File: String): Word; +// ================================= +// Returns the number of times a BMS +// song changes tempo. +// --------------------------------- +var + BMS_File: TextFile; + Data: String; + i, Data_Length: Word; +begin + Result := 0; + + AssignFile(BMS_File, Path_File); // CountEvents function already checked + Reset(BMS_File); // if the file existed, so no need to here. + + while not EOF(BMS_File) do + begin + ReadLn(BMS_File, Data); + + Data_Length := Length(Data); + + if Data_Length > 8 then + if Data[1] = '#' then + if Data[2] in ['0'..'9'] then + if (copy(Data, 5, 2) = '03') or + (copy(Data, 5, 2) = '08') then + begin + i := 8; + while i < Data_Length do + begin + if (Data[i] <> '0') or (Data[i + 1] <> '0') then + inc(Result); + inc(i, 2); + end; + end; + + end; + + CloseFile(BMS_File); +end; + + + +// ---------------------------------------------------------------------------- + + + +function FindFirstSpace(Data: String): Word; +// ======================================= +// Returns the location of the first space +// (ASCII value 32) in a string. +// --------------------------------------- +var + Len: word; +begin + Result := 0; + Len := Length(Data); + if Len = 0 then exit; + while (Result < Len) and (Data[Result] <> ' ') do inc(Result); +end; + + + +// ---------------------------------------------------------------------------- + + + +function FindHighestReference(Path_File, Reference_Type: String): Word; +// ============================================== +// Returns the highest location used by the +// reference type (#WAV, #BMP, #BPM, or other) +// +// For example: if a BMS contains the following +// 5 #WAV reference lines: +// +// #WAV01 1.wav +// #WAV02 2.wav +// #WAV03 3.wav +// #WAV04 4.wav +// #WAV0F 5.wav +// +// ...the function would return 15 (0F in base36) +// ---------------------------------------------- +var + Current_Value, Reference_Length: Word; + BMS_File: TextFile; + Data: String; +begin + + Result := 0; + AssignFile(BMS_File, Path_File); // CountEvents function already checked + Reset(BMS_File); // if the file existed, so no need to here. + + Reference_Length := Length(Reference_Type); + + while not EOF(BMS_File) do + begin + ReadLn(BMS_File, Data); + if Length(Data) > Reference_Length then + if copy(Data, 1, Reference_Length) = Reference_Type then + begin + Current_Value := Base36.Base36ToInt(copy(Data, Reference_Length + 1, 2)); + if Current_Value > Result then Result := Current_Value; + end; + end; + + CloseFile(BMS_File); +end; + + + +// ---------------------------------------------------------- + + + +function OpenBMS(Path_File: String): Boolean; +// =================================================== +// Opens a BMS file through the use of sub-procedures, +// which convert and load the data into the various +// arrays and variables. +// --------------------------------------------------- +begin + Result := False; + BGA_OK := False; + Event_Count := CountEvents(Path_File); + if Event_Count < 0 then exit; + + ReadHeader(Path_File); + + WAV_Count := FindHighestReference(Path_File, '#WAV'); + BMP_Count := FindHighestReference(Path_File, '#BMP'); + CustomTempoChange_Count := FindHighestReference(Path_File, '#BPM'); + TempoChange_Count := CountTempoChanges(Path_File); + + InitializeArrays; + + CollectCustomTempoChanges(Path_File); + CollectWavBmpAssigns(Path_File); + + ParseMainDataField(Path_File); + + SetMeasureStartTimes; + ConvertPositionsIntoTime; + ConvertTempoChangesIntoTime; + AdjustMeasureTimes; + SortTempoChangeArrays; + AddMeasuresToEventList; + AddTempoChangesToEventList; + AssignNotesToMeasure; + + Result := True; +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure AddMeasuresToEventList; +// ============================================ +// This converts the measure lines into events, +// which are then added into the note arrays. +// -------------------------------------------- +var + i, ff: Integer; +begin + + ff := GetFirstFreeEvent; + if ff < 0 then exit; // Error + + for i := 0 to Measure_Count - 1 do + begin + Note_Column[ff] := 10; + Note_Time[ff] := Measure_Time[i]; + inc(ff); + end; + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure AddTempoChangesToEventList; +// =========================================== +// This converts tempo changes into events and +// adds those to the note arrays. +// ------------------------------------------- +var + i, ff: Integer; +begin + + ff := GetFirstFreeEvent; + if ff < 0 then exit; // Error + + for i := 0 to TempoChange_Count - 1 do + begin + Note_Column[ff] := 8; + Note_Time[ff] := TempoChange_Position[i]; + Note_Sound[ff] := Trunc(TempoChange_Amount[i]); + Note_Position[ff] := TempoChange_Amount[i]; // Provides better accuracy when + // using the Be-Music tempo + // change effect! + inc(ff); + end; + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure AdjustMeasureTimes; +// ========================================= +// This procedure applies the song's tempo +// to the current values in the Measure_Time +// array. +// ----------------------------------------- +var + i: Integer; +begin + for i := 0 to Measure_Count - 1 do + Measure_Time[i] := Measure_Time[i] / Tempo * 240; +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure ApplyTempoChanges; +// ======================================================== +// This modifies the trigger time of all objects that exist +// after each tempo change, including later tempo changes. +// +// Only used for "BPM Classic Style" tempo change effect +// or Constant Speed is selected. +// +// Not needed for normal "Be-Music" tempo change effect. +// -------------------------------------------------------- +var + i, i2: Integer; + Current_Tempo: Single; +begin + Current_Tempo := Tempo; + for i := 0 to TempoChange_Count - 1 do + begin + if TempoChange_Amount[i] <> 0 then + begin + + for i2 := 0 to Event_Count - 1 do + if Note_Time[i2] > TempoChange_Position[i] then + Note_Time[i2] := (Note_Time[i2] - TempoChange_Position[i]) / TempoChange_Amount[i] * Current_Tempo + TempoChange_Position[i]; + + for i2 := 0 to Measure_Count - 1 do + if Measure_Time[i2] > TempoChange_Position[i] then + Measure_Time[i2] := (Measure_Time[i2] - TempoChange_Position[i]) / TempoChange_Amount[i] * Current_Tempo + TempoChange_Position[i]; + + for i2 := 0 to TempoChange_Count - 1 do + if TempoChange_Position[i2] > TempoChange_Position[i] then + TempoChange_Position[i2] := (TempoChange_Position[i2] - TempoChange_Position[i]) / TempoChange_Amount[i] * Current_Tempo + TempoChange_Position[i]; + + end; + Current_Tempo := TempoChange_Amount[i]; + end; +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure CollectCustomTempoChanges(Path_File: String); +// =============================== +// Looks for and retrieves all of +// the customized tempo changes, +// which are prefixed with #BPMxx. +// ------------------------------- +var + BMS_File: TextFile; + Data: String; + Data_Length: Word; +begin + AssignFile(BMS_File, Path_File); // CountEvents function already checked + Reset(BMS_File); // if the file existed, so no need to here. + + while not EOF(BMS_File) do + begin + ReadLn(BMS_File, Data); + Data_Length := Length(Data); + + if Data_Length >= 8 then + if copy(Data, 1, 4) = '#BPM' then + if Data[5] <> ' ' then + CustomTempoChange_Amount[Base36.Base36ToInt(copy(Data, 5, 2))] := StrToFloat(copy(Data, 8, Data_Length - 7)); + end; + + CloseFile(BMS_File); +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure CollectWavBmpAssigns(Path_File: String); +// ======================================== +// This looks for #WAV and #BMP file assign +// lines and stores the file name in the +// WAV_Name / BMP_Name arrays. +// +// Even though the file assign lines expect +// WAV or BMP files, the actual file types +// can be any format supported by the BMS +// player. +// ---------------------------------------- +var + BMS_File: TextFile; + Data: String; + Data_Length: Word; +begin + + AssignFile(BMS_File, Path_File); // CountEvents function already checked + Reset(BMS_File); // if the file existed, so no need to here. + + while not EOF(BMS_File) do + begin + ReadLn(BMS_File, Data); + Data_Length := Length(Data); + if Data_Length >= 8 then + begin + if copy(Data, 1, 4) = '#BMP' then + BMP_Name[Base36.Base36ToInt(copy(Data, 5, 2))] := copy(Data, 8, Data_Length - 7); + if copy(Data, 1, 4) = '#WAV' then + WAV_Name[Base36.Base36ToInt(copy(Data, 5, 2))] := copy(Data, 8, Data_Length - 7); + end; + end; + CloseFile(BMS_File); +end; + + + +// ---------------------------------------------------------- + + + +procedure ConvertDataLine(BMS_Measure: Word; BMS_Function: Byte; BMS_DataLine: String); +// ============================================== +// Converts a series of numerical data from a BMS +// into events (including type, column, position) +// +// Output data will be stored in all the defined +// variable arrays. +// ---------------------------------------------- +var + i, Note, Data_Length, Denominator: Word; +begin + Data_Length := Length(BMS_DataLine); + if Data_Length and 1 = 1 then exit; // Odd data length? Bad! Skip the line! + + Denominator := Data_Length shr 1; + i := 1; + + while i < Data_Length do + begin + Note := Base36.Base36ToInt(copy(BMS_DataLine, i, 2)); + if Note > 0 then + begin + + case BMS_Function of + 3: begin // ----------------------------- Tempo Change + TempoChange_Measure[TempoChange_Pointer] := BMS_Measure; + TempoChange_Position[TempoChange_Pointer] := (i shr 1) / Denominator; + TempoChange_Amount[TempoChange_Pointer] := StrToInt('$' + copy(BMS_DataLine, i, 2)); // Base16-to-Decimal + inc(TempoChange_Pointer); + end; + 8: begin // ----------------------------- Custom Tempo Change + TempoChange_Measure[TempoChange_Pointer] := BMS_Measure; + TempoChange_Position[TempoChange_Pointer] := (i shr 1) / Denominator; + TempoChange_Amount[TempoChange_Pointer] := CustomTempoChange_Amount[Note]; + inc(TempoChange_Pointer); + end; + 4, 6, 7: begin // ----------------------- BG Animations + BGA_OK := True; + Note_Sound[NoteArray_Pointer] := Note; + Note_Measure[NoteArray_Pointer] := BMS_Measure; + Note_Position[NoteArray_Pointer] := (i shr 1) / Denominator; + Note_Column[NoteArray_Pointer] := BMS_Function; + inc(NoteArray_Pointer); + if BMP_Name[Note] = '' then + BMP_Name[Note] := ' '; // Prepare blank BGA image + end; + 1, 11..49: begin // -------------------- Key Sound + Note_Sound[NoteArray_Pointer] := Note; + Note_Measure[NoteArray_Pointer] := BMS_Measure; + Note_Position[NoteArray_Pointer] := (i shr 1) / Denominator; + Note_Column[NoteArray_Pointer] := BMS_Function; + if BMS_Function in [11..29] then + inc(Measure_NoteAmount[Note_Measure[NoteArray_Pointer]]); + if BMS_Function = 1 then + Note_Flag[NoteArray_Pointer] := Note_Flag[NoteArray_Pointer] or Flag_AutoPlay; + inc(NoteArray_Pointer); + if WAV_Name[Note] = '' then + WAV_Name[Note] := ' '; // Prepare blank WAV sound + end; + end; + end; + inc(i, 2); + end; + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure ConvertPositionsIntoTime; +// ============================================== +// This converts Event Position values +// into the time the event will be +// triggered. +// +// Formula: +// Time in Seconds = 240 * (Measure_Size / Tempo) +// ---------------------------------------------- +var + i: Integer; +begin + for i := 0 to Event_Count - 1 do + Note_Time[i] := (Measure_Time[Note_Measure[i]] / Tempo * 240) + + (Measure_Size[Note_Measure[i]] / Tempo * 240) * Note_Position[i]; + + FillChar(Note_Position[0], Event_Count shl 2, 0); // Removing now un-needed +end; // data + + + +// ---------------------------------------------------------------------------- + + + +procedure ConvertTempoChangesIntoTime; +// ======================================= +// Similar to the above procedure, this +// converts Tempo Change positions into +// the time the tempo change takes effect. +// +// Same formula used as the above. +// --------------------------------------- +var + i: Integer; +begin + for i := 0 to TempoChange_Count - 1 do + TempoChange_Position[i] := (Measure_Time[TempoChange_Measure[i]] / Tempo * 240) + + (Measure_Size[TempoChange_Measure[i]] / Tempo * 240) + * TempoChange_Position[i]; +end; + + + +// ---------------------------------------------------------- + + + +procedure ParseMainDataField(Path_File: String); +// =============================================== +// Reads the numerical prefixed BMS command lines +// and prepares the data for conversion into notes +// and other events. +// ----------------------------------------------- +var + BMS_File: TextFile; + Data, BMS_DataLine: String; + BMS_Measure: Word; + BMS_Function: Byte; +begin + + AssignFile(BMS_File, Path_File); // CountEvents function already checked + Reset(BMS_File); // if the file existed, so no need to here. + + NoteArray_Pointer := 0; // Start from the beginning! + TempoChange_Pointer := 0; + + while not EOF(BMS_File) do + begin + ReadLn(BMS_File, Data); + + if Length(Data) >= 8 then + if Data[1] = '#' then + if Data[2] in ['0'..'9'] then + begin + + BMS_Measure := StrToInt(copy(Data, 2, 3)); + BMS_Function := StrToInt(copy(Data, 5, 2)); + BMS_DataLine := copy(Data, 8, Length(Data) - 7); + + case BMS_Function of + 1, 3, 4, 6, 7, 8, + 11..19, + 21..49: ConvertDataLine(BMS_Measure, BMS_Function, BMS_DataLine); + 2: Measure_Size[BMS_Measure] := StrToFloat(BMS_DataLine); + end; + + end; + end; + + CloseFile(BMS_File); +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure ReadHeader(Path_File: String); +// ========================================= +// Obtains info about the song, ignoring the +// actual note data, as well as the WAV and +// BMP file name references. +// ----------------------------------------- +var + BMS_File: TextFile; + SpacePosition, Len: Word; + Data1, Data2: String; +begin + + Tempo := 120; + Title := ''; + Genre := ''; + Artist := ''; + Players := 0; + Judgement := 0; + PlayLevel := 0; + + AssignFile(BMS_File, Path_File); // CountEvents function already checked + Reset(BMS_File); // if the file existed, so no need to here. + + while not EOF(BMS_File) do + begin + ReadLn(BMS_File, Data1); + + Len := Length(Data1); + SpacePosition := FindFirstSpace(Data1); + + if Len > SpacePosition then + if Data1[SpacePosition] = ' ' then + begin + Data2 := copy(Data1, SpacePosition + 1, (Len - SpacePosition) + 1); + Data1 := copy(Data1, 1, SpacePosition - 1); + end; + + if Data1 = '#GENRE' then Genre := Data2; + if Data1 = '#ARTIST' then Artist := Data2; + if Data1 = '#TITLE' then Title := Data2; + + if Data2 <> '' then + if (Data2[1] < '0') or // Some songs have non-numerical values for the + (Data2[1] > '9') then // below lines (such as #PLAYLEVEL ?). + Data2 := '0'; // This works around those weird lines. + + if Data1 = '#PLAYER' then Players := StrToInt(Data2); + if Data1 = '#BPM' then Tempo := StrToFloat(Data2); + if Data1 = '#RANK' then Judgement := StrToInt(Data2); + if Data1 = '#PLAYLEVEL' then PlayLevel := StrToInt(Data2); + + end; + + CloseFile(BMS_File); +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure SetMeasureStartTimes; +// ===================================== +// This adds up the total sizes of all +// in-use measures. +// +// Un-used measures with negative values +// will be ignored. +// ------------------------------------- +var + i: Integer; + Total_Size: Single; +begin + Total_Size := 0; + for i := 0 to Measure_Count - 1 do + begin + Measure_Time[i] := Total_Size; + Total_Size := Total_Size + Measure_Size[i]; // No need to abs(Measure_Size), + end; // was done in MarkUsedMeasures! +end; + + + +// ---------------------------------------------------------------------------- + + + +end. diff --git a/iidx/BMSto1/src/BMSto1.dpr b/iidx/BMSto1/src/BMSto1.dpr new file mode 100644 index 0000000..5d757d0 --- /dev/null +++ b/iidx/BMSto1/src/BMSto1.dpr @@ -0,0 +1,144 @@ +program BMSto1; +// ============================================== +// BMSto1 v0.06 +// Created 2007.04.03 +// Updated 2007.04.07 +// +// Converts a Be-Music Source file to .1 format. +// Also combines WAV files to a .2dx format file. +// ---------------------------------------------- + + +{$APPTYPE CONSOLE} + +uses + SysUtils, + Convert in 'Convert.pas', + Utils in 'Utils.pas', + DXAC2DX in 'DXAC2DX.pas'; + +// ---------------------------------------------------------------------------- + + + +function CheckForParam(Param: String): Boolean; +var + i: Word; +begin + + Result := False; + Param := UpperCase(Param); + + for i := 1 to ParamCount do + if UpperCase(ParamStr(i)) = Param then + Result := True; + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure ScanForFiles; +const + SlashRANDOM: array[1..7] of Char = '/RANDOM'; + SlashMIRROR: array[1..7] of Char = '/MIRROR'; + SlashVMIRROR: array[1..8] of Char = '/VMIRROR'; +var + Rec: TSearchRec; + Path: String; + DoRandom: Boolean; + DoMirror: Boolean; + DoVMirror: Boolean; + i: Word; +begin + + DoRandom := False; + DoMirror := False; + DoVMirror := False; + + if CheckForParam(SlashRANDOM) then DoRandom := True; + if CheckForParam(SlashMIRROR) then DoMirror := True; + if CheckForParam(SlashVMIRROR) then DoVMirror := True; + + for i := 1 to ParamCount do + begin + + Path := NoFile(ParamStr(i)); + if Path = '' then Path := '.\'; + if FindFirst(ParamStr(i), + faAnyFile - faDirectory, + Rec) = 0 then + try + repeat + write(Rec.Name + ' > ' + NoExt(Rec.Name) + '.1 + .2dx ...'); + case Do_Stuff(Path + Rec.Name, DoRandom, DoMirror, DoVMirror) of + True: writeln('OK!'); + False: writeln('Error!'); + end; + until FindNext(Rec) <> 0; + finally + FindClose(Rec); + end; + + end; + + writeln('All tasks complete.'); + writeln; + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure DisplayInfo; +// ============================================== +// Displays information on how to use the program +// when no command line parameters exist. +// ---------------------------------------------- +begin + writeln; + write ('================================================================================'); + write ('BMSto1 -- v0.06! - Be-Music Source conversion utility - created 2007.04.07'); + write ('--------------------------------------------------------------------------------'); + writeln; + writeln(' To use: BMSto1 [/RANDOM] [/MIRROR] [/VMIRROR] InputFile1 InputFile2 ...'); + writeln; + writeln(' InputFile - The BMS file(s) to convert. Wildcards ? and * can be used in'); + writeln(' any InputFile name parameter. All Output file(s) will have .1'); + writeln(' as their new file extension. BMS WAV sounds will be combined'); + writeln(' into .2dx files.'); + writeln(' /RANDOM - Applies the Random Modifier effect to the note-chart.'); + writeln(' /MIRROR - Applies the Mirror Modifier effect to the note-chart.'); + writeln(' /VMIRROR - Vertically flips the note-chart. Last note becomes first!'); + writeln; + writeln(' This version of BMSto1 currently isn''t able to combine multiple BMS files of'); + writeln(' the same song. Instead, each BMS will be converted to its own .1 file.'); + writeln; + writeln; + writeln(' Use of BMSto1 is AT YOUR OWN RISK. It has been tested, however I will not'); + writeln(' take responsibility for damaged or corrupted files.'); + writeln; +end; + + + +// ---------------------------------------------------------------------------- + + +begin + { TODO -oUser -cConsole Main : Insert code here } + + if ParamStr(1) = '' then + begin + DisplayInfo; + exit; + end; + ScanForFiles; +end. + diff --git a/iidx/BMSto1/src/Base36.pas b/iidx/BMSto1/src/Base36.pas new file mode 100644 index 0000000..adcd470 --- /dev/null +++ b/iidx/BMSto1/src/Base36.pas @@ -0,0 +1,84 @@ +unit Base36; +// ==================================================== +// Base36.pas v0.11 +// Created 2005.06.02 +// Modified 2007.02.20 +// +// This unit converts a Base-36 number to decimal. +// Base-36 alpha: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +// +// A function to convert from Decimal will most likely +// be added soon. Maybe. +// +// This could be easily modified to support a different +// number base, just modify the 2 constants below. +// ---------------------------------------------------- + +interface + +uses SysUtils; + +const + B36: byte = 36; + Base36String: String = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + +Function Base36ToInt(B36Num: string): Integer; +Function Exp(Base: Integer; Power: Byte): Integer; + + +implementation + + + +function Base36ToInt(B36Num: string): Integer; +// ========================================= +// Converts a Base-36 number of any length +// to a decimal number. +// ----------------------------------------- +var + Number_Length, Number_Position: word; + i: Byte; +begin + B36Num := UpperCase(B36Num); + Number_Length := Length(B36Num); + Number_Position := Number_Length; + Result := 0; + while Number_Position >= 1 do + begin + i := 1; + while B36Num[Number_Position] <> Base36String[i] do + begin + inc(i); + if i > B36 then + begin + Result := 0; + exit; + end; + end; + Result := Result + (i - 1) * Exp(B36, Number_Length - Number_Position); + dec(Number_Position); + end; +end; + + + +// --------------------------------------------------------------------------- + + + +function Exp(Base:Integer; Power:Byte): Integer; +// ============================================== +// A quickie exponential function where the power +// is exclusively a rounded non-negative number +// between (and including) 0 and 255! +// ---------------------------------------------- +var + i: byte; +begin + Result := 1; + for i := 1 to Power do Result := Result * Base; +end; + + + +end. diff --git a/iidx/BMSto1/src/Convert.pas b/iidx/BMSto1/src/Convert.pas new file mode 100644 index 0000000..852c32b --- /dev/null +++ b/iidx/BMSto1/src/Convert.pas @@ -0,0 +1,56 @@ +unit Convert; +// ============================= +// Convert.pas +// Created 2007.04.04 +// Updated 2007.04.07 +// +// Holds the code that calls the +// various conversion routines. +// ----------------------------- + +interface + +uses + BMS, DB_Main, DB_XForm, DXAC1, DXAC2DX, Utils; + + +function Do_Stuff(Path_Name: String; DoRandom, DoMirror, DoVMirror: Boolean): Boolean; + + +implementation + + + +// --------------------------------------------------------------------------- + + + +function Do_Stuff(Path_Name: String; DoRandom, DoMirror, DoVMirror: Boolean): Boolean; +begin + + OpenBMS(Path_Name); + SortEvents; // Database always needs sorting after opening. + KeyAmount := GetKeyAmount; + TotalNotes := ReCalculatePlayableNotes; + ApplyTempoChanges; + if DoRandom then ApplyRandom; + if DoMirror then ApplyMirror; + if DoVMirror then ApplyMirrorPlus; + SortEvents; + SortWAVNames; // Compress the WAV list! + AddSoundChanges; + SortEvents; // All that modifying! Let's re-sort! + + Save1(NoExt(Path_Name) + '.1'); // Generate and save the .1 file + Save2dx(NoExt(Path_Name) + '.2dx'); // Generate and save the .2dx file + + Result := True; +end; + + + +// --------------------------------------------------------------------------- + + + +end. diff --git a/iidx/BMSto1/src/DB_Main.pas b/iidx/BMSto1/src/DB_Main.pas new file mode 100644 index 0000000..886d4cd --- /dev/null +++ b/iidx/BMSto1/src/DB_Main.pas @@ -0,0 +1,639 @@ +unit DB_Main; +// =================================================== +// DB_Main.pas +// Created 2007.02.24 +// +// This file contains the various arrays and variables +// for storing converted note/event data. +// --------------------------------------------------- + +interface + +const + Flag_Hidden: byte = 1; // Constants used for Note_Flag[] + Flag_Judged: byte = 2; // + Flag_Autoplay: byte = 4; // + Flag_Player1: byte = 8; // + +var + Note_Time: array of Single; // How long before the note is played. + Note_Sound: array of Word; // # of sound file to play. + Note_Column: array of Byte; // The column the note appears in. + Note_Measure: array of Word; // The measure the note appears in. + Note_Position: array of Single; // Where in the measure it is. + // 0 meaning measure start, and + // 0.999~ meaning real close to + // the next measure line. + Note_Flag: array of Byte; // What options are set on the note. + // + // Byte and 1: Hidden. Don't Display! + // Byte and 2: Judged. Don't re-judge! + // Byte and 4: Autoplay. + // + // For use later: + // Byte and 8: Player number? + + TempoChange_Measure: array of Word; // Where the tempo change is. + TempoChange_Position: array of Single; // How far above the divider. + TempoChange_Amount: array of Single; // Amount to change tempo to. + + CustomTempoChange_Amount: array of Single; // For the #BPMxx lines. + + Measure_Time: array of Single; // Divider line's placing. + Measure_Size: array of Single; // Distance between 2 lines. + Measure_NoteAmount: array of Byte; // + Measure_HitNotes: array of Byte; // + // These 4 arrays are only + // used when loading BMS + // format songs. + + WAV_Name: array of string; // Name of sounds used in the song. + BMP_Name: array of string; // Name of images used in the song. + + KeyAmount: Byte; // (5, 7, 9, 10, 14?) + + Tempo: Single; + Event_Count: Integer; + Title, Artist, Genre, FileName: String; + Measure_Count, WAV_Count, BMP_Count, + TempoChange_Count, CustomTempoChange_Count, + NoteArray_Pointer, TempoChange_Pointer, + TotalPlayableNotes, TotalNotes: Word; + Players, PlayLevel, Judgement: Byte; + BGA_OK: Boolean; + + +function GetFirstFreeBMP: Integer; +function GetFirstFreeEvent: Integer; +function GetFirstFreeWAV: Integer; +function GetKeyAmount: Byte; +function GetLastWavNumber: Word; +function ReCalculatePlayableNotes: Word; + +procedure AssignNotesToMeasure; +procedure FreeArrays; +procedure InitializeArrays; +procedure SortBmpNames; +procedure SortEvents; +procedure SortTempoChangeArrays; +procedure SortWavNames; +procedure SwapBmpNames(X1, X2: Word); +procedure SwapEvents(X1, X2: Word); +procedure SwapTempoChanges(X1, X2: Word); +procedure SwapWavNames(X1, X2: Word); + + +implementation + + + +// ---------------------------------------------------------------------------- + + + +function GetFirstFreeBMP: Integer; +// ============================================== +// Returns the first un-used location in the BMP +// name array. +// +// If all locations are in use, this will return +// a value of -1. +// ---------------------------------------------- +var + i: Integer; +begin + Result := -1; + + for i := BMP_Count downto 1 do + if BMP_Name[i] = '' then + Result := i; + +end; + + + +// ---------------------------------------------------------------------------- + + + +function GetFirstFreeEvent: Integer; +// ============================================== +// Returns the first un-used location in the note +// variable arrays. +// +// If all locations are in use, this will return +// a value of -1. +// ---------------------------------------------- +var + i: Integer; +begin + Result := -1; + + for i := Event_Count - 1 downto 0 do + if Note_Column[i] = 0 then + Result := i; + +end; + + + +// ---------------------------------------------------------------------------- + + + +function GetFirstFreeWAV: Integer; +// ============================================== +// Returns the first un-used location in the WAV +// name array. +// +// If all locations are in use, this will return +// a value of -1. +// ---------------------------------------------- +var + i: Integer; +begin + Result := -1; + + for i := WAV_Count downto 1 do + if WAV_Name[i] = '' then + Result := i; + +end; + + + +// ---------------------------------------------------------------------------- + + + +function GetKeyAmount: Byte; +// ========================================= +// Returns the play mode of the loaded song. +// (5 or 7 keys) +// ----------------------------------------- +var + i: Integer; + Key: Array[11..29] of Boolean; +begin + + Result := 5; // Default return value + + for i := 11 to 29 do + Key[i] := False; + + for i := 0 to Event_Count - 1 do + if Note_Column[i] in [11..29] then + Key[Note_Column[i]] := True; + + if Key[18] or Key[19] or Key[28] or Key[29] then + Result := 7; + + if Players in [2..3] then + inc(Result, Result); // from 5-7 to 10-14 + +end; + + + +// ---------------------------------------------------------------------------- + + + +function GetLastWavNumber: Word; +// =================================== +// Looks for and returns the highest +// WAV assign number currently in use. +// ----------------------------------- +var + i: Word; +begin + Result := 0; + + for i := Wav_Count downto 1 do + if Wav_Name[i] <> '' then + if Result = 0 then + Result := i; +end; + + + +// ---------------------------------------------------------------------------- + + + +function ReCalculatePlayableNotes: Word; +// =================================================== +// Does what it says. +// +// This is useful after using the DB_XForm procedures. +// --------------------------------------------------- +var + i: Word; +begin + Result := 0; + + for i := 0 to Event_Count - 1 do + if Note_Column[i] in [11..29] then + inc(Result); + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure AssignNotesToMeasure; +// ============================================== +// This procedure sets the notes' "measure" value +// to the number of the measure the note exists +// in. +// +// This is used so Be-Pachi mode can detect when +// all notes in a measure have been played. +// +// This works best if the event/note arrays have +// been sorted with SortEvents procedure first. +// ---------------------------------------------- +var + i: Integer; + Current_Measure: Word; +begin + + Current_Measure := 0; + + for i := 0 to Event_Count - 1 do + begin + + case Note_Column[i] of + 10: begin + Measure_NoteAmount[Current_Measure] := 0; + inc(Current_Measure); + end; + else begin + Note_Measure[i] := Current_Measure; + if Note_Column[i] in [11..29] then inc(Measure_NoteAmount[Current_Measure]); + end; + end; + + end; + +end; + + + +// ---------------------------------------------------------- + + + +procedure FreeArrays; +// =================================================== +// Sets all arrays to nil, freeing up any memory used, +// and erases all stored array data as well. +// --------------------------------------------------- +begin + + Note_Time := nil; + Note_Sound := nil; + Note_Column := nil; + Note_Measure := nil; + Note_Position := nil; + Note_Flag := nil; + Measure_Time := nil; + Measure_Size := nil; + Measure_NoteAmount := nil; + Measure_HitNotes := nil; + WAV_Name := nil; + BMP_Name := nil; + TempoChange_Measure := nil; + TempoChange_Position := nil; + TempoChange_Amount := nil; + CustomTempoChange_Amount := nil; + +end; + + + +// ---------------------------------------------------------- + + + +procedure InitializeArrays; +// ============================================== +// Prepares the variable arrays for receiving the +// proper amounts of data. +// ---------------------------------------------- +var + i: Word; +begin + + FreeArrays; // To completely get rid of any data that might still exist + // in the arrays + + SetLength(Note_Time, Event_Count); + SetLength(Note_Sound, Event_Count); + SetLength(Note_Column, Event_Count); + SetLength(Note_Measure, Event_Count); + SetLength(Note_Position, Event_Count); + SetLength(Note_Flag, Event_Count); + + SetLength(Measure_Time, Measure_Count); + SetLength(Measure_Size, Measure_Count); + SetLength(Measure_NoteAmount, Measure_Count); + SetLength(Measure_HitNotes, Measure_Count); + + SetLength(WAV_Name, WAV_Count + 2); // An extra value for blank sounds + SetLength(BMP_Name, BMP_Count + 2); // and images + + SetLength(TempoChange_Measure, TempoChange_Count); + SetLength(TempoChange_Position, TempoChange_Count); + SetLength(TempoChange_Amount, TempoChange_Count); + + SetLength(CustomTempoChange_Amount, CustomTempoChange_Count + 1); + + for i := 0 to Measure_Count - 1 do + Measure_Size[i] := 1; + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure SortBmpNames; +// =============================================== +// Sorts the BMP names so that in-use names appear +// at the start of the array. +// +// The Note_Sound[] Array will also be modified to +// reflect the changes in the BMP_Name[] array, +// despite the name. +// ----------------------------------------------- +var + i: Integer; + Swapped: Boolean; +begin + + repeat + Swapped := False; + + for i := 1 to BMP_Count - 1 do // Start counter at 1. + if BMP_Name[i] = '' then // 0 references the 'Miss' BMP image. + if BMP_Name[i + 1] <> '' then + begin + SwapBmpNames(i, i + 1); + Swapped := True; + end; + + until not Swapped; + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure SortEvents; +// =============================================== +// This sorts the events in the various Note_...[] +// arrays from earliest to latest. +// ----------------------------------------------- +var + i: Integer; + Swapped: Boolean; +begin + + repeat + Swapped := False; + for i := 0 to Event_Count - 2 do + if Note_Time[i] > Note_Time[i + 1] then + if Note_Column[i + 1] <> 0 then + begin + SwapEvents(i, i + 1); + Swapped := True; + end; + until not Swapped; + + repeat // This places 'Measure Line' + Swapped := False; // events earlier in the note + for i := 0 to Event_Count - 2 do // array if they appear at the + if Note_Time[i] = Note_Time[i + 1] then // same time as other events or + if Note_Column[i + 1] = 10 then // notes. + if Note_Column[i + 1] <> 0 then // + if Note_Column[i] <> 10 then // + begin // + SwapEvents(i, i + 1); // + Swapped := True; // + end; // + until not Swapped; // + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure SortTempoChangeArrays; +// ============================================ +// Sort the BPM changes from first-appearing to +// last-appearing. +// -------------------------------------------- +var + i: Integer; + Swapped: Boolean; +begin + + repeat + Swapped := False; + + for i := 0 to TempoChange_Count - 2 do + if TempoChange_Position[i] > TempoChange_Position[i + 1] then + begin + SwapTempoChanges(i, i + 1); + Swapped := True; + end; + + until not Swapped; + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure SortWavNames; +// =============================================== +// Sorts the WAV names so that in-use names appear +// at the start of the array. +// +// The Note_Sound[] Array will also be modified to +// reflect the changes in the WAV_Name[] array. +// ----------------------------------------------- +var + i: Integer; + Swapped: Boolean; +begin + + repeat + Swapped := False; + + for i := 1 to WAV_Count - 1 do + if WAV_Name[i] = '' then + if WAV_Name[i + 1] <> '' then + begin + SwapWavNames(i, i + 1); + Swapped := True; + end; + + until not Swapped; + +end; + + + +// ---------------------------------------------------------- + + + +procedure SwapBmpNames(X1, X2: Word); +// ====================================== +// Swaps the 2 file names in the BMP_Name +// array, and also all respective values +// in Note_Sound array (Also used for +// image numbers, despite the name) +// -------------------------------------- +var + Temp_BMP: String; + i: Word; +begin + Temp_BMP := BMP_Name[X1]; + BMP_Name[X1] := BMP_Name[X2]; + BMP_Name[X2] := Temp_BMP; + + for i := 0 to Event_Count - 1 do + if Note_Column[i] in [4..7] then + begin + if Note_Sound[i] = X1 then + Note_Sound[i] := X2 + else + if Note_Sound[i] = X2 then + Note_Sound[i] := X1; + end; + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure SwapEvents(X1, X2: Word); +// ================================== +// Swaps the positions of 2 events in +// all related variable arrays. +// ---------------------------------- +var + Temp_NT, Temp_NP: Single; + Temp_NM, Temp_NS: Word; + Temp_NC, Temp_NF: Byte; +begin + Temp_NT := Note_Time[X1]; + Temp_NP := Note_Position[X1]; + Temp_NM := Note_Measure[X1]; + Temp_NS := Note_Sound[X1]; + Temp_NC := Note_Column[X1]; + Temp_NF := Note_Flag[X1]; + + Note_Time[X1] := Note_Time[X2]; + Note_Position[X1] := Note_Position[X2]; + Note_Measure[X1] := Note_Measure[X2]; + Note_Sound[X1] := Note_Sound[X2]; + Note_Column[X1] := Note_Column[X2]; + Note_Flag[X1] := Note_Flag[X2]; + + Note_Time[X2] := Temp_NT; + Note_Position[X2] := Temp_NP; + Note_Measure[X2] := Temp_NM; + Note_Sound[X2] := Temp_NS; + Note_Column[X2] := Temp_NC; + Note_Flag[X2] := Temp_NF; +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure SwapTempoChanges(X1, X2: Word); +// ==================================== +// Swaps 2 values in each of the arrays +// related to Tempo Changes. +// ------------------------------------ +var + Temp_TCP, Temp_TCA: Single; + Temp_TCM: Word; +begin + Temp_TCM := TempoChange_Measure[X1]; + Temp_TCP := TempoChange_Position[X1]; + Temp_TCA := TempoChange_Amount[X1]; + + TempoChange_Measure[X1] := TempoChange_Measure[X2]; + TempoChange_Amount[X1] := TempoChange_Amount[X2]; + TempoChange_Position[X1] := TempoChange_Position[X2]; + + TempoChange_Measure[X2] := Temp_TCM; + TempoChange_Position[X2] := Temp_TCP; + TempoChange_Amount[X2] := Temp_TCA; +end; + + + +// ---------------------------------------------------------- + + + +procedure SwapWavNames(X1, X2: Word); +// ====================================== +// Swaps the 2 file names in the WAV_Name +// array, and also all respective values +// in Note_Sound array. +// -------------------------------------- +var + Temp_WAV: String; + i: Word; +begin + Temp_WAV := WAV_Name[X1]; + WAV_Name[X1] := WAV_Name[X2]; + WAV_Name[X2] := Temp_WAV; + + for i := 0 to Event_Count - 1 do + if (Note_Column[i] = 1) or + (Note_Column[i] >= 11) then + begin + if Note_Sound[i] = X1 then + Note_Sound[i] := X2 + else + if Note_Sound[i] = X2 then + Note_Sound[i] := X1; + end; + +end; + + + +// ---------------------------------------------------------- + + + +end. diff --git a/iidx/BMSto1/src/DB_XForm.pas b/iidx/BMSto1/src/DB_XForm.pas new file mode 100644 index 0000000..ff1465e --- /dev/null +++ b/iidx/BMSto1/src/DB_XForm.pas @@ -0,0 +1,459 @@ +unit DB_XForm; +// =============================================== +// DB_XForm.pas +// Created 2007.02.24 +// +// Contains procedures to transform and manipulate +// the data stored in the DB_Main.pas arrays. +// ----------------------------------------------- + +interface + +uses + DB_Main; + +procedure AddBackgroundStars; +procedure AddSoundChanges; +procedure ApplyAutoPlay; +procedure ApplyAutoScratch; +procedure ApplyEasy; +procedure ApplyMirror; +procedure ApplyRandom; +procedure ApplyMirrorPlus; +procedure CheckNoteSounds; +procedure DelayEvents(Seconds: Single); +procedure MakeKeyAmount(Amount: Byte); +procedure MakePlayerAmount(Amount: Byte); + + +implementation + + + +// ---------------------------------------------------------------------------- + + + +procedure AddBackgroundStars; +// =========================================================== +// Adds the Background star-field into the note pattern array, +// so they can be properly Z-plane sorted too! +// +// Only needed for the 3D mode. +// +// It's a good idea to call SortEvents after using this! +// ----------------------------------------------------------- +var + Latest_Note: Single; + i, ff: Integer; + Star_Type: Byte; +begin + + ff := GetFirstFreeEvent; + if ff < 0 then exit; + + Latest_Note := 0; + Star_Type := 0; + + for i := 0 to Event_Count - 1 do + if Note_Time[i] > Latest_Note then + Latest_Note := Note_Time[i]; + + repeat + Note_Column[ff] := 5; + Note_Time[ff] := Latest_Note; + Note_Sound[ff] := (Star_Type and 1) + 2; + Latest_Note := Latest_Note - 0.3; + inc(ff); + inc(Star_Type); + until Latest_Note < 0; + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure AddSoundChanges; +// ============================================== +// Creates a list of 'current sound to play when +// a button is pressed' events, and adds them to +// the note arrays. +// +// The sound change events will be placed halfway +// between 2 notes in a column. +// ---------------------------------------------- +var + i, ff: Integer; + Current_Time: Single; + Current_Sound: Word; + Current_Column: Byte; +begin + + ff := GetFirstFreeEvent; + if ff < 0 then exit; // Error! To handle later + + for Current_Column := 11 to 29 do + begin + Current_Sound := 0; + Current_Time := 0; + + for i := 0 to Event_Count - 1 do + if (Note_Column[i] = Current_Column) or + (Note_Column[i] = Current_Column + 20) then + begin + if Note_Sound[i] <> Current_Sound then + begin + if Current_Time = 0 then Note_Time[ff] := 0 + else Note_Time[ff] := ((Note_Time[i] - Current_Time) / 2) + Current_Time; + Note_Column[ff] := Note_Column[i] + 20; + Current_Sound := Note_Sound[i]; + Note_Sound[ff] := Current_Sound; + inc(ff); + end; + Current_Time := Note_Time[i]; + end; + + end; + +end; + + + +// ------------------------------------------------------------------------- + + + +procedure ApplyAutoPlay; +// ================================== +// This procedure sets the 'AutoPlay' +// flag of all notes. +// ---------------------------------- +var + i: Word; +begin + + for i := 0 to Event_Count - 1 do + if Note_Column[i] in [11..29] then + Note_Flag[i] := Note_Flag[i] or Flag_AutoPlay; + +end; + + + +// ------------------------------------------------------------------------- + + + +procedure ApplyAutoScratch; +// ================================= +// Converts all scratch-column notes +// into auto-play notes. +// --------------------------------- +var + i: Word; +begin + + for i := 0 to Event_Count - 1 do + if (Note_Column[i] = 16) or + (Note_Column[i] = 26) then + Note_Flag[i] := Note_Flag[i] or Flag_AutoPlay; + +end; + + + +// ------------------------------------------------------------------------- + + + +procedure ApplyEasy; +// ================================== +// This Auto-plays and hides all blue +// and scratch notes! +// ---------------------------------- +var + i: Word; +begin + + for i := 0 to Event_Count - 1 do + if Note_Time[i] > 0 then + case Note_Column[i] of + 12, 14, 16, 18, 22, 24: Note_Flag[i] := Note_Flag[i] or Flag_AutoPlay; + end; + +end; + + + +// ------------------------------------------------------------------------- + + + +procedure ApplyMirror; +// ===================================== +// Horizontally flips the note patterns. +// For now, only works on 5 and 7 key +// note charts. +// ------------------------------------- +var + i: word; + Column_From, Column_Base: byte; +const + M_5: array[1..6] of byte = (5, 4, 3, 2, 1, 6); + M_7: array[1..9] of byte = (9, 8, 5, 4, 3, 6, 0, 2, 1); +begin + for i := 0 to Event_Count - 1 do + begin + + if Note_Column[i] > 10 then + begin + Column_From := Note_Column[i]; + while Column_From > 10 do dec(Column_From, 10); + Column_Base := Note_Column[i] - Column_From; + case KeyAmount of + 5: Note_Column[i] := Column_Base + M_5[Column_From]; + 7: Note_Column[i] := Column_Base + M_7[Column_From]; + end; + end; + + end; +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure ApplyMirrorPlus; +// =========================================== +// This flips the note patterns upside down... +// Last note first, and first note last! +// +// Only transforms the visible keys. BG sounds +// and other things aren't modified. +// +// A call to DB.SortEvents will definitely be +// needed after calling this. +// ------------------------------------------- +var + i: Word; + MaxNoteTime: Single; +begin + MaxNoteTime := 0; + + for i := 0 to Event_Count - 1 do // Find the note with the + if Note_Time[i] > MaxNoteTime then // latest play-time. + if Note_Column[i] in [11..29] then // + MaxNoteTime := Note_Time[i]; // + + for i := 0 to Event_Count - 1 do + if Note_Column[i] >= 11 then + begin + Note_Time[i] := MaxNoteTime - Note_Time[i]; + Note_Measure[i] := Measure_Count - Note_Measure[i]; + end; + +end; + + + +// ------------------------------------------------------------------------- + + + +procedure ApplyRandom; +// ============================================= +// Randomizes the columns of notes, not the note +// positions themselves. +// --------------------------------------------- +var + i: word; + i2, r_i, pl_num, column: byte; + R_9, R2_9: array[1..10] of byte; + ok: boolean; +begin + + for i2 := 1 to 10 do + R_9[i2] := i2; + + R2_9 := R_9; + + if KeyAmount <> 9 then + R2_9[6] := 10; + + if KeyAmount = 5 then + for i2 := 7 to 9 do R2_9[i2] := 10; + + if KeyAmount = 7 then + R2_9[7] := 10; + + Randomize; + + for i2 := 1 to 9 do + begin + ok := True; + if R2_9[i2] = 10 then ok := False; + if ok then + begin + r_i := Random(9); + while (R2_9[r_i] = 0) or + (R2_9[r_i] = 10) do + begin + inc(r_i); + if r_i = 10 then r_i := 1 + end; + R_9[i2] := r_i; + R2_9[r_i] := 0; + end; + end; + + for i := 0 to Event_Count - 1 do // New column places generated, + begin // now look through the arrays + Column := Note_Column[i]; // and change the needed notes. + while Column > 10 do dec(Column, 10); + pl_num := Note_Column[i] - Column; + if pl_num > 0 then + if Column > 0 then + Note_Column[i] := pl_num + R_9[Column]; + end; + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure CheckNoteSounds; +// ====================================== +// This checks to make sure the values in +// the Note_Sound array don't exceed the +// total amount of WAV files. +// +// If a note does, then it is set to 0, +// a blank WAV. +// -------------------------------------- +var + i: Word; +begin + + for i := 0 to Event_Count - 1 do + if Note_Sound[i] > WAV_Count then + if (Note_Column[i] = 1) or + (Note_Column[i] >= 11) then + Note_Sound[i] := 0; + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure DelayEvents(Seconds: Single); +// ======================================================== +// Re-positions the events so that the first playable note +// is no less than the specified time in seconds from the +// song's beginning. +// +// If the note array is already sorted before calling this, +// another sort after won't be necessary. The notes will +// still be in the same time order as before this procedure +// is called. +// -------------------------------------------------------- +var + i: Integer; + Delay_Time: single; +begin + + Delay_Time := Seconds; + + for i := 0 to Event_Count - 1 do // Find the first playable note + if Note_Column[i] in [11..29] then // closest to the song's start, + if Note_Time[i] < Seconds then // but which also appears before + if Note_Time[i] >= 0 then // the song's 3-second mark. + if Note_Time[i] < Delay_Time then // + Delay_Time := Note_Time[i]; // + + Delay_Time := Seconds - Delay_Time; // Change the note's time into the + // desired amount to add to all notes. + + for i := 0 to Event_Count - 1 do + Note_Time[i] := Note_Time[i] + Delay_Time; + +end; + + + +// ---------------------------------------------------------------------------- + + + +procedure MakeKeyAmount(Amount: byte); +// ========================================= +// This optimizes a note layout to match the +// specified key amount. +// +// 7-key note layouts don't seem to need any +// modification. +// ----------------------------------------- +var + i: Word; +begin + + for i := 0 to Event_Count - 1 do + case Amount of + 5: if (Note_Column[i] in [18..19]) or + (Note_Column[i] in [28..29]) then + begin + Note_Column[i] := 1; + Note_Flag[i] := Note_Flag[i] or Flag_AutoPlay; + end; + 9: if (Note_Column[i] in [16..21]) or + (Note_Column[i] in [26..29]) then + begin + Note_Column[i] := 1; + Note_Flag[i] := Note_Flag[i] or Flag_AutoPlay; + end; + end; + +end; + + + +// ------------------------------------------------------------------------- + + + +procedure MakePlayerAmount(Amount: Byte); +// ================================================ +// This will optimize a note-chart for the intended +// amount of players. +// ------------------------------------------------ +var + i: Word; +begin + + for i := 0 to Event_Count - 1 do + if Amount = 1 then + if Note_Column[i] in [21..29] then + begin + Note_Column[i] := 1; + Note_Flag[i] := Note_Flag[i] or Flag_AutoPlay; + end; + +end; + + + +// ------------------------------------------------------------------------- + + + +end. diff --git a/iidx/BMSto1/src/DXAC1.pas b/iidx/BMSto1/src/DXAC1.pas new file mode 100644 index 0000000..125aa13 --- /dev/null +++ b/iidx/BMSto1/src/DXAC1.pas @@ -0,0 +1,297 @@ +unit DXAC1; +// ========================================================= +// DXAC1.pas +// Created 2007.04.03 +// Updated 2007.04.05 - Fixed 'no end-of-song' event bug. +// Updated 2007.04.06 - Corrected time of 'song stop' event. +// +// Converts data currently loaded in DB_Main arrays +// to the .1 format. +// --------------------------------------------------------- + +interface + +uses + SysUtils, Classes, DB_Main; + +type T1Event = packed record + Event_Time: Cardinal; // Time of the event, in (Seconds*FrameRate) + Event_Type: Byte; // What kind of event. + Data1: Byte; // Use depends on the event's type. + Data2: Word; // Use depends on the event's type. + end; + +type T1HeaderEntry = packed record + NoteChart_Offset: Cardinal; // Byte location of note chart. + NoteChart_Size: Cardinal; // Byte size of note chart. + end; + +type T1Header = packed record + Entry: array[1..12] of T1HeaderEntry; + end; + +const + EndSequenceTime: Cardinal = 2130706432; // This value (0, 0, 0, 127) marks the + // end of the note data sequence + + FrameRate: Single = 59.941; // Try 60 if this value gives undesired results. + + JudgementEvents: array[1..48] of byte = (0, 0, 0, 0, 8, 0, 240, 0, // These + 0, 0, 0, 0, 8, 1, 248, 0, // are + 0, 0, 0, 0, 8, 2, 255, 0, // from + 0, 0, 0, 0, 8, 3, 3, 0, // 5.1.1 + 0, 0, 0, 0, 8, 4, 10, 0, // + 0, 0, 0, 0, 8, 5, 18, 0); // + +var + DX1Stream: TMemoryStream; + + +function Save1(Path_File: String): Boolean; +function Create1Chart: Boolean; + +implementation + + + +// ---------------------------------------------------------------------------- + + + +function Save1(Path_File: String): Boolean; +begin + Create1Chart; + DX1Stream.SaveToFile(Path_File); + DX1Stream.Free; + Result := True; +end; + + + +// ---------------------------------------------------------------------------- + + + +function Create1Chart: Boolean; +// ================================== +// Generates a .1 note chart from the +// currently loaded song, and keeps +// the data stream in memory. +// ---------------------------------- +var + i, LastEventTime: Integer; + Event: T1Event; + Header: T1Header; + TempStream: TMemoryStream; + +begin + + // ================================= + // Create a temporary data stream to + // hold the converted note info. + // + // Also prepare the note chart's + // "header". + // --------------------------------- + TempStream := TMemoryStream.Create; + TempStream.SetSize(Event_Count shl 5); // Allow for 2x space + // just to be safe. + + Event.Event_Time := 0; // Add 'Total Notes' + Event.Event_Type := 16; // event marker + Event.Data1 := 0; // + Event.Data2 := TotalNotes; // + TempStream.WriteBuffer(Event, 8); // + + Event.Data1 := 1; // The 'Bad' event? + Event.Data2 := 0; // + TempStream.WriteBuffer(Event, 8); // + // + + Event.Event_Type := 4; // Prepare and write the + Event.Data1 := 100; // song's starting tempo + Event.Data2 := Trunc(Tempo * 100); // event. + TempStream.WriteBuffer(Event, 8); // + + Event.Event_Type := 5; // The 'Measure Size' + Event.Data1 := 4; // event. Not sure if + Event.Data2 := 4; // this is even used + TempStream.WriteBuffer(Event, 8); // by anything. + + TempStream.WriteBuffer(JudgementEvents, 48); // Default timing + // settings. + + // ================================= + // Now go through the Event database + // and convert to .1 events + // --------------------------------- + LastEventTime := 0; + for i := 0 to Event_Count - 1 do + begin + FillChar(Event, 8, 0); // Reset event variable + Event.Event_Time := Trunc(Note_Time[i] * FrameRate); + + case Note_Column[i] of + 1: begin // -------------------------------------------------------------- + Event.Event_Type := 7; // BG Autoplay + Event.Data2 := Note_Sound[i]; // + end; + 8: begin + Event.Event_Type := 4; // Tempo Change + if Note_Position[i] <= 655.35 then // + begin // Tempo values + Event.Data1 := 100; // 655.35 BPM and + Event.Data2 := Trunc(Note_Position[i] * 100); // smaller will + end // use the special + else // '100' divisor. + begin // + Event.Data1 := 1; // Higher values + Event.Data2 := Trunc(Note_Position[i]); // will be divided + end; // by 1. + end; + 10: Event.Event_Type := 12; // Measure Line + 11..15: begin // --------------------------------------------------------- + Event.Event_Type := 0; // Player 1 + Event.Data1 := Note_Column[i] - 11; // Keys 1-5 + end; + 16: begin + Event.Event_Type := 0; // Player 1 + Event.Data1 := 7; // Scratch Note + end; + 18..19: begin + Event.Event_Type := 0; // Player 1 + Event.Data1 := Note_Column[i] - 13; // Keys 6-7 + end; + 21..25: begin // --------------------------------------------------------- + Event.Event_Type := 1; // Player 2 + Event.Data1 := Note_Column[i] - 21; // Keys 1-5 + end; + 26: begin + Event.Event_Type := 1; // Player 2 + Event.Data1 := 7; // Scratch Note + end; + 28..29: begin + Event.Event_Type := 1; // Player 2 + Event.Data1 := Note_Column[i] - 23; // Keys 6-7 + end; + 31..35: begin // --------------------------------------------------------- + Event.Event_Type := 2; // Player 1 Sound + Event.Data1 := Note_Column[i] - 31; // Change,Keys 1-5 + Event.Data2 := Note_Sound[i]; // + end; + 36: begin + Event.Event_Type := 2; // Player 1 Sound + Event.Data1 := 7; // Change,Scratch + Event.Data2 := Note_Sound[i]; // + end; + 38..39: begin + Event.Event_Type := 2; // Player 1 Sound + Event.Data1 := Note_Column[i] - 33; // Change,Keys 6-7 + Event.Data2 := Note_Sound[i]; // + end; + 41..45: begin // --------------------------------------------------------- + Event.Event_Type := 3; // Player 2 Sound + Event.Data1 := Note_Column[i] - 41; // Change,Keys 1-5 + Event.Data2 := Note_Sound[i]; // + end; + 46: begin + Event.Event_Type := 3; // Player 2 Sound + Event.Data1 := 7; // Change,Scratch + Event.Data2 := Note_Sound[i]; // + end; + 48..49: begin + Event.Event_Type := 3; // Player 2 Sound + Event.Data1 := Note_Column[i] - 43; // Change,Keys 6-7 + Event.Data2 := Note_Sound[i]; // + end; // ---------------------------------------------------------- + else Event.Event_Type := 255; // BGA? Skip it! + end; + + if Event.Event_Type <> 255 then + begin + LastEventTime := Event.Event_Time; + TempStream.WriteBuffer(Event, 8); + + if (Event.Event_Type = 12) and // Note chart data streams in 2-player + (Players > 1) then // .1 files require a seperate measure + begin // divider line event for each player. + Event.Data1 := 1; // Absolutely no idea why that is, but + TempStream.WriteBuffer(Event, 8); // this code portion will add it in. + end; + + end; + + end; + + + // ============================ + // Done with all of that? Yes! + // Finalize the note chart now. + // ---------------------------- + Event.Event_Time := LastEventTime + 60; // Create the "End Song" event. + Event.Event_Type := 6; // For now, this event will + Event.Data1 := 0; // always be placed 1 second + Event.Data2 := 0; // after the last event. + TempStream.WriteBuffer(Event, 8); // + + if Players > 1 then + begin + Event.Data1 := 1; // Write a second end-of-song event + TempStream.WriteBuffer(Event, 8); // for player 2 if needed. + end; + + + FillChar(Event, 8, 0); // Create the "0 0 0 127 0 0 0 0" + Event.Event_Time := EndSequenceTime; // "End of Sequence" event marker. + TempStream.WriteBuffer(Event, 8); // + + // ============================= + // Create the actual data stream + // and the .1 header. + // ----------------------------- + TempStream.SetSize(TempStream.Position); + TempStream.Seek(0, soFromBeginning); + FillChar(Header, 96, 0); // Erase any existing old info in this + + Header.Entry[1].NoteChart_Offset := 96; // Create the entry + Header.Entry[1].NoteChart_Size := TempStream.Size; // to the chart's data. + + for i := 2 to 4 do // Copy entry #1 to all other in-use + Header.Entry[i] := Header.Entry[1]; // entry positions for player 1. + // (7,L7,A7,Beg) + + for i := 7 to 9 do // And again for all of player 2's + Header.Entry[i] := Header.Entry[1]; // note charts. (14,L14,A14) + + + // ===================================================================== + // A little information about why the above is doing that... + // + // .1 headers are always 96 bytes long, so the first existing note chart + // can have an offset value of 96. + // + // And since this early version of Save1 supports only 1 BMS at a time, + // this will use that BMS note chart for all supported difficulties. + // + // Also, since all difficulties share the same chart, each offset in the + // .1 header can point to the same byte location. No idea if that will + // actually work on the official implementation, but let's try it! + // --------------------------------------------------------------------- + + + // ====================================== + // Finally, create the actual data stream + // to use for saving the .1 file. + // -------------------------------------- + DX1Stream := TMemoryStream.Create; + DX1Stream.WriteBuffer(Header, 96); + DX1Stream.CopyFrom(TempStream, TempStream.Size); + TempStream.Free; + + Result := True; + +end; + + + +end. diff --git a/iidx/BMSto1/src/DXAC2DX.pas b/iidx/BMSto1/src/DXAC2DX.pas new file mode 100644 index 0000000..444324e --- /dev/null +++ b/iidx/BMSto1/src/DXAC2DX.pas @@ -0,0 +1,148 @@ +unit DXAC2DX; +// ========================================== +// DXAC2DX.pas +// Created 2007.04.07 +// +// Compiles all the WAV sounds of a BMS song +// and combines them into 1 .2dx file. +// +// Thanks to Kitaru and L for 2dx info. +// ------------------------------------------ + +interface + +uses + SysUtils, Classes, DB_Main, Utils; + +var + DX2DXStream: TMemoryStream; + + +function Save2DX(Path_File: String): Boolean; +function Create2DX(Path_File: String): Boolean; + + +implementation + + + +// ---------------------------------------------------------------------------- + + + +function Save2DX(Path_File: String): Boolean; +// ===================================== +// Creates a 2DX file through the use of +// other functions and procedures, then +// saves it. +// ------------------------------------- +begin + Create2DX(Path_File); + DX2DXStream.SaveToFile(Path_File); + DX2DXStream.Free; + Result := True; +end; + + + +// ---------------------------------------------------------------------------- + + + +function Create2DX(Path_File: String): Boolean; +// ==================================== +// Generates a .2dx combined audio file +// from the currently loaded BMS, and +// keeps the data stream in memory. +// ------------------------------------ +const + TwoDX9: Array[1..4] of Char = '2DX9'; + HeaderSize: Integer = 24; + Unknown1: Array[1..4] of Char = '02'#255#255; // Maybe L/R Volume? + Unknown2: Array[1..4] of Char = #64#0#1#0; // WAV format info? + Unknown3: Array[1..4] of Char = #0#0#0#0; // No idea... + +var + i, TotalWavs, + CurrentOffset, + WavSize: Integer; + Wav: TFileStream; + L: Word; + Text: String; +begin + + DX2DXStream := TMemoryStream.Create; + + Result := False; // At least 1 WAV is + TotalWavs := GetLastWavNumber; // needed for 2dx file + if TotalWavs = 0 then exit; // creation. + + + // ====================================== + // Create and write the .2dx header here. + // -------------------------------------- + + Text := copy(Artist, 1, 16); // First 16 bytes of a 2dx + L := Length(Text); // file are ignored. + if L < 16 then Text := Text + DupChar(16 - L, 0); // BMSto1 will use the BMS + DX2DXStream.WriteBuffer(Text[1], 16); // Artist's name here. + + TotalWavs := GetLastWavNumber; // Location of the first + CurrentOffset := 72 + TotalWavs * 4; // keysound is next. + DX2DXStream.WriteBuffer(CurrentOffset, 4); // Its location is usually + // Header Size + number of + // 4-byte WAV entries. + + DX2DXStream.WriteBuffer(TotalWavs, 4); // Write the total number + // of WAV sounds. + + Text := copy(TitleOnly(Title), 1, 48); // Next 48 bytes are also + L := Length(Text); // ignored. + if L < 48 then Text := Text + DupChar(48 - L, 0); // The BMS Title will be + DX2DXStream.WriteBuffer(Text[1], 48); // entered here. + + + // ================================ + // Now for the .2dx WAV entry list. + // -------------------------------- + for i := 1 to TotalWavs do + begin + DX2DXStream.WriteBuffer(CurrentOffset, 4); // In a 2dx file, + WavSize := FileSize2(NoFile(Path_File) + Wav_Name[i]); // WAV files have 24 + inc(CurrentOffset, WavSize + 24); // extra bytes added. + end; + + + // ================================ + // Now for the WAV files + headers. + // -------------------------------- + for i := 1 to TotalWavs do + begin + + DX2DXStream.WriteBuffer(TwoDX9[1], 4); // Header begins with + DX2DXStream.WriteBuffer(HeaderSize, 4); // '2DX9'. Size of + // header is 24 bytes + + WavSize := FileSize2(NoFile(Path_File) + Wav_Name[i]); // Actual WAV file + DX2DXStream.WriteBuffer(WavSize, 4); // size (no header) + + DX2DXStream.WriteBuffer(Unknown1, 4); // Volume/pan? + DX2DXStream.WriteBuffer(Unknown2, 4); // WAV Format info? + DX2DXStream.WriteBuffer(Unknown3, 4); // Null? + + Wav := TFileStream.Create(NoFile(Path_File) + Wav_Name[i], fmOpenRead); + DX2DXStream.CopyFrom(Wav, WavSize); + Wav.Free; + + end; + + Result := True; +end; + + + +// ---------------------------------------------------------------------------- + + + +end. diff --git a/iidx/BMSto1/src/Utils.pas b/iidx/BMSto1/src/Utils.pas new file mode 100644 index 0000000..2352868 --- /dev/null +++ b/iidx/BMSto1/src/Utils.pas @@ -0,0 +1,271 @@ +unit Utils; +// ================================================= +// Utils.pas +// Created 2007.02.27 +// Updated 2007.04.05 - Fixed a NoFile bug. +// Updated 2007.04.07 - Added DupChar and FileSize2. +// Re-wrote IsIn function. +// +// A set of various often-used routines. +// ------------------------------------------------- + + +interface + +uses + SysUtils; + +function DupChar(Amount: Word; Value: Byte): String; +function FileSize2(Path_File: String): Integer; +function HexToInt(HexNum: String): Integer; +function IntToBool(i: Integer): Boolean; +function IsIn(Text1, Text2: String): Boolean; +function NoExt(Text: String): String; +function NoFile(Text: String): String; +function NoPath(Text: String): String; +function TitleOnly(Title: String): String; + + +implementation + + + +// --------------------------------------------------------------------------- + + + +function DupChar(Amount: Word; Value: Byte): String; +// =========================================== +// Creates a text string consisting of a given +// ASCII value repeated a specified number of +// times. +// ------------------------------------------- +var + i: Byte; +begin + Result := ''; + for i := 1 to Amount do + Result := Result + Char(Value); +end; + + + +// --------------------------------------------------------------------------- + + + +function FileSize2(Path_File: String): Integer; +// =============================== +// An easier way to call FileSize. +// ------------------------------- +var + F: File; +begin + AssignFile(F, Path_File); + Reset(F, 1); + Result := FileSize(F); + CloseFile(f); +end; + + + +// --------------------------------------------------------------------------- + + + +function HexToInt(HexNum: string): Integer; +// ============================================== +// Converts a Hexadecimal number to decimal form. +// ---------------------------------------------- +begin + Result := StrToInt('$' + HexNum); +end; + + + +// --------------------------------------------------------------------------- + + + +function IntToBool(i: Integer): Boolean; +// ============================================ +// Converts a number into a boolean expression. +// -------------------------------------------- +begin + if i <> 0 then Result := True + else Result := False; +end; + + + +// --------------------------------------------------------------------------- + + + +function IsIn(Text1, Text2: String): Boolean; +// ============================================= +// Checks to see if the letter/word/phrase Text2 +// exists somewhere in Text1. +// --------------------------------------------- +var + Amount_Similar, i1, i2, L1, L2: Word; +begin + + Result := False; + L1 := Length(Text1); + L2 := Length(Text2); + + if (L1 = 0) or // Search fails with Zero-length strings. + (L2 = 0) or // + (L2 > L1) then exit; // Also fails if the text to look for + // is larger than the text to look in. + + for i1 := 0 to L1 - L2 do + begin + Amount_Similar := 0; + + for i2 := 1 to L2 do + if Text1[i1 + i2] = Text2[i2] then + inc(Amount_Similar); + + if Amount_Similar = L2 then + Result := True; + + end; + +end; + + + +// --------------------------------------------------------------------------- + + + +function NoExt(Text: String): String; +// ============================================ +// Removes a file extension from a text string. +// +// For example, NoExt('C:\PATH\FILE.TXT') +// would return C:\PATH\FILE +// -------------------------------------------- +var + i: Byte; +begin + i := Length(Text); + while (i > 1) and (Text[i] <> '.') and (Text[i] <> '\') do dec(i); + if (i > 1) and (Text[i] <> '\') then Result := copy(Text, 1, i - 1) + else Result := Text; // No extension found! +end; + + + +// --------------------------------------------------------------------------- + + + +function NoFile(Text: String): String; +// ========================================= +// Removes the file name from a text string. +// +// For example, NoFile('C:\PATH\FILE.TXT') +// would return C:\PATH\ +// ----------------------------------------- +var + i: Word; +begin + i := Length(Text); + while (i >= 1) and (Text[i] <> '\') do dec(i); + if i >= 1 then Result := copy(Text, 1, i) + else Result := ''; // No path found. Erase it! +end; + + + +// --------------------------------------------------------------------------- + + + +function NoPath(Text: String): String; +// ======================================= +// Removes the path from a text string. +// For example, NoPath('C:\PATH\FILE.TXT') +// would return FILE.TXT +// ---------------------------------------- +var + i: Word; +begin + i := Length(Text); + while (i > 1) and (Text[i] <> '\') do dec(i); + if i > 1 then Result := copy(Text, i + 1, Length(Text) - i) + else Result := Text; // Already file-only! +end; + + + +// --------------------------------------------------------------------------- + + + +function TitleOnly(Title: String): String; +// ===================================================== +// Almost every BMS song contains multiple difficulties. +// +// As a way to mark the different difficulties, authors +// usually add in some text to the title of the song. +// +// This function attempts to find and remove such text, +// to make the song names match a little better. +// +// This isn't a catch-all, but it's successful on over +// 99% of existing BMS songs. +// +// First it looks for text surrounded by () [] or --. +// +// Then it checks if the text contains a certain phrase. +// If it does, the text starting with and following the +// first bracket will be removed from the song title. +// ----------------------------------------------------- +var + i, i2: Byte; + chr1, chr2: Char; + txt: String; + RemoveOK: Boolean; +begin + Result := Title; + i2 := Length(Title); + i := i2; + if i <= 1 then exit; + chr2 := Title[i]; + chr1 := ' '; + if chr2 = '-' then chr1 := chr2; + if chr2 = ')' then chr1 := '('; + if chr2 = ']' then chr1 := '['; + if chr1 = ' ' then exit; + dec(i); + while (i > 1) and (Title[i] <> chr1) do dec(i); + if i = 1 then exit; + + txt := UpperCase(copy(Title, i + 1, i2 - (i + 1))); // Get and check the text + RemoveOK := False; // between the 2 symbols + if IsIn(txt, 'BEGINNER') then RemoveOK := True; + if IsIn(txt, 'NORMAL') then RemoveOK := True; + if IsIn(txt, 'LIGHT') then RemoveOK := True; + if IsIn(txt, 'HYPER') then RemoveOK := True; + if IsIn(txt, 'ANOTHER') then RemoveOK := True; + if IsIn(txt, '5K') then RemoveOK := True; + if IsIn(txt, '7K') then RemoveOK := True; + if IsIn(txt, '9K') then RemoveOK := True; + if IsIn(txt, 'HARD') then RemoveOK := True; + if IsIn(txt, 'EASY') then RemoveOK := True; + + if RemoveOK then Result := TrimRight(copy(Title, 1, i - 1)); + +end; + + + +// --------------------------------------------------------------------------- + + + +end. diff --git a/iidx/Eout Editor/EoutEditor/EoutEnglish/decrypt.exe b/iidx/Eout Editor/EoutEditor/EoutEnglish/decrypt.exe new file mode 100644 index 0000000..b74fcbc Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/EoutEnglish/decrypt.exe differ diff --git a/iidx/Eout Editor/EoutEditor/EoutEnglish/encrypt.exe b/iidx/Eout Editor/EoutEditor/EoutEnglish/encrypt.exe new file mode 100644 index 0000000..8fb4693 Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/EoutEnglish/encrypt.exe differ diff --git a/iidx/Eout Editor/EoutEditor/EoutEnglish/eoutEdit.exe b/iidx/Eout Editor/EoutEditor/EoutEnglish/eoutEdit.exe new file mode 100644 index 0000000..a1257e5 Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/EoutEnglish/eoutEdit.exe differ diff --git a/iidx/Eout Editor/EoutEditor/EoutEnglish/eoutEdit.jar b/iidx/Eout Editor/EoutEditor/EoutEnglish/eoutEdit.jar new file mode 100644 index 0000000..833b5d0 Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/EoutEnglish/eoutEdit.jar differ diff --git a/iidx/Eout Editor/EoutEditor/EoutEnglish/readme-2ch.rtf b/iidx/Eout Editor/EoutEditor/EoutEnglish/readme-2ch.rtf new file mode 100644 index 0000000..82784a3 --- /dev/null +++ b/iidx/Eout Editor/EoutEditor/EoutEnglish/readme-2ch.rtf @@ -0,0 +1,286 @@ +{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;} +{\f11\fbidi \fmodern\fcharset128\fprq1{\*\panose 02020609040205080304}MS Mincho{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f34\fbidi \froman\fcharset1\fprq2{\*\panose 00000000000000000000}Cambria Math;} +{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f40\fbidi \fmodern\fcharset128\fprq1{\*\panose 02020609040205080304}@MS Mincho;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;} +{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} +{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f41\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f42\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\f44\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f45\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f46\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f47\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\f48\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f49\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f61\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f62\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;} +{\f64\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f65\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f66\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f67\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);} +{\f68\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f69\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f153\fbidi \fmodern\fcharset0\fprq1 MS Mincho Western{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};} +{\f151\fbidi \fmodern\fcharset238\fprq1 MS Mincho CE{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f152\fbidi \fmodern\fcharset204\fprq1 MS Mincho Cyr{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};} +{\f154\fbidi \fmodern\fcharset161\fprq1 MS Mincho Greek{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f155\fbidi \fmodern\fcharset162\fprq1 MS Mincho Tur{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};} +{\f158\fbidi \fmodern\fcharset186\fprq1 MS Mincho Baltic{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f411\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f412\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;} +{\f414\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f415\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f418\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f443\fbidi \fmodern\fcharset0\fprq1 @MS Mincho Western;} +{\f441\fbidi \fmodern\fcharset238\fprq1 @MS Mincho CE;}{\f442\fbidi \fmodern\fcharset204\fprq1 @MS Mincho Cyr;}{\f444\fbidi \fmodern\fcharset161\fprq1 @MS Mincho Greek;}{\f445\fbidi \fmodern\fcharset162\fprq1 @MS Mincho Tur;} +{\f448\fbidi \fmodern\fcharset186\fprq1 @MS Mincho Baltic;}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;} +{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} +{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;} +{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} +{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\*\defchp \fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{ +\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 +\snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* +\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 +\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}{\s15\ql \li0\ri0\widctlpar +\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 +\f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext15 \slink16 \ssemihidden \sunhideused \styrsid1316374 HTML Preformatted;}{\*\cs16 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 +\sbasedon10 \slink15 \slocked \ssemihidden \styrsid1316374 HTML Preformatted Char;}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid1316374}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1 +\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Anthony}{\operator Anthony}{\creatim\yr2007\mo8\dy5\hr14\min15}{\revtim\yr2007\mo8\dy5\hr14\min15}{\version2}{\edmins0}{\nofpages2}{\nofwords162}{\nofchars928}{\nofcharsws1088}{\vern32889}} +{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect +\widowctrl\ftnbj\aenddoc\trackmoves1\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\noxlattoyen +\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1440\dgvorigin1440\dghshow1\dgvshow1 +\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct +\asianbrkrule\rsidroot1316374\newtblstyruls\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0 +{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang +{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} +\pard\plain \ltrpar\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1316374 \rtlch\fcs1 +\af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +/*::::::::::::::::::::::::::::::::::::::::::::::::::: +\par :: +\par :: EditOut Ver. 2.10 +\par :: +\par :: Software for editing music information in eout +\par :: +\par :::::::::::::::::::::::::::::::::::::::::::::::::::*/ +\par +\par Included files: +\par EditOut.jar +\par swt.jar +\par swt-win32-3236.dll +\par split/1.SPLIT +\par eout.csv +\par +\par To use: +\par Double click on EditOut.jar if you have JRE5 or above installed on Windows. +\par (* Confirmed to work in JDK6u2 + Windows XP sp2) +\par +\par Operation: +\par CSV}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u19968\'88\'ea\u25324\'8a\'87\u12452\'83\'43\u12531\'83\'93\u12509\'83\'7c\u12540\'81\'5b\u12488\'83\'67\u12399 +\'82\'cd\u20184\'95\'74\u23646\'91\'ae\u12398\'82\'cc}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 eout.csv}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 +\loch\af11\hich\af11\dbch\f11 \uc2\u12434\'82\'f0\u-30325\'8c\'a9\u12394\'82\'c8\u12364\'82\'aa\u12425\'82\'e7\u-26619\'8d\'80\u30446\'96\'da\u22475\'96\'84\u12417\'82\'df\u12390\'82\'c4\u12367\'82\'ad\u12384\'82\'be\u12373\'82\'b3\u12356\'82\'a2\u12290 +\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par CSV}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12452\'83\'43\u12531\'83\'93\u12509\'83\'7c\u12540\'81\'5b\u12488\'83\'67\u21069\'91\'4f\u12395\'82\'c9}{ +\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 CSV}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u-30163\'90\'dd\u23450\'92\'e8\u12424 +\'82\'e6\u12426\'82\'e8\u20986\'8f\'6f\u21147\'97\'cd\u12375\'82\'b5\u12383\'82\'bd\u12356\'82\'a2}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 eout}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 +\fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12398\'82\'cc\u12496\'83\'6f\u12540\'81\'5b\u12472\'83\'57\u12519\'83\'87\u12531\'83\'93\u12434\'82\'f0\u-28552\'91\'49\u25246\'91\'f0\u12375\'82\'b5 +\u12390\'82\'c4\u12367\'82\'ad\u12384\'82\'be\u12373\'82\'b3\u12356\'82\'a2\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12487\'83\'66\u12540\'81\'5b\u12479\'83\'5e\u12501\'83\'74\u12457\'83\'48\u12523\'83\'8b +\loch\af11\hich\af11\dbch\f11 \u12480\'83\'5f\u12398\'82\'cc\u-27056\'8c\'c0\u30028\'8a\'45\u12434\'82\'f0\u-27036\'8f\'9c\u21435\'8b\'8e\u12375\'82\'b5\u12383\'82\'bd\u12398\'82\'cc\u12391\'82\'c5\u22909\'8d\'44\u12365\'82\'ab\u12394\'82\'c8\u30058 +\'94\'d4\u21495\'8d\'86\u12395\'82\'c9\u-28675\'92\'c7\u21152\'89\'c1\u21487\'89\'c2\u-32515\'94\'5c\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12524\'83\'8c\u12467\'83\'52\u12540\'81\'5b\u12489\'83\'68\u-30163\'90\'dd\u23450\'92\'e8\u12363\'82\'a9\u12425 +\'82\'e7\u25313\'8a\'67\u24373\'92\'a3\u12377\'82\'b7\u12427\'82\'e9\u12371\'82\'b1\u12392\'82\'c6\u12391\'82\'c5\u26032\'90\'56\u12383\'82\'bd\u12394\'82\'c8\u27005\'8a\'79\u26354\'8b\'c8\u12398\'82\'cc\u23450\'92\'e8\u32681\'8b\'60\u12418\'82\'e0\u21487 +\'89\'c2\u-32515\'94\'5c\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u-28666\'8b\'74\u-30335\'97\'76\u26395\'96\'5d\u-230\'81\'46}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par HS}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12398\'82\'cc\u12514\'83\'82\u12540\'81\'5b\u12489\'83\'68\u12479\'83\'5e\u12452\'83\'43\u12503\'83\'76\u-225 +\'81\'48}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 (104-105)}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12289\'81\'41\u12512 +\'83\'80\u12540\'81\'5b\u12499\'83\'72\u12540\'81\'5b\u12514\'83\'82\u12540\'81\'5b\u12489\'83\'68\u-225\'81\'48}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 (152-153)}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 +\fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12399\'82\'cd\u20206\'89\'bc\u21517\'96\'bc\u12391\'82\'c5\u12377\'82\'b7\u12289\'81\'41\u29992\'97\'70\u-28652\'93\'72\u12364\'82\'aa\u20998\'95\'aa +\u12363\'82\'a9\u12425\'82\'e7\u12394\'82\'c8\u12356\'82\'a2\u12398\'82\'cc\u12391\'82\'c5\u24773\'8f\'ee\u22577\'95\'f1\u19979\'89\'ba\u12373\'82\'b3\u12356\'82\'a2\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u21508\'8a\'65\u-26619\'8d\'80\u30446\'96\'da\u21517\'96\'bc\u12398\'82\'cc\u12418\'82\'e0\u12387\'82\'c1\u12392 +\'82\'c6\u-32145\'97\'c7\u12356\'82\'a2\u-26619\'8d\'80\u30446\'96\'da\u21517\'96\'bc\u26696\'88\'c4\u12434\'82\'f0\u21215\'95\'e5\u-26938\'8f\'57\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par +\par Bugs, etc: +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u-26618\'8f\'87\u27425\'8e\'9f\u23550\'91\'ce\u24540\'89\'9e\u12375\'82\'b5\u12414\'82\'dc\u12377\'82\'b7\u12398 +\'82\'cc\u12391\'82\'c5\u12473\'83\'58\u12524\'83\'8c\u12395\'82\'c9\u-30335\'97\'76\u26395\'96\'5d}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 age}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 +\fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12390\'82\'c4\u12367\'82\'ad\u12384\'82\'be\u12373\'82\'b3\u12356\'82\'a2\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par +\par Misc. Notes: +\par GOLD}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12461\'83\'4c\u12508\'83\'7b\u12531\'83\'93\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par I want to analyze data from 8th Style and below. +\par +\par History: +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12539\'81\'45}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 >>748}{\rtlch\fcs1 +\af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12373\'82\'b3\u12435\'82\'f1\u12398\'82\'cc\u24076\'8a\'f3\u26395\'96\'5d\u27231\'8b\'40\u-32515\'94\'5c\u-28675\'92\'c7\u21152 +\'89\'c1\u-248\'81\'69}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 HS}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12394\'82\'c8 +\u12425\'82\'e7}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 1300}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u-162\'81\'60 +\u12418\'82\'e0\u20351\'8e\'67\u29992\'97\'70\u21487\'89\'c2\u-32515\'94\'5c\u12395\'82\'c9\u12289\'81\'41}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 9999}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 +\fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12414\'82\'dc\u12391\'82\'c5\u30906\'8a\'6d\u-30067\'94\'46\u28168\'8d\'cf\u12415\'82\'dd\u-247\'81\'6a}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u12524\'83\'8c\u12452\'83\'43\u12516\'83\'84\u12540\'81\'5b\u-30163\'90\'dd\u23450\'92\'e8\u12398 +\'82\'cc}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 7}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12392\'82\'c6}{\rtlch\fcs1 +\af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 8}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12364\'82\'aa\u20837\'93\'fc\u12428\'82\'ea\u22793 +\'95\'cf\u12431\'82\'ed\u12387\'82\'c1\u12390\'82\'c4\u12383\'82\'bd\u12398\'82\'cc\u12434\'82\'f0\u20462\'8f\'43\u27491\'90\'b3}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u-29860\'95\'88\u-26782\'96\'ca\u23450\'92\'e8\u32681\'8b\'60\u12364\'82\'aa\u12468\'83\'53\u12511 +\'83\'7e\u12392\'82\'c6\u12375\'82\'b5\u12390\'82\'c4\u27531\'8e\'63\u12427\'82\'e9\u12398\'82\'cc\u12434\'82\'f0\u20462\'8f\'43\u27491\'90\'b3}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12539\'81\'45\u26354\'8b\'c8\u-30163\'90\'dd\u23450\'92\'e8\u-237\'82\'52\u12398\'82\'cc\u-29860\'95\'88\u-26782 +\'96\'ca\u12501\'83\'74\u12449\'83\'40\u12452\'83\'43\u12523\'83\'8b\u12398\'82\'cc\u21517\'96\'bc\u31216\'8f\'cc\u22793\'95\'cf\u26356\'8d\'58\u-248\'81\'69}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 ->2dx}{\rtlch\fcs1 +\af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12501\'83\'74\u12449\'83\'40\u12452\'83\'43\u12523\'83\'8b\u-247\'81\'6a}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u20445\'95\'db\u23384\'91\'b6\u26178\'8e\'9e\u12395\'82\'c9\u22833\'8e\'b8\u25943\'94\'73\u12377 +\'82\'b7\u12427\'82\'e9\u21839\'96\'e2\u-26548\'91\'e8\u12398\'82\'cc\u20462\'8f\'43\u27491\'90\'b3}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12539\'81\'45}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 HS}{\rtlch\fcs1 +\af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12289\'81\'41}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 DD}{\rtlch\fcs1 \af11\afs20 +\ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12289\'81\'41}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 GD}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 +\fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12398\'82\'cc\u20027\'8e\'e5\u-30335\'97\'76\u-237\'82\'52\u31278\'8e\'ed\u12398\'82\'cc}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 eout}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12395\'82\'c9\u23550\'91\'ce\u24540\'89\'9e}{\rtlch\fcs1 \af2\afs20 +\ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 AC6th}{\rtlch\fcs1 +\af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12473\'83\'58\u12524\'83\'8c\u12398\'82\'cc}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 >>592}{ +\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12373\'82\'b3\u12435\'82\'f1\u-32765\'8d\'6c\u26696\'88\'c4\u12398\'82\'cc}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 CSV}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u19968\'88\'ea\u25324\'8a\'87\u12452\'83\'43\u12531\'83\'93\u12509 +\'83\'7c\u12540\'81\'5b\u12488\'83\'67\u12395\'82\'c9\u23550\'91\'ce\u24540\'89\'9e}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u20104\'97\'5c\u32004\'96\'f1\u-26600\'97\'cc\u22495\'88\'e6\u12395\'82\'c9\u12388\'82\'c2\u12356 +\'82\'a2\u12390\'82\'c4\u25805\'91\'80\u20316\'8d\'ec\u19981\'95\'73\u-30335\'97\'76\u12398\'82\'cc\u12383\'82\'bd\u12417\'82\'df\u20840\'91\'53\u25764\'93\'50\u24259\'94\'70}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 + +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u12354\'82\'a0\u12427\'82\'e9\u31243\'92\'f6\u24230\'93\'78\u12398\'82\'cc\u-27245\'8a\'d4\u-28587 +\'88\'e1\u12356\'82\'a2\u12364\'82\'aa\u21547\'8a\'dc\u12414\'82\'dc\u12428\'82\'ea\u12383\'82\'bd\u25163\'8e\'e8\u21205\'93\'ae\u32232\'95\'d2\u-26938\'8f\'57\u28168\'8d\'cf\u12415\'82\'dd\u12398\'82\'cc}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 eout}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12395\'82\'c9\u23550\'91\'ce\u24540\'89\'9e}{\rtlch\fcs1 \af2\afs20 +\ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u21517\'96\'bc\u21069\'91\'4f\u12434\'82\'f0\u20184\'95\'74\u12369\'82\'af\u12390\'82\'c4\u20445 +\'95\'db\u23384\'91\'b6\u12434\'82\'f0\u-28675\'92\'c7\u21152\'89\'c1}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u21508\'8a\'65\u31278\'8e\'ed\u20462\'8f\'43\u27491\'90\'b3}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u20869\'93\'e0\loch\af11\hich\af11\dbch\f11 \u-28440\'95\'94\u12467\'83\'52\u12540\'81\'5b\u12489 +\'83\'68\u26368\'8d\'c5\u-28567\'93\'4b\u21270\'89\'bb}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12539\'81\'45\u21508\'8a\'65\u31278\'8e\'ed\u20462\'8f\'43\u27491\'90\'b3}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u19981\'95\'73\u-30335\'97\'76\u12394\'82\'c8\u-26619\'8d\'80\u30446\'96\'da\u12398\'82\'cc\u21066 +\'8d\'ed\u-27036\'8f\'9c}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12539\'81\'45\u21508\'8a\'65\u31278\'8e\'ed\u20462\'8f\'43\u27491\'90\'b3}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u26032\'90\'56\u-30321\'8b\'4b\u-28675\'92\'c7\u21152\'89\'c1\u12364\'82\'aa\u12391\'82\'c5\u12365 +\'82\'ab\u12394\'82\'c8\u12363\'82\'a9\u12387\'82\'c1\u12383\'82\'bd\u20214\'8c\'8f}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u26354\'8b\'c8\u-28675\'92\'c7\u21152\'89\'c1\u24460\'8c\'e3\u12484\'83\'63\u12522\'83\'8a\u12540 +\'81\'5b\u12395\'82\'c9\u21517\'96\'bc\u21069\'91\'4f\u12364\'82\'aa\u20986\'8f\'6f\u12394\'82\'c8\u12363\'82\'a9\u12387\'82\'c1\u12383\'82\'bd\u20214\'8c\'8f}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u-30616\'95\'5c\u31034\'8e\'a6\u12364\'82\'aa\u12362\'82\'a8\u12363\'82\'a9\u12375\'82\'b5\u12363 +\'82\'a9\u12387\'82\'c1\u12383\'82\'bd\u20214\'8c\'8f}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid1316374 +\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 +72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 +2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b +44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 +065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 +00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 +84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc +52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 +bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 +656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c +070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 +29e245eb2b260a0238fd010000ffff0300504b03041400060008000000210096b5ade296060000501b0000160000007468656d652f7468656d652f7468656d65 +312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87615b8116d8 +a5fb34d93a6c1dd0afb0475292c5585e9236d88aad3e2412f9e3fbff1e1fa9abd7eec70c1d1221294fda5efd72cd4324f1794093b0eddd1ef62fad79482a9c04 +98f184b4bd2991deb58df7dfbb8ad755446282607d22d771db8b944ad79796a40fc3585ee62949606ecc458c15bc8a702910f808e8c66c69b9565b5d8a314d3c +94e018c8de1a8fa94fd05093f43672e23d06af89927ac06762a049136785c10607758d9053d965021d62d6f6804fc08f86e4bef210c352c144dbab999fb7b471 +7509af678b985ab0b6b4ae6f7ed9ba6c4170b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83a6569632cd467faddec9699640f671 +9e76b7d6ac355c7c89feca9cccad4ea7d36c65b258a206641f1b73f8b5da6a6373d9c11b90c537e7f08dce66b7bbeae00dc8e257e7f0fd2badd5868b37a088d1 +e4600ead1ddaef67d40bc898b3ed4af81ac0d76a197c86826828a24bb318f3442d8ab518dfe3a20f000d6458d104a9694ac6d88728eee2782428d60cf03ac1a5 +193be4cbb921cd0b495fd054b5bd0f530c1931a3f7eaf9f7af9e3f45c70f9e1d3ff8e9f8e1c3e3073f5a42ceaa6d9c84e5552fbffdeccfc71fa33f9e7ef3f2d1 +17d57859c6fffac327bffcfc793510d26726ce8b2f9ffcf6ecc98baf3efdfdbb4715f04d814765f890c644a29be408edf3181433567125272371be15c308d3f2 +8acd249438c19a4b05fd9e8a1cf4cd296699771c393ac4b5e01d01e5a30a787d72cf1178108989a2159c77a2d801ee72ce3a5c545a6147f32a99793849c26ae6 +6252c6ed637c58c5bb8b13c7bfbd490a75330f4b47f16e441c31f7184e140e494214d273fc80900aedee52ead87597fa824b3e56e82e451d4c2b4d32a423279a +668bb6690c7e9956e90cfe766cb37b077538abd27a8b1cba48c80acc2a841f12e698f13a9e281c57911ce298950d7e03aba84ac8c154f8655c4f2af074481847 +bd804859b5e696007d4b4edfc150b12addbecba6b18b148a1e54d1bc81392f23b7f84137c2715a851dd0242a633f900710a218ed715505dfe56e86e877f0034e +16bafb0e258ebb4faf06b769e888340b103d3311da9750aa9d0a1cd3e4efca31a3508f6d0c5c5c398602f8e2ebc71591f5b616e24dd893aa3261fb44f95d843b +5974bb5c04f4edafb95b7892ec1108f3f98de75dc97d5772bdff7cc95d94cf672db4b3da0a6557f70db629362d72bcb0431e53c6066acac80d699a6409fb44d0 +8741bdce9c0e4971624a2378cceaba830b05366b90e0ea23aaa241845368b0eb9e2612ca8c742851ca251ceccc70256d8d87265dd96361531f186c3d9058edf2 +c00eafe8e1fc5c509031bb4d680e9f39a3154de0accc56ae644441edd76156d7429d995bdd88664a9dc3ad50197c38af1a0c16d684060441db02565e85f3b966 +0d0713cc48a0ed6ef7dedc2dc60b17e92219e180643ed27acffba86e9c94c78ab90980d8a9f0913ee49d62b512b79626fb06dccee2a432bbc60276b9f7dec44b +7904cfbca4f3f6443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc399161ee314bc2e75cf8759081743be1236ec4f4d6693e5336fb672c5dc24a8c33585b5fb +9cc24e1d4885545b58463634cc5416022cd19cacfccb4d30eb45296023fd35a458598360f8d7a4003bbaae25e331f155d9d9a5116d3bfb9a95523e51440ca2e0 +088dd844ec6370bf0e55d027a012ae264c45d02f708fa6ad6da6dce29c255df9f6cae0ec38666984b372ab5334cf640b37795cc860de4ae2816e95b21be5ceaf +8a49f90b52a51cc6ff3355f47e0237052b81f6800fd7b802239daf6d8f0b1571a8426944fdbe80c6c1d40e8816b88b8569082ab84c36ff0539d4ff6dce591a26 +ade1c0a7f669880485fd484582903d284b26fa4e2156cff62e4b9265844c4495c495a9157b440e091bea1ab8aaf7760f4510eaa69a6465c0e04ec69ffb9e65d0 +28d44d4e39df9c1a52ecbd3607fee9cec7263328e5d661d3d0e4f62f44acd855ed7ab33cdf7bcb8ae889599bd5c8b3029895b6825696f6af29c239b75a5bb1e6 +345e6ee6c28117e73586c1a2214ae1be07e93fb0ff51e133fb65426fa843be0fb515c187064d0cc206a2fa926d3c902e907670048d931db4c1a44959d366ad93 +b65abe595f70a75bf03d616c2dd959fc7d4e6317cd99cbcec9c58b34766661c7d6766ca1a9c1b327531486c6f941c638c67cd22a7f75e2a37be0e82db8df9f30 +254d30c1372581a1f51c983c80e4b71ccdd28dbf000000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f74 +68656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f24 +51eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198 +720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528 +a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c0200001300000000000000000000000000 +000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b000000000000000000000000 +002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c00000000000000000000000000140200007468 +656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210096b5ade296060000501b000016000000000000000000 +00000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b010000270000000000 +00000000000000009b0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000960a00000000} +{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d +617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 +6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 +656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} +{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; +\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; +\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; +\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 +4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 +d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f00000000000000000000000020cc +61a28cd7c701feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/iidx/Eout Editor/EoutEditor/EoutEnglish/readme.txt b/iidx/Eout Editor/EoutEditor/EoutEnglish/readme.txt new file mode 100644 index 0000000..87ece43 --- /dev/null +++ b/iidx/Eout Editor/EoutEditor/EoutEnglish/readme.txt @@ -0,0 +1,44 @@ +EditOut -2chan Sucks Edition- BETA +v1.0 for bemaniso +-------------------------------------- +Files found on 2ch by musicboy +Translations done by Soveryshiny +Translations Added to code by Anthony +Program Recompiled by infamouspat +Eout Encrypter/Decrypter by Tau +-------------------------------------- +Included in this package: + +decrypt.exe - eout.bin decrypter +encrypt.exe - eout.bin encrypter +eout.csv - Matser Song List (missing currently) +eoutEdit.exe - eout Editor execulatable +eoutEdit.jar - eout Editor jar file +readme.txt - readme +readme-2ch.rtf - original 2chan readme +swt-win32-3236.dll - dll file required for eout Editor +-------------------------------------- + +Basic uses: + +This program has not undergone much testing as we are still unaware +of it's full potential. We have currently got it to change some +difficulties on HS songs, but we don't really know what else it can +do. It potentially has the ability to Add songs to IIDX AC mixes. +From what we can tell it can currently only save proper eouts in +HS format. We have not been able to get it to work properly with DD +or GOLD. We have also not been able to try to add older songs as the +Master Songlist CSV file (eout.csv) was missing from the 2ch rar we +found. If anyone finds the eout.csv please send it to us. If anyone +has any luck with this program please post it in this thread: + +http://bemaniso.ws/forums.php?action=viewtopic&topicid=9206 + +To use the program, you must first decrypt the eout.bin from the game: +decrypt eout.bin eout.dec + +You then run that dec file into eoutEdit.exe(.jar) and edit as needed. +Afterwards you must re-encrypt the eout.dec file: +encrypt eout.dec eout.bin + +-Anthony \ No newline at end of file diff --git a/iidx/Eout Editor/EoutEditor/EoutEnglish/split/1.SPLIT b/iidx/Eout Editor/EoutEditor/EoutEnglish/split/1.SPLIT new file mode 100644 index 0000000..1c0d380 Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/EoutEnglish/split/1.SPLIT differ diff --git a/iidx/Eout Editor/EoutEditor/EoutEnglish/swt-win32-3236.dll b/iidx/Eout Editor/EoutEditor/EoutEnglish/swt-win32-3236.dll new file mode 100644 index 0000000..ca2abdf Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/EoutEnglish/swt-win32-3236.dll differ diff --git a/iidx/Eout Editor/EoutEditor/eout files/10_eout.dat b/iidx/Eout Editor/EoutEditor/eout files/10_eout.dat new file mode 100644 index 0000000..1089873 Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eout files/10_eout.dat differ diff --git a/iidx/Eout Editor/EoutEditor/eout files/crackeout.c b/iidx/Eout Editor/EoutEditor/eout files/crackeout.c new file mode 100644 index 0000000..08bd1a9 --- /dev/null +++ b/iidx/Eout Editor/EoutEditor/eout files/crackeout.c @@ -0,0 +1,111 @@ +#include +#include +#include + +#define ONE_BILLION 1000000000 +#define IDX_CURRENT_KEY 55 +#define IDX_COUNTER 56 +#define IDX_LAST 57 + +typedef unsigned char byte; + +static void mix(int *state) +{ + int tmp; + int i; + + for (i = 1 ; i < 25 ; i++) { + tmp = state[i]; + tmp -= state[i + 31]; + + if (tmp < 0) tmp += ONE_BILLION; + state[i] = tmp; + } + + for (i = 25 ; i <= IDX_CURRENT_KEY ; i++) { + tmp = state[i]; + tmp -= state[i - 24]; + + if (tmp < 0) tmp += ONE_BILLION; + state[i] = tmp; + } +} + +static void update_state(int *state, byte src_byte) +{ + int src; + int tmp; + int i; + + src = src_byte; + tmp = 1; + + state[IDX_CURRENT_KEY] = src; + + for (i = 0x15 ; i <= 0x46E ; i += 0x15) { + src -= tmp; + state[i % 0x37] = tmp; + tmp = src; + + if (tmp < 0) tmp += ONE_BILLION; + src = state[i % 0x37]; + } + + mix(state); + mix(state); + mix(state); + + state[IDX_COUNTER] = 0x37; +} + +static byte produce_key(int *state) +{ + int counter; + + counter = state[IDX_COUNTER] + 1; + state[IDX_COUNTER] = counter; + + if (counter > 0x37) { + mix(state); + counter = 1; + } + + state[IDX_COUNTER] = counter; + return state[counter]; +} + +int main(int argc, char **argv) +{ + const byte key[] = { + 0x55, 0x37, 0x9F, 0xCC, 0xE3, 0xA7, 0x7D, 0x99, + 0xDD, 0xAA, 0xBB, 0xCF, 0xFC, 0x67, 0x43, 0x17 + }; + + int state[IDX_LAST]; + int quo; + int rem; + int i; + byte b; + + /* Setup */ + i = 0; + memset(state, 0, sizeof(state)); + + /* Descramble */ + while (!feof(stdin)) { + quo = i / 0x10; + rem = i % 0x10; + i++; + + if (rem == 0) update_state(state, key[quo % 0x10]); + + b = getc(stdin); + b -= produce_key(state); + /* To rescramble an eout.bin, change -= above to += */ + + putc(b, stdout); + } + + return EXIT_SUCCESS; +} + diff --git a/iidx/Eout Editor/EoutEditor/eout files/dd_eout.dat b/iidx/Eout Editor/EoutEditor/eout files/dd_eout.dat new file mode 100644 index 0000000..26d7c05 Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eout files/dd_eout.dat differ diff --git a/iidx/Eout Editor/EoutEditor/eout files/eout/crackeout.c b/iidx/Eout Editor/EoutEditor/eout files/eout/crackeout.c new file mode 100644 index 0000000..08bd1a9 --- /dev/null +++ b/iidx/Eout Editor/EoutEditor/eout files/eout/crackeout.c @@ -0,0 +1,111 @@ +#include +#include +#include + +#define ONE_BILLION 1000000000 +#define IDX_CURRENT_KEY 55 +#define IDX_COUNTER 56 +#define IDX_LAST 57 + +typedef unsigned char byte; + +static void mix(int *state) +{ + int tmp; + int i; + + for (i = 1 ; i < 25 ; i++) { + tmp = state[i]; + tmp -= state[i + 31]; + + if (tmp < 0) tmp += ONE_BILLION; + state[i] = tmp; + } + + for (i = 25 ; i <= IDX_CURRENT_KEY ; i++) { + tmp = state[i]; + tmp -= state[i - 24]; + + if (tmp < 0) tmp += ONE_BILLION; + state[i] = tmp; + } +} + +static void update_state(int *state, byte src_byte) +{ + int src; + int tmp; + int i; + + src = src_byte; + tmp = 1; + + state[IDX_CURRENT_KEY] = src; + + for (i = 0x15 ; i <= 0x46E ; i += 0x15) { + src -= tmp; + state[i % 0x37] = tmp; + tmp = src; + + if (tmp < 0) tmp += ONE_BILLION; + src = state[i % 0x37]; + } + + mix(state); + mix(state); + mix(state); + + state[IDX_COUNTER] = 0x37; +} + +static byte produce_key(int *state) +{ + int counter; + + counter = state[IDX_COUNTER] + 1; + state[IDX_COUNTER] = counter; + + if (counter > 0x37) { + mix(state); + counter = 1; + } + + state[IDX_COUNTER] = counter; + return state[counter]; +} + +int main(int argc, char **argv) +{ + const byte key[] = { + 0x55, 0x37, 0x9F, 0xCC, 0xE3, 0xA7, 0x7D, 0x99, + 0xDD, 0xAA, 0xBB, 0xCF, 0xFC, 0x67, 0x43, 0x17 + }; + + int state[IDX_LAST]; + int quo; + int rem; + int i; + byte b; + + /* Setup */ + i = 0; + memset(state, 0, sizeof(state)); + + /* Descramble */ + while (!feof(stdin)) { + quo = i / 0x10; + rem = i % 0x10; + i++; + + if (rem == 0) update_state(state, key[quo % 0x10]); + + b = getc(stdin); + b -= produce_key(state); + /* To rescramble an eout.bin, change -= above to += */ + + putc(b, stdout); + } + + return EXIT_SUCCESS; +} + diff --git a/iidx/Eout Editor/EoutEditor/eout files/eout/dd_eout.dat b/iidx/Eout Editor/EoutEditor/eout files/eout/dd_eout.dat new file mode 100644 index 0000000..26d7c05 Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eout files/eout/dd_eout.dat differ diff --git a/iidx/Eout Editor/EoutEditor/eout files/eout/eout.bin b/iidx/Eout Editor/EoutEditor/eout files/eout/eout.bin new file mode 100644 index 0000000..1089873 Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eout files/eout/eout.bin differ diff --git a/iidx/Eout Editor/EoutEditor/eout files/eout/hs_eout.bin b/iidx/Eout Editor/EoutEditor/eout files/eout/hs_eout.bin new file mode 100644 index 0000000..b320e6c Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eout files/eout/hs_eout.bin differ diff --git a/iidx/Eout Editor/EoutEditor/eout files/eout/rd_eout.bin b/iidx/Eout Editor/EoutEditor/eout files/eout/rd_eout.bin new file mode 100644 index 0000000..78263a9 Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eout files/eout/rd_eout.bin differ diff --git a/iidx/Eout Editor/EoutEditor/eout files/hs_eout.dat b/iidx/Eout Editor/EoutEditor/eout files/hs_eout.dat new file mode 100644 index 0000000..b320e6c Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eout files/hs_eout.dat differ diff --git a/iidx/Eout Editor/EoutEditor/eout files/rd_eout.dat b/iidx/Eout Editor/EoutEditor/eout files/rd_eout.dat new file mode 100644 index 0000000..78263a9 Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eout files/rd_eout.dat differ diff --git a/iidx/Eout Editor/EoutEditor/eout/10_eout.dat b/iidx/Eout Editor/EoutEditor/eout/10_eout.dat new file mode 100644 index 0000000..1089873 Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eout/10_eout.dat differ diff --git a/iidx/Eout Editor/EoutEditor/eout/crackeout.c b/iidx/Eout Editor/EoutEditor/eout/crackeout.c new file mode 100644 index 0000000..08bd1a9 --- /dev/null +++ b/iidx/Eout Editor/EoutEditor/eout/crackeout.c @@ -0,0 +1,111 @@ +#include +#include +#include + +#define ONE_BILLION 1000000000 +#define IDX_CURRENT_KEY 55 +#define IDX_COUNTER 56 +#define IDX_LAST 57 + +typedef unsigned char byte; + +static void mix(int *state) +{ + int tmp; + int i; + + for (i = 1 ; i < 25 ; i++) { + tmp = state[i]; + tmp -= state[i + 31]; + + if (tmp < 0) tmp += ONE_BILLION; + state[i] = tmp; + } + + for (i = 25 ; i <= IDX_CURRENT_KEY ; i++) { + tmp = state[i]; + tmp -= state[i - 24]; + + if (tmp < 0) tmp += ONE_BILLION; + state[i] = tmp; + } +} + +static void update_state(int *state, byte src_byte) +{ + int src; + int tmp; + int i; + + src = src_byte; + tmp = 1; + + state[IDX_CURRENT_KEY] = src; + + for (i = 0x15 ; i <= 0x46E ; i += 0x15) { + src -= tmp; + state[i % 0x37] = tmp; + tmp = src; + + if (tmp < 0) tmp += ONE_BILLION; + src = state[i % 0x37]; + } + + mix(state); + mix(state); + mix(state); + + state[IDX_COUNTER] = 0x37; +} + +static byte produce_key(int *state) +{ + int counter; + + counter = state[IDX_COUNTER] + 1; + state[IDX_COUNTER] = counter; + + if (counter > 0x37) { + mix(state); + counter = 1; + } + + state[IDX_COUNTER] = counter; + return state[counter]; +} + +int main(int argc, char **argv) +{ + const byte key[] = { + 0x55, 0x37, 0x9F, 0xCC, 0xE3, 0xA7, 0x7D, 0x99, + 0xDD, 0xAA, 0xBB, 0xCF, 0xFC, 0x67, 0x43, 0x17 + }; + + int state[IDX_LAST]; + int quo; + int rem; + int i; + byte b; + + /* Setup */ + i = 0; + memset(state, 0, sizeof(state)); + + /* Descramble */ + while (!feof(stdin)) { + quo = i / 0x10; + rem = i % 0x10; + i++; + + if (rem == 0) update_state(state, key[quo % 0x10]); + + b = getc(stdin); + b -= produce_key(state); + /* To rescramble an eout.bin, change -= above to += */ + + putc(b, stdout); + } + + return EXIT_SUCCESS; +} + diff --git a/iidx/Eout Editor/EoutEditor/eout/crackeout.exe b/iidx/Eout Editor/EoutEditor/eout/crackeout.exe new file mode 100644 index 0000000..f52005e Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eout/crackeout.exe differ diff --git a/iidx/Eout Editor/EoutEditor/eout/dd_eout.dat b/iidx/Eout Editor/EoutEditor/eout/dd_eout.dat new file mode 100644 index 0000000..26d7c05 Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eout/dd_eout.dat differ diff --git a/iidx/Eout Editor/EoutEditor/eout/hs_eout.dat b/iidx/Eout Editor/EoutEditor/eout/hs_eout.dat new file mode 100644 index 0000000..b320e6c Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eout/hs_eout.dat differ diff --git a/iidx/Eout Editor/EoutEditor/eout/rd_eout.dat b/iidx/Eout Editor/EoutEditor/eout/rd_eout.dat new file mode 100644 index 0000000..78263a9 Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eout/rd_eout.dat differ diff --git a/iidx/Eout Editor/EoutEditor/eoutnum/eoutnum.exe b/iidx/Eout Editor/EoutEditor/eoutnum/eoutnum.exe new file mode 100644 index 0000000..c02715a Binary files /dev/null and b/iidx/Eout Editor/EoutEditor/eoutnum/eoutnum.exe differ diff --git a/iidx/Eout Editor/EoutEditor/eoutnum/list.txt b/iidx/Eout Editor/EoutEditor/eoutnum/list.txt new file mode 100644 index 0000000..7ee6b21 --- /dev/null +++ b/iidx/Eout Editor/EoutEditor/eoutnum/list.txt @@ -0,0 +1,446 @@ +1200 0 +1201 1 +1202 2 +1203 3 +1204 4 +1205 5 +1206 6 +1207 7 +1208 8 +1209 9 +1210 10 +1211 11 +1212 12 +1213 13 +1214 14 +1215 15 +1216 16 +1217 17 +1218 18 +1219 19 +1220 20 +1221 21 +1222 22 +1223 23 +1224 24 +1225 25 +1226 26 +1227 27 +1228 28 +1229 29 +1230 30 +1231 31 +1232 32 +1233 33 +1234 34 +1235 35 +1236 36 +1237 37 +1238 38 +1239 39 +1240 40 +1241 41 +1242 42 +1243 43 +1244 44 +1245 45 +1246 46 +1247 47 +1248 48 +1249 49 +1250 50 +1251 51 +1101 52 +1102 53 +1103 54 +1104 55 +1105 56 +1106 57 +1107 58 +1108 59 +1109 60 +1110 61 +1111 62 +1112 63 +1113 64 +1114 65 +1115 66 +1116 67 +1117 68 +1118 69 +1119 70 +1120 71 +1121 72 +1122 73 +1123 74 +1124 75 +1125 76 +1126 77 +1127 78 +1128 79 +1129 80 +1130 81 +1131 82 +1132 83 +1133 84 +1134 85 +1135 86 +1136 87 +1137 88 +1138 89 +1139 90 +1140 91 +1141 92 +1142 93 +1143 94 +1144 95 +1145 96 +1146 97 +1147 98 +1148 99 +1149 100 +1150 101 +1151 102 +1152 103 +1001 104 +1002 105 +1003 106 +1004 107 +1005 108 +1006 109 +1007 110 +1008 111 +1009 112 +1010 113 +1011 114 +1012 115 +1013 116 +1014 117 +1015 118 +1016 119 +1017 120 +1018 121 +1019 122 +1020 123 +1021 124 +1022 125 +1023 126 +1024 127 +1025 128 +1026 129 +1027 130 +1028 131 +1029 132 +1030 133 +1031 134 +1032 135 +1033 136 +1034 137 +1035 138 +1036 139 +1037 140 +1038 141 +1039 142 +1040 143 +1041 144 +1042 145 +1043 146 +1044 147 +1045 148 +1046 149 +1047 150 +1048 151 +1049 152 +1050 153 +1051 154 +1052 155 +1053 156 +1054 157 +0900 158 +0901 159 +0902 160 +0903 161 +0904 162 +0905 163 +0906 164 +0907 165 +0908 166 +0909 167 +0910 168 +0911 169 +0912 170 +0913 171 +0914 172 +0915 173 +0916 174 +0917 175 +0918 176 +0919 177 +0920 178 +0921 179 +0922 180 +0923 181 +0924 182 +0925 183 +0926 184 +0927 185 +0928 186 +0929 187 +0930 188 +0931 189 +0932 190 +0933 191 +0934 192 +0935 193 +0936 194 +0937 195 +0938 196 +0939 197 +0940 198 +0941 199 +0942 200 +0943 201 +0944 202 +0945 203 +0946 204 +0947 205 +0948 206 +0949 207 +0950 208 +0951 209 +0952 210 +0953 211 +0954 212 +0955 213 +0956 214 +0957 215 +0958 216 +0959 217 +0800 218 +0801 219 +0802 220 +0803 221 +0804 222 +0805 223 +0806 224 +0807 225 +0808 226 +0809 227 +0810 228 +0811 229 +0812 230 +0813 231 +0814 232 +0815 233 +0816 234 +0817 235 +0818 236 +0819 237 +0820 238 +0821 239 +0822 240 +0823 241 +0824 242 +0825 243 +0826 244 +0827 245 +0828 246 +0829 247 +0830 248 +0831 249 +0832 250 +0833 251 +0834 252 +0835 253 +0836 254 +0837 255 +0838 256 +0839 257 +0840 258 +0841 259 +0842 260 +0843 261 +0844 262 +0845 263 +0846 264 +0847 265 +0848 266 +0849 267 +0700 268 +0701 269 +0702 270 +0703 271 +0704 272 +0705 273 +0706 274 +0707 275 +0708 276 +0709 277 +0710 278 +0711 279 +0712 280 +0713 281 +0714 282 +0715 283 +0716 284 +0717 285 +0718 286 +0719 287 +0720 288 +0721 289 +0722 290 +0723 291 +0724 292 +0725 293 +0726 294 +0727 295 +0728 296 +0729 297 +0730 298 +0731 299 +0732 300 +0733 301 +0734 302 +0735 303 +0736 304 +0737 305 +0738 306 +0739 307 +0600 308 +0601 309 +0602 310 +0603 311 +0604 312 +0605 313 +0606 314 +0607 315 +0608 316 +0609 317 +0610 318 +0611 319 +0612 320 +0613 321 +0614 322 +0615 323 +0616 324 +0617 325 +0618 326 +0619 327 +0620 328 +0621 329 +0622 330 +0623 331 +0624 332 +0625 333 +0626 334 +0627 335 +0628 336 +0629 337 +0630 338 +0500 339 +0501 340 +0502 341 +0503 342 +0504 343 +0505 344 +0506 345 +0507 346 +0508 347 +0509 348 +0510 349 +0511 350 +0512 351 +0513 352 +0514 353 +0515 354 +0516 355 +0517 356 +0518 357 +0519 358 +0520 359 +0521 360 +0522 361 +0523 362 +0524 363 +0525 364 +0539 365 +0400 366 +0401 367 +0402 368 +0403 369 +0404 370 +0405 371 +0406 372 +0407 373 +0408 374 +0409 375 +0410 376 +0411 377 +0412 378 +0413 379 +0414 380 +0415 381 +0416 382 +0417 383 +0418 384 +0419 385 +0420 386 +0421 387 +0422 388 +0423 389 +0424 390 +0425 391 +0426 392 +0427 393 +0428 394 +0494 395 +0300 396 +0301 397 +0302 398 +0303 399 +0304 400 +0305 401 +0306 402 +0307 403 +0308 404 +0309 405 +0310 406 +0311 407 +0312 408 +0313 409 +0314 410 +0315 411 +0316 412 +0200 413 +0201 414 +0202 415 +0203 416 +0204 417 +0205 418 +0206 419 +0207 420 +0208 421 +0209 422 +0210 423 +0211 424 +0212 425 +0213 426 +0214 427 +0100 428 +0101 429 +0102 430 +0103 431 +0104 432 +0105 433 +0106 434 +0107 435 +0108 436 +0109 437 +0110 438 +0111 439 +0112 440 +0113 441 +0114 442 +0115 443 +0116 444 +0117 445 diff --git a/iidx/Eout Editor/EoutEditor/old/EoutEditor.jad b/iidx/Eout Editor/EoutEditor/old/EoutEditor.jad new file mode 100644 index 0000000..0bfe4ca --- /dev/null +++ b/iidx/Eout Editor/EoutEditor/old/EoutEditor.jad @@ -0,0 +1,1461 @@ +// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. +// Jad home page: http://www.kpdus.com/jad.html +// Decompiler options: packimports(3) ansi +// Source File Name: EoutEditor.java + +package net.ch2.ac.iidx; + +import com.cloudgarden.resource.SWTResourceManager; +import java.io.File; +import java.io.IOException; +import java.text.DecimalFormat; +import java.util.*; +import net.ch2.ac.iidx.eout.Eout; +import net.ch2.ac.iidx.eout.EoutSong; +import org.eclipse.swt.custom.*; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.*; + +public class EoutEditor extends Composite +{ + + public EoutEditor(Composite parent, int style) + { + super(parent, style); + SWTResourceManager.registerResourceUser(this); + writeMode = 12; + initGUI(); + } + + private void initGUI() + { + try + { + setSize(600, 400); + setBackground(SWTResourceManager.getColor(192, 192, 192)); + FillLayout thisLayout = new FillLayout(256); + setLayout(thisLayout); + sashForm = new SashForm(this, 0); + recordTree = new Tree(sashForm, 0); + recordTree.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + recordTreeWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + recordHead = new TreeItem(recordTree, 0); + recordHead.setText("BEMANI records"); + recordHead.setData("head"); + recordHead.setForeground(SWTResourceManager.getColor(0, 0, 255)); + songTabFolder = new CTabFolder(sashForm, 0); + Display display = Display.getDefault(); + songTabFolder.setSelectionBackground(new Color[] { + display.getSystemColor(32), display.getSystemColor(1) + }, new int[] { + 90 + }, true); + songSet1CTabItem = new CTabItem(songTabFolder, 0); + songSet1CTabItem.setText("‹È�Ý’è‚P"); // Song settings 1 + songSet1ScrolledComposite = new ScrolledComposite(songTabFolder, 2816); + songSet1CTabItem.setControl(songSet1ScrolledComposite); + songSet1ScrolledComposite.setBackground(SWTResourceManager.getColor(212, 208, 200)); + songSet1ScrolledComposite.setEnabled(true); + songSet1Composite = new Composite(songSet1ScrolledComposite, 0); + songSet1Composite.setLayout(null); + songSet1ScrolledComposite.setContent(songSet1Composite); + songSet1Composite.setBounds(0, 0, 406, 203); + label6 = new Label(songSet1Composite, 0); + label6.setText("‹Èƒ^ƒCƒgƒ‹"); // Song Title + label6.setBounds(7, 14, 56, 14); + songNameText = new Text(songSet1Composite, 2052); + songNameText.setBounds(98, 7, 301, 21); + songNameText.setTextLimit(32); + label7 = new Label(songSet1Composite, 0); + label7.setText("ƒ‰ƒxƒ‹’è‹`–¼"); // Label name assigned + label7.setBounds(7, 42, 70, 14); + labelImageText = new Text(songSet1Composite, 2052); + labelImageText.setTextLimit(32); + labelImageText.setBounds(98, 35, 301, 21); + label8 = new Label(songSet1Composite, 0); + label8.setText("ƒ^ƒCƒgƒ‹’è‹`–¼"); // Title name assigned + label8.setBounds(7, 70, 77, 14); + titleImageText = new Text(songSet1Composite, 2052); + titleImageText.setTextLimit(32); + titleImageText.setBounds(98, 63, 301, 21); + label9 = new Label(songSet1Composite, 0); + label9.setText("ƒ}�[ƒN’è‹`–¼"); // Mark name assigned + label9.setBounds(7, 98, 70, 14); + markImageText = new Text(songSet1Composite, 2052); + markImageText.setTextLimit(32); + markImageText.setBounds(98, 91, 301, 21); + label11 = new Label(songSet1Composite, 0); + label11.setText("ƒWƒƒƒ“ƒ‹’è‹`–¼"); // Genre name assigned + label11.setBounds(7, 126, 77, 14); + genreImageText = new Text(songSet1Composite, 2052); + genreImageText.setTextLimit(32); + genreImageText.setBounds(98, 119, 301, 21); + label12 = new Label(songSet1Composite, 0); + label12.setText("ƒA�[ƒeƒBƒXƒg’è‹`–¼"); // Artist name assigned + label12.setBounds(7, 154, 91, 14); + artistImageText = new Text(songSet1Composite, 2052); + artistImageText.setTextLimit(32); + artistImageText.setBounds(98, 147, 301, 21); + songSet1Button = new Button(songSet1Composite, 0x1000008); + songSet1Button.setText("�‘‚«Š·‚¦"); // write changes + songSet1Button.setBounds(98, 175, 63, 21); + songSet1Button.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + songSet1ButtonWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + text1 = new Text(songSet1Composite, 2052); + text1.setTextLimit(32); + text1.setBounds(98, 7, 301, 21); + songSet2CTabItem = new CTabItem(songTabFolder, 0); + songSet2CTabItem.setText("‹È�Ý’è‚Q"); // song settings 2 + songSet2ScrolledComposite = new ScrolledComposite(songTabFolder, 2816); + songSet2CTabItem.setControl(songSet2ScrolledComposite); + songSet2ScrolledComposite.setEnabled(true); + songSet2Composite = new Composite(songSet2ScrolledComposite, 0); + songSet2Composite.setLayout(null); + songSet2ScrolledComposite.setContent(songSet2Composite); + songSet2Composite.setBounds(0, 0, 266, 182); + label13 = new Label(songSet2Composite, 0); + label13.setText("‘I‹ÈƒtƒHƒ‹ƒ_"); // Selected song folder + label13.setBounds(7, 14, 63, 14); + versionFolderCombo = new Combo(songSet2Composite, 0); + versionFolderCombo.setBounds(70, 7, 105, 21); + versionFolderCombo.add("1st style"); + versionFolderCombo.add("sub stream"); + versionFolderCombo.add("2nd style"); + versionFolderCombo.add("3rd style"); + versionFolderCombo.add("4th style"); + versionFolderCombo.add("5th style"); + versionFolderCombo.add("6th style"); + versionFolderCombo.add("7th style"); + versionFolderCombo.add("8th style"); + versionFolderCombo.add("9th style"); + versionFolderCombo.add("10th style"); + versionFolderCombo.add("IIDX RED"); + versionFolderCombo.add("HAPPY SKY"); + otherFolderButton = new Button(songSet2Composite, 16416); + otherFolderButton.setText("OtherƒtƒHƒ‹ƒ_‚ɒljÁ"); // Add to other folder + otherFolderButton.setBounds(70, 35, 119, 14); + bemaniFolderButton = new Button(songSet2Composite, 16416); + bemaniFolderButton.setText("BEMANIƒtƒHƒ‹ƒ_‚ɒljÁ"); // Add to BEMANI folder + bemaniFolderButton.setBounds(70, 56, 133, 14); + bemaniFolderButton.setVisible(false); + battleAllowedButton = new Button(songSet2Composite, 16416); + battleAllowedButton.setText("ƒoƒgƒ‹‰Â”\•ˆ–Ê"); // Battle enabled music + battleAllowedButton.setBounds(70, 77, 98, 14); + battleAllowedButton.setVisible(false); + label14 = new Label(songSet2Composite, 0); + label14.setText("ƒ‚�[ƒhƒ^ƒCƒv (3,4,6,7)"); // mode type + label14.setBounds(7, 63, 98, 14); + label14.setVisible(false); + modeTypeText = new Text(songSet2Composite, 2048); + modeTypeText.setBounds(112, 56, 21, 21); + modeTypeText.setVisible(false); + label28 = new Label(songSet2Composite, 0); + label28.setText("•ˆ–Ê—v‘f"); // Music element + label28.setBounds(182, 63, 49, 14); + label28.setEnabled(false); + label28.setVisible(false); + noteAssortText = new Text(songSet2Composite, 2048); + noteAssortText.setBounds(238, 56, 21, 21); + noteAssortText.setEditable(false); + noteAssortText.setVisible(false); + label24 = new Label(songSet2Composite, 0); + label24.setText("BPM"); + label24.setBounds(7, 91, 28, 14); + label24.setVisible(false); + bpmText = new Text(songSet2Composite, 2048); + bpmText.setBounds(70, 84, 35, 21); + bpmText.setVisible(false); + label25 = new Label(songSet2Composite, 0); + label25.setText("�Å‘åBPM"); // Highest BPM + label25.setBounds(168, 91, 49, 14); + label25.setVisible(false); + bpmMaximumText = new Text(songSet2Composite, 2048); + bpmMaximumText.setBounds(224, 84, 35, 21); + bpmMaximumText.setVisible(false); + label15 = new Label(songSet2Composite, 0); + label15.setText("“ïˆÕ“x"); // Difficulty + label15.setBounds(7, 126, 42, 14); + label16 = new Label(songSet2Composite, 0); + label16.setText("N7 "); + label16.setBounds(70, 112, 21, 14); + levelNormal7Text = new Text(songSet2Composite, 2048); + levelNormal7Text.setBounds(70, 126, 21, 21); + label17 = new Label(songSet2Composite, 0); + label17.setText("H7 "); + label17.setBounds(98, 112, 21, 14); + levelHyper7Text = new Text(songSet2Composite, 2048); + levelHyper7Text.setBounds(98, 126, 21, 21); + label18 = new Label(songSet2Composite, 0); + label18.setText("A7 "); + label18.setBounds(126, 112, 21, 14); + levelAnother7Text = new Text(songSet2Composite, 2048); + levelAnother7Text.setBounds(126, 126, 21, 21); + label19 = new Label(songSet2Composite, 0); + label19.setText("N14"); + label19.setBounds(154, 112, 21, 14); + levelNormal14Text = new Text(songSet2Composite, 2048); + levelNormal14Text.setBounds(154, 126, 21, 21); + label20 = new Label(songSet2Composite, 0); + label20.setText("H14"); + label20.setBounds(182, 112, 21, 14); + levelHyper14Text = new Text(songSet2Composite, 2048); + levelHyper14Text.setBounds(182, 126, 21, 21); + label21 = new Label(songSet2Composite, 0); + label21.setText("A14"); + label21.setBounds(210, 112, 21, 14); + levelAnother14Text = new Text(songSet2Composite, 2048); + levelAnother14Text.setBounds(210, 126, 21, 21); + label23 = new Label(songSet2Composite, 0); + label23.setText("B7"); + label23.setBounds(238, 112, 21, 14); + levelBeginner7Text = new Text(songSet2Composite, 2048); + levelBeginner7Text.setBounds(238, 126, 21, 21); + songSet2Button = new Button(songSet2Composite, 0x1000008); + songSet2Button.setText("�‘‚«Š·‚¦"); // Write changes + songSet2Button.setBounds(70, 154, 63, 21); + songSet2Button.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + songSet2ButtonWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + songSet3CTabItem = new CTabItem(songTabFolder, 0); + songSet3CTabItem.setText("‹È�Ý’è‚R"); // Song settings 3 + songSet3ScrolledComposite = new ScrolledComposite(songTabFolder, 2816); + songSet3CTabItem.setControl(songSet3ScrolledComposite); + songSet3ScrolledComposite.setEnabled(true); + songSet3Composite = new Composite(songSet3ScrolledComposite, 0); + songSet3Composite.setLayout(null); + songSet3ScrolledComposite.setContent(songSet3Composite); + songSet3Composite.setBounds(0, 0, 315, 161); + label30 = new Label(songSet3Composite, 0); + label30.setText("ƒf�[ƒ^ƒtƒHƒ‹ƒ_–¼"); // Data folder name + label30.setBounds(7, 14, 84, 14); + songFolderText = new Text(songSet3Composite, 2048); + songFolderText.setText("1299"); + songFolderText.setBounds(91, 7, 35, 21); + songFolderText.setEditable(false); + label32 = new Label(songSet3Composite, 0); + label32.setText("Šy‹Èƒ{ƒŠƒ…�[ƒ€"); // Music volume + label32.setBounds(7, 42, 70, 14); + volumeText = new Text(songSet3Composite, 2048); + volumeText.setText("100"); + volumeText.setBounds(91, 35, 28, 21); + label33 = new Label(songSet3Composite, 0); + label33.setText("�“"); + label33.setBounds(119, 42, 14, 14); + volumeScale = new Scale(songSet3Composite, 0); + volumeScale.setSelection(100); + volumeScale.setMaximum(255); + volumeScale.setBounds(133, 14, 175, 42); + volumeScale.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + volumeScaleWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + label47 = new Label(songSet3Composite, 0); + label47.setText("2dxƒtƒ@ƒCƒ‹"); // 2dx file + label47.setBounds(7, 77, 63, 14); + label39 = new Label(songSet3Composite, 0); + label39.setText("N7 "); + label39.setBounds(91, 63, 21, 14); + fileNoramal7Text = new Text(songSet3Composite, 2048); + fileNoramal7Text.setBounds(91, 77, 21, 21); + label40 = new Label(songSet3Composite, 0); + label40.setText("H7 "); + label40.setBounds(119, 63, 21, 14); + fileHyper7Text = new Text(songSet3Composite, 2048); + fileHyper7Text.setBounds(119, 77, 21, 21); + label41 = new Label(songSet3Composite, 0); + label41.setText("A7 "); + label41.setBounds(147, 63, 21, 14); + fileAnother7Text = new Text(songSet3Composite, 2048); + fileAnother7Text.setBounds(147, 77, 21, 21); + label42 = new Label(songSet3Composite, 0); + label42.setText("N14"); + label42.setBounds(175, 63, 21, 14); + fileNoramal14Text = new Text(songSet3Composite, 2048); + fileNoramal14Text.setBounds(175, 77, 21, 21); + label43 = new Label(songSet3Composite, 0); + label43.setText("H14"); + label43.setBounds(203, 63, 21, 14); + fileHyper14Text = new Text(songSet3Composite, 2048); + fileHyper14Text.setBounds(203, 77, 21, 21); + label44 = new Label(songSet3Composite, 0); + label44.setText("A14"); + label44.setBounds(231, 63, 21, 14); + fileAnother14Text = new Text(songSet3Composite, 2048); + fileAnother14Text.setBounds(231, 77, 21, 21); + label46 = new Label(songSet3Composite, 0); + label46.setText("B7"); + label46.setBounds(259, 63, 21, 14); + fileBeginner7Text = new Text(songSet3Composite, 2048); + fileBeginner7Text.setBounds(259, 77, 21, 21); + songSet3button = new Button(songSet3Composite, 0x1000008); + songSet3button.setText("�‘‚«Š·‚¦"); // Write changes + songSet3button.setBounds(91, 105, 63, 21); + songSet3button.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + songSet3buttonWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + movieSetCTabItem = new CTabItem(songTabFolder, 0); + movieSetCTabItem.setText("ƒ€�[ƒr�[�Ý’è"); // Movie settings + movieSetScrolledComposite = new ScrolledComposite(songTabFolder, 2816); + movieSetCTabItem.setControl(movieSetScrolledComposite); + movieSetScrolledComposite.setEnabled(true); + movieSetComposite = new Composite(movieSetScrolledComposite, 0); + movieSetComposite.setLayout(null); + movieSetScrolledComposite.setContent(movieSetComposite); + movieSetComposite.setBounds(0, 0, 406, 112); + label1 = new Label(movieSetComposite, 0); + label1.setText("ƒ€�[ƒr�[ƒtƒ@ƒCƒ‹–¼"); // Movie file name + label1.setBounds(7, 14, 84, 14); + movieFileText = new Text(movieSetComposite, 2048); + movieFileText.setBounds(105, 7, 294, 21); + movieFileText.setTextLimit(32); + label2 = new Label(movieSetComposite, 0); + label2.setText("�Ä�¶ŠJŽnƒ^ƒCƒ~ƒ“ƒO"); // Movie playback start timing + label2.setBounds(7, 42, 91, 14); + movieDelayScale = new Scale(movieSetComposite, 0); + movieDelayScale.setBounds(147, 35, 259, 42); + movieDelayScale.setMaximum(255); + movieDelayScale.setSelection(128); + movieDelayScale.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + movieDelayScaleWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + movieDelayText = new Text(movieSetComposite, 2052); + movieDelayText.setBounds(105, 35, 35, 21); + movieDelayText.setText("0"); + movieModeButton = new Button(movieSetComposite, 16416); + movieModeButton.setText("ƒ€�[ƒr�[ƒ‚�[ƒh"); // Movie mode + movieModeButton.setBounds(7, 63, 91, 21); + movieModeButton.setVisible(false); + movieSetButton = new Button(movieSetComposite, 0x1000008); + movieSetButton.setText("�‘‚«Š·‚¦"); // Write settings + movieSetButton.setBounds(105, 84, 63, 21); + movieSetButton.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + movieSetButtonWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + titleSetCTabItem = new CTabItem(songTabFolder, 0); + titleSetCTabItem.setText("ƒ^ƒCƒgƒ‹�Ý’è"); // Title settings + titleSetScrolledComposite = new ScrolledComposite(songTabFolder, 2816); + titleSetCTabItem.setControl(titleSetScrolledComposite); + titleSetScrolledComposite.setEnabled(true); + titleSetComposite = new Composite(titleSetScrolledComposite, 0); + titleSetComposite.setLayout(null); + titleSetScrolledComposite.setContent(titleSetComposite); + titleSetComposite.setBounds(0, 0, 420, 91); + label3 = new Label(titleSetComposite, 0); + label3.setBounds(7, 14, 98, 14); + label3.setText("ƒ^ƒCƒgƒ‹‰æ‘œ’è‹`–¼"); // Title image assigned name + innerTitleText = new Text(titleSetComposite, 2048); + innerTitleText.setTextLimit(32); + innerTitleText.setBounds(119, 7, 294, 21); + titleSetButton = new Button(titleSetComposite, 0x1000008); + titleSetButton.setText("�‘‚«Š·‚¦"); // Write changes + titleSetButton.setBounds(119, 63, 63, 21); + titleSetButton.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + titleSetButtonWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + innerImageFolderText = new Text(titleSetComposite, 2048); + innerImageFolderText.setBounds(119, 35, 294, 21); + innerImageFolderText.setTextLimit(32); + label4 = new Label(titleSetComposite, 0); + label4.setText("ƒ^ƒCƒgƒ‹‰æ‘œƒtƒHƒ‹ƒ_–¼"); // Title image folder name + label4.setBounds(7, 42, 119, 14); + layerSetCTabItem = new CTabItem(songTabFolder, 0); + layerSetCTabItem.setText("ƒŒƒCƒ„�[�Ý’è"); // Layer settings + layerSetScrolledComposite = new ScrolledComposite(songTabFolder, 2816); + layerSetCTabItem.setControl(layerSetScrolledComposite); + layerSetScrolledComposite.setEnabled(true); + layerSetComposite = new Composite(layerSetScrolledComposite, 0); + layerSetComposite.setLayout(null); + layerSetScrolledComposite.setContent(layerSetComposite); + layerSetComposite.setBounds(0, 0, 413, 252); + layerpointButton = new Button(layerSetComposite, 16416); + layerpointButton.setText("ƒŒƒCƒ„�[Žw’è"); // Layers assigned + layerpointButton.setBounds(7, 7, 84, 21); + layerGgroup = new Group(layerSetComposite, 0); + layerGgroup.setLayout(null); + layerGgroup.setText("ƒŒƒCƒ„�[ 0�`8"); // Layer 0~8 + layerGgroup.setBounds(98, 7, 308, 210); + layer0Text = new Text(layerGgroup, 2052); + layer0Text.setBounds(7, 14, 294, 21); + layer0Text.setTextLimit(32); + layer1Text = new Text(layerGgroup, 2052); + layer1Text.setBounds(7, 35, 294, 21); + layer1Text.setTextLimit(32); + layer2Text = new Text(layerGgroup, 2052); + layer2Text.setBounds(7, 56, 294, 21); + layer2Text.setTextLimit(32); + layer3Text = new Text(layerGgroup, 2052); + layer3Text.setBounds(7, 77, 294, 21); + layer3Text.setTextLimit(32); + layer4Text = new Text(layerGgroup, 2052); + layer4Text.setBounds(7, 98, 294, 21); + layer4Text.setTextLimit(32); + layer5Text = new Text(layerGgroup, 2052); + layer5Text.setBounds(7, 119, 294, 21); + layer5Text.setTextLimit(32); + layer6Text = new Text(layerGgroup, 2052); + layer6Text.setBounds(7, 140, 294, 21); + layer6Text.setTextLimit(32); + layer7Text = new Text(layerGgroup, 2052); + layer7Text.setBounds(7, 161, 294, 21); + layer7Text.setTextLimit(32); + layer8Text = new Text(layerGgroup, 2052); + layer8Text.setBounds(7, 182, 294, 21); + layer8Text.setTextLimit(32); + layerSetButton = new Button(layerSetComposite, 0x1000008); + layerSetButton.setText("�‘‚«Š·‚¦"); // Write changes + layerSetButton.setBounds(7, 224, 63, 21); + layerSetButton.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + layerSetButtonWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + songTabFolder.setBorderVisible(true); + songTabFolder.setBackground(SWTResourceManager.getColor(255, 255, 255)); + songTabFolder.setSelection(0); + sashForm.setBackground(SWTResourceManager.getColor(255, 255, 255)); + sashForm.setWeights(new int[] { + 22, 78 + }); + menu1 = new Menu(getShell(), 2); + getShell().setMenuBar(menu1); + fileMenuItem = new MenuItem(menu1, 64); + fileMenuItem.setText("ƒtƒ@ƒCƒ‹"); // File + fileMenu = new Menu(fileMenuItem); + openFileMenuItem = new MenuItem(fileMenu, 64); + openFileMenuItem.setText("eout.dec‚ðŠJ‚­"); // Open eout.dec + openFileMenuItem.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + openDecMenuItemWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + open2MenuItem = new MenuItem(fileMenu, 64); + open2MenuItem.setText("eout.csv‚ðŠJ‚­"); // Open eout.csv + open2MenuItem.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + openCsvMenuItemWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + menuItem1 = new MenuItem(fileMenu, 2); + menuItem1.setText("menuItem1"); + saveFileMenuItem = new MenuItem(fileMenu, 64); + saveFileMenuItem.setText("�ã�‘‚«•Û‘¶"); // Save + saveFileMenuItem.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + saveFileMenuItemWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + saveAsMenuItem = new MenuItem(fileMenu, 64); + saveAsMenuItem.setText("–¼‘O‚ð•t‚¯‚ĕۑ¶"); // Save as + saveAsMenuItem.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + saveAsMenuItemWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + menuItem2 = new MenuItem(fileMenu, 2); + menuItem2.setText("menuItem2"); + exitMenuItem = new MenuItem(fileMenu, 64); + exitMenuItem.setText("�I—¹"); // Exit + exitMenuItem.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + exitFileMenuItemWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + fileMenuItem.setMenu(fileMenu); + settingMenuItem = new MenuItem(menu1, 64); + settingMenuItem.setText("CSV�Ý’è"); // CSV settings + settingMenu = new Menu(settingMenuItem); + settingMenuItem.setMenu(settingMenu); + hsMenuItem = new MenuItem(settingMenu, 16); + hsMenuItem.setText("HSƒ‚�[ƒh"); // HS mode + hsMenuItem.setSelection(true); + hsMenuItem.setData(""); + hsMenuItem.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + modeMenuItemWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + ddMenuItem1 = new MenuItem(settingMenu, 16); + ddMenuItem1.setText("DDƒ‚�[ƒh"); // DD Mode + ddMenuItem1.setData("_dd"); + ddMenuItem1.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + modeMenuItemWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + gdMenuItem1 = new MenuItem(settingMenu, 16); + gdMenuItem1.setText("GDƒ‚�[ƒh"); // GD mode + gdMenuItem1.setData("_gd"); + gdMenuItem1.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + modeMenuItemWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + menuItem3 = new MenuItem(menu1, 64); + menuItem3.setText("ƒŒƒR�[ƒh�Ý’è"); // Record settings + menuItem3.setEnabled(true); + menu2 = new Menu(menuItem3); + menuItem3.setMenu(menu2); + expandMenuItem = new MenuItem(menu2, 8); + expandMenuItem.setText("100‹ÈŠg’£"); // Expand by 100 songs + expandMenuItem.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + expandMenuItemWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + helpMenuItem = new MenuItem(menu1, 64); + helpMenuItem.setText("ƒwƒ‹ƒv"); // Help + helpMenu = new Menu(helpMenuItem); + aboutMenuItem = new MenuItem(helpMenu, 64); + aboutMenuItem.setText("EditOut‚ɂ‚¢‚Ä"); // About EditOut + aboutMenuItem.addSelectionListener(new SelectionAdapter() { + + public void widgetSelected(SelectionEvent evt) + { + aboutMenuItemWidgetSelected(evt); + } + + final EoutEditor this$0; + + + { + this$0 = EoutEditor.this; + super(); + } + } +); + helpMenuItem.setMenu(helpMenu); + layout(); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + + public static void main(String args[]) + { + try + { + Display display = Display.getDefault(); + shell = new Shell(display); + EoutEditor inst = new EoutEditor(shell, 2048); + Point size = inst.getSize(); + shell.setLayout(new FillLayout()); + shell.setText("EditOut - 2nd style -"); + shell.setToolTipText("‚Ó‚Ÿ�[‚·‚Æ ‚·‚½‚¢‚é"); // First Style + shell.setImage(SWTResourceManager.getImage("icons/tran.gif")); + if(size.x == 0 && size.y == 0) + { + inst.pack(); + shell.pack(); + } else + { + Rectangle shellBounds = shell.computeTrim(0, 0, size.x, size.y); + shell.setSize(shellBounds.width, shellBounds.height); + } + shell.open(); + while(!shell.isDisposed()) + if(!display.readAndDispatch()) + display.sleep(); + } + catch(NullPointerException e) + { + Display display = Display.getDefault(); + Shell shell = new Shell(display); + MessageBox box1 = new MessageBox(shell, 32); + box1.setText("EditOut �ƒ‚Ê‚é‚Û"); // Fuck you if you think I'm translating the ascii art + box1.setMessage("�@�@ �i�@�E�Í�E�j�@�@�@|�@|�@¶Þ¯\n�@�@‚Æ�@�@�@�@�j�@ �@ |�@|\n�@�@�@ ‚x�@/ƒm�@�@�@ �l\n�@�@�@�@ /�@�j�@ �@ < �@>__ƒ©�¿\n�@�@ �Q/‚µ'�@�^�^. ‚u�M„D\264�j/\n�@�@�i�Qƒtœc�@�@�@�@�@ �@�@/ �@�©>>EditOutHS"); + shell.dispose(); + display = null; + } + } + + private void exitFileMenuItemWidgetSelected(SelectionEvent evt) + { + if(isUpdate) + { + Display display = Display.getDefault(); + Shell shell = new Shell(display); + MessageBox box1 = new MessageBox(shell, 288); + box1.setText("Šm”F"); // Confirm + box1.setMessage("�X�V‚³‚ꂽƒf�[ƒ^‚ª‚ ‚è‚Ü‚·‚ª‚±‚̂܂Ü�I—¹‚µ‚Ü‚·‚©�H"); // Data has been changed, are you sure you want to exit without saving? + int answer = box1.open(); + shell.dispose(); + display = null; + if(answer == 256) + return; + } + System.exit(0); + } + + private void openDecMenuItemWidgetSelected(SelectionEvent evt) + { + FileDialog openDialog = new FileDialog(shell, 4096); + openDialog.setFilterPath(".\\"); + openDialog.setFilterExtensions(new String[] { + "*.dec;*eout*" + }); + String loadEoutPath = openDialog.open(); + if(loadEoutPath != null) + { + try + { + eout = new Eout(loadEoutPath); + createTreeItem(eout); + } + catch(Exception e) + { + e.printStackTrace(); + } + songSet1Composite.setVisible(false); + songSet2Composite.setVisible(false); + songSet3Composite.setVisible(false); + movieSetComposite.setVisible(false); + titleSetComposite.setVisible(false); + layerSetComposite.setVisible(false); + } + } + + private void openCsvMenuItemWidgetSelected(SelectionEvent evt) + { + FileDialog openDialog = new FileDialog(shell, 4096); + openDialog.setFilterPath(".\\"); + openDialog.setFilterExtensions(new String[] { + "*.csv" + }); + String loadCsvPath = openDialog.open(); + if(loadCsvPath != null) + { + try + { + eout = new Eout(loadCsvPath, (new StringBuilder(String.valueOf(openDialog.getFilterPath()))).append("\\eout.dec").toString(), writeMode); + createTreeItem(eout); + } + catch(Exception e) + { + e.printStackTrace(); + } + songSet1Composite.setVisible(false); + songSet2Composite.setVisible(false); + songSet3Composite.setVisible(false); + movieSetComposite.setVisible(false); + titleSetComposite.setVisible(false); + layerSetComposite.setVisible(false); + } + } + + private void createTreeItem(Eout eout) + { + recordHead.removeAll(); + TreeMap indexs = eout.getSongsIndex(); + TreeMap songs = eout.getSongs(); + String index = null; + TreeItem songItem = null; + for(Iterator iterator = indexs.keySet().iterator(); iterator.hasNext(); songItem.setData(index)) + { + String address = (String)iterator.next(); + index = (String)indexs.get(address); + songItem = new TreeItem(recordHead, 0); + if(index.equals("")) + { + songItem.setText(address); + songItem.setForeground(SWTResourceManager.getColor(150, 150, 150)); + } else + { + song = (EoutSong)songs.get(index); + songItem.setText(song.getSongnameString()); + } + } + + if(versionFolderCombo.getItemCount() == 14) + versionFolderCombo.remove("DistorteD"); + else + if(versionFolderCombo.getItemCount() == 15) + { + versionFolderCombo.remove("DistorteD"); + versionFolderCombo.remove("GOLD"); + } + version = eout.getEoutVersion(); + if(version == 728) + { + shell.setImage(SWTResourceManager.getImage("icons/tran.gif")); + label14.setVisible(true); + modeTypeText.setVisible(true); + label24.setVisible(true); + bpmText.setVisible(true); + label25.setText("�Å‘åBPM"); // Highest BPM + label25.setVisible(true); + bpmMaximumText.setVisible(true); + label28.setVisible(true); + noteAssortText.setVisible(true); + battleAllowedButton.setVisible(false); + bemaniFolderButton.setVisible(false); + movieModeButton.setVisible(true); + } else + if(version == 680) + { + shell.setImage(SWTResourceManager.getImage("icons/tran_dd.gif")); + label14.setVisible(false); + modeTypeText.setVisible(false); + label24.setVisible(true); + bpmText.setVisible(true); + label25.setText("�Å�¬BPM"); // Lowest BPM + label25.setVisible(true); + bpmMaximumText.setVisible(true); + label28.setVisible(false); + noteAssortText.setVisible(false); + battleAllowedButton.setVisible(false); + bemaniFolderButton.setVisible(true); + movieModeButton.setVisible(false); + versionFolderCombo.add("DistorteD"); + } else + if(version == 796) + { + shell.setImage(SWTResourceManager.getImage("icons/tran_gd.gif")); + label14.setVisible(false); + modeTypeText.setVisible(false); + label24.setVisible(false); + bpmText.setVisible(false); + label25.setVisible(false); + bpmMaximumText.setVisible(false); + label28.setVisible(false); + noteAssortText.setVisible(false); + battleAllowedButton.setVisible(true); + bemaniFolderButton.setVisible(true); + movieModeButton.setVisible(false); + versionFolderCombo.add("DistorteD"); + versionFolderCombo.add("GOLD"); + } + } + + private void aboutMenuItemWidgetSelected(SelectionEvent evt) + { + String selif; + switch((int)(Math.random() * 10D)) + { + case 0: // '\0' + selif = "IIDX Goooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooold !"; + break; + + case 1: // '\001' + selif = "30’†”NAVƒpƒ��["; // 30 years of Porn Power + break; + + case 2: // '\002' + selif = "I'm �_�X"; // I'm The Gods + break; + + case 3: // '\003' + selif = "ƒpƒXƒ^"; // Pasta + break; + + case 4: // '\004' + selif = "3”{ƒAƒCƒXƒNƒŠ�[ƒ€"; // 3x Ice Cream + break; + + default: + selif = "�E�E�E"; + break; + } + Display display = Display.getDefault(); + Shell shell = new Shell(display); + MessageBox box1 = new MessageBox(shell, 32); + box1.setText("EditOut‚ɂ‚¢‚Ä"); // About EditOut + box1.setMessage((new StringBuilder("�@�@�@�@�@�@ |�P \r\n�@( ß„tß )�@ | �@�ƒ ")).append(selif).append("\r\n�@|�@�RÉ�Rr„£\r\n�@ �„�„�@'‚s").toString()); + box1.open(); + shell.dispose(); + display = null; + } + + private void saveFileMenuItemWidgetSelected(SelectionEvent evt) + { + if(eout != null) + { + String result; + try + { + eout.saveEout(); + result = "•Û‘¶‚µ‚Ü‚µ‚½�B"; // Saved + isUpdate = false; + if((new File("createeout.exe")).exists()) + { + String path = eout.getSourcePath(); + Runtime.getRuntime().exec((new StringBuilder(".\\createeout.exe ")).append(path).append(" ").append(path.substring(0, path.lastIndexOf('\\') + 1)).append("eout.bin").toString()); + } + } + catch(Exception e) + { + result = "•Û‘¶‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½�B"; // Attempt to save failed + e.printStackTrace(); + } + MessageBox box1 = new MessageBox(shell, 32); + box1.setText("•Û‘¶Œ‹‰Ê"); // Save results + box1.setMessage(result); + box1.open(); + } + } + + private void saveAsMenuItemWidgetSelected(SelectionEvent evt) + { + FileDialog saveDialog = new FileDialog(shell, 8192); + saveDialog.setFilterPath(".\\"); + saveDialog.setFilterExtensions(new String[] { + "*.dec;*eout*" + }); + saveDialog.setFileName("eout.dec"); + String saveEoutPath = saveDialog.open(); + if(saveEoutPath != null && eout != null) + { + String result; + try + { + eout.saveAsEout(saveEoutPath); + result = "•Û‘¶‚µ‚Ü‚µ‚½�B"; // Saved + isUpdate = false; + if((new File("createeout.exe")).exists()) + { + String path = eout.getSourcePath(); + Runtime.getRuntime().exec((new StringBuilder(".\\createeout.exe ")).append(path).append(" ").append(path.substring(0, path.lastIndexOf('\\') + 1)).append("eout.bin").toString()); + } + } + catch(Exception e) + { + result = "•Û‘¶‚Å‚«‚Ü‚¹‚ñ‚Å‚µ‚½�B"; // Attempt to save failed + e.printStackTrace(); + } + MessageBox box1 = new MessageBox(shell, 32); + box1.setText("•Û‘¶Œ‹‰Ê"); // Save results + box1.setMessage(result); + box1.open(); + } + } + + private void recordTreeWidgetSelected(SelectionEvent evt) + { + Tree records = (Tree)evt.widget; + TreeItem selectedItems[] = records.getSelection(); + if(selectedItems.length > 0) + { + String index = (String)selectedItems[0].getData(); + if(!index.equals("head")) + { + TreeMap songs = eout.getSongs(); + if(songs.containsKey(index)) + { + song = (EoutSong)songs.get(index); + songSet(); + selectedItems[0].setText(song.getSongnameString()); + } else + { + MessageBox box1 = new MessageBox(shell, 288); + box1.setText("Šm”F"); // Confirm + box1.setMessage("‚±‚̃ŒƒR�[ƒh‚Í–¢Žg—p‚Å‚·�B\n�V‹KŠy‹È‚ð’ljÁ‚µ‚Ü‚·‚©�H"); // This record is not yet usable. Add the new songs anyway? + int answer = box1.open(); + if(answer == 32) + { + try + { + DecimalFormat formatter = new DecimalFormat("0000"); + index = formatter.format(songs.size()); + song = new EoutSong(version); + song.setSongfolder(selectedItems[0].getText()); + songs.put(index, song); + eout.getSongsIndex().put(selectedItems[0].getText(), index); + eout.setSongcount(songs.size()); + selectedItems[0].setData(index); + selectedItems[0].setText("’ljÁ’†�I"); // Adding + selectedItems[0].setForeground(SWTResourceManager.getColor(0, 0, 0)); + songSet(); + isUpdate = true; + } + catch(IOException e) + { + e.printStackTrace(); + } + } else + { + songSet1Composite.setVisible(false); + songSet2Composite.setVisible(false); + songSet3Composite.setVisible(false); + movieSetComposite.setVisible(false); + titleSetComposite.setVisible(false); + layerSetComposite.setVisible(false); + } + } + } + } + } + + private void songSet() + { + songSet1Composite.setVisible(true); + songNameText.setText(song.getSongnameString()); + labelImageText.setText(song.getLabelimageString()); + titleImageText.setText(song.getTitleimageString()); + markImageText.setText(song.getMarkimageString()); + genreImageText.setText(song.getGenreimageString()); + artistImageText.setText(song.getArtistimageString()); + songSet2Composite.setVisible(true); + versionFolderCombo.select(song.getVersionfolderInt()); + otherFolderButton.setSelection(song.getOtherFolderBoolean()); + if(version == 728) + modeTypeText.setText((new StringBuilder(String.valueOf(song.getModeTypeInt()))).toString()); + if(version == 680 || version == 796) + bemaniFolderButton.setSelection(song.getBemaniFolderBoolean()); + if(version == 796) + battleAllowedButton.setSelection(song.getBattleAllowedBoolean()); + levelNormal7Text.setText(song.getLevelnormal7String()); + levelHyper7Text.setText(song.getLevelhyper7String()); + levelAnother7Text.setText(song.getLevelanother7String()); + levelNormal14Text.setText(song.getLevelnormal14String()); + levelHyper14Text.setText(song.getLevelhyper14String()); + levelAnother14Text.setText(song.getLevelanother14String()); + levelBeginner7Text.setText(song.getLevelBeginner7String()); + if(version == 728 || version == 680) + { + bpmText.setText(song.getBpmString()); + bpmMaximumText.setText(song.getBpmmaximumString()); + } + if(version == 728) + noteAssortText.setText(song.getNoteAssortString()); + songSet3Composite.setVisible(true); + DecimalFormat formatter = new DecimalFormat("0000"); + songFolderText.setText(formatter.format(Integer.parseInt(song.getSongfolderString()))); + volumeText.setText(song.getVolumeString()); + volumeScale.setSelection(Integer.parseInt(song.getVolumeString())); + fileNoramal7Text.setText(song.getFilenormal7String()); + fileHyper7Text.setText(song.getFilehyper7String()); + fileAnother7Text.setText(song.getFileanother7String()); + fileNoramal14Text.setText(song.getFilenormal14String()); + fileHyper14Text.setText(song.getFilehyper14String()); + fileAnother14Text.setText(song.getFileanother14String()); + fileBeginner7Text.setText(song.getFileBeginner7String()); + movieSetComposite.setVisible(true); + movieDelayText.setText(song.getMoviedelayString()); + movieDelayScale.setSelection(Integer.parseInt(song.getMoviedelayString()) + 128); + movieFileText.setText(song.getMoviefileString()); + if(version == 728) + movieModeButton.setSelection(song.getMoviemodeBoolean()); + titleSetComposite.setVisible(true); + innerTitleText.setText(song.getInnertitleString()); + innerImageFolderText.setText(song.getInnerimagefolderString()); + layerSetComposite.setVisible(true); + layerpointButton.setSelection(song.getLayerpointBoolean()); + layer0Text.setText(song.getLayer0String()); + layer1Text.setText(song.getLayer1String()); + layer2Text.setText(song.getLayer2String()); + layer3Text.setText(song.getLayer3String()); + layer4Text.setText(song.getLayer4String()); + layer5Text.setText(song.getLayer5String()); + layer6Text.setText(song.getLayer6String()); + layer7Text.setText(song.getLayer7String()); + layer8Text.setText(song.getLayer8String()); + } + + private void movieDelayScaleWidgetSelected(SelectionEvent evt) + { + Scale scale = (Scale)evt.widget; + movieDelayText.setText(String.valueOf(scale.getSelection() - 128)); + } + + private void volumeScaleWidgetSelected(SelectionEvent evt) + { + Scale scale = (Scale)evt.widget; + volumeText.setText(String.valueOf(scale.getSelection())); + } + + private void songSet1ButtonWidgetSelected(SelectionEvent evt) + { + song.setSongname(songNameText.getText()); + song.setLabelimage(labelImageText.getText()); + song.setTitleimage(titleImageText.getText()); + song.setMarkimage(markImageText.getText()); + song.setGenreimage(genreImageText.getText()); + song.setArtistimage(artistImageText.getText()); + isUpdate = true; + } + + private void songSet2ButtonWidgetSelected(SelectionEvent evt) + { + song.setVersionfolder(versionFolderCombo.getSelectionIndex()); + song.setOtherFolder(otherFolderButton.getSelection()); + if(version == 728) + song.setModeType(modeTypeText.getText()); + if(version == 680 || version == 796) + song.setBemaniFolder(bemaniFolderButton.getSelection()); + if(version == 796) + song.setBattleAllowed(battleAllowedButton.getSelection()); + song.setLevelnormal7(levelNormal7Text.getText()); + song.setLevelhyper7(levelHyper7Text.getText()); + song.setLevelanother7(levelAnother7Text.getText()); + song.setLevelnormal14(levelNormal14Text.getText()); + song.setLevelhyper14(levelHyper14Text.getText()); + song.setLevelanother14(levelAnother14Text.getText()); + song.setLevelBeginner7(levelBeginner7Text.getText()); + if(version == 728 || version == 680) + { + song.setBpm(bpmText.getText()); + song.setBpmmaximum(bpmMaximumText.getText()); + } + if(version == 728) + { + if(levelAnother7Text.getText().equals("0") && levelAnother14Text.getText().equals("0")) + noteAssortText.setText("1B"); + else + if(levelAnother14Text.getText().equals("0")) + noteAssortText.setText("1F"); + else + noteAssortText.setText("3F"); + song.setNoteAssort(noteAssortText.getText()); + } + isUpdate = true; + } + + private void songSet3buttonWidgetSelected(SelectionEvent evt) + { + song.setSongfolder(songFolderText.getText()); + song.setVolume(volumeText.getText()); + song.setFilenormal7(fileNoramal7Text.getText()); + song.setFilehyper7(fileHyper7Text.getText()); + song.setFileanother7(fileAnother7Text.getText()); + song.setFilenormal14(fileNoramal14Text.getText()); + song.setFilehyper14(fileHyper14Text.getText()); + song.setFileanother14(fileAnother14Text.getText()); + song.setFileBeginner7(fileBeginner7Text.getText()); + isUpdate = true; + } + + private void movieSetButtonWidgetSelected(SelectionEvent evt) + { + song.setMoviedelay(movieDelayText.getText()); + song.setMoviefile(movieFileText.getText()); + if(version == 728) + song.setMoviemode(movieModeButton.getSelection()); + isUpdate = true; + } + + private void titleSetButtonWidgetSelected(SelectionEvent evt) + { + song.setInnertitle(innerTitleText.getText()); + song.setInnerimagefolder(innerImageFolderText.getText()); + isUpdate = true; + } + + private void layerSetButtonWidgetSelected(SelectionEvent evt) + { + song.setLayerpoint(layerpointButton.getSelection()); + song.setLayer0(layer0Text.getText()); + song.setLayer1(layer1Text.getText()); + song.setLayer2(layer2Text.getText()); + song.setLayer3(layer3Text.getText()); + song.setLayer4(layer4Text.getText()); + song.setLayer5(layer5Text.getText()); + song.setLayer6(layer6Text.getText()); + song.setLayer7(layer7Text.getText()); + song.setLayer8(layer8Text.getText()); + isUpdate = true; + } + + private void modeMenuItemWidgetSelected(SelectionEvent evt) + { + Widget menu = evt.widget; + String modeData = (String)menu.getData(); + if(modeData.equals("")) + writeMode = 12; + else + if(modeData.equals("_dd")) + writeMode = 13; + else + if(modeData.equals("_gd")) + writeMode = 14; + } + + private void expandMenuItemWidgetSelected(SelectionEvent evt) + { + int indexCount = eout.getSongsIndex().size(); + int endCount = indexCount + 100; + TreeItem songItem = null; + DecimalFormat formatter = new DecimalFormat("0000"); + for(int i = indexCount; i < endCount; i++) + { + songItem = new TreeItem(recordHead, 0); + songItem.setText(formatter.format(i)); + songItem.setData(""); + } + + } + + private static Shell shell; + private Button layerSetButton; + private Button layerpointButton; + private Button movieSetButton; + private Button otherFolderButton; + private Button songSet1Button; + private Button songSet2Button; + private Button songSet3button; + private Button titleSetButton; + private CTabFolder songTabFolder; + private CTabItem layerSetCTabItem; + private CTabItem movieSetCTabItem; + private CTabItem songSet1CTabItem; + private CTabItem songSet2CTabItem; + private CTabItem songSet3CTabItem; + private CTabItem titleSetCTabItem; + private Combo versionFolderCombo; + private Composite layerSetComposite; + private Composite movieSetComposite; + private Composite songSet1Composite; + private Composite songSet2Composite; + private Composite songSet3Composite; + private Composite titleSetComposite; + private Group layerGgroup; + private Label label11; + private Label label12; + private Label label13; + private Label label14; + private Label label15; + private Label label16; + private Label label17; + private Label label18; + private Label label19; + private Label label1; + private Label label20; + private Label label21; + private Label label23; + private Label label24; + private Label label25; + private Label label28; + private Label label2; + private Label label30; + private Label label32; + private Label label33; + private Label label39; + private Label label3; + private Label label40; + private Label label41; + private Label label42; + private Label label43; + private Label label44; + private Label label46; + private Label label47; + private Label label4; + private Label label6; + private Label label7; + private Label label8; + private Label label9; + private Menu fileMenu; + private Menu helpMenu; + private Menu menu1; + private MenuItem aboutMenuItem; + private MenuItem exitMenuItem; + private MenuItem fileMenuItem; + private MenuItem helpMenuItem; + private MenuItem openFileMenuItem; + private MenuItem saveFileMenuItem; + private SashForm sashForm; + private Scale movieDelayScale; + private Scale volumeScale; + private ScrolledComposite layerSetScrolledComposite; + private ScrolledComposite movieSetScrolledComposite; + private MenuItem expandMenuItem; + private Menu menu2; + private MenuItem menuItem3; + private Text text1; + private MenuItem open2MenuItem; + private MenuItem menuItem2; + private MenuItem menuItem1; + private MenuItem saveAsMenuItem; + private Button battleAllowedButton; + private Button bemaniFolderButton; + private Button movieModeButton; + private ScrolledComposite songSet1ScrolledComposite; + private ScrolledComposite songSet2ScrolledComposite; + private ScrolledComposite songSet3ScrolledComposite; + private ScrolledComposite titleSetScrolledComposite; + private Text artistImageText; + private Text bpmMaximumText; + private Text bpmText; + private Text fileAnother14Text; + private Text fileAnother7Text; + private Text fileBeginner7Text; + private Text fileHyper14Text; + private Text fileHyper7Text; + private Text fileNoramal14Text; + private Text fileNoramal7Text; + private Text genreImageText; + private Text innerImageFolderText; + private Text innerTitleText; + private Text labelImageText; + private Text layer0Text; + private Text layer1Text; + private Text layer2Text; + private Text layer3Text; + private Text layer4Text; + private Text layer5Text; + private Text layer6Text; + private Text layer7Text; + private Text layer8Text; + private Text levelAnother14Text; + private Text levelAnother7Text; + private Text levelBeginner7Text; + private Text levelHyper14Text; + private Text levelHyper7Text; + private Text levelNormal14Text; + private Text levelNormal7Text; + private Text markImageText; + private Text movieDelayText; + private Text movieFileText; + private Text modeTypeText; + private Text songFolderText; + private Text songNameText; + private Text titleImageText; + private Text noteAssortText; + private Text volumeText; + private Tree recordTree; + private TreeItem recordHead; + private MenuItem settingMenuItem; + private Menu settingMenu; + private MenuItem hsMenuItem; + private MenuItem ddMenuItem1; + private MenuItem gdMenuItem1; + private boolean isUpdate; + private int version; + private Eout eout; + private EoutSong song; + private int writeMode; + + + + + + + + + + + + + + + + + +} diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/10-12eout.dec b/iidx/Eout Editor/eoutEnglish-1.1-biso/10-12eout.dec new file mode 100644 index 0000000..a16e729 Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/10-12eout.dec differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/13eout.dec b/iidx/Eout Editor/eoutEnglish-1.1-biso/13eout.dec new file mode 100644 index 0000000..26d7c05 Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/13eout.dec differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/14eout.dec b/iidx/Eout Editor/eoutEnglish-1.1-biso/14eout.dec new file mode 100644 index 0000000..11bc355 Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/14eout.dec differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/decrypt.exe b/iidx/Eout Editor/eoutEnglish-1.1-biso/decrypt.exe new file mode 100644 index 0000000..b74fcbc Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/decrypt.exe differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/encrypt.exe b/iidx/Eout Editor/eoutEnglish-1.1-biso/encrypt.exe new file mode 100644 index 0000000..8fb4693 Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/encrypt.exe differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/eout.dec b/iidx/Eout Editor/eoutEnglish-1.1-biso/eout.dec new file mode 100644 index 0000000..23aca66 Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/eout.dec differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/eout.dec.BCK b/iidx/Eout Editor/eoutEnglish-1.1-biso/eout.dec.BCK new file mode 100644 index 0000000..505446a Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/eout.dec.BCK differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/eoutEdit.exe b/iidx/Eout Editor/eoutEnglish-1.1-biso/eoutEdit.exe new file mode 100644 index 0000000..a1257e5 Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/eoutEdit.exe differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/eoutEdit.jar b/iidx/Eout Editor/eoutEnglish-1.1-biso/eoutEdit.jar new file mode 100644 index 0000000..833b5d0 Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/eoutEdit.jar differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/0.jpg b/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/0.jpg new file mode 100644 index 0000000..a6d53f5 Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/0.jpg differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/1.jpg b/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/1.jpg new file mode 100644 index 0000000..57ac802 Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/1.jpg differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/2.jpg b/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/2.jpg new file mode 100644 index 0000000..a07c97c Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/2.jpg differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/3.jpg b/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/3.jpg new file mode 100644 index 0000000..6125adb Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/3.jpg differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/4.jpg b/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/4.jpg new file mode 100644 index 0000000..16b3c16 Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/4.jpg differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/5.jpg b/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/5.jpg new file mode 100644 index 0000000..a31f686 Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/mdata/5.jpg differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/readme-2ch.rtf b/iidx/Eout Editor/eoutEnglish-1.1-biso/readme-2ch.rtf new file mode 100644 index 0000000..82784a3 --- /dev/null +++ b/iidx/Eout Editor/eoutEnglish-1.1-biso/readme-2ch.rtf @@ -0,0 +1,286 @@ +{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;} +{\f11\fbidi \fmodern\fcharset128\fprq1{\*\panose 02020609040205080304}MS Mincho{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f34\fbidi \froman\fcharset1\fprq2{\*\panose 00000000000000000000}Cambria Math;} +{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f40\fbidi \fmodern\fcharset128\fprq1{\*\panose 02020609040205080304}@MS Mincho;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;} +{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} +{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f41\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f42\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\f44\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f45\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f46\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f47\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\f48\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f49\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f61\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f62\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;} +{\f64\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f65\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f66\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f67\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);} +{\f68\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f69\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f153\fbidi \fmodern\fcharset0\fprq1 MS Mincho Western{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};} +{\f151\fbidi \fmodern\fcharset238\fprq1 MS Mincho CE{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f152\fbidi \fmodern\fcharset204\fprq1 MS Mincho Cyr{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};} +{\f154\fbidi \fmodern\fcharset161\fprq1 MS Mincho Greek{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f155\fbidi \fmodern\fcharset162\fprq1 MS Mincho Tur{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};} +{\f158\fbidi \fmodern\fcharset186\fprq1 MS Mincho Baltic{\*\falt \'82\'6c\'82\'72 \'96\'be\'92\'a9};}{\f411\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f412\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;} +{\f414\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f415\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f418\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f443\fbidi \fmodern\fcharset0\fprq1 @MS Mincho Western;} +{\f441\fbidi \fmodern\fcharset238\fprq1 @MS Mincho CE;}{\f442\fbidi \fmodern\fcharset204\fprq1 @MS Mincho Cyr;}{\f444\fbidi \fmodern\fcharset161\fprq1 @MS Mincho Greek;}{\f445\fbidi \fmodern\fcharset162\fprq1 @MS Mincho Tur;} +{\f448\fbidi \fmodern\fcharset186\fprq1 @MS Mincho Baltic;}{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;} +{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;}{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;} +{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;} +{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} +{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; +\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; +\red192\green192\blue192;}{\*\defchp \fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{ +\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 +\snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* +\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 +\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 +\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}{\s15\ql \li0\ri0\widctlpar +\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 +\f2\fs20\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext15 \slink16 \ssemihidden \sunhideused \styrsid1316374 HTML Preformatted;}{\*\cs16 \additive \rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20 +\sbasedon10 \slink15 \slocked \ssemihidden \styrsid1316374 HTML Preformatted Char;}}{\*\pgptbl {\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid1316374}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1 +\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author Anthony}{\operator Anthony}{\creatim\yr2007\mo8\dy5\hr14\min15}{\revtim\yr2007\mo8\dy5\hr14\min15}{\version2}{\edmins0}{\nofpages2}{\nofwords162}{\nofchars928}{\nofcharsws1088}{\vern32889}} +{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/2003/wordml}}\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect +\widowctrl\ftnbj\aenddoc\trackmoves1\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata0\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1\noxlattoyen +\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1440\dgvorigin1440\dghshow1\dgvshow1 +\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct +\asianbrkrule\rsidroot1316374\newtblstyruls\nogrowautofit\usenormstyforlist\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet\cachedcolbal \nouicompat \fet0 +{\*\wgrffmtfilter 2450}\nofeaturethrottle1\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang +{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang +{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}} +\pard\plain \ltrpar\ql \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1316374 \rtlch\fcs1 +\af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +/*::::::::::::::::::::::::::::::::::::::::::::::::::: +\par :: +\par :: EditOut Ver. 2.10 +\par :: +\par :: Software for editing music information in eout +\par :: +\par :::::::::::::::::::::::::::::::::::::::::::::::::::*/ +\par +\par Included files: +\par EditOut.jar +\par swt.jar +\par swt-win32-3236.dll +\par split/1.SPLIT +\par eout.csv +\par +\par To use: +\par Double click on EditOut.jar if you have JRE5 or above installed on Windows. +\par (* Confirmed to work in JDK6u2 + Windows XP sp2) +\par +\par Operation: +\par CSV}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u19968\'88\'ea\u25324\'8a\'87\u12452\'83\'43\u12531\'83\'93\u12509\'83\'7c\u12540\'81\'5b\u12488\'83\'67\u12399 +\'82\'cd\u20184\'95\'74\u23646\'91\'ae\u12398\'82\'cc}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 eout.csv}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 +\loch\af11\hich\af11\dbch\f11 \uc2\u12434\'82\'f0\u-30325\'8c\'a9\u12394\'82\'c8\u12364\'82\'aa\u12425\'82\'e7\u-26619\'8d\'80\u30446\'96\'da\u22475\'96\'84\u12417\'82\'df\u12390\'82\'c4\u12367\'82\'ad\u12384\'82\'be\u12373\'82\'b3\u12356\'82\'a2\u12290 +\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par CSV}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12452\'83\'43\u12531\'83\'93\u12509\'83\'7c\u12540\'81\'5b\u12488\'83\'67\u21069\'91\'4f\u12395\'82\'c9}{ +\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 CSV}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u-30163\'90\'dd\u23450\'92\'e8\u12424 +\'82\'e6\u12426\'82\'e8\u20986\'8f\'6f\u21147\'97\'cd\u12375\'82\'b5\u12383\'82\'bd\u12356\'82\'a2}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 eout}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 +\fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12398\'82\'cc\u12496\'83\'6f\u12540\'81\'5b\u12472\'83\'57\u12519\'83\'87\u12531\'83\'93\u12434\'82\'f0\u-28552\'91\'49\u25246\'91\'f0\u12375\'82\'b5 +\u12390\'82\'c4\u12367\'82\'ad\u12384\'82\'be\u12373\'82\'b3\u12356\'82\'a2\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12487\'83\'66\u12540\'81\'5b\u12479\'83\'5e\u12501\'83\'74\u12457\'83\'48\u12523\'83\'8b +\loch\af11\hich\af11\dbch\f11 \u12480\'83\'5f\u12398\'82\'cc\u-27056\'8c\'c0\u30028\'8a\'45\u12434\'82\'f0\u-27036\'8f\'9c\u21435\'8b\'8e\u12375\'82\'b5\u12383\'82\'bd\u12398\'82\'cc\u12391\'82\'c5\u22909\'8d\'44\u12365\'82\'ab\u12394\'82\'c8\u30058 +\'94\'d4\u21495\'8d\'86\u12395\'82\'c9\u-28675\'92\'c7\u21152\'89\'c1\u21487\'89\'c2\u-32515\'94\'5c\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12524\'83\'8c\u12467\'83\'52\u12540\'81\'5b\u12489\'83\'68\u-30163\'90\'dd\u23450\'92\'e8\u12363\'82\'a9\u12425 +\'82\'e7\u25313\'8a\'67\u24373\'92\'a3\u12377\'82\'b7\u12427\'82\'e9\u12371\'82\'b1\u12392\'82\'c6\u12391\'82\'c5\u26032\'90\'56\u12383\'82\'bd\u12394\'82\'c8\u27005\'8a\'79\u26354\'8b\'c8\u12398\'82\'cc\u23450\'92\'e8\u32681\'8b\'60\u12418\'82\'e0\u21487 +\'89\'c2\u-32515\'94\'5c\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u-28666\'8b\'74\u-30335\'97\'76\u26395\'96\'5d\u-230\'81\'46}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par HS}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12398\'82\'cc\u12514\'83\'82\u12540\'81\'5b\u12489\'83\'68\u12479\'83\'5e\u12452\'83\'43\u12503\'83\'76\u-225 +\'81\'48}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 (104-105)}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12289\'81\'41\u12512 +\'83\'80\u12540\'81\'5b\u12499\'83\'72\u12540\'81\'5b\u12514\'83\'82\u12540\'81\'5b\u12489\'83\'68\u-225\'81\'48}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 (152-153)}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 +\fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12399\'82\'cd\u20206\'89\'bc\u21517\'96\'bc\u12391\'82\'c5\u12377\'82\'b7\u12289\'81\'41\u29992\'97\'70\u-28652\'93\'72\u12364\'82\'aa\u20998\'95\'aa +\u12363\'82\'a9\u12425\'82\'e7\u12394\'82\'c8\u12356\'82\'a2\u12398\'82\'cc\u12391\'82\'c5\u24773\'8f\'ee\u22577\'95\'f1\u19979\'89\'ba\u12373\'82\'b3\u12356\'82\'a2\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u21508\'8a\'65\u-26619\'8d\'80\u30446\'96\'da\u21517\'96\'bc\u12398\'82\'cc\u12418\'82\'e0\u12387\'82\'c1\u12392 +\'82\'c6\u-32145\'97\'c7\u12356\'82\'a2\u-26619\'8d\'80\u30446\'96\'da\u21517\'96\'bc\u26696\'88\'c4\u12434\'82\'f0\u21215\'95\'e5\u-26938\'8f\'57\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par +\par Bugs, etc: +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u-26618\'8f\'87\u27425\'8e\'9f\u23550\'91\'ce\u24540\'89\'9e\u12375\'82\'b5\u12414\'82\'dc\u12377\'82\'b7\u12398 +\'82\'cc\u12391\'82\'c5\u12473\'83\'58\u12524\'83\'8c\u12395\'82\'c9\u-30335\'97\'76\u26395\'96\'5d}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 age}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 +\fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12390\'82\'c4\u12367\'82\'ad\u12384\'82\'be\u12373\'82\'b3\u12356\'82\'a2\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par +\par Misc. Notes: +\par GOLD}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12461\'83\'4c\u12508\'83\'7b\u12531\'83\'93\u12290\'81\'42}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par I want to analyze data from 8th Style and below. +\par +\par History: +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12539\'81\'45}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 >>748}{\rtlch\fcs1 +\af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12373\'82\'b3\u12435\'82\'f1\u12398\'82\'cc\u24076\'8a\'f3\u26395\'96\'5d\u27231\'8b\'40\u-32515\'94\'5c\u-28675\'92\'c7\u21152 +\'89\'c1\u-248\'81\'69}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 HS}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12394\'82\'c8 +\u12425\'82\'e7}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 1300}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u-162\'81\'60 +\u12418\'82\'e0\u20351\'8e\'67\u29992\'97\'70\u21487\'89\'c2\u-32515\'94\'5c\u12395\'82\'c9\u12289\'81\'41}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 9999}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 +\fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12414\'82\'dc\u12391\'82\'c5\u30906\'8a\'6d\u-30067\'94\'46\u28168\'8d\'cf\u12415\'82\'dd\u-247\'81\'6a}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u12524\'83\'8c\u12452\'83\'43\u12516\'83\'84\u12540\'81\'5b\u-30163\'90\'dd\u23450\'92\'e8\u12398 +\'82\'cc}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 7}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12392\'82\'c6}{\rtlch\fcs1 +\af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 8}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12364\'82\'aa\u20837\'93\'fc\u12428\'82\'ea\u22793 +\'95\'cf\u12431\'82\'ed\u12387\'82\'c1\u12390\'82\'c4\u12383\'82\'bd\u12398\'82\'cc\u12434\'82\'f0\u20462\'8f\'43\u27491\'90\'b3}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u-29860\'95\'88\u-26782\'96\'ca\u23450\'92\'e8\u32681\'8b\'60\u12364\'82\'aa\u12468\'83\'53\u12511 +\'83\'7e\u12392\'82\'c6\u12375\'82\'b5\u12390\'82\'c4\u27531\'8e\'63\u12427\'82\'e9\u12398\'82\'cc\u12434\'82\'f0\u20462\'8f\'43\u27491\'90\'b3}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12539\'81\'45\u26354\'8b\'c8\u-30163\'90\'dd\u23450\'92\'e8\u-237\'82\'52\u12398\'82\'cc\u-29860\'95\'88\u-26782 +\'96\'ca\u12501\'83\'74\u12449\'83\'40\u12452\'83\'43\u12523\'83\'8b\u12398\'82\'cc\u21517\'96\'bc\u31216\'8f\'cc\u22793\'95\'cf\u26356\'8d\'58\u-248\'81\'69}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 ->2dx}{\rtlch\fcs1 +\af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12501\'83\'74\u12449\'83\'40\u12452\'83\'43\u12523\'83\'8b\u-247\'81\'6a}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u20445\'95\'db\u23384\'91\'b6\u26178\'8e\'9e\u12395\'82\'c9\u22833\'8e\'b8\u25943\'94\'73\u12377 +\'82\'b7\u12427\'82\'e9\u21839\'96\'e2\u-26548\'91\'e8\u12398\'82\'cc\u20462\'8f\'43\u27491\'90\'b3}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12539\'81\'45}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 HS}{\rtlch\fcs1 +\af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12289\'81\'41}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 DD}{\rtlch\fcs1 \af11\afs20 +\ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12289\'81\'41}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 GD}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 +\fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12398\'82\'cc\u20027\'8e\'e5\u-30335\'97\'76\u-237\'82\'52\u31278\'8e\'ed\u12398\'82\'cc}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 eout}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12395\'82\'c9\u23550\'91\'ce\u24540\'89\'9e}{\rtlch\fcs1 \af2\afs20 +\ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 AC6th}{\rtlch\fcs1 +\af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12473\'83\'58\u12524\'83\'8c\u12398\'82\'cc}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 >>592}{ +\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12373\'82\'b3\u12435\'82\'f1\u-32765\'8d\'6c\u26696\'88\'c4\u12398\'82\'cc}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 CSV}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u19968\'88\'ea\u25324\'8a\'87\u12452\'83\'43\u12531\'83\'93\u12509 +\'83\'7c\u12540\'81\'5b\u12488\'83\'67\u12395\'82\'c9\u23550\'91\'ce\u24540\'89\'9e}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u20104\'97\'5c\u32004\'96\'f1\u-26600\'97\'cc\u22495\'88\'e6\u12395\'82\'c9\u12388\'82\'c2\u12356 +\'82\'a2\u12390\'82\'c4\u25805\'91\'80\u20316\'8d\'ec\u19981\'95\'73\u-30335\'97\'76\u12398\'82\'cc\u12383\'82\'bd\u12417\'82\'df\u20840\'91\'53\u25764\'93\'50\u24259\'94\'70}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 + +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u12354\'82\'a0\u12427\'82\'e9\u31243\'92\'f6\u24230\'93\'78\u12398\'82\'cc\u-27245\'8a\'d4\u-28587 +\'88\'e1\u12356\'82\'a2\u12364\'82\'aa\u21547\'8a\'dc\u12414\'82\'dc\u12428\'82\'ea\u12383\'82\'bd\u25163\'8e\'e8\u21205\'93\'ae\u32232\'95\'d2\u-26938\'8f\'57\u28168\'8d\'cf\u12415\'82\'dd\u12398\'82\'cc}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 eout}{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12395\'82\'c9\u23550\'91\'ce\u24540\'89\'9e}{\rtlch\fcs1 \af2\afs20 +\ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u21517\'96\'bc\u21069\'91\'4f\u12434\'82\'f0\u20184\'95\'74\u12369\'82\'af\u12390\'82\'c4\u20445 +\'95\'db\u23384\'91\'b6\u12434\'82\'f0\u-28675\'92\'c7\u21152\'89\'c1}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u21508\'8a\'65\u31278\'8e\'ed\u20462\'8f\'43\u27491\'90\'b3}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u20869\'93\'e0\loch\af11\hich\af11\dbch\f11 \u-28440\'95\'94\u12467\'83\'52\u12540\'81\'5b\u12489 +\'83\'68\u26368\'8d\'c5\u-28567\'93\'4b\u21270\'89\'bb}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12539\'81\'45\u21508\'8a\'65\u31278\'8e\'ed\u20462\'8f\'43\u27491\'90\'b3}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u19981\'95\'73\u-30335\'97\'76\u12394\'82\'c8\u-26619\'8d\'80\u30446\'96\'da\u12398\'82\'cc\u21066 +\'8d\'ed\u-27036\'8f\'9c}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12539\'81\'45\u21508\'8a\'65\u31278\'8e\'ed\u20462\'8f\'43\u27491\'90\'b3}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 +\f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u26032\'90\'56\u-30321\'8b\'4b\u-28675\'92\'c7\u21152\'89\'c1\u12364\'82\'aa\u12391\'82\'c5\u12365 +\'82\'ab\u12394\'82\'c8\u12363\'82\'a9\u12387\'82\'c1\u12383\'82\'bd\u20214\'8c\'8f}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u26354\'8b\'c8\u-28675\'92\'c7\u21152\'89\'c1\u24460\'8c\'e3\u12484\'83\'63\u12522\'83\'8a\u12540 +\'81\'5b\u12395\'82\'c9\u21517\'96\'bc\u21069\'91\'4f\u12364\'82\'aa\u20986\'8f\'6f\u12394\'82\'c8\u12363\'82\'a9\u12387\'82\'c1\u12383\'82\'bd\u20214\'8c\'8f}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }{\rtlch\fcs1 \af11\afs20 \ltrch\fcs0 \fs20\loch\af11\hich\af11\dbch\af11\insrsid1316374\charrsid1316374 \loch\af11\hich\af11\dbch\f11 \uc2\u12288\'81\'40\u-30616\'95\'5c\u31034\'8e\'a6\u12364\'82\'aa\u12362\'82\'a8\u12363\'82\'a9\u12375\'82\'b5\u12363 +\'82\'a9\u12387\'82\'c1\u12383\'82\'bd\u20214\'8c\'8f}{\rtlch\fcs1 \af2\afs20 \ltrch\fcs0 \f2\fs20\insrsid1316374\charrsid1316374 +\par }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af31507 \ltrch\fcs0 \insrsid1316374 +\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 +72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 +2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b +44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 +065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 +00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 +84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc +52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 +bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 +656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c +070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 +29e245eb2b260a0238fd010000ffff0300504b03041400060008000000210096b5ade296060000501b0000160000007468656d652f7468656d652f7468656d65 +312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87615b8116d8 +a5fb34d93a6c1dd0afb0475292c5585e9236d88aad3e2412f9e3fbff1e1fa9abd7eec70c1d1221294fda5efd72cd4324f1794093b0eddd1ef62fad79482a9c04 +98f184b4bd2991deb58df7dfbb8ad755446282607d22d771db8b944ad79796a40fc3585ee62949606ecc458c15bc8a702910f808e8c66c69b9565b5d8a314d3c +94e018c8de1a8fa94fd05093f43672e23d06af89927ac06762a049136785c10607758d9053d965021d62d6f6804fc08f86e4bef210c352c144dbab999fb7b471 +7509af678b985ab0b6b4ae6f7ed9ba6c4170b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83a6569632cd467faddec9699640f671 +9e76b7d6ac355c7c89feca9cccad4ea7d36c65b258a206641f1b73f8b5da6a6373d9c11b90c537e7f08dce66b7bbeae00dc8e257e7f0fd2badd5868b37a088d1 +e4600ead1ddaef67d40bc898b3ed4af81ac0d76a197c86826828a24bb318f3442d8ab518dfe3a20f000d6458d104a9694ac6d88728eee2782428d60cf03ac1a5 +193be4cbb921cd0b495fd054b5bd0f530c1931a3f7eaf9f7af9e3f45c70f9e1d3ff8e9f8e1c3e3073f5a42ceaa6d9c84e5552fbffdeccfc71fa33f9e7ef3f2d1 +17d57859c6fffac327bffcfc793510d26726ce8b2f9ffcf6ecc98baf3efdfdbb4715f04d814765f890c644a29be408edf3181433567125272371be15c308d3f2 +8acd249438c19a4b05fd9e8a1cf4cd296699771c393ac4b5e01d01e5a30a787d72cf1178108989a2159c77a2d801ee72ce3a5c545a6147f32a99793849c26ae6 +6252c6ed637c58c5bb8b13c7bfbd490a75330f4b47f16e441c31f7184e140e494214d273fc80900aedee52ead87597fa824b3e56e82e451d4c2b4d32a423279a +668bb6690c7e9956e90cfe766cb37b077538abd27a8b1cba48c80acc2a841f12e698f13a9e281c57911ce298950d7e03aba84ac8c154f8655c4f2af074481847 +bd804859b5e696007d4b4edfc150b12addbecba6b18b148a1e54d1bc81392f23b7f84137c2715a851dd0242a633f900710a218ed715505dfe56e86e877f0034e +16bafb0e258ebb4faf06b769e888340b103d3311da9750aa9d0a1cd3e4efca31a3508f6d0c5c5c398602f8e2ebc71591f5b616e24dd893aa3261fb44f95d843b +5974bb5c04f4edafb95b7892ec1108f3f98de75dc97d5772bdff7cc95d94cf672db4b3da0a6557f70db629362d72bcb0431e53c6066acac80d699a6409fb44d0 +8741bdce9c0e4971624a2378cceaba830b05366b90e0ea23aaa241845368b0eb9e2612ca8c742851ca251ceccc70256d8d87265dd96361531f186c3d9058edf2 +c00eafe8e1fc5c509031bb4d680e9f39a3154de0accc56ae644441edd76156d7429d995bdd88664a9dc3ad50197c38af1a0c16d684060441db02565e85f3b966 +0d0713cc48a0ed6ef7dedc2dc60b17e92219e180643ed27acffba86e9c94c78ab90980d8a9f0913ee49d62b512b79626fb06dccee2a432bbc60276b9f7dec44b +7904cfbca4f3f6443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc399161ee314bc2e75cf8759081743be1236ec4f4d6693e5336fb672c5dc24a8c33585b5fb +9cc24e1d4885545b58463634cc5416022cd19cacfccb4d30eb45296023fd35a458598360f8d7a4003bbaae25e331f155d9d9a5116d3bfb9a95523e51440ca2e0 +088dd844ec6370bf0e55d027a012ae264c45d02f708fa6ad6da6dce29c255df9f6cae0ec38666984b372ab5334cf640b37795cc860de4ae2816e95b21be5ceaf +8a49f90b52a51cc6ff3355f47e0237052b81f6800fd7b802239daf6d8f0b1571a8426944fdbe80c6c1d40e8816b88b8569082ab84c36ff0539d4ff6dce591a26 +ade1c0a7f669880485fd484582903d284b26fa4e2156cff62e4b9265844c4495c495a9157b440e091bea1ab8aaf7760f4510eaa69a6465c0e04ec69ffb9e65d0 +28d44d4e39df9c1a52ecbd3607fee9cec7263328e5d661d3d0e4f62f44acd855ed7ab33cdf7bcb8ae889599bd5c8b3029895b6825696f6af29c239b75a5bb1e6 +345e6ee6c28117e73586c1a2214ae1be07e93fb0ff51e133fb65426fa843be0fb515c187064d0cc206a2fa926d3c902e907670048d931db4c1a44959d366ad93 +b65abe595f70a75bf03d616c2dd959fc7d4e6317cd99cbcec9c58b34766661c7d6766ca1a9c1b327531486c6f941c638c67cd22a7f75e2a37be0e82db8df9f30 +254d30c1372581a1f51c983c80e4b71ccdd28dbf000000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f74 +68656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f24 +51eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198 +720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528 +a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c0200001300000000000000000000000000 +000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b000000000000000000000000 +002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c00000000000000000000000000140200007468 +656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210096b5ade296060000501b000016000000000000000000 +00000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b010000270000000000 +00000000000000009b0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000960a00000000} +{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d +617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 +6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 +656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} +{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; +\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; +\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; +\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 +4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 +d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f00000000000000000000000020cc +61a28cd7c701feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/readme.txt b/iidx/Eout Editor/eoutEnglish-1.1-biso/readme.txt new file mode 100644 index 0000000..91b5774 --- /dev/null +++ b/iidx/Eout Editor/eoutEnglish-1.1-biso/readme.txt @@ -0,0 +1,113 @@ +EditOut -2chan Sucks Edition- +v1.1 for bemaniso +-------------------------------------- +Files found on 2ch by musicboy +Translations done by Soveryshiny +Translations Added to code by Anthony +Program Recompiled by infamouspat +Eout Encrypter/Decrypter by Tau +Testing and mdata provided by Raoh +-------------------------------------- +Included in this package: + +mdata (DIR) - GOLD mdata JPGs +split (DIR) - Required Files. +10-12eout.dec - 10th - HS eout merged +13eout.dec - DistorteD eout +14eout - GOLD eout +decrypt.exe - eout.bin decrypter +encrypt.exe - eout.bin encrypter +eoutEdit.exe - eout Editor execulatable +eoutEdit.jar - eout Editor jar file +readme.txt - readme +readme-2ch.rtf - original 2chan readme +swt-win32-3236.dll - dll file required for eout Editor +-------------------------------------- + +Instructions: + +-------------------------------------- +Decompressing the eout.bin file +-------------------------------------- +1) Place the eout.bin from the game you wish to use +(found in data/info) into the eoutEnglish folder. + +2) In your command line navigate to your eoutEnglish +folder and run "decrypt eout.bin eout.dec". You will +now have a decrypted eout file. + +-------------------------------------- +Opening the eout file +-------------------------------------- +1) In eoutEdit change your CSV Settings to the game you +will be editing. THIS MUST BE DONE BEFORE STEP 2 OR +YOUR SAVED EOUT WILL BE CORRUPT. + +2) Open your eout.dec in eoutEdit. + +-------------------------------------- +Adding Data to your eout +-------------------------------------- +Adding data to your eout file is rather easy. Find the number +of the song you wish to add to your name and click the number. +It will ask you if you wish to add it. Click yes and begin +entering the data. The best way to find the data you need is +to run a second instance of eoutEdit and load in one of the +included eout.dec files and get the data from that file. +Remember you must click save to every individual page of data +to properly add the song. + +**NOTE** If you try to add a song that does NOT have graphics in +the current game's mdata then you will get HDD errors on game +boot. I have included a folder of GOLD's mdata in JPG format +for those of you working with GOLD. + +After adding a song into your list, copy it's sd_data, movie (if +available) and overlays (if available) to the new game directory. + +Examples! + +To add Car of Your Dreams (movie) to GOLD you must copy: +1) +1106 (DIR) from the previous game's 'data\sd_data' to your +GOLD's 'data\sd_data' +2) +1106.4 (DIR) from the previous game's 'data\movie' to your +GOLD's 'data\movie' + +To add Samba de Janeiro (overlay) to GOLD you must copy: +1) +1304 (DIR) from the previous game's 'data\sd_data' to your +GOLD's 'data\sd_data' +2) +1304 (DIR) from the previous game's 'data\graph\sys' to your +GOLD's 'data\graph\sys' + +When in doubt of what you need to move, check both data\movie and +data\graph\sys for files with the same number as the song. + +Once you are done saving songs just click 'File->Save' to resave the +eout.dec file. + +-------------------------------------- +Recompressing the eout.bin file +-------------------------------------- +1) In your command line navigate to your eoutEnglish +folder and run "encrypt eout.dec eout.bin". You will +now have an encrypted eout file. + +2) Place the eout.bin from your eoutEnglish folder +back into the 'data/info' folder of the game. + +REMEMBER TO MAKE BACKUPS!!! This program does not have a delete +song option. So if a song you add does not work you will need to +go to your backups. If you don't make backups, the most you can +do is blank song info out and end up with songwheel cluster. + +Thats all you need to do. + +For discussion on this please refer to: +http://bemaniso.ws/forums.php?action=viewtopic&topicid=9206 + + +-Anthony \ No newline at end of file diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/split/1.SPLIT b/iidx/Eout Editor/eoutEnglish-1.1-biso/split/1.SPLIT new file mode 100644 index 0000000..1c0d380 Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/split/1.SPLIT differ diff --git a/iidx/Eout Editor/eoutEnglish-1.1-biso/swt-win32-3236.dll b/iidx/Eout Editor/eoutEnglish-1.1-biso/swt-win32-3236.dll new file mode 100644 index 0000000..ca2abdf Binary files /dev/null and b/iidx/Eout Editor/eoutEnglish-1.1-biso/swt-win32-3236.dll differ diff --git a/iidx/bme2ac/0.7/1.h b/iidx/bme2ac/0.7/1.h new file mode 100755 index 0000000..3f0acf0 --- /dev/null +++ b/iidx/bme2ac/0.7/1.h @@ -0,0 +1,1020 @@ +//1.h +//deals with parsing the bms files for events and converting them into a chain of .1 file events and other .1 related stuff +//largely based on DXAC1.pas (QQQ) + +//2dx ac framerate +#define FPS_GOLD 60.05 //According to Tau GOLD uses this framerate instead of the standard 60.04 for internal computations +#define FPS_DD 59.95 //framerate for DistorteD and up +#define PRELOAD_DELAY 200 //specifies the maximum keysound preload delay before the actual key in ms +#define ENDSONG_DELAY 3000 //end a song 3 seconds after the last measure + +//BMS event/channel list + +#define BMS_BPM_CUST 8 +#define BMS_BPM 3 +#define BMS_STOP 9 + +#define BMS_AUTOPLAY 1 + +#define BMS_P1_1 11 +#define BMS_P1_2 12 +#define BMS_P1_3 13 +#define BMS_P1_4 14 +#define BMS_P1_5 15 +#define BMS_P1_6 18 +#define BMS_P1_7 19 +#define BMS_P1_S 16 + +#define BMS_P2_1 21 +#define BMS_P2_2 22 +#define BMS_P2_3 23 +#define BMS_P2_4 24 +#define BMS_P2_5 25 +#define BMS_P2_6 28 +#define BMS_P2_7 29 +#define BMS_P2_S 26 + +//.1 file event type list + + +#define ONE_AUTOPLAY 7 + +#define ONE_TYPE_P1 0 +#define ONE_TYPE_P2 1 +#define ONE_KEYCHANGE1 2 +#define ONE_KEYCHANGE2 3 +#define ONE_TYPE_BPM 4 +#define ONE_MEASURESIZE 5 +#define ONE_ENDSONG 6 +#define ONE_JUDGEMENT 8 +#define ONE_MEASURE 0xC +#define ONE_NOTECOUNT 0x10 +#define ENDSEQ 0x7FFFFFFF + +#define ONE_DUMMY 0xF0 +#define ONE_STOP 0xF1 //this is not the actual event, just a marker for later +#define ONE_LONG_P1 0xF2 //same here +#define ONE_LONG_P2 0xF3 //same here +#define ONE_ENDLONG_P1 0xF4 //lnobj handling +#define ONE_ENDLONG_P2 0xF5 + + +#define EVENTSIZE 8 + + + +//we build a linked list of events so we can easily append stuff +typedef struct +{ + //entries are the same as in the .1 file + unsigned int time; + byte type; + byte data1; + unsigned short int data2; + + //longnote duration + unsigned short int longdur; + + void *prev; + void *next; +} event; + +//this will hold pointers to the first node for each chart +event *onecharts[CHARTCOUNT]; + +//These are from D.C.Fish (Gold AC) +//note to self: look up other charts +unsigned short int judgements[6] = {0xF0, 0xFA, 0xFF, 0x3, 0x8, 0x12}; + +//offsets inside the .1 header for chart i +int offsets[CHARTCOUNT] = {0, 8, 16, 24, 48, 56, 64}; + +//the write order inside the official .1 charts is h7, h14, n7, n14, a7, a14, b, maybe this matters +//anyway, it's not much hassle, so let's write them in "official" order +int worder[7] = {0, 4, 1, 5, 2, 6, 3}; +int onesize; //size of the whole .1 file +byte *onefile; + + + +//inserts an event into the chain for chart i while keeping the timestamps in ascending order +//this might seem overly complicated, but for several reasons we need to know where exactly + //events with equal timestamps are positioned +void add_event(int i, event ev) +{ + event *temp, *ev_n; + + if(!onecharts[i]) + { + onecharts[i] = malloc(sizeof(event)); + memcpy(onecharts[i], &ev, sizeof(event)); + onecharts[i]->prev = onecharts[i]->next = NULL; + return; + } + + temp = onecharts[i]; + + while(temp->next != NULL && temp->time < ev.time) + { + temp = temp->next; + } + + ev_n = malloc(sizeof(event)); //create the new event to insert + memcpy(ev_n, &ev, sizeof(event)); //and copy what we need + + if(temp->time < ev.time) //this is an append or insert after the current note + { + if(temp->next) + ((event*)temp->next)->prev = ev_n; + + ev_n->next = temp->next; + temp->next = ev_n; + + ev_n->prev = temp; + + } + else //this is an insert before the current node + { + if(temp->prev) + ((event*)temp->prev)->next = ev_n; + else //this is to become the first element + onecharts[i] = ev_n; + + ev_n->next = temp; + ev_n->prev = temp->prev; + + temp->prev = ev_n; + } +} + +//deletes an event from the chain +void delete_event(event *ev) +{ + event *pr, *nx; + pr = ev->prev; + nx = ev->next; + + if(pr) + pr->next = nx; + if(nx) + nx->prev = pr; + + free(ev); +} + +//main parser logic +//converts the bms events to .1 events +//this does _not_ add the standard events yet +void convert_to_1_events() +{ + int i,j,k; + char measure_c[4]; //use this to store the first 3 bytes after '#'. I hate writing parsers + int measure,channel; + float mtime; + int denom, nume; //denominator and nominator of a note inside a measure + + byte ev_type, ev_type_keep; + float ev_time; + byte ev_data1; + int bms_ev; + event temp; + + int ln; + int flip1, flip2; + + unsigned short int ev_data2; + + byte *data; + + measure_c[3] = '\0'; + flip1 = 0; + flip2 = 0; + + temp.next = temp.prev = NULL; + + printf("converting bms charts to .1 charts\n"); + for(i = 0; i < CHARTCOUNT; i++) + { + if(!bms[i].length) continue; + + printf("chart %s: ", CHARTNAMES[i]); + + data = bms[i].data; + + for(j = 1; j < bms[i].length; j++) + { + //find a candidate (parse for "#XXXYY:") + if(data[j] == '#' && data[j+6] == ':') + { + measure_c[0] = data[j+1]; + measure_c[1] = data[j+2]; + measure_c[2] = data[j+3]; + sscanf(measure_c, "%d", &measure); + sscanf(data+j+4, "%d", &channel); + + ev_data1 = 0; + ev_data2 = 0; + ev_time = 0; + ev_type = 0; + + if(channel >= 50) //longnotes + { + channel -= 40; + ln = 1; + //printf("!"); + } + else + { + ln = 0; + } + + //check the channel and if we support it, if so set the event type and data type + //don't be scared by the fancy switch magic, we just evaluate bms events to .1 events in a tricky way to save typing work :P + switch(channel) + { + case BMS_P1_S: + ev_data1 += 4; + case BMS_P1_6: + case BMS_P1_7: + ev_data1 -= 2; + case BMS_P1_1: + case BMS_P1_2: + case BMS_P1_3: + case BMS_P1_4: + case BMS_P1_5: + ev_data1 += channel - 11; + ev_type = ONE_TYPE_P1; + break; + + case BMS_P2_S: + ev_data1 += 4; + case BMS_P2_6: + case BMS_P2_7: + ev_data1 -= 2; + case BMS_P2_1: + case BMS_P2_2: + case BMS_P2_3: + case BMS_P2_4: + case BMS_P2_5: + ev_data1 += channel - 21; + ev_type = ONE_TYPE_P2; + break; + + case BMS_BPM: + case BMS_BPM_CUST: + ev_type = ONE_TYPE_BPM; + break; + + case BMS_AUTOPLAY: + ev_type = ONE_AUTOPLAY; + break; + + case BMS_STOP: + ev_type = ONE_STOP; + break; + + default: + //printf("%d ", channel); + continue; //unsupported event type, we skip this + } + + //calculate the start of the measure + mtime = 0; + for(k = 0; k < measure; k++) + mtime += bms[i].msize[k]; + + //now that we've got the measure and the channel, count the number of events for this measure to get the denominator + denom = 0; + for(k = j+7/*after the ':'*/; (k<=bms[i].length) && (data[k] != '\n') && (data[k] != '\r') && (data[k] != '#'); k+=2) //just to be sure... + denom++; + + k = j + 7; + nume = 0; + ev_type_keep = ev_type; + + //now for the interesting part + for(k = j+7; nume < denom; k+=2) + { + ev_time = mtime + ((float)nume/(float)denom)*bms[i].msize[measure]; + ev_time *= 4. * 60. * 1000./ bms[i].bpm; //timestamp in milliseconds + nume++; + + ev_type = ev_type_keep; //in case we run into a lnobj on the way + + bms_ev = strtoi(data+k); + + if(!bms_ev) + { + continue; //'00', skip this + } + + if(channel == BMS_AUTOPLAY) + { + ev_data2 = bms[i].ref[bms_ev-1]; //remember that we always count from 0 while bms indices start from 1 + } + else if(channel == BMS_BPM_CUST) + { + //printf("BPM change!\n"); + if(((bms[i].bpmchange[bms_ev-1] - (int)bms[i].bpmchange[bms_ev-1]) < 0.01) || (bms[i].bpmchange[bms_ev-1] > 655.35)) + { + //an interesting way to work around the short int limit + ev_data1 = 1; + ev_data2 = (unsigned short int)(bms[i].bpmchange[bms_ev-1]); + } + else + { + ev_data1 = 100; + ev_data2 = (unsigned short int)bms[i].bpmchange[bms_ev-1]*100; + } + } + else if(channel == BMS_BPM) + { + //printf("BPM change!\n"); + ev_data1 = 1; + ev_data2 = (unsigned short)strtoi_h(data+k); //in this case we have to use hex, meh + } + else if(channel == BMS_STOP) + { + //printf("STOP!\n"); + ev_data2 = (unsigned short)strtoi(data+k) - 1; //BMS starts indexing at 1 blablabla + //continue; + } + else if(channel >= 11 && channel <= 29) //keypress + { + //for now we store the keysound number in the key event; we create the actual keysound event later + if(bms_ev != bms[i].lnobj) + { + ev_data2 = bms[i].ref[bms_ev-1]; //data2 is the keysound index inside the .2dx file + } + else + { + ev_data2 = 0; + } + + + if(channel <= 19) //1player side + { + bms[i].numkeys[0]++; + + if(ln) //longnote handling + { + ev_type = ONE_LONG_P1; + //don't count every second longnote event; notecount stays consistant + if(flip1) + { + bms[i].numkeys[0]--; + flip1 = 0; + } + else + { + flip1 = 1; + } + } + } + else //2player side + { + bms[i].numkeys[1]++; + + if(ln) + { + ev_type = ONE_LONG_P2; + if(flip2) + { + bms[i].numkeys[1]--; + flip2 = 0; + } + else + { + flip2 = 1; + } + } + } + + if(bms_ev == bms[i].lnobj) + { + //longnote end marker + if(channel <= 19) + { + ev_type = ONE_ENDLONG_P1; + bms[i].numkeys[0]--; + } + else + { + ev_type = ONE_ENDLONG_P2; + bms[i].numkeys[1]--; + } + //continue; + } + } + + //now add the actual event to the list; + + temp.time = ev_time; + temp.type = ev_type; + temp.data1 = ev_data1; + temp.data2 = ev_data2; + temp.longdur = 0; + //printf("time:%d channel:%d type:%d(bms:%d), data1:%d, data2:%d\n", (int)ev_time, channel, ev_type, bms_ev, ev_data1, bms[i].ref[bms_ev-1]); + add_event(i, temp); + if(i >= 4 && temp.type == ONE_TYPE_BPM) + { + add_event(i, temp); //for some reason these are added twice for double charts + } + } + //shortcut, skip parsed line + j = k; + + } + } + printf("keypresses: %d(P1) %d(P2)\n", bms[i].numkeys[0], bms[i].numkeys[1]); + //printf("adding measure lines...\n"); + //now that we're done with the normal events, add the measure lines + ev_time = 0; + temp.time = 0; + temp.type = ONE_MEASURE; + temp.data1 = 0; + temp.data2 = 0; + for(j = 0; j <= bms[i].mcount; j++) + { + temp.time = ev_time * 4. * 60. * 1000. / bms[i].bpm; + if(i >= 4) //for double charts, add a measure line for the 2p side, too + { + temp.data1 = 1; + add_event(i, temp); + } + temp.data1 = 0; + add_event(i, temp); + ev_time += bms[i].msize[j]; + } + + //we add this dummy event as the marker for the end of the last measure + //note that this is not really optimal for calculating the end of the song (will fix later) + temp.type = ONE_DUMMY; + temp.time = ev_time * 4. * 60. * 1000. / bms[i].bpm; + add_event(i, temp); + } + +} + +void add_standard_events() +{ + int i,j,k; + + event total_notes_p1, total_notes_p2; + event bpm; //starting bpm + event msize; //measure size + event timings; //timing windows + event endmark; //marks the end of the song + event endseq; //end sequence + event *temp; + int twop = 0; //double chart indicator + + printf("adding standard events..."); + for(i = 0; i < CHARTCOUNT; i++) + { + if(!onecharts[i]) + continue; + + if(i >= 4) twop = 1; + else twop = 0; + + printf("%s...", CHARTNAMES[i]); + + for(k = twop; k >= 0; k--) //double charts have two entries for everything, so add them in, too + { + + memset(&total_notes_p1, 0, sizeof(event)); + memset(&total_notes_p2, 0, sizeof(event)); + memset(&bpm, 0, sizeof(event)); + memset(&msize, 0, sizeof(event)); + memset(&timings, 0, sizeof(event)); + memset(&endmark, 0, sizeof(event)); + memset(&endseq, 0, sizeof(event)); + + + total_notes_p1.type = ONE_NOTECOUNT; + total_notes_p1.data2 = bms[i].numkeys[0]; + + total_notes_p2.type = ONE_NOTECOUNT; + total_notes_p2.data1 = 1; + total_notes_p2.data2 = bms[i].numkeys[1]; + + bpm.type = ONE_TYPE_BPM; + if((bms[i].bpm-(int)bms[i].bpm < 0.01) || (bms[i].bpm > 655.35)) //ass-check for fractional bpm, probably doesn't even matter + { + bpm.data1 = 1; + bpm.data2 = (unsigned short int)(bms[i].bpm); + } + else + { + bpm.data1 = 100; + bpm.data2 = (unsigned short int)bms[i].bpm*100; + } + + msize.type = ONE_MEASURESIZE; + msize.data1 = 4; + msize.data2 = 4; + + //add judgement events + timings.type = ONE_JUDGEMENT; + for(j = 5; j >= 0; j--) + { + timings.data1 = (byte)j; + timings.data2 = judgements[j]; + add_event(i, timings); + } + + add_event(i, msize); + add_event(i, bpm); + if(k != 1) + { + add_event(i, total_notes_p2); + add_event(i, total_notes_p1); + } + + + temp = onecharts[i]; + while(temp->next) temp = temp->next; //temp->type == ONE_DUMMY + + endmark.type = ONE_ENDSONG; + endmark.time = temp->time + ENDSONG_DELAY*(1-twop*(1-k)); //evil hack :D; ensures we add both the p1 and the p2 event at the same time + endmark.data1 = k; + + add_event(i, endmark); + + } + + endseq.time = ENDSEQ; + add_event(i, endseq); + + //kill the dummy event + temp = onecharts[i]; + while(temp = temp->next) + { + if(temp->type == ONE_DUMMY) + { + delete_event(temp); + break; //only one dummy event per chart + } + } + } + PNEWLINE; +} + +void handle_longnotes() +{ + int i, player, time, count; + + event *temp; + event *temp2; + + int debug[8]; + int ev_debug[8]; + + memset(debug, 0, 8*sizeof(int)); + + printf("processing longnotes (if neccesary).."); + for(i = 0; i < CHARTCOUNT; i++) + { + if(!onecharts[i]) + continue; + + printf("%s..", CHARTNAMES[i]); + + temp = onecharts[i]; + count = 0; + + //find longnote events + do + { + //longnotes from the longnote channel + if(temp->type == ONE_LONG_P1 || temp->type == ONE_LONG_P2) //longnote + { + count++; + if(temp->type == ONE_LONG_P1) + { + player = ONE_TYPE_P1; + } + else + { + player = ONE_TYPE_P2; + } + + //find the exact time the longnote ends + temp2 = temp; + while((temp2 = temp2->next)) + { + if((temp2->type == temp->type) && (temp2->data1 == temp->data1)) //end the longnote + { + //chargenote handling for sirius + temp->longdur = temp2->time - temp->time; + + delete_event(temp2); //kill the endnote + //bms[i].numkeys[player]--; + break; + } + } + + //set correct event type + temp->type = player; + } + + //longnotes from lnobj + if((temp->type == ONE_ENDLONG_P1) || (temp->type == ONE_ENDLONG_P2)) + { + count++; + if(temp->type == ONE_ENDLONG_P1) + { + player = ONE_TYPE_P1; + } + else + { + player = ONE_TYPE_P2; + } + + //find the previous keypress event + temp2 = temp; + while((temp2 = temp2->prev)) + { + if((temp2->type == player) && (temp2->data1 == temp->data1) && (temp2->time < temp->time)) //same player, same lane, back in time + { + //set longnote duration + temp2->longdur = temp->time - temp2->time; + + //printf("TI:%d TY:%d D1:%d D2:%d DUR:%d\n", temp2->time, temp2->type, temp2->data1, temp2->data2, temp2->longdur); + + //kill lnobj event + temp = temp->prev; + temp2 = temp->next; + //printf(" TI:%d TY:%d D1:%d D2:%d DUR:%d\n", temp2->time, temp2->type, temp2->data1, temp2->data2, temp2->longdur); + delete_event(temp2); + + break; + } + } + } + } while((temp = temp->next)); + printf("(%d)...", count); + } + PNEWLINE; +} + +//remove multiple keysound loads +void cleanup_1() +{ + int i,j,k; + + event *temp; + event *temp2; + event ref; + + printf("cleaning up charts.."); + for(i = 0; i < CHARTCOUNT; i++) + { + if(!onecharts[i]) + continue; + + printf("%s..", CHARTNAMES[i]); + memset(&ref, 0, sizeof(event)); + + //delete useless keysound loads; walk the chain once for the p1 side, once for the p2 side + for(k = 0; k <= 1; k++) + { + for(j = 0; j <= 7; j++) + { + ref.data2 = 0xFFFF; //just to be sure we don't accidently kill the first sample load + temp = onecharts[i]; + + do + { + if(temp->type == k+2 && temp->data1 == j) //soundchange for player k and key j + { + if(temp->data2 == ref.data2) + { + //printf("deleted a keysound event in %s: player:%d time:%d key:%d sound:%d\n", \ + CHARTNAMES[i], k+1, temp->time, temp->data1, temp->data2); + temp2 = temp->next; + delete_event(temp); + temp = temp2; + + if(!temp) break; + } + else + { + ref.data2 = temp->data2; + } + } + } while(temp = temp->next); + } + } + } + PNEWLINE; +} + +void create_1() +{ + int i; + int pos; //position + int size[CHARTCOUNT]; //size of the chains inside the .1 file + + event *temp; + + pos = 0x60; //start writing after the .1 header which is 96 bytes + memset(size, 0, sizeof(int)*CHARTCOUNT); + + onesize = 96; //header is always the same size + + printf("creating .1 file\n"); + //first calculate the size for each event chain and the resulting size of the .1 file + for(i = 0; i < CHARTCOUNT; i++) + { + if(!onecharts[i]) + continue; + + temp = onecharts[i]; + + do + { + //printf("(%d %d) ", temp->time, temp->type); + size[i] += EVENTSIZE; + } + while(temp = temp->next); + + onesize += size[i]; + //printf("size for %s is %d\n", CHARTNAMES[i], size[i]); + } + + + onefile = malloc(onesize); + memset(onefile, 0, onesize); + + //printf("onesize is %d\n", onesize); + + //write the header and the chains to the buffer + for(i = 0; i < CHARTCOUNT; i++) + { + //printf("size[worder[i]]: %d\n", size[worder[i]]); + if(!onecharts[worder[i]]) + continue; + + + memcpy(onefile+offsets[worder[i]], &pos, 4); //write the position of the chart + memcpy(onefile+offsets[worder[i]]+4, &size[worder[i]], 4); //write the size of the chart + + //write out the events + temp = onecharts[worder[i]]; + do + { + memcpy(onefile+pos, &temp->time, 4); + memcpy(onefile+pos+4, &temp->type, 1); + memcpy(onefile+pos+5, &temp->data1, 1); + memcpy(onefile+pos+6, &temp->data2, 2); + + pos += 8; + } + while(temp = temp->next); + + } + PNEWLINE; +} + +void adjust_bpm() +{ + int i; + + float oldbpm = 0; + float newbpm = 0; + int stime = 0; + int tdiff = 0; + event *temp; + + event *tadjust; + + printf("adjusting for (possible) BPM changes..."); + + for(i = 0; i < CHARTCOUNT; i++) + { + if(!onecharts[i]) continue; + + temp = onecharts[i]; + + oldbpm = bms[i].bpm; + + //search for bpm change events and adjust all timestamps after those events accordingly + do + { + if(temp->type == ONE_TYPE_BPM) + { + newbpm = temp->data2 / temp->data1; + stime = temp->time; + + if(oldbpm == newbpm) //no need to do anything + continue; + + tadjust = temp; + + //events are sorted by time so this works just peachy + while(tadjust = tadjust->next) + { + tdiff = tadjust->time - stime; + tdiff = (int)((float)tdiff * oldbpm / newbpm); //adjust the timestamp accordingly + tadjust->time = stime + tdiff; + } + + oldbpm = newbpm; + } + } + while(temp = temp->next); + } + PNEWLINE; +} + +void writeout_1() +{ + FILE *f; + + printf("writing output.1 to disk\n"); + f = fopen("output.1", "wb"); + fwrite(onefile, onesize, 1, f); + fclose(f); +} + + +void add_keysounds() +{ + event *key; + event *p; + event temp; + int i; + int tdiff; + + printf("adding keysound events..."); + for(i = 0; i < CHARTCOUNT; i++) + { + if(!onecharts[i]) continue; + + printf("%s...", CHARTNAMES[i]); + + //search the chain for key events + key = onecharts[i]; + do + { + if(key->type == ONE_TYPE_P1 || key->type == ONE_TYPE_P2) + { + //found a key event, let's add the keysound change for it + tdiff = 0; + + //walk the timeline backwards and try to find the previous key event for the same key + p = key; + while(p = p->prev) + { + if(p->type == key->type && p->data1 == key->data1) + { + tdiff = p->time; + break; + } + } + + //calculate the time difference between the two key events and place the keysound event right between them + + tdiff = key->time - tdiff; + + if(tdiff == key->time && key->time < PRELOAD_DELAY) //we found no key event before this one and the current key event is really close to time 0 + ; //do nothing as tdiff == key->time + else if(tdiff >= PRELOAD_DELAY*2) //the keys are far enough apart to use the standard preload delay + tdiff = PRELOAD_DELAY; + else //the keys are quite close together so place the keysound load event right between them + { + tdiff /= 2; + //printf("TDIFF: %d\n", tdiff); + } + + memcpy(&temp, key, sizeof(event)); + temp.time -= tdiff; + temp.type += 2; //preload event = playerside + 2 + + //printf("key: time:%d player:%d key:%d index:%d TDIFF:%d\n", key->time, key->type-2, key->data1+1, key->data2, tdiff); + //printf("keysoundevent: time:%d player:%d key:%d index:%d TDIFF:%d\n", temp.time, temp.type-2, temp.data1+1, temp.data2, tdiff); + add_event(i, temp); + + if(key->longdur) + { + //keypress is a longnote + key->data2 = key->longdur; + } + else + key->data2 = 0; + } + } + while(key = key->next); + } + PNEWLINE; +} + +void add_stop_events() +{ + int i; + + float bpm = 0; + + float tdiff = 0; + int d1, d2; + event *temp; + event *helper; + event bpm_help; + + printf("adjusting for (possible) stops..."); + + for(i = 0; i < CHARTCOUNT; i++) + { + if(!onecharts[i]) continue; + + if(!bms[i].stopcount) continue; + + printf("%s...", CHARTNAMES[i]); + + temp = onecharts[i]; + + //search for stop events and adjust all timestamps after those events accordingly + do + { + if(temp->type == ONE_STOP) + { + //find the bpm for the current stop event + helper = onecharts[i]; + do + { + if(helper->type == ONE_TYPE_BPM) + { + d1 = helper->data1; + d2 = helper->data2; + bpm = (float)helper->data2 / (float)helper->data1; + } + } while((helper = helper->next) && (helper->time <= temp->time)); + + //calculate the stop time + tdiff = bms[i].stops[temp->data2] / 192.; + tdiff = tdiff * 4. * 60. * 1000. / bpm; + + //adjust all event times after the stop event + helper = temp->next; + do + { + if(helper->time > temp->time && helper->time != ENDSEQ) //in case there's another event at the same time as the stop + helper->time += tdiff; + } + while(helper = helper->next); + + //add two bpm changes to simulate the stop + bpm_help.time = temp->time; + bpm_help.type = ONE_TYPE_BPM; + bpm_help.data1 = 100; + bpm_help.data2 = 100; //1 bpm (stop); iidx doesn't seem to support any lower + + add_event(i, bpm_help); + if(i >= 4) //as always, add another event for double charts + add_event(i, bpm_help); + + bpm_help.time += tdiff; + bpm_help.data1 = d1; + bpm_help.data2 = d2; //restore old bpm + + add_event(i, bpm_help); + if(i >= 4) + add_event(i, bpm_help); + } + } + while(temp = temp->next); + + //delete all stop events + + temp = onecharts[i]; + + do + { + helper = temp->next; + if(helper && helper->type == ONE_STOP) + delete_event(helper); + } + while(temp = temp->next); + } + PNEWLINE; +} + +void stretch_times(double factor) +{ + int i; + event *temp; + + for(i = 0; i < CHARTCOUNT; i++) + { + if(!onecharts[i]) continue; + + temp = onecharts[i]; + //walk the chain and multiply timestamps with factor + do + if(temp->time != ENDSEQ) + temp->time = (int)((float)temp->time * factor); + while(temp = temp->next); + } +} diff --git a/iidx/bme2ac/0.7/2dx.h b/iidx/bme2ac/0.7/2dx.h new file mode 100755 index 0000000..c97af08 --- /dev/null +++ b/iidx/bme2ac/0.7/2dx.h @@ -0,0 +1,94 @@ +//2dx.h +//deals with compiling the .2dx file + +#define TWODXHSIZE 72 //size of the .2dx header +#define WAVHSIZE 24 //size of the wav header + +int twodxsize; + +byte *tdx; //this will hold the decrypted .2dx file +byte *tdx_enc; //this will hold the encrypted .2dx file + +const byte wavheader[24] = { + '2', 'D', 'X', '9', //const string + 0x18, 0x00, 0x00, 0x00, //headersize (== 24) + 0x00, 0x00, 0x00, 0x00, //size of wave file (written at runtime) + 0x30, 0x32, 0xFF, 0xFF, //panning/initial volume? + 0x40, 0x00, 0x01, 0x00, //??? (64, 0, sample format, 0) + 0x00, 0x00, 0x00, 0x00 //??? (0, 0, 0, 0) +}; +//sample format notes: +//1: 44.1khz, 16bit MS ADPCM stereo +//0: 44.1khz, 16bit MS ADPCM mono +//8: almost but not the same as 1? +//7: ??? + +//construct the .2dx file +//specs were taken from Kitaru's create2dx.c (QQQ) +void create_2dx() +{ + int i, j, firstwav; + + printf("authoring .2dx file\n"); + //calculate the size of the final .2dx file + twodxsize = TWODXHSIZE + wavcount * WAVHSIZE + wavcount*4; //header + ToC + headers for wav files + for(i = 0; i < wavcount; i++) + twodxsize+=waves[i].length; + + twodxsize = CIELMOD8(twodxsize); //just make sure we don't run into unallocated memory while encrypting + + tdx = malloc(twodxsize); + memset(tdx, 0, twodxsize); + + //twodxsize = oldsize; + firstwav = TWODXHSIZE + wavcount*4; + + memcpy(tdx + 16, &firstwav, 4); //first wave position = 2dx header + size of TOC (= 72 + wavcount * sizeof(int)) + memcpy(tdx + 20, &wavcount, 4); //the total numbers of waves + + //write the ToC + printf("writing sample TOC...", firstwav); + j = firstwav; + for(i = 0; i < wavcount; i++) + { + //printf("%d...", j); + memcpy(tdx+TWODXHSIZE+i*4, &j, 4); + j += waves[i].length + WAVHSIZE; + } + + //write the waves + printf("writing keysounds (%d in all)...\n", wavcount); + j = firstwav; + for(i = 0; i < wavcount; i++) + { + //printf("%d...", waves[i].length); + memcpy(tdx+j, wavheader, 24); //write the header + memcpy(tdx+j+8, &waves[i].length, 4); //write the length + memcpy(tdx+j+24, waves[i].data, waves[i].length); + j += WAVHSIZE + waves[i].length; + } + //printf("twodxsize: %d\n", twodxsize); + //PNEWLINE; +} + + +//actually write the stuff to disk +void writeout_2dx() +{ + FILE *out; + + printf("writing output.2dx to disk\n"); + + /*out = fopen("decrypted.2dx", "wb"); + + //fflush(out); + + fwrite(tdx, twodxsize, 1, out); + + fclose(out);*/ + + out = fopen("output.2dx", "wb"); + fwrite(tdx_enc, twodxsize+8, 1, out); + fclose(out); + +} diff --git a/iidx/bme2ac/0.7/bme2ac.c b/iidx/bme2ac/0.7/bme2ac.c new file mode 100755 index 0000000..d366b8b --- /dev/null +++ b/iidx/bme2ac/0.7/bme2ac.c @@ -0,0 +1,127 @@ +//bme2ac by ryuuou +//takes a bunch of bms/bme files and produces .2dx and .1 files (hopefully) usable with beatmania iidx ac +//!!!WARNING!!! THIS WILL PROBABLY FAIL HORRIBLY ON 64BIT PLATFORMS!!! Then again it might just work + +//still unsupported: +// - songs with missing wav files? + + +//Changelog: +// v0.7 +// - chargenote support for Sirius +// - speedups +// v0.6 +// - greater accuracy in case of many bpm changes +// - proper longnote handling support (both channel and lnobj) +// v0.5 +// - partial support for freezenotes +// v0.4 +// - speedups +// - implemented #STOP events (_NOT_ #STP events!) +// - fixed a potential problem with fractional bpm +// - fixed a bug with file names that have '#' in them +// - the measure line of the last measure wasn't written out correctly +// - nixed decrypted.2dx; encrypted.2dx -> output.2dx +// - songs now end 3 seconds after the end of the last measure +// - added several tools: +// create2dx_new, crack2dx_new, timebase_single, encrypt2dx, merge1, parse1; with sources +// v0.3 +// - killed debug output +// - standard events are now written after bpm corrections to avoid screwing with the end-song event +// - keysound preload events are now dynamic and always placed between keys; this should fix wrong keysounds on fast repeats once and for all +// v0.2 +// - implemented bpm changes +// - implemented changing measure sizes, this should fix a lot of offsync songs +// v0.1 +// - initial release + + +#include "common.h" + +#include "bms.h" +#include "wav.h" +#include "2dx.h" +#include "crypt.h" +#include "1.h" +#include + +//initialize stuff, set things to zero etc. +void init() +{ + memset(bms, 0, sizeof(bmsfile)*CHARTCOUNT); + memset(waves, 0, sizeof(WAVE)*MAXWAVS*CHARTCOUNT); + + memset(onecharts, 0, sizeof(event*)*CHARTCOUNT); + + wavcount = 0; + wavlen = 0; + onesize = 0; + onefile = NULL; + + twodxsize = 0; + + style = 0; //standard = troopers + return; +} + +int main() +{ + init(); + + printf("bme2ac v0.7 by ryuuou\n \ + Converts BME/BMS style files and WAVs into .1 and .2dx files\n\ + Suitable for use with beatmania IIDX TROOPERS AC and up _only_\n\n\n"); + + if(!readbmsfiles()) + { + printf("found no charts, aborting\n"); + getchar(); + return 1; + } + + parsebms(); + + /*parsebms_bpm(); + parsebms_measures(); + parsebms_stops();*/ + create_wavtable(); + if(load_waves()) + { + printf("!!!Several wave files failed to load, IIDX might crash!!!\npress enter to continue\n"); + getchar(); + //return 1; + } + + convert_to_1_events(); + + stretch_times(100.); //for greater accuracy in case of many bpm changes + adjust_bpm(); + stretch_times(1./100.); + //note: we still have inaccuracy of 1ms while converting from bms, but there's nothing we can do about that + + add_standard_events(); + + add_stop_events(); //we need at least one bpm event for calculations + handle_longnotes(); + add_keysounds(); + cleanup_1(); + + //stretch_times(FPS_DD/1000.); //for DistorteD to Happy Sky + //stretch_times(FPS_GOLD/1000.); //for GOLD + + create_1(); + + create_2dx(); + encrypt_2dx(tdx, twodxsize, &tdx_enc); + + writeout_1(); + writeout_2dx(); + + if(twodxsize > 25000000) + printf("!!!.2dx file is larger than 25,000,000 bytes, IIDX will crash trying to load it!!!\n"); + + printf("\nDone. Press enter to exit.\n"); + getchar(); + return 0; +} + diff --git a/iidx/bme2ac/0.7/bms.h b/iidx/bme2ac/0.7/bms.h new file mode 100755 index 0000000..d91f532 --- /dev/null +++ b/iidx/bme2ac/0.7/bms.h @@ -0,0 +1,146 @@ +//bms.h +//stuff for .bms/.bme processing + +//searches *bms for stuff +//WARNING: this is very intolerant concerning capitalization and trailing whitespaces! + +#define BMS_MSIZE 2 + +typedef struct +{ + int length; //length of the data + byte* data; + unsigned char wavnames[MAXWAVS][64]; //names of the wavfiles + int ref[MAXWAVS]; //used for crossreferencing samples across different bms files + float bpmchange[MAXWAVS]; //bms change array + int bpmchangecount; + float msize[999]; //measure sizes + int mcount; //highest measure count + float bpm; //initial bpm + float stops[MAXWAVS]; //stop event array + int stopcount; + int lnobj; //lnobj index + int numwaves; //number of samples + int numkeys[2]; //keypresscount for player 1 and 2 +} bmsfile; + +bmsfile bms[CHARTCOUNT]; //one bme for each chart + +//attempt to read in the charts; returns the number of loaded charts +int readbmsfiles() +{ + int ret = 0; + int i; + FILE *f; + + printf("trying to open charts\n"); + for(i = 0; i < CHARTCOUNT; i++) + { + printf("%s...", BMENAMES[i]); + f = fopen(BMENAMES[i], "rb"); + + if(f == NULL) + { + printf("not found\n"); + continue; + } + + ret++; //we got a chart, yay + + fseek(f, 0, SEEK_END); + bms[i].length = (int)ftell(f); + fseek(f, 0, SEEK_SET); + + bms[i].data = malloc(bms[i].length + 32); //safety bytes + memset(bms[i].data, 0, bms[i].length + 32); + + fread(bms[i].data, bms[i].length, 1, f); + fclose(f); + + printf("OK\n"); + } + PNEWLINE; +} + +//parses the bms files for data needed to build the timeline, sample index and other stuff +void parsebms() +{ + int i,j,k,l; + char *data; + int measure, channel; + byte measure_c[4]; + + printf("parsing bms..."); + for(i = 0; i < CHARTCOUNT; i++) + { + if(bms[i].length == 0) + continue; + + data = bms[i].data; + + for(k = 0; k < bms[i].length; k++) + { + l = 0; + + //wavefile names + if(data[k] == '#' && data[k+1] == 'W' && data[k+2] == 'A' && data[k+3] == 'V') + { + j = strtoi(data+k+4) - 1; + k += 7; //skip to the filename (after "#WAVxy ") + while((data[k+l] != '\n') && (data[k+l] != '\r') && k+l < bms[i].length) //CR or LF + l++; //count the length of the filename + memcpy(bms[i].wavnames[j], data+k, l); //copy the wavename + bms[i].numwaves++; + } + //bpm data "#BPM xx" + else if(data[k] == '#' && data[k+1] == 'B' && data[k+2] == 'P' && data[k+3] == 'M' && data[k+4] == ' ') + { + k += 5; + sscanf((const char*)(data+k), "%f", &bms[i].bpm); + } + //bpm data "BPMyy xx" + else if(data[k] == '#' && data[k+1] == 'B' && data[k+2] == 'P' && data[k+3] == 'M' && data[k+4] != ' ') + { + j = strtoi(data+k+4) - 1; + k += 7; + sscanf((const char*)(data+k), "%f", &bms[i].bpmchange[j]); + bms[i].bpmchangecount++; + } + //measure data + else if(data[k] == '#' && data[k+6] == ':') + { + measure_c[0] = data[k+1]; + measure_c[1] = data[k+2]; + measure_c[2] = data[k+3]; + sscanf(measure_c, "%d", &measure); + bms[i].msize[measure] = 1.; //default measure size + + //keep track of the highest measure count for later + if(measure > bms[i].mcount) bms[i].mcount = measure; + + //measure length + sscanf(data+k+4, "%d", &channel); + if(channel == BMS_MSIZE) + { + sscanf((const char*)(data+k+7), "%f", &bms[i].msize[measure]); //read in the new measure size + } + } + //stop data + else if(data[k] == '#' && data[k+1] == 'S' && data[k+2] == 'T' && data[k+3] == 'O' && data[k+4] == 'P') + { + j = strtoi(data+k+5) - 1; + k += 7; + sscanf((const char*)(data+k), "%f", &bms[i].stops[j]); + bms[i].stopcount++; + } + //lnobj data + else if(data[k] == '#' && data[k+1] == 'L' && data[k+2] == 'N' && data[k+3] == 'O' && data[k+4] == 'B' && data[k+5] == 'J') + { + k += 7; + bms[i].lnobj = strtoi(data+k); + } + } + printf("%s...", CHARTNAMES[i]); + } + PNEWLINE; +} \ No newline at end of file diff --git a/iidx/bme2ac/0.7/common.h b/iidx/bme2ac/0.7/common.h new file mode 100755 index 0000000..fbab33e --- /dev/null +++ b/iidx/bme2ac/0.7/common.h @@ -0,0 +1,65 @@ +//common.h + + +#include +#include +#include +#include + + +#define MAXWAVS (36*36-1) //wav files from 01-0A-0Z-10-ZZ (you get it) = 36*36 - 1 +#define CHARTCOUNT 7 //beginner + (normal,hyper,another times two), what about kaiden in gold cs? + +#define PNEWLINE printf("\n") //used too often + +#define CIELMOD8(a) (!(a%8)?(a):((a)+(8-(a)%8))) //rounds (a) up to the next mod 8 int + +typedef unsigned char byte; + +//chartorder inside .1 file: h7, n7, a7, b, h14, n14, a14 +const char *BMENAMES[] = { "h7.bme", "n7.bme", "a7.bme", "b.bme", "h14.bme", "n14.bme", "a14.bme" }; //we use constant filenames here for ease of coding/use +const char *CHARTNAMES[] = { "h7", "n7", "a7", "b", "h14", "n14", "a14" }; +int style; //produce files for this iidx version; 0 == Troopers, 1 == GOLD, 2 == DistorteD and Happy Sky +float factor; //us this factor to strech .1 event time indices (based on version); 1 for Troopers, FPS/1000 for everything else + + +//helper functions for BME numbering weirdness; +//converts a number to a 01-ZZ style string and places that in the first two bytes of str +inline void itostr(char *str, int i) +{ + str[0] = i / 36; //works because this floors + if(str[0] > 9) + str[0] += 7; //there's a gap of 8 characters between '9' and 'A' + str[0] += 48; //fancy charactermap magic + + str[1] = i % 36; //mod operator = <3 + if(str[1] > 9) + str[1] += 7; + str[1] += 48; +} + +//the above in inverse; convert a BME-style numbering to int. +//stupidly tries to convert the first two bytes of *str +inline int strtoi(char *str) +{ + char conv[3]; + int ret; + conv[0] = str[0]; + conv[1] = str[1]; + conv[2] = '\0'; + ret = strtol(conv, 0, 36); + return ret; +} + + +//does the same as the above but converts from hex instead +inline int strtoi_h(char *str) +{ + char conv[3]; + int ret; + conv[0] = str[0]; + conv[1] = str[1]; + conv[2] = '\0'; + ret = strtol(conv, 0, 16); + return ret; +} diff --git a/iidx/bme2ac/0.7/crypt.h b/iidx/bme2ac/0.7/crypt.h new file mode 100755 index 0000000..c467e40 --- /dev/null +++ b/iidx/bme2ac/0.7/crypt.h @@ -0,0 +1,207 @@ + +//crypt.h +//code for encrypting .2dx files with DistorteD's algorithm/key + +//apparently konami's internal implementation of this doesn't do proper boundchecking and also doesn't zero its buffers, so there is some garbage left behind in the original files + +//format of encrypted .2dx file: +//header: +//4 bytes: identifier ("%e12" in case of distorted) +//4 bytes: length of the decrypted .2dx file +//after this follows the encrypted data + + +#define byte unsigned char + +byte keys_09[] = { //9th style + 0x97, 0x1E, 0x24, 0xA0, 0x9A, 0x00, 0x10, 0x2B, + 0x91, 0xEF, 0xD7, 0x7A, 0xCD, 0x11, 0xAF, 0xAF, + 0x8D, 0x26, 0x5D, 0xBB, 0xE0, 0xC6, 0x1B, 0x2B }; + +byte keys_10[] = { //10th style + 0x2D, 0x86, 0x56, 0x62, 0xD7, 0xFD, 0xCA, 0xA4, + 0xB3, 0x24, 0x60, 0x26, 0x24, 0x81, 0xDB, 0xC2, + 0x57, 0xB1, 0x74, 0x6F, 0xA7, 0x52, 0x99, 0x21 }; + +byte keys_11[] = { //Happy Sky+ + 0xED, 0xF0, 0x9C, 0x90, 0x44, 0x1A, 0x5A, 0x03, + 0xAB, 0x07, 0xC1, 0x99, 0x23, 0x24, 0x32, 0xC7, + 0x5F, 0x32, 0xA5, 0x97, 0xAD, 0x98, 0x0F, 0x8F }; + +byte keys_16[] = { //empress + 0x28, 0x22, 0x28, 0x54, 0x63, 0x3F, 0x0E, 0x42, + 0x6F, 0x45, 0x4E, 0x50, 0x67, 0x53, 0x61, 0x7C, + 0x04, 0x46, 0x00, 0x3B, 0x13, 0x2B, 0x45, 0x6A }; + +byte cryptkey[8] = { 0xED, 0xF0, 0x9C, 0x90, 0x44, 0x1A, 0x5A, 0x03 }; //DistorteD'S encryption key + +//XORs two 8 byte blocks +inline void block_xor(byte *data, byte *parm) +{ + int i; + for (i = 0 ; i < 8 ; i++) + data[i] ^= parm[i]; + return; +} + +//Swaps the lower 4 bytes with the upper 4 bytes +inline void block_swap(byte *data) +{ + int i; + for (i = 0 ; i < 4 ; i++) + { + data[i] ^= data[i+4]; //let's do this without temp variables ;D + data[i+4] ^= data[i]; + data[i] ^= data[i+4]; + } + return; +} + +//I bow to whoever figured this one out +inline void block_obfus(byte *data) +{ + byte a,b,c,d,e,f,g,h,i; + + a = data[0] * 63; + b = a + data[3]; + c = data[1] * 17; + d = c + data[2]; + e = d + b; + f = e * data[3]; + g = f + b + 51; + h = b ^ d; + i = g ^ e; + + data[4] ^= h; + data[5] ^= d; + data[6] ^= i; + data[7] ^= g; + + return; +} + +//encrypts the .2dx file; this simply takes the reverse way from crack2dx.c by an unknown author (QQQ again, but HOLY SHIT that code is a mess (and buggy)) +int encrypt_2dx(byte *dec, int len, byte **enc) +{ + byte *cur; //current block of 8 bytes + int enclen; + + int i; + + //ciel to mod 8; + + enclen = len + 8; //length of the encoded 2dx = length of unencoded 2dx + headersize (8 bytes) + + if(enclen%8) + enclen += 8-enclen%8; + + *enc = malloc(enclen); + memset(*enc, 0, enclen); + memcpy(*enc+8, dec, len); //fill up the encoded array with unencoded stuff + + printf("encrypting .2dx file...\n"); + for(i = 8; i <= enclen - 8; i+=8) //encode in blocks of 8 bytes, start at byte 8 of data + { + cur = *enc+i; + + //Step 1: XOR the current block with the encrypted previous block + block_xor(cur, cur-8); + + //Step 2: Swap the lower and upper 4 bytes of the block + block_swap(cur); + + //Step 3: Further obfuscation with XOR; the lower 4 bytes are untouched, so encrypting works the same as decrypting + block_obfus(cur); + + //Step 4: XOR the block (yet again) with DistorteD's key + block_xor(cur, keys_11); + } + + memcpy(*enc, "%hid", 4); //encryption identifier (Troopers) + + memcpy(*enc+4, &len, 4); //write the length of the decoded 2dx file + + return enclen; +} + +int decrypt_2dx(byte *enc, byte **dec) +{ + int i; + int mult; + int len; + byte *buf; + byte *cur, *prev; + byte *cryptkey; + + buf = enc; + + //identify iidx version + + mult = 1; + if(!strncmp(buf, "%eNc", 4)) + { + cryptkey = keys_09; //9th style + } + else if(!strncmp(buf, "%e10", 4)) + { + cryptkey = keys_10; //10th style + } + else if(!strncmp(buf, "%e11", 4)) + { + cryptkey = keys_11; //RED + } + else if(!strncmp(buf, "%e12", 4)) + { + cryptkey = keys_11; //HS+ + mult = 0; + } + else if(!strncmp(buf, "%hid", 4)) + { + cryptkey = keys_11; //Troopers + mult = 0; + } + else if(!strncmp(buf, "%iO0", 4)) + { + cryptkey = keys_16; //Empress + } + else + { + return -1; + } + + len = *((int*)(enc + 4)); + + if(len%8) + len += 8-len%8; + + + *dec = malloc(len); + //decrypt + + if(!(mult == 2)) //skip for unencrypted + { + memcpy(*dec, buf+8, len-8); //copy the encrypted part + memset(buf, 0, 8); //zero the first block to make the loop easier + + for(i = 0; i <= len-16; i+= 8) + { + cur = *dec + i; //cur points to the current encrypted block to decrypt + prev = buf + i; //prev points to the cur-8 in encrypted form + + block_xor(cur, cryptkey); + block_obfus(cur); + block_swap(cur); + + if(mult) // for versions prior to DistorteD and Empress + { + block_xor(cur, cryptkey+8); + block_obfus(cur); + block_xor(cur, cryptkey+16); + } + + block_xor(cur, prev); + } + } + + return len; +} \ No newline at end of file diff --git a/iidx/bme2ac/0.7/wav.h b/iidx/bme2ac/0.7/wav.h new file mode 100755 index 0000000..932d5e2 --- /dev/null +++ b/iidx/bme2ac/0.7/wav.h @@ -0,0 +1,103 @@ +//wav.h +//deals with stuff like reading wavfiles and stuff and such stuff + +typedef struct +{ + int length; + char *data; + char *name; +} WAVE; + +WAVE waves[MAXWAVS*CHARTCOUNT]; //wasteful but safe, whatever... +int wavcount; //stores the number of wavefiles to be used in the 2dx file +int wavlen; //stores the sum of length all wavefiles we have loaded + +//this fills up "waves" while eliminating duplicates across bme files. while doing so it fills up the bms's structs reference array like this: +//for any bms[i].ref[j], j+1 is the index inside the bme file while ref[j] contains the index which will be used in the .2dx and .1 files +//TODO: What do we do when files are (intentionally?) missing? needs investigation on what 2dx does with 0-byte waves... +void create_wavtable() +{ + int i,j,k; + int dup = 0; + + printf("building wave index.."); + for(i = 0; i < CHARTCOUNT; i++) + { + if(!bms[i].numwaves) continue; //no waves, no fun + + printf("%s...", CHARTNAMES[i]); + + for(j = 0; j < MAXWAVS; j++) + { + if(bms[i].wavnames[j][0] != 0) //a wave to load + { + //now check if we've found a wavefile with the same name before to avoid duplicates + for(k = 0; k < wavcount; k++) + { + if(!strcmp(waves[k].name, bms[i].wavnames[j])) + { + dup = 1; //this is a duplicate + //printf("dup(%d,%d %s == %s)\n", j, k, waves[k].name, bms[i].wavnames[j]); + break; + } + } + + if(dup) + { + bms[i].ref[j] = k+1; //save the reference for later use + //printf("%s (%d)\n", bms[i].wavnames[j], k); + dup = 0; + } + else //this is a new wavefile + { + wavcount++; //iidx starts counting samples at _1_, not 0 + bms[i].ref[j] = wavcount; //save the reference + waves[wavcount-1].name = bms[i].wavnames[j]; //remember decem^H^H^H^H^H the name of the ga..(ry + //printf("load(%d,%d %s)\n", j, wavcount, waves[wavcount-1].name); + } + } + } + } + printf("added %d wave files to table\n", wavcount); + return; +} + + +//actually load the wave files +int load_waves() +{ + int i, fail=0; + FILE *f; + + printf("loading wave files..."); + for(i = 0; i < wavcount; i++) + { + f = fopen(waves[i].name, "rb"); + if(f == NULL) + { + if(!fail) + printf("failed to load waves:\n"); + //printf("wav referenced but not found: %s\n", waves[i].name); + fail++; + printf("%s ", waves[i].name); + continue; + } + + fseek(f, 0, SEEK_END); + waves[i].length = (int)ftell(f); + fseek(f, 0, SEEK_SET); + + waves[i].data = malloc(waves[i].length); + + fread(waves[i].data, waves[i].length, 1, f); + + fclose(f); + //printf("loaded wave %s of length %d\n", waves[i].name, waves[i].length); + } + if(fail) + printf("\nout of %d wave files, %d were not found\n", wavcount, fail); + else + printf("all waves loaded successfully\n"); + PNEWLINE; + return fail; +} diff --git a/iidx/bme2ac/old/checkeout.c b/iidx/bme2ac/old/checkeout.c new file mode 100644 index 0000000..b28f06e --- /dev/null +++ b/iidx/bme2ac/old/checkeout.c @@ -0,0 +1,279 @@ +#define byte unsigned char + +#include +#include +#include +#include "crypt.h" + +typedef struct +{ + byte iidx[4]; + int version; + short int songcount; + short int indexcount; + int zero; +} eoutheader; + +typedef struct +{ + byte songname[64]; + byte labelname[32]; //filename + byte titlename[64]; //filename + byte genrename[32]; //filename + byte artistname[32]; //filename + + short int style; + short int sort_others; + short int sort_bemani; + short int sort_bemani2; + + byte diff_n7; + byte diff_h7; + byte diff_a7; + byte diff_n14; + byte diff_h14; + byte diff_a14; + byte diff_beg; + byte diff_ex; + + byte zeros[128]; + byte FF[20]; + + int index; + int volume; + + char suffix[8]; + + int movieoffset; //used as temp var here + byte moviefile[32]; + + byte bgname[32]; + byte graphicsfolder[32]; + + int layerinfo; + byte layerdata[9*32]; +} songinfo; + +typedef struct +{ + int offh7; + int lenh7; + int offn7; + int lenn7; + int offa7; + int lena7; + int offb; + int lenb; + int offex1; + int lenex1; + int offex2; + int lenex2; + int offh14; + int lenh14; + int offn14; + int lenn14; + int offa14; + int lena14; +} oneheader; + +eoutheader ehead; +songinfo cursong; +unsigned short int judgements[6] = {0xF0, 0xFA, 0xFF, 0x3, 0x8, 0x12}; + +#define PRINTW(a,b) if(warn) {printf("__: %d (%s) - ", cursong.index, cursong.songname);printf(a,b);} +#define PRINTA(a,b) if(warn) {printf("**: %d (%s) - ", cursong.index, cursong.songname);printf(a,b);} +#define PRINTE(a,b) if(err) {printf("!!: %d (%s) - ", cursong.index, cursong.songname);printf(a,b);} + +int main(int argc, char* argv[]) +{ + FILE *eout, *one, *tdx, *movie; + char file[60]; + char onepart[2], prev, *diff; + oneheader onehead; + int warn, err; + int k, i, l, songcount; + int tdxlen; + byte *enc, *dec; + short int fmt; + int pos, wavcount, wavlen; + + if(argc < 2) + { + printf("checkeout \n\tlevel: v = errors only\n\tvv = warnings only\n\t(default) = errors and warnings"); + return 0; + } + + warn = err = 1; + + if(argc > 2) + { + if(!strcmp(argv[2], "vv")) + err = 0; + else if(!strcmp(argv[2], "v")) + warn = 0; + } + + //warn=err=0; + eout = fopen(argv[1], "rb"); + + if(!eout) + { + printf("could not find %s, aborting\n", argv[1]); + return 0; + } + + fread(&ehead, sizeof(eoutheader), 1, eout); + + if(strncmp(ehead.iidx, "IIDX", 4)) + { + printf("%s is not a decrypted eout.bin file, aborting\n", argv[1]); + return -1; + } + + fseek(eout, sizeof(eoutheader) + ehead.indexcount*2, SEEK_SET); + + songcount = 0; + + //while(!feof(eout)) + for(k = 0; k < ehead.songcount; k++) + { + fread(&cursong, sizeof(songinfo), 1, eout); + songcount++; + //printf("ID: %d\tNAME: %s || %d\n", cursong.index, cursong.songname, cursong.style); + + //check for movie file + sprintf(file, "movie/%s.4", cursong.moviefile); + if(!(movie = fopen(file, "rb"))) + {PRINTW("moviefile not found: %s\n", file)} + else + fclose(movie); + + //check mendatory difficulties + if(!cursong.diff_h7) + {PRINTE("song has no hyper7 chart\n", NULL)} + + if(!cursong.diff_h14) + {PRINTE("song has no hyper14 chart\n", NULL)} + + //check .1 files + sprintf(file, "sd_data/%04d/%04d.1", cursong.index, cursong.index); + printf("checking %s (%d)...\n", file, k); + if(!(one = fopen(file, "rb"))) + {PRINTE(".1 file not found: %s\n", file)} + else + { + //check if difficulties are availible + fread(&onehead, sizeof(onehead), 1, one); + fclose(one); + + if(cursong.diff_n7 && !onehead.offn7) + PRINTE("referenced n7 (%d) chart not found in .1 file\n", cursong.diff_n7) + if(cursong.diff_h7 && !onehead.offh7) + PRINTE("referenced h7 (%d) chart not found in .1 file\n", cursong.diff_h7) + if(cursong.diff_a7 && !onehead.offa7) + PRINTE("referenced a7 (%d) chart not found in .1 file\n", cursong.diff_a7) + if(cursong.diff_n14 && !onehead.offn14) + PRINTE("referenced n14 (%d) chart not found in .1 file\n", cursong.diff_n14) + if(cursong.diff_h14 && !onehead.offh14) + PRINTE("referenced h14 (%d) chart not found in .1 file\n", cursong.diff_h14) + if(cursong.diff_a14 && !onehead.offa14) + PRINTE("referenced a14 (%d) chart not found in .1 file\n", cursong.diff_a14) + if(cursong.diff_beg && !onehead.offb) + PRINTE("referenced beg (%d) chart not found in .1 file\n", cursong.diff_beg) + if(cursong.diff_ex && !onehead.offex1) + PRINTE("referenced ex (%d) chart not found in .1 file\n", cursong.diff_ex) + + if(!cursong.diff_n7 && onehead.offn7) + PRINTW("unreferenced n7 chart in .1 file\n", NULL) + if(!cursong.diff_h7 && onehead.offh7) + PRINTW("unreferenced h7 chart in .1 file\n", NULL) + if(!cursong.diff_a7 && onehead.offa7) + PRINTW("unreferenced a7 chart in .1 file\n", NULL) + if(!cursong.diff_n14 && onehead.offn14) + PRINTW("unreferenced n14 chart in .1 file\n", NULL) + if(!cursong.diff_h14 && onehead.offh14) + PRINTW("unreferenced h14 chart in .1 file\n", NULL) + if(!cursong.diff_a14 && onehead.offa14) + PRINTW("unreferenced a14 chart in .1 file\n", NULL) + if(!cursong.diff_beg && onehead.offb) + PRINTW("unreferenced beg chart in .1 file\n", NULL) + if(!cursong.diff_ex && onehead.offex1) + PRINTA("unreferenced ex chart in .1 file\n", NULL) + + if(cursong.diff_ex) + PRINTA("ex chart (%d) in eout\n", cursong.diff_ex) + if(onehead.offex1) + PRINTA("ex1 chart in .1 file\n", NULL) + if(onehead.offex2) + PRINTA("ex2 chart in .1 file\n", NULL) + + //todo: .1 file sanity check? + } + + + //check .2dx files + onepart[0] = prev = 0xFF; + onepart[1] = '\0'; + diff = &cursong.diff_n7; + + for(i = 0; i <= 7; i++) + { + if(!diff[i]) + continue; + if(prev == cursong.suffix[i]) + continue; + else + onepart[0] = prev = cursong.suffix[i]; + + if(onepart[0] == '0') + onepart[0] = '\0'; + + sprintf(file, "sd_data/%04d/%04d%s.2dx", cursong.index, cursong.index, onepart); + //printf("checking %s (%d)...\n", file, k); + if(!(tdx = fopen(file, "rb"))) + {PRINTE(".2dx file not found: %s\n", file)} + else + { + //printf("decoding: %s...", file); + fseek(tdx, 0, SEEK_END); + tdxlen = (int)ftell(tdx); + if(tdxlen > 25000000) + {PRINTE("%s larger than 25,000,000 bytes\n", file)} + rewind(tdx); + enc = malloc(tdxlen); + fread(enc, 1, tdxlen, tdx); + fclose(tdx); + decrypt_2dx(enc, &dec); + //printf("done\n"); + memcpy(&wavcount, dec + 20, 4); + pos = 72; + + for(l=0; l < wavcount-1; l++) + { + memcpy(&fmt, dec + *((int*)(dec+pos)) + 24 + 20, 2); + memcpy(&wavlen, dec + *((int*)(dec+pos)) + 8, 4); + pos += 4; + //printf("(%d %d %d)\n", wavcount, pos, *((int*)(dec+pos))); + /*if(wavlen == 0) + { + {PRINTE("%s has 0-length wav files\n", file)} + break; + } + if(fmt != 2) + { + {PRINTE("%s has unconverted wav files\n", file)} + break; + }*/ + } + free(enc); + free(dec); + } + } + } + + printf("songcount: %d", songcount); + + getchar(); + + return 0; +} diff --git a/iidx/bme2ac/old/create2dx_cs2emp.c b/iidx/bme2ac/old/create2dx_cs2emp.c new file mode 100644 index 0000000..80622f0 --- /dev/null +++ b/iidx/bme2ac/old/create2dx_cs2emp.c @@ -0,0 +1,254 @@ +//create2dx_dumb.c by ryuuou +//Authoring the 2dx file is based on create2dx.c by Kitaru +//Encrypting is taking the reverse way from crack2dx.c by some unknown author (at least to me) +//Packs BME-style sequenced .wav (01.wav to ZZ.wav, but should work with BMS-style 01 - FF as well) in the current folder +//into an unencrypted unencrypted.2dx and an DistorteD-style encrypted encrypted.2dx +//Takes no arguments and always outputs to the same files; only works with uppercase on unix but should work with lowercase on windows; +//We also assume that the ascending order or the wavefiles equals their order in the corresponding bme/bms file +//...hence "_dumb" + + +#include +#include +#include + +//wav files from 01-0A-0Z-10-ZZ (you get it) = 36*36 - 1 +#define MAXWAVS (36*36-1) + +#define CIELMOD8(a) (!(a%8)?(a):((a)+(8-(a)%8))) + +typedef unsigned char byte; + +typedef struct{ + int length; + byte *data; + int offset; +} wavefile; + +const byte aftertoc[24] = { + '2', 'D', 'X', '9', //const string + 0x18, 0x00, 0x00, 0x00, //headersize (== 24) + 0x00, 0x00, 0x00, 0x00, //size of wave file (written at runtime) + 0x30, 0x32, 0xFF, 0xFF, //panning/initial volume? + 0x40, 0x00, 0x08, 0x00, //??? (64, 0, 8, 0) + 0x00, 0x00, 0x00, 0x00 //??? (0, 0, 0, 0) +}; + + +//helper function for BME numbering weirdness; +//converts a number to a 01-ZZ style string +char *itostr(int i) +{ + char *str; + + str = malloc(3); + + str[0] = i / 36; //works because this floors + if(str[0] > 9) + str[0] += 7; //there's a gap of 8 characters between '9' and 'A' + str[0] += 48; //fancy charactermap magic + + str[1] = i % 36; //mod operator = <3 + if(str[1] > 9) + str[1] += 7; + str[1] += 48; + + str[2] = '\0'; + + return str; +} + +/// +/// encryption related +/// + +byte cryptkey[] = { //empress + 0x28, 0x22, 0x28, 0x54, 0x63, 0x3F, 0x0E, 0x42, + 0x6F, 0x45, 0x4E, 0x50, 0x67, 0x53, 0x61, 0x7C, + 0x04, 0x46, 0x00, 0x3B, 0x13, 0x2B, 0x45, 0x6A }; + +//XORs two 8 byte blocks +void block_xor(byte *data, byte *parm) +{ + int i; + for (i = 0 ; i < 8 ; i++) + data[i] ^= parm[i]; + return; +} + +//Swaps the lower 4 bytes with the upper 4 bytes +void block_swap(byte *data) +{ + int i; + for (i = 0 ; i < 4 ; i++) + { + data[i] ^= data[i+4]; //let's do this without temp variables ;D + data[i+4] ^= data[i]; + data[i] ^= data[i+4]; + } + return; +} + +//I bow to whoever figured this one out +void block_obfus(byte *data) +{ + byte a,b,c,d,e,f,g,h,i; + + a = data[0] * 63; + b = a + data[3]; + c = data[1] * 17; + d = c + data[2]; + e = d + b; + f = e * data[3]; + g = f + b + 51; + h = b ^ d; + i = g ^ e; + + data[4] ^= h; + data[5] ^= d; + data[6] ^= i; + data[7] ^= g; + + return; +} + +//Encrypts length bytes of inc and returns a pointer to the encoded array +byte *encrypt(byte *inc, int length) +{ + byte *data; + byte *cur; //current block of 8 bytes + + int i, enclen; + + enclen = 8 + CIELMOD8(length); //let's just make sure we're not running into uninitialized memory while encrypting + data = malloc(enclen); + + memset(data, 0, enclen); + memcpy(data+8, inc, length); //fill up the encoded array with unencoded stuff + + + for(i = 8; i <= enclen-8; i+=8) //encode in blocks of 8 bytes, start at byte 8 of data + { + cur = data+i; + + block_xor(cur, cur-8); + block_xor(cur, cryptkey+16); + block_obfus(cur); + block_xor(cur, cryptkey+8); + block_swap(cur); + block_obfus(cur); + block_xor(cur, cryptkey); + } + + memcpy(data, "%iO0", 4); //encryption identifier + enclen -= 8; + memcpy(data+4, &enclen, 4); //write the length of the decoded 2dx file + return data; +} + +int main(int argc, const char **argv) +{ + wavefile waves[MAXWAVS]; + + FILE *wavfile; + FILE *out; + FILE *bmsfile; + + byte *decrypted, *encrypted, *bms; + + int wav = 0; //wavefile count + int pos = 0, i = 0, ii = 0, j, firstwav = 0, bmslength = 0, len = 0; + int length = 72; //use this to compute the final file length along the way (72 = 2dx headersize) + int prev, maxwav; + + char wavepath[32]; //helperstring; ugly but works + + int bmestyle = 0; + memset(waves, 0, MAXWAVS*sizeof(wavefile)); + + printf("reading samples..."); + for(i = 1; i <= MAXWAVS; i++) //this is really inefficient but works, meh + { + if(bmestyle == 0) + { + sprintf(wavepath, "%s.wav", itostr(i)); + } + else if(bmestyle == 1) + { + sprintf(wavepath, "%d.wav", i); + } + + wavfile = fopen(wavepath, "rb"); + + if (wavfile != NULL) + { + //open the wave file and save its length and contents to the array + printf("%s...",wavepath); + fseek(wavfile, 0, SEEK_END); + waves[i-1].length = (int)ftell(wavfile); + fseek(wavfile, 0, SEEK_SET); + + waves[i-1].data = malloc(waves[i-1].length); + + fread(waves[i-1].data, waves[i-1].length, 1, wavfile); + + fclose(wavfile); + wav++; + length += 4 + 24 + waves[i-1].length; //toc index + header + actual length + maxwav = i; + } + } + + if(wav == 0) //learn2placefilesindirectories + { + printf("no wave files found, go die in a fire\n"); + return 0; + } + printf("OK\n"); + printf("\ntotal samplecount: %d, actual wavcount in .2dx: %d\n\n",wav, maxwav); + + wav = maxwav; + + for(i = maxwav-2; i >= 0; i--) + { + if(waves[i].length == 0) + { + waves[i].data = waves[i+1].data; + waves[i].length = waves[i+1].length; + printf("added wav: %i, len %i\n", i, waves[i].length); + length += waves[i].length; + } + } + + + //start constructing the 2dx file + decrypted = malloc(length); + memset(decrypted, 0, length); + + firstwav = 72+wav*4; //ugly... + memcpy(decrypted + 16, &firstwav, 4); //first wave position = 2dx header + size of TOC (= 72 + wavecount * sizeof(int)) + memcpy(decrypted + 20, &wav, 4); //the total numbers of waves + + printf("writing samples..."); + pos = firstwav; + for(i = 0; i < maxwav; i++) + { + memcpy(decrypted+pos, aftertoc, 8); //"2DX9" + headersize (== 24) + memcpy(decrypted+pos+8, &waves[i].length, 4); //size of the wave + memcpy(decrypted+pos+12, aftertoc+12, 12); //rest of the header + memcpy(decrypted+pos+24, waves[i].data, waves[i].length); //write the actual wav + memcpy(decrypted+0x48+(i*4), &pos, 4); //write toc entry + pos += 24 + waves[i].length; + } + printf("OK\n"); + + printf("encrypting..."); + encrypted = encrypt(decrypted, length); + printf("OK\n"); + + out = fopen("output.2dx", "wb"); //open the 2dx file and write out the array + fwrite(encrypted, 8+CIELMOD8(length), 1, out); + fclose(out); + + return 0; +} diff --git a/iidx/bme2ac/old/crypt.h b/iidx/bme2ac/old/crypt.h new file mode 100644 index 0000000..a310e3b --- /dev/null +++ b/iidx/bme2ac/old/crypt.h @@ -0,0 +1,207 @@ + +//crypt.h +//code for encrypting .2dx files with DistorteD's algorithm/key + +//apparently konami's internal implementation of this doesn't do proper boundchecking and also doesn't zero its buffers, so there is some garbage left behind in the original files + +//format of encrypted .2dx file: +//header: +//4 bytes: identifier ("%e12" in case of distorted) +//4 bytes: length of the decrypted .2dx file +//after this follows the encrypted data + + +#define byte unsigned char + +byte keys_09[] = { //9th style + 0x97, 0x1E, 0x24, 0xA0, 0x9A, 0x00, 0x10, 0x2B, + 0x91, 0xEF, 0xD7, 0x7A, 0xCD, 0x11, 0xAF, 0xAF, + 0x8D, 0x26, 0x5D, 0xBB, 0xE0, 0xC6, 0x1B, 0x2B }; + +byte keys_10[] = { //10th style + 0x2D, 0x86, 0x56, 0x62, 0xD7, 0xFD, 0xCA, 0xA4, + 0xB3, 0x24, 0x60, 0x26, 0x24, 0x81, 0xDB, 0xC2, + 0x57, 0xB1, 0x74, 0x6F, 0xA7, 0x52, 0x99, 0x21 }; + +byte keys_11[] = { //Happy Sky+ + 0xED, 0xF0, 0x9C, 0x90, 0x44, 0x1A, 0x5A, 0x03, + 0xAB, 0x07, 0xC1, 0x99, 0x23, 0x24, 0x32, 0xC7, + 0x5F, 0x32, 0xA5, 0x97, 0xAD, 0x98, 0x0F, 0x8F }; + +byte keys_16[] = { //empress + 0x28, 0x22, 0x28, 0x54, 0x63, 0x3F, 0x0E, 0x42, + 0x6F, 0x45, 0x4E, 0x50, 0x67, 0x53, 0x61, 0x7C, + 0x04, 0x46, 0x00, 0x3B, 0x13, 0x2B, 0x45, 0x6A }; + +byte cryptkey[8] = { 0xED, 0xF0, 0x9C, 0x90, 0x44, 0x1A, 0x5A, 0x03 }; //DistorteD'S encryption key + +//XORs two 8 byte blocks +void block_xor(byte *data, byte *parm) +{ + int i; + for (i = 0 ; i < 8 ; i++) + data[i] ^= parm[i]; + return; +} + +//Swaps the lower 4 bytes with the upper 4 bytes +void block_swap(byte *data) +{ + int i; + for (i = 0 ; i < 4 ; i++) + { + data[i] ^= data[i+4]; //let's do this without temp variables ;D + data[i+4] ^= data[i]; + data[i] ^= data[i+4]; + } + return; +} + +//I bow to whoever figured this one out +void block_obfus(byte *data) +{ + byte a,b,c,d,e,f,g,h,i; + + a = data[0] * 63; + b = a + data[3]; + c = data[1] * 17; + d = c + data[2]; + e = d + b; + f = e * data[3]; + g = f + b + 51; + h = b ^ d; + i = g ^ e; + + data[4] ^= h; + data[5] ^= d; + data[6] ^= i; + data[7] ^= g; + + return; +} + +//encrypts the .2dx file; this simply takes the reverse way from crack2dx.c by an unknown author (QQQ again, but HOLY SHIT that code is a mess (and buggy)) +int encrypt_2dx(byte *dec, int len, byte **enc) +{ + byte *cur; //current block of 8 bytes + int enclen; + + int i; + + //ciel to mod 8; + + enclen = len + 8; //length of the encoded 2dx = length of unencoded 2dx + headersize (8 bytes) + + if(enclen%8) + enclen += 8-enclen%8; + + *enc = malloc(enclen); + memset(*enc, 0, enclen); + memcpy(*enc+8, dec, len); //fill up the encoded array with unencoded stuff + + printf("encrypting .2dx file...\n"); + for(i = 8; i <= enclen - 8; i+=8) //encode in blocks of 8 bytes, start at byte 8 of data + { + cur = *enc+i; + + //Step 1: XOR the current block with the encrypted previous block + block_xor(cur, cur-8); + + //Step 2: Swap the lower and upper 4 bytes of the block + block_swap(cur); + + //Step 3: Further obfuscation with XOR; the lower 4 bytes are untouched, so encrypting works the same as decrypting + block_obfus(cur); + + //Step 4: XOR the block (yet again) with DistorteD's key + block_xor(cur, keys_11); + } + + memcpy(*enc, "%hid", 4); //encryption identifier (Troopers) + + memcpy(*enc+4, &len, 4); //write the length of the decoded 2dx file + + return enclen; +} + +int decrypt_2dx(byte *enc, byte **dec) +{ + int i; + int mult; + int len; + byte *buf; + byte *cur, *prev; + byte *cryptkey; + + buf = enc; + + //identify iidx version + + mult = 1; + if(!strncmp(buf, "%eNc", 4)) + { + cryptkey = keys_09; //9th style + } + else if(!strncmp(buf, "%e10", 4)) + { + cryptkey = keys_10; //10th style + } + else if(!strncmp(buf, "%e11", 4)) + { + cryptkey = keys_11; //RED + } + else if(!strncmp(buf, "%e12", 4)) + { + cryptkey = keys_11; //HS+ + mult = 0; + } + else if(!strncmp(buf, "%hid", 4)) + { + cryptkey = keys_11; //Troopers + mult = 0; + } + else if(!strncmp(buf, "%iO0", 4)) + { + cryptkey = keys_16; //Empress + } + else + { + return -1; + } + + len = *((int*)(enc + 4)); + + if(len%8) + len += 8-len%8; + + + *dec = malloc(len); + //decrypt + + if(!(mult == 2)) //skip for unencrypted + { + memcpy(*dec, buf+8, len-8); //copy the encrypted part + memset(buf, 0, 8); //zero the first block to make the loop easier + + for(i = 0; i <= len-16; i+= 8) + { + cur = *dec + i; //cur points to the current encrypted block to decrypt + prev = buf + i; //prev points to the cur-8 in encrypted form + + block_xor(cur, cryptkey); + block_obfus(cur); + block_swap(cur); + + if(mult) // for versions prior to DistorteD and Empress + { + block_xor(cur, cryptkey+8); + block_obfus(cur); + block_xor(cur, cryptkey+16); + } + + block_xor(cur, prev); + } + } + + return len; +} \ No newline at end of file diff --git a/iidx/bme2ac/old/cs2ac v1.3.c b/iidx/bme2ac/old/cs2ac v1.3.c new file mode 100644 index 0000000..135df7b --- /dev/null +++ b/iidx/bme2ac/old/cs2ac v1.3.c @@ -0,0 +1,479 @@ +/* cs2ac by 697�—14 */ +/* + 09/05/22 v1.0 CS GOLD�ê—p”Å + 09/05/24 v1.1 CS DJT‚ɉ¼‘Ήž + 09/05/28 v1.2 ƒŠƒtƒ@ƒNƒ^ƒŠƒ“ƒO + 09/05/30 v1.3 CS DistorteDˆÈ‘O‚ɉ¼‘Ήž +*/ + + +/* �ì‹Æ‚È‚ª‚ç‚Ì‚ ‚ꂱ‚ê +/* + 0x07: 3rd style CS BGM autoplay + 0x0A: ??? style CS BGM autoplay + 0x82, 0x82: 3rd style CS ƒL�[‰¹•Ï�X? + ‹ŒCSƒo�[ƒWƒ‡ƒ“DP•ˆ–Ê�I—¹�錾ƒCƒxƒ“ƒgƒoƒO‘Ήž + BGMŽ©“®‰‰‘t�iindex==1�j‚ª•¡�””­“®‚³‚¹‚È‚¢ +*/ + +#include +#include +#include + +#define MAGNIA 16.71309 // 3rd style - 8th style +#define MAGNIB 16.68335 // 9th style - DJ TROOPERS + +#define NAMEMAX 32 + +double version = 1.3; + +FILE *in, *out; +int i_timeA; +double i_timeB; +int d_type; +int b_data[3]; +int t_notes[7]; // 0:SPN 1:SPH 2:SPA 3:SPB 4:DPN 5:DPN 6:DPA +int f_size[7]; // 0:SPN 1:SPH 2:SPA 3:SPB 4:DPN 5:DPN 6:DPA +int head_adrs; +int f_exist[7]; // 0:SPN 1:SPH 2:SPA 3:SPB 4:DPN 5:DPN 6:DPA +int filetype; +int t_base_type; +int maxwav; +char inName[NAMEMAX], + outName[NAMEMAX]; + +/* ƒwƒbƒ_�‘‚«Š·‚¦ */ +int headWritingUnit(int dif){ + int adrsA, adrsB; + + switch(dif) { + case 0: adrsA = 0x08; adrsB = 0x0c; break; // SPN + case 1: adrsA = 0x00; adrsB = 0x04; break; // SPH + case 2: adrsA = 0x10; adrsB = 0x14; break; // SPA + case 3: adrsA = 0x18; adrsB = 0x1c; break; // SPB + case 4: adrsA = 0x38; adrsB = 0x3c; break; // DPN + case 5: adrsA = 0x30; adrsB = 0x34; break; // DPH + case 6: adrsA = 0x40; adrsB = 0x44; break; // DPA + } + + fseek(out, adrsA, SEEK_SET); + fwrite(&head_adrs, 1, 4, out); + fseek(out, adrsB, SEEK_SET); + fwrite(&f_size[dif], 1, 4, out); + head_adrs += f_size[dif]; + + return 0; +} + +/* ƒf�[ƒ^�‘‚«�ž‚Ý */ +int dataWritingUnit(int dif){ + i_timeB = i_timeA; + switch(t_base_type){ + case 0: + i_timeB *= MAGNIA; + break; + case 1: + i_timeB *= MAGNIB; + break; + } + i_timeA = i_timeB; + fwrite(&i_timeA, 1, 4, out); + fwrite(&d_type, 1, 1, out); + fwrite(&b_data[0], 1, 1, out); + fwrite(&b_data[1], 1, 1, out); + fwrite(&b_data[2], 1, 1, out); + f_size[dif] += 8; + + return 0; +} + +int cs2ac(int dif){ + /* •Ï�”�Ý’è */ + int i; + int temp; + int dp_flag; + int rtm_flag = 0; + int start_flag = 0; + int wav01_auto = 0; + + /* �ˆ—�•”•ª */ + /* •Ï�”�‰Šú‰» */ + t_base_type = 0; + f_size[dif] = 0; + t_notes[dif] = 0; + + if(dif >= 4){ + dp_flag = 1; + } + else { + dp_flag = 0; + } + + fseek(out, head_adrs, SEEK_SET); + + /* ƒTƒuƒwƒbƒ_�‘‚«�ž‚Ý */ + /* [00 00 00 00 10 00 00 00][00 00 00 00 10 01 00 00] */ + temp = 0x00; + for(i=0;i<0x04;i++){ + fwrite(&temp, 1, 1, out); + } + temp = 0x10; + fwrite(&temp, 1, 1, out); + temp = 0x00; + for(i=0;i<0x07;i++){ + fwrite(&temp, 1, 1, out); + } + temp = 0x0110; + fwrite(&temp, 1, 2, out); + temp = 0x00; + for(i=0;i<0x02;i++){ + fwrite(&temp, 1, 1, out); + } + f_size[dif] += 16; + + /* •ˆ–Ê�I’[‚܂ŌJ‚è•Ô‚µ */ + while((d_type != 0x06)||((dp_flag != 2)&&(dp_flag != 5))) { + /* ƒf�[ƒ^�‰Šú‰» */ + i_timeA = 0x00; + d_type = 0x00; + b_data[0] = 0x00; + b_data[1] = 0x00; + b_data[2] = 0x00; + + /* ƒf�[ƒ^“Ç‚Ý�ž‚Ý */ + switch(filetype){ + case 1: case 2: // CS3(DJT,GOLD),CS(DistorteD - 7th style) + fread(&i_timeA, 1, 4, in); + fread(&d_type, 1, 1, in); + fread(&b_data[0], 1, 1, in); + fread(&b_data[1], 1, 1, in); + fread(&b_data[2], 1, 1, in); + break; + + case 3: // CS2 (6th style - 3rd style) + fread(&i_timeA, 1, 2, in); + fread(&d_type, 1, 1, in); + fread(&b_data[0], 1, 1, in); + b_data[1] = 0x00; + b_data[2] = 0x00; + break; + } + + //ˆê•”‚Ì‹ŒCSƒo�[ƒWƒ‡ƒ“•ˆ–ʃoƒO‘Ήž�iDP‚Ȃ̂É2P‚Ì•ˆ–Ê�I—¹�錾ƒCƒxƒ“ƒg‚ª‚È‚¢�j + if((short int)i_timeA == 0x7FFF && dp_flag == 3) + d_type = 0x06; + + /* ƒf�[ƒ^ƒ^ƒCƒv‚Å�U‚蕪‚¯ */ + switch(d_type) { + /* ƒm�[ƒgƒCƒxƒ“ƒg */ + case 0x00: case 0x10: case 0x20: case 0x30: case 0x40: case 0x50: case 0x60: case 0x70: + case 0x01: case 0x11: case 0x21: case 0x31: case 0x41: case 0x51: case 0x61: case 0x71: + if (start_flag == 0){ break; } + t_notes[dif]++; + + b_data[0] = d_type / 0x10; + d_type %= 0x10; + + dataWritingUnit(dif); + break; + + /* ƒL�[‰¹•Ï�X */ + case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52: case 0x62: case 0x72: + case 0x03: case 0x13: case 0x23: case 0x33: case 0x43: case 0x53: case 0x63: case 0x73: + switch(filetype){ + case 3: b_data[1] = b_data[0]; break; + } + if (maxwav < (b_data[2]*0x100 + b_data[1])){ + maxwav = b_data[2]*0x100 + b_data[1]; + } + if ((b_data[2]*0x100 + b_data[1]) == 0){ + printf("\nFile \"00\" assigned ! : %08x : %02x\n",i_timeA ,d_type); + } + + /* �¬�ß�ü */ + case 0x0C: case 0x1C: + b_data[0] = d_type / 0x10; + d_type %= 0x10; + + dataWritingUnit(dif); + break; + + /* ”»’è•��Ý’è */ + case 0x08: case 0x18: case 0x28: case 0x38: case 0x48: case 0x58: + switch(filetype){ + case 3: // 6th style ‰ð�̓oƒO‘Î�ô + if(d_type == 0x48){ + b_data[1] = 0x08; + b_data[0] = 0x04; + } + else { + b_data[1] = b_data[0]; + b_data[0] = d_type / 0x10; + } + break; + + default: + b_data[1] = b_data[0]; + b_data[0] = d_type / 0x10; + break; + } + d_type %= 0x10; + + dataWritingUnit(dif); + break; + + /* Ž©“®‰‰‘t */ + case 0xF7: + break; + case 0x87: case 0x17: case 0x07: case 0xA7: + switch(filetype){ + case 3: + b_data[1] = b_data[0]; + b_data[0] = 0x00; + } + d_type %= 0x10; + + if (maxwav < (b_data[2]*0x100 + b_data[1])){ + maxwav = b_data[2]*0x100 + b_data[1]; + } + + if((b_data[2]*0x100 + b_data[1]) == 1) + { + if(wav01_auto) + break; + else + wav01_auto++; + } + + dataWritingUnit(dif); + break; + + + /* BPM•Ï�X */ + case 0x04: case 0x14: case 0x24: case 0x34: + b_data[2] = d_type / 0x10; + b_data[1] = b_data[0]; + b_data[0] = 0x01; + d_type %= 0x10; + dataWritingUnit(dif); + + start_flag++; + + switch(filetype){ + case 3: + if(rtm_flag == 0){ + d_type = 0x05; + b_data[0] = 0x04; + b_data[1] = 0x04; + b_data[2] = 0x00; + dataWritingUnit(dif); + rtm_flag++; + } + break; + } + break; + + /* ”�Žq•Ï�X */ + case 0x05: + switch(filetype){ + case 3: + break; + default: + dataWritingUnit(dif); + } + break; + + /* •ˆ–Ê�I—¹�錾 */ + case 0x06: + if(dp_flag == 3){ + b_data[0] = 0x01; + } + dataWritingUnit(dif); + + if((dp_flag == 0)||(dp_flag == 3)){ + temp = 0x7FFFFFFF; + fwrite(&temp, 1, 4, out); + temp = 0x00; + for(i=0;i<0x04;i++){ + fwrite(&temp, 1, 1, out); + } + f_size[dif] += 8; + } + dp_flag += 2; + break; + + /* ’PˆÊŽžŠÔ”»’è */ + case 0x2B: + t_base_type = 1; + break; + + case 0x4C: + break; + + default: + printf("Unknown data type! : %06x : %02x (%02x %02x %02x)\n",i_timeA ,d_type, b_data[0], b_data[1], b_data[2]); + break; + } + //printf("DEBUG: %06x : %02x (%02x %02x %02x); %d\n",i_timeA ,d_type, b_data[0], b_data[1], b_data[2], dp_flag); + } + + /* ƒTƒuƒwƒbƒ_‚ÌTotalNotes�‘‚«Š·‚¦ */ + fseek(out, head_adrs + 0x06, SEEK_SET); + fwrite(&t_notes[dif], 1, 2, out); + + /* ƒwƒbƒ_�‘‚«Š·‚¦ */ + headWritingUnit(dif); + + return 0; +} + +/* .1ƒwƒbƒ_�¶�¬ */ +int makeHeader(void){ + int i; + int temp; + /* ƒwƒbƒ_‰¼’u‚« */ + temp = 0x00; + for(i=0;i<0x60;i++){ + fwrite(&temp, 1, 1, out); + } + return 0; +} + +/* CS•ˆ–ʃtƒ@ƒCƒ‹Šm”F */ +int checkScoreFile(void){ + int i,j; + int existflag; + int headerflag; + char f_type[NAMEMAX]; + + filetype = 0; + headerflag = 0; + + /* CS3ƒtƒ@ƒCƒ‹ */ + if((in = fopen("cs3.raw", "rb")) == NULL) { + printf("cs3.raw : Not Found.\n\n"); + } + else { + printf("cs3.raw : Read success / "); + filetype = 1; + + /* DJT,GOLD”»•Ê */ + fseek(in, 0, SEEK_END); + if (ftell(in) / 0x10000 == 6){ + f_exist[3] = -1; + printf("CS3 type : GOLD\n\n"); + } + else { + printf("CS3 type : DJ TROOPERS\n\n"); + } + + /* •ˆ–Ê‘¶�݃tƒ‰ƒOŒŸ�o */ + printf("Prosessing "); + for(j=0;j<7;j++){ + /* ƒtƒ‰ƒO“Ç‚Ý�ž‚Ý */ + existflag = 0; + fseek(in, 0x10000 * j, SEEK_SET); + fread(&existflag, 1, 1, in); + fseek(in, 0x10000 * j, SEEK_SET); + + /* GOLD‚Ì�ê�‡SPB•ª‚ð”ò‚΂· */ + if((j >= 3)&&(f_exist[3] == -1)){ + j++; + } + + /* ƒtƒ‰ƒO”»’è */ + if(existflag == 0x00){ // ‘¶�Ý‚µ‚È‚¢ + f_exist[j] = 0; + } + else { // ‘¶�Ý‚·‚é + /* ƒwƒbƒ_�¶�¬ */ + if(headerflag == 0){ + makeHeader(); + headerflag++; + } + /* •ÏŠ·�ˆ—� */ + printf("-"); + cs2ac(j); + printf("> "); + f_exist[j] = 1; + } + + /* GOLD‚Ì�ê�‡ƒ‹�[ƒvƒJƒEƒ“ƒ^‚ð–ß‚· */ + if((j >= 3)&&(j != 6)&&(f_exist[3] == -1)){ j--; } + } + printf("OK\n"); + } + + /* CS,CS2,CS5ƒtƒ@ƒCƒ‹ */ + for(i=2;i<=3;i++){ + if(filetype != 0){ + break; + } + + switch(i){ + case 2: sprintf(f_type, "cs"); break; // 7th style - DistorteD + case 3: sprintf(f_type, "cs2"); break; // 3rd style - 6th style +// case 4: sprintf(f_type, "cs5"); break; // ?? + } + for(j=0;j<7;j++){ + switch(j){ + case 0: sprintf(inName, "n7.%s",f_type); break; + case 1: sprintf(inName, "h7.%s",f_type); break; + case 2: sprintf(inName, "a7.%s",f_type); break; + case 3: sprintf(inName, "b.%s",f_type); break; + case 4: sprintf(inName, "n14.%s",f_type); break; + case 5: sprintf(inName, "h14.%s",f_type); break; + case 6: sprintf(inName, "a14.%s",f_type); break; + } + if((in = fopen(inName, "rb")) == NULL) { + printf("%7s : Not Found.\n",inName); + } + else { + printf("%7s : Prosessing ",inName); + filetype = i; + /* ƒwƒbƒ_�¶�¬ */ + if(headerflag == 0){ + makeHeader(); + headerflag++; + } + /* •ÏŠ·�ˆ—� */ + printf("-"); + cs2ac(j); + f_exist[j] = 1; + fclose(in); + printf("> OK\n"); + } + } + printf("\n"); + } + return filetype; +} + +int main(){ + char wait[0xff]; + head_adrs = 0x60; + maxwav = 0; + + printf(" -* beatmaniaIIDX CS to AC Chart Converter v%.2f by 697@14 *-\n\n",version); + + if((out = fopen("output.1", "wb")) == NULL) { + printf("Failed to open \"output.1\".\n"); + return 1; + } + + if(checkScoreFile() == 0) { + printf("Chart File not found...\n"); + return 1; + } + else { + printf("Number of wav : %d\n\n",maxwav); + printf("Writing \"output.1\"\n\nDone.\n"); + } + fclose(out); + + //gets(wait); + return 0; +} + + + diff --git a/iidx/bme2ac/old/fixtimingwindows.c b/iidx/bme2ac/old/fixtimingwindows.c new file mode 100644 index 0000000..1f06649 --- /dev/null +++ b/iidx/bme2ac/old/fixtimingwindows.c @@ -0,0 +1,129 @@ +//timebase_single.c by ryuuou +//changes the base fps value of .1 files like timebase.exe, but works on a bunch of single .1 files instead of folders +//this is mainly to assist with custom songs so that you don't have to timebase your whole folder again for single songs and deal with file versions + +#include +#include +#include +#include + +#define byte unsigned char + +#define CHARTCOUNT 7 +#define EVENTSIZE 8 +#define FPS_STANDARD_GOLD 60.05 +#define FPS_STANDARD_DD 59.95 + +int offsets[CHARTCOUNT] = {0, 8, 16, 24, 48, 56, 64}; +const char *CHARTNAMES[] = { "h7", "n7", "a7", "b", "h14", "n14", "a14" }; +unsigned short int judgements[6] = {0xF0, 0xFA, 0xFF, 0x3, 0x8, 0x12}; + +typedef struct +{ + unsigned int time; + byte type; + byte data1; + unsigned short int data2; +} event; + +int main(int argc, const char **argv) +{ + int i,j,k; + FILE *in, *out; + byte *buf; + int *p; + int flength; + int pos, len; + short int np1, np2; + + event *ev; + + printf("fixtimingwindows by ryuuou\n\tfixes timing windows to be consistent\n\n"); + if(argc < 2) + { + printf("usage: fixtimingwindows ...\n\talternatively drop a bunch of .1 files on the executable\n"); + getchar(); + return 0; + } + + for(i = 2; i <= argc; i++) + { + printf("processing %s...", argv[i-1]); + in = fopen(argv[i-1], "rb"); + if(!in) + { + printf("file not found\n"); + continue; + } + + fseek(in, 0, SEEK_END); + flength = (int)ftell(in); + fseek(in, 0, SEEK_SET); + + buf = malloc(flength); + + fread(buf, flength, 1, in); + fclose(in); + + for(j = 0; j < CHARTCOUNT; j++) + { + p = (int*)(buf+offsets[j]); + if(!*p) continue; //no chart here + + //printf("%s...\n", CHARTNAMES[j]); + + pos = p[0]; + len = p[1]; + + np1 = 0; + np2 = 0; + + for(k = pos; k < pos+len - EVENTSIZE; k += EVENTSIZE) + { + ev = (event*)(buf+k); + + if(ev->type == 8) //adjust timing + { + //printf("%d (%d->%d)...", ev->data1, ev->data2, judgements[ev->data1]); + ev->data2 = judgements[ev->data1]; + } + if(ev->type == 0)//player 1 keypress + { + np1++; + } + else if(ev->type == 1) //player 2 keypress + { + np2++; + } + } + + for(k = pos; k < pos+len; k += EVENTSIZE) + { + ev = (event*)(buf+k); + + if(ev->type == 0x10)//notecount + { + if(ev->data1 == 0) //player1 + { + printf("%d -> %d | ", ev->data2, np1); + ev->data2 = np1; + } + else if(ev->data1 == 1) //player2 + { + printf("%d -> %d\n", ev->data2, np2); + ev->data2 = np2; + } + } + } + //printf("%s: p1: %d, p2: %d\n", CHARTNAMES[j], np1, np2); + } + + out = fopen(argv[i-1], "wb"); + fwrite(buf, flength, 1, out); + fclose(out); + + free(buf); + + printf("done\n"); + } +} diff --git a/iidx/bme2ac/old/gcz2tga.c b/iidx/bme2ac/old/gcz2tga.c new file mode 100644 index 0000000..70e5b8e --- /dev/null +++ b/iidx/bme2ac/old/gcz2tga.c @@ -0,0 +1,306 @@ +/* gcz2tga.c: Slice up a directory full of GCZ (texture) files into TGA files. + * + * Credit goes to afwefwe for reverse-engineering the texture format + * and LZSS compression */ + +#include +#include +#include + +/* Assuming x86, usual endian crap is not accounted for */ +typedef unsigned char u8_t; +typedef unsigned short u16_t; +typedef unsigned int u32_t; + +struct image +{ + unsigned int width, height; + u8_t *planes; +}; + +struct clip +{ + short x, y, w, h; +}; + +static u16_t swab16(u16_t in) +{ + /* GC headers are big-endian */ + return ((in & 0xFF) << 8) | (in >> 8); +} + +static void unpack_gc(struct image *out, u8_t *in, size_t out_sz) +{ + unsigned int npixels; + unsigned int i; + unsigned int j; + u16_t *pixels; + u16_t *pheight; + u16_t *pwidth; + u16_t *pmagic; + u16_t pixel; + + pmagic = (u16_t *) in; + pheight = (u16_t *) (in + 14); + pwidth = (u16_t *) (in + 12); + + if (*pmagic != 0x4347) { + fprintf(stderr, "(FAIL: Invalid header)\n"); + exit(EXIT_FAILURE); + } + + /* Set up output image struct */ + in += 24; + out->width = swab16(*pwidth); + out->height = swab16(*pheight); + out->planes = malloc(out->width * out->height * 4); + + /* Clamp W/H (don't know why this is necessary but it is) */ + out->width = out->width > 1024 ? 1024 : out->width; + out->height = out->height > 1024 ? 1024 : out->height; + + fprintf(stderr, "(%dx%d)", out->width, out->height); + + /* Unpack pixels */ + pixels = (u16_t *) in; + npixels = out->width * out->height; + + if (out_sz > npixels * 4) { + /* Deep image (i.e. 32-bit) */ + memcpy(out->planes, pixels, npixels * 4); + } else { + /* Shallow image (i.e. 16-bit) */ + for (i = 0, j = 0 ; i < npixels ; i++) { + pixel = pixels[i]; + out->planes[j++] = ((pixel ) & 0x1F) << 3; /* B */ + out->planes[j++] = ((pixel >> 5) & 0x1F) << 3; /* G */ + out->planes[j++] = ((pixel >> 10) ) << 3; /* R */ + out->planes[j++] = pixel & 0x8000 ? 0xFF : 0x00; /* A */ + } + } +} + +static u8_t *expand_lzss(u8_t *lzss, size_t *pout_sz) +{ + static u8_t ring[0x1000]; + unsigned int ring_pos = 0x0FEE; + unsigned int chunk_offset; + unsigned int chunk_length; + u32_t control_word = 1; + size_t length; + u8_t cmd1; + u8_t cmd2; + u8_t *out; + u8_t *pos; + u8_t *in; + + /* Header = 32 bit unpacked file length */ + length = *((u32_t *) lzss); + *pout_sz = length; + + if (length > 8000000) { + fprintf(stderr, "(FAIL: Unreasonably large expanded size %d)\n", + length); + + exit(EXIT_FAILURE); + } + + out = malloc(length * 2); /* Seems to overrun */ + pos = out; + in = lzss + 4; + + while (length > 0) { + if (control_word == 1) { + /* Read a control byte */ + control_word = 0x100 | *in++; + } + + /* Decode a byte according to the current control byte bit */ + if (control_word & 1) { + /* Straight copy */ + *pos++ = *in; + ring[ring_pos] = *in++; + + ring_pos = (ring_pos + 1) % 0x1000; + length--; + } else { + /* Reference to data in ring buffer */ + cmd1 = *in++; + cmd2 = *in++; + + chunk_length = (cmd2 & 0x0F) + 3; + chunk_offset = ((cmd2 & 0xF0) << 4) | cmd1; + + for ( ; chunk_length > 0 ; chunk_length--) { + /* Copy historical data to output AND current ring pos */ + *pos++ = ring[chunk_offset]; + ring[ring_pos] = ring[chunk_offset]; + + /* Update counters */ + chunk_offset = (chunk_offset + 1) % 0x1000; + ring_pos = (ring_pos + 1) % 0x1000; + length--; + } + } + + /* Get next control bit */ + control_word >>= 1; + } + + return out; +} + +static void readfile(const char *filename, u8_t **data, long *nbytes) +{ + FILE *f; + + f = fopen(filename, "rb"); + if (f == NULL) abort(); + + fseek(f, 0, SEEK_END); + *nbytes = ftell(f); + fseek(f, 0, SEEK_SET); + + *data = malloc(*nbytes); + fread(*data, *nbytes, 1, f); + + fclose(f); +} + +void put8(FILE *f, unsigned char val) +{ + fwrite(&val, 1, 1, f); +} + +void put16(FILE *f, unsigned short val) +{ + fwrite(&val, 2, 1, f); +} + +void split_images(const char *in_dir, const char *out_dir, + struct image *images, int nimages) +{ + struct clip *clips; + char filename[512]; + long nbytes; + u8_t *data; + char *name; + FILE *f; + int i; + int j; + int k; + + /* Read file and get TOC */ + sprintf(filename, "%s/system.idx", in_dir); + readfile(filename, &data, &nbytes); + clips = (struct clip *) (data + 0x01BC); + name = (char *) (data + 8 + *((long *) data)); + + /* Guess how many clips there are with a heuristic */ + for (i = 0 ; clips[i].w != 0 && clips[i].h != 0 ; i++) { + sprintf(filename, "%s/%s.tga", out_dir, name); + name += strlen(name) + 3; + + f = fopen(filename, "wb"); + if (f == NULL) abort(); + + /* Locate the correct source image */ + j = 0; + while (clips[i].y > images[j].height) { + clips[i].y -= images[j].height; + j++; + } + + /* Write header */ + put8(f, 0); put8(f, 0); put8(f, 2); + put16(f, 0); put16(f, 0); put8(f, 0); + put16(f, 0); put16(f, 0); put16(f, clips[i].w); put16(f, clips[i].h); + put8(f, 32); put8(f, 32); + + /* Write scanlines */ + for (k = 0 ; k < clips[i].h ; k++) { + if (clips[i].y == images[j].height) { + clips[i].y = 0; + j++; + } + + fwrite(images[j].planes + ((images[j].width * clips[i].y) + + clips[i].x) * 4, clips[i].w, 4, f); + clips[i].y++; + } + + /* Close output file */ + fclose(f); + } + + /* Cleanup */ + free(data); +} + +int main(int argc, char **argv) +{ + char *in_dir; + char *out_dir; + + struct image images[32]; + char filename[256]; + unsigned int i; + long filesize; + u8_t *lzss, *gc; + size_t out_sz; + FILE *f; + + /* Usage */ + if (argc != 3) { + fprintf(stderr, "Usage: %s [indir] [outdir]\n", argv[0]); + return EXIT_FAILURE; + } + + /* Setup */ + memset(images, 0, sizeof(images)); + in_dir = argv[1]; + out_dir = argv[2]; + + for (i = 0 ; i < 32 ; i++) { + /* Open 0.gcz, 1.gcz etc ... */ + sprintf(filename, "%s/%d.gcz", in_dir, i); + f = fopen(filename, "rb"); + if (f == NULL) break; + + /* Read entire file */ + fseek(f, 0, SEEK_END); + filesize = ftell(f); + fseek(f, 0, SEEK_SET); + + fprintf(stderr, "%s: fread", filename); + lzss = malloc(filesize); + fread(lzss, filesize, 1, f); + fclose(f); + + /* Decompress */ + fprintf(stderr, "(OK) expand_lzss"); + gc = expand_lzss(lzss, &out_sz); + free(lzss); + + /* Unpack GC to 32-bit RGBA */ + fprintf(stderr, "(OK) unpack_gc"); + unpack_gc(&images[i], gc, out_sz); + free(gc); + + fprintf(stderr, "(OK)\n"); + } + + /* Sanity check */ + if (i == 0) { + fprintf(stderr, "No GCZ files found\n"); + exit(EXIT_FAILURE); + } + + /* Emit pile of TGAs */ + fprintf(stderr, "split_images"); + split_images(in_dir, out_dir, images, i); + fprintf(stderr, "(OK)\n\n"); + + return 0; +} + diff --git a/iidx/bme2ac/old/merge1.c b/iidx/bme2ac/old/merge1.c new file mode 100644 index 0000000..2425e57 --- /dev/null +++ b/iidx/bme2ac/old/merge1.c @@ -0,0 +1,157 @@ +//merge1.c by ryuuou +//merges several .1 files into a single one to help with songs that have too many wav references + +#include +#include +#include + +#define CHARTCOUNT 7 +#define byte unsigned char + +const char *ONAMES[] = { "h7.1", "n7.1", "a7.1", "b.1", "h14.1", "n14.1", "a14.1" }; +const char *NAMES[] = { "h7", "n7", "a7", "b", "h14", "n14", "a14" }; +int offsets[CHARTCOUNT] = {0, 8, 16, 24, 48, 56, 64}; +int worder[CHARTCOUNT] = {0, 4, 1, 5, 2, 6, 3}; + + +int main() +{ + int i, len; + int *plen, *poff; + byte *onechart[CHARTCOUNT]; + int olen[CHARTCOUNT]; + FILE *in, *out; + int ccount = 0; + + byte *buf; + int blen; + + printf("merge1 by ryuuou\n\tmultiplexes several .1 files into a single one\n\n\n"); + + in = fopen("base.1", "rb"); + + memset(onechart, 0, sizeof(int*)*CHARTCOUNT); + memset(olen, 0, sizeof(int)*CHARTCOUNT); + + printf("trying to open files...\n"); + printf("base.1..."); + if(!in) printf("not found, authoring new .1 file\n"); + else printf("OK\n"); + + if(in) //load base.1 as reference + { + fseek(in, 0, SEEK_END); + blen = (int)ftell(in); + fseek(in, 0, SEEK_SET); + + buf = malloc(blen); + fread(buf, blen, 1, in); + fclose(in); + + printf("loading charts from base.1..."); + //load the charts contained in the base file + for(i = 0; i < CHARTCOUNT; i++) + { + poff = (int*)(buf+offsets[i]); + plen = (int*)(buf+offsets[i]+4); + if(!*plen) continue; //no chart + + olen[i] = *plen; + + printf("%s...", NAMES[i]); + + onechart[i] = malloc(olen[i]); + + memcpy(onechart[i], buf+*poff, olen[i]); //copy the chart + } + + free(buf); + printf("done\n\n"); + } + + printf("loading and inserting/overwriting charts...\n"); + + for(i = 0; i < CHARTCOUNT; i++) + { + printf("%s...", ONAMES[i]); + in = fopen(ONAMES[i], "rb"); + if(!in) + { + printf("not found\n"); + continue; + } + + ccount++; + + fseek(in, 0, SEEK_END); + blen = (int)ftell(in); + fseek(in, 0, SEEK_SET); + + buf = malloc(blen); + fread(buf, blen, 1, in); + fclose(in); + + poff = (int*)(buf+offsets[i]); + plen = (int*)(buf+offsets[i]+4); + + if(!*plen) + { + printf("no %s chart\n", NAMES[i]); + continue; //this file contains no appropriate chart, l2namefiles + } + + if(olen[i]) //we previously loaded a chart from base.1 and we don't want to leak memory + free(onechart[i]); + + olen[i] = *plen; + + onechart[i] = malloc(*plen); + + memcpy(onechart[i], buf+*poff, *plen); + free(buf); + printf("OK\n"); + } + + if(!ccount) + { + printf("no charts found, aborting\npress any key to exit\n"); + getchar(); + return 0; + } + + //create the aggregated .1 file + + len = 96; //.1 headersize + + for(i = 0; i < CHARTCOUNT; i++) + len += olen[i]; + + buf = malloc(len); + + memset(buf, 0, len); + + len = 96; //abuse len as position counter + + printf("\nauthoring .1 file..."); + for(i = 0; i < CHARTCOUNT; i++) + { + memcpy(buf+offsets[worder[i]], &len, 4); + memcpy(buf+offsets[worder[i]]+4, &olen[worder[i]], 4); + + memcpy(buf+len, onechart[worder[i]], olen[worder[i]]); + len += olen[worder[i]]; + } + printf("done\n"); + + printf("writing merged.1..."); + out = fopen("merged.1", "wb"); + + fwrite(buf, len, 1, out); + + fclose(out); + free(buf); + printf("done\npress any key to exit\n"); + + getchar(); + return 0; +} diff --git a/iidx/bme2ac/old/oldac2dx2newac2dx.c b/iidx/bme2ac/old/oldac2dx2newac2dx.c new file mode 100644 index 0000000..5a27f3d --- /dev/null +++ b/iidx/bme2ac/old/oldac2dx2newac2dx.c @@ -0,0 +1,228 @@ +//crack2dx_new.c +//decrypts .2dx files from every style from 9th to Troopers +//decryption method and keys taken from crack2dx.c, rewritten with added support for Troopers, Empress and usablility +//...and for bugfixing -_- + +#include +#include +#include + +#define byte unsigned char + +byte keys_09[] = { //9th style + 0x97, 0x1E, 0x24, 0xA0, 0x9A, 0x00, 0x10, 0x2B, + 0x91, 0xEF, 0xD7, 0x7A, 0xCD, 0x11, 0xAF, 0xAF, + 0x8D, 0x26, 0x5D, 0xBB, 0xE0, 0xC6, 0x1B, 0x2B }; + +byte keys_10[] = { //10th style + 0x2D, 0x86, 0x56, 0x62, 0xD7, 0xFD, 0xCA, 0xA4, + 0xB3, 0x24, 0x60, 0x26, 0x24, 0x81, 0xDB, 0xC2, + 0x57, 0xB1, 0x74, 0x6F, 0xA7, 0x52, 0x99, 0x21 }; + +byte keys_11[] = { //Happy Sky+ + 0xED, 0xF0, 0x9C, 0x90, 0x44, 0x1A, 0x5A, 0x03, + 0xAB, 0x07, 0xC1, 0x99, 0x23, 0x24, 0x32, 0xC7, + 0x5F, 0x32, 0xA5, 0x97, 0xAD, 0x98, 0x0F, 0x8F }; + +byte keys_16[] = { //empress + 0x28, 0x22, 0x28, 0x54, 0x63, 0x3F, 0x0E, 0x42, + 0x6F, 0x45, 0x4E, 0x50, 0x67, 0x53, 0x61, 0x7C, + 0x04, 0x46, 0x00, 0x3B, 0x13, 0x2B, 0x45, 0x6A }; + +//XORs two 8 byte blocks +void block_xor(byte *data, byte *parm) +{ + int i; + for (i = 0 ; i < 8 ; i++) + data[i] ^= parm[i]; + return; +} + +//Swaps the lower 4 bytes with the upper 4 bytes +void block_swap(byte *data) +{ + int i; + for (i = 0 ; i < 4 ; i++) + { + data[i] ^= data[i+4]; //let's do this without temp variables ;D + data[i+4] ^= data[i]; + data[i] ^= data[i+4]; + } + return; +} + +//I bow to whoever figured this one out +void block_obfus(byte *data) +{ + byte a,b,c,d,e,f,g,h,i; + + a = data[0] * 63; + b = a + data[3]; + c = data[1] * 17; + d = c + data[2]; + e = d + b; + f = e * data[3]; + g = f + b + 51; + h = b ^ d; + i = g ^ e; + + data[4] ^= h; + data[5] ^= d; + data[6] ^= i; + data[7] ^= g; + + return; +} + + +int main(int argc, byte **argv) +{ + int i; + int style=2; + int mult; + byte *buf, *buf_dec, *enc; + byte *cur, *prev; + byte *cryptkey; + int *wavcount; + int *wavpos, *wavlen; + int len; + FILE *in, *out; + unsigned char n_out[10]; //wav name + + printf("oldac2newac_2dx by v0.1 ryuuou\n\treencrypts .2dx files from Troopers AC and before \n\tto .2dx compatible with Empress AC\n\n"); + + if(argc < 2) + { + printf("USAGE: oldac2newac_2dx \n"); + return 0; + } + + printf("\nprocessing %s...\n", argv[1]); + + in = fopen(argv[1], "rb"); + + if(!in) + { + printf("not found: %s\n", argv[1]); + return -1; + } + + fseek(in, 0, SEEK_END); + len = (int)ftell(in); + fseek(in, 0, SEEK_SET); + + buf = malloc(len); + + fread(buf, len, 1, in); + fclose(in); + + //identify iidx version + + printf("identifying encryption..."); + mult = 1; + if(!strncmp(buf, "%eNc", 4)) + { + printf("9th style\n"); + cryptkey = keys_09; //9th style + } + else if(!strncmp(buf, "%e10", 4)) + { + printf("10th style\n"); + cryptkey = keys_10; //10th style + } + else if(!strncmp(buf, "%e11", 4)) + { + printf("RED\n"); + cryptkey = keys_11; //RED + } + else if(!strncmp(buf, "%e12", 4)) + { + printf("Happy Sky/DistorteD/GOLD\n"); + cryptkey = keys_11; //HS+ + mult = 0; + } + else if(!strncmp(buf, "%hid", 4)) + { + printf("Troopers\n"); + cryptkey = keys_11; //Troopers + mult = 0; + } + else if(!strncmp(buf, "%iO0", 4)) + { + printf("Empress, nothing to do\n"); + cryptkey = keys_16; //Empress + return 0; + } + else + { + printf("unknown encryption, trying unencrypted...\n"); + mult = 2; + } + + + //decrypt + + + + if(!(mult == 2)) //skip for unencrypted + { + buf_dec = malloc(len); + memcpy(buf_dec, buf, len); //copy the encrypted part + memset(buf, 0, 8); //zero the first block to make the loop easier + + for(i = 0; i <= len-16; i+= 8) + { + cur = buf_dec + 8 + i; //cur points to the current encrypted block to decrypt + prev = buf + i; //prev points to the cur-8 in encrypted form + + block_xor(cur, cryptkey); + block_obfus(cur); + block_swap(cur); + + if(mult) // for versions prior to DistorteD and Empress + { + block_xor(cur, cryptkey+8); + block_obfus(cur); + block_xor(cur, cryptkey+16); + } + + block_xor(cur, prev); + } + } + else + { + buf_dec = malloc(len); + memcpy(buf_dec, buf, len); //copy for splitting + } + + + //reencrypt to empress + + cryptkey = keys_16; + + for(i = 0; i <= len-16; i+= 8) + { + cur = buf_dec + i + 8; //cur points to the current decrypted block to encrypt + + block_xor(cur, cur-8); + block_xor(cur, cryptkey+16); + block_obfus(cur); + block_xor(cur, cryptkey+8); + block_swap(cur); + block_obfus(cur); + block_xor(cur, cryptkey); + } + + memcpy(buf_dec, "%iO0", 4); + + //*((int*)buf_dec+4) = len-8; + + out = fopen(argv[1], "wb"); + fwrite(buf_dec, len, 1, out); + fclose(out); + + printf("done\n"); + free(buf); + free(buf_dec); + return 0; +} diff --git a/iidx/bme2ac/old/split2dx.c b/iidx/bme2ac/old/split2dx.c new file mode 100644 index 0000000..88e3730 --- /dev/null +++ b/iidx/bme2ac/old/split2dx.c @@ -0,0 +1,78 @@ +/* split2dx.c: Extract all WAVs from a .2DX file (sound archive) */ +#include +#include +#include + +int main(int argc, char **argv) +{ + static const char base36[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + char outname[64]; + FILE *out; + FILE *in; + void *bytes; + int nfiles; + int nbytes; + int *toc; + int i; + + /* Usage */ + if (argc != 3) { + fprintf(stderr, "Usage: %s [infile] [outdir]\n", argv[0]); + return EXIT_FAILURE; + } + + /* Open input */ + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "%s: Could not open file for reading\n", argv[1]); + return EXIT_FAILURE; + } + + /* Read TOC length */ + fseek(in, 0x14, SEEK_SET); + fread(&nfiles, 4, 1, in); + + /* Read TOC */ + toc = malloc(4 * nfiles); + fseek(in, 0x48, SEEK_SET); + fread(toc, 4, nfiles, in); + + /* Extract files */ + for (i = 0 ; i < nfiles ; i++) { + /* Name output file */ + sprintf(outname, "%s/%c%c.wav", argv[2], + base36[(i + 1) / 36], base36[(i + 1) % 36]); + + /* Open output file */ + out = fopen(outname, "wb"); + if (!out) { + fprintf(stderr, "%s: Could not open file for writing\n", outname); + free(toc); + + return EXIT_FAILURE; + } + + /* Put RIFF fourcc which we skipped */ + fwrite("RIFF", 4, 1, out); + + /* Get file length */ + fseek(in, toc[i] + 0x1C, SEEK_SET); + fread(&nbytes, 4, 1, in); + fwrite(&nbytes, 4, 1, out); + + /* Copy */ + bytes = malloc(nbytes); + fread(bytes, 1, nbytes, in); + fwrite(bytes, 1, nbytes, out); + + /* Clean up */ + fclose(out); + free(bytes); + } + + fclose(in); + free(toc); + + return EXIT_SUCCESS; +} + diff --git a/iidx/bme2ac/old/timebase_59.c b/iidx/bme2ac/old/timebase_59.c new file mode 100644 index 0000000..28404f8 --- /dev/null +++ b/iidx/bme2ac/old/timebase_59.c @@ -0,0 +1,103 @@ +//timebase_single.c by ryuuou +//changes the base fps value of .1 files like timebase.exe, but works on a bunch of single .1 files instead of folders +//this is mainly to assist with custom songs so that you don't have to timebase your whole folder again for single songs and deal with file versions + +#include +#include +#include +#include + +#define byte unsigned char + +#define CHARTCOUNT 7 +#define EVENTSIZE 8 +#define FPS_STANDARD_GOLD 60.05 +#define FPS_STANDARD_DD 59.95 + +int offsets[CHARTCOUNT] = {0, 8, 16, 24, 48, 56, 64}; +const char *CHARTNAMES[] = { "h7", "n7", "a7", "b", "h14", "n14", "a14" }; + +int main(int argc, const char **argv) +{ + int i,j,k; + float basefps, targetfps; + FILE *in, *out; + byte *buf; + int *p; + int flength; + int pos, len; + + printf("timebase_single by ryuuou\n\tchanges the base fps of .1 files like timebase.exe,\n\tbut works on a batch of files instead of folders\n\n"); + if(argc < 2) + { + printf("usage: timebase_single ...\n\talternatively drop a bunch of .1 files on the executable\n"); + getchar(); + return 0; + } + + basefps = targetfps = 0; + + /*printf("please input the current fps (or 0 for 60.05 or 1 for 59.95): "); + scanf("%f", &basefps); + if(basefps == 0) + basefps = FPS_STANDARD_GOLD; + if(basefps == 1) + basefps = FPS_STANDARD_DD; + printf("please input the target fps: (or 0 for 60.05 or 1 for 59.95)"); + scanf("%f", &targetfps); + if(targetfps == 0) + targetfps = FPS_STANDARD_GOLD; + if(targetfps == 1) + targetfps = FPS_STANDARD_DD; + + + printf("converting from %.3f fps to %.3f fps\npress enter to continue or ctrl-c to cancel\nMAKE SURE YOU HAVE BACKUPS OF YOUR FILES!!\n", basefps, targetfps); + getchar();getchar();*/ + + for(i = 2; i <= argc; i++) + { + printf("processing %s...", argv[i-1]); + in = fopen(argv[i-1], "rb"); + if(!in) + { + printf("file not found\n"); + continue; + } + + fseek(in, 0, SEEK_END); + flength = (int)ftell(in); + fseek(in, 0, SEEK_SET); + + buf = malloc(flength); + + fread(buf, flength, 1, in); + fclose(in); + + for(j = 0; j < CHARTCOUNT; j++) + { + p = (int*)(buf+offsets[j]); + if(!*p) continue; //no chart here + + printf("%s...", CHARTNAMES[j]); + + pos = p[0]; + len = p[1]; + + for(k = pos; k < pos+len; k += EVENTSIZE) + { + p = (int*)(buf+k); + if(*p == 0x7FFFFFFF || *p == 0x7F000000) //end sequence event, we skip these + continue; + *p = (int)roundf((float)*p *1000. / FPS_STANDARD_DD); + } + } + + out = fopen(argv[i-1], "wb"); + fwrite(buf, flength, 1, out); + fclose(out); + + free(buf); + + printf("done\n"); + } +} diff --git a/iidx/bme2ac/old/txt2eout.c b/iidx/bme2ac/old/txt2eout.c new file mode 100644 index 0000000..5fac2a7 --- /dev/null +++ b/iidx/bme2ac/old/txt2eout.c @@ -0,0 +1,144 @@ + +#define byte unsigned char + +#include "stdio.h" +#include "string.h" + +typedef struct +{ + byte iidx[4]; + int version; + short int songcount; + short int indexcount; + int zero; +} eoutheader; + +typedef struct +{ + byte songname[64]; + byte labelname[32]; //filename + byte titlename[64]; //filename + byte genrename[32]; //filename + byte artistname[32]; //filename + + short int style; + short int sort_others; + short int sort_bemani; + short int sort_bemani2; + + byte diff_n7; + byte diff_h7; + byte diff_a7; + byte diff_n14; + byte diff_h14; + byte diff_a14; + byte diff_beg; + byte diff_zero; + + byte zeros[128]; + byte FF[20]; + + int index; + int volume; + + byte suffix[8]; + + int movieoffset; + byte moviefile[32]; + + byte bgname[32]; + byte graphicsfolder[32]; + + int layerinfo; + byte layerdata[9*32]; +} songinfo; + +int main(int *argc, char* argv[]) +{ + eoutheader header; + songinfo info; + FILE *in, *out; + int i; + int pc, id; + int myn; + byte asuffix[9]; + + in = fopen(argv[1], "rb"); + if(!in) + { + printf("file not found: %s", argv[1]); + return 0; + } + + out = fopen("txt_eout.dec", "wb"); + + memset(&header, 0, 16); + sprintf(header.iidx, "IIDX"); + header.version = 15; + + fwrite(&header, sizeof(eoutheader), 1, out); + + while(!feof(in)) + { + memset(&info, 0, sizeof(songinfo)); + memset(info.FF, 0xFF, 20); + memset(info.suffix, 0x30, 8); + + pc = fscanf(in, "%d\t%[a-zA-Z0-9*+<>/\()!? -]\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%[a-z.]\n",\ + &info.index, info.songname, \ + &info.diff_beg, &info.diff_n7, &info.diff_h7, &info.diff_a7, &info.diff_n14, &info.diff_h14, &info.diff_a14,\ + &info.style, &info.sort_others, &info.sort_bemani, &myn, &info.movieoffset, asuffix); + + if(pc != 15) + { + printf("parse error in line %d after token %d\n", header.songcount+1, pc); + break; + } + + id = info.index; + + sprintf(info.labelname, "L_%d", id); + sprintf(info.titlename, "T_%d", id); + sprintf(info.genrename, "G_%d", id); + sprintf(info.artistname, "A_%d", id); + sprintf(info.bgname, "B_%d", id); + + sprintf(info.graphicsfolder, "in_%02d", id/100); + + if(myn == 1) + sprintf(info.moviefile, "%d", id); + else if(!myn) + sprintf(info.moviefile, "0000"); + else + sprintf(info.moviefile, "%d", myn); + + for(i = 0; i < 8; i++) + if(asuffix[i] == '.') + asuffix[i] = '0'; + + memcpy(info.suffix, asuffix, 8); + + if(info.diff_h7 == 0) + info.diff_h7 = 1; + if(info.diff_h14 == 0) + info.diff_h14 = 1; + + info.sort_bemani2 = info.sort_bemani; //??? + + info.volume = 90; + + header.songcount++; + + fwrite(&info, sizeof(songinfo), 1, out); + } + + rewind(out); + fwrite(&header, sizeof(eoutheader), 1, out); + + fclose(in); + fclose(out); + + printf("%d songs in all\n", header.songcount); + + return 0; +} diff --git a/iidx/bme2ac/old/unz.c b/iidx/bme2ac/old/unz.c new file mode 100644 index 0000000..8f633f3 --- /dev/null +++ b/iidx/bme2ac/old/unz.c @@ -0,0 +1,84 @@ +/** unz.c: Decompress miscellaneous stuff like .INZ and .XZ files */ +#include +#include + +typedef unsigned char u8_t; +typedef unsigned int u32_t; + +static void expand_lzss(FILE *in, FILE *out) +{ + static u8_t ring[0x1000]; + unsigned int ring_pos = 0x0FEE; + unsigned int chunk_offset; + unsigned int chunk_length; + unsigned int length; + u32_t control_word = 1; + u8_t cmd1; + u8_t cmd2; + u8_t byte; + + /* Read header (i.e. file length, ignore it) */ + fread(&length, 4, 1, in); + + while (!feof(in) && length > 0) { + if (control_word == 1) { + /* Read a control byte */ + control_word = 0x100 | getc(in); + } + + /* Decode a byte according to the current control byte bit */ + if (control_word & 1) { + /* Straight copy, store into history ring */ + byte = getc(in); + + putc(byte, out); + ring[ring_pos] = byte; + + ring_pos = (ring_pos + 1) % 0x1000; + length--; + } else { + /* Reference to data in ring buffer */ + cmd1 = getc(in); + cmd2 = getc(in); + + chunk_length = (cmd2 & 0x0F) + 3; + chunk_offset = ((cmd2 & 0xF0) << 4) | cmd1; + + for ( ; chunk_length > 0 && length > 0 ; chunk_length--) { + /* Copy historical data to output AND current ring pos */ + putc(ring[chunk_offset], out); + ring[ring_pos] = ring[chunk_offset]; + + /* Update counters */ + chunk_offset = (chunk_offset + 1) % 0x1000; + ring_pos = (ring_pos + 1) % 0x1000; + length--; + } + } + + /* Get next control bit */ + control_word >>= 1; + } +} + +int main(int argc, char **argv) +{ + FILE *in; + FILE *out; + + if (argc != 3) { + fprintf(stderr, "Usage: %s [infile] [outfile]\n", argv[0]); + return EXIT_FAILURE; + } + + in = fopen(argv[1], "rb"); + out = fopen(argv[2], "wb"); + + expand_lzss(in, out); + + fclose(in); + fclose(out); + + return EXIT_SUCCESS; +} + diff --git a/iidx/crack2dx/crack2dx.c b/iidx/crack2dx/crack2dx.c new file mode 100644 index 0000000..f70df1d --- /dev/null +++ b/iidx/crack2dx/crack2dx.c @@ -0,0 +1,228 @@ +#include +#include +#include +#include + +typedef unsigned char byte; + +const byte keys_09[3][8] = { + { 0x97, 0x1E, 0x24, 0xA0, 0x9A, 0x00, 0x10, 0x2B }, + { 0x91, 0xEF, 0xD7, 0x7A, 0xCD, 0x11, 0xAF, 0xAF }, + { 0x8D, 0x26, 0x5D, 0xBB, 0xE0, 0xC6, 0x1B, 0x2B } +}; + +const byte keys_10[3][8] = { + { 0x2D, 0x86, 0x56, 0x62, 0xD7, 0xFD, 0xCA, 0xA4 }, + { 0xB3, 0x24, 0x60, 0x26, 0x24, 0x81, 0xDB, 0xC2 }, + { 0x57, 0xB1, 0x74, 0x6F, 0xA7, 0x52, 0x99, 0x21 } +}; + +const byte keys_11[3][8] = { + { 0xED, 0xF0, 0x9C, 0x90, 0x44, 0x1A, 0x5A, 0x03 }, + { 0xAB, 0x07, 0xC1, 0x99, 0x23, 0x24, 0x32, 0xC7 }, + { 0x5F, 0x32, 0xA5, 0x97, 0xAD, 0x98, 0x0F, 0x8F } +}; + +byte block[8]; +byte *decrypted, *decpos; + +void die(const byte *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + + exit(EXIT_FAILURE); +} + +void decrypt_common() +{ + byte a = block[0] * 63; + byte b = a + block[3]; + byte c = block[1] * 17; + byte d = c + block[2]; + byte e = d + b; + byte f = e * block[3]; + byte g = f + b + 51; + byte h = b ^ d; + byte i = g ^ e; + + block[4] ^= h; + block[5] ^= d; + block[6] ^= i; + block[7] ^= g; +} + +void decrypt_normal(const byte *key1, const byte *key2, const byte *key3) +{ + byte tmp; + int i; + + for (i = 0 ; i < 8 ; i++) block[i] ^= key1[i]; + decrypt_common(); + + for (i = 0 ; i < 4 ; i++) { + tmp = block[i]; + block[i] = block[i + 4]; + block[i + 4] = tmp; + } + + for (i = 0 ; i < 8 ; i++) block[i] ^= key2[i]; + decrypt_common(); + + for (i = 0 ; i < 8 ; i++) block[i] ^= key3[i]; +} + +void decrypt_09() +{ + decrypt_normal(keys_09[0], keys_09[1], keys_09[2]); +} + +void decrypt_10() +{ + decrypt_normal(keys_10[0], keys_10[1], keys_10[2]); +} + +void decrypt_11() +{ + decrypt_normal(keys_11[0], keys_11[1], keys_11[2]); +} + +void decrypt_12() +{ + byte tmp; + int i; + + for (i = 0 ; i < 8 ; i++) block[i] ^= keys_11[0][i]; + decrypt_common(); + + for (i = 0 ; i < 4 ; i++) { + tmp = block[i]; + block[i] = block[i + 4]; + block[i + 4] = tmp; + } +} + +void decrypt(FILE *in, const char *filename) +{ + void (*decrypt_block)(); + byte curBlock[8], prevBlock[8]; + int i; + + memset(curBlock, 0, 8); + memset(prevBlock, 0, 8); + + switch (block[2]) + { + case 'N': + if (block[3] != 'c') die("%s: Unknown encryption type", filename); + decrypt_block = decrypt_09; + + break; + + case '1': + switch (block[3]) + { + case '0': + decrypt_block = decrypt_10; + break; + + case '1': + decrypt_block = decrypt_11; + break; + + case '2': + decrypt_block = decrypt_12; + break; + + default: + die("%s: Unknown encryption type", filename); + break; + } + + break; + + default: + die("%s: Unknown encryption type", filename); + break; + } + + /* Decrypt loop */ + while (!feof(in)) { + fread(block, 8, 1, in); + memcpy(curBlock, block, 8); + + decrypt_block(); + for (i = 0 ; i < 8 ; i++) { + block[i] ^= prevBlock[i]; + } + + memcpy(decpos, block, 8); + memcpy(prevBlock, curBlock, 8); + + decpos += 8; + } +} + +void extract(int file_num, byte *data) +{ + char filename[16]; + int *length = (int *) (data + 4); + FILE *out; + + sprintf(filename, "%d.wav", file_num); + printf("Dumping %s ...\n", filename); + + out = fopen(filename, "wb"); + fwrite(data, *length + 8, 1, out); + fclose(out); +} + +void split_files() +{ + int *nfiles = (int *) (decrypted + 0x14); + int *toc = (int *) (decrypted + 0x48); + int i; + + for (i = 0 ; i < *nfiles ; i++) { + extract(i + 1, decrypted + toc[i] + 0x18); + } +} + +int main(int argc, byte **argv) +{ + const char *filename = argv[1]; + long length; + FILE *in; + + if (argc != 2) die("Usage: %0 [.2dx input file]", argv[0]); + + in = fopen(filename, "rb"); + if (in == NULL) die("Error opening %s", filename); + + fseek(in, 0, SEEK_END); + length = ftell(in); + fseek(in, 0, SEEK_SET); + + decrypted = malloc(length); + + fread(block, 8, 1, in); + if (block[0] == '%' && block[1] == 'e') { + printf("Decrypting ...\n"); + + decpos = decrypted; + decrypt(in, filename); + } else { + fseek(in, 0, SEEK_SET); + fread(decrypted, length, 1, in); + } + + fclose(in); + split_files(); + + free(decrypted); + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/iidx/crack2dx/crack2dx.exe b/iidx/crack2dx/crack2dx.exe new file mode 100644 index 0000000..55da6cc Binary files /dev/null and b/iidx/crack2dx/crack2dx.exe differ diff --git a/iidx/crack2dx/crack2dx/crack 2dx old/crack2dx.c b/iidx/crack2dx/crack2dx/crack 2dx old/crack2dx.c new file mode 100644 index 0000000..f70df1d --- /dev/null +++ b/iidx/crack2dx/crack2dx/crack 2dx old/crack2dx.c @@ -0,0 +1,228 @@ +#include +#include +#include +#include + +typedef unsigned char byte; + +const byte keys_09[3][8] = { + { 0x97, 0x1E, 0x24, 0xA0, 0x9A, 0x00, 0x10, 0x2B }, + { 0x91, 0xEF, 0xD7, 0x7A, 0xCD, 0x11, 0xAF, 0xAF }, + { 0x8D, 0x26, 0x5D, 0xBB, 0xE0, 0xC6, 0x1B, 0x2B } +}; + +const byte keys_10[3][8] = { + { 0x2D, 0x86, 0x56, 0x62, 0xD7, 0xFD, 0xCA, 0xA4 }, + { 0xB3, 0x24, 0x60, 0x26, 0x24, 0x81, 0xDB, 0xC2 }, + { 0x57, 0xB1, 0x74, 0x6F, 0xA7, 0x52, 0x99, 0x21 } +}; + +const byte keys_11[3][8] = { + { 0xED, 0xF0, 0x9C, 0x90, 0x44, 0x1A, 0x5A, 0x03 }, + { 0xAB, 0x07, 0xC1, 0x99, 0x23, 0x24, 0x32, 0xC7 }, + { 0x5F, 0x32, 0xA5, 0x97, 0xAD, 0x98, 0x0F, 0x8F } +}; + +byte block[8]; +byte *decrypted, *decpos; + +void die(const byte *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + + exit(EXIT_FAILURE); +} + +void decrypt_common() +{ + byte a = block[0] * 63; + byte b = a + block[3]; + byte c = block[1] * 17; + byte d = c + block[2]; + byte e = d + b; + byte f = e * block[3]; + byte g = f + b + 51; + byte h = b ^ d; + byte i = g ^ e; + + block[4] ^= h; + block[5] ^= d; + block[6] ^= i; + block[7] ^= g; +} + +void decrypt_normal(const byte *key1, const byte *key2, const byte *key3) +{ + byte tmp; + int i; + + for (i = 0 ; i < 8 ; i++) block[i] ^= key1[i]; + decrypt_common(); + + for (i = 0 ; i < 4 ; i++) { + tmp = block[i]; + block[i] = block[i + 4]; + block[i + 4] = tmp; + } + + for (i = 0 ; i < 8 ; i++) block[i] ^= key2[i]; + decrypt_common(); + + for (i = 0 ; i < 8 ; i++) block[i] ^= key3[i]; +} + +void decrypt_09() +{ + decrypt_normal(keys_09[0], keys_09[1], keys_09[2]); +} + +void decrypt_10() +{ + decrypt_normal(keys_10[0], keys_10[1], keys_10[2]); +} + +void decrypt_11() +{ + decrypt_normal(keys_11[0], keys_11[1], keys_11[2]); +} + +void decrypt_12() +{ + byte tmp; + int i; + + for (i = 0 ; i < 8 ; i++) block[i] ^= keys_11[0][i]; + decrypt_common(); + + for (i = 0 ; i < 4 ; i++) { + tmp = block[i]; + block[i] = block[i + 4]; + block[i + 4] = tmp; + } +} + +void decrypt(FILE *in, const char *filename) +{ + void (*decrypt_block)(); + byte curBlock[8], prevBlock[8]; + int i; + + memset(curBlock, 0, 8); + memset(prevBlock, 0, 8); + + switch (block[2]) + { + case 'N': + if (block[3] != 'c') die("%s: Unknown encryption type", filename); + decrypt_block = decrypt_09; + + break; + + case '1': + switch (block[3]) + { + case '0': + decrypt_block = decrypt_10; + break; + + case '1': + decrypt_block = decrypt_11; + break; + + case '2': + decrypt_block = decrypt_12; + break; + + default: + die("%s: Unknown encryption type", filename); + break; + } + + break; + + default: + die("%s: Unknown encryption type", filename); + break; + } + + /* Decrypt loop */ + while (!feof(in)) { + fread(block, 8, 1, in); + memcpy(curBlock, block, 8); + + decrypt_block(); + for (i = 0 ; i < 8 ; i++) { + block[i] ^= prevBlock[i]; + } + + memcpy(decpos, block, 8); + memcpy(prevBlock, curBlock, 8); + + decpos += 8; + } +} + +void extract(int file_num, byte *data) +{ + char filename[16]; + int *length = (int *) (data + 4); + FILE *out; + + sprintf(filename, "%d.wav", file_num); + printf("Dumping %s ...\n", filename); + + out = fopen(filename, "wb"); + fwrite(data, *length + 8, 1, out); + fclose(out); +} + +void split_files() +{ + int *nfiles = (int *) (decrypted + 0x14); + int *toc = (int *) (decrypted + 0x48); + int i; + + for (i = 0 ; i < *nfiles ; i++) { + extract(i + 1, decrypted + toc[i] + 0x18); + } +} + +int main(int argc, byte **argv) +{ + const char *filename = argv[1]; + long length; + FILE *in; + + if (argc != 2) die("Usage: %0 [.2dx input file]", argv[0]); + + in = fopen(filename, "rb"); + if (in == NULL) die("Error opening %s", filename); + + fseek(in, 0, SEEK_END); + length = ftell(in); + fseek(in, 0, SEEK_SET); + + decrypted = malloc(length); + + fread(block, 8, 1, in); + if (block[0] == '%' && block[1] == 'e') { + printf("Decrypting ...\n"); + + decpos = decrypted; + decrypt(in, filename); + } else { + fseek(in, 0, SEEK_SET); + fread(decrypted, length, 1, in); + } + + fclose(in); + split_files(); + + free(decrypted); + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/iidx/crack2dx/crack2dx/crack 2dx old/crack2dx.exe b/iidx/crack2dx/crack2dx/crack 2dx old/crack2dx.exe new file mode 100644 index 0000000..55da6cc Binary files /dev/null and b/iidx/crack2dx/crack2dx/crack 2dx old/crack2dx.exe differ diff --git a/iidx/crack2dx/crack2dx/create2dx-kitaru/crack2dx.c b/iidx/crack2dx/crack2dx/create2dx-kitaru/crack2dx.c new file mode 100644 index 0000000..f70df1d --- /dev/null +++ b/iidx/crack2dx/crack2dx/create2dx-kitaru/crack2dx.c @@ -0,0 +1,228 @@ +#include +#include +#include +#include + +typedef unsigned char byte; + +const byte keys_09[3][8] = { + { 0x97, 0x1E, 0x24, 0xA0, 0x9A, 0x00, 0x10, 0x2B }, + { 0x91, 0xEF, 0xD7, 0x7A, 0xCD, 0x11, 0xAF, 0xAF }, + { 0x8D, 0x26, 0x5D, 0xBB, 0xE0, 0xC6, 0x1B, 0x2B } +}; + +const byte keys_10[3][8] = { + { 0x2D, 0x86, 0x56, 0x62, 0xD7, 0xFD, 0xCA, 0xA4 }, + { 0xB3, 0x24, 0x60, 0x26, 0x24, 0x81, 0xDB, 0xC2 }, + { 0x57, 0xB1, 0x74, 0x6F, 0xA7, 0x52, 0x99, 0x21 } +}; + +const byte keys_11[3][8] = { + { 0xED, 0xF0, 0x9C, 0x90, 0x44, 0x1A, 0x5A, 0x03 }, + { 0xAB, 0x07, 0xC1, 0x99, 0x23, 0x24, 0x32, 0xC7 }, + { 0x5F, 0x32, 0xA5, 0x97, 0xAD, 0x98, 0x0F, 0x8F } +}; + +byte block[8]; +byte *decrypted, *decpos; + +void die(const byte *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + + exit(EXIT_FAILURE); +} + +void decrypt_common() +{ + byte a = block[0] * 63; + byte b = a + block[3]; + byte c = block[1] * 17; + byte d = c + block[2]; + byte e = d + b; + byte f = e * block[3]; + byte g = f + b + 51; + byte h = b ^ d; + byte i = g ^ e; + + block[4] ^= h; + block[5] ^= d; + block[6] ^= i; + block[7] ^= g; +} + +void decrypt_normal(const byte *key1, const byte *key2, const byte *key3) +{ + byte tmp; + int i; + + for (i = 0 ; i < 8 ; i++) block[i] ^= key1[i]; + decrypt_common(); + + for (i = 0 ; i < 4 ; i++) { + tmp = block[i]; + block[i] = block[i + 4]; + block[i + 4] = tmp; + } + + for (i = 0 ; i < 8 ; i++) block[i] ^= key2[i]; + decrypt_common(); + + for (i = 0 ; i < 8 ; i++) block[i] ^= key3[i]; +} + +void decrypt_09() +{ + decrypt_normal(keys_09[0], keys_09[1], keys_09[2]); +} + +void decrypt_10() +{ + decrypt_normal(keys_10[0], keys_10[1], keys_10[2]); +} + +void decrypt_11() +{ + decrypt_normal(keys_11[0], keys_11[1], keys_11[2]); +} + +void decrypt_12() +{ + byte tmp; + int i; + + for (i = 0 ; i < 8 ; i++) block[i] ^= keys_11[0][i]; + decrypt_common(); + + for (i = 0 ; i < 4 ; i++) { + tmp = block[i]; + block[i] = block[i + 4]; + block[i + 4] = tmp; + } +} + +void decrypt(FILE *in, const char *filename) +{ + void (*decrypt_block)(); + byte curBlock[8], prevBlock[8]; + int i; + + memset(curBlock, 0, 8); + memset(prevBlock, 0, 8); + + switch (block[2]) + { + case 'N': + if (block[3] != 'c') die("%s: Unknown encryption type", filename); + decrypt_block = decrypt_09; + + break; + + case '1': + switch (block[3]) + { + case '0': + decrypt_block = decrypt_10; + break; + + case '1': + decrypt_block = decrypt_11; + break; + + case '2': + decrypt_block = decrypt_12; + break; + + default: + die("%s: Unknown encryption type", filename); + break; + } + + break; + + default: + die("%s: Unknown encryption type", filename); + break; + } + + /* Decrypt loop */ + while (!feof(in)) { + fread(block, 8, 1, in); + memcpy(curBlock, block, 8); + + decrypt_block(); + for (i = 0 ; i < 8 ; i++) { + block[i] ^= prevBlock[i]; + } + + memcpy(decpos, block, 8); + memcpy(prevBlock, curBlock, 8); + + decpos += 8; + } +} + +void extract(int file_num, byte *data) +{ + char filename[16]; + int *length = (int *) (data + 4); + FILE *out; + + sprintf(filename, "%d.wav", file_num); + printf("Dumping %s ...\n", filename); + + out = fopen(filename, "wb"); + fwrite(data, *length + 8, 1, out); + fclose(out); +} + +void split_files() +{ + int *nfiles = (int *) (decrypted + 0x14); + int *toc = (int *) (decrypted + 0x48); + int i; + + for (i = 0 ; i < *nfiles ; i++) { + extract(i + 1, decrypted + toc[i] + 0x18); + } +} + +int main(int argc, byte **argv) +{ + const char *filename = argv[1]; + long length; + FILE *in; + + if (argc != 2) die("Usage: %0 [.2dx input file]", argv[0]); + + in = fopen(filename, "rb"); + if (in == NULL) die("Error opening %s", filename); + + fseek(in, 0, SEEK_END); + length = ftell(in); + fseek(in, 0, SEEK_SET); + + decrypted = malloc(length); + + fread(block, 8, 1, in); + if (block[0] == '%' && block[1] == 'e') { + printf("Decrypting ...\n"); + + decpos = decrypted; + decrypt(in, filename); + } else { + fseek(in, 0, SEEK_SET); + fread(decrypted, length, 1, in); + } + + fclose(in); + split_files(); + + free(decrypted); + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/iidx/crack2dx/crack2dx/create2dx-kitaru/crack2dx.exe b/iidx/crack2dx/crack2dx/create2dx-kitaru/crack2dx.exe new file mode 100644 index 0000000..e4729e9 Binary files /dev/null and b/iidx/crack2dx/crack2dx/create2dx-kitaru/crack2dx.exe differ diff --git a/iidx/crack2dx/crack2dx/create2dx-kitaru/create2dx.c b/iidx/crack2dx/crack2dx/create2dx-kitaru/create2dx.c new file mode 100644 index 0000000..406f158 --- /dev/null +++ b/iidx/crack2dx/crack2dx/create2dx-kitaru/create2dx.c @@ -0,0 +1,274 @@ +//create2dx.c by Kitaru +//Packs numerically sequenced .wav in folder ./input into an unencrypted .2dx. +//Based on crack2dx.c by Tau and a few chunks from create2dx.c by icex2. +//TODO: add different numbering specifications (BMS, BME, etc.) + +#include +#include +#include +#include + +typedef unsigned char byte; + +const byte keys_09[3][8] = { + { 0x97, 0x1E, 0x24, 0xA0, 0x9A, 0x00, 0x10, 0x2B }, + { 0x91, 0xEF, 0xD7, 0x7A, 0xCD, 0x11, 0xAF, 0xAF }, + { 0x8D, 0x26, 0x5D, 0xBB, 0xE0, 0xC6, 0x1B, 0x2B } +}; + +const byte keys_10[3][8] = { + { 0x2D, 0x86, 0x56, 0x62, 0xD7, 0xFD, 0xCA, 0xA4 }, + { 0xB3, 0x24, 0x60, 0x26, 0x24, 0x81, 0xDB, 0xC2 }, + { 0x57, 0xB1, 0x74, 0x6F, 0xA7, 0x52, 0x99, 0x21 } +}; + +const byte keys_11[3][8] = { + { 0xED, 0xF0, 0x9C, 0x90, 0x44, 0x1A, 0x5A, 0x03 }, + { 0xAB, 0x07, 0xC1, 0x99, 0x23, 0x24, 0x32, 0xC7 }, + { 0x5F, 0x32, 0xA5, 0x97, 0xAD, 0x98, 0x0F, 0x8F } +}; + +const unsigned char aftertoc[24] = { + '2', 'D', 'X', '9', 0x18, 0x00, 0x00, 0x00, 0x5A, 0x07, 0x01, 0x00, 0x30, 0x32, 0xFF, 0xFF, + 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +byte block[8]; +byte *encrypted, *encpos; + +void die(const byte *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + + exit(EXIT_FAILURE); +} +//I guess we could encrypt it eventually, but I found DistorteD doesn't bother to reject non-encrypted .2dx, so I just commented everything out. +/*void encrypt_common() //I guess I need to reverse the operands? +{ + byte a = block[0] * 63; + byte b = a + block[3]; + byte c = block[1] * 17; + byte d = c + block[2]; + byte e = d + b; + byte f = e * block[3]; + byte g = f + b + 51; + byte h = b ^ d; + byte i = g ^ e; + + block[4] ^= h; + block[5] ^= d; + block[6] ^= i; + block[7] ^= g; +} + +void encrypt_normal(const byte *key1, const byte *key2, const byte *key3) +{ + byte tmp; + int i; + + for (i = 0 ; i < 8 ; i++) block[i] ^= key3[i]; + encrypt_common(); + for (i = 0 ; i < 8 ; i++) block[i] ^= key2[i]; + + for (i = 0 ; i < 4 ; i++) { + tmp = block[i]; + block[i] = block[i + 4]; + block[i + 4] = tmp; + } + + encrypt_common(); + for (i = 0 ; i < 8 ; i++) block[i] ^= key1[i]; +} + +void encrypt_09() +{ + encrypt_normal(keys_09[0], keys_09[1], keys_09[2]); +} + +void encrypt_10() +{ + encrypt_normal(keys_10[0], keys_10[1], keys_10[2]); +} + +void encrypt_11() +{ + encrypt_normal(keys_11[0], keys_11[1], keys_11[2]); +} + +void encrypt_12() +{ + byte tmp; + int i; + + for (i = 0 ; i < 4 ; i++) { + tmp = block[i]; + block[i] = block[i + 4]; + block[i + 4] = tmp; + } + encrypt_common(); + + for (i = 0 ; i < 8 ; i++) block[i] ^= keys_11[0][i]; +} + +void encrypt(FILE *in, const char *filename) +{ + void (*encrypt_block)(); + byte curBlock[8], prevBlock[8]; + int i; + + memset(curBlock, 0, 8); + memset(prevBlock, 0, 8); + + encrypt_block = encrypt_12; //eventually you'll be presented with a choice somehow + + while (!feof(in)) { + fread(block, 8, 1, in); + memcpy(curBlock, block, 8); + + encrypt_block(); + for (i = 0 ; i < 8 ; i++) { + block[i] ^= prevBlock[i]; + } + + memcpy(encpos, block, 8); + memcpy(prevBlock, curBlock, 8); + + encpos += 8; + } +}*/ + +int main(int argc, byte **argv) +{ + const char *filename = argv[1]; + long length, length2; + FILE *in; + FILE *out; + byte *buffer; + char path1[511], path2[511]; + int *toc; + + if (argc != 2) die("Usage: %0 [.2dx input file]", argv[0]); + + int i = 0, ii = 0, wav = 0; + char wavc[16]; + + strcpy(path1, argv[0]); + _strrev(path1); + while(path1[i] != '\\') + i++; + while(path1[ii] != '\0') + ii++; + _strrev(path1); + path1[ii - i] = '\0'; + strcat(path1,"input\\"); + + while(1){ + wav++; + printf("%d\n",wav); + //getch(); + strcpy(path2,path1); + sprintf(wavc,"%d.wav",wav); + strcat(path2,wavc); + + in = fopen(path2, "rb"); + if (in == NULL){ + printf("Error opening %s\n", path2); + wav--; + break;} + else{fclose(in); + printf(" OK! %d\n",wav);}} + + in = NULL; + + toc = malloc(wav*sizeof(int)); + length = 0x48 + ((wav) * 4); + + for(i = 0; i < wav; i++){ + strcpy(path2,path1); + sprintf(wavc,"%d.wav",i+1); + strcat(path2,wavc); + + in = fopen(path2, "rb"); + + if (in == NULL){ + printf("Error opening %s\n", path2); + break;} + else{ + printf(" OK! %d\n",i+1); + fseek(in, 0, SEEK_END); + toc[i] = length; + printf("%d\n",toc[i]); + length += ftell(in) + 0x18; + fclose(in);}} + + in = NULL; + + out = fopen(filename, "wb"); + + fseek(out, 0x14, SEEK_SET); + for(i = 0; i < 4; i++) + fprintf(out,"%c",((wav>>(i*8))&255)); + + + fseek(out, 0x48, SEEK_SET); + printf("%d",&toc[0]); + for(i = 1; i < wav+1; i++) + for(ii = 0; ii < 4; ii++){ + fprintf(out,"%c",(((toc[i-1])>>(ii*8))&255));} + + for (i = 0; i < wav; i++) + { + strcpy(path2,path1); + sprintf(wavc,"%d.wav",i+1); + strcat(path2,wavc); + + printf("File %s...", path2); + + in = fopen(path2, "rb"); + fseek(in, 0, SEEK_END); + length2 = ftell(in); + fseek(in, 0, SEEK_SET); + + printf("reading %li...", length2); + buffer = malloc(length2); + fread(buffer, length2, 1, in); + fclose(in); + + fseek(out, 0, SEEK_END); + printf("writing..."); + out = fopen(filename, "ab"); + fwrite(aftertoc, 0x18, 1, out); + fwrite(buffer, length2, 1, out); + fclose(out); + printf("done\n"); + } + + encrypted = malloc(length); + + printf("Encrypting ...\n"); + out = fopen(filename, "rb"); + + fread(block, 8, 1, in); + //encpos = encrypted; + //encrypt(out, filename); + + //out = fopen(filename, "wb"); + //fprintf(out,"%%e12"); + //fseek(out, 0x04, SEEK_SET); + //for(i = 0; i < 4; i++) + //fprintf(out,"%c",((length>>(i*8))&255)); + + //fseek(out, 0x08, SEEK_SET); + //fwrite(encrypted, length, 1, out); + + fclose(out); + //split_files(); + + free(encrypted); + return EXIT_SUCCESS; +} diff --git a/iidx/crack2dx/crack2dx/create2dx-kitaru/create2dx.exe b/iidx/crack2dx/crack2dx/create2dx-kitaru/create2dx.exe new file mode 100644 index 0000000..1628f39 Binary files /dev/null and b/iidx/crack2dx/crack2dx/create2dx-kitaru/create2dx.exe differ diff --git a/iidx/crack2dx/create2dx_dumb.c b/iidx/crack2dx/create2dx_dumb.c new file mode 100644 index 0000000..ca6de51 --- /dev/null +++ b/iidx/crack2dx/create2dx_dumb.c @@ -0,0 +1,135 @@ +//create2dx_dumb.c by kinryuu based on create2dx.c by Kitaru, but aside from some variables not much is left ;D +//Packs BME-style sequenced .wav (01.wav to ZZ.wav, but should work with BMS style 01 - FF as well) in the current folder into an unencrypted output.2dx +//Takes no arguments and always outputs to the same file; only works with uppercase on unix but should work with lowercase on windows (if at all); +//We also assume that the ascending order or the wavefiles equals their order in the corresponding bme/bms file +//...hence "_dumb" + + +#include +#include +#include + +//wav files from 01-0A-0Z-10-ZZ (you get it) = 36*36 - 1 +#define MAXWAVS (36*36-1) + +typedef unsigned char byte; + +const byte aftertoc[24] = { + '2', 'D', 'X', '9', //const string + 0x18, 0x00, 0x00, 0x00, //headersize (== 24) + 0x00, 0x00, 0x00, 0x00, //size of wave file (written at runtime) + 0x30, 0x32, 0xFF, 0xFF, //panning/initial volume? + 0x40, 0x00, 0x08, 0x00, //??? (64, 0, 8, 0) + 0x00, 0x00, 0x00, 0x00 //??? (0, 0, 0, 0) +}; + +typedef struct{ + int length; + byte *data; +} wavefile; + +int main() +{ + //coding while listening to kachoufuusetsu long, hell yeah! + + wavefile waves[MAXWAVS]; //use this to hold the wavefiles; MAYBE I SHOULD NAME THIS SMALL_WAVES ZOMG GET IT? + + FILE *wavfile; + FILE *out; + + char digit1, digit2; //use this to hold the XY of [XY].wav + int wav = 0; //wavefile count + int firstwav = 0; //position of the first wave in the .2dx file (needed in .2dx header) + int pos = 0, i = 0; + + char wavepath[7]; //helperstring; ugly but works + + memset(waves, 0, MAXWAVS*sizeof(wavefile)); + + i = 1; //BME starts counting at 01.wav, how stupid -_- + + while(i <= MAXWAVS) + { + digit1 = i / 36; //works because this floors + if(digit1 > 9) + digit1 += 7; //there's a gap of 8 characters between '9' and 'A' + digit1 += 48; //fancy charactermap magic + + digit2 = i % 36; //mod operator = <3 + if(digit2 > 9) + digit2 += 7; + digit2 += 48; + sprintf(wavepath,"%c%c.wav",digit1,digit2); + + wavfile = fopen(wavepath, "rb"); + if (wavfile != NULL) + { + //open the wave file and save its length and contents to the array + printf("reading %c%c.wav...",digit1,digit2); + fseek(wavfile, 0, SEEK_END); + waves[i-1].length = (int)ftell(wavfile); + fseek(wavfile, 0, SEEK_SET); + printf("length %d...", waves[i-1].length); + + waves[i-1].data = malloc(waves[i-1].length); + + fread(waves[i-1].data, waves[i-1].length, 1, wavfile); + + fclose(wavfile); + wav++; + printf("OK\n"); + } + i++; + } + + if(wav == 0) //learn2placefilesindirectories + { + printf("no wave files found, go die in a fire\n"); + return 0; + } + + printf("\ntotal samplecount: %d\n\n",wav); + + out = fopen("output.2dx", "wb"); //open the 2dx file + + fseek(out, 0x10, SEEK_SET); //ignore the first 16 bytes (TODO: zero them to be sure?) + + firstwav = 72 + wav*4; //first wave position = 2dx header + size of TOC (= wavecount * sizeof(int)) + fwrite(&firstwav, 4, 1, out); //write the position of the first wave file + fwrite(&wav, 4, 1, out); //write the total numbers of waves + + fseek(out, 0x48, SEEK_SET); + + printf("writing TOC..."); + + pos = 0x48 + ((wav) * 4); //start of the wavefiles + //write the table of contents (absolute position of the waves in the .2dx file) + for(i = 0; i < MAXWAVS; i++) + { + if(waves[i].length > 0) //we only want waves with content + { + printf("%d...",pos); + fwrite(&pos, 4, 1, out); + pos += waves[i].length + 0x18; //don't forget about the 24 byte header + } + } + printf("OK!\n\n"); + + //write the actual waves + printf("writing samples..."); + for(i = 0; i < MAXWAVS; i++) + { + if(waves[i].length > 0) + { + printf("%d ", i); + fwrite(aftertoc, 8, 1, out); //"2DX9" + headersize (== 24) + fwrite(&waves[i].length, 4, 1, out); //size of the wave + printf("(%d)...", waves[i].length); + fwrite(aftertoc+12, 12, 1, out); //rest of the header + fwrite(waves[i].data, waves[i].length, 1, out); + } + } + printf("OK!\n"); + fclose(out); + return 0; +} diff --git a/iidx/crack2dx/create2dx_dumb.exe b/iidx/crack2dx/create2dx_dumb.exe new file mode 100644 index 0000000..d57b4ac Binary files /dev/null and b/iidx/crack2dx/create2dx_dumb.exe differ diff --git a/iidx/gczView/gczView.exe b/iidx/gczView/gczView.exe new file mode 100644 index 0000000..9fca95f Binary files /dev/null and b/iidx/gczView/gczView.exe differ diff --git a/iidx/generator/generator.exe b/iidx/generator/generator.exe new file mode 100644 index 0000000..ab5bfd8 Binary files /dev/null and b/iidx/generator/generator.exe differ diff --git a/iidx/generator/generator.sln b/iidx/generator/generator.sln new file mode 100644 index 0000000..292310d --- /dev/null +++ b/iidx/generator/generator.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "generator", "generator\generator.vcproj", "{55B5ABC8-C84C-43AE-B135-E21D7B6B79BE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {55B5ABC8-C84C-43AE-B135-E21D7B6B79BE}.Debug|Win32.ActiveCfg = Debug|Win32 + {55B5ABC8-C84C-43AE-B135-E21D7B6B79BE}.Debug|Win32.Build.0 = Debug|Win32 + {55B5ABC8-C84C-43AE-B135-E21D7B6B79BE}.Release|Win32.ActiveCfg = Release|Win32 + {55B5ABC8-C84C-43AE-B135-E21D7B6B79BE}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/iidx/generator/generator/generator.cpp b/iidx/generator/generator/generator.cpp new file mode 100644 index 0000000..eda124f --- /dev/null +++ b/iidx/generator/generator/generator.cpp @@ -0,0 +1,119 @@ +#include +#include +#include + +using namespace Gdiplus; + +static Bitmap *renderString(const wchar_t *str) +{ + Pen black(Color::Black); + FontFamily font(L"Impact"); + RectF rect(0, 0, 512, 44); + LinearGradientBrush brush(rect, Color(0xFFFFFFFF), Color(0xFF707070), + LinearGradientModeVertical); + GraphicsPath path; + StringFormat fmt; + Rect bounds; + Matrix trans(1, 0, 0, 1, 0, 0); + + // Create path + path.AddString(str, -1, &font, 0, 42, PointF(-8, -8), &fmt); + path.GetBounds(&bounds); + + // Squeeze + if (bounds.Width > 260) { + trans.SetElements(260.0f / bounds.Width, 0, 0, 1, 0, 0); + bounds.Width = 260; + } + + // Allocate + Bitmap *bmp = new Bitmap(bounds.Width, bounds.Height); + Graphics g(bmp); + + // Render path + g.SetSmoothingMode(SmoothingModeAntiAlias); + g.SetTransform(&trans); + g.FillPath(&brush, &path); + g.DrawPath(&black, &path); + + return bmp; +} + +#define put8(f, v) putc(v, f) + +static void put16(FILE *f, SHORT value) +{ + fwrite(&value, 2, 1, f); +} + +static void emitTGA(const char *filename, Bitmap *bmp) +{ + Rect rect(0, 0, bmp->GetWidth(), bmp->GetHeight()); + BitmapData data; + FILE *f; + + f = fopen(filename, "wb"); + if (!f) { + fprintf(stderr, "Could not open %s for writing\n", filename); + exit(-1); + } + + // Put TGA header + put8(f, 0); put8(f, 0); put8(f, 2); + put16(f, 0); put16(f, 0); put8(f, 0); + put16(f, 0); put16(f, 0); put16(f, bmp->GetWidth()); put16(f, bmp->GetHeight()); + put8(f, 32); put8(f, 0x28); + + // Put pixels + bmp->LockBits(&rect, ImageLockModeRead, PixelFormat32bppARGB, &data); + fwrite(data.Scan0, 4, rect.Width * rect.Height, f); + + // Clean up + bmp->UnlockBits(&data); + fclose(f); +} + +int main(int argc, char **argv) +{ + GdiplusStartupInput start; + ULONG_PTR token; + Bitmap *bmp; + wchar_t wbuf[512]; + char filename[512]; + char buf[512]; + char *text; + char *id; + FILE *f; + + if (argc != 3) { + fprintf(stderr, "Usage: %s [infile] [outdir]\n", argv[0]); + return -1; + } + + GdiplusStartup(&token, &start, NULL); + f = fopen(argv[1], "r"); + + while (true) { + // Get line + fgets(buf, 512, f); + if (feof(f)) break; + + // Toke + id = strtok(buf, "|\r\n"); + text = strtok(NULL, "|\r\n"); + + // Render string + printf("Generating %s ...\n", id); + mbstowcs(wbuf, text, 512); + bmp = renderString(wbuf); + + // Emit TGA + sprintf(filename, "%s/%s.tga", argv[2], id); + emitTGA(filename, bmp); + + // Clean up + delete bmp; + } + + return 0; +} diff --git a/iidx/generator/generator/generator.vcproj b/iidx/generator/generator/generator.vcproj new file mode 100644 index 0000000..6ef6e3c --- /dev/null +++ b/iidx/generator/generator/generator.vcproj @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iidx/generator/input.txt b/iidx/generator/input.txt new file mode 100644 index 0000000..0599bd6 --- /dev/null +++ b/iidx/generator/input.txt @@ -0,0 +1,64 @@ +T_2DX|IIDX +T_9CLOCK|9 O'Clocks +T_ADVANC|ADVANCE +T_ALLRIG|ALL RIGHT +T_AY_CARUMBA|ay carumba!! +T_BDOWN|BRING HER DOWN +T_BEDAYS|Beautiful Days +T_BFOYOU|BALLAD FOR YOU +T_BIGGES|The Biggest Roaster +T_BUFYOU|BURNING UP FOR YOU +T_CMUSIC|CLOUDY MUSIC +T_COMEW|Come With Me +T_DEADLI|Deadline +T_DISSOL|dissolve +T_DROWIN|LOVE IS DROWING +T_DTEPO1|dong-tepo no. 1 +T_ENTRAN|entrance +T_EVCAFE|E.V CAFE +T_FANTAS|FANTASY +T_FAWAY|Fly Away (Instrumental) +T_FBP|FUNKY BINGO PARADISE +T_FLUTEM|FLUTE MAN +T_FUN|fun +T_GENERA|General Relativity +T_GMIYS|Get me in your sight +T_HBEAT|HEARTBEAT +T_HBGATE|HYPER BOUNDARY GATE +T_HEADAC|Headache +T_HHIKER|Hitch Hiker +T_HONEY|Honey +T_HORMIG|Hormiga obrera +T_ICF58|I.C.F.5800 +T_JAM|JAM +T_JELLYK|jelly kiss +T_LETSRU|Let's run +T_LGENER|LOVE GENERATION +T_LUV2|Luv 2 Feel Your Body +T_NWYORK|New York +T_OLIMIT|OUTER LIMITS +T_OTCMIX|OVER THE CLOUDS Rmx +T_PDREAM|POWER DREAM +T_R80S|route 80s +T_REMEMB|REMEMBER ME +T_ROMEO|ROMEO&JULIET +T_RTRB|Ready To Rockit Blues +T_SAVAGE|SWEETEST SAVAGE +T_SCLONE|Small clone +T_SCORE|SCORE +T_SGOLD|SOLID GOLD +T_SHAKIN|Shakin' 31 +T_SILHOE|Silhoette of My Mind +T_SMOKE|Smoke +T_SNOW|SNOW +T_SOFTL|SOFT LANDING ON THE BODY +T_SOMEBO|Somebody Like You +T_STARDR|STAR DREAM +T_STICKA|Stick Around +T_STM3|SPEED TRANCE MACH 3 +T_SWITCH|SWITCH +T_TBEOFS|The Beauty Of Silence +T_TRIBAL|TRIBAL MASTER +T_WOW70S|Wow Wow 70's +T_WTTW|WANNA TELL THAT WORD +T_YESTER|YESTERDAY diff --git a/iidx/idxEdit/idxEdit.exe b/iidx/idxEdit/idxEdit.exe new file mode 100644 index 0000000..75b3596 Binary files /dev/null and b/iidx/idxEdit/idxEdit.exe differ diff --git a/iidx/idxEdit/readme.txt b/iidx/idxEdit/readme.txt new file mode 100644 index 0000000..e781327 --- /dev/null +++ b/iidx/idxEdit/readme.txt @@ -0,0 +1,47 @@ +–¼‘O idxEdit +ƒo�[ƒWƒ‡ƒ“ 0.2 + + +�š‚Ȃɂ±‚ê +DDˆÈŠO‚Ìidx‚ð•Ò�W‚µ‚½‚è�Apng - bmp - gc - gcz ‚Ì‘ŠŒÝ•ÏŠ·‚·‚éƒc�[ƒ‹�B + + +�š‹ï‘Ì“I‚ɉ½‚ª‚Å‚«‚é‚Ì +�E“Ç‚Ý�ž‚Ý +png : ‘½•ª‚Ù‚Æ‚ñ‚ǓǂÝ�ž‚ß‚é�BŠe�F‰ºˆÊ3bit‚Í�Ø‚èŽÌ‚Ä +bmp : 24bit ‚Æ 32bit ‚̃rƒbƒgƒ}ƒbƒv‚È‚ç“Ç‚Ý�ž‚ß‚é�BŠe�F‰ºˆÊ3bit‚Í�Ø‚èŽÌ‚Ä +gc : ‰Â +gcz : ‰Â + +�E�‘‚«�o‚µ +png : 32bit�[“x‚Ì“§‰ßpng +bmp : 24bit�[“x‚̃rƒbƒgƒ}ƒbƒv +gc : ‰Â +gcz : ŽžŠÔ‚©‚©‚é�BSig‚½‚ñ‚Å‚à’­‚߂Ȃª‚炨‘Ò‚¿‰º‚³‚¢�B + +�Eidxƒtƒ@ƒCƒ‹ +ˆµ‚¦‚é‚͓̂ǂÝ�ž‚Þgczƒtƒ@ƒCƒ‹–¼‚Æ�A�؂蔲‚«‚Ì�î•ñ‚Ì‚Ý�B +‚Å‚àˆµ‚¦‚È‚¢�î•ñ‚à‚¿‚á‚ñ‚ƕێ�‚·‚é‚Ì‚Å�Aˆµ‚¦‚È‚¢�î•ñ‚ðŠÜ‚Þidx‚Ì•Ò�W‚à‰Â”\�B + +‚ ‚Æ�A�؂蔲‚«‚̈ꊇ•Û‘¶‚à�o—ˆ‚Ü‚·�B + + +�š‚Ç‚¤‚â‚Á‚ÄŽg‚¤‚Ì +‚¾‚¢‚½‚¢ƒXƒe�[ƒ^ƒXƒo�[Œ©‚Ä—�‰ð‚µ‚Ăقµ‚¢‚ñ‚Å‚·‚ª�Aˆê‰ž‚¢‚­‚‚©�à–¾�B + +idx‚ðŠJ‚¢‚½Žž‚É�o‚Ä‚­‚é�¶‘¤‚̃c�[ƒ‹‚ɂ‚¢‚Ä�B +�uƒNƒŠƒbƒsƒ“ƒO�vƒ^ƒu‚Å�A�؂蔲‚«�À•W‚Ì•Ò�W‚ð‚µ‚Ü‚·�B‚µ‚©‚µ‚±‚êƒAƒ“ƒhƒD‚ª–³‚¢‚̂Š+‚¤‚©‚‚ɉ摜‚Ì•ûƒNƒŠƒbƒN‚µ‚È‚¢‚ʼnº‚³‚¢�B‘I‘ð”͈͂ª•Ï�X‚³‚ê‚Ä‚µ‚Ü‚¢‚Ü‚·�B + +�ugczƒtƒ@ƒCƒ‹�vƒ^ƒu‚Å�A“Ç‚Ý�ž‚Þgczƒtƒ@ƒCƒ‹‚Ì•Ò�W‚ð‚µ‚Ü‚·�B +’Ê�í‚ÍŽQ�ƃ{ƒ^ƒ“‚ÅgraphƒtƒHƒ‹ƒ_‚ðŽw’肵‚Ä‚¨‚¯‚Î�Agczƒtƒ@ƒCƒ‹‚̃pƒX‚©‚ç +Ž©“®“I‚Égczƒtƒ@ƒCƒ‹‚ðŒŸ�õ‚µ‚ĉæ–ʂɕ\ަ‚µ‚Ü‚·�B +‚±‚̃tƒHƒ‹ƒ_‚̃pƒX‚͕ۑ¶‚³‚ê‚Ü‚¹‚ñ�Bgczƒtƒ@ƒCƒ‹‚ð’T‚·‚̂Ɏg‚¤‚¾‚¯‚Å‚·�B + +�u•s–¾‚È�€–Ú�vƒ^ƒu‚É‚ ‚é�A�u‰ð�͂ł«‚È‚¢�î•ñ‚ð�í�œ�v‚̃{ƒ^ƒ“‚ð‰Ÿ‚µ‚Ä +Šm”F‰æ–Ê‚ÅOK‚ð‰Ÿ‚·‚Æ�A�uƒNƒŠƒbƒsƒ“ƒO�vƒ^ƒu‚Æ�ugczƒtƒ@ƒCƒ‹�vƒ^ƒu‚Ì�î•ñˆÈŠO‚Ì +�€–Ú‚ð�í�œ‚µ‚Ü‚·�B‚ ‚ñ‚ÜŽg‚¤‚±‚Æ–³‚¢‚ÆŽv‚¢‚Ü‚·�B + + +�š‚²ˆÓŒ©‚²—v–] +ƒXƒŒ‚É‚Ä�B‹C‚Ü‚®‚ê‚Å�X�V diff --git a/iidx/old 2dx tools/crack2dx.c b/iidx/old 2dx tools/crack2dx.c new file mode 100644 index 0000000..f77a052 --- /dev/null +++ b/iidx/old 2dx tools/crack2dx.c @@ -0,0 +1,130 @@ +/* crack2dx.c: Descramble a .2DX (sound archive) file */ +#include +#include +#include + +typedef unsigned char byte; + +const byte keys_09[] = { + 0x97, 0x1E, 0x24, 0xA0, 0x9A, 0x00, 0x10, 0x2B, + 0x91, 0xEF, 0xD7, 0x7A, 0xCD, 0x11, 0xAF, 0xAF, + 0x8D, 0x26, 0x5D, 0xBB, 0xE0, 0xC6, 0x1B, 0x2B +}; + +const byte keys_10[] = { + 0x2D, 0x86, 0x56, 0x62, 0xD7, 0xFD, 0xCA, 0xA4, + 0xB3, 0x24, 0x60, 0x26, 0x24, 0x81, 0xDB, 0xC2, + 0x57, 0xB1, 0x74, 0x6F, 0xA7, 0x52, 0x99, 0x21 +}; + +const byte keys_11[] = { + 0xED, 0xF0, 0x9C, 0x90, 0x44, 0x1A, 0x5A, 0x03, + 0xAB, 0x07, 0xC1, 0x99, 0x23, 0x24, 0x32, 0xC7, + 0x5F, 0x32, 0xA5, 0x97, 0xAD, 0x98, 0x0F, 0x8F +}; + +/** :gonk: */ +static void mix(byte block[8]) +{ + byte a = block[0] * 63; + byte b = a + block[3]; + byte c = block[1] * 17; + byte d = c + block[2]; + byte e = d + b; + byte f = e * block[3]; + byte g = f + b + 51; + byte h = b ^ d; + byte i = g ^ e; + + block[4] ^= h; + block[5] ^= d; + block[6] ^= i; + block[7] ^= g; +} + +/** Descrambling loop */ +static void descramble(FILE *in, FILE *out, const byte key[24], int full) +{ + byte prev_sblock[8]; + byte cur_sblock[8]; + byte block[8]; + byte tmp; + int i; + + while (!feof(in)) { + fread(block, 8, 1, in); + memcpy(cur_sblock, block, 8); + + for (i = 0 ; i < 8 ; i++) block[i] ^= key[i]; + mix(block); + + for (i = 0 ; i < 4 ; i++) { + tmp = block[i]; + block[i] = block[i + 4]; + block[i + 4] = tmp; + } + + if (full) { + for (i = 0 ; i < 8 ; i++) block[i] ^= key[8 + i]; + mix(block); + + for (i = 0 ; i < 8 ; i++) block[i] ^= key[16 + i]; + } + + for (i = 0 ; i < 8 ; i++) { + block[i] ^= prev_sblock[i]; + } + + memcpy(prev_sblock, cur_sblock, 8); + fwrite(block, 8, 1, out); + } +} + +/** Entry point */ +int main(int argc, char **argv) +{ + byte hdr[8]; + FILE *out; + FILE *in; + + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return EXIT_FAILURE; + } + + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "%s: Could not open file for input\n", argv[1]); + return EXIT_FAILURE; + } + + out = fopen(argv[2], "wb"); + if (!out) { + fprintf(stderr, "%s: Could not open file for output\n", argv[2]); + return EXIT_FAILURE; + } + + fread(hdr, 8, 1, in); + if (memcmp(hdr, "%eNc", 4) == 0) { + descramble(in, out, keys_09, 1); + + } else if (memcmp(hdr, "%e10", 4) == 0) { + descramble(in, out, keys_10, 1); + + } else if (memcmp(hdr, "%e11", 4) == 0) { + descramble(in, out, keys_11, 1); + + } else if (memcmp(hdr, "%e12", 4) == 0 || memcmp(hdr, "%hid", 4) == 0) { + descramble(in, out, keys_11, 0); + + } else { + fprintf(stderr, + "Unknown scrambling type, probably not a scrambled file.\n"); + return EXIT_FAILURE; + } + + fclose(out); + fclose(in); + return EXIT_SUCCESS; +} + diff --git a/iidx/old 2dx tools/crackeout.c b/iidx/old 2dx tools/crackeout.c new file mode 100644 index 0000000..73c33ca --- /dev/null +++ b/iidx/old 2dx tools/crackeout.c @@ -0,0 +1,126 @@ +/* crackeout.c: Descramble DATA\INFO\EOUT.BIN. This is a song list file of + * sorts. Alter the indicated line in main() to turn it into a rescrambler. */ +#include +#include +#include + +#define ONE_BILLION 1000000000 +#define IDX_CURRENT_KEY 55 +#define IDX_COUNTER 56 +#define IDX_LAST 57 + +typedef unsigned char byte; + +static void mix(int *state) +{ + int tmp; + int i; + + for (i = 1 ; i < 25 ; i++) { + tmp = state[i]; + tmp -= state[i + 31]; + + if (tmp < 0) tmp += ONE_BILLION; + state[i] = tmp; + } + + for (i = 25 ; i <= IDX_CURRENT_KEY ; i++) { + tmp = state[i]; + tmp -= state[i - 24]; + + if (tmp < 0) tmp += ONE_BILLION; + state[i] = tmp; + } +} + +static void update_state(int *state, byte src_byte) +{ + int src; + int tmp; + int i; + + src = src_byte; + tmp = 1; + + state[IDX_CURRENT_KEY] = src; + + for (i = 0x15 ; i <= 0x46E ; i += 0x15) { + src -= tmp; + state[i % 0x37] = tmp; + tmp = src; + + if (tmp < 0) tmp += ONE_BILLION; + src = state[i % 0x37]; + } + + mix(state); + mix(state); + mix(state); + + state[IDX_COUNTER] = 0x37; +} + +static byte produce_key(int *state) +{ + int counter; + + counter = state[IDX_COUNTER] + 1; + state[IDX_COUNTER] = counter; + + if (counter > 0x37) { + mix(state); + counter = 1; + } + + state[IDX_COUNTER] = counter; + return state[counter]; +} + +int main(int argc, char **argv) +{ + static const byte key[] = { + 0x55, 0x37, 0x9F, 0xCC, 0xE3, 0xA7, 0x7D, 0x99, + 0xDD, 0xAA, 0xBB, 0xCF, 0xFC, 0x67, 0x43, 0x17 + }; + + FILE *in; + FILE *out; + int state[IDX_LAST]; + int quo; + int rem; + int i; + byte b; + + /* Usage */ + if (argc != 3) { + fprintf(stderr, "Usage: %s [infile] [outfile]\n", argv[0]); + return EXIT_FAILURE; + } + + /* Setup */ + i = 0; + memset(state, 0, sizeof(state)); + in = fopen(argv[1], "rb"); + out = fopen(argv[2], "wb"); + + /* Descramble */ + while (!feof(in)) { + quo = i / 0x10; + rem = i % 0x10; + i++; + + if (rem == 0) update_state(state, key[quo % 0x10]); + + b = getc(in); + b -= produce_key(state); + /* To rescramble an eout.bin, change -= above to += */ + + putc(b, out); + } + + /* Cleanup */ + fclose(in); + fclose(out); + return EXIT_SUCCESS; +} + diff --git a/iidx/old 2dx tools/crackgcz.c b/iidx/old 2dx tools/crackgcz.c new file mode 100644 index 0000000..3893b36 --- /dev/null +++ b/iidx/old 2dx tools/crackgcz.c @@ -0,0 +1,792 @@ +/* crackgcz.c: Decrypt a IIDX 13 DistorteD AC GCZ file into the pre-DistorteD + * format. + * + * Don't expect any meaningful function or variable names, because none of this + * makes much sense. "Seeds" are the starting constants given below, "Keys" are + * produced by combining seeds with the filename via a rather convoluted + * process, and "States" are any values in between. + * + * The base name of the input file (i.e. the path of the input file stripped + * of directories and its extension) forms part of the encryption key, so make + * sure this is preserved, or decryption will fail. For example, the basename + * of the path "data/graph/sys/mdata/4.gcz" is the string "4". */ + +#include +#include +#include + +typedef unsigned int u32_t; +typedef unsigned char u8_t; + +/* Key data. May change in GOLD etc */ +static const u8_t seed1[] = "tukupypy"; +static const u8_t seed2[] = "omE872M2akmRkERh4177S"; +static const u8_t seed3[] = { + 0x88, 0x6A, 0x3F, 0x24, 0xD3, 0x08, 0xA3, 0x85, 0x2E, 0x8A, + 0x19, 0x13, 0x44, 0x73, 0x70, 0x03, 0x22, 0x38, 0x09, 0xA4, + 0xD0, 0x31, 0x9F, 0x29, 0x98, 0xFA, 0x2E, 0x08, 0x89, 0x6C, + 0x4E, 0xEC, 0xE6, 0x21, 0x28, 0x45, 0x77, 0x13, 0xD0, 0x38, + 0xCF, 0x66, 0x54, 0xBE, 0x6C, 0x0C, 0xE9, 0x34, 0xB7, 0x29, + 0xAC, 0xC0, 0xDD, 0x50, 0x7C, 0xC9, 0xB5, 0xD5, 0x84, 0x3F, + 0x17, 0x09, 0x47, 0xB5, 0xD9, 0xD5, 0x16, 0x92, 0x1B, 0xFB, + 0x79, 0x89, 0xA6, 0x0B, 0x31, 0xD1, 0xAC, 0xB5, 0xDF, 0x98, + 0xDB, 0x72, 0xFD, 0x2F, 0xB7, 0xDF, 0x1A, 0xD0, 0xED, 0xAF, + 0xE1, 0xB8, 0x96, 0x7E, 0x26, 0x6A, 0x45, 0x90, 0x7C, 0xBA, + 0x99, 0x7F, 0x2C, 0xF1, 0x47, 0x99, 0xA1, 0x24, 0xF7, 0x6C, + 0x91, 0xB3, 0xE2, 0xF2, 0x01, 0x08, 0x16, 0xFC, 0x8E, 0x85, + 0xD8, 0x20, 0x69, 0x63, 0x69, 0x4E, 0x57, 0x71, 0xA3, 0xFE, + 0x58, 0xA4, 0x7E, 0x3D, 0x93, 0xF4, 0x8F, 0x74, 0x95, 0x0D, + 0x58, 0xB6, 0x8E, 0x72, 0x58, 0xCD, 0x8B, 0x71, 0xEE, 0x4A, + 0x15, 0x82, 0x1D, 0xA4, 0x54, 0x7B, 0xB5, 0x59, 0x5A, 0xC2, + 0x39, 0xD5, 0x30, 0x9C, 0x13, 0x60, 0xF2, 0x2A, 0x23, 0xB0, + 0xD1, 0xC5, 0xF0, 0x85, 0x60, 0x28, 0x18, 0x79, 0x41, 0xCA, + 0xEF, 0x38, 0xDB, 0xB8, 0xB0, 0xDC, 0x79, 0x8E, 0x0E, 0x18, + 0x3A, 0x60, 0x8B, 0x0E, 0x9E, 0x6C, 0x3E, 0x8A, 0x1E, 0xB0, + 0xC1, 0x77, 0x15, 0xD7, 0x27, 0x4B, 0x31, 0xBD, 0xDA, 0x2F, + 0xAF, 0x78, 0x60, 0x5C, 0x60, 0x55, 0xF3, 0x25, 0x55, 0xE6, + 0x94, 0xAB, 0x55, 0xAA, 0x62, 0x98, 0x48, 0x57, 0x40, 0x14, + 0xE8, 0x63, 0x6A, 0x39, 0xCA, 0x55, 0xB6, 0x10, 0xAB, 0x2A, + 0x34, 0x5C, 0xCC, 0xB4, 0xCE, 0xE8, 0x41, 0x11, 0xAF, 0x86, + 0x54, 0xA1, 0x93, 0xE9, 0x72, 0x7C, 0x11, 0x14, 0xEE, 0xB3, + 0x2A, 0xBC, 0x6F, 0x63, 0x5D, 0xC5, 0xA9, 0x2B, 0xF6, 0x31, + 0x18, 0x74, 0x16, 0x3E, 0x5C, 0xCE, 0x1E, 0x93, 0x87, 0x9B, + 0x33, 0xBA, 0xD6, 0xAF, 0x5C, 0xCF, 0x24, 0x6C, 0x81, 0x53, + 0x32, 0x7A, 0x77, 0x86, 0x95, 0x28, 0x98, 0x48, 0x8F, 0x3B, + 0xAF, 0xB9, 0x4B, 0x6B, 0x1B, 0xE8, 0xBF, 0xC4, 0x93, 0x21, + 0x28, 0x66, 0xCC, 0x09, 0xD8, 0x61, 0x91, 0xA9, 0x21, 0xFB, + 0x60, 0xAC, 0x7C, 0x48, 0x32, 0x80, 0xEC, 0x5D, 0x5D, 0x5D, + 0x84, 0xEF, 0xB1, 0x75, 0x85, 0xE9, 0x02, 0x23, 0x26, 0xDC, + 0x88, 0x1B, 0x65, 0xEB, 0x81, 0x3E, 0x89, 0x23, 0xC5, 0xAC, + 0x96, 0xD3, 0xF3, 0x6F, 0x6D, 0x0F, 0x39, 0x42, 0xF4, 0x83, + 0x82, 0x44, 0x0B, 0x2E, 0x04, 0x20, 0x84, 0xA4, 0x4A, 0xF0, + 0xC8, 0x69, 0x5E, 0x9B, 0x1F, 0x9E, 0x42, 0x68, 0xC6, 0x21, + 0x9A, 0x6C, 0xE9, 0xF6, 0x61, 0x9C, 0x0C, 0x67, 0xF0, 0x88, + 0xD3, 0xAB, 0xD2, 0xA0, 0x51, 0x6A, 0x68, 0x2F, 0x54, 0xD8, + 0x28, 0xA7, 0x0F, 0x96, 0xA3, 0x33, 0x51, 0xAB, 0x6C, 0x0B, + 0xEF, 0x6E, 0xE4, 0x3B, 0x7A, 0x13, 0x50, 0xF0, 0x3B, 0xBA, + 0x98, 0x2A, 0xFB, 0x7E, 0x1D, 0x65, 0xF1, 0xA1, 0x76, 0x01, + 0xAF, 0x39, 0x3E, 0x59, 0xCA, 0x66, 0x88, 0x0E, 0x43, 0x82, + 0x19, 0x86, 0xEE, 0x8C, 0xB4, 0x9F, 0x6F, 0x45, 0xC3, 0xA5, + 0x84, 0x7D, 0xBE, 0x5E, 0x8B, 0x3B, 0xD8, 0x75, 0x6F, 0xE0, + 0x73, 0x20, 0xC1, 0x85, 0x9F, 0x44, 0x1A, 0x40, 0xA6, 0x6A, + 0xC1, 0x56, 0x62, 0xAA, 0xD3, 0x4E, 0x06, 0x77, 0x3F, 0x36, + 0x72, 0xDF, 0xFE, 0x1B, 0x3D, 0x02, 0x9B, 0x42, 0x24, 0xD7, + 0xD0, 0x37, 0x48, 0x12, 0x0A, 0xD0, 0xD3, 0xEA, 0x0F, 0xDB, + 0x9B, 0xC0, 0xF1, 0x49, 0xC9, 0x72, 0x53, 0x07, 0x7B, 0x1B, + 0x99, 0x80, 0xD8, 0x79, 0xD4, 0x25, 0xF7, 0xDE, 0xE8, 0xF6, + 0x1A, 0x50, 0xFE, 0xE3, 0x3B, 0x4C, 0x79, 0xB6, 0xBD, 0xE0, + 0x6C, 0x97, 0xBA, 0x06, 0xC0, 0x04, 0xB6, 0x4F, 0xA9, 0xC1, + 0xC4, 0x60, 0x9F, 0x40, 0xC2, 0x9E, 0x5C, 0x5E, 0x63, 0x24, + 0x6A, 0x19, 0xAF, 0x6F, 0xFB, 0x68, 0xB5, 0x53, 0x6C, 0x3E, + 0xEB, 0xB2, 0x39, 0x13, 0x6F, 0xEC, 0x52, 0x3B, 0x1F, 0x51, + 0xFC, 0x6D, 0x2C, 0x95, 0x30, 0x9B, 0x44, 0x45, 0x81, 0xCC, + 0x09, 0xBD, 0x5E, 0xAF, 0x04, 0xD0, 0xE3, 0xBE, 0xFD, 0x4A, + 0x33, 0xDE, 0x07, 0x28, 0x0F, 0x66, 0xB3, 0x4B, 0x2E, 0x19, + 0x57, 0xA8, 0xCB, 0xC0, 0x0F, 0x74, 0xC8, 0x45, 0x39, 0x5F, + 0x0B, 0xD2, 0xDB, 0xFB, 0xD3, 0xB9, 0xBD, 0xC0, 0x79, 0x55, + 0x0A, 0x32, 0x60, 0x1A, 0xC6, 0x00, 0xA1, 0xD6, 0x79, 0x72, + 0x2C, 0x40, 0xFE, 0x25, 0x9F, 0x67, 0xCC, 0xA3, 0x1F, 0xFB, + 0xF8, 0xE9, 0xA5, 0x8E, 0xF8, 0x22, 0x32, 0xDB, 0xDF, 0x16, + 0x75, 0x3C, 0x15, 0x6B, 0x61, 0xFD, 0xC8, 0x1E, 0x50, 0x2F, + 0xAB, 0x52, 0x05, 0xAD, 0xFA, 0xB5, 0x3D, 0x32, 0x60, 0x87, + 0x23, 0xFD, 0x48, 0x7B, 0x31, 0x53, 0x82, 0xDF, 0x00, 0x3E, + 0xBB, 0x57, 0x5C, 0x9E, 0xA0, 0x8C, 0x6F, 0xCA, 0x2E, 0x56, + 0x87, 0x1A, 0xDB, 0x69, 0x17, 0xDF, 0xF6, 0xA8, 0x42, 0xD5, + 0xC3, 0xFF, 0x7E, 0x28, 0xC6, 0x32, 0x67, 0xAC, 0x73, 0x55, + 0x4F, 0x8C, 0xB0, 0x27, 0x5B, 0x69, 0xC8, 0x58, 0xCA, 0xBB, + 0x5D, 0xA3, 0xFF, 0xE1, 0xA0, 0x11, 0xF0, 0xB8, 0x98, 0x3D, + 0xFA, 0x10, 0xB8, 0x83, 0x21, 0xFD, 0x6C, 0xB5, 0xFC, 0x4A, + 0x5B, 0xD3, 0xD1, 0x2D, 0x79, 0xE4, 0x53, 0x9A, 0x65, 0x45, + 0xF8, 0xB6, 0xBC, 0x49, 0x8E, 0xD2, 0x90, 0x97, 0xFB, 0x4B, + 0xDA, 0xF2, 0xDD, 0xE1, 0x33, 0x7E, 0xCB, 0xA4, 0x41, 0x13, + 0xFB, 0x62, 0xE8, 0xC6, 0xE4, 0xCE, 0xDA, 0xCA, 0x20, 0xEF, + 0x01, 0x4C, 0x77, 0x36, 0xFE, 0x9E, 0x7E, 0xD0, 0xB4, 0x1F, + 0xF1, 0x2B, 0x4D, 0xDA, 0xDB, 0x95, 0x98, 0x91, 0x90, 0xAE, + 0x71, 0x8E, 0xAD, 0xEA, 0xA0, 0xD5, 0x93, 0x6B, 0xD0, 0xD1, + 0x8E, 0xD0, 0xE0, 0x25, 0xC7, 0xAF, 0x2F, 0x5B, 0x3C, 0x8E, + 0xB7, 0x94, 0x75, 0x8E, 0xFB, 0xE2, 0xF6, 0x8F, 0x64, 0x2B, + 0x12, 0xF2, 0x12, 0xB8, 0x88, 0x88, 0x1C, 0xF0, 0x0D, 0x90, + 0xA0, 0x5E, 0xAD, 0x4F, 0x1C, 0xC3, 0x8F, 0x68, 0x91, 0xF1, + 0xCF, 0xD1, 0xAD, 0xC1, 0xA8, 0xB3, 0x18, 0x22, 0x2F, 0x2F, + 0x77, 0x17, 0x0E, 0xBE, 0xFE, 0x2D, 0x75, 0xEA, 0xA1, 0x1F, + 0x02, 0x8B, 0x0F, 0xCC, 0xA0, 0xE5, 0xE8, 0x74, 0x6F, 0xB5, + 0xD6, 0xF3, 0xAC, 0x18, 0x99, 0xE2, 0x89, 0xCE, 0xE0, 0x4F, + 0xA8, 0xB4, 0xB7, 0xE0, 0x13, 0xFD, 0x81, 0x3B, 0xC4, 0x7C, + 0xD9, 0xA8, 0xAD, 0xD2, 0x66, 0xA2, 0x5F, 0x16, 0x05, 0x77, + 0x95, 0x80, 0x14, 0x73, 0xCC, 0x93, 0x77, 0x14, 0x1A, 0x21, + 0x65, 0x20, 0xAD, 0xE6, 0x86, 0xFA, 0xB5, 0x77, 0xF5, 0x42, + 0x54, 0xC7, 0xCF, 0x35, 0x9D, 0xFB, 0x0C, 0xAF, 0xCD, 0xEB, + 0xA0, 0x89, 0x3E, 0x7B, 0xD3, 0x1B, 0x41, 0xD6, 0x49, 0x7E, + 0x1E, 0xAE, 0x2D, 0x0E, 0x25, 0x00, 0x5E, 0xB3, 0x71, 0x20, + 0xBB, 0x00, 0x68, 0x22, 0xAF, 0xE0, 0xB8, 0x57, 0x9B, 0x36, + 0x64, 0x24, 0x1E, 0xB9, 0x09, 0xF0, 0x1D, 0x91, 0x63, 0x55, + 0xAA, 0xA6, 0xDF, 0x59, 0x89, 0x43, 0xC1, 0x78, 0x7F, 0x53, + 0x5A, 0xD9, 0xA2, 0x5B, 0x7D, 0x20, 0xC5, 0xB9, 0xE5, 0x02, + 0x76, 0x03, 0x26, 0x83, 0xA9, 0xCF, 0x95, 0x62, 0x68, 0x19, + 0xC8, 0x11, 0x41, 0x4A, 0x73, 0x4E, 0xCA, 0x2D, 0x47, 0xB3, + 0x4A, 0xA9, 0x14, 0x7B, 0x52, 0x00, 0x51, 0x1B, 0x15, 0x29, + 0x53, 0x9A, 0x3F, 0x57, 0x0F, 0xD6, 0xE4, 0xC6, 0x9B, 0xBC, + 0x76, 0xA4, 0x60, 0x2B, 0x00, 0x74, 0xE6, 0x81, 0xB5, 0x6F, + 0xBA, 0x08, 0x1F, 0xE9, 0x1B, 0x57, 0x6B, 0xEC, 0x96, 0xF2, + 0x15, 0xD9, 0x0D, 0x2A, 0x21, 0x65, 0x63, 0xB6, 0xB6, 0xF9, + 0xB9, 0xE7, 0x2E, 0x05, 0x34, 0xFF, 0x64, 0x56, 0x85, 0xC5, + 0x5D, 0x2D, 0xB0, 0x53, 0xA1, 0x8F, 0x9F, 0xA9, 0x99, 0x47, + 0xBA, 0x08, 0x6A, 0x07, 0x85, 0x6E, 0xE9, 0x70, 0x7A, 0x4B, + 0x44, 0x29, 0xB3, 0xB5, 0x2E, 0x09, 0x75, 0xDB, 0x23, 0x26, + 0x19, 0xC4, 0xB0, 0xA6, 0x6E, 0xAD, 0x7D, 0xDF, 0xA7, 0x49, + 0xB8, 0x60, 0xEE, 0x9C, 0x66, 0xB2, 0xED, 0x8F, 0x71, 0x8C, + 0xAA, 0xEC, 0xFF, 0x17, 0x9A, 0x69, 0x6C, 0x52, 0x64, 0x56, + 0xE1, 0x9E, 0xB1, 0xC2, 0xA5, 0x02, 0x36, 0x19, 0x29, 0x4C, + 0x09, 0x75, 0x40, 0x13, 0x59, 0xA0, 0x3E, 0x3A, 0x18, 0xE4, + 0x9A, 0x98, 0x54, 0x3F, 0x65, 0x9D, 0x42, 0x5B, 0xD6, 0xE4, + 0x8F, 0x6B, 0xD6, 0x3F, 0xF7, 0x99, 0x07, 0x9C, 0xD2, 0xA1, + 0xF5, 0x30, 0xE8, 0xEF, 0xE6, 0x38, 0x2D, 0x4D, 0xC1, 0x5D, + 0x25, 0xF0, 0x86, 0x20, 0xDD, 0x4C, 0x26, 0xEB, 0x70, 0x84, + 0xC6, 0xE9, 0x82, 0x63, 0x5E, 0xCC, 0x1E, 0x02, 0x3F, 0x6B, + 0x68, 0x09, 0xC9, 0xEF, 0xBA, 0x3E, 0x14, 0x18, 0x97, 0x3C, + 0xA1, 0x70, 0x6A, 0x6B, 0x84, 0x35, 0x7F, 0x68, 0x86, 0xE2, + 0xA0, 0x52, 0x05, 0x53, 0x9C, 0xB7, 0x37, 0x07, 0x50, 0xAA, + 0x1C, 0x84, 0x07, 0x3E, 0x5C, 0xAE, 0xDE, 0x7F, 0xEC, 0x44, + 0x7D, 0x8E, 0xB8, 0xF2, 0x16, 0x57, 0x37, 0xDA, 0x3A, 0xB0, + 0x0D, 0x0C, 0x50, 0xF0, 0x04, 0x1F, 0x1C, 0xF0, 0xFF, 0xB3, + 0x00, 0x02, 0x1A, 0xF5, 0x0C, 0xAE, 0xB2, 0x74, 0xB5, 0x3C, + 0x58, 0x7A, 0x83, 0x25, 0xBD, 0x21, 0x09, 0xDC, 0xF9, 0x13, + 0x91, 0xD1, 0xF6, 0x2F, 0xA9, 0x7C, 0x73, 0x47, 0x32, 0x94, + 0x01, 0x47, 0xF5, 0x22, 0x81, 0xE5, 0xE5, 0x3A, 0xDC, 0xDA, + 0xC2, 0x37, 0x34, 0x76, 0xB5, 0xC8, 0xA7, 0xDD, 0xF3, 0x9A, + 0x46, 0x61, 0x44, 0xA9, 0x0E, 0x03, 0xD0, 0x0F, 0x3E, 0xC7, + 0xC8, 0xEC, 0x41, 0x1E, 0x75, 0xA4, 0x99, 0xCD, 0x38, 0xE2, + 0x2F, 0x0E, 0xEA, 0x3B, 0xA1, 0xBB, 0x80, 0x32, 0x31, 0xB3, + 0x3E, 0x18, 0x38, 0x8B, 0x54, 0x4E, 0x08, 0xB9, 0x6D, 0x4F, + 0x03, 0x0D, 0x42, 0x6F, 0xBF, 0x04, 0x0A, 0xF6, 0x90, 0x12, + 0xB8, 0x2C, 0x79, 0x7C, 0x97, 0x24, 0x72, 0xB0, 0x79, 0x56, + 0xAF, 0x89, 0xAF, 0xBC, 0x1F, 0x77, 0x9A, 0xDE, 0x10, 0x08, + 0x93, 0xD9, 0x12, 0xAE, 0x8B, 0xB3, 0x2E, 0x3F, 0xCF, 0xDC, + 0x1F, 0x72, 0x12, 0x55, 0x24, 0x71, 0x6B, 0x2E, 0xE6, 0xDD, + 0x1A, 0x50, 0x87, 0xCD, 0x84, 0x9F, 0x18, 0x47, 0x58, 0x7A, + 0x17, 0xDA, 0x08, 0x74, 0xBC, 0x9A, 0x9F, 0xBC, 0x8C, 0x7D, + 0x4B, 0xE9, 0x3A, 0xEC, 0x7A, 0xEC, 0xFA, 0x1D, 0x85, 0xDB, + 0x66, 0x43, 0x09, 0x63, 0xD2, 0xC3, 0x64, 0xC4, 0x47, 0x18, + 0x1C, 0xEF, 0x08, 0xD9, 0x15, 0x32, 0x37, 0x3B, 0x43, 0xDD, + 0x16, 0xBA, 0xC2, 0x24, 0x43, 0x4D, 0xA1, 0x12, 0x51, 0xC4, + 0x65, 0x2A, 0x02, 0x00, 0x94, 0x50, 0xDD, 0xE4, 0x3A, 0x13, + 0x9E, 0xF8, 0xDF, 0x71, 0x55, 0x4E, 0x31, 0x10, 0xD6, 0x77, + 0xAC, 0x81, 0x9B, 0x19, 0x11, 0x5F, 0xF1, 0x56, 0x35, 0x04, + 0x6B, 0xC7, 0xA3, 0xD7, 0x3B, 0x18, 0x11, 0x3C, 0x09, 0xA5, + 0x24, 0x59, 0xED, 0xE6, 0x8F, 0xF2, 0xFA, 0xFB, 0xF1, 0x97, + 0x2C, 0xBF, 0xBA, 0x9E, 0x6E, 0x3C, 0x15, 0x1E, 0x70, 0x45, + 0xE3, 0x86, 0xB1, 0x6F, 0xE9, 0xEA, 0x0A, 0x5E, 0x0E, 0x86, + 0xB3, 0x2A, 0x3E, 0x5A, 0x1C, 0xE7, 0x1F, 0x77, 0xFA, 0x06, + 0x3D, 0x4E, 0xB9, 0xDC, 0x65, 0x29, 0x0F, 0x1D, 0xE7, 0x99, + 0xD6, 0x89, 0x3E, 0x80, 0x25, 0xC8, 0x66, 0x52, 0x78, 0xC9, + 0x4C, 0x2E, 0x6A, 0xB3, 0x10, 0x9C, 0xBA, 0x0E, 0x15, 0xC6, + 0x78, 0xEA, 0xE2, 0x94, 0x53, 0x3C, 0xFC, 0xA5, 0xF4, 0x2D, + 0x0A, 0x1E, 0xA7, 0x4E, 0xF7, 0xF2, 0x3D, 0x2B, 0x1D, 0x36, + 0x0F, 0x26, 0x39, 0x19, 0x60, 0x79, 0xC2, 0x19, 0x08, 0xA7, + 0x23, 0x52, 0xB6, 0x12, 0x13, 0xF7, 0x6E, 0xFE, 0xAD, 0xEB, + 0x66, 0x1F, 0xC3, 0xEA, 0x95, 0x45, 0xBC, 0xE3, 0x83, 0xC8, + 0x7B, 0xA6, 0xD1, 0x37, 0x7F, 0xB1, 0x28, 0xFF, 0x8C, 0x01, + 0xEF, 0xDD, 0x32, 0xC3, 0xA5, 0x5A, 0x6C, 0xBE, 0x85, 0x21, + 0x58, 0x65, 0x02, 0x98, 0xAB, 0x68, 0x0F, 0xA5, 0xCE, 0xEE, + 0x3B, 0x95, 0x2F, 0xDB, 0xAD, 0x7D, 0xEF, 0x2A, 0x84, 0x2F, + 0x6E, 0x5B, 0x28, 0xB6, 0x21, 0x15, 0x70, 0x61, 0x07, 0x29, + 0x75, 0x47, 0xDD, 0xEC, 0x10, 0x15, 0x9F, 0x61, 0x30, 0xA8, + 0xCC, 0x13, 0x96, 0xBD, 0x61, 0xEB, 0x1E, 0xFE, 0x34, 0x03, + 0xCF, 0x63, 0x03, 0xAA, 0x90, 0x5C, 0x73, 0xB5, 0x39, 0xA2, + 0x70, 0x4C, 0x0B, 0x9E, 0x9E, 0xD5, 0x14, 0xDE, 0xAA, 0xCB, + 0xBC, 0x86, 0xCC, 0xEE, 0xA7, 0x2C, 0x62, 0x60, 0xAB, 0x5C, + 0xAB, 0x9C, 0x6E, 0x84, 0xF3, 0xB2, 0xAF, 0x1E, 0x8B, 0x64, + 0xCA, 0xF0, 0xBD, 0x19, 0xB9, 0x69, 0x23, 0xA0, 0x50, 0xBB, + 0x5A, 0x65, 0x32, 0x5A, 0x68, 0x40, 0xB3, 0xB4, 0x2A, 0x3C, + 0xD5, 0xE9, 0x9E, 0x31, 0xF7, 0xB8, 0x21, 0xC0, 0x19, 0x0B, + 0x54, 0x9B, 0x99, 0xA0, 0x5F, 0x87, 0x7E, 0x99, 0xF7, 0x95, + 0xA8, 0x7D, 0x3D, 0x62, 0x9A, 0x88, 0x37, 0xF8, 0x77, 0x2D, + 0xE3, 0x97, 0x5F, 0x93, 0xED, 0x11, 0x81, 0x12, 0x68, 0x16, + 0x29, 0x88, 0x35, 0x0E, 0xD6, 0x1F, 0xE6, 0xC7, 0xA1, 0xDF, + 0xDE, 0x96, 0x99, 0xBA, 0x58, 0x78, 0xA5, 0x84, 0xF5, 0x57, + 0x63, 0x72, 0x22, 0x1B, 0xFF, 0xC3, 0x83, 0x9B, 0x96, 0x46, + 0xC2, 0x1A, 0xEB, 0x0A, 0xB3, 0xCD, 0x54, 0x30, 0x2E, 0x53, + 0xE4, 0x48, 0xD9, 0x8F, 0x28, 0x31, 0xBC, 0x6D, 0xEF, 0xF2, + 0xEB, 0x58, 0xEA, 0xFF, 0xC6, 0x34, 0x61, 0xED, 0x28, 0xFE, + 0x73, 0x3C, 0x7C, 0xEE, 0xD9, 0x14, 0x4A, 0x5D, 0xE3, 0xB7, + 0x64, 0xE8, 0x14, 0x5D, 0x10, 0x42, 0xE0, 0x13, 0x3E, 0x20, + 0xB6, 0xE2, 0xEE, 0x45, 0xEA, 0xAB, 0xAA, 0xA3, 0x15, 0x4F, + 0x6C, 0xDB, 0xD0, 0x4F, 0xCB, 0xFA, 0x42, 0xF4, 0x42, 0xC7, + 0xB5, 0xBB, 0x6A, 0xEF, 0x1D, 0x3B, 0x4F, 0x65, 0x05, 0x21, + 0xCD, 0x41, 0x9E, 0x79, 0x1E, 0xD8, 0xC7, 0x4D, 0x85, 0x86, + 0x6A, 0x47, 0x4B, 0xE4, 0x50, 0x62, 0x81, 0x3D, 0xF2, 0xA1, + 0x62, 0xCF, 0x46, 0x26, 0x8D, 0x5B, 0xA0, 0x83, 0x88, 0xFC, + 0xA3, 0xB6, 0xC7, 0xC1, 0xC3, 0x24, 0x15, 0x7F, 0x92, 0x74, + 0xCB, 0x69, 0x0B, 0x8A, 0x84, 0x47, 0x85, 0xB2, 0x92, 0x56, + 0x00, 0xBF, 0x5B, 0x09, 0x9D, 0x48, 0x19, 0xAD, 0x74, 0xB1, + 0x62, 0x14, 0x00, 0x0E, 0x82, 0x23, 0x2A, 0x8D, 0x42, 0x58, + 0xEA, 0xF5, 0x55, 0x0C, 0x3E, 0xF4, 0xAD, 0x1D, 0x61, 0x70, + 0x3F, 0x23, 0x92, 0xF0, 0x72, 0x33, 0x41, 0x7E, 0x93, 0x8D, + 0xF1, 0xEC, 0x5F, 0xD6, 0xDB, 0x3B, 0x22, 0x6C, 0x59, 0x37, + 0xDE, 0x7C, 0x60, 0x74, 0xEE, 0xCB, 0xA7, 0xF2, 0x85, 0x40, + 0x6E, 0x32, 0x77, 0xCE, 0x84, 0x80, 0x07, 0xA6, 0x9E, 0x50, + 0xF8, 0x19, 0x55, 0xD8, 0xEF, 0xE8, 0x35, 0x97, 0xD9, 0x61, + 0xAA, 0xA7, 0x69, 0xA9, 0xC2, 0x06, 0x0C, 0xC5, 0xFC, 0xAB, + 0x04, 0x5A, 0xDC, 0xCA, 0x0B, 0x80, 0x2E, 0x7A, 0x44, 0x9E, + 0x84, 0x34, 0x45, 0xC3, 0x05, 0x67, 0xD5, 0xFD, 0xC9, 0x9E, + 0x1E, 0x0E, 0xD3, 0xDB, 0x73, 0xDB, 0xCD, 0x88, 0x55, 0x10, + 0x79, 0xDA, 0x5F, 0x67, 0x40, 0x43, 0x67, 0xE3, 0x65, 0x34, + 0xC4, 0xC5, 0xD8, 0x38, 0x3E, 0x71, 0x9E, 0xF8, 0x28, 0x3D, + 0x20, 0xFF, 0x6D, 0xF1, 0xE7, 0x21, 0x3E, 0x15, 0x4A, 0x3D, + 0xB0, 0x8F, 0x2B, 0x9F, 0xE3, 0xE6, 0xF7, 0xAD, 0x83, 0xDB, + 0x68, 0x5A, 0x3D, 0xE9, 0xF7, 0x40, 0x81, 0x94, 0x1C, 0x26, + 0x4C, 0xF6, 0x34, 0x29, 0x69, 0x94, 0xF7, 0x20, 0x15, 0x41, + 0xF7, 0xD4, 0x02, 0x76, 0x2E, 0x6B, 0xF4, 0xBC, 0x68, 0x00, + 0xA2, 0xD4, 0x71, 0x24, 0x08, 0xD4, 0x6A, 0xF4, 0x20, 0x33, + 0xB7, 0xD4, 0xB7, 0x43, 0xAF, 0x61, 0x00, 0x50, 0x2E, 0xF6, + 0x39, 0x1E, 0x46, 0x45, 0x24, 0x97, 0x74, 0x4F, 0x21, 0x14, + 0x40, 0x88, 0x8B, 0xBF, 0x1D, 0xFC, 0x95, 0x4D, 0xAF, 0x91, + 0xB5, 0x96, 0xD3, 0xDD, 0xF4, 0x70, 0x45, 0x2F, 0xA0, 0x66, + 0xEC, 0x09, 0xBC, 0xBF, 0x85, 0x97, 0xBD, 0x03, 0xD0, 0x6D, + 0xAC, 0x7F, 0x04, 0x85, 0xCB, 0x31, 0xB3, 0x27, 0xEB, 0x96, + 0x41, 0x39, 0xFD, 0x55, 0xE6, 0x47, 0x25, 0xDA, 0x9A, 0x0A, + 0xCA, 0xAB, 0x25, 0x78, 0x50, 0x28, 0xF4, 0x29, 0x04, 0x53, + 0xDA, 0x86, 0x2C, 0x0A, 0xFB, 0x6D, 0xB6, 0xE9, 0x62, 0x14, + 0xDC, 0x68, 0x00, 0x69, 0x48, 0xD7, 0xA4, 0xC0, 0x0E, 0x68, + 0xEE, 0x8D, 0xA1, 0x27, 0xA2, 0xFE, 0x3F, 0x4F, 0x8C, 0xAD, + 0x87, 0xE8, 0x06, 0xE0, 0x8C, 0xB5, 0xB6, 0xD6, 0xF4, 0x7A, + 0x7C, 0x1E, 0xCE, 0xAA, 0xEC, 0x5F, 0x37, 0xD3, 0x99, 0xA3, + 0x78, 0xCE, 0x42, 0x2A, 0x6B, 0x40, 0x35, 0x9E, 0xFE, 0x20, + 0xB9, 0x85, 0xF3, 0xD9, 0xAB, 0xD7, 0x39, 0xEE, 0x8B, 0x4E, + 0x12, 0x3B, 0xF7, 0xFA, 0xC9, 0x1D, 0x56, 0x18, 0x6D, 0x4B, + 0x31, 0x66, 0xA3, 0x26, 0xB2, 0x97, 0xE3, 0xEA, 0x74, 0xFA, + 0x6E, 0x3A, 0x32, 0x43, 0x5B, 0xDD, 0xF7, 0xE7, 0x41, 0x68, + 0xFB, 0x20, 0x78, 0xCA, 0x4E, 0xF5, 0x0A, 0xFB, 0x97, 0xB3, + 0xFE, 0xD8, 0xAC, 0x56, 0x40, 0x45, 0x27, 0x95, 0x48, 0xBA, + 0x3A, 0x3A, 0x53, 0x55, 0x87, 0x8D, 0x83, 0x20, 0xB7, 0xA9, + 0x6B, 0xFE, 0x4B, 0x95, 0x96, 0xD0, 0xBC, 0x67, 0xA8, 0x55, + 0x58, 0x9A, 0x15, 0xA1, 0x63, 0x29, 0xA9, 0xCC, 0x33, 0xDB, + 0xE1, 0x99, 0x56, 0x4A, 0x2A, 0xA6, 0xF9, 0x25, 0x31, 0x3F, + 0x1C, 0x7E, 0xF4, 0x5E, 0x7C, 0x31, 0x29, 0x90, 0x02, 0xE8, + 0xF8, 0xFD, 0x70, 0x2F, 0x27, 0x04, 0x5C, 0x15, 0xBB, 0x80, + 0xE3, 0x2C, 0x28, 0x05, 0x48, 0x15, 0xC1, 0x95, 0x22, 0x6D, + 0xC6, 0xE4, 0x3F, 0x13, 0xC1, 0x48, 0xDC, 0x86, 0x0F, 0xC7, + 0xEE, 0xC9, 0xF9, 0x07, 0x0F, 0x1F, 0x04, 0x41, 0xA4, 0x79, + 0x47, 0x40, 0x17, 0x6E, 0x88, 0x5D, 0xEB, 0x51, 0x5F, 0x32, + 0xD1, 0xC0, 0x9B, 0xD5, 0x8F, 0xC1, 0xBC, 0xF2, 0x64, 0x35, + 0x11, 0x41, 0x34, 0x78, 0x7B, 0x25, 0x60, 0x9C, 0x2A, 0x60, + 0xA3, 0xE8, 0xF8, 0xDF, 0x1B, 0x6C, 0x63, 0x1F, 0xC2, 0xB4, + 0x12, 0x0E, 0x9E, 0x32, 0xE1, 0x02, 0xD1, 0x4F, 0x66, 0xAF, + 0x15, 0x81, 0xD1, 0xCA, 0xE0, 0x95, 0x23, 0x6B, 0xE1, 0x92, + 0x3E, 0x33, 0x62, 0x0B, 0x24, 0x3B, 0x22, 0xB9, 0xBE, 0xEE, + 0x0E, 0xA2, 0xB2, 0x85, 0x99, 0x0D, 0xBA, 0xE6, 0x8C, 0x0C, + 0x72, 0xDE, 0x28, 0xF7, 0xA2, 0x2D, 0x45, 0x78, 0x12, 0xD0, + 0xFD, 0x94, 0xB7, 0x95, 0x62, 0x08, 0x7D, 0x64, 0xF0, 0xF5, + 0xCC, 0xE7, 0x6F, 0xA3, 0x49, 0x54, 0xFA, 0x48, 0x7D, 0x87, + 0x27, 0xFD, 0x9D, 0xC3, 0x1E, 0x8D, 0x3E, 0xF3, 0x41, 0x63, + 0x47, 0x0A, 0x74, 0xFF, 0x2E, 0x99, 0xAB, 0x6E, 0x6F, 0x3A, + 0x37, 0xFD, 0xF8, 0xF4, 0x60, 0xDC, 0x12, 0xA8, 0xF8, 0xDD, + 0xEB, 0xA1, 0x4C, 0xE1, 0x1B, 0x99, 0x0D, 0x6B, 0x6E, 0xDB, + 0x10, 0x55, 0x7B, 0xC6, 0x37, 0x2C, 0x67, 0x6D, 0x3B, 0xD4, + 0x65, 0x27, 0x04, 0xE8, 0xD0, 0xDC, 0xC7, 0x0D, 0x29, 0xF1, + 0xA3, 0xFF, 0x00, 0xCC, 0x92, 0x0F, 0x39, 0xB5, 0x0B, 0xED, + 0x0F, 0x69, 0xFB, 0x9F, 0x7B, 0x66, 0x9C, 0x7D, 0xDB, 0xCE, + 0x0B, 0xCF, 0x91, 0xA0, 0xA3, 0x5E, 0x15, 0xD9, 0x88, 0x2F, + 0x13, 0xBB, 0x24, 0xAD, 0x5B, 0x51, 0xBF, 0x79, 0x94, 0x7B, + 0xEB, 0xD6, 0x3B, 0x76, 0xB3, 0x2E, 0x39, 0x37, 0x79, 0x59, + 0x11, 0xCC, 0x97, 0xE2, 0x26, 0x80, 0x2D, 0x31, 0x2E, 0xF4, + 0xA7, 0xAD, 0x42, 0x68, 0x3B, 0x2B, 0x6A, 0xC6, 0xCC, 0x4C, + 0x75, 0x12, 0x1C, 0xF1, 0x2E, 0x78, 0x37, 0x42, 0x12, 0x6A, + 0xE7, 0x51, 0x92, 0xB7, 0xE6, 0xBB, 0xA1, 0x06, 0x50, 0x63, + 0xFB, 0x4B, 0x18, 0x10, 0x6B, 0x1A, 0xFA, 0xED, 0xCA, 0x11, + 0xD8, 0xBD, 0x25, 0x3D, 0xC9, 0xC3, 0xE1, 0xE2, 0x59, 0x16, + 0x42, 0x44, 0x86, 0x13, 0x12, 0x0A, 0x6E, 0xEC, 0x0C, 0xD9, + 0x2A, 0xEA, 0xAB, 0xD5, 0x4E, 0x67, 0xAF, 0x64, 0x5F, 0xA8, + 0x86, 0xDA, 0x88, 0xE9, 0xBF, 0xBE, 0xFE, 0xC3, 0xE4, 0x64, + 0x57, 0x80, 0xBC, 0x9D, 0x86, 0xC0, 0xF7, 0xF0, 0xF8, 0x7B, + 0x78, 0x60, 0x4D, 0x60, 0x03, 0x60, 0x46, 0x83, 0xFD, 0xD1, + 0xB0, 0x1F, 0x38, 0xF6, 0x04, 0xAE, 0x45, 0x77, 0xCC, 0xFC, + 0x36, 0xD7, 0x33, 0x6B, 0x42, 0x83, 0x71, 0xAB, 0x1E, 0xF0, + 0x87, 0x41, 0x80, 0xB0, 0x5F, 0x5E, 0x00, 0x3C, 0xBE, 0x57, + 0xA0, 0x77, 0x24, 0xAE, 0xE8, 0xBD, 0x99, 0x42, 0x46, 0x55, + 0x61, 0x2E, 0x58, 0xBF, 0x8F, 0xF4, 0x58, 0x4E, 0xA2, 0xFD, + 0xDD, 0xF2, 0x38, 0xEF, 0x74, 0xF4, 0xC2, 0xBD, 0x89, 0x87, + 0xC3, 0xF9, 0x66, 0x53, 0x74, 0x8E, 0xB3, 0xC8, 0x55, 0xF2, + 0x75, 0xB4, 0xB9, 0xD9, 0xFC, 0x46, 0x61, 0x26, 0xEB, 0x7A, + 0x84, 0xDF, 0x1D, 0x8B, 0x79, 0x0E, 0x6A, 0x84, 0xE2, 0x95, + 0x5F, 0x91, 0x8E, 0x59, 0x6E, 0x46, 0x70, 0x57, 0xB4, 0x20, + 0x91, 0x55, 0xD5, 0x8C, 0x4C, 0xDE, 0x02, 0xC9, 0xE1, 0xAC, + 0x0B, 0xB9, 0xD0, 0x05, 0x82, 0xBB, 0x48, 0x62, 0xA8, 0x11, + 0x9E, 0xA9, 0x74, 0x75, 0xB6, 0x19, 0x7F, 0xB7, 0x09, 0xDC, + 0xA9, 0xE0, 0xA1, 0x09, 0x2D, 0x66, 0x33, 0x46, 0x32, 0xC4, + 0x02, 0x1F, 0x5A, 0xE8, 0x8C, 0xBE, 0xF0, 0x09, 0x25, 0xA0, + 0x99, 0x4A, 0x10, 0xFE, 0x6E, 0x1D, 0x1D, 0x3D, 0xB9, 0x1A, + 0xDF, 0xA4, 0xA5, 0x0B, 0x0F, 0xF2, 0x86, 0xA1, 0x69, 0xF1, + 0x68, 0x28, 0x83, 0xDA, 0xB7, 0xDC, 0xFE, 0x06, 0x39, 0x57, + 0x9B, 0xCE, 0xE2, 0xA1, 0x52, 0x7F, 0xCD, 0x4F, 0x01, 0x5E, + 0x11, 0x50, 0xFA, 0x83, 0x06, 0xA7, 0xC4, 0xB5, 0x02, 0xA0, + 0x27, 0xD0, 0xE6, 0x0D, 0x27, 0x8C, 0xF8, 0x9A, 0x41, 0x86, + 0x3F, 0x77, 0x06, 0x4C, 0x60, 0xC3, 0xB5, 0x06, 0xA8, 0x61, + 0x28, 0x7A, 0x17, 0xF0, 0xE0, 0x86, 0xF5, 0xC0, 0xAA, 0x58, + 0x60, 0x00, 0x62, 0x7D, 0xDC, 0x30, 0xD7, 0x9E, 0xE6, 0x11, + 0x63, 0xEA, 0x38, 0x23, 0x94, 0xDD, 0xC2, 0x53, 0x34, 0x16, + 0xC2, 0xC2, 0x56, 0xEE, 0xCB, 0xBB, 0xDE, 0xB6, 0xBC, 0x90, + 0xA1, 0x7D, 0xFC, 0xEB, 0x76, 0x1D, 0x59, 0xCE, 0x09, 0xE4, + 0x05, 0x6F, 0x88, 0x01, 0x7C, 0x4B, 0x3D, 0x0A, 0x72, 0x39, + 0x24, 0x7C, 0x92, 0x7C, 0x5F, 0x72, 0xE3, 0x86, 0xB9, 0x9D, + 0x4D, 0x72, 0xB4, 0x5B, 0xC1, 0x1A, 0xFC, 0xB8, 0x9E, 0xD3, + 0x78, 0x55, 0x54, 0xED, 0xB5, 0xA5, 0xFC, 0x08, 0xD3, 0x7C, + 0x3D, 0xD8, 0xC4, 0x0F, 0xAD, 0x4D, 0x5E, 0xEF, 0x50, 0x1E, + 0xF8, 0xE6, 0x61, 0xB1, 0xD9, 0x14, 0x85, 0xA2, 0x3C, 0x13, + 0x51, 0x6C, 0xE7, 0xC7, 0xD5, 0x6F, 0xC4, 0x4E, 0xE1, 0x56, + 0xCE, 0xBF, 0x2A, 0x36, 0x37, 0xC8, 0xC6, 0xDD, 0x34, 0x32, + 0x9A, 0xD7, 0x12, 0x82, 0x63, 0x92, 0x8E, 0xFA, 0x0E, 0x67, + 0xE0, 0x00, 0x60, 0x40, 0x37, 0xCE, 0x39, 0x3A, 0xCF, 0xF5, + 0xFA, 0xD3, 0x37, 0x77, 0xC2, 0xAB, 0x1B, 0x2D, 0xC5, 0x5A, + 0x9E, 0x67, 0xB0, 0x5C, 0x42, 0x37, 0xA3, 0x4F, 0x40, 0x27, + 0x82, 0xD3, 0xBE, 0x9B, 0xBC, 0x99, 0x9D, 0x8E, 0x11, 0xD5, + 0x15, 0x73, 0x0F, 0xBF, 0x7E, 0x1C, 0x2D, 0xD6, 0x7B, 0xC4, + 0x00, 0xC7, 0x6B, 0x1B, 0x8C, 0xB7, 0x45, 0x90, 0xA1, 0x21, + 0xBE, 0xB1, 0x6E, 0xB2, 0xB4, 0x6E, 0x36, 0x6A, 0x2F, 0xAB, + 0x48, 0x57, 0x79, 0x6E, 0x94, 0xBC, 0xD2, 0x76, 0xA3, 0xC6, + 0xC8, 0xC2, 0x49, 0x65, 0xEE, 0xF8, 0x0F, 0x53, 0x7D, 0xDE, + 0x8D, 0x46, 0x1D, 0x0A, 0x73, 0xD5, 0xC6, 0x4D, 0xD0, 0x4C, + 0xDB, 0xBB, 0x39, 0x29, 0x50, 0x46, 0xBA, 0xA9, 0xE8, 0x26, + 0x95, 0xAC, 0x04, 0xE3, 0x5E, 0xBE, 0xF0, 0xD5, 0xFA, 0xA1, + 0x9A, 0x51, 0x2D, 0x6A, 0xE2, 0x8C, 0xEF, 0x63, 0x22, 0xEE, + 0x86, 0x9A, 0xB8, 0xC2, 0x89, 0xC0, 0xF6, 0x2E, 0x24, 0x43, + 0xAA, 0x03, 0x1E, 0xA5, 0xA4, 0xD0, 0xF2, 0x9C, 0xBA, 0x61, + 0xC0, 0x83, 0x4D, 0x6A, 0xE9, 0x9B, 0x50, 0x15, 0xE5, 0x8F, + 0xD6, 0x5B, 0x64, 0xBA, 0xF9, 0xA2, 0x26, 0x28, 0xE1, 0x3A, + 0x3A, 0xA7, 0x86, 0x95, 0xA9, 0x4B, 0xE9, 0x62, 0x55, 0xEF, + 0xD3, 0xEF, 0x2F, 0xC7, 0xDA, 0xF7, 0x52, 0xF7, 0x69, 0x6F, + 0x04, 0x3F, 0x59, 0x0A, 0xFA, 0x77, 0x15, 0xA9, 0xE4, 0x80, + 0x01, 0x86, 0xB0, 0x87, 0xAD, 0xE6, 0x09, 0x9B, 0x93, 0xE5, + 0x3E, 0x3B, 0x5A, 0xFD, 0x90, 0xE9, 0x97, 0xD7, 0x34, 0x9E, + 0xD9, 0xB7, 0xF0, 0x2C, 0x51, 0x8B, 0x2B, 0x02, 0x3A, 0xAC, + 0xD5, 0x96, 0x7D, 0xA6, 0x7D, 0x01, 0xD6, 0x3E, 0xCF, 0xD1, + 0x28, 0x2D, 0x7D, 0x7C, 0xCF, 0x25, 0x9F, 0x1F, 0x9B, 0xB8, + 0xF2, 0xAD, 0x72, 0xB4, 0xD6, 0x5A, 0x4C, 0xF5, 0x88, 0x5A, + 0x71, 0xAC, 0x29, 0xE0, 0xE6, 0xA5, 0x19, 0xE0, 0xFD, 0xAC, + 0xB0, 0x47, 0x9B, 0xFA, 0x93, 0xED, 0x8D, 0xC4, 0xD3, 0xE8, + 0xCC, 0x57, 0x3B, 0x28, 0x29, 0x66, 0xD5, 0xF8, 0x28, 0x2E, + 0x13, 0x79, 0x91, 0x01, 0x5F, 0x78, 0x55, 0x60, 0x75, 0xED, + 0x44, 0x0E, 0x96, 0xF7, 0x8C, 0x5E, 0xD3, 0xE3, 0xD4, 0x6D, + 0x05, 0x15, 0xBA, 0x6D, 0xF4, 0x88, 0x25, 0x61, 0xA1, 0x03, + 0xBD, 0xF0, 0x64, 0x05, 0x15, 0x9E, 0xEB, 0xC3, 0xA2, 0x57, + 0x90, 0x3C, 0xEC, 0x1A, 0x27, 0x97, 0x2A, 0x07, 0x3A, 0xA9, + 0x9B, 0x6D, 0x3F, 0x1B, 0xF5, 0x21, 0x63, 0x1E, 0xFB, 0x66, + 0x9C, 0xF5, 0x19, 0xF3, 0xDC, 0x26, 0x28, 0xD9, 0x33, 0x75, + 0xF5, 0xFD, 0x55, 0xB1, 0x82, 0x34, 0x56, 0x03, 0xBB, 0x3C, + 0xBA, 0x8A, 0x11, 0x77, 0x51, 0x28, 0xF8, 0xD9, 0x0A, 0xC2, + 0x67, 0x51, 0xCC, 0xAB, 0x5F, 0x92, 0xAD, 0xCC, 0x51, 0x17, + 0xE8, 0x4D, 0x8E, 0xDC, 0x30, 0x38, 0x62, 0x58, 0x9D, 0x37, + 0x91, 0xF9, 0x20, 0x93, 0xC2, 0x90, 0x7A, 0xEA, 0xCE, 0x7B, + 0x3E, 0xFB, 0x64, 0xCE, 0x21, 0x51, 0x32, 0xBE, 0x4F, 0x77, + 0x7E, 0xE3, 0xB6, 0xA8, 0x46, 0x3D, 0x29, 0xC3, 0x69, 0x53, + 0xDE, 0x48, 0x80, 0xE6, 0x13, 0x64, 0x10, 0x08, 0xAE, 0xA2, + 0x24, 0xB2, 0x6D, 0xDD, 0xFD, 0x2D, 0x85, 0x69, 0x66, 0x21, + 0x07, 0x09, 0x0A, 0x46, 0x9A, 0xB3, 0xDD, 0xC0, 0x45, 0x64, + 0xCF, 0xDE, 0x6C, 0x58, 0xAE, 0xC8, 0x20, 0x1C, 0xDD, 0xF7, + 0xBE, 0x5B, 0x40, 0x8D, 0x58, 0x1B, 0x7F, 0x01, 0xD2, 0xCC, + 0xBB, 0xE3, 0xB4, 0x6B, 0x7E, 0x6A, 0xA2, 0xDD, 0x45, 0xFF, + 0x59, 0x3A, 0x44, 0x0A, 0x35, 0x3E, 0xD5, 0xCD, 0xB4, 0xBC, + 0xA8, 0xCE, 0xEA, 0x72, 0xBB, 0x84, 0x64, 0xFA, 0xAE, 0x12, + 0x66, 0x8D, 0x47, 0x6F, 0x3C, 0xBF, 0x63, 0xE4, 0x9B, 0xD2, + 0x9E, 0x5D, 0x2F, 0x54, 0x1B, 0x77, 0xC2, 0xAE, 0x70, 0x63, + 0x4E, 0xF6, 0x8D, 0x0D, 0x0E, 0x74, 0x57, 0x13, 0x5B, 0xE7, + 0x71, 0x16, 0x72, 0xF8, 0x5D, 0x7D, 0x53, 0xAF, 0x08, 0xCB, + 0x40, 0x40, 0xCC, 0xE2, 0xB4, 0x4E, 0x6A, 0x46, 0xD2, 0x34, + 0x84, 0xAF, 0x15, 0x01, 0x28, 0x04, 0xB0, 0xE1, 0x1D, 0x3A, + 0x98, 0x95, 0xB4, 0x9F, 0xB8, 0x06, 0x48, 0xA0, 0x6E, 0xCE, + 0x82, 0x3B, 0x3F, 0x6F, 0x82, 0xAB, 0x20, 0x35, 0x4B, 0x1D, + 0x1A, 0x01, 0xF8, 0x27, 0x72, 0x27, 0xB1, 0x60, 0x15, 0x61, + 0xDC, 0x3F, 0x93, 0xE7, 0x2B, 0x79, 0x3A, 0xBB, 0xBD, 0x25, + 0x45, 0x34, 0xE1, 0x39, 0x88, 0xA0, 0x4B, 0x79, 0xCE, 0x51, + 0xB7, 0xC9, 0x32, 0x2F, 0xC9, 0xBA, 0x1F, 0xA0, 0x7E, 0xC8, + 0x1C, 0xE0, 0xF6, 0xD1, 0xC7, 0xBC, 0xC3, 0x11, 0x01, 0xCF, + 0xC7, 0xAA, 0xE8, 0xA1, 0x49, 0x87, 0x90, 0x1A, 0x9A, 0xBD, + 0x4F, 0xD4, 0xCB, 0xDE, 0xDA, 0xD0, 0x38, 0xDA, 0x0A, 0xD5, + 0x2A, 0xC3, 0x39, 0x03, 0x67, 0x36, 0x91, 0xC6, 0x7C, 0x31, + 0xF9, 0x8D, 0x4F, 0x2B, 0xB1, 0xE0, 0xB7, 0x59, 0x9E, 0xF7, + 0x3A, 0xBB, 0xF5, 0x43, 0xFF, 0x19, 0xD5, 0xF2, 0x9C, 0x45, + 0xD9, 0x27, 0x2C, 0x22, 0x97, 0xBF, 0x2A, 0xFC, 0xE6, 0x15, + 0x71, 0xFC, 0x91, 0x0F, 0x25, 0x15, 0x94, 0x9B, 0x61, 0x93, + 0xE5, 0xFA, 0xEB, 0x9C, 0xB6, 0xCE, 0x59, 0x64, 0xA8, 0xC2, + 0xD1, 0xA8, 0xBA, 0x12, 0x5E, 0x07, 0xC1, 0xB6, 0x0C, 0x6A, + 0x05, 0xE3, 0x65, 0x50, 0xD2, 0x10, 0x42, 0xA4, 0x03, 0xCB, + 0x0E, 0x6E, 0xEC, 0xE0, 0x3B, 0xDB, 0x98, 0x16, 0xBE, 0xA0, + 0x98, 0x4C, 0x64, 0xE9, 0x78, 0x32, 0x32, 0x95, 0x1F, 0x9F, + 0xDF, 0x92, 0xD3, 0xE0, 0x2B, 0x34, 0xA0, 0xD3, 0x1E, 0xF2, + 0x71, 0x89, 0x41, 0x74, 0x0A, 0x1B, 0x8C, 0x34, 0xA3, 0x4B, + 0x20, 0x71, 0xBE, 0xC5, 0xD8, 0x32, 0x76, 0xC3, 0x8D, 0x9F, + 0x35, 0xDF, 0x2E, 0x2F, 0x99, 0x9B, 0x47, 0x6F, 0x0B, 0xE6, + 0x1D, 0xF1, 0xE3, 0x0F, 0x54, 0xDA, 0x4C, 0xE5, 0x91, 0xD8, + 0xDA, 0x1E, 0xCF, 0x79, 0x62, 0xCE, 0x6F, 0x7E, 0x3E, 0xCD, + 0x66, 0xB1, 0x18, 0x16, 0x05, 0x1D, 0x2C, 0xFD, 0xC5, 0xD2, + 0x8F, 0x84, 0x99, 0x22, 0xFB, 0xF6, 0x57, 0xF3, 0x23, 0xF5, + 0x23, 0x76, 0x32, 0xA6, 0x31, 0x35, 0xA8, 0x93, 0x02, 0xCD, + 0xCC, 0x56, 0x62, 0x81, 0xF0, 0xAC, 0xB5, 0xEB, 0x75, 0x5A, + 0x97, 0x36, 0x16, 0x6E, 0xCC, 0x73, 0xD2, 0x88, 0x92, 0x62, + 0x96, 0xDE, 0xD0, 0x49, 0xB9, 0x81, 0x1B, 0x90, 0x50, 0x4C, + 0x14, 0x56, 0xC6, 0x71, 0xBD, 0xC7, 0xC6, 0xE6, 0x0A, 0x14, + 0x7A, 0x32, 0x06, 0xD0, 0xE1, 0x45, 0x9A, 0x7B, 0xF2, 0xC3, + 0xFD, 0x53, 0xAA, 0xC9, 0x00, 0x0F, 0xA8, 0x62, 0xE2, 0xBF, + 0x25, 0xBB, 0xF6, 0xD2, 0xBD, 0x35, 0x05, 0x69, 0x12, 0x71, + 0x22, 0x02, 0x04, 0xB2, 0x7C, 0xCF, 0xCB, 0xB6, 0x2B, 0x9C, + 0x76, 0xCD, 0xC0, 0x3E, 0x11, 0x53, 0xD3, 0xE3, 0x40, 0x16, + 0x60, 0xBD, 0xAB, 0x38, 0xF0, 0xAD, 0x47, 0x25, 0x9C, 0x20, + 0x38, 0xBA, 0x76, 0xCE, 0x46, 0xF7, 0xC5, 0xA1, 0xAF, 0x77, + 0x60, 0x60, 0x75, 0x20, 0x4E, 0xFE, 0xCB, 0x85, 0xD8, 0x8D, + 0xE8, 0x8A, 0xB0, 0xF9, 0xAA, 0x7A, 0x7E, 0xAA, 0xF9, 0x4C, + 0x5C, 0xC2, 0x48, 0x19, 0x8C, 0x8A, 0xFB, 0x02, 0xE4, 0x6A, + 0xC3, 0x01, 0xF9, 0xE1, 0xEB, 0xD6, 0x69, 0xF8, 0xD4, 0x90, + 0xA0, 0xDE, 0x5C, 0xA6, 0x2D, 0x25, 0x09, 0x3F, 0x9F, 0xE6, + 0x08, 0xC2, 0x32, 0x61, 0x4E, 0xB7, 0x5B, 0xE2, 0x77, 0xCE, + 0xE3, 0xDF, 0x8F, 0x57, 0xE6, 0x72, 0xC3, 0x3A +}; + +/* Key lengths, and lengths of various bits of seed3 */ +#define PART1_WORDS 18 +#define PART2_WORDS 1024 +#define KEY1_WORDS 1042 +#define KEY2_WORDS 6 + +#define PART1_BYTES 72 +#define PART2_BYTES 4096 +#define KEY1_BYTES 4168 +#define KEY2_BYTES 24 + +#define BASENAME_BYTES 256 + +/* Hash a single state variable based on the current state of key1 */ +static u32_t hash_common(u32_t state, const u32_t *key1) +{ + u8_t bytes[4]; + u32_t retval; + + memcpy(bytes, &state, 4); + + retval = key1[bytes[3] + 0x012]; + retval += key1[bytes[2] + 0x112]; + retval ^= key1[bytes[1] + 0x212]; + retval += key1[bytes[0] + 0x312]; + + return retval; +} + +/* Fold key1 into *state1 and *state2, forwards */ +static void hash_fwd(u32_t *pstate1, u32_t *pstate2, const u32_t *key1) +{ + u32_t state1; + u32_t state2; + u32_t tmp; + int i; + + state1 = *pstate1; + state2 = *pstate2; + + for (i = 0 ; i < 0x10 ; i++) { + state1 ^= key1[i]; + state2 ^= hash_common(state1, key1); + + tmp = state2; + state2 = state1; + state1 = tmp; + } + + tmp = state1; + state1 = state2; + state2 = tmp; + + state2 ^= key1[0x10]; + state1 ^= key1[0x11]; + + *pstate1 = state1; + *pstate2 = state2; +} + +/* Same but backwards */ +static void hash_rev(u32_t *pstate1, u32_t *pstate2, const u32_t *key3) +{ + u32_t state1; + u32_t state2; + u32_t tmp; + int i; + + state1 = *pstate1; + state2 = *pstate2; + + for (i = 0x11 ; i > 1 ; i--) { + state1 ^= key3[i]; + state2 ^= hash_common(state1, key3); + + tmp = state2; + state2 = state1; + state1 = tmp; + } + + tmp = state1; + state1 = state2; + state2 = tmp; + + state2 ^= key3[1]; + state1 ^= key3[0]; + + *pstate1 = state1; + *pstate2 = state2; +} + +/* Prepare a key from seed3[] and a seed string, given as a parameter */ +static void generate_key1(u32_t *key1_words, const u8_t *seed) +{ + u32_t *seed3_words; + u32_t cur_word; + u32_t state1; + u32_t state2; + int seed_len; + int i; + int j; + int k; + + seed_len = strlen(seed); + seed3_words = (u32_t *) seed3; + + /* Prepare PART1: Cyclic XOR of the given seed with seed3, reversing end.*/ + for (i = 0, j = 0 ; i < PART1_WORDS ; i++) { + cur_word = 0; + + for (k = 0 ; k < 4 ; k++) { + cur_word <<= 8; + cur_word |= seed[j]; + + j = (j + 1) % seed_len; + } + + key1_words[i] = cur_word ^ seed3_words[i]; + } + + /* Prepare PART2: Straight memcpy() */ + memcpy(key1_words + PART1_WORDS, seed3 + PART1_BYTES, PART2_BYTES); + + /* Initialise some state */ + state1 = 0; + state2 = 0; + + /* Progressive hashing of the key */ + for (i = 0 ; i < KEY1_WORDS ; i += 2) { + hash_fwd(&state1, &state2, key1_words); + + key1_words[i + 0] = state1; + key1_words[i + 1] = state2; + } +} + +/* Form key2 from key1 and the filename */ +static void generate_key2(const u8_t *key1_bytes, const u8_t *basename, + u8_t *key2) +{ + u32_t *key1_words; + u32_t state1a; + u32_t state2a; + u32_t state1; + u32_t state2; + int i1; + int i2; + int j; + + key1_words = (u32_t *) key1_bytes; + memcpy(&state1a, seed1 + 0, 4); + memcpy(&state2a, seed1 + 4, 4); + + for (i1 = 0, i2 = 0 ; i1 < KEY2_BYTES ; ) { + state1 = 0; + state2 = 0; + + /* Copy 8 bytes to state1 and state2, reversing endian */ + for (j = 0 ; j < 4 ; j++) { + state1 <<= 8; + if (i1 < KEY2_BYTES) state1 += basename[i1++]; + } + + for (j = 0 ; j < 4 ; j++) { + state2 <<= 8; + if (i1 < KEY2_BYTES) state2 += basename[i1++]; + } + + state1 ^= state1a; + state2 ^= state2a; + hash_fwd(&state1, &state2, key1_words); + + state1a = state1; + state2a = state2; + + /* Store state1 and state2, reverse endian again */ + key2[i2++] = (state1 >> 24) & 0xFF; + key2[i2++] = (state1 >> 16) & 0xFF; + key2[i2++] = (state1 >> 8) & 0xFF; + key2[i2++] = (state1 >> 0) & 0xFF; + key2[i2++] = (state2 >> 24) & 0xFF; + key2[i2++] = (state2 >> 16) & 0xFF; + key2[i2++] = (state2 >> 8) & 0xFF; + key2[i2++] = (state2 >> 0) & 0xFF; + } +} + +/* Generate key1, fold in basename for key2, then feed back into key1 */ +static void generate_key(const u8_t *basename, u8_t *key) +{ + u8_t key2[KEY2_BYTES]; + + memset(key2, 0, KEY2_BYTES); + generate_key1((u32_t *) key, seed2); + generate_key2(key, basename, key2); + key2[KEY2_BYTES - 1] = '\0'; + + generate_key1((u32_t *) key, key2); +} + +static void do_decrypt(const u8_t *key, u8_t *input, int nbytes, u8_t *output) +{ + u32_t state1a; + u32_t state2a; + u32_t state1b; + u32_t state2b; + u32_t in_word1; + u32_t in_word2; + int i1; + int i2; + int j; + + memcpy(&state1b, seed1 + 0, 4); + memcpy(&state2b, seed1 + 4, 4); + + for (i1 = 0, i2 = 0 ; i2 < nbytes ; ) { + in_word1 = 0; + in_word2 = 0; + + /* Read in_word1 and in_word2, reversing endian */ + for (j = 0 ; j < 4 ; j++) { + in_word1 <<= 8; + in_word1 += input[i1]; + + if (i1 < nbytes) i1++; + } + + for (j = 0 ; j < 4 ; j++) { + in_word2 <<= 8; + in_word2 += input[i1]; + + if (i1 < nbytes) i1++; + } + + /* Decrypt */ + state1a = in_word1; + state2a = in_word2; + hash_rev(&in_word1, &in_word2, (const u32_t *) key); + + in_word1 ^= state1b; + in_word2 ^= state2b; + + state1b = state1a; + state2b = state2a; + + /* Reverse the byte order again on output */ + output[i2++] = (in_word1 >> 24) & 0xFF; + output[i2++] = (in_word1 >> 16) & 0xFF; + output[i2++] = (in_word1 >> 8) & 0xFF; + output[i2++] = (in_word1 >> 0) & 0xFF; + output[i2++] = (in_word2 >> 24) & 0xFF; + output[i2++] = (in_word2 >> 16) & 0xFF; + output[i2++] = (in_word2 >> 8) & 0xFF; + output[i2++] = (in_word2 >> 0) & 0xFF; + } +} + +static void *decrypt(const char *basename_param, u8_t *input, int nbytes) +{ + u8_t basename[BASENAME_BYTES]; + u8_t key[KEY1_BYTES]; + u8_t *output; + + /* Extend basename into a buffer of the correct length, padded with zeros */ + memset(basename, 0, BASENAME_BYTES); + strncpy(basename, basename_param, BASENAME_BYTES); + + /* Prepare result buffer */ + output = malloc(nbytes); + + /* Generate the key */ + generate_key(basename, key); + + /* Decrypt the data and return */ + do_decrypt(key, input, nbytes, output); + return output; +} + +static char *basename(const char *src) +{ + const char *pslash; + const char *pdot; + char *result; + + pslash = strrchr(src, '/'); + pdot = strrchr(src, '.'); + + if (pslash == NULL) pslash = strrchr(src, '\\'); + if (pdot == NULL) pdot = src + strlen(src); + + if (pslash == NULL) { + pslash = src; + } else { + pslash++; + } + + result = calloc(pdot - pslash + 1, 1); + strncpy(result, pslash, pdot - pslash); + + return result; +} + +int main(int argc, char **argv) +{ + const char *in_filename = argv[1]; + const char *out_filename = argv[2]; + u8_t *input; + u8_t *output; + long length; + char *base; + FILE *out; + FILE *in; + + /* Usage */ + if (argc != 3) { + fprintf(stderr, "Usage: %s [infile] [outfile]\n", argv[0]); + return EXIT_FAILURE; + } + + /* Open input */ + in = fopen(in_filename, "rb"); + + /* Determine input file length */ + fseek(in, 0, SEEK_END); + length = ftell(in); + fseek(in, 0, SEEK_SET); + + /* Allocate memory and read input */ + input = malloc(length); + fread(input, 1, length, in); + fclose(in); + + /* Get basename (i.e. file name sans directories and extension) and dec. */ + base = basename(in_filename); + output = decrypt(base, input, length); + + /* Write out */ + out = fopen(out_filename, "wb"); + fwrite(output, 1, length, out); + fclose(out); + + /* Clean up */ + free(base); + free(input); + free(output); + + return EXIT_SUCCESS; +} + diff --git a/iidx/old 2dx tools/gcz2tga-alt.c b/iidx/old 2dx tools/gcz2tga-alt.c new file mode 100644 index 0000000..70e5b8e --- /dev/null +++ b/iidx/old 2dx tools/gcz2tga-alt.c @@ -0,0 +1,306 @@ +/* gcz2tga.c: Slice up a directory full of GCZ (texture) files into TGA files. + * + * Credit goes to afwefwe for reverse-engineering the texture format + * and LZSS compression */ + +#include +#include +#include + +/* Assuming x86, usual endian crap is not accounted for */ +typedef unsigned char u8_t; +typedef unsigned short u16_t; +typedef unsigned int u32_t; + +struct image +{ + unsigned int width, height; + u8_t *planes; +}; + +struct clip +{ + short x, y, w, h; +}; + +static u16_t swab16(u16_t in) +{ + /* GC headers are big-endian */ + return ((in & 0xFF) << 8) | (in >> 8); +} + +static void unpack_gc(struct image *out, u8_t *in, size_t out_sz) +{ + unsigned int npixels; + unsigned int i; + unsigned int j; + u16_t *pixels; + u16_t *pheight; + u16_t *pwidth; + u16_t *pmagic; + u16_t pixel; + + pmagic = (u16_t *) in; + pheight = (u16_t *) (in + 14); + pwidth = (u16_t *) (in + 12); + + if (*pmagic != 0x4347) { + fprintf(stderr, "(FAIL: Invalid header)\n"); + exit(EXIT_FAILURE); + } + + /* Set up output image struct */ + in += 24; + out->width = swab16(*pwidth); + out->height = swab16(*pheight); + out->planes = malloc(out->width * out->height * 4); + + /* Clamp W/H (don't know why this is necessary but it is) */ + out->width = out->width > 1024 ? 1024 : out->width; + out->height = out->height > 1024 ? 1024 : out->height; + + fprintf(stderr, "(%dx%d)", out->width, out->height); + + /* Unpack pixels */ + pixels = (u16_t *) in; + npixels = out->width * out->height; + + if (out_sz > npixels * 4) { + /* Deep image (i.e. 32-bit) */ + memcpy(out->planes, pixels, npixels * 4); + } else { + /* Shallow image (i.e. 16-bit) */ + for (i = 0, j = 0 ; i < npixels ; i++) { + pixel = pixels[i]; + out->planes[j++] = ((pixel ) & 0x1F) << 3; /* B */ + out->planes[j++] = ((pixel >> 5) & 0x1F) << 3; /* G */ + out->planes[j++] = ((pixel >> 10) ) << 3; /* R */ + out->planes[j++] = pixel & 0x8000 ? 0xFF : 0x00; /* A */ + } + } +} + +static u8_t *expand_lzss(u8_t *lzss, size_t *pout_sz) +{ + static u8_t ring[0x1000]; + unsigned int ring_pos = 0x0FEE; + unsigned int chunk_offset; + unsigned int chunk_length; + u32_t control_word = 1; + size_t length; + u8_t cmd1; + u8_t cmd2; + u8_t *out; + u8_t *pos; + u8_t *in; + + /* Header = 32 bit unpacked file length */ + length = *((u32_t *) lzss); + *pout_sz = length; + + if (length > 8000000) { + fprintf(stderr, "(FAIL: Unreasonably large expanded size %d)\n", + length); + + exit(EXIT_FAILURE); + } + + out = malloc(length * 2); /* Seems to overrun */ + pos = out; + in = lzss + 4; + + while (length > 0) { + if (control_word == 1) { + /* Read a control byte */ + control_word = 0x100 | *in++; + } + + /* Decode a byte according to the current control byte bit */ + if (control_word & 1) { + /* Straight copy */ + *pos++ = *in; + ring[ring_pos] = *in++; + + ring_pos = (ring_pos + 1) % 0x1000; + length--; + } else { + /* Reference to data in ring buffer */ + cmd1 = *in++; + cmd2 = *in++; + + chunk_length = (cmd2 & 0x0F) + 3; + chunk_offset = ((cmd2 & 0xF0) << 4) | cmd1; + + for ( ; chunk_length > 0 ; chunk_length--) { + /* Copy historical data to output AND current ring pos */ + *pos++ = ring[chunk_offset]; + ring[ring_pos] = ring[chunk_offset]; + + /* Update counters */ + chunk_offset = (chunk_offset + 1) % 0x1000; + ring_pos = (ring_pos + 1) % 0x1000; + length--; + } + } + + /* Get next control bit */ + control_word >>= 1; + } + + return out; +} + +static void readfile(const char *filename, u8_t **data, long *nbytes) +{ + FILE *f; + + f = fopen(filename, "rb"); + if (f == NULL) abort(); + + fseek(f, 0, SEEK_END); + *nbytes = ftell(f); + fseek(f, 0, SEEK_SET); + + *data = malloc(*nbytes); + fread(*data, *nbytes, 1, f); + + fclose(f); +} + +void put8(FILE *f, unsigned char val) +{ + fwrite(&val, 1, 1, f); +} + +void put16(FILE *f, unsigned short val) +{ + fwrite(&val, 2, 1, f); +} + +void split_images(const char *in_dir, const char *out_dir, + struct image *images, int nimages) +{ + struct clip *clips; + char filename[512]; + long nbytes; + u8_t *data; + char *name; + FILE *f; + int i; + int j; + int k; + + /* Read file and get TOC */ + sprintf(filename, "%s/system.idx", in_dir); + readfile(filename, &data, &nbytes); + clips = (struct clip *) (data + 0x01BC); + name = (char *) (data + 8 + *((long *) data)); + + /* Guess how many clips there are with a heuristic */ + for (i = 0 ; clips[i].w != 0 && clips[i].h != 0 ; i++) { + sprintf(filename, "%s/%s.tga", out_dir, name); + name += strlen(name) + 3; + + f = fopen(filename, "wb"); + if (f == NULL) abort(); + + /* Locate the correct source image */ + j = 0; + while (clips[i].y > images[j].height) { + clips[i].y -= images[j].height; + j++; + } + + /* Write header */ + put8(f, 0); put8(f, 0); put8(f, 2); + put16(f, 0); put16(f, 0); put8(f, 0); + put16(f, 0); put16(f, 0); put16(f, clips[i].w); put16(f, clips[i].h); + put8(f, 32); put8(f, 32); + + /* Write scanlines */ + for (k = 0 ; k < clips[i].h ; k++) { + if (clips[i].y == images[j].height) { + clips[i].y = 0; + j++; + } + + fwrite(images[j].planes + ((images[j].width * clips[i].y) + + clips[i].x) * 4, clips[i].w, 4, f); + clips[i].y++; + } + + /* Close output file */ + fclose(f); + } + + /* Cleanup */ + free(data); +} + +int main(int argc, char **argv) +{ + char *in_dir; + char *out_dir; + + struct image images[32]; + char filename[256]; + unsigned int i; + long filesize; + u8_t *lzss, *gc; + size_t out_sz; + FILE *f; + + /* Usage */ + if (argc != 3) { + fprintf(stderr, "Usage: %s [indir] [outdir]\n", argv[0]); + return EXIT_FAILURE; + } + + /* Setup */ + memset(images, 0, sizeof(images)); + in_dir = argv[1]; + out_dir = argv[2]; + + for (i = 0 ; i < 32 ; i++) { + /* Open 0.gcz, 1.gcz etc ... */ + sprintf(filename, "%s/%d.gcz", in_dir, i); + f = fopen(filename, "rb"); + if (f == NULL) break; + + /* Read entire file */ + fseek(f, 0, SEEK_END); + filesize = ftell(f); + fseek(f, 0, SEEK_SET); + + fprintf(stderr, "%s: fread", filename); + lzss = malloc(filesize); + fread(lzss, filesize, 1, f); + fclose(f); + + /* Decompress */ + fprintf(stderr, "(OK) expand_lzss"); + gc = expand_lzss(lzss, &out_sz); + free(lzss); + + /* Unpack GC to 32-bit RGBA */ + fprintf(stderr, "(OK) unpack_gc"); + unpack_gc(&images[i], gc, out_sz); + free(gc); + + fprintf(stderr, "(OK)\n"); + } + + /* Sanity check */ + if (i == 0) { + fprintf(stderr, "No GCZ files found\n"); + exit(EXIT_FAILURE); + } + + /* Emit pile of TGAs */ + fprintf(stderr, "split_images"); + split_images(in_dir, out_dir, images, i); + fprintf(stderr, "(OK)\n\n"); + + return 0; +} + diff --git a/iidx/old 2dx tools/gcz2tga.c b/iidx/old 2dx tools/gcz2tga.c new file mode 100644 index 0000000..41ef1bf --- /dev/null +++ b/iidx/old 2dx tools/gcz2tga.c @@ -0,0 +1,297 @@ +/* gcz2tga.c: Slice up a directory full of GCZ (texture) files into TGA files. + * + * Credit goes to afwefwe for reverse-engineering the texture format + * and LZSS compression */ + +#include +#include +#include + +/* Assuming x86, usual endian crap is not accounted for */ +typedef unsigned char u8_t; +typedef unsigned short u16_t; +typedef unsigned int u32_t; + +struct image +{ + unsigned int width, height; + u8_t *planes; +}; + +struct clip +{ + short x, y, w, h; +}; + +static u16_t swab16(u16_t in) +{ + /* GC headers are big-endian */ + return ((in & 0xFF) << 8) | (in >> 8); +} + +static void unpack_gc(struct image *out, u8_t *in) +{ + unsigned int npixels; + unsigned int i; + unsigned int j; + u16_t *pixels; + u16_t *pheight; + u16_t *pwidth; + u16_t *pmagic; + u16_t pixel; + + pmagic = (u16_t *) in; + pheight = (u16_t *) (in + 14); + pwidth = (u16_t *) (in + 12); + + if (*pmagic != 0x4347) { + fprintf(stderr, "(FAIL: Invalid header)\n"); + exit(EXIT_FAILURE); + } + + /* Set up output image struct */ + in += 24; + out->width = swab16(*pwidth); + out->height = swab16(*pheight); + out->planes = malloc(out->width * out->height * 4); + + /* Clamp W/H (don't know why this is necessary but it is) */ + out->width = out->width > 1024 ? 1024 : out->width; + out->height = out->height > 1024 ? 1024 : out->height; + + fprintf(stderr, "(%dx%d)", out->width, out->height); + + /* Unpack pixels */ + pixels = (u16_t *) in; + npixels = out->width * out->height; + + for (i = 0, j = 0 ; i < npixels ; i++) { + pixel = pixels[i]; + out->planes[j++] = ((pixel ) & 0x1F) << 3; /* B */ + out->planes[j++] = ((pixel >> 5) & 0x1F) << 3; /* G */ + out->planes[j++] = ((pixel >> 10) ) << 3; /* R */ + out->planes[j++] = pixel & 0x8000 ? 0xFF : 0x00; /* A */ + } +} + +static u8_t *expand_lzss(u8_t *lzss) +{ + static u8_t ring[0x1000]; + unsigned int ring_pos = 0x0FEE; + unsigned int chunk_offset; + unsigned int chunk_length; + unsigned int length; + u32_t control_word = 1; + u8_t cmd1; + u8_t cmd2; + u8_t *out; + u8_t *pos; + u8_t *in; + + /* Header = 32 bit unpacked file length */ + length = *((u32_t *) lzss); + if (length > 4000000) { + fprintf(stderr, "(FAIL: Unreasonably large expanded size %d)\n", + length); + + exit(EXIT_FAILURE); + } + + out = malloc(length * 2); /* Seems to overrun */ + pos = out; + in = lzss + 4; + + while (length > 0) { + if (control_word == 1) { + /* Read a control byte */ + control_word = 0x100 | *in++; + } + + /* Decode a byte according to the current control byte bit */ + if (control_word & 1) { + /* Straight copy */ + *pos++ = *in; + ring[ring_pos] = *in++; + + ring_pos = (ring_pos + 1) % 0x1000; + length--; + } else { + /* Reference to data in ring buffer */ + cmd1 = *in++; + cmd2 = *in++; + + chunk_length = (cmd2 & 0x0F) + 3; + chunk_offset = ((cmd2 & 0xF0) << 4) | cmd1; + + for ( ; chunk_length > 0 ; chunk_length--) { + /* Copy historical data to output AND current ring pos */ + *pos++ = ring[chunk_offset]; + ring[ring_pos] = ring[chunk_offset]; + + /* Update counters */ + chunk_offset = (chunk_offset + 1) % 0x1000; + ring_pos = (ring_pos + 1) % 0x1000; + length--; + } + } + + /* Get next control bit */ + control_word >>= 1; + } + + return out; +} + +static void readfile(const char *filename, u8_t **data, long *nbytes) +{ + FILE *f; + + f = fopen(filename, "rb"); + if (f == NULL) abort(); + + fseek(f, 0, SEEK_END); + *nbytes = ftell(f); + fseek(f, 0, SEEK_SET); + + *data = malloc(*nbytes); + fread(*data, *nbytes, 1, f); + + fclose(f); +} + +void put8(FILE *f, unsigned char val) +{ + fwrite(&val, 1, 1, f); +} + +void put16(FILE *f, unsigned short val) +{ + fwrite(&val, 2, 1, f); +} + +void split_images(const char *in_dir, const char *out_dir, + struct image *images, int nimages) +{ + struct clip *clips; + char filename[256]; + long nbytes; + u8_t *data; + char *name; + FILE *f; + int i; + int j; + int k; + + /* Read file and get TOC */ + snprintf(filename, sizeof(filename), "%s/system.idx", in_dir); + readfile(filename, &data, &nbytes); + clips = (struct clip *) (data + 0x01BC); + name = (char *) (data + 8 + *((long *) data)); + + /* Guess how many clips there are with a heuristic */ + for (i = 0 ; clips[i].w != 0 && clips[i].h != 0 ; i++) { + sprintf(filename, "%s/%s.tga", out_dir, name); + name += strlen(name) + 3; + + f = fopen(filename, "wb"); + if (f == NULL) abort(); + + /* Locate the correct source image */ + j = 0; + while (clips[i].y > images[j].height) { + clips[i].y -= images[j].height; + j++; + } + + /* Write header */ + put8(f, 0); put8(f, 0); put8(f, 2); + put16(f, 0); put16(f, 0); put8(f, 0); + put16(f, 0); put16(f, 0); put16(f, clips[i].w); put16(f, clips[i].h); + put8(f, 32); put8(f, 32); + + /* Write scanlines */ + for (k = 0 ; k < clips[i].h ; k++) { + if (clips[i].y == images[j].height) { + clips[i].y = 0; + j++; + } + + fwrite(images[j].planes + ((images[j].width * clips[i].y) + + clips[i].x) * 4, clips[i].w, 4, f); + clips[i].y++; + } + + /* Close output file */ + fclose(f); + } + + /* Cleanup */ + free(data); +} + +int main(int argc, char **argv) +{ + char *in_dir; + char *out_dir; + + struct image images[32]; + char filename[256]; + unsigned int i; + long filesize; + u8_t *lzss, *gc; + FILE *f; + + /* Usage */ + if (argc != 3) { + fprintf(stderr, "Usage: %s [indir] [outdir]\n", argv[0]); + return EXIT_FAILURE; + } + + /* Setup */ + memset(images, 0, sizeof(images)); + in_dir = argv[1]; + out_dir = argv[2]; + + for (i = 0 ; i < 32 ; i++) { + /* Open 0.gcz, 1.gcz etc ... */ + snprintf(filename, sizeof(filename), "%s/%d.gcz", in_dir, i); + f = fopen(filename, "rb"); + if (f == NULL) break; + + /* Read entire file */ + fseek(f, 0, SEEK_END); + filesize = ftell(f); + fseek(f, 0, SEEK_SET); + + fprintf(stderr, "%s: fread", filename); + lzss = malloc(filesize); + fread(lzss, filesize, 1, f); + fclose(f); + + /* Decompress */ + fprintf(stderr, "(OK) expand_lzss"); + gc = expand_lzss(lzss); + free(lzss); + + /* Unpack GC to 32-bit RGBA */ + fprintf(stderr, "(OK) unpack_gc"); + unpack_gc(&images[i], gc); + free(gc); + + fprintf(stderr, "(OK)\n"); + } + + /* Sanity check */ + if (i == 0) { + fprintf(stderr, "No GCZ files found\n"); + exit(EXIT_FAILURE); + } + + /* Emit pile of TGAs */ + fprintf(stderr, "split_images"); + split_images(in_dir, out_dir, images, i); + fprintf(stderr, "(OK)\n\n"); + + return 0; +} + diff --git a/iidx/old 2dx tools/info b/iidx/old 2dx tools/info new file mode 100644 index 0000000..52f563d --- /dev/null +++ b/iidx/old 2dx tools/info @@ -0,0 +1,15 @@ +I have decided to take a break from the world of IIDX AC reverse-engineering, mostly since I've figured out every scrambling algorithm that Konami has thrown at us so far. Here you can download the various information that I and others have gathered about IIDX AC so far. Hope you like C... + +Source Code +crack2dx.c Descramble .2DX (sound archive) files +crackeout.c Descramble/rescramble DATA\INFO\EOUT.BIN (song index file) +crackgcz.c Descramble IIDX DistorteD GCZ files (only DD has scrambled GCZs) +gcz2tga.c Unpack a GCZ (texture) directory into separate TGA files [UPDATED] +packgcz.c Assembles GCZ and IDX files from TGA files +pack2dx.c Import BME charts into IIDX. UNFINISHED, DOES NOT WORK YET. +split2dx.c Splits a non-scrambled .2DX file into WAV files +unz.c Decompress .INZ and .XZ files into .INIs and .Xs respectively + +Contributions and patches are welcome, but don't expect me to work on this stuff again anytime soon. + +Have fun. diff --git a/iidx/old 2dx tools/pack2dx.c b/iidx/old 2dx tools/pack2dx.c new file mode 100644 index 0000000..97ee62a --- /dev/null +++ b/iidx/old 2dx tools/pack2dx.c @@ -0,0 +1,1045 @@ +/* pack2dx.c: Create .1 and .2DX files from .BME and .WAV files. + * + * NOTE: _THIS DOES NOT WORK YET_. Fixing this shit up is left as an exercise + * for the reader. Both the .1 and .2DX stuff generates borked output atm. + * + * Have fun. */ + +#include +#include +#include +#include + +/* + * Error handling + */ + +/** Print an error message and exit with a generic error code */ +void die(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + exit(EXIT_FAILURE); +} + +/* + * Arrays + */ + +struct array { + int step; + int alloced; + int nelts; + void *elts; +}; + +/** Initialise array structure */ +void array_init(struct array *self, int step) +{ + self->step = step; + self->alloced = 4; + self->nelts = 0; + self->elts = malloc(step * 4); +} + +/** Allocate count new entries in the array, returning a pointer to the first + * new entry. Invalidates self->elts. */ +void *array_append(struct array *self, int count) +{ + if (self->nelts + count > self->alloced) { + while (self->nelts + count > self->alloced) self->alloced <<= 1; + self->elts = realloc(self->elts, self->alloced * self->step); + } + + memset(self->elts + (self->step * self->nelts), 0, count * self->step); + + self->nelts += count; + return self->elts + (self->step * (self->nelts - count)); +} + +/** Ensure that the array has at least count elements, filling any newly + * introduced entries with *value. Returns a valid value for self->elts */ +void *array_fill(struct array *self, int count, const void *value) +{ + int resized = 0; + int i; + + if (count <= self->nelts) return self->elts; + + /* Allocate extra memory if necessary */ + while (self->alloced < count) { + self->alloced <<= 1; + resized = 1; + } + + if (resized) { + self->elts = realloc(self->elts, self->alloced * self->step); + } + + /* Fill the empty space */ + for (i = self->nelts ; i < count ; i++) { + memcpy(self->elts + (i * self->step), value, self->step); + } + + self->nelts = count; + return self->elts; +} + +/** Dispose of the array */ +void array_fini(struct array *self) +{ + free(self->elts); +} + +/* + * Hash Tables (string -> int) + */ + +struct hash_node +{ + struct hash_node *next; + int val; + char key[1]; +}; + +struct hash_table { + struct hash_node *buckets[256]; +}; + +/** 8-bit hash function for arbitrary C strings. Adapted from Bob Jenkins' + * hash function. */ +unsigned char hash_function(const char *key) +{ + int hash = 0; + + for ( ; *key != '\0' ; key++) { + hash += *key; + hash += (hash << 10); + hash ^= (hash >> 6); + } + + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + + return (hash ^ (hash >> 8) ^ (hash >> 16) ^ (hash >> 24)); +} + +/** Initialise a hash table */ +void hash_init(struct hash_table *self) +{ + memset(self, 0, sizeof(struct hash_table)); +} + +/** Look up an integer key in the hash table. Returns -1 if not found. */ +int hash_get(struct hash_table *self, const char *key) +{ + struct hash_node *node; + unsigned char bucket; + + bucket = hash_function(key); + for (node = self->buckets[bucket] ; node != NULL ; node = node->next) { + if (strcmp(key, node->key) == 0) { + /* Found it */ + return node->val; + } + } + + /* Not found */ + return -1; +} + +/** Add an entry to the hash table. Note that this function assumes that there + * is no entry currently in the hash table for the current key. */ +void hash_set(struct hash_table *self, const char *key, int val) +{ + struct hash_node *node; + unsigned char bucket; + + bucket = hash_function(key); + + /* Allocate new node */ + node = malloc(sizeof(struct hash_node) + strlen(key)); + node->next = self->buckets[bucket]; + node->val = val; + strcpy(node->key, key); + + /* Prepend to bucket */ + bucket = hash_function(key); + self->buckets[bucket] = node; +} + +/** Hash table cleanup */ +void hash_fini(struct hash_table *self) +{ + struct hash_node *node, *next; + int i; + + for (i = 0 ; i < 256 ; i++) { + node = self->buckets[i]; + next = node != NULL ? node->next : NULL; + + while (node != NULL) { + next = node->next; + free(node); + + node = next; + } + } +} + +/* + * Keysound registry and .2dx construction + */ + +struct keysound { + int id; + char filename[1]; +}; + +struct ks_registry { + struct hash_table filenames; + struct array keysounds; +}; + +/** Initialise the keysound registry */ +void ks_init(struct ks_registry *self) +{ + hash_init(&self->filenames); + array_init(&self->keysounds, sizeof(void *)); +} + +/** Register a WAV file with the keysound registry, or look up an existing + * entry. Returns the integer identifier for the keysound, starting from 1 */ +int ks_register(struct ks_registry *self, const char *filename) +{ + struct keysound **pks; + struct keysound *ks; + int id; + + /* See if we've already allocated a slot for this file */ + id = hash_get(&self->filenames, filename); + + if (id == -1) { + /* Allocate id */ + id = self->keysounds.nelts + 1; + hash_set(&self->filenames, filename, id); + + /* Create keysound record */ + ks = malloc(sizeof(struct keysound) + strlen(filename)); + ks->id = id; + strcpy(ks->filename, filename); + + pks = array_append(&self->keysounds, 1); + *pks = ks; + } + + return id; +} + +/** Construct an unencrypted .2DX file from the contents of the keysound + * registry. */ +void ks_create_2dx(struct ks_registry *self, const char *filename) +{ + unsigned long subheader[] = { + 0x39584432, /* "2DX9" Little Endian */ + 0x00000000, /* Insert filesize here */ + 0xFFFF3230, /* Arbitrary constant */ + 0x00080040, /* Sometimes 0x00010040 */ + 0x00000000 /* Uh, zero I guess */ + }; + + unsigned long wav_length; + struct keysound **keysounds = self->keysounds.elts; + long nkeysounds = self->keysounds.nelts; + long offset = 0x48 + 4 * nkeysounds; + void *wav_data; + FILE *wav; + FILE *out; + int i; + + out = fopen(filename, "wb"); + if (out == NULL) die("Could not create .2dx file %s\n", filename); + + /* Write keysound count */ + fseek(out, 0x14, SEEK_SET); + fwrite(&nkeysounds, 4, 1, out); + + for (i = 0 ; i < nkeysounds ; i++) { + /* Write offset to TOC */ + fseek(out, 0x48 + (i * 4), SEEK_SET); + fwrite(&offset, 4, 1, out); + + /* Open WAV */ + wav = fopen(keysounds[i]->filename, "rb"); + if (wav == NULL) die("Could not open keysound WAV %s\n", + keysounds[i]->filename); + + /* Determine WAV length */ + fseek(wav, 0, SEEK_END); + wav_length = ftell(wav); + fseek(wav, 0, SEEK_SET); + + subheader[1] = wav_length; + wav_data = malloc(wav_length); + fread(wav_data, 1, wav_length, wav); + + /* Output subheader and WAV data at offset */ + fseek(out, offset, SEEK_SET); + fwrite(subheader, 1, sizeof(subheader), out); + fwrite(wav_data, 1, wav_length, out); + + /* Advance offset */ + offset += wav_length; + + /* Cleanup */ + free(wav_data); + fclose(wav); + } +} + +/** Clean up keysound registry */ +void ks_fini(struct ks_registry *self) +{ + struct keysound **keysounds = self->keysounds.elts; + int i; + + for (i = 0 ; i < self->keysounds.nelts ; i++) { + free(keysounds[i]); + } + + hash_fini(&self->filenames); + array_fini(&self->keysounds); +} + +/* + * BMS Data Structures + */ + +enum bms_ev_type { BMS_EV_AUTO, BMS_EV_NOTE, BMS_EV_BPM }; + +struct bms_ev_auto { + int keysound; +}; + +struct bms_ev_note { + int keysound; + int lane; +}; + +struct bms_ev_bpm { + int bpm; +}; + +struct bms_ev { + enum bms_ev_type type; + double measure; + double sec; + union { + struct bms_ev_auto ev_auto; + struct bms_ev_note ev_note; + struct bms_ev_bpm ev_bpm; + } ev; +}; + +struct bms_measure { + double beats; + double start_sec; +}; + +struct bms { + struct hash_table wavs; + struct hash_table bpms; + struct array events; + struct array measures; + const char *filename; + int max_measure; + int start_bpm; +}; + +/* + * BMS Parser + */ + +/** Parse a measure multiplier. Damn that's some hacky syntax */ +void bms_measure_mul(struct bms *self, int measure, char *str) +{ + static const struct bms_measure default_measure = { 4.0, 0 }; + struct bms_measure *measures; + + measures = array_fill(&self->measures, measure, &default_measure); + measures[measure].beats = atof(str) * 4.0; +} + +/** Parse a list of events. Yes I'm aware that this is a horrible mess, + * although having said that I've tried to make it less so. Still, hey, it's + * BMS. It's a mess anyway. */ +void bms_block_list(struct bms *self, struct ks_registry *registry, + int measure, int channel, char *body) +{ + static int lane_map[] = { 1, 2, 3, 4, 5, 0, 0, 6, 7 }; + + char block[3] = { 0, 0, 0 }; /* Null terminate it */ + struct bms_ev *ev; + double step; + int nblocks; + int nchars; + int lane; + int bpm; + int id; + int i; + + self->max_measure = + self->max_measure < measure ? measure : self->max_measure; + + nblocks = strlen(body) / 2; + nchars = nblocks * 2; /* Ignore any odd dangling crap */ + step = 1.0 / nblocks; + + for (i = 0 ; i < nchars ; i += 2) { + block[0] = body[i]; + block[1] = body[i] + 1; + + /* Skip zeros */ + if (block[0] == '0' && block[1] == '0') continue; + + switch (channel) { + case 1: + /* Auto sound */ + id = hash_get(&self->wavs, block); + if (id == -1) continue; + + ev = array_append(&self->events, 1); + ev->measure = measure + (i * step); + ev->type = BMS_EV_AUTO; + ev->ev.ev_auto.keysound = id; + + break; + + case 3: + /* Hex BPM */ + bpm = 0; + sscanf(block, "%x", &bpm); /* Parse hex BPM into bpm */ + if (bpm == 0) continue; + + ev = array_append(&self->events, 1); + ev->measure = measure + (i * step); + ev->type = BMS_EV_BPM; + ev->ev.ev_bpm.bpm = bpm; + + break; + + case 9: + /* Referenced BPM */ + bpm = hash_get(&self->bpms, block); + if (bpm == -1) continue; + + ev = array_append(&self->events, 1); + ev->measure = measure + (i * step); + ev->type = BMS_EV_BPM; + ev->ev.ev_bpm.bpm = bpm; + + break; + + case 11: case 12: case 13: case 14: case 15: case 16: case 18: case 19: + /* P1 note */ + lane = lane_map[channel - 11]; + id = hash_get(&self->wavs, block); + if (id == -1) id = 0; + + ev = array_append(&self->events, 1); + ev->measure = measure + (i * step); + ev->type = BMS_EV_NOTE; + ev->ev.ev_note.keysound = id; + ev->ev.ev_note.lane = lane; + + break; + + case 21: case 22: case 23: case 24: case 25: case 26: case 28: case 29: + /* P2 note */ + lane = lane_map[channel - 21]; + id = hash_get(&self->wavs, block); + if (id == -1) i = 0; + + ev = array_append(&self->events, 1); + ev->measure = measure + (i * step); + ev->type = BMS_EV_NOTE; + ev->ev.ev_note.keysound = id; + ev->ev.ev_note.lane = lane; + + break; + } + } +} + +/** Parse a #WAV declaration */ +void bms_wav_def(struct bms *self, struct ks_registry *registry, char *line) +{ + char *filename; + char *tag; + int id; + + /* Split into tag and filename strings */ + tag = line + 4; + filename = line + 7; + tag[2] = '\0'; + + /* Look up the keysound ID for this filename in the global keysound + * registry. Then associate that ID with the WAV tag */ + id = ks_register(registry, filename); + hash_set(&self->wavs, tag, id); +} + +/** Parse the starting BPM declaration */ +void bms_start_bpm(struct bms *self, char *line) +{ + double bpm; + + sscanf(line, "#BPM %lf", &bpm); + self->start_bpm = (int) bpm; /* BPM must be an integer */ +} + +/** Parse a #BPMxx BPM tag declaration */ +void bms_bpm_def(struct bms *self, char *line) +{ + char *str; + char *tag; + int bpm; + + tag = line + 5; + str = line + 8; + tag[2] = '\0'; + + /* BPM must be an integer */ + bpm = (int) atof(str); + hash_set(&self->bpms, tag, bpm); +} + +void bms_parse_line(struct bms *self, struct ks_registry *registry, char *line) +{ + int measure; + int channel; + char c; + + if (sscanf(line, "#%3d%2d%c", &measure, &channel, &c) == 3 && c == ':') { + /* Probably a block list, unless... */ + if (channel == 2) { + /* Measure multiplier is a special case */ + bms_measure_mul(self, measure, line + 7); + } else { + bms_block_list(self, registry, measure, channel, line + 7); + } + + } else if (strncmp(line, "#WAV", 4) == 0) { + /* Wav def */ + bms_wav_def(self, registry, line); + + } else if (strncmp(line, "#BPM ", 5) == 0) { + /* Starting BPM: note the space */ + bms_start_bpm(self, line); + + } else if (strncmp(line, "#BPM", 4) == 0) { + /* BPM def */ + bms_bpm_def(self, line); + + } else { + /* Something we don't care about */ + } +} + +/** Translate measure positions to absolute time */ +void bms_measure_to_sec(struct bms *self) +{ + struct bms_measure *measures = self->measures.elts; + struct bms_ev *events = self->events.elts; + double ms_beat = 0.0; /* Measure started at this beat */ + double ss_beat = 0.0; /* BPM segment started at this beat */ + double ss_sec = 0.0; /* BPM segment started at this sec */ + double sr_beat; /* Segment relative beat (beats since start of seg) */ + double beat; + double spb = 60.0 / self->start_bpm; /* Seconds per beat */ + int measure = 0; + int i; + + for (i = 0 ; i < self->events.nelts ; i++) { + while (events[i].measure > measure) { + ms_beat += measures[measure++].beats; + measures[measure].start_sec = ss_sec + (ms_beat - ss_beat) * spb; + } + + beat = ms_beat + + (events[i].measure - measure) / measures[measure].beats; + sr_beat = beat - ss_beat; + events[i].sec = ss_sec + sr_beat * spb; + + if (events[i].type == BMS_EV_BPM) { + ss_beat = beat; + ss_sec = events[i].sec; + spb = 60.0 / events[i].ev.ev_bpm.bpm; + } + } + + for ( ; measure < self->measures.nelts ; measure++) { + ms_beat += measures[measure++].beats; + measures[measure].start_sec = ss_sec + (ms_beat - ss_beat) * spb; + } +} + +/** Main BMS parsing function. Keysounds are registered in a common registry */ +struct bms *bms_read(const char *filename, struct ks_registry *registry) +{ + static const struct bms_measure default_measure = { 4.0, 0 }; + struct bms *self; + char buf[16384]; + FILE *f; + int i; + + f = fopen(filename, "r"); + if (f == NULL) return NULL; + + self = calloc(sizeof(struct bms), 1); + self->filename = filename; + + hash_init(&self->wavs); + hash_init(&self->bpms); + array_init(&self->events, sizeof(struct bms_ev)); + array_init(&self->measures, sizeof(struct bms_measure)); + + while (!feof(f)) { + /* Read a line and cut off any trailing CR/LF's */ + fgets(buf, sizeof(buf), f); + if (buf[0] != '#') continue; /* Skip non-directive lines */ + + for (i = 0 ; buf[i] != '\0' ; i++) { + if (buf[i] == '\r' || buf[i] == '\n') buf[i] = '\0'; + } + + /* Process the line */ + bms_parse_line(self, registry, buf); + } + + if (self->start_bpm == 0) die("%s: No starting BPM given\n", filename); + + /* Pad out measure list and perform measure -> sec conversion */ + array_fill(&self->measures, self->max_measure + 2, &default_measure); + bms_measure_to_sec(self); + + /* Clean up temporary hash tables */ + hash_fini(&self->wavs); + hash_fini(&self->bpms); + + return self; +} + +void bms_destroy(struct bms *self) +{ + array_fini(&self->events); + array_fini(&self->measures); + free(self); +} + +/* + * .1 Data Structures + */ + +#define SYSTEM_FPS 59.94 /* NTSC refresh rate */ +#define BINDING_LEAD 15 /* KS binding lead time in FRAMES */ +#define CHART_FRAME(sec) ((sec) * SYSTEM_FPS) + +enum chart_id { + CHART_SP_HYPER, CHART_SP_NORMAL, CHART_SP_ANOTHER, CHART_SP_BEGINNER, + CHART_SP_EXTRA1, CHART_SP_EXTRA2, + + CHART_DP_HYPER, CHART_DP_NORMAL, CHART_DP_ANOTHER, CHART_DP_BEGINNER, + CHART_DP_EXTRA1, CHART_DP_EXTRA2, CHART_MAX +}; + +const char *bms_filenames[] = { + "sp_hyper.bme", "sp_normal.bme", "sp_another.bme", "sp_beginner.bme", + "sp_extra1.bme", "sp_extra2.bme", + + "dp_hyper.bme", "dp_normal.bme", "dp_another.bme", "dp_beginner.bme", + "dp_extra1.bme", "dp_extra2.bme" +}; + +enum one_ev_type { + /* .1 event types in order of sorting tiebreak priority */ + ONE_EV_NOTECOUNT, + ONE_EV_BPM, + ONE_EV_UNKNOWN, + ONE_EV_TIMING, + ONE_EV_BAR_LINE, + ONE_EV_AUTO, + ONE_EV_BIND_KS_1P, + ONE_EV_BIND_KS_2P, + ONE_EV_NOTE_1P, + ONE_EV_NOTE_2P, + ONE_EV_END_CHART +}; + +unsigned char one_ev_codes[] = { + /* .1 event codes as written out to the file */ + 0x10, /* ONE_EV_NOTECOUNT */ + 0x04, /* ONE_EV_BPM */ + 0x05, /* ONE_EV_UNKNOWN */ + 0x08, /* ONE_EV_TIMING */ + 0x0C, /* ONE_EV_BAR_LINE */ + 0x07, /* ONE_EV_AUTO */ + 0x02, /* ONE_EV_BIND_KS_1P */ + 0x03, /* ONE_EV_BIND_KS_2P */ + 0x00, /* ONE_EV_BIND_NOTE_1P */ + 0x01, /* ONE_EV_BIND_NOTE_2P */ + 0x06 /* ONE_EV_END_CHART */ +}; + +struct one_ev { + unsigned int frame; + unsigned char type; + unsigned char selector; + unsigned short value; +}; + +struct one_chart { + struct array events; + int keys[16]; + int is_2p; +}; + +struct one_ev common_prolog[] = { + /* Something or other ... */ + { 0, ONE_EV_UNKNOWN, 0x04, 0x0004 }, + + /* Timing windows (I took 0500's entries as a default, they're all the + * same anyway ... well, with the exception of GAMBOL and others...) */ + { 0, ONE_EV_TIMING, 0x00, 0x00F0 }, + { 0, ONE_EV_TIMING, 0x01, 0x00FA }, + { 0, ONE_EV_TIMING, 0x02, 0x00FF }, + { 0, ONE_EV_TIMING, 0x03, 0x0003 }, + { 0, ONE_EV_TIMING, 0x04, 0x0008 }, + { 0, ONE_EV_TIMING, 0x05, 0x0012 } +}; + +struct one_ev common_epilog[] = { + { 0x7FFFFFFF, 0x00, 0x00, 0x00 } +}; + +/* + * .1 Chart Generation + */ + +/** Emit note count, initial BPM, an unknown required event code, and the + * default IIDX timing windows */ +void chart_emit_prolog(struct one_chart *self, struct bms *bms) +{ + struct one_ev *one_ev; + struct bms_ev *bms_events = bms->events.elts; + int notecount_p1 = 0; + int notecount_p2 = 0; + int i; + + /* Count the notes for P1 and P2 */ + for (i = 0 ; i < bms->events.nelts ; i++) { + if (bms_events[i].type != BMS_EV_NOTE) continue; + + if (bms_events[i].ev.ev_note.lane < 8) { + notecount_p1++; + } else { + notecount_p2++; + } + } + + /* Emit notecount */ + one_ev = array_append(&self->events, 1); + one_ev->type = ONE_EV_NOTECOUNT; + one_ev->value = notecount_p1; + + if (notecount_p2 != 0) { + self->is_2p = 1; + + one_ev = array_append(&self->events, 1); + one_ev->type = ONE_EV_NOTECOUNT; + one_ev->selector = 1; + one_ev->value = notecount_p2; + } + + /* Emit initial BPM */ + one_ev = array_append(&self->events, 1); + one_ev->type = ONE_EV_BPM; + one_ev->value = bms->start_bpm; + + if (notecount_p2 != 0) { + one_ev = array_append(&self->events, 1); + one_ev->type = ONE_EV_BPM; + one_ev->selector = 1; + one_ev->value = bms->start_bpm; + } + + /* Emit rest of prolog */ + one_ev = array_append(&self->events, 7); + memcpy(one_ev, common_prolog, sizeof(struct one_ev) * 7); +} + +/** Emit other stuff that doesn't fit anywhere else (autoplay sounds and BPM + * changes). */ +void chart_emit_misc(struct one_chart *self, struct bms *bms) +{ + struct bms_ev *bms_events = bms->events.elts; + struct one_ev *one_ev; + int i; + + for (i = 0 ; i < bms->events.nelts; i++) { + switch (bms_events[i].type) { + case BMS_EV_AUTO: + one_ev = array_append(&self->events, 1); + one_ev->type = ONE_EV_AUTO; + one_ev->frame = CHART_FRAME(bms_events[i].sec); + one_ev->value = bms_events[i].ev.ev_auto.keysound; + + break; + + case BMS_EV_BPM: + one_ev = array_append(&self->events, 1); + one_ev->type = ONE_EV_BPM; + one_ev->frame = CHART_FRAME(bms_events[i].sec); + one_ev->value = bms_events[i].ev.ev_bpm.bpm; + + if (self->is_2p) { + one_ev = array_append(&self->events, 1); + one_ev->type = ONE_EV_BPM; + one_ev->frame = CHART_FRAME(bms_events[i].sec); + one_ev->value = bms_events[i].ev.ev_bpm.bpm; + one_ev->selector = 1; + } + + break; + + default: + break; + } + } +} + +/** Emit notes and keysound rebind events from BMS (lane,keysound,time) + * tuples */ +void chart_emit_notes(struct one_chart *self, struct bms *bms) +{ + struct bms_ev *bms_events = bms->events.elts; + struct bms_ev_note *bms_note; + struct one_ev *one_ev; + int frame; + int lane; + int i; + + for (i = 0 ; i < bms->events.nelts ; i++) { + if (bms_events[i].type != BMS_EV_NOTE) continue; + bms_note = &bms_events[i].ev.ev_note; + + /* Get some note properties */ + frame = CHART_FRAME(bms_events[i].sec) - BINDING_LEAD; + frame = frame < 0 ? 0 : frame; + lane = bms_note->lane; + + /* Check if we need to bind a different keysound */ + if (bms_note->keysound != 0 && bms_note->keysound != self->keys[lane]){ + /* Change keysound binding on this lane just before the note + * comes up. */ + + one_ev = array_append(&self->events, 1); + one_ev->frame = frame; + one_ev->value = bms_note->keysound + 1; + + if (lane < 8) { + one_ev->type = ONE_EV_BIND_KS_1P; + one_ev->selector = lane; + } else { + one_ev->type = ONE_EV_BIND_KS_2P; + one_ev->selector = lane - 8; + } + + self->keys[lane] = lane; + } + + /* Emit a note event in any case */ + one_ev = array_append(&self->events, 1); + one_ev->frame = frame; + + if (lane < 8) { + one_ev->type = ONE_EV_NOTE_1P; + one_ev->selector = lane; + } else { + one_ev->type = ONE_EV_NOTE_2P; + one_ev->selector = lane - 8; + } + } +} + +/** What it says on the tin. */ +void chart_emit_bar_lines(struct one_chart *self, struct bms *bms) +{ + struct bms_measure *measures = bms->measures.elts; + struct one_ev *one_ev; + int i; + + /* Final measure signifies end-of-chart so we don't draw a bar line + * for it. */ + for (i = 0 ; i < bms->measures.nelts - 1 ; i++) { + one_ev = array_append(&self->events, 1); + one_ev->frame = CHART_FRAME(measures[i].start_sec); + one_ev->type = ONE_EV_BAR_LINE; + + if (self->is_2p) { + one_ev = array_append(&self->events, 1); + one_ev->frame = CHART_FRAME(measures[i].start_sec); + one_ev->type = ONE_EV_BAR_LINE; + one_ev->selector = 1; + } + } +} + +/** Emit an end event and end marker */ +void chart_emit_epilog(struct one_chart *self, struct bms *bms) +{ + struct bms_measure *last_measure; /* HURR */ + struct one_ev *one_ev; + + /* Locate last measure; this isn't actually a measure, instead it indicates + * the end of the chart. */ + last_measure = bms->measures.elts; + last_measure += bms->measures.nelts - 1; + + /* Emit first end marker */ + one_ev = array_append(&self->events, 1); + one_ev->frame = CHART_FRAME(last_measure->start_sec); + one_ev->type = ONE_EV_END_CHART; + + if (self->is_2p) { + one_ev = array_append(&self->events, 1); + one_ev->frame = CHART_FRAME(last_measure->start_sec); + one_ev->type = ONE_EV_END_CHART; + one_ev->selector = 1; + } + + /* Emit second end marker */ + one_ev = array_append(&self->events, 1); + memcpy(one_ev, common_epilog, sizeof(struct one_ev)); +} + +/** qsort() collation function */ +int chart_ev_cmp(const void *p1, const void *p2) +{ + const struct one_ev *lhs = p1; + const struct one_ev *rhs = p2; + + return lhs->frame != rhs->frame + ? lhs->frame - rhs->frame : lhs->type - rhs->type; +} + +/** Top-level BMS to .1 data structure conversion, this is more or less the + * "core" of the application (alongside the .2DX packer) */ +struct one_chart *chart_convert(struct bms *bms) +{ + struct one_chart *self; + + self = calloc(sizeof(struct one_chart), 1); + array_init(&self->events, sizeof(struct one_ev)); + + chart_emit_prolog(self, bms); + chart_emit_notes(self, bms); + chart_emit_bar_lines(self, bms); + chart_emit_misc(self, bms); + chart_emit_epilog(self, bms); + + /* Arrange events in the proper order */ + qsort(self->events.elts, self->events.nelts, sizeof(struct one_ev), + chart_ev_cmp); + + return self; +} + +void chart_destroy(struct one_chart *self) +{ + array_fini(&self->events); + free(self); +} + +/* + * Driver + */ + +/** Read all of the BMS files that are present, convert them into .1 event + * lists, then write out the event lists and a TOC to a .1 file. */ +void chart_create_onefile(const char *outfile, struct ks_registry *registry) +{ + struct one_ev *one_events; + struct one_chart *one; + struct bms *bms; + long offset = 96; + long length = 0; + long zero = 0; + FILE *f; + int i; + int j; + + f = fopen("output.1", "wb"); + if (f == NULL) die("Could not create output.1\n"); + + for (i = 0 ; i < CHART_MAX ; i++) { + /* Read a BMS */ + bms = bms_read(bms_filenames[i], registry); + + if (bms) { + /* Convert the BMS to a one-chart and free the BMS */ + one = chart_convert(bms); + one_events = one->events.elts; + bms_destroy(bms); + + /* Compute offset and emit offset/length */ + length = one->events.nelts * 8; + fwrite(&offset, 4, 1, f); + fwrite(&length, 4, 1, f); + + /* Seek to chart offset and write out chart */ + fseek(f, offset, SEEK_SET); + + for (j = 0 ; j < one->events.nelts ; j++) { + fwrite(&one_events[j].frame, 4, 1, f); + fwrite(&one_ev_codes[one_events[j].type], 1, 1, f); + fwrite(&one_events[j].selector, 1, 1, f); + fwrite(&one_events[j].value, 2, 1, f); + } + + /* Return to next header entry */ + fseek(f, (i + 1) * 8, SEEK_SET); + + /* Finalise and advance position counter */ + offset += length; + chart_destroy(one); + + } else { + /* No corresponding BMS, omit this entry */ + fwrite(&zero, 4, 1, f); + fwrite(&zero, 4, 1, f); + } + } +} + +/** Entry point. This application reads several BMS files having the fixed + * names given in bms_filenames[], when present. The notecharts expressed in + * these BMS files are converted into an equivalent representation in IIDX AC's + * chart format, then combined into a IIDX .1 file. Keysound WAV files + * referenced in these BMS files are then packed into an unencrypted .2DX */ +int main(int argc, char **argv) +{ + struct ks_registry registry; + + ks_init(®istry); + chart_create_onefile("output.1", ®istry); + ks_create_2dx(®istry, "output.2dx"); + + return EXIT_SUCCESS; +} + diff --git a/iidx/old 2dx tools/packgcz.c b/iidx/old 2dx tools/packgcz.c new file mode 100644 index 0000000..fc4e75b --- /dev/null +++ b/iidx/old 2dx tools/packgcz.c @@ -0,0 +1,421 @@ +#include +#include +#include +#include +#include + +#define MAXX 1024 + +typedef enum { true = 1, false = 0 } bool_t; +typedef enum { RIGHT, BELOW } position_t; +typedef unsigned char u8_t; +typedef unsigned short u16_t; +typedef unsigned int u32_t; + +struct image { + u16_t width; + u16_t height; + u32_t pixels[1]; +}; + +struct gc { + u32_t fourcc; + u32_t length_entire; + u32_t unk1; + u16_t width_be; + u16_t height_be; + u32_t unk2; + u32_t length_pixels; + u16_t pixels[0x100000]; +}; + +struct subtexture { + u16_t x; + u16_t y; + u16_t w; + u16_t h; + char *name; + struct image *img; +}; + +static void die(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + exit(EXIT_FAILURE); +} + +static char *stem(const char *src) +{ + /* Borrowed from crackgcz.c */ + const char *pslash; + const char *pdot; + char *result; + + pslash = strrchr(src, '/'); + pdot = strrchr(src, '.'); + + if (pslash == NULL) pslash = strrchr(src, '\\'); + if (pdot == NULL) pdot = src + strlen(src); + + if (pslash == NULL) { + pslash = src; + } else { + pslash++; + } + + result = calloc(pdot - pslash + 1, 1); + strncpy(result, pslash, pdot - pslash); + + return result; +} + +static struct image *read_tga(const char *filename) +{ + struct image *img; + u16_t width; + u16_t height; + u8_t bits; + FILE *f; + + f = fopen(filename, "rb"); + if (f == NULL) die("%s: Error opening file\n", filename); + + /* Get dimensions. We assume this is actually a TGA of the common + * top-left origin true colour type. */ + fseek(f, 0xC, SEEK_SET); + fread(&width, 2, 1, f); + fread(&height, 2, 1, f); + fread(&bits, 1, 1, f); + + if (bits != 32) die("%s: Not a 32-bit TGA file\n", filename); + + /* Alloc */ + img = malloc(sizeof(struct image) + width * height * 4); + img->width = width; + img->height = height; + + /* Read in */ + fseek(f, 0x12, SEEK_SET); + fread(img->pixels, 4, width * height, f); + + /* Cleanup */ + fclose(f); + return img; +} + +static struct subtexture *get_subs(char **filenames, int nsubs) +{ + struct subtexture *subs; + struct image *img; + int i; + + fprintf(stderr, "Reading TGA files ... "); + subs = malloc(sizeof(struct subtexture) * nsubs); + + for (i = 0 ; i < nsubs ; i++) { + img = read_tga(filenames[i]); + + subs[i].w = img->width; + subs[i].h = img->height; + subs[i].name = stem(filenames[i]); + subs[i].img = img; + } + + fprintf(stderr, "%d read\n", nsubs); + return subs; +} + +static int height_pred(const void *ptr1, const void *ptr2) +{ + const struct subtexture *lhs = ptr1; + const struct subtexture *rhs = ptr2; + + /* Descending order */ + return rhs->h == lhs->h ? rhs->w - lhs->w : rhs->h - lhs->h; +} + +static int name_pred(const void *ptr1, const void *ptr2) +{ + const struct subtexture *lhs = ptr1; + const struct subtexture *rhs = ptr2; + + return strcmp(lhs->name, rhs->name); +} + +static bool_t place(struct subtexture *subs, int operand_idx, + int adjunct_idx, position_t pos) +{ + struct subtexture *adjunct = subs + adjunct_idx; + struct subtexture *operand = subs + operand_idx; + struct subtexture *sub; + int i; + + /* Position operand relative to adjunct. We leave 1px of separation + * between the subs to avoid resampling artefacts in-game. */ + operand->x = adjunct->x + (pos == RIGHT ? adjunct->w + 1 : 0); + operand->y = adjunct->y + (pos == BELOW ? adjunct->h + 1 : 0); + + /* Check for X overrun */ + if (operand->x + operand->w > MAXX) return false; + + /* Test for collisions */ + for (i = 0 ; i < operand_idx ; i++) { + sub = subs + i; + + if (!( + operand->x + operand->w < sub->x || + operand->x > sub->x + sub->w || + operand->y + operand->h < sub->y || + operand->y > sub->y + sub->h + )) return false; /* Collision */ + } + + /* No collisions with any other subs that have been placed so far, + * accept this placement. */ + return true; +} + +static u16_t place_subs(struct subtexture *subs, int nsubs) +{ + u16_t maxy; + int i; + int j; + + fprintf(stderr, "Arranging subtextures ...\n"); + + /* Place subs in order of descending height */ + qsort(subs, nsubs, sizeof(struct subtexture), height_pred); + + /* Seed the process */ + subs[0].x = 0; + subs[0].y = 0; + maxy = 0; + + /* For each sub, try to place the sub to the right of a placed sub, + * or failing that try to place the sub below a placed sub. There is + * no vertical limit to the tiling's dimension, so the latter approach + * will always succeed eventually. */ + for (i = 1 ; i < nsubs ; i++) { + for (j = 0 ; j < i ; j++) { + if (place(subs, i, j, RIGHT)) break; + } + + if (j == i) for (j = 0 ; j < i ; j++) { + if (place(subs, i, j, BELOW)) break; + } + + assert(j != nsubs); /* Like I said, place_below() shouldn't fail. */ + + /* Update maxy */ + maxy = maxy < subs[i].y + subs[i].h ? subs[i].y + subs[i].h : maxy; + if (i % 100 == 0) fprintf(stderr, "%d/%d ...\n", i, nsubs); + } + +#ifndef NDEBUG + /* Dump the tiling in the form of some rather bad HTML */ + printf("\n"); + + for (i = 0 ; i < nsubs ; i++) { + printf("
" + "%s
\n", subs[i].x, subs[i].y, subs[i].w, subs[i].h, + subs[i].name); + } +#endif + + /* Finally, sort everything by name */ + qsort(subs, nsubs, sizeof(struct subtexture), name_pred); + + fprintf(stderr, "maxy = %d\n", maxy); + return maxy; +} + +static void copy_scanlines(struct subtexture *sub, struct gc *gcs) +{ + struct gc *gc; + u32_t p32; + u16_t p16; + int gc_top; + int gc_nr; + int x; + int y; + + for (y = 0 ; y < sub->h ; y++) { + gc_nr = (sub->y + y) / 1024; + gc = gcs + gc_nr; + gc_top = gc_nr * 1024; + + for (x = 0 ; x < sub->w ; x++) { + p32 = sub->img->pixels[y * sub->w + x]; + p16 = + (((p32 & 0xFF000000) >= 0x80) << 15) + | (((p32 & 0x00FF0000) >> 19) << 10) + | (((p32 & 0x0000FF00) >> 11) << 5) + | (((p32 & 0x000000FF) >> 3)); + + gc->pixels[(sub->y + y - gc_top) * 1024 + sub->x + x] = p16; + } + } +} + +static u32_t swab32(u32_t in) +{ + u32_t out; + + out = ((in & 0xFF000000) >> 24) | ((in & 0x00FF0000) >> 8) + | ((in & 0x0000FF00) << 8 ) | ((in & 0x000000FF) << 24); + return out; +} + +static struct gc *pack_gc_files(struct subtexture *subs, int nsubs,int ngcs) +{ + struct subtexture *sub; + struct gc *gcs; + int i; + + fprintf(stderr, "Allocating a huge amount of memory and " + "generating GC files ... "); + gcs = calloc(sizeof(struct gc), ngcs); + + for (i = 0 ; i < ngcs ; i++) { + gcs[i].fourcc = 0x204347; /* 'GC \0' */ + gcs[i].length_entire = swab32(sizeof(struct gc)); + gcs[i].width_be = 0x0004; /* stores as 0x0400 BE */ + gcs[i].height_be = 0x0004; /* ditto */ + gcs[i].length_pixels = swab32(1024 * 1024 * 2); + } + + for (i = 0 ; i < nsubs ; i++) { + sub = subs + i; + copy_scanlines(sub, gcs); + + /* Release a bit of memory */ + free(sub->img); + } + + fprintf(stderr, "Done\n"); + return gcs; +} + +static void write_gcz_files(const char *dir, const struct gc *gcs, int ngcs) +{ + static const u32_t exsize = sizeof(struct gc); + char filename[256]; + u8_t *bytes; + FILE *f; + int i; + int j; + + fprintf(stderr, "Writing out GCZ files ... "); + + for (i = 0 ; i < ngcs ; i++) { + /* Open up */ + snprintf(filename, sizeof(filename), "%s/%x.gcz", dir, i); + f = fopen(filename, "wb"); + if (f == NULL) die("Error opening %s for writing\n", filename); + + fwrite(&exsize, 4, 1, f); + bytes = (u8_t *) (gcs + i); + + for (j = sizeof(struct gc) / 8 ; j > 0 ; j--) { + fputc(0xFF, f); + fwrite(bytes, 1, 8, f); + bytes += 8; + } + } + + fprintf(stderr, "Done\n"); +} + +static void write_system_idx(const char *dir, const struct subtexture *subs, + int nsubs, int ngcs) +{ + char trailer[8]; + char gczname[32]; + char filename[512]; + long p1; + long p2; + u32_t rect_offset; + u32_t label_offset; + FILE *f; + u16_t i; + + fprintf(stderr, "Creating SYSTEM.IDX ... "); + + snprintf(filename, 512, "%s/SYSTEM.IDX", dir); + f = fopen(filename, "wb"); + if (f == NULL) die("%s: Could not open for writing\n"); + + rect_offset = 0x1B8; + label_offset = 0x1B8 + (nsubs + 1) * 8; + + /* Write header */ + fwrite(&label_offset, 4, 1, f); + fputc(0x14, f); + fputc(0x00, f); + fputc(ngcs, f); + fputc(0x00, f); + fwrite(&rect_offset, 4, 1, f); + fwrite(&label_offset, 4, 1, f); + + /* Write GCZ path list */ + fseek(f, 0x18, SEEK_SET); + memset(gczname, 0, 32); + + for (i = 0 ; i < ngcs ; i++) { + snprintf(gczname, 32, "/sys/%s/%x.gcz", dir, i); + fwrite(gczname, 1, 32, f); + } + + /* Write rect list */ + fseek(f, rect_offset + 4, SEEK_SET); + + for (i = 0 ; i < nsubs ; i++) { + fwrite(subs + i, 2, 4, f); + } + + memset(trailer, 0, 8); + fwrite(trailer, 2, 4, f); + + /* Write label list */ + fseek(f, label_offset + 8, SEEK_SET); + p1 = ftell(f); + + for (i = 0 ; i < nsubs ; i++) { + fwrite(subs[i].name, 1, strlen(subs[i].name) + 1, f); + fwrite(&i, 2, 1, f); + } + + /* Go back and write the label list length */ + p2 = ftell(f) - p1; + fseek(f, label_offset + 4, SEEK_SET); + fwrite(&p2, 4, 1, f); + + fprintf(stderr, "Done\n"); + fclose(f); +} + +int main(int argc, char **argv) +{ + struct subtexture *subs; + struct gc *gcs; + int nsubs; + int ngcs; + u16_t height; + + nsubs = argc - 2; + subs = get_subs(argv + 2, nsubs); + height = place_subs(subs, nsubs); + + ngcs = height % 1024 == 0 ? height / 1024 : height / 1024 + 1; + gcs = pack_gc_files(subs, nsubs, ngcs); + write_gcz_files(argv[1], gcs, ngcs); + write_system_idx(argv[1], subs, nsubs, ngcs); + + return EXIT_SUCCESS; +} diff --git a/iidx/old 2dx tools/split2dx.c b/iidx/old 2dx tools/split2dx.c new file mode 100644 index 0000000..fa6d7dc --- /dev/null +++ b/iidx/old 2dx tools/split2dx.c @@ -0,0 +1,78 @@ +/* split2dx.c: Extract all WAVs from a .2DX file (sound archive) */ +#include +#include +#include + +int main(int argc, char **argv) +{ + static const char base36[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + char outname[64]; + FILE *out; + FILE *in; + void *bytes; + int nfiles; + int nbytes; + int *toc; + int i; + + /* Usage */ + if (argc != 3) { + fprintf(stderr, "Usage: %s [infile] [outdir]\n", argv[0]); + return EXIT_FAILURE; + } + + /* Open input */ + in = fopen(argv[1], "rb"); + if (!in) { + fprintf(stderr, "%s: Could not open file for reading\n", argv[1]); + return EXIT_FAILURE; + } + + /* Read TOC length */ + fseek(in, 0x14, SEEK_SET); + fread(&nfiles, 4, 1, in); + + /* Read TOC */ + toc = malloc(4 * nfiles); + fseek(in, 0x48, SEEK_SET); + fread(toc, 4, nfiles, in); + + /* Extract files */ + for (i = 0 ; i < nfiles ; i++) { + /* Name output file */ + snprintf(outname, sizeof(outname), "%s/%c%c.wav", argv[2], + base36[(i + 1) / 36], base36[(i + 1) % 36]); + + /* Open output file */ + out = fopen(outname, "wb"); + if (!out) { + fprintf(stderr, "%s: Could not open file for writing\n", outname); + free(toc); + + return EXIT_FAILURE; + } + + /* Put RIFF fourcc which we skipped */ + fwrite("RIFF", 4, 1, out); + + /* Get file length */ + fseek(in, toc[i] + 0x1C, SEEK_SET); + fread(&nbytes, 4, 1, in); + fwrite(&nbytes, 4, 1, out); + + /* Copy */ + bytes = malloc(nbytes); + fread(bytes, 1, nbytes, in); + fwrite(bytes, 1, nbytes, out); + + /* Clean up */ + fclose(out); + free(bytes); + } + + fclose(in); + free(toc); + + return EXIT_SUCCESS; +} + diff --git a/iidx/old 2dx tools/unz.c b/iidx/old 2dx tools/unz.c new file mode 100644 index 0000000..8f633f3 --- /dev/null +++ b/iidx/old 2dx tools/unz.c @@ -0,0 +1,84 @@ +/** unz.c: Decompress miscellaneous stuff like .INZ and .XZ files */ +#include +#include + +typedef unsigned char u8_t; +typedef unsigned int u32_t; + +static void expand_lzss(FILE *in, FILE *out) +{ + static u8_t ring[0x1000]; + unsigned int ring_pos = 0x0FEE; + unsigned int chunk_offset; + unsigned int chunk_length; + unsigned int length; + u32_t control_word = 1; + u8_t cmd1; + u8_t cmd2; + u8_t byte; + + /* Read header (i.e. file length, ignore it) */ + fread(&length, 4, 1, in); + + while (!feof(in) && length > 0) { + if (control_word == 1) { + /* Read a control byte */ + control_word = 0x100 | getc(in); + } + + /* Decode a byte according to the current control byte bit */ + if (control_word & 1) { + /* Straight copy, store into history ring */ + byte = getc(in); + + putc(byte, out); + ring[ring_pos] = byte; + + ring_pos = (ring_pos + 1) % 0x1000; + length--; + } else { + /* Reference to data in ring buffer */ + cmd1 = getc(in); + cmd2 = getc(in); + + chunk_length = (cmd2 & 0x0F) + 3; + chunk_offset = ((cmd2 & 0xF0) << 4) | cmd1; + + for ( ; chunk_length > 0 && length > 0 ; chunk_length--) { + /* Copy historical data to output AND current ring pos */ + putc(ring[chunk_offset], out); + ring[ring_pos] = ring[chunk_offset]; + + /* Update counters */ + chunk_offset = (chunk_offset + 1) % 0x1000; + ring_pos = (ring_pos + 1) % 0x1000; + length--; + } + } + + /* Get next control bit */ + control_word >>= 1; + } +} + +int main(int argc, char **argv) +{ + FILE *in; + FILE *out; + + if (argc != 3) { + fprintf(stderr, "Usage: %s [infile] [outfile]\n", argv[0]); + return EXIT_FAILURE; + } + + in = fopen(argv[1], "rb"); + out = fopen(argv[2], "wb"); + + expand_lzss(in, out); + + fclose(in); + fclose(out); + + return EXIT_SUCCESS; +} + diff --git a/iidx/packgcz_pop/cygwin1.dll b/iidx/packgcz_pop/cygwin1.dll new file mode 100644 index 0000000..f1a22fe Binary files /dev/null and b/iidx/packgcz_pop/cygwin1.dll differ diff --git a/iidx/packgcz_pop/packgcz.exe b/iidx/packgcz_pop/packgcz.exe new file mode 100644 index 0000000..442bf01 Binary files /dev/null and b/iidx/packgcz_pop/packgcz.exe differ diff --git a/misc/firebeatdump/firebeatdump.exe b/misc/firebeatdump/firebeatdump.exe new file mode 100644 index 0000000..40ec51c Binary files /dev/null and b/misc/firebeatdump/firebeatdump.exe differ diff --git a/misc/firebeatdump/main.cpp b/misc/firebeatdump/main.cpp new file mode 100644 index 0000000..5f5c31b --- /dev/null +++ b/misc/firebeatdump/main.cpp @@ -0,0 +1,93 @@ +#include +#include "common/IFileStream.h" + +void main(int argc, char ** argv) +{ + if(argc != 3) + { + _FATALERROR("usage: firebeatdump [in] [out]"); + return; + } + + IFileStream in; + IFileStream out; + + if(!in.Open(argv[1])) + { + _FATALERROR("couldn't open input file (%s)", argv[1]); + return; + } + + if(!out.Create(argv[2])) + { + _FATALERROR("couldn't open output file (%s)", argv[2]); + return; + } + + UInt32 header = in.Read32(); + + _MESSAGE("header = %08X", header); + + UInt8 history[0x1000]; + memset(&history, 0, sizeof(history)); + UInt32 historyOffset = 0x0FEE; // wtf + + while(in.GetRemain() >= 9) + { + UInt32 offset = in.GetOffset(); + UInt8 select = in.Read8(); + + _MESSAGE("%08X: %02X", offset, select); + + gLog.Indent(); + + try + { + for(UInt8 bit = 0; bit < 8; bit++) + { + if(select & (1 << bit)) + { + UInt8 data = in.Read8(); + + if(std::isprint(data)) + _MESSAGE("%c (%02X)", data, data); + else + _MESSAGE("%02X", data); + + out.Write8(data); + + history[historyOffset] = data; + historyOffset = (historyOffset + 1) & 0x0FFF; + } + else + { + UInt8 data0 = in.Read8(); + UInt8 data1 = in.Read8(); + + UInt8 chunkLen = (data1 & 0x0F) + 3; + UInt16 offset = ((data1 & 0xF0) << 4) | data0; + + _MESSAGE("%02X %02X (len = %02X, offset = %04X)", data0, data1, chunkLen, offset); + + for(UInt32 i = 0; i < chunkLen; i++) + { + UInt8 data = history[offset]; + + out.Write8(data); + + history[historyOffset] = data; + historyOffset = (historyOffset + 1) & 0x0FFF; + + offset = (offset + 1) & 0x0FFF; + } + } + } + } + catch(...) + { + _MESSAGE("### EOF"); + } + + gLog.Outdent(); + } +} diff --git a/misc/hsdump/hsdump.exe b/misc/hsdump/hsdump.exe new file mode 100644 index 0000000..505cbb0 Binary files /dev/null and b/misc/hsdump/hsdump.exe differ diff --git a/misc/hsdump/main.cpp b/misc/hsdump/main.cpp new file mode 100644 index 0000000..d0a04c5 --- /dev/null +++ b/misc/hsdump/main.cpp @@ -0,0 +1,94 @@ +#include "common/IFileStream.h" + +IDebugLog gLog("hsdump.log"); + +#pragma pack (push, 1) +struct GCHeader +{ + char sig[4]; + UInt32 unk1; + UInt32 unk2; + UInt16 width; + UInt16 height; + UInt32 unk3; + UInt32 unk4; + + void Swap(void) + { + width = Swap16(width); + height = Swap16(height); + } +}; + +struct TGAHeader +{ + UInt8 identSize; + UInt8 palType; + UInt8 imgType; + UInt16 palStart; + UInt16 palLen; + UInt8 palBpp; + UInt16 xOrigin; + UInt16 yOrigin; + UInt16 width; + UInt16 height; + UInt8 bpp; + UInt8 flags; +}; + +int main(int argc, char ** argv) +{ + if(argc != 3) + { + _ERROR("usage: hsdump [in] [out]"); + return -1; + } + + IFileStream src, dst; + if(src.Open(argv[1]) && dst.Create(argv[2])) + { + GCHeader header; + + src.ReadBuf(&header, sizeof(header)); + header.Swap(); + + if((header.sig[0] == 'G') && (header.sig[1] == 'C')) + { + _MESSAGE("size %dx%d", header.width, header.height); + + TGAHeader tgaHeader; + memset(&tgaHeader, 0, sizeof(tgaHeader)); + tgaHeader.imgType = 2; // rgb + tgaHeader.width = header.width; + tgaHeader.height = header.height; + tgaHeader.bpp = 16; + tgaHeader.flags = 0x21; // y goes down, 1 alpha bit + + dst.WriteBuf(&tgaHeader, sizeof(tgaHeader)); + + UInt32 expectedLength = header.width * header.height * 2; + UInt32 actualLength = src.GetRemain(); + if(expectedLength < actualLength) + actualLength = expectedLength; + + IDataStream::CopySubStreams(&dst, &src, actualLength); + + UInt32 padding = expectedLength - actualLength; + for(UInt32 i = 0; i < padding; i++) + dst.Write8(0); + } + else + { + _ERROR("bad sig %.4s", header.sig); + } + } + else + { + _ERROR("couldn't open src file %s", argv[1]); + } +} + +#pragma pack (pop, 1) + +// 47432000 001CA018 00000000 03940400 00000000 001CA000 +// 47432000 00020018 00000000 01000100 00000000 00020000