Skip to content

Commit

Permalink
Add initial sail implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
garrettjoecox committed Nov 23, 2024
1 parent 8c8b9ad commit ee47074
Show file tree
Hide file tree
Showing 13 changed files with 750 additions and 30 deletions.
19 changes: 16 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ jobs:
- name: Build 2Ship
run: |
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DBUILD_NETWORKING=1
cmake --build build-cmake --config Release --parallel 10
(cd build-cmake && cpack)
Expand Down Expand Up @@ -259,6 +259,7 @@ jobs:
SDL2-2.30.3
tinyxml2-10.0.0
libzip-1.10.1
SDL2_net-2.2.0
- name: Install latest SDL
run: |
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
Expand All @@ -285,6 +286,18 @@ jobs:
cmake ..
make
sudo make install
- name: Install latest SDL_net
run: |
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
if [ ! -d "SDL2_net-2.2.0" ]; then
wget https://www.libsdl.org/projects/SDL_net/release/SDL2_net-2.2.0.tar.gz
tar -xzf SDL2_net-2.2.0.tar.gz
fi
cd SDL2_net-2.2.0
./configure
make -j 10
sudo make install
sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/
- name: Install libzip without crypto
run: |
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
Expand All @@ -307,7 +320,7 @@ jobs:
- name: Build 2Ship
run: |
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release -DBUILD_REMOTE_CONTROL=1
cmake --no-warn-unused-cli -H. -Bbuild-cmake -GNinja -DCMAKE_BUILD_TYPE:STRING=Release -DBUILD_NETWORKING=1
cmake --build build-cmake --config Release -j3
(cd build-cmake && cpack -G External)
Expand Down Expand Up @@ -367,7 +380,7 @@ jobs:
VCPKG_ROOT: ${{github.workspace}}/vcpkg
run: |
set $env:PATH="$env:USERPROFILE/.cargo/bin;$env:PATH"
cmake -S . -B build-windows -G Ninja -DCMAKE_MAKE_PROGRAM=ninja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache
cmake -S . -B build-windows -G Ninja -DCMAKE_MAKE_PROGRAM=ninja -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -DBUILD_NETWORKING=1
cmake --build build-windows --config Release --parallel 10
(cd build-windows && cpack)
Expand Down
6 changes: 0 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
endif()
endif()

if (CMAKE_SYSTEM_NAME MATCHES "Windows|Linux")
if(NOT DEFINED BUILD_CROWD_CONTROL)
set(BUILD_CROWD_CONTROL OFF)
endif()
endif()

# Enable the Gfx debugger in LUS to use libgfxd from ZAPDTR
set(GFX_DEBUG_DISASSEMBLER ON)

Expand Down
118 changes: 117 additions & 1 deletion mm/2s2h/BenGui/SearchableMenuItems.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "variables.h"
#include <variant>
#include <tuple>
#include "ShipUtils.h"
#include "2s2h/Network/Sail.h"

extern "C" {
#include "functions.h"
Expand Down Expand Up @@ -50,6 +52,8 @@ typedef enum {
DISABLE_FOR_FRAME_ADVANCE_OFF,
DISABLE_FOR_WARP_POINT_NOT_SET,
DISABLE_FOR_INTRO_SKIP_OFF,
DISABLE_FOR_SAIL_FORM_INVALID,
DISABLE_FOR_SAIL_ENABLED,
} DisableOption;

struct widgetInfo;
Expand All @@ -73,6 +77,8 @@ typedef enum {
WIDGET_CVAR_COMBOBOX,
WIDGET_CVAR_SLIDER_INT,
WIDGET_CVAR_SLIDER_FLOAT,
WIDGET_CVAR_INPUT_STRING,
WIDGET_CVAR_INPUT_INT,
WIDGET_BUTTON,
WIDGET_COLOR_24, // color picker without alpha
WIDGET_COLOR_32, // color picker with alpha
Expand Down Expand Up @@ -347,7 +353,16 @@ static std::map<DisableOption, disabledInfo> disabledMap = {
"Warp Point Not Saved" } },
{ DISABLE_FOR_INTRO_SKIP_OFF,
{ [](disabledInfo& info) -> bool { return !CVarGetInteger("gEnhancements.Cutscenes.SkipIntroSequence", 0); },
"Intro Skip Not Selected" } }
"Intro Skip Not Selected" } },
{ DISABLE_FOR_SAIL_FORM_INVALID,
{ [](disabledInfo& info) -> bool {
return !(!isStringEmpty(CVarGetString("gNetwork.Sail.Host", "127.0.0.1")) &&
CVarGetInteger("gNetwork.Sail.Port", 43384) > 1024 &&
CVarGetInteger("gNetwork.Sail.Port", 43384) < 65535);
},
"Invalid Host/Port" } },
{ DISABLE_FOR_SAIL_ENABLED,
{ [](disabledInfo& info) -> bool { return Sail::Instance->isEnabled; }, "Sail is Enabled" } },
};

std::unordered_map<int32_t, const char*> menuThemeOptions = {
Expand Down Expand Up @@ -764,6 +779,78 @@ void AddSettings() {
} },
} } });

#ifdef ENABLE_NETWORKING
// Network
settingsSidebar.push_back(
{ "Network",
3,
{ {
{ .widgetName = "Sail", .widgetType = WIDGET_SEPARATOR_TEXT },
{ "Host",
"gNetwork.Sail.Host",
"",
WIDGET_CVAR_INPUT_STRING,
{ .defaultVariant = "127.0.0.1" },
{},
[](widgetInfo& info) {
if (disabledMap.at(DISABLE_FOR_SAIL_ENABLED).active) {
info.activeDisables.push_back(DISABLE_FOR_SAIL_ENABLED);
}
} },
{ "Port",
"gNetwork.Sail.Port",
"",
WIDGET_CVAR_INPUT_INT,
{ .defaultVariant = 43384 },
{},
[](widgetInfo& info) {
if (disabledMap.at(DISABLE_FOR_SAIL_ENABLED).active) {
info.activeDisables.push_back(DISABLE_FOR_SAIL_ENABLED);
}
} },
{ "Connect",
"",
"Connect/Disconnect to the Sail server.",
WIDGET_BUTTON,
{},
[](widgetInfo& info) {
if (Sail::Instance->isEnabled) {
CVarClear("gNetwork.Sail.Enabled");
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Sail::Instance->Disable();
} else {
CVarSetInteger("gNetwork.Sail.Enabled", 1);
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Sail::Instance->Enable();
}
},
[](widgetInfo& info) {
if (Sail::Instance->isEnabled) {
info.widgetName = "Disconnect";
} else {
info.widgetName = "Connect";
}
if (disabledMap.at(DISABLE_FOR_SAIL_FORM_INVALID).active)
info.activeDisables.push_back(DISABLE_FOR_SAIL_FORM_INVALID);
} },
{ "Connected",
"",
"Displays the current connection status.",
WIDGET_TEXT,
{},
{},
[](widgetInfo& info) {
if (Sail::Instance->isEnabled && Sail::Instance->isConnected) {
info.widgetName = "Connected";
} else if (Sail::Instance->isEnabled) {
info.widgetName = "Connecting...";
} else {
info.isHidden = true;
}
} },
} } });
#endif

if (CVarGetInteger("gSettings.SidebarSearch", 0)) {
settingsSidebar.insert(settingsSidebar.begin() + searchSidebarIndex, searchSidebarEntry);
}
Expand Down Expand Up @@ -1813,6 +1900,35 @@ void SearchMenuGetItem(widgetInfo& widget) {
}
}
break;
case WIDGET_CVAR_INPUT_STRING: {
if (UIWidgets::CVarInputString(
widget.widgetName.c_str(), widget.widgetCVar,
{
.color = menuTheme[menuThemeIndex],
.tooltip = widget.widgetTooltip,
.disabled = disabledValue,
.disabledTooltip = disabledTooltip,
.defaultValue = std::get<const char*>(widget.widgetOptions.defaultVariant),
})) {
if (widget.widgetCallback != nullptr) {
widget.widgetCallback(widget);
}
}
} break;
case WIDGET_CVAR_INPUT_INT: {
if (UIWidgets::CVarInputInt(widget.widgetName.c_str(), widget.widgetCVar,
{
.color = menuTheme[menuThemeIndex],
.tooltip = widget.widgetTooltip,
.disabled = disabledValue,
.disabledTooltip = disabledTooltip,
.defaultValue = std::get<int32_t>(widget.widgetOptions.defaultVariant),
})) {
if (widget.widgetCallback != nullptr) {
widget.widgetCallback(widget);
}
}
} break;
case WIDGET_SLIDER_INT: {
int32_t* pointer = std::get<int32_t*>(widget.widgetOptions.valuePointer);
if (pointer == nullptr) {
Expand Down
105 changes: 105 additions & 0 deletions mm/2s2h/BenGui/UIWidgets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,111 @@ bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaul
return changed;
}

void PushStyleInput(const ImVec4& color) {
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_FrameBgActive, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(color.x, color.y, color.z, 1.0f));
ImGui::PushStyleColor(ImGuiCol_SliderGrab, ImVec4(1.0, 1.0, 1.0, 0.4f));
ImGui::PushStyleColor(ImGuiCol_SliderGrabActive, ImVec4(1.0, 1.0, 1.0, 0.5f));
ImGui::PushStyleVar(ImGuiStyleVar_GrabRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 8.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
}

void PopStyleInput() {
ImGui::PopStyleVar(4);
ImGui::PopStyleColor(6);
}

// Reference: imgui-src/misc/cpp/imgui_stdlib.cpp
int InputTextResizeCallback(ImGuiInputTextCallbackData* data) {
std::string* value = (std::string*)data->UserData;
if (data->EventFlag == ImGuiInputTextFlags_CallbackResize) {
value->resize(data->BufTextLen);
data->Buf = (char*)value->c_str();
}
return 0;
}

bool InputString(const char* label, std::string* value, const InputStringOptions& options) {
bool dirty = false;
ImGui::PushID(label);
ImGui::BeginGroup();
std::string invisibleLabelStr = "##" + std::string(label);
const char* invisibleLabel = invisibleLabelStr.c_str();
PushStyleInput(options.color);
ImGui::BeginDisabled(options.disabled);
if (options.labelPosition != LabelPosition::None) {
ImGui::Text(label);
}
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputText(invisibleLabel, (char*)value->c_str(), value->capacity() + 1,
ImGuiInputTextFlags_CallbackResize, InputTextResizeCallback, value)) {
dirty = true;
}
ImGui::EndDisabled();
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
strcmp(options.disabledTooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.tooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
}
PopStyleInput();
ImGui::EndGroup();
ImGui::PopID();
return dirty;
}

bool CVarInputString(const char* label, const char* cvarName, const InputStringOptions& options) {
std::string value = CVarGetString(cvarName, options.defaultValue);
bool dirty = InputString(label, &value, options);
if (dirty) {
CVarSetString(cvarName, value.c_str());
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
}
return dirty;
}

bool InputInt(const char* label, int32_t* value, const InputIntOptions& options) {
bool dirty = false;
ImGui::PushID(label);
ImGui::BeginGroup();
std::string invisibleLabelStr = "##" + std::string(label);
const char* invisibleLabel = invisibleLabelStr.c_str();
PushStyleInput(options.color);
ImGui::BeginDisabled(options.disabled);
if (options.labelPosition != LabelPosition::None) {
ImGui::Text(label);
}
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt(invisibleLabel, value, NULL, NULL)) {
dirty = true;
}
ImGui::EndDisabled();
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) &&
strcmp(options.disabledTooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && strcmp(options.tooltip, "") != 0) {
ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
}
PopStyleInput();
ImGui::EndGroup();
ImGui::PopID();
return dirty;
}

bool CVarInputInt(const char* label, const char* cvarName, const InputIntOptions& options) {
int32_t value = CVarGetInteger(cvarName, options.defaultValue);
bool dirty = InputInt(label, &value, options);
if (dirty) {
CVarSetInteger(cvarName, value);
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
}
return dirty;
}

void DrawFlagArray32(const std::string& name, uint32_t& flags) {
ImGui::PushID(name.c_str());
for (int32_t flagIndex = 0; flagIndex < 32; flagIndex++) {
Expand Down
27 changes: 27 additions & 0 deletions mm/2s2h/BenGui/UIWidgets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,33 @@ namespace UIWidgets {
bool SliderFloat(const char* label, float* value, float min, float max, const FloatSliderOptions& options = {});
bool CVarSliderFloat(const char* label, const char* cvarName, float min, float max, const float defaultValue, const FloatSliderOptions& options = {});
bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaultColor);

struct InputStringOptions {
const ImVec4 color = Colors::Gray;
const char* tooltip = "";
bool disabled = false;
const char* disabledTooltip = "";
const char* placeholder = "";
const char* defaultValue = ""; // Only applicable to CVarInputString
LabelPosition labelPosition = LabelPosition::Above;
};

struct InputIntOptions {
const ImVec4 color = Colors::Gray;
const char* tooltip = "";
bool disabled = false;
const char* disabledTooltip = "";
const char* placeholder = "";
int32_t defaultValue = 0; // Only applicable to CVarInputInt
LabelPosition labelPosition = LabelPosition::Above;
};

void PushStyleInput(const ImVec4& color = Colors::Indigo);
void PopStyleInput();
bool InputString(const char* label, std::string* value, const InputStringOptions& options = {});
bool CVarInputString(const char* label, const char* cvarName, const InputStringOptions& options = {});
bool InputInt(const char* label, int32_t* value, const InputIntOptions& options = {});
bool CVarInputInt(const char* label, const char* cvarName, const InputIntOptions& options = {});
void DrawFlagArray32(const std::string& name, uint32_t& flags);
void DrawFlagArray16(const std::string& name, uint16_t& flags);
void DrawFlagArray8(const std::string& name, uint8_t& flags);
Expand Down
Loading

0 comments on commit ee47074

Please sign in to comment.