const char* Backtrace::GetMapName(uintptr_t pc, uintptr_t* map_start) { const backtrace_map_info_t* map_info = FindMapInfo(pc); if (map_info) { if (map_start) { *map_start = map_info->start; } return map_info->name; } return NULL; }
bool BacktraceCurrent::ReadWord(uintptr_t ptr, uint32_t* out_value) { if (!VerifyReadWordArgs(ptr, out_value)) { return false; } const backtrace_map_info_t* map_info = FindMapInfo(ptr); if (map_info && map_info->is_readable) { *out_value = *reinterpret_cast<uint32_t*>(ptr); return true; } else { BACK_LOGW("pointer %p not in a readable map", reinterpret_cast<void*>(ptr)); *out_value = static_cast<uint32_t>(-1); return false; } }
// ticks the game forward in time void GameInfo::Ticker() { tic++; // TODO read/write demo ticcmd's here // do main actions switch (state) { case GS_INTRO: if (--pagetic <= 0) AdvanceIntro(); break; case GS_LEVEL: if (!paused && currentcluster) currentcluster->Ticker(); if (!dedicated) { hud.Ticker(); automap.Ticker(); } break; case GS_INTERMISSION: wi.Ticker(); break; case GS_FINALE: F_Ticker(); break; case GS_NULL: default: // do nothing break; } MapInfo *m; PlayerInfo *p; if (state != GS_LEVEL) return; // manage players for (player_iter_t t = Players.begin(); t != Players.end(); ) { p = t->second; t++; // because "old t" may be invalidated if (p->playerstate == PST_REMOVE) { // the player is removed from the game (invalidates "old t") if (!p->mp) RemovePlayer(p->number); // first the maps throw out the removed player, then the game proper. // TODO purge the removed players from the frag maps of other players? } else p->Ticker(); } if (!server) return; // for (player_iter_t t = Players.begin(); t != Players.end(); t++) { p = t->second; if (p->playerstate == PST_NEEDMAP) { LConnection *conn = p->connection; if (conn && !conn->isGhostAvailable(p)) { // remote player, is it already being ghosted? if not, wait. CONS_Printf(" server waiting for client ghost\n"); continue; } // assign the player to a map CONS_Printf("Map request.."); if (p->requestmap == 0) { m = initial_map; // first map in game p->entrypoint = initial_ep; } else m = FindMapInfo(p->requestmap); if (!m) { // game ends currentcluster->Finish(p->requestmap, p->entrypoint); StartFinale(NULL); break; } else if (!m->found) m = currentcluster->maps[0]; // TODO or give an error? // cluster change? if (currentcluster->number != m->cluster) { // TODO minor thing: if several players exit maps on the same tick, // and someone besides the first one causes a cluster change, some // maps could be loaded in vain... // cluster change! currentcluster->Finish(p->requestmap, p->entrypoint); MapCluster *next = FindCluster(m->cluster); StartFinale(next); currentcluster = next; break; // this is important! no need to check the other players. } p->Reset(!currentcluster->keepstuff, true); // normal individual mapchange if (!m->Activate(p)) I_Error("Darn!\n"); if (conn) { CONS_Printf(" server sending rpc\n"); // nonlocal player enters a new map, notify client // send the EnterMap rpc only to the owning connection NetEvent *e = TNL_RPC_CONSTRUCT_NETEVENT(p, s2cEnterMap, (m->mapnumber)); conn->postNetEvent(e); } } } }