1. spencercw
  2. gb_emulator

Commits

spencercw  committed 5705d84

Implement sound channel 3.

  • Participants
  • Parent commits b32ec56
  • Branches default

Comments (0)

Files changed (5)

File gb_emulator/gb.pb.cc

View file
 const ::google::protobuf::Descriptor* GbSoundData_Sound2_descriptor_ = NULL;
 const ::google::protobuf::internal::GeneratedMessageReflection*
   GbSoundData_Sound2_reflection_ = NULL;
+const ::google::protobuf::Descriptor* GbSoundData_Sound3_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  GbSoundData_Sound3_reflection_ = NULL;
 const ::google::protobuf::Descriptor* GbVideoData_descriptor_ = NULL;
 const ::google::protobuf::internal::GeneratedMessageReflection*
   GbVideoData_reflection_ = NULL;
       ::google::protobuf::MessageFactory::generated_factory(),
       sizeof(GbMemoryData));
   GbSoundData_descriptor_ = file->message_type(2);
-  static const int GbSoundData_offsets_[3] = {
+  static const int GbSoundData_offsets_[4] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbSoundData, excess_samples_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbSoundData, sound_1_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbSoundData, sound_2_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbSoundData, sound_3_),
   };
   GbSoundData_reflection_ =
     new ::google::protobuf::internal::GeneratedMessageReflection(
       ::google::protobuf::DescriptorPool::generated_pool(),
       ::google::protobuf::MessageFactory::generated_factory(),
       sizeof(GbSoundData_Sound2));
+  GbSoundData_Sound3_descriptor_ = GbSoundData_descriptor_->nested_type(2);
+  static const int GbSoundData_Sound3_offsets_[7] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbSoundData_Sound3, gb_frequency_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbSoundData_Sound3, act_frequency_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbSoundData_Sound3, duration_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbSoundData_Sound3, countdown_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbSoundData_Sound3, wave_index_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbSoundData_Sound3, out_level_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbSoundData_Sound3, wave_pattern_),
+  };
+  GbSoundData_Sound3_reflection_ =
+    new ::google::protobuf::internal::GeneratedMessageReflection(
+      GbSoundData_Sound3_descriptor_,
+      GbSoundData_Sound3::default_instance_,
+      GbSoundData_Sound3_offsets_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbSoundData_Sound3, _has_bits_[0]),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbSoundData_Sound3, _unknown_fields_),
+      -1,
+      ::google::protobuf::DescriptorPool::generated_pool(),
+      ::google::protobuf::MessageFactory::generated_factory(),
+      sizeof(GbSoundData_Sound3));
   GbVideoData_descriptor_ = file->message_type(3);
   static const int GbVideoData_offsets_[7] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GbVideoData, priority_map_),
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     GbSoundData_Sound2_descriptor_, &GbSoundData_Sound2::default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+    GbSoundData_Sound3_descriptor_, &GbSoundData_Sound3::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     GbVideoData_descriptor_, &GbVideoData::default_instance());
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
     GbData_descriptor_, &GbData::default_instance());
   delete GbSoundData_Sound1_reflection_;
   delete GbSoundData_Sound2::default_instance_;
   delete GbSoundData_Sound2_reflection_;
+  delete GbSoundData_Sound3::default_instance_;
+  delete GbSoundData_Sound3_reflection_;
   delete GbVideoData::default_instance_;
   delete GbVideoData_reflection_;
   delete GbData::default_instance_;
     "ram_enable\030\t \002(\010\022\020\n\010rom_bank\030\n \002(\r\022\020\n\010ra"
     "m_bank\030\013 \002(\r\022\024\n\014ext_ram_bank\030\014 \002(\r\022\021\n\tvr"
     "am_bank\030\r \002(\r\022\013\n\003mbc\030\016 \002(\014\022\013\n\003rtc\030\017 \002(\014\""
-    "\234\004\n\013GbSoundData\022\026\n\016excess_samples\030\001 \002(\001\022"
+    "\334\005\n\013GbSoundData\022\026\n\016excess_samples\030\001 \002(\001\022"
     "$\n\007sound_1\030\002 \002(\0132\023.GbSoundData.Sound1\022$\n"
-    "\007sound_2\030\003 \002(\0132\023.GbSoundData.Sound2\032\376\001\n\006"
-    "Sound1\022\024\n\014gb_frequency\030\001 \002(\001\022\025\n\ract_freq"
-    "uency\030\002 \002(\001\022\n\n\002hi\030\003 \002(\010\022\014\n\004duty\030\004 \002(\001\022\021\n"
-    "\tcountdown\030\005 \002(\001\022\024\n\014sweep_shifts\030\006 \002(\r\022\022"
-    "\n\nsweep_type\030\007 \002(\010\022\022\n\nsweep_step\030\010 \002(\001\022\027"
-    "\n\017sweep_countdown\030\t \002(\001\022\020\n\010envelope\030\n \002("
-    "\r\022\025\n\renvelope_step\030\013 \002(\001\022\032\n\022envelope_cou"
-    "ntdown\030\014 \002(\001\032\247\001\n\006Sound2\022\024\n\014gb_frequency\030"
-    "\001 \002(\001\022\025\n\ract_frequency\030\002 \002(\001\022\n\n\002hi\030\003 \002(\010"
-    "\022\014\n\004duty\030\004 \002(\001\022\021\n\tcountdown\030\005 \002(\001\022\020\n\010env"
-    "elope\030\006 \002(\r\022\025\n\renvelope_step\030\007 \002(\001\022\032\n\022en"
-    "velope_countdown\030\010 \002(\001\"\272\001\n\013GbVideoData\022\024"
-    "\n\014priority_map\030\001 \002(\014\022\026\n\016gbc_bg_palette\030\002"
-    " \002(\014\022\032\n\022gbc_sprite_palette\030\003 \002(\014\022\025\n\rhbla"
-    "nk_cycles\030\004 \002(\r\022\027\n\017oam_read_cycles\030\005 \002(\r"
-    "\022\034\n\024oam_vram_read_cycles\030\006 \002(\r\022\023\n\013line_c"
-    "ycles\030\007 \002(\r\"\274\001\n\006GbData\022\013\n\003rom\030\001 \002(\t\022\020\n\010r"
-    "om_size\030\002 \002(\r\022\024\n\014rom_checksum\030\003 \002(\r\022\013\n\003g"
-    "bc\030\004 \002(\010\022\027\n\003cpu\030\005 \002(\0132\n.GbCpuData\022\035\n\006mem"
-    "ory\030\006 \002(\0132\r.GbMemoryData\022\033\n\005sound\030\007 \002(\0132"
-    "\014.GbSoundData\022\033\n\005video\030\010 \002(\0132\014.GbVideoDa"
-    "ta", 1322);
+    "\007sound_2\030\003 \002(\0132\023.GbSoundData.Sound2\022$\n\007s"
+    "ound_3\030\004 \002(\0132\023.GbSoundData.Sound3\032\376\001\n\006So"
+    "und1\022\024\n\014gb_frequency\030\001 \002(\001\022\025\n\ract_freque"
+    "ncy\030\002 \002(\001\022\n\n\002hi\030\003 \002(\010\022\014\n\004duty\030\004 \002(\001\022\021\n\tc"
+    "ountdown\030\005 \002(\001\022\024\n\014sweep_shifts\030\006 \002(\r\022\022\n\n"
+    "sweep_type\030\007 \002(\010\022\022\n\nsweep_step\030\010 \002(\001\022\027\n\017"
+    "sweep_countdown\030\t \002(\001\022\020\n\010envelope\030\n \002(\r\022"
+    "\025\n\renvelope_step\030\013 \002(\001\022\032\n\022envelope_count"
+    "down\030\014 \002(\001\032\247\001\n\006Sound2\022\024\n\014gb_frequency\030\001 "
+    "\002(\001\022\025\n\ract_frequency\030\002 \002(\001\022\n\n\002hi\030\003 \002(\010\022\014"
+    "\n\004duty\030\004 \002(\001\022\021\n\tcountdown\030\005 \002(\001\022\020\n\010envel"
+    "ope\030\006 \002(\r\022\025\n\renvelope_step\030\007 \002(\001\022\032\n\022enve"
+    "lope_countdown\030\010 \002(\001\032\227\001\n\006Sound3\022\024\n\014gb_fr"
+    "equency\030\001 \002(\001\022\025\n\ract_frequency\030\002 \002(\001\022\020\n\010"
+    "duration\030\003 \002(\001\022\021\n\tcountdown\030\004 \002(\001\022\022\n\nwav"
+    "e_index\030\005 \002(\r\022\021\n\tout_level\030\006 \002(\r\022\024\n\014wave"
+    "_pattern\030\007 \002(\014\"\272\001\n\013GbVideoData\022\024\n\014priori"
+    "ty_map\030\001 \002(\014\022\026\n\016gbc_bg_palette\030\002 \002(\014\022\032\n\022"
+    "gbc_sprite_palette\030\003 \002(\014\022\025\n\rhblank_cycle"
+    "s\030\004 \002(\r\022\027\n\017oam_read_cycles\030\005 \002(\r\022\034\n\024oam_"
+    "vram_read_cycles\030\006 \002(\r\022\023\n\013line_cycles\030\007 "
+    "\002(\r\"\274\001\n\006GbData\022\013\n\003rom\030\001 \002(\t\022\020\n\010rom_size\030"
+    "\002 \002(\r\022\024\n\014rom_checksum\030\003 \002(\r\022\013\n\003gbc\030\004 \002(\010"
+    "\022\027\n\003cpu\030\005 \002(\0132\n.GbCpuData\022\035\n\006memory\030\006 \002("
+    "\0132\r.GbMemoryData\022\033\n\005sound\030\007 \002(\0132\014.GbSoun"
+    "dData\022\033\n\005video\030\010 \002(\0132\014.GbVideoData", 1514);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "gb.proto", &protobuf_RegisterTypes);
   GbCpuData::default_instance_ = new GbCpuData();
   GbSoundData::default_instance_ = new GbSoundData();
   GbSoundData_Sound1::default_instance_ = new GbSoundData_Sound1();
   GbSoundData_Sound2::default_instance_ = new GbSoundData_Sound2();
+  GbSoundData_Sound3::default_instance_ = new GbSoundData_Sound3();
   GbVideoData::default_instance_ = new GbVideoData();
   GbData::default_instance_ = new GbData();
   GbCpuData::default_instance_->InitAsDefaultInstance();
   GbSoundData::default_instance_->InitAsDefaultInstance();
   GbSoundData_Sound1::default_instance_->InitAsDefaultInstance();
   GbSoundData_Sound2::default_instance_->InitAsDefaultInstance();
+  GbSoundData_Sound3::default_instance_->InitAsDefaultInstance();
   GbVideoData::default_instance_->InitAsDefaultInstance();
   GbData::default_instance_->InitAsDefaultInstance();
   ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_gb_2eproto);
 // -------------------------------------------------------------------
 
 #ifndef _MSC_VER
+const int GbSoundData_Sound3::kGbFrequencyFieldNumber;
+const int GbSoundData_Sound3::kActFrequencyFieldNumber;
+const int GbSoundData_Sound3::kDurationFieldNumber;
+const int GbSoundData_Sound3::kCountdownFieldNumber;
+const int GbSoundData_Sound3::kWaveIndexFieldNumber;
+const int GbSoundData_Sound3::kOutLevelFieldNumber;
+const int GbSoundData_Sound3::kWavePatternFieldNumber;
+#endif  // !_MSC_VER
+
+GbSoundData_Sound3::GbSoundData_Sound3()
+  : ::google::protobuf::Message() {
+  SharedCtor();
+}
+
+void GbSoundData_Sound3::InitAsDefaultInstance() {
+}
+
+GbSoundData_Sound3::GbSoundData_Sound3(const GbSoundData_Sound3& from)
+  : ::google::protobuf::Message() {
+  SharedCtor();
+  MergeFrom(from);
+}
+
+void GbSoundData_Sound3::SharedCtor() {
+  _cached_size_ = 0;
+  gb_frequency_ = 0;
+  act_frequency_ = 0;
+  duration_ = 0;
+  countdown_ = 0;
+  wave_index_ = 0u;
+  out_level_ = 0u;
+  wave_pattern_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+}
+
+GbSoundData_Sound3::~GbSoundData_Sound3() {
+  SharedDtor();
+}
+
+void GbSoundData_Sound3::SharedDtor() {
+  if (wave_pattern_ != &::google::protobuf::internal::kEmptyString) {
+    delete wave_pattern_;
+  }
+  if (this != default_instance_) {
+  }
+}
+
+void GbSoundData_Sound3::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* GbSoundData_Sound3::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return GbSoundData_Sound3_descriptor_;
+}
+
+const GbSoundData_Sound3& GbSoundData_Sound3::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_gb_2eproto();  return *default_instance_;
+}
+
+GbSoundData_Sound3* GbSoundData_Sound3::default_instance_ = NULL;
+
+GbSoundData_Sound3* GbSoundData_Sound3::New() const {
+  return new GbSoundData_Sound3;
+}
+
+void GbSoundData_Sound3::Clear() {
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    gb_frequency_ = 0;
+    act_frequency_ = 0;
+    duration_ = 0;
+    countdown_ = 0;
+    wave_index_ = 0u;
+    out_level_ = 0u;
+    if (has_wave_pattern()) {
+      if (wave_pattern_ != &::google::protobuf::internal::kEmptyString) {
+        wave_pattern_->clear();
+      }
+    }
+  }
+  ::memset(_has_bits_, 0, sizeof(_has_bits_));
+  mutable_unknown_fields()->Clear();
+}
+
+bool GbSoundData_Sound3::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
+  ::google::protobuf::uint32 tag;
+  while ((tag = input->ReadTag()) != 0) {
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // required double gb_frequency = 1;
+      case 1: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
+                 input, &gb_frequency_)));
+          set_has_gb_frequency();
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(17)) goto parse_act_frequency;
+        break;
+      }
+      
+      // required double act_frequency = 2;
+      case 2: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) {
+         parse_act_frequency:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
+                 input, &act_frequency_)));
+          set_has_act_frequency();
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(25)) goto parse_duration;
+        break;
+      }
+      
+      // required double duration = 3;
+      case 3: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) {
+         parse_duration:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
+                 input, &duration_)));
+          set_has_duration();
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(33)) goto parse_countdown;
+        break;
+      }
+      
+      // required double countdown = 4;
+      case 4: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) {
+         parse_countdown:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
+                 input, &countdown_)));
+          set_has_countdown();
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(40)) goto parse_wave_index;
+        break;
+      }
+      
+      // required uint32 wave_index = 5;
+      case 5: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_wave_index:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 input, &wave_index_)));
+          set_has_wave_index();
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(48)) goto parse_out_level;
+        break;
+      }
+      
+      // required uint32 out_level = 6;
+      case 6: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+         parse_out_level:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(
+                 input, &out_level_)));
+          set_has_out_level();
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectTag(58)) goto parse_wave_pattern;
+        break;
+      }
+      
+      // required bytes wave_pattern = 7;
+      case 7: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+         parse_wave_pattern:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
+                input, this->mutable_wave_pattern()));
+        } else {
+          goto handle_uninterpreted;
+        }
+        if (input->ExpectAtEnd()) return true;
+        break;
+      }
+      
+      default: {
+      handle_uninterpreted:
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          return true;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+  return true;
+#undef DO_
+}
+
+void GbSoundData_Sound3::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // required double gb_frequency = 1;
+  if (has_gb_frequency()) {
+    ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->gb_frequency(), output);
+  }
+  
+  // required double act_frequency = 2;
+  if (has_act_frequency()) {
+    ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->act_frequency(), output);
+  }
+  
+  // required double duration = 3;
+  if (has_duration()) {
+    ::google::protobuf::internal::WireFormatLite::WriteDouble(3, this->duration(), output);
+  }
+  
+  // required double countdown = 4;
+  if (has_countdown()) {
+    ::google::protobuf::internal::WireFormatLite::WriteDouble(4, this->countdown(), output);
+  }
+  
+  // required uint32 wave_index = 5;
+  if (has_wave_index()) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->wave_index(), output);
+  }
+  
+  // required uint32 out_level = 6;
+  if (has_out_level()) {
+    ::google::protobuf::internal::WireFormatLite::WriteUInt32(6, this->out_level(), output);
+  }
+  
+  // required bytes wave_pattern = 7;
+  if (has_wave_pattern()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBytes(
+      7, this->wave_pattern(), output);
+  }
+  
+  if (!unknown_fields().empty()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        unknown_fields(), output);
+  }
+}
+
+::google::protobuf::uint8* GbSoundData_Sound3::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // required double gb_frequency = 1;
+  if (has_gb_frequency()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->gb_frequency(), target);
+  }
+  
+  // required double act_frequency = 2;
+  if (has_act_frequency()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(2, this->act_frequency(), target);
+  }
+  
+  // required double duration = 3;
+  if (has_duration()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(3, this->duration(), target);
+  }
+  
+  // required double countdown = 4;
+  if (has_countdown()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(4, this->countdown(), target);
+  }
+  
+  // required uint32 wave_index = 5;
+  if (has_wave_index()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->wave_index(), target);
+  }
+  
+  // required uint32 out_level = 6;
+  if (has_out_level()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(6, this->out_level(), target);
+  }
+  
+  // required bytes wave_pattern = 7;
+  if (has_wave_pattern()) {
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
+        7, this->wave_pattern(), target);
+  }
+  
+  if (!unknown_fields().empty()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        unknown_fields(), target);
+  }
+  return target;
+}
+
+int GbSoundData_Sound3::ByteSize() const {
+  int total_size = 0;
+  
+  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    // required double gb_frequency = 1;
+    if (has_gb_frequency()) {
+      total_size += 1 + 8;
+    }
+    
+    // required double act_frequency = 2;
+    if (has_act_frequency()) {
+      total_size += 1 + 8;
+    }
+    
+    // required double duration = 3;
+    if (has_duration()) {
+      total_size += 1 + 8;
+    }
+    
+    // required double countdown = 4;
+    if (has_countdown()) {
+      total_size += 1 + 8;
+    }
+    
+    // required uint32 wave_index = 5;
+    if (has_wave_index()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt32Size(
+          this->wave_index());
+    }
+    
+    // required uint32 out_level = 6;
+    if (has_out_level()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::UInt32Size(
+          this->out_level());
+    }
+    
+    // required bytes wave_pattern = 7;
+    if (has_wave_pattern()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::BytesSize(
+          this->wave_pattern());
+    }
+    
+  }
+  if (!unknown_fields().empty()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        unknown_fields());
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void GbSoundData_Sound3::MergeFrom(const ::google::protobuf::Message& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  const GbSoundData_Sound3* source =
+    ::google::protobuf::internal::dynamic_cast_if_available<const GbSoundData_Sound3*>(
+      &from);
+  if (source == NULL) {
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+    MergeFrom(*source);
+  }
+}
+
+void GbSoundData_Sound3::MergeFrom(const GbSoundData_Sound3& from) {
+  GOOGLE_CHECK_NE(&from, this);
+  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
+    if (from.has_gb_frequency()) {
+      set_gb_frequency(from.gb_frequency());
+    }
+    if (from.has_act_frequency()) {
+      set_act_frequency(from.act_frequency());
+    }
+    if (from.has_duration()) {
+      set_duration(from.duration());
+    }
+    if (from.has_countdown()) {
+      set_countdown(from.countdown());
+    }
+    if (from.has_wave_index()) {
+      set_wave_index(from.wave_index());
+    }
+    if (from.has_out_level()) {
+      set_out_level(from.out_level());
+    }
+    if (from.has_wave_pattern()) {
+      set_wave_pattern(from.wave_pattern());
+    }
+  }
+  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
+}
+
+void GbSoundData_Sound3::CopyFrom(const ::google::protobuf::Message& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void GbSoundData_Sound3::CopyFrom(const GbSoundData_Sound3& from) {
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool GbSoundData_Sound3::IsInitialized() const {
+  if ((_has_bits_[0] & 0x0000007f) != 0x0000007f) return false;
+  
+  return true;
+}
+
+void GbSoundData_Sound3::Swap(GbSoundData_Sound3* other) {
+  if (other != this) {
+    std::swap(gb_frequency_, other->gb_frequency_);
+    std::swap(act_frequency_, other->act_frequency_);
+    std::swap(duration_, other->duration_);
+    std::swap(countdown_, other->countdown_);
+    std::swap(wave_index_, other->wave_index_);
+    std::swap(out_level_, other->out_level_);
+    std::swap(wave_pattern_, other->wave_pattern_);
+    std::swap(_has_bits_[0], other->_has_bits_[0]);
+    _unknown_fields_.Swap(&other->_unknown_fields_);
+    std::swap(_cached_size_, other->_cached_size_);
+  }
+}
+
+::google::protobuf::Metadata GbSoundData_Sound3::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = GbSoundData_Sound3_descriptor_;
+  metadata.reflection = GbSoundData_Sound3_reflection_;
+  return metadata;
+}
+
+
+// -------------------------------------------------------------------
+
+#ifndef _MSC_VER
 const int GbSoundData::kExcessSamplesFieldNumber;
 const int GbSoundData::kSound1FieldNumber;
 const int GbSoundData::kSound2FieldNumber;
+const int GbSoundData::kSound3FieldNumber;
 #endif  // !_MSC_VER
 
 GbSoundData::GbSoundData()
 void GbSoundData::InitAsDefaultInstance() {
   sound_1_ = const_cast< ::GbSoundData_Sound1*>(&::GbSoundData_Sound1::default_instance());
   sound_2_ = const_cast< ::GbSoundData_Sound2*>(&::GbSoundData_Sound2::default_instance());
+  sound_3_ = const_cast< ::GbSoundData_Sound3*>(&::GbSoundData_Sound3::default_instance());
 }
 
 GbSoundData::GbSoundData(const GbSoundData& from)
   excess_samples_ = 0;
   sound_1_ = NULL;
   sound_2_ = NULL;
+  sound_3_ = NULL;
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 
   if (this != default_instance_) {
     delete sound_1_;
     delete sound_2_;
+    delete sound_3_;
   }
 }
 
     if (has_sound_2()) {
       if (sound_2_ != NULL) sound_2_->::GbSoundData_Sound2::Clear();
     }
+    if (has_sound_3()) {
+      if (sound_3_ != NULL) sound_3_->::GbSoundData_Sound3::Clear();
+    }
   }
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   mutable_unknown_fields()->Clear();
         } else {
           goto handle_uninterpreted;
         }
+        if (input->ExpectTag(34)) goto parse_sound_3;
+        break;
+      }
+      
+      // required .GbSoundData.Sound3 sound_3 = 4;
+      case 4: {
+        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
+         parse_sound_3:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_sound_3()));
+        } else {
+          goto handle_uninterpreted;
+        }
         if (input->ExpectAtEnd()) return true;
         break;
       }
       3, this->sound_2(), output);
   }
   
+  // required .GbSoundData.Sound3 sound_3 = 4;
+  if (has_sound_3()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      4, this->sound_3(), output);
+  }
+  
   if (!unknown_fields().empty()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
         unknown_fields(), output);
         3, this->sound_2(), target);
   }
   
+  // required .GbSoundData.Sound3 sound_3 = 4;
+  if (has_sound_3()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        4, this->sound_3(), target);
+  }
+  
   if (!unknown_fields().empty()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
         unknown_fields(), target);
           this->sound_2());
     }
     
+    // required .GbSoundData.Sound3 sound_3 = 4;
+    if (has_sound_3()) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          this->sound_3());
+    }
+    
   }
   if (!unknown_fields().empty()) {
     total_size +=
     if (from.has_sound_2()) {
       mutable_sound_2()->::GbSoundData_Sound2::MergeFrom(from.sound_2());
     }
+    if (from.has_sound_3()) {
+      mutable_sound_3()->::GbSoundData_Sound3::MergeFrom(from.sound_3());
+    }
   }
   mutable_unknown_fields()->MergeFrom(from.unknown_fields());
 }
 }
 
 bool GbSoundData::IsInitialized() const {
-  if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false;
+  if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false;
   
   if (has_sound_1()) {
     if (!this->sound_1().IsInitialized()) return false;
   if (has_sound_2()) {
     if (!this->sound_2().IsInitialized()) return false;
   }
+  if (has_sound_3()) {
+    if (!this->sound_3().IsInitialized()) return false;
+  }
   return true;
 }
 
     std::swap(excess_samples_, other->excess_samples_);
     std::swap(sound_1_, other->sound_1_);
     std::swap(sound_2_, other->sound_2_);
+    std::swap(sound_3_, other->sound_3_);
     std::swap(_has_bits_[0], other->_has_bits_[0]);
     _unknown_fields_.Swap(&other->_unknown_fields_);
     std::swap(_cached_size_, other->_cached_size_);

File gb_emulator/gb.pb.h

View file
 class GbSoundData;
 class GbSoundData_Sound1;
 class GbSoundData_Sound2;
+class GbSoundData_Sound3;
 class GbVideoData;
 class GbData;
 
 };
 // -------------------------------------------------------------------
 
+class GbSoundData_Sound3 : public ::google::protobuf::Message {
+ public:
+  GbSoundData_Sound3();
+  virtual ~GbSoundData_Sound3();
+  
+  GbSoundData_Sound3(const GbSoundData_Sound3& from);
+  
+  inline GbSoundData_Sound3& operator=(const GbSoundData_Sound3& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  
+  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
+    return _unknown_fields_;
+  }
+  
+  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
+    return &_unknown_fields_;
+  }
+  
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const GbSoundData_Sound3& default_instance();
+  
+  void Swap(GbSoundData_Sound3* other);
+  
+  // implements Message ----------------------------------------------
+  
+  GbSoundData_Sound3* New() const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const GbSoundData_Sound3& from);
+  void MergeFrom(const GbSoundData_Sound3& from);
+  void Clear();
+  bool IsInitialized() const;
+  
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  public:
+  
+  ::google::protobuf::Metadata GetMetadata() const;
+  
+  // nested types ----------------------------------------------------
+  
+  // accessors -------------------------------------------------------
+  
+  // required double gb_frequency = 1;
+  inline bool has_gb_frequency() const;
+  inline void clear_gb_frequency();
+  static const int kGbFrequencyFieldNumber = 1;
+  inline double gb_frequency() const;
+  inline void set_gb_frequency(double value);
+  
+  // required double act_frequency = 2;
+  inline bool has_act_frequency() const;
+  inline void clear_act_frequency();
+  static const int kActFrequencyFieldNumber = 2;
+  inline double act_frequency() const;
+  inline void set_act_frequency(double value);
+  
+  // required double duration = 3;
+  inline bool has_duration() const;
+  inline void clear_duration();
+  static const int kDurationFieldNumber = 3;
+  inline double duration() const;
+  inline void set_duration(double value);
+  
+  // required double countdown = 4;
+  inline bool has_countdown() const;
+  inline void clear_countdown();
+  static const int kCountdownFieldNumber = 4;
+  inline double countdown() const;
+  inline void set_countdown(double value);
+  
+  // required uint32 wave_index = 5;
+  inline bool has_wave_index() const;
+  inline void clear_wave_index();
+  static const int kWaveIndexFieldNumber = 5;
+  inline ::google::protobuf::uint32 wave_index() const;
+  inline void set_wave_index(::google::protobuf::uint32 value);
+  
+  // required uint32 out_level = 6;
+  inline bool has_out_level() const;
+  inline void clear_out_level();
+  static const int kOutLevelFieldNumber = 6;
+  inline ::google::protobuf::uint32 out_level() const;
+  inline void set_out_level(::google::protobuf::uint32 value);
+  
+  // required bytes wave_pattern = 7;
+  inline bool has_wave_pattern() const;
+  inline void clear_wave_pattern();
+  static const int kWavePatternFieldNumber = 7;
+  inline const ::std::string& wave_pattern() const;
+  inline void set_wave_pattern(const ::std::string& value);
+  inline void set_wave_pattern(const char* value);
+  inline void set_wave_pattern(const void* value, size_t size);
+  inline ::std::string* mutable_wave_pattern();
+  inline ::std::string* release_wave_pattern();
+  
+  // @@protoc_insertion_point(class_scope:GbSoundData.Sound3)
+ private:
+  inline void set_has_gb_frequency();
+  inline void clear_has_gb_frequency();
+  inline void set_has_act_frequency();
+  inline void clear_has_act_frequency();
+  inline void set_has_duration();
+  inline void clear_has_duration();
+  inline void set_has_countdown();
+  inline void clear_has_countdown();
+  inline void set_has_wave_index();
+  inline void clear_has_wave_index();
+  inline void set_has_out_level();
+  inline void clear_has_out_level();
+  inline void set_has_wave_pattern();
+  inline void clear_has_wave_pattern();
+  
+  ::google::protobuf::UnknownFieldSet _unknown_fields_;
+  
+  double gb_frequency_;
+  double act_frequency_;
+  double duration_;
+  double countdown_;
+  ::google::protobuf::uint32 wave_index_;
+  ::google::protobuf::uint32 out_level_;
+  ::std::string* wave_pattern_;
+  
+  mutable int _cached_size_;
+  ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32];
+  
+  friend void  protobuf_AddDesc_gb_2eproto();
+  friend void protobuf_AssignDesc_gb_2eproto();
+  friend void protobuf_ShutdownFile_gb_2eproto();
+  
+  void InitAsDefaultInstance();
+  static GbSoundData_Sound3* default_instance_;
+};
+// -------------------------------------------------------------------
+
 class GbSoundData : public ::google::protobuf::Message {
  public:
   GbSoundData();
   
   typedef GbSoundData_Sound1 Sound1;
   typedef GbSoundData_Sound2 Sound2;
+  typedef GbSoundData_Sound3 Sound3;
   
   // accessors -------------------------------------------------------
   
   inline ::GbSoundData_Sound2* mutable_sound_2();
   inline ::GbSoundData_Sound2* release_sound_2();
   
+  // required .GbSoundData.Sound3 sound_3 = 4;
+  inline bool has_sound_3() const;
+  inline void clear_sound_3();
+  static const int kSound3FieldNumber = 4;
+  inline const ::GbSoundData_Sound3& sound_3() const;
+  inline ::GbSoundData_Sound3* mutable_sound_3();
+  inline ::GbSoundData_Sound3* release_sound_3();
+  
   // @@protoc_insertion_point(class_scope:GbSoundData)
  private:
   inline void set_has_excess_samples();
   inline void clear_has_sound_1();
   inline void set_has_sound_2();
   inline void clear_has_sound_2();
+  inline void set_has_sound_3();
+  inline void clear_has_sound_3();
   
   ::google::protobuf::UnknownFieldSet _unknown_fields_;
   
   double excess_samples_;
   ::GbSoundData_Sound1* sound_1_;
   ::GbSoundData_Sound2* sound_2_;
+  ::GbSoundData_Sound3* sound_3_;
   
   mutable int _cached_size_;
-  ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32];
+  ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32];
   
   friend void  protobuf_AddDesc_gb_2eproto();
   friend void protobuf_AssignDesc_gb_2eproto();
 
 // -------------------------------------------------------------------
 
+// GbSoundData_Sound3
+
+// required double gb_frequency = 1;
+inline bool GbSoundData_Sound3::has_gb_frequency() const {
+  return (_has_bits_[0] & 0x00000001u) != 0;
+}
+inline void GbSoundData_Sound3::set_has_gb_frequency() {
+  _has_bits_[0] |= 0x00000001u;
+}
+inline void GbSoundData_Sound3::clear_has_gb_frequency() {
+  _has_bits_[0] &= ~0x00000001u;
+}
+inline void GbSoundData_Sound3::clear_gb_frequency() {
+  gb_frequency_ = 0;
+  clear_has_gb_frequency();
+}
+inline double GbSoundData_Sound3::gb_frequency() const {
+  return gb_frequency_;
+}
+inline void GbSoundData_Sound3::set_gb_frequency(double value) {
+  set_has_gb_frequency();
+  gb_frequency_ = value;
+}
+
+// required double act_frequency = 2;
+inline bool GbSoundData_Sound3::has_act_frequency() const {
+  return (_has_bits_[0] & 0x00000002u) != 0;
+}
+inline void GbSoundData_Sound3::set_has_act_frequency() {
+  _has_bits_[0] |= 0x00000002u;
+}
+inline void GbSoundData_Sound3::clear_has_act_frequency() {
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline void GbSoundData_Sound3::clear_act_frequency() {
+  act_frequency_ = 0;
+  clear_has_act_frequency();
+}
+inline double GbSoundData_Sound3::act_frequency() const {
+  return act_frequency_;
+}
+inline void GbSoundData_Sound3::set_act_frequency(double value) {
+  set_has_act_frequency();
+  act_frequency_ = value;
+}
+
+// required double duration = 3;
+inline bool GbSoundData_Sound3::has_duration() const {
+  return (_has_bits_[0] & 0x00000004u) != 0;
+}
+inline void GbSoundData_Sound3::set_has_duration() {
+  _has_bits_[0] |= 0x00000004u;
+}
+inline void GbSoundData_Sound3::clear_has_duration() {
+  _has_bits_[0] &= ~0x00000004u;
+}
+inline void GbSoundData_Sound3::clear_duration() {
+  duration_ = 0;
+  clear_has_duration();
+}
+inline double GbSoundData_Sound3::duration() const {
+  return duration_;
+}
+inline void GbSoundData_Sound3::set_duration(double value) {
+  set_has_duration();
+  duration_ = value;
+}
+
+// required double countdown = 4;
+inline bool GbSoundData_Sound3::has_countdown() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void GbSoundData_Sound3::set_has_countdown() {
+  _has_bits_[0] |= 0x00000008u;
+}
+inline void GbSoundData_Sound3::clear_has_countdown() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+inline void GbSoundData_Sound3::clear_countdown() {
+  countdown_ = 0;
+  clear_has_countdown();
+}
+inline double GbSoundData_Sound3::countdown() const {
+  return countdown_;
+}
+inline void GbSoundData_Sound3::set_countdown(double value) {
+  set_has_countdown();
+  countdown_ = value;
+}
+
+// required uint32 wave_index = 5;
+inline bool GbSoundData_Sound3::has_wave_index() const {
+  return (_has_bits_[0] & 0x00000010u) != 0;
+}
+inline void GbSoundData_Sound3::set_has_wave_index() {
+  _has_bits_[0] |= 0x00000010u;
+}
+inline void GbSoundData_Sound3::clear_has_wave_index() {
+  _has_bits_[0] &= ~0x00000010u;
+}
+inline void GbSoundData_Sound3::clear_wave_index() {
+  wave_index_ = 0u;
+  clear_has_wave_index();
+}
+inline ::google::protobuf::uint32 GbSoundData_Sound3::wave_index() const {
+  return wave_index_;
+}
+inline void GbSoundData_Sound3::set_wave_index(::google::protobuf::uint32 value) {
+  set_has_wave_index();
+  wave_index_ = value;
+}
+
+// required uint32 out_level = 6;
+inline bool GbSoundData_Sound3::has_out_level() const {
+  return (_has_bits_[0] & 0x00000020u) != 0;
+}
+inline void GbSoundData_Sound3::set_has_out_level() {
+  _has_bits_[0] |= 0x00000020u;
+}
+inline void GbSoundData_Sound3::clear_has_out_level() {
+  _has_bits_[0] &= ~0x00000020u;
+}
+inline void GbSoundData_Sound3::clear_out_level() {
+  out_level_ = 0u;
+  clear_has_out_level();
+}
+inline ::google::protobuf::uint32 GbSoundData_Sound3::out_level() const {
+  return out_level_;
+}
+inline void GbSoundData_Sound3::set_out_level(::google::protobuf::uint32 value) {
+  set_has_out_level();
+  out_level_ = value;
+}
+
+// required bytes wave_pattern = 7;
+inline bool GbSoundData_Sound3::has_wave_pattern() const {
+  return (_has_bits_[0] & 0x00000040u) != 0;
+}
+inline void GbSoundData_Sound3::set_has_wave_pattern() {
+  _has_bits_[0] |= 0x00000040u;
+}
+inline void GbSoundData_Sound3::clear_has_wave_pattern() {
+  _has_bits_[0] &= ~0x00000040u;
+}
+inline void GbSoundData_Sound3::clear_wave_pattern() {
+  if (wave_pattern_ != &::google::protobuf::internal::kEmptyString) {
+    wave_pattern_->clear();
+  }
+  clear_has_wave_pattern();
+}
+inline const ::std::string& GbSoundData_Sound3::wave_pattern() const {
+  return *wave_pattern_;
+}
+inline void GbSoundData_Sound3::set_wave_pattern(const ::std::string& value) {
+  set_has_wave_pattern();
+  if (wave_pattern_ == &::google::protobuf::internal::kEmptyString) {
+    wave_pattern_ = new ::std::string;
+  }
+  wave_pattern_->assign(value);
+}
+inline void GbSoundData_Sound3::set_wave_pattern(const char* value) {
+  set_has_wave_pattern();
+  if (wave_pattern_ == &::google::protobuf::internal::kEmptyString) {
+    wave_pattern_ = new ::std::string;
+  }
+  wave_pattern_->assign(value);
+}
+inline void GbSoundData_Sound3::set_wave_pattern(const void* value, size_t size) {
+  set_has_wave_pattern();
+  if (wave_pattern_ == &::google::protobuf::internal::kEmptyString) {
+    wave_pattern_ = new ::std::string;
+  }
+  wave_pattern_->assign(reinterpret_cast<const char*>(value), size);
+}
+inline ::std::string* GbSoundData_Sound3::mutable_wave_pattern() {
+  set_has_wave_pattern();
+  if (wave_pattern_ == &::google::protobuf::internal::kEmptyString) {
+    wave_pattern_ = new ::std::string;
+  }
+  return wave_pattern_;
+}
+inline ::std::string* GbSoundData_Sound3::release_wave_pattern() {
+  clear_has_wave_pattern();
+  if (wave_pattern_ == &::google::protobuf::internal::kEmptyString) {
+    return NULL;
+  } else {
+    ::std::string* temp = wave_pattern_;
+    wave_pattern_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
+    return temp;
+  }
+}
+
+// -------------------------------------------------------------------
+
 // GbSoundData
 
 // required double excess_samples = 1;
   return temp;
 }
 
+// required .GbSoundData.Sound3 sound_3 = 4;
+inline bool GbSoundData::has_sound_3() const {
+  return (_has_bits_[0] & 0x00000008u) != 0;
+}
+inline void GbSoundData::set_has_sound_3() {
+  _has_bits_[0] |= 0x00000008u;
+}
+inline void GbSoundData::clear_has_sound_3() {
+  _has_bits_[0] &= ~0x00000008u;
+}
+inline void GbSoundData::clear_sound_3() {
+  if (sound_3_ != NULL) sound_3_->::GbSoundData_Sound3::Clear();
+  clear_has_sound_3();
+}
+inline const ::GbSoundData_Sound3& GbSoundData::sound_3() const {
+  return sound_3_ != NULL ? *sound_3_ : *default_instance_->sound_3_;
+}
+inline ::GbSoundData_Sound3* GbSoundData::mutable_sound_3() {
+  set_has_sound_3();
+  if (sound_3_ == NULL) sound_3_ = new ::GbSoundData_Sound3;
+  return sound_3_;
+}
+inline ::GbSoundData_Sound3* GbSoundData::release_sound_3() {
+  clear_has_sound_3();
+  ::GbSoundData_Sound3* temp = sound_3_;
+  sound_3_ = NULL;
+  return temp;
+}
+
 // -------------------------------------------------------------------
 
 // GbVideoData

File gb_emulator/gb.proto

View file
 		required double envelope_countdown  = 8;
 	}
 
+	message Sound3
+	{
+		required double gb_frequency        = 1;
+		required double act_frequency       = 2;
+		required double duration            = 3;
+		required double countdown           = 4;
+		required uint32 wave_index          = 5;
+		required uint32 out_level           = 6;
+		required bytes  wave_pattern        = 7;
+	}
+
 	required double excess_samples  = 1;
 	required Sound1 sound_1         = 2;
 	required Sound2 sound_2         = 3;
+	required Sound3 sound_3         = 4;
 }
 
 message GbVideoData

File gb_emulator/gb_sound.cpp

View file
 
 #include <algorithm>
 #include <iostream>
+#include <limits>
 #include <math.h>
 #include <SDL/SDL.h>
 #include <stdexcept>
 using std::clog;
 using std::ios_base;
 using std::min;
+using std::numeric_limits;
 using std::runtime_error;
 using std::string;
 using std::vector;
 	excessSamples_(0),
 	gbFrequency1_(0),
 	gbFrequency2_(0),
+	gbFrequency3_(0),
 	actFrequency1_(0),
 	actFrequency2_(0),
+	actFrequency3_(0),
 	hi1_(false),
 	hi2_(false),
+	duration3_(0),
 	duty1_(1),
 	duty2_(1),
 	countdown1_(0),
 	countdown2_(0),
+	countdown3_(0),
 	sweepShifts_(0),
 	sweepType_(0),
 	sweepStep_(0),
 	envelope1_(0),
 	envelope2_(0),
 	envelopeCountdown1_(0),
-	envelopeCountdown2_(0)
+	envelopeCountdown2_(0),
+	waveIndex3_(0),
+	outLevel3_(0)
 {
+	memset(wavePattern3_, 0, 0x10);
+
 	// Open the device
 	if (!SDL_WasInit(SDL_INIT_AUDIO))
 	{
 	return hi2_ ? amplitude : -amplitude;
 }
 
+int16_t GbSound::sound3()
+{
+	if (countdown3_ <= 0)
+	{
+		// Update the sound parameters if necessary
+		if (!waveIndex3_ && gb_.mem_.ioPorts[NR34] & 0x80)
+		{
+			gb_.mem_.ioPorts[NR34] &= ~0x80;
+
+			// Calculate the tone frequency
+			gbFrequency3_ =
+				(gb_.mem_.ioPorts[NR33] | ((gb_.mem_.ioPorts[NR34] & 0x07) << 8));
+			actFrequency3_ = 131072. / (0x800 - gbFrequency3_);
+
+			// Save the wave pattern
+			memcpy(wavePattern3_, &gb_.mem_.ioPorts[0x30], 0x10);
+
+			// Save the playback duration
+			if (gb_.mem_.ioPorts[NR34] & 0x40)
+			{
+				duration3_ = (256 - gb_.mem_.ioPorts[NR31]) * (1. / 256);
+			}
+			else
+			{
+				duration3_ = numeric_limits<double>::infinity();
+			}
+
+			// Save the output level
+			uint8_t outLevel = (gb_.mem_.ioPorts[NR32] & 0x60) >> 5;
+			if (!outLevel)
+			{
+				// TODO: Fix
+				//outLevel3_ = 8;
+			}
+			else
+			{
+				outLevel3_ = outLevel - 1;
+			}
+
+			waveIndex3_ = 0;
+		}
+		
+		// No sound initialising; check whether anything is playing at all
+		else if (!actFrequency3_ || !(gb_.mem_.ioPorts[NR30] & 0x80) || duration3_ < 0)
+		{
+			gb_.mem_.ioPorts[NR52] &= ~0x04;
+			return 0;
+		}
+
+		// Sound should be playing; increment the index after each sample has had an up/down state
+		else
+		{
+			waveIndex3_ = (waveIndex3_ + 1) % 32;
+		}
+
+		// Set the index into the wave data and reset the countdown if there is any sound to play
+		countdown3_ += 1 / actFrequency3_ / 16 * sampleRate_;
+		duration3_  -= 1 / actFrequency3_ / 16 * sampleRate_;
+	}
+
+	int16_t amplitude;
+	if (!(gb_.mem_.ioPorts[NR51] & 0x44))
+	{
+		gb_.mem_.ioPorts[NR52] &= ~0x04;
+		amplitude = 0;
+	}
+	else
+	{
+		gb_.mem_.ioPorts[NR52] |= 0x04;
+
+		uint8_t sample = wavePattern3_[waveIndex3_ / 2];
+		// Samples are packed two to the byte
+		if (waveIndex3_ % 2)
+		{
+			sample &= 0x0f;
+		}
+		else
+		{
+			sample >>= 4;
+		}
+		// Shift right to adjust the output level
+		sample >>= outLevel3_;
+
+		amplitude = static_cast<int16_t>(0x500 * ((sample - 7.5) / 7.5));
+	}
+
+	--countdown3_;
+	return amplitude;
+}
+
 void GbSound::soundCallback(void *userData, uint8_t *stream, int len)
 {
 	GbSound *parent = static_cast<GbSound *>(userData);
 		int16_t amplitude = 0;
 		amplitude += parent->sound1();
 		amplitude += parent->sound2();
+		amplitude += parent->sound3();
 		actStream[i] = amplitude;
 	}
 }
 
 void GbSound::load(const GbSoundData &data)
 {
+	assert(data.sound_3().wave_pattern().length() == 0x10);
+
 	excessSamples_ = data.excess_samples();
 
 	const GbSoundData::Sound1 &sound1 = data.sound_1();
 	envelope2_ = static_cast<uint8_t>(sound2.envelope());
 	envelopeStep2_ = sound2.envelope_step();
 	envelopeCountdown2_ = sound2.envelope_countdown();
+
+	const GbSoundData::Sound3 &sound3 = data.sound_3();
+	gbFrequency3_ = sound3.gb_frequency();
+	actFrequency3_ = sound3.act_frequency();
+	duration3_ = sound3.duration();
+	countdown3_ = sound3.countdown();
+	waveIndex3_ = static_cast<uint8_t>(sound3.wave_index());
+	outLevel3_ = static_cast<uint8_t>(sound3.out_level());
+	memcpy(wavePattern3_, sound3.wave_pattern().data(), 0x10);
 }
 
 void GbSound::save(GbSoundData &data) const
 	sound2.set_envelope(envelope2_);
 	sound2.set_envelope_step(envelopeStep2_);
 	sound2.set_envelope_countdown(envelopeCountdown2_);
+
+	GbSoundData::Sound3 &sound3 = *data.mutable_sound_3();
+	sound3.set_gb_frequency(gbFrequency3_);
+	sound3.set_act_frequency(actFrequency3_);
+	sound3.set_duration(duration3_);
+	sound3.set_countdown(countdown3_);
+	sound3.set_wave_index(waveIndex3_);
+	sound3.set_out_level(outLevel3_);
+	sound3.set_wave_pattern(wavePattern3_, 0x10);
 }

File gb_emulator/gb_sound.hpp

View file
 	// prevent timing errors
 	double excessSamples_;
 	// Current frequency in GameBoy format
-	double gbFrequency1_, gbFrequency2_;
+	double gbFrequency1_, gbFrequency2_, gbFrequency3_;
 	// Current frequency in Hz
-	double actFrequency1_, actFrequency2_;
+	double actFrequency1_, actFrequency2_, actFrequency3_;
 	// Whether the square wave is currently in the high or low part
 	bool hi1_, hi2_;
+	// Remaining playback duration
+	double duration3_;
 	// Wave pattern duty
 	double duty1_, duty2_;
 	// Number of samples before toggling the high or low part of the square wave
-	double countdown1_, countdown2_;
+	double countdown1_, countdown2_, countdown3_;
 	// Amount the frequency is shifted by at each sweep shift
 	uint8_t sweepShifts_;
 	// Type of shift. 0 = addition, 1 = subtraction
 	double envelopeStep1_, envelopeStep2_;
 	// Number of samples to the next envelope step
 	double envelopeCountdown1_, envelopeCountdown2_;
+	// Current half-byte index into wavePattern3_
+	uint8_t waveIndex3_;
+	// Wave pattern for sound mode 3
+	uint8_t wavePattern3_[0x10];
+	// Output level for sound mode 3 (i.e., number of bits to shift right by)
+	uint8_t outLevel3_;
 
 	// Functions for each of the sound modes. The output is mixed in the main poll() function
 	int16_t sound1();
 	int16_t sound2();
+	int16_t sound3();
 
 	// Sound callback which copies samples from soundBuf_ into the device buffer
 	static void soundCallback(void *userData, uint8_t *stream, int len);