Пример #1
0
// init level-info subsystem
void LoadLevelsList(void)
{
  CPrintF(TRANSV("Reading levels directory...\n"));

  // list the levels directory with subdirs
  CDynamicStackArray<CTFileName> afnmDir;
  MakeDirList(afnmDir, CTString("Levels\\"), CTString("*.wld"), DLI_RECURSIVE|DLI_SEARCHCD);

  // for each file in the directory
  for (INDEX i=0; i<afnmDir.Count(); i++) {
    CTFileName fnm = afnmDir[i];

    CPrintF(TRANSV("  file '%s' : "), (const char *)fnm);
    // try to load its info, and if valid
    CLevelInfo li;
    if (GetLevelInfo(li, fnm)) {
      CPrintF(TRANSV("'%s' spawn=0x%08x\n"), (const char *) li.li_strName, li.li_ulSpawnFlags);

      // create new info for that file
      CLevelInfo *pliNew = new CLevelInfo;
      *pliNew = li;
      // add it to list of all levels
      _lhAllLevels.AddTail(pliNew->li_lnNode);
    } else {
      CPrintF(TRANSV("invalid level\n"));
    }
  }

  // sort the list
  _lhAllLevels.Sort(qsort_CompareLevels, _offsetof(CLevelInfo, li_lnNode));
}
Пример #2
0
/*
 * Move all elements of another list into this one.
 */
void CListHead::MoveList(CListHead &lhOther)
{
  ASSERT(IsValid() && lhOther.IsValid());

  // if the second list is empty
  if (lhOther.IsEmpty()) {
    // no moving
    return;
  }

  // get first element in other list
  CListNode &lnOtherFirst = *lhOther.lh_Head;
  // get last element in other list
  CListNode &lnOtherLast = *lhOther.lh_Tail;

  // get last element in this list
  CListNode &lnThisLast = *lh_Tail;

  // relink elements
  lnOtherLast.ln_Succ = lnThisLast.ln_Succ;
  lnThisLast.ln_Succ = &lnOtherFirst;
  lnOtherFirst.ln_Pred = &lnThisLast;
  lh_Tail = &lnOtherLast;

  // clear the other list
  lhOther.Clear();
}
Пример #3
0
void FillDirList_internal(const CTFileName &fnmBasePath,
  CDynamicStackArray<CTFileName> &afnm, const CTFileName &fnmDir, const CTString &strPattern, BOOL bRecursive,
  CDynamicStackArray<CTFileName> *pafnmInclude, CDynamicStackArray<CTFileName> *pafnmExclude)
{
  // add the directory to list of directories to search
  CListHead lhDirs;
  CDirToRead *pdrFirst = new CDirToRead;
  pdrFirst->dr_strDir = fnmDir;
  lhDirs.AddTail(pdrFirst->dr_lnNode);

  // while the list of directories is not empty
  while (!lhDirs.IsEmpty()) {
    // take the first one
    CDirToRead *pdr = LIST_HEAD(lhDirs, CDirToRead, dr_lnNode);
    CTFileName fnmDir = pdr->dr_strDir;
    delete pdr;

    // if the dir is not allowed
    if (pafnmInclude!=NULL &&
      (!FileMatchesList(*pafnmInclude, fnmDir) || FileMatchesList(*pafnmExclude, fnmDir)) ) {
      // skip it
      continue;
    }
    
    // start listing the directory
    struct _finddata_t c_file; long hFile;
    hFile = _findfirst( (const char *)(fnmBasePath+fnmDir+"*"), &c_file );
    
    // for each file in the directory
    for (
      BOOL bFileExists = hFile!=-1; 
      bFileExists; 
      bFileExists = _findnext( hFile, &c_file )==0) {

      // if dummy dir (this dir, parent dir, or any dir starting with '.')
      if (c_file.name[0]=='.') {
        // skip it
        continue;
      }

      // get the file's filepath
      CTFileName fnm = fnmDir+c_file.name;

      // if it is a directory
      if (c_file.attrib&_A_SUBDIR) {
        // if recursive reading
        if (bRecursive) {
          // add it to the list of directories to search
          CDirToRead *pdrNew = new CDirToRead;
          pdrNew->dr_strDir = fnm+"\\";
          lhDirs.AddTail(pdrNew->dr_lnNode);
        }
      // if it matches the pattern
      } else if (strPattern=="" || fnm.Matches(strPattern)) {
        // add that file
        afnm.Push() = fnm;
      }
    }
  }
}
/*
 * Enumerate all providers at startup (later enumeration just copies this list).
 */
void CMessageDispatcher::EnumNetworkProviders_startup(CListHead &lh)
{
  // create local connection provider
  CNetworkProvider *pnpLocal = new CNetworkProvider;
  pnpLocal->np_Description = "Local";
  lh.AddTail(pnpLocal->np_Node);
  // create TCP/IP connection provider
  CNetworkProvider *pnpTCP = new CNetworkProvider;
  pnpTCP->np_Description = "TCP/IP Server";
  lh.AddTail(pnpTCP->np_Node);

  CNetworkProvider *pnpTCPCl = new CNetworkProvider;
  pnpTCPCl->np_Description = "TCP/IP Client";
  lh.AddTail(pnpTCPCl->np_Node);
}
Пример #5
0
  /* Sort the list. */
void CListHead::Sort(int (*pCompare)(const void *p0, const void *p1), int iNodeOffset)
{
  // get number of elements
  INDEX ctCount = Count();
  // if none
  if (ctCount==0) {
    // do not sort
  }

  // create array of that much integers (the array will hold pointers to the list)
  ULONG *aulPointers = new ULONG[ctCount];
  // fill it
  INDEX i=0;
  for ( CListIter<int, 0> iter(*this); !iter.IsPastEnd(); iter.MoveToNext() ) {
    aulPointers[i] = ((ULONG)&*iter)-iNodeOffset;
    i++;
  }

  // sort it
  qsort(aulPointers, ctCount, sizeof(SLONG), pCompare);

  // make temporary list
  CListHead lhTmp;
  // for each pointer
  {for(INDEX i=0; i<ctCount; i++) {
    ULONG ul = aulPointers[i];
    // get the node
    CListNode *pln = (CListNode*)(ul+iNodeOffset);
    // remove it from original list
    pln->Remove();
    // add it to the end of new list
    lhTmp.AddTail(*pln);
  }}

  // free the pointer array
  delete[] aulPointers;

  // move the sorted list here
  MoveList(lhTmp);
}
Пример #6
0
// add given node to open list, sorting best first
static void SortIntoOpenList(CPathNode *ppnLink)
{
  // start at head of the open list
  LISTITER(CPathNode, pn_lnInOpen) itpn(_lhOpen);
  // while the given node is further than the one in list
  while(ppnLink->pn_fF>itpn->pn_fF && !itpn.IsPastEnd()) {
    // move to next node
    itpn.MoveToNext();
  }

  // if past the end of list
  if (itpn.IsPastEnd()) {
    // add to the end of list
    _lhOpen.AddTail(ppnLink->pn_lnInOpen);
  // if not past end of list
  } else {
    // add before current node
    itpn.InsertBeforeCurrent(ppnLink->pn_lnInOpen);
  }
}
Пример #7
0
// find shortest path from one marker to another
static BOOL FindPath(CNavigationMarker *pnmSrc, CNavigationMarker *pnmDst)
{

  ASSERT(pnmSrc!=pnmDst);
  CPathNode *ppnSrc = pnmSrc->GetPathNode();
  CPathNode *ppnDst = pnmDst->GetPathNode();

  PRINTOUT(CPrintF("--------------------\n"));
  PRINTOUT(CPrintF("FindPath(%s, %s)\n", ppnSrc->GetName(), ppnDst->GetName()));

  // start with empty open and closed lists
  ASSERT(_lhOpen.IsEmpty());
  ASSERT(_lhClosed.IsEmpty());

  // add the start node to open list
  ppnSrc->pn_fG = 0.0f;
  ppnSrc->pn_fH = NodeDistance(ppnSrc, ppnDst);
  ppnSrc->pn_fF = ppnSrc->pn_fG +ppnSrc->pn_fH;
  _lhOpen.AddTail(ppnSrc->pn_lnInOpen);
  PRINTOUT(CPrintF("StartState: %s\n", ppnSrc->GetName()));

  // while the open list is not empty
  while (!_lhOpen.IsEmpty()) {
    // get the first node from open list (that is, the one with lowest F)
    CPathNode *ppnNode = LIST_HEAD(_lhOpen, CPathNode, pn_lnInOpen);
    ppnNode->pn_lnInOpen.Remove();
      _lhClosed.AddTail(ppnNode->pn_lnInClosed);
    PRINTOUT(CPrintF("Node: %s - moved from OPEN to CLOSED\n", ppnNode->GetName()));

    // if this is the goal
    if (ppnNode==ppnDst) {
      PRINTOUT(CPrintF("PATH FOUND!\n"));
      // the path is found
      return TRUE;
    }

    // for each link of current node
    CPathNode *ppnLink = NULL;
    for(INDEX i=0; (ppnLink=ppnNode->GetLink(i))!=NULL; i++) {
      PRINTOUT(CPrintF(" Link %d: %s\n", i, ppnLink->GetName()));
      // get cost to get to this node if coming from current node
      FLOAT fNewG = ppnLink->pn_fG+NodeDistance(ppnNode, ppnLink);
      // if a shorter path already exists
      if ((ppnLink->pn_lnInOpen.IsLinked() || ppnLink->pn_lnInClosed.IsLinked()) && fNewG>=ppnLink->pn_fG) {
        PRINTOUT(CPrintF("  shorter path exists through: %s\n", ppnLink->pn_ppnParent->GetName()));
        // skip this link
        continue;
      }
      // remember this path
      ppnLink->pn_ppnParent = ppnNode;
      ppnLink->pn_fG = fNewG;
      ppnLink->pn_fH = NodeDistance(ppnLink, ppnDst);
      ppnLink->pn_fF = ppnLink->pn_fG + ppnLink->pn_fH;
      // remove from closed list, if in it
      if (ppnLink->pn_lnInClosed.IsLinked()) {
        ppnLink->pn_lnInClosed.Remove();
        PRINTOUT(CPrintF("  %s removed from CLOSED\n", ppnLink->GetName()));
      }
      // add to open if not in it
      if (!ppnLink->pn_lnInOpen.IsLinked()) {
        SortIntoOpenList(ppnLink);
        PRINTOUT(CPrintF("  %s added to OPEN\n", ppnLink->GetName()));
      }
    }
  }

  // if we get here, there is no path
  PRINTOUT(CPrintF("PATH NOT FOUND!\n"));
  return FALSE;
}