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

Add Lua support #6689

Merged
merged 1 commit into from
Oct 8, 2023
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
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
24 changes: 24 additions & 0 deletions CMake/Dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,30 @@ if(SUPPORTS_MPQ)
endif()
endif()

find_package(Lua 5.4 QUIET)
if(LUA_FOUND)
message("-- Found Lua ${LUA_VERSION_STRING}")
# No clear way to statically link from the system lib
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
3 changes: 2 additions & 1 deletion vcpkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"dependencies": [
"fmt",
"bzip2",
"simpleini"
"simpleini",
"lua"
],
"builtin-baseline": "e8c2a04eb7ca058b6e2f0e6e33c67fdbffeee846",
"features": {
Expand Down
Loading