bool CDIF_ST::Eject(bool eject_status)
{
   if(UnrecoverableError)
      return(false);

   try
   {
      int32_t old_de = DiscEjected;

      DiscEjected = eject_status;

      if(old_de != DiscEjected)
      {
         disc_cdaccess->Eject(eject_status);

         if(!eject_status)     // Re-read the TOC
         {
            disc_cdaccess->Read_TOC(&disc_toc);

            if(disc_toc.first_track < 1 || disc_toc.last_track > 99 || disc_toc.first_track > disc_toc.last_track)
               throw(MDFN_Error(0, _("TOC first(%d)/last(%d) track numbers bad."), disc_toc.first_track, disc_toc.last_track));
         }
      }
   }
   catch(std::exception &e)
   {
      log_cb(RETRO_LOG_ERROR, "%s\n", e.what());
      return(false);
   }

   return(true);
}
MemoryStream::MemoryStream() : data_buffer(NULL), data_buffer_size(0), data_buffer_alloced(0), position(0)
{
 data_buffer_size = 0;
 data_buffer_alloced = 64;
 if(!(data_buffer = (uint8*)realloc(data_buffer, data_buffer_alloced)))
  throw MDFN_Error(ErrnoHolder(errno));
}
예제 #3
0
파일: unif.cpp 프로젝트: Oggom/mednafen-git
static void LoadPRG(Stream *fp)
{
 uint32 t;
 unsigned z;

 z = uchead.ID[3] - '0';	// FIXME hex

 if(z > 15)
  throw MDFN_Error(0, "Invalid PRG ROM index '%c'.\n", uchead.ID[3]);

 MDFN_printf(_("PRG ROM %u size: %u\n"), z, uchead.info);

 if(malloced[z])
  free(malloced[z]);

 t = FixRomSize(uchead.info, 2048);

 malloced[z] = (uint8 *)MDFN_malloc_T(t, _("PRG ROM"));
 mallocedsizes[z] = t;
 memset(malloced[z] + uchead.info, 0xFF, t - uchead.info);

 fp->read(malloced[z], uchead.info);

 SetupCartPRGMapping(z,malloced[z],t,0); 
}
예제 #4
0
void Stream::print_format(const char *format, ...)
{
 char *str = NULL;
 int rc;

 va_list ap;

 va_start(ap, format);

 rc = trio_vasprintf(&str, format, ap);

 va_end(ap);

 if(rc < 0)
  throw MDFN_Error(0, "Error in trio_vasprintf()");
 else
 {
  try	// Bleck
  {
   write(str, rc);
  }
  catch(...)
  {
   free(str);
   throw;
  }
  free(str);
 }
}
void CDIF_MT::RT_EjectDisc(bool eject_status, bool skip_actual_eject)
{
   int32_t old_de = DiscEjected;

   DiscEjected = eject_status;

   if(old_de != DiscEjected)
   {
      if(!skip_actual_eject)
         disc_cdaccess->Eject(eject_status);

      if(!eject_status)	// Re-read the TOC
      {
         disc_cdaccess->Read_TOC(&disc_toc);

         if(disc_toc.first_track < 1 || disc_toc.last_track > 99 || disc_toc.first_track > disc_toc.last_track)
            throw(MDFN_Error(0, _("TOC first(%d)/last(%d) track numbers bad."), disc_toc.first_track, disc_toc.last_track));
      }

      SBWritePos = 0;
      ra_lba = 0;
      ra_count = 0;
      last_read_lba = ~0U;
      memset(SectorBuffers, 0, SBSize * sizeof(CDIF_Sector_Buffer));
   }
}
// Returns FALSE if message not read, TRUE if it was read.  Will always return TRUE if "blocking" is set.
// Will throw MDFN_Error if the read message code is CDIF_MSG_FATAL_ERROR
bool CDIF_Queue::Read(CDIF_Message *message, bool blocking)
{
   bool ret = true;

   slock_lock((slock_t*)ze_mutex);

   if(blocking)
   {
      while(ze_queue.size() == 0)	// while, not just if.
         scond_wait((scond_t*)ze_cond, (slock_t*)ze_mutex);
   }

   if(ze_queue.size() == 0)
      ret = false;
   else
   {
      *message = ze_queue.front();
      ze_queue.pop();
   }  

   slock_unlock((slock_t*)ze_mutex);

   if(ret && message->message == CDIF_MSG_FATAL_ERROR)
      throw MDFN_Error(0, "%s", message->str_message.c_str());

   return(ret);
}
예제 #7
0
// Integrity checking is experimental, and needs work to function properly(in the emulator cores).
static int SendIntegrity(void)
{
 StateMem sm;
 md5_context md5;
 uint8 digest[16];

 memset(&sm, 0, sizeof(StateMem));

 // Do not do a raw/data-only state for speed, due to lack of endian and bool conversion.
 if(!MDFNSS_SaveSM(&sm, 0, false))
 {
  throw MDFN_Error(0, _("Error during save state generation."));
 }

 md5.starts();
 md5.update(sm.data, sm.len);
 md5.finish(digest);

 free(sm.data);

 //for(int i = 15; i >= 0; i--)
 // printf("%02x", digest[i]);
 //puts("");

 SendCommand(MDFNNPCMD_INTEGRITY_RES, 16, digest);

 return(1);
}
MemoryStream::MemoryStream(uint64 size_hint) : data_buffer(NULL), data_buffer_size(0), data_buffer_alloced(0), position(0)
{
 data_buffer_size = 0;
 data_buffer_alloced = (size_hint > SIZE_MAX) ? SIZE_MAX : size_hint;

 if(!(data_buffer = (uint8*)realloc(data_buffer, (size_t)data_buffer_alloced)))
  throw MDFN_Error(ErrnoHolder(errno));
}
예제 #9
0
FileWrapper::FileWrapper(const char *path, const int mode, const char *purpose) : OpenedMode(mode)
{
 path_save = std::string(path);

 if(mode == MODE_READ)
  fp = fopen(path, "rb");
 else if(mode == MODE_WRITE)
  fp = fopen(path, "wb");
 else if(mode == MODE_WRITE_SAFE)	// SO ANNOYING
 {
  int open_flags = O_WRONLY | O_CREAT | O_EXCL;

  #ifdef O_BINARY
   open_flags |= O_BINARY;
  #elif defined(_O_BINARY)
   open_flags |= _O_BINARY;
  #endif

  #if defined(S_IRGRP) && defined(S_IROTH) 
  int tmpfd = open(path, open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  #else
  int tmpfd = open(path, open_flags, S_IRUSR | S_IWUSR);
  #endif
  if(tmpfd == -1)
  {
   ErrnoHolder ene(errno);

   if(purpose)
    throw(MDFN_Error(ene.Errno(), _("Error opening file \"%s\" for \"%s\": %s"), path_save.c_str(), purpose, ene.StrError()));
   else
    throw(MDFN_Error(ene.Errno(), _("Error opening file \"%s\": %s"), path_save.c_str(), ene.StrError()));
  }
  fp = fdopen(tmpfd, "wb");
 }

 if(!fp)
 {
  ErrnoHolder ene(errno);

  if(purpose)
   throw(MDFN_Error(ene.Errno(), _("Error opening file \"%s\" for \"%s\": %s"), path_save.c_str(), purpose, ene.StrError()));
  else
   throw(MDFN_Error(ene.Errno(), _("Error opening file \"%s\": %s"), path_save.c_str(), ene.StrError()));
 }
}
예제 #10
0
void FileWrapper::flush(void)
{
 if(fflush(fp) == EOF)
 {
  ErrnoHolder ene(errno);

  throw(MDFN_Error(ene.Errno(), _("Error flushing to opened file \"%s\": %s"), path_save.c_str(), ene.StrError()));
 }
}
예제 #11
0
void FileWrapper::write(const void *data, uint64 count)
{
 if(fwrite(data, 1, count, fp) != count)
 {
  ErrnoHolder ene(errno);

  throw(MDFN_Error(ene.Errno(), _("Error writing to opened file \"%s\": %s"), path_save.c_str(), ene.StrError()));
 }
}
예제 #12
0
void FileWrapper::put_char(int c)
{
 if(fputc(c, fp) == EOF)
 {
  ErrnoHolder ene(errno);

  throw(MDFN_Error(ene.Errno(), _("Error writing to opened file \"%s\": %s"), path_save.c_str(), ene.StrError()));
 }
}
예제 #13
0
void FileWrapper::seek(int64 offset, int whence)
{
 if(fseeko(fp, offset, whence) == -1)
 {
  ErrnoHolder ene(errno);

  throw(MDFN_Error(ene.Errno(), _("Error seeking in opened file \"%s\": %s"), path_save.c_str(), ene.StrError()));
 }
}
예제 #14
0
void FileStream::truncate(uint64 length)
{
 if(fflush(fp) == EOF)
 {
  ErrnoHolder ene(errno);

  throw(MDFN_Error(ene.Errno(), _("Error truncating opened file \"%s\": %s"), path_save.c_str(), ene.StrError()));
 }
}
예제 #15
0
파일: FileStream.cpp 프로젝트: ircluzar/RTC
FileStream::FileStream(const std::string& path, const int mode) : OpenedMode(mode), mapping(NULL), mapping_size(0)
{
 path_save = path;

 if(mode == MODE_READ)
  fp = fopen(path.c_str(), "rb");
 else if(mode == MODE_WRITE)
  fp = fopen(path.c_str(), "wb");
 else if(mode == MODE_WRITE_SAFE || mode == MODE_WRITE_INPLACE)	// SO ANNOYING
 {
  int open_flags = O_WRONLY | O_CREAT;

  if(mode == MODE_WRITE_SAFE)
   open_flags |= O_EXCL;

  #ifdef O_BINARY
   open_flags |= O_BINARY;
  #elif defined(_O_BINARY)
   open_flags |= _O_BINARY;
  #endif

  #if defined(S_IRGRP) && defined(S_IROTH) 
  int tmpfd = open(path.c_str(), open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  #else
  int tmpfd = open(path.c_str(), open_flags, S_IRUSR | S_IWUSR);
  #endif
  if(tmpfd == -1)
  {
   ErrnoHolder ene(errno);

   throw(MDFN_Error(ene.Errno(), _("Error opening file \"%s\": %s"), path_save.c_str(), ene.StrError()));
  }
  fp = fdopen(tmpfd, "wb");
 }
 else
  abort();

 if(!fp)
 {
  ErrnoHolder ene(errno);

  throw(MDFN_Error(ene.Errno(), _("Error opening file \"%s\": %s"), path_save.c_str(), ene.StrError()));
 }
}
예제 #16
0
MCGenjin::MCGenjin(Blip_Buffer *bb, const uint8 *rr, uint32 rr_size)
{
 uint8 revision, num256_pages, region, cs_di[2];

 if(rr_size < 8192)
  throw MDFN_Error(0, _("MCGenjin ROM size is too small!"));

 if(memcmp(rr + 0x1FD0, "MCGENJIN", 8))
  throw MDFN_Error(0, _("MC Genjin header magic missing!"));

 rom.resize(round_up_pow2(rr_size));

 memcpy(&rom[0], rr, rr_size);

 revision = rom[0x1FD8];
 num256_pages = rom[0x1FD9];
 region = rom[0x1FDA];
 cs_di[0] = rom[0x1FDB];
 cs_di[1] = rom[0x1FDC];

 for(unsigned i = 0; i < 2; i++)
 {
  switch(cs_di[i])
  {
   default:
	for(unsigned si = 0; si < i; si++) // FIXME: auto ptr to make this not necessary
         delete cs[si];

	throw MDFN_Error(0, _("Unsupported MCGENJIN device on CS%d: 0x%02x"), i, cs_di[i]);
	break;

   case 0x00:
	MDFN_printf(_("CS%d: Unused\n"), i);
	cs[i] = new MCGenjin_CS_Device();
	break;

   case 0x10 ... 0x18:
   case 0x20 ... 0x28:
	MDFN_printf(_("CS%d: %uKiB %sRAM\n"), i, 8 << (cs_di[i] & 0xF), (cs_di[i] & 0x20) ? "Nonvolatile " : "");
	cs[i] = new MCGenjin_CS_Device_RAM(8192 << (cs_di[i] & 0xF), (bool)(cs_di[i] & 0x20));
	break;
  }
 }
}
예제 #17
0
파일: FileStream.cpp 프로젝트: ircluzar/RTC
void FileStream::truncate(uint64 length)
{
	//not needed by mednadisc
 //if(fflush(fp) == EOF || ftruncate(fileno(fp), length) != 0)
 {
  ErrnoHolder ene(errno);

  throw(MDFN_Error(ene.Errno(), _("Error truncating opened file \"%s\": %s"), path_save.c_str(), ene.StrError()));
 }
}
예제 #18
0
static void RecvState(const uint32 clen)
{
 StateMem sm;
 std::vector<uint8> cbuf;
 std::vector<uint8> buf;

 memset(&sm, 0, sizeof(StateMem));

 if(clen < 4)
 {
  throw MDFN_Error(0, _("Compressed save state data is too small: %u"), clen);
 }

 if(clen > 8 * 1024 * 1024) // Compressed length sanity check - 8 MiB max.
 {
  throw MDFN_Error(0, _("Compressed save state data is too large: %u"), clen);
 }

 cbuf.resize(clen);

 MDFND_RecvData(&cbuf[0], clen);

 uLongf len = MDFN_de32lsb(&cbuf[0]);
 if(len > 12 * 1024 * 1024) // Uncompressed length sanity check - 12 MiB max.
 {
  throw MDFN_Error(0, _("Uncompressed save state data is too large: %llu"), (unsigned long long)len);
 }

 buf.resize(len);

 uncompress((Bytef *)&buf[0], &len, (Bytef *)&cbuf[0] + 4, clen - 4);

 sm.data = &buf[0];
 sm.len = len;

 if(!MDFNSS_LoadSM(&sm, 0, 0))
 {
  throw MDFN_Error(0, _("Error during save state loading."));
 }

 if(MDFNMOV_IsRecording())
  MDFNMOV_RecordState();
}
static T CCD_ReadInt(CCD_Section &s, const std::string &propname, const bool have_defval = false, const int defval = 0)
{
 CCD_Section::iterator zit = s.find(propname);

 if(zit == s.end())
 {
  if(have_defval)
   return defval;
  else
   throw MDFN_Error(0, _("Missing property: %s"), propname.c_str());
 }

 const std::string &v = zit->second;
 int scan_base = 10;
 size_t scan_offset = 0;
 long ret = 0;
 
 if(v.length() >= 3 && v[0] == '0' && v[1] == 'x')
 {
  scan_base = 16;
  scan_offset = 2;
 }

 const char *vp = v.c_str() + scan_offset;
 char *ep = NULL;

 if(std::numeric_limits<T>::is_signed)
  ret = strtol(vp, &ep, scan_base);
 else
  ret = strtoul(vp, &ep, scan_base);

 if(!vp[0] || ep[0])
 {
  throw MDFN_Error(0, _("Property %s: Malformed integer: %s"), propname.c_str(), v.c_str());
 }

 //if(ret < minv || ret > maxv)
 //{
 // throw MDFN_Error(0, _("Property %s: Integer %ld out of range(accepted: %d through %d)."), propname.c_str(), ret, minv, maxv);
 //}

 return ret;
}
예제 #20
0
void MDFNSS_LoadSM(Stream *st, bool data_only)
{
	if(MDFN_LIKELY(data_only))
	{
	 StateMem sm(st);
	 MDFN_StateAction(&sm, MEDNAFEN_VERSION_NUMERIC, true);
	 sm.ThrowDeferred();
	}
	else
	{
         uint8 header[32];
	 uint32 width, height, preview_len;
  	 uint32 stateversion;
	 uint32 total_len;
	 int64 start_pos;
	 bool svbe;

	 start_pos = st->tell();
         st->read(header, 32);

         if(memcmp(header, "MEDNAFENSVESTATE", 16) && memcmp(header, "MDFNSVST", 8))
	  throw MDFN_Error(0, _("Missing/Wrong save state header ID."));

	 stateversion = MDFN_de32lsb(header + 16);
	 total_len = MDFN_de32lsb(header + 20) & 0x7FFFFFFF;
         svbe = MDFN_de32lsb(header + 20) & 0x80000000;
         width = MDFN_de32lsb(header + 24);
         height = MDFN_de32lsb(header + 28);
	 preview_len = width * height * 3;

	 if((int)stateversion < 0x900)	// Ensuring that (int)stateversion is > 0 is the most important part.
	  throw MDFN_Error(0, _("Invalid/Unsupported version in save state header."));

	 st->seek(preview_len, SEEK_CUR);				// Skip preview

	 StateMem sm(st, start_pos + total_len, svbe);
	 MDFN_StateAction(&sm, stateversion, false);			// Load state data.
	 sm.ThrowDeferred();

	 st->seek(start_pos + total_len, SEEK_SET);			// Seek to just beyond end of save state before returning.
	}
}
MemoryStream::MemoryStream(const MemoryStream *zs)
{
 data_buffer_size = zs->data_buffer_size;
 data_buffer_alloced = zs->data_buffer_alloced;
 if(!(data_buffer = (uint8*)malloc((size_t)data_buffer_alloced)))
  throw MDFN_Error(ErrnoHolder(errno));

 memcpy(data_buffer, zs->data_buffer, (size_t)data_buffer_size);

 position = zs->position;
}
예제 #22
0
FileStream::FileStream(const char *path, const int mode)
{
   fp = filestream_open(path, (mode == MODE_WRITE || mode == MODE_WRITE_INPLACE) ? RETRO_VFS_FILE_ACCESS_WRITE : RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);

   if (!fp)
   {
      ErrnoHolder ene(errno);

      MDFN_Error(ene.Errno(), "Error opening file:\n%s\n%s", path, ene.StrError());
   }
}
void MemoryStream::write(const void *data, uint64 count)
{
 uint64 nrs = position + count;

 if(nrs < position)
  throw MDFN_Error(ErrnoHolder(EFBIG));

 grow_if_necessary(nrs);

 memmove(&data_buffer[position], data, (size_t)count);
 position += count;
}
CDIF_ST::CDIF_ST(CDAccess *cda) : disc_cdaccess(cda)
{
   //puts("***WARNING USING SINGLE-THREADED CD READER***");

   UnrecoverableError = false;
   DiscEjected = false;

   disc_cdaccess->Read_TOC(&disc_toc);

   if(disc_toc.first_track < 1 || disc_toc.last_track > 99 || disc_toc.first_track > disc_toc.last_track)
      throw(MDFN_Error(0, _("TOC first(%d)/last(%d) track numbers bad."), disc_toc.first_track, disc_toc.last_track));
}
예제 #25
0
uint64 FileWrapper::read(void *data, uint64 count, bool error_on_eof)
{
 uint64 read_count;

 clearerr(fp);

 read_count = fread(data, 1, count, fp);

 if(read_count != count)
 {
  ErrnoHolder ene(errno);

  if(ferror(fp))
   throw(MDFN_Error(ene.Errno(), _("Error reading from opened file \"%s\": %s"), path_save.c_str(), ene.StrError()));

  if(error_on_eof)
   throw(MDFN_Error(ene.Errno(), _("Error reading from opened file \"%s\": %s"), path_save.c_str(), "EOF"));
 }

 return(read_count);
}
예제 #26
0
uint32 NetClient_WS2::Receive(void *data, uint32 len)
{
 int rv;

 rv = recv(*(SOCKET*)sd, (char *)data, len, 0);

 if(rv < 0)
 {
  int errcode = WSAGetLastError();
  if(errcode != WSAEWOULDBLOCK && errcode != WSAEINTR)
  {
   throw MDFN_Error(0, _("recv() failed: %d %s"), errcode, ErrCodeToString(errcode).c_str());
  }
  return(0);
 }
 else if(rv == 0)
 {
  throw MDFN_Error(0, _("recv() failed: peer has closed connection"));
 }

 return rv;
}
예제 #27
0
uint32 NetClient_POSIX::Receive(void *data, uint32 len)
{
 ssize_t rv;

 rv = recv(fd, data, len, 0);

 if(rv < 0)
 {
  if(errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
  {
   ErrnoHolder ene(errno);

   throw MDFN_Error(ene.Errno(), _("recv() failed: %s"), ene.StrError());
  }
  return(0);
 }
 else if(rv == 0)
 {
  throw MDFN_Error(0, _("recv() failed: peer has closed connection"));
 }
 return rv;
}
예제 #28
0
파일: FileStream.cpp 프로젝트: ircluzar/RTC
uint64 FileStream::tell(void)
{
 auto offset = ftello(fp);

 if(offset == -1)
 {
  ErrnoHolder ene(errno);

  throw(MDFN_Error(ene.Errno(), _("Error getting position in opened file \"%s\": %s"), path_save.c_str(), ene.StrError()));
 }

 return (std::make_unsigned<decltype(offset)>::type)offset;
}
예제 #29
0
파일: FileStream.cpp 프로젝트: ircluzar/RTC
uint64 FileStream::size(void)
{
 STRUCT_STAT buf;

 if((OpenedMode != MODE_READ && fflush(fp) == EOF) || fstat(fileno(fp), &buf) == -1)
 {
  ErrnoHolder ene(errno);

  throw(MDFN_Error(ene.Errno(), _("Error getting the size of opened file \"%s\": %s"), path_save.c_str(), ene.StrError()));
 }

 return (std::make_unsigned<decltype(buf.st_size)>::type)buf.st_size;
}
예제 #30
0
static void LoadNSF(Stream *fp)
{
 NSF_HEADER NSFHeader;

 fp->read(&NSFHeader, 0x80);

 // NULL-terminate strings just in case.
 NSFHeader.GameName[31] = NSFHeader.Artist[31] = NSFHeader.Copyright[31] = 0;

 MDFN_zapctrlchars((char*)NSFHeader.GameName);
 MDFN_zapctrlchars((char*)NSFHeader.Artist);
 MDFN_zapctrlchars((char*)NSFHeader.Copyright);

 MDFN_trim((char*)NSFHeader.GameName);
 MDFN_trim((char*)NSFHeader.Artist);
 MDFN_trim((char*)NSFHeader.Copyright);

 NSFInfo->GameName = std::string((const char *)NSFHeader.GameName);
 NSFInfo->Artist = std::string((const char *)NSFHeader.Artist);
 NSFInfo->Copyright = std::string((const char *)NSFHeader.Copyright);

 NSFInfo->LoadAddr = NSFHeader.LoadAddressLow | (NSFHeader.LoadAddressHigh << 8);
 NSFInfo->InitAddr = NSFHeader.InitAddressLow | (NSFHeader.InitAddressHigh << 8);
 NSFInfo->PlayAddr = NSFHeader.PlayAddressLow | (NSFHeader.PlayAddressHigh << 8);

 uint64 tmp_size = fp->size() - 0x80;
 if(tmp_size > 16 * 1024 * 1024)
  throw MDFN_Error(0, _("NSF is too large."));

 NSFInfo->NSFSize = tmp_size;

 NSFInfo->NSFMaxBank = ((NSFInfo->NSFSize+(NSFInfo->LoadAddr&0xfff)+4095)/4096);
 NSFInfo->NSFMaxBank = round_up_pow2(NSFInfo->NSFMaxBank);

 NSFInfo->NSFDATA = new uint8[NSFInfo->NSFMaxBank * 4096];

 memset(NSFInfo->NSFDATA, 0x00, NSFInfo->NSFMaxBank*4096);
 fp->read(NSFInfo->NSFDATA+(NSFInfo->LoadAddr&0xfff), NSFInfo->NSFSize);
 
 NSFInfo->NSFMaxBank--;

 NSFInfo->VideoSystem = NSFHeader.VideoSystem;
 NSFInfo->SoundChip = NSFHeader.SoundChip;
 NSFInfo->TotalSongs = NSFHeader.TotalSongs;

 if(NSFHeader.StartingSong == 0)
  NSFHeader.StartingSong = 1;

 NSFInfo->StartingSong = NSFHeader.StartingSong - 1;
 memcpy(NSFInfo->BankSwitch, NSFHeader.BankSwitch, 8);
}