Skip to content

Commit

Permalink
CLES viewer functional
Browse files Browse the repository at this point in the history
  • Loading branch information
Zachary Canann committed Jan 13, 2023
1 parent f8be346 commit 2c29d3a
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 63 deletions.
67 changes: 66 additions & 1 deletion GES/Source/CraftListViewer/CraftData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace GES.Source.CraftListViewer
using GES.Source.InventoryViewer;
using System;
using System.Collections;
using System.ComponentModel;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, Pack = 1, Size = (1 + 256 + 256 * 56))]
Expand All @@ -18,6 +19,42 @@ public class CraftDataSerializable
public Byte[] craftListRawData;
}

public class RawCommandListEntry : INotifyPropertyChanged
{
public UInt16 PlayerSlotId { get; set; }

public UInt16 InventorySlotId { get; set; }

public Int32 Index { get; set; }

public UInt32 Address { get; set; }

public UInt64 RawAddress { get; set; }

public CraftData Parent { get; set; }

public event PropertyChangedEventHandler PropertyChanged;

public void Refresh()
{
this.RaisePropertyChanged(nameof(this.PlayerSlotId));
this.RaisePropertyChanged(nameof(this.InventorySlotId));
this.RaisePropertyChanged(nameof(this.Index));
this.RaisePropertyChanged(nameof(this.Address));
this.RaisePropertyChanged(nameof(this.RawAddress));
this.RaisePropertyChanged(nameof(this.Parent));
}

/// <summary>
/// Indicates that a given property in this project item has changed.
/// </summary>
/// <param name="propertyName">The name of the changed property.</param>
protected void RaisePropertyChanged(String propertyName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

public class CraftData
{
public CraftData()
Expand All @@ -29,8 +66,12 @@ public CraftData()

public Int32 PlayerIndex { get; set; }

public Int32 CommandListCount { get; set; }

public CraftEntry[] craftSlotList;

public RawCommandListEntry[] commandListItems;

public String JISText { get; set; }

public String BytesText { get; set; }
Expand Down Expand Up @@ -61,8 +102,9 @@ public static void Deserialize(CraftData entry, Byte[] bytes)
}
}

public void Refresh(UInt64 address, UInt64 rawAddress, Byte[] bytes, Int32 playerSlotIndex)
public void Refresh(UInt64 address, UInt64 rawAddress, Byte[] bytes, Int32 playerSlotIndex, Int32 commandListCount)
{
this.CommandListCount = commandListCount;
this.PlayerIndex = playerSlotIndex;

Int32 remainder = (this.SerializableData.itemCount + 1) % 4;
Expand All @@ -73,6 +115,29 @@ public void Refresh(UInt64 address, UInt64 rawAddress, Byte[] bytes, Int32 playe
this.craftSlotList = new CraftEntry[256];
}

// if (this.CommandListItems == null)
{
this.commandListItems = new RawCommandListEntry[64];
}

for (Int32 index = 0; index < 64; index++)
{
if (this.commandListItems[index] == null)
{
this.commandListItems[index] = new RawCommandListEntry();
}

this.commandListItems[index].Index = index;
this.commandListItems[index].InventorySlotId = BitConverter.ToUInt16(bytes, index * sizeof(UInt16));
this.commandListItems[index].PlayerSlotId = (UInt16)playerSlotIndex;
this.commandListItems[index].Parent = this;
this.commandListItems[index].Address = (UInt32)address + (UInt32)(index * 2);
this.commandListItems[index].RawAddress = rawAddress + (UInt32)(index * 2);
this.commandListItems[index].Parent = this;
this.RawAddress = rawAddress;
this.commandListItems[index].Refresh();
}

for (Int32 index = 0; index < 256; index++)
{
Byte[] recipeProperties = new Byte[56];
Expand Down
28 changes: 28 additions & 0 deletions GES/Source/CraftListViewer/CraftDataView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ public int PlayerIndex
}
}

public int CommandListCount
{
get
{
return CraftData.CommandListCount;
}

set
{
CraftData.CommandListCount = value;
}
}

public Byte ItemCount
{
get
Expand All @@ -53,6 +66,19 @@ public CraftEntry[] CraftSlotList
}
}

public RawCommandListEntry[] CommandListItems
{
get
{
return CraftData.commandListItems;
}

set
{
CraftData.commandListItems = value;
}
}

public String JISText
{
get
Expand Down Expand Up @@ -107,9 +133,11 @@ public UInt64 RawAddress

public void RefreshAllProperties()
{
RaisePropertyChanged(nameof(CommandListCount));
RaisePropertyChanged(nameof(PlayerIndex));
RaisePropertyChanged(nameof(ItemCount));
RaisePropertyChanged(nameof(CraftSlotList));
RaisePropertyChanged(nameof(CommandListItems));
RaisePropertyChanged(nameof(JISText));
RaisePropertyChanged(nameof(BytesText));
RaisePropertyChanged(nameof(Address));
Expand Down
76 changes: 55 additions & 21 deletions GES/Source/CraftListViewer/CraftListViewerViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ public class CraftListViewerViewModel : ToolViewModel
private UInt64 CraftListAddressJP = 0x32800;
private UInt64 CraftListAddressPal = 0x3A800;

private UInt64 CommandListItemCountAddressEN = 0x27B4;
private UInt64 CommandListItemCountAddressJP = 0x2778;
private UInt64 CommandListItemCountAddressPAL = 0x27B4;



/// <summary>
/// Prevents a default instance of the <see cref="CraftListViewerViewModel" /> class from being created.
/// </summary>
Expand Down Expand Up @@ -138,27 +144,43 @@ public void ExternalRefresh(Int32 playerIndex)

private unsafe void UpdateCraftListData()
{
UInt64[] gbaMemoryBases = new UInt64[PlayerCount]
UInt64[] gbaWMMemoryBases = new UInt64[PlayerCount]
{
MemoryQueryer.Instance.ResolveModule(SessionManager.Session.OpenedProcess, "GBA_WM_0", EmulatorType.Dolphin),
MemoryQueryer.Instance.ResolveModule(SessionManager.Session.OpenedProcess, "GBA_WM_1", EmulatorType.Dolphin),
MemoryQueryer.Instance.ResolveModule(SessionManager.Session.OpenedProcess, "GBA_WM_2", EmulatorType.Dolphin),
MemoryQueryer.Instance.ResolveModule(SessionManager.Session.OpenedProcess, "GBA_WM_3", EmulatorType.Dolphin),
};
UInt64[] gbaIMMemoryBases = new UInt64[PlayerCount]
{
MemoryQueryer.Instance.ResolveModule(SessionManager.Session.OpenedProcess, "GBA_IM_0", EmulatorType.Dolphin),
MemoryQueryer.Instance.ResolveModule(SessionManager.Session.OpenedProcess, "GBA_IM_1", EmulatorType.Dolphin),
MemoryQueryer.Instance.ResolveModule(SessionManager.Session.OpenedProcess, "GBA_IM_2", EmulatorType.Dolphin),
MemoryQueryer.Instance.ResolveModule(SessionManager.Session.OpenedProcess, "GBA_IM_3", EmulatorType.Dolphin),
};

UInt64 craftListAddress;

switch(MainViewModel.GetInstance().DetectedVersion)
UInt64 commandListItemCountAddress;

switch (MainViewModel.GetInstance().DetectedVersion)
{
default: return;
case EDetectedVersion.JP: craftListAddress = CraftListAddressJP; break;
case EDetectedVersion.EN: craftListAddress = CraftListAddressEN; break;
case EDetectedVersion.PAL: craftListAddress = CraftListAddressPal; break;
}

switch (MainViewModel.GetInstance().DetectedVersion)
{
default: return;
case EDetectedVersion.JP: commandListItemCountAddress = CommandListItemCountAddressJP; break;
case EDetectedVersion.EN: commandListItemCountAddress = CommandListItemCountAddressEN; break;
case EDetectedVersion.PAL: commandListItemCountAddress = CommandListItemCountAddressPAL; break;
}

for (Int32 playerIndex = 0; playerIndex < PlayerCount; playerIndex++)
{
UInt64 slotPointer = gbaMemoryBases[playerIndex] + craftListAddress;
UInt64 slotPointer = gbaWMMemoryBases[playerIndex] + craftListAddress;

if (this.RawCraftData == null)
{
Expand All @@ -173,29 +195,41 @@ private unsafe void UpdateCraftListData()
slotPointer,
out success);

if (success)
if (!success)
{
if (this.CachedPlayerSlotData[playerIndex] == null)
{
this.CachedPlayerSlotData[playerIndex] = new Byte[typeof(CraftDataSerializable).StructLayoutAttribute.Size];
}
continue;
}

if (this.PlayerCraftData[playerIndex].CraftData == null)
{
this.PlayerCraftData[playerIndex].CraftData = new CraftData();
}
Byte commandListCount = MemoryReader.Instance.Read<Byte>(
SessionManager.Session.OpenedProcess,
gbaIMMemoryBases[playerIndex] + commandListItemCountAddress,
out success);

CraftData.Deserialize(this.PlayerCraftData[playerIndex].CraftData, this.RawCraftData);
if (!success)
{
continue;
}

// Notify changes if new bytes differ from cached
if (!this.CachedPlayerSlotData[playerIndex].SequenceEqual(this.RawCraftData) || this.ForceRefresh)
{
this.PlayerCraftData[playerIndex].CraftData.Refresh(craftListAddress, slotPointer, this.RawCraftData, playerIndex);
this.PlayerCraftData[playerIndex].RefreshAllProperties();
}
if (this.CachedPlayerSlotData[playerIndex] == null)
{
this.CachedPlayerSlotData[playerIndex] = new Byte[typeof(CraftDataSerializable).StructLayoutAttribute.Size];
}

this.RawCraftData.CopyTo(this.CachedPlayerSlotData[playerIndex], 0);
if (this.PlayerCraftData[playerIndex].CraftData == null)
{
this.PlayerCraftData[playerIndex].CraftData = new CraftData();
}

CraftData.Deserialize(this.PlayerCraftData[playerIndex].CraftData, this.RawCraftData);

// Notify changes if new bytes differ from cached
if (!this.CachedPlayerSlotData[playerIndex].SequenceEqual(this.RawCraftData) || this.ForceRefresh)
{
this.PlayerCraftData[playerIndex].CraftData.Refresh(craftListAddress, slotPointer, this.RawCraftData, playerIndex, commandListCount);
this.PlayerCraftData[playerIndex].RefreshAllProperties();
}

this.RawCraftData.CopyTo(this.CachedPlayerSlotData[playerIndex], 0);
}

this.ForceRefresh = false;
Expand Down
8 changes: 8 additions & 0 deletions GES/Source/Mvvm/Converters/FFCC/ItemRefToIconConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@ public Object Convert(Object value, Type targetType, Object parameter, CultureIn
EquipmentEntry equipmentEntry = value as EquipmentEntry;
CraftEntry craftEntry = value as CraftEntry;
RawEquipmentEntry rawEquipmentEntry = value as RawEquipmentEntry;
RawCommandListEntry rawCommandListEntry = value as RawCommandListEntry;

if ((equipmentEntry == null || equipmentEntry.Parent == null)
&& (rawEquipmentEntry == null || rawEquipmentEntry.Parent == null)
&& (craftEntry == null || craftEntry.Parent == null)
&& (rawCommandListEntry == null || rawCommandListEntry.Parent == null)
&& value is not UInt16
&& value is not Int32)
{
Expand Down Expand Up @@ -77,6 +79,12 @@ public Object Convert(Object value, Type targetType, Object parameter, CultureIn
playerSlotId = rawEquipmentEntry.Parent.PlayerSlotIndex;
}

if (rawCommandListEntry != null)
{
inventorySlot = rawCommandListEntry.InventorySlotId;
playerSlotId = rawCommandListEntry.Parent.PlayerIndex;
}

PlayerSlotDataView slotDataView = InventoryViewerViewModel.GetInstance().PlayerSlots.ElementAtOrDefault(playerSlotId);

if (slotDataView != null && slotDataView.Slot != null)
Expand Down
8 changes: 8 additions & 0 deletions GES/Source/Mvvm/Converters/FFCC/ItemRefToIdConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ public Object Convert(Object value, Type targetType, Object parameter, CultureIn
EquipmentEntry equipmentEntry = value as EquipmentEntry;
CraftEntry craftEntry = value as CraftEntry;
RawEquipmentEntry rawEquipmentEntry = value as RawEquipmentEntry;
RawCommandListEntry rawCommandListEntry = value as RawCommandListEntry;

if ((equipmentEntry == null || equipmentEntry.Parent == null)
&& (rawEquipmentEntry == null || rawEquipmentEntry.Parent == null)
&& (craftEntry == null || craftEntry.Parent == null)
&& (rawCommandListEntry == null || rawCommandListEntry.Parent == null)
&& value is not UInt16
&& value is not Int32)
{
Expand Down Expand Up @@ -58,6 +60,12 @@ public Object Convert(Object value, Type targetType, Object parameter, CultureIn
playerSlotId = rawEquipmentEntry.Parent.PlayerSlotIndex;
}

if (rawCommandListEntry != null)
{
inventorySlot = rawCommandListEntry.InventorySlotId;
playerSlotId = rawCommandListEntry.Parent.PlayerIndex;
}

PlayerSlotDataView slotDataView = InventoryViewerViewModel.GetInstance().PlayerSlots.ElementAtOrDefault(playerSlotId);

if (slotDataView != null && slotDataView.Slot != null)
Expand Down
8 changes: 8 additions & 0 deletions GES/Source/Mvvm/Converters/FFCC/ItemRefToNameConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ public Object Convert(Object value, Type targetType, Object parameter, CultureIn
EquipmentEntry equipmentEntry = value as EquipmentEntry;
CraftEntry craftEntry = value as CraftEntry;
RawEquipmentEntry rawEquipmentEntry = value as RawEquipmentEntry;
RawCommandListEntry rawCommandListEntry = value as RawCommandListEntry;

if ((equipmentEntry == null || equipmentEntry.Parent == null)
&& (rawEquipmentEntry == null || rawEquipmentEntry.Parent == null)
&& (craftEntry == null || craftEntry.Parent == null)
&& (rawCommandListEntry == null || rawCommandListEntry.Parent == null)
&& value is not UInt16
&& value is not Int32)
{
Expand Down Expand Up @@ -88,6 +90,12 @@ public Object Convert(Object value, Type targetType, Object parameter, CultureIn
playerSlotId = rawEquipmentEntry.Parent.PlayerSlotIndex;
}

if (rawCommandListEntry != null)
{
inventorySlot = rawCommandListEntry.InventorySlotId;
playerSlotId = rawCommandListEntry.Parent.PlayerIndex;
}

PlayerSlotDataView slotDataView = InventoryViewerViewModel.GetInstance().PlayerSlots.ElementAtOrDefault(playerSlotId);

if (slotDataView != null && slotDataView.Slot != null)
Expand Down
10 changes: 5 additions & 5 deletions GES/View/CommandListViewer.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
d:DesignHeight="512"
d:DesignWidth="1024"
x:ClassModifier="public"
DataContext="{Binding CommandListViewerViewModel, Source={StaticResource ViewModelLocator}}"
DataContext="{Binding CraftListViewerViewModel, Source={StaticResource ViewModelLocator}}"
mc:Ignorable="d">
<x:Code>
<![CDATA[ public CommandListViewer() { InitializeComponent(); }]]>
Expand Down Expand Up @@ -46,16 +46,16 @@
</Style>
</TabControl.Resources>
<TabItem Background="Transparent" Header="Player 1">
<templates:CommandListView DataContext="{Binding PlayerCommandListData[0]}" Index="0" />
<templates:CommandListView DataContext="{Binding PlayerCraftData[0]}" Index="0" />
</TabItem>
<TabItem Background="Transparent" Header="Player 2">
<templates:CommandListView DataContext="{Binding PlayerCommandListData[1]}" Index="1" />
<templates:CommandListView DataContext="{Binding PlayerCraftData[1]}" Index="1" />
</TabItem>
<TabItem Background="Transparent" Header="Player 3">
<templates:CommandListView DataContext="{Binding PlayerCommandListData[2]}" Index="2" />
<templates:CommandListView DataContext="{Binding PlayerCraftData[2]}" Index="2" />
</TabItem>
<TabItem Background="Transparent" Header="Player 4">
<templates:CommandListView DataContext="{Binding PlayerCommandListData[3]}" Index="3" />
<templates:CommandListView DataContext="{Binding PlayerCraftData[3]}" Index="3" />
</TabItem>
</TabControl>
</Grid>
Expand Down
Loading

0 comments on commit 2c29d3a

Please sign in to comment.