Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing cleo_arg_count opcode #125

Merged
merged 2 commits into from
Apr 17, 2024
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
- implemented support for **memory pointer string** arguments for all game's native opcodes
- **0B1E ([sign_extend](https://library.sannybuilder.com/#/sa/bitwise/0B1E))**
- **0DD5 ([get_game_platform](https://library.sannybuilder.com/#/sa/CLEO/0DD5))**
- **2000 ([get_cleo_arg_count](https://library.sannybuilder.com/#/sa/CLEO/2000))**
- **2002 ([cleo_return_with](https://library.sannybuilder.com/#/sa/CLEO/2002))**
- **2003 ([cleo_return_fail](https://library.sannybuilder.com/#/sa/CLEO/2003))**
- 'argument count' parameter of **0AB1 (cleo_call)** is now optional. `cleo_call @LABEL args 0` can be written as `cleo_call @LABEL`
Expand Down
31 changes: 23 additions & 8 deletions source/CCustomOpcodeSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ namespace CLEO
OpcodeResult __stdcall opcode_0AE3(CRunningScript* thread); // get_random_object_in_sphere_no_save_recursive

OpcodeResult __stdcall opcode_0DD5(CRunningScript* thread); // get_platform
// 2000 free slot

OpcodeResult __stdcall opcode_2000(CRunningScript* thread); // get_cleo_arg_count
// 2001 free slot
OpcodeResult __stdcall opcode_2002(CRunningScript* thread); // cleo_return_with
OpcodeResult __stdcall opcode_2003(CRunningScript* thread); // cleo_return_fail
Expand Down Expand Up @@ -247,7 +248,8 @@ namespace CLEO

CLEO_RegisterOpcode(0x0DD5, opcode_0DD5); // get_platform

// 2000, 2001 free
CLEO_RegisterOpcode(0x2000, opcode_2000); // get_cleo_arg_count
// 2001 free
CLEO_RegisterOpcode(0x2002, opcode_2002); // cleo_return_with
CLEO_RegisterOpcode(0x2003, opcode_2003); // cleo_return_fail
}
Expand Down Expand Up @@ -1042,18 +1044,19 @@ namespace CLEO
return thread->Suspend();
}
}
scmFunc->callArgCount = (BYTE)nParams;

static SCRIPT_VAR arguments[32];
SCRIPT_VAR* locals = thread->IsMission() ? missionLocals : thread->GetVarPtr();
SCRIPT_VAR* localsEnd = locals + 32;
SCRIPT_VAR* storedLocals = scmFunc->savedTls;

// collect arguments
for (DWORD i = 0; i < min(nParams, 32); i++)
for (DWORD i = 0; i < nParams; i++)
{
SCRIPT_VAR* arg = arguments + i;

auto paramType = (eDataType)*thread->GetBytePointer();
auto paramType = thread->PeekDataType();
if (IsImmInteger(paramType) || IsVariable(paramType))
{
*thread >> arg->dwParam;
Expand All @@ -1079,10 +1082,6 @@ namespace CLEO
}
}

// skip unused args
if (nParams > 32)
GetScriptParams(thread, nParams - 32);

// all arguments read
scmFunc->retnAddress = thread->GetBytePointer();

Expand Down Expand Up @@ -1520,6 +1519,22 @@ namespace CLEO
return OR_CONTINUE;
}

//2000=1, %1d% = get_cleo_arg_count
OpcodeResult __stdcall opcode_2000(CRunningScript* thread)
{
auto cs = reinterpret_cast<CCustomScript*>(thread);

ScmFunction* scmFunc = ScmFunction::Get(cs->GetScmFunction());
if (scmFunc == nullptr)
{
SHOW_ERROR("Quering argument count without preceding CLEO function call in script %s\nScript suspended.", cs->GetInfoStr().c_str());
return thread->Suspend();
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At some point this opcode might be extended to return number of arguments passed to current script with 004f, 0913, 0a92, etc.

But good for now


OPCODE_WRITE_PARAM_INT(scmFunc->callArgCount);
return OR_CONTINUE;
}

//2002=-1, cleo_return_with ...
OpcodeResult __stdcall opcode_2002(CRunningScript* thread)
{
Expand Down
3 changes: 3 additions & 0 deletions source/ScmFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ namespace CLEO
static void Clear();

unsigned short prevScmFunctionId, thisScmFunctionId;
BYTE callArgCount = 0; // args provided to cleo_call

// saved nesting context state
void* savedBaseIP;
BYTE* retnAddress;
BYTE* savedStack[8]; // gosub stack
Expand Down
34 changes: 34 additions & 0 deletions tests/cleo_tests/Cleo/2000.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{$CLEO .s}
{$INCLUDE_ONCE ../cleo_tester.inc}

script_name '2000'
test("2000 (get_cleo_arg_count)", tests)
terminate_this_custom_script


:return_arg_count
0@ = get_cleo_arg_count
cleo_return 1 0@


function tests
it("should return cleo call arguments count", test1)
return

function test1
cleo_call @return_arg_count {numParams} 0 {params} {result} 0@
assert_eq(0@, 0)

cleo_call @return_arg_count {numParams} 1 {params} 123 {result} 0@
assert_eq(0@, 1)

cleo_call @return_arg_count {numParams} 2 {params} 123 0@ {result} 0@
assert_eq(0@, 2)

cleo_call @return_arg_count {numParams} 3 {params} 123 0@ "some_text" {result} 0@
assert_eq(0@, 3)

cleo_call @return_arg_count {numParams} 25 {params} 123 0@ "some_text" 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 {result} 0@
assert_eq(0@, 25)
end
end
Loading