-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTemplate_GameCube.asl
113 lines (94 loc) · 3.66 KB
/
Template_GameCube.asl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Basic template for GameCube games
// Coding: Jujstme
// Should support every available version of Dolphin
state("Dolphin") {}
init
{
// Known gamecodes for the game you want to support
// You can look for known gamecodes on https://wiki.dolphin-emu.org/
// For example, known gamecodes for Sonic Adventure 2 Battle are: GSNP8P, GSNE8P, GSBJ8P
var Gamecodes = new List<string>
{
"GSNP8P", "GSNE8P", "GSBJ8P"
};
// Input your memory addresses here
var GetWatchers = (Func<IntPtr, MemoryWatcherList>)(MEM1 => new MemoryWatcherList{
new MemoryWatcher<int>(MEM1 + 0xA5584) { Name = "IGT" },
new MemoryWatcher<byte>(MEM1 + 0xA3408) { Name = "LevelNo" },
});
// Please do not modify the script below this point unless you know what you're doing
vars.InitTask = (Action)(() => {
vars.InitCompleted = false;
vars.CancelSource = new CancellationTokenSource();
System.Threading.Tasks.Task.Run(async () =>
{
vars.DebugPrint(" => Init Task started");
IntPtr MEM1 = IntPtr.Zero;
while (!vars.CancelSource.IsCancellationRequested && MEM1 == IntPtr.Zero)
{
vars.DebugPrint(" => Locating base RAM address (MEM1)...");
MEM1 = game.MemoryPages(true).FirstOrDefault(p => p.Type == MemPageType.MEM_MAPPED && p.State == MemPageState.MEM_COMMIT && (int)p.RegionSize == 0x2000000).BaseAddress;
if (MEM1 != IntPtr.Zero)
vars.DebugPrint(" => MEM1 address found at 0x" + MEM1.ToString("X"));
else
{
vars.DebugPrint(" => MEM1 address not found. Retrying in 2000ms...");
await System.Threading.Tasks.Task.Delay(2000, vars.CancelSource.Token);
}
}
if (!vars.CancelSource.IsCancellationRequested)
{
vars.DebugPrint(" => Setting up MemoryWatchers...");
vars.watchers = GetWatchers(MEM1);
vars.KeepAlive = (Func<bool>)(() => { byte[] output; return game.ReadBytes(MEM1, 1, out output); });
vars.CheckGameCode = (Func<bool>)(() => Gamecodes.Contains(game.ReadString(MEM1, 6, " ")));
vars.DebugPrint(" => Done");
vars.InitCompleted = true;
vars.DebugPrint(" => Init completed.");
}
});
});
vars.PreUpdate = (Func<bool>)(() => {
if (!vars.InitCompleted)
return false;
if (!vars.KeepAlive())
{
vars.InitTask();
return false;
}
if (!vars.CheckGameCode())
return false;
vars.watchers.UpdateAll(game);
return true;
});
vars.InitTask();
}
startup
{
vars.DebugPrint = (Action<string>)((string obj) => print("[Dolphin] " + obj));
vars.CancelSource = new CancellationTokenSource();
vars.ShortToLittleEndian = (Func<short, short>)(input => BitConverter.ToInt16(BitConverter.GetBytes(input).Reverse().ToArray(), 0));
vars.IntToLittleEndian = (Func<int, int>)(input => BitConverter.ToInt32(BitConverter.GetBytes(input).Reverse().ToArray(), 0));
vars.FloatToLittleEndian = (Func<float, float>)(input => BitConverter.ToSingle(BitConverter.GetBytes(input).Reverse().ToArray(), 0));
}
update
{
if (!vars.PreUpdate())
return false;
}
gameTime
{
return current.IGT + vars.AccumulatedIGT;
}
isLoading
{
return true;
}
exit
{
vars.CancelSource.Cancel();
}
shutdown
{
vars.CancelSource.Cancel();
}