void* implementation_snes_allocSharedMemory() { const char* memtype = s_EmulationControl.cb_allocSharedMemory_params.memtype; size_t amt = s_EmulationControl.cb_allocSharedMemory_params.amt; if(!running) { s_EmulationControl.cb_allocSharedMemory_params.result = NULL; return NULL; } //printf("WritePipe(eMessage_SIG_allocSharedMemory)\n"); WritePipe(eMessage_SIG_allocSharedMemory); WritePipeString(memtype); WritePipe(amt); std::string blockname = ReadPipeString(); auto mapfile = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, blockname.c_str()); if(mapfile == INVALID_HANDLE_VALUE) return NULL; auto ptr = MapViewOfFile(mapfile, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); auto smb = new SharedMemoryBlock(); smb->memtype = memtype; smb->handle = mapfile; memHandleTable[ptr] = smb; s_EmulationControl.cb_allocSharedMemory_params.result = ptr; return ptr; }
bool Write(HANDLE Pipe, const void* Data, size_t DataSize) { bool Result=false; if(WritePipe(Pipe, &DataSize, sizeof(DataSize)) && WritePipe(Pipe, Data, DataSize)) { Result=true; } return Result; }
/* --------------------------------------------------------------------------- * save PCB */ int SavePCB (char *file) { int retcode; if (gui->notify_save_pcb == NULL) return WritePipe (file, true); gui->notify_save_pcb (file, false); retcode = WritePipe (file, true); gui->notify_save_pcb (file, true); return retcode; }
int cnprocWriteCommand( CnpkPipeFds tFds, int nCmdID, char *pData, int nDataSize) { int result = -1; int write_size = CMD_HEADER_SIZE + nDataSize; BufTool *buftool = buftool_new( write_size, BUFTOOL_LITTLE_ENDIAN ); if( buftool ){ buftool_write_short(buftool, nCmdID); buftool_write_short(buftool, nDataSize); buftool_write(buftool, pData, nDataSize); if( WritePipe(tFds.cmd_fd, (char *)buftool_data(buftool), buftool_pos(buftool) ) < 0 ){ DebugPrint("cnprocWriteCommand\n"); result = -1; } else result = 0; buftool_destroy( buftool ); } return result; }
void CUsbDkRedirectorStrategy::IoDeviceControl(WDFREQUEST Request, size_t OutputBufferLength, size_t InputBufferLength, ULONG IoControlCode) { UNREFERENCED_PARAMETER(InputBufferLength); UNREFERENCED_PARAMETER(OutputBufferLength); switch (IoControlCode) { default: { CWdfRequest(Request).ForwardToIoQueue(*m_IncomingConfigQueue); break; } case IOCTL_USBDK_DEVICE_READ_PIPE: { ReadPipe(Request); break; } case IOCTL_USBDK_DEVICE_WRITE_PIPE: { WritePipe(Request); break; } } }
static DWORD WINAPI ThreadProc(_In_ LPVOID lpParameter) { MessageLoop(); //send a message to the other thread to synchronize the shutdown of this thread //after that message is received, this thread (and the whole dll instance) is dead. WritePipe(eMessage_BRK_Complete); return 0; }
void Handle_SIG_audio_flush() { WritePipe(eMessage_SIG_audio_flush); int nsamples = audiobuffer_idx; WritePipe(nsamples); char* buf = ReadPipeSharedPtr(); memcpy(buf,audiobuffer,nsamples*2); //extra just in case we had to unexpectedly flush audio and then carry on with some other process... yeah, its rickety. WritePipe(0); //dummy synchronization //wait for frontend to consume data ReadPipe<int>(); //dummy synchronization WritePipe(0); //dummy synchronization audiobuffer_idx = 0; }
int cnprocWriteData( CnpkPipeFds tFds, char *pData, int nDataSize ) { if( WritePipe(tFds.dat_fd, pData, nDataSize) < 0 ){ DebugPrint( "cnprocWriteData: Error\n"); return -1; } return 0; }
void implementation_snes_freeSharedMemory() { void* ptr = s_EmulationControl.cb_freeSharedMemory_params.ptr; if(!ptr) return; auto smb = memHandleTable.find(ptr)->second; UnmapViewOfFile(ptr); CloseHandle(smb->handle); //printf("WritePipe(eMessage_SIG_freeSharedMemory);\n"); WritePipe(eMessage_SIG_freeSharedMemory); WritePipeString(smb->memtype.c_str()); }
/* --------------------------------------------------------------------------- * save elements in the current buffer */ int SaveBufferElements (char *Filename) { int result; if (SWAP_IDENT) SwapBuffers (); result = WritePipe (Filename, false); if (SWAP_IDENT) SwapBuffers (); return (result); }
/* --------------------------------------------------------------------------- * save PCB */ int SavePCB (char *Filename) { int retcode; char *copy; if (!(retcode = WritePipe (Filename, true))) { /* thanks to Nick Bailey for the bug-fix; * first of all make a copy of the passed filename because * it might be identical to 'PCB->Filename' */ copy = strdup (Filename); free (PCB->Filename); PCB->Filename = copy; SetChangedFlag (false); } return (retcode); }
// simplest of all tests. Just set a file descriptor and see that it's available // repeat many times HRESULT CTestPolling::Test1() { HRESULT hr = S_OK; HRESULT hrResult; size_t size; PollEvent event; int fd; int count = 0; srand(100); ChkA(TestInit(10, 10)); size = _pipes.size(); hrResult = _spPolling->WaitForNextEvent(&event, 0); ChkIfA(hrResult != S_FALSE, E_UNEXPECTED); // one event at a time model for (int index = 0; index < 100; index++) { size_t item = rand() % size; ChkA(WritePipe(&_pipes[item])); ConsumeEvent(&fd, &count); ChkIfA(fd != _pipes[item].readpipe, E_UNEXPECTED); ChkIfA(count != 1, E_UNEXPECTED); } hrResult = _spPolling->WaitForNextEvent(&event, 0); ChkIfA(hrResult != S_FALSE, E_UNEXPECTED); Cleanup: return hr; }
// create a polling set HRESULT CTestPolling::Test2() { // simulate the following events in random order: // socket added (did it succeed as expected) // incoming data (write to a random pipe) // WaitForNextEvent called (did it return an expected result/socket) // Remove socket last notified about HRESULT hr = S_OK; HRESULT hrResult; PollEvent event; const size_t c_maxSockets = 10; srand(100); ChkA(TestInit(c_maxSockets, 0)); hrResult = _spPolling->WaitForNextEvent(&event, 0); ChkIfA(hrResult != S_FALSE, E_UNEXPECTED); for (size_t index = 0; index < 1000; index++) { int randresult = ::rand() % 4; switch (randresult) { case 0: { // simulate a new socket being added if (_pipes.size() >= c_maxSockets) { continue; } ChkA(CreateAndAddPipe()); break; } case 1: { // simulate incoming data size_t size = _pipes.size(); size_t itemindex; if (size == 0) { continue; } itemindex = rand() % size; ChkA(WritePipe(&_pipes[itemindex])); break; } case 2: case 3: { int fd; size_t pending = GetPendingCount(); if (pending == 0) { continue; } ChkA(ConsumeEvent(&fd, NULL)); if (randresult == 3) { // simulate removing this pipe from the set ChkA(RemovePipe(FindPipePairIndex(fd))); } break; } // case } // switch } // for Cleanup: return hr; }
/* * Launch an OpenVPN process and the accompanying thread to monitor it */ BOOL StartOpenVPN(connection_t *c) { TCHAR cmdline[1024]; TCHAR *options = cmdline + 8; TCHAR exit_event_name[17]; HANDLE hStdInRead = NULL, hStdInWrite = NULL; HANDLE hNul = NULL, hThread = NULL; DWORD written; BOOL retval = FALSE; CLEAR(c->ip); if (c->hwndStatus) { PrintDebug(L"Connection request when previous status window is still open -- ignored"); WriteStatusLog(c, L"OpenVPN GUI> ", L"Complete the pending dialog before starting a new connection", false); SetForegroundWindow(c->hwndStatus); return FALSE; } RunPreconnectScript(c); /* Create thread to show the connection's status dialog */ hThread = CreateThread(NULL, 0, ThreadOpenVPNStatus, c, CREATE_SUSPENDED, &c->threadId); if (hThread == NULL) { ShowLocalizedMsg(IDS_ERR_CREATE_THREAD_STATUS); goto out; } /* Create an event object to signal OpenVPN to exit */ _sntprintf_0(exit_event_name, _T("%x%08x"), GetCurrentProcessId(), c->threadId); c->exit_event = CreateEvent(NULL, TRUE, FALSE, exit_event_name); if (c->exit_event == NULL) { ShowLocalizedMsg(IDS_ERR_CREATE_EVENT, exit_event_name); goto out; } /* Create a management interface password */ GetRandomPassword(c->manage.password, sizeof(c->manage.password) - 1); /* Construct command line -- put log first */ _sntprintf_0(cmdline, _T("openvpn --log%s \"%s\" --config \"%s\" " "--setenv IV_GUI_VER \"%S\" --service %s 0 --auth-retry interact " "--management %S %hd stdin --management-query-passwords %s" "--management-hold"), (o.log_append ? _T("-append") : _T("")), c->log_path, c->config_file, PACKAGE_STRING, exit_event_name, inet_ntoa(c->manage.skaddr.sin_addr), ntohs(c->manage.skaddr.sin_port), (o.proxy_source != config ? _T("--management-query-proxy ") : _T(""))); /* Try to open the service pipe */ if (!IsUserAdmin() && InitServiceIO (&c->iserv)) { DWORD size = _tcslen(c->config_dir) + _tcslen(options) + sizeof(c->manage.password) + 3; TCHAR startup_info[1024]; if ( !AuthorizeConfig(c)) { CloseHandle(c->exit_event); goto out; } c->hProcess = NULL; c->manage.password[sizeof(c->manage.password) - 1] = '\n'; _sntprintf_0(startup_info, _T("%s%c%s%c%.*S"), c->config_dir, _T('\0'), options, _T('\0'), sizeof(c->manage.password), c->manage.password); c->manage.password[sizeof(c->manage.password) - 1] = '\0'; if (!WritePipe(c->iserv.pipe, startup_info, size * sizeof (TCHAR))) { ShowLocalizedMsg (IDS_ERR_WRITE_SERVICE_PIPE); CloseHandle(c->exit_event); CloseServiceIO(&c->iserv); goto out; } } else { /* Start OpenVPN directly */ DWORD priority; STARTUPINFO si; PROCESS_INFORMATION pi; SECURITY_DESCRIPTOR sd; /* Make I/O handles inheritable and accessible by all */ SECURITY_ATTRIBUTES sa = { .nLength = sizeof(sa), .lpSecurityDescriptor = &sd, .bInheritHandle = TRUE }; if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) { ShowLocalizedMsg(IDS_ERR_INIT_SEC_DESC); CloseHandle(c->exit_event); return FALSE; } if (!SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE)) { ShowLocalizedMsg(IDS_ERR_SET_SEC_DESC_ACL); CloseHandle(c->exit_event); return FALSE; } /* Set process priority */ if (!SetProcessPriority(&priority)) { CloseHandle(c->exit_event); return FALSE; } /* Get a handle of the NUL device */ hNul = CreateFile(_T("NUL"), GENERIC_WRITE, FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 0, NULL); if (hNul == INVALID_HANDLE_VALUE) { CloseHandle(c->exit_event); return FALSE; } /* Create the pipe for STDIN with only the read end inheritable */ if (!CreatePipe(&hStdInRead, &hStdInWrite, &sa, 0)) { ShowLocalizedMsg(IDS_ERR_CREATE_PIPE_IN_READ); CloseHandle(c->exit_event); goto out; } if (!SetHandleInformation(hStdInWrite, HANDLE_FLAG_INHERIT, 0)) { ShowLocalizedMsg(IDS_ERR_DUP_HANDLE_IN_WRITE); CloseHandle(c->exit_event); goto out; } /* Fill in STARTUPINFO struct */ GetStartupInfo(&si); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = hStdInRead; si.hStdOutput = hNul; si.hStdError = hNul; /* Create an OpenVPN process for the connection */ if (!CreateProcess(o.exe_path, cmdline, NULL, NULL, TRUE, priority | CREATE_NO_WINDOW, NULL, c->config_dir, &si, &pi)) { ShowLocalizedMsg(IDS_ERR_CREATE_PROCESS, o.exe_path, cmdline, c->config_dir); CloseHandle(c->exit_event); goto out; } /* Pass management password to OpenVPN process */ c->manage.password[sizeof(c->manage.password) - 1] = '\n'; WriteFile(hStdInWrite, c->manage.password, sizeof(c->manage.password), &written, NULL); c->manage.password[sizeof(c->manage.password) - 1] = '\0'; c->hProcess = pi.hProcess; /* Will be closed in the event loop on exit */ CloseHandle(pi.hThread); } /* Start the status dialog thread */ ResumeThread(hThread); retval = TRUE; out: if (hThread && hThread != INVALID_HANDLE_VALUE) CloseHandle(hThread); if (hStdInWrite && hStdInWrite != INVALID_HANDLE_VALUE) CloseHandle(hStdInWrite); if (hStdInRead && hStdInRead != INVALID_HANDLE_VALUE) CloseHandle(hStdInRead); if (hNul && hNul != INVALID_HANDLE_VALUE) CloseHandle(hNul); return retval; } void StopOpenVPN(connection_t *c) { PostMessage(c->hwndStatus, WM_OVPN_STOP, 0, 0); }
void FArtemis::StartupModule() { WritePipe(FString(TEXT("Unreal Tournament plugin loaded"))); }
void WritePipeString(const char* str) { int len = strlen(str); WritePipe(len); WritePipeBuffer(str,len); }
static void debug_op_irq() { WritePipe(eMessage_BRK_hook_irq); }
static void debug_op_nmi() { WritePipe(eMessage_BRK_hook_nmi); }
void FArtemis::Tick(float DeltaTime) { if (GIsEditor) { return; } // Avoid double ticking if (LastFrameCounter > 0 && LastFrameCounter == GFrameCounter) { return; } LastFrameCounter = GFrameCounter; // We may be going 120hz, don't spam the device DeltaTimeAccumulator += DeltaTime; if (DeltaTimeAccumulator < FrameTimeMinimum) { return; } DeltaTimeAccumulator = 0; // Setup JSON object TSharedRef<FJsonObject> RootJson(new FJsonObject()); TSharedRef<FJsonObject> PlayerJson(new FJsonObject()); TSharedRef<FJsonObject> EnvironmentJson(new FJsonObject()); RootJson->SetObjectField("Player", PlayerJson); RootJson->SetObjectField("Environment", EnvironmentJson); // Setup JSON writer to be used before returning FString Buffer; TSharedRef<TJsonWriter<> > Writer = TJsonWriterFactory<>::Create(&Buffer); AUTPlayerController* UTPC = nullptr; AUTGameState* GS = nullptr; const TIndirectArray<FWorldContext>& AllWorlds = GEngine->GetWorldContexts(); for (const FWorldContext& Context : AllWorlds) { UWorld* World = Context.World(); if (World && World->WorldType == EWorldType::Game) { UTPC = Cast<AUTPlayerController>(GEngine->GetFirstLocalPlayerController(World)); if (UTPC) { UUTLocalPlayer* UTLP = Cast<UUTLocalPlayer>(UTPC->GetLocalPlayer()); if (UTLP == nullptr || UTLP->IsMenuGame()) { UTPC = nullptr; continue; } GS = World->GetGameState<AUTGameState>(); break; } } } if (!UTPC || !GS) { RootJson->SetStringField("State", "MainMenu"); FJsonSerializer::Serialize(RootJson, Writer); WritePipe(Buffer); return; } // Update environment data if (GS->GetGameModeClass()) { EnvironmentJson->SetStringField("GameMode", GS->GetGameModeClass()->GetName()); } EnvironmentJson->SetBoolField("MatchStarted", GS->HasMatchStarted()); EnvironmentJson->SetNumberField("GoalScore", GS->GoalScore); // Insert GameState JsonReport GS->MakeJsonReport(EnvironmentJson); // The JsonReport may contain all players, which is a bit too much if (EnvironmentJson->HasField("Players")) { EnvironmentJson->RemoveField("Players"); } // Update player data // If character not found player must be spectating(?) if (!UTPC->GetUTCharacter()) { RootJson->SetStringField("State", "Spectating"); } // If dead, don't try reading HP/Armor else if (UTPC->GetUTCharacter()->IsDead()) { RootJson->SetStringField("State", "Dead"); PlayerJson->SetNumberField("Health", 0); PlayerJson->SetNumberField("Armor", 0); } // Player is found and alive else { // Update HP and armor RootJson->SetStringField("State", "Alive"); PlayerJson->SetNumberField("Health", UTPC->GetUTCharacter()->Health); PlayerJson->SetNumberField("Armor", UTPC->GetUTCharacter()->ArmorAmount); // Update player powerups data TSharedRef<FJsonObject> InventoryJson(new FJsonObject()); PlayerJson->SetObjectField("Inventory", InventoryJson); InventoryJson->SetBoolField("HasJumpBoots", false); InventoryJson->SetBoolField("HasInvisibility", false); InventoryJson->SetBoolField("HasBerserk", false); InventoryJson->SetBoolField("HasUDamage", false); InventoryJson->SetBoolField("HasThighPads", false); InventoryJson->SetBoolField("HasShieldBelt", false); InventoryJson->SetBoolField("HasChestArmor", false); InventoryJson->SetBoolField("HasHelmet", false); for (TInventoryIterator<> It(UTPC->GetUTCharacter()); It; ++It) { AUTInventory* InventoryItem = (*It); // Using Contains here because pickups might have slighty different names in different contexts if (InventoryItem->GetClass()->GetName().Contains("Armor_ThighPads")) { InventoryJson->SetBoolField("HasThighPads", true); } else if (InventoryItem->GetClass()->GetName().Contains("Armor_ShieldBelt")) { InventoryJson->SetBoolField("HasShieldBelt", true); } else if (InventoryItem->GetClass()->GetName().Contains("Armor_Chest")) { InventoryJson->SetBoolField("HasChestArmor", true); } else if (InventoryItem->GetClass()->GetName().Contains("Armor_Helmet")) { InventoryJson->SetBoolField("HasHelmet", true); } else if (InventoryItem->GetClass()->GetName().Contains("JumpBoots")) { InventoryJson->SetBoolField("HasJumpBoots", true); } else if (InventoryItem->GetClass()->GetName().Contains("Invis")) { InventoryJson->SetBoolField("HasInvisibility", true); } else if (InventoryItem->GetClass()->GetName().Contains("Berserk")) { InventoryJson->SetBoolField("HasBerserk", true); } else if (InventoryItem->GetClass()->GetName().Contains("UDamage")) { InventoryJson->SetBoolField("HasUDamage", true); } } // Update player weapon data TSharedRef<FJsonObject> WeaponJson(new FJsonObject()); PlayerJson->SetObjectField("Weapon", WeaponJson); if (UTPC->GetUTCharacter()->GetWeapon()) { WeaponJson->SetStringField("Name", UTPC->GetUTCharacter()->GetWeapon()->GetClass()->GetName()); WeaponJson->SetNumberField("Ammo", UTPC->GetUTCharacter()->GetWeapon()->Ammo); WeaponJson->SetNumberField("MaxAmmo", UTPC->GetUTCharacter()->GetWeapon()->MaxAmmo); WeaponJson->SetBoolField("IsFiring", UTPC->GetUTCharacter()->GetWeapon()->IsFiring()); WeaponJson->SetNumberField("FireMode", UTPC->GetUTCharacter()->GetWeapon()->GetCurrentFireMode()); WeaponJson->SetNumberField("ZoomState", UTPC->GetUTCharacter()->GetWeapon()->ZoomState); } else { WeaponJson->SetStringField("Name", "None"); } } // Insert PlayerState JsonReport TSharedRef<FJsonObject> PlayerStateJson(new FJsonObject()); PlayerJson->SetObjectField("State", PlayerStateJson); if (UTPC->UTPlayerState) { UTPC->UTPlayerState->MakeJsonReport(PlayerStateJson); } FJsonSerializer::Serialize(RootJson, Writer); WritePipe(Buffer); }
void WritePipeBlob(void* buf, int len) { WritePipe(len); WritePipeBuffer(buf,len); }
bool Handle_QUERY(eMessage msg) { switch(msg) { default: return false; case eMessage_QUERY_library_id: WritePipeString(snes_library_id()); break; case eMessage_QUERY_library_revision_major: WritePipe(snes_library_revision_major()); break; case eMessage_QUERY_library_revision_minor: WritePipe(snes_library_revision_minor()); break; case eMessage_QUERY_get_region: WritePipe((char)snes_get_region()); break; case eMessage_QUERY_get_memory_size: WritePipe((u32)snes_get_memory_size(ReadPipe<u32>())); break; case eMessage_QUERY_get_memory_data: { unsigned int id = ReadPipe<u32>(); char* dstbuf = ReadPipeSharedPtr(); uint8_t* srcbuf = snes_get_memory_data(id); memcpy(dstbuf,srcbuf,snes_get_memory_size(id)); WritePipe(eMessage_BRK_Complete); break; } case eMessage_QUERY_peek: { int id = ReadPipe<s32>(); unsigned int addr = ReadPipe<u32>(); uint8_t ret; if(id == SNES_MEMORY_SYSBUS) ret = bus_read(addr); else ret = snes_get_memory_data(id)[addr]; WritePipe(ret); } break; case eMessage_QUERY_poke: { int id = ReadPipe<s32>(); unsigned int addr = ReadPipe<u32>(); uint8_t val = ReadPipe<uint8_t>(); if(id == SNES_MEMORY_SYSBUS) bus_write(addr,val); else snes_get_memory_data(id)[addr] = val; break; } break; case eMessage_QUERY_serialize_size: WritePipe((u32)snes_serialize_size()); break; case eMessage_QUERY_poll_message: //TBD WritePipe(-1); break; case eMessage_QUERY_dequeue_message: //TBD break; case eMessage_QUERY_set_color_lut: { auto blob = ReadPipeBlob(); snes_set_color_lut((uint32_t*)&blob[0]); break; } break; case eMessage_QUERY_enable_trace: if(!!ReadPipe<char>()) snes_set_trace_callback(snes_trace); else snes_set_trace_callback(NULL); break; case eMessage_QUERY_enable_scanline: if(ReadPipe<bool>()) snes_set_scanlineStart(snes_scanlineStart); else snes_set_scanlineStart(NULL); break; case eMessage_QUERY_enable_audio: audio_en = ReadPipe<bool>(); break; case eMessage_QUERY_set_layer_enable: { int layer = ReadPipe<s32>(); int priority = ReadPipe<s32>(); bool enable = ReadPipe<bool>(); snes_set_layer_enable(layer,priority,enable); break; } case eMessage_QUERY_set_backdropColor: snes_set_backdropColor(ReadPipe<s32>()); break; case eMessage_QUERY_peek_logical_register: WritePipe(snes_peek_logical_register(ReadPipe<s32>())); break; case eMessage_QUERY_peek_cpu_regs: { //watch it! the size of this struct is important! #ifdef _MSC_VER #pragma pack(push,1) #endif struct { u32 pc; u16 a,x,y,z,s,d,vector; //7x u8 p, nothing; u32 aa,rd; u8 sp, dp, db, mdr; } #ifndef _MSC_VER __attribute__((__packed__)) #endif cpuregs; #ifdef _MSC_VER #pragma pack(pop) #endif cpuregs.pc = (u32)SNES::cpu.regs.pc; cpuregs.a = SNES::cpu.regs.a; cpuregs.x = SNES::cpu.regs.x; cpuregs.y = SNES::cpu.regs.y; cpuregs.z = SNES::cpu.regs.z; cpuregs.s = SNES::cpu.regs.s; cpuregs.d = SNES::cpu.regs.d; cpuregs.aa = (u32)SNES::cpu.aa; cpuregs.rd = (u32)SNES::cpu.rd; cpuregs.sp = SNES::cpu.sp; cpuregs.dp = SNES::cpu.dp; cpuregs.db = SNES::cpu.regs.db; cpuregs.mdr = SNES::cpu.regs.mdr; cpuregs.vector = SNES::cpu.regs.vector; cpuregs.p = SNES::cpu.regs.p; cpuregs.nothing = 0; WritePipeBuffer(&cpuregs,32); //watch it! the size of this struct is important! } break; case eMessage_QUERY_GetMemoryIdName: { uint32 id = ReadPipe<uint32>(); const char* ret = snes_get_memory_id_name(id); if(!ret) ret = ""; WritePipeString(ret); break; } case eMessage_QUERY_state_hook_exec: SNES::cpu.debugger.op_exec = ReadPipe<bool>() ? debug_op_exec : hook<void (uint24)>(); break; case eMessage_QUERY_state_hook_read: SNES::cpu.debugger.op_read = ReadPipe<bool>() ? debug_op_read : hook<void (uint24)>(); break; case eMessage_QUERY_state_hook_write: SNES::cpu.debugger.op_write = ReadPipe<bool>() ? debug_op_write : hook<void (uint24, uint8)>(); break; case eMessage_QUERY_state_hook_nmi: SNES::cpu.debugger.op_nmi = ReadPipe<bool>() ? debug_op_nmi : hook<void ()>(); break; case eMessage_QUERY_state_hook_irq: SNES::cpu.debugger.op_irq = ReadPipe<bool>() ? debug_op_irq : hook<void ()>(); break; } return true; }
void MessageLoop() { for(;;) { TOP: switch(s_EmulationControl.exitReason) { case eEmulationExitReason_NotSet: goto HANDLEMESSAGES; case eEmulationExitReason_CMD_Complete: //printf("eEmulationExitReason_CMD_Complete (command:%d)\n",s_EmulationControl.command); //MessageBox(0,"ZING","ZING",MB_OK); //printf("WRITING COMPLETE\n"); WritePipe(eMessage_BRK_Complete); //special post-completion messages (return values) switch(s_EmulationControl.command) { case eMessage_CMD_load_cartridge_normal: case eMessage_CMD_load_cartridge_super_game_boy: case eMessage_CMD_serialize: case eMessage_CMD_unserialize: WritePipe(s_EmulationControl.cmd_result); break; } s_EmulationControl.exitReason = eEmulationExitReason_NotSet; s_EmulationControl.command = eMessage_NotSet; goto TOP; case eEmulationExitReason_SIG: s_EmulationControl.exitReason = eEmulationExitReason_NotSet; switch(s_EmulationControl.exitCallbackType) { case eEmulationCallback_snes_video_refresh: { WritePipe(eMessage_SIG_video_refresh); WritePipe(s_EmulationControl.cb_video_refresh_params.width); WritePipe(s_EmulationControl.cb_video_refresh_params.height); int destOfs = ReadPipe<int>(); char* buf = (char*)hMapFilePtr + destOfs; int bufsize = 512 * 480 * 4; memcpy(buf,s_EmulationControl.cb_video_refresh_params.data,bufsize); WritePipe((char)0); //dummy synchronization break; } case eEmulationCallback_snes_audio_flush: Handle_SIG_audio_flush(); break; case eEmulationCallback_snes_input_poll: WritePipe(eMessage_SIG_input_poll); break; case eEmulationCallback_snes_input_state: WritePipe(eMessage_SIG_input_state); WritePipe(s_EmulationControl.cb_input_state_params.port); WritePipe(s_EmulationControl.cb_input_state_params.device); WritePipe(s_EmulationControl.cb_input_state_params.index); WritePipe(s_EmulationControl.cb_input_state_params.id); s_EmulationControl.cb_input_state_params.result = ReadPipe<int16_t>(); break; case eEmulationCallback_snes_input_notify: WritePipe(eMessage_SIG_input_notify); WritePipe(s_EmulationControl.cb_input_notify_params.index); break; case eEmulationCallback_snes_path_request: { WritePipe(eMessage_SIG_path_request); WritePipe(s_EmulationControl.cb_path_request_params.slot); WritePipeString(s_EmulationControl.cb_path_request_params.hint); std::string temp = ReadPipeString(); //yucky! use strncpy and ARRAY_SIZE or something! strcpy(s_EmulationControl.cb_path_request_params.result,temp.c_str()); } break; case eEmulationCallback_snes_allocSharedMemory: implementation_snes_allocSharedMemory(); break; case eEmulationCallback_snes_freeSharedMemory: implementation_snes_freeSharedMemory(); break; case eEmulationCallback_snes_trace: WritePipe(eMessage_SIG_trace_callback); WritePipeString(s_EmulationControl.cb_trace_params.msg); break; } //when callbacks finish, we automatically resume emulation. be careful to go back to top!!!!!!!! SETEMU; goto TOP; case eEmulationExitReason_BRK: s_EmulationControl.exitReason = eEmulationExitReason_NotSet; switch(s_EmulationControl.hookExitType) { case eMessage_BRK_hook_exec: WritePipe(eMessage_BRK_hook_exec); WritePipe((uint32)s_EmulationControl.hookAddr); break; case eMessage_BRK_hook_read: WritePipe(eMessage_BRK_hook_read); WritePipe((uint32)s_EmulationControl.hookAddr); break; case eMessage_BRK_hook_write: WritePipe(eMessage_BRK_hook_write); WritePipe((uint32)s_EmulationControl.hookAddr); WritePipe((uint8)s_EmulationControl.hookValue); break; } goto TOP; } HANDLEMESSAGES: //printf("Reading message from pipe...\n"); eMessage msg = ReadPipe<eMessage>(); //printf("...slam: %08X\n",msg); if(Handle_QUERY(msg)) goto TOP; if(Handle_CMD(msg)) goto TOP; switch(msg) { case eMessage_BRK_Complete: return; case eMessage_Shutdown: //terminate this dll process return; case eMessage_SetBuffer: { printf("eMessage_SetBuffer\n"); int which = ReadPipe<s32>(); std::string name = ReadPipeString(); IPCRingBuffer* ipcrb = new IPCRingBuffer(); ipcrb->Open(name); if(which==0) rbuf = ipcrb; else wbuf = ipcrb; break; } case eMessage_BeginBufferIO: bufio = true; break; case eMessage_EndBufferIO: bufio = false; break; } //switch(msg) } }