Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions docs/guides/lua.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,91 @@ Sleep for `length` milliseconds.

Pause the game if playing, resume otherwise.

### Ramsearch functions

Ramsearch functions configure a ram search similar to the one of the Ramsearch window. The parameters correspond to what can be found there.

| value_type | Number |
| -------------- | ------ |
| unsigned char | 0 |
| char | 1 |
| unsigned short | 2 |
| short | 3 |
| unsigned int | 4 |
| int | 5 |
| unsigned int64 | 6 |
| int64 | 7 |
| float | 8 |
| double | 9 |
| byte array | 10 |
| string | 11 |

| alignment | Number |
| -------------- | ------ |
| default | 0 |
| 1 | 1 |
| 2 | 2 |
| 4 | 3 |

| compare_type | Number |
| ---------------------- | ------ |
| Unknown/Previous Value | 0 |
| Specific Value | 1 |

In the `Specific Value` case, the value must be passed in the `compare_value` parameter.

| compare_operator | String |
| ------------------------ | ------ |
| Equal To | == |
| Not Equal To | != |
| Less Than | < |
| Greater Than | > |
| Less Than Or Equal To | <= |
| Greater Than Or Equal To | >= |
| Different By | ! |

In the `Different By` case, the value must be passed in the `different value` parameter.

MemFlags uses three bitwise options with values 1, 2, and 4: Exclude special regions, Exclude read-only regions, Exclude executable regions.
They combine by adding their values using a bitwise OR.
No options = 0, and all three selected = 7 (default).

#### ramsearch.newsearch

Number ramsearch.newsearch([Number value_type = 0], [Number alignment = 0], [Number compare_type = 0], [Number compare_value = 0], [String compare_operator = "=="], [Number different_value = 0], [Number memflags = 7], [String begin_address = "0000000000000000"], [String end_address = "00007fffffffffff"])

Start a new ramsearch. Returns number of results.

#### ramsearch.search

Number ramsearch.search([Number compare_type], [Number compare_value], [String compare_operator], [Number different_value])

Perform a new step on previously started search. Parameters that are not passed will default to their previous value set up in former calls to newsearch() or search() or using the `ramsearch:set_*` functions. Returns number of results.

#### ramsearch.get_current_value

Number ramsearch.get_current_value(Number index)

Get current value of address at a given index of the search results.

#### ramsearch.get_address

String ramsearch.get_address(Number index)

Get address at a given index of the search results

#### ramsearch.set_compare_operator

none ramsearch.set_compare_operator(String operator, [Number different_value])

Set comparison operator for next search. It is only necessary to pass the different value in the `Different By` case.

#### ramsearch.set_comparison_type

none ramsearch.set_comparison_type(Number type, [Number compare_value])

Set comparison type for next search. It is only necessary to pass the compare_value in the `Specific Value` case.

### Callbacks

#### callback.onStartup
Expand Down Expand Up @@ -393,3 +478,51 @@ Display a simple text on top of the game:
end

callback.onPaint(hello_world)

#### Using Ramsearch to automate finding x;y position in memory

local memx = ""
local x_position_frame_10 = 580

function onFrame()
local f = movie.currentFrame()
if f == 10 then
-- look for doubles of value 580 on frame 10
local nb_results= ramsearch.newsearch(9, 0, 1, x_position_frame_10, "==")
print(string.format("number of results on newsearch: %d", nb_results))
end
if f == 11 then
-- filter out addresses that changed on frame 11 (we didn't move)
local nb_results = ramsearch.search()
print(string.format("number of results on frame 11: %d", nb_results))
end
if f == 12 then
-- filter out addresses that didn't change on frame 12 (after we moved)
local nb_results = ramsearch.search(0, 0, "!=")
print(string.format("number of results on frame 12: %d", nb_results))
if nb_results == 1 then
-- We found our value, let's store it to display it in the
-- onPaint() callback
memx = ramsearch.get_address(0)
else
print("Error: found too many values")
for i = 0,nb_results-1,1
do
local v = ramsearch.get_current_value(i)
local addr = ramsearch.get_address(i)
print(string.format("current value: %f @ %s", v, addr))
end
end
end
end

function onPaint()
if memx ~= "" then
local x_num = tonumber(memx, 16)
local x = memory.readd(x_num)
local y_num = x_num + 56
local y = memory.readd(y_num)
gui.ellipse(x, y, 10, 10)
gui.text(100, 100, string.format("%f ; %f", x, y))
end
end
4 changes: 1 addition & 3 deletions src/program/GameLoop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -809,10 +809,8 @@ void GameLoop::processInputs(AllInputs &ai)
ai.clear();

/* Allow lua to modify inputs past the end of the movie */
Lua::Input::registerInputs(&ai, &modified);
Lua::Input::registerInputs(&ai, &modified_by_lua);
Lua::Callbacks::call(Lua::NamedLuaFunction::CallbackInput);
if (modified)
movie.inputs->wasModified();
}

/* Update controller inputs if controller window is shown */
Expand Down
1 change: 1 addition & 0 deletions src/program/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ libTAS_SOURCES = \
lua/Movie.cpp \
lua/Print.cpp \
lua/Runtime.cpp \
lua/Ramsearch.cpp \
movie/InputSerialization.cpp \
movie/MovieActionEditFrames.cpp \
movie/MovieActionInsertFrames.cpp \
Expand Down
2 changes: 2 additions & 0 deletions src/program/lua/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "Print.h"
#include "Runtime.h"
#include "Callbacks.h"
#include "Ramsearch.h"

#include <iostream>
extern "C" {
Expand Down Expand Up @@ -56,6 +57,7 @@ lua_State* Lua::Main::new_state()
Lua::Callbacks::registerFunctions(lua_state);
Lua::Print::init(lua_state);
Lua::Runtime::registerFunctions(lua_state, context);
Lua::Ramsearch::registerFunctions(lua_state, context);

return lua_state;
}
Expand Down
Loading