Skip to content

Commit

Permalink
Readme, doc, tools
Browse files Browse the repository at this point in the history
  • Loading branch information
thelink2012 committed Sep 7, 2014
1 parent fcdda9a commit 85e0cb5
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 37 deletions.
23 changes: 0 additions & 23 deletions LICENSE

This file was deleted.

29 changes: 29 additions & 0 deletions README.md
@@ -0,0 +1,29 @@
Open Limit Adjuster
==============================

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.

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.

### Goals
* Bring limit adjusters back to the scene, but not totally centralized into one person
* Avoid little limit adjusters here and there
* Be an extremely stable limit adjuster
* Purge out limits from the face of the community, we are in a dynamic world!

### Compiling

The source code targets pre-C++11 compilers with naked attribute, that is Visual Studio 2010 and above.

You'll need to following tools to compile the source code.
+ [CMake](http://www.cmake.org/) 2.8 or greater
+ [Visual Studio](http://www.visualstudio.com/downloads) 2010 or greater

Then run CMake in the base source directory to generate the projects file in the *msvc/* directory.
By using command line, this can be done by:

mkdir msvc
cd msvc
cmake ../

That's it, you have a Visual Studio solution now, you are ready to contribute and compile.
38 changes: 38 additions & 0 deletions doc/Creating Your Own Adjuster.md
@@ -0,0 +1,38 @@
Creating Your Own Adjuster
=============================

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.

Creating The Adjuster Instance
--------------------------------

First of all you need a new cpp file to implement your adjuster class.
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.

Then, you need to create a derived class from either `SimpleAdjuster` or `Adjuster`, those are in the *LimitAdjuster.h* header.
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`.
You can check examples of adjusters at the **src/sample/** directory.

The interface is simple and event-based:

* **The Limit Name**
+ `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).
+ `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
* **Changing the Limit**
+ 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
+ `ChangeLimit` is guaranteed to not get called more than once for each limit name.
+ The `Adjuster::IsUnlimited ` should be used if it's necessary to check if the string has the *unlimited* value.
* **Pos Processing**
+ 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.
* **Telling the Limit Usage**
+ Optionally `GetUsage` can be implemented to tell the user how much of the limit has been used
+ The `Adjuster::GetUsage<T>` method can be used to straightly get the string from the usage and max usage integers.
* **Injector and Game Version Manager**
+ The basic frontend for patches is the blessed injector library.
+ It includes a game version manager, that can be accessed from `Adjuster::GetGVM` or the shortcuts `Adjuster::IsIII`, `Adjuster::IsVC` and `Adjuster::IsSA`
+ 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.

Finally, you should instance the final adjuster object in the global scope, that will tell the Limit Adjuster about it's existence.
Don't forget to add the limit to the ini file at `doc/limit_adjuster_gta3vcsa.ini`.

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.
14 changes: 0 additions & 14 deletions doc/Creating Your Own Adjuster.txt

This file was deleted.

5 changes: 5 additions & 0 deletions src/LimitAdjuster.h
Expand Up @@ -87,6 +87,11 @@ class Adjuster
*/
virtual bool GetUsage(int id, std::string& usagebuf) { return false; }

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

public:

Expand Down
8 changes: 8 additions & 0 deletions src/dllmain.cpp
Expand Up @@ -174,6 +174,14 @@ void AdjustLimits(const std::map<std::string, std::string>& section)
}
}
}

// Run Process()
std::map<Adjuster*, int> adjz; // list of already processed adjusters (int is dummy, too lazy to use std::set)
for(auto it = limits.begin(); it != limits.end(); ++it)
{
auto* adj = it->second.adjuster;
if(adjz[adj]++ == 0) adj->Process(); // Run only once for each Adjuster*
}
}


Expand Down
58 changes: 58 additions & 0 deletions tools/idc/find_xrefs.idc
@@ -0,0 +1,58 @@
#include <idc.idc>

static main()
{
auto ea, ref;
auto f = 0, fname = AskFile(1, "*.*", "Select a file to save the references");
if(fname != 0 && (f = fopen(fname, "w")) != 0)
{
auto begin_ea = BADADDR, end_ea = BADADDR;

auto yn = AskYN(1, "Would you like to search all xrefs to the identifier the cursor is over?");
if(yn == 0)
{
begin_ea = AskAddr(0x0, "What's the begin of the data to search refs for?");
if(begin_ea != BADADDR) end_ea = AskAddr(0x0, "What's the end of the data (exclusive) to search refs for?");
}
else if(yn == 1)
{
begin_ea = ScreenEA();
end_ea = begin_ea + ItemSize(begin_ea);
}

if(begin_ea != BADADDR && end_ea != BADADDR)
{
for(ea = begin_ea; ea < end_ea; ++ea)
{
// Iterate on the data range finding the xrefs
for (ref = DfirstB(ea); ref != BADADDR; ref = DnextB(ea, ref))
{
// Find the exact position of the reference (assumes little endian code)
auto pos = ref, inst, max_inst = NextHead(ref, BADADDR) - 3; // 'cuz of ref
if(max_inst != BADADDR)
{
for(inst = ref; inst < max_inst; ++inst)
{
auto v = (GetOriginalByte(inst) | (GetOriginalByte(inst+1) << 8) | (GetOriginalByte(inst+2) << 16) | (GetOriginalByte(inst+3) << 24));
if(v == ea) { pos = inst; break; }
}

if(inst == max_inst)
Message("Warning: Could not find exact address of reference, this should never happen\n");
}

// Output it to the file
auto str = "0x" + ltoa(pos, 16) + " = 0x" + ltoa(begin_ea, 16) + " + 0x" + ltoa(ea - begin_ea, 16) + " -> " + GetDisasm(ref) + "\n";
//Message(str);
fprintf(f, str);
}
}

Message("References found successfully\n");
}

fclose(f);
}
else
Message("Failed to open file to output references\n");
}

0 comments on commit 85e0cb5

Please sign in to comment.