1
0
mirror of https://github.com/pumpitupdev/pumptools.git synced 2024-12-26 21:24:08 +01:00
pumptools/doc/development/notes/exc2-unlock-songs.md

217 lines
8.4 KiB
Markdown
Raw Normal View History

# Notes about song unlocks in Exceed 2
Executable of v1.02, build 7th December 2004.
A bunch of copy-pastes from IDA checking which songs can be unlocked permanently.
## Internal song list and state structure
```
00000000 SongList struc ; (sizeof=0x48, mappedto_187) ; XREF: .data:songList/r
00000000 trackNum dd ?
00000004 ptrArtistNameKr dd ?
00000008 ptrArtistNameEn dd ?
0000000C ptrSongNameKr dd ? ; XREF: sub_805186E+7A/r
0000000C ; sub_805186E+B4/r ...
00000010 ptrSongNameEn dd ?
00000014 ptrBpm dd ?
00000018 channelInfo dd ?
0000001C level dd 6 dup(?)
00000034 enableSong db ?
00000035 hiddenSong db ?
00000036 enableDemoPlay db ?
00000037 censor db ?
00000038 pad db ?
00000039 censorLock db ?
0000003A enable_play db ?
0000003B hidden_play db ?
0000003C enableMode db 6 dup(?) ; string(C)
00000042 enableMode_play db 6 dup(?) ; string(C)
00000048 SongList ends
```
## Internal song list
```
.data:080890E4 ; SongList songList
.data:080890E4 songList dd 101h ; trackNum
.data:080890E4 ; DATA XREF: sub_8062D22+38o
.data:080890E4 ; GetSongRealIndex+33o ...
.data:080890E4 dd 807BC28h ; ptrArtistNameKr
.data:080890E4 dd 807BC2Dh ; ptrArtistNameEn
.data:080890E4 dd 807BC33h ; ptrSongNameKr
.data:080890E4 dd 0 ; ptrSongNameEn
.data:080890E4 dd 0 ; ptrBpm
.data:080890E4 dd 40624000h ; channelInfo
.data:080890E4 dd 0, 0FFFFFFFFh, 6, 0Ch, 7, 0FFFFFFFFh; level
.data:080890E4 db 1 ; enableSong
.data:080890E4 db 0 ; hiddenSong
.data:080890E4 db 1 ; enableDemoPlay
.data:080890E4 db 0 ; censor
.data:080890E4 db 0FFh ; pad
.data:080890E4 db 0FFh ; censorLock
.data:080890E4 db 0FFh ; enable_play
.data:080890E4 db 0FFh ; hidden_play
.data:080890E4 db 0,0,0,0,0,0 ; enableMode
.data:080890E4 db 0,0,1,0,0,0 ; enableMode_play
.data:080890E4 dd 102h ; trackNum
.data:080890E4 dd 807BC28h ; ptrArtistNameKr
.data:080890E4 dd 807BC2Dh ; ptrArtistNameEn
.data:080890E4 dd 807BC44h ; ptrSongNameKr
.data:080890E4 dd 0 ; ptrSongNameEn
.data:080890E4 dd 0 ; ptrBpm
.data:080890E4 dd 40668000h ; channelInfo
.data:080890E4 dd 0, 0FFFFFFFFh, 6, 0Ch, 7, 0Fh; level
.data:080890E4 db 1 ; enableSong
.data:080890E4 db 0 ; hiddenSong
.data:080890E4 db 1 ; enableDemoPlay
.data:080890E4 db 0 ; censor
.data:080890E4 db 0FFh ; pad
.data:080890E4 db 0FFh ; censorLock
.data:080890E4 db 0FFh ; enable_play
.data:080890E4 db 0FFh ; hidden_play
.data:080890E4 db 0,0,0,0,0,0 ; enableMode
.data:080890E4 db 0,0,2,0,0,0 ; enableMode_play
...
```
## Settings struct first few fields
```
00000000 settings_struct struc ; (sizeof=0x162B, mappedto_186)
00000000 ff_area db 1307 dup(?) ; string(C)
0000051B unlocks_maybe db 16 dup(?) ; string(C)
0000052B blacklist db 139 dup(?) ; string(C)
000005B6 unkn2 db 117 dup(?) ; string(C)
0000062B remain db 4096 dup(?) ; string(C)
0000162B settings_struct ends
```
## Function that checks for song unlocks
Located at 0x0806307E
```
int __usercall unlock_song@<eax>(int a1@<esi>, _DWORD *arg_0, _DWORD *songid)
{
int v3; // eax@1
int v4; // ecx@1
signed int v5; // edi@3
int v6; // eax@6
signed int v7; // eax@16
signed int v8; // eax@23
signed int v9; // eax@30
signed int v10; // eax@37
signed int v11; // eax@42
int v13; // [sp+0h] [bp-18h]@3
char result_unlocked_song; // [sp+7h] [bp-11h]@1
result_unlocked_song = 0;
v3 = sub_8061C62(dword_80BED54, "PLAY");
v4 = v3 - 200696;
if ( !v3 )
v4 = 0;
v5 = 0;
v13 = v4;
do
{
if ( v5 )
{
if ( v5 != 1 )
goto LABEL_11;
if ( !(dword_80BECD4 & 2) )
goto LABEL_43;
v6 = sub_8056E76(v13, 1);
}
else
{
if ( !(dword_80BECD4 & 1) )
goto LABEL_43;
v6 = sub_8056E76(v13, 0);
}
a1 = v6;
LABEL_11:
if ( currentStateCount > 2
&& !stationCurrentlySelected // 0 = arcade station
&& *(&songList.trackNum + 18 * sub_8062DC6(dword_80BECE4)) == 0xB13// ill give you all my love
&& byte_80BECF5 & 2
&& *(_DWORD *)(a1 + 456) <= 10 )
{
v7 = GetSongRealIndex(0xB19); // canon-d
*arg_0 = 0;
result_unlocked_song = 1;
*songid = 0xB19; // canon-d
songList.enableMode[72 * v7 + 4] = 0; // +4 mode offset = nightmare
}
if ( currentStateCount == 1 )
{
if ( stationCurrentlySelected == 1 // 1 = remix station
&& *(&songList.trackNum + 18 * sub_8062DC6(dword_80BECDC)) == 0xB31// diva's remix
&& *(_DWORD *)(a1 + 400) <= 20
&& !*(_DWORD *)(a1 + 448)
&& *(float *)(a1 + 368) >= 1.0 )
{
v8 = GetSongRealIndex(0xB54); // 2nd hidden remix
*arg_0 = 3;
result_unlocked_song = 1;
*songid = 0xB54; // 2nd hidden remix
songList.enableMode[72 * v8 + 4] = 0; // +4 mode offset = nightmare
}
if ( currentStateCount == 1 )
{
if ( stationCurrentlySelected == 1
&& *(&songList.trackNum + 18 * sub_8062DC6(dword_80BECDC)) == 0xB30// deux remix
&& *(_DWORD *)(a1 + 400) <= 20
&& !*(_DWORD *)(a1 + 448)
&& *(float *)(a1 + 368) >= 1.0 )
{
v9 = GetSongRealIndex(0xB29); // banya classic remix
*arg_0 = 3;
result_unlocked_song = 1;
*songid = 0xB29; // banya classic remix
songList.enableMode[72 * v9 + 4] = 0; // +4 mode offset = nightmare
}
if ( currentStateCount == 1 )
{
if ( stationCurrentlySelected == 1
&& *(&songList.trackNum + 18 * sub_8062DC6(dword_80BECDC)) == 0xB29// banya classic remix
&& *(_DWORD *)(a1 + 400) <= 20
&& !*(_DWORD *)(a1 + 448)
&& *(float *)(a1 + 368) >= 1.0 )
{
v10 = GetSongRealIndex(0xB51); // dignity full remix
*arg_0 = 3;
result_unlocked_song = 1;
*songid = 0xB51; // dignity full remix
songList.enableMode[72 * v10 + 2] = 0;// +2 mode offset = crazy
}
if ( currentStateCount == 1
&& stationCurrentlySelected == 1
&& *(&songList.trackNum + 18 * sub_8062DC6(dword_80BECDC)) == 0xB28// treme vook of the war
&& byte_80BECED & 2 )
{
*(&songList.hiddenSong + 72 * GetSongRealIndex(0xB58)) = 0;// disable this song as a hidden song
v11 = GetSongRealIndex(0xB58); // treme of the vook war another
*arg_0 = 3;
result_unlocked_song = 1;
*(&songList.enableSong + 72 * v11) = 1;
*songid = 0xB58;
}
}
}
}
LABEL_43:
++v5;
}
while ( v5 <= 1 );
if ( result_unlocked_song )
sub_8074CA8(9, 0);
if ( settings->unlocks_maybe[10] == 1 && stationCurrentlySelected == 1 )
{
*(&songList.hiddenSong + 0x48 * GetSongRealIndex(0xB57)) = 0;// disable this song as a hidden song
*(&songList.enableSong + 0x48 * GetSongRealIndex(0xB57)) = 1;
if ( !result_unlocked_song )
{
*arg_0 = 3;
*songid = 0xB57; // canon-d full mix
}
result_unlocked_song = 1;
}
return (unsigned __int8)result_unlocked_song;
}
```