diff --git a/.github/workflows/gh-actions-pr.yml b/.github/workflows/gh-actions-pr.yml index 1af5de15f1..00a6ac6978 100644 --- a/.github/workflows/gh-actions-pr.yml +++ b/.github/workflows/gh-actions-pr.yml @@ -46,11 +46,11 @@ jobs: OpenGL_GL_PREFERENCE: 'GLVND' ENABLE_PIE: 'OFF' allow_failure: false - - FROM: 'opensuse/leap:15.6' - COMPILER: 'clang' - OpenGL_GL_PREFERENCE: 'LEGACY' - ENABLE_PIE: 'ON' - allow_failure: true + #- FROM: 'opensuse/leap:15.6' + # COMPILER: 'clang' + # OpenGL_GL_PREFERENCE: 'LEGACY' + # ENABLE_PIE: 'ON' + # allow_failure: true - FROM: 'fedora:41' COMPILER: 'clang' OpenGL_GL_PREFERENCE: 'LEGACY' @@ -71,11 +71,11 @@ jobs: OpenGL_GL_PREFERENCE: 'GLVND' ENABLE_PIE: 'ON' allow_failure: false - - FROM: 'rockylinux_rockylinux:9.5' - COMPILER: 'gcc' - OpenGL_GL_PREFERENCE: 'GLVND' - ENABLE_PIE: 'ON' - allow_failure: true + #- FROM: 'rockylinux_rockylinux:9.5' + # COMPILER: 'gcc' + # OpenGL_GL_PREFERENCE: 'GLVND' + # ENABLE_PIE: 'ON' + # allow_failure: true # Disabled until the build can be fixed #- FROM: 'rockylinux_rockylinux:8.10' # COMPILER: 'clang' diff --git a/engine/src/cmd/basecomputer.cpp b/engine/src/cmd/basecomputer.cpp index cecd498967..a388bef9fb 100644 --- a/engine/src/cmd/basecomputer.cpp +++ b/engine/src/cmd/basecomputer.cpp @@ -1,5 +1,7 @@ /* - * Copyright (C) 2001-2022 Daniel Horn, Mike Byron, pyramid3d, Stephen G. Tuggy, + * basecomputer.cpp + * + * Copyright (C) 2001-2025 Daniel Horn, Mike Byron, pyramid3d, Stephen G. Tuggy, * and other Vega Strike contributors. * * https://github.com/vegastrike/Vega-Strike-Engine-Source @@ -13,7 +15,7 @@ * * Vega Strike is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -114,8 +116,8 @@ std::vector getWeapFilterVec() { std::vector weapfiltervec = getWeapFilterVec(); bool upgradeNotAddedToCargo(std::string category) { - for (unsigned int i = 0; i < weapfiltervec.size(); ++i) { - if (weapfiltervec[i].find(category) == 0) { + for (const auto & i : weapfiltervec) { + if (i.find(category) == 0) { return true; } } @@ -527,7 +529,7 @@ void BaseComputer::constructControls(void) { return; } - if (m_displayModes.size() != 1 || m_displayModes[0] != NETWORK) { + if (m_displayModes.size() != 1 || m_displayModes.at(0) != NETWORK) { //Base info title. StaticDisplay *baseTitle = (StaticDisplay*)getControl(controls["baseTitle"]); window()->addControl(baseTitle); @@ -974,7 +976,7 @@ void BaseComputer::constructControls(void) { //GameMenu::createNetworkControls( netJoinGroup, &base_keyboard_queue ); - if (m_displayModes.size() != 1 || m_displayModes[0] != NETWORK) { + if (m_displayModes.size() != 1 || m_displayModes.at(0) != NETWORK) { NewButton *loadsave = new NewButton; loadsave->setRect(Rect(.7, -.9, .25, .1)); loadsave->setColor(GFXColor(1, .5, .1, .1)); @@ -991,7 +993,7 @@ void BaseComputer::constructControls(void) { loadsave->setCommand("ShowOptionsMenu"); networkGroup->addChild(loadsave); } - if ((m_displayModes.size() == 1 && m_displayModes[0] == NETWORK)) { + if ((m_displayModes.size() == 1 && m_displayModes.at(0) == NETWORK)) { NewButton *quit = new NewButton; quit->setRect(Rect(-.95, -.9, .3, .1)); quit->setColor(GFXColor(.8, 1, .1, .1)); @@ -1258,8 +1260,7 @@ void BaseComputer::createModeButtons(void) { if (m_displayModes.size() > 1) { //Create a button for each display mode, copying the original button. Rect rect = originalButton->rect(); - for (unsigned int i = 0; i < m_displayModes.size(); i++) { - DisplayMode mode = m_displayModes[i]; + for (const auto mode : m_displayModes) { NewButton *newButton = new NewButton(*originalButton); newButton->setRect(rect); newButton->setLabel(modeInfo[mode].button); @@ -1820,7 +1821,7 @@ void BaseComputer::updateTransactionControlsForSelection(TransactionList *tlist) //The selected item. const PickerCell *cell = tlist->picker->selectedCell(); assert(cell != NULL); - Cargo &item = tlist->masterList[cell->tag()].cargo; + Cargo &item = tlist->masterList.at(cell->tag()).cargo; bool damaged_mode = false; if (!isTransactionOK(item, tlist->transaction)) { //We can't do the transaction. so hide the transaction button. @@ -2325,7 +2326,7 @@ void BaseComputer::loadListPicker(TransactionList &tlist, string currentCategory = "--ILLEGAL CATEGORY--"; //Current category we are adding cells to. SimplePickerCell *parentCell = NULL; //Place to add new items. NULL = Add to picker. for (size_t i = 0; i < tlist.masterList.size(); i++) { - Cargo &item = tlist.masterList[i].cargo; + Cargo &item = tlist.masterList.at(i).cargo; std::string icategory = getDisplayCategory(item); if (icategory != currentCategory) { //Create new cell(s) for the new category. @@ -2481,12 +2482,12 @@ void BaseComputer::loadMasterList(Unit *un, bool invfilter = true; size_t vecindex; for (vecindex = 0; !filter && (vecindex < filtervec.size()); vecindex++) { - if (un->GetCargo(i).GetCategory().find(filtervec[vecindex]) != string::npos) { + if (un->GetCargo(i).GetCategory().find(filtervec.at(vecindex)) != string::npos) { filter = true; } } for (vecindex = 0; invfilter && (vecindex < invfiltervec.size()); vecindex++) { - if (un->GetCargo(i).GetCategory().find(invfiltervec[vecindex]) != string::npos) { + if (un->GetCargo(i).GetCategory().find(invfiltervec.at(vecindex)) != string::npos) { invfilter = false; } } @@ -2511,7 +2512,7 @@ Cargo *BaseComputer::selectedItem(void) { assert(m_selectedList->picker); PickerCell *cell = m_selectedList->picker->selectedCell(); if (cell) { - result = &m_selectedList->masterList[cell->tag()].cargo; + result = &m_selectedList->masterList.at(cell->tag()).cargo; } } return result; @@ -2923,7 +2924,7 @@ void BaseComputer::loadMissionsMasterList(TransactionList &tlist) { } //Sort the list. Better for display, easier to compile into categories, etc. std::sort(tlist.masterList.begin(), tlist.masterList.end(), CargoColorSort()); - if (active_missions.size()) { + if (!active_missions.empty()) { for (unsigned int i = 1; i < active_missions.size(); ++i) { CargoColor amission; amission.cargo.SetName(XMLSupport::tostring(i) + " " + active_missions[i]->mission_name); @@ -2933,9 +2934,9 @@ void BaseComputer::loadMissionsMasterList(TransactionList &tlist) { amission.cargo.SetDescription("Objectives\\"); for (unsigned int j = 0; j < active_missions[i]->objectives.size(); ++j) { amission.cargo.SetDescription( - amission.cargo.GetDescription() + active_missions[i]->objectives[j].objective + ": " + amission.cargo.GetDescription() + active_missions[i]->objectives.at(j).objective + ": " + XMLSupport::tostring((int) (100 - * active_missions[i]->objectives[j].completeness)) + * active_missions[i]->objectives.at(j).completeness)) + "%\\"); } amission.color = DEFAULT_UPGRADE_COLOR(); @@ -3098,7 +3099,7 @@ void BaseComputer::loadSellUpgradeControls(void) { if (clearDowngrades) { std::set downgradeMap = GetListOfDowngrades(); for (unsigned int i = 0; i < tlist.masterList.size(); ++i) { - if (downgradeMap.find(tlist.masterList[i].cargo.GetName()) == downgradeMap.end()) { + if (downgradeMap.find(tlist.masterList.at(i).cargo.GetName()) == downgradeMap.end()) { tlist.masterList.erase(tlist.masterList.begin() + i); i--; } @@ -3427,15 +3428,15 @@ void BaseComputer::BuyUpgradeOperation::selectMount(void) { GFXColor mountColor = MOUNT_POINT_NO_SELECT(); string mountName; string ammoexp; - if (playerUnit->mounts[i].status == Mount::ACTIVE || playerUnit->mounts[i].status == Mount::INACTIVE) { - mountName = tostring(i + 1) + " " + playerUnit->mounts[i].type->name; + if (playerUnit->mounts.at(i).status == Mount::ACTIVE || playerUnit->mounts.at(i).status == Mount::INACTIVE) { + mountName = tostring(i + 1) + " " + playerUnit->mounts.at(i).type->name; ammoexp = - (playerUnit->mounts[i].ammo == -1) ? string("") : string((" ammo: " - + tostring(playerUnit->mounts[i].ammo))); + (playerUnit->mounts.at(i).ammo == -1) ? string("") : string((" ammo: " + + tostring(playerUnit->mounts.at(i).ammo))); mountName += ammoexp; mountColor = MOUNT_POINT_FULL(); } else { - const std::string temp = getMountSizeString(playerUnit->mounts[i].size); + const std::string temp = getMountSizeString(playerUnit->mounts.at(i).size); mountName = tostring(i + 1) + " (Empty) " + temp.c_str(); mountColor = MOUNT_POINT_EMPTY(); } @@ -3511,7 +3512,7 @@ void BaseComputer::BuyUpgradeOperation::concludeTransaction(void) { } if (m_newPart->mounts.size() == 0) { break; - } else if (m_newPart->mounts[0].ammo <= 0) { + } else if (m_newPart->mounts.at(0).ammo <= 0) { break; } numleft = basecargoassets(baseUnit, m_part.GetName()); @@ -3557,7 +3558,7 @@ void BaseComputer::SellUpgradeOperation::start(void) { } } -//Try to match a mounted waepon name with the cargo name. +//Try to match a mounted weapon name with the cargo name. //Returns true if they are the same. static bool matchCargoToWeapon(const std::string &cargoName, const std::string &weaponName) { //Weapon names have capitalized words, and no spaces between the words. @@ -3619,20 +3620,20 @@ void BaseComputer::SellUpgradeOperation::selectMount(void) { //Get the name. string mountName; - if (playerUnit->mounts[i].status == Mount::ACTIVE || playerUnit->mounts[i].status == Mount::INACTIVE) { + if (playerUnit->mounts.at(i).status == Mount::ACTIVE || playerUnit->mounts.at(i).status == Mount::INACTIVE) { //Something is mounted here. - const std::string unitName = playerUnit->mounts[i].type->name; + const std::string unitName = playerUnit->mounts.at(i).type->name; const Unit *partUnit = UnitConstCache::getCachedConst(StringIntKey(m_part.GetName(), FactionUtil::GetUpgradeFaction())); string ammoexp; mountName = tostring(i + 1) + " " + unitName.c_str(); ammoexp = - (playerUnit->mounts[i].ammo == -1) ? string("") : string((" ammo: " - + tostring(playerUnit->mounts[i].ammo))); + (playerUnit->mounts.at(i).ammo == -1) ? string("") : string((" ammo: " + + tostring(playerUnit->mounts.at(i).ammo))); mountName += ammoexp; if (partUnit) { if (partUnit->getNumMounts()) { - if (partUnit->mounts[0].type == playerUnit->mounts[i].type) { + if (partUnit->mounts.at(0).type == playerUnit->mounts.at(i).type) { selectable = true; selectableCount++; mount = i; @@ -3645,7 +3646,7 @@ void BaseComputer::SellUpgradeOperation::selectMount(void) { } } else { //Nothing at this mount point. - const std::string temp = getMountSizeString(playerUnit->mounts[i].size); + const std::string temp = getMountSizeString(playerUnit->mounts.at(i).size); mountName = tostring(i + 1) + " (Empty) " + temp.c_str(); } //Now we add the cell. Note that "selectable" is stored in the tag property. @@ -3942,7 +3943,7 @@ string buildUpgradeDescription(Cargo &item) { const std::string key = item.GetName() + "__upgrades"; PyObject* args = PyTuple_Pack(1, PyUnicode_FromString(key.c_str())); const std::string text = GetString("get_upgrade_info", "upgrade_view", - "python/base_computer/upgrade_view.py", args); + "upgrade_view.py", args); return text; } @@ -3957,9 +3958,9 @@ class PriceSort { bool operator()(size_t a, size_t b) { if (reverse) { - return price[a] > price[b]; + return price.at(a) > price.at(b); } else { - return price[a] < price[b]; + return price.at(a) < price.at(b); } } }; @@ -4015,7 +4016,7 @@ void trackPrice(int whichplayer, const Cargo &item, float price, const string &s indices.resize(mymin(prices.size(), locs.size())); { for (size_t i = 0; i < indices.size(); ++i) { - indices[i] = i; + indices.at(i) = i; } } @@ -4028,8 +4029,8 @@ void trackPrice(int whichplayer, const Cargo &item, float price, const string &s newprices.reserve(indices.size()); { for (size_t i = 0; i < indices.size() && i < toprank; ++i) { - newlocs.push_back(locs[indices[i]]); - newprices.push_back(prices[indices[i]]); + newlocs.push_back(locs[indices.at(i)]); + newprices.push_back(prices[indices.at(i)]); } } @@ -4045,7 +4046,7 @@ void trackPrice(int whichplayer, const Cargo &item, float price, const string &s // Limited lifetime iterator (points to invalid data after save data manipulation) const vector &recordedLowestLocs = getStringList(whichplayer, lolock); const vector &recordedLowestPrices = getSaveData(whichplayer, lopricek); - vector::const_iterator prev = std::find( + auto prev = std::find( recordedLowestLocs.begin(), recordedLowestLocs.end(), locname); @@ -4070,7 +4071,7 @@ void trackPrice(int whichplayer, const Cargo &item, float price, const string &s indices.resize(mymin(prices.size(), locs.size())); { for (size_t i = 0; i < indices.size(); ++i) { - indices[i] = i; + indices.at(i) = i; } } @@ -4083,8 +4084,8 @@ void trackPrice(int whichplayer, const Cargo &item, float price, const string &s newprices.reserve(indices.size()); { for (size_t i = 0; i < indices.size() && i < toprank; ++i) { - newlocs.push_back(locs[indices[i]]); - newprices.push_back(prices[indices[i]]); + newlocs.push_back(locs.at(indices.at(i))); + newprices.push_back(prices.at(indices.at(i))); } } @@ -4109,7 +4110,7 @@ void trackPrice(int whichplayer, const Cargo &item, float price, const string &s VS_LOG(info, (boost::format(" highest locs: (%1%)") % recordedHighestLocs.size())); { for (size_t i = 0; i < recordedHighestLocs.size(); ++i) { - VS_LOG(info, (boost::format(" %1% : %2%") % i % recordedHighestLocs[i])); + VS_LOG(info, (boost::format(" %1% : %2%") % i % recordedHighestLocs.at(i))); } } @@ -4117,14 +4118,14 @@ void trackPrice(int whichplayer, const Cargo &item, float price, const string &s { for (size_t i = 0; i < recordedHighestPrices.size(); ++i) { // POSIX-printf style - VS_LOG(info, (boost::format(" %1$d : %2$.2f") % i % recordedHighestPrices[i])); + VS_LOG(info, (boost::format(" %1$d : %2$.2f") % i % recordedHighestPrices.at(i))); } } VS_LOG(info, (boost::format(" lowest locs: (%1%)") % recordedLowestLocs.size())); { for (size_t i = 0; i < recordedLowestLocs.size(); ++i) { - VS_LOG(info, (boost::format(" %1% : %2%") % i % recordedLowestLocs[i])); + VS_LOG(info, (boost::format(" %1% : %2%") % i % recordedLowestLocs.at(i))); } } @@ -4132,7 +4133,7 @@ void trackPrice(int whichplayer, const Cargo &item, float price, const string &s { for (size_t i = 0; i < recordedLowestPrices.size(); ++i) { // POSIX-printf style - VS_LOG(info, (boost::format(" %1$d : %2$.2f") % i % recordedLowestPrices[i])); + VS_LOG(info, (boost::format(" %1$d : %2$.2f") % i % recordedLowestPrices.at(i))); } } @@ -4143,8 +4144,8 @@ void trackPrice(int whichplayer, const Cargo &item, float price, const string &s { for (size_t i = 0; i < recordedHighestPrices.size(); ++i) { string &text = highest[i]; - PRETTY_ADD("", recordedHighestPrices[i], 2); - text += " (at " + recordedHighestLocs[i] + ")"; + PRETTY_ADD("", recordedHighestPrices.at(i), 2); + text += " (at " + recordedHighestLocs.at(i) + ")"; VS_LOG(info, (boost::format("Highest item %1%") % text)); } @@ -4155,8 +4156,8 @@ void trackPrice(int whichplayer, const Cargo &item, float price, const string &s { for (size_t i = 0; i < recordedLowestPrices.size(); ++i) { string &text = lowest[i]; - PRETTY_ADD("", recordedLowestPrices[i], 2); - text += " (at " + recordedLowestLocs[i] + ")"; + PRETTY_ADD("", recordedLowestPrices.at(i), 2); + text += " (at " + recordedLowestLocs.at(i) + ")"; VS_LOG(info, (boost::format("Lowest item %1%") % text)); } @@ -4500,7 +4501,7 @@ bool BaseComputer::showPlayerInfo(const EventCommandId &command, Control *contro PyObject* args = PyTuple_Pack(3, names_list.ptr(), relations_list.ptr(), kills_list.ptr()); const std::string text = GetString("get_player_info", "player_info", - "python/base_computer/player_info.py", args); + "player_info.py", args); //Put this in the description. StaticDisplay *desc = static_cast< StaticDisplay * > ( window()->findControlById("Description")); @@ -4653,7 +4654,7 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C if (!mode) { std::map ship_map = playerUnit->UnitToMap(); text += GetString("get_ship_description", "ship_view", - "python/base_computer/ship_view.py", + "ship_view.py", ship_map); } if (mode && replacement_mode == 2 && playerUnit->getMass() != blankUnit->getMass()) @@ -4930,7 +4931,7 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C } if (mode && MODIFIES(replacement_mode, playerUnit, blankUnit, - armor->facets[as_integer(FacetName::left_top_front)].health)) { + armor->facets.at(as_integer(FacetName::left_top_front)).health)) { switch (replacement_mode) { case 0: //Replacement or new Module text += "#n#" + prefix + statcolor + "Replaces existing armor, if any.#n#Armor damage resistance:#-c"; @@ -4948,7 +4949,7 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C } // Add Armor stats - if (mode && MODIFIES(replacement_mode, playerUnit, blankUnit, armor->facets[2].health)) { + if (mode && MODIFIES(replacement_mode, playerUnit, blankUnit, armor->facets.at(2).health)) { std::string armor_color_strings[8] = { " - Fore-starboard-high: #-c", " - Aft-starboard-high: #-c", @@ -4960,14 +4961,14 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C " - Aft-port-low: #-c" }; - int armor_indices[8] = {2, 6, 0, 4, 3, 7, 1, 5}; + int armor_indices[4] = {0, 1, 2, 3}; - for (int i = 0; i < 8; i++) { + for (int i = 0; i < 4; ++i) { PRETTY_ADDU( substatcolor + armor_color_strings[i], (mode && replacement_mode - == 2) ? 100.0 * (playerUnit->armor->facets[armor_indices[i]].health - 1) : - playerUnit->armor->facets[2].health * VSDM, + == 2) ? 100.0 * (playerUnit->armor->facets.at(armor_indices[i]).health - 1.0): + static_cast(playerUnit->armor->facets.at(2).health) * static_cast(VSDM), 0, (2 == replacement_mode) ? "%" : "MJ"); } @@ -5038,8 +5039,8 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C shield->GetMaxHealth())) { for (int i = 0; i < num_shields; i++) { PRETTY_ADDU(substatcolor + shield_strings[i], (mode && replacement_mode == 2) ? - (100.0 * (playerUnit->shield->facets[i].max_health - 1)) : - playerUnit->shield->facets[i].max_health * VSDM, 0, + (100.0 * (playerUnit->shield->facets.at(i).max_health - 1.0)) : + static_cast(playerUnit->shield->facets.at(i).max_health) * static_cast(VSDM), 0, (2 == replacement_mode) ? "%" : "MJ"); } } @@ -5097,7 +5098,7 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C bool anyweapons = false; for (int i = 0; i < playerUnit->getNumMounts(); i++) { - const WeaponInfo *wi = playerUnit->mounts[i].type; + const WeaponInfo *wi = playerUnit->mounts.at(i).type; if (wi && wi->name != "") { anyweapons = true; } @@ -5105,7 +5106,7 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C if (anyweapons) { for (int i = 0; i < playerUnit->getNumMounts(); i++) { - const WeaponInfo *wi = playerUnit->mounts[i].type; + const WeaponInfo *wi = playerUnit->mounts.at(i).type; if ((!wi) || (wi->name == "")) { continue; } else { @@ -5152,11 +5153,11 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C } //damage per second PRETTY_ADDU(statcolor + " Exit velocity: #-c", wi->speed, 0, "meters/second"); - if (playerUnit->mounts[i].ammo != -1) { + if (playerUnit->mounts.at(i).ammo != -1) { if ((as_integer(wi->size) & as_integer(MOUNT_SIZE::SPECIALMISSILE)) == 0) - PRETTY_ADD(statcolor + " Rounds remaining: #-c", playerUnit->mounts[i].ammo, 0); + PRETTY_ADD(statcolor + " Rounds remaining: #-c", playerUnit->mounts.at(i).ammo, 0); else - PRETTY_ADD(statcolor + " Rockets remaining: #-c", playerUnit->mounts[i].ammo, 0); + PRETTY_ADD(statcolor + " Rockets remaining: #-c", playerUnit->mounts.at(i).ammo, 0); } totalWeaponEnergyUsage += (wi->energy_rate / wi->Refire()); break; @@ -5172,7 +5173,7 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C text += statcolor + " Missile Lock Type: #-c#c1:.3:.3#None.#-c Inertial Guidance Only"; } - PRETTY_ADD(statcolor + " Missiles remaining: #-c", playerUnit->mounts[i].ammo, 0); + PRETTY_ADD(statcolor + " Missiles remaining: #-c", playerUnit->mounts.at(i).ammo, 0); totalWeaponEnergyUsage += (wi->energy_rate / wi->Refire()); break; case WEAPON_TYPE::BEAM: @@ -5183,8 +5184,8 @@ void showUnitStats(Unit *playerUnit, string &text, int subunitlevel, int mode, C totalWeaponDamage += wi->phase_damage; } PRETTY_ADDU(statcolor + " Beam stability: #-c", wi->stability, 2, "seconds"); - if (playerUnit->mounts[i].ammo != -1) - PRETTY_ADD(statcolor + " Shots remaining: #-c", playerUnit->mounts[i].ammo, 0); + if (playerUnit->mounts.at(i).ammo != -1) + PRETTY_ADD(statcolor + " Shots remaining: #-c", playerUnit->mounts.at(i).ammo, 0); totalWeaponEnergyUsage += wi->energy_rate; break; default: diff --git a/engine/src/cmd/collide2/CSopcodecollider.cpp b/engine/src/cmd/collide2/CSopcodecollider.cpp index 255f5db051..05625871a4 100644 --- a/engine/src/cmd/collide2/CSopcodecollider.cpp +++ b/engine/src/cmd/collide2/CSopcodecollider.cpp @@ -26,7 +26,7 @@ /* * Copyright (C) 2020 pyramid3d - * Copyright (C) 2020-2022 Stephen G. Tuggy + * Copyright (C) 2020-2025 Stephen G. Tuggy */ @@ -40,9 +40,8 @@ #undef _X using namespace Opcode; -using namespace VegaStrike; -static vs_vector pairs; +static std::vector pairs; csOPCODECollider::csOPCODECollider(const std::vector &polygons) { m_pCollisionModel = nullptr; @@ -70,8 +69,8 @@ void csOPCODECollider::GeometryInitialize(const std::vector &polyg OPCODECREATE OPCC; unsigned int tri_count = 0; std::vector::size_type vert_count = 0; - for (std::vector::size_type i = 0; i < polygons.size(); ++i) { - vert_count += polygons.at(i).v.size(); + for (const auto & polygon : polygons) { + vert_count += polygon.v.size(); } tri_count = vert_count / 3; if (tri_count) { @@ -88,11 +87,11 @@ void csOPCODECollider::GeometryInitialize(const std::vector &polyg /* Copies the Vector's in mesh_polygon to Point's in vertholder. * This sucks but i dont see anyway around it */ - for (std::vector::size_type i = 0; i < polygons.size(); ++i) { - const mesh_polygon *p = (&polygons.at(i)); - for (std::vector::size_type j = 0; j < p->v.size(); ++j) { - vertholder[last++].Set(p->v[j].i, p->v[j].j, p->v[j].k); - tmp.AddBoundingVertex(p->v[j]); + for (const auto & polygon : polygons) { + const mesh_polygon *p = (&polygon); + for (const auto & j : p->v) { + vertholder[last++].Set(j.i, j.j, j.k); + tmp.AddBoundingVertex(j); } } radius = max3(tmp.MaxX() - tmp.MinX(), tmp.MaxY() - tmp.MinY(), @@ -284,11 +283,12 @@ void csOPCODECollider::CopyCollisionPairs(csOPCODECollider *col1, const Pair *colPairs = TreeCollider.GetPairs(); Point *vertholder0 = col1->vertholder; Point *vertholder1 = col2->vertholder; - int j; + uint32_t j; size_t oldlen = pairs.size(); - pairs.resize(oldlen + N_pairs); + size_t newlen = oldlen + N_pairs; + pairs.resize(newlen); - for (unsigned int i = 0; i < N_pairs; ++i) { + for (unsigned int i = 0; i < N_pairs && oldlen < newlen; ++i) { j = 3 * colPairs[i].id0; pairs.at(oldlen).a1 = vertholder0[j]; pairs.at(oldlen).b1 = vertholder0[j + 1]; diff --git a/engine/src/cmd/collide2/Stdafx.h b/engine/src/cmd/collide2/Stdafx.h index 4fa112e909..3a3adfcbe1 100644 --- a/engine/src/cmd/collide2/Stdafx.h +++ b/engine/src/cmd/collide2/Stdafx.h @@ -4,9 +4,8 @@ * Copyright (C) 2001 Pierre Terdiman * Homepage: http://www.codercorner.com/Opcode.htm * - * Copyright (C) Daniel Horn, chuck starchaser, and pheonixstorm - * Copyright (C) 2020 pyramid3d, Stephen G. Tuggy, and other Vega Strike contributors - * Copyright (C) 2021-2023 Stephen G. Tuggy, Benjamen R. Meyer + * Copyright (C) 2001-2025 Daniel Horn, chuck starchaser, pheonixstorm, + * Stephen G. Tuggy, Benjamen R. Meyer, and other Vega Strike contributors * * https://github.com/vegastrike/Vega-Strike-Engine-Source * @@ -19,11 +18,11 @@ * * Vega Strike is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Vega Strike. If not, see . + * along with Vega Strike. If not, see . */ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -46,6 +45,5 @@ #include "opcodetypes.h" #include "opcodesysdef.h" #include "Opcode.h" -#include "vs_vector.h" #endif //VEGA_STRIKE_ENGINE_CMD_COLLSION2_STDAFX_H diff --git a/engine/src/cmd/controls_factory.cpp b/engine/src/cmd/controls_factory.cpp index b84bd6266c..281f9a77b1 100644 --- a/engine/src/cmd/controls_factory.cpp +++ b/engine/src/cmd/controls_factory.cpp @@ -1,9 +1,8 @@ -/** +/* * controls_factory.cpp * - * Copyright (C) Daniel Horn - * Copyright (C) 2023 Roy Falk, Stephen G. Tuggy, Benjamen R. Meyer and other Vega Strike - * contributors + * Copyright (C) 2001-2025 Daniel Horn, Roy Falk, Stephen G. Tuggy, + * Benjamen R. Meyer and other Vega Strike contributors * * https://github.com/vegastrike/Vega-Strike-Engine-Source * @@ -16,11 +15,11 @@ * * Vega Strike is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Vega Strike. If not, see . + * along with Vega Strike. If not, see . */ #include "controls_factory.h" @@ -105,9 +104,9 @@ static std::vector splitAndConvert (const std::string &s, char delim) { GFXColor getColor(const std::string& colorString) { std::vector colorTuple = splitAndConvert(colorString, ','); if(colorTuple.size() == 4) { - return GFXColor(colorTuple[0], colorTuple[1], colorTuple[2], colorTuple[3]); + return GFXColor(colorTuple.at(0), colorTuple.at(1), colorTuple.at(2), colorTuple.at(3)); } else { - return GFXColor(colorTuple[0], colorTuple[1], colorTuple[2]); + return GFXColor(colorTuple.at(0), colorTuple.at(1), colorTuple.at(2)); } } @@ -140,7 +139,7 @@ Control* getControl(std::map attributes) { // Text Margin if(attributes.count("textMargins")) { std::vector size = splitAndConvert(attributes["textMargins"], ','); - sd->setTextMargins(Size(size[0], size[1])); + sd->setTextMargins(Size(size.at(0), size.at(1))); } if(attributes.count("multiline")) { @@ -258,7 +257,7 @@ Control* getControl(std::map attributes) { // Text Margin if(attributes.count("textMargins")) { std::vector size = splitAndConvert(attributes["textMargins"], ','); - p->setTextMargins(Size(size[0], size[1])); + p->setTextMargins(Size(size.at(0), size.at(1))); } } else if(type == "staticImageDisplay") { StaticImageDisplay* sid = new StaticImageDisplay; @@ -272,14 +271,18 @@ Control* getControl(std::map attributes) { // Font if(attributes.count("font")) { std::vector font_array = splitAndConvert(attributes["font"], ','); - Font font(font_array[0], font_array[1]); - c->setFont(font); + if (font_array.size() < 2) { + VS_LOG(error, "controls_factory getControl(): font_array doesn't have enough elements"); + } else { + Font font(font_array.at(0), font_array.at(1)); + c->setFont(font); + } } // Rect if(attributes.count("rect")) { std::vector rect = splitAndConvert(attributes["rect"], ','); - c->setRect(Rect(rect[0], rect[1], rect[2], rect[3])); + c->setRect(Rect(rect.at(0), rect.at(1), rect.at(2), rect.at(3))); } // Color diff --git a/engine/src/cmd/damageable.cpp b/engine/src/cmd/damageable.cpp index 7847c00040..fe89134e81 100644 --- a/engine/src/cmd/damageable.cpp +++ b/engine/src/cmd/damageable.cpp @@ -1,7 +1,7 @@ /* * damageable.cpp * - * Copyright (C) 2020-2022 Daniel Horn, Roy Falk, Stephen G. Tuggy and + * Copyright (C) 2020-2025 Daniel Horn, Roy Falk, Stephen G. Tuggy and * other Vega Strike contributors * * https://github.com/vegastrike/Vega-Strike-Engine-Source @@ -15,11 +15,11 @@ * * Vega Strike is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Vega Strike. If not, see . + * along with Vega Strike. If not, see . */ @@ -524,7 +524,7 @@ float Damageable::RShieldData() const { void Damageable::ArmorData(float armor[8]) const { Damageable *damageable = const_cast(this); DamageableLayer armor_layer = damageable->GetArmorLayer(); - for (int i = 0; i < 8; i++) { + for (int i = 0; i < armor_layer.number_of_facets; ++i) { armor[i] = armor_layer.facets[i].health; } } @@ -612,5 +612,3 @@ bool Damageable::flickerDamage() { } return false; } - - diff --git a/engine/src/cmd/unit_csv.cpp b/engine/src/cmd/unit_csv.cpp index d2127be1ba..019766f812 100644 --- a/engine/src/cmd/unit_csv.cpp +++ b/engine/src/cmd/unit_csv.cpp @@ -1,6 +1,8 @@ /* - * Copyright (C) 2001-2022 Daniel Horn, pyramid3d, Stephen G. Tuggy, - * and other Vega Strike contributors. + * unit_csv.cpp + * + * Copyright (C) 2001-2025 Daniel Horn, pyramid3d, Stephen G. Tuggy, + * Roy Falk, and other Vega Strike contributors. * * https://github.com/vegastrike/Vega-Strike-Engine-Source * @@ -13,7 +15,7 @@ * * Vega Strike is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -854,7 +856,16 @@ void Unit::LoadRow(std::string unit_identifier, string modification, bool saved_ for (int i = 0; i < shield->number_of_facets; i++) { const std::string shield_string_value = UnitCSVFactory::GetVariable(unit_key, shield_keys[i], std::string()); - shield_values[i] = std::stoi(shield_string_value); + if (shield_string_value.empty()) { + shield_values[i] = 0.0f; + } else { + try { + shield_values[i] = static_cast(std::stoi(shield_string_value)); + } catch (const std::invalid_argument& ex) { + VS_LOG(warning, (boost::format("Unable to convert shield value '%1%' to a number") % shield_string_value)); + shield_values[i] = 0.0f; + } + } } if (shield->number_of_facets == 4 || shield->number_of_facets == 2) { @@ -1389,8 +1400,3 @@ string Unit::WriteUnitString() { std::map unit = UnitToMap(); return writeCSV(unit); } - - - - - diff --git a/engine/src/cmd/unit_generic.cpp b/engine/src/cmd/unit_generic.cpp index 71c36a3cfd..b61652103a 100644 --- a/engine/src/cmd/unit_generic.cpp +++ b/engine/src/cmd/unit_generic.cpp @@ -1,7 +1,7 @@ /* * unit_generic.cpp * - * Copyright (C) 2001-2023 Daniel Horn, pyramid3d, Stephen G. Tuggy, + * Copyright (C) 2001-2025 Daniel Horn, pyramid3d, Stephen G. Tuggy, * and other Vega Strike contributors. * * https://github.com/vegastrike/Vega-Strike-Engine-Source @@ -19,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Vega Strike. If not, see . + * along with Vega Strike. If not, see . */ // -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- @@ -2941,7 +2941,7 @@ bool Unit::UpAndDownGrade(const Unit *up, if (!csv_cell_null_check || force_change_on_nothing || cell_has_recursive_data(upgrade_name, up->faction, "Armor_Front_Top_Right")) { - for (int i = 0; i < 8; i++) { + for (int i = 0; i < armor->number_of_facets; ++i) { STDUPGRADE(armor->facets[i].health, up->armor->facets[i].health, templ->armor->facets[i].health, 0); @@ -4682,4 +4682,4 @@ float Unit::energyData() const { } else { return energy.Percent(); } -} \ No newline at end of file +} diff --git a/engine/src/cmd/unit_json_factory.cpp b/engine/src/cmd/unit_json_factory.cpp index 760dc2fd99..059122bb7d 100644 --- a/engine/src/cmd/unit_json_factory.cpp +++ b/engine/src/cmd/unit_json_factory.cpp @@ -1,8 +1,7 @@ /* * unit_csv_factory.cpp * - * Copyright (C) 2021 Roy Falk - * Copyright (C) 2022 Stephen G. Tuggy + * Copyright (C) 2021-2025 Roy Falk and Stephen G. Tuggy * * https://github.com/vegastrike/Vega-Strike-Engine-Source * @@ -39,7 +38,12 @@ void UnitJSONFactory::ParseJSON(VSFileSystem::VSFile &file, bool player_ship) { const std::string json_text = file.ReadFull(); - boost::json::value json_value = boost::json::parse(json_text); + boost::json::value json_value; + try { + json_value = boost::json::parse(json_text); + } catch (std::exception const& e) { + VS_LOG_FLUSH_EXIT(fatal, (boost::format("Error parsing JSON in UnitJSONFactory::ParseJSON(): %1%") % e.what()), 42); + } boost::json::array root_array = json_value.get_array(); for(boost::json::value& unit_value : root_array) { diff --git a/engine/src/components/component_utils.cpp b/engine/src/components/component_utils.cpp index 29fdf8651c..d8acb35eec 100644 --- a/engine/src/components/component_utils.cpp +++ b/engine/src/components/component_utils.cpp @@ -1,7 +1,7 @@ /* - * src/components/component_printer.cpp + * src/components/component_utils.cpp * - * Copyright (C) 2001-2023 Daniel Horn, Benjamen Meyer, Roy Falk, Stephen G. Tuggy, + * Copyright (C) 2001-2025 Daniel Horn, Benjamen Meyer, Roy Falk, Stephen G. Tuggy, * and other Vega Strike contributors. * * https://github.com/vegastrike/Vega-Strike-Engine-Source @@ -15,7 +15,7 @@ * * Vega Strike is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -139,7 +139,7 @@ EnergyContainer* GetSourceFromConfiguration(const EnergyConsumerSource source, E // For Drive and DriveUpgrade -const std::string yaw_governor[] = {"Yaw_Governor", "Yaw_Governor", "Yaw_Governor"}; +const std::string yaw_governor[] = {"Yaw_Governor", "Yaw_Governor_Right", "Yaw_Governor_Left"}; const std::string pitch_governor[] = {"Pitch_Governor", "Pitch_Governor_Up", "Pitch_Governor_Down"}; const std::string roll_governor[] = {"Roll_Governor", "Roll_Governor_Right", "Roll_Governor_Left"}; diff --git a/engine/src/gfx/cockpit.cpp b/engine/src/gfx/cockpit.cpp index 55590d1cd0..ec7878f132 100644 --- a/engine/src/gfx/cockpit.cpp +++ b/engine/src/gfx/cockpit.cpp @@ -3,7 +3,7 @@ /* * cockpit.cpp * - * Copyright (C) 2001-2023 Daniel Horn, pyramid3d, Stephen G. Tuggy, + * Copyright (C) 2001-2025 Daniel Horn, pyramid3d, Stephen G. Tuggy, * and other Vega Strike contributors * * https://github.com/vegastrike/Vega-Strike-Engine-Source @@ -17,11 +17,11 @@ * * Vega Strike is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Vega Strike. If not, see . + * along with Vega Strike. If not, see . */ @@ -1836,20 +1836,27 @@ void GameCockpit::Draw() { //////////////////// DISPLAY CURRENT POSITION //////////////////// if (configuration()->graphics_config.hud.debug_position) { TextPlane tp; - char str[400]; //don't make the sprintf format too big... :-P + std::string str; Unit *you = parent.GetUnit(); if (you) { - sprintf(str, "Your Position: (%lf,%lf,%lf); Velocity: (%f,%f,%f); Frame: %lf\n", - you->curr_physical_state.position.i, you->curr_physical_state.position.j, - you->curr_physical_state.position.k, you->Velocity.i, you->Velocity.j, you->Velocity.k, - getNewTime()); + str = (boost::format("Your Position: (%1%,%2%,%3%); Velocity: (%4%,%5%,%6%); Frame: %7%\n") + % you->curr_physical_state.position.i + % you->curr_physical_state.position.j + % you->curr_physical_state.position.k + % you->Velocity.i + % you->Velocity.j + % you->Velocity.k + % getNewTime()).str(); Unit *yourtarg = you->computer.target.GetUnit(); if (yourtarg) { - sprintf(str + strlen( - str), "Target Position: (%lf,%lf,%lf); Velocity: (%f,%f,%f); Now: %lf\n", - yourtarg->curr_physical_state.position.i, yourtarg->curr_physical_state.position.j, - yourtarg->curr_physical_state.position.k, yourtarg->Velocity.i, yourtarg->Velocity.j, - yourtarg->Velocity.k, queryTime()); + str += (boost::format("Target Position: (%1%,%2%,%3%); Velocity: (%4%,%5%,%6%); Now: %7%\n") + % yourtarg->curr_physical_state.position.i + % yourtarg->curr_physical_state.position.j + % yourtarg->curr_physical_state.position.k + % yourtarg->Velocity.i + % yourtarg->Velocity.j + % yourtarg->Velocity.k + % queryTime()).str(); } } tp.SetPos(-0.8, -0.8); diff --git a/engine/src/gfx/mesh_gfx.cpp b/engine/src/gfx/mesh_gfx.cpp index abb7eeb5ea..a0c2b4e8b2 100644 --- a/engine/src/gfx/mesh_gfx.cpp +++ b/engine/src/gfx/mesh_gfx.cpp @@ -408,22 +408,23 @@ extern Hashtable, MESH_HASTHABLE_SIZE> bfxmHash Mesh::~Mesh() { if (!orig || orig == this) { - for (int j = 0; j < NUM_MESH_SEQUENCE; j++) { - for (OrigMeshVector::iterator it = undrawn_meshes[j].begin(); it != undrawn_meshes[j].end(); ++it) { - if (it->orig == this) { - undrawn_meshes[j].erase(it--); - VS_LOG(debug, "stale mesh found in draw queue--removed!"); - } + for (auto & undrawn_mesh : undrawn_meshes) { + const auto first_to_remove1 = std::stable_partition(undrawn_mesh.begin(), undrawn_mesh.end(), + [this](const OrigMeshContainer & pi) { return pi.orig != this; }); + const intmax_t num_meshes_removed = undrawn_mesh.end() - first_to_remove1; + undrawn_mesh.erase(first_to_remove1, undrawn_mesh.end()); + if (num_meshes_removed > 0) { + VS_LOG(debug, (boost::format("Found and removed %1% stale meshes in draw queue") % num_meshes_removed)); } } if (vlist != nullptr) { delete vlist; vlist = nullptr; } - for (size_t i = 0; i < Decal.size(); ++i) { - if (Decal[i] != nullptr) { - delete Decal[i]; - Decal[i] = nullptr; + for (auto & texture : Decal) { + if (texture != nullptr) { + delete texture; + texture = nullptr; } } if (squadlogos != nullptr) { @@ -439,43 +440,19 @@ Mesh::~Mesh() { } vector *hashers = bfxmHashTable.Get(hash_name); vector::iterator finder; - if (hashers) { - // the foollowing loop has several tricks to it: - // 1. `std::vector::erase()` can take an interator and remove it from the vector; but invalidates - // the iterator in the process - // 2. To overcome the invalid iterator issue, the next previous iterator is cached - // 3. In the case that the previous iterator would be invalid (e.g it's at the start) then it needs - // to restart the loop without the loop conditions, therefore a simple GOTO is used instead to - // avoid the incrementing the iterator so that values are not skipped - // A reverse iterator could kind of help this; however, `std::vector::erase` unfortunately - // does not work on reverse iterators. - for (auto hashItem = hashers->begin(); hashItem != hashers->end(); ++hashItem) { -retryEraseItem: - if (*hashItem == this) { - bool resetIter = false; - auto cachedHashItem = hashers->begin(); - if (hashItem != hashers->begin()) { - cachedHashItem = hashItem - 1; - } else { - resetIter = true; - cachedHashItem = hashItem + 1; - } - hashers->erase(hashItem); - if (hashers->empty()) { - bfxmHashTable.Delete(hash_name); - delete hashers; - hashers = nullptr; - break; - } - - if (resetIter) { - hashItem = hashers->begin(); - // a necessary use of Goto as we do not want to use ++hashItem - goto retryEraseItem; - } else { - hashItem = cachedHashItem; - } - } + if (hashers && !hashers->empty()) { + const auto first_to_remove = std::stable_partition(hashers->begin(), hashers->end(), + [this](const Mesh * pi) { return pi != this; }); + const intmax_t num_meshes_removed = hashers->end() - first_to_remove; + hashers->erase(first_to_remove, hashers->end()); + if (num_meshes_removed > 0) { + VS_LOG(debug, (boost::format("Mesh::~Mesh(): erased %1% meshes from hashers") % num_meshes_removed)); + } + if (hashers->empty()) { + bfxmHashTable.Delete(hash_name); + delete hashers; + hashers = nullptr; + VS_LOG(debug, "Mesh::~Mesh(): deleted hashers"); } } if (draw_queue != nullptr) { diff --git a/engine/src/gfx/vdu.cpp b/engine/src/gfx/vdu.cpp index 6e15f3e5cd..1d41415917 100644 --- a/engine/src/gfx/vdu.cpp +++ b/engine/src/gfx/vdu.cpp @@ -1185,21 +1185,18 @@ void VDU::DrawDamage(Unit *parent) { float x, y, w, h; //float th; //char st[1024]; - GFXColor4f(1, parent->GetHull() / (*maxhull), parent->GetHull() / (*maxhull), 1); + double health_percent = parent->layers[0].facets[0].Percent(); + GFXColor4f(1, health_percent, health_percent, 1); GFXEnable(TEXTURE0); float armor[8]; parent->ArmorData(armor); const bool draw_damage_sprite = configuration()->graphics_config.hud.draw_damage_sprite; - DrawHUDSprite(this, draw_damage_sprite ? parent->getHudImage() : NULL, .6, x, y, w, h, - (armor[0] + armor[2] + armor[4] + armor[6]) - / (float) (StartArmor[0] + StartArmor[2] + StartArmor[4] + StartArmor[6]), - (armor[0] + armor[1] + armor[4] + armor[5]) - / (float) (StartArmor[0] + StartArmor[1] + StartArmor[4] + StartArmor[5]), - (armor[2] + armor[3] + armor[6] + armor[7]) - / (float) (StartArmor[2] + StartArmor[3] + StartArmor[6] + StartArmor[7]), - (armor[1] + armor[3] + armor[5] - + armor[7]) / (float) (StartArmor[1] + StartArmor[3] + StartArmor[5] + StartArmor[7]), - parent->GetHull() / (*maxhull), true, false); + DrawHUDSprite(this, draw_damage_sprite ? parent->getHudImage() : nullptr, .6, x, y, w, h, + parent->layers[1].facets[0].Percent(), + parent->layers[1].facets[3].Percent(), + parent->layers[1].facets[2].Percent(), + parent->layers[1].facets[1].Percent(), + health_percent, true, false); GFXDisable(TEXTURE0); //Unit *thr = parent->Threat(); parent->Threat(); diff --git a/engine/src/gfxlib.h b/engine/src/gfxlib.h index ddbee14d5c..0541ded60e 100644 --- a/engine/src/gfxlib.h +++ b/engine/src/gfxlib.h @@ -1,5 +1,7 @@ /* - * Copyright (C) 2001-2023 Daniel Horn, pyramid3d, Stephen G. Tuggy, Benjamen R. Meyer, + * gfxlib.h + * + * Copyright (C) 2001-2025 Daniel Horn, pyramid3d, Stephen G. Tuggy, Benjamen R. Meyer, * and other Vega Strike contributors. * * https://github.com/vegastrike/Vega-Strike-Engine-Source @@ -296,7 +298,7 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferSubTexture(unsigned char *buffer, enum TEXTURE_IMAGE_TARGET image2D = TEXTURE_2D); ///Deletes the texture from the graphics card -void /*GFXDRVAPI*/ GFXDeleteTexture(int handle); +void /*GFXDRVAPI*/ GFXDeleteTexture(size_t handle); ///Cleans up all textures void /*GFXDRVAPI*/ GFXDestroyAllTextures(); diff --git a/engine/src/gldrv/gl_texture.cpp b/engine/src/gldrv/gl_texture.cpp index 7a743cc712..51c0e74e09 100644 --- a/engine/src/gldrv/gl_texture.cpp +++ b/engine/src/gldrv/gl_texture.cpp @@ -331,7 +331,7 @@ GFXBOOL /*GFXDRVAPI*/ GFXCreateTexture(int width, GFXActiveTexture(texturestage); *handle = 0; while (*handle < static_cast(textures.size())) { - if (!textures[*handle].alive) { + if (!textures.at(*handle).alive) { break; } else { (*handle)++; @@ -346,58 +346,58 @@ GFXBOOL /*GFXDRVAPI*/ GFXCreateTexture(int width, } switch (texture_target) { case TEXTURE1D: - textures[*handle].targets = GL_TEXTURE_1D; + textures.at(*handle).targets = GL_TEXTURE_1D; break; case TEXTURE2D: - textures[*handle].targets = GL_TEXTURE_2D; + textures.at(*handle).targets = GL_TEXTURE_2D; break; case TEXTURE3D: - textures[*handle].targets = GL_TEXTURE_3D; + textures.at(*handle).targets = GL_TEXTURE_3D; break; case CUBEMAP: - textures[*handle].targets = GL_TEXTURE_CUBE_MAP_EXT; + textures.at(*handle).targets = GL_TEXTURE_CUBE_MAP_EXT; break; case TEXTURERECT: - textures[*handle].targets = GL_TEXTURE_RECTANGLE_ARB; + textures.at(*handle).targets = GL_TEXTURE_RECTANGLE_ARB; break; } //for those libs with stubbed out handle gen't - textures[*handle].name = *handle + 1; - textures[*handle].alive = GFXTRUE; - textures[*handle].texturestage = texturestage; - textures[*handle].mipmapped = mipmap; - glGenTextures(1, &textures[*handle].name); - glBindTexture(textures[*handle].targets, textures[*handle].name); + textures.at(*handle).name = *handle + 1; + textures.at(*handle).alive = GFXTRUE; + textures.at(*handle).texturestage = texturestage; + textures.at(*handle).mipmapped = mipmap; + glGenTextures(1, &textures.at(*handle).name); + glBindTexture(textures.at(*handle).targets, textures.at(*handle).name); activetexture[texturestage] = *handle; GFXTextureAddressMode(address_mode, texture_target); - if (textures[*handle].mipmapped & (TRILINEAR | MIPMAP) && gl_options.mipmap >= 2) { - glTexParameteri(textures[*handle].targets, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - if (textures[*handle].mipmapped & TRILINEAR && gl_options.mipmap >= 3) { - glTexParameteri(textures[*handle].targets, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + if (textures.at(*handle).mipmapped & (TRILINEAR | MIPMAP) && gl_options.mipmap >= 2) { + glTexParameteri(textures.at(*handle).targets, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (textures.at(*handle).mipmapped & TRILINEAR && gl_options.mipmap >= 3) { + glTexParameteri(textures.at(*handle).targets, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else { - glTexParameteri(textures[*handle].targets, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(textures.at(*handle).targets, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); } } else { - if (textures[*handle].mipmapped == NEAREST || gl_options.mipmap == 0) { - glTexParameteri(textures[*handle].targets, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(textures[*handle].targets, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + if (textures.at(*handle).mipmapped == NEAREST || gl_options.mipmap == 0) { + glTexParameteri(textures.at(*handle).targets, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(textures.at(*handle).targets, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } else { - glTexParameteri(textures[*handle].targets, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(textures[*handle].targets, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(textures.at(*handle).targets, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(textures.at(*handle).targets, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } } - glTexParameterf(textures[*handle].targets, GL_TEXTURE_PRIORITY, .5); - textures[*handle].width = width; - textures[*handle].height = height; - textures[*handle].iwidth = width; - textures[*handle].iheight = height; - textures[*handle].palette = NULL; + glTexParameterf(textures.at(*handle).targets, GL_TEXTURE_PRIORITY, .5); + textures.at(*handle).width = width; + textures.at(*handle).height = height; + textures.at(*handle).iwidth = width; + textures.at(*handle).iheight = height; + textures.at(*handle).palette = NULL; if (palette && textureformat == PALETTE8) { VS_LOG(trace, " palette "); - textures[*handle].palette = (GLubyte *) malloc(sizeof(GLubyte) * 1024); - ConvertPalette(textures[*handle].palette, (unsigned char *) palette); + textures.at(*handle).palette = (GLubyte *) malloc(sizeof(GLubyte) * 1024); + ConvertPalette(textures.at(*handle).palette, (unsigned char *) palette); } - textures[*handle].textureformat = GetUncompressedTextureFormat(textureformat); + textures.at(*handle).textureformat = GetUncompressedTextureFormat(textureformat); return GFXTRUE; } @@ -410,8 +410,8 @@ void /*GFXDRVAPI*/ GFXPrioritizeTexture(unsigned int handle, float priority) { } void /*GFXDRVAPI*/ GFXAttachPalette(unsigned char *palette, int handle) { - ConvertPalette(textures[handle].palette, palette); - //memcpy (textures[handle].palette,palette,768); + ConvertPalette(textures.at(handle).palette, palette); + //memcpy (textures.at(handle).palette,palette,768); } static void DownSampleTexture(unsigned char **newbuf, @@ -698,11 +698,11 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferSubTexture(unsigned char *buffer, unsigned int height, enum TEXTURE_IMAGE_TARGET imagetarget) { GLenum image2D = GetImageTarget(imagetarget); - glBindTexture(textures[handle].targets, textures[handle].name); + glBindTexture(textures.at(handle).targets, textures.at(handle).name); //internalformat = GetTextureFormat (handle); - glTexSubImage2D(image2D, 0, x, y, width, height, textures[handle].textureformat, GL_UNSIGNED_BYTE, buffer); + glTexSubImage2D(image2D, 0, x, y, width, height, textures.at(handle).textureformat, GL_UNSIGNED_BYTE, buffer); return GFXTRUE; } @@ -726,7 +726,7 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, unsigned char *tempbuf = NULL; GLenum internalformat; GLenum image2D = GetImageTarget(imagetarget); - glBindTexture(textures[handle].targets, textures[handle].name); + glBindTexture(textures.at(handle).targets, textures.at(handle).name); int blocksize = 16; bool comptemp = gl_options.compression; @@ -744,14 +744,14 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, } } if (inWidth > 0) { - textures[handle].iwidth = textures[handle].width = inWidth; + textures.at(handle).iwidth = textures.at(handle).width = inWidth; } if (inHeight > 0) { - textures[handle].iheight = textures[handle].height = inHeight; + textures.at(handle).iheight = textures.at(handle).height = inHeight; } //This code i believe is executed if our texture isn't power of two - if ((textures[handle].mipmapped & (TRILINEAR | MIPMAP)) - && (!isPowerOfTwo(textures[handle].width, logwid) || !isPowerOfTwo(textures[handle].height, logsize))) { + if ((textures.at(handle).mipmapped & (TRILINEAR | MIPMAP)) + && (!isPowerOfTwo(textures.at(handle).width, logwid) || !isPowerOfTwo(textures.at(handle).height, logsize))) { static unsigned char NONPOWEROFTWO[1024] = { 255, 127, 127, 255, 255, 255, 0, 255, @@ -759,8 +759,8 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, 255, 127, 127, 255 }; buffer = NONPOWEROFTWO; - textures[handle].width = 2; - textures[handle].height = 2; + textures.at(handle).width = 2; + textures.at(handle).height = 2; //assert (false); } logsize = logsize > logwid ? logsize : logwid; @@ -773,14 +773,14 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, VS_LOG(debug, (boost::format( "Transferring %1%x%2% texture, page %3% (eff: %4%x%5% - limited at %6% - %7% mips), onto name %8% (%9%)") - % textures[handle].iwidth - % textures[handle].iheight + % textures.at(handle).iwidth + % textures.at(handle).iheight % pageIndex - % textures[handle].width - % textures[handle].height + % textures.at(handle).width + % textures.at(handle).height % maxdimension % mips - % textures[handle].name + % textures.at(handle).name % GetImageTargetName(imagetarget))); if (maxdimension == 44) { detail_texture = 0; @@ -791,19 +791,19 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if (internformat >= DXT1 && internformat <= DXT5) { - if (textures[handle].width > 8 && textures[handle].height > 8 && mips > 0) { - offset1 += ((textures[handle].width + 3) / 4) * ((textures[handle].height + 3) / 4) * blocksize; - if (textures[handle].width > 1) { - textures[handle].width >>= 1; + if (textures.at(handle).width > 8 && textures.at(handle).height > 8 && mips > 0) { + offset1 += ((textures.at(handle).width + 3) / 4) * ((textures.at(handle).height + 3) / 4) * blocksize; + if (textures.at(handle).width > 1) { + textures.at(handle).width >>= 1; } - if (textures[handle].height > 1) { - textures[handle].height >>= 1; + if (textures.at(handle).height > 1) { + textures.at(handle).height >>= 1; } - if (textures[handle].iwidth > 1) { - textures[handle].iwidth >>= 1; + if (textures.at(handle).iwidth > 1) { + textures.at(handle).iwidth >>= 1; } - if (textures[handle].iheight > 1) { - textures[handle].iheight >>= 1; + if (textures.at(handle).iheight > 1) { + textures.at(handle).iheight >>= 1; } --mips; } @@ -814,25 +814,25 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, blocksize = 8; } if (internformat >= DXT1 && internformat <= DXT5) { - while ((textures[handle].width > maxdimension || textures[handle].height > maxdimension) && mips > 0) { - offset1 += ((textures[handle].width + 3) / 4) * ((textures[handle].height + 3) / 4) * blocksize; - if (textures[handle].width > 1) { - textures[handle].width >>= 1; + while ((textures.at(handle).width > maxdimension || textures.at(handle).height > maxdimension) && mips > 0) { + offset1 += ((textures.at(handle).width + 3) / 4) * ((textures.at(handle).height + 3) / 4) * blocksize; + if (textures.at(handle).width > 1) { + textures.at(handle).width >>= 1; } - if (textures[handle].height > 1) { - textures[handle].height >>= 1; + if (textures.at(handle).height > 1) { + textures.at(handle).height >>= 1; } - if (textures[handle].iwidth > 1) { - textures[handle].iwidth >>= 1; + if (textures.at(handle).iwidth > 1) { + textures.at(handle).iwidth >>= 1; } - if (textures[handle].iheight > 1) { - textures[handle].iheight >>= 1; + if (textures.at(handle).iheight > 1) { + textures.at(handle).iheight >>= 1; } --mips; } offset2 = offset1; - int w = textures[handle].width; - int h = textures[handle].height; + int w = textures.at(handle).width; + int h = textures.at(handle).height; for (int i = 0; i < mips; ++i) { offset2 += ((w + 3) / 4) * ((h + 3) / 4) * blocksize; if (w > 1) { @@ -844,19 +844,19 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, } } else { //If we're not DDS, we have to generate a scaled version of the image - if (textures[handle].iwidth > maxdimension || textures[handle].iheight > maxdimension || textures[handle].iwidth - > MAX_TEXTURE_SIZE || textures[handle].iheight > MAX_TEXTURE_SIZE) { + if (textures.at(handle).iwidth > maxdimension || textures.at(handle).iheight > maxdimension || textures.at(handle).iwidth + > MAX_TEXTURE_SIZE || textures.at(handle).iheight > MAX_TEXTURE_SIZE) { #if !defined (GL_COLOR_INDEX8_EXT) if (internformat != PALETTE8) { #else if (internformat != PALETTE8 || gl_options.PaletteExt) { #endif - textures[handle].height = textures[handle].iheight; - textures[handle].width = textures[handle].iwidth; + textures.at(handle).height = textures.at(handle).iheight; + textures.at(handle).width = textures.at(handle).iwidth; DownSampleTexture(&tempbuf, buffer, - textures[handle].height, - textures[handle].width, + textures.at(handle).height, + textures.at(handle).width, (internformat == PALETTE8 ? 1 : (internformat == RGBA32 ? 4 : 3)) * sizeof(unsigned char), handle, @@ -866,17 +866,17 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, buffer = tempbuf; VS_LOG(debug, (boost::format("Downsampled %1%x%2% texture (target: %3%x%4% - limited at %5%)") - % textures[handle].iwidth - % textures[handle].iheight - % textures[handle].width - % textures[handle].height + % textures.at(handle).iwidth + % textures.at(handle).iheight + % textures.at(handle).width + % textures.at(handle).height % maxdimension)); } offset2 = 2; } else { offset2 = offset1; - int w = textures[handle].width; - int h = textures[handle].height; + int w = textures.at(handle).width; + int h = textures.at(handle).height; switch (internformat) { case PALETTE8: offset2 += (w * h); @@ -917,27 +917,27 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, //skip to desired page offset1 += pageIndex * (offset2 - 2); - int height = textures[handle].height; - int width = textures[handle].width; + int height = textures.at(handle).height; + int width = textures.at(handle).width; //If s3tc compression is disabled, our DDS files must be software decompressed if (internformat >= DXT1 && internformat <= DXT5 && !gl_options.s3tc) { unsigned char *tmpbuffer = buffer + offset1; - ddsDecompress(tmpbuffer, data, internformat, textures[handle].height, textures[handle].width); + ddsDecompress(tmpbuffer, data, internformat, textures.at(handle).height, textures.at(handle).width); buffer = data; internformat = RGBA32; - textures[handle].textureformat = GL_RGBA; + textures.at(handle).textureformat = GL_RGBA; } if (internformat != PALETTE8 && internformat != PNGPALETTE8) { internalformat = GetTextureFormat(internformat); - if (((textures[handle].mipmapped & (TRILINEAR | MIPMAP)) && gl_options.mipmap >= 2) || detail_texture) { + if (((textures.at(handle).mipmapped & (TRILINEAR | MIPMAP)) && gl_options.mipmap >= 2) || detail_texture) { if (detail_texture) { static FILTER fil = game_options()->detail_texture_trilinear ? TRILINEAR : MIPMAP; - textures[handle].mipmapped = fil; - glTexParameteri(textures[handle].targets, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + textures.at(handle).mipmapped = fil; + glTexParameteri(textures.at(handle).targets, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if (fil & TRILINEAR) { - glTexParameteri(textures[handle].targets, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(textures.at(handle).targets, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else { - glTexParameteri(textures[handle].targets, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(textures.at(handle).targets, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); } } //If we are DDS and we need to generate mipmaps (almost everything gets sent here, even non-3d visuals) @@ -978,8 +978,8 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, size = ((width + 3) / 4) * ((height + 3) / 4) * blocksize; //We need to reverse some parameters that are set cuz //we're supposed to have mipmaps here. But ani_texture hates us. - glTexParameteri(textures[handle].targets, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(textures[handle].targets, GL_TEXTURE_MAX_LEVEL, 0); + glTexParameteri(textures.at(handle).targets, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(textures.at(handle).targets, GL_TEXTURE_MAX_LEVEL, 0); glCompressedTexImage2D_p(image2D, 0, internalformat, width, height, 0, size, buffer + offset1); } /* END HACK */ @@ -987,9 +987,9 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, //We want mipmaps but we have uncompressed data gluBuild2DMipmaps(image2D, internalformat, - textures[handle].width, - textures[handle].height, - textures[handle].textureformat, + textures.at(handle).width, + textures.at(handle).height, + textures.at(handle).textureformat, GL_UNSIGNED_BYTE, buffer); } @@ -1003,17 +1003,17 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, int size = 0; size = ((width + 3) / 4) * ((height + 3) / 4) * blocksize; //force GL to only display our one texture (just in case) - glTexParameteri(textures[handle].targets, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(textures[handle].targets, GL_TEXTURE_MAX_LEVEL, 0); + glTexParameteri(textures.at(handle).targets, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(textures.at(handle).targets, GL_TEXTURE_MAX_LEVEL, 0); glCompressedTexImage2D_p(image2D, 0, internalformat, width, height, 0, size, buffer + offset1); } else { glTexImage2D(image2D, 0, internalformat, - textures[handle].width, - textures[handle].height, + textures.at(handle).width, + textures.at(handle).height, 0, - textures[handle].textureformat, + textures.at(handle).textureformat, GL_UNSIGNED_BYTE, buffer); } @@ -1025,7 +1025,7 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, #if defined (GL_COLOR_INDEX8_EXT) if (gl_options.PaletteExt) { error = glGetError(); - glColorTable_p(textures[handle].targets, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, textures[handle].palette); + glColorTable_p(textures.at(handle).targets, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, textures.at(handle).palette); error = glGetError(); if (error) { if (tempbuf != nullptr) { @@ -1039,11 +1039,11 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, } return GFXFALSE; } - if ((textures[handle].mipmapped & (MIPMAP | TRILINEAR)) && gl_options.mipmap >= 2) { + if ((textures.at(handle).mipmapped & (MIPMAP | TRILINEAR)) && gl_options.mipmap >= 2) { gluBuild2DMipmaps(image2D, GL_COLOR_INDEX8_EXT, - textures[handle].width, - textures[handle].height, + textures.at(handle).width, + textures.at(handle).height, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, buffer); @@ -1051,8 +1051,8 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, glTexImage2D(image2D, 0, GL_COLOR_INDEX8_EXT, - textures[handle].width, - textures[handle].height, + textures.at(handle).width, + textures.at(handle).height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, @@ -1061,21 +1061,21 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, } else #endif { - int nsize = 4 * textures[handle].iheight * textures[handle].iwidth; + int nsize = 4 * textures.at(handle).iheight * textures.at(handle).iwidth; unsigned char *tbuf = (unsigned char *) malloc(sizeof(unsigned char) * nsize); - //textures[handle].texture = tbuf; + //textures.at(handle).texture = tbuf; int j = 0; for (int i = 0; i < nsize; i += 4) { - tbuf[i] = textures[handle].palette[4 * buffer[j]]; - tbuf[i + 1] = textures[handle].palette[4 * buffer[j] + 1]; - tbuf[i + 2] = textures[handle].palette[4 * buffer[j] + 2]; + tbuf[i] = textures.at(handle).palette[4 * buffer[j]]; + tbuf[i + 1] = textures.at(handle).palette[4 * buffer[j] + 1]; + tbuf[i + 2] = textures.at(handle).palette[4 * buffer[j] + 2]; //used to be 255 - tbuf[i + 3] = textures[handle].palette[4 * buffer[j] + 3]; + tbuf[i + 3] = textures.at(handle).palette[4 * buffer[j] + 3]; j++; } GFXTransferTexture( tbuf, handle, - textures[handle].iwidth, textures[handle].iheight, + textures.at(handle).iwidth, textures.at(handle).iheight, RGBA32, imagetarget, maxdimension, detail_texture); free(tbuf); } @@ -1092,32 +1092,34 @@ GFXBOOL /*GFXDRVAPI*/ GFXTransferTexture(unsigned char *buffer, return GFXTRUE; } -void /*GFXDRVAPI*/ GFXDeleteTexture(int handle) { - if (textures[handle].alive) { - glDeleteTextures(1, &textures[handle].name); - for (size_t i = 0; i < sizeof(activetexture) / sizeof(int); ++i) { - if (activetexture[i] == handle) { - activetexture[i] = -1; +void /*GFXDRVAPI*/ GFXDeleteTexture(const size_t handle) { + if (handle < textures.size()) { + if (textures.at(handle).alive) { + glDeleteTextures(1, &textures.at(handle).name); + for (int & texture : activetexture) { + if (texture == handle) { + texture = -1; + } } } + if (textures.at(handle).palette != nullptr) { + free(textures.at(handle).palette); + textures.at(handle).palette = nullptr; + } + textures.at(handle).alive = GFXFALSE; } - if (textures[handle].palette != nullptr) { - free(textures[handle].palette); - textures[handle].palette = nullptr; - } - textures[handle].alive = GFXFALSE; } void GFXInitTextureManager() { - for (size_t handle = 0; handle < textures.size(); ++handle) { - textures[handle].palette = NULL; - textures[handle].width = textures[handle].height = textures[handle].iwidth = textures[handle].iheight = 0; - textures[handle].texturestage = 0; - textures[handle].name = 0; - textures[handle].alive = 0; - textures[handle].textureformat = DUMMY; - textures[handle].targets = 0; - textures[handle].mipmapped = NEAREST; + for (auto & texture : textures) { + texture.palette = nullptr; + texture.width = texture.height = texture.iwidth = texture.iheight = 0; + texture.texturestage = 0; + texture.name = 0; + texture.alive = 0; + texture.textureformat = DUMMY; + texture.targets = 0; + texture.mipmapped = NEAREST; } glGetIntegerv(GL_MAX_TEXTURE_SIZE, &MAX_TEXTURE_SIZE); } @@ -1187,7 +1189,7 @@ void /*GFXDRVAPI*/ GFXSelectTexture(int handle, int stage) { GFXActiveTexture(stage); activetexture[stage] = handle; if (gl_options.Multitexture || (stage == 0)) { - glBindTexture(textures[handle].targets, textures[handle].name); + glBindTexture(textures.at(handle).targets, textures.at(handle).name); } } } diff --git a/engine/src/python/config/python_utils.cpp b/engine/src/python/config/python_utils.cpp index e5ca4d21fb..7e80b8a328 100644 --- a/engine/src/python/config/python_utils.cpp +++ b/engine/src/python/config/python_utils.cpp @@ -30,6 +30,9 @@ #include #include +//#include "vsfilesystem.h" +//#include "vs_logging.h" + using namespace boost::python; using namespace boost::filesystem; @@ -55,6 +58,7 @@ std::string GetPythonPath() { PyObject* GetClassFromPython( const std::string build_path, const std::string path_string, + const std::string datadir, const std::string module_name, const std::string function_name) { boost::filesystem::path full_path = boost::filesystem::path(path_string); @@ -72,6 +76,7 @@ PyObject* GetClassFromPython( status = Py_PreInitialize(&py_pre_config); if (PyStatus_Exception(status)) { + std::cerr << "Python pre-initialization failed" << std::endl << std::flush; Py_ExitStatusException(status); } @@ -81,21 +86,39 @@ PyObject* GetClassFromPython( const std::string python_sitelib_path = QUOTE(Python_SITELIB); const std::wstring python_sitelib_path_wstring = std::wstring(python_sitelib_path.begin(), python_sitelib_path.end()); const std::wstring build_path_w = std::wstring(build_path.begin(), build_path.end()); + const std::wstring data_path_w = std::wstring(datadir.begin(), datadir.end()); PyWideStringList python_path_py_wide_string_list{}; status = PyWideStringList_Append(&python_path_py_wide_string_list, python_path_w.c_str()); if (PyStatus_Exception(status)) { + std::cerr << "Python path list append 1 failed" << std::endl << std::flush; + PyErr_Print(); Py_ExitStatusException(status); } status = PyWideStringList_Append(&python_path_py_wide_string_list, path_string_w.c_str()); if (PyStatus_Exception(status)) { + std::cerr << "Python path list append 2 failed" << std::endl << std::flush; + PyErr_Print(); Py_ExitStatusException(status); } status = PyWideStringList_Append(&python_path_py_wide_string_list, python_sitelib_path_wstring.c_str()); if (PyStatus_Exception(status)) { + std::cerr << "Python path list append 3 failed" << std::endl << std::flush; + PyErr_Print(); Py_ExitStatusException(status); } status = PyWideStringList_Append(&python_path_py_wide_string_list, build_path_w.c_str()); + if (PyStatus_Exception(status)) { + std::cerr << "Python path list append 4 failed" << std::endl << std::flush; + PyErr_Print(); + Py_ExitStatusException(status); + } + status = PyWideStringList_Append(&python_path_py_wide_string_list, data_path_w.c_str()); + if (PyStatus_Exception(status)) { + std::cerr << "Python path list append 5 failed" << std::endl << std::flush; + PyErr_Print(); + Py_ExitStatusException(status); + } PyConfig config; PyConfig_InitPythonConfig(&config); @@ -105,6 +128,8 @@ PyObject* GetClassFromPython( status = Py_InitializeFromConfig(&config); if (PyStatus_Exception(status)) { + std::cerr << "Python config initialization failed" << std::endl << std::flush; + PyErr_Print(); PyConfig_Clear(&config); Py_ExitStatusException(status); } @@ -112,7 +137,7 @@ PyObject* GetClassFromPython( PyObject* module = PyImport_ImportModule(module_name.c_str()); if(!module) { - std::cerr << "PyImport_ImportModule is null\n" << std::flush; + std::cerr << "Python module import failed (PyImport_ImportModule is null)" << std::endl << std::flush; PyErr_Print(); Py_Finalize(); // TODO: throw exception @@ -121,7 +146,7 @@ PyObject* GetClassFromPython( PyObject* function = PyObject_GetAttrString(module,function_name.c_str()); if(!function) { - std::cerr << "PyObject_GetAttrString is null\n" << std::flush; + std::cerr << "PyObject_GetAttrString is null" << std::endl << std::flush; PyErr_Print(); Py_Finalize(); // TODO: throw exception diff --git a/engine/src/python/config/python_utils.h b/engine/src/python/config/python_utils.h index 65c2cb4e76..63004b8de1 100644 --- a/engine/src/python/config/python_utils.h +++ b/engine/src/python/config/python_utils.h @@ -39,8 +39,9 @@ std::string GetPythonPath(); PyObject* GetClassFromPython( std::string build_path, std::wstring path_string, + std::string datadir, std::string module_name, std::string function_name); -#endif //VEGA_STRIKE_ENGINE_RESOURCE_PYTHON_UTILS_H \ No newline at end of file +#endif //VEGA_STRIKE_ENGINE_RESOURCE_PYTHON_UTILS_H diff --git a/engine/src/python/infra/get_string.cpp b/engine/src/python/infra/get_string.cpp index 1849e2cf90..50e5786657 100644 --- a/engine/src/python/infra/get_string.cpp +++ b/engine/src/python/infra/get_string.cpp @@ -1,9 +1,8 @@ /* * get_string.cpp * - * Copyright (c) 2001-2002 Daniel Horn - * Copyright (c) 2002-2019 pyramid3d and other Vega Strike Contributors - * Copyright (c) 2019-2023 Stephen G. Tuggy, Benjamen R. Meyer, Roy Falk and other Vega Strike Contributors + * Copyright (c) 2001-2025 Daniel Horn, pyramid3d, Stephen G. Tuggy, + * Benjamen R. Meyer, Roy Falk and other Vega Strike Contributors * * https://github.com/vegastrike/Vega-Strike-Engine-Source * @@ -11,7 +10,7 @@ * * Vega Strike is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or + * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Vega Strike is distributed in the hope that it will be useful, @@ -20,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Vega Strike. If not, see . + * along with Vega Strike. If not, see . */ // -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- @@ -38,32 +37,36 @@ const std::string GetString(const std::string function_name, const std::string module_name, const std::string file_name, PyObject* args) { - if(!boost::filesystem::exists(file_name)) { - return "Error:" + file_name + "not found"; - } - PyObject* module = PyImport_ImportModule(module_name.c_str()); if(!module) { + VS_LOG_AND_FLUSH(error, "Error: PyImport_ImportModule failed"); PyErr_Print(); + PyErr_Clear(); return "Error: PyImport_ImportModule is null"; } PyObject* function = PyObject_GetAttrString(module, function_name.c_str()); if(!function) { + VS_LOG_AND_FLUSH(error, "Error: PyObject_GetAttrString failed"); PyErr_Print(); + PyErr_Clear(); return "Error: PyObject_GetAttrString is null"; } if(args == nullptr) { + VS_LOG_AND_FLUSH(error, "Error: args is null"); PyErr_Print(); + PyErr_Clear(); return "Error: PyTuple_Pack is null"; } PyObject* pyResult = PyObject_CallObject(function, args); if(!pyResult) { + VS_LOG_AND_FLUSH(error, "Error: PyObject_CallObject failed"); PyErr_Print(); + PyErr_Clear(); return "Error: PyObject_CallObject is null"; } @@ -86,5 +89,3 @@ const std::string GetString(const std::string function_name, return GetString(function_name, module_name, file_name, args); } - - diff --git a/engine/src/python/init.cpp b/engine/src/python/init.cpp index 8d173af3c3..1910335628 100644 --- a/engine/src/python/init.cpp +++ b/engine/src/python/init.cpp @@ -69,6 +69,9 @@ class Unit; #define PATHSEP "/" #endif +#define Q(x) #x +#define QUOTE(x) Q(x) + void Python::initpaths() { /* * char pwd[2048]; @@ -97,7 +100,8 @@ void Python::initpaths() { modpaths += "r\"" + VSFileSystem::Rootdir[i] + PATHSEP + moduledir + PATHSEP "missions\","; modpaths += "r\"" + VSFileSystem::Rootdir[i] + PATHSEP + moduledir + PATHSEP "ai\","; modpaths += "r\"" + VSFileSystem::Rootdir[i] + PATHSEP + moduledir + "\","; - modpaths += "r\"" + VSFileSystem::Rootdir[i] + PATHSEP + basesdir + "\""; + modpaths += "r\"" + VSFileSystem::Rootdir[i] + PATHSEP + basesdir + "\","; + modpaths += "r\"" + VSFileSystem::Rootdir[i] + PATHSEP + "python" + PATHSEP + "base_computer\""; if (i + 1 < VSFileSystem::Rootdir.size()) { modpaths += ","; } @@ -163,7 +167,8 @@ void Python::init() { return; } isinit = true; -//initialize python library + + // initialize python library PyPreConfig py_pre_config; PyPreConfig_InitPythonConfig(&py_pre_config); @@ -171,46 +176,36 @@ void Python::init() { status = Py_PreInitialize(&py_pre_config); if (PyStatus_Exception(status)) { + VS_LOG_AND_FLUSH(fatal, "Python::init(): PyPreInitialize failed"); + PyErr_Print(); + VegaStrikeLogging::VegaStrikeLogger::instance().FlushLogsProgramExiting(); Py_ExitStatusException(status); } Py_NoSiteFlag = 1; -// These functions add these modules to the builtin package + // These functions add these modules to the builtin package InitVS(); InitBriefing(); InitBase(); InitDirector(); -// Add relevant paths to python path - const std::string python_path = GetPythonPath(); - const std::wstring python_path_w(python_path.begin(), python_path.end()); - const std::wstring program_dir_w = std::wstring(VSFileSystem::programdir.begin(), VSFileSystem::programdir.end()); - const std::string base_computer_path = VSFileSystem::datadir + "/python/base_computer/"; - const std::wstring base_computer_path_w = std::wstring(base_computer_path.begin(), base_computer_path.end()); - - PyWideStringList python_path_py_wide_string_list{}; - status = PyWideStringList_Append(&python_path_py_wide_string_list, python_path_w.c_str()); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } - status = PyWideStringList_Append(&python_path_py_wide_string_list, program_dir_w.c_str()); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } - status = PyWideStringList_Append(&python_path_py_wide_string_list, base_computer_path_w.c_str()); - if (PyStatus_Exception(status)) { - Py_ExitStatusException(status); - } - PyConfig config; PyConfig_InitPythonConfig(&config); - config.module_search_paths = python_path_py_wide_string_list; - config.isolated = 0; + config.isolated = 1; -// Now we can do python things about them and initialize them + // Now we can do python things about them and initialize them Py_Initialize(); + status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + VS_LOG_AND_FLUSH(fatal, "Python::init(): Py_InitializeFromConfig failed"); + PyErr_Print(); + VegaStrikeLogging::VegaStrikeLogger::instance().FlushLogsProgramExiting(); + PyConfig_Clear(&config); + Py_ExitStatusException(status); + } + initpaths(); #if BOOST_VERSION != 102800 @@ -224,7 +219,6 @@ void Python::init() { InitVS2(); #endif VS_LOG(important_info, "testing Python integration"); -// VS_LOG(info, "testing VS random"); std::string python_snippet_to_run_1("import sys\nprint(sys.path)\n"); VegaPyRunString(python_snippet_to_run_1); @@ -285,4 +279,3 @@ void Python::test() { } #endif - diff --git a/engine/src/vs_vector.h b/engine/src/vs_vector.h deleted file mode 100644 index e73d3d0a5b..0000000000 --- a/engine/src/vs_vector.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * vs_vector.h - * - * Copyright (C) 2001-2023 Daniel Horn, Stephen G. Tuggy, Benjamen R. Meyer, - * and other Vega Strike contributors. - * - * https://github.com/vegastrike/Vega-Strike-Engine-Source - * - * This file is part of Vega Strike. - * - * Vega Strike is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Vega Strike is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Vega Strike. If not, see . - */ -#ifndef VEGA_STRIKE_ENGINE_VS_VECTOR_H -#define VEGA_STRIKE_ENGINE_VS_VECTOR_H - -#include -#include -#include - -namespace VegaStrike { - -template> -class vs_vector : public std::vector { -public: - vs_vector() = default; - vs_vector(const vs_vector &) = default; - virtual ~vs_vector() = default; - typedef typename std::vector::reference vs_vector_reference; - typedef typename std::vector::size_type vs_vector_size_type; - - inline vs_vector_reference operator[](vs_vector_size_type pos) { - return this->at(pos); - } -}; - -} - -#endif //VEGA_STRIKE_ENGINE_VS_VECTOR_H diff --git a/engine/src/vsfilesystem.cpp b/engine/src/vsfilesystem.cpp index 729fadfc64..dcb9d0d622 100644 --- a/engine/src/vsfilesystem.cpp +++ b/engine/src/vsfilesystem.cpp @@ -1,5 +1,7 @@ /* - * Copyright (C) 2001-2022 Daniel Horn, Nachum Barcohen, Roy Falk, + * vsfilesystem.cpp + * + * Copyright (C) 2001-2025 Daniel Horn, Nachum Barcohen, Roy Falk, * pyramid3d, Stephen G. Tuggy, and other Vega Strike contributors. * * https://github.com/vegastrike/Vega-Strike-Engine-Source @@ -17,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Vega Strike. If not, see . + * along with Vega Strike. If not, see . */ @@ -1867,41 +1869,6 @@ int VSFile::Fprintf(const char *format, ...) { return 0; } -#if 0 -#ifdef HAVE_VFSCANF -int VSFile::Fscanf( const char *format, ... ) -{ - int ret = -1; - int readbytes = 0; - //We add the parameter %n to the format string in order to get the number of bytes read - int format_length = strlen( format ); - char *newformat = new char[format_length+3]; - memset( newformat, 0, format_length+3 ); - memcpy( newformat, format, format_length ); - strcat( newformat, "%n" ); - va_list arglist; - va_start( arglist, format ); - if (!UseVolumes[alt_type] || this->volume_type == VSFSNone) { - //return _input(fp,(unsigned char*)format,arglist); - ret = vfscanf( this->fp, newformat, arglist ); - va_end( arglist ); - } else { - if (q_volume_format == vfmtVSR) {} else if (q_volume_format == vfmtPK3) { - //If the file has not been extracted yet we do now - checkExtracted(); - ret = vsscanf( pk3_extracted_file+offset, newformat, arglist ); - readbytes = GetReadBytes( newformat, arglist ); - va_end( arglist ); - cerr<<" SSCANF : Read "<offset += readbytes; - } - } - delete[] newformat; - return ret; -} -#endif -#endif - void VSFile::Begin() { if (!UseVolumes[alt_type] || this->volume_type == VSFSNone || this->file_mode != ReadOnly) { fseek(this->fp, 0, SEEK_SET); diff --git a/engine/src/xml_support.h b/engine/src/xml_support.h index c901b43671..268bc6494a 100644 --- a/engine/src/xml_support.h +++ b/engine/src/xml_support.h @@ -1,5 +1,7 @@ /* - * Copyright (C) 2001-2023 Daniel Horn, pyramid3d, Stephen G. Tuggy, Benjamen R. Meyer, + * xml_support.h + * + * Copyright (C) 2001-2025 Daniel Horn, pyramid3d, Stephen G. Tuggy, Benjamen R. Meyer, * and other Vega Strike contributors. * * https://github.com/vegastrike/Vega-Strike-Engine-Source @@ -17,7 +19,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Vega Strike. If not, see . + * along with Vega Strike. If not, see . */ #ifndef VEGA_STRIKE_ENGINE_XML_SUPPORT_H #define VEGA_STRIKE_ENGINE_XML_SUPPORT_H @@ -33,11 +35,6 @@ #include //needed for cout calls in config_xml.cpp (and other places too I'm sure) #include "gfx/vec.h" -//#if defined (_MSC_VER) && defined (_WIN32) && (_MSC_VER >= 1400) -////Disable useless "sprintf deprecated" errors in Visual Studio 2005 Express. -//#pragma warning(disable : 4996) -//#endif - #define ARRAY_LENGTH(a) ( sizeof (a)/sizeof (a[0]) ) std::string strtoupper(const std::string &foo);