Skip to content

Commit

Permalink
Add Lua support
Browse files Browse the repository at this point in the history
  • Loading branch information
AJenbo committed Oct 8, 2023
1 parent e18b37a commit 1abcbec
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 4 deletions.
24 changes: 24 additions & 0 deletions 3rdParty/Lua/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
include(functions/FetchContent_MakeAvailableExcludeFromAll)

set(LUA_ENABLE_TESTING OFF)
set(LUA_BUILD_COMPILER OFF)
if(DEVILUTIONX_STATIC_LUA)
set(LUA_ENABLE_SHARED OFF)
else()
set(LUA_ENABLE_SHARED ON)
endif()

include(FetchContent)
FetchContent_Declare(Lua
URL https://github.com/walterschell/Lua/archive/88246d621abf7b6fba9332f49229d507f020e450.tar.gz
URL_HASH MD5=03b76927cb5341ffc53bea12c37ddcca
)
FetchContent_MakeAvailableExcludeFromAll(Lua)

if(ANDROID AND ("${ANDROID_ABI}" STREQUAL "armeabi-v7a" OR "${ANDROID_ABI}" STREQUAL "x86"))
target_compile_definitions(lua_internal INTERFACE -DLUA_USE_C89)
elseif(NINTENDO_3DS OR VITA OR NINTENDO_SWITCH OR NXDK)
target_compile_definitions(lua_static PUBLIC -DLUA_USE_C89)
elseif(IOS)
target_compile_definitions(lua_static PUBLIC -DLUA_USE_IOS)
endif()
1 change: 1 addition & 0 deletions CMake/Assets.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ set(devilutionx_assets
levels/l2data/bonechat.dun
levels/towndata/automap.dun
levels/towndata/automap.amp
lua/init.lua
nlevels/cutl5w.clx
nlevels/cutl6w.clx
nlevels/l5data/cornerstone.dun
Expand Down
23 changes: 23 additions & 0 deletions CMake/Dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,29 @@ if(SUPPORTS_MPQ)
endif()
endif()

find_package(Lua 5.4 QUIET)
if(Lua_FOUND)
message("-- Found Lua ${LUA_VERSION_STRING}")
set(DEVILUTIONX_STATIC_LUA OFF)
else()
if(NOT DEFINED DEVILUTIONX_SYSTEM_LUA)
message("-- Suitable system Lua package not found, will use Lua from source")
set(DEVILUTIONX_SYSTEM_LUA OFF)
endif()
endif()
dependency_options("lua" DEVILUTIONX_SYSTEM_LUA ON DEVILUTIONX_STATIC_LUA)
if(NOT DEVILUTIONX_SYSTEM_LUA)
add_subdirectory(3rdParty/Lua)
if(DEVILUTIONX_STATIC_LUA)
set(LUA_LIBRARIES lua_static)
else()
set(LUA_LIBRARIES lua_shared)
endif()
else()
find_package(Lua 5.4 REQUIRED)
include_directories(${LUA_INCLUDE_DIR})
endif()

if(SCREEN_READER_INTEGRATION)
if(WIN32)
add_subdirectory(3rdParty/tolk)
Expand Down
26 changes: 26 additions & 0 deletions Packaging/resources/assets/lua/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Events = {}

function Events:RegisterEvent(eventName)
self[eventName] = {
Functions = {},
Add = function(func)
table.insert(self[eventName].Functions, func)
end,
Remove = function(func)
for i, f in ipairs(self[eventName].Functions) do
if f == func then
table.remove(self[eventName].Functions, i)
break
end
end
end,
Trigger = function()
for _, func in ipairs(self[eventName].Functions) do
func()
end
end,
}
end

Events:RegisterEvent("OnGameBoot")
Events:RegisterEvent("OnGameStart")
3 changes: 3 additions & 0 deletions Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ set(libdevilutionx_SRCS
utils/format_int.cpp
utils/language.cpp
utils/logged_fstream.cpp
utils/lua.cpp
utils/paths.cpp
utils/parse_int.cpp
utils/pcx_to_clx.cpp
Expand Down Expand Up @@ -287,6 +288,8 @@ if(DISCORD_INTEGRATION)
target_link_libraries(libdevilutionx PRIVATE discord discord_game_sdk)
endif()

target_link_libraries(libdevilutionx PRIVATE ${LUA_LIBRARIES})

if(SCREEN_READER_INTEGRATION AND WIN32)
target_compile_definitions(libdevilutionx PRIVATE Tolk)
endif()
Expand Down
4 changes: 4 additions & 0 deletions Source/diablo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
#include "utils/console.h"
#include "utils/display.h"
#include "utils/language.h"
#include "utils/lua.hpp"
#include "utils/parse_int.hpp"
#include "utils/paths.h"
#include "utils/screen_reader.hpp"
Expand Down Expand Up @@ -822,6 +823,7 @@ void RunGameLoop(interface_mode uMsg)
nthread_ignore_mutex(false);

discord_manager::StartGame();
LuaEvent("OnGameStart");
#ifdef GPERF_HEAP_FIRST_GAME_ITERATION
unsigned run_game_iteration = 0;
#endif
Expand Down Expand Up @@ -1230,6 +1232,7 @@ void DiabloDeinit()
{
FreeItemGFX();

LuaShutdown();
ShutDownScreenReader();

if (gbSndInited)
Expand Down Expand Up @@ -2449,6 +2452,7 @@ int DiabloMain(int argc, char **argv)
LoadLanguageArchive();

ApplicationInit();
LuaInitialize();
SaveOptions();

// Finally load game data
Expand Down
147 changes: 147 additions & 0 deletions Source/utils/lua.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
#include "utils/lua.hpp"

#include <string_view>

extern "C" {
#include "lauxlib.h"
#include "lua.h"
#include "lualib.h"
}

#include "engine/assets.hpp"
#include "plrmsg.h"
#include "utils/console.h"

namespace devilution {

namespace {

lua_State *LuaState;

int LuaPrint(lua_State *state)
{
int nargs = lua_gettop(state);
if (nargs >= 1 && lua_isstring(state, 1)) {
std::string msg = lua_tostring(state, 1);
msg += "\n";
printInConsole(msg);
}

return 0;
}

int LuaPlayerMessage(lua_State *state)
{
int nargs = lua_gettop(state);
if (nargs >= 1 && lua_isstring(state, 1)) {
std::string_view msg = lua_tostring(state, 1);
EventPlrMsg(msg, UiFlags::ColorRed);
}

return 0;
}

void RunScript(std::string_view path)
{
AssetRef ref = FindAsset(path);
if (!ref.ok())
return;

const size_t size = ref.size();
std::unique_ptr<char[]> luaScript { new char[size + 1] };

AssetHandle handle = OpenAsset(std::move(ref));
if (!handle.ok())
return;

if (size > 0 && !handle.read(luaScript.get(), size))
return;

luaScript[size] = '\0'; // Terminate string

int status = luaL_loadstring(LuaState, luaScript.get());
if (status == LUA_OK)
status = lua_pcall(LuaState, 0, 0, 0);
if (status != LUA_OK)
SDL_Log("%s", lua_tostring(LuaState, -1));
}

} // namespace

void LuaInitialize()
{
LuaState = luaL_newstate();

// Load libraries
luaL_requiref(LuaState, LUA_GNAME, luaopen_base, 1);
lua_pop(LuaState, 1);
luaL_requiref(LuaState, LUA_LOADLIBNAME, luaopen_package, 1);
lua_pop(LuaState, 1);
luaL_requiref(LuaState, LUA_COLIBNAME, luaopen_coroutine, 1);
lua_pop(LuaState, 1);
luaL_requiref(LuaState, LUA_TABLIBNAME, luaopen_table, 1);
lua_pop(LuaState, 1);
luaL_requiref(LuaState, LUA_STRLIBNAME, luaopen_string, 1);
lua_pop(LuaState, 1);
luaL_requiref(LuaState, LUA_MATHLIBNAME, luaopen_math, 1);
lua_pop(LuaState, 1);
luaL_requiref(LuaState, LUA_UTF8LIBNAME, luaopen_utf8, 1);
lua_pop(LuaState, 1);

#ifdef _DEBUG
luaL_requiref(LuaState, LUA_DBLIBNAME, luaopen_debug, 1);
lua_pop(LuaState, 1);
#endif

// Registering globals
lua_register(LuaState, "print", LuaPrint);
lua_pushstring(LuaState, LUA_VERSION);
lua_setglobal(LuaState, "_VERSION");

// Registering devilutionx object table
lua_newtable(LuaState);
lua_pushcfunction(LuaState, LuaPlayerMessage);
lua_setfield(LuaState, -2, "message");
lua_setglobal(LuaState, "devilutionx");

RunScript("lua/init.lua");
RunScript("lua/user.lua");

LuaEvent("OnGameBoot");
}

void LuaShutdown()
{
if (LuaState == nullptr)
return;

lua_close(LuaState);
}

void LuaEvent(std::string name)
{
lua_getglobal(LuaState, "Events");
if (!lua_istable(LuaState, -1)) {
lua_pop(LuaState, 1);
SDL_Log("Events table missing!");
return;
}
lua_getfield(LuaState, -1, name.c_str());
if (!lua_istable(LuaState, -1)) {
lua_pop(LuaState, 2);
SDL_Log("Events.%s event not registered", name.c_str());
return;
}
lua_getfield(LuaState, -1, "Trigger");
if (!lua_isfunction(LuaState, -1)) {
lua_pop(LuaState, 3);
SDL_Log("Events.%s.Trigger is not a function", name.c_str());
return;
}
if (lua_pcall(LuaState, 0, 0, 0) != LUA_OK) {
SDL_Log("%s", lua_tostring(LuaState, -1));
}
lua_pop(LuaState, 2);
}

} // namespace devilution
11 changes: 11 additions & 0 deletions Source/utils/lua.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

#include <string>

namespace devilution {

void LuaInitialize();
void LuaShutdown();
void LuaEvent(std::string name);

} // namespace devilution
2 changes: 2 additions & 0 deletions test/timedemo_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "pfile.h"
#include "playerdat.hpp"
#include "utils/display.h"
#include "utils/lua.hpp"
#include "utils/paths.h"

using namespace devilution;
Expand All @@ -33,6 +34,7 @@ void RunTimedemo(std::string timedemoFolderName)

InitKeymapActions();
LoadOptions();
LuaInitialize();

const int demoNumber = 0;

Expand Down
8 changes: 4 additions & 4 deletions uwp-project/devilutionx.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Link>
<AdditionalDependencies>sdl_image.lib;libpng16_staticd.lib;pkware.lib;fmtd.lib;zlibstatic.lib;bzip2.lib;libsmackerdec.lib;libmpq.lib;libdevilutionx.lib;sdl2.lib;sdl_audiolib.lib;asio.lib;sodium.lib;zt.lib;lwip_pic.lib;miniupnpc_pic.lib;natpmp_pic.lib;zt_pic.lib;zto_pic.lib;shlwapi.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\build\SDL\VisualC-WinRT\x64\Debug\SDL-UWP;..\build\3rdParty\SDL_image\Debug;..\build\_deps\zlib-build\Debug;..\build\3rdParty\PKWare\Debug;..\build\3rdParty\bzip2\Debug;..\build\3rdParty\libsmackerdec\Debug;..\build\3rdParty\libmpq\Debug;..\build\_deps\sdl_audiolib-build\Debug;..\build\3rdParty\asio\Release;..\build\_deps\libsodium-build\Debug;..\build\_deps\libzt-build\lib\Debug;..\build\_deps\libfmt-build\Debug;..\build\_deps\libpng-build\Debug;..\build\Source\libdevilutionx.dir\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>sdl_image.lib;libpng16_staticd.lib;pkware.lib;fmtd.lib;zlibstatic.lib;bzip2.lib;libsmackerdec.lib;libmpq.lib;libdevilutionx.lib;lua_static.lib;sdl2.lib;sdl_audiolib.lib;asio.lib;sodium.lib;zt.lib;lwip_pic.lib;miniupnpc_pic.lib;natpmp_pic.lib;zt_pic.lib;zto_pic.lib;shlwapi.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\build\SDL\VisualC-WinRT\x64\Debug\SDL-UWP;..\build\3rdParty\SDL_image\Debug;..\build\_deps\zlib-build\Debug;..\build\3rdParty\PKWare\Debug;..\build\3rdParty\bzip2\Debug;..\build\3rdParty\libsmackerdec\Debug;..\build\3rdParty\libmpq\Debug;..\build\_deps\lua-build\lua-5.4.6\Debug;..\build\_deps\sdl_audiolib-build\Debug;..\build\3rdParty\asio\Debug;..\build\_deps\libsodium-build\Debug;..\build\_deps\libzt-build\lib\Debug;..\build\_deps\libfmt-build\Debug;..\build\_deps\libpng-build\Debug;..\build\Source\libdevilutionx.dir\Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<ClCompile>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
Expand All @@ -92,8 +92,8 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
<AdditionalDependencies>sdl_image.lib;libpng16_static.lib;pkware.lib;fmt.lib;zlibstatic.lib;bzip2.lib;libsmackerdec.lib;libmpq.lib;libdevilutionx.lib;sdl2.lib;sdl_audiolib.lib;asio.lib;sodium.lib;zt.lib;lwip_pic.lib;miniupnpc_pic.lib;natpmp_pic.lib;zt_pic.lib;zto_pic.lib;shlwapi.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\build\SDL\VisualC-WinRT\x64\Release\SDL-UWP;..\build\3rdParty\SDL_image\Release;..\build\_deps\zlib-build\Release;..\build\3rdParty\PKWare\Release;..\build\3rdParty\bzip2\Release;..\build\3rdParty\libsmackerdec\Release;..\build\3rdParty\libmpq\Release;..\build\_deps\sdl_audiolib-build\Release;..\build\3rdParty\asio\Release;..\build\_deps\libsodium-build\Release;..\build\_deps\libzt-build\lib\Release;..\build\_deps\libfmt-build\Release;..\build\_deps\libpng-build\Release;..\build\Source\libdevilutionx.dir\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>sdl_image.lib;libpng16_static.lib;pkware.lib;fmt.lib;zlibstatic.lib;bzip2.lib;libsmackerdec.lib;libmpq.lib;libdevilutionx.lib;lua_static.lib;sdl2.lib;sdl_audiolib.lib;asio.lib;sodium.lib;zt.lib;lwip_pic.lib;miniupnpc_pic.lib;natpmp_pic.lib;zt_pic.lib;zto_pic.lib;shlwapi.lib;shell32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>..\build\SDL\VisualC-WinRT\x64\Release\SDL-UWP;..\build\3rdParty\SDL_image\Release;..\build\_deps\zlib-build\Release;..\build\3rdParty\PKWare\Release;..\build\3rdParty\bzip2\Release;..\build\3rdParty\libsmackerdec\Release;..\build\3rdParty\libmpq\Release;..\build\_deps\lua-build\lua-5.4.6\Release;..\build\_deps\sdl_audiolib-build\Release;..\build\3rdParty\asio\Release;..\build\_deps\libsodium-build\Release;..\build\_deps\libzt-build\lib\Release;..\build\_deps\libfmt-build\Release;..\build\_deps\libpng-build\Release;..\build\Source\libdevilutionx.dir\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<ClCompile>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
Expand Down

0 comments on commit 1abcbec

Please sign in to comment.