/** ============================================================================ * @func LIST_GetHead * * @desc Pops the head off the list and returns a pointer to it. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS LIST_GetHead (IN List * list, OUT ListElement ** headElement) { DSP_STATUS status = DSP_SOK ; TRC_2ENTER ("LIST_GetHead", list, headElement) ; DBC_Require (list != NULL) ; DBC_Require (headElement != NULL) ; if ((list == NULL) || (headElement == NULL)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { if (LIST_IsEmpty (list)) { *headElement = NULL ; } else { *headElement = list->head.next ; list->head.next = (*headElement)->next ; (*headElement)->next->prev = &list->head ; } } TRC_1LEAVE ("LIST_GetHead", status) ; return status ; }
/** ============================================================================ * @func LIST_Next * * @desc Returns a pointer to the next element of the list, or NULL if * the next element is the head of the list or the list is empty. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS LIST_Next (IN List * list, IN ListElement * currentElement, OUT ListElement ** nextElement) { DSP_STATUS status = DSP_SOK ; TRC_3ENTER ("LIST_Next", list, currentElement, nextElement) ; DBC_Require (list != NULL) ; DBC_Require (currentElement != NULL) ; DBC_Require (nextElement != NULL) ; if ( (list == NULL) || (currentElement == NULL) || (nextElement == NULL)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { *nextElement = NULL ; /* prime the variable */ if (!LIST_IsEmpty (list)) { if (currentElement->next != &list->head) { *nextElement = currentElement->next ; } } } TRC_1LEAVE ("LIST_Next", status) ; return status ; }
/** ============================================================================ * @func LIST_First * * @desc Returns a pointer to the first element of the list, or NULL if * the list is empty. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS LIST_First (IN List * list, OUT ListElement ** element) { DSP_STATUS status = DSP_SOK ; TRC_2ENTER ("LIST_First", list, element) ; DBC_Require (list != NULL) ; if ((list == NULL) || (element == NULL)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { if (!LIST_IsEmpty (list)) { *element = list->head.next ; } else { *element = NULL ; } } TRC_1LEAVE ("LIST_First", status) ; return status ; }
/** ============================================================================ * @func LIST_RemoveElement * * @desc Removes (unlinks) the given element from the list, if the list is * not empty. Does not free the list element. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS LIST_RemoveElement (IN List * list, IN ListElement * element) { DSP_STATUS status = DSP_SOK ; TRC_2ENTER ("LIST_RemoveElement", list, element) ; DBC_Require (list != NULL) ; DBC_Require (element != NULL) ; if ((list == NULL) || (element == NULL)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { if (!LIST_IsEmpty (list)) { element->prev->next = element->next ; element->next->prev = element->prev ; /* set elem fields to NULL to prevent illegal references */ element->next = NULL ; element->prev = NULL ; } else { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } } TRC_1LEAVE ("LIST_RemoveElement", status) ; return status ; }
/** ============================================================================ * @func LIST_PutTail * * @desc Adds the specified element to the tail of the list. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS LIST_PutTail (IN List * list, IN ListElement * element) { DSP_STATUS status = DSP_SOK ; TRC_2ENTER ("LIST_PutTail", list, element) ; DBC_Require (list != NULL) ; DBC_Require (element != NULL) ; if ((list == NULL) || (element == NULL)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { element->prev = list->head.prev ; element->next = &list->head ; list->head.prev = element ; element->prev->next = element ; } DBC_Assert ( (DSP_SUCCEEDED (status) && (!LIST_IsEmpty (list))) || (DSP_FAILED (status))); TRC_1LEAVE ("LIST_PutTail", status) ; return status ; }
/** ============================================================================ * @func LIST_InsertBefore * * @desc Insert the element before the existing element. * * @modif None * ============================================================================ */ EXPORT_API DSP_STATUS LIST_InsertBefore (IN List * list, IN ListElement * insertElement, IN ListElement * existingElement) { DSP_STATUS status = DSP_SOK ; TRC_3ENTER ("LIST_InsertBefore", list, insertElement, existingElement) ; DBC_Require(list != NULL) ; DBC_Require(insertElement != NULL) ; DBC_Require(existingElement != NULL) ; if ( (list == NULL) || (insertElement == NULL) || (existingElement == NULL)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { existingElement->prev->next = insertElement ; insertElement->prev = existingElement->prev ; insertElement->next = existingElement ; existingElement->prev = insertElement ; } DBC_Assert ( (DSP_SUCCEEDED (status) && (!LIST_IsEmpty (list))) || (DSP_FAILED (status))); TRC_1LEAVE ("LIST_InsertBefore", status) ; return status ; }
/** ============================================================================ * @func LIST_SearchElement * * @desc This function searchs for a element in the List. * * @modif None. * ============================================================================ */ EXPORT_API DSP_STATUS LIST_SearchElement (IN List * list, IN Pvoid data, OUT ListElement ** elem, IN ListMatchFunc matchFunc) { DSP_STATUS status = DSP_SOK ; ListElement * temp = NULL ; ListElement * temp1 = NULL ; Bool found = FALSE ; DBC_Require (list != NULL) ; DBC_Require (elem != NULL) ; DBC_Require (matchFunc != NULL) ; if ((list == NULL) || (elem == NULL)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } else { if (LIST_IsEmpty (list)) { status = DSP_EINVALIDARG ; SET_FAILURE_REASON ; } if (DSP_SUCCEEDED (status)) { status = LIST_First (list, &temp) ; if (DSP_SUCCEEDED (status)) { while ((found == FALSE) && (temp != NULL)) { if ((*matchFunc) (temp, data) == TRUE) { found = TRUE ; } else { temp1 = temp ; LIST_Next (list, temp1, &temp) ; } } if (found == TRUE) { *elem = temp ; } else { *elem = NULL ; status = DSP_ENOTFOUND ; SET_FAILURE_REASON ; } } else { SET_FAILURE_REASON ; } } } return status ; }
static void testTeamDefsModelScriptData (void) { int i; linkedList_t *armourPaths = NULL; for (i = 0; i < csi.numTeamDefs; i++) { int j; const teamDef_t *teamDef = &csi.teamDef[i]; if (!teamDef->armour) continue; for (j = 0; j < csi.numODs; j++) { const objDef_t *od = INVSH_GetItemByIDX(j); if (!INV_IsArmour(od)) continue; /* not for this team */ if (!CHRSH_IsArmourUseableForTeam(od, teamDef)) continue; if (!LIST_ContainsString(armourPaths, od->armourPath)) LIST_AddString(&armourPaths, od->armourPath); } UFO_CU_ASSERT_TRUE_MSG(!LIST_IsEmpty(armourPaths), va("no armour definitions found for team %s - but armour is set to true", teamDef->id)); LIST_Foreach(armourPaths, char const, armourPath) { int l; for (l = NAME_NEUTRAL; l < NAME_LAST; l++) { /* no models for this gender */ if (!teamDef->numModels[l]) continue; CU_ASSERT_PTR_NOT_NULL_FATAL(teamDef->models[l]); for (linkedList_t const* list = teamDef->models[l]; list; list = list->next) { teamDef_t::model_t const& m = *static_cast<teamDef_t::model_t const*>(list->data); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s/%s", m.path, m.body)), va("%s does not exist in models/%s (teamDef: %s)", m.body, m.path, teamDef->id)); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s%s/%s", m.path, armourPath, m.body)), va("%s does not exist in models/%s%s (teamDef: %s)", m.body, m.path, armourPath, teamDef->id)); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s/%s", m.path, m.head)), va("%s does not exist in models/%s (teamDef: %s)", m.head, m.path, teamDef->id)); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s%s/%s", m.path, armourPath, m.head)), va("%s does not exist in models/%s%s (teamDef: %s)", m.head, m.path, armourPath, teamDef->id)); } } } LIST_Delete(&armourPaths); }
int LIST_NumOfObjs(t_List *p_List) { t_List *p_Tmp; int numOfObjs = 0; if (!LIST_IsEmpty(p_List)) LIST_FOR_EACH(p_Tmp, p_List) numOfObjs++; return numOfObjs; }
/** * @brief Callback every time the parent window is closed (pop from the active window stack) */ void uiCvarNode::onWindowClosed (uiNode_t* node) { cvar_t* var; var = Cvar_FindVar(node->name); if (var == nullptr) return; cvarChangeListener_t* l = var->changeListener; while (l) { if (l->exec == UI_CvarListenerNodeCallback) { LIST_Remove(reinterpret_cast<linkedList_t**>(&l->data), node); if (LIST_IsEmpty(static_cast<linkedList_t*>(l->data))) { Cvar_UnRegisterChangeListener(node->name, UI_CvarListenerNodeCallback); } break; } l = l->next; } }
void GameTest::testCountSpawnpointsForMapInMultiplayerMode(bool verbose, const mapDef_t *md, const char *asmName, const char *aircraft, const char *ufo) { if (verbose) { std::cout << "[ ] adding test parameter: gamemode multiplayer" << std::endl; Com_Printf("CountSpawnpoints - adding test parameter: gamemode multiplayer\n"); } if (LIST_IsEmpty(md->gameTypes)) { ADD_FAILURE() << "Error: Multiplayer enabled, but no gametypes defined in mapdef " << md->id; Com_Printf("CountSpawnpoints - error: Multiplayer enabled, but no gametypes defined in mapdef.\n"); return; } if (md->teams < 1) { ADD_FAILURE() << "Error: Multiplayer enabled, but number of teams is " << md->teams; Com_Printf("CountSpawnpoints - error: Multiplayer enabled, but number of teams is %i.\n", md->teams); return; } /* Set initial values. */ /* Load map in multiplayer mode. */ Cvar_Set("sv_maxclients", DOUBLEQUOTE(MAX_CLIENTS)); /* It seems, because of reaction-fire limitations we cannot spawn more than 128 actors total. */ Cvar_Set("sv_maxsoldiersperteam", "12"); Cvar_Set("ai_multiplayeraliens", "64"); Cvar_Set("ai_numcivilians", "16"); Com_Printf("CountSpawnpoints - loading map: mode multiplayer mapdef %s map %s assembly %s dropship %s ufo %s\n", md->id, md->mapTheme, asmName, aircraft, ufo); long time = Sys_Milliseconds(); try { SV_Map(true, md->mapTheme, asmName, true); } catch (comDrop_t&) { ADD_FAILURE() << "Error: Failed to load assembly " << asmName << " from mapdef " << md->id << ", map " << md->mapTheme << " aircraft: " << aircraft << ", ufo: " << ufo << " => multiplayer mode."; Com_Printf("CountSpawnpoints - error: Multiplayer enabled, but no gametypes defined in mapdef.\n"); Com_Printf("CountSpawnpoints - error: Failed to load map.\n"); SV_ShutdownGameProgs(); return; } time = Sys_Milliseconds() - time; Com_Printf("CountSpawnpoints - result: %li ms\n", time); SV_ShutdownGameProgs(); mapCount++; /* Print report to log. */ Com_Printf("CountSpawnpoints - map: mode multiplayer\n"); Com_Printf("CountSpawnpoints - map: mapdef %s\n", md->id); Com_Printf("CountSpawnpoints - map: map %s\n", md->mapTheme); Com_Printf("CountSpawnpoints - map: assembly %s\n", asmName); Com_Printf("CountSpawnpoints - map: aircraft %s \n", aircraft); Com_Printf("CountSpawnpoints - map: ufo %s\n", ufo); /* Check if one of the gametypes available in the mapdef defines a coop mode, in which case we will need aliens on the map. */ int coop = 0; /* The number of alien spawnpoints required on the map. In PvP gamemodes this is zero, while in coop games we check for the number given as 'maxaliens' in the mapdef. */ int minAliens = 0; /* The number of player spawnpoints required for each team is determined by the value of sv_maxsoldiersperteam given in the gametype def. */ int minMP = 0; /* Count spawnpoints for TEAM_CIVILIAN. */ const int spawnCivs = static_cast<int>(level.num_spawnpoints[TEAM_CIVILIAN]); Com_Printf("CountSpawnpoints - count spawnpoints: civilian %i\n", spawnCivs); /* Find the highest numbers for alien and player spawnpoints needed in the map. */ LIST_Foreach(md->gameTypes, const char, gameType) { for (int i = 0; i < csi.numGTs; i++) { const gametype_t* gt = &csi.gts[i]; if (!Q_streq(gt->id, gameType)) continue; const cvarlist_t* list = gt->cvars; for (int j = 0; j < gt->num_cvars; j++, list++) { if (Q_streq(list->name, "ai_multiplayeraliens")) { coop = std::max(coop, atoi(list->value)); } else if (Q_streq(list->name, "sv_maxsoldiersperteam")) { minMP = std::max(minMP, atoi(list->value)); } } } } /* If the mapdef does not define a coop mode, we do not need aliens. */ if (coop) minAliens = std::min(md->maxAliens, testCountSpawnpointsGetNumteamValueForUFO(ufo)); const int startTeam = TEAM_CIVILIAN + 1; /* For every single mp team defined in the mapdef - check if there are enough spawnpoints available. */ for (int currTeamNum = startTeam; currTeamNum < startTeam + md->teams; ++currTeamNum) { if (currTeamNum > TEAM_MAX_HUMAN) { ADD_FAILURE() << "Error: Mapdef " << md->id << " has too many teams set."; Com_Printf("CountSpawnpoints - error: Too many teams set.\n"); break; } const int spawnTeam = static_cast<int>(level.num_spawnpoints[currTeamNum]); /* Make gtest report back in case there are not enough spawnpoints available for the team. */ EXPECT_GE(spawnTeam, minMP) << "Error: Assembly " << asmName << " from mapdef " << md->id << ", map " << md->mapTheme << "(aircraft: " << aircraft << ", ufo: " << ufo << ") in multiplayer mode: Only " << spawnTeam << " spawnpoints for team " << currTeamNum << " but " << minMP << " expected."; /* Log the result. */ Com_Printf("CountSpawnpoints - count spawnpoints: player team/needs/found %i/%i/%i\n", currTeamNum, minMP, spawnTeam); if (spawnTeam < minMP) Com_Printf("CountSpawnpoints - error: missing spawnpoints - player team/needs/found %i/%i/%i\n", currTeamNum, minMP, spawnTeam); } if (minAliens) { const int spawnAliens = static_cast<int>(level.num_spawnpoints[TEAM_ALIEN]); /* Make gtest report back in case there are not enough alien spawnpoints available. */ EXPECT_GE(spawnAliens, minAliens) << "Assembly " << asmName << " from mapdef " << md->id << ", map " << md->mapTheme << "(aircraft: " << aircraft << ", ufo: " << ufo << ") in multiplayer mode defines at least one coop game mode," << " but does not have enough alien spawn positions for that. We expect at least " << minAliens << " spawn positions for aliens, the map provides " << spawnAliens << "."; /* Log the result. */ Com_Printf("CountSpawnpoints - count spawnpoints: alien needs/found %i/%i\n", minAliens, spawnAliens); if (spawnAliens < minAliens) Com_Printf("CountSpawnpoints - error: missing spawnpoints - alien needs/found %i/%i\n", minAliens, spawnAliens); } SV_ShutdownGameProgs(); }
static void testTeamDefsModelScriptData (void) { int i; linkedList_t *armourPaths = NULL; for (i = 0; i < csi.numTeamDefs; i++) { int j; const teamDef_t *teamDef = &csi.teamDef[i]; if (!teamDef->armour) continue; for (j = 0; j < csi.numODs; j++) { const objDef_t *od = INVSH_GetItemByIDX(j); if (!INV_IsArmour(od)) continue; /* not for this team */ if (!CHRSH_IsArmourUseableForTeam(od, teamDef)) continue; if (!LIST_ContainsString(armourPaths, od->armourPath)) LIST_AddString(&armourPaths, od->armourPath); } UFO_CU_ASSERT_TRUE_MSG(!LIST_IsEmpty(armourPaths), va("no armour definitions found for team %s - but armour is set to true", teamDef->id)); LIST_Foreach(armourPaths, char const, armourPath) { nametypes_t l; for (l = NAME_NEUTRAL; l < NAME_LAST; l++) { linkedList_t *list = teamDef->models[l]; int k; /* no models for this gender */ if (!teamDef->numModels[l]) continue; CU_ASSERT_PTR_NOT_NULL(list); for (k = 0; k < teamDef->numModels[l]; k++) { const char *path; CU_ASSERT_PTR_NOT_NULL_FATAL(list); path = (const char*)list->data; /* body */ list = list->next; CU_ASSERT_PTR_NOT_NULL_FATAL(list); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s/%s", path, list->data)), va("%s does not exist in models/%s (teamDef: %s)", list->data, path, teamDef->id)); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s%s/%s", path, armourPath, list->data)), va("%s does not exist in models/%s%s (teamDef: %s)", list->data, path, armourPath, teamDef->id)); list = list->next; CU_ASSERT_PTR_NOT_NULL_FATAL(list); /* head */ UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s/%s", path, list->data)), va("%s does not exist in models/%s (teamDef: %s)", list->data, path, teamDef->id)); UFO_CU_ASSERT_TRUE_MSG(TEST_CheckModel(va("%s%s/%s", path, armourPath, list->data)), va("%s does not exist in models/%s%s (teamDef: %s)", list->data, path, armourPath, teamDef->id)); /* skip skin */ /** @todo check that the skin is valid for the given model */ list = list->next; CU_ASSERT_PTR_NOT_NULL_FATAL(list); /* new path */ list = list->next; } } } LIST_Delete(&armourPaths); }
/** * @sa CL_ParseScriptFirst */ static void CP_ParseAlienTeam (const char *name, const char **text) { const char *errhead = "CP_ParseAlienTeam: unexpected end of file (alienteam "; const char *token; int i; alienTeamCategory_t *alienCategory; /* get it's body */ token = Com_Parse(text); if (!*text || *token != '{') { Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" without body ignored\n", name); return; } if (ccs.numAlienCategories >= ALIENCATEGORY_MAX) { Com_Printf("CP_ParseAlienTeam: maximum number of alien team category reached (%i)\n", ALIENCATEGORY_MAX); return; } /* search for category with same name */ for (i = 0; i < ccs.numAlienCategories; i++) if (Q_streq(name, ccs.alienCategories[i].id)) break; if (i < ccs.numAlienCategories) { Com_Printf("CP_ParseAlienTeam: alien category def \"%s\" with same name found, second ignored\n", name); return; } alienCategory = &ccs.alienCategories[ccs.numAlienCategories++]; Q_strncpyz(alienCategory->id, name, sizeof(alienCategory->id)); do { token = Com_EParse(text, errhead, name); if (!*text) break; if (*token == '}') break; if (Q_streq(token, "equipment")) { linkedList_t **list = &alienCategory->equipment; token = Com_EParse(text, errhead, name); if (!*text || *token != '{') { Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" has equipment with no opening brace\n", name); break; } do { token = Com_EParse(text, errhead, name); if (!*text || *token == '}') break; LIST_AddString(list, token); } while (*text); } else if (Q_streq(token, "category")) { token = Com_EParse(text, errhead, name); if (!*text || *token != '{') { Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" has category with no opening brace\n", name); break; } do { token = Com_EParse(text, errhead, name); if (!*text || *token == '}') break; alienCategory->missionCategories[alienCategory->numMissionCategories] = CP_GetAlienMissionTypeByID(token); if (alienCategory->missionCategories[alienCategory->numMissionCategories] == INTERESTCATEGORY_NONE) Com_Printf("CP_ParseAlienTeam: alien team category \"%s\" is used with no mission category. It won't be used in game.\n", name); alienCategory->numMissionCategories++; } while (*text); } else if (Q_streq(token, "team")) { alienTeamGroup_t *group; token = Com_EParse(text, errhead, name); if (!*text || *token != '{') { Com_Printf("CP_ParseAlienTeam: alien team \"%s\" has team with no opening brace\n", name); break; } if (alienCategory->numAlienTeamGroups >= MAX_ALIEN_GROUP_PER_CATEGORY) { Com_Printf("CP_ParseAlienTeam: maximum number of alien team reached (%i) in category \"%s\"\n", MAX_ALIEN_GROUP_PER_CATEGORY, name); break; } group = &alienCategory->alienTeamGroups[alienCategory->numAlienTeamGroups]; group->idx = alienCategory->numAlienTeamGroups; group->categoryIdx = alienCategory - ccs.alienCategories; alienCategory->numAlienTeamGroups++; do { token = Com_EParse(text, errhead, name); if (!Com_ParseBlockToken(name, text, group, alien_group_vals, cp_campaignPool, token)) { const teamDef_t *teamDef; if (!*text || *token == '}') break; /* This is an alien team */ if (group->numAlienTeams >= MAX_TEAMS_PER_MISSION) Com_Error(ERR_DROP, "CL_ParseAlienTeam: MAX_TEAMS_PER_MISSION hit"); teamDef = Com_GetTeamDefinitionByID(token); if (teamDef) group->alienTeams[group->numAlienTeams++] = teamDef; } } while (*text); } else { Com_Printf("CP_ParseAlienTeam: unknown token \"%s\" ignored (category %s)\n", token, name); continue; } } while (*text); if (LIST_IsEmpty(alienCategory->equipment)) Sys_Error("alien category equipment list is empty"); }
void LIST_Sort (linkedList_t **list, linkedListSort_t sorter, const void *userData) { if (LIST_IsEmpty(*list)) return; *list = _LIST_Sort(*list, sorter, userData); }