2012-08-05 2 views
3

Infinite Engine (Baldur 's gate, planescape Torment 등)에서 만든 게임에 대한 modding 도구를 개발하려고합니다. 어떤 종류의 데이터 구조가 Infinity 엔진 파일에 있는지 알기 때문에 byte [] 내용의 일부 객체를 매핑하고 있습니다. 그러나 그것은 약간의 성과가 부족하고 나는 이것에 만족하지 않습니다.올바른 인코딩으로 고정 char 배열 읽기

관리 세계에 매핑 된 객체는 구조체이며 구조체의 바이트 수를 나타냅니다. 따라서 안전하지 않은 코드로 매핑 프로세스를 만들기로 결정했습니다. 나는 UINT와 관련하여 아무런 문제가 없지만 문자열 유형에서 char [] 인코딩 문제에 문제가 있습니다. 예를 들어

, 당신이이 개체를 매핑하는 방법입니다

http://iesdp.gibberlings3.net/file_formats/ie_formats/gam_v2.0.htm

[StructLayout(LayoutKind.Explicit, Size = 180,CharSet = CharSet.Ansi)] 
public unsafe struct Header 
{ 
    [FieldOffset(0)] 
    public fixed char Signature[4]; 

    [FieldOffset(0x0004)] 
    public fixed char Version[4]; 

    [FieldOffset(0x0008)] public uint GameTime; 

    [FieldOffset(0x000c)] public ushort SelectedFormation; 

    [FieldOffset(0x000e)] public ushort FormationButton1; 

    [FieldOffset(0x0010)] public ushort FormationButton2; 

    [FieldOffset(0x0012)] public ushort FormationButton3; 

    [FieldOffset(0x0014)] public ushort FormationButton4; 

    [FieldOffset(0x0016)] public ushort FormationButton5; 

    [FieldOffset(0x0018)] public uint PartyGold; 

    [FieldOffset(0x001c)] public ushort NpcStructCountForPartyEx; 

    [FieldOffset(0x001e)] public ushort WeatherBitfield; 

    [FieldOffset(0x0020)] public uint NpcStructOffsetForParty; 

    [FieldOffset(0x0024)] public uint NpcStructCountForPartyInc; 

    [FieldOffset(0x0028)] public uint Unknown1; 

    [FieldOffset(0x002c)] public uint Unknown2; 

    [FieldOffset(0x0030)] public uint NpcStructOffsetForNonParty; 

    [FieldOffset(0x0034)] public uint NpcStructCountForNonParty; 

    [FieldOffset(0x0038)] public uint GlobalNamespaceVarOffset; 

    [FieldOffset(0x003c)] public uint GlobalNamespaceVarCount; 

    [FieldOffset(0x0040)] public fixed char MainArea[8]; 

    [FieldOffset(0x0048)] public uint FamilarExtraOffset; 

    [FieldOffset(0x004c)] public uint JournalEntriesCount; 

    [FieldOffset(0x0050)] public uint JournalEntriesOffset; 

    [FieldOffset(0x0054)] public uint PartyReputation; 

    [FieldOffset(0x0058)] public fixed char CurrentArea [8]; 

    [FieldOffset(0x0060)] public uint GuiFlags; 

    [FieldOffset(0x0064)] public uint LoadingProgress; 

    [FieldOffset(0x0068)] public uint FamilarInfoOffset; 

    [FieldOffset(0x006c)] public uint StoredLocOffset; 

    [FieldOffset(0x0070)] public uint StoredLocCount; 

    [FieldOffset(0x0074)] public uint GameTimeSec; 

    [FieldOffset(0x0078)] public uint PocketPlaneOffset; 

    [FieldOffset(0x007c)] public uint PocketPlaneCount; 

    [FieldOffset(0x0080)] public fixed byte Unknown3 [52]; 
} 

, C#에서 구조체 GAM 파일의 헤더를 볼 수 있습니다;

 string path = @"C:\Baldur.gam"; 

     byte[] content = IoHelper.ReadBinaryFile(path); 

     unsafe 
     { 
      fixed (byte* pointContent = content) 
      { 
       Header* header = (Header*) pointContent; 
      } 
     } 

나는 데 문자 서명의 결과입니다;

[0] = 21,057 '剁' [1] = 13624 '㔸'

이러한 문자 정말 합리적인 아니다. 인코딩에 의한 것 같습니다. 누구든지 이것에 대한 해결책을 알고 있습니까? 또는 Encoding.ASCII.GetString을 사용하여 char 배열을 직접 읽어야합니까? 이 메서드를 사용하여 spesific 크기의 바이트 []를 읽으면 나는 진정한 결과를 얻습니다.

또한 이러한 종류의 구조에는 여러 가지 버전이 있습니다. 위의 샘플에서 볼 수 있듯이 V.2.0 버전의 Baldur 's Gate 2 Gam 파일이 있습니다. 그러나 Baldur 's Gate 1에서는 버전이 v.1.0으로 변경되어 내 방식과 호환되지 않습니다. 이 여러 가지 방법을 읽고 모델에 매핑 한 다음 UI 레이어로 다시 보내고 싶습니다. 다른 종류의 버전을 읽으려는 제안이 있습니까? 사전에

감사합니다.

답변

2

나는 나의 문제를 해결한다.

나는 사람들이 물었다.

".NET 숯불에서 당신이 직접 캐스팅하는 경우 당신이 그것을 할 수 없습니다. 2 바이트입니다.이 작업을 수행하려면 마샬 클래스 PtrToStructureMethod을 사용할 수 있습니다"나는 문자열로 고정 바이트 멤버 교체

및 MarshalAs 속성 사용 처럼 ;

[FieldOffset(0x0004), MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)] 
    public string Version; 

내 매핑 코드를 다음으로 대체하십시오. 마법처럼

 string path = @"G:\Games\BGOrg\BGII - SoA\save\000000001-Quick-Save\Baldur.gam"; 

     byte[] content = IoHelper.ReadBinaryFile(path); 

     IntPtr unmanagedPointer = Marshal.AllocHGlobal(content.Length); 
     Marshal.Copy(content, 0, unmanagedPointer, content.Length); 

     Header header = (Header) Marshal.PtrToStructure(unmanagedPointer, typeof (Header)); 

작품 :

감사합니다.