Пример #1
0
bool MemDebuggerPrompt::DoRSearch(uint32 byte_count, uint8 *the_bytes)
{
	 const uint64 zemod = SizeCache[CurASpace];
         const uint32 start_a = (ASpacePos[CurASpace] - 1) % zemod;
         uint32 a = start_a;
	 bool found = FALSE;
	 uint8 *bbuffer = (uint8 *)calloc(1, byte_count);

	 LockGameMutex(1);
         do
         {
          ASpace->GetAddressSpaceBytes(ASpace->name, a, byte_count + 1, bbuffer);
          bool match = TRUE;

          for(uint32 i = 1; i <= byte_count; i++)
          {
           if(((bbuffer[i] - bbuffer[i - 1]) & 0xFF) != the_bytes[i - 1])
           {
            match = FALSE;
            break;
           }
          }
          if(match)
          {
           found = TRUE;
           ASpacePos[CurASpace] = (a + 1) % zemod;
           break;
          }
          a = (a + 1) % zemod;
         } while(a != start_a);
	 LockGameMutex(0);
	 free(bbuffer);

	 return(found);
}
Пример #2
0
bool MemDebuggerPrompt::DoBSSearch(uint32 byte_count, uint8 *thebytes)
{
	 const uint64 zemod = SizeCache[CurASpace];
         const uint32 start_a = ASpacePos[CurASpace] % zemod;
         uint32 a = start_a;
	 bool found = FALSE;
	 uint8 *bbuffer = (uint8 *)calloc(1, byte_count);

	 LockGameMutex(1);
         do
         {
          ASpace->GetAddressSpaceBytes(ASpace->name, a, byte_count, bbuffer);
          if(!memcmp(bbuffer, thebytes, byte_count))
          {
           ASpacePos[CurASpace] = a;
           found = TRUE;
           break;
          }
          a = (a + 1) % zemod;
         } while(a != start_a);
	 LockGameMutex(0);

	 free(bbuffer);
	 return(found);
}
Пример #3
0
// Call this function from either thread.
void MemDebugger_SetActive(bool newia)
{
 if(CurGame->Debugger)
 {
  LockGameMutex(1);

  IsActive = newia;
  if(!newia)
  {
   InEditMode = FALSE;
   LowNib = FALSE;
  }
  LockGameMutex(0);
 }
}
Пример #4
0
void DebuggerFudge(void)
{
          LockGameMutex(0);

	  int MeowCowHowFlown = VTBackBuffer;

          MDFND_Update((uint32 *)VTBuffer[VTBackBuffer], NULL, 0);
	  VTBackBuffer = MeowCowHowFlown;

	  if(sound_active)
	   WriteSoundSilence(10);
	  else
	   SDL_Delay(10);

	  LockGameMutex(1);
}
Пример #5
0
// Call this function from either thread.
void GfxDebugger_SetActive(bool newia)
{
 if(CurGame->Debugger && CurGame->Debugger->SetGraphicsDecode)
 {
  LockGameMutex(1);

  IsActive = newia;

  if(IsActive && !LayerCount)
  {
   LayerCount = 0;

   int clen;
   const char *lnp = CurGame->LayerNames;
   while((clen = strlen(lnp)))
   {
    LayerNames[LayerCount] = lnp;
    LayerCount++;
    lnp += clen + 1;
   }
  }

  if(!IsActive)
  {
   if(gd_surface)
   {
    delete gd_surface;
    gd_surface = NULL;
   }
  }
  else if(IsActive)
  {
   if(!gd_surface)
    gd_surface = new MDFN_Surface(NULL, 128, 128, 128 * 3, MDFN_PixelFormat(MDFN_COLORSPACE_RGB, 0, 8, 16, 24));
  }
  RedoSGD();
  LockGameMutex(0);
 }
}
Пример #6
0
static void ParseSTDIOCommand(char *buf)
{
 char *arguments[8];
 int which_argument = 0;
 size_t blen = strlen(buf);
 bool InQuote = 0;
 char *InBegin = NULL;
 char last_char = 0;

 memset(arguments, 0, sizeof(arguments));

 for(size_t x = 0; x <= blen; x++)
 {
  if((buf[x] == ' ' || buf[x] == 0) && last_char != '\\' && !InQuote && InBegin)
  {
   buf[x] = 0;

   unescape_string(InBegin);
   arguments[which_argument] = InBegin;
   which_argument++;
   if(which_argument == 8)
   {
    break;
   }
   InBegin = NULL;
  }
  else if(buf[x] != ' ' && buf[x] != '\t' && buf[x] != '"' && last_char != '\\' && !InQuote && !InBegin)
  {
   InBegin = &buf[x];
  }
  else if(buf[x] == '"' && last_char != '\\')
  {
   if(InBegin)
   {
    buf[x] = 0;
    unescape_string(InBegin);
    arguments[which_argument] = InBegin;
    which_argument++;
    if(which_argument == 8)
    {
     break;
    }
    InQuote = 0;
    InBegin = NULL;
   }
   else
   {
    InQuote = TRUE;
    InBegin = &buf[x + 1];
   }
  }
  last_char = buf[x];
 }

 int numargs = which_argument; // numargs count includes the command.  Misleading, yes!
 bool success = 0;
 bool suppress_success = 0;

 if(numargs)
 {
  if(!strcasecmp(arguments[0], "exit"))
  {
   MainRequestExit();
   suppress_success = TRUE;
  }
  else if(!strcasecmp(arguments[0], "sync_video"))
  {
   success = MT_FromRemote_VideoSync();
  }
  else if(!strcasecmp(arguments[0], "sync_sound"))
  {
   success = MT_FromRemote_SoundSync();
  }
  else if(!strcasecmp(arguments[0], "get_setting"))
  {
   if(numargs == 2)
   {
    std::string sval;

    LockGameMutex(TRUE);

    sval = MDFN_GetSettingS(arguments[1]);
    success = TRUE;

    LockGameMutex(FALSE);

    Remote_SendCommand("return", 2, "success", sval.c_str());
    return;
   }
   else
    puts("Invalid number of arguments");
  }
  else if(!strcasecmp(arguments[0], "set_setting"))
  {
   if(numargs == 3)
   {
    LockGameMutex(TRUE);
    success = MDFNI_SetSetting(arguments[1], arguments[2]);
    LockGameMutex(FALSE);
   }
   else
    puts("Invalid number of arguments");
  }
  else if(!strcasecmp(arguments[0], "get_known_fileexts"))
  {
   uint32 count = 0;
   char count_string[64];

   // TODO:  Move to core
   for(unsigned int i = 0; i < MDFNSystems.size(); i++)
   {
    const FileExtensionSpecStruct *FileExtensions = MDFNSystems[i]->FileExtensions;
    if(FileExtensions)
     while(FileExtensions->extension)
     {
      count++;
      FileExtensions++;
     }
   }
   trio_snprintf(count_string, 64, "%u", count);
   Remote_SendCommand("result_count", 1, count_string);

   for(unsigned int i = 0; i < MDFNSystems.size(); i++)
   {
    const FileExtensionSpecStruct *FileExtensions = MDFNSystems[i]->FileExtensions;
    if(FileExtensions)
     while(FileExtensions->extension)
     {
      Remote_SendCommand("result", 3, MDFNSystems[i]->shortname, FileExtensions->extension, FileExtensions->description);
      FileExtensions++;
     }
   }
   success = TRUE;
  }
  else
  {
   puts("Unknown command!");
  }
 }

 if(!suppress_success)
 {
  if(success)
  {
   Remote_SendCommand("return", 1, "success");
  }
  else
  {
   Remote_SendCommand("return", 1, "failure");
  }
 }
 //printf("%s %s %s %s %s %s\n", arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
}
Пример #7
0
// Call this function from the main thread
void GfxDebugger_Draw(MDFN_Surface *surface, const MDFN_Rect *rect, const MDFN_Rect *screen_rect)
{
 if(!IsActive)
  return;

 const MDFN_PixelFormat pf_cache = surface->format;
 uint32 *src_pixels;
 uint32 * pixels = surface->pixels;
 uint32 pitch32 = surface->pitchinpix;
 bool ism;

 LockGameMutex(1);

 ism = InSteppingMode;

 if(ism)
 {
  RedoSGD(TRUE);
 }

 if(gd_surface->format.Rshift != surface->format.Rshift || gd_surface->format.Gshift != surface->format.Gshift ||
  gd_surface->format.Bshift != surface->format.Bshift || gd_surface->format.Ashift != surface->format.Ashift ||
  gd_surface->format.colorspace != surface->format.colorspace)
 {
  //puts("Convert Meow");
  gd_surface->SetFormat(surface->format, TRUE);
 }

 src_pixels = gd_surface->pixels;

 if(!src_pixels)
 {
  LockGameMutex(0);
  return;
 }

 for(unsigned int y = 0; y < 128; y++)
 {
  uint32 *row = pixels + ((rect->w - 256) / 2) + y * pitch32 * 2;
  for(unsigned int x = 0; x < 128; x++)
  {
   //printf("%d %d %d\n", y, x, pixels);
   row[x*2] = row[x*2 + 1] = row[pitch32 + x*2] = row[pitch32 + x*2 + 1] = src_pixels[x + y * 128 * 3];
   //row[x] = MK_COLOR_A(0, 0, 0, 0xc0);
   //row[x] = MK_COLOR_A(0x00, 0x00, 0x00, 0x7F);
  }
 }


 // Draw layer name
 {
  for(unsigned int y = 256; y < 256 + 18; y++)
   for(unsigned int x = 0; x < rect->w; x++)
   {
    pixels[y * pitch32 + x] = MK_COLOR_A(0x00, 0x00, 0x00, 0xC0);
   }
  char buf[256];

  if(ism)
   trio_snprintf(buf, 256, "%s, PBN: %d, Scroll: %d, Instant", LayerNames[CurLayer], LayerPBN[CurLayer], LayerScroll[CurLayer]);
  else
   trio_snprintf(buf, 256, "%s, PBN: %d, Scroll: %d, Line: %d", LayerNames[CurLayer], LayerPBN[CurLayer], LayerScroll[CurLayer], LayerScanline[CurLayer]);
  DrawTextTransShadow(pixels + 256 * pitch32, surface->pitchinpix << 2, rect->w, (UTF8*)buf, MK_COLOR_A(0xF0, 0xF0, 0xF0, 0xFF), MK_COLOR_A(0, 0, 0, 0xFF), 1, FALSE);
 }

 int mousex, mousey;
 SDL_GetMouseState(&mousex, &mousey);
 int vx, vy;

 vx = (mousex - screen_rect->x) * rect->w / screen_rect->w - ((rect->w - 256) / 2);
 vy = (mousey - screen_rect->y) * rect->h / screen_rect->h;

 vx /= 2;
 vy /= 2;

 if(vx < 128 && vy < 128 && vx >= 0 && vy >= 0)
 {
  if(src_pixels[vx + vy * 128 * 3] & (0xFF << surface->format.Ashift))
  {
   for(unsigned int y = 278; y < 278 + 18; y++)
    for(unsigned int x = 0; x < rect->w; x++)
    {
     pixels[y * pitch32 + x] = MK_COLOR_A(0x00, 0x00, 0x00, 0xC0);
    }
   char buf[256];

   trio_snprintf(buf, 256, "Tile: %08x, Address: %08x", src_pixels[128 + vx + vy * 128 * 3], src_pixels[256 + vx + vy * 128 * 3]);

   DrawTextTransShadow(pixels + 278 * pitch32, surface->pitchinpix << 2, rect->w, (UTF8*)buf, MK_COLOR_A(0xF0, 0xF0, 0xF0, 0xFF), MK_COLOR_A(0, 0, 0, 0xFF), 1, FALSE);  
  }
 }

 LockGameMutex(0);
}
Пример #8
0
// Call this from the main thread
int GfxDebugger_Event(const SDL_Event *event)
{
 switch(event->type)
 {
  case SDL_KEYDOWN:
	switch(event->key.keysym.sym)
	{
	 default: break;

	 case SDLK_MINUS:
		       LockGameMutex(1);
		       if(LayerScanline[CurLayer])
		       {
			LayerScanline[CurLayer]--;
			RedoSGD();
		       }
		       LockGameMutex(0);
		       break;
	 case SDLK_EQUALS:
		       LockGameMutex(1);
		       LayerScanline[CurLayer]++;
		       RedoSGD();
		       LockGameMutex(0);
		       break;
         case SDLK_UP: LockGameMutex(1);
		       if(LayerScroll[CurLayer])
		       {
                        LayerScroll[CurLayer]--;
                        RedoSGD();
		       }
                       LockGameMutex(0);
                       break;

         case SDLK_PAGEUP:
                         LockGameMutex(1);
                         LayerScroll[CurLayer] -= 8;
			 if(LayerScroll[CurLayer] < 0)
			  LayerScroll[CurLayer] = 0;
                         RedoSGD();
                         LockGameMutex(0);
                         break;

	 case SDLK_PAGEDOWN:
			 LockGameMutex(1);
			 LayerScroll[CurLayer] += 8;
			 RedoSGD();
			 LockGameMutex(0);
			 break;
	 case SDLK_DOWN: LockGameMutex(1);
			 LayerScroll[CurLayer]++;
			 RedoSGD();
			 LockGameMutex(0);
			 break;
	 case SDLK_LEFT: LockGameMutex(1);
			 CurLayer = (CurLayer - 1);

			 if(CurLayer < 0) CurLayer = LayerCount - 1;

			 RedoSGD();
			 LockGameMutex(0);
			 break;
	 case SDLK_RIGHT: LockGameMutex(1);
			  CurLayer = (CurLayer + 1) % LayerCount;
			  RedoSGD();
			  LockGameMutex(0);
			  break;


	 case SDLK_COMMA: LockGameMutex(1);
			  if(LayerPBN[CurLayer] >= 0)
			   LayerPBN[CurLayer]--;
			  RedoSGD();
			  LockGameMutex(0);
			  break;

	 case SDLK_PERIOD:
			  LockGameMutex(1);
			  LayerPBN[CurLayer]++;
			  RedoSGD();
			  LockGameMutex(0);
			  break;
	}
	break;
 }
 return(1);
}
Пример #9
0
int GameLoop(void *arg)
{
	while(GameThreadRun)
	{
         int16 *sound;
         int32 ssize;
         int fskip;
        
	 /* If we requested a new video mode, wait until it's set before calling the emulation code again.
	 */
	 while(NeedVideoChange) 
	 { 
	  if(!GameThreadRun) return(1);	// Might happen if video initialization failed
	  SDL_Delay(1);
	  }
         do
         {
	  if(InFrameAdvance && !NeedFrameAdvance)
	  {
	   SDL_Delay(10);
	  }
	 } while(InFrameAdvance && !NeedFrameAdvance);

         fskip = ThrottleCheckFS();

	 if(pending_snapshot || pending_save_state || pending_save_movie || NeedFrameAdvance)
	  fskip = 0;

 	 NeedFrameAdvance = 0;
         if(NoWaiting) fskip = 1;

	 VTLineWidths[VTBackBuffer][0].w = ~0;

	 int ThisBackBuffer = VTBackBuffer;

	 LockGameMutex(1);
	 {
	  EmulateSpecStruct espec;
 	  memset(&espec, 0, sizeof(EmulateSpecStruct));

	  espec.pixels = (uint32 *)VTBuffer[VTBackBuffer];
	  espec.LineWidths = (MDFN_Rect *)VTLineWidths[VTBackBuffer];
	  espec.SoundBuf = &sound;
	  espec.SoundBufSize = &ssize;
	  espec.skip = fskip;
	  espec.soundmultiplier = CurGameSpeed;
	  espec.NeedRewind = DNeedRewind;
          MDFNI_Emulate(&espec); //(uint32 *)VTBuffer[VTBackBuffer], (MDFN_Rect *)VTLineWidths[VTBackBuffer], &sound, &ssize, fskip, CurGameSpeed);
	 }
	 LockGameMutex(0);
	 FPS_IncVirtual();
	 if(!fskip)
	  FPS_IncDrawn();

	 do
	 {
          GameThread_HandleEvents();
	  VTBackBuffer = ThisBackBuffer;
          MDFND_Update(fskip ? NULL : (uint32 *)VTBuffer[ThisBackBuffer], sound, ssize);
          if((InFrameAdvance && !NeedFrameAdvance) || GameLoopPaused)
	  {
           if(!ssize)
	    ThrottleCheckFS();
	   else
	    for(int x = 0; x < CurGame->soundchan * ssize; x++)
	     sound[x] = 0;
	  }
	 } while(((InFrameAdvance && !NeedFrameAdvance) || GameLoopPaused) && GameThreadRun);
	}
	return(1);
}   
Пример #10
0
// 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);
}
Пример #11
0
static void DoCrazy(void)
{
 LockGameMutex(1);

 uint32 start = ASpacePos[CurASpace];
 uint32 A = ASpacePos[CurASpace];

 for(;;)
 {
  uint8 zebyte;

  ASpace->GetAddressSpaceBytes(ASpace->name, A, 1, &zebyte);

  // Simple control codes
  if(zebyte < 0x20)
  {
   switch(zebyte)
   {
    default:    printf("UNKNOWN GAHGAHGAH:  %02x\n", zebyte); 
		return;

    case 0x00: goto GetOut; // Crazy escape
    case 0x05: goto GetOut; // Pause+close text box

    // Print numbers, 3 arguments
    case 0x06: 
    case 0x07:
    case 0x08: A += 3; break;

    // Transfer control, 4 arguments
    case 0x12: A += 4; break;

    case 0x0C: break; // Clear text box
    case 0x0D: break; // New line
    case 0x0F: goto GetOut; // Pause+close text box

    case 0x10: break; // Prompt for button to continue
    case 0x11: goto GetOut; // Binary selection magic
    case 0x14: A += 1; break; // Set draw speed, 1 argument
    case 0x17: A += 1; break; // Delay, 1 argument
   }
  }
  else if(zebyte <= 0x7F) // ASCII
  {

  }
  else if(zebyte < 0xEB) // 2-byte SJIS
  {
   A += 1;
  }
  else
  {
   printf("UNKNOWN GAHGAHGAH:  %02x\n", zebyte);
   return;
  }
  A++;
 }

 GetOut:

 ASpacePos[CurASpace] = A;
 printf("%08x\n", A);
 FILE *fp = fopen("markers.txt", "ab");
 fprintf(fp, "%08x %08x\n", start, ASpacePos[CurASpace]);
 fclose(fp);

 LockGameMutex(0);
}
Пример #12
0
// Call this function from the main thread
void MemDebugger_Draw(MDFN_Surface *surface, const MDFN_Rect *rect, const MDFN_Rect *screen_rect)
{
 if(!IsActive) return;

 const MDFN_PixelFormat pf_cache = surface->format;
 uint32 *pixels = surface->pixels;
 uint32 pitch32 = surface->pitchinpix;
 const uint64 zemod = SizeCache[CurASpace];

 LockGameMutex(1);

 DrawTextTrans(pixels, surface->pitchinpix << 2, rect->w, (UTF8*)ASpace->long_name, MK_COLOR_A(0x20, 0xFF, 0x20, 0xFF), 1, 1);
 pixels += 10 * pitch32;

 uint32 A;
 uint32 Ameow; // A meow for a cat

 if(ASpacePos[CurASpace] < 128)
  A = (SizeCache[CurASpace] - 128 + ASpacePos[CurASpace]) % SizeCache[CurASpace];
 else
  A = ASpacePos[CurASpace] - 128;

 Ameow = A &~ 0xF;

 int numrows = zemod / 16;

 if(numrows > 16)
  numrows = 16;
 else if(numrows < 4)
  numrows = 4;

 for(int y = 0; y < numrows; y++)
 {
  uint8 byte_buffer[16];
  char abuf[32];

  Ameow %= zemod;

  ASpace->GetAddressSpaceBytes(ASpace->name, Ameow, 16, byte_buffer);

  if(zemod <= (1 << 16))
   trio_snprintf(abuf, 32, "%04X:", Ameow);
  else if(zemod <= (1 << 24))
   trio_snprintf(abuf, 32, "%06X:", Ameow);
  else
   trio_snprintf(abuf, 32, "%08X:", Ameow);

  uint32 alen;
  uint32 addr_color = MK_COLOR_A(0xA0, 0xA0, 0xFF, 0xFF);

  if(Ameow == (ASpacePos[CurASpace] & ~0xF))
   addr_color = MK_COLOR_A(0x80, 0xB0, 0xFF, 0xFF);

  alen = DrawTextTrans(pixels, surface->pitchinpix << 2, rect->w, (UTF8*)abuf, addr_color, 0, 1);
  alen += 3;

  for(int x = 0; x < 16; x++)
  {
   uint32 bcolor = MK_COLOR_A(0xFF, 0xFF, 0xFF, 0xFF);
   uint32 acolor = MK_COLOR_A(0xA0, 0xA0, 0xA0, 0xFF);

   char quickbuf[16];
   uint32 test_match_pos;
   uint8 ascii_str[2];

   ascii_str[1] = 0;
   ascii_str[0] = byte_buffer[x];

   if(ascii_str[0] < 0x20 || ascii_str[0] >= 128)
    ascii_str[0] = '.';

   trio_snprintf(quickbuf, 16, "%02X", byte_buffer[x]);

   test_match_pos = ASpacePos[CurASpace] % zemod;

   if(InMarkMode)
   {
    if(MarkModeBegin < test_match_pos && Ameow < test_match_pos && Ameow >= MarkModeBegin)
    {
     if(InTextArea)
     {
      acolor = MK_COLOR_A(0xFF, 0x00, 0x00, 0xFF);
      bcolor = MK_COLOR_A(0xFF, 0x80, 0x80, 0xFF);
     }
     else
     { 
      acolor = MK_COLOR_A(0xFF, 0x80, 0x80, 0xFF);
      bcolor = MK_COLOR_A(0xFF, 0x00, 0x00, 0xFF);
     }
    }
   }
   if(Ameow == test_match_pos)
   {
    if(InEditMode)
     if(SDL_GetTicks() & 0x80)
     {
      int pix_offset = alen;

      if(InTextArea)
       pix_offset += 16 * 12 + x * 5;
      else
       pix_offset += (LowNib ? 5 : 0) + x * 12;

      DrawTextTrans(pixels + pix_offset, surface->pitchinpix << 2, rect->w, (UTF8*)"▉", MK_COLOR_A(0xFF, 0xFF, 0xFF, 0xFF), 0, 1);
     }
    if(InTextArea)
    {
     acolor = MK_COLOR_A(0xFF, 0x00, 0x00, 0xFF);
     bcolor = MK_COLOR_A(0xFF, 0x80, 0x80, 0xFF);
    }
    else
    {
     acolor = MK_COLOR_A(0xFF, 0x80, 0x80, 0xFF);
     bcolor = MK_COLOR_A(0xFF, 0x00, 0x00, 0xFF);
    }
   }

   // hex display
   DrawTextTrans(pixels + alen + x * 12, surface->pitchinpix << 2, rect->w, (UTF8*)quickbuf, bcolor, 0, 1);

   // ASCII display
   DrawTextTrans(pixels + alen + 16 * 12 + x * 5, surface->pitchinpix << 2, rect->w, (UTF8 *)ascii_str, acolor, 0, 1);
   Ameow++;
  }
  pixels += 9 * pitch32;
 }

 {
  char cpstr[32];
  uint32 curpos = ASpacePos[CurASpace];
  uint8 zebytes[4];
  uint32 tmpval;

  curpos %= zemod;

  ASpace->GetAddressSpaceBytes(ASpace->name, curpos, 4, zebytes);

  pixels += 8 + 5 * pitch32;

  if(zemod <= (1 << 16))
   trio_snprintf(cpstr, 32, "%04X", curpos);
  else if(zemod <= (1 << 24))
   trio_snprintf(cpstr, 32, "%06X", curpos);
  else
   trio_snprintf(cpstr, 32, "%08X", curpos);

  uint32 cpplen;
  uint32 cplen;

  cpplen = DrawTextTrans(pixels, surface->pitchinpix << 2, rect->w, (UTF8*)"Cursor position: ", MK_COLOR_A(0xa0, 0xa0, 0xFF, 0xFF), 0, 1);
  cplen = DrawTextTrans(pixels + cpplen, surface->pitchinpix << 2, rect->w, (UTF8*)cpstr , MK_COLOR_A(0xFF, 0xFF, 0xFF, 0xFF), 0, 1);
  if(GoGoPowerDD[CurASpace])
  {
   char ggddstr[32];

   if(zemod <= (1 << 16))
    trio_snprintf(ggddstr, 32, "%04X", curpos - GoGoPowerDD[CurASpace]);
   else if(zemod <= (1 << 24))
    trio_snprintf(ggddstr, 32, "%06X", curpos - GoGoPowerDD[CurASpace]);
   else
    trio_snprintf(ggddstr, 32, "%08X", curpos - GoGoPowerDD[CurASpace]);

   DrawTextTrans(pixels + cpplen + cplen + 8, surface->pitchinpix << 2, rect->w, (UTF8*)ggddstr, MK_COLOR_A(0xFF, 0x80, 0x80, 0xFF), 0, 1);
  }
  pixels += 5 + 10 * pitch32;

  tmpval = zebytes[0];
  trio_snprintf(cpstr, 32, "%02x(%u, %d)", tmpval, (uint8)tmpval, (int8)tmpval);
  cpplen = DrawTextTrans(pixels, surface->pitchinpix << 2, rect->w, (UTF8*)"1-byte value: ", MK_COLOR_A(0xA0, 0xA0, 0xFF, 0xFF), 0, 1);
  DrawTextTrans(pixels + cpplen, surface->pitchinpix << 2, rect->w, (UTF8*)cpstr , MK_COLOR_A(0xFF, 0xFF, 0xFF, 0xFF), 0, 1);

  pixels += 10 * pitch32;


  if(ASpace->IsWave && SizeCache[CurASpace] <= 128 && ASpace->WaveBits <= 6)
  {
   const int32 wf_size = SizeCache[CurASpace];
   uint8 waveform[wf_size];
   const int32 pcm_max = (1 << ASpace->WaveBits) - 1;

   DrawTextTrans(pixels - 5, surface->pitchinpix << 2, rect->w, (UTF8 *)"Full waveform:", MK_COLOR_A(0xA0, 0xA0, 0xFF, 0xFF), 0, 1);
   pixels += 9 * pitch32;
   MDFN_DrawRectangleFill(pixels, surface->pitchinpix, 0, 0, MK_COLOR_A(0xA0,0xA0,0xA0,0xFF), MK_COLOR_A(0,0,0,0xFF), 2 + wf_size * 2 + 2, 2 + (pcm_max + 1) + 2);

   ASpace->GetAddressSpaceBytes(ASpace->name, 0, wf_size, waveform);

   for(int i = 0; i < wf_size; i++)
   {
    int32 delta;
    int32 current;
    int32 previous;

    current = waveform[i];
    previous = waveform[(i + wf_size - 1) % wf_size];

    delta = current - previous;

    for(int y = previous; y != current; y += delta / abs(delta))
     pixels[2 + i * 2 + 0 + (2 + (pcm_max - y)) * surface->pitchinpix] = MK_COLOR_A(0x00,0xA0,0x00,0xFF);

    pixels[2 + i * 2 + 0 + (2 + (pcm_max - current)) * surface->pitchinpix] = MK_COLOR_A(0x00,0xA0,0x00,0xFF);
    pixels[2 + i * 2 + 1 + (2 + (pcm_max - current)) * surface->pitchinpix] = MK_COLOR_A(0x00,0xA0,0x00,0xFF);
   }
  }
  else
  {
  tmpval = zebytes[0] | (zebytes[1] << 8);
  trio_snprintf(cpstr, 32, "%04x(%u, %d)", tmpval, (uint16)tmpval, (int16)tmpval);
  cpplen = DrawTextTrans(pixels, surface->pitchinpix << 2, rect->w, (UTF8*)"2-byte value(LSB): ", MK_COLOR_A(0xA0, 0xA0, 0xFF, 0xFF), 0, 1);
  DrawTextTrans(pixels + cpplen, surface->pitchinpix << 2, rect->w, (UTF8*)cpstr , MK_COLOR_A(0xFF, 0xFF, 0xFF, 0xFF), 0, 1);

  pixels += 10 * pitch32;
  tmpval = zebytes[0] | (zebytes[1] << 8) | (zebytes[2] << 16) | (zebytes[3] << 24);
  trio_snprintf(cpstr, 32, "%08x(%u, %d)", tmpval, (uint32)tmpval, (int32)tmpval);
  cpplen = DrawTextTrans(pixels, surface->pitchinpix << 2, rect->w, (UTF8*)"4-byte value(LSB): ", MK_COLOR_A(0xA0, 0xA0, 0xFF, 0xFF), 0, 1);
  DrawTextTrans(pixels + cpplen, surface->pitchinpix << 2, rect->w, (UTF8*)cpstr , MK_COLOR_A(0xFF, 0xFF, 0xFF, 0xFF), 0, 1);

  pixels += 10 * pitch32;
  tmpval = zebytes[1] | (zebytes[0] << 8);
  trio_snprintf(cpstr, 32, "%04x(%u, %d)", tmpval, (uint16)tmpval, (int16)tmpval);
  cpplen = DrawTextTrans(pixels, surface->pitchinpix << 2, rect->w, (UTF8*)"2-byte value(MSB): ", MK_COLOR_A(0xA0, 0xA0, 0xFF, 0xFF), 0, 1);
  DrawTextTrans(pixels + cpplen, surface->pitchinpix << 2, rect->w, (UTF8*)cpstr , MK_COLOR_A(0xFF, 0xFF, 0xFF, 0xFF), 0, 1);

  pixels += 10 * pitch32;
  tmpval = zebytes[3] | (zebytes[2] << 8) | (zebytes[1] << 16) | (zebytes[0] << 24);
  trio_snprintf(cpstr, 32, "%08x(%u, %d)", tmpval, (uint32)tmpval, (int32)tmpval);
  cpplen = DrawTextTrans(pixels, surface->pitchinpix << 2, rect->w, (UTF8*)"4-byte value(MSB): ", MK_COLOR_A(0xA0, 0xA0, 0xFF, 0xFF), 0, 1);
  DrawTextTrans(pixels + cpplen, surface->pitchinpix << 2, rect->w, (UTF8*)cpstr , MK_COLOR_A(0xFF, 0xFF, 0xFF, 0xFF), 0, 1);

  trio_snprintf(cpstr, 32, "%s text: ", GameCode);
  cpplen = DrawTextTrans(pixels + 10 * pitch32, surface->pitchinpix << 2, rect->w, (UTF8*)cpstr, MK_COLOR_A(0xA0, 0xA0, 0xFF, 0xFF), 0, MDFN_FONT_5x7);

  {
   char rawbuf[64];
   char textbuf[256];

   ASpace->GetAddressSpaceBytes(ASpace->name, curpos, 64, (uint8*)rawbuf);

   size_t ibl, obl, obl_start;
   char *inbuf, *outbuf;
   ibl = 64;
   obl_start = obl = 255; // Hehe, ugly maximum estimation!
   inbuf = rawbuf;
   outbuf = textbuf;

   iconv(ict_to_utf8, (ICONV_CONST char **)&inbuf, &ibl, &outbuf, &obl);
   textbuf[obl_start - obl] = 0;

   DrawTextTrans(pixels + 8 * pitch32 + cpplen, surface->pitchinpix << 2, rect->w - cpplen - 13, (UTF8*)textbuf, MK_COLOR_A(0xFF, 0xFF, 0xFF, 0xFF), 0, MDFN_FONT_9x18_18x18);
  }

 }

 }
 LockGameMutex(0);

 if(InPrompt)
  myprompt->Draw(surface, rect);
 else if(myprompt)
 {
  delete myprompt;
  myprompt = NULL;
 }

 if(error_string)
 {
  if(SDL_GetTicks() >= (error_time + 4000))
  {
   free(error_string);
   error_string = NULL;
  }
  else
  {
   DrawTextTrans((uint32*)surface->pixels + (rect->h - 7) * pitch32, surface->pitchinpix << 2, rect->w, (UTF8*)error_string, MK_COLOR_A(0xFF, 0x00, 0x00, 0xFF), 1, 1);
  }
 }
}
Пример #13
0
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;
}