static bool ICV_Init(const char *newcode) { if((size_t)ict != (size_t)-1) { iconv_close(ict); ict = (iconv_t)-1; } if((size_t)ict_to_utf8 != (size_t)-1) { iconv_close(ict_to_utf8); ict_to_utf8 = (iconv_t)-1; } if((size_t)ict_utf16_to_game != (size_t)-1) { iconv_close(ict_utf16_to_game); ict_utf16_to_game = (iconv_t)-1; } ict = iconv_open(newcode, "UTF-8"); if((size_t)ict == (size_t)-1) { error_string = trio_aprintf("iconv_open() error: %m", errno); error_time = SDL_GetTicks(); return(0); } ict_to_utf8 = iconv_open("UTF-8", newcode); if((size_t)ict_to_utf8 == (size_t)-1) { error_string = trio_aprintf("iconv_open() error: %m", errno); error_time = SDL_GetTicks(); return(0); } ict_utf16_to_game = iconv_open(newcode, "UTF-16"); if((size_t)ict_utf16_to_game == (size_t)-1) { error_string = trio_aprintf("iconv_open() error: %m", errno); error_time = SDL_GetTicks(); return(0); } if(GameCode) free(GameCode); GameCode = strdup(newcode); return(1); }
uint8 *MemDebuggerPrompt::TextToBS(const char *text, size_t *TheCount) { size_t byte_count; uint8 *thebytes = NULL; size_t text_len = strlen(text); size_t nib_count; thebytes = (uint8 *)calloc(1, text_len / 2); nib_count = 0; for(size_t x = 0; x < text_len; x++) { int c = tolower(text[x]); if(c >= '0' && c <= '9') c -= '0'; else if(c >= 'a' && c <= 'f') { c = c - 'a' + 0xa; } else if(c == ' ') { continue; } else { error_string = trio_aprintf("Invalid character '%c' in bytestring.", c); error_time = SDL_GetTicks(); InPrompt = None; free(thebytes); return(NULL); } thebytes[nib_count >> 1] |= c << ((nib_count & 1) ? 0 : 4); nib_count++; } if(nib_count & 1) { error_string = trio_aprintf("Invalid number of characters in bytestring."); error_time = SDL_GetTicks(); InPrompt = None; free(thebytes); return(NULL);; } byte_count = nib_count >> 1; *TheCount = byte_count; return(thebytes); }
std::vector<std::string> WSwanDBG_GetBranchTrace(void) { std::vector<std::string> ret; for(int x = 0; x < 16; x++) { char *tmps = trio_aprintf("%04x:%04X", BTEntriesCS[(x + BTIndex) & 0xF], BTEntries[(x + BTIndex) & 0xF]); ret.push_back(std::string(tmps)); free(tmps); } return(ret); }
static void CreateDirs(void) { const char *subs[6]={"mcs","mcm","snaps","gameinfo","sav","cheats"}; char *tdir; int x; MDFN_mkdir(DrBaseDirectory, S_IRWXU); for(x = 0;x < 6;x++) { tdir = trio_aprintf("%s"PSS"%s",DrBaseDirectory,subs[x]); MDFN_mkdir(tdir, S_IRWXU); free(tdir); } }
static void ProcessCommand(const uint8 cmd, const uint32 raw_len, const char **PortDNames, void *PortData[], uint32 PortLen[], int NumPorts) { switch(cmd) { case 0: break; // No command default: MDFN_DoSimpleCommand(cmd); break; case MDFNNPCMD_INTEGRITY: SendIntegrity(); break; case MDFNNPCMD_REQUEST_STATE: SendState(); break; case MDFNNPCMD_LOADSTATE: RecvState(raw_len); MDFN_DispMessage(_("Remote state loaded.")); break; case MDFNNPCMD_SERVERTEXT: { static const uint32 MaxLength = 2000; uint8 neobuf[MaxLength + 1]; char *textbuf = NULL; const uint32 totallen = raw_len; if(totallen > MaxLength) // Sanity check { throw MDFN_Error(0, _("Text length is too long: %u"), totallen); } MDFND_RecvData(neobuf, totallen); neobuf[totallen] = 0; trio_asprintf(&textbuf, "** %s", neobuf); MDFND_NetplayText((UTF8*)textbuf, FALSE); free(textbuf); } break; case MDFNNPCMD_ECHO: { uint32 totallen = raw_len; uint64 then_time; uint64 now_time; if(totallen != sizeof(then_time)) { throw MDFN_Error(0, _("Echo response length is incorrect size: %u"), totallen); } MDFND_RecvData(&then_time, sizeof(then_time)); now_time = MDFND_GetTime(); char *textbuf = NULL; trio_asprintf(&textbuf, _("*** Round-trip time: %llu ms"), (unsigned long long)(now_time - then_time)); MDFND_NetplayText((UTF8*)textbuf, FALSE); free(textbuf); } break; case MDFNNPCMD_TEXT: { static const uint32 MaxLength = 2000; uint8 neobuf[MaxLength + 1]; const uint32 totallen = raw_len; uint32 nicklen; bool NetEcho = false; char *textbuf = NULL; if(totallen < 4) { throw MDFN_Error(0, _("Text command length is too short: %u"), totallen); } if(totallen > MaxLength) // Sanity check { throw MDFN_Error(0, _("Text command length is too long: %u"), totallen); } MDFND_RecvData(neobuf, totallen); nicklen = MDFN_de32lsb(neobuf); if(nicklen > (totallen - 4)) // Sanity check { throw MDFN_Error(0, _("Received nickname length is too long: %u"), nicklen); } neobuf[totallen] = 0; if(nicklen) { uint8 nickbuf[nicklen + 1]; memcpy(nickbuf, neobuf + 4, nicklen); nickbuf[nicklen] = 0; if(OurNick && !strcasecmp(OurNick, (char *)nickbuf)) { trio_asprintf(&textbuf, "> %s", &neobuf[4 + nicklen]); NetEcho = true; } else trio_asprintf(&textbuf, "<%s> %s", nickbuf, &neobuf[4 + nicklen]); } else { trio_asprintf(&textbuf, "* %s", &neobuf[4]); } MDFND_NetplayText((UTF8*)textbuf, NetEcho); free(textbuf); } break; case MDFNNPCMD_NICKCHANGED: { static const uint32 MaxLength = 2000; uint8 neobuf[MaxLength + 1]; uint8 *newnick; char *textbuf = NULL; const uint32 len = raw_len; if(len > MaxLength) // Sanity check { throw MDFN_Error(0, _("Nickname change length is too long: %u"), len); } MDFND_RecvData(neobuf, len); neobuf[len] = 0; newnick = (uint8*)strchr((char*)neobuf, '\n'); if(newnick) { bool IsMeow = FALSE; *newnick = 0; newnick++; if(OurNick) { if(!strcasecmp((char*)neobuf, (char*)OurNick)) { free(OurNick); OurNick = strdup((char*)newnick); textbuf = trio_aprintf(_("* You are now known as <%s>."), newnick); IsMeow = TRUE; } } if(!textbuf) textbuf = trio_aprintf(_("* <%s> is now known as <%s>"), neobuf, newnick); MDFND_NetplayText((UTF8*)textbuf, IsMeow); free(textbuf); } } break; case MDFNNPCMD_CTRL_CHANGE: { const uint32 len = raw_len; // // Joined = true; SendCommand(MDFNNPCMD_CTRL_CHANGE_ACK, len); // // LocalInputStateSize = 0; LocalPlayersMask = len; for(int x = 0; x < MDFNGameInfo->InputInfo->InputPorts; x++) { if(LocalPlayersMask & (1 << x)) LocalInputStateSize += PortLen[x]; } } break; case MDFNNPCMD_CTRLR_SWAP_NOTIF: { const uint32 cm = raw_len; char textbuf[512]; trio_snprintf(textbuf, sizeof(textbuf), _("* All instances of controllers %u and %u have been swapped."), ((cm & 0xFF) + 1), ((cm >> 8) & 0xFF) + 1); MDFND_NetplayText((UTF8*)textbuf, false); } break; case MDFNNPCMD_CTRLR_TAKE_NOTIF: case MDFNNPCMD_CTRLR_DROP_NOTIF: case MDFNNPCMD_CTRLR_DUPE_NOTIF: { static const uint32 MaxNicknameLength = 1000; static const uint32 MaxLength = 12 + MaxNicknameLength; const char *fstr = NULL; const uint32 len = raw_len; uint8 ntf_buf[MaxLength + 1]; char *textbuf = NULL; if(len < 12) throw MDFN_Error(0, _("Take/drop/dupe notification is too short: %u"), len); if(len > MaxLength) throw MDFN_Error(0, _("Take/drop/dupe notification is too long: %u"), len); MDFND_RecvData(ntf_buf, len); ntf_buf[len] = 0; switch(cmd) { case MDFNNPCMD_CTRLR_TAKE_NOTIF: fstr = _("* <%s> took all instances of %s, and is now %s."); break; case MDFNNPCMD_CTRLR_DUPE_NOTIF: fstr = _("* <%s> took copies of %s, and is now %s."); break; case MDFNNPCMD_CTRLR_DROP_NOTIF: fstr = _("* <%s> dropped %s, and is now %s."); break; } trio_asprintf(&textbuf, fstr, ntf_buf + 12, GenerateMPSString(MDFN_de32lsb(&ntf_buf[0]), true).c_str(), GenerateMPSString(MDFN_de32lsb(&ntf_buf[4]), false).c_str()); MDFND_NetplayText((UTF8*)textbuf, false); free(textbuf); } break; case MDFNNPCMD_YOUJOINED: case MDFNNPCMD_YOULEFT: case MDFNNPCMD_PLAYERLEFT: case MDFNNPCMD_PLAYERJOINED: { static const uint32 MaxLength = 2000; uint8 neobuf[MaxLength + 1]; char *textbuf = NULL; uint32 mps; std::string mps_string; const uint32 len = raw_len; if(len < 8) { throw MDFN_Error(0, _("Join/Left length is too short: %u"), len); } if(len > MaxLength) // Sanity check { throw MDFN_Error(0, _("Join/Left length is too long: %u"), len); } MDFND_RecvData(neobuf, len); neobuf[len] = 0; // NULL-terminate the string mps = MDFN_de32lsb(&neobuf[0]); mps_string = GenerateMPSString(mps); if(cmd == MDFNNPCMD_YOULEFT) { // Uhm, not supported yet! LocalPlayersMask = 0; LocalInputStateSize = 0; Joined = FALSE; } else if(cmd == MDFNNPCMD_YOUJOINED) { if(OurNick) // This shouldn't happen, really... { free(OurNick); OurNick = NULL; } OurNick = strdup((char*)neobuf + 8); trio_asprintf(&textbuf, _("* You, %s, have connected as: %s"), neobuf + 8, mps_string.c_str()); LocalPlayersMask = mps; LocalInputStateSize = 0; for(int x = 0; x < MDFNGameInfo->InputInfo->InputPorts; x++) { if(LocalPlayersMask & (1U << x)) LocalInputStateSize += PortLen[x]; } Joined = TRUE; SendCommand(MDFNNPCMD_SETFPS, MDFNGameInfo->fps); } else if(cmd == MDFNNPCMD_PLAYERLEFT) { trio_asprintf(&textbuf, _("* %s(%s) has left"), neobuf + 8, mps_string.c_str()); } else { trio_asprintf(&textbuf, _("* %s has connected as: %s"), neobuf + 8, mps_string.c_str()); } MDFND_NetplayText((UTF8*)textbuf, FALSE); free(textbuf); } break; } }
MDFN_Error::MDFN_Error(const ErrnoHolder &enh) { errno_code = enh.Errno(); error_message = trio_aprintf("%s", enh.StrError()); }
// Call this from the main thread int MemDebugger_Event(const SDL_Event *event) { if(!InPrompt && myprompt) { delete myprompt; myprompt = NULL; } unsigned int keysym = event->key.keysym.sym; switch(event->type) { case SDL_KEYDOWN: if(event->key.keysym.mod & KMOD_ALT) break; if(InPrompt) { myprompt->Event(event); } else if(InEditMode && InTextArea && keysym != SDLK_TAB && keysym != SDLK_INSERT && keysym != SDLK_UP && keysym != SDLK_DOWN && keysym != SDLK_LEFT && keysym != SDLK_RIGHT && (event->key.keysym.unicode >= 0x20)) { uint8 to_write[16]; int to_write_len; size_t ibl, obl, obl_start; char *inbuf, *outbuf; ibl = 2; obl_start = obl = 16; inbuf = (char *)&event->key.keysym.unicode; outbuf = (char*)to_write; size_t result = iconv(ict_utf16_to_game, (ICONV_CONST char **)&inbuf, &ibl, &outbuf, &obl); if(result != (size_t)-1) { to_write_len = 16 - obl; LockGameMutex(1); ASpace->PutAddressSpaceBytes(ASpace->name, ASpacePos[CurASpace], to_write_len, 1, TRUE, to_write); LockGameMutex(0); LowNib = 0; ChangePos(to_write_len); } } else if(InEditMode && ((event->key.keysym.sym >= SDLK_0 && event->key.keysym.sym <= SDLK_9) || (event->key.keysym.sym >= SDLK_a && event->key.keysym.sym <= SDLK_f))) { uint8 tc = 0; uint8 meowbyte = 0; if(event->key.keysym.sym >= SDLK_0 && event->key.keysym.sym <= SDLK_9) tc = 0x0 + event->key.keysym.sym - SDLK_0; else if(event->key.keysym.sym >= SDLK_a && event->key.keysym.sym <= SDLK_f) tc = 0xA + event->key.keysym.sym - SDLK_a; LockGameMutex(1); ASpace->GetAddressSpaceBytes(ASpace->name, ASpacePos[CurASpace], 1, &meowbyte); meowbyte &= 0xF << ((LowNib) * 4); meowbyte |= tc << ((!LowNib) * 4); ASpace->PutAddressSpaceBytes(ASpace->name, ASpacePos[CurASpace], 1, 1, TRUE, &meowbyte); LockGameMutex(0); LowNib = !LowNib; if(!LowNib) ChangePos(1); } else switch(event->key.keysym.sym) { default: break; case SDLK_MINUS: Debugger_ModOpacity(-8); break; case SDLK_EQUALS: Debugger_ModOpacity(8); break; case SDLK_TAB: InTextArea = !InTextArea; LowNib = FALSE; break; case SDLK_d: InPrompt = DumpMem; myprompt = new MemDebuggerPrompt("Dump Memory(start end filename)", ""); break; case SDLK_l: InPrompt = LoadMem; myprompt = new MemDebuggerPrompt("Load Memory(start end filename)", ""); break; case SDLK_s: if(SizeCache[CurASpace] > (1 << 24)) { error_string = trio_aprintf("Address space is too large to search!"); error_time = SDL_GetTicks(); } else { InPrompt = ByteStringSearch; myprompt = new MemDebuggerPrompt("Byte String Search", BSS_String); } break; case SDLK_r: if(SizeCache[CurASpace] > (1 << 24)) { error_string = trio_aprintf("Address space is too large to search!"); error_time = SDL_GetTicks(); } else { InPrompt = RelSearch; myprompt = new MemDebuggerPrompt("Byte String Relative/Delta Search", RS_String); } break; case SDLK_c: InPrompt = SetCharset; myprompt = new MemDebuggerPrompt("Charset", GameCode); break; case SDLK_t: if(ASpace->TotalBits > 24) { error_string = trio_aprintf("Address space is too large to search!"); error_time = SDL_GetTicks(); } else { InPrompt = TextSearch; myprompt = new MemDebuggerPrompt("Text Search", TS_String); } break; case SDLK_g: if(event->key.keysym.mod & KMOD_SHIFT) { InPrompt = GotoDD; myprompt = new MemDebuggerPrompt("Goto Address(DD)", ""); } else { InPrompt = Goto; myprompt = new MemDebuggerPrompt("Goto Address", ""); } break; case SDLK_INSERT: InEditMode = !InEditMode; LowNib = FALSE; break; case SDLK_END: ASpacePos[CurASpace] = (SizeCache[CurASpace] - 128) % SizeCache[CurASpace]; LowNib = FALSE; break; case SDLK_HOME: ASpacePos[CurASpace] = 0; LowNib = FALSE; break; case SDLK_PAGEUP: ChangePos(-16 * 16); break; case SDLK_PAGEDOWN: ChangePos(16 * 16); break; case SDLK_UP: ChangePos(-16); break; case SDLK_DOWN: ChangePos(16); break; case SDLK_LEFT: ChangePos(-1); break; case SDLK_RIGHT: ChangePos(1); break; case SDLK_COMMA: if(CurASpace) CurASpace--; else CurASpace = AddressSpaces->size() - 1; ASpace = &(*AddressSpaces)[CurASpace]; LowNib = FALSE; break; case SDLK_PERIOD: CurASpace = (CurASpace + 1) % AddressSpaces->size(); ASpace = &(*AddressSpaces)[CurASpace]; LowNib = FALSE; break; case SDLK_b: //InMarkMode = !InMarkMode; //if(InMarkMode) // MarkModeBegin = ASpacePos[CurASpace]; DoCrazy(); break; case SDLK_e: if(InMarkMode) { FILE *fp = fopen("markers.txt", "ab"); fprintf(fp, "%08x %08x\n", MarkModeBegin, ASpacePos[CurASpace]); fclose(fp); InMarkMode = FALSE; } break; } break; } return(1); }
void MemDebuggerPrompt::TheEnd(const std::string &pstring) { if(error_string) { free(error_string); error_string = NULL; } if(InPrompt == Goto || InPrompt == GotoDD) { unsigned long NewAddie; if(trio_sscanf(pstring.c_str(), "%08lx", &NewAddie) == 1) { ASpacePos[CurASpace] = NewAddie; LowNib = FALSE; if(InPrompt == GotoDD) GoGoPowerDD[CurASpace] = NewAddie; } } else if(InPrompt == SetCharset) { if(ICV_Init(pstring.c_str())) { LockGameMutex(1); MDFNI_SetSetting(std::string(std::string(CurGame->shortname) + "." + std::string("debugger.memcharenc")).c_str(), pstring.c_str()); LockGameMutex(0); } } else if(InPrompt == DumpMem) { uint32 A1, A2, tmpsize; char fname[256]; bool acceptable = FALSE; if(trio_sscanf(pstring.c_str(), "%08x %08x %255[^\r\n]", &A1, &A2, fname) == 3) acceptable = TRUE; else if(trio_sscanf(pstring.c_str(), "%08x +%08x %255[^\r\n]", &A1, &tmpsize, fname) == 3) { acceptable = TRUE; A2 = A1 + tmpsize - 1; } if(acceptable) { FILE *fp = fopen(fname, "wb"); if(fp) { uint8 write_buffer[256]; uint64 a = A1; //printf("%08x %08x\n", A1, A2); LockGameMutex(1); while(a <= A2) { size_t to_write; to_write = A2 - a + 1; if(to_write > 256) to_write = 256; ASpace->GetAddressSpaceBytes(ASpace->name, a, to_write, write_buffer); if(fwrite(write_buffer, 1, to_write, fp) != to_write) { error_string = trio_aprintf("File write error: %m", errno); error_time = SDL_GetTicks(); break; } a += to_write; } LockGameMutex(0); fclose(fp); } else { error_string = trio_aprintf("File open error: %m", errno); error_time = SDL_GetTicks(); } } } else if(InPrompt == LoadMem) { uint32 A1, A2, tmpsize; char fname[256]; bool acceptable = FALSE; if(trio_sscanf(pstring.c_str(), "%08x %08x %255[^\r\n]", &A1, &A2, fname) == 3) acceptable = TRUE; else if(trio_sscanf(pstring.c_str(), "%08x +%08x %255[^\r\n]", &A1, &tmpsize, fname) == 3) { acceptable = TRUE; A2 = A1 + tmpsize - 1; } if(acceptable) { FILE *fp = fopen(fname, "rb"); if(fp) { LockGameMutex(1); uint8 read_buffer[256]; uint64 a = A1; while(a <= A2) { size_t to_read; size_t read_len; to_read = A2 - a + 1; if(to_read > 256) to_read = 256; read_len = fread(read_buffer, 1, to_read, fp); if(read_len > 0) ASpace->PutAddressSpaceBytes(ASpace->name, a, read_len, 1, TRUE, read_buffer); a += read_len; if(read_len != to_read) { if(ferror(fp)) { error_string = trio_aprintf("File read error: %m", errno); error_time = SDL_GetTicks(); } else if(feof(fp)) { error_string = trio_aprintf("Warning: unexpected EOF(short by %08x byte(s))", A2 - a + 1); error_time = SDL_GetTicks(); } break; } } LockGameMutex(0); fclose(fp); } else { error_string = trio_aprintf("File open error: %m", errno); error_time = SDL_GetTicks(); } } } else if(InPrompt == TextSearch) { uint8 *thebytes; uint32 bcount; TS_String = pstring; char *inbuf, *outbuf; char *utf8_string; size_t ibl, obl, obl_start; size_t result; utf8_string = strdup(pstring.c_str()); ibl = strlen(utf8_string); obl_start = obl = (ibl + 1) * 8; // Hehe, ugly maximum estimation! thebytes = (uint8 *)calloc(1, obl_start); inbuf = utf8_string; outbuf = (char*)thebytes; result = iconv(ict, (ICONV_CONST char **)&inbuf, &ibl, &outbuf, &obl); if(result == (size_t)-1) { error_string = trio_aprintf("iconv() error: %m", errno); error_time = SDL_GetTicks(); InPrompt = None; free(utf8_string); free(thebytes); return; } bcount = obl_start - obl; free(utf8_string); if(!DoBSSearch(bcount, thebytes)) { error_string = trio_aprintf("String not found."); error_time = SDL_GetTicks(); InPrompt = None; } free(thebytes); } else if(InPrompt == ByteStringSearch) { size_t byte_count; uint8 *the_bytes; BSS_String = pstring; if(!(the_bytes = TextToBS(pstring.c_str(), &byte_count))) return; if(!DoBSSearch(byte_count, the_bytes)) { free(the_bytes); error_string = trio_aprintf("Bytestring \"%s\" not found.", pstring.c_str()); error_time = SDL_GetTicks(); InPrompt = None; return; } free(the_bytes); } else if(InPrompt == RelSearch) { size_t byte_count; uint8 *the_bytes; RS_String = pstring; if(!(the_bytes = TextToBS(pstring.c_str(), &byte_count))) return; if(!DoRSearch(byte_count, the_bytes)) { free(the_bytes); error_string = trio_aprintf("Bytestring \"%s\" not found.", pstring.c_str()); error_time = SDL_GetTicks(); InPrompt = None; return; } free(the_bytes); } InPrompt = None; }