Initial Commit
First commit of the overhauled ACSE. Supports all Animal Crossing games from the GameCube version all the way through Welcome Amiibo!
17
.gitattributes
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
|
||||
# Custom for Visual Studio
|
||||
*.cs diff=csharp
|
||||
|
||||
# Standard to msysgit
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
10
.gitignore
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
*.suo
|
||||
*.exe
|
||||
*.resources
|
||||
*.cache
|
||||
*.pdb
|
||||
*.db
|
||||
*.config
|
||||
bin/
|
||||
.vs/
|
||||
obj/
|
2816
ACSE.csproj
Normal file
3
ACSE.csproj.user
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
</Project>
|
28
ACSE.sln
Normal file
|
@ -0,0 +1,28 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ACSE", "ACSE.csproj", "{078BA400-42DD-432A-9844-32213157A29D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{078BA400-42DD-432A-9844-32213157A29D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{078BA400-42DD-432A-9844-32213157A29D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{078BA400-42DD-432A-9844-32213157A29D}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{078BA400-42DD-432A-9844-32213157A29D}.Debug|x86.Build.0 = Debug|x86
|
||||
{078BA400-42DD-432A-9844-32213157A29D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{078BA400-42DD-432A-9844-32213157A29D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{078BA400-42DD-432A-9844-32213157A29D}.Release|x86.ActiveCfg = Release|x86
|
||||
{078BA400-42DD-432A-9844-32213157A29D}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
BIN
ACSE_Logo_2.ico
Normal file
After Width: | Height: | Size: 361 KiB |
2007
Classes/AcreData.cs
Normal file
206
Classes/Checksum.cs
Normal file
|
@ -0,0 +1,206 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
//Used in Doubutsu no Mori, Doubutsu no Mori+, Animal Crossing, Doubutsu no Mori e+, and Wild World
|
||||
public static class Checksum
|
||||
{
|
||||
|
||||
//Checksum Calculation Method:
|
||||
//The checksum is located at 0x26052, and is an Unsigned Short
|
||||
//The checksum is an offset value, so that the final additive of the save + the checksum is equal to 0
|
||||
//The checksum offset is calculated by iterating through 0x26040 - 0x26051 and 0x26053 - 0x4C03F inclusively and adding every two bytes as a 16 bit ushort
|
||||
//The checksum offset can then be verfied by adding 0x26040 - 0x4C03F in two byte intervals. If your sum is 0, then the checksum offset value is correct!
|
||||
//Important to note that the gamecube used Big Endian notation, so you will likely have to convert between Little & Big Endian values to get a correct chksum
|
||||
|
||||
public static ushort Calculate(byte[] buffer, int checksumOffset, bool little_endian = false)
|
||||
{
|
||||
ushort checksum = 0;
|
||||
if (little_endian)
|
||||
{
|
||||
for (int i = 0; i < checksumOffset; i += 2)
|
||||
checksum += (ushort)((buffer[i + 1] << 8) + buffer[i]);
|
||||
for (int i = checksumOffset + 2; i < buffer.Length - 1; i += 2)
|
||||
checksum += (ushort)((buffer[i + 1] << 8) + buffer[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < checksumOffset; i += 2)
|
||||
checksum += (ushort)((buffer[i] << 8) + buffer[i + 1]);
|
||||
for (int i = checksumOffset + 2; i < buffer.Length - 1; i += 2)
|
||||
checksum += (ushort)((buffer[i] << 8) + buffer[i + 1]);
|
||||
}
|
||||
return (ushort)-checksum;
|
||||
}
|
||||
|
||||
public static bool Verify(byte[] buffer, int checksumOffset)
|
||||
{
|
||||
return BitConverter.ToUInt16(new byte[2] { buffer[checksumOffset + 1], buffer[checksumOffset] }, 0) == Calculate(buffer, checksumOffset);
|
||||
}
|
||||
|
||||
public static void Update(byte[] buffer, int checksumOffset)
|
||||
{
|
||||
byte[] chksumBytes = BitConverter.GetBytes(Calculate(buffer, checksumOffset));
|
||||
Array.Reverse(chksumBytes);
|
||||
chksumBytes.CopyTo(buffer, checksumOffset);
|
||||
}
|
||||
}
|
||||
|
||||
//Used in City Folk
|
||||
public static class CRC32
|
||||
{
|
||||
// Table of CRC-32's of all single byte values
|
||||
public static uint[] crctab = new uint[]
|
||||
{
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419,
|
||||
0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4,
|
||||
0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07,
|
||||
0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
|
||||
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856,
|
||||
0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
|
||||
0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
|
||||
0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3,
|
||||
0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A,
|
||||
0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599,
|
||||
0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
|
||||
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190,
|
||||
0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
|
||||
0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E,
|
||||
0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED,
|
||||
0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
|
||||
0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3,
|
||||
0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
|
||||
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
|
||||
0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
|
||||
0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010,
|
||||
0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17,
|
||||
0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6,
|
||||
0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,
|
||||
0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
|
||||
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344,
|
||||
0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
|
||||
0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A,
|
||||
0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1,
|
||||
0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C,
|
||||
0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
|
||||
0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
|
||||
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE,
|
||||
0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
|
||||
0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C,
|
||||
0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B,
|
||||
0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
|
||||
0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1,
|
||||
0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
|
||||
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278,
|
||||
0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
|
||||
0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66,
|
||||
0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
|
||||
0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8,
|
||||
0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B,
|
||||
0x2D02EF8D
|
||||
};
|
||||
|
||||
public static uint GetCRC32(byte[] pBuf, uint initial = 0xFFFFFFFF)
|
||||
{
|
||||
uint c = initial;
|
||||
int i, n = pBuf.Length;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
byte index = (byte)((c & 0xFF) ^ pBuf[i]);
|
||||
c = crctab[index] ^ ((c >> 8) & 0xFFFFFF);
|
||||
}
|
||||
return ~c;
|
||||
}
|
||||
}
|
||||
|
||||
//Used in New Leaf
|
||||
public static class NL_CRC32
|
||||
{
|
||||
public static uint[] NL_CRC_Table = {
|
||||
0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F,
|
||||
0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, 0x8AD958CF, 0x78B2DBCC,
|
||||
0x6BE22838, 0x9989AB3B, 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27,
|
||||
0x5E133C24, 0x105EC76F, 0xE235446C, 0xF165B798, 0x30E349B,
|
||||
0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384, 0x9A879FA0,
|
||||
0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, 0x5D1D08BF, 0xAF768BBC,
|
||||
0xBC267848, 0x4E4DFB4B, 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29,
|
||||
0x33ED7D2A, 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
|
||||
0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, 0x6DFE410E,
|
||||
0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA, 0x30E349B1, 0xC288CAB2,
|
||||
0xD1D83946, 0x23B3BA45, 0xF779DEAE, 0x05125DAD, 0x1642AE59,
|
||||
0xE4292D5A, 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
|
||||
0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, 0x417B1DBC,
|
||||
0xB3109EBF, 0xA0406D4B, 0x522BEE48, 0x86E18AA3, 0x748A09A0,
|
||||
0x67DAFA54, 0x95B17957, 0xCBA24573, 0x39C9C670, 0x2A993584,
|
||||
0xD8F2B687, 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
|
||||
0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, 0x96BF4DCC,
|
||||
0x64D4CECF, 0x77843D3B, 0x85EFBE38, 0xDBFC821C, 0x2997011F,
|
||||
0x3AC7F2EB, 0xC8AC71E8, 0x1C661503, 0xEE0D9600, 0xFD5D65F4,
|
||||
0x0F36E6F7, 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
|
||||
0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789, 0xEB1FCBAD,
|
||||
0x197448AE, 0x0A24BB5A, 0xF84F3859, 0x2C855CB2, 0xDEEEDFB1,
|
||||
0xCDBE2C45, 0x3FD5AF46, 0x7198540D, 0x83F3D70E, 0x90A324FA,
|
||||
0x62C8A7F9, 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
|
||||
0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, 0x3CDB9BDD,
|
||||
0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829, 0x82F63B78, 0x709DB87B,
|
||||
0x63CD4B8F, 0x91A6C88C, 0x456CAC67, 0xB7072F64, 0xA457DC90,
|
||||
0x563C5F93, 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
|
||||
0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C, 0x92A8FC17,
|
||||
0x60C37F14, 0x73938CE0, 0x81F80FE3, 0x55326B08, 0xA759E80B,
|
||||
0xB4091BFF, 0x466298FC, 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F,
|
||||
0x0B21572C, 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
|
||||
0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, 0x65D122B9,
|
||||
0x97BAA1BA, 0x84EA524E, 0x7681D14D, 0x2892ED69, 0xDAF96E6A,
|
||||
0xC9A99D9E, 0x3BC21E9D, 0xEF087A76, 0x1D63F975, 0x0E330A81,
|
||||
0xFC588982, 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
|
||||
0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, 0x38CC2A06,
|
||||
0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, 0xFF56BD19, 0x0D3D3E1A,
|
||||
0x1E6DCDEE, 0xEC064EED, 0xC38D26C4, 0x31E6A5C7, 0x22B65633,
|
||||
0xD0DDD530, 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
|
||||
0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, 0x8ECEE914,
|
||||
0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, 0xD3D3E1AB, 0x21B862A8,
|
||||
0x32E8915C, 0xC083125F, 0x144976B4, 0xE622F5B7, 0xF5720643,
|
||||
0x07198540, 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
|
||||
0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F, 0xE330A81A,
|
||||
0x115B2B19, 0x020BD8ED, 0xF0605BEE, 0x24AA3F05, 0xD6C1BC06,
|
||||
0xC5914FF2, 0x37FACCF1, 0x69E9F0D5, 0x9B8273D6, 0x88D28022,
|
||||
0x7AB90321, 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
|
||||
0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, 0x34F4F86A,
|
||||
0xC69F7B69, 0xD5CF889D, 0x27A40B9E, 0x79B737BA, 0x8BDCB4B9,
|
||||
0x988C474D, 0x6AE7C44E, 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052,
|
||||
0xAD7D5351
|
||||
};
|
||||
|
||||
public static uint Calculate_CRC32(byte[] data)
|
||||
{
|
||||
int size = data.Length;
|
||||
uint crc = 0xFFFFFFFF;
|
||||
int p = 0;
|
||||
while (size-- != 0)
|
||||
crc = NL_CRC_Table[(crc ^ data[p++]) & 0xFF] ^ (crc >> 8);
|
||||
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
public static uint Get_CRC32(byte[] data, int offset, int length)
|
||||
{
|
||||
return Calculate_CRC32(data.Skip(offset).Take(length).ToArray());
|
||||
}
|
||||
|
||||
public static bool Verify_CRC32(byte[] data, int offset, int length)
|
||||
{
|
||||
return Get_CRC32(data, offset + 4, length - 4) == BitConverter.ToUInt32(data, offset);
|
||||
}
|
||||
}
|
||||
}
|
173
Classes/DataConverter.cs
Normal file
|
@ -0,0 +1,173 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
public static class DataConverter
|
||||
{
|
||||
private static byte ConvertByte(BitArray b)
|
||||
{
|
||||
byte value = 0;
|
||||
for (byte i = 0; i < b.Count; i++)
|
||||
if (b[i])
|
||||
value |= (byte)(1 << i);
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Dictionary<Type, Delegate> typeMap = new Dictionary<Type, Delegate>
|
||||
{
|
||||
{typeof(byte[]), new Func<byte[], byte>
|
||||
(b => {
|
||||
return ConvertByte(new BitArray(b));
|
||||
})
|
||||
},
|
||||
{typeof(BitArray), new Func<BitArray, byte>
|
||||
(b => {
|
||||
return ConvertByte(b);
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
public static void WriteByte(int offset, byte data)
|
||||
{
|
||||
//MainForm.SaveBuffer[offset] = data;
|
||||
}
|
||||
|
||||
public static void WriteByteArray(int offset, byte[] data, bool reverse = true)
|
||||
{
|
||||
if (reverse)
|
||||
Array.Reverse(data);
|
||||
//data.CopyTo(MainForm.SaveBuffer, offset);
|
||||
}
|
||||
|
||||
public static void Write(int offset, object data, bool reverse = true)
|
||||
{
|
||||
Type type = data.GetType();
|
||||
if (type.IsArray && typeof(byte[]) != type)
|
||||
{
|
||||
object[] arr = ((Array)data).Cast<object>().ToArray();
|
||||
int objSize = Marshal.SizeOf(arr[0]);
|
||||
Type t = type.GetElementType();
|
||||
for (int i = 0; i < arr.Length; i++)
|
||||
WriteByteArray(offset + i * objSize,
|
||||
(byte[])typeof(BitConverter).GetMethod("GetBytes", new Type[] { type.GetElementType() }).Invoke(null, new object[] { arr[i] }),
|
||||
reverse);
|
||||
}
|
||||
else if (type.IsArray && typeof(byte[]) == type)
|
||||
WriteByteArray(offset, (byte[])data, reverse);
|
||||
else if (typeof(byte) == type)
|
||||
WriteByte(offset, (byte)data);
|
||||
else
|
||||
{
|
||||
var convertedData = Convert.ChangeType(data, type);
|
||||
WriteByteArray(offset, (byte[])typeof(BitConverter)
|
||||
.GetMethod("GetBytes", new Type[] { convertedData.GetType() })
|
||||
.Invoke(null, new object[] { convertedData }), reverse);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte ReadByte(int offset)
|
||||
{
|
||||
return 0; //MainForm.SaveBuffer[offset];
|
||||
}
|
||||
|
||||
public static byte[] ReadData(int offset, int size)
|
||||
{
|
||||
byte[] data = new byte[size];
|
||||
//Buffer.BlockCopy(MainForm.SaveBuffer, offset, data, 0, size);
|
||||
Array.Reverse(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
public static byte[] ReadDataRaw(int offset, int size)
|
||||
{
|
||||
byte[] data = new byte[size];
|
||||
//Buffer.BlockCopy(MainForm.SaveBuffer, offset, data, 0, size);
|
||||
return data;
|
||||
}
|
||||
|
||||
public static ushort ReadUShort(int offset)
|
||||
{
|
||||
return BitConverter.ToUInt16(ReadData(offset, 2), 0);
|
||||
}
|
||||
|
||||
public static ushort[] ReadUShortArray(int offset, int numUshorts)
|
||||
{
|
||||
ushort[] ushortArray = new ushort[numUshorts];
|
||||
for (int i = 0; i < numUshorts; i++)
|
||||
ushortArray[i] = ReadUShort(offset + i * 2);
|
||||
return ushortArray;
|
||||
}
|
||||
|
||||
public static uint ReadUInt(int offset)
|
||||
{
|
||||
return BitConverter.ToUInt32(ReadData(offset, 4), 0);
|
||||
}
|
||||
|
||||
public static uint[] ReadUIntArray(int offset, int numInts)
|
||||
{
|
||||
uint[] uintArray = new uint[numInts];
|
||||
for (int i = 0; i < numInts; i++)
|
||||
uintArray[i] = ReadUInt(offset + i * 4);
|
||||
return uintArray;
|
||||
}
|
||||
|
||||
public static ACString ReadString(int offset, int maxSize)
|
||||
{
|
||||
byte[] data = new byte[maxSize];
|
||||
//Buffer.BlockCopy(MainForm.SaveBuffer, offset, data, 0, maxSize);
|
||||
return new ACString(data);
|
||||
}
|
||||
|
||||
public static void WriteString(int offset, string str, int maxSize)
|
||||
{
|
||||
byte[] strBytes = new byte[maxSize];
|
||||
byte[] ACStringBytes = ACString.GetBytes(str, maxSize);
|
||||
if (ACStringBytes.Length <= maxSize)
|
||||
{
|
||||
ACStringBytes.CopyTo(strBytes, 0);
|
||||
if (str.Length < maxSize)
|
||||
for (int i = (str.Length); i <= maxSize - 1; i++)
|
||||
strBytes[i] = 0x20;
|
||||
//strBytes.CopyTo(MainForm.SaveBuffer, offset);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] ToBits(byte[] Byte_Buffer, bool Reverse = false)
|
||||
{
|
||||
byte[] Bits = new byte[8 * Byte_Buffer.Length];
|
||||
for (int i = 0; i < Byte_Buffer.Length; i++)
|
||||
{
|
||||
BitArray Bit_Array = new BitArray(new byte[] { Byte_Buffer[i] });
|
||||
for (int x = 0; x < Bit_Array.Length; x++)
|
||||
Bits[i * 8 + (Reverse ? 7 - x : x)] = Convert.ToByte(Bit_Array[x]);
|
||||
}
|
||||
return Bits;
|
||||
}
|
||||
|
||||
public static byte ToBit(byte Bit_Byte, int Bit_Index, bool Reverse = false)
|
||||
{
|
||||
return (byte)((Reverse ? Bit_Byte >> (7 - Bit_Index) : Bit_Byte >> Bit_Index) & 1);
|
||||
}
|
||||
|
||||
public static void SetBit(ref byte Bit_Byte, int Bit_Index, bool Set, bool Reverse = false)
|
||||
{
|
||||
int Mask = 1 << (Reverse ? 7 - Bit_Index : Bit_Index);
|
||||
if (Set)
|
||||
Bit_Byte = Bit_Byte |= (byte)Mask;
|
||||
else
|
||||
Bit_Byte = Bit_Byte &= (byte)~Mask;
|
||||
}
|
||||
|
||||
public static byte ToByte(object Variant)
|
||||
{
|
||||
return (byte)typeMap[Variant.GetType()].DynamicInvoke(Variant);
|
||||
}
|
||||
}
|
||||
}
|
90
Classes/DateUtil.cs
Normal file
|
@ -0,0 +1,90 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
public static class DateUtil
|
||||
{
|
||||
//Might use for something
|
||||
public static uint Day_String_to_Number(string day)
|
||||
{
|
||||
if (Enum.IsDefined(typeof(DayOfWeek), day))
|
||||
return Convert.ToUInt32((DayOfWeek)Enum.Parse(typeof(DayOfWeek), day, true));
|
||||
return 0; //Guess we're going Sunday
|
||||
}
|
||||
}
|
||||
|
||||
public class ACDate
|
||||
{
|
||||
public uint Second = 0;
|
||||
public uint Minute = 0;
|
||||
public uint Hour = 0;
|
||||
public uint Day = 0;
|
||||
public uint Day_of_Week = 0;
|
||||
public uint Month = 0;
|
||||
public uint Year = 0;
|
||||
public string Date_Time_String = "";
|
||||
public bool Is_PM = false;
|
||||
|
||||
public ACDate(byte[] dateData, bool reversed = false)
|
||||
{
|
||||
if (dateData.Length == 0x8)
|
||||
{
|
||||
Second = dateData[0];
|
||||
Minute = dateData[1];
|
||||
Hour = dateData[2];
|
||||
Day = dateData[3];
|
||||
Day_of_Week = dateData[4];
|
||||
Month = dateData[5];
|
||||
Year = BitConverter.ToUInt16(new byte[] { dateData[7], dateData[6] }, 0);
|
||||
}
|
||||
else if (dateData.Length == 0x4)
|
||||
{
|
||||
Year = BitConverter.ToUInt16(new byte[] { dateData[reversed ? 3 : 1], dateData[reversed ? 2 : 0] }, 0);
|
||||
Month = dateData[reversed ? 1 : 2];
|
||||
Day = dateData[reversed ? 0 : 3];
|
||||
}
|
||||
|
||||
Is_PM = Hour >= 12;
|
||||
Date_Time_String = string.Format("{0}:{1}:{2} {3}, {4}/{5}/{6}", (Hour % 12) == 0 ? 12 : Hour % 12,
|
||||
Minute.ToString("D2"), Second.ToString("D2"), Is_PM ? "PM" : "AM", Month, Day, Year); //Default date/time string
|
||||
}
|
||||
|
||||
public string Format(string formatString) //Need to redo this if there is a more efficient/cleaner way
|
||||
{
|
||||
formatString = formatString.Replace("(s)", Second.ToString("D2"));
|
||||
formatString = formatString.Replace("(m)", Minute.ToString("D2"));
|
||||
formatString = formatString.Replace("(h)", (Hour % 12) == 0 ? "12" : (Hour % 12).ToString());
|
||||
formatString = formatString.Replace("(H)", Hour.ToString());
|
||||
formatString = formatString.Replace("(d)", Day.ToString());
|
||||
formatString = formatString.Replace("(D)", Day.ToString("D2"));
|
||||
formatString = formatString.Replace("(w)", Day_of_Week.ToString());
|
||||
formatString = formatString.Replace("(W)", Enum.GetName(typeof(DayOfWeek), Day_of_Week));
|
||||
formatString = formatString.Replace("(m)", Month.ToString());
|
||||
formatString = formatString.Replace("(M)", Month.ToString("D2"));
|
||||
formatString = formatString.Replace("(y)", Year.ToString());
|
||||
formatString = formatString.Replace("(Y)", Year.ToString().Substring(2, 2));
|
||||
formatString = formatString.Replace("(a)", Is_PM ? "PM" : "AM");
|
||||
formatString = formatString.Replace("(A)", Is_PM ? "P.M." : "A.M.");
|
||||
return formatString;
|
||||
}
|
||||
|
||||
public byte[] ToBytes()
|
||||
{
|
||||
return new byte[8]
|
||||
{
|
||||
(byte)Second,
|
||||
(byte)Minute,
|
||||
(byte)Hour,
|
||||
(byte)Day,
|
||||
(byte)Day_of_Week,
|
||||
(byte)Month,
|
||||
(byte)((Year & 0xFF00) >> 8),
|
||||
(byte)(Year & 0x00FF)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
60
Classes/DebugManager.cs
Normal file
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
public enum DebugLevel
|
||||
{
|
||||
None,
|
||||
Error,
|
||||
Info,
|
||||
Debug
|
||||
}
|
||||
|
||||
public class DebugManager
|
||||
{
|
||||
private static string Log_File_Name = "ACSE_Log";
|
||||
private FileStream Log_File;
|
||||
private StreamWriter Log_Writer;
|
||||
public bool Enabled = false;
|
||||
|
||||
public DebugManager()
|
||||
{
|
||||
if (Properties.Settings.Default.DebugLevel > 0)
|
||||
{
|
||||
Log_File = new FileStream(Get_Log_File_Path(), FileMode.OpenOrCreate);
|
||||
Log_Writer = new StreamWriter(Log_File);
|
||||
Log_Writer.BaseStream.Seek(0, SeekOrigin.End);
|
||||
Enabled = true;
|
||||
WriteLine("========== Debug Log Initiated ==========");
|
||||
}
|
||||
else
|
||||
{
|
||||
Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Log_File_Exists()
|
||||
{
|
||||
return File.Exists(Get_Log_File_Path());
|
||||
}
|
||||
|
||||
public string Get_Log_File_Path()
|
||||
{
|
||||
return NewMainForm.Assembly_Location + string.Format("\\{0}.txt", Log_File_Name);
|
||||
}
|
||||
|
||||
public void WriteLine(string Contents, DebugLevel Level = DebugLevel.Info)
|
||||
{
|
||||
if (Log_Writer != null && Level <= Properties.Settings.Default.DebugLevel)
|
||||
{
|
||||
Log_Writer.WriteLine(string.Format("[{0}] - ({1}) - {2} => {3}", Level, NewMainForm.Save_File != null
|
||||
? NewMainForm.Save_File.Save_Type.ToString().Replace("_", " ") : "No Save", DateTime.Now, Contents));
|
||||
Log_Writer.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
315
Classes/HouseData.cs
Normal file
|
@ -0,0 +1,315 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
public struct House_Offsets
|
||||
{
|
||||
public int Room_Start;
|
||||
public int Room_Size;
|
||||
public int Layer_Size;
|
||||
public int Layer_Count;
|
||||
public int House_Upgrade_Size;
|
||||
public int Owning_Player_ID;
|
||||
public int Owning_Player_Name;
|
||||
public int Town_ID;
|
||||
public int Town_Name;
|
||||
public int Design;
|
||||
public int Design_Size;
|
||||
public int Bed; //CF Exclusive
|
||||
public int Roof_Color;
|
||||
public int Customization_Start; //NL Exclusive
|
||||
public int Mailbox;
|
||||
public int Mail_Size;
|
||||
public int Mail_Count;
|
||||
public int Gyroid_Items; //AC Exclusive
|
||||
public int Gryoid_Message; //AC Exclusive
|
||||
}
|
||||
|
||||
public struct House_Data
|
||||
{
|
||||
public Room[] Rooms;
|
||||
public byte House_Upgrade_Size;
|
||||
public ushort Owning_Player_ID;
|
||||
public string Owning_Player_Name;
|
||||
public ushort Town_ID;
|
||||
public string Town_Name;
|
||||
public Pattern Design;
|
||||
public Item Bed;
|
||||
public byte Roof_Color;
|
||||
public Item[] Customizations;
|
||||
public Mail[] Mailbox;
|
||||
public Gyroid_Item[] Gyroid_Items;
|
||||
public string Gyroid_Message;
|
||||
}
|
||||
|
||||
public class NewHouse
|
||||
{
|
||||
public int Index;
|
||||
public int Offset;
|
||||
public House_Data Data;
|
||||
}
|
||||
|
||||
class HouseData
|
||||
{
|
||||
public static House_Offsets City_Folk_Offsets = new House_Offsets
|
||||
{
|
||||
Room_Start = 0x8AC,
|
||||
Room_Size = 0x458,
|
||||
Layer_Size = 0x200, //16 * 16 DWORDs
|
||||
Layer_Count = 2,
|
||||
House_Upgrade_Size = 0x15B4, //Also at 0x15B5
|
||||
|
||||
};
|
||||
|
||||
public static House_Offsets New_Leaf_Offsets = new House_Offsets //HouseData is duplicated starting at 0x9 (0x0 - 0x8)
|
||||
{
|
||||
House_Upgrade_Size = 0,
|
||||
Customization_Start = 1,
|
||||
//Style = 1,
|
||||
//DoorShape = 2,
|
||||
//Walls = 3,
|
||||
//Roof = 4,
|
||||
//Door = 5,
|
||||
//Fence = 6,
|
||||
//Pavement = 7,
|
||||
//Mailbox = 8,
|
||||
Room_Start = 0x76,
|
||||
Room_Size = 0x302,
|
||||
};
|
||||
|
||||
/*
|
||||
* New Discovery (AC):
|
||||
* Houses have four levels in them. These are layers you can store items on top of each other.
|
||||
* This is how dressers work in the game. Each layer is 0x228 bytes away from the beginning of the previous one.
|
||||
* So, a dresser with three items looks like this:
|
||||
* Fourth Layer: Item 3
|
||||
* Third Layer: Item 2
|
||||
* Second Layer: Item 1
|
||||
* Main Floor: Dresser
|
||||
*
|
||||
* This means that it's unnecessary to add "storage" to the inventory editor.
|
||||
*/
|
||||
public static ushort[] House_Identifiers = new ushort[10]
|
||||
{
|
||||
0x0480, 0x2480, 0x4880, 0x24A0, 0x4890, 0x48A0, 0x6C90, 0x6C80, 0x7000, 0x0000
|
||||
//StarterHouse, First Upgrade, Expanded Main Room (No Basement), First Upgrade + Basement, Expanded Room + Basement (From Basement),
|
||||
//Expanded Room + Basement (From Expanded Room), 2nd Floor (From Expanded Room), 2nd Floor (From Basement), Statue (From Basement)
|
||||
};
|
||||
|
||||
//Rewrote all methods here to be significantly shorter. I originally wrote them when I had just started in C#.
|
||||
|
||||
public static int ReadHouseSize(ushort[] houseBuffer, bool includesPadding = true)
|
||||
{
|
||||
int x;
|
||||
for (x = (includesPadding ? 0x11 : 0x0); x < houseBuffer.Length; x++)
|
||||
if (houseBuffer[x] == 0xFFFE)
|
||||
break;
|
||||
return (x - (includesPadding ? 0x11 : 0x0));
|
||||
}
|
||||
|
||||
public static Furniture[] ReadHouseData(ushort[] houseBuffer, int size = 0, bool includesPadding = true)
|
||||
{
|
||||
if (size == 0)
|
||||
size = ReadHouseSize(houseBuffer, includesPadding);
|
||||
Furniture[] Furniture_Array = new Furniture[size * size];
|
||||
|
||||
for (int y = 0; y < size; y++)
|
||||
for (int x = 0; x < size; x++)
|
||||
Furniture_Array[y * size + x] = new Furniture(houseBuffer[(includesPadding ? 0x11 : 0x0) + 0x10 * y + x]);
|
||||
|
||||
return Furniture_Array;
|
||||
}
|
||||
|
||||
public static void UpdateHouseData(Furniture[] houseItems, ushort[] houseBuffer, int size, bool includesPadding = true)
|
||||
{
|
||||
for (int y = 0; y < size; y++)
|
||||
for (int x = 0; x < size; x++)
|
||||
houseBuffer[(includesPadding ? 0x11 : 0x0) + 0x10 * y + x] = houseItems[y * size + x].ItemID;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Struct Size: 0x26B0
|
||||
public class House
|
||||
{
|
||||
public int Offset;
|
||||
//
|
||||
public string Owning_Player_Name;
|
||||
public string Town_Name;
|
||||
public uint Player_ID;
|
||||
public ACDate Last_Entry_Date; //Last day the house was entered
|
||||
public ACDate Last_Upgrade_Date; //Not sure if this is accurate (Also is reversed)
|
||||
public ushort Garbage; //Not really sure what this is (it could also be two bytes)
|
||||
public byte House_Number; //Appears again two bytes away, with 0xFF following (not always FF following..)
|
||||
public Room[] Rooms = new Room[3];
|
||||
public Mail[] Mailbox = new Mail[10];
|
||||
public Gyroid_Item[] Gyroid_Storage = new Gyroid_Item[4];
|
||||
public ACString Gyroid_Message;
|
||||
public byte Cockroach_Count;
|
||||
|
||||
public House(int offset)
|
||||
{
|
||||
Offset = offset;
|
||||
Owning_Player_Name = DataConverter.ReadString(offset, 8).Trim();
|
||||
Town_Name = DataConverter.ReadString(offset + 8, 8).Trim();
|
||||
Player_ID = DataConverter.ReadUInt(offset + 0x10);
|
||||
Last_Entry_Date = new ACDate(DataConverter.ReadDataRaw(offset + 0x1C, 4));
|
||||
Last_Upgrade_Date = new ACDate(DataConverter.ReadDataRaw(offset + 0x26, 4), true);
|
||||
//Garbage here
|
||||
House_Number = (byte)((offset - 0x9CE8) / 0x26B0);
|
||||
for (int i = 0; i < 3; i++)
|
||||
Rooms[i] = new Room(DataConverter.ReadUShortArray(offset + 0x38 + i * 0x8A8, 0x454), i);
|
||||
for (int i = 0; i < 10; i++)
|
||||
Mailbox[i] = new Mail(offset + 0x1A30 + i * 0x12A);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int local_Offset = offset + 0x25D4 + i * 0x8;
|
||||
Gyroid_Storage[i] = new Gyroid_Item(DataConverter.ReadUShort(local_Offset), DataConverter.ReadUInt(local_Offset + 4), DataConverter.ReadByte(local_Offset + 3));
|
||||
}
|
||||
|
||||
Gyroid_Message = DataConverter.ReadString(offset + 0x25F4, 0x80);
|
||||
Cockroach_Count = DataConverter.ReadByte(offset + 0x2648);
|
||||
//MessageBox.Show(Gyroid_Message.Clean());
|
||||
}
|
||||
}
|
||||
|
||||
//Struct Size: 0x8A8
|
||||
public class Room
|
||||
{
|
||||
public Layer[] Layers = new Layer[4];
|
||||
public Item Carpet;
|
||||
public Item Wallpaper;
|
||||
public byte Unknown_1;
|
||||
public byte Unknown_2;
|
||||
public int Room_Size;
|
||||
|
||||
public Room(ushort[] Room_Buffer, int Floor)
|
||||
{
|
||||
bool Includes_Wall = Room_Buffer[1] == 0xFFFE;
|
||||
int Data_Start_Offset = Includes_Wall ? 16 : 1; //Data with wall looks like this: 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, ..., 0xFFFE, 0xITEM_ID
|
||||
Room_Size = HouseData.ReadHouseSize(Room_Buffer, Includes_Wall);
|
||||
for (int i = 0; i < 4; i++) //4 layers per room
|
||||
{
|
||||
ushort[] Layer_Buffer = new ushort[0x114];
|
||||
Buffer.BlockCopy(Room_Buffer, i * 0x228, Layer_Buffer, 0, 0x228);
|
||||
Layers[i] = new Layer(Layer_Buffer, Room_Size, Floor, i, true);
|
||||
}
|
||||
Carpet = new Item((ushort)((0x26 << 8) + (Room_Buffer[0x450] & 0xFF00) >> 8));
|
||||
Wallpaper = new Item((ushort)((0x27 << 8) + Room_Buffer[0x450] & 0x00FF));
|
||||
Unknown_1 = (byte)((Room_Buffer[0x451] & 0xFF00) >> 4);
|
||||
Unknown_2 = (byte)(Room_Buffer[0x451] & 0x00FF);
|
||||
}
|
||||
}
|
||||
|
||||
//Struct Size: 0x228
|
||||
public class Layer
|
||||
{
|
||||
public Furniture[] Furniture;
|
||||
public ushort[] Raw_Data;
|
||||
public bool Has_Wall;
|
||||
public int Size;
|
||||
public string Name;
|
||||
|
||||
public Layer(ushort[] Layer_Buffer, int Layer_Size, int Floor, int Layer, bool Includes_Wall = false)
|
||||
{
|
||||
Name = (Floor == 0 ? "First Floor" : (Floor == 1 ? "Second Floor" : "Basement")) + " Layer #" + Layer;
|
||||
Size = Layer_Size;
|
||||
Has_Wall = Includes_Wall;
|
||||
Raw_Data = Layer_Buffer; //Remove this to use Furniture in the future
|
||||
Furniture = new Furniture[Size * Size];
|
||||
for (int y = 0; y < Size; y++)
|
||||
for (int x = 0; x < Size; x++)
|
||||
Furniture[y * Size + x] = new Furniture(Layer_Buffer[(Includes_Wall ? 0x11 : 0) + y * 0x10 + x]);
|
||||
}
|
||||
|
||||
public ushort[] Get_Data(Furniture[] Updated_Furniture)
|
||||
{
|
||||
if (Updated_Furniture.Length == Furniture.Length)
|
||||
for (int y = 0; y < Size; y++)
|
||||
for (int x = 0; x < Size; x++)
|
||||
Raw_Data[(Has_Wall ? 0x11 : 0) + y * 0x10 + x] = Updated_Furniture[y * Size + x].ItemID;
|
||||
else
|
||||
MessageBox.Show(string.Format("{0}: New Furniture Array length ({1}) does not match original length ({2})!", Name, Updated_Furniture.Length, Furniture.Length));
|
||||
Furniture = Updated_Furniture;
|
||||
return Raw_Data;
|
||||
}
|
||||
}
|
||||
|
||||
//Struct Size: 0x12A (Villager Stored Mail Size: 0x100)
|
||||
public class Mail
|
||||
{
|
||||
public int Offset;
|
||||
public bool Player_Mail;
|
||||
public string Reciepiant_Name;
|
||||
public string Reciepiant_Town_Name;
|
||||
public uint Reciepiant_ID;
|
||||
public string Sender_Name;
|
||||
public string Sender_Town_Name;
|
||||
public uint Sender_ID;
|
||||
public byte Event_Flag; //Not sure about this
|
||||
public byte Unknown_1; //Never seen it be anything other than 0
|
||||
public Item Present;
|
||||
public byte Read;
|
||||
public byte Unknown_2; //Letter_Type/Event_ID? (Could have something to do with name positioning, since it's not in the message)
|
||||
public byte Sender_Type; //Not 100% sure (0 = Player, 2 = Tom Nook, 6 = HRA, A = Post Office)
|
||||
public Item Stationary_Type;
|
||||
public ACString Message_Data;
|
||||
public string Message;
|
||||
|
||||
public Mail(int offset, bool Player_Mail = false)
|
||||
{
|
||||
this.Player_Mail = Player_Mail;
|
||||
Offset = Player_Mail ? offset : offset - 0x2A;
|
||||
if (Player_Mail)
|
||||
{
|
||||
Reciepiant_Name = DataConverter.ReadString(Offset, 8).Trim();
|
||||
Reciepiant_Town_Name = DataConverter.ReadString(Offset + 8, 8).Trim();
|
||||
Reciepiant_ID = DataConverter.ReadUInt(Offset + 0x10);
|
||||
Sender_Name = DataConverter.ReadString(Offset + 0x16, 8).Trim();
|
||||
Sender_Town_Name = DataConverter.ReadString(Offset + 0x1E, 8).Trim();
|
||||
Sender_ID = DataConverter.ReadUInt(Offset + 0x26);
|
||||
}
|
||||
Event_Flag = DataConverter.ReadByte(Offset + 0x2A);
|
||||
Unknown_1 = DataConverter.ReadByte(Offset + 0x2B);
|
||||
Present = new Item(DataConverter.ReadUShort(Offset + 0x2C));
|
||||
Read = DataConverter.ReadByte(Offset + 0x2E);
|
||||
Unknown_2 = DataConverter.ReadByte(Offset + 0x2F);
|
||||
Sender_Type = DataConverter.ReadByte(Offset + 0x30);
|
||||
Stationary_Type = new Item((ushort)((0x20 << 8) + DataConverter.ReadByte(Offset + 0x31)));
|
||||
Message_Data = DataConverter.ReadString(Offset + 0x32, 0xF8);
|
||||
Message = Message_Data.Clean();
|
||||
}
|
||||
|
||||
public string GetMessage()
|
||||
{
|
||||
int idx = Message.IndexOf(",");
|
||||
if (idx > -1)
|
||||
return string.Format("{0}{1},\n\n{2}", idx > 0 ? Message.Substring(0, idx - 1) : "", Reciepiant_Name, Message.Substring(idx + 1));
|
||||
else
|
||||
return string.Format("{0}{1}{2}", Message.IndexOf(" ") > 0 ? Message.Substring(0, Message.IndexOf(" ") + 1) : "", Reciepiant_Name + "\n",
|
||||
Message.IndexOf(" ") > 0 ? Message.Substring(Message.IndexOf(" ")) : Message);
|
||||
}
|
||||
}
|
||||
|
||||
//Struct Size: 0xC8
|
||||
public class Messageboard_Post
|
||||
{
|
||||
public ACString Post;
|
||||
public string Post_String;
|
||||
public ACDate Post_Date;
|
||||
|
||||
public Messageboard_Post(int offset)
|
||||
{
|
||||
Post = DataConverter.ReadString(offset, 0xC0);
|
||||
Post_String = Post.Clean();
|
||||
Post_Date = new ACDate(DataConverter.ReadDataRaw(offset + 0xC0, 8));
|
||||
//MessageBox.Show(string.Format("{0}\n\nPosted at:\n{1}", Post_String, Post_Date.Date_Time_String));
|
||||
}
|
||||
}
|
||||
}
|
283
Classes/ImageGeneration.cs
Normal file
|
@ -0,0 +1,283 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Resources;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Windows.Forms;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
public static class ImageGeneration
|
||||
{
|
||||
//From: http://stackoverflow.com/questions/7350679/convert-a-bitmap-into-a-byte-array
|
||||
public static byte[] BitmapToByteArray(Bitmap bitmap)
|
||||
{
|
||||
|
||||
BitmapData bmpdata = null;
|
||||
|
||||
try
|
||||
{
|
||||
bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
||||
int numbytes = bmpdata.Stride * bitmap.Height;
|
||||
byte[] bytedata = new byte[numbytes];
|
||||
IntPtr ptr = bmpdata.Scan0;
|
||||
|
||||
Marshal.Copy(ptr, bytedata, 0, numbytes);
|
||||
|
||||
return bytedata;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (bmpdata != null)
|
||||
bitmap.UnlockBits(bmpdata);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Bitmap Draw_Grid(Bitmap Map, int Item_Size, uint Grid_Color = 0x41444444, int Grid_Pixel_Size = 1)
|
||||
{
|
||||
Graphics Bitmap_Graphics = Graphics.FromImage(Map);
|
||||
Bitmap_Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
Bitmap_Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
Bitmap_Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
int Num_Lines_X = Map.Width / Item_Size, Num_Lines_Y = Map.Height / Item_Size;
|
||||
Pen Grid_Pen = new Pen(new SolidBrush(Color.FromArgb((int)Grid_Color)));
|
||||
Grid_Pen.Width = Grid_Pixel_Size;
|
||||
for (int Y = 1; Y < Num_Lines_Y; Y++)
|
||||
Bitmap_Graphics.DrawLine(Grid_Pen, 0, Y * Item_Size - 1, Map.Width, Y * Item_Size - 1);
|
||||
for (int X = 1; X < Num_Lines_X; X++)
|
||||
Bitmap_Graphics.DrawLine(Grid_Pen, X * Item_Size - 1, 0, X * Item_Size - 1, Map.Height);
|
||||
Bitmap_Graphics.Flush();
|
||||
Bitmap_Graphics.Dispose();
|
||||
return Map;
|
||||
}
|
||||
|
||||
public static Bitmap Draw_Acre_Highlight()
|
||||
{
|
||||
Bitmap Acre_Highlight = new Bitmap(64, 64);
|
||||
Graphics Bitmap_Graphics = Graphics.FromImage(Acre_Highlight);
|
||||
Pen Border_Color = new Pen(Color.FromArgb(0x80, Color.Gold));
|
||||
Border_Color.Width = 8;
|
||||
Bitmap_Graphics.DrawRectangle(Border_Color, new Rectangle(0, 0, 64, 64));
|
||||
Bitmap_Graphics.FillRectangle(new SolidBrush(Color.FromArgb(0x80, Color.Yellow)), new Rectangle(4, 4, 56, 56));
|
||||
Bitmap_Graphics.Flush();
|
||||
Bitmap_Graphics.Dispose();
|
||||
return Acre_Highlight;
|
||||
}
|
||||
|
||||
public static Bitmap Draw_Building(Bitmap Acre_Map, Building Building_to_Draw, bool Use_Text = false)
|
||||
{
|
||||
RectangleF RectF = new RectangleF(Building_to_Draw.X_Pos * 8, Building_to_Draw.Y_Pos * 8, 8, 8);
|
||||
Graphics Bitmap_Graphics = Graphics.FromImage(Acre_Map);
|
||||
Bitmap_Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
Bitmap_Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
Bitmap_Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
if (Use_Text)
|
||||
{
|
||||
Bitmap_Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
|
||||
Bitmap_Graphics.DrawString("B", new Font("Tahoma", 8), Brushes.White, RectF);
|
||||
}
|
||||
else
|
||||
Bitmap_Graphics.DrawImage(Properties.Resources.Building, Building_to_Draw.X_Pos * 8, Building_to_Draw.Y_Pos * 8, 8, 8);
|
||||
Bitmap_Graphics.Flush();
|
||||
return Acre_Map;
|
||||
}
|
||||
|
||||
public static Bitmap Draw_Buildings(Bitmap Acre_Map, Building[] Building_List, int Acre)
|
||||
{
|
||||
if (Building_List == null)
|
||||
return Acre_Map;
|
||||
foreach (Building B in Building_List)
|
||||
{
|
||||
if (B.Exists && B.Acre_Index == Acre)
|
||||
{
|
||||
Draw_Building(Acre_Map, B);
|
||||
}
|
||||
}
|
||||
return Acre_Map;
|
||||
}
|
||||
|
||||
public static Bitmap Draw_Inner_House_Extents(Bitmap Furniture_Map, int Floor_Size = 8)
|
||||
{
|
||||
using (Graphics Bitmap_Graphics = Graphics.FromImage(Furniture_Map))
|
||||
{
|
||||
int Corner = (16 - Floor_Size) / 2;
|
||||
using (Pen Border_Pen = new Pen(Color.Gray, 2))
|
||||
{
|
||||
Border_Pen.Alignment = PenAlignment.Inset;
|
||||
Bitmap_Graphics.DrawRectangle(Border_Pen, new Rectangle(Corner, Corner, Floor_Size * 16, Floor_Size * 16));
|
||||
}
|
||||
}
|
||||
return Furniture_Map;
|
||||
}
|
||||
|
||||
public static Bitmap Draw_Furniture_Arrows(Bitmap Furniture_Map, Furniture[] Furniture, int Columns = 16)
|
||||
{
|
||||
Graphics Bitmap_Graphics = Graphics.FromImage(Furniture_Map);
|
||||
Bitmap_Graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
Bitmap_Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
Bitmap_Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
for (int i = 0; i < Furniture.Length; i++)
|
||||
{
|
||||
if (Furniture[i].Name != "Empty")
|
||||
{
|
||||
Image Arrow = Properties.Resources.Arrow;
|
||||
if (Furniture[i].Rotation > 0)
|
||||
{
|
||||
switch(Furniture[i].Rotation)
|
||||
{
|
||||
case 90:
|
||||
Arrow.RotateFlip(RotateFlipType.Rotate90FlipNone);
|
||||
break;
|
||||
case 180:
|
||||
Arrow.RotateFlip(RotateFlipType.Rotate180FlipNone);
|
||||
break;
|
||||
case 270:
|
||||
Arrow.RotateFlip(RotateFlipType.Rotate270FlipNone);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Bitmap_Graphics.DrawImage(Arrow, (i % Columns) * (Furniture_Map.Width / Columns), (i / Columns) * (Furniture_Map.Width / Columns));
|
||||
}
|
||||
}
|
||||
Bitmap_Graphics.Flush();
|
||||
Bitmap_Graphics.Dispose();
|
||||
return Furniture_Map;
|
||||
}
|
||||
|
||||
public static int[] Grass_Wear_Offset_Map = new int[64] //Lazy Hack
|
||||
{
|
||||
0, 1, 4, 5, 16, 17, 20, 21,
|
||||
2, 3, 6, 7, 18, 19, 22, 23,
|
||||
8, 9, 12, 13, 24, 25, 28, 29,
|
||||
10, 11, 14, 15, 26, 27, 30, 31,
|
||||
32, 33, 36, 37, 48, 49, 52, 53,
|
||||
34, 35, 38, 39, 50, 51, 54, 55,
|
||||
40, 41, 44, 45, 56, 57, 60, 61,
|
||||
42, 43, 46, 47, 58, 59, 62, 63
|
||||
};
|
||||
|
||||
public static Bitmap Draw_Grass_Wear(byte[] Grass_Buffer)
|
||||
{
|
||||
if (NewMainForm.Save_File.Save_Type == SaveType.City_Folk)
|
||||
{
|
||||
Bitmap Grass_Bitmap = new Bitmap(64, 64, PixelFormat.Format32bppArgb);
|
||||
Graphics Bitmap_Graphics = Graphics.FromImage(Grass_Bitmap);
|
||||
int i = 0;
|
||||
for (int Y2 = 0; Y2 < 4; Y2++)
|
||||
for (int X2 = 0; X2 < 2; X2++)
|
||||
for (int Y = 0; Y < 4; Y++)
|
||||
for (int X = 0; X < 8; X++)
|
||||
{
|
||||
Bitmap_Graphics.FillRectangle(new SolidBrush(Color.FromArgb(Grass_Buffer[i] == 0 ? 0 : 0x60, 0, Grass_Buffer[i], 0)), (X + X2 * 8) * 4, (Y + Y2 * 4) * 4, 4, 4);
|
||||
i++;
|
||||
}
|
||||
Bitmap_Graphics.Flush();
|
||||
Bitmap_Graphics.Dispose();
|
||||
return Grass_Bitmap;
|
||||
}
|
||||
else // NL/WA
|
||||
{
|
||||
Bitmap Grass_Bitmap = new Bitmap(7 * 64, 6 * 64, PixelFormat.Format32bppArgb);
|
||||
Graphics Bitmap_Graphics = Graphics.FromImage(Grass_Bitmap);
|
||||
for (int Y = 0; Y < 6 * 16; Y++)
|
||||
{
|
||||
for (int X = 0; X < 7 * 16; X++)
|
||||
{
|
||||
int Offset = 64 * ((Y / 8) * 16 + (X / 8)) + Grass_Wear_Offset_Map[(Y % 8) * 8 + (X % 8)];
|
||||
SolidBrush Brush = new SolidBrush(Color.FromArgb(Grass_Buffer[Offset] == 0 ? 0 : 0x60, 0, Grass_Buffer[Offset], 0));
|
||||
Bitmap_Graphics.FillRectangle(Brush, X * 4, Y * 4, 4, 4);
|
||||
}
|
||||
}
|
||||
Bitmap_Graphics.Flush();
|
||||
Bitmap_Graphics.Dispose();
|
||||
return Grass_Bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
public static Bitmap Draw_NL_Grass_BG(PictureBox[] Acre_Map)
|
||||
{
|
||||
Bitmap BG_Bitmap = new Bitmap(64 * 7, 64 * 6);
|
||||
Graphics BG_Graphics = Graphics.FromImage(BG_Bitmap);
|
||||
for (int i = 0; i < Acre_Map.Length; i++)
|
||||
if (Acre_Map[i].BackgroundImage != null)
|
||||
BG_Graphics.DrawImage(MakeGrayscale((Bitmap)Acre_Map[i].BackgroundImage), 64 * (i % 7), 64 * (i / 7));
|
||||
BG_Graphics.Flush();
|
||||
BG_Graphics.Dispose();
|
||||
return BG_Bitmap;
|
||||
}
|
||||
|
||||
|
||||
//From: http://stackoverflow.com/questions/2265910/convert-an-image-to-grayscale
|
||||
public static Bitmap MakeGrayscale(Bitmap original)
|
||||
{
|
||||
if (original == null)
|
||||
return null;
|
||||
Bitmap newBitmap = new Bitmap(original.Width, original.Height);
|
||||
Graphics g = Graphics.FromImage(newBitmap);
|
||||
|
||||
//create the grayscale ColorMatrix
|
||||
ColorMatrix colorMatrix = new ColorMatrix(
|
||||
new float[][]
|
||||
{
|
||||
new float[] {.3f, .3f, .3f, 0, 0},
|
||||
new float[] {.59f, .59f, .59f, 0, 0},
|
||||
new float[] {.11f, .11f, .11f, 0, 0},
|
||||
new float[] {0, 0, 0, 1, 0},
|
||||
new float[] {0, 0, 0, 0, 1}
|
||||
});
|
||||
|
||||
ImageAttributes attributes = new ImageAttributes();
|
||||
attributes.SetColorMatrix(colorMatrix);
|
||||
|
||||
g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
|
||||
0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);
|
||||
g.Dispose();
|
||||
return newBitmap;
|
||||
}
|
||||
|
||||
public static byte[] GetTPCTrimmedBytes(byte[] TPC_Bytes)
|
||||
{
|
||||
byte[] Finalized_TPC_Bytes = new byte[0x1400];
|
||||
if (TPC_Bytes.Length > 0x1400)
|
||||
{
|
||||
MessageBox.Show("Received TPC Card file size: " + TPC_Bytes.Length.ToString("X"));
|
||||
Array.Resize(ref TPC_Bytes, 0x1400);
|
||||
}
|
||||
for (int i = TPC_Bytes.Length - 1; i > 0; i--)
|
||||
{
|
||||
if (i > 0 && TPC_Bytes[i - 1] == 0xFF && TPC_Bytes[i] == 0xD9)
|
||||
{
|
||||
Buffer.BlockCopy(TPC_Bytes, 0, Finalized_TPC_Bytes, 0, i == 0x13FF ? i : i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Finalized_TPC_Bytes;
|
||||
}
|
||||
|
||||
public static Image GetTPCImage(byte[] TPC_Bytes)
|
||||
{
|
||||
if (TPC_Bytes.Length != 0x1400)
|
||||
{
|
||||
MessageBox.Show("The TPC Picture was an incorrect data size.");
|
||||
return null;
|
||||
}
|
||||
if (TPC_Bytes[TPC_Bytes.Length - 1] == 0xD9 && TPC_Bytes[TPC_Bytes.Length - 2] == 0xFF)
|
||||
return Image.FromStream(new MemoryStream(TPC_Bytes));
|
||||
for (int i = TPC_Bytes.Length - 1; i > 0; i --)
|
||||
{
|
||||
if (i > 0 && TPC_Bytes[i - 1] == 0xFF && TPC_Bytes[i] == 0xD9)
|
||||
{
|
||||
return Image.FromStream(new MemoryStream(TPC_Bytes.Take(i).ToArray()));
|
||||
}
|
||||
}
|
||||
NewMainForm.Debug_Manager.WriteLine("Unable to find JPEG End-of-File marker. No TPC?", DebugLevel.Error);
|
||||
return Properties.Resources.no_tpc;
|
||||
}
|
||||
}
|
||||
}
|
114
Classes/Inventory.cs
Normal file
|
@ -0,0 +1,114 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
public class Inventory
|
||||
{
|
||||
public Item[] Items;
|
||||
|
||||
public Inventory(ushort[] inventoryData)
|
||||
{
|
||||
Items = new Item[inventoryData.Length];
|
||||
for(int i = 0; i < inventoryData.Length; i++)
|
||||
{
|
||||
Item item = new Item(inventoryData[i]);
|
||||
Items[i] = item;
|
||||
}
|
||||
}
|
||||
|
||||
public Inventory(uint[] inventoryData)
|
||||
{
|
||||
Items = new Item[inventoryData.Length];
|
||||
for (int i = 0; i < inventoryData.Length; i++)
|
||||
{
|
||||
Item item = new Item(inventoryData[i]);
|
||||
Items[i] = item;
|
||||
}
|
||||
}
|
||||
|
||||
public static Image GetItemPic(int itemsize, int itemsPerRow, Item[] items, SaveType Save_Type = SaveType.Animal_Crossing)
|
||||
{
|
||||
int width = itemsize * itemsPerRow, height = itemsize * items.Length / itemsPerRow;
|
||||
height = height < 1 ? width : height;
|
||||
byte[] bmpData = new byte[4 * ((width) * (height))];
|
||||
for (int i = 0; i < items.Length; i++)
|
||||
{
|
||||
int X = i % itemsPerRow;
|
||||
int Y = i / itemsPerRow;
|
||||
Item item = items[i] ?? new Item(0);
|
||||
uint itemColor = ItemData.GetItemColor(ItemData.GetItemType(item.ItemID, Save_Type));
|
||||
|
||||
for (int x = 0; x < itemsize * itemsize; x++)
|
||||
{
|
||||
int dataPosition = (Y * itemsize + x % itemsize) * width * 4 + (X * itemsize + x / itemsize) * 4;
|
||||
if (dataPosition >= bmpData.Length)
|
||||
{
|
||||
System.Windows.Forms.MessageBox.Show("Item Bitmap generation received more items than allocated space. Skipping " + (items.Length - i).ToString() + " Item(s).");
|
||||
break;
|
||||
}
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(itemColor), 0, bmpData, dataPosition, 4);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < (width * height); i++)
|
||||
if ((i / itemsize > 0 && i % (itemsize * itemsPerRow) > 0 && i % (itemsize) == 0) || (i / (itemsize * itemsPerRow) > 0 && (i / (itemsize * itemsPerRow)) % (itemsize) == 0))
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(0x41000000), 0, bmpData,
|
||||
((i / (itemsize * itemsPerRow)) * width * 4) + ((i % (itemsize * itemsPerRow)) * 4), 4);
|
||||
|
||||
Bitmap b = new Bitmap(width, height, PixelFormat.Format32bppArgb);
|
||||
BitmapData bData = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
System.Runtime.InteropServices.Marshal.Copy(bmpData, 0, bData.Scan0, bmpData.Length);
|
||||
b.UnlockBits(bData);
|
||||
return b;
|
||||
}
|
||||
|
||||
public static Image GetItemPic(int itemsize, Item item, SaveType Save_Type = SaveType.Animal_Crossing)
|
||||
{
|
||||
int width = 16;
|
||||
int height = 16;
|
||||
byte[] bmpData = new byte[1024];
|
||||
byte[] itemColor = item == null ? new byte[4] { 0xFF, 0xFF, 0x00, 0x00 } : BitConverter.GetBytes(ItemData.GetItemColor(ItemData.GetItemType(item.ItemID, Save_Type)));
|
||||
|
||||
for (int i = 0; i < 1024; i+=4)
|
||||
itemColor.CopyTo(bmpData, i);
|
||||
|
||||
for (int i = 0; i < (width * height); i++)
|
||||
if ((i / itemsize > 0 && i % 16 > 0 && i % 16 == 0) || (i / 16 > 0 && (i / 16) % 16 == 0))
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(0x41000000), 0, bmpData,
|
||||
((i / 16) * width * 4) + ((i % 16) * 4), 4);
|
||||
|
||||
Bitmap b = new Bitmap(width, height, PixelFormat.Format32bppArgb);
|
||||
BitmapData bData = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
System.Runtime.InteropServices.Marshal.Copy(bmpData, 0, bData.Scan0, bmpData.Length);
|
||||
b.UnlockBits(bData);
|
||||
return b;
|
||||
}
|
||||
|
||||
public ushort[] GetItemIDs()
|
||||
{
|
||||
ushort[] ids = new ushort[15];
|
||||
for (int i = 0; i < 15; i++)
|
||||
ids[i] = Items[i].ItemID;
|
||||
return ids;
|
||||
}
|
||||
}
|
||||
|
||||
public class InventorySlot
|
||||
{
|
||||
public Item Item;
|
||||
public int SlotID;
|
||||
|
||||
public InventorySlot(Item item, int slotId)
|
||||
{
|
||||
Item = item;
|
||||
SlotID = slotId;
|
||||
}
|
||||
}
|
||||
}
|
1419
Classes/ItemData.cs
Normal file
102
Classes/NL_Int32.cs
Normal file
|
@ -0,0 +1,102 @@
|
|||
using System;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
/*
|
||||
* Animal Crossing: New Leaf (and Welcome Amiibo) Interger Encryption Documentation
|
||||
*
|
||||
* Animal Crossing: New Leaf uses a combination of methods to obfuscate their integer values in the save file.
|
||||
* The encryption consists of two integer values. The first integer is the encrypted integer. The second integer contains the checksum of the encryption and
|
||||
* the data needed to decrypt it.
|
||||
*
|
||||
* The lower two bytes are a short which has a randomized "adjustment value"
|
||||
* This is likely to throw off anyone looking for a static value that is added/removed from it.
|
||||
*
|
||||
* The second byte in the int contains the "Shift Value" which is a random number between 0x00 and 0x1A. This number is then subtracted from a static value of 0x1C
|
||||
* to determine the left bitshift count.
|
||||
*
|
||||
* The left bitshift count is then subtracted from a static value of 0x20 to determine the right bitshift count.
|
||||
*
|
||||
* The uppermost byte in the second integer is the Checksum of all the bytes in the Encrypted Integer + a statc value of 0xBA.
|
||||
*
|
||||
* Once we have the left & right bitshift counts, we can decode the Encrypted Integer.
|
||||
*
|
||||
* The formula is this:
|
||||
* uint Unencrypted_Int = ((Encrypted_Integer << Left_Shift_Count) + (Encrypted_Integer >> Right_Shift_Count)) - (Random_Adjustment_Value + Static_Int 0x8F187432);
|
||||
*/
|
||||
|
||||
public class NL_Int32
|
||||
{
|
||||
public uint Int_1;
|
||||
public uint Int_2;
|
||||
public uint Value;
|
||||
public bool Valid = false;
|
||||
|
||||
public NL_Int32()
|
||||
{
|
||||
Int_1 = 0;
|
||||
Int_2 = 0;
|
||||
|
||||
Value = 0;
|
||||
}
|
||||
|
||||
public NL_Int32(uint Int_A, uint Int_B)
|
||||
{
|
||||
Int_1 = Int_A;
|
||||
Int_2 = Int_B;
|
||||
|
||||
ushort Adjust_Value = (ushort)(Int_B);
|
||||
byte Shift_Value = (byte)(Int_B >> 16);
|
||||
byte Int_Checksum = (byte)(Int_B >> 24);
|
||||
byte Computed_Checksum = GetChecksum(Int_A);
|
||||
|
||||
if (Int_Checksum != Computed_Checksum)
|
||||
{
|
||||
NewMainForm.Debug_Manager.WriteLine("Encrypted Int had an invalid Checksum at offset!", DebugLevel.Error);
|
||||
Int_1 = 0;
|
||||
Int_2 = 0;
|
||||
Value = 0;
|
||||
Valid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
byte Left_Shift_Count = (byte)(0x1C - Shift_Value);
|
||||
byte Right_Shift_Count = (byte)(0x20 - Left_Shift_Count);
|
||||
|
||||
if (Left_Shift_Count < 0x20)
|
||||
{
|
||||
Value = ((Int_A << Left_Shift_Count) + (Int_A >> Right_Shift_Count)) - (Adjust_Value + 0x8F187432);
|
||||
Valid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewMainForm.Debug_Manager.WriteLine("Invalid Shift Count was detected!", DebugLevel.Error);
|
||||
Value = (Int_A << Right_Shift_Count) - (Adjust_Value + 0x8F187432);
|
||||
Valid = true; // Is this right?
|
||||
}
|
||||
}
|
||||
//System.Windows.Forms.MessageBox.Show("Value = " + Value.ToString());
|
||||
}
|
||||
|
||||
public NL_Int32(uint Unencrypted_Int)
|
||||
{
|
||||
Random Generator = new Random();
|
||||
ushort Adjust_Value = (ushort)(Generator.Next(0x10000));
|
||||
byte Shift_Value = (byte)(Generator.Next(0x1A));
|
||||
|
||||
uint Encrypted_Int = Unencrypted_Int + Adjust_Value + 0x8F187432;
|
||||
Encrypted_Int = (Encrypted_Int >> (0x1C - Shift_Value)) + (Encrypted_Int << (Shift_Value + 4));
|
||||
uint Encryption_Data = (uint)(Adjust_Value + (Shift_Value << 16) + (GetChecksum(Encrypted_Int) << 24));
|
||||
|
||||
//System.Windows.Forms.MessageBox.Show("Encryped Int is decrypted properly: " + (new NL_Int32(Encrypted_Int, Encryption_Data).Value == Unencrypted_Int).ToString());
|
||||
Int_1 = Encrypted_Int;
|
||||
Int_2 = Encryption_Data;
|
||||
Value = Unencrypted_Int;
|
||||
}
|
||||
|
||||
public static byte GetChecksum(uint Encrypted_Int)
|
||||
{
|
||||
return (byte)((byte)(Encrypted_Int) + (byte)(Encrypted_Int >> 8) + (byte)(Encrypted_Int >> 16) + (byte)(Encrypted_Int >> 24) + 0xBA);
|
||||
}
|
||||
}
|
||||
}
|
574
Classes/Pattern.cs
Normal file
|
@ -0,0 +1,574 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
/// <summary>
|
||||
/// GameCube Pattern Data Write-up
|
||||
/// Patterns consist of a 15-color palette.
|
||||
/// There are 16 palettes to select from, but you can only use one palette at a time.
|
||||
/// To save space, the AC Devs used each nibble for a pixel on the pattern. FF = White, White | 1F = Red, White
|
||||
/// Each Pattern is 32x32 pixels. So the total space in memory was halved by doing this (only 0x220 bytes)
|
||||
/// Data is stored like this:
|
||||
/// Name: 0x10 bytes
|
||||
/// Palette: 0x1 bytes
|
||||
/// Alignment Bytes?: 0xF bytes
|
||||
/// Pattern Data: 0x200 bytes
|
||||
/// </summary>
|
||||
class PatternData
|
||||
{
|
||||
public static uint[][] AC_Palette_Data = new uint[16][]
|
||||
{
|
||||
new uint[15]
|
||||
{
|
||||
0xFFCD4A4A, 0xFFDE8341, 0xFFE6AC18, 0xFFE6C520, 0xFFD5DE18, 0xFFB4E618, 0xFF83D552, 0xFF39C56A, 0xFF29ACC5, 0xFF417BEE, 0xFF6A4AE6, 0xFF945ACD, 0xFFBD41B4, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFFFF8B8B, 0xFFFFCD83, 0xFFFFE65A, 0xFFFFF662, 0xFFFFFF83, 0xFFDEFF52, 0xFFB4FF83, 0xFF7BF6AC, 0xFF62E6F6, 0xFF83C5FF, 0xFFA49CFF, 0xFFD59CFF, 0xFFFF9CF6, 0xFF8B8B8B, 0xFFFFFFFF
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFF9C1818, 0xFFAC5208, 0xFFB47B00, 0xFFB49400, 0xFFA4AC00, 0xFF83B400, 0xFF52A431, 0xFF089439, 0xFF007B94, 0xFF104ABD, 0xFF3918AC, 0xFF5A2994, 0xFF8B087B, 0xFF080808, 0xFFFFFFFF
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFF41945A, 0xFF73C58B, 0xFF94E6AC, 0xFF008B7B, 0xFF5AB4AC, 0xFF83C5C5, 0xFF2073A4, 0xFF4A9CCD, 0xFF6AACDE, 0xFF7383BD, 0xFF6A73AC, 0xFF525294, 0xFF39397B, 0xFF181862, 0xFFFFFFFF
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFF9C8352, 0xFFBD945A, 0xFFD5BD83, 0xFF9C5252, 0xFFCD7362, 0xFFEE9C8B, 0xFF8B6283, 0xFFA483B4, 0xFFDEB4DE, 0xFFBD8383, 0xFFAC736A, 0xFF945252, 0xFF7B3939, 0xFF621810, 0xFFFFFFFF
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFFEE5A00, 0xFFFF9C41, 0xFFFFCD83, 0xFFFFEEA4, 0xFF8B4A29, 0xFFB47B5A, 0xFFE6AC8B, 0xFFFFDEBD, 0xFF318BFF, 0xFF62B4FF, 0xFF9CDEFF, 0xFFC5E6FF, 0xFF6A6A6A, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFF39B441, 0xFF62DE5A, 0xFF8BEE83, 0xFFB4FFAC, 0xFF2020C5, 0xFF5252F6, 0xFF8383FF, 0xFFB4B4FF, 0xFFCD3939, 0xFFDE6A6A, 0xFFE68B9C, 0xFFEEBDBD, 0xFF6A6A6A, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFF082000, 0xFF415A39, 0xFF6A8362, 0xFF9CB494, 0xFF5A2900, 0xFF7B4A20, 0xFFA4734A, 0xFFD5A47B, 0xFF947B00, 0xFFB49439, 0xFFCDB46A, 0xFFDED59C, 0xFF6A6A6A, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFF2020FF, 0xFFFF2020, 0xFFD5D500, 0xFF6262FF, 0xFFFF6262, 0xFFD5D562, 0xFF9494FF, 0xFFFF9494, 0xFFD5D594, 0xFFACACFF, 0xFFFFACAC, 0xFFE6E6AC, 0xFF6A6A6A, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFF20A420, 0xFF39ACFF, 0xFF9C52EE, 0xFF52BD52, 0xFF5AC5FF, 0xFFB49CFF, 0xFF6AD573, 0xFF8BE6FF, 0xFFCDB4FF, 0xFF94DEAC, 0xFFBDF6FF, 0xFFD5CDFF, 0xFF6A6A6A, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFFD50000, 0xFFFFBD00, 0xFFEEF631, 0xFF4ACD41, 0xFF299C29, 0xFF528BBD, 0xFF414AAC, 0xFF9452D5, 0xFFF67BDE, 0xFFA49439, 0xFF9C4141, 0xFF5A3139, 0xFF6A6A6A, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFFE6CD18, 0xFF20C518, 0xFFFF6A00, 0xFF0000FF, 0xFF9400BD, 0xFFE6CD18, 0xFF00A400, 0xFFCD4100, 0xFF0000D5, 0xFF5A008B, 0xFF9C8B18, 0xFF008300, 0xFFA42000, 0xFF0000A4, 0xFF4A005A
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFFFF2020, 0xFFE6D500, 0xFFF639BD, 0xFF00D59C, 0xFF107310, 0xFFC52020, 0xFFBDA400, 0xFFCD3994, 0xFF009C6A, 0xFF204A20, 0xFF8B2020, 0xFF836A00, 0xFF941862, 0xFF00734A, 0xFF183918
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFFEED5D5, 0xFFDEC5C5, 0xFFCDB4B4, 0xFFBDA4A4, 0xFFAC9494, 0xFF9C8383, 0xFF8B7373, 0xFF7B6262, 0xFF6A5252, 0xFF5A4141, 0xFF4A3131, 0xFF392020, 0xFF291010, 0xFF180000, 0xFF100000
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFFEEEEEE, 0xFFDEDEDE, 0xFFCDCDCD, 0xFFBDBDBD, 0xFFACACAC, 0xFF9C9C9C, 0xFF8B8B8B, 0xFF7B7B7B, 0xFF6A6A6A, 0xFF5A5A5A, 0xFF4A4A4A, 0xFF393939, 0xFF292929, 0xFF181818, 0xFF101010
|
||||
},
|
||||
new uint[15]
|
||||
{
|
||||
0xFFEE7B7B, 0xFFD51818, 0xFFF69418, 0xFFE6E652, 0xFF006A00, 0xFF39B439, 0xFF0039B4, 0xFF399CFF, 0xFF940094, 0xFFFF6AFF, 0xFF944108, 0xFFEE9C5A, 0xFFFFC594, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
};
|
||||
|
||||
public static byte[] WW_Pattern_Offsets = new byte[16]
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xC, 0xB, 0xD, 0xE, 0xF //Not in order??
|
||||
};
|
||||
|
||||
public static uint[][] WW_Palette_Data = new uint[16][]
|
||||
{
|
||||
new uint [15]
|
||||
{
|
||||
0xFF0000FF, 0xFF3173FF, 0xFF00ADFF, 0xFF00FFFF, 0xFF00FFAD, 0xFF00FF52, 0xFF00FF00, 0xFF52AD00, 0xFFAD5200, 0xFFFF0000, 0xFFFF0052, 0xFFFF00AD, 0xFFFF00FF, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFF7B7BFF, 0xFF7BB5FF, 0xFF7BE7FF, 0xFF7BFFFF, 0xFF7BFFDE, 0xFF7BFFAD, 0xFF7BFF7B, 0xFF84AD52, 0xFFAD8452, 0xFFFF7B7B, 0xFFFF7BB5, 0xFFFF7BE7, 0xFFFF7BFF, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFF0000A5, 0xFF0031A5, 0xFF0073A5, 0xFF00A5A5, 0xFF00A573, 0xFF00A531, 0xFF00A500, 0xFF215200, 0xFF522100, 0xFFA50000, 0xFFA50031, 0xFFA50073, 0xFFA500A5, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFF009C00, 0xFF6BCE5A, 0xFFDEFFB5, 0xFF6B9C00, 0xFFA5CE52, 0xFFD6FFAD, 0xFFAD5200, 0xFFD68429, 0xFFFFAD5A, 0xFFFF0000, 0xFFFF6B4A, 0xFFDE4A31, 0xFFB52118, 0xFF8C0000, 0xFFFFFFFF
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFF0073AD, 0xFF42ADD6, 0xFF8CDEFF, 0xFF3908FF, 0xFF6B4AFF, 0xFF9C94FF, 0xFFFF00AD, 0xFFFF63D6, 0xFFFFCEFF, 0xFF9CBDFF, 0xFF7394DE, 0xFF4A63BD, 0xFF21399C, 0xFF00107B, 0xFFFFFFFF
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFF0000FF, 0xFF0052FF, 0xFF5AB5FF, 0xFFADEFFF, 0xFF00107B, 0xFF314AA5, 0xFF6B84D6, 0xFF9CBDFF, 0xFFFFAD5A, 0xFFFFC684, 0xFFFFE7AD, 0xFFFFFFD6, 0xFF6B6B6B, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFF00FF00, 0xFF42FF42, 0xFF8CFF8C, 0xFFD6FFD6, 0xFFFF0000, 0xFFFF4242, 0xFFFF8C8C, 0xFFFFD6D6, 0xFF0000FF, 0xFF4242FF, 0xFF8C8CFF, 0xFFD6D6FF, 0xFF6B6B6B, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFF003100, 0xFF426342, 0xFF849C84, 0xFFC6D6C6, 0xFF00107B, 0xFF294AA5, 0xFF5A8CD6, 0xFF8CC6FF, 0xFF00B5D6, 0xFF39CEE7, 0xFF7BDEF7, 0xFFBDF7FF, 0xFF6B6B6B, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFFFF0000, 0xFF0000FF, 0xFF00FFFF, 0xFFFF4242, 0xFF4242FF, 0xFF42FFFF, 0xFFFF8C8C, 0xFF8C8CFF, 0xFF8CFFFF, 0xFFFFD6D6, 0xFFD6D6FF, 0xFFD6FFFF, 0xFF6B6B6B, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFF00FF00, 0xFFFF0000, 0xFFFF00FF, 0xFF42FF42, 0xFFFF4242, 0xFFFF42FF, 0xFF8CFF8C, 0xFFFF8C8C, 0xFFFF8CFF, 0xFFD6FFD6, 0xFFFFD6D6, 0xFFFFD6FF, 0xFF6B6B6B, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFF0000FF, 0xFF007BFF, 0xFF00FFFF, 0xFF00FF84, 0xFF00FF00, 0xFF7B8400, 0xFFFF0000, 0xFFFF007B, 0xFFFF94FF, 0xFF00B5D6, 0xFF0010BD, 0xFF00105A, 0xFF6B6B6B, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFF639410, 0xFF527B08, 0xFF398C10, 0xFF319C31, 0xFF4AA5CE, 0xFF3994CE, 0xFF4A8CBD, 0xFF318CD6, 0xFF4A73AD, 0xFF315A8C, 0xFF29426B, 0xFFFFEF84, 0xFFEFCE31, 0xFFC6A500, 0xFFFFFFFF
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFFE7DED6, 0xFFDECEB5, 0xFFEFEFE7, 0xFFF7F7F7, 0xFF7B7384, 0xFF6B8C94, 0xFF637B84, 0xFF5A849C, 0xFFB59C73, 0xFF2929FF, 0xFF00FFFF, 0xFFFF2194, 0xFFBD9C00, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFFFFFFFF, 0xFFEFEFF7, 0xFFDEDEE7, 0xFFCECED6, 0xFFB5B5C6, 0xFFA5A5B5, 0xFF9494A5, 0xFF84849C, 0xFF6B6B8C, 0xFF5A5A7B, 0xFF4A4A6B, 0xFF31315A, 0xFF21214A, 0xFF101042, 0xFF000031
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFFFFFFFF, 0xFFEFEFEF, 0xFFDEDEDE, 0xFFCECECE, 0xFFB5B5B5, 0xFFA5A5A5, 0xFF949494, 0xFF848484, 0xFF6B6B6B, 0xFF5A5A5A, 0xFF4A4A4A, 0xFF313131, 0xFF212121, 0xFF101010, 0xFF000000
|
||||
},
|
||||
new uint [15]
|
||||
{
|
||||
0xFF7B8CFF, 0xFF0000FF, 0xFF007BFF, 0xFF00FFFF, 0xFF008400, 0xFF00FF00, 0xFFFF0000, 0xFFFF9C00, 0xFFFF00D6, 0xFFFF6BFF, 0xFF00009C, 0xFF0094FF, 0xFF94BDFF, 0xFF000000, 0xFFFFFFFF
|
||||
},
|
||||
};
|
||||
|
||||
public static uint[][] CF_Palette_Data = new uint[16][]
|
||||
{
|
||||
new uint [15]
|
||||
{
|
||||
0xFFFF0000, 0xFF008000, 0xFF0000FF, 0xFF804000, 0xFF000000, 0xFFFF8000, 0xFF80FF00, 0xFF00EAEA, 0xFF800080, 0xFF808080, 0xFFFFCAE4, 0xFFFFFF00, 0xFFACCCFD, 0xFFFF66B3, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFFFD561E, 0xFF00C400, 0xFF3982FB, 0xFFAC6802, 0xFF000000, 0xFFFFA54A, 0xFF9FFF40, 0xFF51A8FF, 0xFFEE70FC, 0xFF808080, 0xFFFFC993, 0xFFFFFF80, 0xFFC1E0FF, 0xFFFFC4E1, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFF804040, 0xFF006633, 0xFF4B4BA9, 0xFF4B2F21, 0xFF000000, 0xFFAC6802, 0xFF00A854, 0xFF317BF7, 0xFF5F3E86, 0xFF969696, 0xFFDFB9AC, 0xFFA4A400, 0xFF9CBACF, 0xFFB06FB0, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFFB02902, 0xFFA29F4F, 0xFF008282, 0xFF022B68, 0xFF000000, 0xFFFA7403, 0xFFE6C947, 0xFF04C67D, 0xFF5A5ACD, 0xFF808080, 0xFFFED7AF, 0xFFFFFFA8, 0xFFC4EBC2, 0xFF94B4FE, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFFD05B9C, 0xFFEAB602, 0xFF2291FF, 0xFF8000FF, 0xFF000000, 0xFFFF9FCF, 0xFFF4F400, 0xFF7EC8FE, 0xFFB376C7, 0xFF808080, 0xFFEECCCC, 0xFFFFFFB0, 0xFFC1F4F3, 0xFFE7CFEF, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFF400040, 0xFF424505, 0xFF006262, 0xFF2D0059, 0xFF000000, 0xFF981F5F, 0xFF9D6B4D, 0xFF377D95, 0xFF7143BC, 0xFF808080, 0xFFEC95C5, 0xFFCEC68A, 0xFF80AECA, 0xFFB56AFF, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFF710071, 0xFF950000, 0xFF438507, 0xFF005984, 0xFF000000, 0xFFD9006C, 0xFFFF8000, 0xFF66CC00, 0xFF049788, 0xFF808080, 0xFFFF93FF, 0xFFF7BA02, 0xFFDCD838, 0xFF00FFFF, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFF6D6D36, 0xFFA4A4A4, 0xFF371C00, 0xFF002D00, 0xFF000000, 0xFFAD8301, 0xFFB4B4B4, 0xFF5C3F23, 0xFF23673A, 0xFF808080, 0xFFD2CC5B, 0xFFE1E1E1, 0xFFB08364, 0xFF66938A, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFF804040, 0xFF666666, 0xFF003737, 0xFF83745C, 0xFF000000, 0xFFB3757E, 0xFFC3C3C3, 0xFF233641, 0xFFA39E65, 0xFF808080, 0xFFD7A8A8, 0xFFD0CDB9, 0xFF5F5F6D, 0xFFC9BE98, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFFAB5436, 0xFF3D140A, 0xFF6B3F8F, 0xFF793431, 0xFF000000, 0xFFD69769, 0xFF6A390D, 0xFF5050AF, 0xFFD1423F, 0xFF808080, 0xFFFABEBE, 0xFFCBAB69, 0xFF286249, 0xFFFF8B17, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFF800080, 0xFF800040, 0xFFB35900, 0xFF8C8C00, 0xFF000000, 0xFFDF00DF, 0xFFE4013A, 0xFFFF8000, 0xFFFFFF00, 0xFF808080, 0xFFFF8CFF, 0xFFD68585, 0xFFFECF78, 0xFFFFFF80, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFF4E009B, 0xFF0000A0, 0xFF538BB5, 0xFF008040, 0xFF000000, 0xFF8000FF, 0xFF5F22FD, 0xFF58CFFC, 0xFF029D5B, 0xFF84846F, 0xFFD896FC, 0xFF9595FF, 0xFF93FFFF, 0xFF43FEA5, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFF9E8B49, 0xFF8B96A7, 0xFFB78786, 0xFF432121, 0xFF000000, 0xFFBF7E3E, 0xFFAFB0BC, 0xFFDDC9BF, 0xFF562945, 0xFF5B5B5B, 0xFFBBA85B, 0xFFB1C1D1, 0xFFE0CFA9, 0xFF8A5353, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFF003535, 0xFF00974B, 0xFF487776, 0xFFF5F5F5, 0xFF8C4600, 0xFF00773C, 0xFF02B78E, 0xFF95B5BF, 0xFFEAF1F2, 0xFFCF7625, 0xFF02B08D, 0xFF64AB03, 0xFFE1E1E1, 0xFFFFFFFF, 0xFFE6AD59
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFFA5ABBC, 0xFF002828, 0xFFCBA0BE, 0xFF392837, 0xFF000000, 0xFFBDC8D2, 0xFF44526A, 0xFFDBB0CF, 0xFF593349, 0xFF808080, 0xFFC6DDDD, 0xFF687D93, 0xFFE9C7C7, 0xFF8D6376, 0xFFFFFFFF
|
||||
},
|
||||
|
||||
new uint [15]
|
||||
{
|
||||
0xFFBDA98A, 0xFF222200, 0xFFBCBCBC, 0xFF232332, 0xFF000000, 0xFFE6D6BD, 0xFF5C5C2E, 0xFFD2D7DB, 0xFF424D55, 0xFF808080, 0xFFEFE7E7, 0xFF7B7C56, 0xFFE9EAED, 0xFF6B6B6B, 0xFFFFFFFF
|
||||
},
|
||||
};
|
||||
|
||||
//Should probably convert other palette data to be like this, and just do palette * 16 + color_idx to find the color
|
||||
public static uint[] NL_Palette_Data = new uint[256]
|
||||
{
|
||||
0xFFFFEFFF, 0xFFFF9AAD, 0xFFEF559C, 0xFFFF65AD, 0xFFFF0063, 0xFFBD4573, 0xFFCE0052, 0xFF9C0031, 0xFF522031, 0xFF000009, 0xFF00000A, 0xFF00000B, 0xFF00000C, 0xFF00000D, 0xFF00000E, 0xFFFFFFFF,
|
||||
0xFFFFBACE, 0xFFFF7573, 0xFFDE3010, 0xFFFF5542, 0xFFFF0000, 0xFFCE6563, 0xFFBD4542, 0xFFBD0000, 0xFF8C2021, 0xFF000019, 0xFF00001A, 0xFF00001B, 0xFF00001C, 0xFF00001D, 0xFF00001E, 0xFFECECEC,
|
||||
0xFFDECFBD, 0xFFFFCF63, 0xFFDE6521, 0xFFFFAA21, 0xFFFF6500, 0xFFBD8A52, 0xFFDE4500, 0xFFBD4500, 0xFF633010, 0xFF000029, 0xFF00002A, 0xFF00002B, 0xFF00002C, 0xFF00002D, 0xFF00002E, 0xFFDADADA,
|
||||
0xFFFFEFDE, 0xFFFFDFCE, 0xFFFFCFAD, 0xFFFFBA8C, 0xFFFFAA8C, 0xFFDE8A63, 0xFFBD6542, 0xFF9C5531, 0xFF8C4521, 0xFF000039, 0xFF00003A, 0xFF00003B, 0xFF00003C, 0xFF00003D, 0xFF00003E, 0xFFC8C8C8,
|
||||
0xFFFFCFFF, 0xFFEF8AFF, 0xFFCE65DE, 0xFFBD8ACE, 0xFFCE00FF, 0xFF9C659C, 0xFF8C00AD, 0xFF520073, 0xFF310042, 0xFF000049, 0xFF00004A, 0xFF00004B, 0xFF00004C, 0xFF00004D, 0xFF00004E, 0xFFB6B6B6,
|
||||
0xFFFFBAFF, 0xFFFF9AFF, 0xFFDE20BD, 0xFFFF55EF, 0xFFFF00CE, 0xFF8C5573, 0xFFBD009C, 0xFF8C0063, 0xFF520042, 0xFF000059, 0xFF00005A, 0xFF00005B, 0xFF00005C, 0xFF00005D, 0xFF00005E, 0xFFA3A3A3,
|
||||
0xFFDEBA9C, 0xFFCEAA73, 0xFF734531, 0xFFAD7542, 0xFF9C3000, 0xFF733021, 0xFF522000, 0xFF311000, 0xFF211000, 0xFF000069, 0xFF00006A, 0xFF00006B, 0xFF00006C, 0xFF00006D, 0xFF00006E, 0xFF919191,
|
||||
0xFFFFFFCE, 0xFFFFFF73, 0xFFDEDF21, 0xFFFFFF00, 0xFFFFDF00, 0xFFCEAA00, 0xFF9C9A00, 0xFF8C7500, 0xFF525500, 0xFF000079, 0xFF00007A, 0xFF00007B, 0xFF00007C, 0xFF00007D, 0xFF00007E, 0xFF7F7F7F,
|
||||
0xFFDEBAFF, 0xFFBD9AEF, 0xFF6330CE, 0xFF9C55FF, 0xFF6300FF, 0xFF52458C, 0xFF42009C, 0xFF210063, 0xFF211031, 0xFF000089, 0xFF00008A, 0xFF00008B, 0xFF00008C, 0xFF00008D, 0xFF00008E, 0xFF6D6D6D,
|
||||
0xFFBDBAFF, 0xFF8C9AFF, 0xFF3130AD, 0xFF3155EF, 0xFF0000FF, 0xFF31308C, 0xFF0000AD, 0xFF101063, 0xFF000021, 0xFF000099, 0xFF00009A, 0xFF00009B, 0xFF00009C, 0xFF00009D, 0xFF00009E, 0xFF5B5B5B,
|
||||
0xFF9CEFBD, 0xFF63CF73, 0xFF216510, 0xFF42AA31, 0xFF008A31, 0xFF527552, 0xFF215500, 0xFF103021, 0xFF002010, 0xFF0000A9, 0xFF0000AA, 0xFF0000AB, 0xFF0000AC, 0xFF0000AD, 0xFF0000AE, 0xFF484848,
|
||||
0xFFDEFFBD, 0xFFCEFF8C, 0xFF8CAA52, 0xFFADDF8C, 0xFF8CFF00, 0xFFADBA9C, 0xFF63BA00, 0xFF529A00, 0xFF316500, 0xFF0000B9, 0xFF0000BA, 0xFF0000BB, 0xFF0000BC, 0xFF0000BD, 0xFF0000BE, 0xFF363636,
|
||||
0xFFBDDFFF, 0xFF73CFFF, 0xFF31559C, 0xFF639AFF, 0xFF1075FF, 0xFF4275AD, 0xFF214573, 0xFF002073, 0xFF001042, 0xFF0000C9, 0xFF0000CA, 0xFF0000CB, 0xFF0000CC, 0xFF0000CD, 0xFF0000CE, 0xFF242424,
|
||||
0xFFADFFFF, 0xFF52FFFF, 0xFF008ABD, 0xFF52BACE, 0xFF00CFFF, 0xFF429AAD, 0xFF00658C, 0xFF004552, 0xFF002031, 0xFF0000D9, 0xFF0000DA, 0xFF0000DB, 0xFF0000DC, 0xFF0000DD, 0xFF0000DE, 0xFF121212,
|
||||
0xFFCEFFEF, 0xFFADEFDE, 0xFF31CFAD, 0xFF52EFBD, 0xFF00FFCE, 0xFF73AAAD, 0xFF00AA9C, 0xFF008A73, 0xFF004531, 0xFF0000E9, 0xFF0000EA, 0xFF0000EB, 0xFF0000EC, 0xFF0000ED, 0xFF0000EE, 0xFF000000,
|
||||
0xFFADFFAD, 0xFF73FF73, 0xFF63DF42, 0xFF00FF00, 0xFF21DF21, 0xFF52BA52, 0xFF00BA00, 0xFF008A00, 0xFF214521, 0xFF0000F9, 0xFF0000FA, 0xFF0000FB, 0xFF0000FC, 0xFF0000FD, 0xFF0000FE, 0xFF0000FF
|
||||
};
|
||||
|
||||
|
||||
private static Color ColorFromUInt32(uint color)
|
||||
{
|
||||
return Color.FromArgb(0xFF, (byte)(color >> 16), (byte)(color >> 8), (byte)(color));
|
||||
}
|
||||
|
||||
public static byte ClosestColor(uint color, int palette, uint[][] paletteData)
|
||||
{
|
||||
uint closestColor = paletteData[palette][0];
|
||||
double diff = double.MaxValue;
|
||||
Color c = ColorFromUInt32(color);
|
||||
float targetHue = c.GetHue();
|
||||
float targetSat = c.GetSaturation();
|
||||
float targetBri = c.GetBrightness();
|
||||
|
||||
foreach (uint validColor in paletteData[palette])
|
||||
{
|
||||
Color checkColor = ColorFromUInt32(validColor);
|
||||
float currentHue = checkColor.GetHue();
|
||||
float currentSat = checkColor.GetSaturation();
|
||||
float currentBri = checkColor.GetBrightness();
|
||||
|
||||
double currentDiff = Math.Pow(targetHue - currentHue, 2) + Math.Pow(targetSat - currentSat, 2) + Math.Pow(targetBri - currentBri, 2);
|
||||
|
||||
if (currentDiff < diff)
|
||||
{
|
||||
diff = currentDiff;
|
||||
closestColor = validColor;
|
||||
}
|
||||
}
|
||||
|
||||
return (byte)(Array.IndexOf(paletteData[palette], closestColor) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public class Pattern
|
||||
{
|
||||
private Save Save_File;
|
||||
private int Offset = 0;
|
||||
public byte[] patternBitmapBuffer = new byte[4 * 32 * 32];
|
||||
public byte[] rawPatternArray;
|
||||
public string Name;
|
||||
public string CreatorName;
|
||||
public string TownName;
|
||||
public byte Palette;
|
||||
public byte Concept;
|
||||
public Bitmap Pattern_Bitmap;
|
||||
|
||||
public Pattern(int patternOffset, Save save = null)
|
||||
{
|
||||
Offset = patternOffset;
|
||||
Save_File = save;
|
||||
Read();
|
||||
}
|
||||
|
||||
//AC only
|
||||
public void GeneratePatternBitmapFromImport(byte[] buffer)
|
||||
{
|
||||
int pos = 0;
|
||||
for (int i = 0; i < buffer.Length; i++)
|
||||
{
|
||||
byte RightPixel = (byte)(buffer[i] & 0x0F);
|
||||
byte LeftPixel = (byte)((buffer[i] & 0xF0) >> 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(PatternData.AC_Palette_Data[Palette][LeftPixel - 1]), 0, patternBitmapBuffer, pos * 4, 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(PatternData.AC_Palette_Data[Palette][RightPixel - 1]), 0, patternBitmapBuffer, (pos + 1) * 4, 4);
|
||||
pos += 2;
|
||||
}
|
||||
Pattern_Bitmap = new Bitmap(32, 32, PixelFormat.Format32bppArgb);
|
||||
BitmapData bitmapData = Pattern_Bitmap.LockBits(new Rectangle(0, 0, 32, 32), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); //Should probably switch to 24bit rgb since alpha channel isn't used
|
||||
System.Runtime.InteropServices.Marshal.Copy(patternBitmapBuffer, 0, bitmapData.Scan0, patternBitmapBuffer.Length);
|
||||
Pattern_Bitmap.UnlockBits(bitmapData);
|
||||
rawPatternArray = buffer;
|
||||
}
|
||||
|
||||
//AC only
|
||||
public byte[] ConvertImport()
|
||||
{
|
||||
byte[] correctedBuffer = new byte[512];
|
||||
if (rawPatternArray != null)
|
||||
{
|
||||
List<byte[]> Block_Data = new List<byte[]>();
|
||||
for (int i = 0; i < 32; i ++)
|
||||
{
|
||||
byte[] block = new byte[16];
|
||||
for (int x = 0; x < 4; x++)
|
||||
{
|
||||
int pos = (i % 4) * 4 + (i / 4) * 64 + x * 16;
|
||||
Buffer.BlockCopy(rawPatternArray, pos, block, x * 4, 4);
|
||||
}
|
||||
Block_Data.Add(block);
|
||||
}
|
||||
List<byte[]> Sorted_Blocks = new List<byte[]>()
|
||||
{
|
||||
Block_Data[0], Block_Data[4], Block_Data[1], Block_Data[5], //0, 1, 2, 3|
|
||||
Block_Data[2], Block_Data[6], Block_Data[3], Block_Data[7], //4, 5, 6, 7|
|
||||
Block_Data[8], Block_Data[12], Block_Data[9], Block_Data[13], //8, 9, 10, 11|
|
||||
Block_Data[10], Block_Data[14], Block_Data[11], Block_Data[15], //12, 13, 14, 15|
|
||||
Block_Data[16], Block_Data[20], Block_Data[17], Block_Data[21], //16, 17, 18, 19
|
||||
Block_Data[18], Block_Data[22], Block_Data[19], Block_Data[23], //20, 21, 22, 23
|
||||
Block_Data[24], Block_Data[28], Block_Data[25], Block_Data[29], //24, 25, 26, 27
|
||||
Block_Data[26], Block_Data[30], Block_Data[27], Block_Data[31], //28, 29, 30, 31
|
||||
};
|
||||
for (int i = 0; i < 32; i++)
|
||||
Sorted_Blocks[i].CopyTo(correctedBuffer, i * 16);
|
||||
}
|
||||
return correctedBuffer;
|
||||
}
|
||||
|
||||
public void AdjustPalette()
|
||||
{
|
||||
if (rawPatternArray == null)
|
||||
GeneratePatternBitmap();
|
||||
else
|
||||
GeneratePatternBitmapFromImport(rawPatternArray);
|
||||
}
|
||||
|
||||
public void GeneratePatternBitmap()
|
||||
{
|
||||
byte[] patternRawData = Save_File == null ? DataConverter.ReadDataRaw(Offset + 0x20, 0x200) : Save_File.ReadByteArray(Offset + 0x20, 0x200);
|
||||
if (PatternData.AC_Palette_Data.Length >= Palette + 1)
|
||||
{
|
||||
byte[][] Block_Data = new byte[32][];
|
||||
for (int block = 0; block < 32; block++)
|
||||
{
|
||||
byte[] Block = new byte[16];
|
||||
Buffer.BlockCopy(patternRawData, block * 16, Block, 0, 16);
|
||||
Block_Data[block] = Block;
|
||||
}
|
||||
byte[][] Sorted_Block_Data = new byte[32][]; // Ayy I finally derived the formula! (04/28/2017) Now to write the reverse equation (should just be reverse assigned)
|
||||
for (int Grouped_Block = 0; Grouped_Block < 4; Grouped_Block++)
|
||||
{
|
||||
for (int Double_Block = 0; Double_Block < 4; Double_Block++)
|
||||
{
|
||||
for (int Block = 0; Block < 2; Block++)
|
||||
{
|
||||
Sorted_Block_Data[Grouped_Block * 8 + Double_Block + (Block % 2) * 4] = Block_Data[Grouped_Block * 8 + Double_Block * 2 + Block];
|
||||
}
|
||||
}
|
||||
}
|
||||
int pos = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
for (int y = 0; y < 4; y++)
|
||||
{
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
byte RightPixel = (byte)(Sorted_Block_Data[i * 4 + x / 4][x % 4 + y * 4] & 0x0F);
|
||||
byte LeftPixel = (byte)((Sorted_Block_Data[i * 4 + x / 4][x % 4 + y * 4] & 0xF0) >> 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(PatternData.AC_Palette_Data[Palette][Math.Max(0, LeftPixel - 1)]), 0, patternBitmapBuffer, pos * 4, 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(PatternData.AC_Palette_Data[Palette][Math.Max(0, RightPixel - 1)]), 0, patternBitmapBuffer, (pos + 1) * 4, 4);
|
||||
pos += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
Pattern_Bitmap = new Bitmap(32, 32, PixelFormat.Format32bppArgb);
|
||||
BitmapData bitmapData = Pattern_Bitmap.LockBits(new Rectangle(0, 0, 32, 32), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
System.Runtime.InteropServices.Marshal.Copy(patternBitmapBuffer, 0, bitmapData.Scan0, patternBitmapBuffer.Length);
|
||||
Pattern_Bitmap.UnlockBits(bitmapData);
|
||||
}
|
||||
}
|
||||
|
||||
public void GenerateWWPatternBitmap()
|
||||
{
|
||||
byte[] Raw_Data = Save_File.ReadByteArray(Offset, 0x200);
|
||||
byte[] Expanded_Data = new byte[0x400];
|
||||
for (int i = 0; i < 0x200; i++)
|
||||
{
|
||||
Expanded_Data[i * 2] = (byte)(Raw_Data[i] & 0x0F); //Left is Right
|
||||
Expanded_Data[i * 2 + 1] = (byte)((Raw_Data[i] & 0xF0) >> 4); //Right is Left
|
||||
}
|
||||
uint[] Palette_Array = PatternData.WW_Palette_Data[Palette];
|
||||
//All colors are reversed in there... fix sometime pls
|
||||
for (int i = 0; i < 0x400; i++)
|
||||
{
|
||||
int color_idx = Math.Max(0, Expanded_Data[i] - 1);
|
||||
uint color = Palette_Array[color_idx];
|
||||
byte[] color_bytes = BitConverter.GetBytes(color);
|
||||
byte[] corrected_bytes = new byte[4] {color_bytes[2], color_bytes[1], color_bytes[0], 0xFF };
|
||||
Buffer.BlockCopy(corrected_bytes, 0, patternBitmapBuffer, i * 4, 4);
|
||||
}
|
||||
Pattern_Bitmap = new Bitmap(32, 32, PixelFormat.Format32bppArgb);
|
||||
BitmapData bitmapData = Pattern_Bitmap.LockBits(new Rectangle(0, 0, 32, 32), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
System.Runtime.InteropServices.Marshal.Copy(patternBitmapBuffer, 0, bitmapData.Scan0, patternBitmapBuffer.Length);
|
||||
Pattern_Bitmap.UnlockBits(bitmapData);
|
||||
}
|
||||
|
||||
//Add "pro" patterns (supports four patterns in one)
|
||||
public void GenerateCFPatternBitmap()
|
||||
{
|
||||
byte[] Raw_Data = Save_File.ReadByteArray(Offset, 0x200);
|
||||
{
|
||||
List<byte[]> Block_Data = new List<byte[]>();
|
||||
for (int block = 0; block < 32; block++)
|
||||
{
|
||||
byte[] Block = new byte[16];
|
||||
Buffer.BlockCopy(Raw_Data, block * 16, Block, 0, 16);
|
||||
Block_Data.Add(Block);
|
||||
}
|
||||
List<byte[]> Sorted_Block_Data = new List<byte[]>() //Too lazy to derive the actual formula to decode it, so I'll sort it manually
|
||||
{
|
||||
Block_Data[0], Block_Data[2], Block_Data[4], Block_Data[6],
|
||||
Block_Data[1], Block_Data[3], Block_Data[5], Block_Data[7],
|
||||
Block_Data[8], Block_Data[10], Block_Data[12], Block_Data[14],
|
||||
Block_Data[9], Block_Data[11], Block_Data[13], Block_Data[15],
|
||||
Block_Data[16], Block_Data[18], Block_Data[20], Block_Data[22],
|
||||
Block_Data[17], Block_Data[19], Block_Data[21], Block_Data[23],
|
||||
Block_Data[24], Block_Data[26], Block_Data[28], Block_Data[30],
|
||||
Block_Data[25], Block_Data[27], Block_Data[29], Block_Data[31],
|
||||
};
|
||||
int pos = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
for (int y = 0; y < 4; y++)
|
||||
{
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
byte RightPixel = (byte)(Sorted_Block_Data[i * 4 + x / 4][x % 4 + y * 4] & 0x0F);
|
||||
byte LeftPixel = (byte)((Sorted_Block_Data[i * 4 + x / 4][x % 4 + y * 4] & 0xF0) >> 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(PatternData.CF_Palette_Data[Palette][Math.Max(0, LeftPixel - 1)]), 0, patternBitmapBuffer, pos * 4, 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(PatternData.CF_Palette_Data[Palette][Math.Max(0, RightPixel - 1)]), 0, patternBitmapBuffer, (pos + 1) * 4, 4);
|
||||
pos += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
Pattern_Bitmap = new Bitmap(32, 32, PixelFormat.Format32bppArgb);
|
||||
BitmapData bitmapData = Pattern_Bitmap.LockBits(new Rectangle(0, 0, 32, 32), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
System.Runtime.InteropServices.Marshal.Copy(patternBitmapBuffer, 0, bitmapData.Scan0, patternBitmapBuffer.Length);
|
||||
Pattern_Bitmap.UnlockBits(bitmapData);
|
||||
}
|
||||
}
|
||||
|
||||
//NL Patterns have a custom palette, created by the user by choosing 15 colors
|
||||
public void GenerateNLPatternBitmap()
|
||||
{
|
||||
//Add decoding of "Pro" patterns
|
||||
byte[] Raw_Data = Save_File.ReadByteArray(Offset + 0x6C, 0x200); //32x32 doubled up pixels
|
||||
byte[] Expanded_Data = new byte[0x400]; //32x32 expanded pixel buffer
|
||||
byte[] Custom_Palette = Save_File.ReadByteArray(Offset + 0x58, 15); //New Leaf user selected palette data
|
||||
|
||||
//Expand data for working with
|
||||
for (int i = 0; i < 0x200; i++)
|
||||
{
|
||||
Expanded_Data[i * 2] = (byte)(Raw_Data[i] & 0x0F);
|
||||
Expanded_Data[i * 2 + 1] = (byte)((Raw_Data[i] >> 4) & 0x0F);
|
||||
}
|
||||
|
||||
//Convert palette color index to argb color
|
||||
for (int i = 0; i < 0x400; i++)
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(PatternData.NL_Palette_Data[Custom_Palette[Expanded_Data[i]]]), 0, patternBitmapBuffer, i * 4, 4);
|
||||
|
||||
//Create new bitmap
|
||||
Pattern_Bitmap = new Bitmap(32, 32, PixelFormat.Format32bppArgb);
|
||||
BitmapData bitmapData = Pattern_Bitmap.LockBits(new Rectangle(0, 0, 32, 32), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
System.Runtime.InteropServices.Marshal.Copy(patternBitmapBuffer, 0, bitmapData.Scan0, patternBitmapBuffer.Length);
|
||||
Pattern_Bitmap.UnlockBits(bitmapData);
|
||||
}
|
||||
|
||||
public void Read()
|
||||
{
|
||||
if (Save_File.Save_Type == SaveType.Animal_Crossing || Save_File.Save_Type == SaveType.Doubutsu_no_Mori_e_Plus || Save_File.Save_Type == SaveType.Doubutsu_no_Mori
|
||||
|| Save_File.Save_Type == SaveType.Doubutsu_no_Mori_Plus)
|
||||
{
|
||||
Name = Save_File == null ? DataConverter.ReadString(Offset, 0x10).Trim() : new ACString(Save_File.ReadByteArray(Offset, 0x10)).Trim();
|
||||
Palette = Save_File == null ? DataConverter.ReadData(Offset + 0x10, 0x1)[0] : Save_File.ReadByte(Offset + 0x10);
|
||||
GeneratePatternBitmap();
|
||||
}
|
||||
else if (Save_File.Save_Type == SaveType.Wild_World)
|
||||
{
|
||||
TownName = new ACString(Save_File.ReadByteArray(Offset + 0x202, 8), SaveType.Wild_World).Trim();
|
||||
CreatorName = new ACString(Save_File.ReadByteArray(Offset + 0x20C, 8), SaveType.Wild_World).Trim();
|
||||
Name = new ACString(Save_File.ReadByteArray(Offset + 0x216, 16), SaveType.Wild_World).Trim();
|
||||
Palette = (byte)((Save_File.ReadByte(Offset + 0x226) & 0xF0) >> 4);
|
||||
Concept = (byte)(Save_File.ReadByte(Offset + 0x226) & 0x0F);
|
||||
GenerateWWPatternBitmap();
|
||||
}
|
||||
else if (Save_File.Save_Type == SaveType.City_Folk)
|
||||
{
|
||||
TownName = new ACString(Save_File.ReadByteArray(Offset + 0x822, 16), SaveType.City_Folk).Trim();
|
||||
CreatorName = new ACString(Save_File.ReadByteArray(Offset + 0x838, 16), SaveType.City_Folk).Trim();
|
||||
Name = new ACString(Save_File.ReadByteArray(Offset + 0x84C, 32), SaveType.City_Folk).Trim();
|
||||
Palette = Save_File.ReadByte(Offset + 0x86F);
|
||||
GenerateCFPatternBitmap();
|
||||
}
|
||||
else if (Save_File.Save_Type == SaveType.New_Leaf || Save_File.Save_Type == SaveType.Welcome_Amiibo)
|
||||
{
|
||||
Name = new ACString(Save_File.ReadByteArray(Offset, 0x2A), SaveType.New_Leaf).Trim();
|
||||
CreatorName = new ACString(Save_File.ReadByteArray(Offset + 0x2C, 0x14), SaveType.New_Leaf).Trim();
|
||||
TownName = new ACString(Save_File.ReadByteArray(Offset + 0x42, 0x14), SaveType.New_Leaf).Trim();
|
||||
//No specific palette in NL/WA
|
||||
GenerateNLPatternBitmap();
|
||||
}
|
||||
else
|
||||
MessageBox.Show("Patterns: Unknown Save Type");
|
||||
}
|
||||
|
||||
public void Write()
|
||||
{
|
||||
DataConverter.WriteString(Offset, Name, 0x10);
|
||||
DataConverter.WriteByte(Offset + 0x10, Palette);
|
||||
if (rawPatternArray != null)
|
||||
DataConverter.WriteByteArray(Offset + 0x20, ConvertImport(), false);
|
||||
}
|
||||
}
|
||||
}
|
1035
Classes/Player.cs
Normal file
24
Classes/Program.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
||||
Application.Run(new NewMainForm());
|
||||
}
|
||||
}
|
||||
}
|
873
Classes/Save.cs
Normal file
|
@ -0,0 +1,873 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Reflection;
|
||||
using System.Globalization;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
public enum SaveType
|
||||
{
|
||||
Unknown,
|
||||
Doubutsu_no_Mori,
|
||||
Doubutsu_no_Mori_Plus, //Possible to remove this? I can't even find a valid file on the internet... Perhaps I'll just buy a copy
|
||||
Animal_Crossing,
|
||||
Doubutsu_no_Mori_e_Plus,
|
||||
Wild_World,
|
||||
City_Folk,
|
||||
New_Leaf,
|
||||
Welcome_Amiibo
|
||||
}
|
||||
|
||||
public struct Offsets
|
||||
{
|
||||
public int Save_Size;
|
||||
public int Checksum;
|
||||
public int Town_Name;
|
||||
public int Player_Start;
|
||||
public int Player_Size;
|
||||
public int Town_Data;
|
||||
public int Town_Data_Size;
|
||||
public int Acre_Data;
|
||||
public int Acre_Data_Size;
|
||||
public int Buried_Data;
|
||||
public int Buried_Data_Size;
|
||||
public int Island_Acre_Data;
|
||||
public int Island_World_Data;
|
||||
public int Island_World_Size;
|
||||
public int Island_Buried_Data;
|
||||
public int Island_Buried_Size;
|
||||
public int Island_Buildings;
|
||||
public int House_Data;
|
||||
public int House_Data_Size;
|
||||
public int Villager_Data;
|
||||
public int Villager_Size;
|
||||
public int Islander_Data;
|
||||
public int Debt; //Only global in WW
|
||||
public int Buildings; //CF/NL
|
||||
public int Buildings_Count;
|
||||
public int Grass_Wear;
|
||||
public int Grass_Wear_Size;
|
||||
public int PWPs; //NL only
|
||||
public int Past_Villagers;
|
||||
public int[] CRC_Offsets;
|
||||
}
|
||||
|
||||
public struct Save_Info
|
||||
{
|
||||
public bool Contains_Island;
|
||||
public bool Has_Islander;
|
||||
public int Pattern_Count;
|
||||
public bool Player_JPEG_Picture;
|
||||
public Offsets Save_Offsets;
|
||||
public int Acre_Count;
|
||||
public int X_Acre_Count;
|
||||
public int Town_Acre_Count;
|
||||
public int Town_Y_Acre_Start;
|
||||
public int Island_Acre_Count;
|
||||
public int Island_X_Acre_Count;
|
||||
public int Villager_Count;
|
||||
public string[] House_Rooms;
|
||||
}
|
||||
|
||||
public enum SaveFileDataOffset
|
||||
{
|
||||
nafjfla = 0,
|
||||
gafegci = 0x26040,
|
||||
gafegcs = 0x26150,
|
||||
admeduc = 0x1F4,
|
||||
admedss = 0x1F4,
|
||||
admedsv = 0,
|
||||
admesav = 0,
|
||||
ruuedat = 0,
|
||||
edgedat = 0x80,
|
||||
edgebin = 0, //RAM Dump
|
||||
eaaedat = 0x80,
|
||||
}
|
||||
|
||||
public static class SaveDataManager
|
||||
{
|
||||
public static Offsets Animal_Crossing_Offsets = new Offsets
|
||||
{
|
||||
Save_Size = 0x26000,
|
||||
Town_Name = 0x9120,
|
||||
Player_Start = 0x20,
|
||||
Player_Size = 0x2440,
|
||||
Villager_Data = 0x17438,
|
||||
Villager_Size = 0x988,
|
||||
Acre_Data = 0x173A8,
|
||||
Acre_Data_Size = 0x8C,
|
||||
Town_Data = 0x137A8,
|
||||
Town_Data_Size = 0x3C00,
|
||||
Buried_Data = 0x20F1C,
|
||||
Buried_Data_Size = 0x3C0,
|
||||
Island_World_Data = 0x22554,
|
||||
Island_World_Size = 0x400,
|
||||
Island_Buried_Data = 0x23DC8, //C9
|
||||
Island_Buried_Size = 0x40,
|
||||
Islander_Data = 0x23440,
|
||||
House_Data = 0x9CE8,
|
||||
House_Data_Size = 0x26B0,
|
||||
Island_Acre_Data = 0x17420,
|
||||
Buildings = -1,
|
||||
Debt = -1,
|
||||
Grass_Wear = -1,
|
||||
Past_Villagers = -1,
|
||||
PWPs = -1,
|
||||
Island_Buildings = -1,
|
||||
Checksum = 0x12
|
||||
};
|
||||
|
||||
public static Offsets Wild_World_Offsets = new Offsets
|
||||
{
|
||||
Save_Size = 0x15FE0,
|
||||
Town_Name = 0x0004,
|
||||
Player_Start = 0x000C,
|
||||
Player_Size = 0x228C,
|
||||
Villager_Data = 0x8A3C,
|
||||
Villager_Size = 0x700,
|
||||
Acre_Data = 0xC330,
|
||||
Acre_Data_Size = 0x24,
|
||||
Town_Data = 0xC354,
|
||||
Town_Data_Size = 0x2000,
|
||||
Buried_Data = 0xE354,
|
||||
Buried_Data_Size = 0x200,
|
||||
House_Data = 0xE558,
|
||||
House_Data_Size = 0x15A0,
|
||||
Debt = 0xFAE8,
|
||||
Buildings = -1,
|
||||
Grass_Wear = -1,
|
||||
Islander_Data = -1,
|
||||
Island_Buried_Data = -1,
|
||||
Island_World_Data = -1,
|
||||
Past_Villagers = -1,
|
||||
PWPs = -1,
|
||||
Island_Acre_Data = -1,
|
||||
Island_Buildings = -1,
|
||||
Checksum = 0x15FDC
|
||||
};
|
||||
|
||||
public static Offsets City_Folk_Offsets = new Offsets
|
||||
{
|
||||
Save_Size = 0x40F340,
|
||||
Player_Start = 0,
|
||||
Player_Size = 0x86C0,
|
||||
Buildings = 0x5EB0A,
|
||||
Buildings_Count = 0x33, //Not sure
|
||||
Acre_Data = 0x68414, //Don't forget about the additional acres before?
|
||||
Acre_Data_Size = 0x62,
|
||||
Town_Name = 0x640E8,
|
||||
Town_Data = 0x68476,
|
||||
Town_Data_Size = 0x3200,
|
||||
Buried_Data = 0x6B676,
|
||||
Buried_Data_Size = 400,
|
||||
Grass_Wear = 0x6BCB6,
|
||||
Grass_Wear_Size = 0x1900,
|
||||
House_Data = 0x6D5C0,
|
||||
House_Data_Size = 0x15C0,
|
||||
Checksum = -1,
|
||||
Debt = -1,
|
||||
Islander_Data = -1,
|
||||
Island_Buried_Data = -1,
|
||||
Island_World_Data = -1,
|
||||
Past_Villagers = -1,
|
||||
PWPs = -1,
|
||||
Villager_Data = -1, //finish this sometime
|
||||
Island_Acre_Data = -1,
|
||||
Island_Buildings = -1,
|
||||
};
|
||||
|
||||
public static Offsets New_Leaf_Offsets = new Offsets
|
||||
{
|
||||
Save_Size = 0x7F980,
|
||||
Player_Start = 0x20,
|
||||
Player_Size = 0x9F10,
|
||||
Villager_Data = 0x27C90,
|
||||
Villager_Size = 0x24F8,
|
||||
Buildings = 0x49528,
|
||||
Buildings_Count = 58, //TODO: Add island buildings (Island Hut & Loaner Gyroid at 59 and 60)
|
||||
Acre_Data = 0x4DA04,
|
||||
Acre_Data_Size = 0x54,
|
||||
Town_Data = 0x4DA58,
|
||||
Town_Data_Size = 0x5000,
|
||||
Buried_Data = -1,
|
||||
Town_Name = 0x5C73A,
|
||||
Grass_Wear = 0x53E80,
|
||||
Grass_Wear_Size = 0x3000, //Extra row of "Invisible" X Acres
|
||||
Past_Villagers = 0x3F17E,
|
||||
Island_Acre_Data = 0x6A408,
|
||||
Island_World_Data = 0x6A428,
|
||||
Island_Buildings = 0x6B428,
|
||||
//Campsite_Villager = 0x3F1CA
|
||||
};
|
||||
|
||||
public static Offsets Welcome_Amiibo_Offsets = new Offsets
|
||||
{
|
||||
Save_Size = 0x89A80,
|
||||
Player_Start = 0x20,
|
||||
Player_Size = 0xA480,
|
||||
Villager_Data = 0x29250,
|
||||
Villager_Size = 0x2518,
|
||||
Buildings = 0x4BE08,
|
||||
Buildings_Count = 58, //TODO: Add island buildings (Island Hut & Loaner Gyroid at 59 and 60)
|
||||
Acre_Data = 0x53404,
|
||||
Acre_Data_Size = 0x54,
|
||||
Town_Data = 0x53458,
|
||||
Town_Data_Size = 0x5000,
|
||||
Buried_Data = -1,
|
||||
Town_Name = 0x6213A,
|
||||
Grass_Wear = 0x59880,
|
||||
Grass_Wear_Size = 0x3000, //Extra row of "Invisible" X Acres
|
||||
Past_Villagers = 0x4087A,
|
||||
Island_Acre_Data = 0x6FE38,
|
||||
Island_World_Data = 0x6FE58,
|
||||
Island_Buildings = 0x70E58,
|
||||
};
|
||||
|
||||
public static Save_Info Animal_Crossing = new Save_Info
|
||||
{
|
||||
Contains_Island = true,
|
||||
Has_Islander = true,
|
||||
Player_JPEG_Picture = false,
|
||||
Pattern_Count = 8,
|
||||
Save_Offsets = Animal_Crossing_Offsets,
|
||||
Acre_Count = 70,
|
||||
X_Acre_Count = 7,
|
||||
Town_Acre_Count = 30,
|
||||
Island_Acre_Count = 2,
|
||||
Island_X_Acre_Count = 2,
|
||||
Town_Y_Acre_Start = 1,
|
||||
Villager_Count = 16,
|
||||
House_Rooms = new string[3] { "Main Floor", "Upper Floor", "Basement" } //Don't forget about island house
|
||||
};
|
||||
|
||||
public static Save_Info Wild_World = new Save_Info
|
||||
{
|
||||
Contains_Island = false,
|
||||
Has_Islander = false,
|
||||
Player_JPEG_Picture = false,
|
||||
Pattern_Count = 8,
|
||||
Save_Offsets = Wild_World_Offsets,
|
||||
Acre_Count = 36,
|
||||
X_Acre_Count = 6,
|
||||
Town_Acre_Count = 16,
|
||||
Town_Y_Acre_Start = 1,
|
||||
Villager_Count = 8,
|
||||
House_Rooms = new string[6] { "Main Floor", "Basement", "Upper Floor", "Left Wing", "Right Wing", "Back Wing" } //Confirm order
|
||||
//6 drawers with 15 items per
|
||||
};
|
||||
|
||||
public static Save_Info City_Folk = new Save_Info
|
||||
{
|
||||
Contains_Island = false,
|
||||
Has_Islander = false,
|
||||
Player_JPEG_Picture = false,
|
||||
Pattern_Count = 8,
|
||||
Save_Offsets = City_Folk_Offsets,
|
||||
Acre_Count = 49,
|
||||
X_Acre_Count = 7,
|
||||
Town_Acre_Count = 25,
|
||||
Town_Y_Acre_Start = 1,
|
||||
Villager_Count = 10,
|
||||
House_Rooms = new string[3] { "Main Floor", "Upper Floor", "Basement" }
|
||||
};
|
||||
|
||||
public static Save_Info New_Leaf = new Save_Info
|
||||
{
|
||||
Contains_Island = true,
|
||||
Has_Islander = false,
|
||||
Player_JPEG_Picture = true,
|
||||
Pattern_Count = 10,
|
||||
Save_Offsets = New_Leaf_Offsets,
|
||||
Acre_Count = 42,
|
||||
X_Acre_Count = 7,
|
||||
Town_Acre_Count = 20,
|
||||
Town_Y_Acre_Start = 1,
|
||||
Villager_Count = 10,
|
||||
Island_Acre_Count = 16,
|
||||
Island_X_Acre_Count = 4,
|
||||
House_Rooms = new string[6] { "Main Floor", "Upper Floor", "Basement", "Left Wing", "Right Wing", "Back Wing" } //Check order
|
||||
//3 drawers with 60 items per
|
||||
};
|
||||
|
||||
public static Save_Info Welcome_Amiibo = new Save_Info
|
||||
{
|
||||
Contains_Island = true,
|
||||
Has_Islander = false,
|
||||
Player_JPEG_Picture = true,
|
||||
Pattern_Count = 10,
|
||||
Save_Offsets = Welcome_Amiibo_Offsets,
|
||||
Acre_Count = 42,
|
||||
X_Acre_Count = 7,
|
||||
Town_Acre_Count = 20,
|
||||
Town_Y_Acre_Start = 1,
|
||||
Villager_Count = 10,
|
||||
Island_Acre_Count = 16,
|
||||
Island_X_Acre_Count = 4,
|
||||
House_Rooms = new string[6] { "Main Floor", "Upper Floor", "Basement", "Left Wing", "Right Wing", "Back Wing" }
|
||||
//3 drawers with 60 items per
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Used for Doubutsu no Mori. Every four bytes is reversed in the save, so we change it back.
|
||||
/// </summary>
|
||||
/// <param name="saveBuff"></param>
|
||||
/// <returns></returns>
|
||||
public static byte[] ByteSwap(byte[] saveBuff)
|
||||
{
|
||||
byte[] Corrected_Save = new byte[saveBuff.Length];
|
||||
for (int i = 0; i < saveBuff.Length; i += 4)
|
||||
{
|
||||
byte[] Temp = new byte[4];
|
||||
Buffer.BlockCopy(saveBuff, i, Temp, 0, 4);
|
||||
Array.Reverse(Temp);
|
||||
Temp.CopyTo(Corrected_Save, i);
|
||||
}
|
||||
return Corrected_Save;
|
||||
}
|
||||
|
||||
public static SaveType GetSaveType(byte[] Save_Data)
|
||||
{
|
||||
if (Save_Data.Length == 0x20000)
|
||||
return SaveType.Doubutsu_no_Mori;
|
||||
else if (Save_Data.Length == 0x72040 || Save_Data.Length == 0x72150)
|
||||
{
|
||||
string Game_ID = Encoding.ASCII.GetString(Save_Data, Save_Data.Length == 0x72150 ? 0x110 : 0, 4);
|
||||
if (Game_ID == "GAFE")
|
||||
return SaveType.Animal_Crossing;
|
||||
else if (Game_ID == "GAFJ")
|
||||
return SaveType.Doubutsu_no_Mori_Plus;
|
||||
else if (Game_ID == "GAEJ")
|
||||
return SaveType.Doubutsu_no_Mori_e_Plus;
|
||||
}
|
||||
else if (Save_Data.Length == 0x4007A || Save_Data.Length == 0x401F4 || Save_Data.Length == 0x40000)
|
||||
return SaveType.Wild_World;
|
||||
else if (Save_Data.Length == 0x40F340 || Save_Data.Length == 0x47A0DA)
|
||||
return SaveType.City_Folk;
|
||||
else if (Save_Data.Length == 0x7FA00 || Save_Data.Length == 0x80000)
|
||||
return SaveType.New_Leaf;
|
||||
else if (Save_Data.Length == 0x89B00)
|
||||
return SaveType.Welcome_Amiibo;
|
||||
return SaveType.Unknown;
|
||||
}
|
||||
|
||||
public static int GetSaveDataOffset(string Game_ID, string Extension)
|
||||
{
|
||||
if (Enum.TryParse(Game_ID + Extension, out SaveFileDataOffset Extension_Enum))
|
||||
return (int)Extension_Enum;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static string GetGameID(SaveType Save_Type)
|
||||
{
|
||||
switch (Save_Type)
|
||||
{
|
||||
case SaveType.Doubutsu_no_Mori:
|
||||
return "NAFJ";
|
||||
case SaveType.Animal_Crossing:
|
||||
return "GAFE";
|
||||
case SaveType.Doubutsu_no_Mori_Plus:
|
||||
return "GAFJ";
|
||||
case SaveType.Doubutsu_no_Mori_e_Plus:
|
||||
return "GAEJ";
|
||||
case SaveType.Wild_World: //Currently only supporting the English versions of WW+
|
||||
return "ADME";
|
||||
case SaveType.City_Folk:
|
||||
return "RUUE";
|
||||
case SaveType.New_Leaf:
|
||||
return "EDGE";
|
||||
case SaveType.Welcome_Amiibo:
|
||||
return "EAAE";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public static Save_Info GetSaveInfo(SaveType Save_Type)
|
||||
{
|
||||
switch(Save_Type)
|
||||
{
|
||||
case SaveType.Animal_Crossing:
|
||||
return Animal_Crossing;
|
||||
case SaveType.Wild_World:
|
||||
return Wild_World;
|
||||
case SaveType.City_Folk:
|
||||
return City_Folk;
|
||||
case SaveType.New_Leaf:
|
||||
return New_Leaf;
|
||||
case SaveType.Welcome_Amiibo:
|
||||
return Welcome_Amiibo;
|
||||
default:
|
||||
return Wild_World;
|
||||
}
|
||||
}
|
||||
|
||||
public static Dictionary<ushort, string> GetItemInfo(SaveType Save_Type, string Language = "en")
|
||||
{
|
||||
StreamReader Contents = null;
|
||||
string Item_DB_Location = NewMainForm.Assembly_Location + "\\Resources\\";
|
||||
if (Save_Type == SaveType.Wild_World)
|
||||
Item_DB_Location += "WW_Items_" + Language + ".txt";
|
||||
else if (Save_Type == SaveType.Animal_Crossing)
|
||||
Item_DB_Location += "AC_Items_" + Language + ".txt";
|
||||
else if (Save_Type == SaveType.City_Folk)
|
||||
Item_DB_Location += "CF_Items_" + Language + ".txt";
|
||||
else if (Save_Type == SaveType.New_Leaf)
|
||||
Item_DB_Location += "NL_Items_" + Language + ".txt";
|
||||
else if (Save_Type == SaveType.Welcome_Amiibo)
|
||||
Item_DB_Location += "WA_Items_" + Language + ".txt";
|
||||
try { Contents = File.OpenText(Item_DB_Location); }
|
||||
catch (Exception e)
|
||||
{
|
||||
NewMainForm.Debug_Manager.WriteLine(string.Format("An error occured opening item database file:\n\"{0}\"\nError Info:\n{1}", Item_DB_Location, e.Message), DebugLevel.Error);
|
||||
return null;
|
||||
}
|
||||
Dictionary<ushort, string> Item_Dictionary = new Dictionary<ushort, string>();
|
||||
string Line;
|
||||
while ((Line = Contents.ReadLine()) != null)
|
||||
{
|
||||
if (!Properties.Settings.Default.DebuggingEnabled && Line.Contains("//"))
|
||||
MessageBox.Show("Now loading item type: " + Line.Replace("//", ""));
|
||||
else if (Line.Contains("0x"))
|
||||
{
|
||||
string Item_ID_String = Line.Substring(0, 6), Item_Name = Line.Substring(7).Trim();
|
||||
if (ushort.TryParse(Item_ID_String.Replace("0x", ""), NumberStyles.AllowHexSpecifier, null, out ushort Item_ID))
|
||||
Item_Dictionary.Add(Item_ID, Item_Name);
|
||||
else
|
||||
NewMainForm.Debug_Manager.WriteLine("Unable to add item: " + Item_ID_String + " | " + Item_Name, DebugLevel.Error);
|
||||
}
|
||||
}
|
||||
return Item_Dictionary;
|
||||
}
|
||||
|
||||
public static Dictionary<byte, string> GetAcreInfo(SaveType Save_Type, string Language = "en")
|
||||
{
|
||||
StreamReader Contents = null;
|
||||
string Acre_DB_Location = NewMainForm.Assembly_Location + "\\Resources\\";
|
||||
if (Save_Type == SaveType.Wild_World)
|
||||
Acre_DB_Location += "WW_Acres_" + Language + ".txt";
|
||||
try { Contents = File.OpenText(Acre_DB_Location); }
|
||||
catch (Exception e)
|
||||
{
|
||||
NewMainForm.Debug_Manager.WriteLine(string.Format("An error occured opening acre database file:\n\"{0}\"\nError Info:\n{1}", Acre_DB_Location, e.Message), DebugLevel.Error);
|
||||
return null;
|
||||
}
|
||||
Dictionary<byte, string> Acre_Dictionary = new Dictionary<byte, string>();
|
||||
string Line;
|
||||
while ((Line = Contents.ReadLine()) != null)
|
||||
{
|
||||
if (!Properties.Settings.Default.DebuggingEnabled && Line.Contains("//"))
|
||||
MessageBox.Show("Now loading Acre type: " + Line.Replace("//", ""));
|
||||
else if (Line.Contains("0x"))
|
||||
{
|
||||
string Acre_ID_String = Line.Substring(0, 4), Acre_Name = Line.Substring(5);
|
||||
if (byte.TryParse(Acre_ID_String.Replace("0x", ""), NumberStyles.AllowHexSpecifier, null, out byte Acre_ID))
|
||||
Acre_Dictionary.Add(Acre_ID, Acre_Name);
|
||||
else
|
||||
NewMainForm.Debug_Manager.WriteLine("Unable to add Acre: " + Acre_ID_String + " | " + Acre_Name, DebugLevel.Error);
|
||||
}
|
||||
}
|
||||
return Acre_Dictionary;
|
||||
}
|
||||
|
||||
public static Dictionary<ushort, string> GetAcreInfoUInt16(SaveType Save_Type, string Language = "en")
|
||||
{
|
||||
StreamReader Contents = null;
|
||||
string Acre_DB_Location = NewMainForm.Assembly_Location + "\\Resources\\";
|
||||
if (Save_Type == SaveType.Animal_Crossing)
|
||||
Acre_DB_Location += "AC_Acres_" + Language + ".txt";
|
||||
else if (Save_Type == SaveType.City_Folk)
|
||||
Acre_DB_Location += "CF_Acres_" + Language + ".txt";
|
||||
else if (Save_Type == SaveType.New_Leaf)
|
||||
Acre_DB_Location += "NL_Acres_" + Language + ".txt";
|
||||
else if (Save_Type == SaveType.Welcome_Amiibo)
|
||||
Acre_DB_Location += "WA_Acres_" + Language + ".txt";
|
||||
try { Contents = File.OpenText(Acre_DB_Location); }
|
||||
catch (Exception e)
|
||||
{
|
||||
NewMainForm.Debug_Manager.WriteLine(string.Format("An error occured opening acre database file:\n\"{0}\"\nError Info:\n{1}", Acre_DB_Location, e.Message), DebugLevel.Error);
|
||||
return null;
|
||||
}
|
||||
Dictionary<ushort, string> Acre_Dictionary = new Dictionary<ushort, string>();
|
||||
string Line;
|
||||
while ((Line = Contents.ReadLine()) != null)
|
||||
{
|
||||
if (!Properties.Settings.Default.DebuggingEnabled && Line.Contains("//"))
|
||||
MessageBox.Show("Now loading Acre type: " + Line.Replace("//", ""));
|
||||
else if (Line.Contains("0x"))
|
||||
{
|
||||
string Acre_ID_String = Line.Substring(0, 6), Acre_Name = Line.Substring(7);
|
||||
if (ushort.TryParse(Acre_ID_String.Replace("0x", ""), NumberStyles.AllowHexSpecifier, null, out ushort Acre_ID))
|
||||
Acre_Dictionary.Add(Acre_ID, Acre_Name);
|
||||
else
|
||||
NewMainForm.Debug_Manager.WriteLine("Unable to add Acre: " + Acre_ID_String + " | " + Acre_Name, DebugLevel.Error);
|
||||
}
|
||||
}
|
||||
return Acre_Dictionary;
|
||||
}
|
||||
|
||||
|
||||
public static Dictionary<string, List<byte>> GetFiledAcreData(SaveType Save_Type, string Language = "en")
|
||||
{
|
||||
StreamReader Contents = null;
|
||||
string Acre_DB_Location = NewMainForm.Assembly_Location + "\\Resources\\";
|
||||
if (Save_Type == SaveType.Wild_World)
|
||||
Acre_DB_Location += "WW_Acres_" + Language + ".txt";
|
||||
try { Contents = File.OpenText(Acre_DB_Location); }
|
||||
catch (Exception e)
|
||||
{
|
||||
NewMainForm.Debug_Manager.WriteLine(string.Format("An error occured opening acre database file:\n\"{0}\"\nError Info:\n{1}", Acre_DB_Location, e.Message), DebugLevel.Error);
|
||||
return null;
|
||||
}
|
||||
Dictionary<string, List<byte>> Filed_List = new Dictionary<string, List<byte>>();
|
||||
string Line;
|
||||
string Current_Acre_Type = "Unsorted";
|
||||
while ((Line = Contents.ReadLine()) != null)
|
||||
{
|
||||
if (Line.Contains("//"))
|
||||
{
|
||||
if (Current_Acre_Type != "Unsorted")
|
||||
{
|
||||
if (!Filed_List.ContainsKey(Current_Acre_Type))
|
||||
Filed_List.Add(Current_Acre_Type, new List<byte>());
|
||||
}
|
||||
Current_Acre_Type = Line.Replace("//", "");
|
||||
}
|
||||
else if (Line.Contains("0x"))
|
||||
{
|
||||
if (!Filed_List.ContainsKey(Current_Acre_Type))
|
||||
Filed_List.Add(Current_Acre_Type, new List<byte>());
|
||||
string Acre_ID_String = Line.Substring(0, 4), Acre_Name = Line.Substring(5);
|
||||
if (byte.TryParse(Acre_ID_String.Replace("0x", ""), NumberStyles.AllowHexSpecifier, null, out byte Acre_ID))
|
||||
Filed_List[Current_Acre_Type].Add(Acre_ID);
|
||||
else
|
||||
NewMainForm.Debug_Manager.WriteLine("Unable to add Acre: " + Acre_ID_String + " | " + Acre_Name, DebugLevel.Error);
|
||||
}
|
||||
}
|
||||
return Filed_List;
|
||||
}
|
||||
|
||||
public static Dictionary<string, Dictionary<ushort, string>> GetFiledAcreDataUInt16(SaveType Save_Type, string Language = "en")
|
||||
{
|
||||
StreamReader Contents = null;
|
||||
string Acre_DB_Location = NewMainForm.Assembly_Location + "\\Resources\\";
|
||||
if (Save_Type == SaveType.Animal_Crossing)
|
||||
Acre_DB_Location += "AC_Acres_" + Language + ".txt";
|
||||
else if (Save_Type == SaveType.City_Folk)
|
||||
Acre_DB_Location += "CF_Acres_" + Language + ".txt";
|
||||
else if (Save_Type == SaveType.New_Leaf)
|
||||
Acre_DB_Location += "NL_Acres_" + Language + ".txt";
|
||||
else if (Save_Type == SaveType.Welcome_Amiibo)
|
||||
Acre_DB_Location += "WA_Acres_" + Language + ".txt";
|
||||
try { Contents = File.OpenText(Acre_DB_Location); }
|
||||
catch (Exception e)
|
||||
{
|
||||
NewMainForm.Debug_Manager.WriteLine(string.Format("An error occured opening acre database file:\n\"{0}\"\nError Info:\n{1}", Acre_DB_Location, e.Message), DebugLevel.Error);
|
||||
return null;
|
||||
}
|
||||
Dictionary<string, Dictionary<ushort, string>> Filed_List = new Dictionary<string, Dictionary<ushort, string>>();
|
||||
string Line;
|
||||
string Current_Acre_Type = "Unsorted";
|
||||
while ((Line = Contents.ReadLine()) != null)
|
||||
{
|
||||
if (Line.Contains("//"))
|
||||
{
|
||||
if (Current_Acre_Type != "Unsorted")
|
||||
{
|
||||
if (!Filed_List.ContainsKey(Current_Acre_Type))
|
||||
Filed_List.Add(Current_Acre_Type, new Dictionary<ushort, string>());
|
||||
}
|
||||
Current_Acre_Type = Line.Replace("//", "");
|
||||
}
|
||||
else if (Line.Contains("0x"))
|
||||
{
|
||||
if (!Filed_List.ContainsKey(Current_Acre_Type))
|
||||
Filed_List.Add(Current_Acre_Type, new Dictionary<ushort, string>());
|
||||
string Acre_ID_String = Line.Substring(0, 6), Acre_Name = Line.Substring(7);
|
||||
if (ushort.TryParse(Acre_ID_String.Replace("0x", ""), NumberStyles.AllowHexSpecifier, null, out ushort Acre_ID))
|
||||
Filed_List[Current_Acre_Type].Add(Acre_ID, Line.Substring(7));
|
||||
else
|
||||
NewMainForm.Debug_Manager.WriteLine("Unable to add Acre: " + Acre_ID_String + " | " + Acre_Name, DebugLevel.Error);
|
||||
}
|
||||
}
|
||||
return Filed_List;
|
||||
}
|
||||
|
||||
public static void GetNibbles(byte Byte_to_Split, out byte Lower_Nibble, out byte Upper_Nibble)
|
||||
{
|
||||
Lower_Nibble = (byte)(Byte_to_Split & 0x0F);
|
||||
Upper_Nibble = (byte)((Byte_to_Split & 0xF0) >> 4);
|
||||
}
|
||||
|
||||
public static byte CondenseNibbles(byte Lower_Nibble, byte Upper_Nibble)
|
||||
{
|
||||
return (byte)(((Upper_Nibble & 0x0F) >> 4) + Lower_Nibble & 0x0F);
|
||||
}
|
||||
}
|
||||
|
||||
public class Save
|
||||
{
|
||||
public SaveType Save_Type;
|
||||
public byte[] Original_Save_Data;
|
||||
public byte[] Working_Save_Data;
|
||||
public int Save_Data_Start_Offset;
|
||||
public string Save_Path;
|
||||
public string Save_Name;
|
||||
public string Save_Extension;
|
||||
public string Save_ID;
|
||||
public bool Is_Big_Endian = true;
|
||||
private FileStream Save_File;
|
||||
private BinaryReader Save_Reader;
|
||||
private BinaryWriter Save_Writer;
|
||||
|
||||
public Save(string File_Path)
|
||||
{
|
||||
if (File.Exists(File_Path))
|
||||
{
|
||||
if (Save_File != null)
|
||||
{
|
||||
Save_Reader.Close();
|
||||
Save_File.Close();
|
||||
}
|
||||
bool Failed_to_Load = false;
|
||||
try { Save_File = new FileStream(File_Path, FileMode.Open); } catch { Failed_to_Load = true; }
|
||||
if (Save_File == null || Failed_to_Load || !Save_File.CanWrite)
|
||||
{
|
||||
MessageBox.Show(string.Format("Error: File {0} is being used by another process. Please close any process using it before editing!",
|
||||
Path.GetFileName(File_Path)), "File Opening Error");
|
||||
try { Save_File.Close(); } catch { };
|
||||
return;
|
||||
}
|
||||
|
||||
Save_Reader = new BinaryReader(Save_File);
|
||||
|
||||
Original_Save_Data = Save_Type == SaveType.Doubutsu_no_Mori ? SaveDataManager.ByteSwap(Save_Reader.ReadBytes((int)Save_File.Length)) : Save_Reader.ReadBytes((int)Save_File.Length);
|
||||
Working_Save_Data = new byte[Original_Save_Data.Length];
|
||||
Buffer.BlockCopy(Original_Save_Data, 0, Working_Save_Data, 0, Original_Save_Data.Length);
|
||||
|
||||
Save_Type = SaveDataManager.GetSaveType(Original_Save_Data);
|
||||
Save_Name = Path.GetFileNameWithoutExtension(File_Path);
|
||||
Save_Path = Path.GetDirectoryName(File_Path) + Path.DirectorySeparatorChar;
|
||||
Save_Extension = Path.GetExtension(File_Path);
|
||||
Save_ID = SaveDataManager.GetGameID(Save_Type);
|
||||
Save_Data_Start_Offset = SaveDataManager.GetSaveDataOffset(Save_ID.ToLower(), Save_Extension.Replace(".", "").ToLower());
|
||||
|
||||
if (Save_Type == SaveType.Wild_World || Save_Type == SaveType.New_Leaf || Save_Type == SaveType.Welcome_Amiibo)
|
||||
Is_Big_Endian = false;
|
||||
|
||||
Save_Reader.Close();
|
||||
Save_File.Close();
|
||||
}
|
||||
else
|
||||
MessageBox.Show("File doesn't exist!");
|
||||
}
|
||||
|
||||
public void Flush()
|
||||
{
|
||||
string Full_Save_Name = Save_Path + Path.DirectorySeparatorChar + Save_Name + Save_Extension;
|
||||
Save_File = new FileStream(Full_Save_Name, FileMode.OpenOrCreate);
|
||||
Save_Writer = new BinaryWriter(Save_File);
|
||||
if (Save_Type == SaveType.Animal_Crossing)
|
||||
{
|
||||
Write(Save_Data_Start_Offset + 0x12, Checksum.Calculate(Working_Save_Data.Skip(Save_Data_Start_Offset).Take(0x26000).ToArray(), 0x12), true);
|
||||
Working_Save_Data.Skip(Save_Data_Start_Offset).Take(0x26000).ToArray().CopyTo(Working_Save_Data, Save_Data_Start_Offset + 0x26000); //Update second save copy
|
||||
}
|
||||
else if (Save_Type == SaveType.Wild_World)
|
||||
{
|
||||
Write(Save_Data_Start_Offset + 0x15FDC, Checksum.Calculate(Working_Save_Data.Skip(Save_Data_Start_Offset).Take(0x15FE0).ToArray(),
|
||||
0x15FDC, true));
|
||||
Working_Save_Data.Skip(Save_Data_Start_Offset).Take(0x15FE0).ToArray().CopyTo(Working_Save_Data, Save_Data_Start_Offset + 0x15FE0); //Update both save copies on WW
|
||||
}
|
||||
else if (Save_Type == SaveType.City_Folk)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int Player_Data_Offset = Save_Data_Start_Offset + i * 0x86C0 + 0x1140;
|
||||
uint Player_CRC32 = CRC32.GetCRC32(Working_Save_Data.Skip(Player_Data_Offset + 4).Take(0x759C).ToArray());
|
||||
Write(Player_Data_Offset, Player_CRC32, true);
|
||||
}
|
||||
Write(Save_Data_Start_Offset + 0x5EC60, CRC32.GetCRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x5EC64).Take(0x1497C).ToArray()), true);
|
||||
Write(Save_Data_Start_Offset + 0x5EB04, CRC32.GetCRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x5EB08).Take(0x152).ToArray(), 0x12141018), true);
|
||||
Write(Save_Data_Start_Offset + 0x73600, CRC32.GetCRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x73604).Take(0x19BD1C).ToArray()), true);
|
||||
Write(Save_Data_Start_Offset, CRC32.GetCRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 4).Take(0x1C).ToArray()), true);
|
||||
Write(Save_Data_Start_Offset + 0x20, CRC32.GetCRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x24).Take(0x111C).ToArray()), true);
|
||||
}
|
||||
else if (Save_Type == SaveType.New_Leaf)
|
||||
{
|
||||
Write(Save_Data_Start_Offset, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 4).Take(0x1C).ToArray()));
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int DataOffset = Save_Data_Start_Offset + 0x20 + i * 0x9F10;
|
||||
Write(DataOffset, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(DataOffset + 4).Take(0x6B64).ToArray()));
|
||||
int DataOffset2 = Save_Data_Start_Offset + 0x20 + 0x6B68 + i * 0x9F10;
|
||||
Write(DataOffset2, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(DataOffset2 + 4).Take(0x33A4).ToArray()));
|
||||
|
||||
}
|
||||
Write(Save_Data_Start_Offset + 0x27C60, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x27C60 + 4).Take(0x218B0).ToArray()));
|
||||
Write(Save_Data_Start_Offset + 0x49520, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x49520 + 4).Take(0x44B8).ToArray()));
|
||||
Write(Save_Data_Start_Offset + 0x4D9DC, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x4D9DC + 4).Take(0x1E420).ToArray()));
|
||||
Write(Save_Data_Start_Offset + 0x6BE00, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x6BE00 + 4).Take(0x20).ToArray()));
|
||||
Write(Save_Data_Start_Offset + 0x6BE24, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x6BE24 + 4).Take(0x13AF8).ToArray()));
|
||||
}
|
||||
else if (Save_Type == SaveType.Welcome_Amiibo)
|
||||
{
|
||||
Write(Save_Data_Start_Offset, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 4).Take(0x1C).ToArray()));
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int DataOffset = Save_Data_Start_Offset + 0x20 + i * 0xA480;
|
||||
Write(DataOffset, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(DataOffset + 4).Take(0x6B84).ToArray()));
|
||||
int DataOffset2 = Save_Data_Start_Offset + 0x20 + 0x6B88 + i * 0xA480;
|
||||
Write(DataOffset2, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(DataOffset2 + 4).Take(0x38F4).ToArray()));
|
||||
}
|
||||
Write(Save_Data_Start_Offset + 0x29220, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x29220 + 4).Take(0x22BC8).ToArray()));
|
||||
Write(Save_Data_Start_Offset + 0x4BE00, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x4BE00 + 4).Take(0x44B8).ToArray()));
|
||||
Write(Save_Data_Start_Offset + 0x533A4, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x533A4 + 4).Take(0x1E4D8).ToArray()));
|
||||
Write(Save_Data_Start_Offset + 0x71880, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x71880 + 4).Take(0x20).ToArray()));
|
||||
Write(Save_Data_Start_Offset + 0x718A4, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x718A4 + 4).Take(0xBE4).ToArray()));
|
||||
Write(Save_Data_Start_Offset + 0x738D4, NL_CRC32.Calculate_CRC32(Working_Save_Data.Skip(Save_Data_Start_Offset + 0x738D4 + 4).Take(0x16188).ToArray()));
|
||||
}
|
||||
Save_Writer.Write(Save_Type == SaveType.Doubutsu_no_Mori ? SaveDataManager.ByteSwap(Working_Save_Data) : Working_Save_Data); //Doubutsu no Mori is dword byteswapped
|
||||
Save_Writer.Flush();
|
||||
Save_File.Flush();
|
||||
|
||||
Save_Writer.Close();
|
||||
Save_File.Close();
|
||||
}
|
||||
|
||||
public void Write(int offset, dynamic data, bool reversed = false, int stringLength = 0)
|
||||
{
|
||||
Type Data_Type = data.GetType();
|
||||
NewMainForm.Debug_Manager.WriteLine(string.Format("Writing Data{2} of type {0} to offset {1}", Data_Type.Name, "0x" + offset.ToString("X"), //recasting a value shows it as original type?
|
||||
Data_Type.IsArray ? "" : " with value 0x" + (data.ToString("X"))), DebugLevel.Debug);
|
||||
if (!Data_Type.IsArray)
|
||||
{
|
||||
if (Data_Type == typeof(byte))
|
||||
Working_Save_Data[offset] = (byte)data;
|
||||
else if (Data_Type == typeof(string))
|
||||
{
|
||||
byte[] String_Byte_Buff = ACString.GetBytes((string)data, stringLength);
|
||||
Buffer.BlockCopy(String_Byte_Buff, 0, Working_Save_Data, offset, String_Byte_Buff.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] Byte_Array = BitConverter.GetBytes(data);
|
||||
if (reversed)
|
||||
Array.Reverse(Byte_Array);
|
||||
Buffer.BlockCopy(Byte_Array, 0, Working_Save_Data, offset, Byte_Array.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dynamic Data_Array = data;
|
||||
if (Data_Type == typeof(byte[]))
|
||||
for (int i = 0; i < Data_Array.Length; i++)
|
||||
Working_Save_Data[offset + i] = Data_Array[i];
|
||||
else
|
||||
{
|
||||
int Data_Size = Marshal.SizeOf(Data_Array[0]);
|
||||
for (int i = 0; i < Data_Array.Length; i++)
|
||||
{
|
||||
byte[] Byte_Array = BitConverter.GetBytes(Data_Array[i]);
|
||||
if (reversed)
|
||||
Array.Reverse(Byte_Array);
|
||||
Byte_Array.CopyTo(Working_Save_Data, offset + i * Data_Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Used for replacing instances of player/town names. Possibly other uses?
|
||||
public void FindAndReplaceByteArray(int end, byte[] oldarr, byte[] newarr)
|
||||
{
|
||||
for (int i = Save_Data_Start_Offset; i < Save_Data_Start_Offset + end; i += 2) //Every? dword or larger is aligned
|
||||
{
|
||||
if (Enumerable.SequenceEqual(ReadByteArray(i, oldarr.Length), oldarr))
|
||||
{
|
||||
MessageBox.Show("Match found at offset: 0x" + i.ToString("X"));
|
||||
Write(i, newarr, Is_Big_Endian);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte ReadByte(int offset)
|
||||
{
|
||||
return Working_Save_Data[offset];
|
||||
}
|
||||
|
||||
public byte[] ReadByteArray(int offset, int count, bool reversed = false)
|
||||
{
|
||||
byte[] Data = new byte[count];
|
||||
Buffer.BlockCopy(Working_Save_Data, offset, Data, 0, count);
|
||||
if (reversed)
|
||||
Array.Reverse(Data);
|
||||
return Data;
|
||||
}
|
||||
|
||||
public ushort ReadUInt16(int offset, bool reversed = false)
|
||||
{
|
||||
return BitConverter.ToUInt16(ReadByteArray(offset, 2, reversed), 0);
|
||||
}
|
||||
|
||||
public ushort[] ReadUInt16Array(int offset, int count, bool reversed = false)
|
||||
{
|
||||
ushort[] Returned_Values = new ushort[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
Returned_Values[i] = ReadUInt16(offset + i * 2, reversed);
|
||||
return Returned_Values;
|
||||
}
|
||||
|
||||
public uint ReadUInt32(int offset, bool reversed = false)
|
||||
{
|
||||
return BitConverter.ToUInt32(ReadByteArray(offset, 4, reversed), 0);
|
||||
}
|
||||
|
||||
public uint[] ReadUInt32Array(int offset, int count, bool reversed = false)
|
||||
{
|
||||
uint[] Returned_Values = new uint[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
Returned_Values[i] = ReadUInt32(offset + i * 4, reversed);
|
||||
return Returned_Values;
|
||||
}
|
||||
|
||||
public ulong ReadUInt64(int offset, bool reversed = false)
|
||||
{
|
||||
return BitConverter.ToUInt64(ReadByteArray(offset, 8, reversed), 0);
|
||||
}
|
||||
|
||||
public string ReadString(int offset, int length)
|
||||
{
|
||||
return new ACString(ReadByteArray(offset, length), Save_Type).Trim();
|
||||
}
|
||||
|
||||
public string[] ReadStringArray(int offset, int length, int count) //Only useful for strings of matching lengths, possibly "fix" this in the future
|
||||
{
|
||||
string[] String_Array = new string[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
String_Array[i] = ReadString(offset + i * length, length);
|
||||
return String_Array;
|
||||
}
|
||||
|
||||
public string[] ReadStringArrayWithVariedLengths(int offset, int count, byte endCharByte, int maxLength = 10) // ^^ Fixed it ^^
|
||||
{
|
||||
string[] String_Array = new string[count];
|
||||
int lastOffset = 0;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
byte lastChar = 0;
|
||||
int idx = 0;
|
||||
while (lastChar != endCharByte && idx < maxLength)
|
||||
{
|
||||
lastChar = ReadByte(offset + lastOffset + idx);
|
||||
idx++;
|
||||
}
|
||||
String_Array[i] = ReadString(offset + lastOffset, idx);
|
||||
lastOffset += idx;
|
||||
}
|
||||
return String_Array;
|
||||
}
|
||||
}
|
||||
}
|
362
Classes/StringUtil.cs
Normal file
|
@ -0,0 +1,362 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
public static class StringUtil
|
||||
{
|
||||
public static readonly Dictionary<byte, string> AC_CharacterDictionary = new Dictionary<byte, string>()
|
||||
{
|
||||
{0x90, "–" },
|
||||
{0xCD, "\n" },
|
||||
{0x2A, "~" },
|
||||
{0xD0, ";" },
|
||||
{0xD4, "⚷" },
|
||||
{0xD1, "#" },
|
||||
{0x85, "•" },
|
||||
{0xA2, "Æ" },
|
||||
{0xA0, "¯" },
|
||||
{0xAE, "/" },
|
||||
{0x97, "¦" },
|
||||
{0xC0, "×" },
|
||||
{0xC1, "÷" },
|
||||
{0xA5, "»" },
|
||||
{0xA6, "«" },
|
||||
{0xAC, "∋" },
|
||||
{0xAD, "∈" },
|
||||
{0xB4, "+" },
|
||||
{0x1D, "ß" },
|
||||
{0x1E, "Þ" },
|
||||
{0x86, "ð" },
|
||||
{0x98, "§" },
|
||||
{0x9B, "‖" },
|
||||
{0x9C, "µ" },
|
||||
{0xA1, "¬" },
|
||||
{0x2B, "♥" },
|
||||
{0xB9, "★" },
|
||||
{0x2F, "♪" },
|
||||
{0x3B, "🌢" },
|
||||
{0x5C, "💢" },
|
||||
{0xB8, "🍀"},
|
||||
{0xC6, "🐾" },
|
||||
{0xB6, "♂" },
|
||||
{0xB7, "♀" },
|
||||
{0xAF, "∞" },
|
||||
{0xB0, "○" },
|
||||
{0xB1, "🗙" },
|
||||
{0xB2, "□" },
|
||||
{0xB3, "△" },
|
||||
{0xBA, "💀" },
|
||||
{0xBB, "😮" },
|
||||
{0xBC, "😄" },
|
||||
{0xBD, "😣" },
|
||||
{0xBE, "😠" },
|
||||
{0xBF, "😃" },
|
||||
{0xA7, "☀" },
|
||||
{0xA8, "☁" },
|
||||
{0xA9, "☂" },
|
||||
{0xAB, "☃" },
|
||||
{0xAA, "🌬" }, //Wind...
|
||||
{0xB5, "⚡" },
|
||||
{0xC2, "🔨" }, //Hammer??
|
||||
{0xC3, "🎀" }, //Not sure wtf this is (put it as ribbon)
|
||||
{0xC4, "✉" },
|
||||
{0xC7, "🐶" },
|
||||
{0xC8, "🐱" },
|
||||
{0xC9, "🐰" },
|
||||
{0xCA, "🐦" },
|
||||
{0xCB, "🐮" },
|
||||
{0xCC, "🐷" },
|
||||
{0xC5, "💰" },
|
||||
{0xCE, "🐟" },
|
||||
{0xCF, "🐞" },
|
||||
{0x7B, "è" },
|
||||
{0x7C, "é" },
|
||||
{0x7D, "ê" },
|
||||
{0x7E, "ë" },
|
||||
{0x93, "ý" },
|
||||
{0x94, "ÿ" },
|
||||
{0x8E, "ù" },
|
||||
{0x8F, "ú" },
|
||||
{0x91, "û" },
|
||||
{0x92, "ü" },
|
||||
{0x81, "ì" },
|
||||
{0x82, "í" },
|
||||
{0x83, "î" },
|
||||
{0x84, "ï" },
|
||||
{0x88, "ò" },
|
||||
{0x89, "ó" },
|
||||
{0x8A, "ô" },
|
||||
{0x8B, "õ" },
|
||||
{0x8C, "ö" },
|
||||
{0x1F, "à" },
|
||||
{0x23, "á" },
|
||||
{0x24, "â" },
|
||||
{0x5B, "ã" },
|
||||
{0x5D, "ä" },
|
||||
{0x5E, "å" },
|
||||
{0x09, "È" },
|
||||
{0x0A, "É" },
|
||||
{0x0B, "Ê" },
|
||||
{0x0C, "Ë" },
|
||||
{0x96, "Ý" },
|
||||
{0x19, "Ù" },
|
||||
{0x1A, "Ú" },
|
||||
{0x1B, "Û" },
|
||||
{0x1C, "Ü" },
|
||||
{0x0D, "Ì" },
|
||||
{0x0E, "Í" },
|
||||
{0x0F, "Î" },
|
||||
{0x10, "Ï" },
|
||||
{0x13, "Ò" },
|
||||
{0x14, "Ó" },
|
||||
{0x15, "Ô" },
|
||||
{0x16, "Õ" },
|
||||
{0x17, "Ö" },
|
||||
{0x02, "Ä" },
|
||||
{0x03, "À" },
|
||||
{0x04, "Á" },
|
||||
{0x05, "Â" },
|
||||
{0x06, "Ã" },
|
||||
{0x07, "Å" },
|
||||
{0x11, "Ð" },
|
||||
{0x08, "Ç" },
|
||||
{0x12, "Ñ" },
|
||||
{0x87, "ñ" },
|
||||
{0x60, "ç" },
|
||||
{0x95, "þ" },
|
||||
{0x01, "¿" },
|
||||
{0xA4, "„" },
|
||||
{0xA3, "æ" }
|
||||
};
|
||||
|
||||
public static readonly Dictionary<byte, string> WW_CharacterDictionary = new Dictionary<byte, string>()
|
||||
{
|
||||
{ 0x41, "Œ"},
|
||||
{ 0x44, "œ"},
|
||||
{ 0x47, "À"},
|
||||
{ 0x48, "Á"},
|
||||
{ 0x49, "Â"},
|
||||
{ 0x4B, "Ä"},
|
||||
{ 0x4E, "Ç"},
|
||||
{ 0x4F, "È"},
|
||||
{ 0x50, "É"},
|
||||
{ 0x51, "Ê"},
|
||||
{ 0x52, "Ë"},
|
||||
{ 0x53, "Ì"},
|
||||
{ 0x54, "Í"},
|
||||
{ 0x55, "Î"},
|
||||
{ 0x56, "Ï"},
|
||||
{ 0x58, "Ñ"},
|
||||
{ 0x59, "Ò"},
|
||||
{ 0x5A, "Ó"},
|
||||
{ 0x5B, "Ô"},
|
||||
{ 0x5D, "Ö"},
|
||||
{ 0x5F, "Ù"},
|
||||
{ 0x60, "Ú"},
|
||||
{ 0x61, "Û"},
|
||||
{ 0x62, "Ü"},
|
||||
{ 0x65, "ß"},
|
||||
{ 0x66, "à"},
|
||||
{ 0x67, "á"},
|
||||
{ 0x68, "â"},
|
||||
{ 0x6A, "ä"},
|
||||
{ 0x6D, "ç"},
|
||||
{ 0x6E, "è"},
|
||||
{ 0x6F, "é"},
|
||||
{ 0x70, "ê"},
|
||||
{ 0x71, "ë"},
|
||||
{ 0x72, "ì"},
|
||||
{ 0x73, "í"},
|
||||
{ 0x74, "î"},
|
||||
{ 0x75, "ï"},
|
||||
{ 0x77, "ñ"},
|
||||
{ 0x78, "ò"},
|
||||
{ 0x79, "ó"},
|
||||
{ 0x7A, "ô"},
|
||||
{ 0x7C, "ö"},
|
||||
{ 0x7E, "ù"},
|
||||
{ 0x7F, "ú"},
|
||||
{ 0x80, "û"},
|
||||
{ 0x81, "ü"},
|
||||
{ 0x85, " "}, // "(space)"
|
||||
{ 0x86, " "}, //breaking space
|
||||
{ 0x87, "!" },
|
||||
//{ 0x87, "\n"},
|
||||
{ 0x8C, "&" },
|
||||
{ 0x8D, "\"" }, // single quote
|
||||
{ 0x8E, "(" },
|
||||
{ 0x8F, ")" },
|
||||
{ 0x91, "+" },
|
||||
{ 0x92, "," },
|
||||
{ 0x93, "-" },
|
||||
{ 0x94, "." },
|
||||
{ 0x96, ":" },
|
||||
{ 0x97, ";" },
|
||||
{ 0x98, "<" },
|
||||
{ 0x99, "=" },
|
||||
{ 0x9A, ">" },
|
||||
{ 0x9B, "?" },
|
||||
{ 0x9C, "@" },
|
||||
{ 0x9D, "[" },
|
||||
{ 0x9F, "]" },
|
||||
{ 0xA1, "_" },
|
||||
{ 0xA6, "~" },
|
||||
{ 0xA7, "€"},
|
||||
{ 0xB1, "'" },
|
||||
{ 0xB3, "\"" },
|
||||
{ 0xBB, "¡"}, //(i)??
|
||||
{ 0xBC, "¢"},
|
||||
{ 0xBD, "£"},
|
||||
{ 0xD1, "•"},
|
||||
{ 0xD9, "¿"},
|
||||
{ 0xDA, "×"},
|
||||
{ 0xDB, "÷"},
|
||||
{ 0xDC, "💧"},
|
||||
{ 0xDD, "★"},
|
||||
{ 0xDE, "❤"},
|
||||
{ 0xDF, "♪"},
|
||||
};
|
||||
|
||||
public static int StringToMaxChars(string s)
|
||||
{
|
||||
TextElementEnumerator t = StringInfo.GetTextElementEnumerator(s);
|
||||
int size = 0;
|
||||
int chars = 0;
|
||||
while (t.MoveNext())
|
||||
{
|
||||
chars++;
|
||||
size += Encoding.UTF8.GetBytes(((string)(t.Current)).ToCharArray()).Length;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public static byte[] Fix_Wild_World_String(byte[] mangled_String_Bytes)
|
||||
{
|
||||
byte[] Fixed_String_Bytes = new byte[mangled_String_Bytes.Length];
|
||||
for (int i = 0; i < mangled_String_Bytes.Length; i++)
|
||||
{
|
||||
byte Mangled_Char = mangled_String_Bytes[i];
|
||||
if (Mangled_Char > 0 && Mangled_Char <= 0x1A)
|
||||
Fixed_String_Bytes[i] = (byte)(Mangled_Char + 0x40);
|
||||
else if (Mangled_Char >= 0x1B && Mangled_Char <= 0x34)
|
||||
Fixed_String_Bytes[i] = (byte)(Mangled_Char + 0x46);
|
||||
else if (Mangled_Char >= 0x35 && Mangled_Char <= 0x3E)
|
||||
Fixed_String_Bytes[i] = (byte)(Mangled_Char - 0x5); //Char - 0x35 + 0x30 (0)
|
||||
}
|
||||
return Fixed_String_Bytes;
|
||||
}
|
||||
|
||||
public static byte[] To_Wild_World_String(byte[] string_Bytes)
|
||||
{
|
||||
byte[] WW_String_Bytes = new byte[string_Bytes.Length];
|
||||
for (int i = 0; i < WW_String_Bytes.Length; i++)
|
||||
{
|
||||
byte Char = string_Bytes[i];
|
||||
if (Char > 0x40 && Char <= 0x5A)
|
||||
WW_String_Bytes[i] = (byte)(Char - 0x40);
|
||||
else if (Char >= 0x61 && Char <= 0x7A)
|
||||
WW_String_Bytes[i] = (byte)(Char - 0x46);
|
||||
else if (Char >= 0x30 && Char <= 0x39)
|
||||
WW_String_Bytes[i] = (byte)(Char + 0x5);
|
||||
else if (WW_CharacterDictionary.Values.Contains(Encoding.ASCII.GetString(new byte[1] { Char })))
|
||||
WW_String_Bytes[i] = WW_CharacterDictionary.First(x => x.Value == Encoding.ASCII.GetString(new byte[1] { Char })).Key;
|
||||
}
|
||||
return WW_String_Bytes;
|
||||
}
|
||||
}
|
||||
|
||||
public class ACString
|
||||
{
|
||||
byte[] String_Bytes;
|
||||
static SaveType Save_Type; //This won't be changing during our save, so a static cast is fine
|
||||
public string String = "";
|
||||
static Dictionary<byte, string> Char_Dictionary;
|
||||
|
||||
public ACString(byte[] stringBuffer, SaveType saveType = SaveType.Animal_Crossing)
|
||||
{
|
||||
Save_Type = saveType;
|
||||
String_Bytes = stringBuffer;
|
||||
Char_Dictionary = saveType == SaveType.Animal_Crossing ? StringUtil.AC_CharacterDictionary
|
||||
: (saveType == SaveType.Wild_World ? StringUtil.WW_CharacterDictionary : null);
|
||||
if (saveType == SaveType.Animal_Crossing || saveType == SaveType.Wild_World)
|
||||
foreach (byte b in stringBuffer)
|
||||
if (Char_Dictionary != null && Char_Dictionary.ContainsKey(b))
|
||||
String += Char_Dictionary[b];
|
||||
else
|
||||
String += Encoding.UTF8.GetString(saveType == SaveType.Wild_World ? StringUtil.Fix_Wild_World_String(new byte[1] { b }) : new byte[1] { b });
|
||||
else if (saveType == SaveType.City_Folk)
|
||||
for (int i = 0; i < stringBuffer.Length; i += 2)
|
||||
String += Encoding.Unicode.GetString(stringBuffer.Skip(i).Take(2).Reverse().ToArray());
|
||||
else if (saveType == SaveType.New_Leaf || saveType == SaveType.Welcome_Amiibo)
|
||||
{
|
||||
String = Encoding.Unicode.GetString(stringBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] GetBytes(string String, int maxSize = 0)
|
||||
{
|
||||
if (Save_Type == SaveType.Animal_Crossing)
|
||||
{
|
||||
byte[] returnedString = new byte[maxSize > 0 ? maxSize : String.Length];
|
||||
TextElementEnumerator t = StringInfo.GetTextElementEnumerator(String);
|
||||
int i = 0;
|
||||
while (t.MoveNext() && i < returnedString.Length)
|
||||
{
|
||||
if (Char_Dictionary.ContainsValue((string)t.Current))
|
||||
returnedString[i] = Char_Dictionary.FirstOrDefault(o => o.Value == (string)t.Current).Key;
|
||||
else
|
||||
returnedString[i] = Encoding.UTF8.GetBytes(new char[1] { String[t.ElementIndex] })[0];
|
||||
i++;
|
||||
}
|
||||
for (int x = 0; x < returnedString.Length; x++)
|
||||
if (returnedString[x] == 0)
|
||||
returnedString[x] = 0x20;
|
||||
return returnedString;
|
||||
}
|
||||
else if (Save_Type == SaveType.Wild_World)
|
||||
{
|
||||
byte[] String_Buffer = StringUtil.To_Wild_World_String(Encoding.UTF8.GetBytes(String));
|
||||
if (maxSize > 0)
|
||||
Array.Resize(ref String_Buffer, maxSize);
|
||||
return String_Buffer;
|
||||
}
|
||||
else if (Save_Type == SaveType.City_Folk)
|
||||
{
|
||||
byte[] String_Buffer = new byte[maxSize > 0 ? maxSize : String.Length * 2]; //Characters are now unicode
|
||||
byte[] String_Bytes = Encoding.Unicode.GetBytes(String);
|
||||
for (int i = 0; i < String_Bytes.Length; i+=2)
|
||||
Buffer.BlockCopy(String_Bytes.Skip(i).Take(2).Reverse().ToArray(), 0, String_Buffer, i, 2);
|
||||
return String_Buffer;
|
||||
}
|
||||
else if (Save_Type == SaveType.New_Leaf || Save_Type == SaveType.Welcome_Amiibo)
|
||||
{
|
||||
byte[] String_Buffer = Encoding.Unicode.GetBytes(String);
|
||||
if (maxSize > 0)
|
||||
Array.Resize(ref String_Buffer, maxSize);
|
||||
return String_Buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
NewMainForm.Debug_Manager.WriteLine(string.Format("StringUtil was passed an unknown SaveType enum. Received Type: {0}", Save_Type.ToString()), DebugLevel.Error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string Trim()
|
||||
{
|
||||
return String.Trim(' ');
|
||||
}
|
||||
|
||||
public string Clean()
|
||||
{
|
||||
string Cleaned_String = Regex.Replace(String, "[\n]{3,}", "\n\n");
|
||||
return Regex.Replace(Cleaned_String.Trim(' '), "[ ]{2,}", " ");
|
||||
}
|
||||
}
|
||||
}
|
23
Classes/Utility.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
public static class Utility
|
||||
{
|
||||
public static void Scan_For_NL_Int32()
|
||||
{
|
||||
if (NewMainForm.Save_File != null && (NewMainForm.Save_File.Save_Type == SaveType.New_Leaf || NewMainForm.Save_File.Save_Type == SaveType.Welcome_Amiibo))
|
||||
{
|
||||
for (int i = 0; i < NewMainForm.Save_File.Working_Save_Data.Length; i += 4)
|
||||
{
|
||||
NL_Int32 Possible_NL_Int32 = new NL_Int32(NewMainForm.Save_File.ReadUInt32(i), NewMainForm.Save_File.ReadUInt32(i + 4));
|
||||
if (Possible_NL_Int32.Valid)
|
||||
System.Windows.Forms.MessageBox.Show(string.Format("Found Valid NL_Int32 at offset 0x{0} | Value: {1}", i.ToString("X"), Possible_NL_Int32.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
736
Classes/VillagerData.cs
Normal file
|
@ -0,0 +1,736 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Globalization;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
class VillagerData
|
||||
{
|
||||
public static Dictionary<ushort, string> WA_Special_Villagers = new Dictionary<ushort, string>
|
||||
{
|
||||
{0x1000, "Copper"},
|
||||
{0x1001, "Booker"},
|
||||
{0x1002, "Jingle"},
|
||||
{0x1003, "Jack"},
|
||||
{0x1004, "Zipper"},
|
||||
{0x1005, "Blanca"},
|
||||
{0x1006, "Pavé"},
|
||||
{0x1007, "Chip"},
|
||||
{0x1008, "Nat"},
|
||||
{0x1009, "Franklin"},
|
||||
{0x100A, "Joan"},
|
||||
{0x100B, "Wendell"},
|
||||
{0x100C, "Pascal"},
|
||||
{0x100D, "Gulliver"},
|
||||
{0x100E, "Saharah"},
|
||||
{0x2000, "Isabelle (1)"},
|
||||
{0x2001, "Digby"},
|
||||
{0x2002, "Reese"},
|
||||
{0x2003, "Cyrus"},
|
||||
{0x2004, "Tom Nook"},
|
||||
{0x2005, "Lottie"},
|
||||
{0x2006, "Mabel"},
|
||||
{0x2007, "K.K. Slider"},
|
||||
{0x2008, "Kicks"},
|
||||
{0x2009, "Resetti"},
|
||||
{0x200A, "Celeste"},
|
||||
{0x200B, "Blathers"},
|
||||
{0x200C, "Rover"},
|
||||
{0x200D, "Timmy"},
|
||||
{0x200E, "Kapp'n"},
|
||||
{0x200F, "Wisp"},
|
||||
{0x2010, "Isabelle (2)"}
|
||||
};
|
||||
|
||||
public static BindingSource GetCaravanBindingSource()
|
||||
{
|
||||
Dictionary<ushort, SimpleVillager> WA_Database = VillagerInfo.GetVillagerDatabase(SaveType.Welcome_Amiibo);
|
||||
if (WA_Database != null)
|
||||
{
|
||||
foreach (var v in WA_Special_Villagers)
|
||||
{
|
||||
SimpleVillager SpecialVillager = new SimpleVillager();
|
||||
SpecialVillager.Villager_ID = v.Key;
|
||||
SpecialVillager.Name = v.Value;
|
||||
WA_Database.Add(v.Key, SpecialVillager);
|
||||
}
|
||||
return new BindingSource(WA_Database, null);
|
||||
}
|
||||
return new BindingSource(WA_Special_Villagers, null);
|
||||
}
|
||||
|
||||
public static Dictionary<ushort, string> Villagers = new Dictionary<ushort, string>()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
public static List<KeyValuePair<ushort, string>> VillagerDatabase = new List<KeyValuePair<ushort, string>>();
|
||||
|
||||
public static void CreateVillagerDatabase()
|
||||
{
|
||||
foreach (KeyValuePair<ushort, string> k in Villagers)
|
||||
VillagerDatabase.Add(k);
|
||||
}
|
||||
|
||||
public static string[] Personalities = new string[6]
|
||||
{
|
||||
"Lazy", "Normal", "Peppy", "Jock", "Cranky", "Snooty"
|
||||
};
|
||||
|
||||
public static string GetVillagerName(ushort villagerId)
|
||||
{
|
||||
if (Villagers.ContainsKey(villagerId))
|
||||
return Villagers[villagerId];
|
||||
return villagerId == 0x0 ? "No Villager" : "Unknown";
|
||||
}
|
||||
|
||||
public static string GetVillagerPersonality(int type)
|
||||
{
|
||||
return type < 6 ? Personalities[type] : "Lazy";
|
||||
}
|
||||
|
||||
public static int GetVillagerPersonalityID(string personality)
|
||||
{
|
||||
return Array.IndexOf(Personalities, personality) > -1 ? Array.IndexOf(Personalities, personality) : 0;
|
||||
}
|
||||
|
||||
public static ushort GetVillagerID(string villagerName)
|
||||
{
|
||||
if (Villagers.ContainsValue(villagerName))
|
||||
return Villagers.FirstOrDefault(x => x.Value == villagerName).Key;
|
||||
return 0xE000;
|
||||
}
|
||||
|
||||
public static ushort GetVillagerIdByIndex(int i)
|
||||
{
|
||||
if (Villagers.Count > i)
|
||||
return Villagers.Keys.ElementAt(i);
|
||||
return 0xE000;
|
||||
}
|
||||
}
|
||||
|
||||
public class Villager
|
||||
{
|
||||
public ushort ID = 0;
|
||||
public ushort TownIdentifier = 0;
|
||||
public string Name = "";
|
||||
public string Personality = "";
|
||||
public byte PersonalityID = 0;
|
||||
public int Index = 0;
|
||||
public string Catchphrase = "";
|
||||
public bool Exists = false;
|
||||
public bool Modified = false;
|
||||
public Item Shirt;
|
||||
public byte[] House_Coords = new byte[4]; //X-Acre, Y-Acre, Y-Position, X-Position - 1 (This is actually the location of their sign, also dictates map location)
|
||||
public Villager_Player_Entry[] Villager_Player_Entries = new Villager_Player_Entry[7];
|
||||
public int Offset = 0;
|
||||
|
||||
public Villager(int idx)
|
||||
{
|
||||
Index = idx;
|
||||
//Offset = Index == 16 ? MainForm.Islander_Offset : MainForm.VillagerData_Offset + (Index - 1) * 0x988;
|
||||
ID = DataConverter.ReadUShort(Offset);
|
||||
TownIdentifier = DataConverter.ReadUShort(Offset + 2);
|
||||
Name = VillagerData.GetVillagerName(ID);
|
||||
PersonalityID = DataConverter.ReadDataRaw(Offset + 0xD, 1)[0];
|
||||
Personality = VillagerData.GetVillagerPersonality(PersonalityID);
|
||||
Catchphrase = DataConverter.ReadString(Offset + 0x89D, 10).Trim();
|
||||
Shirt = new Item(DataConverter.ReadUShort(Offset + 0x8E4));
|
||||
House_Coords = DataConverter.ReadDataRaw(Offset + 0x899, 4); //Could make this WorldCoords class if used for other things
|
||||
//House_Coords[2] = (byte)(House_Coords[2] + 1);
|
||||
//House_Coords[3] = (byte)(House_Coords[3] + 1); //X-Position is the position of the Villager Name Sign, which is to the left of the house object, so we add one.
|
||||
Exists = ID != 0x0000 && ID != 0xFFFF;
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
int Entry_Offset = Offset + 0x10 + (i * 0x138); //Offset + 16 data bytes + entrynum * entrysize
|
||||
uint Player_ID = DataConverter.ReadUInt(Entry_Offset + 0x10);
|
||||
if (Player_ID < 0xFFFFFFFF && Player_ID >= 0xF0000000)
|
||||
Villager_Player_Entries[i] = new Villager_Player_Entry(DataConverter.ReadDataRaw(Entry_Offset, 0x138), Entry_Offset);
|
||||
}
|
||||
}
|
||||
|
||||
public void Write()
|
||||
{
|
||||
//House_Coords[2] = (byte)(House_Coords[2] - 1);
|
||||
//House_Coords[3] = (byte)(House_Coords[3] - 1);
|
||||
DataConverter.Write(Offset, ID);
|
||||
DataConverter.Write(Offset + 2, TownIdentifier);
|
||||
//DataConverter.WriteString(Offset + 4, DataConverter.ReadString(MainForm.Town_Name_Offset, 8).Trim(), 8); //Set town name
|
||||
DataConverter.WriteByte(Offset + 0xC, Index == 16 ? (byte)0xFF : (byte)(ID & 0x00FF)); //Normally same as villager identifier, but is 0xFF for islanders. This is likely the byte for what AI the villager will use.
|
||||
DataConverter.WriteByte(Offset + 0xD, PersonalityID);
|
||||
DataConverter.WriteString(Offset + 0x89D, Catchphrase, 10);
|
||||
DataConverter.WriteByteArray(Offset + 0x899, House_Coords, false);
|
||||
if (Shirt != null)
|
||||
DataConverter.Write(Offset + 0x8E4, Shirt.ItemID);
|
||||
if (!Exists && Modified)
|
||||
{
|
||||
DataConverter.WriteByteArray(Offset + 0x8EB, new byte[] { 0xFF, 0x01 }, false); //This byte might be the met flag. Setting it just in case
|
||||
Exists = true;
|
||||
if (Index < 16)
|
||||
Add_House();
|
||||
}
|
||||
foreach (Villager_Player_Entry Entry in Villager_Player_Entries)
|
||||
if (Entry != null && Entry.Exists)
|
||||
Entry.Write(); //Update Player Entries
|
||||
Modified = false;
|
||||
//Second byte here is always a random number. This could be responsible for the Villager's AI, but I'm not sure. Just writing it for good measure.
|
||||
//If the Villager's house location is out of bounds, (or just left 0xFFFF) the game will pick a random signboard as the new house location and write it on load.
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
if (Index < 16) //Don't delete islander
|
||||
{
|
||||
//if (Properties.Settings.Default.ModifyVillagerHouse)
|
||||
//Remove_House();
|
||||
ID = 0;
|
||||
TownIdentifier = 0xFFFF;
|
||||
PersonalityID = 6;
|
||||
Catchphrase = "";
|
||||
House_Coords = new byte[4] { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
Shirt = new Item(0);
|
||||
Exists = false;
|
||||
Modified = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Remove_House()
|
||||
{
|
||||
ushort House_ID = BitConverter.ToUInt16(new byte[] { (byte)(ID & 0x00FF), 0x50 }, 0);
|
||||
/*ushort[] World_Buffer = DataConverter.ReadUShortArray(MainForm.AcreData_Offset, MainForm.AcreData_Size / 2);
|
||||
for (int i = 0; i < World_Buffer.Length; i++)
|
||||
{
|
||||
if (World_Buffer[i] == House_ID)
|
||||
{
|
||||
for (int x = i - 17; x < i - 14; x++) //First Row
|
||||
World_Buffer[x] = 0;
|
||||
for (int x = i - 1; x < i + 2; x++) //Middle Row
|
||||
World_Buffer[x] = 0;
|
||||
for (int x = i + 15; x < i + 18; x++) //Final Row
|
||||
World_Buffer[x] = 0;
|
||||
World_Buffer[i] = BitConverter.ToUInt16(new byte[] { (byte)(new Random().Next(0x10, 0x25)), 0x58 }, 0); //New Signboard to replace house
|
||||
//This is akin to actual game behavior
|
||||
}
|
||||
}*/
|
||||
//DataConverter.Write(MainForm.AcreData_Offset, World_Buffer);
|
||||
}
|
||||
|
||||
public void Add_House()
|
||||
{
|
||||
ushort House_ID = BitConverter.ToUInt16(new byte[] { (byte)(ID & 0x00FF), 0x50 }, 0);
|
||||
/*ushort[] World_Buffer = DataConverter.ReadUShortArray(MainForm.AcreData_Offset, MainForm.AcreData_Size / 2);
|
||||
if (House_Coords[0] > 5 || House_Coords[1] > 6 || House_Coords[2] > 15 || House_Coords[3] > 15) //Houses can't be on edge of acres
|
||||
return;
|
||||
int Position = (House_Coords[0] - 1) * 256 + (House_Coords[1] - 1) * 1280 + (House_Coords[2]) + (House_Coords[3] - 1) * 16; //X Acre + Y Acre + X Pos + Y Pos
|
||||
if (Position > 0x1E00) //7,680 item spots per town (minus island acres) (5 * 6 * 16^2)
|
||||
return;
|
||||
for (int x = Position - 17; x < Position - 14; x++) //First Row
|
||||
World_Buffer[x] = 0xFFFF;
|
||||
for (int x = Position - 1; x < Position + 2; x++) //Middle Row
|
||||
World_Buffer[x] = 0xFFFF;
|
||||
for (int x = Position + 15; x < Position + 18; x++) //Final Row
|
||||
World_Buffer[x] = 0xFFFF;
|
||||
World_Buffer[Position] = House_ID;
|
||||
World_Buffer[Position + 15] = 0xA012; //Add Nameplate
|
||||
|
||||
DataConverter.Write(MainForm.AcreData_Offset, World_Buffer);*/
|
||||
}
|
||||
|
||||
public Villager_Player_Entry[] Get_Player_Entries(uint Matching_Player_ID)
|
||||
{
|
||||
return Villager_Player_Entries.Where(Entry => Entry.Player_ID == Matching_Player_ID).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Animal Crossing: Population Growing Villager Player Entry Structure:
|
||||
|
||||
Villager Player Entry Structure (Size: 0x138)
|
||||
Player Name: 0x000 - 0x007
|
||||
Town Name: 0x008 - 0x00F
|
||||
Player ID: 0x010 - 0x013
|
||||
Met Date: 0x014 - 0x01B
|
||||
Met Town Name: 0x01C - 0x023
|
||||
Met Town ID: 0x024 - 0x025
|
||||
Padding??: 0x026 - 0x027
|
||||
Unknown Data: 0x028 - 0x02F
|
||||
Friendship: 0x030 (Min = 0 (1), Max = 7F (128))
|
||||
Unknown Bytes: 0x031 - 0x032
|
||||
Saved Message: 0x033? - 0x138
|
||||
*/
|
||||
public class Villager_Player_Entry
|
||||
{
|
||||
public bool Exists = false;
|
||||
public int Offset;
|
||||
//Struct Start
|
||||
public string Player_Name;
|
||||
public string Player_Town_Name;
|
||||
public uint Player_ID;
|
||||
public ACDate Met_Date;
|
||||
public string Met_Town_Name;
|
||||
public ushort Met_Town_ID;
|
||||
public byte[] Garbage = new byte[8]; //I have no idea wtf these are for. Might investigate some day.
|
||||
public sbyte Friendship;
|
||||
public Mail Saved_Letter; //Going to have to change this to a custom class, as it strips most mail header data (Length is 0x100? Message part is still 0xF8)
|
||||
//
|
||||
|
||||
public Villager_Player_Entry(byte[] entryData, int offset)
|
||||
{
|
||||
Exists = true;
|
||||
Offset = offset;
|
||||
byte[] playerNameBytes = new byte[8], playerTownName = new byte[8], metTownName = new byte[8], metDate = new byte[8], playerId = new byte[4], metTownId = new byte[2];
|
||||
Buffer.BlockCopy(entryData, 0, playerNameBytes, 0, 8);
|
||||
Buffer.BlockCopy(entryData, 8, playerTownName, 0, 8);
|
||||
Buffer.BlockCopy(entryData, 0x1C, metTownName, 0, 8);
|
||||
Buffer.BlockCopy(entryData, 0x10, playerId, 0, 4);
|
||||
Buffer.BlockCopy(entryData, 0x14, metDate, 0, 8);
|
||||
Buffer.BlockCopy(entryData, 0x24, metTownId, 0, 2);
|
||||
Array.Reverse(playerId);
|
||||
Array.Reverse(metTownId);
|
||||
|
||||
Player_Name = new ACString(playerNameBytes).Trim();
|
||||
Player_Town_Name = new ACString(playerTownName).Trim();
|
||||
Met_Town_Name = new ACString(metTownName).Trim();
|
||||
Met_Date = new ACDate(metDate);
|
||||
Player_ID = BitConverter.ToUInt32(playerId, 0);
|
||||
Met_Town_ID = BitConverter.ToUInt16(metTownId, 0);
|
||||
Friendship = (sbyte)entryData[0x30];
|
||||
}
|
||||
|
||||
public void Max_Friendship()
|
||||
{
|
||||
Friendship = 0x7F;
|
||||
}
|
||||
|
||||
public void Write()
|
||||
{
|
||||
//Player Name is handled by renaming the player
|
||||
//DataConverter.WriteByteArray(Offset + 0x8, DataConverter.ReadDataRaw(MainForm.Town_Name_Offset, 8)); //Update Town Name
|
||||
//if (DataConverter.ReadUShort(8) == Met_Town_ID)
|
||||
// DataConverter.WriteByteArray(Offset + 0x1C, DataConverter.ReadDataRaw(MainForm.Town_Name_Offset, 8)); //Update Met Town Name
|
||||
}
|
||||
}
|
||||
|
||||
public struct VillagerOffsets
|
||||
{
|
||||
public int Villager_ID;
|
||||
public int Catchphrase;
|
||||
public int CatchphraseSize;
|
||||
public int Nicknames;
|
||||
public int NicknamesSize;
|
||||
public int NicknamesCount;
|
||||
public int Personality;
|
||||
public int Town_ID;
|
||||
public int Town_Name;
|
||||
public int Town_NameSize;
|
||||
public int Shirt;
|
||||
public int Umbrella;
|
||||
public int Song;
|
||||
public int Carpet;
|
||||
public int Wallpaper;
|
||||
public int Furniture;
|
||||
public int FurnitureCount;
|
||||
public int House_Coordinates;
|
||||
public int House_CoordinatesSize;
|
||||
public int Status;
|
||||
}
|
||||
|
||||
//Rename when VillagerData class is removed
|
||||
public struct VillagerDataStruct
|
||||
{
|
||||
public ushort Villager_ID;
|
||||
public string Catchphrase;
|
||||
public string[] Nicknames;
|
||||
public byte Personality;
|
||||
public ushort Town_ID;
|
||||
public string Town_Name;
|
||||
public Item Shirt;
|
||||
public Item Umbrella;
|
||||
public Item Song;
|
||||
public Item Carpet;
|
||||
public Item Wallpaper;
|
||||
public Item[] Furniture;
|
||||
public byte[] House_Coordinates; //Animal Crossing only?
|
||||
public byte Status;
|
||||
//Player Entries?
|
||||
}
|
||||
|
||||
public static class VillagerInfo
|
||||
{
|
||||
public static VillagerOffsets AC_Villager_Offsets = new VillagerOffsets
|
||||
{
|
||||
Villager_ID = 0,
|
||||
Town_ID = 2,
|
||||
Town_Name = 4,
|
||||
Town_NameSize = 8,
|
||||
Personality = 0xD,
|
||||
House_Coordinates = 0x899,
|
||||
House_CoordinatesSize = 4,
|
||||
Catchphrase = 0x89D,
|
||||
CatchphraseSize = 0xA,
|
||||
Shirt = 0x8E4,
|
||||
Status = -1, //Research
|
||||
Umbrella = -1, //Research this as well
|
||||
Furniture = -1, //No Furniture customization in AC
|
||||
Carpet = -1,
|
||||
Wallpaper = -1,
|
||||
Nicknames = -1, //Inside of "Player Entries"
|
||||
Song = -1,
|
||||
//Add Player Entries (Relationships)
|
||||
};
|
||||
|
||||
public static VillagerOffsets WW_Villager_Offsets = new VillagerOffsets
|
||||
{
|
||||
//0 = Relationships (0x68 bytes each)
|
||||
//Pattern as well
|
||||
Furniture = 0x6AC,
|
||||
FurnitureCount = 0xA,
|
||||
Personality = 0x6CA,
|
||||
Villager_ID = 0x6CB,
|
||||
Wallpaper = 0x6CC,
|
||||
Carpet = 0x6CE,
|
||||
Song = 0x6D0, //Check this
|
||||
Shirt = 0x6EC,
|
||||
Catchphrase = 0x6DE,
|
||||
CatchphraseSize = 0xA,
|
||||
//Finish rest of offsets
|
||||
};
|
||||
|
||||
public static VillagerOffsets CF_Villager_Offsets = new VillagerOffsets
|
||||
{
|
||||
//Villagers in City Folk are interesting.
|
||||
//The actual data structure is stored in the save file, allowing for customization of the entire villager.
|
||||
//This includes name, textures, and what villager model it uses!
|
||||
//That will mean a lot more work will have to go into this part of the villager editor, though.
|
||||
//I'll have to finish it at a later date. Unfortunately, I can't find the source to NPC Tool, a tool that allowed all of these modifications to be done
|
||||
//This means I'll probably have to reverse engineer the format myself
|
||||
};
|
||||
|
||||
public static VillagerOffsets NL_Villager_Offsets = new VillagerOffsets
|
||||
{
|
||||
Villager_ID = 0,
|
||||
Personality = 2,
|
||||
Status = 0x24C4,
|
||||
Catchphrase = 0x24A6,
|
||||
CatchphraseSize = 0x16,
|
||||
Town_Name = 0x24CE,
|
||||
Town_NameSize = 0x12,
|
||||
Town_ID = -1, // Research
|
||||
Shirt = 0x244E,
|
||||
Song = 0x2452,
|
||||
Wallpaper = 0x2456,
|
||||
Carpet = 0x245A,
|
||||
Umbrella = 0x245E,
|
||||
Furniture = 0x2462,
|
||||
FurnitureCount = 16,
|
||||
House_Coordinates = -1,
|
||||
Nicknames = -1 //Research
|
||||
};
|
||||
|
||||
public static VillagerOffsets WA_Villager_Offsets = new VillagerOffsets
|
||||
{
|
||||
Villager_ID = 0,
|
||||
Personality = 2,
|
||||
Status = 0x24E4,
|
||||
Catchphrase = 0x24C6,
|
||||
CatchphraseSize = 0x16,
|
||||
Town_Name = 0x24CE,
|
||||
Town_NameSize = 0x12,
|
||||
Town_ID = -1, // Research
|
||||
Shirt = 0x246E,
|
||||
Song = 0x2472,
|
||||
Wallpaper = 0x2476,
|
||||
Carpet = 0x247A,
|
||||
Umbrella = 0x247E,
|
||||
Furniture = 0x2482,
|
||||
FurnitureCount = 16,
|
||||
House_Coordinates = -1,
|
||||
Nicknames = -1 //Research
|
||||
};
|
||||
|
||||
public static string[] AC_Personalities = new string[7]
|
||||
{
|
||||
"Normal (Female)", "Peppy (Female)", "Lazy (Male)", "Jock (Male)", "Cranky (Male)", "Snooty (Female)", "Not Set"
|
||||
};
|
||||
|
||||
public static string[] WW_Personalities = new string[7]
|
||||
{
|
||||
"Lazy (Male)", "Jock (Male)", "Cranky (Male)", "Normal (Female)", "Peppy (Female)", "Snooty (Female)", "Not Set"
|
||||
};
|
||||
|
||||
public static string[] NL_Personalities = new string[9]
|
||||
{
|
||||
"Lazy (Male)", "Jock (Male)", "Cranky (Male)", "Smug (Male)", "Normal (Female)", "Peppy (Female)", "Snooty (Female)", "Caring (Uchi) (Female)", "Not Set"
|
||||
};
|
||||
|
||||
public static string[] GetPersonalities(SaveType Save_Type)
|
||||
{
|
||||
switch (Save_Type)
|
||||
{
|
||||
case SaveType.Animal_Crossing:
|
||||
return AC_Personalities;
|
||||
case SaveType.Wild_World:
|
||||
return WW_Personalities;
|
||||
case SaveType.New_Leaf:
|
||||
return NL_Personalities;
|
||||
case SaveType.Welcome_Amiibo:
|
||||
return NL_Personalities;
|
||||
}
|
||||
return new string[0];
|
||||
}
|
||||
|
||||
public static Dictionary<ushort, SimpleVillager> GetVillagerDatabase(SaveType Save_Type, string Language = "en")
|
||||
{
|
||||
Dictionary<ushort, SimpleVillager> Database = new Dictionary<ushort, SimpleVillager>();
|
||||
StreamReader Contents = null;
|
||||
string Database_Filename = NewMainForm.Assembly_Location + "\\Resources\\{0}_Villagers_" + Language + ".txt";
|
||||
switch (Save_Type)
|
||||
{
|
||||
case SaveType.Animal_Crossing:
|
||||
Database_Filename = string.Format(Database_Filename, "AC");
|
||||
break;
|
||||
case SaveType.Wild_World:
|
||||
Database_Filename = string.Format(Database_Filename, "WW");
|
||||
break;
|
||||
case SaveType.New_Leaf:
|
||||
Database_Filename = string.Format(Database_Filename, "NL");
|
||||
break;
|
||||
case SaveType.Welcome_Amiibo:
|
||||
Database_Filename = string.Format(Database_Filename, "WA");
|
||||
break;
|
||||
}
|
||||
try { Contents = File.OpenText(Database_Filename); }
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(string.Format("An error occured opening villager database file:\n\"{0}\"\nError Info:\n{1}", Database_Filename, e.Message));
|
||||
return null;
|
||||
}
|
||||
string Line;
|
||||
if (Save_Type == SaveType.New_Leaf || Save_Type == SaveType.Welcome_Amiibo)
|
||||
{
|
||||
while ((Line = Contents.ReadLine()) != null)
|
||||
{
|
||||
if (Line.Contains("0x"))
|
||||
{
|
||||
SimpleVillager Entry = new SimpleVillager();
|
||||
string ID = Regex.Match(Line, @"ID = 0x....,").Value.Substring(7, 4);
|
||||
Entry.Villager_ID = ushort.Parse(ID, NumberStyles.AllowHexSpecifier);
|
||||
string Name_Str = Regex.Match(Line, @"Name = .+").Value.Substring(7);
|
||||
Entry.Name = Name_Str.Substring(0, Name_Str.IndexOf(','));
|
||||
string Personality = Regex.Match(Line, @"Personality = .").Value;
|
||||
Entry.Personality = byte.Parse(Personality.Substring(Personality.Length - 1, 1));
|
||||
Database.Add(Entry.Villager_ID, Entry);
|
||||
//MessageBox.Show("ID: " + Entry.Villager_ID.ToString("X4") + " | Name: " + Entry.Name + " | Personality: " + Entry.Personality);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Save_Type == SaveType.Wild_World)
|
||||
{
|
||||
while ((Line = Contents.ReadLine()) != null)
|
||||
{
|
||||
if (Line.Contains("0x"))
|
||||
{
|
||||
SimpleVillager Entry = new SimpleVillager();
|
||||
Entry.Villager_ID = ushort.Parse(Line.Substring(2, 2), NumberStyles.AllowHexSpecifier);
|
||||
Entry.Name = Line.Substring(6);
|
||||
Database.Add(Entry.Villager_ID, Entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Save_Type == SaveType.Animal_Crossing)
|
||||
{
|
||||
while ((Line = Contents.ReadLine()) != null)
|
||||
{
|
||||
if (Line.Contains("0x"))
|
||||
{
|
||||
SimpleVillager Entry = new SimpleVillager();
|
||||
Entry.Villager_ID = ushort.Parse(Line.Substring(2, 4), NumberStyles.AllowHexSpecifier);
|
||||
Entry.Name = Line.Substring(8);
|
||||
Database.Add(Entry.Villager_ID, Entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Database;
|
||||
}
|
||||
|
||||
public static VillagerOffsets GetVillagerInfo(SaveType Save_Type)
|
||||
{
|
||||
switch(Save_Type)
|
||||
{
|
||||
case SaveType.Animal_Crossing:
|
||||
return AC_Villager_Offsets;
|
||||
case SaveType.Wild_World:
|
||||
return WW_Villager_Offsets;
|
||||
case SaveType.New_Leaf:
|
||||
return NL_Villager_Offsets;
|
||||
case SaveType.Welcome_Amiibo:
|
||||
return WA_Villager_Offsets;
|
||||
}
|
||||
return new VillagerOffsets { };
|
||||
}
|
||||
}
|
||||
|
||||
public class SimpleVillager
|
||||
{
|
||||
public ushort Villager_ID;
|
||||
public byte Personality;
|
||||
public string Name;
|
||||
public string Catchphrase;
|
||||
public Item Shirt;
|
||||
public Item[] Furniture;
|
||||
//public uint AI (Last bytes in NL Villagers?)
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name ?? "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public class NewVillager
|
||||
{
|
||||
public VillagerOffsets Offsets;
|
||||
public VillagerDataStruct Data;
|
||||
public int Index;
|
||||
public int Offset;
|
||||
public string Name;
|
||||
public bool Exists = false;
|
||||
private Save SaveData;
|
||||
|
||||
public NewVillager(int offset, int idx, Save save)
|
||||
{
|
||||
SaveData = save;
|
||||
Index = idx;
|
||||
Offset = offset;
|
||||
Offsets = VillagerInfo.GetVillagerInfo(save.Save_Type);
|
||||
if (save.Save_Type == SaveType.Wild_World)
|
||||
Exists = SaveData.ReadByte(offset + Offsets.Villager_ID) != 0 && SaveData.ReadByte(offset + Offsets.Villager_ID) != 0xFF;
|
||||
else
|
||||
Exists = SaveData.ReadUInt16(offset + Offsets.Villager_ID, save.Is_Big_Endian) != 0 && SaveData.ReadUInt16(offset + Offsets.Villager_ID, save.Is_Big_Endian) != 0xFFFF;
|
||||
object BoxedData = new VillagerDataStruct();
|
||||
foreach (var Field in typeof(VillagerOffsets).GetFields(BindingFlags.Public | BindingFlags.Instance))
|
||||
if (Field.GetValue(Offsets) != null && !Field.Name.Contains("Count") && !Field.Name.Contains("Size"))
|
||||
if (typeof(VillagerDataStruct).GetField(Field.Name) != null)
|
||||
{
|
||||
if (Field.FieldType == typeof(int) && (int)Field.GetValue(Offsets) != -1)
|
||||
{
|
||||
Type FieldType = typeof(VillagerDataStruct).GetField(Field.Name).FieldType;
|
||||
int DataOffset = Offset + (int)Field.GetValue(Offsets);
|
||||
|
||||
if (Field.Name == "Villager_ID" && save.Save_Type == SaveType.Wild_World) //Villager IDs are only a byte in WW
|
||||
typeof(VillagerDataStruct).GetField(Field.Name).SetValue(BoxedData, SaveData.ReadByte(DataOffset));
|
||||
else if (FieldType == typeof(byte))
|
||||
typeof(VillagerDataStruct).GetField(Field.Name).SetValue(BoxedData, SaveData.ReadByte(DataOffset));
|
||||
else if (FieldType == typeof(byte[]) && typeof(VillagerOffsets).GetField(Field.Name + "Count") != null)
|
||||
typeof(VillagerDataStruct).GetField(Field.Name).SetValue(BoxedData, SaveData.ReadByteArray(DataOffset,
|
||||
(int)typeof(VillagerOffsets).GetField(Field.Name + "Count").GetValue(Offsets)));
|
||||
else if (FieldType == typeof(ushort))
|
||||
typeof(VillagerDataStruct).GetField(Field.Name).SetValue(BoxedData, SaveData.ReadUInt16(DataOffset, SaveData.Is_Big_Endian));
|
||||
else if (FieldType == typeof(ushort[]))
|
||||
typeof(VillagerDataStruct).GetField(Field.Name).SetValue(BoxedData, SaveData.ReadUInt16Array(DataOffset,
|
||||
(int)typeof(VillagerOffsets).GetField(Field.Name + "Count").GetValue(Offsets), SaveData.Is_Big_Endian));
|
||||
else if (FieldType == typeof(uint))
|
||||
typeof(VillagerDataStruct).GetField(Field.Name).SetValue(BoxedData, SaveData.ReadUInt32(DataOffset, SaveData.Is_Big_Endian));
|
||||
else if (FieldType == typeof(string))
|
||||
typeof(VillagerDataStruct).GetField(Field.Name).SetValue(BoxedData, new ACString(SaveData.ReadByteArray(DataOffset,
|
||||
(int)typeof(VillagerOffsets).GetField(Field.Name + "Size").GetValue(Offsets)), SaveData.Save_Type).Trim());
|
||||
else if (FieldType == typeof(string[])) { }
|
||||
//Add logic
|
||||
else if (FieldType == typeof(Item))
|
||||
if (save.Save_Type == SaveType.New_Leaf || save.Save_Type == SaveType.Welcome_Amiibo)
|
||||
typeof(VillagerDataStruct).GetField(Field.Name).SetValue(BoxedData, new Item(SaveData.ReadUInt32(DataOffset, false)));
|
||||
else
|
||||
typeof(VillagerDataStruct).GetField(Field.Name).SetValue(BoxedData, new Item(SaveData.ReadUInt16(DataOffset, SaveData.Is_Big_Endian)));
|
||||
else if (FieldType == typeof(Item[]))
|
||||
{
|
||||
Item[] Collection = new Item[(int)typeof(VillagerOffsets).GetField(Field.Name + "Count").GetValue(Offsets)];
|
||||
for (int i = 0; i < Collection.Length; i++)
|
||||
{
|
||||
if (save.Save_Type == SaveType.New_Leaf || save.Save_Type == SaveType.Welcome_Amiibo)
|
||||
Collection[i] = new Item(SaveData.ReadUInt32(DataOffset + i * 4, false));
|
||||
else
|
||||
Collection[i] = new Item(SaveData.ReadUInt16(DataOffset + i * 2, SaveData.Is_Big_Endian));
|
||||
}
|
||||
typeof(VillagerDataStruct).GetField(Field.Name).SetValue(BoxedData, Collection);
|
||||
}
|
||||
}
|
||||
}
|
||||
Data = (VillagerDataStruct)BoxedData;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name ?? "Unknown";
|
||||
}
|
||||
|
||||
public void Write()
|
||||
{
|
||||
//MessageBox.Show(string.Format("Writing Villager #{0} with data offset of 0x{1}", Index, Offset.ToString("X")));
|
||||
Type VillagerOffsetData = typeof(VillagerOffsets);
|
||||
Type VillagerDataType = typeof(VillagerDataStruct);
|
||||
foreach (var Field in VillagerOffsetData.GetFields(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
if (Field.GetValue(Offsets) != null && !Field.Name.Contains("Count") && !Field.Name.Contains("Size"))
|
||||
{
|
||||
if (VillagerDataType.GetField(Field.Name) != null)
|
||||
{
|
||||
if (Field.FieldType == typeof(int) && (int)Field.GetValue(Offsets) != -1)
|
||||
{
|
||||
Type FieldType = VillagerDataType.GetField(Field.Name).FieldType;
|
||||
int DataOffset = Offset + (int)Field.GetValue(Offsets);
|
||||
//MessageBox.Show("Field Name: " + Field.Name + " | Data Offset: " + DataOffset.ToString("X"));
|
||||
if (Field.Name == "Villager_ID")
|
||||
{
|
||||
if (SaveData.Save_Type == SaveType.Wild_World)
|
||||
{
|
||||
SaveData.Write(DataOffset, Convert.ToByte(VillagerDataType.GetField(Field.Name).GetValue(Data)));
|
||||
}
|
||||
else //Might not encompass City Folk
|
||||
{
|
||||
SaveData.Write(DataOffset, (ushort)VillagerDataType.GetField(Field.Name).GetValue(Data), SaveData.Is_Big_Endian);
|
||||
}
|
||||
}
|
||||
else if (FieldType == typeof(string))
|
||||
{
|
||||
SaveData.Write(DataOffset, ACString.GetBytes((string)VillagerDataType.GetField(Field.Name).GetValue(Data),
|
||||
(int)VillagerOffsetData.GetField(Field.Name + "Size").GetValue(Offsets)));
|
||||
}
|
||||
else if (FieldType == typeof(byte))
|
||||
{
|
||||
SaveData.Write(DataOffset, (byte)VillagerDataType.GetField(Field.Name).GetValue(Data));
|
||||
}
|
||||
else if (FieldType == typeof(ushort))
|
||||
{
|
||||
SaveData.Write(DataOffset, (ushort)VillagerDataType.GetField(Field.Name).GetValue(Data), SaveData.Is_Big_Endian);
|
||||
}
|
||||
else if (FieldType == typeof(Item))
|
||||
{
|
||||
if (SaveData.Save_Type == SaveType.New_Leaf || SaveData.Save_Type == SaveType.Welcome_Amiibo)
|
||||
{
|
||||
SaveData.Write(DataOffset, ItemData.EncodeItem((Item)VillagerDataType.GetField(Field.Name).GetValue(Data)), SaveData.Is_Big_Endian);
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveData.Write(DataOffset, ((Item)VillagerDataType.GetField(Field.Name).GetValue(Data)).ItemID, SaveData.Is_Big_Endian);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Special case here, since Villager_Data_Start + 0xC is always the same as the villager's ID. (Lower byte)
|
||||
// TODO: Add check to see if the villager is an islander. If they are, use 0xFF instead.
|
||||
if (SaveData.Save_Type == SaveType.Animal_Crossing)
|
||||
{
|
||||
SaveData.Write(Offset + 0xC, (byte)Data.Villager_ID);
|
||||
}
|
||||
// TODO: Add House Coordinate Saving/Updating (Also automatic placing/removing??) for the GC version
|
||||
}
|
||||
}
|
||||
}
|
170
Forms/AboutBox2.Designer.cs
generated
Normal file
|
@ -0,0 +1,170 @@
|
|||
namespace ACSE
|
||||
{
|
||||
partial class AboutBox1
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutBox1));
|
||||
this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.logoPictureBox = new System.Windows.Forms.PictureBox();
|
||||
this.labelProductName = new System.Windows.Forms.Label();
|
||||
this.labelVersion = new System.Windows.Forms.Label();
|
||||
this.labelCopyright = new System.Windows.Forms.Label();
|
||||
this.okButton = new System.Windows.Forms.Button();
|
||||
this.labelCompanyName = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel
|
||||
//
|
||||
this.tableLayoutPanel.ColumnCount = 2;
|
||||
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F));
|
||||
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 67F));
|
||||
this.tableLayoutPanel.Controls.Add(this.logoPictureBox, 0, 0);
|
||||
this.tableLayoutPanel.Controls.Add(this.labelProductName, 1, 0);
|
||||
this.tableLayoutPanel.Controls.Add(this.labelVersion, 1, 1);
|
||||
this.tableLayoutPanel.Controls.Add(this.labelCopyright, 1, 2);
|
||||
this.tableLayoutPanel.Controls.Add(this.okButton, 1, 5);
|
||||
this.tableLayoutPanel.Controls.Add(this.labelCompanyName, 1, 3);
|
||||
this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel.Location = new System.Drawing.Point(9, 9);
|
||||
this.tableLayoutPanel.Name = "tableLayoutPanel";
|
||||
this.tableLayoutPanel.RowCount = 6;
|
||||
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
|
||||
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
|
||||
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 10F));
|
||||
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 43.70861F));
|
||||
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 5.298013F));
|
||||
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 20.5298F));
|
||||
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel.Size = new System.Drawing.Size(417, 151);
|
||||
this.tableLayoutPanel.TabIndex = 0;
|
||||
//
|
||||
// logoPictureBox
|
||||
//
|
||||
this.logoPictureBox.Image = ((System.Drawing.Image)(resources.GetObject("logoPictureBox.Image")));
|
||||
this.logoPictureBox.Location = new System.Drawing.Point(3, 3);
|
||||
this.logoPictureBox.Name = "logoPictureBox";
|
||||
this.tableLayoutPanel.SetRowSpan(this.logoPictureBox, 6);
|
||||
this.logoPictureBox.Size = new System.Drawing.Size(128, 128);
|
||||
this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||
this.logoPictureBox.TabIndex = 12;
|
||||
this.logoPictureBox.TabStop = false;
|
||||
//
|
||||
// labelProductName
|
||||
//
|
||||
this.labelProductName.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.labelProductName.Location = new System.Drawing.Point(143, 0);
|
||||
this.labelProductName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
|
||||
this.labelProductName.MaximumSize = new System.Drawing.Size(0, 17);
|
||||
this.labelProductName.Name = "labelProductName";
|
||||
this.labelProductName.Size = new System.Drawing.Size(271, 15);
|
||||
this.labelProductName.TabIndex = 19;
|
||||
this.labelProductName.Text = "ACSE\r\n";
|
||||
this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// labelVersion
|
||||
//
|
||||
this.labelVersion.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.labelVersion.Location = new System.Drawing.Point(143, 15);
|
||||
this.labelVersion.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
|
||||
this.labelVersion.MaximumSize = new System.Drawing.Size(0, 17);
|
||||
this.labelVersion.Name = "labelVersion";
|
||||
this.labelVersion.Size = new System.Drawing.Size(271, 15);
|
||||
this.labelVersion.TabIndex = 0;
|
||||
this.labelVersion.Text = "Created By: Cuyler_36 (Jeremy Olsen)";
|
||||
this.labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// labelCopyright
|
||||
//
|
||||
this.labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.labelCopyright.Location = new System.Drawing.Point(143, 30);
|
||||
this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
|
||||
this.labelCopyright.MaximumSize = new System.Drawing.Size(0, 17);
|
||||
this.labelCopyright.Name = "labelCopyright";
|
||||
this.labelCopyright.Size = new System.Drawing.Size(271, 15);
|
||||
this.labelCopyright.TabIndex = 21;
|
||||
this.labelCopyright.Text = "Special Thanks:";
|
||||
this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// okButton
|
||||
//
|
||||
this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.okButton.Location = new System.Drawing.Point(339, 125);
|
||||
this.okButton.Name = "okButton";
|
||||
this.okButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.okButton.TabIndex = 24;
|
||||
this.okButton.Text = "&OK";
|
||||
this.okButton.Click += new System.EventHandler(this.okButton_Click);
|
||||
//
|
||||
// labelCompanyName
|
||||
//
|
||||
this.labelCompanyName.AutoSize = true;
|
||||
this.labelCompanyName.Location = new System.Drawing.Point(143, 45);
|
||||
this.labelCompanyName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
|
||||
this.labelCompanyName.Name = "labelCompanyName";
|
||||
this.labelCompanyName.Size = new System.Drawing.Size(237, 52);
|
||||
this.labelCompanyName.TabIndex = 22;
|
||||
this.labelCompanyName.Text = "Kaphotics/kwsch - Item Bitmap Generation Code\r\nMarc Robledo - New Leaf Offsets/ID" +
|
||||
"s\r\nVirus - City Folk Offets/IDs\r\nDsPet - Wild World Offsets/IDs";
|
||||
this.labelCompanyName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
//
|
||||
// AboutBox1
|
||||
//
|
||||
this.AcceptButton = this.okButton;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(435, 169);
|
||||
this.Controls.Add(this.tableLayoutPanel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "AboutBox1";
|
||||
this.Padding = new System.Windows.Forms.Padding(9);
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "AboutBox1";
|
||||
this.tableLayoutPanel.ResumeLayout(false);
|
||||
this.tableLayoutPanel.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
|
||||
private System.Windows.Forms.PictureBox logoPictureBox;
|
||||
private System.Windows.Forms.Label labelProductName;
|
||||
private System.Windows.Forms.Label labelVersion;
|
||||
private System.Windows.Forms.Label labelCopyright;
|
||||
private System.Windows.Forms.Label labelCompanyName;
|
||||
private System.Windows.Forms.Button okButton;
|
||||
}
|
||||
}
|
104
Forms/AboutBox2.cs
Normal file
|
@ -0,0 +1,104 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
partial class AboutBox1 : Form
|
||||
{
|
||||
public AboutBox1()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Text = String.Format("About {0}", AssemblyTitle);
|
||||
}
|
||||
|
||||
#region Assembly Attribute Accessors
|
||||
|
||||
public string AssemblyTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);
|
||||
if (attributes.Length > 0)
|
||||
{
|
||||
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];
|
||||
if (titleAttribute.Title != "")
|
||||
{
|
||||
return titleAttribute.Title;
|
||||
}
|
||||
}
|
||||
return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
|
||||
}
|
||||
}
|
||||
|
||||
public string AssemblyVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public string AssemblyDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);
|
||||
if (attributes.Length == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return ((AssemblyDescriptionAttribute)attributes[0]).Description;
|
||||
}
|
||||
}
|
||||
|
||||
public string AssemblyProduct
|
||||
{
|
||||
get
|
||||
{
|
||||
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);
|
||||
if (attributes.Length == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return ((AssemblyProductAttribute)attributes[0]).Product;
|
||||
}
|
||||
}
|
||||
|
||||
public string AssemblyCopyright
|
||||
{
|
||||
get
|
||||
{
|
||||
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);
|
||||
if (attributes.Length == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return ((AssemblyCopyrightAttribute)attributes[0]).Copyright;
|
||||
}
|
||||
}
|
||||
|
||||
public string AssemblyCompany
|
||||
{
|
||||
get
|
||||
{
|
||||
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);
|
||||
if (attributes.Length == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return ((AssemblyCompanyAttribute)attributes[0]).Company;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void okButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
}
|
545
Forms/AboutBox2.resx
Normal file
|
@ -0,0 +1,545 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="logoPictureBox.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
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
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
1732
Forms/NewMainForm.Designer.cs
generated
Normal file
2519
Forms/NewMainForm.cs
Normal file
6326
Forms/NewMainForm.resx
Normal file
76
Forms/SecureValueForm.Designer.cs
generated
Normal file
|
@ -0,0 +1,76 @@
|
|||
namespace ACSE
|
||||
{
|
||||
partial class SecureValueForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.button1 = new System.Windows.Forms.Button();
|
||||
this.textBox1 = new System.Windows.Forms.TextBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// button1
|
||||
//
|
||||
this.button1.Location = new System.Drawing.Point(197, 12);
|
||||
this.button1.Name = "button1";
|
||||
this.button1.Size = new System.Drawing.Size(75, 20);
|
||||
this.button1.TabIndex = 0;
|
||||
this.button1.Text = "Save";
|
||||
this.button1.UseVisualStyleBackColor = true;
|
||||
this.button1.Click += new System.EventHandler(this.button1_Click);
|
||||
//
|
||||
// textBox1
|
||||
//
|
||||
this.textBox1.Location = new System.Drawing.Point(12, 12);
|
||||
this.textBox1.MaxLength = 16;
|
||||
this.textBox1.Name = "textBox1";
|
||||
this.textBox1.Size = new System.Drawing.Size(179, 20);
|
||||
this.textBox1.TabIndex = 1;
|
||||
this.textBox1.Text = "0000000000000000";
|
||||
this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
|
||||
//
|
||||
// SecureValueForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(284, 45);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.textBox1);
|
||||
this.Controls.Add(this.button1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.Name = "SecureValueForm";
|
||||
this.Text = "Secure_Value_Form";
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button button1;
|
||||
private System.Windows.Forms.TextBox textBox1;
|
||||
}
|
||||
}
|
42
Forms/SecureValueForm.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
public partial class SecureValueForm : Form
|
||||
{
|
||||
public SecureValueForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void Set_Secure_NAND_Value(ulong value)
|
||||
{
|
||||
textBox1.Text = value.ToString("X16");
|
||||
}
|
||||
|
||||
private void textBox1_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void button1_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (NewMainForm.Save_File != null && (NewMainForm.Save_File.Save_Type == SaveType.New_Leaf || NewMainForm.Save_File.Save_Type == SaveType.Welcome_Amiibo))
|
||||
{
|
||||
if (ulong.TryParse(textBox1.Text, NumberStyles.AllowHexSpecifier, null, out ulong Secure_NAND_Value))
|
||||
{
|
||||
NewMainForm.Save_File.Write(0, Secure_NAND_Value);
|
||||
}
|
||||
}
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
}
|
120
Forms/SecureValueForm.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
125
Forms/SettingsMenuForm.Designer.cs
generated
Normal file
|
@ -0,0 +1,125 @@
|
|||
namespace ACSE
|
||||
{
|
||||
partial class SettingsMenuForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.imageSizeModeComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.doneButton = new System.Windows.Forms.Button();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.debugLevelComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// imageSizeModeComboBox
|
||||
//
|
||||
this.imageSizeModeComboBox.FormattingEnabled = true;
|
||||
this.imageSizeModeComboBox.Location = new System.Drawing.Point(125, 6);
|
||||
this.imageSizeModeComboBox.Name = "imageSizeModeComboBox";
|
||||
this.imageSizeModeComboBox.Size = new System.Drawing.Size(121, 21);
|
||||
this.imageSizeModeComboBox.TabIndex = 0;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(12, 9);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(107, 13);
|
||||
this.label1.TabIndex = 1;
|
||||
this.label1.Text = "Image Resize Mode: ";
|
||||
//
|
||||
// doneButton
|
||||
//
|
||||
this.doneButton.Location = new System.Drawing.Point(317, 132);
|
||||
this.doneButton.Name = "doneButton";
|
||||
this.doneButton.Size = new System.Drawing.Size(75, 23);
|
||||
this.doneButton.TabIndex = 2;
|
||||
this.doneButton.Text = "Done";
|
||||
this.doneButton.UseVisualStyleBackColor = true;
|
||||
this.doneButton.Click += new System.EventHandler(this.doneButton_Click);
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(252, 9);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(92, 13);
|
||||
this.label2.TabIndex = 3;
|
||||
this.label2.Text = "(Requires Restart)";
|
||||
//
|
||||
// debugLevelComboBox
|
||||
//
|
||||
this.debugLevelComboBox.FormattingEnabled = true;
|
||||
this.debugLevelComboBox.Items.AddRange(new object[] {
|
||||
"None",
|
||||
"Error",
|
||||
"Info",
|
||||
"Debug"});
|
||||
this.debugLevelComboBox.Location = new System.Drawing.Point(125, 33);
|
||||
this.debugLevelComboBox.Name = "debugLevelComboBox";
|
||||
this.debugLevelComboBox.Size = new System.Drawing.Size(121, 21);
|
||||
this.debugLevelComboBox.TabIndex = 4;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(2, 36);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(117, 13);
|
||||
this.label3.TabIndex = 5;
|
||||
this.label3.Text = "Debug Message Level:";
|
||||
//
|
||||
// SettingsMenuForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(404, 167);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.debugLevelComboBox);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.doneButton);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.imageSizeModeComboBox);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.Name = "SettingsMenuForm";
|
||||
this.Text = "ACSE Settings";
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.ComboBox imageSizeModeComboBox;
|
||||
private System.Windows.Forms.Button doneButton;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.ComboBox debugLevelComboBox;
|
||||
private System.Windows.Forms.Label label3;
|
||||
}
|
||||
}
|
44
Forms/SettingsMenuForm.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace ACSE
|
||||
{
|
||||
public partial class SettingsMenuForm : Form
|
||||
{
|
||||
public SettingsMenuForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
Array EnumItems = Enum.GetValues(typeof(InterpolationMode));
|
||||
foreach (var Enum in EnumItems)
|
||||
imageSizeModeComboBox.Items.Add(Enum.ToString());
|
||||
imageSizeModeComboBox.SelectedIndex = Properties.Settings.Default.ImageResizeMode;
|
||||
imageSizeModeComboBox.SelectedIndexChanged += new EventHandler((object o, EventArgs e) => ImageResizeMode_Changed());
|
||||
debugLevelComboBox.SelectedIndex = (int)Properties.Settings.Default.DebugLevel;
|
||||
debugLevelComboBox.SelectedIndexChanged += new EventHandler((object o, EventArgs e) => DebugLevel_Changed());
|
||||
}
|
||||
|
||||
private void ImageResizeMode_Changed()
|
||||
{
|
||||
Properties.Settings.Default.ImageResizeMode = imageSizeModeComboBox.SelectedIndex;
|
||||
//TODO: Redraw pictureboxes with the image mode, rather than wait to restart
|
||||
}
|
||||
|
||||
private void DebugLevel_Changed()
|
||||
{
|
||||
Properties.Settings.Default.DebugLevel = (DebugLevel)Math.Max(0, debugLevelComboBox.SelectedIndex);
|
||||
}
|
||||
|
||||
private void doneButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Properties.Settings.Default.Save();
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
}
|
120
Forms/SettingsMenuForm.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
36
Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ACSE")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ACSE")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("52b2adb4-812e-4b42-9955-9e8f1f14dbea")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
133
Properties/Resources.resx
Normal file
|
@ -0,0 +1,133 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="no_tpc" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Images\no_tpc.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="X" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Images\X.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Arrow" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Images\Arrow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="Building" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Images\Building.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
103
Properties/Resources1.Designer.cs
generated
Normal file
|
@ -0,0 +1,103 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ACSE.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ACSE.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap Arrow {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Arrow", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap Building {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Building", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap no_tpc {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("no_tpc", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap X {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("X", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
Properties/Settings.settings
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="ACSE.Properties" GeneratedClassName="Settings">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="DebuggingEnabled" Type="System.Boolean" Scope="User">
|
||||
<Value Profile="(Default)">True</Value>
|
||||
</Setting>
|
||||
<Setting Name="ImageResizeMode" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">5</Value>
|
||||
</Setting>
|
||||
<Setting Name="DebugLevel" Type="ACSE.DebugLevel" Scope="User">
|
||||
<Value Profile="(Default)">Info</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
62
Properties/Settings1.Designer.cs
generated
Normal file
|
@ -0,0 +1,62 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ACSE.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.0.1.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("True")]
|
||||
public bool DebuggingEnabled {
|
||||
get {
|
||||
return ((bool)(this["DebuggingEnabled"]));
|
||||
}
|
||||
set {
|
||||
this["DebuggingEnabled"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("5")]
|
||||
public int ImageResizeMode {
|
||||
get {
|
||||
return ((int)(this["ImageResizeMode"]));
|
||||
}
|
||||
set {
|
||||
this["ImageResizeMode"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("Info")]
|
||||
public global::ACSE.DebugLevel DebugLevel {
|
||||
get {
|
||||
return ((global::ACSE.DebugLevel)(this["DebugLevel"]));
|
||||
}
|
||||
set {
|
||||
this["DebugLevel"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
119
README.md
Normal file
|
@ -0,0 +1,119 @@
|
|||
# ACSE - Animal Crossing Save Editor
|
||||
|
||||
ACSE is a save editor for the GameCube version of Animal Crossing.
|
||||
|
||||
## Features
|
||||
* Player Editing
|
||||
* Name
|
||||
* Bells
|
||||
* Debt
|
||||
* Pockets
|
||||
* House
|
||||
* Acre Editing
|
||||
* Town Editing
|
||||
* Items
|
||||
* Buildings
|
||||
* Villager Editing
|
||||
* Villagers
|
||||
* Personalities
|
||||
* Catchphrases
|
||||
* Nicknames (Not Implemented)
|
||||
|
||||
## Extracting Save Files
|
||||
|
||||
### Dolphin Emulator
|
||||
To extract save files from Dolphin, on the main form, click Tools > Memcard Manager (GC).
|
||||
![Main Form](http://i.imgur.com/wH5OCQO.png)
|
||||
|
||||
Then click on Animal Crossing, and click the Export GCI button.
|
||||
![Memcard Manager](http://i.imgur.com/t2GBonJ.png)
|
||||
|
||||
### Modded GameCube/Wii
|
||||
Refer to the article here: https://wiki.dolphin-emu.org/index.php?title=Ripping_Games#Retrieving_Game_Saves
|
||||
|
||||
## Using the Editor
|
||||
|
||||
### Opening your Save File
|
||||
Click on the File button, then click Open and select your save file!
|
||||
|
||||
![Open Save](https://puu.sh/toNcf/998c395bf9.png)
|
||||
|
||||
### Using the Main Editor Form
|
||||
This contains the Players, Patterns, Town Name, and buttons to access the other editors! Simply change the values of the text/combo boxes to edit them.
|
||||
|
||||
![Main Editor](https://puu.sh/tIJV9/2db8da73fc.png)
|
||||
|
||||
### Using the Acre Editor Form
|
||||
This form allows you to change your acre tiles! There is a 7x10 grid of acre tiles. To select an acre to place, click the "Check Tile" button, then left click on the desired acre. You can also simply click on one of the entries in the acre list to the right of the acre grid. Once selected, a preview image of the selected acre will appear on the bottom right of the screen, along with it's name and AcreID. To place an acre, click on the "Place Tile" button, then just left click over any acre tile on the grid!
|
||||
|
||||
![Acre Editor](https://puu.sh/tIJTI/cb72b4831e.png)
|
||||
|
||||
#### Acre Editor Precautions
|
||||
Placing/Removing specific acres can damage your town. Here is a list of possible things that could break your game:
|
||||
* Changing the top row of acres (Untested)
|
||||
* Putting a non A-Acre in the A-Acre row (Also untested, but quite likely)
|
||||
* Removing a Dump Acre, but not removing the dump in the Town Editor (This WILL cause your game to break, but only until you remove the dump or put a Dump Acre back)
|
||||
* Placing regular land acres in the Ocean/Border acres, and dropping items in those acres. (The game doesn't have save data for those acres, and could possibly crash. You will definitely lose whatever you place in those acres, though)
|
||||
* Not including at least one of each type of acre: Post Office, Dump (This will break your game), Nook's Shop Acre, Museum, Wishing Well, Police Station, Tailor's Shop, Lake & Beachfront w/ Dock (Also untested)
|
||||
|
||||
### Using the Town Editor Form
|
||||
The Town Editor allows you to customize your town to the fullest extent. You can place/move/remove items, buildings, trees, rocks, decorative items, etc! To select an item to place, either select it in the combo box on the top, or right click on an item on the map. The combo box text will then change and the ItemID & buried checkbox should update to the right of it. To place an item, just left click on the map where you want the item placed. You can change whether or not the item is buried (minus outdoor objects like trees & buildings) by checking/unchecking the buried checkbox. You can also toggle the acre background display with the "Show Background" checkbox!
|
||||
|
||||
![Town Editor](http://i.imgur.com/18YlO3K.png)
|
||||
|
||||
#### Town Editor Precautions
|
||||
As the case was with the Acre Editor, there are specific items you can place/remove that can possibly break your game. Here is a list of said items:
|
||||
* Dumps (This is confirmed. It will break your game if you place it in a non A-Acre & a non Dump Acre. The Town Editor will confirm with you that you wish to place a dump in an incorrect acre, if you do. Otherwise, no warning will be shown!)
|
||||
* Placing things in the top rows of the A-Acres that have "Occupied/Unavailable" as the item. (Not tested, I'm not sure what will happen if you change them. Feel free to, and let me know what happens!)
|
||||
* Removing all instances of a building (Neighbor houses, Nook's Shop, Tailor's Shop, etc. could break your game. This is not certain, but it's definitely possible.)
|
||||
* Placing multiple buildings/decorative items IS safe, as long as it is not a Dump.
|
||||
|
||||
### Using the Villager Editor Form
|
||||
Using the Villager Editor for is fairly safe. There are a few possible game breaking things that will be discussed in the section below. To change a villager, all you have to do is select a different one in the drop down box! It's that easy, really. If you do change a villager, make sure you add the correct house for them in the Town Editor, though! You can also edit their Personality and Catchphrase!
|
||||
|
||||
![Villager Editor](http://i.imgur.com/XylZA3v.png)
|
||||
|
||||
#### Village Editor Precautions
|
||||
There are a few cases where editing Villagers can cause strange results or break your game. The list is as follows:
|
||||
* Adding any of the Villagers below Punchy (They are corrupted, and can cause your game to reset whenever you enter their acre. I added them in case people wanted to play around with them.)
|
||||
* Not removing the old villagers house or not adding the new villagers house in the Town Editor (It's important that their house is removed/added. Where else would they live???)
|
||||
* Changing an empty villager slot (No Villager) to another villager (Not 100% sure this can break your game, but it caused some weird AI glitches in mine. If you add their correct house, things might be fine.)
|
||||
|
||||
### Using the Shop Editor Form
|
||||
This form allows you to edit Tom Nook's shop. It automatically detects which iteration of the shop exists in your town. You can change what is being sold, and how many bells you have spent/received from him.
|
||||
|
||||
![Shop Editor](https://puu.sh/tIKoj/e3b0269524.png)
|
||||
|
||||
### Using the Pocket Editor Form
|
||||
Editing your pockets is very safe and probably the easiest part of this editor to grasp. You can place ANY item in your pocket. Items, Buildings, Trees, Rocks, etc. Same as before, right click or change the combo box selection to set the selected item. Left click to place in that spot. This form also contains the Dresser editor (See below section for more info about it.)
|
||||
|
||||
![Pocket Editor](https://puu.sh/tIJXx/8fbd037246.png)
|
||||
|
||||
#### Inventory/Pocket Editor Precautions
|
||||
There is only one concern when using this editor.
|
||||
* If you place furniture into the first spot in the dresser, it will appear on top of the dresser. This is due to how the items are stored. The first item is stored on top of the dresser, so it will cause the "Stacked Furniture Glitch" that many speed runners use to duplicate items.
|
||||
|
||||
### Using the House Editor Form
|
||||
The House Editor is pretty simple as well. The floors are labeled for you. The top section is the "ground layer", where all furniture that goes on the floor should be placed. The section below it is the "top layer" where items that go on top of tables should be placed. This editor works exactly like the Town/Pocket Editors.
|
||||
|
||||
![House Editor](http://i.imgur.com/upNkKKz.png)
|
||||
|
||||
#### House Editor Precautions
|
||||
There are only a few precautions:
|
||||
* Placing outdoor objects (trees/buildings) in your house will not make them show up, and could break your game (although they just disappeared when I did it.)
|
||||
* Placing furniture on the "top layer" with nothing below them will place them on the floor instead (Won't break your game or anything, but the save editor will notify you every time you try to do it.)
|
||||
|
||||
### Changing Settings
|
||||
In the Settings Form, you can customize a few options that effect the save editor's behavior.
|
||||
![Settings Form](https://puu.sh/tIK8r/3835737ec3.png)
|
||||
|
||||
### Saving Your Changes
|
||||
Until you click File > Save, none of your changes will be commited. You must do this when you are ready to save your game. It will overwrite your old file, so make a backup if you're experimenting!
|
||||
|
||||
![Save File](https://puu.sh/toNoF/0a84b27f2c.png)
|
||||
|
||||
## Other Questions
|
||||
Message me on Reddit (Cuyler_36) or on Github. I will do my best to help you with whatever you may need.
|
||||
|
||||
## Helping with the Editor
|
||||
If you would like to contribute, I would appreciate it. Currently, I need someone to make graphics for the island acres, and possibly also for every acre. This would be nice, as it would give the user a feel of what the acre actually looks like.
|
BIN
Resources/AC Save Editor Logo.ico
Normal file
After Width: | Height: | Size: 361 KiB |
BIN
Resources/ACSE_Logo_2.ico
Normal file
After Width: | Height: | Size: 361 KiB |
52
Resources/AC_Acres_en.txt
Normal file
|
@ -0,0 +1,52 @@
|
|||
//Building Acres
|
||||
0x0118, Dump #1
|
||||
0x0294, Dump #2
|
||||
0x0298, Dump #3
|
||||
0x0154, Train Station #1
|
||||
0x02F0, Train Station #2
|
||||
0x02F4, Train Station #3
|
||||
0x034C, Police Station #1
|
||||
0x0350, Police Station #2
|
||||
0x0354, Police Station #3
|
||||
0x0358, Player Houses #1
|
||||
0x035C, Player Houses #2
|
||||
0x0360, Player Houses #3
|
||||
0x0364, Wishing Well #1
|
||||
0x0368, Wishing Well #2
|
||||
0x036C, Wishing Well #3
|
||||
0x0370, Post Office #1
|
||||
0x0380, Post Office #2
|
||||
0x0384, Post Office #3
|
||||
0x0374, Nook's Shop #1
|
||||
0x0378, Nook's Shop #2
|
||||
0x037C, Nook's Shop #3
|
||||
0x0480, Museum #1
|
||||
0x0484, Museum #2
|
||||
0x0488, Museum #3
|
||||
0x048C, Tailor's Shop #1
|
||||
0x0490, Tailor's Shop #2
|
||||
0x0494, Tailor's Shop #3
|
||||
//Border Acres
|
||||
0x0324, Upper Border Cliff (w/ Train Tracks)
|
||||
0x0328, Upper Border Cliff (w/ River & Tracks)
|
||||
0x032C, Left Border Cliff #1
|
||||
0x0330, Left Border Cliff #1 <=> #2
|
||||
0x0334, Left Border Cliff #2
|
||||
0x0338, Right Border Cliff #1
|
||||
0x033C, Right Border Cliff #1 <=> #2
|
||||
0x0340, Right Border Cliff #2
|
||||
0x0344, Left Border Cliff (w/ Train Tunnel) #2 <=> #3
|
||||
0x0348, Right Border Cliff (w/ Train Tunnel) #2 <=> #3
|
||||
0x03B4, Left Ocean Border Cliff
|
||||
0x03B8, Right Ocean Border Cliff
|
||||
//Grass Acres
|
||||
0x0094, Grass Acre #1
|
||||
0x0098, Grass Acre #2
|
||||
0x0274, Grass Acre #3
|
||||
0x0278, Grass Acre #4
|
||||
0x027C, Grass Acre #5
|
||||
0x0280, Grass Acre #6
|
||||
0x0284, Grass Acre #7
|
||||
0x0288, Grass Acre #8
|
||||
0x028C, Grass Acre #9
|
||||
0x0290, Grass Acre #10
|
2577
Resources/AC_Items_en.txt
Normal file
239
Resources/AC_Villagers_en.txt
Normal file
|
@ -0,0 +1,239 @@
|
|||
0x0000, No Villager
|
||||
0xE000, Bob
|
||||
0xE001, Olivia
|
||||
0xE002, Mitzi
|
||||
0xE003, Kiki
|
||||
0xE004, Tangy
|
||||
0xE005, Kabuki
|
||||
0xE006, Tabby
|
||||
0xE007, Monique
|
||||
0xE008, Stinky
|
||||
0xE009, Purrl
|
||||
0xE00A, Kitty
|
||||
0xE00B, Tom
|
||||
0xE00C, Rosie
|
||||
0xE00D, Nosegay
|
||||
0xE00E, Zoe
|
||||
0xE00F, Pango
|
||||
0xE010, Cyrano
|
||||
0xE011, Snooty
|
||||
0xE012, Teddy
|
||||
0xE013, Chow
|
||||
0xE014, Dozer
|
||||
0xE015, Nate
|
||||
0xE016, Groucho
|
||||
0xE017, Tutu
|
||||
0xE018, Ursala
|
||||
0xE019, Grizzly
|
||||
0xE01A, Pinky
|
||||
0xE01B, Jay
|
||||
0xE01C, Twiggy
|
||||
0xE01D, Anchovy
|
||||
0xE01E, Piper
|
||||
0xE01F, Admiral
|
||||
0xE020, Otis
|
||||
0xE021, Robin
|
||||
0xE022, Midge
|
||||
0xE023, Ace
|
||||
0xE024, Twirp
|
||||
0xE025, Chuck
|
||||
0xE026, Stu
|
||||
0xE027, Goose
|
||||
0xE028, Betty
|
||||
0xE029, Hector
|
||||
0xE02A, Egbert
|
||||
0xE02B, Ava
|
||||
0xE02C, Hank
|
||||
0xE02D, Leigh
|
||||
0xE02E, Rhoda
|
||||
0xE02F, Vladimir
|
||||
0xE030, Murphy
|
||||
0xE031, Cupcake
|
||||
0xE032, Kody
|
||||
0xE033, Maple
|
||||
0xE034, Pudge
|
||||
0xE035, Olive
|
||||
0xE036, Poncho
|
||||
0xE037, Bluebear
|
||||
0xE038, Patty
|
||||
0xE039, Petunia
|
||||
0xE03A, Bessie
|
||||
0xE03B, Belle
|
||||
0xE03C, Alfonso
|
||||
0xE03D, Boots
|
||||
0xE03E, Liz
|
||||
0xE03F, Biskit
|
||||
0xE040, Goldie
|
||||
0xE041, Daisy
|
||||
0xE042, Lucky
|
||||
0xE043, Portia
|
||||
0xE044, Maddie
|
||||
0xE045, Butch
|
||||
0xE046, Bill
|
||||
0xE047, Pompom
|
||||
0xE048, Joey
|
||||
0xE049, Scoot
|
||||
0xE04A, Derwin
|
||||
0xE04B, Freckles
|
||||
0xE04C, Paolo
|
||||
0xE04D, Dizzy
|
||||
0xE04E, Axel
|
||||
0xE04F, Emerald
|
||||
0xE050, Tad
|
||||
0xE051, Wart Jr.
|
||||
0xE052, Cousteau
|
||||
0xE053, Puddles
|
||||
0xE054, Lily
|
||||
0xE055, Jeremiah
|
||||
0xE056, Huck
|
||||
0xE057, Camofrog
|
||||
0xE058, Ribbot
|
||||
0xE059, Prince
|
||||
0xE05A, Jambette
|
||||
0xE05B, Billy
|
||||
0xE05C, Chevere
|
||||
0xE05D, Iggy
|
||||
0xE05E, Gruff
|
||||
0xE05F, Sven
|
||||
0xE060, Velma
|
||||
0xE061, Jane
|
||||
0xE062, Cesar
|
||||
0xE063, Louie
|
||||
0xE064, Peewee
|
||||
0xE065, Rollo
|
||||
0xE066, Bubbles
|
||||
0xE067, Bertha
|
||||
0xE068, Elmer
|
||||
0xE069, Winnie
|
||||
0xE06A, Savannah
|
||||
0xE06B, Ed
|
||||
0xE06C, Cleo
|
||||
0xE06D, Peaches
|
||||
0xE06E, Buck
|
||||
0xE06F, Carrie
|
||||
0xE070, Mathilda
|
||||
0xE071, Marcy
|
||||
0xE072, Kitt
|
||||
0xE073, Valise
|
||||
0xE074, Astrid
|
||||
0xE075, Sydney
|
||||
0xE076, Gonzo
|
||||
0xE077, Ozzie
|
||||
0xE078, Yuka
|
||||
0xE079, Huggy
|
||||
0xE07A, Rex
|
||||
0xE07B, Aziz
|
||||
0xE07C, Leopold
|
||||
0xE07D, Samson
|
||||
0xE07E, Penny
|
||||
0xE07F, Dora
|
||||
0xE080, Chico
|
||||
0xE081, Candi
|
||||
0xE082, Rizzo
|
||||
0xE083, Anicotti
|
||||
0xE084, Limberg
|
||||
0xE085, Carmen
|
||||
0xE086, Octavian
|
||||
0xE087, Sandy
|
||||
0xE088, Sprocket
|
||||
0xE089, Rio
|
||||
0xE08A, Queenie
|
||||
0xE08B, Apollo
|
||||
0xE08C, Buzz
|
||||
0xE08D, Quetzel
|
||||
0xE08E, Amelia
|
||||
0xE08F, Pierce
|
||||
0xE090, Roald
|
||||
0xE091, Aurora
|
||||
0xE092, Hopper
|
||||
0xE093, Cube
|
||||
0xE094, Puck
|
||||
0xE095, Gwen
|
||||
0xE096, Friga
|
||||
0xE097, Curly
|
||||
0xE098, Truffles
|
||||
0xE099, Spork
|
||||
0xE09A, Hugh
|
||||
0xE09B, Rasher
|
||||
0xE09C, Sue E
|
||||
0xE09D, Hambo
|
||||
0xE09E, Lucy
|
||||
0xE09F, Cobb
|
||||
0xE0A0, Boris
|
||||
0xE0A1, Bunnie
|
||||
0xE0A2, Doc
|
||||
0xE0A3, Gaston
|
||||
0xE0A4, Coco
|
||||
0xE0A5, Gabi
|
||||
0xE0A6, Dotty
|
||||
0xE0A7, Genji
|
||||
0xE0A8, Snake
|
||||
0xE0A9, Claude
|
||||
0xE0AA, Tank
|
||||
0xE0AB, Spike
|
||||
0xE0AC, Tiara
|
||||
0xE0AD, Vesta
|
||||
0xE0AE, Filbert
|
||||
0xE0AF, Hazel
|
||||
0xE0B0, Peanut
|
||||
0xE0B1, Pecan
|
||||
0xE0B2, Ricky
|
||||
0xE0B3, Static
|
||||
0xE0B4, Mint
|
||||
0xE0B5, Nibbles
|
||||
0xE0B6, Tybalt
|
||||
0xE0B7, Rolf
|
||||
0xE0B8, Bangle
|
||||
0xE0B9, Lobo
|
||||
0xE0BA, Freya
|
||||
0xE0BB, Chief
|
||||
0xE0BC, Weber
|
||||
0xE0BD, Mallary
|
||||
0xE0BE, Wolfgang
|
||||
0xE0BF, Hornsby
|
||||
0xE0C0, Oxford
|
||||
0xE0C1, T-Bone
|
||||
0xE0C2, Biff
|
||||
0xE0C3, Opal
|
||||
0xE0C4, Bones
|
||||
0xE0C5, Bea
|
||||
0xE0C6, Bitty
|
||||
0xE0C7, Rocco
|
||||
0xE0C8, Lulu
|
||||
0xE0C9, Blaire
|
||||
0xE0CA, Sally
|
||||
0xE0CB, Ellie
|
||||
0xE0CC, Eloise
|
||||
0xE0CD, Alli
|
||||
0xE0CE, Pippy
|
||||
0xE0CF, Eunice
|
||||
0xE0D0, Baabara
|
||||
0xE0D1, Fang
|
||||
0xE0D2, Deena
|
||||
0xE0D3, Pate
|
||||
0xE0D4, Stella
|
||||
0xE0D5, Cashmere
|
||||
0xE0D6, Woolio
|
||||
0xE0D7, Cookie
|
||||
//Beginning of Islanders
|
||||
0xE0D8, Maelle
|
||||
0xE0D9, O'Hare
|
||||
0xE0DA, Bliss
|
||||
0xE0DB, Drift
|
||||
0xE0DC, Bud
|
||||
0xE0DD, Boomer
|
||||
0xE0DE, Elina
|
||||
0xE0DF, Flash
|
||||
0xE0E0, Dobie
|
||||
0xE0E1, Flossie
|
||||
0xE0E2, Annalise
|
||||
0xE0E3, Plucky
|
||||
0xE0E4, Faith
|
||||
0xE0E5, Yodel
|
||||
0xE0E6, Rowan
|
||||
0xE0E7, June
|
||||
0xE0E8, Cheri
|
||||
0xE0E9, Pigleg
|
||||
0xE0EA, Ankha
|
||||
//End of Islanders
|
||||
0xE0EB, Punchy
|
374
Resources/CF_Acres_en.txt
Normal file
|
@ -0,0 +1,374 @@
|
|||
//Transition Acres
|
||||
0x0000, 0
|
||||
0x0001, 1
|
||||
0x0002, 2
|
||||
0x0003, 3
|
||||
0x0004, 4
|
||||
0x0005, 5
|
||||
0x0006, 6 (River EW)
|
||||
0x0007, 7 (River EW)
|
||||
0x0008, 8 (Ramp)
|
||||
0x0009, 9 (Ramp)
|
||||
0x000A, 10 (Ramp)
|
||||
0x000B, 11 (Ramp)
|
||||
0x000C, 12
|
||||
0x000D, 13
|
||||
0x000E, 14
|
||||
0x000F, 15
|
||||
0x0010, 16
|
||||
0x0011, 17
|
||||
0x0012, 18
|
||||
0x0013, 19
|
||||
0x0014, 20 (River NS)
|
||||
0x0015, 21 (River NS)
|
||||
0x0016, 22 (Ramp)
|
||||
0x0017, 23 (Ramp)
|
||||
0x0018, 24 (Ramp)
|
||||
0x0019, 25 (Ramp)
|
||||
0x001A, 26
|
||||
0x001B, 27
|
||||
0x001C, 28
|
||||
0x001D, 29
|
||||
0x001E, 30
|
||||
0x001F, 31
|
||||
0x0020, 32
|
||||
0x0021, 33
|
||||
0x0022, 34 (River NS)
|
||||
0x0023, 35 (River NS)
|
||||
0x0024, 36 (River NS)
|
||||
0x0025, 37 (River NS)
|
||||
0x0026, 38 (Ramp)
|
||||
0x0027, 39 (Ramp)
|
||||
0x0028, 40 (Ramp)
|
||||
0x0029, 41 (Ramp)
|
||||
0x002A, 42
|
||||
0x002B, 43
|
||||
0x002C, 44
|
||||
0x002D, 45
|
||||
0x002E, 46
|
||||
0x002F, 47
|
||||
0x0030, 48
|
||||
0x0031, 49
|
||||
0x0032, 50 (River NS)
|
||||
0x0033, 51 (River NS)
|
||||
0x0034, 52 (Ramp)
|
||||
0x0035, 53 (Ramp)
|
||||
0x0036, 54 (Ramp)
|
||||
0x0037, 55 (Ramp)
|
||||
0x0038, 56
|
||||
0x0039, 57
|
||||
0x003A, 58
|
||||
0x003B, 59
|
||||
0x003C, 60
|
||||
0x003D, 61
|
||||
0x003E, 62
|
||||
0x003F, 63
|
||||
0x0040, 64 (River NS)
|
||||
0x0041, 65 (River NS)
|
||||
0x0042, 66 (Ramp)
|
||||
0x0043, 67 (Ramp)
|
||||
0x0044, 68 (Ramp)
|
||||
0x0045, 69 (Ramp)
|
||||
0x0046, 70
|
||||
0x0047, 71
|
||||
0x0048, 72
|
||||
0x0049, 73
|
||||
0x004A, 74
|
||||
0x004B, 75
|
||||
0x004C, 76 (Ramp)
|
||||
0x004D, 77 (Ramp)
|
||||
0x004E, 78 (Ramp)
|
||||
0x004F, 79 (Ramp)
|
||||
0x0050, 80
|
||||
0x0051, 81
|
||||
0x0052, 82
|
||||
0x0053, 83
|
||||
0x0054, 84
|
||||
0x0055, 85
|
||||
0x0056, 86
|
||||
0x0057, 87
|
||||
0x0058, 88 (River NS)
|
||||
0x0059, 89 (River NS)
|
||||
0x005A, 90 (Ramp)
|
||||
0x005B, 91 (Ramp)
|
||||
0x005C, 92 (Ramp)
|
||||
0x005D, 93 (Ramp)
|
||||
0x005E, 94 (River EW)
|
||||
0x005F, 95 (River EW)
|
||||
//Grass Acres
|
||||
0x0060, 0
|
||||
0x0061, 1
|
||||
0x0062, 2
|
||||
0x0063, 3
|
||||
0x0064, 4
|
||||
0x0065, 5
|
||||
0x0066, 6 (Pond)
|
||||
0x0067, 7 (Pond)
|
||||
0x0068, 8 (Pond)
|
||||
0x0069, 9 (Pond)
|
||||
0x006A, 10 (Pond)
|
||||
0x006B, 11 (Pond)
|
||||
//Building Acres
|
||||
0x006C, 12 (Gate)
|
||||
0x006D, 13 (Gate)
|
||||
0x006E, 14 (Gate)
|
||||
0x006F, 15 (Gate)
|
||||
0x0070, 16 (Gate + Pond)
|
||||
0x0071, 17 (Gate + Pond)
|
||||
0x0072, 18 (Museum)
|
||||
0x0073, 19 (Museum)
|
||||
0x0074, 20 (Museum + Pond)
|
||||
0x0075, 21 (Museum + Pond)
|
||||
0x0076, 22 (Museum + Pond)
|
||||
0x0077, 23 (Museum + Pond)
|
||||
0x0078, 24 (Nook's)
|
||||
0x0079, 25 (Nook's)
|
||||
0x007A, 26 (Nook's)
|
||||
0x007B, 27 (Nook's)
|
||||
0x007C, 28 (Nook's + Pond)
|
||||
0x007D, 29 (Nook's + Pond)
|
||||
0x007E, 30 (Townhall)
|
||||
0x007F, 31 (Townhall)
|
||||
0x0080, 32 (Townhall)
|
||||
0x0081, 33 (Townhall)
|
||||
0x0082, 34 (Townhall)
|
||||
0x0083, 35 (Townhall)
|
||||
0x0084, 36 (Tailor)
|
||||
0x0085, 37 (Tailor)
|
||||
0x0086, 38 (Tailor + Pond)
|
||||
0x0087, 39 (Tailor + Pond)
|
||||
0x0088, 40 (Tailor + Pond)
|
||||
0x0089, 41 (Tailor + Pond)
|
||||
//Beachfront Acres
|
||||
0x008A, 0
|
||||
0x008B, 1
|
||||
0x008C, 2
|
||||
0x008D, 3
|
||||
0x008E, 4
|
||||
0x008F, 5
|
||||
0x0090, 6
|
||||
0x0091, 7
|
||||
0x0092, 8
|
||||
0x0093, 9
|
||||
0x0094, 10
|
||||
0x0095, 11
|
||||
0x0096, 12 (River W)
|
||||
0x0097, 13 (River W)
|
||||
0x0098, 14 (River W)
|
||||
0x0099, 15 (River W)
|
||||
0x009A, 16 (River W + Bridge)
|
||||
0x009B, 17 (River W + Bridge)
|
||||
0x009C, 18 (River W + Bridge)
|
||||
0x009D, 19 (River W + Bridge)
|
||||
0x009E, 20 (River N)
|
||||
0x009F, 21 (River N)
|
||||
0x00A0, 22 (River N)
|
||||
0x00A1, 23 (River N)
|
||||
0x00A2, 24 (River N)
|
||||
0x00A3, 25 (River N)
|
||||
0x00A4, 26 (River N + Bridge)
|
||||
0x00A5, 27 (River N + Bridge)
|
||||
0x00A6, 28 (River N + Bridge)
|
||||
0x00A7, 29 (River N + Bridge)
|
||||
0x00A8, 30 (River N + Bridge)
|
||||
0x00A9, 31 (River N + Bridge)
|
||||
0x00AA, 32 (River NE)
|
||||
0x00AB, 33 (River NE)
|
||||
0x00AC, 34 (River NE)
|
||||
0x00AD, 35 (River NE)
|
||||
0x00AE, 36 (River NE + Bridge)
|
||||
0x00AF, 37 (River NE + Bridge)
|
||||
0x00B0, 38 (River NE + Bridge)
|
||||
0x00B1, 39 (River NE + Bridge)
|
||||
0x00B2, 40 (River NW)
|
||||
0x00B3, 41 (River NW)
|
||||
0x00B4, 42 (River NW)
|
||||
0x00B5, 43 (River NW)
|
||||
0x00B6, 44 (River NW + Bridge)
|
||||
0x00B7, 45 (River NW + Bridge)
|
||||
0x00B8, 46 (River NW + Bridge)
|
||||
0x00B9, 47 (River NW + Bridge)
|
||||
0x00BA, 48 (River E)
|
||||
0x00BB, 49 (River E)
|
||||
0x00BC, 50 (River E)
|
||||
0x00BD, 51 (River E)
|
||||
0x00BE, 52 (River E + Bridge)
|
||||
0x00BF, 53 (River E + Bridge)
|
||||
0x00C0, 54 (River E + Bridge)
|
||||
0x00C1, 55 (River E + Bridge)
|
||||
//Border Acres
|
||||
0x00C2, 0 (Left)
|
||||
0x00C3, 1 (Left)
|
||||
0x00C4, 2 (Transition)
|
||||
0x00C5, 3 (Transition)
|
||||
0x00C6, 4 (Ocean Transition)
|
||||
0x00C7, 5 (Ocean Transition)
|
||||
0x00C8, 6 (Top)
|
||||
0x00C9, 7 (Top)
|
||||
0x00CA, 8 (Gate)
|
||||
0x00CB, 9 (Gate)
|
||||
0x00CC, 10 (Waterfall)
|
||||
0x00CD, 11 (Waterfall)
|
||||
0x00CE, 12 (Top Left)
|
||||
0x00CF, 13 (Top Left)
|
||||
0x00D0, 14 (Top Right)
|
||||
0x00D1, 15 (Top Right)
|
||||
0x00D2, 16 (Right)
|
||||
0x00D3, 17 (Right)
|
||||
0x00D4, 18 (Transition)
|
||||
0x00D5, 19 (Transition)
|
||||
0x00D6, 20 (Ocean Transition)
|
||||
0x00D7, 21 (Ocean Transition)
|
||||
0x00D8, 22 (Open Ocean)
|
||||
0x00D9, 23 (Open Ocean)
|
||||
//River Acres
|
||||
0x00DA, 0 (EW)
|
||||
0x00DB, 1 (EW)
|
||||
0x00DC, 2 (EW)
|
||||
0x00DD, 3 (EW)
|
||||
0x00DE, 4 (EW)
|
||||
0x00DF, 5 (EW)
|
||||
0x00E0, 6 (EW + Bridge)
|
||||
0x00E1, 7 (EW + Bridge)
|
||||
0x00E2, 8 (EW + Bridge)
|
||||
0x00E3, 9 (EW + Bridge)
|
||||
0x00E4, 10 (EW + Bridge)
|
||||
0x00E5, 11 (EW + Bridge)
|
||||
0x00E6, 12 (EW + Lake)
|
||||
0x00E7, 13 (EW + Lake)
|
||||
0x00E8, 14 (EW + Lake)
|
||||
0x00E9, 15 (EW + Lake)
|
||||
0x00EA, 16 (SW)
|
||||
0x00EB, 17 (SW)
|
||||
0x00EC, 18 (SW)
|
||||
0x00ED, 19 (SW)
|
||||
0x00EE, 20 (SW)
|
||||
0x00EF, 21 (SW)
|
||||
0x00F0, 22 (SW)
|
||||
0x00F1, 23 (SW)
|
||||
0x00F2, 24 (SW + Bridge)
|
||||
0x00F3, 25 (SW + Bridge)
|
||||
0x00F4, 26 (SW)
|
||||
0x00F5, 27 (SW + Bridge)
|
||||
0x00F6, 28 (SW + Bridge)
|
||||
0x00F7, 29 (SW + Bridge)
|
||||
0x00F8, 30 (SW + Bridge)
|
||||
0x00F9, 31 (SW + Bridge)
|
||||
0x00FA, 32 (SW + Lake)
|
||||
0x00FB, 33 (SW + Lake)
|
||||
0x00FC, 34 (SW + Lake)
|
||||
0x00FD, 35 (SW + Lake)
|
||||
0x00FE, 36 (EWS)
|
||||
0x00FF, 37 (EWS)
|
||||
0x0100, 38 (NS)
|
||||
0x0101, 39 (NS)
|
||||
0x0102, 40 (NS)
|
||||
0x0103, 41 (NS)
|
||||
0x0104, 42 (NS)
|
||||
0x0105, 43 (NS)
|
||||
0x0106, 44 (NS + Bridge)
|
||||
0x0107, 45 (NS + Bridge)
|
||||
0x0108, 46 (NS + Bridge)
|
||||
0x0109, 47 (NS + Bridge)
|
||||
0x010A, 48 (NS + Bridge)
|
||||
0x010B, 49 (NS + Bridge)
|
||||
0x010C, 50 (Waterfall)
|
||||
0x010D, 51 (Waterfall)
|
||||
0x010E, 52 (Waterfall)
|
||||
0x010F, 53 (Waterfall)
|
||||
0x0110, 54 (Waterfall)
|
||||
0x0111, 55 (Waterfall)
|
||||
0x0112, 56 (NS + Lake)
|
||||
0x0113, 57 (NS + Lake)
|
||||
0x0114, 58 (NS + Lake)
|
||||
0x0115, 59 (NS + Lake)
|
||||
0x0116, 60 (NE)
|
||||
0x0117, 61 (NE)
|
||||
0x0118, 62 (NE)
|
||||
0x0119, 63 (NE)
|
||||
0x011A, 64 (NE)
|
||||
0x011B, 65 (NE)
|
||||
0x011C, 66 (NE)
|
||||
0x011D, 67 (NE)
|
||||
0x011E, 68 (NE + Bridge)
|
||||
0x011F, 69 (NE + Bridge)
|
||||
0x0120, 70 (NE + Bridge)
|
||||
0x0121, 71 (NE + Bridge)
|
||||
0x0122, 72 (NE + Bridge)
|
||||
0x0123, 73 (NE + Bridge)
|
||||
0x0124, 74 (NE + Bridge)
|
||||
0x0125, 75 (NE + Bridge)
|
||||
0x0126, 76 (NE + Lake)
|
||||
0x0127, 77 (NE + Lake)
|
||||
0x0128, 78 (NE + Lake)
|
||||
0x0129, 79 (NE + Lake)
|
||||
0x012A, 80 (NSE)
|
||||
0x012B, 81 (NSE)
|
||||
0x012C, 82 (NSE)
|
||||
0x012D, 83 (NSE)
|
||||
0x012E, 84 (NW)
|
||||
0x012F, 85 (NW)
|
||||
0x0130, 86 (NW)
|
||||
0x0131, 87 (NW)
|
||||
0x0132, 88 (NW)
|
||||
0x0133, 89 (NW)
|
||||
0x0134, 90 (NW)
|
||||
0x0135, 91 (NW)
|
||||
0x0136, 92 (NW + Bridge)
|
||||
0x0137, 93 (NW + Bridge)
|
||||
0x0138, 94 (NW + Bridge)
|
||||
0x0139, 95 (NW + Bridge)
|
||||
0x013A, 96 (NW + Bridge)
|
||||
0x013B, 97 (NW + Bridge)
|
||||
0x013C, 98 (NW + Bridge)
|
||||
0x013D, 99 (NW + Bridge)
|
||||
0x013E, 100 (NW + Lake)
|
||||
0x013F, 101 (NW + Lake)
|
||||
0x0140, 102 (NW + Lake)
|
||||
0x0141, 103 (NW + Lake)
|
||||
0x0142, 104 (EWN)
|
||||
0x0143, 105 (EWN)
|
||||
0x0144, 106 (EWN)
|
||||
0x0145, 107 (EWN)
|
||||
0x0146, 108 (NSW)
|
||||
0x0147, 109 (NSW)
|
||||
0x0148, 110 (NSW)
|
||||
0x0149, 111 (NSW)
|
||||
0x014A, 112 (EW)
|
||||
0x014B, 113 (EW)
|
||||
0x014C, 114 (EW)
|
||||
0x014D, 115 (EW)
|
||||
0x014E, 116 (EW)
|
||||
0x014F, 117 (EW)
|
||||
0x0150, 118 (EW + Bridge)
|
||||
0x0151, 119 (EW + Bridge)
|
||||
0x0152, 120 (EW + Bridge)
|
||||
0x0153, 121 (EW + Bridge)
|
||||
0x0154, 122 (EW + Bridge)
|
||||
0x0155, 123 (EW + Bridge)
|
||||
0x0156, 124 (EW + Lake)
|
||||
0x0157, 125 (EW + Lake)
|
||||
0x0158, 126 (EW + Lake)
|
||||
0x0159, 127 (EW + Lake)
|
||||
0x015A, 128 (SE)
|
||||
0x015B, 129 (SE)
|
||||
0x015C, 130 (SE)
|
||||
0x015D, 131 (SE)
|
||||
0x015E, 132 (SE)
|
||||
0x015F, 133 (SE)
|
||||
0x0160, 134 (SE)
|
||||
0x0161, 135 (SE)
|
||||
0x0162, 136 (SE + Bridge)
|
||||
0x0163, 137 (SE + Bridge)
|
||||
0x0164, 138 (SE + Bridge)
|
||||
0x0165, 139 (SE + Bridge)
|
||||
0x0166, 140 (SE + Bridge)
|
||||
0x0167, 141 (SE + Bridge)
|
||||
0x0168, 142 (SE + Bridge)
|
||||
0x0169, 143 (SE + Bridge)
|
||||
0x016A, 144 (SE + Lake)
|
||||
0x016B, 145 (SE + Lake)
|
||||
0x016C, 146 (SE + Lake)
|
||||
0x016D, 147 (SE + Lake)
|
||||
0x016E, 148 (EWS)
|
||||
0x016F, 149 (EWS)
|
2822
Resources/CF_Items_en.txt
Normal file
BIN
Resources/Images/1.jpg
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
Resources/Images/10.jpg
Normal file
After Width: | Height: | Size: 520 B |
BIN
Resources/Images/100.jpg
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
Resources/Images/11.jpg
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
Resources/Images/12.jpg
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Resources/Images/13.jpg
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
Resources/Images/14.jpg
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
Resources/Images/15.jpg
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Resources/Images/16.jpg
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
Resources/Images/17.jpg
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Resources/Images/18.jpg
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Resources/Images/19.jpg
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
Resources/Images/2.jpg
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
Resources/Images/20.jpg
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
Resources/Images/21.jpg
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Resources/Images/22.jpg
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
Resources/Images/23.jpg
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
Resources/Images/24.jpg
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Resources/Images/25.jpg
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
Resources/Images/26.jpg
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Resources/Images/27.jpg
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Resources/Images/28.jpg
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
Resources/Images/29.jpg
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Resources/Images/3.jpg
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
Resources/Images/30.jpg
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
Resources/Images/31.jpg
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
Resources/Images/32.jpg
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Resources/Images/33.jpg
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Resources/Images/34.jpg
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
Resources/Images/35.jpg
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
Resources/Images/36.jpg
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Resources/Images/37.jpg
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
Resources/Images/38.jpg
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
Resources/Images/39.jpg
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
Resources/Images/4.jpg
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
Resources/Images/40.jpg
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
Resources/Images/41.jpg
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
Resources/Images/42.jpg
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
Resources/Images/43.jpg
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
Resources/Images/44.jpg
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
Resources/Images/45.jpg
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Resources/Images/46.jpg
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Resources/Images/47.jpg
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
Resources/Images/48.jpg
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
Resources/Images/49.jpg
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
Resources/Images/5.jpg
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
Resources/Images/50.jpg
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
Resources/Images/51.jpg
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
Resources/Images/52.jpg
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
Resources/Images/53.jpg
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
Resources/Images/54.jpg
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
Resources/Images/55.jpg
Normal file
After Width: | Height: | Size: 1.2 KiB |