Ejemplo n.º 1
0
static void FreeUNIF(void)
{
 if(UNIFchrrama)
 {
  MDFN_free(UNIFchrrama);
  UNIFchrrama = NULL;
 }

 if(exntar)
 {
  MDFN_free(exntar);
  exntar = NULL;
 }

 if(boardname)
 {
  MDFN_free(boardname);
  boardname = NULL;
 }

 for(int x = 0; x < 32; x++)
 {
  if(malloced[x])
  {
   MDFN_free(malloced[x]);
   malloced[x] = NULL;
  }
 }
}
Ejemplo n.º 2
0
void HuCClose(void)
{
 HuCDumpSave();
 if(IsTsushin && TsushinRAM)
 {
   MDFN_free(TsushinRAM);
   TsushinRAM = NULL;
 }

 if(arcade_card)
 {
  delete arcade_card;
  arcade_card = NULL;
 }

 if(PCE_IsCD)
 {
  PCECD_Close();
 }

 if(HuCROM)
 {
  MDFN_free(HuCROM);
  HuCROM = NULL;
 }
}
Ejemplo n.º 3
0
void HES_Close(void)
{
 if(rom)
 {
  MDFN_free(rom);
  rom = NULL;
 }

 if(rom_backup)
 {
  MDFN_free(rom_backup);
  rom_backup = NULL;
 }
}
Ejemplo n.º 4
0
static bool LoadCPalette(const char *syspalname, uint8 **ptr, uint32 num_entries)
{
 std::string colormap_fn = MDFN_MakeFName(MDFNMKF_PALETTE, 0, syspalname).c_str();

 MDFN_printf(_("Loading custom palette from \"%s\"...\n"),  colormap_fn.c_str());
 MDFN_indent(1);

 *ptr = NULL;
 try
 {
  FileStream fp(colormap_fn.c_str(), FileStream::MODE_READ);

  if(!(*ptr = (uint8 *)MDFN_malloc(num_entries * 3, _("custom color map"))))
  {
   MDFN_indent(-1);
   return(false);
  }

  fp.read(*ptr, num_entries * 3);
 }
 catch(MDFN_Error &e)
 {
  if(*ptr)
  {
   MDFN_free(*ptr);
   *ptr = NULL;
  }

  MDFN_printf(_("Error: %s\n"), e.what());
  MDFN_indent(-1);
  return(e.GetErrno() == ENOENT);        // Return fatal error if it's an error other than the file not being found.
 }
 catch(std::exception &e)
 {
  if(*ptr)
  {
   MDFN_free(*ptr);
   *ptr = NULL;
  }

  MDFN_printf(_("Error: %s\n"), e.what());
  MDFN_indent(-1);
  return(false);
 }

 MDFN_indent(-1);

 return(true);
}
Ejemplo n.º 5
0
void KillOpenGL(void)
{
 if(textures[0])
  p_glDeleteTextures(4, &textures[0]);

 textures[0] = textures[1] = textures[2] = textures[3] = 0;

 if(rgb_mask)
 {
  p_glDeleteTextures(1, &rgb_mask);
  rgb_mask = 0;
 }

 if(DummyBlack)
 {
  MDFN_free(DummyBlack);
  DummyBlack = NULL;
 }
 DummyBlackSize = 0;

 #if MDFN_WANT_OPENGL_SHADERS
 if(UsingShader)
 {
  KillShader();
  UsingShader = FALSE;
 }
 #endif
}
Ejemplo n.º 6
0
void OpenGL_Blitter::Cleanup(void)
{
 if(textures[0])
  p_glDeleteTextures(4, &textures[0]);

 textures[0] = textures[1] = textures[2] = textures[3] = 0;

 if(rgb_mask)
 {
  p_glDeleteTextures(1, &rgb_mask);
  rgb_mask = 0;
 }

 if(DummyBlack)
 {
  MDFN_free(DummyBlack);
  DummyBlack = NULL;
 }
 DummyBlackSize = 0;

 if(shader)
 {
  delete shader;
  shader = NULL;
 }
}
Ejemplo n.º 7
0
void HuCClose(void)
{
 if(IsPopulous)
 {
  MDFN_DumpToFile(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), 6, ROMSpace + 0x40 * 8192, 32768);
 }
 else if(IsBRAMUsed())
 {
  MDFN_DumpToFile(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), 0, SaveRAM, 2048);
 }

 if(arcade_card)
 {
  delete arcade_card;
  arcade_card = NULL;
 }

 if(PCE_IsCD)
 {
  PCECD_Close();
 }

 if(HuCROM)
 {
  MDFN_free(HuCROM);
  HuCROM = NULL;
 }
}
Ejemplo n.º 8
0
MD_Cart_Type_SRAM::~MD_Cart_Type_SRAM()
{
 if(sram)
 {
  MDFN_free(sram);
  sram = NULL;
 }
}
Ejemplo n.º 9
0
static void Close(void)
{
 if(WRAM)
 {
  MDFN_free(WRAM);
  WRAM = NULL;
 }
}
Ejemplo n.º 10
0
//-----------------------------------------------------------------------------
// rom_unload()
//-----------------------------------------------------------------------------
void rom_unload(void)
{
 if(ngpc_rom.data)
 {
	MDFN_free(ngpc_rom.data);
	ngpc_rom.data = NULL;
	ngpc_rom.length = 0;
	rom_header = 0;

	for(int i = 0; i < 16; i++)
	 ngpc_rom.name[i] = 0;
 }		

 if(ngpc_rom.orig_data)
 {
  	MDFN_free(ngpc_rom.orig_data);
  	ngpc_rom.orig_data = NULL;
 }
}
Ejemplo n.º 11
0
void HES_Close(void)
{
 if(rom)
 {
  MDFN_free(rom);
  rom = NULL;
 }
#ifdef WII
 if(rom_backup)
 {
  MDFN_free(rom_backup);
  rom_backup = NULL;
 }

 if(PCE_IsCD)
 {
  PCECD_Close();
 }
#endif
}
Ejemplo n.º 12
0
static void Cleanup(void)
{
 if(cart_hardware)
 {
  delete cart_hardware;
  cart_hardware = NULL;
 }

 if(cart_rom)
 {
  MDFN_free(cart_rom);
  cart_rom = NULL;
 }
}
Ejemplo n.º 13
0
void HuC_Close(void)
{
 if(mcg)
 {
  for(unsigned i = 0; i < mcg->GetNVPDC(); i++)
  {
   uint32 nvs = mcg->GetNVSize(i);

   if(nvs)
   {
    char buf[32];
    std::vector<uint8> tmp_buf;

    tmp_buf.resize(nvs);

    mcg->ReadNV(i, &tmp_buf[0], 0, tmp_buf.size());

    trio_snprintf(buf, sizeof(buf), "mg%d", i);
    MDFN_DumpToFile(MDFN_MakeFName(MDFNMKF_SAV, 0, buf).c_str(), 6, &tmp_buf[0], tmp_buf.size());
   }
  }
 }

 if(IsPopulous)
 {
  if(PopRAM)
  {
   MDFN_DumpToFile(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), 6, PopRAM, 32768);
  }
 }
 else if(IsTsushin)
 {
  if(TsushinRAM)
  {
   MDFN_DumpToFile(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), 6, TsushinRAM, 32768);
   MDFN_free(TsushinRAM);
   TsushinRAM = NULL;
  }
 }
 else if(!BRAM_Disabled && IsBRAMUsed())
 {
  MDFN_DumpToFile(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), 0, SaveRAM, 2048);
 }

 Cleanup();
}
Ejemplo n.º 14
0
void MDFNSS_GetStateInfo(const char *filename, StateStatusStruct *status)
{
 uint32 StateShowPBWidth;
 uint32 StateShowPBHeight;
 uint8 *previewbuffer = NULL;

 try
 {
  GZFileStream fp(filename, GZFileStream::MODE::READ);
  uint8 header[32];

  fp.read(header, 32);

  uint32 width = MDFN_de32lsb(header + 24);
  uint32 height = MDFN_de32lsb(header + 28);

  if(width > 1024)
   width = 1024;

  if(height > 1024)
   height = 1024;

  previewbuffer = (uint8 *)MDFN_malloc_T(3 * width * height, _("Save state preview buffer"));
  fp.read(previewbuffer, 3 * width * height);

  StateShowPBWidth = width;
  StateShowPBHeight = height;
 }
 catch(std::exception &e)
 {
  if(previewbuffer != NULL)
  {
   MDFN_free(previewbuffer);
   previewbuffer = NULL;
  }

  StateShowPBWidth = MDFNGameInfo->nominal_width;
  StateShowPBHeight = MDFNGameInfo->nominal_height;
 }

 status->gfx = previewbuffer;
 status->w = StateShowPBWidth;
 status->h = StateShowPBHeight;
}
Ejemplo n.º 15
0
static void Cleanup(void)
{
 if(arcade_card)
 {
  delete arcade_card;
  arcade_card = NULL;
 }

 if(PCE_IsCD)
 {
  PCECD_Close();
 }

 if(HuCROM)
 {
  MDFN_free(HuCROM);
  HuCROM = NULL;
 }
}
Ejemplo n.º 16
0
void HuC_Close(void)
{
 HuC_DumpSave();

 if(arcade_card)
 {
  delete arcade_card;
  arcade_card = NULL;
 }

 if(PCE_IsCD)
 {
  PCECD_Close();
 }

 if(HuCROM)
 {
  MDFN_free(HuCROM);
  HuCROM = NULL;
 }

 Cleanup();
}
Ejemplo n.º 17
0
void OpenGL_Blitter::Blit(MDFN_Surface *src_surface, const MDFN_Rect *src_rect, const MDFN_Rect *dest_rect, const MDFN_Rect *original_src_rect, int InterlaceField, int UsingIP, int rotated)
{
 MDFN_Rect tex_src_rect = *src_rect;
 float src_coords[4][2];
 int dest_coords[4][2];
 unsigned int tmpwidth;
 unsigned int tmpheight;
 uint32 *src_pixies;

 if(shader)
 {
  if(shader->ShaderNeedsBTIP())
   UsingIP = VIDEOIP_BILINEAR;
  else
   UsingIP = VIDEOIP_OFF;
 }

 if(src_rect->w == 0 || src_rect->h == 0 || dest_rect->w == 0 || dest_rect->h == 0 || original_src_rect->w == 0 || original_src_rect->h == 0)
 {
  printf("[BUG] OpenGL blitting nothing? --- %d:%d %d:%d %d:%d\n", src_rect->w, src_rect->h, dest_rect->w, dest_rect->h, original_src_rect->w, original_src_rect->h);
  return;
 }


 src_pixies = src_surface->pixels + tex_src_rect.x + tex_src_rect.y * src_surface->pitchinpix;
 tex_src_rect.x = 0;
 tex_src_rect.y = 0;

 MakeDestCoords(dest_rect, dest_coords, rotated);

 p_glBindTexture(GL_TEXTURE_2D, textures[0]);
 p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, UsingIP ? GL_LINEAR : GL_NEAREST);
 p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, UsingIP ? GL_LINEAR : GL_NEAREST);

 if(SupportNPOT)
 {
  tmpwidth = src_rect->w;
  tmpheight = src_rect->h;

  if(tmpwidth != last_w || tmpheight != last_h)
  {
   p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tmpwidth, tmpheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
   last_w = tmpwidth;
   last_h = tmpheight;
  }
 }
 else
 {
  bool ImageSizeChange = FALSE;

  tmpwidth = round_up_pow2(src_rect->w);
  tmpheight = round_up_pow2(src_rect->h);

  // If the required GL texture size has changed, resize the texture! :b
  if(tmpwidth != round_up_pow2(last_w) || tmpheight != round_up_pow2(last_h))
  {
   p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tmpwidth, tmpheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
   ImageSizeChange = TRUE;
  }
 
  // If the dimensions of our image stored in the texture have changed...
  if(src_rect->w != last_w || src_rect->h != last_h)
   ImageSizeChange = TRUE;

  // Only clean up if we're using pixel shaders and/or bilinear interpolation
  if(ImageSizeChange && (shader || UsingIP))
  {
   uint32 neo_dbs = DummyBlackSize;

   if(src_rect->w != tmpwidth && neo_dbs < src_rect->h)
    neo_dbs = src_rect->h;

   if(src_rect->h != tmpheight && neo_dbs < src_rect->w)
    neo_dbs = src_rect->w;

   if(neo_dbs != DummyBlackSize)
   {
    //printf("Realloc: %d\n", neo_dbs);
    if(DummyBlack)
     MDFN_free(DummyBlack);

    if((DummyBlack = (uint32 *)MDFN_calloc(neo_dbs, sizeof(uint32), _("OpenGL dummy black texture data"))))
     DummyBlackSize = neo_dbs;
    else
     DummyBlackSize = 0;
   }

   //printf("Cleanup: %d %d, %d %d\n", src_rect->w, src_rect->h, tmpwidth, tmpheight);

   if(DummyBlack) // If memory allocation failed for some reason, don't clean the texture. :(
   {
    if(src_rect->w < tmpwidth)
    {
     //puts("X");
     p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 1);
     p_glTexSubImage2D(GL_TEXTURE_2D, 0, src_rect->w, 0, 1, src_rect->h, GL_RGBA, GL_UNSIGNED_BYTE, DummyBlack);
    }
    if(src_rect->h < tmpheight)
    {
     //puts("Y");
     p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_rect->w);
     p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, src_rect->h, src_rect->w, 1, GL_RGBA, GL_UNSIGNED_BYTE, DummyBlack);
    }
   } // end if(DummyBlack)

  }

  last_w = src_rect->w;
  last_h = src_rect->h;
 }

 MakeSourceCoords(&tex_src_rect, src_coords, tmpwidth, tmpheight);

 if(shader)
  shader->ShaderBegin(gl_screen_w, gl_screen_h, src_rect, dest_rect, tmpwidth, tmpheight, round((double)tmpwidth * original_src_rect->w / src_rect->w), round((double)tmpheight * original_src_rect->h / src_rect->h), rotated);

 p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_surface->pitchinpix);

 p_glTexSubImage2D(GL_TEXTURE_2D, 0, tex_src_rect.x, tex_src_rect.y, tex_src_rect.w, tex_src_rect.h, PixelFormat, PixelType, src_pixies);

 //
 // Draw texture
 //
#ifdef MDFN_TRIANGLE_STRIP_TEST
 p_glBegin(GL_TRIANGLE_STRIP);
#else
 p_glBegin(GL_QUADS);
#endif

 if(UsingIP == VIDEOIP_LINEAR_X || UsingIP == VIDEOIP_LINEAR_Y)	// Linear interpolation, on one axis
 {
  DrawLinearIP(UsingIP, rotated, &tex_src_rect, dest_rect, tmpwidth, tmpheight);
 }
 else	// Regular bilinear or no interpolation.
 {
  DrawQuad(src_coords, dest_coords);
 }

 p_glEnd();

 if(shader)
  shader->ShaderEnd();

 if(using_scanlines)
 {
  float yif_offset = 0;
  int yh_shift = 0;

  if(using_scanlines < 0 && InterlaceField >= 0)
  {
   yif_offset = (float)InterlaceField / 512;
   yh_shift = 1;
  }


  p_glEnable(GL_BLEND);

  p_glBindTexture(GL_TEXTURE_2D, textures[1]);
  p_glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);

  p_glBegin(GL_QUADS);

  p_glTexCoord2f(0.0f, yif_offset + (original_src_rect->h >> yh_shift) / 256.0f);  // Bottom left of our picture.
  p_glVertex2f((signed)dest_coords[3][0], (signed)dest_coords[3][1]);

  p_glTexCoord2f(1.0f, yif_offset + (original_src_rect->h >> yh_shift) / 256.0f); // Bottom right of our picture.
  p_glVertex2f((signed)dest_coords[2][0], (signed)dest_coords[2][1]);

  p_glTexCoord2f(1.0f, yif_offset);    // Top right of our picture.
  p_glVertex2f((signed)dest_coords[1][0], (signed)dest_coords[1][1]);

  p_glTexCoord2f(0.0f, yif_offset);     // Top left of our picture.
  p_glVertex2f((signed)dest_coords[0][0], (signed)dest_coords[0][1]);

  p_glEnd();
  p_glDisable(GL_BLEND);
 }

 //if(1)
 //{
 // p_glAccum(GL_MULT, 0.99);
 // p_glAccum(GL_ACCUM, 1 - 0.99);
 // p_glAccum(GL_RETURN, 1.0);
 //}
}
Ejemplo n.º 18
0
int HuCLoad(const uint8 *data, uint32 len, uint32 crc32)
{
 uint32 sf2_threshold = 2048 * 1024;
 uint32 sf2_required_size = 2048 * 1024 + 512 * 1024;
 uint32 m_len = (len + 8191)&~8191;
 bool sf2_mapper = FALSE;

 if(m_len >= sf2_threshold)
 {
  sf2_mapper = TRUE;

  if(m_len != sf2_required_size)
   m_len = sf2_required_size;
 }

 IsPopulous = 0;
 PCE_IsCD = 0;

 md5_context md5;
 md5.starts();
 md5.update(data, len);
 md5.finish(MDFNGameInfo->MD5);

 MDFN_printf(_("ROM:       %dKiB\n"), (len + 1023) / 1024);
 MDFN_printf(_("ROM CRC32: 0x%04x\n"), crc32);
 MDFN_printf(_("ROM MD5:   0x%s\n"), md5_context::asciistr(MDFNGameInfo->MD5, 0).c_str());

 if(!(HuCROM = (uint8 *)MDFN_malloc(m_len, _("HuCard ROM"))))
 {
  return(0);
 }

 memset(HuCROM, 0xFF, m_len);
 memcpy(HuCROM, data, len);

 memset(ROMSpace, 0xFF, 0x88 * 8192 + 8192);

 if(m_len == 0x60000)
 {
  memcpy(ROMSpace + 0x00 * 8192, HuCROM, 0x20 * 8192);
  memcpy(ROMSpace + 0x20 * 8192, HuCROM, 0x20 * 8192);
  memcpy(ROMSpace + 0x40 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192);
  memcpy(ROMSpace + 0x50 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192);
  memcpy(ROMSpace + 0x60 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192);
  memcpy(ROMSpace + 0x70 * 8192, HuCROM + 0x20 * 8192, 0x10 * 8192);
 }
 else if(m_len == 0x80000)
 {
  memcpy(ROMSpace + 0x00 * 8192, HuCROM, 0x40 * 8192);
  memcpy(ROMSpace + 0x40 * 8192, HuCROM + 0x20 * 8192, 0x20 * 8192);
  memcpy(ROMSpace + 0x60 * 8192, HuCROM + 0x20 * 8192, 0x20 * 8192);
 }
 else
 {
  memcpy(ROMSpace + 0x00 * 8192, HuCROM, (m_len < 1024 * 1024) ? m_len : 1024 * 1024);
 }

 for(int x = 0x00; x < 0x80; x++)
 {
  HuCPUFastMap[x] = ROMSpace;
  PCERead[x] = HuCRead;
 }

 if(!memcmp(HuCROM + 0x1F26, "POPULOUS", strlen("POPULOUS")))
 {
  uint8 *PopRAM = ROMSpace + 0x40 * 8192;
  gzFile fp;
  
  memset(PopRAM, 0xFF, 32768);
  if((fp = gzopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb")))
  {
   gzread(fp, PopRAM, 32768);
   gzclose(fp);
  }

  IsPopulous = 1;

  MDFN_printf("Populous\n");

  for(int x = 0x40; x < 0x44; x++)
  {
   HuCPUFastMap[x] = &PopRAM[(x & 3) * 8192] - x * 8192;
   PCERead[x] = HuCRead;
   PCEWrite[x] = HuCRAMWrite;
  }
  MDFNMP_AddRAM(32768, 0x40 * 8192, PopRAM);
 }
 else if(crc32 == 0x34dc65c4) // Tsushin Booster
 {
  gzFile fp;

  if(!(TsushinRAM = (uint8*)MDFN_calloc(1, 0x8000 + 8192, _("Tsushin Booster RAM"))))	// + 8192 for PC-as-ptr safety padding
  {
   MDFN_free(HuCROM);
   return(0);
  }
  memset(TsushinRAM, 0xFF, 0x8000);

  if((fp = gzopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb")))
  {
   gzread(fp, TsushinRAM, 32768);
   gzclose(fp);
  }
  IsTsushin = 1;
  MDFN_printf("Tsushin Booster\n");
  for(int x = 0x88; x < 0x8C; x++)
  {
   HuCPUFastMap[x] = &TsushinRAM[(x & 3) * 8192] - x * 8192;
   PCERead[x] = HuCRead;
   PCEWrite[x] = HuCRAMWrite;
  }
  MDFNMP_AddRAM(32768, 0x88 * 8192, TsushinRAM);
 }
 else
 {
  gzFile fp;

  memset(SaveRAM, 0x00, 2048);
  memcpy(SaveRAM, BRAM_Init_String, 8);    // So users don't have to manually intialize the file cabinet
                                                // in the CD BIOS screen.
  if((fp = gzopen(MDFN_MakeFName(MDFNMKF_SAV, 0, "sav").c_str(), "rb")))
  {
   gzread(fp, SaveRAM, 2048);
   gzclose(fp);
  }
  PCEWrite[0xF7] = SaveRAMWrite;
  PCERead[0xF7] = SaveRAMRead;
  MDFNMP_AddRAM(2048, 0xF7 * 8192, SaveRAM);
 }

 // 0x1A558
 //if(len >= 0x20000 && !memcmp(HuCROM + 0x1A558, "STREET FIGHTER#", strlen("STREET FIGHTER#")))
 if(sf2_mapper)
 {
  for(int x = 0x40; x < 0x80; x++)
  {
   // FIXME: PCE_FAST
   HuCPUFastMap[x] = NULL; // Make sure our reads go through our read function, and not a table lookup
   PCERead[x] = HuCSF2Read;
  }
  PCEWrite[0] = HuCSF2Write;
  MDFN_printf("Street Fighter 2 Mapper\n");
  HuCSF2Latch = 0;
 }

 return(1);
}
Ejemplo n.º 19
0
void BlitOpenGL(MDFN_Surface *src_surface, const MDFN_Rect *src_rect, const MDFN_Rect *dest_rect, const MDFN_Rect *original_src_rect)
{
 MDFN_Rect tex_src_rect = *src_rect;
 float src_coords[4][2];
 int dest_coords[4][2];
 unsigned int tmpwidth;
 unsigned int tmpheight;
 uint32 *src_pixies;

 src_pixies = src_surface->pixels + tex_src_rect.x + tex_src_rect.y * src_surface->pitchinpix;
 tex_src_rect.x = 0;
 tex_src_rect.y = 0;

 MakeDestCoords(dest_rect, dest_coords);

 p_glBindTexture(GL_TEXTURE_2D, textures[0]);

 if(SupportNPOT)
 {
  tmpwidth = src_rect->w;
  tmpheight = src_rect->h;

  if(tmpwidth != last_w || tmpheight != last_h)
  {
   p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tmpwidth, tmpheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
   last_w = tmpwidth;
   last_h = tmpheight;
  }
 }
 else
 {
  bool ImageSizeChange = FALSE;

  tmpwidth = round_up_pow2(src_rect->w);
  tmpheight = round_up_pow2(src_rect->h);

  // If the required GL texture size has changed, resize the texture! :b
  if(tmpwidth != round_up_pow2(last_w) || tmpheight != round_up_pow2(last_h))
  {
   p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tmpwidth, tmpheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
   ImageSizeChange = TRUE;
  }
 
  // If the dimensions of our image stored in the texture have changed...
  if(src_rect->w != last_w || src_rect->h != last_h)
   ImageSizeChange = TRUE;

  // Only clean up if we're using pixel shaders and/or bilinear interpolation
  if(ImageSizeChange && (UsingShader || UsingIP))
  {
   uint32 neo_dbs = DummyBlackSize;

   if(src_rect->w != tmpwidth && neo_dbs < src_rect->h)
    neo_dbs = src_rect->h;

   if(src_rect->h != tmpheight && neo_dbs < src_rect->w)
    neo_dbs = src_rect->w;

   if(neo_dbs != DummyBlackSize)
   {
    //printf("Realloc: %d\n", neo_dbs);
    if(DummyBlack)
     MDFN_free(DummyBlack);

    if((DummyBlack = (uint32 *)MDFN_calloc(neo_dbs, sizeof(uint32), _("OpenGL dummy black texture data"))))
     DummyBlackSize = neo_dbs;
    else
     DummyBlackSize = 0;
   }

   //printf("Cleanup: %d %d, %d %d\n", src_rect->w, src_rect->h, tmpwidth, tmpheight);

   if(DummyBlack) // If memory allocation failed for some reason, don't clean the texture. :(
   {
    if(src_rect->w < tmpwidth)
    {
     //puts("X");
     p_glPixelStorei(GL_UNPACK_ROW_LENGTH, 1);
     p_glTexSubImage2D(GL_TEXTURE_2D, 0, src_rect->w, 0, 1, src_rect->h, GL_RGBA, GL_UNSIGNED_BYTE, DummyBlack);
    }
    if(src_rect->h < tmpheight)
    {
     //puts("Y");
     p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_rect->w);
     p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, src_rect->h, src_rect->w, 1, GL_RGBA, GL_UNSIGNED_BYTE, DummyBlack);
    }
   } // end if(DummyBlack)

  }

  last_w = src_rect->w;
  last_h = src_rect->h;
 }

 MakeSourceCoords(&tex_src_rect, src_coords, tmpwidth, tmpheight);

 #if MDFN_WANT_OPENGL_SHADERS
 if(UsingShader)
  ShaderBegin(src_rect, dest_rect, tmpwidth, tmpheight);
 #endif

 p_glPixelStorei(GL_UNPACK_ROW_LENGTH, src_surface->pitchinpix);

 p_glTexSubImage2D(GL_TEXTURE_2D, 0, tex_src_rect.x, tex_src_rect.y, tex_src_rect.w, tex_src_rect.h, PixelFormat, PixelType, src_pixies);

 //
 // Draw texture
 //
 p_glBegin(GL_QUADS);

 if(UsingIP == VIDEOIP_LINEAR_X || UsingIP == VIDEOIP_LINEAR_Y)	// Linear interpolation, on one axis
 {
  DrawLinearIP(UsingIP, CurGame->rotated, &tex_src_rect, dest_rect, tmpwidth, tmpheight);
 }
 else	// Regular bilinear or no interpolation.
 {
  DrawQuad(src_coords, dest_coords);
 }

 p_glEnd();

 #if MDFN_WANT_OPENGL_SHADERS
 if(UsingShader)
  ShaderEnd();
 #endif

 if(using_scanlines)
 {
  p_glEnable(GL_BLEND);

  p_glBindTexture(GL_TEXTURE_2D, textures[1]);
  p_glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);

  p_glBegin(GL_QUADS);

  p_glTexCoord2f(0.0f, 1.0f * original_src_rect->h / 256);  // Bottom left of our picture.
  p_glVertex2f((signed)dest_coords[3][0], (signed)dest_coords[3][1]);

  p_glTexCoord2f(1.0f, 1.0f * original_src_rect->h / 256); // Bottom right of our picture.
  p_glVertex2f((signed)dest_coords[2][0], (signed)dest_coords[2][1]);

  p_glTexCoord2f(1.0f, 0.0f);    // Top right of our picture.
  p_glVertex2f((signed)dest_coords[1][0], (signed)dest_coords[1][1]);

  p_glTexCoord2f(0.0f, 0.0f);     // Top left of our picture.
  p_glVertex2f((signed)dest_coords[0][0], (signed)dest_coords[0][1]);

  p_glEnd();
  p_glDisable(GL_BLEND);
 }

 //if(1)
 //{
 // p_glAccum(GL_MULT, 0.99);
 // p_glAccum(GL_ACCUM, 1 - 0.99);
 // p_glAccum(GL_RETURN, 1.0);
 //}
}