diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..23d47f8 --- /dev/null +++ b/build.zig @@ -0,0 +1,804 @@ +const std = @import("std"); +const system = @import("system"); + +const Dependencies = struct { + bc: *std.Build.Dependency, + common: *std.Build.Dependency, + squall: *std.Build.Dependency, + typhoon: *std.Build.Dependency, + + lua: *std.Build.Dependency, + freetype: *std.Build.Dependency, + stormlib: *std.Build.Dependency, + + sdl: *std.Build.Dependency, + glew: *std.Build.Dependency, +}; + +var dependencies: Dependencies = undefined; + +fn get_dependencies(b: *std.Build) void { + const d = &dependencies; + + d.bc = b.dependency("bc", .{}); + d.common = b.dependency("common", .{}); + d.squall = b.dependency("squall", .{}); + d.typhoon = b.dependency("typhoon", .{}); + + d.lua = b.dependency("lua", .{}); + d.freetype = b.dependency("freetype", .{}); + d.stormlib = b.dependency("stormlib", .{}); + + d.sdl = b.dependency("sdl", .{}); + d.glew = b.dependency("glew", .{}); +} + +fn link_core_dependencies(c: *std.Build.Step.Compile) void { + const d = &dependencies; + // link bc + c.linkLibrary(d.bc.artifact("bc")); + // link common + c.linkLibrary(d.common.artifact("common")); + // link squall + c.linkLibrary(d.squall.artifact("storm")); + // link typhoon + c.linkLibrary(d.typhoon.artifact("tempest")); + + // link stormlib + c.linkLibrary(d.stormlib.artifact("stormlib")); + // link lua + c.linkLibrary(d.lua.artifact("lua")); + // link freetype + c.linkLibrary(d.freetype.artifact("freetype")); + // // link sdl + // c.linkLibrary(d.sdl.artifact("SDL3")); + // // link glew + // c.linkLibrary(d.glew.artifact("glew")); +} + +fn link_glsdl_dependencies(target: std.Build.ResolvedTarget, c: *std.Build.Step.Compile) void { + const t = &target.result; + const d = &dependencies; + // link SDL + c.linkLibrary(d.sdl.artifact("SDL2")); + // link GLEW + c.linkLibrary(d.glew.artifact("glew")); + // Make headers work in static mode + c.defineCMacro("GLEW_STATIC", "1"); + // on windows, link opengl32.lib + if (t.os.tag == .windows) { + c.linkSystemLibrary("opengl32"); + } +} + +pub fn build(b: *std.Build) void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const t = &target.result; + + const whoa_compiler_flags = [_][]const u8 { + "-std=c++11", + + "-Wno-invalid-offsetof", + + // Disable UBsan alignment checks + "-fno-sanitize=alignment", + }; + + // dependencies + get_dependencies(b); + + const whoa_core = b.addStaticLibrary(.{ + .name = "whoa_core", + .target = target, + .optimize = optimize + }); + + // Add system detection defines + system.add_defines(whoa_core); + // Link C++ standard library + whoa_core.linkLibCpp(); + // Include "src/" + whoa_core.addIncludePath(b.path("src")); + + link_core_dependencies(whoa_core); + + // OS defines + + if (t.os.tag == .windows) { + whoa_core.defineCMacro("NOMINMAX", "1"); + whoa_core.defineCMacro("WIN32_LEAN_AND_MEAN", "1"); + + whoa_core.defineCMacro("_XM_NO_INTRINSICS_", "1"); + } + + // **************** + // * async module * + // **************** + const whoa_async_sources = [_][]const u8 { + "src/async/AsyncFile.cpp", + "src/async/AsyncFileRead.cpp" + }; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_async_sources, + .flags = &whoa_compiler_flags + }); + + // ***************** + // * client module * + // ***************** + const whoa_client_sources = [_][]const u8 { + "src/client/Client.cpp", + "src/client/ClientRealmResponseAdapter.cpp", + "src/client/ClientServices.cpp", + "src/client/CmdLine.cpp" + }; + + const whoa_client_windows_sources = [_][]const u8 { + "src/client/gui/win/OsGui.cpp", + }; + + const whoa_client_macos_sources = [_][]const u8 { + "src/client/gui/mac/OsGui.cpp", + }; + + const whoa_client_linux_sources = [_][]const u8 { + "src/client/gui/linux/OsGui.cpp", + }; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_client_sources, + .flags = &whoa_compiler_flags + }); + + switch (t.os.tag) { + .windows => { + whoa_core.addCSourceFiles(.{ + .files = &whoa_client_windows_sources, + .flags = &whoa_compiler_flags + }); + }, + + .macos => { + whoa_core.addCSourceFiles(.{ + .files = &whoa_client_macos_sources, + .flags = &whoa_compiler_flags + }); + }, + + else => { + whoa_core.addCSourceFiles(.{ + .files = &whoa_client_linux_sources, + .flags = &whoa_compiler_flags + }); + } + } + + // ****************** + // * console module * + // ****************** + const whoa_console_sources = [_][]const u8 { + "src/console/Client.cpp", + "src/console/Command.cpp", + "src/console/Console.cpp", + "src/console/CVar.cpp", + "src/console/Device.cpp", + "src/console/Handlers.cpp", + "src/console/Line.cpp", + "src/console/Screen.cpp", + + "src/console/command/console/AppendLogToFile.cpp", + "src/console/command/console/BackGroundColor.cpp", + "src/console/command/console/BufferSize.cpp", + "src/console/command/console/CharSpacing.cpp", + "src/console/command/console/ClearConsole.cpp", + "src/console/command/console/CloseConsole.cpp", + "src/console/command/console/CurrentSettings.cpp", + "src/console/command/console/DefaultSettings.cpp", + "src/console/command/console/Font.cpp", + "src/console/command/console/FontColor.cpp", + "src/console/command/console/FontSize.cpp", + "src/console/command/console/Help.cpp", + "src/console/command/console/HighLightColor.cpp", + "src/console/command/console/Proportional.cpp", + "src/console/command/console/RepeatHandler.cpp", + "src/console/command/console/Ver.cpp", + + "src/console/command/default/Quit.cpp", + "src/console/command/default/SetMap.cpp", + }; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_console_sources, + .flags = &whoa_compiler_flags + }); + + // ************* + // * db module * + // ************* + const whoa_db_sources = [_][]const u8 { + "src/db/Db.cpp", + + // TODO: replace with full list of generated records + "src/db/rec/AchievementRec.cpp", + "src/db/rec/Cfg_CategoriesRec.cpp", + "src/db/rec/Cfg_ConfigsRec.cpp", + "src/db/rec/ChrRacesRec.cpp", + }; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_db_sources, + .flags = &whoa_compiler_flags + }); + + // **************** + // * event module * + // **************** + const whoa_event_sources = [_][]const u8 { + "src/event/CEvent.cpp", + "src/event/Context.cpp", + "src/event/Event.cpp", + "src/event/EvtContext.cpp", + "src/event/EvtThread.cpp", + "src/event/Input.cpp", + "src/event/Queue.cpp", + "src/event/Scheduler.cpp", + "src/event/Synthesize.cpp", + "src/event/Timer.cpp" + }; + + const whoa_event_windows_sources = [_][]const u8 { + "src/event/win/Input.cpp", + }; + + const whoa_event_macos_sources = [_][]const u8 { + "src/event/mac/Input.cpp", + "src/event/mac/Event.mm", + }; + + const whoa_event_linux_sources = [_][]const u8 { + "src/event/linux/Input.cpp", + }; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_event_sources, + .flags = &whoa_compiler_flags + }); + + switch (t.os.tag) { + .windows => { + whoa_core.addCSourceFiles(.{ + .files = &whoa_event_windows_sources, + .flags = &whoa_compiler_flags + }); + }, + + .macos => { + whoa_core.addCSourceFiles(.{ + .files = &whoa_event_macos_sources, + .flags = &whoa_compiler_flags + }); + }, + + else => { + whoa_core.addCSourceFiles(.{ + .files = &whoa_event_linux_sources, + .flags = &whoa_compiler_flags + }); + } + } + + // *************** + // * glue module * + // *************** + const whoa_glue_sources = [_][]const u8 { + "src/glue/CCharacterSelection.cpp", + "src/glue/CGlueMgr.cpp", + "src/glue/CRealmList.cpp" + }; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_glue_sources, + .flags = &whoa_compiler_flags + }); + + // ************* + // * gx module * + // ************* + const whoa_gx_sources = [_][]const u8 { + "src/gx/Blit.cpp", + "src/gx/Buffer.cpp", + "src/gx/Camera.cpp", + "src/gx/CCamera.cpp", + "src/gx/CGVideoOptions.cpp", + "src/gx/CGxDevice.cpp", + "src/gx/CGxMatrixStack.cpp", + "src/gx/CGxStateBom.cpp", + "src/gx/Coordinate.cpp", + "src/gx/Device.cpp", + "src/gx/Draw.cpp", + "src/gx/Font.cpp", + "src/gx/FontInternal.cpp", + "src/gx/Gx.cpp", + "src/gx/RenderState.cpp", + "src/gx/Screen.cpp", + "src/gx/Shader.cpp", + "src/gx/Texture.cpp", + "src/gx/Transform.cpp", + "src/gx/Window.cpp", + + "src/gx/buffer/CGxPool.cpp", + + "src/gx/font/CGxFont.cpp", + "src/gx/font/CGxString.cpp", + "src/gx/font/CGxStringBatch.cpp", + "src/gx/font/FaceData.cpp", + "src/gx/font/FontFace.cpp", + "src/gx/font/FreeType.cpp", + "src/gx/font/FreeTypeInternal.cpp", + "src/gx/font/Wrap.cpp", + + "src/gx/shader/CGxShader.cpp", + "src/gx/shader/CShaderEffect.cpp", + "src/gx/shader/CShaderEffectManager.cpp", + + "src/gx/texture/CBLPFile.cpp", + "src/gx/texture/CGxTex.cpp", + "src/gx/texture/CTexture.cpp" + }; + + const whoa_gx_d3d_sources = [_][]const u8 { + "src/gx/d3d/CGxDeviceD3d.cpp" + }; + + const whoa_gx_gll_sources = [_][]const u8 { + "src/gx/gll/CGxDeviceGLL.cpp", + "src/gx/gll/GL.cpp", + "src/gx/gll/GLAbstractWindow.cpp", + "src/gx/gll/GLBuffer.cpp", + "src/gx/gll/GLCommand.cpp", + "src/gx/gll/GLContext.mm", + "src/gx/gll/GLDevice.cpp", + "src/gx/gll/GLFramebuffer.cpp", + "src/gx/gll/GLGLSLProgram.cpp", + "src/gx/gll/GLLayerView.mm", + "src/gx/gll/GLMipmap.cpp", + "src/gx/gll/GLObject.cpp", + "src/gx/gll/GLPixelShader.cpp", + "src/gx/gll/GLShader.cpp", + "src/gx/gll/GLTexture.cpp", + "src/gx/gll/GLTypes.cpp", + "src/gx/gll/GLUtil.cpp", + "src/gx/gll/GLVertexArray.cpp", + "src/gx/gll/GLVertexShader.cpp", + "src/gx/gll/GLWindow.mm", + "src/gx/gll/GLWorker.cpp" + }; + + const whoa_gx_glsdl_sources = [_][]const u8 { + "src/gx/glsdl/CGxDeviceGLSDL.cpp", + "src/gx/glsdl/GL.cpp", + "src/gx/glsdl/GLBuffer.cpp", + "src/gx/glsdl/GLFramebuffer.cpp", + "src/gx/glsdl/GLGLSLProgram.cpp", + "src/gx/glsdl/GLMipmap.cpp", + "src/gx/glsdl/GLObject.cpp", + "src/gx/glsdl/GLPixelShader.cpp", + "src/gx/glsdl/GLSDLContext.cpp", + "src/gx/glsdl/GLSDLDevice.cpp", + "src/gx/glsdl/GLSDLWindow.cpp", + "src/gx/glsdl/GLShader.cpp", + "src/gx/glsdl/GLTexture.cpp", + "src/gx/glsdl/GLTypes.cpp", + "src/gx/glsdl/GLUtil.cpp", + "src/gx/glsdl/GLVertexArray.cpp", + "src/gx/glsdl/GLVertexShader.cpp" + }; + + var use_gll = false; + var use_glsdl = false; + var use_d3d = false; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_gx_sources, + .flags = &whoa_compiler_flags + }); + + switch (t.os.tag) { + .windows => { + use_d3d = true; + use_glsdl = true; + }, + + .macos => { + use_gll = true; + }, + + else => { + use_glsdl = true; + } + } + + if (use_d3d) { + whoa_core.addCSourceFiles(.{ + .files = &whoa_gx_d3d_sources, + .flags = &whoa_compiler_flags + }); + whoa_core.linkSystemLibrary("d3d9"); + } + + if (use_gll) { + whoa_core.addCSourceFiles(.{ + .files = &whoa_gx_gll_sources, + .flags = &whoa_compiler_flags + }); + whoa_core.linkFramework("AppKit"); + whoa_core.linkFramework("OpenGL"); + } + + if (use_glsdl) { + whoa_core.addCSourceFiles(.{ + .files = &whoa_gx_glsdl_sources, + .flags = &whoa_compiler_flags + }); + + link_glsdl_dependencies(target, whoa_core); + } + + // *************** + // * math module * + const whoa_math_sources = [_][]const u8 { + "src/math/Types.cpp" + }; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_math_sources, + .flags = &whoa_compiler_flags + }); + + // **************** + // * model module * + // **************** + const whoa_model_sources = [_][]const u8 { + "src/model/CM2Cache.cpp", + "src/model/CM2Light.cpp", + "src/model/CM2Lighting.cpp", + "src/model/CM2Model.cpp", + "src/model/CM2Scene.cpp", + "src/model/CM2SceneRender.cpp", + "src/model/CM2Shared.cpp", + "src/model/M2Init.cpp", + "src/model/M2Internal.cpp", + "src/model/M2Sort.cpp", + "src/model/Model2.cpp" + }; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_model_sources, + .flags = &whoa_compiler_flags + }); + + // ************** + // * net module * + // ************** + const whoa_net_sources = [_][]const u8 { + "src/net/Poll.cpp", + + "src/net/connection/ClientConnection.cpp", + "src/net/connection/NetClient.cpp", + "src/net/connection/RealmConnection.cpp", + "src/net/connection/WowConnection.cpp", + "src/net/connection/WowConnectionNet.cpp", + + "src/net/grunt/ClientLink.cpp", + "src/net/grunt/Grunt.cpp", + "src/net/grunt/Timer.cpp", + + "src/net/login/GruntLogin.cpp", + "src/net/login/Login.cpp", + "src/net/login/LoginResponse.cpp", + + "src/net/srp/SRP6_Client.cpp", + "src/net/srp/SRP6_Random.cpp", + }; + + const whoa_net_winsock_sources = [_][]const u8 { + "src/net/connection/winsock/WowConnectionNet.cpp" + }; + + const whoa_net_bsd_sources = [_][]const u8 { + "src/net/connection/bsd/WowConnectionNet.cpp" + }; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_net_sources, + .flags = &whoa_compiler_flags + }); + + switch (t.os.tag) { + .windows => { + whoa_core.addCSourceFiles(.{ + .files = &whoa_net_winsock_sources, + .flags = &whoa_compiler_flags + }); + whoa_core.linkSystemLibrary("wsock32"); + whoa_core.linkSystemLibrary("ws2_32"); + }, + + else => { + whoa_core.addCSourceFiles(.{ + .files = &whoa_net_bsd_sources, + .flags = &whoa_compiler_flags + }); + } + } + + // // ************* + // // * os module * + // // ************* + // const whoa_os = b.addStaticLibrary(.{ + // .name = "os", + // .target = target, + // .optimize = optimize + // }); + // // Add system detection defines + // system.add_defines(whoa_os); + // // Link C++ standard library + // whoa_os.linkLibCpp(); + // // Include "src/" + // whoa_os.addIncludePath(b.path("src")); + + // **************** + // * sound module * + // **************** + const whoa_sound_sources = [_][]const u8 { + "src/sound/SI2.cpp", + "src/sound/SI2Cvars.cpp", + "src/sound/SI2Log.cpp", + "src/sound/SI2Script.cpp" + }; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_sound_sources, + .flags = &whoa_compiler_flags + }); + + // ************* + // * ui module * + // ************* + const whoa_ui_sources = [_][]const u8 { + "src/ui/CBackdropGenerator.cpp", + "src/ui/CFramePoint.cpp", + "src/ui/CFrameStrata.cpp", + "src/ui/CLayoutFrame.cpp", + "src/ui/CRenderBatch.cpp", + "src/ui/CScriptObject.cpp", + "src/ui/CScriptObjectScript.cpp", + "src/ui/CScriptRegion.cpp", + "src/ui/CScriptRegionScript.cpp", + "src/ui/CSimpleButton.cpp", + "src/ui/CSimpleButtonScript.cpp", + "src/ui/CSimpleCheckbox.cpp", + "src/ui/CSimpleCheckboxScript.cpp", + "src/ui/CSimpleEditBox.cpp", + "src/ui/CSimpleEditBoxScript.cpp", + "src/ui/CSimpleFont.cpp", + "src/ui/CSimpleFontable.cpp", + "src/ui/CSimpleFontScript.cpp", + "src/ui/CSimpleFontString.cpp", + "src/ui/CSimpleFontStringAttributes.cpp", + "src/ui/CSimpleFontStringScript.cpp", + "src/ui/CSimpleFrame.cpp", + "src/ui/CSimpleFrameScript.cpp", + "src/ui/CSimpleHTML.cpp", + "src/ui/CSimpleHTMLScript.cpp", + "src/ui/CSimpleHyperlinkedFrame.cpp", + "src/ui/CSimpleModel.cpp", + "src/ui/CSimpleModelFFX.cpp", + "src/ui/CSimpleModelFFXScript.cpp", + "src/ui/CSimpleModelScript.cpp", + "src/ui/CSimpleRegion.cpp", + "src/ui/CSimpleRender.cpp", + "src/ui/CSimpleScrollFrame.cpp", + "src/ui/CSimpleScrollFrameScript.cpp", + "src/ui/CSimpleSlider.cpp", + "src/ui/CSimpleSliderScript.cpp", + "src/ui/CSimpleTexture.cpp", + "src/ui/CSimpleTextureScript.cpp", + "src/ui/CSimpleTop.cpp", + "src/ui/FrameScript_Object.cpp", + "src/ui/FrameScript.cpp", + "src/ui/FrameXML.cpp", + "src/ui/Interface.cpp", + "src/ui/LoadXML.cpp", + "src/ui/LuaExtraFuncs.cpp", + "src/ui/LuaMemory.cpp", + "src/ui/ScriptFunctions.cpp", + "src/ui/ScriptFunctionsCharCreate.cpp", + "src/ui/ScriptFunctionsCharSelect.cpp", + "src/ui/ScriptFunctionsGlueScriptEvents.cpp", + "src/ui/ScriptFunctionsRealmList.cpp", + "src/ui/ScriptFunctionsShared.cpp", + "src/ui/ScriptFunctionsSimpleFrame.cpp", + "src/ui/ScriptFunctionsSystem.cpp", + "src/ui/Util.cpp" + }; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_ui_sources, + .flags = &whoa_compiler_flags + }); + + // *************** + // * util module * + // *************** + const whoa_util_sources = [_][]const u8 { + "src/util/CStatus.cpp", + "src/util/Filesystem.cpp", + "src/util/HMAC.cpp", + "src/util/SFile.cpp", + "src/util/StringTo.cpp", + "src/util/SysMessage.cpp" + }; + + const whoa_util_macos_sources = [_][]const u8 { + "src/util/Autorelease.mm" + }; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_util_sources, + .flags = &whoa_compiler_flags + }); + + if (t.os.tag == .macos) { + whoa_core.addCSourceFiles(.{ + .files = &whoa_util_macos_sources, + .flags = &whoa_compiler_flags + }); + } + + // **************** + // * world module * + // **************** + const whoa_world_sources = [_][]const u8 { + "src/world/CWorld.cpp" + }; + + whoa_core.addCSourceFiles(.{ + .files = &whoa_world_sources, + .flags = &whoa_compiler_flags + }); + + // ************** + // * app module * + // ************** + const whoa_app = b.addExecutable(.{ + .name = "Whoa", + .target = target, + .optimize = optimize + }); + // Add system detection defines + system.add_defines(whoa_app); + // Link C++ standard library + whoa_app.linkLibCpp(); + // Include "src/" + whoa_app.addIncludePath(b.path("src")); + + const whoa_app_windows_sources = [_][]const u8 { + "src/app/win/Whoa.cpp", + }; + + const whoa_app_macos_sources = [_][]const u8 { + "src/app/macos/MacClient.mm", + "src/app/macos/MainApp.mm", + "src/app/macos/Whoa.mm", + "src/app/macos/View.mm", + "src/app/macos/WindowsCallbacks.mm", + "src/app/macos/WoWApplication.mm", + }; + + const whoa_app_linux_sources = [_][]const u8 { + "src/app/linux/Whoa.cpp", + }; + + switch (t.os.tag) { + .windows => { + whoa_app.addCSourceFiles(.{ + .files = &whoa_app_windows_sources, + .flags = &whoa_compiler_flags + }); + }, + + .macos => { + whoa_app.addCSourceFiles(.{ + .files = &whoa_app_macos_sources, + .flags = &whoa_compiler_flags + }); + }, + + else => { + whoa_app.addCSourceFiles(.{ + .files = &whoa_app_linux_sources, + .flags = &whoa_compiler_flags + }); + } + } + + link_core_dependencies(whoa_app); + + whoa_app.linkLibrary(whoa_core); + + // // link different modules together + + // // whoa_async.linkLibrary(whoa_event); + // // whoa_async.linkLibrary(whoa_util); + + // whoa_client.linkLibrary(whoa_async); + // // whoa_client.linkLibrary(whoa_console); + // // whoa_client.linkLibrary(whoa_db); + // // whoa_client.linkLibrary(whoa_event); + // // whoa_client.linkLibrary(whoa_gx); + // // whoa_client.linkLibrary(whoa_model); + // // whoa_client.linkLibrary(whoa_net); + // // whoa_client.linkLibrary(whoa_ui); + // // whoa_client.linkLibrary(whoa_util); + // // whoa_client.linkLibrary(whoa_world); + + // whoa_console.linkLibrary(whoa_client); + // whoa_console.linkLibrary(whoa_gx); + + // // whoa_event.linkLibrary(whoa_client); + // // whoa_event.linkLibrary(whoa_gx); + + // whoa_glue.linkLibrary(whoa_client); + // whoa_glue.linkLibrary(whoa_console); + // whoa_glue.linkLibrary(whoa_db); + // whoa_glue.linkLibrary(whoa_event); + // whoa_glue.linkLibrary(whoa_gx); + // whoa_glue.linkLibrary(whoa_model); + // whoa_glue.linkLibrary(whoa_net); + // whoa_glue.linkLibrary(whoa_sound); + // whoa_glue.linkLibrary(whoa_ui); + // whoa_glue.linkLibrary(whoa_util); + + // // whoa_gx.linkLibrary(whoa_event); + // whoa_gx.linkLibrary(whoa_math); + // whoa_gx.linkLibrary(whoa_model); + // whoa_gx.linkLibrary(whoa_ui); + // whoa_gx.linkLibrary(whoa_util); + + // whoa_model.linkLibrary(whoa_async); + // // whoa_model.linkLibrary(whoa_gx); + // whoa_model.linkLibrary(whoa_math); + // whoa_model.linkLibrary(whoa_util); + + // whoa_net.linkLibrary(whoa_client); + // whoa_net.linkLibrary(whoa_event); + + // whoa_sound.linkLibrary(whoa_ui); + // whoa_sound.linkLibrary(whoa_util); + + // whoa_ui.linkLibrary(whoa_client); + // whoa_ui.linkLibrary(whoa_console); + // whoa_ui.linkLibrary(whoa_db); + // whoa_ui.linkLibrary(whoa_event); + // whoa_ui.linkLibrary(whoa_glue); + // // whoa_ui.linkLibrary(whoa_gx); + // whoa_ui.linkLibrary(whoa_math); + // whoa_ui.linkLibrary(whoa_model); + // whoa_ui.linkLibrary(whoa_net); + // whoa_ui.linkLibrary(whoa_util); + + // whoa_world.linkLibrary(whoa_gx); + // whoa_world.linkLibrary(whoa_model); + + // whoa_app.linkLibrary(whoa_client); + // // whoa_app.linkLibrary(whoa_event); + // // whoa_app.linkLibrary(whoa_gx); + // // whoa_app.linkLibrary(whoa_net); + // // whoa_app.linkLibrary(whoa_util); + + b.installArtifact(whoa_app); +} \ No newline at end of file diff --git a/build.zig.zon b/build.zig.zon new file mode 100644 index 0000000..788aa4b --- /dev/null +++ b/build.zig.zon @@ -0,0 +1,42 @@ +.{ .name = "whoa", .version = "3.3.5", .dependencies = .{ + .bc = .{ + .url = "https://github.com/thunderbrewhq/bc/archive/refs/heads/master.zip", + .hash = "1220ef571af35d366e093fb7ad65b0ac65dcde291d5bbbd1d2cf42b0b1d59612fa0a", + }, + .common = .{ + .url = "https://github.com/thunderbrewhq/common/archive/refs/heads/master.zip", + .hash = "122083b9b4614e7bc8778f2202d46fa96da7594529b3088708243103700dd3e6f9f2", + }, + .squall = .{ + .url = "https://github.com/thunderbrewhq/squall/archive/refs/heads/master.zip", + .hash = "1220cbe372b510d9f0ecfe42d6e2a819c1baf4e93252911e673d8ce28db256b7fbaf", + }, + .typhoon = .{ + .url = "https://github.com/thunderbrewhq/typhoon/archive/refs/heads/master.zip", + .hash = "1220b606235180891fc4bfaa709050408523b024c5ce8d237eb204e23083eaf4f3bc", + }, + .system = .{ + .url = "https://github.com/thunderbrewhq/system/archive/refs/heads/master.zip", + .hash = "1220d6a6e4e2f836c1c22eb128e6c74c773ea191bfbaac02601dcb5238c2b0874182", + }, + .glew = .{ + .url = "https://github.com/thunderbrewhq/glew/archive/refs/heads/master.zip", + .hash = "12207a20f7a36c864cd82aa0272c18713f1b4318981d821a897b9491432e759eb6a8", + }, + .freetype = .{ + .url = "https://github.com/thunderbrewhq/freetype/archive/refs/heads/master.zip", + .hash = "12206bcb472a69fc610e5d39cbda1ceaba897205daca4b287b6fefeddeb72817d266", + }, + .sdl = .{ + .url = "https://github.com/thunderbrewhq/sdl/archive/refs/heads/master.zip", + .hash = "12206b66f2f21d3fa780a0e6c2623c128f965d84de3daa178338e132e0f00d25123a", + }, + .lua = .{ + .url = "https://github.com/thunderbrewhq/lua/archive/refs/heads/master.zip", + .hash = "12200e9b8b5d49d98a833cf1b34c19ea872c880bf1d8777b07557b2eac1b8a4cf7fe", + }, + .stormlib = .{ + .url = "https://github.com/thunderbrewhq/stormlib/archive/refs/heads/master.zip", + .hash = "1220a383fa2c263cacc9841960af3a87c4c8afb670468894c77b5c05b4b2068af9e4", + }, +}, .paths = .{ "src", "build.zig", "build.zig.zon", "LICENSE", "README.md" } } diff --git a/src/gx/d3d/CGxDeviceD3d.cpp b/src/gx/d3d/CGxDeviceD3d.cpp index 58b103e..cfb655e 100644 --- a/src/gx/d3d/CGxDeviceD3d.cpp +++ b/src/gx/d3d/CGxDeviceD3d.cpp @@ -538,6 +538,8 @@ void CGxDeviceD3d::DeviceWM(EGxWM wm, uintptr_t param1, uintptr_t param2) { break; } + default: { + } } } @@ -727,6 +729,9 @@ void CGxDeviceD3d::DsSet(EDeviceState state, uint32_t val) { case Ds_ZFunc: { this->m_d3dDevice->SetRenderState(D3DRS_ZFUNC, val); break; + } + default: { + } } @@ -1915,6 +1920,7 @@ UNLOCK: } void CGxDeviceD3d::IXformSetProjection(const C44Matrix& matrix) { +#if defined(_MSC_VER) DirectX::XMMATRIX projNative; memcpy(&projNative, &matrix, sizeof(projNative)); @@ -1948,6 +1954,41 @@ void CGxDeviceD3d::IXformSetProjection(const C44Matrix& matrix) { this->m_xforms[GxXform_Projection].m_dirty = 1; memcpy(&this->m_projNative, &projNative, sizeof(this->m_projNative)); +#else + C44Matrix projNative; + memcpy(&projNative, &matrix, sizeof(projNative)); + + if (NotEqual(projNative.c3, 1.0f, WHOA_EPSILON_1) && NotEqual(projNative.c3, 0.0f, WHOA_EPSILON_1)) { + projNative = projNative * (1.0f / projNative.c3); + } + + if (projNative.d3 == 0.0f) { + auto v5 = -(projNative.d2 / (projNative.c2 + 1.0f)); + auto v6 = -(projNative.d2 / (projNative.c2 - 1.0f)); + projNative.c2 = v6 / (v6 - v5); + projNative.d2 = v6 * v5 / (v5 - v6); + } else { + auto v8 = 1.0f / projNative.c2; + auto v9 = (-1.0f - projNative.d2) * v8; + auto v10 = v8 * (1.0f - projNative.d2); + projNative.c2 = 1.0f / (v10 - v9); + projNative.d2 = v9 / (v9 - v10); + } + + if (!this->MasterEnable(GxMasterEnable_NormalProjection) && projNative.d3 != 1.0f) { + C44Matrix shrink = { + 0.2f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.2f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.2f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + + projNative = projNative * shrink; + } + + this->m_xforms[GxXform_Projection].m_dirty = 1; + memcpy(&this->m_projNative, &projNative, sizeof(this->m_projNative)); +#endif } void CGxDeviceD3d::IXformSetViewport() { diff --git a/src/gx/glsdl/GLSDLContext.hpp b/src/gx/glsdl/GLSDLContext.hpp index 8fd074a..10727f6 100644 --- a/src/gx/glsdl/GLSDLContext.hpp +++ b/src/gx/glsdl/GLSDLContext.hpp @@ -1,6 +1,6 @@ #ifndef GX_GL_SDL_GL_SDL_CONTEXT_HPP -#include +#include #include "gx/glsdl/GLSDLWindow.hpp" #include "gx/glsdl/GLTypes.hpp" diff --git a/src/gx/glsdl/GLSDLWindow.cpp b/src/gx/glsdl/GLSDLWindow.cpp index 492eccd..1b37e75 100644 --- a/src/gx/glsdl/GLSDLWindow.cpp +++ b/src/gx/glsdl/GLSDLWindow.cpp @@ -198,6 +198,8 @@ void GLSDLWindow::Create(const char* title, const GLSDLWindowRect& rect, GLTextu this->m_sdlWindow = SDL_CreateWindow( title, + 0, + 0, static_cast(rect.size.width), static_cast(rect.size.height), SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE ); @@ -229,17 +231,15 @@ GLSDLWindowRect GLSDLWindow::GetRect() { int origin_x = 0; int origin_y = 0; - if (SDL_GetWindowPosition(this->m_sdlWindow, &origin_x, &origin_y) == 0) { - rect.origin.x = static_cast(origin_x); - rect.origin.y = static_cast(origin_y); - } + SDL_GetWindowPosition(this->m_sdlWindow, &origin_x, &origin_y); + rect.origin.x = static_cast(origin_x); + rect.origin.y = static_cast(origin_y); int width = 0; int height = 0; - if (SDL_GetWindowSize(this->m_sdlWindow, &width, &height) == 0) { - rect.size.width = static_cast(width); - rect.size.height = static_cast(height); - } + SDL_GetWindowSize(this->m_sdlWindow, &width, &height); + rect.size.width = static_cast(width); + rect.size.height = static_cast(height); return rect; } @@ -251,10 +251,9 @@ GLSDLWindowRect GLSDLWindow::GetBackingRect() { // Query backing width/height int width = 0; int height = 0; - if (SDL_GetWindowSizeInPixels(this->m_sdlWindow, &width, &height) == 0) { - rect.size.width = static_cast(width); - rect.size.height = static_cast(height); - } + SDL_GetWindowSizeInPixels(this->m_sdlWindow, &width, &height); + rect.size.width = static_cast(width); + rect.size.height = static_cast(height); return rect; } @@ -263,8 +262,8 @@ void GLSDLWindow::Resize(const GLSDLWindowRect& rect) { auto current = this->GetBackingRect(); if (current.size.width != rect.size.width || current.size.height != rect.size.width) { - auto status = SDL_SetWindowSize(this->m_sdlWindow, rect.size.width, rect.size.height); - BLIZZARD_ASSERT(status == 0); + SDL_SetWindowSize(this->m_sdlWindow, rect.size.width, rect.size.height); + // BLIZZARD_ASSERT(status == 0); } } @@ -278,24 +277,24 @@ int32_t GLSDLWindow::GetHeight() { void GLSDLWindow::DispatchSDLEvent(const SDL_Event& event) { switch (event.type) { - case SDL_EVENT_KEY_DOWN: - case SDL_EVENT_KEY_UP: + case SDL_KEYDOWN: + case SDL_KEYUP: this->DispatchSDLKeyboardEvent(event); break; - case SDL_EVENT_MOUSE_BUTTON_DOWN: - case SDL_EVENT_MOUSE_BUTTON_UP: + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: this->DispatchSDLMouseButtonEvent(event); break; - case SDL_EVENT_MOUSE_MOTION: + case SDL_MOUSEMOTION: this->DispatchSDLMouseMotionEvent(event); break; - case SDL_EVENT_TEXT_INPUT: + case SDL_TEXTINPUT: this->DispatchSDLTextInputEvent(event); break; - case SDL_EVENT_WINDOW_RESIZED: + case SDL_WINDOWEVENT_RESIZED: this->DispatchSDLWindowResizedEvent(event); break; - case SDL_EVENT_QUIT: + case SDL_QUIT: EventPostClose(); break; default: @@ -305,7 +304,7 @@ void GLSDLWindow::DispatchSDLEvent(const SDL_Event& event) { void GLSDLWindow::DispatchSDLKeyboardEvent(const SDL_Event& event) { // Is this an up or down keypress? - OSINPUT inputclass = event.type == SDL_EVENT_KEY_UP ? OS_INPUT_KEY_UP : OS_INPUT_KEY_DOWN; + OSINPUT inputclass = event.type == SDL_KEYUP ? OS_INPUT_KEY_UP : OS_INPUT_KEY_DOWN; // What key does this SDL scancode correspond to? auto lookup = s_keyConversion.find(event.key.keysym.scancode); @@ -329,7 +328,7 @@ void GLSDLWindow::DispatchSDLMouseMotionEvent(const SDL_Event& event) { void GLSDLWindow::DispatchSDLMouseButtonEvent(const SDL_Event& event) { // Is this an up or down mouse click? - OSINPUT inputclass = event.type == SDL_EVENT_MOUSE_BUTTON_UP ? OS_INPUT_MOUSE_UP : OS_INPUT_MOUSE_DOWN; + OSINPUT inputclass = event.type == SDL_MOUSEBUTTONUP ? OS_INPUT_MOUSE_UP : OS_INPUT_MOUSE_DOWN; // XY click coordinates auto x = static_cast(event.button.x); diff --git a/src/gx/glsdl/GLSDLWindow.hpp b/src/gx/glsdl/GLSDLWindow.hpp index 915d34a..d1303ca 100644 --- a/src/gx/glsdl/GLSDLWindow.hpp +++ b/src/gx/glsdl/GLSDLWindow.hpp @@ -2,7 +2,7 @@ #define GX_GL_SDL_GL_SDL_WINDOW_HPP #include -#include +#include #include "gx/glsdl/GLTypes.hpp" diff --git a/src/sound/SI2.cpp b/src/sound/SI2.cpp index 389d855..6f5176c 100644 --- a/src/sound/SI2.cpp +++ b/src/sound/SI2.cpp @@ -3,6 +3,8 @@ #include "console/CVar.hpp" #include +#if defined(WHOA_BUILD_SOUND_FMOD) + FMOD::System* SI2::sm_pGameSystem = nullptr; FMOD::System* SI2::sm_pChatSystem = nullptr; @@ -18,6 +20,8 @@ void F_CALL FMOD_Free(void* ptr, FMOD_MEMORY_TYPE type, const char* sourcestr) { SMemFree(ptr, sourcestr, 0, 0); } +#endif + void SI2::RegisterScriptFunctions() { for (int32_t i = 0; i < s_NumScriptFunctions; i++) { auto item = &s_ScriptFunctions[i]; @@ -32,6 +36,7 @@ int32_t SI2::Init(int32_t flag) { SI2_LOG("=> Setting up Game Sound:"); SI2_LOG(" - SESound Engine Init"); +#if defined(WHOA_BUILD_SOUND_FMOD) SI2_LOG(" - FMOD Memory Init"); FMOD::Memory_Initialize(nullptr, 0, &FMOD_Alloc, &FMOD_ReAlloc, &FMOD_Free); // sub_877440(&off_B1D5E4); @@ -59,7 +64,7 @@ int32_t SI2::Init(int32_t flag) { } sm_pGameSystem->setOutput(FMOD_OUTPUTTYPE_AUTODETECT); - +#endif LABEL_9: return 0; diff --git a/src/sound/SI2.hpp b/src/sound/SI2.hpp index 7b434d5..edc0aff 100644 --- a/src/sound/SI2.hpp +++ b/src/sound/SI2.hpp @@ -5,12 +5,16 @@ #include #include #include + +#if defined(WHOA_BUILD_SOUND_FMOD) + #include #include +#endif #define SI2_ERR(errcode, format, ...) SI2::Log_Write(__LINE__, __FILE__, errcode, format, ##__VA_ARGS__) -#define SI2_LOG(format, ...) SI2::Log_Write(__LINE__, __FILE__, FMOD_OK, format, ##__VA_ARGS__) +#define SI2_LOG(format, ...) SI2::Log_Write(__LINE__, __FILE__, 0, format, ##__VA_ARGS__) class SI2 { public: @@ -19,14 +23,15 @@ class SI2 { static size_t s_NumScriptFunctions; static uint32_t sm_logFlags; static HSLOG sm_log; +#if defined(WHOA_BUILD_SOUND_FMOD) static FMOD::System* sm_pGameSystem; static FMOD::System* sm_pChatSystem; - +#endif // Static functions static void RegisterScriptFunctions(); static int32_t Log_Init(); static void Log_Write(const char* format, ...); - static void Log_Write(uint32_t line, const char* filename, FMOD_RESULT errcode, const char* format, ...); + static void Log_Write(uint32_t line, const char* filename, int32_t errcode, const char* format, ...); static void RegisterCVars(); static int32_t Init(int32_t flag); static void StartGlueMusic(const char* filename); diff --git a/src/sound/SI2Log.cpp b/src/sound/SI2Log.cpp index e73e07d..64ed766 100644 --- a/src/sound/SI2Log.cpp +++ b/src/sound/SI2Log.cpp @@ -25,10 +25,11 @@ void SI2::Log_Write(const char* format, ...) { va_end(va); } - Log_Write(__LINE__, __FILE__, FMOD_OK, output); + // Log_Write(__LINE__, __FILE__, FMOD_OK, output); + Log_Write(__LINE__, __FILE__, 0, output); } -void SI2::Log_Write(uint32_t line, const char* filename, FMOD_RESULT errcode, const char* format, ...) { +void SI2::Log_Write(uint32_t line, const char* filename, int32_t errcode, const char* format, ...) { static uint32_t s_nNumErrors = 0; if (s_nNumErrors > 200) { @@ -52,6 +53,7 @@ void SI2::Log_Write(uint32_t line, const char* filename, FMOD_RESULT errcode, co va_end(va); } +#if defined(WHOA_BUILD_SOUND_FMOD) if (errcode == FMOD_OK) { SLogWrite(sm_log, output); SLogFlush(sm_log); @@ -62,10 +64,13 @@ void SI2::Log_Write(uint32_t line, const char* filename, FMOD_RESULT errcode, co } SLogWrite(sm_log, " -######## FMOD ERROR! (err %d) %s", errcode, FMOD_ErrorString(errcode)); +#endif + if (format[0]) { SLogWrite(sm_log, output); } SLogWrite(sm_log, "%s(%d)", filename, line); SLogFlush(sm_log); s_nNumErrors++; + } diff --git a/src/ui/CSimpleTop.hpp b/src/ui/CSimpleTop.hpp index 6368742..3cdab38 100644 --- a/src/ui/CSimpleTop.hpp +++ b/src/ui/CSimpleTop.hpp @@ -56,7 +56,7 @@ class CSimpleTop : public CLayoutFrame { frame_layout m_layout; CSimpleSortedArray m_eventqueue[NUM_FRAME_STRATA][NUM_SIMPLE_EVENTS]; int32_t m_checkFocus = 1; - EVENT_DATA_MOUSE m_mousePosition; + EVENT_DATA_MOUSE m_mousePosition = {}; int32_t (*m_mouseButtonCallback)(CMouseEvent*) = nullptr; int32_t (*m_mousePositionCallback)(CMouseEvent*) = nullptr; int32_t (*m_displaySizeCallback)(const CSizeEvent&) = nullptr;