mirror of
https://github.com/claunia/libexeinfo.git
synced 2025-12-16 19:14:24 +00:00
Add Atari ST resource object tree walking.
This commit is contained in:
@@ -143,20 +143,26 @@ namespace exeinfo
|
||||
recognized = true;
|
||||
Console.Write(stExe.Information);
|
||||
if(((AtariST)stExe).resourceStream != null ||
|
||||
(((AtariST)stExe).Resource.rsh_vrsn != 0 && ((AtariST)stExe).Resource.rsh_vrsn != 1 &&
|
||||
((AtariST)stExe).Resource.rsh_vrsn != 4 && ((AtariST)stExe).Resource.rsh_vrsn != 5))
|
||||
(((AtariST)stExe).ResourceHeader.rsh_vrsn != 0 && ((AtariST)stExe).ResourceHeader.rsh_vrsn != 1 &&
|
||||
((AtariST)stExe).ResourceHeader.rsh_vrsn != 4 && ((AtariST)stExe).ResourceHeader.rsh_vrsn != 5))
|
||||
{
|
||||
Console.WriteLine("\tResources:");
|
||||
Console.WriteLine("\t\t{0} OBJECTs start at {1}", ((AtariST)stExe).Resource.rsh_nobs, ((AtariST)stExe).Resource.rsh_object);
|
||||
Console.WriteLine("\t\t{0} TEDINFOs start at {1}", ((AtariST)stExe).Resource.rsh_nted, ((AtariST)stExe).Resource.rsh_tedinfo);
|
||||
Console.WriteLine("\t\t{0} ICONBLKs start at {1}", ((AtariST)stExe).Resource.rsh_nib, ((AtariST)stExe).Resource.rsh_iconblk);
|
||||
Console.WriteLine("\t\t{0} BITBLKs start at {1}", ((AtariST)stExe).Resource.rsh_nbb, ((AtariST)stExe).Resource.rsh_bitblk);
|
||||
Console.WriteLine("\t\t{0} object trees start at {1}", ((AtariST)stExe).Resource.rsh_ntree, ((AtariST)stExe).Resource.rsh_trindex);
|
||||
Console.WriteLine("\t\t{0} free strings start at {1}", ((AtariST)stExe).Resource.rsh_nstring, ((AtariST)stExe).Resource.rsh_frstr);
|
||||
Console.WriteLine("\t\t{0} free images start at {1}", ((AtariST)stExe).Resource.rsh_nimages, ((AtariST)stExe).Resource.rsh_frimg);
|
||||
Console.WriteLine("\t\tString data starts at {0}", ((AtariST)stExe).Resource.rsh_string);
|
||||
Console.WriteLine("\t\tImage data starts at {0}", ((AtariST)stExe).Resource.rsh_imdata);
|
||||
Console.WriteLine("\t\tStandard resource data is {0} bytes", ((AtariST)stExe).Resource.rsh_rssize);
|
||||
Console.WriteLine("\t\t{0} OBJECTs start at {1}", ((AtariST)stExe).ResourceHeader.rsh_nobs, ((AtariST)stExe).ResourceHeader.rsh_object);
|
||||
Console.WriteLine("\t\t{0} TEDINFOs start at {1}", ((AtariST)stExe).ResourceHeader.rsh_nted, ((AtariST)stExe).ResourceHeader.rsh_tedinfo);
|
||||
Console.WriteLine("\t\t{0} ICONBLKs start at {1}", ((AtariST)stExe).ResourceHeader.rsh_nib, ((AtariST)stExe).ResourceHeader.rsh_iconblk);
|
||||
Console.WriteLine("\t\t{0} BITBLKs start at {1}", ((AtariST)stExe).ResourceHeader.rsh_nbb, ((AtariST)stExe).ResourceHeader.rsh_bitblk);
|
||||
Console.WriteLine("\t\t{0} object trees start at {1}", ((AtariST)stExe).ResourceHeader.rsh_ntree, ((AtariST)stExe).ResourceHeader.rsh_trindex);
|
||||
Console.WriteLine("\t\t{0} free strings start at {1}", ((AtariST)stExe).ResourceHeader.rsh_nstring, ((AtariST)stExe).ResourceHeader.rsh_frstr);
|
||||
Console.WriteLine("\t\t{0} free images start at {1}", ((AtariST)stExe).ResourceHeader.rsh_nimages, ((AtariST)stExe).ResourceHeader.rsh_frimg);
|
||||
Console.WriteLine("\t\tString data starts at {0}", ((AtariST)stExe).ResourceHeader.rsh_string);
|
||||
Console.WriteLine("\t\tImage data starts at {0}", ((AtariST)stExe).ResourceHeader.rsh_imdata);
|
||||
Console.WriteLine("\t\tStandard resource data is {0} bytes", ((AtariST)stExe).ResourceHeader.rsh_rssize);
|
||||
|
||||
if(((AtariST)stExe).ResourceObjectRoot != null)
|
||||
{
|
||||
Console.WriteLine("\tObject tree:");
|
||||
PrintAtariResourceTree(((AtariST)stExe).ResourceObjectRoot, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,5 +174,18 @@ namespace exeinfo
|
||||
|
||||
if(!recognized) Console.WriteLine("Executable format not recognized");
|
||||
}
|
||||
|
||||
static void PrintAtariResourceTree(AtariST.TreeObjectNode node, int level)
|
||||
{
|
||||
for(int i = 0; i < level; i++)
|
||||
Console.Write("\t");
|
||||
|
||||
Console.WriteLine("{0} ({1} {2}) data = {3}, coordinates ({4},{5}) size {6}x{7}", node.type, node.flags,
|
||||
node.state, node.data, node.x, node.y, node.width, node.height);
|
||||
|
||||
if(node.child != null) PrintAtariResourceTree(node.child, level + 1);
|
||||
|
||||
if(node.sibling != null) PrintAtariResourceTree(node.sibling, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -102,7 +103,8 @@ namespace libexeinfo
|
||||
public OperatingSystem RequiredOperatingSystem =>
|
||||
new OperatingSystem {Name = Header.mint == MINT_SIGNATURE ? "MiNT" : "Atari TOS"};
|
||||
public Stream resourceStream;
|
||||
public AtariResource Resource;
|
||||
public AtariResourceHeader ResourceHeader;
|
||||
public TreeObjectNode ResourceObjectRoot;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
@@ -122,10 +124,53 @@ namespace libexeinfo
|
||||
|
||||
if(resourceStream == null) return;
|
||||
|
||||
buffer = new byte[Marshal.SizeOf(typeof(AtariResource))];
|
||||
buffer = new byte[Marshal.SizeOf(typeof(AtariResourceHeader))];
|
||||
resourceStream.Position = 0;
|
||||
resourceStream.Read(buffer, 0, buffer.Length);
|
||||
Resource = BigEndianMarshal.ByteArrayToStructureBigEndian<AtariResource>(buffer);
|
||||
ResourceHeader = BigEndianMarshal.ByteArrayToStructureBigEndian<AtariResourceHeader>(buffer);
|
||||
|
||||
if(ResourceHeader.rsh_vrsn != 0 && ResourceHeader.rsh_vrsn != 1 && ResourceHeader.rsh_vrsn != 4 && ResourceHeader.rsh_vrsn != 5) return;
|
||||
|
||||
if(ResourceHeader.rsh_nobs > 0)
|
||||
{
|
||||
ObjectNode[] nodes = new ObjectNode[ResourceHeader.rsh_nobs];
|
||||
|
||||
resourceStream.Position = ResourceHeader.rsh_object;
|
||||
for(short i = 0; i < ResourceHeader.rsh_nobs; i++)
|
||||
{
|
||||
buffer = new byte[Marshal.SizeOf(typeof(ObjectNode))];
|
||||
resourceStream.Read(buffer, 0, buffer.Length);
|
||||
nodes[i] = BigEndianMarshal.ByteArrayToStructureBigEndian<ObjectNode>(buffer);
|
||||
}
|
||||
|
||||
List<short> knownNodes = new List<short>();
|
||||
ResourceObjectRoot = ProcessResourceObject(nodes, ref knownNodes, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static TreeObjectNode ProcessResourceObject(IList<ObjectNode> nodes, ref List<short> knownNodes, short nodeNumber)
|
||||
{
|
||||
TreeObjectNode node = new TreeObjectNode
|
||||
{
|
||||
type = (ObjectTypes)nodes[nodeNumber].ob_type,
|
||||
flags = (ObjectFlags)nodes[nodeNumber].ob_flags,
|
||||
state = (ObjectStates)nodes[nodeNumber].ob_state,
|
||||
data = nodes[nodeNumber].ob_spec,
|
||||
x = nodes[nodeNumber].ob_x,
|
||||
y = nodes[nodeNumber].ob_y,
|
||||
width = nodes[nodeNumber].ob_width,
|
||||
height = nodes[nodeNumber].ob_height
|
||||
};
|
||||
|
||||
knownNodes.Add(nodeNumber);
|
||||
|
||||
if(nodes[nodeNumber].ob_head > 0 && !knownNodes.Contains(nodes[nodeNumber].ob_head))
|
||||
node.child = ProcessResourceObject(nodes, ref knownNodes, nodes[nodeNumber].ob_head);
|
||||
|
||||
if(nodes[nodeNumber].ob_next > 0 && !knownNodes.Contains(nodes[nodeNumber].ob_next))
|
||||
node.sibling = ProcessResourceObject(nodes, ref knownNodes, nodes[nodeNumber].ob_next);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -108,10 +108,6 @@ namespace libexeinfo
|
||||
[Flags]
|
||||
public enum ObjectFlags : short
|
||||
{
|
||||
/// <summary>
|
||||
/// No flags
|
||||
/// </summary>
|
||||
None = 0x0000,
|
||||
/// <summary>
|
||||
/// Indicates that the user can select the object
|
||||
/// </summary>
|
||||
@@ -153,10 +149,6 @@ namespace libexeinfo
|
||||
[Flags]
|
||||
public enum ObjectStates : short
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the object is drawn in normal colors
|
||||
/// </summary>
|
||||
Normal = 0x0000,
|
||||
/// <summary>
|
||||
/// Indicates that the object is highlighted by being drawn with reversed colors
|
||||
/// </summary>
|
||||
|
||||
@@ -191,6 +191,24 @@ namespace libexeinfo
|
||||
public short ob_height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The OBJECT structure contains values that describe the object, its relationship to the other objects in the tree, and its location relative to its parent or (in the case of the root object) the screen.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public class TreeObjectNode
|
||||
{
|
||||
public TreeObjectNode sibling;
|
||||
public TreeObjectNode child;
|
||||
public ObjectTypes type;
|
||||
public ObjectFlags flags;
|
||||
public ObjectStates state;
|
||||
public int data;
|
||||
public short x;
|
||||
public short y;
|
||||
public short width;
|
||||
public short height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The TEDINFO structure lets a user edit formatted text. The object types G_TEXT, G_BOXTEXT, G_FTEXT and G_FBOXTEXT use their <see cref="ObjectNode.ob_spec"/> to point to TEDINFO structures.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user