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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
 }
}
Beispiel #5
0
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;
  }
}
Beispiel #6
0
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;
}