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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@
[submodule "lib/o1heap"]
path = lib/o1heap
url = https://github.com/pavel-kirienko/o1heap.git
[submodule "lib/rbtree"]
path = lib/rbtree
url = https://github.com/SWFRecomp/rb-tree.git
23 changes: 15 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,22 @@ option(NO_GRAPHICS "Build without graphics support (console-only)" OFF)
# Core sources (always included)
set(CORE_SOURCES
${PROJECT_SOURCE_DIR}/src/actionmodern/action.c
${PROJECT_SOURCE_DIR}/src/actionmodern/objects.c
${PROJECT_SOURCE_DIR}/src/actionmodern/variables.c
${PROJECT_SOURCE_DIR}/src/memory/heap.c
${PROJECT_SOURCE_DIR}/src/apis/rbtree/rbtree.c
${PROJECT_SOURCE_DIR}/src/utils.c

${PROJECT_SOURCE_DIR}/lib/o1heap/o1heap/o1heap.c

# Compile hashmap file directly to avoid undefined symbols on Linux
# Compile libs directly to avoid undefined symbols on Linux
${PROJECT_SOURCE_DIR}/lib/c-hashmap/map.c
${PROJECT_SOURCE_DIR}/lib/rbtree/rb_tree.c
${PROJECT_SOURCE_DIR}/lib/o1heap/o1heap/o1heap.c
)

file(GLOB_RECURSE RUNTIME_API_SOURCES ${PROJECT_SOURCE_DIR}/src/actionmodern/runtime_api/*.c)



if(NO_GRAPHICS)
# Console-only mode
message(STATUS "Building in NO_GRAPHICS mode (console-only)")
Expand All @@ -33,8 +39,6 @@ if(NO_GRAPHICS)
${PROJECT_SOURCE_DIR}/src/libswf/swf_core.c
${PROJECT_SOURCE_DIR}/src/libswf/tag_stubs.c
)

set(SOURCES ${CORE_SOURCES} ${SWF_SOURCES})
else()
# Full graphics mode
message(STATUS "Building in full graphics mode")
Expand All @@ -44,10 +48,10 @@ else()
${PROJECT_SOURCE_DIR}/src/libswf/tag.c
${PROJECT_SOURCE_DIR}/src/flashbang/flashbang.c
)

set(SOURCES ${CORE_SOURCES} ${SWF_SOURCES})
endif()

set(SOURCES ${CORE_SOURCES} ${SWF_SOURCES} ${RUNTIME_API_SOURCES})

add_library(${PROJECT_NAME} STATIC ${SOURCES})

if (WIN32)
Expand Down Expand Up @@ -85,13 +89,16 @@ endif()

target_include_directories(${PROJECT_NAME} PRIVATE
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/include/apis
${PROJECT_SOURCE_DIR}/include/actionmodern
${PROJECT_SOURCE_DIR}/include/actionmodern/runtime_api
${PROJECT_SOURCE_DIR}/include/libswf
${PROJECT_SOURCE_DIR}/include/flashbang
${PROJECT_SOURCE_DIR}/include/memory
${PROJECT_SOURCE_DIR}/lib/c-hashmap
${PROJECT_SOURCE_DIR}/lib/SDL3/include
${PROJECT_SOURCE_DIR}/lib/rbtree
${PROJECT_SOURCE_DIR}/lib/o1heap/o1heap
${PROJECT_SOURCE_DIR}/lib/SDL3/include
zlib
lzma/liblzma/api
)
Expand Down
79 changes: 72 additions & 7 deletions include/actionmodern/action.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
#pragma once

#include <swf.h>
#include <objects.h>
#include <variables.h>
#include <stackvalue.h>

#define STACK_VAR_SIZE (4 + 4 + 8 + 8)
#define STACK_FUNC_SIZE (4 + 4 + 8 + 8 + 8 + 8)

#define PUSH(t, v) \
OLDSP = SP; \
SP -= 4 + 4 + 8 + 8; \
SP -= STACK_VAR_SIZE; \
SP &= ~7; \
STACK[SP] = t; \
VAL(u32, &STACK[SP + 4]) = OLDSP; \
VAL(u64, &STACK[SP + 16]) = v; \

// Push string with ID (for constant strings from compiler)
#define PUSH_STR_ID(v, n, id) \
#define PUSH_STR_ID(v, id, n) \
OLDSP = SP; \
SP -= 4 + 4 + 8 + 8; \
SP -= STACK_VAR_SIZE; \
SP &= ~7; \
STACK[SP] = ACTION_STACK_VALUE_STRING; \
VAL(u32, &STACK[SP + 4]) = OLDSP; \
Expand All @@ -24,7 +28,7 @@
VAL(char*, &STACK[SP + 16]) = v; \

// Push string without ID (for dynamic strings, ID = 0)
#define PUSH_STR(v, n) PUSH_STR_ID(v, n, 0)
#define PUSH_STR(v, n) PUSH_STR_ID(v, 0, n)

#define PUSH_STR_LIST(n, size) \
OLDSP = VAL(u32, &STACK[SP_SECOND_TOP + 4]); \
Expand All @@ -34,7 +38,22 @@
VAL(u32, &STACK[SP + 4]) = OLDSP; \
VAL(u32, &STACK[SP + 8]) = n; \

#define PUSH_VAR(p) pushVar(app_context, p);
#define PUSH_FUNC(v, id, f, args) \
OLDSP = SP; \
SP -= STACK_FUNC_SIZE; \
SP &= ~7; \
STACK[SP] = ACTION_STACK_VALUE_FUNCTION; \
VAL(u32, &STACK[SP + 4]) = OLDSP; \
VAL(u32, &STACK[SP + 12]) = id; \
VAL(u64, &STACK[SP + 16]) = (u64) v; \
VAL(u64, &STACK[SP + 24]) = (u64) f; \
VAL(u64, &STACK[SP + 32]) = (u64) args; \

#define PUSH_UNDEFINED() PUSH(ACTION_STACK_VALUE_UNDEFINED, 0)

#define PUSH_OBJ(o) PUSH(ACTION_STACK_VALUE_OBJECT, (u64) o)

#define PUSH_VAR(p) pushVar(app_context, p)

#define POP() \
SP = VAL(u32, &STACK[SP + 4]); \
Expand All @@ -47,12 +66,18 @@
#define STACK_TOP_N VAL(u32, &STACK[SP + 8])
#define STACK_TOP_ID VAL(u32, &STACK[SP + 12])
#define STACK_TOP_VALUE VAL(u64, &STACK[SP + 16])
#define STACK_TOP_FUNC VAL(u64, &STACK[SP + 24])
#define STACK_TOP_FUNC_ARGS VAL(u64, &STACK[SP + 32])

#define SP_SECOND_TOP VAL(u32, &STACK[SP + 4])
#define STACK_SECOND_TOP_TYPE STACK[SP_SECOND_TOP]
#define STACK_SECOND_TOP_N VAL(u32, &STACK[SP_SECOND_TOP + 8])
#define STACK_SECOND_TOP_ID VAL(u32, &STACK[SP_SECOND_TOP + 12])
#define STACK_SECOND_TOP_VALUE VAL(u64, &STACK[SP_SECOND_TOP + 16])
#define STACK_SECOND_TOP_FUNC VAL(u64, &STACK[SP_SECOND_TOP + 24])
#define STACK_SECOND_TOP_FUNC_ARGS VAL(u64, &STACK[SP_SECOND_TOP + 32])

#define RETURN_VOID() PUSH_UNDEFINED()

#define VAL(type, x) *((type*) x)

Expand All @@ -61,26 +86,66 @@

extern ActionVar* temp_val;

void initTime();
// Global object
// Initialized on first use via initActions()
extern ASObject* _global;

void initActions(SWFAppContext* app_context);

void pushVar(SWFAppContext* app_context, ActionVar* p);

ASProperty* getPropertyInThisScope(u32 string_id, const char* name, u32 name_len);

// Arithmetic Operations
void actionAdd(SWFAppContext* app_context);
void actionSubtract(SWFAppContext* app_context);
void actionMultiply(SWFAppContext* app_context);
void actionDivide(SWFAppContext* app_context);

// Comparison Operations
void actionEquals(SWFAppContext* app_context);
void actionLess(SWFAppContext* app_context);
void actionAnd(SWFAppContext* app_context);
void actionOr(SWFAppContext* app_context);
void actionNot(SWFAppContext* app_context);

// String Operations
void actionStringEquals(SWFAppContext* app_context, char* a_str, char* b_str);
void actionStringLength(SWFAppContext* app_context, char* v_str);
void actionStringAdd(SWFAppContext* app_context, char* a_str, char* b_str);

// Variable Operations
void actionGetVariable(SWFAppContext* app_context);
void actionSetVariable(SWFAppContext* app_context);

// Utility Operations
void actionTrace(SWFAppContext* app_context);
void actionGetTime(SWFAppContext* app_context);
void actionGetTime(SWFAppContext* app_context);

// Object Operations
void actionGetMember(SWFAppContext* app_context);
void actionSetMember(SWFAppContext* app_context);
void actionTypeof(SWFAppContext* app_context, char* str_buffer);
void actionEnumerate(SWFAppContext* app_context, char* str_buffer);
void actionDelete(SWFAppContext* app_context);
void actionDelete2(SWFAppContext* app_context, char* str_buffer);
void actionNewObject(SWFAppContext* app_context);
void actionNewMethod(SWFAppContext* app_context);
void actionInitObject(SWFAppContext* app_context);

// Array Operations
void actionInitArray(SWFAppContext* app_context);

// Function Operations
void actionDefineLocal(SWFAppContext* app_context);
void actionDefineLocal2(SWFAppContext* app_context);
void actionCallFunction(SWFAppContext* app_context);
void actionCallMethod(SWFAppContext* app_context);

// Stack/Register Operations
void actionStoreRegister(SWFAppContext* app_context, u8 register_num);

// Function Definitions
void actionDefineFunction(SWFAppContext* app_context, u32 string_id, action_func func, u32* args, bool anonymous);

typedef ActionVar (*Function2Ptr)(SWFAppContext* app_context, ActionVar* args, u32 arg_count, ActionVar* registers, void* this_obj);
30 changes: 30 additions & 0 deletions include/actionmodern/initial_strings_decls.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#include <Object.h>

typedef enum
{
STR_ID_EMPTY = 1,
STR_ID_GLOBAL,
STR_ID_RECOMP,
STR_ID_ARG1,
STR_ID_ARG2,
STR_ID_ARG3,
STR_ID_ARG4,
STR_ID_ARG5,
STR_ID_ARG6,
STR_ID_OBJECT,
STR_ID_THIS,
STR_ID_LENGTH,
STR_ID_MATH,
STR_ID_ABS,
STR_ID_X,
} StringIds;

typedef struct
{
u32 object_string_id;
u32 func_string_id;
action_func func;
u32* args;
} RuntimeFunc;
7 changes: 7 additions & 0 deletions include/actionmodern/initial_strings_defs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <initial_strings_decls.h>

RuntimeFunc runtime_funcs[] =
{
{0, STR_ID_OBJECT, new_Object, NULL},
{STR_ID_MATH, STR_ID_ABS, Math_abs, (u32*) &(u32[]){ STR_ID_X }},
};
Loading