-
Notifications
You must be signed in to change notification settings - Fork 238
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix/finish EMBI, add TGIN internal support, fix EXTN potential crash #76
Changes from all commits
8b0a235
fb52558
c6b10af
427b1a1
544eec3
b63a470
1f28c8e
481bcb4
86ba322
0653028
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace UndertaleModLib.Models | ||
{ | ||
// Not to be confused with the other "embedded" resources, this is a bit separate. | ||
// GMS2 only, see https://github.com/krzys-h/UndertaleModTool/issues/4#issuecomment-421844420 for rough structure, but doesn't appear commonly used | ||
public class UndertaleEmbeddedImage : UndertaleObject | ||
{ | ||
public UndertaleString Name; | ||
public UndertaleTexturePageItem TextureEntry; | ||
|
||
public UndertaleEmbeddedImage() | ||
{ | ||
} | ||
|
||
public void Serialize(UndertaleWriter writer) | ||
{ | ||
writer.WriteUndertaleString(Name); | ||
writer.WriteUndertaleObjectPointer(TextureEntry); | ||
} | ||
|
||
public void Unserialize(UndertaleReader reader) | ||
{ | ||
Name = reader.ReadUndertaleString(); | ||
TextureEntry = reader.ReadUndertaleObjectPointer<UndertaleTexturePageItem>(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ public class UndertaleFont : UndertaleNamedResource, INotifyPropertyChanged | |
private UndertaleTexturePageItem _Texture; | ||
private float _ScaleX; | ||
private float _ScaleY; | ||
private int _AscenderOffset; | ||
|
||
public UndertaleString Name { get => _Name; set { _Name = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name")); } } | ||
public UndertaleString DisplayName { get => _DisplayName; set { _DisplayName = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("DisplayName")); } } | ||
|
@@ -35,6 +36,7 @@ public class UndertaleFont : UndertaleNamedResource, INotifyPropertyChanged | |
public float ScaleX { get => _ScaleX; set { _ScaleX = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ScaleX")); } } | ||
public float ScaleY { get => _ScaleY; set { _ScaleY = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ScaleY")); } } | ||
public UndertalePointerList<Glyph> Glyphs { get; private set; } = new UndertalePointerList<Glyph>(); | ||
public int AscenderOffset { get => _AscenderOffset; set { _AscenderOffset = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("AscenderOffset")); } } | ||
|
||
public event PropertyChangedEventHandler PropertyChanged; | ||
|
||
|
@@ -45,16 +47,18 @@ public class Glyph : UndertaleObject, INotifyPropertyChanged | |
private ushort _SourceY; | ||
private ushort _SourceWidth; | ||
private ushort _SourceHeight; | ||
private ushort _Shift; | ||
private uint _Offset; // TODO: probably signed | ||
private short _Shift; | ||
private int _Offset; | ||
private UndertaleSimpleListShort<GlyphKerning> _Kerning; | ||
|
||
public ushort Character { get => _Character; set { _Character = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Character")); } } | ||
public ushort SourceX { get => _SourceX; set { _SourceX = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SourceX")); } } | ||
public ushort SourceY { get => _SourceY; set { _SourceY = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SourceY")); } } | ||
public ushort SourceWidth { get => _SourceWidth; set { _SourceWidth = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SourceWidth")); } } | ||
public ushort SourceHeight { get => _SourceHeight; set { _SourceHeight = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SourceHeight")); } } | ||
public ushort Shift { get => _Shift; set { _Shift = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Shift")); } } | ||
public uint Offset { get => _Offset; set { _Offset = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Offset")); } } | ||
public short Shift { get => _Shift; set { _Shift = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Shift")); } } | ||
public int Offset { get => _Offset; set { _Offset = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Offset")); } } | ||
public UndertaleSimpleListShort<GlyphKerning> Kerning { get => _Kerning; set { _Kerning = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Kerning")); } } | ||
|
||
public event PropertyChangedEventHandler PropertyChanged; | ||
|
||
|
@@ -66,7 +70,14 @@ public void Serialize(UndertaleWriter writer) | |
writer.Write(SourceWidth); | ||
writer.Write(SourceHeight); | ||
writer.Write(Shift); | ||
writer.Write(Offset); | ||
if (writer.undertaleData.GeneralInfo?.Major >= 2 || (writer.undertaleData.GeneralInfo?.Major == 1 && writer.undertaleData.GeneralInfo?.Build == 9999)) | ||
{ | ||
writer.Write((short)Offset); | ||
writer.WriteUndertaleObject(Kerning); | ||
} else | ||
{ | ||
writer.Write(Offset); | ||
} | ||
} | ||
|
||
public void Unserialize(UndertaleReader reader) | ||
|
@@ -76,8 +87,33 @@ public void Unserialize(UndertaleReader reader) | |
SourceY = reader.ReadUInt16(); | ||
SourceWidth = reader.ReadUInt16(); | ||
SourceHeight = reader.ReadUInt16(); | ||
Shift = reader.ReadUInt16(); | ||
Offset = reader.ReadUInt32(); | ||
Shift = reader.ReadInt16(); | ||
if (reader.undertaleData.GeneralInfo?.Major >= 2 || (reader.undertaleData.GeneralInfo?.Major == 1 && reader.undertaleData.GeneralInfo?.Build == 9999)) | ||
{ | ||
Offset = reader.ReadInt16(); | ||
Kerning = reader.ReadUndertaleObject<UndertaleSimpleListShort<GlyphKerning>>(); | ||
} else | ||
{ | ||
Offset = reader.ReadInt32(); // Maybe? I don't really know, but this definitely used to work | ||
} | ||
} | ||
|
||
public class GlyphKerning : UndertaleObject | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So I guess the editor needs an update... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, I feel stupid because I just realized none of the things I've tested on use the list at all. It doesn't really seem necessary to allocate too much space for them (if any). |
||
{ | ||
public short Other; | ||
public short Amount; | ||
|
||
public void Serialize(UndertaleWriter writer) | ||
{ | ||
writer.Write(Other); | ||
writer.Write(Amount); | ||
} | ||
|
||
public void Unserialize(UndertaleReader reader) | ||
{ | ||
Other = reader.ReadInt16(); | ||
Amount = reader.ReadInt16(); | ||
} | ||
} | ||
} | ||
|
||
|
@@ -95,6 +131,8 @@ public void Serialize(UndertaleWriter writer) | |
writer.WriteUndertaleObjectPointer(Texture); | ||
writer.Write(ScaleX); | ||
writer.Write(ScaleY); | ||
if (writer.undertaleData.GeneralInfo?.BytecodeVersion >= 17) | ||
writer.Write(AscenderOffset); | ||
writer.WriteUndertaleObject(Glyphs); | ||
} | ||
|
||
|
@@ -112,6 +150,8 @@ public void Unserialize(UndertaleReader reader) | |
Texture = reader.ReadUndertaleObjectPointer<UndertaleTexturePageItem>(); | ||
ScaleX = reader.ReadSingle(); | ||
ScaleY = reader.ReadSingle(); | ||
if (reader.undertaleData.GeneralInfo?.BytecodeVersion >= 17) | ||
AscenderOffset = reader.ReadInt32(); | ||
Glyphs = reader.ReadUndertaleObject<UndertalePointerList<Glyph>>(); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace UndertaleModLib.Models | ||
{ | ||
public class UndertaleTextureGroupInfo : UndertaleObject | ||
{ | ||
public UndertaleString GroupName; | ||
public UndertaleSimpleResourcesList<UndertaleEmbeddedTexture, UndertaleChunkTXTR> TexturePages; | ||
public UndertaleSimpleResourcesList<UndertaleSprite, UndertaleChunkSPRT> Sprites; | ||
public UndertaleSimpleResourcesList<UndertaleSprite, UndertaleChunkSPRT> SpineSprites; | ||
public UndertaleSimpleResourcesList<UndertaleFont, UndertaleChunkFONT> Fonts; | ||
public UndertaleSimpleResourcesList<UndertaleBackground, UndertaleChunkBGND> Tilesets; | ||
|
||
public UndertaleTextureGroupInfo() | ||
{ | ||
TexturePages = new UndertaleSimpleResourcesList<UndertaleEmbeddedTexture, UndertaleChunkTXTR>(); | ||
Sprites = new UndertaleSimpleResourcesList<UndertaleSprite, UndertaleChunkSPRT>(); | ||
SpineSprites = new UndertaleSimpleResourcesList<UndertaleSprite, UndertaleChunkSPRT>(); | ||
Fonts = new UndertaleSimpleResourcesList<UndertaleFont, UndertaleChunkFONT>(); | ||
Tilesets = new UndertaleSimpleResourcesList<UndertaleBackground, UndertaleChunkBGND>(); | ||
} | ||
|
||
public void Serialize(UndertaleWriter writer) | ||
{ | ||
writer.WriteUndertaleString(GroupName); | ||
|
||
writer.WriteUndertaleObjectPointer(TexturePages); | ||
writer.WriteUndertaleObjectPointer(Sprites); | ||
writer.WriteUndertaleObjectPointer(SpineSprites); | ||
writer.WriteUndertaleObjectPointer(Fonts); | ||
writer.WriteUndertaleObjectPointer(Tilesets); | ||
|
||
writer.WriteUndertaleObject(TexturePages); | ||
writer.WriteUndertaleObject(Sprites); | ||
writer.WriteUndertaleObject(SpineSprites); | ||
writer.WriteUndertaleObject(Fonts); | ||
writer.WriteUndertaleObject(Tilesets); | ||
} | ||
|
||
public void Unserialize(UndertaleReader reader) | ||
{ | ||
GroupName = reader.ReadUndertaleString(); | ||
|
||
// Read the pointers | ||
TexturePages = reader.ReadUndertaleObjectPointer<UndertaleSimpleResourcesList<UndertaleEmbeddedTexture, UndertaleChunkTXTR>>(); | ||
Sprites = reader.ReadUndertaleObjectPointer<UndertaleSimpleResourcesList<UndertaleSprite, UndertaleChunkSPRT>>(); | ||
SpineSprites = reader.ReadUndertaleObjectPointer<UndertaleSimpleResourcesList<UndertaleSprite, UndertaleChunkSPRT>>(); | ||
Fonts = reader.ReadUndertaleObjectPointer<UndertaleSimpleResourcesList<UndertaleFont, UndertaleChunkFONT>>(); | ||
Tilesets = reader.ReadUndertaleObjectPointer<UndertaleSimpleResourcesList<UndertaleBackground, UndertaleChunkBGND>>(); | ||
|
||
// Read the objects, throwing an error if the pointers are invalid | ||
if (reader.ReadUndertaleObject<UndertaleSimpleResourcesList<UndertaleEmbeddedTexture, UndertaleChunkTXTR>>() != TexturePages || | ||
reader.ReadUndertaleObject<UndertaleSimpleResourcesList<UndertaleSprite, UndertaleChunkSPRT>>() != Sprites || | ||
reader.ReadUndertaleObject<UndertaleSimpleResourcesList<UndertaleSprite, UndertaleChunkSPRT>>() != SpineSprites || | ||
reader.ReadUndertaleObject<UndertaleSimpleResourcesList<UndertaleFont, UndertaleChunkFONT>>() != Fonts || | ||
reader.ReadUndertaleObject<UndertaleSimpleResourcesList<UndertaleBackground, UndertaleChunkBGND>>() != Tilesets) | ||
{ | ||
throw new UndertaleSerializationException("Invalid pointer to SimpleResourcesList"); | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it was two bytes of data and two bytes of padding, or maybe the list always existed but was empty?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess maybe it can assume there's always a list? No real harm in doing so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hard to tell when we don't even have any examples that make use of it