// The takeCensus function works in three phases: // // 1) We examine the 'breakdown' property of our 'options' argument, and // use that to build a CountType tree. // // 2) We create a count node for the root of our CountType tree, and then walk // the heap, counting each node we find, expanding our tree of counts as we // go. // // 3) We walk the tree of counts and produce JavaScript objects reporting the // accumulated results. bool DebuggerMemory::takeCensus(JSContext* cx, unsigned argc, Value* vp) { THIS_DEBUGGER_MEMORY(cx, argc, vp, "Debugger.Memory.prototype.census", args, memory); Census census(cx); if (!census.init()) return false; CountTypePtr rootType; RootedObject options(cx); if (args.get(0).isObject()) options = &args[0].toObject(); if (!JS::ubi::ParseCensusOptions(cx, census, options, rootType)) return false; JS::ubi::RootedCount rootCount(cx, rootType->makeCount()); if (!rootCount) return false; JS::ubi::CensusHandler handler(census, rootCount); Debugger* dbg = memory->getDebugger(); RootedObject dbgObj(cx, dbg->object); // Populate our target set of debuggee zones. for (WeakGlobalObjectSet::Range r = dbg->allDebuggees(); !r.empty(); r.popFront()) { if (!census.targetZones.put(r.front()->zone())) return false; } { Maybe<JS::AutoCheckCannotGC> maybeNoGC; JS::ubi::RootList rootList(cx->runtime(), maybeNoGC); if (!rootList.init(dbgObj)) { ReportOutOfMemory(cx); return false; } JS::ubi::CensusTraversal traversal(cx->runtime(), handler, maybeNoGC.ref()); if (!traversal.init()) { ReportOutOfMemory(cx); return false; } traversal.wantNames = false; if (!traversal.addStart(JS::ubi::Node(&rootList)) || !traversal.traverse()) { ReportOutOfMemory(cx); return false; } } return handler.report(args.rval()); }
/** * Debugs the given SVM class * @param argc the given number of arguments * @param argv the given arguments */ int Main::debug( int argc, char* argv[] ) { // cache the class name const char* classname = argv[2]; // startup the virtual machine Debugger *debugger = new Debugger(); // execute/debug the class return debugger->debug( classname, argc, argv ); }
void closer (t_Tracer_OpenTr *open) { Debugger *c; PROCESS_INFORMATION ProcInfo; char bla[30]; if (open->Definition->Name == "CreateProcessA") { printf("MAIN: Process created (CreateProcessA)\n"); if (!ReadProcessMemory(dbg.getProcessHandle(), (LPCVOID)(open->OutArgs[9].data.address), &ProcInfo, sizeof(ProcInfo), NULL)) { printf("Failed to read process memory at %08X\n", open->OutArgs[9].data.address); } else { c = new (Debugger); sprintf(bla,"Child %u",ProcInfo.dwProcessId); c->attach(ProcInfo.dwProcessId); c->log.Name= bla; Children.push_back(c); } } else if (open->Definition->Name == "CreateProcessAsUserA") { printf("MAIN: Process created (CreateProcessAsUserA)\n"); if (!ReadProcessMemory(dbg.getProcessHandle(), (LPCVOID)(open->OutArgs[10].data.address), &ProcInfo, sizeof(ProcInfo), NULL)) { printf("Failed to read process memory at %08X\n", open->OutArgs[10].data.address); } else { c = new (Debugger); sprintf(bla,"Child %u",ProcInfo.dwProcessId); c->attach(ProcInfo.dwProcessId); c->log.Name= bla; Children.push_back(c); } } }
//static QList<Debugger> Debugger::availableDebuggers(const QString & path, const QString & backend) { QString debuggerDir = QStandardPaths::locate(QStandardPaths::DataLocation, path, QStandardPaths::LocateDirectory); QStringList debuggers = QDir(debuggerDir).entryList(QDir::Files); QList<Debugger> result; foreach (const QString & debuggerFile, debuggers) { Debugger debugger; if (debugger.supportedBackends().contains(backend)) { debugger.setUsedBackend(backend); result.append(debugger); } }
lldb::ProcessSP PlatformRemoteGDBServer::Attach( ProcessAttachInfo &attach_info, Debugger &debugger, Target *target, // Can be NULL, if NULL create a new target, else use // existing one Error &error) { lldb::ProcessSP process_sp; if (IsRemote()) { if (IsConnected()) { lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID; std::string connect_url; if (!LaunchGDBServer(debugserver_pid, connect_url)) { error.SetErrorStringWithFormat("unable to launch a GDB server on '%s'", GetHostname()); } else { if (target == NULL) { TargetSP new_target_sp; error = debugger.GetTargetList().CreateTarget( debugger, NULL, NULL, false, NULL, new_target_sp); target = new_target_sp.get(); } else error.Clear(); if (target && error.Success()) { debugger.GetTargetList().SetSelectedTarget(target); // The darwin always currently uses the GDB remote debugger plug-in // so even when debugging locally we are debugging remotely! process_sp = target->CreateProcess( attach_info.GetListenerForProcess(debugger), "gdb-remote", NULL); if (process_sp) { error = process_sp->ConnectRemote(nullptr, connect_url.c_str()); if (error.Success()) { ListenerSP listener_sp = attach_info.GetHijackListener(); if (listener_sp) process_sp->HijackProcessEvents(listener_sp); error = process_sp->Attach(attach_info); } if (error.Fail() && debugserver_pid != LLDB_INVALID_PROCESS_ID) { KillSpawnedProcess(debugserver_pid); } } } } } else { error.SetErrorString("not connected to remote gdb server"); } } return process_sp; }
static cell AMX_NATIVE_CALL dbg_trace_next(AMX *amx, cell *params) { Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER]; if (!pDebugger) return 0; trace_info_t *pTrace = (trace_info_t *)(params[1]); if (pTrace) return (cell)(pDebugger->GetNextTrace(pTrace)); return 0; }
ErrorObject::ErrorObject(const Object& proto, ErrorType t, const char *m, int l) : ConstructorImp(proto, 1), errType(t) { const char *n = errName[errType]; put("name", String(n)); put("message", String(m)); put("line", Number(l)); #ifdef KJS_DEBUGGER Debugger *dbg = KJScriptImp::current()->debugger(); if (dbg) put("sid", Number(dbg->sourceId())); #endif }
lldb::ProcessSP PlatformWindows::Attach(ProcessAttachInfo &attach_info, Debugger &debugger, Target *target, Listener &listener, Error &error) { lldb::ProcessSP process_sp; if (IsHost()) { if (target == NULL) { TargetSP new_target_sp; FileSpec emptyFileSpec; ArchSpec emptyArchSpec; error = debugger.GetTargetList().CreateTarget (debugger, NULL, NULL, false, NULL, new_target_sp); target = new_target_sp.get(); } else error.Clear(); if (target && error.Success()) { debugger.GetTargetList().SetSelectedTarget(target); // The Windows platform always currently uses the GDB remote debugger plug-in // so even when debugging locally we are debugging remotely! // Just like the darwin plugin. process_sp = target->CreateProcess (listener, "gdb-remote", NULL); if (process_sp) error = process_sp->Attach (attach_info); } } else { if (m_remote_platform_sp) process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error); else error.SetErrorString ("the platform is not currently connected"); } return process_sp; }
lldb::ProcessSP PlatformLinux::Attach(ProcessAttachInfo &attach_info, Debugger &debugger, Target *target, Listener &listener, Error &error) { lldb::ProcessSP process_sp; if (IsHost()) { if (target == NULL) { TargetSP new_target_sp; FileSpec emptyFileSpec; ArchSpec emptyArchSpec; error = debugger.GetTargetList().CreateTarget (debugger, emptyFileSpec, emptyArchSpec, false, m_remote_platform_sp, new_target_sp); target = new_target_sp.get(); } else error.Clear(); if (target && error.Success()) { debugger.GetTargetList().SetSelectedTarget(target); process_sp = target->CreateProcess (listener, attach_info.GetProcessPluginName(), NULL); if (process_sp) error = process_sp->Attach (attach_info); } } else { if (m_remote_platform_sp) process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, listener, error); else error.SetErrorString ("the platform is not currently connected"); } return process_sp; }
void execute_on_main_thread() { const size_t nwords = round_to_word(ui::Const::asm_window_size); buffer_.resize(nwords * sizeof(word_t)); word_t* wordBuf = reinterpret_cast<word_t*>(&buffer_[0]); thread_->read_code(start_->addr(), wordBuf, nwords); Debugger* debugger = CHKPTR(thread_->debugger()); debugger->disassemble( thread_.get(), start_.get(), buffer_.size(), false, /* include source code in listing? */ &buffer_[0], this); }
void ReportFreeMem(void) { #ifndef NDEBUG char string1[80]; int loop1, int1, int2; sprintf(string1, "\nAvail() %luk Largest() %luk HeapCheck() ", pMemMgr->AvailMem() / 1024, pMemMgr->LargestAlloc() / 1024); pMono->Out(string1); BamDebug.Out(string1); pMemMgr->HeapCheck(); pMono->Out("OK\n"); BamDebug.Out("OK\n"); if(pWorld) { strcpy(string1, "UNITLIB: "); for(loop1 = 0, int1 = 0; loop1 < TOTAL_SIDES; loop1++) { int2 = pWorld->unitLib.lUnits[loop1].count; int1 += int2; sprintf(&string1[strlen(string1)], "[%d]%d ", loop1, int2); } strcat(string1, "\n"); pMono->Out(string1); BamDebug.Out(string1); int1 = pWorld->vPort.highestAnim; for(loop1 = 0, int2 = 0; loop1 <= int1; loop1++) if(pWorld->vPort.gAnims[loop1]) int2++; sprintf(string1, "VPORT: highest %d(of %d) total %d empty %d\n", int1, GANIMS_MAX, int2, int1 - (int2 - 1)); pMono->Out(string1); BamDebug.Out(string1); } pMono->Out("ResMgr memory useage:\n"); pMono->Out("RES_ANIM %dk\n", pResMgr->ReportUseage(RES_ANIM)); pMono->Out("RES_DAC %dk\n", pResMgr->ReportUseage(RES_DAC)); pMono->Out("other ???k\n"); pMono->Out("total %dk\n", pResMgr->ReportUseage(RES_LAST)); #endif }
/** * @brief * @param * @see * @remarks * @code * @endcode * @return **/ DWORD __stdcall DebugCoreCallback(_In_ const DEBUG_EVENT* debug_event, _In_ DWORD_PTR tag) { _ASSERTE(NULL != debug_event); _ASSERTE(NULL != tag); if (NULL == debug_event || NULL == tag) return DBG_EXCEPTION_NOT_HANDLED; Debugger* debugger = (Debugger*) tag; DWORD ret = debugger->handle_debug_event(debug_event); //> debuggee is terminating if (EXIT_PROCESS_DEBUG_EVENT == debug_event->dwDebugEventCode) { debugger->stop(); } return ret; }
lldb::ProcessSP PlatformWindows::Attach(ProcessAttachInfo &attach_info, Debugger &debugger, Target *target, Error &error) { error.Clear(); lldb::ProcessSP process_sp; if (!IsHost()) { if (m_remote_platform_sp) process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error); else error.SetErrorString ("the platform is not currently connected"); return process_sp; } if (target == nullptr) { TargetSP new_target_sp; FileSpec emptyFileSpec; ArchSpec emptyArchSpec; error = debugger.GetTargetList().CreateTarget(debugger, nullptr, nullptr, false, nullptr, new_target_sp); target = new_target_sp.get(); } if (!target || error.Fail()) return process_sp; debugger.GetTargetList().SetSelectedTarget(target); const char *plugin_name = attach_info.GetProcessPluginName(); process_sp = target->CreateProcess(attach_info.GetListenerForProcess(debugger), plugin_name, nullptr); process_sp->HijackProcessEvents(attach_info.GetHijackListener()); if (process_sp) error = process_sp->Attach (attach_info); return process_sp; }
ListenerSP ProcessLaunchInfo::GetListenerForProcess (Debugger &debugger) { if (m_listener_sp) return m_listener_sp; else return debugger.GetListener(); }
void Debugger::handleMessage(DebugMessage *msg) { gLog->debug("Handling message {}", (int)msg->type()); switch (msg->type()) { case DebugMessageType::DebuggerDc: { gDebugControl.pauseAll(); gLog->debug("Debugger disconnected, game paused to wait for debugger."); gDebugControl.waitForAllPaused(); while (!gDebugNet.connect()) { std::this_thread::sleep_for(std::chrono::milliseconds(400)); } gDebugNet.writePaused(); break; } case DebugMessageType::PreLaunch: { gDebugControl.waitForAllPaused(); gLog->debug("Prelaunch Occured"); gDebugNet.writePrelaunch(); break; } case DebugMessageType::BpHit: { auto bpMsg = reinterpret_cast<DebugMessageBpHit*>(msg); gDebugControl.waitForAllPaused(); if (bpMsg->userData == 0xFFFFFFFF) { // Temporary step-over breakpoint gDebugger.removeBreakpoint(bpMsg->address); gLog->debug("StepOver BP Hit on Core #{}", bpMsg->coreId); gDebugNet.writeCoreStepped(bpMsg->coreId); } else { gLog->debug("Breakpoint Hit on Core #{}", bpMsg->coreId); gDebugNet.writeBreakpointHit(bpMsg->coreId, bpMsg->userData); } break; } case DebugMessageType::CoreStepped: { auto bpMsg = reinterpret_cast<DebugMessageCoreStepped*>(msg); gDebugControl.waitForAllPaused(); gLog->debug("Core #{} Stepped", bpMsg->coreId); gDebugNet.writeCoreStepped(bpMsg->coreId); break; } } }
/** * Takes the active breakpoints to create a map that is used to count * breakpoint hits and how much time is spent in blocks. **/ std::map<Offset, TimedBlock*> initBlockMap() { std::map<Offset, TimedBlock*> timedBlocks; IdaFile file = IdaFile(); Debugger debugger = file.getDebugger(); // Initialize the time of each basic block to 0 for (unsigned int i=0;i<debugger.getNumberOfBreakpoints();i++) { Breakpoint bp = debugger.getBreakpoint(i); Offset breakpointAddress = bp.getAddress(); timedBlocks[breakpointAddress] = new TimedBlock(breakpointAddress); } return timedBlocks; }
int AMXAPI Debugger::DebugHook(AMX *amx) { Debugger *pDebugger = NULL; if (!amx || !(amx->flags & AMX_FLAG_DEBUG)) return AMX_ERR_NONE; if (amx->flags & AMX_FLAG_PRENIT) return AMX_ERR_NONE; pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER]; if (!pDebugger) return AMX_ERR_NONE; pDebugger->StepI(); return AMX_ERR_NONE; }
JsValueRef WScriptJsrt::DetachCallback(JsValueRef callee, bool isConstructCall, JsValueRef *arguments, unsigned short argumentCount, void *callbackState) { LPCWSTR errorMessage = _u("WScript.Detach requires a function, like WScript.Detach(foo);"); JsValueType argumentType = JsUndefined; if (argumentCount != 2) { goto Error; } IfJsrtError(ChakraRTInterface::JsGetValueType(arguments[1], &argumentType)); if (argumentType != JsFunction) { goto Error; } QueueDebugOperation(arguments[1], [](WScriptJsrt::CallbackMessage& msg) { JsContextRef currentContext = JS_INVALID_REFERENCE; ChakraRTInterface::JsGetCurrentContext(¤tContext); JsRuntimeHandle currentRuntime = JS_INVALID_RUNTIME_HANDLE; ChakraRTInterface::JsGetRuntime(currentContext, ¤tRuntime); if (Debugger::debugger != nullptr) { Debugger* debugger = Debugger::GetDebugger(currentRuntime); debugger->StopDebugging(currentRuntime); } return msg.CallFunction(""); }); Error: JsValueRef errorObject; JsValueRef errorMessageString; ERROR_MESSAGE_TO_STRING(errorCode, errorMessage, errorMessageString); if (errorCode != JsNoError) { errorCode = ChakraRTInterface::JsCreateError(errorMessageString, &errorObject); if (errorCode != JsNoError) { ChakraRTInterface::JsSetException(errorObject); } } return JS_INVALID_REFERENCE; }
/* static */ bool DebuggerMemory::setTrackingAllocationSites(JSContext *cx, unsigned argc, Value *vp) { THIS_DEBUGGER_MEMORY(cx, argc, vp, "(set trackingAllocationSites)", args, memory); if (!args.requireAtLeast(cx, "(set trackingAllocationSites)", 1)) return false; Debugger *dbg = memory->getDebugger(); bool enabling = ToBoolean(args[0]); if (enabling == dbg->trackingAllocationSites) { // Nothing to do here... args.rval().setUndefined(); return true; } if (enabling) { for (GlobalObjectSet::Range r = dbg->debuggees.all(); !r.empty(); r.popFront()) { JSCompartment *compartment = r.front()->compartment(); if (compartment->hasObjectMetadataCallback()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET); return false; } } } for (GlobalObjectSet::Range r = dbg->debuggees.all(); !r.empty(); r.popFront()) { if (enabling) { r.front()->compartment()->setObjectMetadataCallback(SavedStacksMetadataCallback); } else { r.front()->compartment()->forgetObjectMetadataCallback(); } } if (!enabling) dbg->emptyAllocationsLog(); dbg->trackingAllocationSites = enabling; args.rval().setUndefined(); return true; }
int main(int argc, char **argv) { ros::init(argc, argv, "controller_debugger"); ros::NodeHandle node_handle; Debugger debugger; ros::Subscriber cte_subscriber = node_handle.subscribe("controller/cross_track_error", 2, &Debugger::updateCTEPlotData, &debugger); ros::Subscriber pose_subscriber = node_handle.subscribe("localization/pose", 2, &Debugger::updateCurrentPath, &debugger); ros::Subscriber path_subscriber = node_handle.subscribe("local_planner/path", 2, &Debugger::updateTargetPath, &debugger); ros::Rate loop_rate(100); while (ros::ok()) { int debug_mode = 0; node_handle.getParam("/controller_debugger/debug_mode", debug_mode); debugger.display(debug_mode); ros::spinOnce(); loop_rate.sleep(); } }
void JSCompartment::updateDebuggerObservesFlag(unsigned flag) { MOZ_ASSERT(isDebuggee()); MOZ_ASSERT(flag == DebuggerObservesAllExecution || flag == DebuggerObservesAsmJS); const GlobalObject::DebuggerVector *v = maybeGlobal()->getDebuggers(); for (Debugger * const *p = v->begin(); p != v->end(); p++) { Debugger *dbg = *p; if (flag == DebuggerObservesAllExecution ? dbg->observesAllExecution() : dbg->observesAsmJS()) { debugModeBits |= flag; return; } } debugModeBits &= ~flag; }
int main(int argc, const char* const* argv) { // We test-parse the arguments here, so, when we're started from the // terminal and there's an instance already running, we can print an error // message to the terminal, if something's wrong with the arguments. { Options options; parse_arguments(argc, argv, false, options); } Debugger app; status_t error = app.Init(); if (error != B_OK) { fprintf(stderr, "Error: Failed to init application: %s\n", strerror(error)); return 1; } app.Run(); return 0; }
static cell AMX_NATIVE_CALL dbg_trace_info(AMX *amx, cell *params) { Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER]; if (!pDebugger) return 0; trace_info_t *pTrace = (trace_info_t *)(params[1]); if (!pTrace) return 0; cell *line_addr = get_amxaddr(amx, params[2]); long lLine=-1; const char *function=NULL, *file=NULL; pDebugger->GetTraceInfo(pTrace, lLine, function, file); set_amxstring(amx, params[3], function ? function : "", params[4]); set_amxstring(amx, params[5], file ? file : "", params[5]); *line_addr = (cell)lLine + 1; return 1; }
// Return random between 0 and range-1 int ARandomDebug(int range, int line, char *file) { #ifndef NDEBUG BamDebug.Out("#%d@%d ARand(%d)l%d %s\n", bGlobal.randGenCalls, ATicks(), range, line, file); bGlobal.randGenCalls++; return bGlobal.randGen.GetNumber(range); #else range = range; line = line; file = file; APanic("ARandomDebug() called w/ #NDEBUG!\n"); return(0); #endif }
void IDAP_run(int) { IdaFile file; msg("Starting to profile %s\n", file.getName().c_str()); Debugger debugger = file.getDebugger(); debugger.addEventCallback(&debuggerCallback, new UserData); if (debugger.isActive() && !debugger.isSuspended()) { // If the target process is already running, suspend it to set the breakpoints msg("Suspending the target process...\n"); debugger.suspendProcess(true); } else if (debugger.isActive() && debugger.isSuspended()) { // If the target is already suspended, set the breakpoints and resume the process. setBreakpoints(); debugger.resumeProcess(true); } else { // If the debugger is not yet running, set the breakpoints and start the process. setBreakpoints(); msg("Starting target process\n"); debugger.startProcess(file.getInputfilePath(), "", ""); } }
HeapView::HeapView(Debugger& debugger, ProgramView& view) : DialogBox(btn_ok, "Heap View") , debugger_(debugger) , view_(view) , heap_(0) , box_(manage(new Gtk::VBox)) , label_(manage(new Gtk::Label("", .0))) , tree_(0) { get_vbox()->add(*box_); box_->pack_start(*label_, false, false); sortType_[0] = sortType_[1] = GTK_SORT_ASCENDING; debugger.enum_plugins(this); if (!heap_) { CHKPTR(label_)->set_text("Heap plugin not active."); } box_->set_border_width(10); Gtk_set_resizable(this, true); }
bool Debugger::debuggerCompletionCallback(GUI::ConsoleDialog *console, const char *input, Common::String &completion, void *refCon) { Debugger *debugger = (Debugger *)refCon; return debugger->tabComplete(input, completion); }
bool Debugger::debuggerInputCallback(GUI::ConsoleDialog *console, const char *input, void *refCon) { Debugger *debugger = (Debugger *)refCon; return debugger->parseCommand(input); }
bool SwiftREPL::PrintOneVariable (Debugger &debugger, StreamFileSP &output_sp, ValueObjectSP &valobj_sp, ExpressionVariable *var) { bool is_computed = false; if (var) { if (lldb::ValueObjectSP valobj_sp = var->GetValueObject()) { Flags valobj_type_flags(valobj_sp->GetCompilerType().GetTypeInfo()); const bool is_swift(valobj_type_flags.AllSet(eTypeIsSwift)); if ((var->GetName().AsCString("anonymous")[0] != '$') && is_swift) { is_computed = llvm::cast<SwiftExpressionVariable>(var)->GetIsComputed(); } else { return false; } } else { return false; } } const bool colorize_out = output_sp->GetFile().GetIsTerminalWithColors(); bool handled = false; Format format = m_format_options.GetFormat(); bool treat_as_void = (format == eFormatVoid); // if we are asked to suppress void, check if this is the empty tuple type, and if so suppress it if (!treat_as_void && !debugger.GetNotifyVoid()) { const CompilerType &expr_type(valobj_sp->GetCompilerType()); Flags expr_type_flags(expr_type.GetTypeInfo()); if (expr_type_flags.AllSet(eTypeIsSwift | eTypeIsTuple)) { treat_as_void = (expr_type.GetNumFields() == 0); } } if (!treat_as_void) { if (format != eFormatDefault) valobj_sp->SetFormat (format); DumpValueObjectOptions options; options.SetUseDynamicType(lldb::eDynamicCanRunTarget); options.SetMaximumPointerDepth( {DumpValueObjectOptions::PointerDepth::Mode::Formatters,1} ); options.SetUseSyntheticValue(true); options.SetRevealEmptyAggregates(false); options.SetHidePointerValue(true); options.SetVariableFormatDisplayLanguage(lldb::eLanguageTypeSwift); options.SetDeclPrintingHelper ([] (ConstString type_name, ConstString var_name, const DumpValueObjectOptions &options, Stream &stream) -> bool { if (!type_name || !var_name) return false; std::string type_name_str(type_name ? type_name.GetCString() : ""); for(auto iter = type_name_str.find(" *"); iter != std::string::npos; iter = type_name_str.find(" *")) { type_name_str.erase(iter, 2); } if (!type_name_str.empty()) { stream.Printf("%s: %s =", var_name.GetCString(), type_name_str.c_str()); return true; } return false; }); if (is_computed) { StringSummaryFormat::Flags flags; flags.SetDontShowChildren(true); flags.SetDontShowValue(true); flags.SetHideItemNames(true); flags.SetShowMembersOneLiner(false); flags.SetSkipPointers(false); flags.SetSkipReferences(false); options.SetHideValue(true); options.SetShowSummary(true); options.SetSummary(lldb::TypeSummaryImplSP(new StringSummaryFormat(flags,"<computed property>"))); } if (colorize_out) { const char *color = isThrownError(valobj_sp) ? ANSI_ESCAPE1(ANSI_FG_COLOR_RED) : ANSI_ESCAPE1(ANSI_FG_COLOR_CYAN); fprintf(output_sp->GetFile().GetStream(), "%s", color); } valobj_sp->Dump(*output_sp, options); if (colorize_out) fprintf(output_sp->GetFile().GetStream(), ANSI_ESCAPE1(ANSI_CTRL_NORMAL)); handled = true; } return handled; }
int main(int argc, char** argv) { char mess[100], *string1; uint16 saverResult; int loop1, loop2, framesRun, framesPerSec = 0; bool fWaitToSend; BAM_WorldEnderPopup *pWEPop; FILE *pFile; // Nothing *pNothing1 = new Nothing; // NothingMore *pNothingMore1 = new NothingMore; // Dummy *pDummy1 = new Dummy(0x1234); // pNothing1->SetValue(0x1234); // pNothingMore1->SetValue(0x5678); // pDummy1->SetValue(0x90ab); // Unit *pUnit = new Unit(TRUE); // Unit unit1(TRUE); /* Jay - here's the code for the test case you said you wanted to try next: pFile = fopen("unit1.dat", "wb"); fwrite(&unit1, 1, sizeof(unit1), pFile); fclose(pFile); */ /* pFile = fopen("unit1.dat", "rb"); fread(&unit1, 1, sizeof(unit1), pFile); fclose(pFile); */ time_t startTime, timeDif, lastTime; time(&startTime); lastTime = startTime; // disable critical error handler _harderr(critical_error_handler); AInitializePlatform(); #ifndef NDEBUG printf("\n\n&ReportFreeMem==0x%08X\n", (int)ReportFreeMem); #endif #ifdef OS_DOS printf("\nBLOOD & MAGIC Copyright (C) 1996 by Tachyon Studios Inc..\n"); printf("Developed by Tachyon Studios for Interplay Productions.\n"); printf("BLOOD & MAGIC, FORGOTTEN REALMS and the TSR LOGO are Trademarks\n"); printf("owned by TSR, Inc and are used under license.\n"); printf("\nCompiled %s %s\n", __DATE__, __TIME__); printf("%dk free after platform initialization\n", AAvailMem() / 1024); if(AAvailMem() < MIN_MEM_REQ) { printf("\nWARNING: Free XMS memory is low (<%dk)!\nBAM may not run reliably\n", MIN_MEM_REQ / 1000); sleep(4); } #endif // short-circuit any command line args // argc = 1; if(argc > 1 && (!memcmp(argv[1], "?", 2) || !memcmp(argv[1], "-HELP", 6))) { // printf("Format: BAM [mapNum] [-NOINTRO] [-NOFOG] [-SIDEx] [-NOWIN] [-NET] [-SHOWOFF]\n"); return(0); } // if the seed is the same, the sequence will repeat. cool! // ASeedRandom(41); // for repeatability of bugs // ASeedRandom2(41); // for repeatability of bugs ASeedRandom(startTime); // for genuine randomness ASeedRandom2(startTime); // for genuine randomness // If you ever don't want to see unfreed memory, like for demos, // then uncomment this. // extern bool fPrintUnfreedPtrs; // fPrintUnfreedPtrs = FALSE; TRACK_MEM("Mono"); pMono = new Mono; // if we really must allocate this on the fly instead of // having it global, then we must tell the memmgr not to save it. ASetSaveStatus(AGetGrip(pMono), FALSE); // also, we don't want this to be purged on a restore. ASetPurgeStatus(AGetGrip(pMono), FALSE); pMono->SetWindow(0, 7, 79, 12); pMono->Clear(); pMono->Out("Monochrome output initialized\n"); #ifndef NDBEUG pMono->Out("&ReportFreeMem==0x%08X\n", (int)ReportFreeMem); sleep(4); #endif pMono->Out("EventMgr initializing\n"); TRACK_MEM("EventMgr"); new EventMgr; // we are going to update ticks when we want to. AAutoUpdateTicks(FALSE); pMono->Out("ContextMgr initializing\n"); TRACK_MEM("ContextMgr"); new ContextMgr; pMono->Out("ResMgr initializing\n"); TRACK_MEM("ResMgr"); new ResourceMgr(TRUE); // NOTE - IT IS HIGHLY RECOMMENDED THAT YOU INIT THE SOUND MANAGER // BEFORE THE GRAPH MANAGER. If you don't, streamed sounds will // stop and start during restore because of the busy loop in graph // manager that happens when the palette fades up. pMono->Out("SoundMgr initializing\n"); TRACK_MEM("SndMgr"); new SoundMgr; pSoundMgr->Init(); // BUGBUG! If we bind w/ DOS4GW/Pro we will crash here! //setup smacker sound stuff SmackSoundUseSOS3((u16)pSoundMgr->hDigiDriverHandle,0); pMono->Out("GraphMgr initializing\n"); TRACK_MEM("GraphMgr"); pGraphMgr = new GraphicsMgr(MODEX_320X400); pMono->Out("%dk free after platform initialization\n", AAvailMem() / 1024); // Debugger debug1, debug2; // debug1.OpenWindow(0, 0, 79, 10); // debug2.OpenWindow(40, 11, 79, 21); // for(loop1 = 0; loop1 < 25; loop1++) // { // pMono->Out("\n%d", loop1); // } // sleep(2); TRACK_MEM("FontMgr"); pFontMgr = new FontMgr; // default font pFontMgr->SetRes(9050); // default font color pFontMgr->ForeColor(TEXT_DEFAULT); pFontMgr->colors[FNT_BACK_COLOR] = CI_SKIP; #ifdef OS_MAC // #include "menubar.hpp" // DS9MenuBar* pMenuBar; // TRACK_MEM("menuBar"); pMenuBar = new DS9MenuBar; TRACK_MEM("Mouse"); new Mouse; #else TRACK_MEM("Mouse"); new MouseInt; #endif if(pMouse->hideCount == 999) { // init error ShutDownSoundMgr(); APrintUnfreedPtrs(FALSE); exit(1); } pMouse->Init(0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1); pMouse->SetRes(RES_ANIM, POINTER_RES, 1); pMouse->Hide(); //let bamroom show it at room change time. // this is our global data saver AtSave(GlobalSave); // create the application instance TRACK_MEM("BAM App"); pBam = new BAM_Application; bGlobal.gBam = pBam->gSelf; pBam->msgMask = E_MOUSE_DOWN | E_MOUSE_UP | E_KEY_DOWN; // command-line options parsed here memcpy(pBam->scenarioName, "9110", 5); // default scenario pBam->fNoIntro = FALSE; pBam->fDefaultScenario = FALSE; pBam->fUseFog = TRUE; pBam->fUseWinLose = TRUE; pBam->playerSide = SIDE1; pBam->fMapEdit = FALSE; pBam->playerTypes[SIDE0] = PLAYER_NONE; pBam->playerTypes[SIDE1] = PLAYER_LOCAL; pBam->playerTypes[SIDE2] = PLAYER_NONE; pBam->playerTypes[SIDE3] = PLAYER_NONE; pBam->playerTypes[SIDE4] = PLAYER_NONE; { FILE *pPentiumFile; pPentiumFile = fopen("PENTIUM.VAN", "rb"); if(pPentiumFile) { fclose(pPentiumFile); fPentium = TRUE; } } for(loop1 = 1; loop1 < argc; loop1++) { strcpy(mess, argv[loop1]); string1 = mess; do { *string1 = (char) toupper(*string1); string1++; } while(*string1); if(mess[0] == '-') { // #ifdef ENABLE_EDITOR // if(!memcmp(mess, "-EDIT", 5)) // turn on edit mode // pBam->fMapEdit = TRUE; // #endif if(!memcmp(mess, "-NOINTRO", 9)) // turn off opening cinematic pBam->fNoIntro = TRUE; else if(!memcmp(mess, "-NOWIN", 6)) // turn on win/lose conditions pBam->fUseWinLose = FALSE; else if(!memcmp(mess, "-NOFOG", 6)) // turn off fog pBam->fUseFog = FALSE; else if(!memcmp(mess, "-NET", 4)) // network play { pBam->fNetworkTest = TRUE; bGlobal.storyLine = NETGAME; ASeedRandom(42); // need sync'ed RNGs } else if(!memcmp(mess, "-PENTIUM", 8)) { fPentium = TRUE; } else if(!memcmp(mess, "-MUSIC", 6)) { bGlobal.altMusicNum = atoi(mess + 6); } else if(!memcmp(mess, "-AIUNITS", 8)) { bGlobal.aiUnitMultiplier = atoi(mess + 8); } else if(!memcmp(mess, "-AI", 3)) { bGlobal.aiOveride = atoi(mess + 3); } else if(!memcmp(mess, "-FRENCH", 7)) { SetLanguage(LANG_FRENCH); } else if(!memcmp(mess, "-GERMAN", 7)) { SetLanguage(LANG_GERMAN); } else if(!memcmp(mess, "-ENGLISH", 8)) { SetLanguage(LANG_ENGLISH); } else if(!memcmp(mess, "-SHOWOFF", 8)) // storefront demo mode { bGlobal.storyLine = SHOW_OFF; } else if(!memcmp(mess, "-HACKRES", 8)) // allow single resource replacement { pResMgr->fSearchStuffsFirst = FALSE; } else if(!memcmp(mess, "-SIDE", 5)) // set player side (1 or 2) { switch(mess[5]) { case '0': pBam->playerSide = SIDE0; pBam->playerTypes[SIDE1] = PLAYER_NONE; pBam->playerTypes[SIDE2] = PLAYER_NONE; break; case '1': pBam->playerSide = SIDE1; pBam->playerTypes[SIDE1] = PLAYER_LOCAL; pBam->playerTypes[SIDE2] = PLAYER_NONE; break; case '2': pBam->playerSide = SIDE2; pBam->playerTypes[SIDE1] = PLAYER_NONE; pBam->playerTypes[SIDE2] = PLAYER_LOCAL; break; default: pMono->Out("Invalid option to command line arg -SIDEx\n"); break; } } } else if(atoi(argv[loop1])) { memcpy(pBam->scenarioName, argv[loop1], 8); pBam->fDefaultScenario = TRUE; } } #ifdef ENABLE_EDITOR if(pBam->fMapEdit) // if editor mode, then turn off fog pBam->fUseFog = FALSE; pBam->fShowTileNums = TRUE; #endif // initialize game start, pBam->Activate(TRUE); pContextMgr->msgMask = E_MOUSE_DOWN | E_MOUSE_UP | E_KEY_DOWN; #ifdef COUNT_FRAMES FrameCounter fps; #endif // COUNT_FRAMES TRACK_MEM("TCommMgr"); new TCommMgr; if(pBam->fNetworkTest) // if set up network from command line { // TNetwork *pComm; // TModem *pComm; TComm::ERROR errVal; int int1; // pMono->Out("New TCommMgr\n"); // TRACK_MEM("TCommMgr"); pCommMgr = new TCommMgr; //it isn't an object -no gSelf TRACK_MEM("TNetwork"); pComm = new TNetwork; // pComm = new TModem; // ((TModem*) pComm)->SetPort(3); // ((TModem*) pComm)->SetBaud(19200); #ifdef OS_MAC int commInitArg = 0; // ignored by DOS/TIGRE // player 1 is caller, player two is listener // at least for now, using command line args to specify direction if (pBam->playerTypes[SIDE1] == PLAYER_LOCAL) { commInitArg = TCommMacintosh::kATalkCaller; } else { commInitArg = TCommMacintosh::kATalkListener; } pCommMgr->Init(pComm, commInitArg); #else pCommMgr->SetUserAbortFn ((pIntFnInt) CycleConnection); pCommMgr->Init(pComm); #endif pMono->Out("Attempting connection...\n"); int1 = (int)pCommMgr->Connect(); errVal = (TComm::ERROR)int1; if(errVal != TComm::ALL_OK) { pMono->Out("Main() - error, commMgr->Connect() failed\n"); sleep(1); pBam->fNetworkTest = FALSE; } else { pMono->Out("Main() - connection established\n"); pBam->playerTypes[(pBam->playerSide == SIDE1)? SIDE2: SIDE1] = pCommMgr->GetUserID(); pMono->Out("User ID==%d\n", pCommMgr->GetUserID()); // sleep(2); } } pMono->Out("TIGRE engine initialized\n"); ReportFreeMem(); // side1 and side2 MUST have a player setting of some kind if(pBam->playerTypes[SIDE1] == PLAYER_NONE) pBam->playerTypes[SIDE1] = PLAYER_COMPUTER; if(pBam->playerTypes[SIDE2] == PLAYER_NONE) pBam->playerTypes[SIDE2] = PLAYER_COMPUTER; // initial room if(pBam->fDefaultScenario) { SetDefaults(pBam->scenarioName); bGlobal.roomMgr.NewRoom(BR_WORLD); // skip everything, go to game } else if(bGlobal.storyLine == SHOW_OFF) { bGlobal.roomMgr.NewRoom(BR_WORLD); // skip everything, go to game } else if(pBam->fNoIntro) bGlobal.roomMgr.NewRoom(BR_MENU); // skip intro, go to story selector else bGlobal.roomMgr.NewRoom(BR_CINE); // skip nothing bGlobal.roomMgr.CheckRoomChange(); #ifdef OS_MAC #include "menubar.hpp" DS9MenuBar *pMenuBar; TRACK_MEM("menuBar"); MenuBar.Init(); #endif ticks_t currTicks = ATicks(); int snapShot = 0; // anti-piracy stuff pFile = fopen("HMICARDS.386", "rb"); if(!pFile) bGlobal.antiPiracyCrashFlag &= 0xFFFFF0FF; else { for(loop1 = 0; loop1 < 5; loop1++) { char string1[128]; unsigned long lineCheck1, lineCheck2; fread(string1, 32, 1, pFile); // camoflage string fread(string1, 128, 1, pFile); // encrypted string fread(&lineCheck1, sizeof(lineCheck1), 1, pFile); // line checksum // verify checksum for(lineCheck2 = 0, loop2 = 0; loop2 < 128; loop2++) lineCheck2 = lineCheck2 + string1[loop2]; lineCheck2 ^= 0xF61E22C9; if(lineCheck1 != lineCheck2) { // failure - set the delayed crash flag fclose(pFile); bGlobal.antiPiracyCrashFlag &= 0xFFFFF0FF; } } fclose(pFile); } //======================================================================= //MAIN GAME LOOP //======================================================================= ReportFreeMem(); enum timerTags {TIMER_CYC_PER_FRAME = 0, TIMER_UPDATE_TICKS, TIMER_CONTEXT_CYCLE, TIMER_ANIMATE, TIMER_SYNC_SEND, TIMER_SYNC_RECV, TIMER_MAX}; DebugTimer timers[TIMER_MAX]; while (!pContextMgr->fQuitting) { #ifndef NDEBUG timers[TIMER_CYC_PER_FRAME].Start(); #endif #ifdef DEBUG_BIG_NET pMono->Out("main loop().."); #endif // our own exceptional ptrs pBam = ADerefAs(BAM_Application, bGlobal.gBam); if (bGlobal.gWorld) { pWorld = ADerefAs(World, bGlobal.gWorld); } else { pWorld = NULL; } #ifdef DEBUG_BIG_NET pMono->Out("roomMgr.cycle().."); #endif bGlobal.roomMgr.Cycle(); //fps.Count(); #ifdef DEBUG_BIG_NET pMono->Out("memMgr.cycle().."); #endif pMemMgr->Cycle(); #ifndef OLD_MOUSE_INTERRUPT_HANDLER // // MDB - Modified the mouse interrupt handler. // MouseHandler( FALSE ); #endif #ifndef NDEBUG //mem_check(); #endif #ifdef DEBUG_BIG_NET pMono->Out("roomMgr.CheckRoomChange().."); #endif bGlobal.roomMgr.CheckRoomChange(); #ifndef OLD_MOUSE_INTERRUPT_HANDLER // // MDB - Modified the mouse interrupt handler. // MouseHandler( FALSE ); #endif //if snap is on lets handle tick updates ourself if(bGlobal.gSnap && pSnap->snapOn) { //if snap just toggled on if(!snapShot) { snapShot++; currTicks = ATicks(); } else { currTicks += 2; } ASetTicks(currTicks); } else { snapShot = 0; //reset #ifdef DEBUG_BIG_NET pMono->Out("EventMgr->Publish().."); #endif // add local actions to actionPool2 pEventMgr->PublishNext(); #ifndef OLD_MOUSE_INTERRUPT_HANDLER // // MDB - Modified the mouse interrupt handler. // MouseHandler( FALSE ); #endif if(pWorld) { // wait for next tick to occur, because otherwise there's no point. // note: UpdateTicks() cannot be trusted to change, in case of Pause() currTicks = ATicks(); // #ifndef NDEBUG // BamDebug.Out("main() - update tick counter (curr=%d)\n", // currTicks); // #endif #ifndef NDEBUG timers[TIMER_UPDATE_TICKS].Start(); #endif UpdateTicks(); // did the tick counter fail to increment? if(ATicks() == currTicks) { // loop on clock() delta, then resume. A tick will have changed by // then or else we're in Pause() mode, so who cares. clock_t currClock = clock(); while(currClock == clock()) { #ifndef OLD_MOUSE_INTERRUPT_HANDLER MouseHandler( FALSE ); #endif }; // try again - if it fails again, assume Pause() and don't worry UpdateTicks(); } // if we skipped over a tick somehow.. if(ATicks() > currTicks + 1) { // #ifndef NDEBUG // BamDebug.Out("main() WARNING: ATicks() advanced by %d! - retarding\n", // ATicks() - currTicks); // #endif // dont allow the tick counter to increment by more than 1 // tick per frame, or we may get out of sync with the // remote machine ASetTicks(currTicks + 1); } #ifndef NDEBUG timers[TIMER_UPDATE_TICKS].Stop(); #endif // #ifndef NDEBUG // BamDebug.Out("ATicks() == %d\n", ATicks()); // #endif // sync1 - send actionPool2 to remote #ifndef NDEBUG timers[TIMER_SYNC_SEND].Start(); #endif fWaitToSend = FALSE; if(pCommMgr && pCommMgr->totalPacketsWaiting) fWaitToSend = TRUE; if(!pWorld->SyncSend()) { #ifndef OLD_MOUSE_INTERRUPT_HANDLER MouseHandler( FALSE ); #endif //pWorld->AITakeOver(); if(!pBam->fWorldEnderPopupExists) { TRACK_MEM("BAM_WorldEnderPopup"); pWEPop = new BAM_WorldEnderPopup; pWEPop->Setup(); pBam->fWorldEnderPopupExists = TRUE; } } #ifndef NDEBUG timers[TIMER_SYNC_SEND].Stop(); #endif // process actionPool1 pWorld->ProcessActions(); #ifndef OLD_MOUSE_INTERRUPT_HANDLER MouseHandler( FALSE ); #endif } else { #ifndef NDEBUG timers[TIMER_UPDATE_TICKS].Start(); #endif UpdateTicks(); #ifndef NDEBUG timers[TIMER_UPDATE_TICKS].Stop(); #endif } if(bGlobal.storyLine == NETGAME && !bGlobal.netDisconnect) { pCommMgr->EnQueueData(); #ifndef OLD_MOUSE_INTERRUPT_HANDLER MouseHandler( FALSE ); #endif } } #ifdef DEBUG_BIG_NET pMono->Out("contextMgr.cycle().."); #endif #ifndef NDEBUG timers[TIMER_CONTEXT_CYCLE].Start(); #endif pContextMgr->Cycle(); #ifndef NDEBUG timers[TIMER_CONTEXT_CYCLE].Stop(); #endif #ifndef OLD_MOUSE_INTERRUPT_HANDLER MouseHandler( FALSE ); #endif if(bGlobal.storyLine == NETGAME && !bGlobal.netDisconnect) { pCommMgr->EnQueueData(); #ifndef OLD_MOUSE_INTERRUPT_HANDLER MouseHandler( FALSE ); #endif } #ifdef DEBUG_BIG_NET pMono->Out("GraphMgr->Animate().."); #endif #ifndef NDEBUG timers[TIMER_ANIMATE].Start(); #endif pGraphMgr->Animate(); #ifndef NDEBUG timers[TIMER_ANIMATE].Stop(); #endif #ifndef OLD_MOUSE_INTERRUPT_HANDLER MouseHandler( FALSE ); #endif if(bGlobal.storyLine == NETGAME && !bGlobal.netDisconnect) { pCommMgr->EnQueueData(); #ifndef OLD_MOUSE_INTERRUPT_HANDLER MouseHandler( FALSE ); #endif } #ifdef DEBUG_BIG_NET pMono->Out("soundMgr.cycle().."); #endif pSoundMgr->Cycle(); // current frame now done // gather cmds from remote for next frame, then prepare to run it if(pWorld) { pWorld->currFrame++; // sync2 - add remote actions to local actions in actionPool2 #ifndef NDEBUG timers[TIMER_SYNC_RECV].Start(); #endif if(!pWorld->SyncReceive()) { #ifndef OLD_MOUSE_INTERRUPT_HANDLER MouseHandler( FALSE ); #endif //pWorld->AITakeOver(); if(!pBam->fWorldEnderPopupExists) { TRACK_MEM("BAM_WorldEnderPopup"); pWEPop = new BAM_WorldEnderPopup; pWEPop->Setup(); pBam->fWorldEnderPopupExists = TRUE; } } // sync3 - swap action pools pWorld->SwapActionPools(); #ifndef NDEBUG timers[TIMER_SYNC_RECV].Stop(); #endif } if(bGlobal.gSnap && pSnap->snapOn) { pSnap->SnapScreen(); } if(netRestoreNum || netSaveNum) { //this means we're in a netgame save or restore //we don't run the eventmgr to keep both sides in sync //and we set the restore number here, after the context cycle, //to insure the otherside has had time to be notified of this if(netRestoreNum) restoreNum = netRestoreNum; //our one net save game if(netSaveNum) { saveNum = netSaveNum; netSerialNum = ARandom(99999); sprintf(saveMessage,"%d",netSerialNum); } } if (saveNum) { pMemMgr->Dump((uint16) (100 + saveNum), "Save Dump", TRUE); saverResult = saveMgr.Save((uint16) saveNum, bGlobal.versionNum, bGlobal.versionSubNum, bGlobal.buildID, saveMessage); if (saverResult) { sprintf(mess, "save failed. error #%d", saverResult); APanic(mess); } netSaveNum = 0; //reset this after save saveNum = 0; } if (restoreNum) { saverResult = saveMgr.Restore((uint16) restoreNum, bGlobal.versionNum, bGlobal.versionSubNum, bGlobal.buildID); if (saverResult) { // sprintf(mess, "restore failed. error #%d", saverResult); BamDebug.Out("Restore failed! Error %d\n", saverResult); // APanic(mess); } pMemMgr->Dump((uint16) (200 + restoreNum), "Restore Dump", TRUE); netRestoreNum = 0; //reset this after restore restoreNum = 0; bGlobal.roomMgr.Cycle(); // frantic temporary debugging measure pBam = ADerefAs(BAM_Application, bGlobal.gBam); if (bGlobal.gWorld) { pWorld = ADerefAs(World, bGlobal.gWorld); pWorld->Save(AFTER_RESTORE); } else { pWorld = NULL; } bGlobal.roomMgr.Cycle(); pMemMgr->Cycle(); pSoundMgr->Cycle(); if(pWorld) { pBam->fPauseWorld = TRUE; //force ResumeTicks() to be called in PauseWorld pWorld->Pause(FALSE, TRUE); pBam->PauseWorld(); } else bGlobal.roomMgr.curRoom->Pause(FALSE, TRUE); #ifndef OLD_MOUSE_INTERRUPT_HANDLER MouseHandler( FALSE ); #endif } if(pWorld) if(pBam->fPauseWorld != pWorld->fIsPaused) pBam->PauseWorld(); #ifdef DEBUG_BIG_NET pMono->Out("main loop() done\n"); #endif #ifndef NDEBUG timers[TIMER_CYC_PER_FRAME].Stop(); #endif #ifndef NDEBUG pMono->SaveWindow(); pMono->Goto(24, 1); pMono->Out("CpF%5d UTick%5d CmC%5d GmA%5d Tx%4d:%dp@%4db]%c Rx[%4d]", timers[TIMER_CYC_PER_FRAME].duration, timers[TIMER_UPDATE_TICKS].duration, timers[TIMER_CONTEXT_CYCLE].duration, timers[TIMER_ANIMATE].duration, timers[TIMER_SYNC_SEND].duration, pCommMgr->pComm->totalPacketsSent, pCommMgr->pComm->totalBytesSent, fWaitToSend? 'W': 'w', timers[TIMER_SYNC_RECV].duration); pMono->Goto(25, 1); time(&timeDif); if(timeDif != lastTime) { lastTime = timeDif; framesPerSec = AMin(framesRun, 99); framesRun = 0; } else framesRun++; timeDif -= startTime; pMono->Out("%05dkt %05dkl %02d:%02d:%02d %2dFPS", pMemMgr->AvailMem() / 1024, pMemMgr->LargestAlloc() / 1024, timeDif / 3600, (timeDif / 60) % 60, timeDif % 60, framesPerSec); if(pWorld) { pMono->Goto(25, 32); pMono->Out("r%d g%d 0x%08x", pWorld->tileResNum, ALoad(RES_TILELIB, pWorld->tileResNum), AGetResData(ALoad(RES_TILELIB, pWorld->tileResNum))); } pCommMgr->pComm->totalBytesSent = 0; pCommMgr->pComm->totalPacketsSent = 0; pMono->RestoreWindow(); #endif #ifndef OLD_MOUSE_INTERRUPT_HANDLER MouseHandler( FALSE ); #endif } //=================================== LoadExitQuote(); //=================================== // get rid of our current room bGlobal.roomMgr.DeleteCurRoom(); // shut down communications if(pCommMgr) { pCommMgr->Disconnect(); pCommMgr->DiscardData(); delete pCommMgr; //its destructor will delete pComm pCommMgr = NULL; } if(bGlobal.gSnap) ADelete(bGlobal.gSnap); ADelete(bGlobal.gBam); // all actors should be removed from graphmgr, do one more // animate to clear lists. pGraphMgr->Animate(); ADelete(pContextMgr->gSelf); // TSound exitSound; // exitSound.Play(667); // while(exitSound.IsPlaying()) // pSoundMgr->Cycle(); // storm the office! kill all managers! ADelete(pGraphMgr->gSelf); ADelete(pFontMgr->gSelf); ADelete(pSoundMgr->gSelf); ADelete(pResMgr->gSelf); ADelete(pEventMgr->gSelf); ADelete(pMouse->gSelf); delete pMono; // DESTROY_MGR_CAREFUL(GraphicsMgr, pGraphMgr); // DESTROY_MGR_CAREFUL(Mono, pMono); // DESTROY_MGR_CAREFUL(FontMgr, pFontMgr); // DESTROY_MGR_CAREFUL(SoundMgr, pSoundMgr); // DESTROY_MGR(pResMgr); // DESTROY_MGR(pContextMgr); // DESTROY_MGR_CAREFUL(EventMgr, pEventMgr); #ifdef INTERACTIVE_DEMO DPMI dpmi; char *pScreen = (char *)dpmi.RealToProtected(0xB8000000); // kludge - remove "Installer" from data for(loop1 = 0; loop1 < 9; loop1++) MSG_DEMO_ENGL[86 + loop1 * 2] = ' '; memcpy(pScreen, (char *)MSG_DEMO_ENGL, 4000); while(!kbhit()); getch(); #endif system("mode co80"); // yeah, mega-cheesy I know. It's a bug patch. -Van printf("\n%s\n",exitMessage); printf("%s\n",exitAuthor); return 0; }