bool can_be_mfc_app() { netnode importz("$ imports"); if (importz != BADNODE) for (ulong ndx = importz.sup1st(); ndx != BADNODE; ndx = importz.supnxt(ndx)) try { char impname[MAXSPECSIZE]; if (importz.supstr(ndx, CPY(impname)) > 0 && pcre_match("^mfc\\d{2,}", impname, PCRE_CASELESS)) return true; // assumed by imported rtl #ifdef _DEBUG } catch (const std::exception &e) { _RPT3(_CRT_ERROR, "%s(...): %s on iterating import node: index=0x%IX\n", __FUNCTION__, e.what(), ndx); #endif // _DEBUG } catch (...) { _RPT3(_CRT_ERROR, "%s(...): %s on iterating import node: index=0x%IX\n", __FUNCTION__, "unknown exception", ndx); } char buf[MAXSPECSIZE/*??*/]; ulong total(0); for (int counter = 0; counter < get_idasgn_qty(); ++counter) { const long applieds(get_idasgn_desc(counter, CPY(buf), NULL, 0)); if (applieds != -1 && pcre_match("^vc(?:32|64)mfc", buf, PCRE_CASELESS)) switch (calc_idasgn_state(counter)) { case IDASGN_APPLIED: total += applieds; break; case IDASGN_CURRENT: case IDASGN_PLANNED: return true; } } return total > 0; }
STDMETHODIMP CAVIStreamRemote::QueryInterface(const IID& iid, void **ppv) { _RPT1(0,"%08lx->CAVIStreamRemote::QueryInterface()\n", this); _RPT3(0,"\tGUID: {%08lx-%04x-%04x-", iid.Data1, iid.Data2, iid.Data3); _RPT4(0,"%02x%02x-%02x%02x", iid.Data4[0], iid.Data4[1], iid.Data4[2], iid.Data4[3]); _RPT4(0,"%02x%02x%02x%02x} (", iid.Data4[4], iid.Data4[5], iid.Data4[6], iid.Data4[7]); if (iid == IID_IUnknown) { *ppv = (IUnknown *)this; _RPT0(0,"IUnknown)\n"); } else if (iid == IID_IClassFactory) { *ppv = (IClassFactory *)&iclassfactory; _RPT0(0,"IClassFactory)\n"); } else if (iid == IID_IAVIStream) { *ppv = (IAVIStream *)this; _RPT0(0,"IAVIStream)\n"); } else { _RPT0(0,"unknown)\n"); *ppv = NULL; return ResultFromScode(E_NOINTERFACE); } AddRef(); return NULL; }
// If the cache is not being used reset it void Cache::ResetCache(IScriptEnvironment* env) { InterlockedIncrement(&g_Cache_stats.resets); minframe = vi.num_frames; maxframe = -1; CachedVideoFrame *i, *j; _RPT3(0, "Cache:%x: Cache Reset, cache_limit %d, cache_init %d\n", this, cache_limit, cache_init<<CACHE_SCALE_SHIFT); int count=0; for (i = video_frames.next; i != &video_frames; i = i->next) { if (++count >= cache_init) goto purge_old_frame; const int ifn = i->frame_number; if (ifn < minframe) minframe = ifn; if (ifn > maxframe) maxframe = ifn; } return; purge_old_frame: // Truncate the tail of the chain video_frames.prev = i; j = (CachedVideoFrame*)InterlockedExchangePointer(&i->next, &video_frames); // Delete the excess CachedVideoFrames while (j != &video_frames) { i = j->next; ReturnVideoFrameBuffer(j, env); // Return old vfb to vfb pool for early reuse delete j; j = i; } cache_limit = cache_init << CACHE_SCALE_SHIFT; }
// Copy data from the memory bitmap into a buffer void vncDesktop::CopyToBuffer(const rfb::Rect &rect, BYTE *destbuff, UINT destbuffsize) { // Finish drawing anything in this thread // Wish we could do this for the whole system - maybe we should // do something with LockWindowUpdate here. GdiFlush(); // Are we being asked to blit from the DIBsection to itself? if (destbuff == m_DIBbits) { // Yes. Ignore the request! return; } int y_inv; BYTE * destbuffpos; // Calculate the scanline-ordered y position to copy from y_inv = m_scrinfo.framebufferHeight-rect.tl.y-(rect.br.y-rect.tl.y); // Calculate where in the output buffer to put the data destbuffpos = destbuff + (m_bytesPerRow * rect.tl.y); // Set the number of bytes for GetDIBits to actually write // NOTE : GetDIBits pads the destination buffer if biSizeImage < no. of bytes required m_bminfo.bmi.bmiHeader.biSizeImage = (rect.br.y-rect.tl.y) * m_bytesPerRow; // Get the actual bits from the bitmap into the bit buffer // If fast (DIBsection) blits are disabled then use the old GetDIBits technique if (m_DIBbits == NULL) { if (GetDIBits(m_hmemdc, m_membitmap, y_inv, (rect.br.y-rect.tl.y), destbuffpos, &m_bminfo.bmi, DIB_RGB_COLORS) == 0) { _RPT1(_CRT_WARN, "vncDesktop : [1] GetDIBits failed! %d\n", GetLastError()); _RPT3(_CRT_WARN, "vncDesktop : thread = %d, DC = %d, bitmap = %d\n", omni_thread::self(), m_hmemdc, m_membitmap); _RPT2(_CRT_WARN, "vncDesktop : y = %d, height = %d\n", y_inv, (rect.br.y-rect.tl.y)); } } else { // Fast blits are enabled. [I have a sneaking suspicion this will never get used, unless // something weird goes wrong in the code. It's here to keep the function general, though!] int bytesPerPixel = m_scrinfo.format.bitsPerPixel / 8; BYTE *srcbuffpos = (BYTE*)m_DIBbits; srcbuffpos += (m_bytesPerRow * rect.tl.y) + (bytesPerPixel * rect.tl.x); destbuffpos += bytesPerPixel * rect.tl.x; int widthBytes = (rect.br.x-rect.tl.x) * bytesPerPixel; for(int y = rect.tl.y; y < rect.br.y; y++) { memcpy(destbuffpos, srcbuffpos, widthBytes); srcbuffpos += m_bytesPerRow; destbuffpos += m_bytesPerRow; } } }
bool set(const char *loc) { setlocale(LC_ALL, loc); __super::reset(pcre_maketables()); #ifdef _DEBUG if (operator !()) _RPT3(_CRT_ERROR, "%s(\"%s\"): %s() returned NULL\n", __FUNCTION__, loc, "pcre_maketables"); #endif // _DEBUG return get() != 0; }
static HMODULE WINAPI exerb_hook_load_library_ex(LPCTSTR filename, HANDLE file, DWORD flags) { _RPT3(_CRT_WARN, "exerb_hook_load_library_ex('%s', %i, %i)\n", filename, file, flags); if ( filename ) { if ( ::stricmp(filename, "msvcrt-ruby18") == 0 || ::stricmp(filename, "msvcrt-ruby18.dll") == 0 ) { return ::GetModuleHandle(NULL); } else if ( FILE_ENTRY_HEADER *file_entry = ::exerb_find_file_entry(filename, "dll") ) { if ( file_entry->type_of_file == FILE_ENTRY_HEADER_TYPE_EXTENSION_LIBRARY || file_entry->type_of_file == FILE_ENTRY_HEADER_TYPE_DYNAMIC_LIBRARY ) { return ::exerb_preload_library(file_entry); } } } return ::LoadLibraryEx(filename, file, flags); }
void memblockinfo_output_memleak() { if(!Cmdline_show_mem_usage) return; if(TotalRam == 0) return; if(TotalRam < 0) { _RPT1(_CRT_WARN, "TotalRam bad value!",TotalRam); return; } _RPT1(_CRT_WARN, "malloc memory leak of %d\n",TotalRam); // Now if system is compiled register it with the fuller system #ifdef _REPORT_MEM_LEAKS int total = 0; // Find empty slot for(int f = 0; f < MAX_MEM_POINTERS; f++) { if(mem_ptr_list[f].ptr) { _RPT3(_CRT_WARN, "Memory leaks: (%s line %d) of %d bytes\n", mem_ptr_list[f].filename, mem_ptr_list[f].line, mem_ptr_list[f].size); total += mem_ptr_list[f].size; } } Assert(TotalRam == total); #else for(int i = 0; i < MAX_MEM_MODULES; i++) { // Found the first empty entry, fill it if(mem_block_list[i].size > 0) { // Oh... bad code... making assumsions... _RPT2(_CRT_WARN, "Possible memory leaks: %s %d\n", mem_block_list[i].filename, mem_block_list[i].size); } } #endif }
std::string getImageUrlFromReddit(std::string subreddit) { JsonManager jsonMan; // get and parse json page from reddit char* jsonPage = NULL; InternetManager::DownloadPage(subreddit, &jsonPage); jsonMan.setInput(jsonPage); jsonMan.parseInput(); // if it doesn't find urls exit if (jsonMan.getUrlN() == 0) return ""; // random and download the background srand(time(NULL)); int indexRand = rand() % jsonMan.getUrlN(); std::string urlImg = jsonMan.getUrl(indexRand); _RPT3(0, "Random: %d/%d, Url: %s\n", indexRand, jsonMan.getUrlN(), urlImg.c_str()); delete jsonPage; return urlImg; }
/*!*************************************************************************** @Function PVRTGeometrySort @Modified pVtxData Pointer to array of vertices @Modified pwIdx Pointer to array of indices @Input nStride Size of a vertex (in bytes) @Input nVertNum Number of vertices. Length of pVtxData array @Input nTriNum Number of triangles. Length of pwIdx array is 3* this @Input nBufferVtxLimit Number of vertices that can be stored in a buffer @Input nBufferTriLimit Number of triangles that can be stored in a buffer @Input dwFlags PVRTGEOMETRY_SORT_* flags @Description Triangle sorter *****************************************************************************/ void PVRTGeometrySort( void * const pVtxData, PVRTGEOMETRY_IDX * const pwIdx, const int nStride, const int nVertNum, const int nTriNum, const int nBufferVtxLimit, const int nBufferTriLimit, const unsigned int dwFlags) { CObject sOb(pwIdx, nVertNum, nTriNum, nBufferVtxLimit, nBufferTriLimit); CBlock sBlock(nBufferVtxLimit, nBufferTriLimit); PVRTGEOMETRY_IDX *pwIdxOut; int nTriCnt, nVtxCnt; int nOutTriCnt, nOutVtxCnt, nOutBlockCnt; int nMeshToResize; #ifdef PVRTRISORT_ENABLE_VERIFY_RESULTS int i; int pnBlockTriCnt[PVRVGPBLOCKTEST_MAX_BLOCKS]; SVGPModel sVGPMdlBefore; SVGPModel sVGPMdlAfter; #endif if(dwFlags & PVRTGEOMETRY_SORT_VERTEXCACHE) { #ifdef PVRTRISORT_ENABLE_VERIFY_RESULTS VGP590Test(&sVGPMdlBefore, pwIdx, nTriNum); _RPT4(_CRT_WARN, "OptimiseTriListPVR() Before: Tri: %d, Vtx: %d, vtx/tri=%f Blocks=%d\n", nTriNum, sVGPMdlBefore.nVtxCnt, (float)sVGPMdlBefore.nVtxCnt / (float)nTriNum, sVGPMdlBefore.nBlockCnt); #endif pwIdxOut = (PVRTGEOMETRY_IDX*)malloc(nTriNum * 3 * sizeof(*pwIdxOut)); _ASSERT(pwIdxOut); // Sort geometry into blocks nOutTriCnt = 0; nOutVtxCnt = 0; nOutBlockCnt = 0; do { // Clear & fill the block sBlock.Clear(); nMeshToResize = sBlock.Fill(&sOb); // Copy indices into output sBlock.Output(&pwIdxOut[3*nOutTriCnt], &nVtxCnt, &nTriCnt, &sOb); sOb.m_nTriNumFree -= nTriCnt; nOutTriCnt += nTriCnt; if(nMeshToResize >= 0) { SMesh *pMesh; _ASSERT(nMeshToResize <= (nBufferVtxLimit-3)); pMesh = &sOb.m_pvMesh[nMeshToResize].back(); sOb.ResizeMesh(pMesh->nVtxNum, pMesh->ppVtx); sOb.m_pvMesh[nMeshToResize].pop_back(); } _ASSERT(nVtxCnt <= nBufferVtxLimit); _ASSERT(nTriCnt <= nBufferTriLimit); #ifdef PVRTRISORT_ENABLE_VERIFY_RESULTS _ASSERT(nOutBlockCnt < PVRVGPBLOCKTEST_MAX_BLOCKS); pnBlockTriCnt[nOutBlockCnt] = nTriCnt; #endif nOutVtxCnt += nVtxCnt; nOutBlockCnt++; // _RPT4(_CRT_WARN, "%d/%d tris (+%d), %d blocks\n", nOutTriCnt, nTriNum, nTriCnt, nOutBlockCnt); _ASSERT(nTriCnt == nBufferTriLimit || (nBufferVtxLimit - nVtxCnt) < 3 || nOutTriCnt == nTriNum); } while(nOutTriCnt < nTriNum); _ASSERT(nOutTriCnt == nTriNum); // The following will fail if optimising a subset of the mesh (e.g. a bone batching) //_ASSERT(nOutVtxCnt >= nVertNum); // Done! memcpy(pwIdx, pwIdxOut, nTriNum * 3 * sizeof(*pwIdx)); FREE(pwIdxOut); _RPT3(_CRT_WARN, "OptimiseTriListPVR() In: Tri: %d, Vtx: %d, vtx/tri=%f\n", nTriNum, nVertNum, (float)nVertNum / (float)nTriNum); _RPT4(_CRT_WARN, "OptimiseTriListPVR() HW: Tri: %d, Vtx: %d, vtx/tri=%f Blocks=%d\n", nOutTriCnt, nOutVtxCnt, (float)nOutVtxCnt / (float)nOutTriCnt, nOutBlockCnt); #ifdef PVRTRISORT_ENABLE_VERIFY_RESULTS VGP590Test(&sVGPMdlAfter, pwIdx, nTriNum); _RPT4(_CRT_WARN, "OptimiseTriListPVR() After : Tri: %d, Vtx: %d, vtx/tri=%f Blocks=%d\n", nTriNum, sVGPMdlAfter.nVtxCnt, (float)sVGPMdlAfter.nVtxCnt / (float)nTriNum, sVGPMdlAfter.nBlockCnt); _ASSERTE(sVGPMdlAfter.nVtxCnt <= sVGPMdlBefore.nVtxCnt); _ASSERTE(sVGPMdlAfter.nBlockCnt <= sVGPMdlBefore.nBlockCnt); for(i = 0; i < nOutBlockCnt; ++i) { _ASSERT(pnBlockTriCnt[i] == sVGPMdlAfter.pnBlockTriCnt[i]); } #endif } if(!(dwFlags & PVRTGEOMETRY_SORT_IGNOREVERTS)) { // Re-order the vertices so maybe they're accessed in a more linear // manner. Should cut page-breaks on the initial memory read of // vertices. Affects both the order of vertices, and the values // of indices, but the triangle order is unchanged. SortVertices(pVtxData, pwIdx, nStride, nVertNum, nTriNum*3); } }
// Generic interface to poke all cache instances void Cache::PokeCache(int key, int data, IScriptEnvironment* env) { switch (key) { case PC_Nil: { // Do Nothing! return; } case PC_UnlockOld: { // Unlock head vfb // Release the head vfb if it is locked and this // instance is not with the current GetFrame chain. if (Tick != Clock) { if (UnlockVFB(video_frames.next)) { _RPT3(0, "Cache:%x: PokeCache UnlockOld vfb %x, frame %d\n", this, video_frames.next->vfb, video_frames.next->frame_number); } } break; } case PC_UnlockAll: { // Unlock all vfb's if the vfb size is big enough to satisfy // EnterCriticalSection(&cs_cache_V); for (CachedVideoFrame* i = video_frames.next; i != &video_frames; i = i->next) { if (i->vfb->data_size >= data) { if (UnlockVFB(i)) { _RPT3(0, "Cache:%x: PokeCache UnlockAll vfb %x, frame %d\n", this, video_frames.next->vfb, video_frames.next->frame_number); } } } // LeaveCriticalSection(&cs_cache_V); break; } case PC_UnProtect: { // Unprotect 1 vfb if this instance is if (Tick != Clock) { // not with the current GetFrame chain. // EnterCriticalSection(&cs_cache_V); for (CachedVideoFrame* i = video_frames.next; i != &video_frames; i = i->next) { // Unprotect the youngest because it might be the easiest // to regenerate from parent caches that are still current. // And to give it a fair chance we also promote it. if (i->vfb->data_size >= data) { if (UnProtectVFB(i)) { UnlockVFB(i); env->ManageCache(MC_PromoteVideoFrameBuffer, i->vfb); _RPT3(0, "Cache:%x: PokeCache UnProtect vfb %x, frame %d\n", this, video_frames.next->vfb, video_frames.next->frame_number); break; } } } // LeaveCriticalSection(&cs_cache_V); } break; } case PC_UnProtectAll: { // Unprotect all vfb's // EnterCriticalSection(&cs_cache_V); for (CachedVideoFrame* i = video_frames.next; i != &video_frames; i = i->next) { if (i->vfb->data_size >= data) { if (UnProtectVFB(i)) { UnlockVFB(i); env->ManageCache(MC_PromoteVideoFrameBuffer, i->vfb); _RPT3(0, "Cache:%x: PokeCache UnProtectAll vfb %x, frame %d\n", this, video_frames.next->vfb, video_frames.next->frame_number); } } } // LeaveCriticalSection(&cs_cache_V); break; } default: return; } // Poke the next Cache in the chain if (nextCache) nextCache->PokeCache(key, data, env); }
HRESULT mmSource::OnThreadStartPlay() { _RPT3(_CRT_WARN,"OnThreadStartPlay %d %d %f\n",(int)m_rtStart, (int)m_rtStop, (float)m_dRateSeeking); return DeliverNewSegment(m_rtStart, m_rtStop, m_dRateSeeking); }
DWORD WINAPI cProxyServer::TsReader(LPVOID pv) { stTsReaderArg *pArg = static_cast<stTsReaderArg *>(pv); IBonDriver *pIBon = pArg->pIBon; volatile BOOL &StopTsRead = pArg->StopTsRead; volatile BOOL &ChannelChanged = pArg->ChannelChanged; DWORD &pos = pArg->pos; std::list<cProxyServer *> &TsReceiversList = pArg->TsReceiversList; cCriticalSection &TsLock = pArg->TsLock; DWORD dwSize, dwRemain, now, before = 0; float fSignalLevel = 0; DWORD ret = 300; const DWORD TsPacketBufSize = g_TsPacketBufSize; BYTE *pBuf, *pTsBuf = new BYTE[TsPacketBufSize]; #if _DEBUG && DETAILLOG DWORD Counter = 0; #endif // 内部でCOMを使用しているBonDriverに対する対策 HRESULT hr = ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE | COINIT_SPEED_OVER_MEMORY); // TS読み込みループ while (!StopTsRead) { dwSize = dwRemain = 0; { LOCK(TsLock); if ((((now = ::GetTickCount()) - before) >= 1000) || ChannelChanged) { fSignalLevel = pIBon->GetSignalLevel(); before = now; ChannelChanged = FALSE; } if (pIBon->GetTsStream(&pBuf, &dwSize, &dwRemain) && (dwSize != 0)) { if ((pos + dwSize) < TsPacketBufSize) { ::memcpy(&pTsBuf[pos], pBuf, dwSize); pos += dwSize; if (dwRemain == 0) { for (std::list<cProxyServer *>::iterator it = TsReceiversList.begin(); it != TsReceiversList.end(); ++it) (*it)->makePacket(eGetTsStream, pTsBuf, pos, fSignalLevel); #if _DEBUG && DETAILLOG _RPT3(_CRT_WARN, "makePacket0() : %u : size[%x] / dwRemain[%d]\n", Counter++, pos, dwRemain); #endif pos = 0; } } else { DWORD left, dwLen = TsPacketBufSize - pos; ::memcpy(&pTsBuf[pos], pBuf, dwLen); for (std::list<cProxyServer *>::iterator it = TsReceiversList.begin(); it != TsReceiversList.end(); ++it) (*it)->makePacket(eGetTsStream, pTsBuf, TsPacketBufSize, fSignalLevel); #if _DEBUG && DETAILLOG _RPT3(_CRT_WARN, "makePacket1() : %u : size[%x] / dwRemain[%d]\n", Counter++, TsPacketBufSize, dwRemain); #endif left = dwSize - dwLen; pBuf += dwLen; while (left >= TsPacketBufSize) { for (std::list<cProxyServer *>::iterator it = TsReceiversList.begin(); it != TsReceiversList.end(); ++it) (*it)->makePacket(eGetTsStream, pBuf, TsPacketBufSize, fSignalLevel); #if _DEBUG && DETAILLOG _RPT2(_CRT_WARN, "makePacket2() : %u : size[%x]\n", Counter++, TsPacketBufSize); #endif left -= TsPacketBufSize; pBuf += TsPacketBufSize; } if (left != 0) { if (dwRemain == 0) { for (std::list<cProxyServer *>::iterator it = TsReceiversList.begin(); it != TsReceiversList.end(); ++it) (*it)->makePacket(eGetTsStream, pBuf, left, fSignalLevel); #if _DEBUG && DETAILLOG _RPT3(_CRT_WARN, "makePacket3() : %u : size[%x] / dwRemain[%d]\n", Counter++, left, dwRemain); #endif left = 0; } else ::memcpy(pTsBuf, pBuf, left); } pos = left; } } } if (dwRemain == 0) ::Sleep(WAIT_TIME); } if (SUCCEEDED(hr)) ::CoUninitialize(); delete[] pTsBuf; return ret; }
void IslandGame::loadLevel( const char *filename ) { TiXmlDocument *xmlDoc = new TiXmlDocument( filename ); // clear the level clearLevel(); if (!xmlDoc->LoadFile() ) { errorMessage("ERR! Can't load %s\n", filename ); } TiXmlElement *xLevel; TiXmlNode *xText; xLevel = xmlDoc->FirstChildElement( "level" ); assert( xLevel ); m_mapName = xLevel->Attribute( "isleName" ); m_mapText = xLevel->Attribute( "intro" ); showHudText( m_mapName, m_mapText ); const char *waterTex = xLevel->Attribute( "water" ); if (waterTex) { char buff[200]; sprintf( buff, "gamedata/%s.png", waterTex ); m_waterTexId = loadTexture( buff ); } else { m_waterTexId = loadTexture( "gamedata/water.png", 4 ); } // Get width and height TiXmlElement *xTag; xTag = xLevel->FirstChildElement( "width" ); xText = xTag->FirstChild(); m_mapSizeX = atoi( xText->Value() ) / 16; xTag = xLevel->FirstChildElement( "height" ); xText = xTag->FirstChild(); m_mapSizeY = atoi( xText->Value() ) / 16; // Load elevations TiXmlElement *xTile; TiXmlElement *xElevTiles = xLevel->FirstChildElement( "elevTiles" ); xTile = xElevTiles->FirstChildElement( "tile" ); while (xTile) { int id, xpos, ypos; id = atoi( xTile->Attribute( "id" ) ); xpos = atoi( xTile->Attribute( "x" ) ) / 16; ypos = atoi( xTile->Attribute( "y" ) ) / 16; xTile = xTile->NextSiblingElement( "tile" ); MapSquare &m = m_map[xpos][ypos]; m.m_elevation = id; m.m_terrain = 0; // TODO get from terrain tileset } // Load terrain indices TiXmlElement *xTerrainTiles = xLevel->FirstChildElement( "terrainTiles" ); xTile = xTerrainTiles->FirstChildElement( "tile" ); while (xTile) { int id, xpos, ypos; id = atoi( xTile->Attribute( "id" ) ); xpos = atoi( xTile->Attribute( "x" ) ) / 16; ypos = atoi( xTile->Attribute( "y" ) ) / 16; _RPT3( _CRT_WARN, "loc %d %d id %d\n", xpos, ypos, id ); xTile = xTile->NextSiblingElement( "tile" ); MapSquare &m = m_map[xpos][ypos]; m.m_terrain = id; } // Load actors TiXmlElement *xActorLayer = xLevel->FirstChildElement( "actors" ); // Get the player start pos TiXmlElement *xActor = xActorLayer->FirstChildElement( "pstart" ); m_px = atoi( xActor->Attribute( "x" ) ) / 16; m_py = atoi( xActor->Attribute( "y" ) ) / 16; m_camTarg = vec3f( m_px + 0.5f, (m_map[m_px][m_py].m_elevation+1.0) * 0.3f, m_py + 0.5f ); m_camPos = m_camTarg; // first, make sure all master critters are loaded xActor = xActorLayer->FirstChildElement( "critter" ); while (xActor) { // If this is the master copy of the critter, load it if (!strcmp( xActor->Attribute("master"), "true" ) ) { Critter *mcrit = NULL; std::string critKey = xActor->Attribute("displayName" ); std::transform( critKey.begin(), critKey.end(), critKey.begin(), toupper ); // is it in the master list? if ( m_masterCritter.find( critKey ) == m_masterCritter.end() ) { // Nope, load it mcrit = new Critter(); mcrit->m_displayName = xActor->Attribute( "displayName" ); mcrit->m_level = atoi( xActor->Attribute( "level" ) ); mcrit->m_name = atoi( xActor->Attribute( "map" ) ); mcrit->m_behavior = atoi( xActor->Attribute( "behave" ) ); // DBG: mcrit->m_behavior = BEHAVIOR_SEEK_PLAYER; char buff[1000]; sprintf( buff, "gamedata/critter_%s.png", xActor->Attribute( "map" ) ); mcrit->m_critterTex = loadTexture( buff, 4 ); // store in master list m_masterCritter[ critKey ] = mcrit; } } xActor = xActor->NextSiblingElement( "critter" ); } // Now go through all the critters again and create them for (std::vector<Critter*>::iterator ci = m_critters.begin(); ci != m_critters.end(); ++ci ) { delete *ci; } //m_critters.clear( m_critters.begin(), m_critters.end() ); m_critters.clear(); xActor = xActorLayer->FirstChildElement( "critter" ); while (xActor) { Critter *mcrit = NULL; std::string critKey = xActor->Attribute("displayName" ); std::transform( critKey.begin(), critKey.end(), critKey.begin(), toupper ); std::map<std::string, Critter*>::iterator mcriti = m_masterCritter.find( critKey ); if ( mcriti == m_masterCritter.end() ) { DBG::warn( "Couldn't find master critter: %s\n", critKey.c_str() ); } else { mcrit = (*mcriti).second; Critter *crit = new Critter(); *crit = *mcrit; crit->m_x = atoi( xActor->Attribute( "x" ) ) / 16; crit->m_y = atoi( xActor->Attribute( "y" ) ) / 16; crit->m_dir = rand() % 4; m_critters.push_back( crit ); } xActor = xActor->NextSiblingElement( "critter" ); } // Now, load all the NPCs... npcs are simpler than critters for (std::vector<Npc*>::iterator ci = m_npcs.begin(); ci != m_npcs.end(); ++ci ) { delete *ci; } m_npcs.clear(); xActor = xActorLayer->FirstChildElement( "npc" ); while (xActor) { Npc *npc = new Npc(); npc->m_x = atoi( xActor->Attribute( "x" ) ) / 16; npc->m_y = atoi( xActor->Attribute( "y" ) ) / 16; npc->m_displayName = xActor->Attribute("displayName" ); npc->m_name = xActor->Attribute( "map" ); npc->m_speech = xActor->Attribute( "speech" ); char buff[1000]; sprintf( buff, "gamedata/npc_%s.png", xActor->Attribute( "map" ) ); npc->m_personTex = loadTexture( buff, 4 ); m_npcs.push_back( npc ); xActor = xActor->NextSiblingElement( "npc" ); } // Finally, fill in any portal info xActor = xActorLayer->FirstChildElement( "portal" ); while (xActor) { int x = atoi( xActor->Attribute( "x" ) ) / 16; int y = atoi( xActor->Attribute( "y" ) ) / 16; m_map[x][y].m_portal = strdup( xActor->Attribute("dest") ); xActor = xActor->NextSiblingElement( "portal" ); } // And finally, rebuild the graphics buildMap(); }