From 0b8cd9a01cfaccbeeb54e7775eb805e04cf225fa Mon Sep 17 00:00:00 2001 From: jeefo Date: Fri, 9 Jun 2023 06:27:04 +0300 Subject: [PATCH] bot: benefit from sse4.x intrinsics if cpu capable bot: speed some string functions if sse 4.x available build: allow to build with native optimizations by settings -Dnative=true --- ext/crlib | 2 +- meson.build | 26 +++++++++++++++--- meson_options.txt | 5 +++- src/botlib.cpp | 44 +++++++++++++++--------------- src/chatlib.cpp | 4 +-- src/combat.cpp | 6 ++--- src/config.cpp | 4 +-- src/engine.cpp | 60 ++++++++++++++++++++++++++--------------- src/graph.cpp | 12 ++++----- src/linkage.cpp | 9 ++++--- src/manager.cpp | 14 +++++----- src/navigate.cpp | 16 +++++------ src/storage.cpp | 2 +- src/support.cpp | 4 +-- src/tasks.cpp | 4 +-- src/vision.cpp | 2 +- vc/yapb.vcxproj | 3 ++- vc/yapb.vcxproj.filters | 5 +++- 18 files changed, 133 insertions(+), 89 deletions(-) diff --git a/ext/crlib b/ext/crlib index 313311c..41b6193 160000 --- a/ext/crlib +++ b/ext/crlib @@ -1 +1 @@ -Subproject commit 313311c8612ce2a70c616f7187358c397d32765a +Subproject commit 41b6193971079e1d19d7d2d95cfc9204e1ec75b2 diff --git a/meson.build b/meson.build index 4cbb8af..b10861a 100644 --- a/meson.build +++ b/meson.build @@ -38,6 +38,9 @@ cpu = host_machine.cpu_family() cxx = compiler.get_id() build_type = get_option ('buildtype') +opt_64bit = get_option('64bit') +opt_native = get_option('native') + # cpp and ldflags from scratch cxxflags = [] ldflags = [] @@ -87,20 +90,35 @@ if git.found() configure_file (input: 'inc/version.h.in', output: 'version.build.h', configuration: version_data) endif +# define crlib native build +if opt_native + cxxflags += ['-DCR_NATIVE_BUILD'] +endif + # configure flags gcc and clang if cxx == 'clang' or cxx == 'gcc' cxxflags += [ - '-mtune=generic', '-fno-threadsafe-statics', '-pthread' + '-fno-threadsafe-statics', '-pthread' ] + if not opt_native + cxxflags += '-mtune=generic' + endif + if cpu == 'aarch64' cxxflags += [ '-march=armv8-a+fp+simd', ] else cxxflags += [ - '-march=x86-64', '-mmmx', '-msse', '-msse2', '-msse3', '-mssse3', '-mfpmath=sse' + '-mmmx', '-msse', '-msse2', '-msse3', '-mssse3', '-mfpmath=sse' ] + + if opt_native + cxxflags += '-march=native' + else + cxxflags += '-march=x86-64' + endif endif # setup optimization flags @@ -155,7 +173,7 @@ if cxx == 'clang' or cxx == 'gcc' endif # by default we buid 32bit binaries - if cpu != 'aarch64' and not get_option('64bit') + if cpu != 'aarch64' and not opt_64bit cxxflags += '-m32' ldflags += '-m32' @@ -183,7 +201,7 @@ if cxx == 'clang' or cxx == 'gcc' ] endif elif os == 'windows' and (cxx =='msvc' or cxx == 'clang-cl') - if not get_option('64bit') and cxx == 'clang' + if not opt_64bit and cxx == 'clang' cxxflags += '/MACHINE:X86' ldflags += '/MACHINE:X86' endif diff --git a/meson_options.txt b/meson_options.txt index 3d6e907..eaa20a1 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -6,4 +6,7 @@ # option('64bit', type : 'boolean', value : false, - description: 'Enables bot build with as 64-bit binary.') \ No newline at end of file + description: 'Enables bot build with as 64-bit binary.') + +option('native', type : 'boolean', value : false, + description: 'Configure compiler for a native machine build.') \ No newline at end of file diff --git a/src/botlib.cpp b/src/botlib.cpp index 4bc7168..f5a1175 100644 --- a/src/botlib.cpp +++ b/src/botlib.cpp @@ -95,7 +95,7 @@ void Bot::avoidGrenades () { } auto model = pent->v.model.chars (9); - if (m_preventFlashing < game.time () && m_personality == Personality::Rusher && m_difficulty == Difficulty::Expert && strcmp (model, "flashbang.mdl") == 0) { + if (m_preventFlashing < game.time () && m_personality == Personality::Rusher && m_difficulty == Difficulty::Expert && cr::strcmp (model, "flashbang.mdl") == 0) { // don't look at flash bang if (!(m_states & Sense::SeeingEnemy)) { m_lookAt.y = cr::wrapAngle ((game.getEntityOrigin (pent) - getEyesPos ()).angles ().y + 180.0f); @@ -104,7 +104,7 @@ void Bot::avoidGrenades () { m_preventFlashing = game.time () + rg.get (1.0f, 2.0f); } } - else if (game.isNullEntity (m_avoidGrenade) && strcmp (model, "hegrenade.mdl") == 0) { + else if (game.isNullEntity (m_avoidGrenade) && cr::strcmp (model, "hegrenade.mdl") == 0) { if (game.getTeam (pent->v.owner) == m_team || pent->v.owner == ent ()) { continue; } @@ -127,7 +127,7 @@ void Bot::avoidGrenades () { } } } - else if ((pent->v.flags & FL_ONGROUND) && strcmp (model, "smokegrenade.mdl") == 0) { + else if ((pent->v.flags & FL_ONGROUND) && cr::strcmp (model, "smokegrenade.mdl") == 0) { if (isInFOV (pent->v.origin - getEyesPos ()) < pev->fov - 7.0f) { float distance = pent->v.origin.distance (pev->origin); @@ -342,31 +342,31 @@ void Bot::updatePickups () { // check if line of sight to object is not blocked (i.e. visible) if (seesItem (origin, classname)) { - if (strncmp ("hostage_entity", classname, 14) == 0 || strncmp ("monster_scientist", classname, 17) == 0) { + if (cr::strncmp ("hostage_entity", classname, 14) == 0 || cr::strncmp ("monster_scientist", classname, 17) == 0) { allowPickup = true; pickupType = Pickup::Hostage; } - else if (strncmp ("weaponbox", classname, 9) == 0 && strcmp (model, "backpack.mdl") == 0) { + else if (cr::strncmp ("weaponbox", classname, 9) == 0 && cr::strcmp (model, "backpack.mdl") == 0) { allowPickup = true; pickupType = Pickup::DroppedC4; } - else if ((strncmp ("weaponbox", classname, 9) == 0 || strncmp ("armoury_entity", classname, 14) == 0 || strncmp ("csdm", classname, 4) == 0) && !m_isUsingGrenade) { + else if ((cr::strncmp ("weaponbox", classname, 9) == 0 || cr::strncmp ("armoury_entity", classname, 14) == 0 || cr::strncmp ("csdm", classname, 4) == 0) && !m_isUsingGrenade) { allowPickup = true; pickupType = Pickup::Weapon; } - else if (strncmp ("weapon_shield", classname, 13) == 0 && !m_isUsingGrenade) { + else if (cr::strncmp ("weapon_shield", classname, 13) == 0 && !m_isUsingGrenade) { allowPickup = true; pickupType = Pickup::Shield; } - else if (strncmp ("item_thighpack", classname, 14) == 0 && m_team == Team::CT && !m_hasDefuser) { + else if (cr::strncmp ("item_thighpack", classname, 14) == 0 && m_team == Team::CT && !m_hasDefuser) { allowPickup = true; pickupType = Pickup::DefusalKit; } - else if (strncmp ("grenade", classname, 7) == 0 && conf.getBombModelName () == model) { + else if (cr::strncmp ("grenade", classname, 7) == 0 && conf.getBombModelName () == model) { allowPickup = true; pickupType = Pickup::PlantedC4; } - else if (cv_pickup_custom_items.bool_ () && util.isItem (ent) && strncmp ("item_thighpack", classname, 14) != 0) { + else if (cv_pickup_custom_items.bool_ () && util.isItem (ent) && cr::strncmp ("item_thighpack", classname, 14) != 0) { allowPickup = true; pickupType = Pickup::None; } @@ -387,10 +387,10 @@ void Bot::updatePickups () { const auto &primaryProp = conf.getWeaponProp (primary.id); const auto &secondaryProp = conf.getWeaponProp (secondary.id); - if (secondaryWeaponCarried < 7 && (m_ammo[secondary.id] > 0.3 * secondaryProp.ammo1Max) && strcmp (model, "w_357ammobox.mdl") == 0) { + if (secondaryWeaponCarried < 7 && (m_ammo[secondary.id] > 0.3 * secondaryProp.ammo1Max) && cr::strcmp (model, "w_357ammobox.mdl") == 0) { allowPickup = false; } - else if (!m_isVIP && primaryWeaponCarried >= 7 && (m_ammo[primary.id] > 0.3 * primaryProp.ammo1Max) && strncmp (model, "w_", 2) == 0) { + else if (!m_isVIP && primaryWeaponCarried >= 7 && (m_ammo[primary.id] > 0.3 * primaryProp.ammo1Max) && cr::strncmp (model, "w_", 2) == 0) { auto weaponType = conf.getWeaponType (primaryWeaponCarried); const bool isSniperRifle = weaponType == WeaponType::Sniper; @@ -398,38 +398,38 @@ void Bot::updatePickups () { const bool isShotgun = weaponType == WeaponType::Shotgun; const bool isRifle = weaponType == WeaponType::Rifle || weaponType == WeaponType::ZoomRifle; - if (!isRifle && strcmp (model, "w_9mmarclip.mdl") == 0) { + if (!isRifle && cr::strcmp (model, "w_9mmarclip.mdl") == 0) { allowPickup = false; } - else if (!isShotgun && strcmp (model, "w_shotbox.mdl") == 0) { + else if (!isShotgun && cr::strcmp (model, "w_shotbox.mdl") == 0) { allowPickup = false; } - else if (!isSubmachine && strcmp (model, "w_9mmclip.mdl") == 0) { + else if (!isSubmachine && cr::strcmp (model, "w_9mmclip.mdl") == 0) { allowPickup = false; } - else if (!isSniperRifle && strcmp (model, "w_crossbow_clip.mdl") == 0) { + else if (!isSniperRifle && cr::strcmp (model, "w_crossbow_clip.mdl") == 0) { allowPickup = false; } - else if (primaryWeaponCarried != Weapon::M249 && strcmp (model, "w_chainammo.mdl") == 0) { + else if (primaryWeaponCarried != Weapon::M249 && cr::strcmp (model, "w_chainammo.mdl") == 0) { allowPickup = false; } } else if (m_isVIP || !rateGroundWeapon (ent)) { allowPickup = false; } - else if (m_healthValue >= 100.0f && strcmp (model, "medkit.mdl") == 0) { + else if (m_healthValue >= 100.0f && cr::strcmp (model, "medkit.mdl") == 0) { allowPickup = false; } - else if (pev->armorvalue >= 100.0f && (strcmp (model, "kevlar.mdl") == 0 || strcmp (model, "battery.mdl") == 0)) { + else if (pev->armorvalue >= 100.0f && (cr::strcmp (model, "kevlar.mdl") == 0 || cr::strcmp (model, "battery.mdl") == 0)) { allowPickup = false; } - else if ((pev->weapons & cr::bit (Weapon::Flashbang)) && strcmp (model, "flashbang.mdl") == 0) { + else if ((pev->weapons & cr::bit (Weapon::Flashbang)) && cr::strcmp (model, "flashbang.mdl") == 0) { allowPickup = false; } - else if ((pev->weapons & cr::bit (Weapon::Explosive)) && strcmp (model, "hegrenade.mdl") == 0) { + else if ((pev->weapons & cr::bit (Weapon::Explosive)) && cr::strcmp (model, "hegrenade.mdl") == 0) { allowPickup = false; } - else if ((pev->weapons & cr::bit (Weapon::Smoke)) && strcmp (model, "smokegrenade.mdl") == 0) { + else if ((pev->weapons & cr::bit (Weapon::Smoke)) && cr::strcmp (model, "smokegrenade.mdl") == 0) { allowPickup = false; } } diff --git a/src/chatlib.cpp b/src/chatlib.cpp index b87c966..9a258bb 100644 --- a/src/chatlib.cpp +++ b/src/chatlib.cpp @@ -44,14 +44,14 @@ void BotSupport::humanizePlayerName (String &playerName) { } // sometimes switch name to lower characters, only valid for the english languge - if (rg.chance (8) && strcmp (cv_language.str (), "en") == 0) { + if (rg.chance (8) && cr::strcmp (cv_language.str (), "en") == 0) { playerName.lowercase (); } } void BotSupport::addChatErrors (String &line) { // sometimes switch name to lower characters, only valid for the english languge - if (rg.chance (8) && strcmp (cv_language.str (), "en") == 0) { + if (rg.chance (8) && cr::strcmp (cv_language.str (), "en") == 0) { line.lowercase (); } auto length = static_cast (line.length ()); diff --git a/src/combat.cpp b/src/combat.cpp index 7cd6f2a..cb68525 100644 --- a/src/combat.cpp +++ b/src/combat.cpp @@ -1332,7 +1332,7 @@ bool Bot::hasSecondaryWeapon () { bool Bot::hasShield () { // this function returns true, if bot has a tactical shield - return strncmp (pev->viewmodel.chars (14), "v_shield_", 9) == 0; + return cr::strncmp (pev->viewmodel.chars (14), "v_shield_", 9) == 0; } bool Bot::isShieldDrawn () { @@ -1352,7 +1352,7 @@ bool Bot::isEnemyBehindShield (edict_t *enemy) { } // check if enemy has shield and this shield is drawn - if ((enemy->v.weaponanim == 6 || enemy->v.weaponanim == 7) && strncmp (enemy->v.viewmodel.chars (14), "v_shield_", 9) == 0) { + if ((enemy->v.weaponanim == 6 || enemy->v.weaponanim == 7) && cr::strncmp (enemy->v.viewmodel.chars (14), "v_shield_", 9) == 0) { if (util.isInViewCone (pev->origin, enemy)) { return true; } @@ -1474,7 +1474,7 @@ bool Bot::rateGroundWeapon (edict_t *ent) { auto tab = conf.getRawWeapons (); for (int i = 0; i < kNumWeapons; ++i) { - if (strcmp (tab[*pref].model, ent->v.model.chars (9)) == 0) { + if (cr::strcmp (tab[*pref].model, ent->v.model.chars (9)) == 0) { groundIndex = i; break; } diff --git a/src/config.cpp b/src/config.cpp index 35bd5b3..38b0db8 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -501,7 +501,7 @@ void BotConfig::loadLanguageConfig () { } file.close (); } - else if (strcmp (cv_language.str (), "en") != 0) { + else if (cr::strcmp (cv_language.str (), "en") != 0) { logger.error ("Couldn't load language configuration"); } } @@ -835,7 +835,7 @@ bool BotConfig::openConfig (StringRef fileName, StringRef errorIfNotExists, MemF auto configDir = strings.joinPath (folders.addons, folders.bot, folders.config); if (languageDependant) { - if (fileName.startsWith ("lang") && strcmp (cv_language.str (), "en") == 0) { + if (fileName.startsWith ("lang") && cr::strcmp (cv_language.str (), "en") == 0) { return false; } auto langConfig = strings.joinPath (configDir, folders.lang, strings.format ("%s_%s.%s", cv_language.str (), fileName, kConfigExtension)); diff --git a/src/engine.cpp b/src/engine.cpp index d94b2ad..96c9af8 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -95,10 +95,10 @@ void Game::levelInitialize (edict_t *entities, int max) { } auto classname = ent->v.classname.chars (); - if (strcmp (classname, "worldspawn") == 0) { + if (cr::strcmp (classname, "worldspawn") == 0) { m_startEntity = ent; } - else if (strcmp (classname, "player_weaponstrip") == 0) { + else if (cr::strcmp (classname, "player_weaponstrip") == 0) { if (is (GameFlags::Legacy) && strings.isEmpty (ent->v.target.chars ())) { ent->v.target = ent->v.targetname = engfuncs.pfnAllocString ("fake"); } @@ -106,30 +106,30 @@ void Game::levelInitialize (edict_t *entities, int max) { engfuncs.pfnRemoveEntity (ent); } } - else if (strcmp (classname, "info_player_start") == 0 || strcmp (classname, "info_vip_start") == 0) { + else if (cr::strcmp (classname, "info_player_start") == 0 || cr::strcmp (classname, "info_vip_start") == 0) { ent->v.rendermode = kRenderTransAlpha; // set its render mode to transparency ent->v.renderamt = 127; // set its transparency amount ent->v.effects |= EF_NODRAW; ++m_spawnCount[Team::CT]; } - else if (strcmp (classname, "info_player_deathmatch") == 0) { + else if (cr::strcmp (classname, "info_player_deathmatch") == 0) { ent->v.rendermode = kRenderTransAlpha; // set its render mode to transparency ent->v.renderamt = 127; // set its transparency amount ent->v.effects |= EF_NODRAW; ++m_spawnCount[Team::Terrorist]; } - else if (strcmp (classname, "func_vip_safetyzone") == 0 || strcmp (classname, "info_vip_safetyzone") == 0) { + else if (cr::strcmp (classname, "func_vip_safetyzone") == 0 || cr::strcmp (classname, "info_vip_safetyzone") == 0) { m_mapFlags |= MapFlags::Assassination; // assassination map } - else if (strcmp (classname, "hostage_entity") == 0 || strcmp (classname, "monster_scientist") == 0) { + else if (cr::strcmp (classname, "hostage_entity") == 0 || cr::strcmp (classname, "monster_scientist") == 0) { m_mapFlags |= MapFlags::HostageRescue; // rescue map } - else if (strcmp (classname, "func_bomb_target") == 0 || strcmp (classname, "info_bomb_target") == 0) { + else if (cr::strcmp (classname, "func_bomb_target") == 0 || cr::strcmp (classname, "info_bomb_target") == 0) { m_mapFlags |= MapFlags::Demolition; // defusion map } - else if (strcmp (classname, "func_escapezone") == 0) { + else if (cr::strcmp (classname, "func_escapezone") == 0) { m_mapFlags |= MapFlags::Escape; // strange thing on some ES maps, where hostage entity present there @@ -137,10 +137,10 @@ void Game::levelInitialize (edict_t *entities, int max) { m_mapFlags &= ~MapFlags::HostageRescue; } } - else if (strncmp (classname, "func_door", 9) == 0) { + else if (cr::strncmp (classname, "func_door", 9) == 0) { m_mapFlags |= MapFlags::HasDoors; } - else if (strncmp (classname, "func_button", 11) == 0) { + else if (cr::strncmp (classname, "func_button", 11) == 0) { m_mapFlags |= MapFlags::HasButtons; } else if (isShootableBreakable (ent)) { @@ -149,10 +149,10 @@ void Game::levelInitialize (edict_t *entities, int max) { } // next maps doesn't have map-specific entities, so determine it by name - if (strncmp (getMapName (), "fy_", 3) == 0) { + if (cr::strncmp (getMapName (), "fy_", 3) == 0) { m_mapFlags |= MapFlags::FightYard; } - else if (strncmp (getMapName (), "ka_", 3) == 0) { + else if (cr::strncmp (getMapName (), "ka_", 3) == 0) { m_mapFlags |= MapFlags::KnifeArena; } @@ -284,7 +284,7 @@ public: } bool isWave (char *format) { - if (little && memcmp (format, "WAVE", 4) == 0) { + if (little && cr::memcmp (format, "WAVE", 4) == 0) { return true; } return *reinterpret_cast (format) == 0x57415645; @@ -794,7 +794,7 @@ bool Game::loadCSBinary () { } // special case, czero is always detected first, as it's has custom directory - if (strcmp (modname, "czero") == 0) { + if (cr::strcmp (modname, "czero") == 0) { m_gameFlags |= (GameFlags::ConditionZero | GameFlags::HasBotVoice | GameFlags::HasFakePings); if (is (GameFlags::Metamod)) { @@ -1059,7 +1059,7 @@ bool Game::isShootableBreakable (edict_t *ent) { } auto limit = cv_breakable_health_limit.float_ (); - if ((strcmp (ent->v.classname.chars (), "func_breakable") == 0 && ent->v.health < limit) || (strcmp (ent->v.classname.chars (), "func_pushable") == 0 && (ent->v.spawnflags & SF_PUSH_BREAKABLE) && ent->v.health < limit) || (strcmp (ent->v.classname.chars (), "func_wall") == 0 && ent->v.health < limit)) { + if ((cr::strcmp (ent->v.classname.chars (), "func_breakable") == 0 && ent->v.health < limit) || (cr::strcmp (ent->v.classname.chars (), "func_pushable") == 0 && (ent->v.spawnflags & SF_PUSH_BREAKABLE) && ent->v.health < limit) || (cr::strcmp (ent->v.classname.chars (), "func_wall") == 0 && ent->v.health < limit)) { if (ent->v.takedamage > 0.0f && ent->v.impulse <= 0 && !(ent->v.flags & FL_WORLDBRUSH) && !(ent->v.spawnflags & SF_BREAK_TRIGGER_ONLY)) { return (ent->v.movetype == MOVETYPE_PUSH || ent->v.movetype == MOVETYPE_PUSHSTEP); } @@ -1069,7 +1069,7 @@ bool Game::isShootableBreakable (edict_t *ent) { void Game::printBotVersion () { String gameVersionStr; - StringArray gameVersionFlags; + StringArray botRuntimeFlags; if (is (GameFlags::Legacy)) { gameVersionStr.assign ("Legacy"); @@ -1091,21 +1091,37 @@ void Game::printBotVersion () { } if (is (GameFlags::HasBotVoice)) { - gameVersionFlags.push ("BotVoice"); + botRuntimeFlags.push ("BotVoice"); } if (is (GameFlags::ReGameDLL)) { - gameVersionFlags.push ("ReGameDLL"); + botRuntimeFlags.push ("ReGameDLL"); } if (is (GameFlags::HasFakePings)) { - gameVersionFlags.push ("FakePing"); + botRuntimeFlags.push ("FakePing"); } if (is (GameFlags::Metamod)) { - gameVersionFlags.push ("Metamod"); + botRuntimeFlags.push ("Metamod"); } - ctrl.msg ("\n%s v%s successfully loaded for game: Counter-Strike %s.\n\tFlags: %s.\n", product.name, product.version, gameVersionStr, gameVersionFlags.empty () ? "None" : String::join (gameVersionFlags, ", ")); + + // print if we're using sse 4.x instructions + if (cpuflags.sse41 || cpuflags.sse42 || cpuflags.neon) { + Array simdLevels {}; + + if (cpuflags.sse41) { + simdLevels.push ("4.1"); + } + if (cpuflags.sse42) { + simdLevels.push ("4.2"); + } + if (cpuflags.neon) { + simdLevels.push ("NEON"); + } + botRuntimeFlags.push (strings.format ("SIMD: %s", String::join (simdLevels, " & "))); + } + ctrl.msg ("\n%s v%s successfully loaded for game: Counter-Strike %s.\n\tFlags: %s.\n", product.name, product.version, gameVersionStr, botRuntimeFlags.empty () ? "None" : String::join (botRuntimeFlags, ", ")); } void LightMeasure::initializeLightstyles () { @@ -1160,7 +1176,7 @@ void LightMeasure::updateLight (int style, char *value) { strings.copy (m_lightstyle[style].map, value, copyLimit); m_lightstyle[style].map[copyLimit] = kNullChar; - m_lightstyle[style].length = static_cast (strlen (m_lightstyle[style].map)); + m_lightstyle[style].length = static_cast (cr::strlen (m_lightstyle[style].map)); } template bool LightMeasure::recursiveLightPoint (const M *node, const Vector &start, const Vector &end) { diff --git a/src/graph.cpp b/src/graph.cpp index 84a9729..ba8bf56 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -1274,7 +1274,7 @@ void BotGraph::calculatePathRadius (int index) { if (tr.flFraction < 1.0f) { game.testLine (radiusStart, radiusEnd, TraceIgnore::Monsters, nullptr, &tr); - if (tr.pHit && strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0) { + if (tr.pHit && cr::strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0) { path.radius = 0.0f; wayBlocked = true; @@ -1493,7 +1493,7 @@ bool BotGraph::convertOldFormat () { return false; } - if (strncmp (header.header, kPodbotMagic, cr::bufsize (kPodbotMagic)) == 0) { + if (cr::strncmp (header.header, kPodbotMagic, cr::bufsize (kPodbotMagic)) == 0) { if (header.fileVersion != StorageVersion::Podbot) { return false; } @@ -1572,7 +1572,7 @@ bool BotGraph::loadGraphData () { addToBucket (path.origin, path.number); } - if ((outOptions & StorageOption::Official) || strncmp (exten.author, "official", 8) == 0 || strlen (exten.author) < 2) { + if ((outOptions & StorageOption::Official) || cr::strncmp (exten.author, "official", 8) == 0 || cr::strlen (exten.author) < 2) { m_graphAuthor.assign (product.name); } else { @@ -1727,7 +1727,7 @@ bool BotGraph::isNodeReacheableEx (const Vector &src, const Vector &destination, // check if we go through a func_illusionary, in which case return false game.testHull (src, destination, TraceIgnore::Monsters, head_hull, m_editor, &tr); - if (tr.pHit && strcmp ("func_illusionary", tr.pHit->v.classname.chars ()) == 0) { + if (tr.pHit && cr::strcmp ("func_illusionary", tr.pHit->v.classname.chars ()) == 0) { return false; // don't add pathnodes through func_illusionaries } @@ -1735,9 +1735,9 @@ bool BotGraph::isNodeReacheableEx (const Vector &src, const Vector &destination, game.testLine (src, destination, TraceIgnore::Monsters, m_editor, &tr); // if node is visible from current position (even behind head)... - if (tr.pHit && (tr.flFraction >= 1.0f || strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0)) { + if (tr.pHit && (tr.flFraction >= 1.0f || cr::strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0)) { // if it's a door check if nothing blocks behind - if (strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0) { + if (cr::strncmp ("func_door", tr.pHit->v.classname.chars (), 9) == 0) { game.testLine (tr.vecEndPos, destination, TraceIgnore::Monsters, tr.pHit, &tr); if (tr.flFraction < 1.0f) { diff --git a/src/linkage.cpp b/src/linkage.cpp index ac3fe3e..68b901b 100644 --- a/src/linkage.cpp +++ b/src/linkage.cpp @@ -154,7 +154,7 @@ CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int) { // the server for incoming clients. // check if this client is the listen server client - if (strcmp (addr, "loopback") == 0) { + if (cr::strcmp (addr, "loopback") == 0) { game.setLocalEntity (ent); // save the edict of the listen server client... // if not dedicated set the default editor for graph @@ -472,7 +472,7 @@ CR_LINKAGE_C int GetEngineFunctions (enginefuncs_t *table, int *) { if (game.is (GameFlags::Legacy)) { table->pfnFindEntityByString = [] (edict_t *edictStartSearchAfter, const char *field, const char *value) { // round starts in counter-strike 1.5 - if (strcmp (value, "info_map_parameters") == 0) { + if (cr::strcmp (value, "info_map_parameters") == 0) { bots.initRound (); } @@ -891,6 +891,9 @@ DLL_GIVEFNPTRSTODLL GiveFnptrsToDll (enginefuncs_t *table, globalvars_t *glob) { // such if necessary. Nothing really bot-related is done in this function. The actual bot // initialization stuff will be done later, when we'll be certain to have a multilayer game. + // initialize simd-string functions + simdstring.init (); + // get the engine functions from the game... memcpy (&engfuncs, table, sizeof (enginefuncs_t)); globals = glob; @@ -968,7 +971,7 @@ SharedLibrary::Func EntityLinkage::lookup (SharedLibrary::Handle module, const c return m_dlsym (handle, function); }; - if (ents.needsBypass () && !strcmp (function, "CreateInterface")) { + if (ents.needsBypass () && !cr::strcmp (function, "CreateInterface")) { ents.setPaused (true); auto ret = resolve (module); diff --git a/src/manager.cpp b/src/manager.cpp index 37928de..639ba5a 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -1667,7 +1667,7 @@ void BotManager::captureChatRadio (const char *cmd, const char *arg, edict_t *en bool alive = util.isAlive (ent); int team = -1; - if (strcmp (cmd, "say_team") == 0) { + if (cr::strcmp (cmd, "say_team") == 0) { team = game.getTeam (ent); } @@ -1691,7 +1691,7 @@ void BotManager::captureChatRadio (const char *cmd, const char *arg, edict_t *en auto &target = util.getClient (game.indexOfPlayer (ent)); // check if this player alive, and issue something - if ((target.flags & ClientFlags::Alive) && target.radio != 0 && strncmp (cmd, "menuselect", 10) == 0) { + if ((target.flags & ClientFlags::Alive) && target.radio != 0 && cr::strncmp (cmd, "menuselect", 10) == 0) { int radioCommand = atoi (arg); if (radioCommand != 0) { @@ -1711,7 +1711,7 @@ void BotManager::captureChatRadio (const char *cmd, const char *arg, edict_t *en } target.radio = 0; } - else if (strncmp (cmd, "radio", 5) == 0) { + else if (cr::strncmp (cmd, "radio", 5) == 0) { target.radio = atoi (&cmd[5]); } } @@ -1771,22 +1771,22 @@ void BotManager::updateInterestingEntities () { auto classname = e->v.classname.chars (); // search for grenades, weaponboxes, weapons, items and armoury entities - if (strncmp ("weaponbox", classname, 9) == 0 || strncmp ("grenade", classname, 7) == 0 || util.isItem (e) || strncmp ("armoury", classname, 7) == 0) { + if (cr::strncmp ("weaponbox", classname, 9) == 0 || cr::strncmp ("grenade", classname, 7) == 0 || util.isItem (e) || cr::strncmp ("armoury", classname, 7) == 0) { m_interestingEntities.push (e); } // pickup some csdm stuff if we're running csdm - if (game.mapIs (MapFlags::HostageRescue) && strncmp ("hostage", classname, 7) == 0) { + if (game.mapIs (MapFlags::HostageRescue) && cr::strncmp ("hostage", classname, 7) == 0) { m_interestingEntities.push (e); } // add buttons - if (game.mapIs (MapFlags::HasButtons) && strncmp ("func_button", classname, 11) == 0) { + if (game.mapIs (MapFlags::HasButtons) && cr::strncmp ("func_button", classname, 11) == 0) { m_interestingEntities.push (e); } // pickup some csdm stuff if we're running csdm - if (game.is (GameFlags::CSDM) && strncmp ("csdm", classname, 4) == 0) { + if (game.is (GameFlags::CSDM) && cr::strncmp ("csdm", classname, 4) == 0) { m_interestingEntities.push (e); } diff --git a/src/navigate.cpp b/src/navigate.cpp index f1cdfc2..3d92586 100644 --- a/src/navigate.cpp +++ b/src/navigate.cpp @@ -990,7 +990,7 @@ bool Bot::updateNavigation () { if (game.mapIs (MapFlags::HasDoors)) { game.testLine (pev->origin, m_pathOrigin, TraceIgnore::Monsters, ent (), &tr); - if (!game.isNullEntity (tr.pHit) && game.isNullEntity (m_liftEntity) && strncmp (tr.pHit->v.classname.chars (), "func_door", 9) == 0) { + if (!game.isNullEntity (tr.pHit) && game.isNullEntity (m_liftEntity) && cr::strncmp (tr.pHit->v.classname.chars (), "func_door", 9) == 0) { // if the door is near enough... if (pev->origin.distanceSq (game.getEntityOrigin (tr.pHit)) < 2500.0f) { ignoreCollision (); // don't consider being stuck @@ -1169,7 +1169,7 @@ bool Bot::updateLiftHandling () { // trace line to door game.testLine (pev->origin, m_pathOrigin, TraceIgnore::Everything, ent (), &tr); - if (tr.flFraction < 1.0f && tr.pHit && strcmp (tr.pHit->v.classname.chars (), "func_door") == 0 && (m_liftState == LiftState::None || m_liftState == LiftState::WaitingFor || m_liftState == LiftState::LookingButtonOutside) && pev->groundentity != tr.pHit) { + if (tr.flFraction < 1.0f && tr.pHit && cr::strcmp (tr.pHit->v.classname.chars (), "func_door") == 0 && (m_liftState == LiftState::None || m_liftState == LiftState::WaitingFor || m_liftState == LiftState::LookingButtonOutside) && pev->groundentity != tr.pHit) { if (m_liftState == LiftState::None) { m_liftState = LiftState::LookingButtonOutside; m_liftUsageTime = game.time () + 7.0f; @@ -1181,7 +1181,7 @@ bool Bot::updateLiftHandling () { game.testLine (m_path->origin, m_pathOrigin + Vector (0.0f, 0.0f, -50.0f), TraceIgnore::Everything, ent (), &tr); // if trace result shows us that it is a lift - if (!game.isNullEntity (tr.pHit) && !m_pathWalk.empty () && (strcmp (tr.pHit->v.classname.chars (), "func_door") == 0 || strcmp (tr.pHit->v.classname.chars (), "func_plat") == 0 || strcmp (tr.pHit->v.classname.chars (), "func_train") == 0) && !liftClosedDoorExists) { + if (!game.isNullEntity (tr.pHit) && !m_pathWalk.empty () && (cr::strcmp (tr.pHit->v.classname.chars (), "func_door") == 0 || cr::strcmp (tr.pHit->v.classname.chars (), "func_plat") == 0 || cr::strcmp (tr.pHit->v.classname.chars (), "func_train") == 0) && !liftClosedDoorExists) { if ((m_liftState == LiftState::None || m_liftState == LiftState::WaitingFor || m_liftState == LiftState::LookingButtonOutside) && cr::fzero (tr.pHit->v.velocity.z)) { if (cr::abs (pev->origin.z - tr.vecEndPos.z) < 70.0f) { m_liftEntity = tr.pHit; @@ -1203,7 +1203,7 @@ bool Bot::updateLiftHandling () { if (graph.exists (nextNode) && (graph[nextNode].flags & NodeFlag::Lift)) { game.testLine (m_path->origin, graph[nextNode].origin, TraceIgnore::Everything, ent (), &tr); - if (!game.isNullEntity (tr.pHit) && (strcmp (tr.pHit->v.classname.chars (), "func_door") == 0 || strcmp (tr.pHit->v.classname.chars (), "func_plat") == 0 || strcmp (tr.pHit->v.classname.chars (), "func_train") == 0)) { + if (!game.isNullEntity (tr.pHit) && (cr::strcmp (tr.pHit->v.classname.chars (), "func_door") == 0 || cr::strcmp (tr.pHit->v.classname.chars (), "func_plat") == 0 || cr::strcmp (tr.pHit->v.classname.chars (), "func_train") == 0)) { m_liftEntity = tr.pHit; } } @@ -2353,7 +2353,7 @@ bool Bot::cantMoveForward (const Vector &normal, TraceResult *tr) { if (!game.mapIs (MapFlags::HasDoors)) { return false; } - return result->flFraction < 1.0f && strncmp ("func_door", result->pHit->v.classname.chars (), 9) != 0; + return result->flFraction < 1.0f && cr::strncmp ("func_door", result->pHit->v.classname.chars (), 9) != 0; }; // trace from the bot's eyes straight forward... @@ -2361,7 +2361,7 @@ bool Bot::cantMoveForward (const Vector &normal, TraceResult *tr) { // check if the trace hit something... if (tr->flFraction < 1.0f) { - if (game.mapIs (MapFlags::HasDoors) && strncmp ("func_door", tr->pHit->v.classname.chars (), 9) == 0) { + if (game.mapIs (MapFlags::HasDoors) && cr::strncmp ("func_door", tr->pHit->v.classname.chars (), 9) == 0) { return false; } return true; // bot's head will hit something @@ -2712,7 +2712,7 @@ bool Bot::isBlockedLeft () { game.testLine (pev->origin, forward * direction - right * 48.0f, TraceIgnore::Monsters, ent (), &tr); // check if the trace hit something... - if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && tr.pHit && strncmp ("func_door", tr.pHit->v.classname.chars (), 9) != 0) { + if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && tr.pHit && cr::strncmp ("func_door", tr.pHit->v.classname.chars (), 9) != 0) { return true; // bot's body will hit something } return false; @@ -2732,7 +2732,7 @@ bool Bot::isBlockedRight () { game.testLine (pev->origin, pev->origin + forward * direction + right * 48.0f, TraceIgnore::Monsters, ent (), &tr); // check if the trace hit something... - if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && tr.pHit && strncmp ("func_door", tr.pHit->v.classname.chars (), 9) != 0) { + if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && tr.pHit && cr::strncmp ("func_door", tr.pHit->v.classname.chars (), 9) != 0) { return true; // bot's body will hit something } return false; diff --git a/src/storage.cpp b/src/storage.cpp index 7f96b81..f1acea4 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -166,7 +166,7 @@ template bool BotStorage::load (SmallArray &data, ExtenHeader * if (extenSize <= actuallyRead) { // write modified by, only if the name is different - if (!strings.isEmpty (extenHeader.author) && strncmp (extenHeader.author, exten->modified, cr::bufsize (extenHeader.author)) != 0) { + if (!strings.isEmpty (extenHeader.author) && cr::strncmp (extenHeader.author, exten->modified, cr::bufsize (extenHeader.author)) != 0) { strings.copy (extenHeader.modified, exten->modified, cr::bufsize (exten->modified)); } } diff --git a/src/support.cpp b/src/support.cpp index cf662b2..195c90c 100644 --- a/src/support.cpp +++ b/src/support.cpp @@ -204,7 +204,7 @@ bool BotSupport::isMonster (edict_t *ent) { return false; } - if (strncmp ("hostage", ent->v.classname.chars (), 7) == 0) { + if (cr::strncmp ("hostage", ent->v.classname.chars (), 7) == 0) { return false; } @@ -538,7 +538,7 @@ int32_t BotSupport::sendTo (int socket, const void *message, size_t length, int constexpr int32_t packetLength = 5; // player replies response - if (length > packetLength && memcmp (packet, "\xff\xff\xff\xff", packetLength - 1) == 0) { + if (length > packetLength && cr::memcmp (packet, "\xff\xff\xff\xff", packetLength - 1) == 0) { if (packet[4] == 'D') { QueryBuffer buffer { packet, length, packetLength }; auto count = buffer.read (); diff --git a/src/tasks.cpp b/src/tasks.cpp index f24ddf9..88c794e 100644 --- a/src/tasks.cpp +++ b/src/tasks.cpp @@ -1438,7 +1438,7 @@ void Bot::pickupItem_ () { auto &info = conf.getWeapons (); for (index = 0; index < 7; ++index) { - if (strcmp (info[index].model, m_pickupItem->v.model.chars (9)) == 0) { + if (cr::strcmp (info[index].model, m_pickupItem->v.model.chars (9)) == 0) { break; } } @@ -1562,7 +1562,7 @@ void Bot::pickupItem_ () { game.searchEntities (pev->origin, 768.0f, [&] (edict_t *ent) { auto classname = ent->v.classname.chars (); - if (strncmp ("hostage_entity", classname, 14) != 0 && strncmp ("monster_scientist", classname, 17) != 0) { + if (cr::strncmp ("hostage_entity", classname, 14) != 0 && cr::strncmp ("monster_scientist", classname, 17) != 0) { return EntitySearchResult::Continue; } diff --git a/src/vision.cpp b/src/vision.cpp index 19f4c9d..76b844e 100644 --- a/src/vision.cpp +++ b/src/vision.cpp @@ -43,7 +43,7 @@ bool Bot::seesItem (const Vector &destination, const char *classname) { // check if line of sight to object is not blocked (i.e. visible) if (tr.flFraction < 1.0f && tr.pHit && !tr.fStartSolid) { - return strcmp (tr.pHit->v.classname.chars (), classname) == 0; + return cr::strcmp (tr.pHit->v.classname.chars (), classname) == 0; } return true; } diff --git a/vc/yapb.vcxproj b/vc/yapb.vcxproj index a2addf8..f1ba187 100644 --- a/vc/yapb.vcxproj +++ b/vc/yapb.vcxproj @@ -23,6 +23,7 @@ + @@ -32,7 +33,7 @@ - + diff --git a/vc/yapb.vcxproj.filters b/vc/yapb.vcxproj.filters index 6950d47..462bbc9 100644 --- a/vc/yapb.vcxproj.filters +++ b/vc/yapb.vcxproj.filters @@ -93,7 +93,7 @@ inc\ext\crlib - + inc\ext\crlib @@ -165,6 +165,9 @@ inc\ext\linkage + + inc\ext\crlib +