Skip to content

Commit 7f7e967

Browse files
committed
Merge pull request #14 from thelink2012/readme
Readme, doc, tools
2 parents fcdda9a + 85e0cb5 commit 7f7e967

File tree

7 files changed

+138
-37
lines changed

7 files changed

+138
-37
lines changed

LICENSE

Lines changed: 0 additions & 23 deletions
This file was deleted.

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
Open Limit Adjuster
2+
==============================
3+
4+
This is a open source limit adjuster for Grand Theft Auto III, Vice City and San Andreas aiming to bring back limit adjusters to the scene.
5+
6+
But it does not aim to be just a limit ***adjuster***, but a limit ***purger***, that's, turning whatever previosly was limited into unlimited, being only limited by the machine/application capacity.
7+
8+
### Goals
9+
* Bring limit adjusters back to the scene, but not totally centralized into one person
10+
* Avoid little limit adjusters here and there
11+
* Be an extremely stable limit adjuster
12+
* Purge out limits from the face of the community, we are in a dynamic world!
13+
14+
### Compiling
15+
16+
The source code targets pre-C++11 compilers with naked attribute, that is Visual Studio 2010 and above.
17+
18+
You'll need to following tools to compile the source code.
19+
+ [CMake](http://www.cmake.org/) 2.8 or greater
20+
+ [Visual Studio](http://www.visualstudio.com/downloads) 2010 or greater
21+
22+
Then run CMake in the base source directory to generate the projects file in the *msvc/* directory.
23+
By using command line, this can be done by:
24+
25+
mkdir msvc
26+
cd msvc
27+
cmake ../
28+
29+
That's it, you have a Visual Studio solution now, you are ready to contribute and compile.

doc/Creating Your Own Adjuster.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
Creating Your Own Adjuster
2+
=============================
3+
4+
This Limit Adjuster is very flexible when we talk about adding newer limits, it's pretty straightforward if you already know where to patch, you just need to create one cpp file with a class instance and that's it.
5+
6+
Creating The Adjuster Instance
7+
--------------------------------
8+
9+
First of all you need a new cpp file to implement your adjuster class.
10+
In our example we're going to call it *foo.cpp*, right, create it at the src folder and add it to the *CMakeLists.txt* source files.
11+
12+
Then, you need to create a derived class from either `SimpleAdjuster` or `Adjuster`, those are in the *LimitAdjuster.h* header.
13+
The difference between then, is that `Adjuster` is more complex than `SimpleAdjuster` and is supposed to be used when one class will handle more than one limit. Generally you would use `SimpleAdjuster`.
14+
You can check examples of adjusters at the **src/sample/** directory.
15+
16+
The interface is simple and event-based:
17+
18+
* **The Limit Name**
19+
+ `GetLimitName` in `SimpleAdjuster` should return the name of the limit (for the ini file) or null if the limit is not supported at this time (i.e. because game is not supported).
20+
+ `GetLimits` in `Adjuster` should return an static and null terminated array of `Limit` objects, each describes one limit, with name and identifier (possibily an user data value for latter use). It can also return null in case of incompatible game
21+
* **Changing the Limit**
22+
+ When the ini entry for the limit is found, `ChangeLimit` is called with the id of the limit and it's value string, here the limit should be patched
23+
+ `ChangeLimit` is guaranteed to not get called more than once for each limit name.
24+
+ The `Adjuster::IsUnlimited ` should be used if it's necessary to check if the string has the *unlimited* value.
25+
* **Pos Processing**
26+
+ Optionally `Process` can be implemented to post process the values received at `ChangeLimit`, useful for complex adjusters with many limits where all of them are dependent on each other.
27+
* **Telling the Limit Usage**
28+
+ Optionally `GetUsage` can be implemented to tell the user how much of the limit has been used
29+
+ The `Adjuster::GetUsage<T>` method can be used to straightly get the string from the usage and max usage integers.
30+
* **Injector and Game Version Manager**
31+
+ The basic frontend for patches is the blessed injector library.
32+
+ It includes a game version manager, that can be accessed from `Adjuster::GetGVM` or the shortcuts `Adjuster::IsIII`, `Adjuster::IsVC` and `Adjuster::IsSA`
33+
+ You are not totally required to use the injector library if you are implementing a pre-existing adjuster, but making a biding for the other library that translates into injector calls is recommended.
34+
35+
Finally, you should instance the final adjuster object in the global scope, that will tell the Limit Adjuster about it's existence.
36+
Don't forget to add the limit to the ini file at `doc/limit_adjuster_gta3vcsa.ini`.
37+
38+
If still in doubt, the best place to learn the interface are the in the already implemented adjusters itself. But as noted before simple samples are available at the *src/sample/* directory.

doc/Creating Your Own Adjuster.txt

Lines changed: 0 additions & 14 deletions
This file was deleted.

src/LimitAdjuster.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ class Adjuster
8787
*/
8888
virtual bool GetUsage(int id, std::string& usagebuf) { return false; }
8989

90+
/*
91+
* Called after all ChangeLimit's have been called, to post process data, etc
92+
* Note this is called even if this ChangeLimit has not been called because there's no ini entry for it
93+
*/
94+
virtual void Process() {}
9095

9196
public:
9297

src/dllmain.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ void AdjustLimits(const std::map<std::string, std::string>& section)
174174
}
175175
}
176176
}
177+
178+
// Run Process()
179+
std::map<Adjuster*, int> adjz; // list of already processed adjusters (int is dummy, too lazy to use std::set)
180+
for(auto it = limits.begin(); it != limits.end(); ++it)
181+
{
182+
auto* adj = it->second.adjuster;
183+
if(adjz[adj]++ == 0) adj->Process(); // Run only once for each Adjuster*
184+
}
177185
}
178186

179187

tools/idc/find_xrefs.idc

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <idc.idc>
2+
3+
static main()
4+
{
5+
auto ea, ref;
6+
auto f = 0, fname = AskFile(1, "*.*", "Select a file to save the references");
7+
if(fname != 0 && (f = fopen(fname, "w")) != 0)
8+
{
9+
auto begin_ea = BADADDR, end_ea = BADADDR;
10+
11+
auto yn = AskYN(1, "Would you like to search all xrefs to the identifier the cursor is over?");
12+
if(yn == 0)
13+
{
14+
begin_ea = AskAddr(0x0, "What's the begin of the data to search refs for?");
15+
if(begin_ea != BADADDR) end_ea = AskAddr(0x0, "What's the end of the data (exclusive) to search refs for?");
16+
}
17+
else if(yn == 1)
18+
{
19+
begin_ea = ScreenEA();
20+
end_ea = begin_ea + ItemSize(begin_ea);
21+
}
22+
23+
if(begin_ea != BADADDR && end_ea != BADADDR)
24+
{
25+
for(ea = begin_ea; ea < end_ea; ++ea)
26+
{
27+
// Iterate on the data range finding the xrefs
28+
for (ref = DfirstB(ea); ref != BADADDR; ref = DnextB(ea, ref))
29+
{
30+
// Find the exact position of the reference (assumes little endian code)
31+
auto pos = ref, inst, max_inst = NextHead(ref, BADADDR) - 3; // 'cuz of ref
32+
if(max_inst != BADADDR)
33+
{
34+
for(inst = ref; inst < max_inst; ++inst)
35+
{
36+
auto v = (GetOriginalByte(inst) | (GetOriginalByte(inst+1) << 8) | (GetOriginalByte(inst+2) << 16) | (GetOriginalByte(inst+3) << 24));
37+
if(v == ea) { pos = inst; break; }
38+
}
39+
40+
if(inst == max_inst)
41+
Message("Warning: Could not find exact address of reference, this should never happen\n");
42+
}
43+
44+
// Output it to the file
45+
auto str = "0x" + ltoa(pos, 16) + " = 0x" + ltoa(begin_ea, 16) + " + 0x" + ltoa(ea - begin_ea, 16) + " -> " + GetDisasm(ref) + "\n";
46+
//Message(str);
47+
fprintf(f, str);
48+
}
49+
}
50+
51+
Message("References found successfully\n");
52+
}
53+
54+
fclose(f);
55+
}
56+
else
57+
Message("Failed to open file to output references\n");
58+
}

0 commit comments

Comments
 (0)