Browse Source

Merge branch 'dapiintegration' of https://github.com/NiteKat/devilutionX into dapiintegration

pull/7983/head
NiteKat 10 months ago
parent
commit
023cb73d62
  1. 1
      CMake/Definitions.cmake
  2. 8
      CMake/Dependencies.cmake
  3. 3
      CMake/VcPkgManifestFeatures.cmake
  4. 2
      CMakeLists.txt
  5. 24
      CMakeSettings.json
  6. 4
      Packaging/windows/CMakePresets.json
  7. 69
      Source/CMakeLists.txt
  8. 2
      Source/dapi/Server.cpp
  9. 13
      Source/diablo.cpp
  10. 6
      Source/engine/demomode.cpp
  11. 28
      Source/interfac.cpp
  12. 6
      Source/interfac.h
  13. 17
      Source/monster.cpp
  14. 6
      Source/player.cpp
  15. 6
      android-project/build.gradle
  16. 8
      vcpkg.json

1
CMake/Definitions.cmake

@ -19,6 +19,7 @@ foreach(
DEVILUTIONX_RESAMPLER_SDL
DEVILUTIONX_PALETTE_TRANSPARENCY_BLACK_16_LUT
SCREEN_READER_INTEGRATION
DAPI_SERVER
UNPACKED_MPQS
UNPACKED_SAVES
DEVILUTIONX_WINDOWS_NO_WCHAR

8
CMake/Dependencies.cmake

@ -276,7 +276,9 @@ if(GPERF)
message("INFO: ${GPERFTOOLS_LIBRARIES}")
endif()
find_package(SFML 3.0 COMPONENTS Network CONFIG QUIET)
if(NOT SFML_FOUND)
add_subdirectory(3rdParty/sfml)
if(DAPI_SERVER)
find_package(SFML 3.0 COMPONENTS Network CONFIG QUIET)
if(NOT SFML_FOUND)
add_subdirectory(3rdParty/sfml)
endif()
endif()

3
CMake/VcPkgManifestFeatures.cmake

@ -10,6 +10,9 @@ endif()
if(USE_GETTEXT_FROM_VCPKG)
list(APPEND VCPKG_MANIFEST_FEATURES "translations")
endif()
if(DAPI_SERVER)
list(APPEND VCPKG_MANIFEST_FEATURES "dapi")
endif()
if(BUILD_TESTING)
list(APPEND VCPKG_MANIFEST_FEATURES "tests")
endif()

2
CMakeLists.txt

@ -37,6 +37,8 @@ cmake_dependent_option(PACKET_ENCRYPTION "Encrypt network packets" ON "NOT NONET
if(CMAKE_TOOLCHAIN_FILE MATCHES "vcpkg.cmake$")
option(USE_GETTEXT_FROM_VCPKG "Add vcpkg dependency for gettext[tools] for compiling translations" OFF)
endif()
option(DAPI_SERVER "Build with DAPI server component for gameplay automation" OFF)
mark_as_advanced(DAPI_SERVER)
option(BUILD_TESTING "Build tests." ON)
# These must be included after the options above but before the `project` call.

24
CMakeSettings.json

@ -12,7 +12,7 @@
"variables": [
{
"name": "DISCORD_INTEGRATION",
"value": "False",
"value": "True",
"type": "BOOL"
}
]
@ -39,6 +39,28 @@
}
]
},
{
"name": "x64-Debug-DAPI",
"generator": "Ninja",
"configurationType": "Debug",
"buildRoot": "${workspaceRoot}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"inheritEnvironments": [ "msvc_x64" ],
"intelliSenseMode": "windows-msvc-x64",
"enableClangTidyCodeAnalysis": true,
"variables": [
{
"name": "DISCORD_INTEGRATION",
"value": "False",
"type": "BOOL"
},
{
"name": "DAPI_SERVER",
"value": "True",
"type": "BOOL"
}
]
},
{
"name": "x64-Debug-SDL1",
"generator": "Ninja",

4
Packaging/windows/CMakePresets.json

@ -36,6 +36,10 @@
"DISABLE_LTO": {
"type": "BOOL",
"value": "ON"
},
"DAPI_SERVER": {
"type": "BOOL",
"value": "ON"
}
}
},

69
Source/CMakeLists.txt

@ -649,14 +649,16 @@ if(DISCORD_INTEGRATION)
)
endif()
list(APPEND libdevilutionx_SRCS
dapi/Server.cpp
dapi/Backend/DAPIBackendCore/DAPIProtoClient.cpp
dapi/Backend/Messages/command.proto
dapi/Backend/Messages/data.proto
dapi/Backend/Messages/game.proto
dapi/Backend/Messages/init.proto
dapi/Backend/Messages/message.proto)
if(DAPI_SERVER)
list(APPEND libdevilutionx_SRCS
dapi/Server.cpp
dapi/Backend/DAPIBackendCore/DAPIProtoClient.cpp
dapi/Backend/Messages/command.proto
dapi/Backend/Messages/data.proto
dapi/Backend/Messages/game.proto
dapi/Backend/Messages/init.proto
dapi/Backend/Messages/message.proto)
endif()
if(SCREEN_READER_INTEGRATION)
list(APPEND libdevilutionx_SRCS
@ -684,7 +686,6 @@ target_link_dependencies(libdevilutionx PUBLIC
libsmackerdec
${LUA_LIBRARIES}
sol2::sol2
SFML::Network
tl
unordered_dense::unordered_dense
libdevilutionx_assets
@ -752,6 +753,10 @@ if(DISCORD_INTEGRATION)
target_link_libraries(libdevilutionx PRIVATE discord discord_game_sdk)
endif()
if(DAPI_SERVER)
target_link_libraries(libdevilutionx PRIVATE SFML::Network)
endif()
if(SCREEN_READER_INTEGRATION)
if(WIN32)
target_compile_definitions(libdevilutionx PRIVATE Tolk)
@ -807,25 +812,27 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
endif()
endif()
find_package(Protobuf REQUIRED)
target_link_libraries(libdevilutionx PUBLIC protobuf::libprotobuf-lite)
find_package(absl REQUIRED)
set(PROTO_BINARY_DIR "${CMAKE_BINARY_DIR}/generated")
file(MAKE_DIRECTORY ${PROTO_BINARY_DIR})
target_include_directories(libdevilutionx PRIVATE ${Protobuf_INCLUDE_DIRS})
# Generate the protobuf files into the 'generated' directory within the build tree
protobuf_generate(
TARGET libdevilutionx
IMPORT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/dapi/Backend/Messages"
PROTOC_OUT_DIR "${PROTO_BINARY_DIR}"
)
# Make sure the generated protobuf files are correctly included in the build
target_include_directories(libdevilutionx PUBLIC "$<BUILD_INTERFACE:${PROTO_BINARY_DIR}>")
include_directories("${PROTO_BINARY_DIR}/dapi/Backend/Messages")
target_include_directories(libdevilutionx PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/dapi/Backend/DAPIBackendCore")
if(DAPI_SERVER)
find_package(Protobuf REQUIRED)
target_link_libraries(libdevilutionx PUBLIC protobuf::libprotobuf-lite)
find_package(absl REQUIRED)
set(PROTO_BINARY_DIR "${CMAKE_BINARY_DIR}/generated")
file(MAKE_DIRECTORY ${PROTO_BINARY_DIR})
target_include_directories(libdevilutionx PRIVATE ${Protobuf_INCLUDE_DIRS})
# Generate the protobuf files into the 'generated' directory within the build tree
protobuf_generate(
TARGET libdevilutionx
IMPORT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/dapi/Backend/Messages"
PROTOC_OUT_DIR "${PROTO_BINARY_DIR}"
)
# Make sure the generated protobuf files are correctly included in the build
target_include_directories(libdevilutionx PUBLIC "$<BUILD_INTERFACE:${PROTO_BINARY_DIR}>")
include_directories("${PROTO_BINARY_DIR}/dapi/Backend/Messages")
target_include_directories(libdevilutionx PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/dapi/Backend/DAPIBackendCore")
endif()

2
Source/dapi/Server.cpp

@ -1,7 +1,7 @@
#include <thread>
#include "Server.h"
#include "qol\stash.h"
#include "qol/stash.h"

13
Source/diablo.cpp

@ -26,7 +26,6 @@
#include "controls/keymapper.hpp"
#include "controls/plrctrls.h"
#include "controls/remap_keyboard.h"
#include "dapi/Server.h"
#include "diablo.h"
#include "diablo_msg.hpp"
#include "discord/discord.h"
@ -108,6 +107,10 @@
#include "controls/touch/renderers.h"
#endif
#ifdef DAPI_SERVER
#include "dapi/Server.h"
#endif
#ifdef __vita__
#include "platform/vita/touch.h"
#endif
@ -133,7 +136,9 @@ clicktype sgbMouseDown;
uint16_t gnTickDelay = 50;
char gszProductName[64] = "DevilutionX vUnknown";
#ifdef DAPI_SERVER
DAPI::Server dapiServer;
#endif
#ifdef _DEBUG
bool DebugDisableNetworkTimeout = false;
@ -814,7 +819,7 @@ void GameEventHandler(const SDL_Event &event, uint16_t modState)
nthread_ignore_mutex(true);
PaletteFadeOut(8);
sound_stop();
ShowProgress(GetCustomEvent(event.type));
ShowProgress(GetCustomEvent(event));
RedrawEverything();
if (!HeadlessMode) {
@ -1459,11 +1464,15 @@ void UpdateMonsterLights()
void GameLogic()
{
if (!ProcessInput()) {
#ifdef DAPI_SERVER
if (gmenu_is_active())
dapiServer.update(); // For game menu commands
#endif
return;
}
#ifdef DAPI_SERVER
dapiServer.update();
#endif
if (gbProcessPlayers) {
gGameLogicStep = GameLogicStep::ProcessPlayers;
ProcessPlayers();

6
Source/engine/demomode.cpp

@ -280,7 +280,7 @@ bool CreateSdlEvent(const DemoMsg &dmsg, SDL_Event &event, uint16_t &modState)
return true;
default:
if (type >= DemoMsg::MinCustomEvent) {
event.type = CustomEventToSdlEvent(static_cast<interface_mode>(type - DemoMsg::MinCustomEvent));
CustomEventToSdlEvent(event, static_cast<interface_mode>(type - DemoMsg::MinCustomEvent));
return true;
}
event.type = static_cast<SDL_EventType>(0);
@ -377,7 +377,7 @@ bool CreateSdlEvent(const DemoMsg &dmsg, SDL_Event &event, uint16_t &modState)
return true;
default:
if (type >= DemoMsg::MinCustomEvent) {
event.type = CustomEventToSdlEvent(static_cast<interface_mode>(type - DemoMsg::MinCustomEvent));
CustomEventToSdlEvent(event, static_cast<interface_mode>(type - DemoMsg::MinCustomEvent));
return true;
}
event.type = static_cast<SDL_EventType>(0);
@ -802,7 +802,7 @@ void RecordMessage(const SDL_Event &event, uint16_t modState)
default:
if (IsCustomEvent(event.type)) {
WriteDemoMsgHeader(static_cast<DemoMsg::EventType>(
DemoMsg::MinCustomEvent + static_cast<uint8_t>(GetCustomEvent(event.type))));
DemoMsg::MinCustomEvent + static_cast<uint8_t>(GetCustomEvent(event))));
}
break;
}

28
Source/interfac.cpp

@ -40,7 +40,7 @@ namespace devilution {
namespace {
#if (defined(__APPLE__) || defined(__3DS__)) && defined(USE_SDL1)
#if defined(__APPLE__) && defined(USE_SDL1)
// On Tiger PPC, SDL_PushEvent from a background thread appears to do nothing.
#define SDL_PUSH_EVENT_BG_THREAD_WORKS 0
#else
@ -73,8 +73,7 @@ const int BarPos[3][2] = { { 53, 37 }, { 53, 421 }, { 53, 37 } };
OptionalOwnedClxSpriteList ArtCutsceneWidescreen;
SdlEventType CustomEventsBegin = SDL_USEREVENT;
constexpr uint16_t NumCustomEvents = WM_LAST - WM_FIRST + 1;
SdlEventType CustomEventType = SDL_USEREVENT;
Cutscenes GetCutSceneFromLevelType(dungeon_type type)
{
@ -413,7 +412,7 @@ void DoLoad(interface_mode uMsg)
if (!loadResult.has_value()) {
#if SDL_PUSH_EVENT_BG_THREAD_WORKS
SDL_Event event;
event.type = CustomEventToSdlEvent(WM_ERROR);
CustomEventToSdlEvent(event, WM_ERROR);
event.user.data1 = new std::string(std::move(loadResult).error());
if (SDL_PushEvent(&event) < 0) {
LogError("Failed to send WM_ERROR {}", SDL_GetError());
@ -428,7 +427,7 @@ void DoLoad(interface_mode uMsg)
#if SDL_PUSH_EVENT_BG_THREAD_WORKS
SDL_Event event;
event.type = CustomEventToSdlEvent(WM_DONE);
CustomEventToSdlEvent(event, WM_DONE);
if (SDL_PushEvent(&event) < 0) {
LogError("Failed to send WM_DONE {}", SDL_GetError());
SDL_ClearError();
@ -485,7 +484,7 @@ void ProgressEventHandler(const SDL_Event &event, uint16_t modState)
DisableInputEventHandler(event, modState);
if (!IsCustomEvent(event.type)) return;
const interface_mode customEvent = GetCustomEvent(event.type);
const interface_mode customEvent = GetCustomEvent(event);
switch (customEvent) {
case WM_PROGRESS:
if (!HeadlessMode && ProgressEventHandlerState.drawnProgress != sgdwProgress && !ProgressEventHandlerState.skipRendering) {
@ -557,23 +556,24 @@ void ProgressEventHandler(const SDL_Event &event, uint16_t modState)
void RegisterCustomEvents()
{
#ifndef USE_SDL1
CustomEventsBegin = SDL_RegisterEvents(NumCustomEvents);
CustomEventType = SDL_RegisterEvents(1);
#endif
}
bool IsCustomEvent(SdlEventType eventType)
{
return eventType >= CustomEventsBegin && eventType < CustomEventsBegin + NumCustomEvents;
return eventType == CustomEventType;
}
interface_mode GetCustomEvent(SdlEventType eventType)
interface_mode GetCustomEvent(const SDL_Event &event)
{
return static_cast<interface_mode>(eventType - CustomEventsBegin);
return static_cast<interface_mode>(event.user.code);
}
SdlEventType CustomEventToSdlEvent(interface_mode eventType)
void CustomEventToSdlEvent(SDL_Event &event, interface_mode eventType)
{
return CustomEventsBegin + eventType;
event.type = CustomEventType;
event.user.code = static_cast<int>(eventType);
}
void interface_msg_pump()
@ -598,7 +598,7 @@ void IncProgress(uint32_t steps)
if (!HeadlessMode && sgdwProgress != prevProgress) {
#if SDL_PUSH_EVENT_BG_THREAD_WORKS
SDL_Event event;
event.type = CustomEventToSdlEvent(WM_PROGRESS);
CustomEventToSdlEvent(event, WM_PROGRESS);
if (SDL_PushEvent(&event) < 0) {
LogError("Failed to send WM_PROGRESS {}", SDL_GetError());
SDL_ClearError();
@ -691,7 +691,7 @@ void ShowProgress(interface_mode uMsg)
}
#if !SDL_PUSH_EVENT_BG_THREAD_WORKS
if (const int customEventType = NextCustomEvent.type.exchange(-1); customEventType != -1) {
event.type = CustomEventToSdlEvent(static_cast<interface_mode>(customEventType));
CustomEventToSdlEvent(event, static_cast<interface_mode>(customEventType));
if (static_cast<interface_mode>(customEventType) == static_cast<int>(WM_ERROR)) {
event.user.data1 = &NextCustomEvent.error;
}

6
Source/interfac.h

@ -7,6 +7,8 @@
#include <cstdint>
#include <SDL.h>
#include "utils/ui_fwd.h"
namespace devilution {
@ -45,9 +47,9 @@ using SdlEventType = uint8_t;
bool IsCustomEvent(SdlEventType eventType);
interface_mode GetCustomEvent(SdlEventType eventType);
interface_mode GetCustomEvent(const SDL_Event &event);
SdlEventType CustomEventToSdlEvent(interface_mode eventType);
void CustomEventToSdlEvent(SDL_Event &event, interface_mode eventType);
enum Cutscenes : uint8_t {
CutStart,

17
Source/monster.cpp

@ -4102,7 +4102,8 @@ void ProcessMonsters()
monster.hitPoints = std::min(monster.hitPoints, monster.maxHitPoints); // prevent going over max HP with part of a single regen tick
}
if (IsTileVisible(monster.position.tile) && monster.activeForTicks == 0) {
const bool isMonsterVisible = IsTileVisible(monster.position.tile);
if (isMonsterVisible && monster.activeForTicks == 0) {
if (monster.type().type == MT_CLEAVER) {
PlaySFX(SfxID::ButcherGreeting);
}
@ -4130,14 +4131,20 @@ void ProcessMonsters()
assert(monster.enemy >= 0 && monster.enemy < MAX_PLRS);
Player &player = Players[monster.enemy];
monster.enemyPosition = player.position.future;
if (IsTileVisible(monster.position.tile)) {
monster.activeForTicks = UINT8_MAX;
if (isMonsterVisible) {
monster.position.last = player.position.future;
} else if (monster.activeForTicks != 0 && monster.type().type != MT_DIABLO) {
monster.activeForTicks--;
}
}
}
if ((monster.flags & MFLAG_TARGETS_MONSTER) == 0) {
if (isMonsterVisible) {
monster.activeForTicks = UINT8_MAX;
} else if (monster.activeForTicks != 0 && monster.type().type != MT_DIABLO) {
monster.activeForTicks--;
}
}
while (true) {
if ((monster.flags & MFLAG_SEARCH) == 0 || !AiPlanPath(monster)) {
AiProc[static_cast<int8_t>(monster.ai)](monster);

6
Source/player.cpp

@ -2861,7 +2861,7 @@ StartNewLvl(Player &player, interface_mode fom, int lvl)
player._pmode = PM_NEWLVL;
player._pInvincible = true;
SDL_Event event;
event.type = CustomEventToSdlEvent(fom);
CustomEventToSdlEvent(event, fom);
SDL_PushEvent(&event);
if (gbIsMultiplayer) {
NetSendCmdParam2(true, CMD_NEWLVL, fom, lvl);
@ -2887,7 +2887,7 @@ void RestartTownLvl(Player &player)
if (&player == MyPlayer) {
player._pInvincible = true;
SDL_Event event;
event.type = CustomEventToSdlEvent(WM_DIABRETOWN);
CustomEventToSdlEvent(event, WM_DIABRETOWN);
SDL_PushEvent(&event);
}
}
@ -2912,7 +2912,7 @@ void StartWarpLvl(Player &player, size_t pidx)
player._pmode = PM_NEWLVL;
player._pInvincible = true;
SDL_Event event;
event.type = CustomEventToSdlEvent(WM_DIABWARPLVL);
CustomEventToSdlEvent(event, WM_DIABWARPLVL);
SDL_PushEvent(&event);
}
}

6
android-project/build.gradle

@ -6,7 +6,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.9.2'
classpath 'com.android.tools.build:gradle:8.10.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@ -20,6 +20,6 @@ allprojects {
}
}
task clean(type: Delete) {
delete rootProject.buildDir
tasks.register('clean', Delete) {
delete rootProject.layout.buildDirectory
}

8
vcpkg.json

@ -4,9 +4,7 @@
"dependencies": [
"fmt",
"bzip2",
"lua",
"protobuf",
"sfml"
"lua"
],
"builtin-baseline": "533a5fda5c0646d1771345fb572e759283444d5f",
"features": {
@ -31,6 +29,10 @@
}
]
},
"dapi": {
"description": "Build DAPI server for gameplay automation",
"dependencies": [ "protobuf", "sfml" ]
},
"tests": {
"description": "Build tests",
"dependencies": [ "gtest", "benchmark" ]

Loading…
Cancel
Save