示例#1
0
void PSFTags::AddTag(char *tag_line)
{
 char *eq;

 // Transform 0x01-0x1F -> 0x20
 for(unsigned int i = 0; i < strlen(tag_line); i++)
  if((unsigned char)tag_line[i] < 0x20)
   tag_line[i] = 0x20;

 eq = strchr(tag_line, '=');

 if(eq)
 {
  *eq = 0;

  MDFN_trim(tag_line);
  MDFN_trim(eq + 1);

  for(unsigned int i = 0; i < strlen(tag_line); i++)
   tag_line[i] = tolower(tag_line[i]);

  if(TagExists(tag_line))
   tags[tag_line] = tags[std::string(tag_line)] + std::string(1, '\n') + std::string(eq + 1);
  else
   tags[tag_line] = std::string(eq + 1);
 }
}
示例#2
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);
}
示例#3
0
文件: nsf.cpp 项目: IcooN/OpenEmu
int LoadNSF(MDFNFILE *fp)
{
 NSF_HEADER NSFHeader;

 fp->rewind();
 fp->fread(&NSFHeader, 1, 0x80);

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

 NSFInfo->GameName = (UTF8*)MDFN_RemoveControlChars(strdup((char *)NSFHeader.GameName));
 NSFInfo->Artist = (UTF8 *)MDFN_RemoveControlChars(strdup((char *)NSFHeader.Artist));
 NSFInfo->Copyright = (UTF8 *)MDFN_RemoveControlChars(strdup((char *)NSFHeader.Copyright));

 MDFN_trim((char*)NSFInfo->GameName);
 MDFN_trim((char*)NSFInfo->Artist);
 MDFN_trim((char*)NSFInfo->Copyright);

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

 NSFInfo->NSFSize = fp->Size() - 0x80;

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

 if(!(NSFInfo->NSFDATA=(uint8 *)MDFN_malloc(NSFInfo->NSFMaxBank*4096, _("NSF data"))))
  return 0;

 fp->fseek(0x80, SEEK_SET);

 memset(NSFInfo->NSFDATA, 0x00, NSFInfo->NSFMaxBank*4096);
 fp->fread(NSFInfo->NSFDATA+(NSFInfo->LoadAddr&0xfff), 1, 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);

 return(1);
}
示例#4
0
static void MakeGIName(MDFNGI* gi, const char* path)
{
 char* ns = NULL;
 char* tmp;

 if((ns = strdup(GetFNComponent(path))))
 {
  unsigned nslen = strlen(ns);

  for(unsigned x = 0; x < nslen; x++)
  {
   if(ns[x] == '_')
    ns[x] = ' ';
   else if(ns[x] < 0x20)
    ns[x] = ' ';
  }

  if((tmp = strrchr(ns, '.')))
   *tmp = 0;

  MDFN_trim(ns);

  gi->name = (UTF8*)ns;
 }
}
示例#5
0
static std::string GrabString(Stream* fp, size_t len)
{
 std::string ret;
 size_t null_pos;

 ret.resize(len);
 fp->read(&ret[0], len);

 null_pos = ret.find('\0');	// ANDDYYYYYYYYY
 if(null_pos != std::string::npos)
  ret.resize(null_pos);

 MDFN_zapctrlchars(&ret);
 MDFN_trim(&ret);

 return ret;
}
示例#6
0
void MD_ReadSegaHeader(const uint8 *header, md_game_info *ginfo)
{
 ginfo->rom_size = 0; //fp->size;

 memcpy(ginfo->copyright, header + 0x10, 16);
 ginfo->copyright[16] = 0;
 MDFN_RemoveControlChars(ginfo->copyright);

 // FIXME: SJIS to UTF8 conversion.
 memcpy(ginfo->domestic_name, header + 0x20, 0x30);
 ginfo->domestic_name[0x30] = 0;
 MDFN_RemoveControlChars(ginfo->domestic_name);

 memcpy(ginfo->overseas_name, header + 0x50, 0x30);
 ginfo->overseas_name[0x30] = 0;
 MDFN_RemoveControlChars(ginfo->overseas_name);

 memcpy(ginfo->product_code, header + 0x82, 0x0C);
 ginfo->product_code[0xC] = 0;
 MDFN_RemoveControlChars(ginfo->product_code);
 MDFN_trim(ginfo->product_code);

 ginfo->checksum = (header[0x8E] << 8) | (header[0x8F] << 0);

 for(int i = 0; i < 16; i++)
 {
  for(unsigned int iot = 0; iot < sizeof(IO_types) / sizeof(IO_type_t); iot++)
  {
   if(IO_types[iot].code_char == header[0x90 + i])
   {
    ginfo->io_support |= 1 << IO_types[iot].id;
    break;
   }
  }
 }

 ginfo->region_support = get_region_numeric(header[0xF0]);
}
示例#7
0
static void GetString(char *s, int max)
{
 CHEAT_gets(s, max);
 MDFN_trim(s);
}
示例#8
0
static void ValidateSetting(const char *value, const MDFNSetting *setting)
{
 MDFNSettingType base_type = setting->type;

 if(base_type == MDFNST_UINT)
 {
  unsigned long long ullvalue;

  if(!TranslateSettingValueUI(value, ullvalue))
  {
   throw MDFN_Error(0, _("Setting \"%s\", value \"%s\", is not set to a valid unsigned integer."), setting->name, value);
  }
  if(setting->minimum)
  {
   unsigned long long minimum;

   TranslateSettingValueUI(setting->minimum, minimum);
   if(ullvalue < minimum)
   {
    throw MDFN_Error(0, _("Setting \"%s\" is set too small(\"%s\"); the minimum acceptable value is \"%s\"."), setting->name, value, setting->minimum);
   }
  }
  if(setting->maximum)
  {
   unsigned long long maximum;

   TranslateSettingValueUI(setting->maximum, maximum);
   if(ullvalue > maximum)
   {
    throw MDFN_Error(0, _("Setting \"%s\" is set too large(\"%s\"); the maximum acceptable value is \"%s\"."), setting->name, value, setting->maximum);
   }
  }
 }
 else if(base_type == MDFNST_INT)
 {
  long long llvalue;

  if(!TranslateSettingValueI(value, llvalue))
  {
   throw MDFN_Error(0, _("Setting \"%s\", value \"%s\", is not set to a valid signed integer."), setting->name, value);
  }
  if(setting->minimum)
  {
   long long minimum;

   TranslateSettingValueI(setting->minimum, minimum);
   if(llvalue < minimum)
   {
    throw MDFN_Error(0, _("Setting \"%s\" is set too small(\"%s\"); the minimum acceptable value is \"%s\"."), setting->name, value, setting->minimum);
   }
  }
  if(setting->maximum)
  {
   long long maximum;

   TranslateSettingValueI(setting->maximum, maximum);
   if(llvalue > maximum)
   {
    throw MDFN_Error(0, _("Setting \"%s\" is set too large(\"%s\"); the maximum acceptable value is \"%s\"."), setting->name, value, setting->maximum);
   }
  }
 }
 else if(base_type == MDFNST_FLOAT)
 {
  double dvalue;

  if(!MR_StringToDouble(value, &dvalue))
  {
   throw MDFN_Error(0, _("Setting \"%s\", value \"%s\", is not set to a floating-point(real) number."), setting->name, value);
  }

  if(std::isnan(dvalue))
   throw MDFN_Error(0, _("Setting \"%s\", value \"%s\", is NaN!"), setting->name, value);

  if(setting->minimum)
  {
   double minimum;

   if(MDFN_UNLIKELY(!MR_StringToDouble(setting->minimum, &minimum)))
    throw MDFN_Error(0, _("Minimum value, \"%f\", for setting \"%s\" is not set to a floating-point(real) number."), minimum, setting->name);

   if(MDFN_UNLIKELY(dvalue < minimum))
    throw MDFN_Error(0, _("Setting \"%s\" is set too small(\"%s\"); the minimum acceptable value is \"%s\"."), setting->name, value, setting->minimum);
  }
  if(setting->maximum)
  {
   double maximum;

   if(MDFN_UNLIKELY(!MR_StringToDouble(setting->maximum, &maximum)))
    throw MDFN_Error(0, _("Maximum value, \"%f\", for setting \"%s\" is not set to a floating-point(real) number."), maximum, setting->name);

   if(MDFN_UNLIKELY(dvalue > maximum))
    throw MDFN_Error(0, _("Setting \"%s\" is set too large(\"%s\"); the maximum acceptable value is \"%s\"."), setting->name, value, setting->maximum);
  }
 }
 else if(base_type == MDFNST_BOOL)
 {
  if(strlen(value) != 1 || (value[0] != '0' && value[0] != '1'))
  {
   throw MDFN_Error(0, _("Setting \"%s\", value \"%s\",  is not a valid boolean value."), setting->name, value);
  }
 }
 else if(base_type == MDFNST_ENUM)
 {
  const MDFNSetting_EnumList *enum_list = setting->enum_list;
  bool found = false;
  std::string valid_string_list;

  assert(enum_list);

  while(enum_list->string)
  {
   if(!MDFN_strazicmp(value, enum_list->string))
   {
    found = true;
    break;
   }

   if(enum_list->description)	// Don't list out undocumented and deprecated values.
    valid_string_list = valid_string_list + (enum_list == setting->enum_list ? "" : " ") + std::string(enum_list->string);

   enum_list++;
  }

  if(!found)
  {
   throw MDFN_Error(0, _("Setting \"%s\", value \"%s\", is not a recognized string.  Recognized strings: %s"), setting->name, value, valid_string_list.c_str());
  }
 }
 else if(base_type == MDFNST_MULTI_ENUM)
 {
  std::vector<std::string> mel = MDFN_strsplit(value);

  assert(setting->enum_list);

  for(auto& mee : mel)
  {
   bool found = false;
   const MDFNSetting_EnumList* enum_list = setting->enum_list;

   MDFN_trim(&mee);

   while(enum_list->string)
   {
    if(!MDFN_strazicmp(mee.c_str(), enum_list->string))
    {
     found = true;
     break;
    }
    enum_list++;
   }

   if(!found)
   {
    std::string valid_string_list;

    enum_list = setting->enum_list;
    while(enum_list->string)
    {
     if(enum_list->description)	// Don't list out undocumented and deprecated values.
      valid_string_list = valid_string_list + (enum_list == setting->enum_list ? "" : " ") + std::string(enum_list->string);

     enum_list++;
    }
    throw MDFN_Error(0, _("Setting \"%s\", value \"%s\" component \"%s\", is not a recognized string.  Recognized strings: %s"), setting->name, value, mee.c_str(), valid_string_list.c_str());
   }
  }
 }

 if(setting->validate_func && !setting->validate_func(setting->name, value))
 {
  if(base_type == MDFNST_STRING)
   throw MDFN_Error(0, _("Setting \"%s\" is not set to a valid string: \"%s\""), setting->name, value);
  else
   throw MDFN_Error(0, _("Setting \"%s\" is not set to a valid unsigned integer: \"%s\""), setting->name, value);
 }
}
void CDAccess_CCD::Load(const char *path, bool image_memcache)
{
 FileStream cf(path, FileStream::MODE_READ);
 std::map<std::string, CCD_Section> Sections;
 std::string linebuf;
 std::string cur_section_name;
 std::string dir_path, file_base, file_ext;
 char img_extsd[4] = { 'i', 'm', 'g', 0 };
 char sub_extsd[4] = { 's', 'u', 'b', 0 };

 MDFN_GetFilePathComponents(path, &dir_path, &file_base, &file_ext);

 if(file_ext.length() == 4 && file_ext[0] == '.')
 {
  signed char extupt[3] = { -1, -1, -1 };

  for(int i = 1; i < 4; i++)
  {
   if(file_ext[i] >= 'A' && file_ext[i] <= 'Z')
    extupt[i - 1] = 'A' - 'a';
   else if(file_ext[i] >= 'a' && file_ext[i] <= 'z')
    extupt[i - 1] = 0;
  }

  signed char av = -1;
  for(int i = 0; i < 3; i++)
  {
   if(extupt[i] != -1)
    av = extupt[i];
   else
    extupt[i] = av;
  }

  if(av == -1)
   av = 0;

  for(int i = 0; i < 3; i++)
  {
   if(extupt[i] == -1)
    extupt[i] = av;
  }

  for(int i = 0; i < 3; i++)
  {
   img_extsd[i] += extupt[i];
   sub_extsd[i] += extupt[i];
  }
 }

 //printf("%s %d %d %d\n", file_ext.c_str(), extupt[0], extupt[1], extupt[2]);

 linebuf.reserve(256);

 while(cf.get_line(linebuf) >= 0)
 {
  MDFN_trim(linebuf);

  if(linebuf.length() == 0)	// Skip blank lines.
   continue;

  if(linebuf[0] == '[')
  {
   if(linebuf.length() < 3 || linebuf[linebuf.length() - 1] != ']')
    throw MDFN_Error(0, _("Malformed section specifier: %s"), linebuf.c_str());

   cur_section_name = linebuf.substr(1, linebuf.length() - 2);
   MDFN_strtoupper(cur_section_name);
  }
  else
  {
   const size_t feqpos = linebuf.find('=');
   const size_t leqpos = linebuf.rfind('=');
   std::string k, v;

   if(feqpos == std::string::npos || feqpos != leqpos)
    throw MDFN_Error(0, _("Malformed value pair specifier: %s"), linebuf.c_str());

   k = linebuf.substr(0, feqpos);
   v = linebuf.substr(feqpos + 1);

   MDFN_trim(k);
   MDFN_trim(v);

   MDFN_strtoupper(k);

   Sections[cur_section_name][k] = v;
  }
 }

 {
  CCD_Section& ds = Sections["DISC"];
  unsigned toc_entries = CCD_ReadInt<unsigned>(ds, "TOCENTRIES");
  unsigned num_sessions = CCD_ReadInt<unsigned>(ds, "SESSIONS");
  bool data_tracks_scrambled = CCD_ReadInt<unsigned>(ds, "DATATRACKSSCRAMBLED");

  if(num_sessions != 1)
   throw MDFN_Error(0, _("Unsupported number of sessions: %u"), num_sessions);

  if(data_tracks_scrambled)
   throw MDFN_Error(0, _("Scrambled CCD data tracks currently not supported."));

  //printf("MOO: %d\n", toc_entries);

  for(unsigned te = 0; te < toc_entries; te++)
  {
   char tmpbuf[64];
   snprintf(tmpbuf, sizeof(tmpbuf), "ENTRY %u", te);
   CCD_Section& ts = Sections[std::string(tmpbuf)];
   unsigned session = CCD_ReadInt<unsigned>(ts, "SESSION");
   uint8 point = CCD_ReadInt<uint8>(ts, "POINT");
   uint8 adr = CCD_ReadInt<uint8>(ts, "ADR");
   uint8 control = CCD_ReadInt<uint8>(ts, "CONTROL");
   uint8 pmin = CCD_ReadInt<uint8>(ts, "PMIN");
   uint8 psec = CCD_ReadInt<uint8>(ts, "PSEC");
   uint8 pframe = CCD_ReadInt<uint8>(ts, "PFRAME");
   signed plba = CCD_ReadInt<signed>(ts, "PLBA");

   if(session != 1)
    throw MDFN_Error(0, "Unsupported TOC entry Session value: %u", session);

   // Reference: ECMA-394, page 5-14
   switch(point)
   {
    default:
	throw MDFN_Error(0, "Unsupported TOC entry Point value: %u", point);
	break;

    case 0xA0:
	tocd.first_track = pmin;
	tocd.disc_type = psec;
	break;

    case 0xA1:
	tocd.last_track = pmin;
	break;

    case 0xA2:
	tocd.tracks[100].adr = adr;
	tocd.tracks[100].control = control;
	tocd.tracks[100].lba = plba;
	break;

case 99:
case 98:
case 97:
case 96:
case 95:
case 94:
case 93:
case 92:
case 91:
case 90:
case 89:
case 88:
case 87:
case 86:
case 85:
case 84:
case 83:
case 82:
case 81:
case 80:
case 79:
case 78:
case 77:
case 76:
case 75:
case 74:
case 73:
case 72:
case 71:
case 70:
case 69:
case 68:
case 67:
case 66:
case 65:
case 64:
case 63:
case 62:
case 61:
case 60:
case 59:
case 58:
case 57:
case 56:
case 55:
case 54:
case 53:
case 52:
case 51:
case 50:
case 49:
case 48:
case 47:
case 46:
case 45:
case 44:
case 43:
case 42:
case 41:
case 40:
case 39:
case 38:
case 37:
case 36:
case 35:
case 34:
case 33:
case 32:
case 31:
case 30:
case 29:
case 28:
case 27:
case 26:
case 25:
case 24:
case 23:
case 22:
case 21:
case 20:
case 19:
case 18:
case 17:
case 16:
case 15:
case 14:
case 13:
case 12:
case 11:
case 10:
case 9:
case 8:
case 7:
case 6:
case 5:
case 4:
case 3:
case 2:
case 1:
	tocd.tracks[point].adr = adr;
	tocd.tracks[point].control = control;
	tocd.tracks[point].lba = plba;
	break;
   }
  }
 }

 // Convenience leadout track duplication.
 if(tocd.last_track < 99)
  tocd.tracks[tocd.last_track + 1] = tocd.tracks[100];

 //
 // Open image stream.
 {
  std::string image_path = MDFN_EvalFIP(dir_path, file_base + std::string(".") + std::string(img_extsd), true);

  if(image_memcache)
  {
   img_stream = new MemoryStream(new FileStream(image_path.c_str(), FileStream::MODE_READ));
  }
  else
  {
   img_stream = new FileStream(image_path.c_str(), FileStream::MODE_READ);
  }

  int64 ss = img_stream->size();

  if(ss % 2352)
   throw MDFN_Error(0, _("CCD image size is not evenly divisible by 2352."));

  img_numsectors = ss / 2352;  
 }

 //
 // Open subchannel stream
 {
  std::string sub_path = MDFN_EvalFIP(dir_path, file_base + std::string(".") + std::string(sub_extsd), true);

  if(image_memcache)
   sub_stream = new MemoryStream(new FileStream(sub_path.c_str(), FileStream::MODE_READ));
  else
   sub_stream = new FileStream(sub_path.c_str(), FileStream::MODE_READ);

  if(sub_stream->size() != (int64)img_numsectors * 96)
   throw MDFN_Error(0, _("CCD SUB file size mismatch."));
 }

 CheckSubQSanity();
}