Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Libretro
melonDS
Commits
4cefff25
Commit
4cefff25
authored
Aug 13, 2020
by
Arisotura
Browse files
add AR code file parser and shit
parent
28b8f614
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/ARCodeFile.cpp
0 → 100644
View file @
4cefff25
/*
Copyright 2016-2020 Arisotura
This file is part of melonDS.
melonDS is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include <string.h>
#include "ARCodeFile.h"
#include "Platform.h"
// TODO: import codes from other sources (usrcheat.dat, ...)
// TODO: more user-friendly error reporting
ARCodeFile
::
ARCodeFile
(
const
char
*
filename
)
{
memset
(
Filename
,
0
,
sizeof
(
Filename
));
strncpy
(
Filename
,
filename
,
1023
);
Error
=
false
;
Categories
.
clear
();
FILE
*
f
=
Platform
::
OpenFile
(
Filename
,
"r"
);
if
(
!
f
)
return
;
bool
isincat
=
false
;
ARCodeCat
curcat
;
bool
isincode
=
false
;
ARCode
curcode
;
char
linebuf
[
1024
];
while
(
!
feof
(
f
))
{
fgets
(
linebuf
,
1024
,
f
);
linebuf
[
1023
]
=
'\0'
;
char
*
start
=
linebuf
;
while
(
start
[
0
]
==
' '
||
start
[
0
]
==
'\t'
)
start
++
;
if
(
start
[
0
]
==
'#'
||
start
[
0
]
==
'\r'
||
start
[
0
]
==
'\n'
||
start
[
0
]
==
'\0'
)
continue
;
if
(
!
strncasecmp
(
start
,
"CAT"
,
3
))
{
char
catname
[
128
];
int
ret
=
sscanf
(
start
,
"CAT %127[^
\n
]"
,
catname
);
catname
[
127
]
=
'\0'
;
if
(
ret
<
1
)
{
printf
(
"AR: malformed CAT line: %s
\n
"
,
start
);
fclose
(
f
);
Error
=
true
;
return
;
}
if
(
isincode
)
curcat
.
Codes
.
push_back
(
curcode
);
isincode
=
false
;
if
(
isincat
)
Categories
.
push_back
(
curcat
);
isincat
=
true
;
memcpy
(
curcat
.
Name
,
catname
,
128
);
curcat
.
Codes
.
clear
();
}
else
if
(
!
strncasecmp
(
start
,
"CODE"
,
4
))
{
int
enable
;
char
codename
[
128
];
int
ret
=
sscanf
(
start
,
"CODE %d %127[^
\n
]"
,
&
enable
,
codename
);
codename
[
127
]
=
'\0'
;
if
(
ret
<
2
)
{
printf
(
"AR: malformed CODE line: %s
\n
"
,
start
);
fclose
(
f
);
Error
=
true
;
return
;
}
if
(
!
isincat
)
{
printf
(
"AR: encountered CODE line with no category started
\n
"
);
fclose
(
f
);
Error
=
true
;
return
;
}
if
(
isincode
)
curcat
.
Codes
.
push_back
(
curcode
);
isincode
=
true
;
memcpy
(
curcode
.
Name
,
codename
,
128
);
curcode
.
Enabled
=
enable
!=
0
;
curcode
.
CodeLen
=
0
;
}
else
{
u32
c0
,
c1
;
int
ret
=
sscanf
(
start
,
"%08X %08X"
,
&
c0
,
&
c1
);
if
(
ret
<
2
)
{
printf
(
"AR: malformed data line: %s
\n
"
,
start
);
fclose
(
f
);
Error
=
true
;
return
;
}
if
(
!
isincode
)
{
printf
(
"AR: encountered data line with no code started
\n
"
);
fclose
(
f
);
Error
=
true
;
return
;
}
if
(
curcode
.
CodeLen
>=
2
*
64
)
{
printf
(
"AR: code too long!
\n
"
);
fclose
(
f
);
Error
=
true
;
return
;
}
u32
idx
=
curcode
.
CodeLen
;
curcode
.
Code
[
idx
+
0
]
=
c0
;
curcode
.
Code
[
idx
+
1
]
=
c1
;
curcode
.
CodeLen
+=
2
;
}
}
if
(
isincode
)
curcat
.
Codes
.
push_back
(
curcode
);
if
(
isincat
)
Categories
.
push_back
(
curcat
);
fclose
(
f
);
printf
(
"PARSED OUTPUT
\n
"
);
for
(
ARCodeCatList
::
iterator
it
=
Categories
.
begin
();
it
!=
Categories
.
end
();
it
++
)
{
ARCodeCat
&
cat
=
*
it
;
printf
(
"CAT %s
\n
"
,
cat
.
Name
);
for
(
ARCodeList
::
iterator
jt
=
cat
.
Codes
.
begin
();
jt
!=
cat
.
Codes
.
end
();
jt
++
)
{
ARCode
&
code
=
*
jt
;
printf
(
"CODE %d %s
\n
"
,
code
.
Enabled
,
code
.
Name
);
for
(
u32
i
=
0
;
i
<
code
.
CodeLen
;
i
+=
2
)
{
printf
(
"%08X %08X
\n
"
,
code
.
Code
[
i
],
code
.
Code
[
i
+
1
]);
}
}
}
}
ARCodeFile
::~
ARCodeFile
()
{
//
}
src/ARCode
List
.h
→
src/ARCode
File
.h
View file @
4cefff25
...
...
@@ -16,18 +16,48 @@
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#ifndef ARCODELIST_H
#define ARCODELIST_H
#ifndef ARCODEFILE_H
#define ARCODEFILE_H
#include <vector>
#include "types.h"
#define ARCL_MAJOR 1
#define ARCL_MINOR 1
typedef
struct
{
char
Name
[
128
];
bool
Enabled
;
u32
CodeLen
;
u32
Code
[
2
*
64
];
}
ARCode
;
typedef
std
::
vector
<
ARCode
>
ARCodeList
;
class
ARCodeList
typedef
struct
{
char
Name
[
128
];
ARCodeList
Codes
;
}
ARCodeCat
;
typedef
std
::
vector
<
ARCodeCat
>
ARCodeCatList
;
class
ARCodeFile
{
public:
//
ARCodeFile
(
const
char
*
filename
);
~
ARCodeFile
();
bool
Error
;
bool
Save
();
ARCodeCatList
Categories
;
private:
char
Filename
[
1024
];
};
#endif // ARCODE
LIST
_H
#endif // ARCODE
FILE
_H
src/ARCodeList.cpp
deleted
100644 → 0
View file @
28b8f614
/*
Copyright 2016-2020 Arisotura
This file is part of melonDS.
melonDS is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include "ARCodeList.h"
/*
Action Replay code list format
header:
00 - magic MLAR
04 - version major
06 - version minor
08 - length
0C - number of codes
code header:
00 - magic MLCD
04 - name length
08 - code length
0C - enable flag
10 - code data (UTF8 name then actual code)
*/
src/AREngine.cpp
View file @
4cefff25
...
...
@@ -25,119 +25,30 @@
namespace
AREngine
{
typedef
struct
{
u32
Code
[
2
*
64
];
// TODO: more sensible size for this? allocate on demand?
bool
Enabled
;
}
CheatEntry
;
// TODO: more sensible size for this? allocate on demand?
CheatEntry
CheatCodes
[
64
];
u32
NumCheatCodes
;
void
ParseTextCode
(
char
*
text
,
int
tlen
,
u32
*
code
,
int
clen
)
// or whatever this should be named?
{
u32
cur_word
=
0
;
u32
ndigits
=
0
;
u32
nin
=
0
;
u32
nout
=
0
;
char
c
;
while
((
c
=
*
text
++
)
!=
'\0'
)
{
u32
val
;
if
(
c
>=
'0'
&&
c
<=
'9'
)
val
=
c
-
'0'
;
else
if
(
c
>=
'a'
&&
c
<=
'f'
)
val
=
c
-
'a'
+
0xA
;
else
if
(
c
>=
'A'
&&
c
<=
'F'
)
val
=
c
-
'A'
+
0xA
;
else
continue
;
cur_word
<<=
4
;
cur_word
|=
val
;
ndigits
++
;
if
(
ndigits
>=
8
)
{
if
(
nout
>=
clen
)
{
printf
(
"AR: code too long!
\n
"
);
return
;
}
*
code
++
=
cur_word
;
nout
++
;
ndigits
=
0
;
cur_word
=
0
;
}
nin
++
;
if
(
nin
>=
tlen
)
break
;
}
if
(
nout
&
1
)
{
printf
(
"AR: code was missing one word
\n
"
);
if
(
nout
>=
clen
)
{
printf
(
"AR: code too long!
\n
"
);
return
;
}
*
code
++
=
0
;
}
}
// AR code file - frontend is responsible for managing this
ARCodeFile
*
CodeFile
;
bool
Init
()
{
CodeFile
=
nullptr
;
return
true
;
}
void
DeInit
()
{
//
}
void
Reset
()
{
memset
(
CheatCodes
,
0
,
sizeof
(
CheatCodes
));
NumCheatCodes
=
0
;
// TODO: acquire codes from a sensible source!
CheatEntry
*
entry
=
&
CheatCodes
[
0
];
u32
*
ptr
=
&
entry
->
Code
[
0
];
/*char* test = R"(9209D09A 00000000
6209B468 00000000
B209B468 00000000
10000672 000003FF
D2000000 00000000
9209D09A 00000000
94000130 FCBF0000
6209B468 00000000
B209B468 00000000
200006B3 00000001
200006B4 00000001
D2000000 00000000
9209D09A 00000000
94000130 FC7F0000
6209B468 00000000
B209B468 00000000
10000672 00000000
D2000000 00000000)";
ParseTextCode(test, entry->Code, 2*64);
printf("PARSED CODE:\n");
for (int i = 0; i < 2*64; i+=2)
{
printf("%08X %08X\n", entry->Code[i], entry->Code[i+1]);
}
entry->Enabled = true;
NumCheatCodes++;*/
CodeFile
=
nullptr
;
}
void
SetCodeFile
(
ARCodeFile
*
file
)
{
CodeFile
=
file
;
}
...
...
@@ -147,9 +58,9 @@ D2000000 00000000)";
case ((x)+0x08): case ((x)+0x09): case ((x)+0x0A): case ((x)+0x0B): \
case ((x)+0x0C): case ((x)+0x0D): case ((x)+0x0E): case ((x)+0x0F)
void
RunCheat
(
CheatEntry
*
entry
)
void
RunCheat
(
ARCode
&
arcode
)
{
u32
*
code
=
&
entry
->
Code
[
0
];
u32
*
code
=
&
arcode
.
Code
[
0
];
u32
offset
=
0
;
u32
datareg
=
0
;
...
...
@@ -166,9 +77,11 @@ void RunCheat(CheatEntry* entry)
for
(;;)
{
if
(
code
>=
&
arcode
.
Code
[
arcode
.
CodeLen
])
break
;
u32
a
=
*
code
++
;
u32
b
=
*
code
++
;
if
((
a
|
b
)
==
0
)
break
;
u8
op
=
a
>>
24
;
...
...
@@ -179,7 +92,7 @@ void RunCheat(CheatEntry* entry)
if
((
op
&
0xF0
)
==
0xE0
)
{
for
(
u32
i
=
0
;
i
<
b
;
i
+=
8
)
*
code
+=
2
;
code
+=
2
;
}
continue
;
...
...
@@ -428,7 +341,7 @@ void RunCheat(CheatEntry* entry)
if
(
bytesleft
>
0
)
{
u8
*
leftover
=
(
u8
*
)
code
;
*
code
+=
2
;
code
+=
2
;
if
(
bytesleft
>=
4
)
{
NDS
::
ARM7Write32
(
dstaddr
,
*
(
u32
*
)
leftover
);
dstaddr
+=
4
;
...
...
@@ -477,13 +390,19 @@ void RunCheat(CheatEntry* entry)
void
RunCheats
()
{
// TODO: make it disableable in general
if
(
!
CodeFile
)
return
;
for
(
u32
i
=
0
;
i
<
NumCheatCodes
;
i
++
)
for
(
ARCodeCatList
::
iterator
i
=
CodeFile
->
Categories
.
begin
();
i
!=
CodeFile
->
Categories
.
end
()
;
i
++
)
{
CheatEntry
*
entry
=
&
CheatCodes
[
i
];
if
(
entry
->
Enabled
)
RunCheat
(
entry
);
ARCodeCat
&
cat
=
*
i
;
for
(
ARCodeList
::
iterator
j
=
cat
.
Codes
.
begin
();
j
!=
cat
.
Codes
.
end
();
j
++
)
{
ARCode
&
code
=
*
j
;
if
(
code
.
Enabled
)
RunCheat
(
code
);
}
}
}
...
...
src/AREngine.h
View file @
4cefff25
...
...
@@ -19,6 +19,8 @@
#ifndef ARENGINE_H
#define ARENGINE_H
#include "ARCodeFile.h"
namespace
AREngine
{
...
...
@@ -26,6 +28,8 @@ bool Init();
void
DeInit
();
void
Reset
();
void
SetCodeFile
(
ARCodeFile
*
file
);
void
RunCheats
();
}
...
...
src/CMakeLists.txt
View file @
4cefff25
...
...
@@ -3,7 +3,7 @@ project(core)
set
(
CMAKE_CXX_STANDARD 14
)
add_library
(
core STATIC
ARCode
List
.cpp
ARCode
File
.cpp
AREngine.cpp
ARM.cpp
ARM_InstrTable.h
...
...
src/frontend/qt_sdl/CheatsDialog.ui
View file @
4cefff25
...
...
@@ -74,6 +74,9 @@
<height>
0
</height>
</size>
</property>
<property
name=
"headerHidden"
>
<bool>
true
</bool>
</property>
</widget>
</item>
<item>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment