commit
78a48f9a35
117
data/scripts/logging/__init__.lua
Normal file
117
data/scripts/logging/__init__.lua
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
-- modified version of https://github.com/Joelrau/S1x-IW6x-g_log-script (permission to use by author)
|
||||||
|
|
||||||
|
if (game:getdvar("gamemode") ~= "mp") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- setup dvars
|
||||||
|
game:setdvarifuninitialized("logfile", 1)
|
||||||
|
if (tonumber(game:getdvar("logfile")) < 1) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
game:setdvarifuninitialized("g_log", "logs/games_mp.log")
|
||||||
|
|
||||||
|
start_time = 0
|
||||||
|
|
||||||
|
function get_time()
|
||||||
|
local seconds = math.floor((game:gettime() - start_time) / 1000)
|
||||||
|
local minutes = math.floor(seconds / 60)
|
||||||
|
time = string.format("%d:%02d", minutes, seconds - minutes * 60)
|
||||||
|
while (string.len(time) < 6) do
|
||||||
|
time = " " .. time
|
||||||
|
end
|
||||||
|
time = time .. " "
|
||||||
|
return time
|
||||||
|
end
|
||||||
|
|
||||||
|
function create_path(path)
|
||||||
|
local dir = path:gsub("%/", "\\"):match("(.*[\\])")
|
||||||
|
os.execute("if not exist " .. dir .. " mkdir " .. dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
function log_print(message)
|
||||||
|
local path = game:getdvar("g_log")
|
||||||
|
local file = io.open(path, "a")
|
||||||
|
if (file == nil) then
|
||||||
|
create_path(path)
|
||||||
|
file = assert(io.open(path, "a"))
|
||||||
|
end
|
||||||
|
file:write(get_time() .. message .. "\n")
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function init()
|
||||||
|
start_time = game:gettime()
|
||||||
|
|
||||||
|
log_print("------------------------------------------------------------")
|
||||||
|
log_print("InitGame")
|
||||||
|
|
||||||
|
-- player callbacks
|
||||||
|
level:onnotify("connected", function(player)
|
||||||
|
player:player_connected()
|
||||||
|
end)
|
||||||
|
level:onnotify("say", function(player, message, hidden)
|
||||||
|
player:say(message)
|
||||||
|
end)
|
||||||
|
level:onnotify("say_team", function(player, message, hidden)
|
||||||
|
player:say(message, "say_team")
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- damage/killed hooks
|
||||||
|
game:onplayerdamage(player_damage)
|
||||||
|
game:onplayerkilled(player_killed)
|
||||||
|
|
||||||
|
-- other level notifies for log
|
||||||
|
level:onnotify("exitLevel_called", function()
|
||||||
|
log_print("ExitLevel: executed")
|
||||||
|
end)
|
||||||
|
level:onnotify("shutdownGame_called", function()
|
||||||
|
log_print("ShutdownGame:")
|
||||||
|
log_print("------------------------------------------------------------")
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function entity:player_connected()
|
||||||
|
log_print(string.format("J;%s;%i;%s", self:getguid(), self:getentitynumber(), self.name))
|
||||||
|
|
||||||
|
self:onnotifyonce("disconnect", function()
|
||||||
|
self:disconnect()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function entity:disconnect()
|
||||||
|
log_print(string.format("Q;%s;%i;%s", self:getguid(), self:getentitynumber(), self.name))
|
||||||
|
end
|
||||||
|
|
||||||
|
function player_damage(self_, inflictor, attacker, damage, dflags, mod, weapon, vPoint, vDir, hitLoc)
|
||||||
|
if (game:isplayer(attacker) == 1) then
|
||||||
|
log_print(string.format("D;%s;%i;%s;%s;%s;%i;%s;%s;%s;%i;%s;%s", self_:getguid(), self_:getentitynumber(),
|
||||||
|
self_.team, self_.name, attacker:getguid(), attacker:getentitynumber(), attacker.team, attacker.name,
|
||||||
|
weapon, damage, mod, hitLoc))
|
||||||
|
else
|
||||||
|
log_print(string.format("D;%s;%i;%s;%s;%s;%i;%s;%s;%s;%i;%s;%s", self_:getguid(), self_:getentitynumber(),
|
||||||
|
self_.team, self_.name, "", "-1", "world", "", weapon, damage, mod, hitLoc))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function player_killed(self_, inflictor, attacker, damage, mod, weapon, vDir, hitLoc, psTimeOffset, deathAnimDuration)
|
||||||
|
if (game:isplayer(attacker) == 1) then
|
||||||
|
log_print(string.format("K;%s;%i;%s;%s;%s;%i;%s;%s;%s;%i;%s;%s", self_:getguid(), self_:getentitynumber(),
|
||||||
|
self_.team, self_.name, attacker:getguid(), attacker:getentitynumber(), attacker.team, attacker.name,
|
||||||
|
weapon, damage, mod, hitLoc))
|
||||||
|
else
|
||||||
|
log_print(string.format("K;%s;%i;%s;%s;%s;%i;%s;%s;%s;%i;%s;%s", self_:getguid(), self_:getentitynumber(),
|
||||||
|
self_.team, self_.name, "", "-1", "world", "", weapon, damage, mod, hitLoc))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- this function handles 'say' and 'say_team'
|
||||||
|
function entity:say(message, mode)
|
||||||
|
if (not mode) then
|
||||||
|
mode = "say"
|
||||||
|
end
|
||||||
|
|
||||||
|
log_print(string.format("%s;%s;%i;%s;%s", mode, self:getguid(), self:getentitynumber(), self.name, message))
|
||||||
|
end
|
||||||
|
|
||||||
|
init()
|
@ -1,3 +1,7 @@
|
|||||||
|
if (game:issingleplayer() or not Engine.InFrontend()) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
Cac.GameModes.Data = {
|
Cac.GameModes.Data = {
|
||||||
Standard = {
|
Standard = {
|
||||||
Label = Engine.Localize("@MPUI_STANDARD_CAPS"),
|
Label = Engine.Localize("@MPUI_STANDARD_CAPS"),
|
||||||
|
@ -63,6 +63,20 @@ function menu_xboxlive(f16_arg0, f16_arg1)
|
|||||||
Engine.ExecNow("eliteclan_refresh", Engine.GetFirstActiveController())
|
Engine.ExecNow("eliteclan_refresh", Engine.GetFirstActiveController())
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local root = Engine.GetLuiRoot()
|
||||||
|
if (root.vltimer) then
|
||||||
|
root.vltimer:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
root.vltimer = LUI.UITimer.new(4000, "vl")
|
||||||
|
root:addElement(root.vltimer)
|
||||||
|
root:registerEventHandler("vl", function()
|
||||||
|
if (Engine.GetDvarBool("virtualLobbyReady")) then
|
||||||
|
root.vltimer:close()
|
||||||
|
game:virtuallobbypresentable()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
return menu
|
return menu
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ game:addlocalizedstring("MENU_PING", "Ping")
|
|||||||
|
|
||||||
local columns = {
|
local columns = {
|
||||||
{
|
{
|
||||||
offset = 10,
|
offset = 40,
|
||||||
text = "@MENU_HOST_NAME",
|
text = "@MENU_HOST_NAME",
|
||||||
dataindex = 0
|
dataindex = 0
|
||||||
},
|
},
|
||||||
@ -33,6 +33,28 @@ local columns = {
|
|||||||
offset = 1100,
|
offset = 1100,
|
||||||
text = "@MENU_PING",
|
text = "@MENU_PING",
|
||||||
dataindex = 4
|
dataindex = 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset = 10,
|
||||||
|
image = "s1_icon_locked",
|
||||||
|
customelement = function(value, offset)
|
||||||
|
return LUI.UIImage.new({
|
||||||
|
leftAnchor = true,
|
||||||
|
topAnchor = true,
|
||||||
|
height = 20,
|
||||||
|
width = 20,
|
||||||
|
left = offset,
|
||||||
|
top = 2,
|
||||||
|
material = RegisterMaterial(CoD.Material.RestrictedIcon),
|
||||||
|
alpha = value == "1" and 1 or 0,
|
||||||
|
color = {
|
||||||
|
r = 1,
|
||||||
|
b = 1,
|
||||||
|
g = 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
dataindex = 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +90,20 @@ SystemLinkJoinMenu.AddHeaderButton = function(menu, f12_arg1, width)
|
|||||||
button.m_eventHandlers = {}
|
button.m_eventHandlers = {}
|
||||||
|
|
||||||
for i = 1, #columns do
|
for i = 1, #columns do
|
||||||
SystemLinkJoinMenu.MakeText(button.textHolder, columns[i].offset, Engine.Localize(columns[i].text), nil)
|
if (columns[i].text) then
|
||||||
|
SystemLinkJoinMenu.MakeText(button.textHolder, columns[i].offset, Engine.Localize(columns[i].text), nil)
|
||||||
|
elseif (columns[i].image) then
|
||||||
|
local image = LUI.UIImage.new({
|
||||||
|
leftAnchor = true,
|
||||||
|
topAnchor = true,
|
||||||
|
height = 20,
|
||||||
|
width = 20,
|
||||||
|
top = 2,
|
||||||
|
left = columns[i].offset,
|
||||||
|
material = RegisterMaterial(columns[i].image)
|
||||||
|
})
|
||||||
|
button.textHolder:addElement(image)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
element:addElement(button)
|
element:addElement(button)
|
||||||
@ -83,6 +118,9 @@ SystemLinkJoinMenu.AddServerButton = function(menu, controller, index)
|
|||||||
|
|
||||||
local gettext = function(i)
|
local gettext = function(i)
|
||||||
local text = Lobby.GetServerData(controller, index, columns[i].dataindex)
|
local text = Lobby.GetServerData(controller, index, columns[i].dataindex)
|
||||||
|
if (columns[i].customelement) then
|
||||||
|
text = columns[i].customelement(text)
|
||||||
|
end
|
||||||
|
|
||||||
local islast = not columns[i + 1]
|
local islast = not columns[i + 1]
|
||||||
local end_ = islast and 1130 or columns[i + 1].offset
|
local end_ = islast and 1130 or columns[i + 1].offset
|
||||||
@ -100,7 +138,13 @@ SystemLinkJoinMenu.AddServerButton = function(menu, controller, index)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for i = 1, #columns do
|
for i = 1, #columns do
|
||||||
SystemLinkJoinMenu.MakeText(button.textHolder, columns[i].offset, gettext(i), luiglobals.Colors.h1.medium_grey)
|
if (columns[i].customelement) then
|
||||||
|
local value = Lobby.GetServerData(controller, index, columns[i].dataindex)
|
||||||
|
local element = columns[i].customelement(value, columns[i].offset)
|
||||||
|
button.textHolder:addElement(element)
|
||||||
|
else
|
||||||
|
SystemLinkJoinMenu.MakeText(button.textHolder, columns[i].offset, gettext(i), luiglobals.Colors.h1.medium_grey)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
menu.list:addElement(button)
|
menu.list:addElement(button)
|
||||||
@ -131,6 +175,8 @@ SystemLinkJoinMenu.MakeText = function(menu, f5_arg1, text, color)
|
|||||||
|
|
||||||
el:setText(text)
|
el:setText(text)
|
||||||
menu:addElement(el)
|
menu:addElement(el)
|
||||||
|
|
||||||
|
return el
|
||||||
end
|
end
|
||||||
|
|
||||||
function menu_systemlink_join(f19_arg0, f19_arg1)
|
function menu_systemlink_join(f19_arg0, f19_arg1)
|
||||||
|
@ -40,6 +40,7 @@ namespace dedicated
|
|||||||
game::netadr_s target{};
|
game::netadr_s target{};
|
||||||
if (server_list::get_master_server(target))
|
if (server_list::get_master_server(target))
|
||||||
{
|
{
|
||||||
|
console::info("Sending heartbeat");
|
||||||
network::send(target, "heartbeat", "H1");
|
network::send(target, "heartbeat", "H1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,8 +119,8 @@ namespace images
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_texture_hook.create(SELECT_VALUE(0x55F870_b, 0x6829C0_b), setup_texture_stub);
|
setup_texture_hook.create(SELECT_VALUE(0x83300_b, 0xA4AA0_b), setup_texture_stub);
|
||||||
load_texture_hook.create(SELECT_VALUE(0x83300_b, 0xA4AA0_b), load_texture_stub);
|
load_texture_hook.create(SELECT_VALUE(0x82050_b, 0xA37A0_b), load_texture_stub);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -250,6 +250,17 @@ namespace patches
|
|||||||
"Disable shader caching, lower graphic settings, free up RAM, or update your GPU drivers.");
|
"Disable shader caching, lower graphic settings, free up RAM, or update your GPU drivers.");
|
||||||
utils::hook::call(SELECT_VALUE(0x457BC9_b, 0x1D8E09_b), out_of_memory_text_stub); // "Out of memory. You are probably low on disk space."
|
utils::hook::call(SELECT_VALUE(0x457BC9_b, 0x1D8E09_b), out_of_memory_text_stub); // "Out of memory. You are probably low on disk space."
|
||||||
|
|
||||||
|
// "fix" for rare 'Out of memory error' error
|
||||||
|
// this will *at least* generate the configs for mp/sp, which is the #1 issue
|
||||||
|
if (utils::flags::has_flag("memoryfix"))
|
||||||
|
{
|
||||||
|
utils::hook::jump(SELECT_VALUE(0x5110D0_b, 0x6200C0_b), malloc);
|
||||||
|
utils::hook::jump(SELECT_VALUE(0x510FF0_b, 0x61FFE0_b), _aligned_malloc);
|
||||||
|
utils::hook::jump(SELECT_VALUE(0x511130_b, 0x620120_b), free);
|
||||||
|
utils::hook::jump(SELECT_VALUE(0x511220_b, 0x620210_b), realloc);
|
||||||
|
utils::hook::jump(SELECT_VALUE(0x511050_b, 0x620040_b), _aligned_realloc);
|
||||||
|
}
|
||||||
|
|
||||||
if (!game::environment::is_sp())
|
if (!game::environment::is_sp())
|
||||||
{
|
{
|
||||||
patch_mp();
|
patch_mp();
|
||||||
@ -333,16 +344,6 @@ namespace patches
|
|||||||
// Prevent clients from sending invalid reliableAcknowledge
|
// Prevent clients from sending invalid reliableAcknowledge
|
||||||
utils::hook::call(0x1CBD06_b, sv_execute_client_message_stub);
|
utils::hook::call(0x1CBD06_b, sv_execute_client_message_stub);
|
||||||
|
|
||||||
// "fix" for rare 'Out of memory error' error
|
|
||||||
if (utils::flags::has_flag("memoryfix"))
|
|
||||||
{
|
|
||||||
utils::hook::jump(0x6200C0_b, malloc);
|
|
||||||
utils::hook::jump(0x61FFE0_b, _aligned_malloc);
|
|
||||||
utils::hook::jump(0x620120_b, free);
|
|
||||||
utils::hook::jump(0x620210_b, realloc);
|
|
||||||
utils::hook::jump(0x620040_b, _aligned_realloc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change default hostname and make it replicated
|
// Change default hostname and make it replicated
|
||||||
dvars::override::register_string("sv_hostname", "^2H1-Mod^7 Default Server", game::DVAR_FLAG_REPLICATED);
|
dvars::override::register_string("sv_hostname", "^2H1-Mod^7 Default Server", game::DVAR_FLAG_REPLICATED);
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ namespace server_list
|
|||||||
game::CodPlayMode play_mode;
|
game::CodPlayMode play_mode;
|
||||||
char in_game;
|
char in_game;
|
||||||
game::netadr_s address;
|
game::netadr_s address;
|
||||||
|
bool is_private;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@ -156,6 +157,11 @@ namespace server_list
|
|||||||
return servers[i].game_type.empty() ? "" : utils::string::va("%i", servers[i].ping);
|
return servers[i].game_type.empty() ? "" : utils::string::va("%i", servers[i].ping);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (column == 5)
|
||||||
|
{
|
||||||
|
return servers[i].is_private ? "1" : "0";
|
||||||
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,6 +368,7 @@ namespace server_list
|
|||||||
server.max_clients = atoi(info.get("sv_maxclients").data());
|
server.max_clients = atoi(info.get("sv_maxclients").data());
|
||||||
server.bots = atoi(info.get("bots").data());
|
server.bots = atoi(info.get("bots").data());
|
||||||
server.ping = std::min(now - start_time, 999);
|
server.ping = std::min(now - start_time, 999);
|
||||||
|
server.is_private = atoi(info.get("isPrivate").data()) == 1;
|
||||||
|
|
||||||
server.in_game = 1;
|
server.in_game = 1;
|
||||||
|
|
||||||
@ -373,16 +380,22 @@ namespace server_list
|
|||||||
public:
|
public:
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
if (!game::environment::is_mp()) return;
|
if (!game::environment::is_sp())
|
||||||
|
|
||||||
scheduler::once([]()
|
|
||||||
{
|
{
|
||||||
// add dvars to change destination master server ip/port
|
scheduler::once([]()
|
||||||
master_server_ip = dvars::register_string("masterServerIP", "master.h1.gg", game::DVAR_FLAG_NONE,
|
{
|
||||||
"IP of the destination master server to connect to");
|
// add dvars to change destination master server ip/port
|
||||||
master_server_port = dvars::register_string("masterServerPort", "20810", game::DVAR_FLAG_NONE,
|
master_server_ip = dvars::register_string("masterServerIP", "master.h1.gg", game::DVAR_FLAG_NONE,
|
||||||
"Port of the destination master server to connect to");
|
"IP of the destination master server to connect to");
|
||||||
}, scheduler::pipeline::main);
|
master_server_port = dvars::register_string("masterServerPort", "20810", game::DVAR_FLAG_NONE,
|
||||||
|
"Port of the destination master server to connect to");
|
||||||
|
}, scheduler::pipeline::main);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!game::environment::is_mp())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
localized_strings::override("PLATFORM_SYSTEM_LINK_TITLE", "SERVER LIST");
|
localized_strings::override("PLATFORM_SYSTEM_LINK_TITLE", "SERVER LIST");
|
||||||
|
|
||||||
|
@ -337,6 +337,11 @@ namespace ui_scripting
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
game_type["virtuallobbypresentable"] = [](const game&)
|
||||||
|
{
|
||||||
|
::game::Dvar_SetFromStringByNameFromSource("virtualLobbyPresentable", "1", ::game::DvarSetSource::DVAR_SOURCE_INTERNAL);
|
||||||
|
};
|
||||||
|
|
||||||
auto updater_table = table();
|
auto updater_table = table();
|
||||||
lua["updater"] = updater_table;
|
lua["updater"] = updater_table;
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#define DATA_PATH_DEV "data-dev/"
|
#define DATA_PATH_DEV "data-dev/"
|
||||||
|
|
||||||
#define ERR_UPDATE_CHECK_FAIL "Failed to check for updates"
|
#define ERR_UPDATE_CHECK_FAIL "Failed to check for updates"
|
||||||
|
#define ERR_UPDATE_CHECK_FAIL_BAD_RESPONSE "Bad response"
|
||||||
#define ERR_DOWNLOAD_FAIL "Failed to download file "
|
#define ERR_DOWNLOAD_FAIL "Failed to download file "
|
||||||
#define ERR_WRITE_FAIL "Failed to write file "
|
#define ERR_WRITE_FAIL "Failed to write file "
|
||||||
|
|
||||||
@ -345,7 +346,7 @@ namespace updater
|
|||||||
|
|
||||||
if (!j.IsArray())
|
if (!j.IsArray())
|
||||||
{
|
{
|
||||||
set_update_check_status(true, false, ERR_UPDATE_CHECK_FAIL);
|
set_update_check_status(true, false, ERR_UPDATE_CHECK_FAIL_BAD_RESPONSE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,11 +156,6 @@ namespace scripting::lua
|
|||||||
return normalize_vector(a);
|
return normalize_vector(a);
|
||||||
};
|
};
|
||||||
|
|
||||||
vector_type["normalize"] = [](const vector& a)
|
|
||||||
{
|
|
||||||
return normalize_vector(a);
|
|
||||||
};
|
|
||||||
|
|
||||||
vector_type["toangles"] = [](const vector& a)
|
vector_type["toangles"] = [](const vector& a)
|
||||||
{
|
{
|
||||||
return call("vectortoangles", {a}).as<vector>();
|
return call("vectortoangles", {a}).as<vector>();
|
||||||
|
@ -12,11 +12,6 @@ function startupdatecheck(popup, autoclose)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if (not updater.getupdatecheckstatus()) then
|
if (not updater.getupdatecheckstatus()) then
|
||||||
if (autoclose) then
|
|
||||||
LUI.FlowManager.RequestLeaveMenu(popup)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
popup.text:setText("Error: " .. updater.getlasterror())
|
popup.text:setText("Error: " .. updater.getlasterror())
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -71,11 +66,6 @@ function startupdatedownload(popup, autoclose)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if (not updater.getupdatedownloadstatus()) then
|
if (not updater.getupdatedownloadstatus()) then
|
||||||
if (autoclose) then
|
|
||||||
LUI.FlowManager.RequestLeaveMenu(popup)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
popup.text:setText("Error: " .. updater.getlasterror())
|
popup.text:setText("Error: " .. updater.getlasterror())
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -47,6 +47,13 @@ namespace utils::vector
|
|||||||
out[2] = veca[2] - vecb[2];
|
out[2] = veca[2] - vecb[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add(const float* veca, const float* vecb, float* out)
|
||||||
|
{
|
||||||
|
out[0] = veca[0] + vecb[0];
|
||||||
|
out[1] = veca[1] + vecb[1];
|
||||||
|
out[2] = veca[2] + vecb[2];
|
||||||
|
}
|
||||||
|
|
||||||
float length(float* v)
|
float length(float* v)
|
||||||
{
|
{
|
||||||
return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
return sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||||
|
@ -7,6 +7,7 @@ namespace utils::vector
|
|||||||
void scale(const float* in, float scale, float* out);
|
void scale(const float* in, float scale, float* out);
|
||||||
void ma(const float* v1, float scale, const float* v2, float* out);
|
void ma(const float* v1, float scale, const float* v2, float* out);
|
||||||
void subtract(const float* veca, const float* vecb, float* out);
|
void subtract(const float* veca, const float* vecb, float* out);
|
||||||
|
void add(const float* veca, const float* vecb, float* out);
|
||||||
float length(float* v);
|
float length(float* v);
|
||||||
float product(const float* v1, const float* v2);
|
float product(const float* v1, const float* v2);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user