From cc353a47125925ddfd0f16044d7eaff514f40e14 Mon Sep 17 00:00:00 2001 From: Tim Wanders Date: Fri, 1 Nov 2019 14:24:06 +0100 Subject: [PATCH 01/14] [appveyor] fix x64 packaging --- Source/Script/package_zip.cmd | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Source/Script/package_zip.cmd b/Source/Script/package_zip.cmd index a39fab4e4..21761cd0b 100644 --- a/Source/Script/package_zip.cmd +++ b/Source/Script/package_zip.cmd @@ -32,11 +32,11 @@ rd "%base_dir%\Bin\Package" /Q /S > NUL 2>&1 md "%base_dir%\Bin\Package" md "%base_dir%\Bin\Package\Config" md "%base_dir%\Bin\Package\Lang" -md "%base_dir%\Bin\Package\Plugin" -md "%base_dir%\Bin\Package\Plugin\Audio" -md "%base_dir%\Bin\Package\Plugin\GFX" -md "%base_dir%\Bin\Package\Plugin\Input" -md "%base_dir%\Bin\Package\Plugin\RSP" +md "%base_dir%\Bin\Package\Plugin%VSPlatform%" +md "%base_dir%\Bin\Package\Plugin%VSPlatform%\Audio" +md "%base_dir%\Bin\Package\Plugin%VSPlatform%\GFX" +md "%base_dir%\Bin\Package\Plugin%VSPlatform%\Input" +md "%base_dir%\Bin\Package\Plugin%VSPlatform%\RSP" copy "%base_dir%\Bin\Release%VSPlatform%\Project64.exe" "%base_dir%\Bin\Package" copy "%base_dir%\Config\Video.rdb" "%base_dir%\Bin\Package\Config" @@ -46,12 +46,12 @@ copy "%base_dir%\Config\Project64.enh" "%base_dir%\Bin\Package\Config" copy "%base_dir%\Config\Project64.rdb" "%base_dir%\Bin\Package\Config" copy "%base_dir%\Config\Project64.rdx" "%base_dir%\Bin\Package\Config" copy "%base_dir%\Lang\*.pj.Lang" "%base_dir%\Bin\Package\Lang" -copy "%base_dir%\Plugin%VSPlatform%\Audio\Jabo_Dsound.dll" "%base_dir%\Bin\Package\Plugin\Audio" -copy "%base_dir%\Plugin%VSPlatform%\Audio\Project64-Audio.dll" "%base_dir%\Bin\Package\Plugin\Audio" -copy "%base_dir%\Plugin%VSPlatform%\GFX\Jabo_Direct3D8.dll" "%base_dir%\Bin\Package\Plugin\GFX" -copy "%base_dir%\Plugin%VSPlatform%\GFX\Project64-Video.dll" "%base_dir%\Bin\Package\Plugin\GFX" -copy "%base_dir%\Plugin%VSPlatform%\Input\PJ64_NRage.dll" "%base_dir%\Bin\Package\Plugin\Input" -copy "%base_dir%\Plugin%VSPlatform%\RSP\RSP 1.7.dll" "%base_dir%\Bin\Package\Plugin\RSP" +copy "%base_dir%\Plugin%VSPlatform%\Audio\Jabo_Dsound.dll" "%base_dir%\Bin\Package\Plugin%VSPlatform%\Audio" +copy "%base_dir%\Plugin%VSPlatform%\Audio\Project64-Audio.dll" "%base_dir%\Bin\Package\Plugin%VSPlatform%\Audio" +copy "%base_dir%\Plugin%VSPlatform%\GFX\Jabo_Direct3D8.dll" "%base_dir%\Bin\Package\Plugin%VSPlatform%\GFX" +copy "%base_dir%\Plugin%VSPlatform%\GFX\Project64-Video.dll" "%base_dir%\Bin\Package\Plugin%VSPlatform%\GFX" +copy "%base_dir%\Plugin%VSPlatform%\Input\PJ64_NRage.dll" "%base_dir%\Bin\Package\Plugin%VSPlatform%\Input" +copy "%base_dir%\Plugin%VSPlatform%\RSP\RSP 1.7.dll" "%base_dir%\Bin\Package\Plugin%VSPlatform%\RSP" cd %base_dir%\Bin\Package "%zip%" a -tzip -r "%base_dir%\Package\%ZipFileName%" * From 7955cdf04dc1c0eb6dbd2e655a599d533b849bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCrkan=20G=C3=BCll=C3=BC?= <51590667+gurkangullu@users.noreply.github.com> Date: Wed, 6 Nov 2019 21:59:09 +0300 Subject: [PATCH 02/14] Created turkish language file. --- Lang/Turkish.pj.Lang | 1 + 1 file changed, 1 insertion(+) create mode 100644 Lang/Turkish.pj.Lang diff --git a/Lang/Turkish.pj.Lang b/Lang/Turkish.pj.Lang new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Lang/Turkish.pj.Lang @@ -0,0 +1 @@ + From e71598edaf44461895348e8e49a82d170082b390 Mon Sep 17 00:00:00 2001 From: zilmar Date: Sun, 10 Nov 2019 07:04:24 +1030 Subject: [PATCH 03/14] [Project64] make sure m_pDiskInfo is initialized in RomInformation --- .../UserInterface/RomInformationClass.cpp | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Source/Project64/UserInterface/RomInformationClass.cpp b/Source/Project64/UserInterface/RomInformationClass.cpp index f9c81ffcd..60ed9ca5a 100644 --- a/Source/Project64/UserInterface/RomInformationClass.cpp +++ b/Source/Project64/UserInterface/RomInformationClass.cpp @@ -13,11 +13,11 @@ #include RomInformation::RomInformation(const char * RomFile) : -m_DeleteRomInfo(true), -m_DeleteDiskInfo(true), -m_FileName(RomFile ? RomFile : ""), -m_pRomInfo(NULL), -m_pDiskInfo(NULL) + m_DeleteRomInfo(true), + m_DeleteDiskInfo(true), + m_FileName(RomFile ? RomFile : ""), + m_pRomInfo(NULL), + m_pDiskInfo(NULL) { if (m_FileName.length() == 0) { return; } if ((CPath(m_FileName).GetExtension() != "ndd") && (CPath(m_FileName).GetExtension() != "d64")) @@ -43,18 +43,20 @@ m_pDiskInfo(NULL) } RomInformation::RomInformation(CN64Rom * RomInfo) : -m_DeleteRomInfo(false), -m_DeleteDiskInfo(false), -m_FileName(RomInfo ? RomInfo->GetFileName().c_str() : ""), -m_pRomInfo(RomInfo) + m_DeleteRomInfo(false), + m_DeleteDiskInfo(false), + m_FileName(RomInfo ? RomInfo->GetFileName().c_str() : ""), + m_pRomInfo(RomInfo), + m_pDiskInfo(NULL) { } RomInformation::RomInformation(CN64Disk * DiskInfo) : -m_DeleteRomInfo(false), -m_DeleteDiskInfo(false), -m_FileName(DiskInfo ? DiskInfo->GetFileName().c_str() : ""), -m_pDiskInfo(DiskInfo) + m_DeleteRomInfo(false), + m_DeleteDiskInfo(false), + m_FileName(DiskInfo ? DiskInfo->GetFileName().c_str() : ""), + m_pRomInfo(NULL), + m_pDiskInfo(DiskInfo) { } From 8c64c9380d607f3361581e51e60f00249ec62305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCrkan=20G=C3=BCll=C3=BC?= <51590667+gurkangullu@users.noreply.github.com> Date: Sun, 10 Nov 2019 16:59:59 +0300 Subject: [PATCH 04/14] New Turkish translations added. --- Lang/Turkish.pj.Lang | 575 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 575 insertions(+) diff --git a/Lang/Turkish.pj.Lang b/Lang/Turkish.pj.Lang index 8b1378917..e49024bcb 100644 --- a/Lang/Turkish.pj.Lang +++ b/Lang/Turkish.pj.Lang @@ -1 +1,576 @@ +/********************************************************************************* +* Meta Information * +*********************************************************************************/ +//About DLL +#1 # "Turkish" // LANGUAGE ID +#2 # "Gürkan" // Author +#3 # "2.3.2" // Version +#4 # "10 November, 2019" // Date +//About DLL Dialog +#5 # "Mevcut Dil" +#6 # "Yazar" +#7 # "Sürüm" +#8 # "Tarih" +#9 # "Ana Sayfayı Ziyaret Et" +#10 # "ROM Veritabanı (.RDB)" +#11 # "Hile Kodu Dosyası (.CHT)" +#12 # "Genişletilmiş ROM Bilgisi (.RDX)" + +//About INI title +#20 # "Yapılandırma Dosyaları Hakkında" + +/********************************************************************************* +* Menu * +*********************************************************************************/ +//File Menu +#100# "&Dosya" +#101# "&ROM Aç" +#102# "ROM &Bilgisi...." +#103# "Emülasyonu Başlat" +#104# "&Emülasyonu Sonlandır" +#105# "ROM Dizinini Seç..." +#106# "ROM Listesini Yenile" +#107# "Son kullanılan ROM" +#108# "Son kullanılan ROM Dizinleri" +#109# "Ç&ıkış" +#110# "Aç ve Birleştir" + +//System Menu +#120# "&Sistem" +#121# "&Yeniden Başlat" +#122# "&Duraklat" +#123# "Bitmap Oluştur" +#124# "FPS'yi Sınırla" +#125# "&Durumu Kaydet" +#126# "Farklı Kaydet..." +#127# "&Durumu Yüke" +#128# "Yükle..." +#129# "Mevcut durumu kaydet" +#130# "Hileler..." +#131# "Game Shark (GS) Butonu" +#132# "Devam Et" +#133# "&Yazılımsal (Soft) Sıfırlama" +#134# "&Donanımsal (Hard) Sıfırlama" +#135# "Diski &Değiştir" + +//Options Menu +#140# "&Seçenekler" +#141# "&Tam Ekran" +#142# "&Her Zaman &Üstte" +#143# "Grafik Eklentilerini Yapılandır..." +#144# "Ses Eklentilerini Yapılandır..." +#145# "Denetleyici Eklentilerini Yapılandır..." +#146# "RSP Eklentilerini Yapılandır..." +#147# "CPU Kullanımını Göster" +#148# "&Ayarlar..." + +//Debugger Menu +#160# "&Hata Ayıklayıcı" + +//Language Menu +#175# "&Dil" + +//Help Menu +#180# "&Yardım" +#181# "Yapılandırma Dosyaları Hakkında" +#182# "&Project64 Hakkında" +#183# "Destek &Forumu" +#184# "&Ana Sayfa" + +//Current Save Slot menu +#190# "Varsayılan" +#191# "Yuva 1" +#192# "Yuva 2" +#193# "Yuva 3" +#194# "Yuva 4" +#195# "Yuva 5" +#196# "Yuva 6" +#197# "Yuva 7" +#198# "Yuva 8" +#199# "Yuva 9" +#200# "Yuva 10" +#201# "Kayıt Yuvası (%ws) seçildi" + +//Pop up Menu +#210# "Oyunu Oyna" +#211# "ROM Bilgileri" +#212# "Oyun Ayarlarını Düzenle" +#213# "Hileleri Düzenle" +#214# "Grafik Eklentisi" +#215# "Oyunu Disk ile Oyna" + +//Alternate Name to save Slot +#220# "Kayıt Yuvası - Varsayılan" +#221# "Kayıt Yuvası - 1" +#222# "Kayıt Yuvası - 2" +#223# "Kayıt Yuvası - 3" +#224# "Kayıt Yuvası - 4" +#225# "Kayıt Yuvası - 5" +#226# "Kayıt Yuvası - 6" +#227# "Kayıt Yuvası - 7" +#228# "Kayıt Yuvası - 8" +#229# "Kayıt Yuvası - 9" +#230# "Kayıt Yuvası - 10" + +// Menu Descriptions +#250# "Bir N64 ROM imajı aç" +#251# "Yüklenen imaj hakkındaki bilgileri görüntüle" +#252# "Yüklenen ROM imajının emülasyonunu başlat" +#253# "Yüklenen ROM imajının emülasyonunu durdur" +#254# "ROM dizinini seç" +#255# "ROM listesindeki mevcut ROM'ları yenile" +#256# "Bu uygulamadan çık" +#257# "Geçerli ROM imajını yeniden başlat (herhangi bir ayar değişikliğini yeniden yükle)" +#258# "Şu anda çalışan ROM emülasyonunu durdur/başlat" +#259# "Şu anki ekranın bitmap görüntüsünü oluştur" +#260# "FPS'yi N64'ün doğru hızıyla sınırlandır" +#261# "Mevcut sistem durumunu kaydet" +#262# "Mevcut sistem durumunu seçilen bir dosya konumuna kaydet" +#263# "Mevcut sistem durumunu yükle" +#264# "Yüklemek için kayıtlı olan bir sistem durum dosyası seç" +#265# "GameShark hilelerini etkinleştir/devre dışı bırak" +#266# "GameShark tuşu belirli hilelerle kullanılır." +#267# "Emülasyonu pencere modundan tam ekran moduna değiştir." +#268# "Pencereyi diğer tüm pencerelerin üstünde tut" +#269# "Grafik eklentisinin içindeki ayarları değiştir" +#270# "Ses eklentisinin içindeki ayarları değiştir" +#271# "Denetleyici eklentisinin içindeki ayarları değiştir (yani tuşları ayarla)" +#272# "RSP eklentisinin içindeki ayarları değiştir" +#273# "Emülatörün CPU kullanımını farklı kaynaklara ayrılmış olarak göster" +#274# "Bu uygulamanın ayarlarını görüntüle/değiştir" +#275# "Uygulama kılavuzunu görüntüle" +#276# "Uygulamanın SSS bölümünü görüntüle" +#278# "Uygulama ve yazarlar hakkında" +#277# "Destek dosyalarının yazarları hakkında" +#279# "Önceden açılmış olan bu ROM görüntüsünü aç" +#280# "Bu dizini ROM dizini olarak seç" +#281# "Uygulamayı bu dili kullanarak değiştir" +#282# "Kaydedilen durum için bu kaydetme konumunu seçin" +#283# "Seçili oyunu oyna" +#284# "Seçilen oyun hakkında bilgi" +#285# "Seçilen oyun için ayarları düzenle" +#286# "Seçilen oyun için hileleri düzenle" + +/********************************************************************************* +* ROM Browser * +*********************************************************************************/ +//ROM Browser Fields +#300# "Dosya Adı" +#301# "Dahili Ad" +#302# "GoodN64 Adı" +#303# "Durum" +#304# "ROM Boyutu" +#305# "Notlar (çekirdek)" +#306# "Notlar (varsayılan eklentiler)" +#307# "Notlar (kullanıcı)" +#308# "Kartuş ID'si" +#309# "Üretici" +#310# "Ülke" +#311# "Geliştirici" +#312# "CRC1" +#313# "CRC2" +#314# "CIC Yongası" +#315# "Çıkış Tarihi" +#316# "Tür" +#317# "Oyuncular" +#318# "Force Feedback" +#319# "Dosya Formatı" +#321# "Ad" + +//Select ROM +#320# "Geçerli ROM dizinini seç" + +//Messages +#340# "ROM kötü mü? GoodN64 kullanın ve RDB'nin güncel olup olmadığını kontrol edin." + +/********************************************************************************* +* Options * +*********************************************************************************/ +//Options Title +#400# "Ayarlar" + +//Tabs +#401# "Eklentiler" +#402# "Dizinler" +#403# "Seçenekler" +#404# "ROM Seçimi" +#405# "Gelişmiş" +#406# "Genel Ayarlar" +#407# "Kabuk Entegrasyonu" +#408# "Notlar" +#409# "Klavye Kısayolları" +#410# "Durum" +#411# "Recompiler" +#412# "Varsayılan" +#413# "64DD" + +//Plugin Dialog +#420# "Hakkında" +#421# " RSP (Gerçeklik Sinyal İşlemcisi) eklentisi: " +#422# " Video (grafik) eklentisi: " +#423# " Ses eklentisi: " +#424# " Girdi (denetleyici) eklentisi: " +#425# "Grafik YSE" +#426# "Ses YSE" +#427# "** Sistem Eklentisini Kullan **" + +//Directory Dialog +#440# " Eklenti dizini: " +#441# " ROM dizini: " +#442# " N64 yerel kayıt dizini: " +#443# " Kayıtlı durumların dizini: " +#444# " Ekran görüntüsü dizini: " +#445# "ROM’un açık olduğu son klasör" +#446# "Eklenti dizini seçin" +#447# "ROM dizini seçin" +#448# "N64 yerel kayıt dizini seç" +#449# "Kayıtlı durumların dizinini seç" +#450# "Ekran görüntüsü dizini seç" +#451# " Doku paketi dizini: " +#452# "Doku paketi dizini seç" + +//Options (general) Tab +#460# "Pencere etkin değilken emülasyonu durdur" +#461# "ROM yüklenirken tam ekran moduna gir" +#462# "Gelişmiş ayarları gizle" +#463# "Seçilmiş hileleri hatırla" +#464# "ROM çalışırken ekran koruyucuyu devre dışı bırak" +#465# "Ekran hızı" +#466# "Hız göstergesi:" +#467# "Project64'ün zaten çalışıyor olup olmadığını kontrol et" +#468# "Benzersiz Oyun Kayıt Dizini" +#469# "Japon 64DD IPL ROM Yolu:" +#470# "Amerikan 64DD IPL ROM Yolu:" +#471# "Geliştirme 64DD IPL ROM Yolu:" +#472# "Disk Kayıt Türü:" + +//ROM Browser Tab +#480# "Hatırlanan maksimum ROM sayısı (0-10):" +#481# "ROM'lar" +#482# "Hatırlanan maksimum ROM dizini sayısı (0-10):" +#483# "dizinler" +#484# "ROM listeleyicisini kullan" +#485# "Dizin özyinelemesini kullan" +#486# "Kullanılabilir alanlar:" +#487# "Alanların sırası:" +#488# "Ekle ->" +#489# "<- Kaldır" +#490# "Yukarı" +#491# "Aşağı" +#492# "Listeleyiciyi otomatik olarak yenile" + +//Advanced Options +#500# "Bu değişikliklerin çoğu, yeni bir ROM açılana veya mevcut ROM yeniden başlatılıncaya kadar etkili olmaz." +#501# "Çekirdek Varsayılanları" +#502# "CPU çekirdeği stili:" +#503# "Kod işleme yöntemi" +#504# "Varsayılan bellek boyutu:" +#505# "Gelişmiş blok bağlantısı" +#506# "ROM açıldığında emülasyonu başlat" +#507# "RDB ayarlarıyla daima varsayılan ayarları geçersiz kıl" +#508# "Kayıtlı durumları otomatik olarak sıkıştır" +#509# "Hata Ayıklayıcıyı etkinleştir" +#510# "Önbellek" +#511# "PI DMA" +#512# "Başlangıç değiştirildi" +#513# "Belleği koru" +#514# "TLB unmapping" + +//ROM Options +#520# "CPU çekirdeği stili:" +#521# "VI yenileme oranı:" +#522# "Bellek boyutu:" +#523# "Gelişmiş blok bağlantısı" +#524# "Varsayılan kayıt türü:" +#525# "Sayım faktörü:" +#526# "Büyük derleme tamponu" +#527# "TLB kullan" +#528# "Kayıtları önbelleğe alma" +#529# "SI kesmesini geciktirme" +#530# "Hızlı SP" +#531# "Varsayılan" +#532# "RSP ses sinyali" +#533# "Sabit ses zamanlaması" +#534# "Metot arama yöntemi:" +#535# "Özel kod işleme yöntemi" +#536# "Ses kullanarak senkronize et" +#537# "Bayt başına AI sayısı" +#538# "32 bit motor" +#539# "DP kesmesini geciktirme" + +//Core Styles +#540# "Yorumlayıcı" +#541# "Recompiler" +#542# "Çekirdekleri senkronize et" + +//Self Mod Methods +#560# "Yok" +#561# "Önbellek" +#562# "Belleği koru" +#563# "Belleği ve önbelleği kontrol et" +#564# "Belleği ve önbelleği değiştir" +#565# "Bellek ilerlemesini kontrol et" +#566# "Önbellekteki kodu temizle" + +//Function Lookup method +#570# "Fiziksel arama tablosu" +#571# "Sanal arama tablosu" +#572# "Belleği değiştir" + +//RDRAM Size +#580# "4 MB" +#581# "8 MB" + +//Advanced Block Linking +#600# "Açık" +#601# "Kapalı" + +//Save Type +#620# "İlk kullanılan kaydetme türünü kullan" +#621# "4-kbit EEPROM" +#622# "16-kbit EEPROM" +#623# "SRAM" +#624# "Flash RAM" + +//Shell Integration Tab +#640# "Dosya uzantısı ilişkilendirme:" + +//ROM Notes +#660# "ROM durumu:" +#661# "Çekirdek notu:" +#662# "Eklenti notu:" + +// Accelerator Selector +#680# "CPU durumu:" +#681# "Menü öğesi:" +#682# "Geçerli tuşlar:" +#683# "Yeni kısayol tuşu seç:" +#684# "Şu anda atanmış:" +#685# "Ata" +#686# "Kaldır" +#687# "Tümünü Sıfırla" +#688# "Oyun çalışmıyor" +#689# "Oyun çalışıyor" +#690# "Oyun çalışıyor (pencere modu)" +#691# "Oyun çalışıyor (tam ekran)" +#692# "Tuşu Algıla" + +// Frame Rate Option +#700# "Saniyedeki dikey işkesme sinyalleri" +#701# "Saniyedeki listeleri göster" +#702# "Tam hız yüzdesi" + +// Increase speed +#710# "Oyun Hızını Artır" +#711# "Oyun Hızını Azalt" + +//Bottom page buttons +#720# "Sayfayı Sıfırla" +#721# "Tümünü Sıfırla" +#722# "Uygula" +#723# "Kapat" + +//Disk Save Type +#730# "Tam Disk Kopyası" +#731# "Sadece Kayıtlı Alan" + +/********************************************************************************* +* ROM Information * +*********************************************************************************/ +//ROM Info Title +#800# "ROM Bilgileri" + +//ROM Info Text +#801# "ROM adı:" +#802# "Dosya adı:" +#803# "Bölge:" +#804# "ROM boyutu:" +#805# "Kartuş ID'si:" +#806# "Üretici:" +#807# "Ülke:" +#808# "CRC1:" +#809# "CRC2:" +#810# "CIC Yongası:" +#811# "MD5:" + +/********************************************************************************* +* Cheats * +*********************************************************************************/ +//Cheat List +#1000# "Hileler" +#1001# "Hileler:" +#1002# " Notlar: " +#1003# "Tümünü İşaretle" +#1004# "Tümünün İşaretini Kaldır" + +//Add Cheat +#1005# "Hile Ekle" +#1006# "Ad:" +#1007# "Kod:" +#1008# "Ekle" +#1009# "Temizle" +#1010# " Hile Notları: " +#1011# "DB'ye Ekle" + +//Code extension +#1012# "Kod Uzantıları" +#1013# "Lütfen kullanılacak bir değer seçin:" +#1014# "Tamam" +#1015# "İptal" + +//Digital Value +#1016# "Rakam Miktarı" +#1017# "Lütfen bir değer seçin:" +#1018# "&Değer" +#1019# "itibaren" +#1020# "için" +#1021# "&Notlar:" +#1022# "Hile Ekle" +#1023# "Yeni Hile" +#1024# " " +#1025# "Seçenekler:" +#1026# " " + +//Edit Cheat +#1027# "Hile Düzenle" +#1028# "Hile Güncelle" +#1029# "Hile değiştirildi.\n\nGüncellemek ister misiniz?" +#1030# "Hile güncellendi" + +//Cheat Popup Menu +#1040# "Yeni Hile Ekle..." +#1041# "Düzenle" +#1042# "Sil" + +// short-cut editor +#1100# "Kısayolları sıfırla" +#1101# "Kısayolları sıfırlamak istediğinize emin misiniz?\n\nBu işlem geri alınamaz." +#1102# "Dosya Menüsü" +#1103# "Sistem Menüsü" +#1104# "Seçenekler" +#1105# "Yuvaları Kaydet" + +/********************************************************************************* +* Support Window * +*********************************************************************************/ +#1200# "Project64'ü Destekle" +#1201# "Project64, Microsoft Windows tabanlı bir bilgisayarda Nintendo64 video oyun sistemini emüle etmek için tasarlanmış bir yazılım paketidir. Bu, gerçek N64 yazılımını, orijinal donanım sistemindeki gibi oynatmanızı sağlar.\n\nProject64'ten hoşlanıyorsanız ve onu kullanmaktan zevk alıyorsanız, lütfen project64'ü teşekkür olarak veya sürekli olarak iyileştirilme arzusuyla destekleyin.\n\nProject64'ü desteklediyseniz:" +#1202# "Bildirim kodunu giriniz" +#1203# "Project64'ü Destekle" +#1204# "Devam et" +#1205# "Lütfen destek kodunu giriniz" +#1206# "Yanlış destek kodu" +#1207# "Teşekkürler" +#1208# "Kodu giriniz" +#1209# "Lütfen e-postadaki kodu giriniz" +#1210# "Tamam" +#1211# "İptal" + +/********************************************************************************* +* Messages * +*********************************************************************************/ +#2000# "*** CPU DURAKLATILDI ***" +#2001# "CPU Başlatıldı" +#2002# "Program çıkış yapılamayan kalıcı bir döngüye girdi.\nEmülasyon şimdi duracak.\n\nROM'u ve ayarlarını doğrulayın." +#2003# "Bellek ayrılamadı" +#2004# "Varsayılan veya seçilen video eklentisi eksik veya geçersiz.\n\nAyarlar'a girmeniz ve bir video (grafik) eklentisi seçmeniz gerekiyor.\nEklenti klasörünüzde en az bir tane uyumlu eklenti dosyanızın olup olmadığını kontrol edin." +#2005# "Varsayılan veya seçilen ses eklentisi eksik veya geçersiz.\n\nAyarlar'a girmeniz ve bir ses eklentisi seçmeniz gerekiyor.\nEklenti klasörünüzde en az bir tane uyumlu eklenti dosyanızın olup olmadığını kontrol edin." +#2006# "Varsayılan veya seçilen RSP eklentisi eksik veya geçersiz.\n\nAyarlar'a girmeniz ve bir RSP (Gerçeklik Sinyal İşlemcisi) eklentisi seçmeniz gerekiyor.\nEklenti klasörünüzde en az bir tane uyumlu eklenti dosyanızın olup olmadığını kontrol edin." +#2007# "Varsayılan veya seçilen girdi eklentisi eksik veya geçersiz.\n\nAyarlar'a girmeniz ve bir girdi (denetleyici) eklentisi seçmeniz gerekiyor.\nEklenti klasörünüzde en az bir tane uyumlu eklenti dosyanızın olup olmadığını kontrol edin." +#2008# "Eklenti yüklenemedi:" +#2009# "Kelime yüklenemedi.\n\nROM'u ve ayarlarını doğrulayın." +#2010# "Kayıt dosyası açılamadı" +#2011# "EEPROM açılamadı" +#2012# "Flash RAM açılamadı" +#2013# "Mempak açılamadı" +#2014# "Zip dosyası açılamadı.\n\nMuhtemelen zip dosyası bozuk. ROM'u manuel olarak zipten çıkarmayı deneyin." +#2015# "Dosya açma girişimi başarısız oldu." +#2016# "Zip dosyasını açmaya çalışırken hata oluştu." +#2017# "Yüklenen dosya geçerli bir N64 ROM'u gibi görünmüyor.\n\nROM'larınızı GoodN64 ile doğrulayın." +#2018# "Bilinmeyen ülke" +#2019# "Bilinmeyen CIC yongası" +#2020# "Bilinmeyen dosya formatı" +#2021# "Bilinmeyen bellek işlemi\n\nEmülasyon durdu." +#2022# "İşlenmemiş R4300i işlem kodu(opcode)" +#2023# "Eşlenmemiş alandan yürütme.\n\nROM'u ve ayarlarını doğrulayın." +#2024# "Bu kayıtlı durum, çalışan ROM ile eşleşmiyor gibi görünüyor.\n\nDurumlar %100 aynı ROM'lar arasında kaydedilmeli ve yüklenmelidir.\nÖzellikle BÖLGE ve SÜRÜM aynı olmalıdır.\nBu durumu yüklemek, oyunun ve/veya emülatörün çökmesine neden olabilir.\n\nYüklemeye devam etmek istediğinize emin misiniz?" +#2025# "Hata" +#2026# "Telif hakkı dizisi LUT'ta bulunamadı. Oyun artık çalışmayacak." +#2027# "Kopya Koruma Hatası" +#2028# "Bir eklentiyi değiştirmek için Project64'ün çalışan bir ROM'u yeniden başlatması gerekiyor.\nEğer oyundaki yerinizi kaybetmek istemiyorsanız Hayır cevabını verin ve öncelikle mevcut durumu kaydedin.\n\nEklentiler değiştirilip ROM yeniden başlatılsın mı?" +#2029# "Eklentileri Değiştir" +#2030# "Emülasyon sona erdi" +#2031# "Emülasyon başladı" +#2032# "Durum yüklenemedi" +#2033# "Yüklü durum" +#2034# "Kaydedilen mevcut durum" +#2035# "Durum yuvası" +#2036# "İmaj byte değiştirme" +#2037# "N64 imajı seç" +#2038# "Yüklendi" +#2039# "İmaj yükleniyor" +#2040# "Eklentiler başarıyla başlatılmadığından ROM açılamıyor." +#2041# "Bunu gerçekten silmek istediğinize emin misiniz?" +#2042# "Hileyi Sil" +#2043# "Hile adı zaten kullanılıyor." +#2044# "Bu ROM için maksimum hile sınırına ulaştınız." +#2045# "Eklenti başlatılıyor" +#2046# "Menü öğesine atamak için bir sanal anahtar seçmediniz." +#2047# "Bu anahtarı atamak için bir menü öğesi seçmeniz gerekiyor." +#2048# "Kısayol zaten başka bir menü öğesine atanmış." +#2049# "Kaldırılacak kısayol seçilmedi." +#2050# "ROM yüklendi. Emülasyonun başlaması bekleniyor." +#2051# "Project64'ün beta sürümleri sadece üyeler içindir.\n\nEğer www.pj64-emu.com adresinde bir hesabınız varsa, bu hatayı görmemelisiniz!!\nLütfen siteden bize ulaşın." +#2052# "Program Hatası" +#2053# "7z dosyasında dosya adı bulunamadı" +#2054# "Grafik Düşük Seviye Emülasyon" +#2055# "Grafik DSE genel kullanım için değildir!!!\nBunu sadece test yapmak için kullanmanız ve oyun oynamak için kullanmamanız önerilir.\n\nGrafik DSE'ye değiştirilsin mi?" +#2056# "Ses Yüksek Seviye Emülasyon" +#2057# "Ses YSE üçüncü taraf bir eklenti gerektirir !!!\nEğer YSE'yi destekleyen bir üçüncü taraf ses eklentisi kullanmazsanız, ses duyamazsınız.\n\nSes YSE'ye değiştirilsin mi?" +#2058# "Yüklenen dosya geçerli bir 64DD IPL ROM'u gibi görünmüyor.\n\nROM'larınızı GoodN64 ile doğrulayın." +#2059# "Nintendo 64DD Japon IPL ROM'u bulunamadı.\nBu, Japon 64DD imaj görüntülerini oynatmak için gerekir.\n\nLütfen Ayarlar'dan istediğiniz ROM'u seçin." +#2061# "Nintendo 64DD Amerikan IPL ROM'u bulunamadı.\nBu, Amerikan 64DD imaj görüntülerini oynatmak için gerekir.\n\nLütfen Ayarlar'dan istediğiniz ROM'u seçin." +#2062# "Nintendo 64DD Geliştirme IPL ROM'u bulunamadı.\nBu, Geliştirme 64DD imaj görüntülerini oynatmak için gerekir.\n\nLütfen Ayarlar'dan istediğiniz ROM'u seçin." + +/********************************************************************************* +* Android * +*********************************************************************************/ +#3000# "Ayarlar" +#3001# "Yardım/Forum" +#3002# "Sorun Bildir" +#3003# "Hakkında" +#3004# "Son oynanılan" +#3005# "Oyunlar" +#3006# "Oyun Dizini" +#3007# "Taranacak bir klasör seç" +#3008# "Alt dizinleri dahil et" +#3009# "Ana klasör" +#3010# "Dizinler" +#3011# "Dahili bellek" +#3012# "Taranıyor..." +#3013# "Tamam" +#3014# "İptal" +#3015# "Bilgi" +#3016# "Android için Project64" +#3017# "Lisans" +#3018# "Revizyon" +#3019# "Android\u2122 için Project64, project64'ün Windows sürümünün bir bağlantı noktasıdır. Android\u2122 sürümü çoğu N64 oyununu oynatabilir." +#3020# "Project64 Yazarları." +#3021# "Discord" + +//In game menu +#3100# "Ayarlar" +#3101# "Durumu Kaydet" +#3102# "Durumu Yükle" +#3103# "Emülasyonu Sonlandır" +#3104# "Duraklat" +#3105# "Devam et" +#3106# "Oyun Hızı" +#3107# "Mevcut Durum Kaydı..." +#3108# "Otomatik" +#3109# "Yuva" +#3110# "Yeniden başlat" +#3111# "Hata Ayıklama Seçenekleri" +#3112# "Metot Zamanlayıcılarını Sıfırla" +#3113# "Döküm Metodu Zamanlayıcıları" From a72a23117f45d5d522b381679a78ed1a8537e471 Mon Sep 17 00:00:00 2001 From: Kimberly J Ortega Date: Wed, 20 Nov 2019 02:42:12 -0700 Subject: [PATCH 05/14] Update README.md Add development builds, change some wordings, fix grammar, and fix markup. --- README.md | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a485dbbca..277dffa1c 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,34 @@ # Project 64 -Project64 is an N64 emulator for Windows and Android. +Project64 is a N64 emulator for Windows and Android. -## Installation -(note: ROMs will need to be downloaded separately) +## How to use +(Games not included - do not ask for ROMs.) ### Windows -An executable file for the most recent version of Project64 can be downloaded [here](https://www.pj64-emu.com/download/project64-latest). +Installer for the latest stable release: https://www.pj64-emu.com/download/project64-latest Follow the instructions in the setup window to complete the installation. -##### System Requirements -
  • Operating system: Windows XP (or higher)
  • -
  • CPU: Any SSE2 CPU
  • -
  • RAM: 512MB or more
  • -
  • Graphics card: DirectX 9 card or higher
  • - +#### System Requirements +* Operating system: Windows XP (or higher) +* CPU: Any SSE2 CPU +* RAM: 512MB or more +* Graphics card: DirectX 9 card or higher ### Android Project64 is available for free in the Google Play store. The [Project 64 app](https://play.google.com/store/apps/details?id=emu.project64&hl=en&rdid=emu.project64&pli=1) can be downloaded to an Android phone or tablet. Allow the requested permissions on your device as Project64 needs to be able to read your device's storage to read game files, save states, and configuration in order to run. +### Development Builds +Development Builds are based off the latest source at GitHub. This allows you to use the latest changes straight away, tho these changes may not be fully tested and have issues. + +Official buildbot (Windows and Android): https://www.pj64-emu.com/nightly-builds + +AppVeyor (Windows x86/x64): [![Build status](https://ci.appveyor.com/api/projects/status/sbtwyhaexslyhgx3?svg=true +)](https://ci.appveyor.com/project/project64/project64/branch/master) + +Please note: x64 builds are **not** recommended for regular use! They are incomplete and very experimental, and currently _slower_ than 32-bit builds. ### License Project64 is licensed under the From 3fd9760e24e210a463c65fe782cc29f1212ad208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCrkan=20G=C3=BCll=C3=BC?= <51590667+gurkangullu@users.noreply.github.com> Date: Wed, 27 Nov 2019 11:50:20 +0300 Subject: [PATCH 06/14] Character encoding changed to UTF-8 BOM. --- Lang/Turkish.pj.Lang | 1152 +++++++++++++++++++++--------------------- 1 file changed, 576 insertions(+), 576 deletions(-) diff --git a/Lang/Turkish.pj.Lang b/Lang/Turkish.pj.Lang index e49024bcb..fb4cda67e 100644 --- a/Lang/Turkish.pj.Lang +++ b/Lang/Turkish.pj.Lang @@ -1,576 +1,576 @@ -/********************************************************************************* -* Meta Information * -*********************************************************************************/ -//About DLL -#1 # "Turkish" // LANGUAGE ID -#2 # "Gürkan" // Author -#3 # "2.3.2" // Version -#4 # "10 November, 2019" // Date - -//About DLL Dialog -#5 # "Mevcut Dil" -#6 # "Yazar" -#7 # "Sürüm" -#8 # "Tarih" -#9 # "Ana Sayfayı Ziyaret Et" -#10 # "ROM Veritabanı (.RDB)" -#11 # "Hile Kodu Dosyası (.CHT)" -#12 # "Genişletilmiş ROM Bilgisi (.RDX)" - -//About INI title -#20 # "Yapılandırma Dosyaları Hakkında" - -/********************************************************************************* -* Menu * -*********************************************************************************/ -//File Menu -#100# "&Dosya" -#101# "&ROM Aç" -#102# "ROM &Bilgisi...." -#103# "Emülasyonu Başlat" -#104# "&Emülasyonu Sonlandır" -#105# "ROM Dizinini Seç..." -#106# "ROM Listesini Yenile" -#107# "Son kullanılan ROM" -#108# "Son kullanılan ROM Dizinleri" -#109# "Ç&ıkış" -#110# "Aç ve Birleştir" - -//System Menu -#120# "&Sistem" -#121# "&Yeniden Başlat" -#122# "&Duraklat" -#123# "Bitmap Oluştur" -#124# "FPS'yi Sınırla" -#125# "&Durumu Kaydet" -#126# "Farklı Kaydet..." -#127# "&Durumu Yüke" -#128# "Yükle..." -#129# "Mevcut durumu kaydet" -#130# "Hileler..." -#131# "Game Shark (GS) Butonu" -#132# "Devam Et" -#133# "&Yazılımsal (Soft) Sıfırlama" -#134# "&Donanımsal (Hard) Sıfırlama" -#135# "Diski &Değiştir" - -//Options Menu -#140# "&Seçenekler" -#141# "&Tam Ekran" -#142# "&Her Zaman &Üstte" -#143# "Grafik Eklentilerini Yapılandır..." -#144# "Ses Eklentilerini Yapılandır..." -#145# "Denetleyici Eklentilerini Yapılandır..." -#146# "RSP Eklentilerini Yapılandır..." -#147# "CPU Kullanımını Göster" -#148# "&Ayarlar..." - -//Debugger Menu -#160# "&Hata Ayıklayıcı" - -//Language Menu -#175# "&Dil" - -//Help Menu -#180# "&Yardım" -#181# "Yapılandırma Dosyaları Hakkında" -#182# "&Project64 Hakkında" -#183# "Destek &Forumu" -#184# "&Ana Sayfa" - -//Current Save Slot menu -#190# "Varsayılan" -#191# "Yuva 1" -#192# "Yuva 2" -#193# "Yuva 3" -#194# "Yuva 4" -#195# "Yuva 5" -#196# "Yuva 6" -#197# "Yuva 7" -#198# "Yuva 8" -#199# "Yuva 9" -#200# "Yuva 10" -#201# "Kayıt Yuvası (%ws) seçildi" - -//Pop up Menu -#210# "Oyunu Oyna" -#211# "ROM Bilgileri" -#212# "Oyun Ayarlarını Düzenle" -#213# "Hileleri Düzenle" -#214# "Grafik Eklentisi" -#215# "Oyunu Disk ile Oyna" - -//Alternate Name to save Slot -#220# "Kayıt Yuvası - Varsayılan" -#221# "Kayıt Yuvası - 1" -#222# "Kayıt Yuvası - 2" -#223# "Kayıt Yuvası - 3" -#224# "Kayıt Yuvası - 4" -#225# "Kayıt Yuvası - 5" -#226# "Kayıt Yuvası - 6" -#227# "Kayıt Yuvası - 7" -#228# "Kayıt Yuvası - 8" -#229# "Kayıt Yuvası - 9" -#230# "Kayıt Yuvası - 10" - -// Menu Descriptions -#250# "Bir N64 ROM imajı aç" -#251# "Yüklenen imaj hakkındaki bilgileri görüntüle" -#252# "Yüklenen ROM imajının emülasyonunu başlat" -#253# "Yüklenen ROM imajının emülasyonunu durdur" -#254# "ROM dizinini seç" -#255# "ROM listesindeki mevcut ROM'ları yenile" -#256# "Bu uygulamadan çık" -#257# "Geçerli ROM imajını yeniden başlat (herhangi bir ayar değişikliğini yeniden yükle)" -#258# "Şu anda çalışan ROM emülasyonunu durdur/başlat" -#259# "Şu anki ekranın bitmap görüntüsünü oluştur" -#260# "FPS'yi N64'ün doğru hızıyla sınırlandır" -#261# "Mevcut sistem durumunu kaydet" -#262# "Mevcut sistem durumunu seçilen bir dosya konumuna kaydet" -#263# "Mevcut sistem durumunu yükle" -#264# "Yüklemek için kayıtlı olan bir sistem durum dosyası seç" -#265# "GameShark hilelerini etkinleştir/devre dışı bırak" -#266# "GameShark tuşu belirli hilelerle kullanılır." -#267# "Emülasyonu pencere modundan tam ekran moduna değiştir." -#268# "Pencereyi diğer tüm pencerelerin üstünde tut" -#269# "Grafik eklentisinin içindeki ayarları değiştir" -#270# "Ses eklentisinin içindeki ayarları değiştir" -#271# "Denetleyici eklentisinin içindeki ayarları değiştir (yani tuşları ayarla)" -#272# "RSP eklentisinin içindeki ayarları değiştir" -#273# "Emülatörün CPU kullanımını farklı kaynaklara ayrılmış olarak göster" -#274# "Bu uygulamanın ayarlarını görüntüle/değiştir" -#275# "Uygulama kılavuzunu görüntüle" -#276# "Uygulamanın SSS bölümünü görüntüle" -#278# "Uygulama ve yazarlar hakkında" -#277# "Destek dosyalarının yazarları hakkında" -#279# "Önceden açılmış olan bu ROM görüntüsünü aç" -#280# "Bu dizini ROM dizini olarak seç" -#281# "Uygulamayı bu dili kullanarak değiştir" -#282# "Kaydedilen durum için bu kaydetme konumunu seçin" -#283# "Seçili oyunu oyna" -#284# "Seçilen oyun hakkında bilgi" -#285# "Seçilen oyun için ayarları düzenle" -#286# "Seçilen oyun için hileleri düzenle" - -/********************************************************************************* -* ROM Browser * -*********************************************************************************/ -//ROM Browser Fields -#300# "Dosya Adı" -#301# "Dahili Ad" -#302# "GoodN64 Adı" -#303# "Durum" -#304# "ROM Boyutu" -#305# "Notlar (çekirdek)" -#306# "Notlar (varsayılan eklentiler)" -#307# "Notlar (kullanıcı)" -#308# "Kartuş ID'si" -#309# "Üretici" -#310# "Ülke" -#311# "Geliştirici" -#312# "CRC1" -#313# "CRC2" -#314# "CIC Yongası" -#315# "Çıkış Tarihi" -#316# "Tür" -#317# "Oyuncular" -#318# "Force Feedback" -#319# "Dosya Formatı" -#321# "Ad" - -//Select ROM -#320# "Geçerli ROM dizinini seç" - -//Messages -#340# "ROM kötü mü? GoodN64 kullanın ve RDB'nin güncel olup olmadığını kontrol edin." - -/********************************************************************************* -* Options * -*********************************************************************************/ -//Options Title -#400# "Ayarlar" - -//Tabs -#401# "Eklentiler" -#402# "Dizinler" -#403# "Seçenekler" -#404# "ROM Seçimi" -#405# "Gelişmiş" -#406# "Genel Ayarlar" -#407# "Kabuk Entegrasyonu" -#408# "Notlar" -#409# "Klavye Kısayolları" -#410# "Durum" -#411# "Recompiler" -#412# "Varsayılan" -#413# "64DD" - -//Plugin Dialog -#420# "Hakkında" -#421# " RSP (Gerçeklik Sinyal İşlemcisi) eklentisi: " -#422# " Video (grafik) eklentisi: " -#423# " Ses eklentisi: " -#424# " Girdi (denetleyici) eklentisi: " -#425# "Grafik YSE" -#426# "Ses YSE" -#427# "** Sistem Eklentisini Kullan **" - -//Directory Dialog -#440# " Eklenti dizini: " -#441# " ROM dizini: " -#442# " N64 yerel kayıt dizini: " -#443# " Kayıtlı durumların dizini: " -#444# " Ekran görüntüsü dizini: " -#445# "ROM’un açık olduğu son klasör" -#446# "Eklenti dizini seçin" -#447# "ROM dizini seçin" -#448# "N64 yerel kayıt dizini seç" -#449# "Kayıtlı durumların dizinini seç" -#450# "Ekran görüntüsü dizini seç" -#451# " Doku paketi dizini: " -#452# "Doku paketi dizini seç" - -//Options (general) Tab -#460# "Pencere etkin değilken emülasyonu durdur" -#461# "ROM yüklenirken tam ekran moduna gir" -#462# "Gelişmiş ayarları gizle" -#463# "Seçilmiş hileleri hatırla" -#464# "ROM çalışırken ekran koruyucuyu devre dışı bırak" -#465# "Ekran hızı" -#466# "Hız göstergesi:" -#467# "Project64'ün zaten çalışıyor olup olmadığını kontrol et" -#468# "Benzersiz Oyun Kayıt Dizini" -#469# "Japon 64DD IPL ROM Yolu:" -#470# "Amerikan 64DD IPL ROM Yolu:" -#471# "Geliştirme 64DD IPL ROM Yolu:" -#472# "Disk Kayıt Türü:" - -//ROM Browser Tab -#480# "Hatırlanan maksimum ROM sayısı (0-10):" -#481# "ROM'lar" -#482# "Hatırlanan maksimum ROM dizini sayısı (0-10):" -#483# "dizinler" -#484# "ROM listeleyicisini kullan" -#485# "Dizin özyinelemesini kullan" -#486# "Kullanılabilir alanlar:" -#487# "Alanların sırası:" -#488# "Ekle ->" -#489# "<- Kaldır" -#490# "Yukarı" -#491# "Aşağı" -#492# "Listeleyiciyi otomatik olarak yenile" - -//Advanced Options -#500# "Bu değişikliklerin çoğu, yeni bir ROM açılana veya mevcut ROM yeniden başlatılıncaya kadar etkili olmaz." -#501# "Çekirdek Varsayılanları" -#502# "CPU çekirdeği stili:" -#503# "Kod işleme yöntemi" -#504# "Varsayılan bellek boyutu:" -#505# "Gelişmiş blok bağlantısı" -#506# "ROM açıldığında emülasyonu başlat" -#507# "RDB ayarlarıyla daima varsayılan ayarları geçersiz kıl" -#508# "Kayıtlı durumları otomatik olarak sıkıştır" -#509# "Hata Ayıklayıcıyı etkinleştir" -#510# "Önbellek" -#511# "PI DMA" -#512# "Başlangıç değiştirildi" -#513# "Belleği koru" -#514# "TLB unmapping" - -//ROM Options -#520# "CPU çekirdeği stili:" -#521# "VI yenileme oranı:" -#522# "Bellek boyutu:" -#523# "Gelişmiş blok bağlantısı" -#524# "Varsayılan kayıt türü:" -#525# "Sayım faktörü:" -#526# "Büyük derleme tamponu" -#527# "TLB kullan" -#528# "Kayıtları önbelleğe alma" -#529# "SI kesmesini geciktirme" -#530# "Hızlı SP" -#531# "Varsayılan" -#532# "RSP ses sinyali" -#533# "Sabit ses zamanlaması" -#534# "Metot arama yöntemi:" -#535# "Özel kod işleme yöntemi" -#536# "Ses kullanarak senkronize et" -#537# "Bayt başına AI sayısı" -#538# "32 bit motor" -#539# "DP kesmesini geciktirme" - -//Core Styles -#540# "Yorumlayıcı" -#541# "Recompiler" -#542# "Çekirdekleri senkronize et" - -//Self Mod Methods -#560# "Yok" -#561# "Önbellek" -#562# "Belleği koru" -#563# "Belleği ve önbelleği kontrol et" -#564# "Belleği ve önbelleği değiştir" -#565# "Bellek ilerlemesini kontrol et" -#566# "Önbellekteki kodu temizle" - -//Function Lookup method -#570# "Fiziksel arama tablosu" -#571# "Sanal arama tablosu" -#572# "Belleği değiştir" - -//RDRAM Size -#580# "4 MB" -#581# "8 MB" - -//Advanced Block Linking -#600# "Açık" -#601# "Kapalı" - -//Save Type -#620# "İlk kullanılan kaydetme türünü kullan" -#621# "4-kbit EEPROM" -#622# "16-kbit EEPROM" -#623# "SRAM" -#624# "Flash RAM" - -//Shell Integration Tab -#640# "Dosya uzantısı ilişkilendirme:" - -//ROM Notes -#660# "ROM durumu:" -#661# "Çekirdek notu:" -#662# "Eklenti notu:" - -// Accelerator Selector -#680# "CPU durumu:" -#681# "Menü öğesi:" -#682# "Geçerli tuşlar:" -#683# "Yeni kısayol tuşu seç:" -#684# "Şu anda atanmış:" -#685# "Ata" -#686# "Kaldır" -#687# "Tümünü Sıfırla" -#688# "Oyun çalışmıyor" -#689# "Oyun çalışıyor" -#690# "Oyun çalışıyor (pencere modu)" -#691# "Oyun çalışıyor (tam ekran)" -#692# "Tuşu Algıla" - -// Frame Rate Option -#700# "Saniyedeki dikey işkesme sinyalleri" -#701# "Saniyedeki listeleri göster" -#702# "Tam hız yüzdesi" - -// Increase speed -#710# "Oyun Hızını Artır" -#711# "Oyun Hızını Azalt" - -//Bottom page buttons -#720# "Sayfayı Sıfırla" -#721# "Tümünü Sıfırla" -#722# "Uygula" -#723# "Kapat" - -//Disk Save Type -#730# "Tam Disk Kopyası" -#731# "Sadece Kayıtlı Alan" - -/********************************************************************************* -* ROM Information * -*********************************************************************************/ -//ROM Info Title -#800# "ROM Bilgileri" - -//ROM Info Text -#801# "ROM adı:" -#802# "Dosya adı:" -#803# "Bölge:" -#804# "ROM boyutu:" -#805# "Kartuş ID'si:" -#806# "Üretici:" -#807# "Ülke:" -#808# "CRC1:" -#809# "CRC2:" -#810# "CIC Yongası:" -#811# "MD5:" - -/********************************************************************************* -* Cheats * -*********************************************************************************/ -//Cheat List -#1000# "Hileler" -#1001# "Hileler:" -#1002# " Notlar: " -#1003# "Tümünü İşaretle" -#1004# "Tümünün İşaretini Kaldır" - -//Add Cheat -#1005# "Hile Ekle" -#1006# "Ad:" -#1007# "Kod:" -#1008# "Ekle" -#1009# "Temizle" -#1010# " Hile Notları: " -#1011# "DB'ye Ekle" - -//Code extension -#1012# "Kod Uzantıları" -#1013# "Lütfen kullanılacak bir değer seçin:" -#1014# "Tamam" -#1015# "İptal" - -//Digital Value -#1016# "Rakam Miktarı" -#1017# "Lütfen bir değer seçin:" -#1018# "&Değer" -#1019# "itibaren" -#1020# "için" -#1021# "&Notlar:" -#1022# "Hile Ekle" -#1023# "Yeni Hile" -#1024# " " -#1025# "Seçenekler:" -#1026# " " - -//Edit Cheat -#1027# "Hile Düzenle" -#1028# "Hile Güncelle" -#1029# "Hile değiştirildi.\n\nGüncellemek ister misiniz?" -#1030# "Hile güncellendi" - -//Cheat Popup Menu -#1040# "Yeni Hile Ekle..." -#1041# "Düzenle" -#1042# "Sil" - -// short-cut editor -#1100# "Kısayolları sıfırla" -#1101# "Kısayolları sıfırlamak istediğinize emin misiniz?\n\nBu işlem geri alınamaz." -#1102# "Dosya Menüsü" -#1103# "Sistem Menüsü" -#1104# "Seçenekler" -#1105# "Yuvaları Kaydet" - -/********************************************************************************* -* Support Window * -*********************************************************************************/ -#1200# "Project64'ü Destekle" -#1201# "Project64, Microsoft Windows tabanlı bir bilgisayarda Nintendo64 video oyun sistemini emüle etmek için tasarlanmış bir yazılım paketidir. Bu, gerçek N64 yazılımını, orijinal donanım sistemindeki gibi oynatmanızı sağlar.\n\nProject64'ten hoşlanıyorsanız ve onu kullanmaktan zevk alıyorsanız, lütfen project64'ü teşekkür olarak veya sürekli olarak iyileştirilme arzusuyla destekleyin.\n\nProject64'ü desteklediyseniz:" -#1202# "Bildirim kodunu giriniz" -#1203# "Project64'ü Destekle" -#1204# "Devam et" -#1205# "Lütfen destek kodunu giriniz" -#1206# "Yanlış destek kodu" -#1207# "Teşekkürler" -#1208# "Kodu giriniz" -#1209# "Lütfen e-postadaki kodu giriniz" -#1210# "Tamam" -#1211# "İptal" - -/********************************************************************************* -* Messages * -*********************************************************************************/ -#2000# "*** CPU DURAKLATILDI ***" -#2001# "CPU Başlatıldı" -#2002# "Program çıkış yapılamayan kalıcı bir döngüye girdi.\nEmülasyon şimdi duracak.\n\nROM'u ve ayarlarını doğrulayın." -#2003# "Bellek ayrılamadı" -#2004# "Varsayılan veya seçilen video eklentisi eksik veya geçersiz.\n\nAyarlar'a girmeniz ve bir video (grafik) eklentisi seçmeniz gerekiyor.\nEklenti klasörünüzde en az bir tane uyumlu eklenti dosyanızın olup olmadığını kontrol edin." -#2005# "Varsayılan veya seçilen ses eklentisi eksik veya geçersiz.\n\nAyarlar'a girmeniz ve bir ses eklentisi seçmeniz gerekiyor.\nEklenti klasörünüzde en az bir tane uyumlu eklenti dosyanızın olup olmadığını kontrol edin." -#2006# "Varsayılan veya seçilen RSP eklentisi eksik veya geçersiz.\n\nAyarlar'a girmeniz ve bir RSP (Gerçeklik Sinyal İşlemcisi) eklentisi seçmeniz gerekiyor.\nEklenti klasörünüzde en az bir tane uyumlu eklenti dosyanızın olup olmadığını kontrol edin." -#2007# "Varsayılan veya seçilen girdi eklentisi eksik veya geçersiz.\n\nAyarlar'a girmeniz ve bir girdi (denetleyici) eklentisi seçmeniz gerekiyor.\nEklenti klasörünüzde en az bir tane uyumlu eklenti dosyanızın olup olmadığını kontrol edin." -#2008# "Eklenti yüklenemedi:" -#2009# "Kelime yüklenemedi.\n\nROM'u ve ayarlarını doğrulayın." -#2010# "Kayıt dosyası açılamadı" -#2011# "EEPROM açılamadı" -#2012# "Flash RAM açılamadı" -#2013# "Mempak açılamadı" -#2014# "Zip dosyası açılamadı.\n\nMuhtemelen zip dosyası bozuk. ROM'u manuel olarak zipten çıkarmayı deneyin." -#2015# "Dosya açma girişimi başarısız oldu." -#2016# "Zip dosyasını açmaya çalışırken hata oluştu." -#2017# "Yüklenen dosya geçerli bir N64 ROM'u gibi görünmüyor.\n\nROM'larınızı GoodN64 ile doğrulayın." -#2018# "Bilinmeyen ülke" -#2019# "Bilinmeyen CIC yongası" -#2020# "Bilinmeyen dosya formatı" -#2021# "Bilinmeyen bellek işlemi\n\nEmülasyon durdu." -#2022# "İşlenmemiş R4300i işlem kodu(opcode)" -#2023# "Eşlenmemiş alandan yürütme.\n\nROM'u ve ayarlarını doğrulayın." -#2024# "Bu kayıtlı durum, çalışan ROM ile eşleşmiyor gibi görünüyor.\n\nDurumlar %100 aynı ROM'lar arasında kaydedilmeli ve yüklenmelidir.\nÖzellikle BÖLGE ve SÜRÜM aynı olmalıdır.\nBu durumu yüklemek, oyunun ve/veya emülatörün çökmesine neden olabilir.\n\nYüklemeye devam etmek istediğinize emin misiniz?" -#2025# "Hata" -#2026# "Telif hakkı dizisi LUT'ta bulunamadı. Oyun artık çalışmayacak." -#2027# "Kopya Koruma Hatası" -#2028# "Bir eklentiyi değiştirmek için Project64'ün çalışan bir ROM'u yeniden başlatması gerekiyor.\nEğer oyundaki yerinizi kaybetmek istemiyorsanız Hayır cevabını verin ve öncelikle mevcut durumu kaydedin.\n\nEklentiler değiştirilip ROM yeniden başlatılsın mı?" -#2029# "Eklentileri Değiştir" -#2030# "Emülasyon sona erdi" -#2031# "Emülasyon başladı" -#2032# "Durum yüklenemedi" -#2033# "Yüklü durum" -#2034# "Kaydedilen mevcut durum" -#2035# "Durum yuvası" -#2036# "İmaj byte değiştirme" -#2037# "N64 imajı seç" -#2038# "Yüklendi" -#2039# "İmaj yükleniyor" -#2040# "Eklentiler başarıyla başlatılmadığından ROM açılamıyor." -#2041# "Bunu gerçekten silmek istediğinize emin misiniz?" -#2042# "Hileyi Sil" -#2043# "Hile adı zaten kullanılıyor." -#2044# "Bu ROM için maksimum hile sınırına ulaştınız." -#2045# "Eklenti başlatılıyor" -#2046# "Menü öğesine atamak için bir sanal anahtar seçmediniz." -#2047# "Bu anahtarı atamak için bir menü öğesi seçmeniz gerekiyor." -#2048# "Kısayol zaten başka bir menü öğesine atanmış." -#2049# "Kaldırılacak kısayol seçilmedi." -#2050# "ROM yüklendi. Emülasyonun başlaması bekleniyor." -#2051# "Project64'ün beta sürümleri sadece üyeler içindir.\n\nEğer www.pj64-emu.com adresinde bir hesabınız varsa, bu hatayı görmemelisiniz!!\nLütfen siteden bize ulaşın." -#2052# "Program Hatası" -#2053# "7z dosyasında dosya adı bulunamadı" -#2054# "Grafik Düşük Seviye Emülasyon" -#2055# "Grafik DSE genel kullanım için değildir!!!\nBunu sadece test yapmak için kullanmanız ve oyun oynamak için kullanmamanız önerilir.\n\nGrafik DSE'ye değiştirilsin mi?" -#2056# "Ses Yüksek Seviye Emülasyon" -#2057# "Ses YSE üçüncü taraf bir eklenti gerektirir !!!\nEğer YSE'yi destekleyen bir üçüncü taraf ses eklentisi kullanmazsanız, ses duyamazsınız.\n\nSes YSE'ye değiştirilsin mi?" -#2058# "Yüklenen dosya geçerli bir 64DD IPL ROM'u gibi görünmüyor.\n\nROM'larınızı GoodN64 ile doğrulayın." -#2059# "Nintendo 64DD Japon IPL ROM'u bulunamadı.\nBu, Japon 64DD imaj görüntülerini oynatmak için gerekir.\n\nLütfen Ayarlar'dan istediğiniz ROM'u seçin." -#2061# "Nintendo 64DD Amerikan IPL ROM'u bulunamadı.\nBu, Amerikan 64DD imaj görüntülerini oynatmak için gerekir.\n\nLütfen Ayarlar'dan istediğiniz ROM'u seçin." -#2062# "Nintendo 64DD Geliştirme IPL ROM'u bulunamadı.\nBu, Geliştirme 64DD imaj görüntülerini oynatmak için gerekir.\n\nLütfen Ayarlar'dan istediğiniz ROM'u seçin." - -/********************************************************************************* -* Android * -*********************************************************************************/ -#3000# "Ayarlar" -#3001# "Yardım/Forum" -#3002# "Sorun Bildir" -#3003# "Hakkında" -#3004# "Son oynanılan" -#3005# "Oyunlar" -#3006# "Oyun Dizini" -#3007# "Taranacak bir klasör seç" -#3008# "Alt dizinleri dahil et" -#3009# "Ana klasör" -#3010# "Dizinler" -#3011# "Dahili bellek" -#3012# "Taranıyor..." -#3013# "Tamam" -#3014# "İptal" -#3015# "Bilgi" -#3016# "Android için Project64" -#3017# "Lisans" -#3018# "Revizyon" -#3019# "Android\u2122 için Project64, project64'ün Windows sürümünün bir bağlantı noktasıdır. Android\u2122 sürümü çoğu N64 oyununu oynatabilir." -#3020# "Project64 Yazarları." -#3021# "Discord" - -//In game menu -#3100# "Ayarlar" -#3101# "Durumu Kaydet" -#3102# "Durumu Yükle" -#3103# "Emülasyonu Sonlandır" -#3104# "Duraklat" -#3105# "Devam et" -#3106# "Oyun Hızı" -#3107# "Mevcut Durum Kaydı..." -#3108# "Otomatik" -#3109# "Yuva" -#3110# "Yeniden başlat" -#3111# "Hata Ayıklama Seçenekleri" -#3112# "Metot Zamanlayıcılarını Sıfırla" -#3113# "Döküm Metodu Zamanlayıcıları" +/********************************************************************************* +* Meta Information * +*********************************************************************************/ +//About DLL +#1 # "Turkish" // LANGUAGE ID +#2 # "Gürkan" // Author +#3 # "2.3.2" // Version +#4 # "10 November, 2019" // Date + +//About DLL Dialog +#5 # "Mevcut Dil" +#6 # "Yazar" +#7 # "Sürüm" +#8 # "Tarih" +#9 # "Ana Sayfayı Ziyaret Et" +#10 # "ROM Veritabanı (.RDB)" +#11 # "Hile Kodu Dosyası (.CHT)" +#12 # "Genişletilmiş ROM Bilgisi (.RDX)" + +//About INI title +#20 # "Yapılandırma Dosyaları Hakkında" + +/********************************************************************************* +* Menu * +*********************************************************************************/ +//File Menu +#100# "&Dosya" +#101# "&ROM Aç" +#102# "ROM &Bilgisi...." +#103# "Emülasyonu Başlat" +#104# "&Emülasyonu Sonlandır" +#105# "ROM Dizinini Seç..." +#106# "ROM Listesini Yenile" +#107# "Son kullanılan ROM" +#108# "Son kullanılan ROM Dizinleri" +#109# "Ç&ıkış" +#110# "Aç ve Birleştir" + +//System Menu +#120# "&Sistem" +#121# "&Yeniden Başlat" +#122# "&Duraklat" +#123# "Bitmap Oluştur" +#124# "FPS'yi Sınırla" +#125# "&Durumu Kaydet" +#126# "Farklı Kaydet..." +#127# "&Durumu Yüke" +#128# "Yükle..." +#129# "Mevcut durumu kaydet" +#130# "Hileler..." +#131# "Game Shark (GS) Butonu" +#132# "Devam Et" +#133# "&Yazılımsal (Soft) Sıfırlama" +#134# "&Donanımsal (Hard) Sıfırlama" +#135# "Diski &Değiştir" + +//Options Menu +#140# "&Seçenekler" +#141# "&Tam Ekran" +#142# "&Her Zaman &Üstte" +#143# "Grafik Eklentilerini Yapılandır..." +#144# "Ses Eklentilerini Yapılandır..." +#145# "Denetleyici Eklentilerini Yapılandır..." +#146# "RSP Eklentilerini Yapılandır..." +#147# "CPU Kullanımını Göster" +#148# "&Ayarlar..." + +//Debugger Menu +#160# "&Hata Ayıklayıcı" + +//Language Menu +#175# "&Dil" + +//Help Menu +#180# "&Yardım" +#181# "Yapılandırma Dosyaları Hakkında" +#182# "&Project64 Hakkında" +#183# "Destek &Forumu" +#184# "&Ana Sayfa" + +//Current Save Slot menu +#190# "Varsayılan" +#191# "Yuva 1" +#192# "Yuva 2" +#193# "Yuva 3" +#194# "Yuva 4" +#195# "Yuva 5" +#196# "Yuva 6" +#197# "Yuva 7" +#198# "Yuva 8" +#199# "Yuva 9" +#200# "Yuva 10" +#201# "Kayıt Yuvası (%ws) seçildi" + +//Pop up Menu +#210# "Oyunu Oyna" +#211# "ROM Bilgileri" +#212# "Oyun Ayarlarını Düzenle" +#213# "Hileleri Düzenle" +#214# "Grafik Eklentisi" +#215# "Oyunu Disk ile Oyna" + +//Alternate Name to save Slot +#220# "Kayıt Yuvası - Varsayılan" +#221# "Kayıt Yuvası - 1" +#222# "Kayıt Yuvası - 2" +#223# "Kayıt Yuvası - 3" +#224# "Kayıt Yuvası - 4" +#225# "Kayıt Yuvası - 5" +#226# "Kayıt Yuvası - 6" +#227# "Kayıt Yuvası - 7" +#228# "Kayıt Yuvası - 8" +#229# "Kayıt Yuvası - 9" +#230# "Kayıt Yuvası - 10" + +// Menu Descriptions +#250# "Bir N64 ROM imajı aç" +#251# "Yüklenen imaj hakkındaki bilgileri görüntüle" +#252# "Yüklenen ROM imajının emülasyonunu başlat" +#253# "Yüklenen ROM imajının emülasyonunu durdur" +#254# "ROM dizinini seç" +#255# "ROM listesindeki mevcut ROM'ları yenile" +#256# "Bu uygulamadan çık" +#257# "Geçerli ROM imajını yeniden başlat (herhangi bir ayar değişikliğini yeniden yükle)" +#258# "Şu anda çalışan ROM emülasyonunu durdur/başlat" +#259# "Şu anki ekranın bitmap görüntüsünü oluştur" +#260# "FPS'yi N64'ün doğru hızıyla sınırlandır" +#261# "Mevcut sistem durumunu kaydet" +#262# "Mevcut sistem durumunu seçilen bir dosya konumuna kaydet" +#263# "Mevcut sistem durumunu yükle" +#264# "Yüklemek için kayıtlı olan bir sistem durum dosyası seç" +#265# "GameShark hilelerini etkinleştir/devre dışı bırak" +#266# "GameShark tuşu belirli hilelerle kullanılır." +#267# "Emülasyonu pencere modundan tam ekran moduna değiştir." +#268# "Pencereyi diğer tüm pencerelerin üstünde tut" +#269# "Grafik eklentisinin içindeki ayarları değiştir" +#270# "Ses eklentisinin içindeki ayarları değiştir" +#271# "Denetleyici eklentisinin içindeki ayarları değiştir (yani tuşları ayarla)" +#272# "RSP eklentisinin içindeki ayarları değiştir" +#273# "Emülatörün CPU kullanımını farklı kaynaklara ayrılmış olarak göster" +#274# "Bu uygulamanın ayarlarını görüntüle/değiştir" +#275# "Uygulama kılavuzunu görüntüle" +#276# "Uygulamanın SSS bölümünü görüntüle" +#278# "Uygulama ve yazarlar hakkında" +#277# "Destek dosyalarının yazarları hakkında" +#279# "Önceden açılmış olan bu ROM görüntüsünü aç" +#280# "Bu dizini ROM dizini olarak seç" +#281# "Uygulamayı bu dili kullanarak değiştir" +#282# "Kaydedilen durum için bu kaydetme konumunu seçin" +#283# "Seçili oyunu oyna" +#284# "Seçilen oyun hakkında bilgi" +#285# "Seçilen oyun için ayarları düzenle" +#286# "Seçilen oyun için hileleri düzenle" + +/********************************************************************************* +* ROM Browser * +*********************************************************************************/ +//ROM Browser Fields +#300# "Dosya Adı" +#301# "Dahili Ad" +#302# "GoodN64 Adı" +#303# "Durum" +#304# "ROM Boyutu" +#305# "Notlar (çekirdek)" +#306# "Notlar (varsayılan eklentiler)" +#307# "Notlar (kullanıcı)" +#308# "Kartuş ID'si" +#309# "Üretici" +#310# "Ülke" +#311# "Geliştirici" +#312# "CRC1" +#313# "CRC2" +#314# "CIC Yongası" +#315# "Çıkış Tarihi" +#316# "Tür" +#317# "Oyuncular" +#318# "Force Feedback" +#319# "Dosya Formatı" +#321# "Ad" + +//Select ROM +#320# "Geçerli ROM dizinini seç" + +//Messages +#340# "ROM kötü mü? GoodN64 kullanın ve RDB'nin güncel olup olmadığını kontrol edin." + +/********************************************************************************* +* Options * +*********************************************************************************/ +//Options Title +#400# "Ayarlar" + +//Tabs +#401# "Eklentiler" +#402# "Dizinler" +#403# "Seçenekler" +#404# "ROM Seçimi" +#405# "Gelişmiş" +#406# "Genel Ayarlar" +#407# "Kabuk Entegrasyonu" +#408# "Notlar" +#409# "Klavye Kısayolları" +#410# "Durum" +#411# "Recompiler" +#412# "Varsayılan" +#413# "64DD" + +//Plugin Dialog +#420# "Hakkında" +#421# " RSP (Gerçeklik Sinyal İşlemcisi) eklentisi: " +#422# " Video (grafik) eklentisi: " +#423# " Ses eklentisi: " +#424# " Girdi (denetleyici) eklentisi: " +#425# "Grafik YSE" +#426# "Ses YSE" +#427# "** Sistem Eklentisini Kullan **" + +//Directory Dialog +#440# " Eklenti dizini: " +#441# " ROM dizini: " +#442# " N64 yerel kayıt dizini: " +#443# " Kayıtlı durumların dizini: " +#444# " Ekran görüntüsü dizini: " +#445# "ROM’un açık olduğu son klasör" +#446# "Eklenti dizini seçin" +#447# "ROM dizini seçin" +#448# "N64 yerel kayıt dizini seç" +#449# "Kayıtlı durumların dizinini seç" +#450# "Ekran görüntüsü dizini seç" +#451# " Doku paketi dizini: " +#452# "Doku paketi dizini seç" + +//Options (general) Tab +#460# "Pencere etkin değilken emülasyonu durdur" +#461# "ROM yüklenirken tam ekran moduna gir" +#462# "Gelişmiş ayarları gizle" +#463# "Seçilmiş hileleri hatırla" +#464# "ROM çalışırken ekran koruyucuyu devre dışı bırak" +#465# "Ekran hızı" +#466# "Hız göstergesi:" +#467# "Project64'ün zaten çalışıyor olup olmadığını kontrol et" +#468# "Benzersiz Oyun Kayıt Dizini" +#469# "Japon 64DD IPL ROM Yolu:" +#470# "Amerikan 64DD IPL ROM Yolu:" +#471# "Geliştirme 64DD IPL ROM Yolu:" +#472# "Disk Kayıt Türü:" + +//ROM Browser Tab +#480# "Hatırlanan maksimum ROM sayısı (0-10):" +#481# "ROM'lar" +#482# "Hatırlanan maksimum ROM dizini sayısı (0-10):" +#483# "dizinler" +#484# "ROM listeleyicisini kullan" +#485# "Dizin özyinelemesini kullan" +#486# "Kullanılabilir alanlar:" +#487# "Alanların sırası:" +#488# "Ekle ->" +#489# "<- Kaldır" +#490# "Yukarı" +#491# "Aşağı" +#492# "Listeleyiciyi otomatik olarak yenile" + +//Advanced Options +#500# "Bu değişikliklerin çoğu, yeni bir ROM açılana veya mevcut ROM yeniden başlatılıncaya kadar etkili olmaz." +#501# "Çekirdek Varsayılanları" +#502# "CPU çekirdeği stili:" +#503# "Kod işleme yöntemi" +#504# "Varsayılan bellek boyutu:" +#505# "Gelişmiş blok bağlantısı" +#506# "ROM açıldığında emülasyonu başlat" +#507# "RDB ayarlarıyla daima varsayılan ayarları geçersiz kıl" +#508# "Kayıtlı durumları otomatik olarak sıkıştır" +#509# "Hata Ayıklayıcıyı etkinleştir" +#510# "Önbellek" +#511# "PI DMA" +#512# "Başlangıç değiştirildi" +#513# "Belleği koru" +#514# "TLB unmapping" + +//ROM Options +#520# "CPU çekirdeği stili:" +#521# "VI yenileme oranı:" +#522# "Bellek boyutu:" +#523# "Gelişmiş blok bağlantısı" +#524# "Varsayılan kayıt türü:" +#525# "Sayım faktörü:" +#526# "Büyük derleme tamponu" +#527# "TLB kullan" +#528# "Kayıtları önbelleğe alma" +#529# "SI kesmesini geciktirme" +#530# "Hızlı SP" +#531# "Varsayılan" +#532# "RSP ses sinyali" +#533# "Sabit ses zamanlaması" +#534# "Metot arama yöntemi:" +#535# "Özel kod işleme yöntemi" +#536# "Ses kullanarak senkronize et" +#537# "Bayt başına AI sayısı" +#538# "32 bit motor" +#539# "DP kesmesini geciktirme" + +//Core Styles +#540# "Yorumlayıcı" +#541# "Recompiler" +#542# "Çekirdekleri senkronize et" + +//Self Mod Methods +#560# "Yok" +#561# "Önbellek" +#562# "Belleği koru" +#563# "Belleği ve önbelleği kontrol et" +#564# "Belleği ve önbelleği değiştir" +#565# "Bellek ilerlemesini kontrol et" +#566# "Önbellekteki kodu temizle" + +//Function Lookup method +#570# "Fiziksel arama tablosu" +#571# "Sanal arama tablosu" +#572# "Belleği değiştir" + +//RDRAM Size +#580# "4 MB" +#581# "8 MB" + +//Advanced Block Linking +#600# "Açık" +#601# "Kapalı" + +//Save Type +#620# "İlk kullanılan kaydetme türünü kullan" +#621# "4-kbit EEPROM" +#622# "16-kbit EEPROM" +#623# "SRAM" +#624# "Flash RAM" + +//Shell Integration Tab +#640# "Dosya uzantısı ilişkilendirme:" + +//ROM Notes +#660# "ROM durumu:" +#661# "Çekirdek notu:" +#662# "Eklenti notu:" + +// Accelerator Selector +#680# "CPU durumu:" +#681# "Menü öğesi:" +#682# "Geçerli tuşlar:" +#683# "Yeni kısayol tuşu seç:" +#684# "Şu anda atanmış:" +#685# "Ata" +#686# "Kaldır" +#687# "Tümünü Sıfırla" +#688# "Oyun çalışmıyor" +#689# "Oyun çalışıyor" +#690# "Oyun çalışıyor (pencere modu)" +#691# "Oyun çalışıyor (tam ekran)" +#692# "Tuşu Algıla" + +// Frame Rate Option +#700# "Saniyedeki dikey işkesme sinyalleri" +#701# "Saniyedeki listeleri göster" +#702# "Tam hız yüzdesi" + +// Increase speed +#710# "Oyun Hızını Artır" +#711# "Oyun Hızını Azalt" + +//Bottom page buttons +#720# "Sayfayı Sıfırla" +#721# "Tümünü Sıfırla" +#722# "Uygula" +#723# "Kapat" + +//Disk Save Type +#730# "Tam Disk Kopyası" +#731# "Sadece Kayıtlı Alan" + +/********************************************************************************* +* ROM Information * +*********************************************************************************/ +//ROM Info Title +#800# "ROM Bilgileri" + +//ROM Info Text +#801# "ROM adı:" +#802# "Dosya adı:" +#803# "Bölge:" +#804# "ROM boyutu:" +#805# "Kartuş ID'si:" +#806# "Üretici:" +#807# "Ülke:" +#808# "CRC1:" +#809# "CRC2:" +#810# "CIC Yongası:" +#811# "MD5:" + +/********************************************************************************* +* Cheats * +*********************************************************************************/ +//Cheat List +#1000# "Hileler" +#1001# "Hileler:" +#1002# " Notlar: " +#1003# "Tümünü İşaretle" +#1004# "Tümünün İşaretini Kaldır" + +//Add Cheat +#1005# "Hile Ekle" +#1006# "Ad:" +#1007# "Kod:" +#1008# "Ekle" +#1009# "Temizle" +#1010# " Hile Notları: " +#1011# "DB'ye Ekle" + +//Code extension +#1012# "Kod Uzantıları" +#1013# "Lütfen kullanılacak bir değer seçin:" +#1014# "Tamam" +#1015# "İptal" + +//Digital Value +#1016# "Rakam Miktarı" +#1017# "Lütfen bir değer seçin:" +#1018# "&Değer" +#1019# "itibaren" +#1020# "için" +#1021# "&Notlar:" +#1022# "Hile Ekle" +#1023# "Yeni Hile" +#1024# " " +#1025# "Seçenekler:" +#1026# " " + +//Edit Cheat +#1027# "Hile Düzenle" +#1028# "Hile Güncelle" +#1029# "Hile değiştirildi.\n\nGüncellemek ister misiniz?" +#1030# "Hile güncellendi" + +//Cheat Popup Menu +#1040# "Yeni Hile Ekle..." +#1041# "Düzenle" +#1042# "Sil" + +// short-cut editor +#1100# "Kısayolları sıfırla" +#1101# "Kısayolları sıfırlamak istediğinize emin misiniz?\n\nBu işlem geri alınamaz." +#1102# "Dosya Menüsü" +#1103# "Sistem Menüsü" +#1104# "Seçenekler" +#1105# "Yuvaları Kaydet" + +/********************************************************************************* +* Support Window * +*********************************************************************************/ +#1200# "Project64'ü Destekle" +#1201# "Project64, Microsoft Windows tabanlı bir bilgisayarda Nintendo64 video oyun sistemini emüle etmek için tasarlanmış bir yazılım paketidir. Bu, gerçek N64 yazılımını, orijinal donanım sistemindeki gibi oynatmanızı sağlar.\n\nProject64'ten hoşlanıyorsanız ve onu kullanmaktan zevk alıyorsanız, lütfen project64'ü teşekkür olarak veya sürekli olarak iyileştirilme arzusuyla destekleyin.\n\nProject64'ü desteklediyseniz:" +#1202# "Bildirim kodunu giriniz" +#1203# "Project64'ü Destekle" +#1204# "Devam et" +#1205# "Lütfen destek kodunu giriniz" +#1206# "Yanlış destek kodu" +#1207# "Teşekkürler" +#1208# "Kodu giriniz" +#1209# "Lütfen e-postadaki kodu giriniz" +#1210# "Tamam" +#1211# "İptal" + +/********************************************************************************* +* Messages * +*********************************************************************************/ +#2000# "*** CPU DURAKLATILDI ***" +#2001# "CPU Başlatıldı" +#2002# "Program çıkış yapılamayan kalıcı bir döngüye girdi.\nEmülasyon şimdi duracak.\n\nROM'u ve ayarlarını doğrulayın." +#2003# "Bellek ayrılamadı" +#2004# "Varsayılan veya seçilen video eklentisi eksik veya geçersiz.\n\nAyarlar'a girmeniz ve bir video (grafik) eklentisi seçmeniz gerekiyor.\nEklenti klasörünüzde en az bir tane uyumlu eklenti dosyanızın olup olmadığını kontrol edin." +#2005# "Varsayılan veya seçilen ses eklentisi eksik veya geçersiz.\n\nAyarlar'a girmeniz ve bir ses eklentisi seçmeniz gerekiyor.\nEklenti klasörünüzde en az bir tane uyumlu eklenti dosyanızın olup olmadığını kontrol edin." +#2006# "Varsayılan veya seçilen RSP eklentisi eksik veya geçersiz.\n\nAyarlar'a girmeniz ve bir RSP (Gerçeklik Sinyal İşlemcisi) eklentisi seçmeniz gerekiyor.\nEklenti klasörünüzde en az bir tane uyumlu eklenti dosyanızın olup olmadığını kontrol edin." +#2007# "Varsayılan veya seçilen girdi eklentisi eksik veya geçersiz.\n\nAyarlar'a girmeniz ve bir girdi (denetleyici) eklentisi seçmeniz gerekiyor.\nEklenti klasörünüzde en az bir tane uyumlu eklenti dosyanızın olup olmadığını kontrol edin." +#2008# "Eklenti yüklenemedi:" +#2009# "Kelime yüklenemedi.\n\nROM'u ve ayarlarını doğrulayın." +#2010# "Kayıt dosyası açılamadı" +#2011# "EEPROM açılamadı" +#2012# "Flash RAM açılamadı" +#2013# "Mempak açılamadı" +#2014# "Zip dosyası açılamadı.\n\nMuhtemelen zip dosyası bozuk. ROM'u manuel olarak zipten çıkarmayı deneyin." +#2015# "Dosya açma girişimi başarısız oldu." +#2016# "Zip dosyasını açmaya çalışırken hata oluştu." +#2017# "Yüklenen dosya geçerli bir N64 ROM'u gibi görünmüyor.\n\nROM'larınızı GoodN64 ile doğrulayın." +#2018# "Bilinmeyen ülke" +#2019# "Bilinmeyen CIC yongası" +#2020# "Bilinmeyen dosya formatı" +#2021# "Bilinmeyen bellek işlemi\n\nEmülasyon durdu." +#2022# "İşlenmemiş R4300i işlem kodu(opcode)" +#2023# "Eşlenmemiş alandan yürütme.\n\nROM'u ve ayarlarını doğrulayın." +#2024# "Bu kayıtlı durum, çalışan ROM ile eşleşmiyor gibi görünüyor.\n\nDurumlar %100 aynı ROM'lar arasında kaydedilmeli ve yüklenmelidir.\nÖzellikle BÖLGE ve SÜRÜM aynı olmalıdır.\nBu durumu yüklemek, oyunun ve/veya emülatörün çökmesine neden olabilir.\n\nYüklemeye devam etmek istediğinize emin misiniz?" +#2025# "Hata" +#2026# "Telif hakkı dizisi LUT'ta bulunamadı. Oyun artık çalışmayacak." +#2027# "Kopya Koruma Hatası" +#2028# "Bir eklentiyi değiştirmek için Project64'ün çalışan bir ROM'u yeniden başlatması gerekiyor.\nEğer oyundaki yerinizi kaybetmek istemiyorsanız Hayır cevabını verin ve öncelikle mevcut durumu kaydedin.\n\nEklentiler değiştirilip ROM yeniden başlatılsın mı?" +#2029# "Eklentileri Değiştir" +#2030# "Emülasyon sona erdi" +#2031# "Emülasyon başladı" +#2032# "Durum yüklenemedi" +#2033# "Yüklü durum" +#2034# "Kaydedilen mevcut durum" +#2035# "Durum yuvası" +#2036# "İmaj byte değiştirme" +#2037# "N64 imajı seç" +#2038# "Yüklendi" +#2039# "İmaj yükleniyor" +#2040# "Eklentiler başarıyla başlatılmadığından ROM açılamıyor." +#2041# "Bunu gerçekten silmek istediğinize emin misiniz?" +#2042# "Hileyi Sil" +#2043# "Hile adı zaten kullanılıyor." +#2044# "Bu ROM için maksimum hile sınırına ulaştınız." +#2045# "Eklenti başlatılıyor" +#2046# "Menü öğesine atamak için bir sanal anahtar seçmediniz." +#2047# "Bu anahtarı atamak için bir menü öğesi seçmeniz gerekiyor." +#2048# "Kısayol zaten başka bir menü öğesine atanmış." +#2049# "Kaldırılacak kısayol seçilmedi." +#2050# "ROM yüklendi. Emülasyonun başlaması bekleniyor." +#2051# "Project64'ün beta sürümleri sadece üyeler içindir.\n\nEğer www.pj64-emu.com adresinde bir hesabınız varsa, bu hatayı görmemelisiniz!!\nLütfen siteden bize ulaşın." +#2052# "Program Hatası" +#2053# "7z dosyasında dosya adı bulunamadı" +#2054# "Grafik Düşük Seviye Emülasyon" +#2055# "Grafik DSE genel kullanım için değildir!!!\nBunu sadece test yapmak için kullanmanız ve oyun oynamak için kullanmamanız önerilir.\n\nGrafik DSE'ye değiştirilsin mi?" +#2056# "Ses Yüksek Seviye Emülasyon" +#2057# "Ses YSE üçüncü taraf bir eklenti gerektirir !!!\nEğer YSE'yi destekleyen bir üçüncü taraf ses eklentisi kullanmazsanız, ses duyamazsınız.\n\nSes YSE'ye değiştirilsin mi?" +#2058# "Yüklenen dosya geçerli bir 64DD IPL ROM'u gibi görünmüyor.\n\nROM'larınızı GoodN64 ile doğrulayın." +#2059# "Nintendo 64DD Japon IPL ROM'u bulunamadı.\nBu, Japon 64DD imaj görüntülerini oynatmak için gerekir.\n\nLütfen Ayarlar'dan istediğiniz ROM'u seçin." +#2061# "Nintendo 64DD Amerikan IPL ROM'u bulunamadı.\nBu, Amerikan 64DD imaj görüntülerini oynatmak için gerekir.\n\nLütfen Ayarlar'dan istediğiniz ROM'u seçin." +#2062# "Nintendo 64DD Geliştirme IPL ROM'u bulunamadı.\nBu, Geliştirme 64DD imaj görüntülerini oynatmak için gerekir.\n\nLütfen Ayarlar'dan istediğiniz ROM'u seçin." + +/********************************************************************************* +* Android * +*********************************************************************************/ +#3000# "Ayarlar" +#3001# "Yardım/Forum" +#3002# "Sorun Bildir" +#3003# "Hakkında" +#3004# "Son oynanılan" +#3005# "Oyunlar" +#3006# "Oyun Dizini" +#3007# "Taranacak bir klasör seç" +#3008# "Alt dizinleri dahil et" +#3009# "Ana klasör" +#3010# "Dizinler" +#3011# "Dahili bellek" +#3012# "Taranıyor..." +#3013# "Tamam" +#3014# "İptal" +#3015# "Bilgi" +#3016# "Android için Project64" +#3017# "Lisans" +#3018# "Revizyon" +#3019# "Android\u2122 için Project64, project64'ün Windows sürümünün bir bağlantı noktasıdır. Android\u2122 sürümü çoğu N64 oyununu oynatabilir." +#3020# "Project64 Yazarları." +#3021# "Discord" + +//In game menu +#3100# "Ayarlar" +#3101# "Durumu Kaydet" +#3102# "Durumu Yükle" +#3103# "Emülasyonu Sonlandır" +#3104# "Duraklat" +#3105# "Devam et" +#3106# "Oyun Hızı" +#3107# "Mevcut Durum Kaydı..." +#3108# "Otomatik" +#3109# "Yuva" +#3110# "Yeniden başlat" +#3111# "Hata Ayıklama Seçenekleri" +#3112# "Metot Zamanlayıcılarını Sıfırla" +#3113# "Döküm Metodu Zamanlayıcıları" \ No newline at end of file From d3f69997b1e78265fb04a34656a4921bdced7692 Mon Sep 17 00:00:00 2001 From: oddMLan Date: Thu, 28 Nov 2019 17:17:19 -0700 Subject: [PATCH 07/14] [Audio] Move SetTimerResolution() to InitiateAudio Enforces a timer of 1.0ms without conflicting with other plugins that might reset it unknowingly Fixes VI drop when changing settings in GLideN64 --- Source/Project64-audio/AudioMain.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/Project64-audio/AudioMain.cpp b/Source/Project64-audio/AudioMain.cpp index d27782027..e02f07ae4 100644 --- a/Source/Project64-audio/AudioMain.cpp +++ b/Source/Project64-audio/AudioMain.cpp @@ -58,9 +58,7 @@ void PluginInit(void) SetupTrace(); SetupAudioSettings(); StartTrace(); -#ifdef _WIN32 - SetTimerResolution(); -#endif + //SetTimerResolution(); g_PluginInit = true; } @@ -224,6 +222,9 @@ EXPORT int32_t CALL InitiateAudio(AUDIO_INFO Audio_Info) g_SoundDriver->AI_Shutdown(); delete g_SoundDriver; } +#ifdef _WIN32 + SetTimerResolution(); +#endif g_AudioInfo = Audio_Info; #ifdef _WIN32 g_SoundDriver = new DirectSoundDriver; From 5f3a7c288eb167a7869f240baaed8f74aa40ebfb Mon Sep 17 00:00:00 2001 From: oddMLan Date: Thu, 28 Nov 2019 17:18:10 -0700 Subject: [PATCH 08/14] Update .gitignore Ignore git.properties generated after compilation --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index bb8b5980b..28bf983c2 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ Thumbs.db /.vs +/git.properties /Bin/Debug /Bin/Debug64 /Bin/Package From 9cc953ade1efeb8b6ed879ad6fde260e6ee65cee Mon Sep 17 00:00:00 2001 From: Alen Alic <51973334+AceAlen@users.noreply.github.com> Date: Fri, 29 Nov 2019 17:56:09 -0600 Subject: [PATCH 09/14] Project 64 Bosnian Translation Translated by me (AceAlen) --- Lang/Bosnian.pj.Lang | 578 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 578 insertions(+) create mode 100644 Lang/Bosnian.pj.Lang diff --git a/Lang/Bosnian.pj.Lang b/Lang/Bosnian.pj.Lang new file mode 100644 index 000000000..c14dc319b --- /dev/null +++ b/Lang/Bosnian.pj.Lang @@ -0,0 +1,578 @@ +/ *************************************************** ******************************** +* Meta informacije * +**************************************************** ******************************* / +// O DLL-u +# 1 # "Bosanski" // ID JEZIKA +# 2 # "Alen Alic" // Autor +# 3 # "2.3" // Verzija +# 4 # "November, 2019" // Datum + +// O DLL dijalogu +# 5 # "Trenutni jezik" +# 6 # "Autor" +# 7 # "Verzija" +# 8 # "Datum" +# 9 # "Posetite početnu stranicu" +# 10 # "Baza podataka ROM-a (.RDB)" +# 11 # "Datoteka šifre šifre (.CHT)" +# 12 # "Prošireni ROM podaci (.RDX)" + +// O INI naslovu +# 20 # "O konfiguriranju datoteka" + +/ *************************************************** ******************************** +* Meni * +**************************************************** ******************************* / +// Izbornik datoteke +# 100 # "& datoteka" +# 101 # "& Otvori ROM" +# 102 # "ROM i informacije ...." +# 103 # "Pokrenite emulaciju" +# 104 # "& Krajnja emulacija" +# 105 # "Odaberite ROM direktorijum ..." +# 106 # "Osveži listu ROM-a" +# 107 # "Najnoviji ROM" +# 108 # "Najnoviji ROM direktoriji" +# 109 # "E & xit" +# 110 # "Otvori i kombinovano" + + +// Sistemski meni +# 120 # "i sistem" +# 121 # "Poništi" +# 122 # "Pauza" +# 123 # "Generiranje bitmape" +# 124 # "Ograniči FPS" +# 125 # "I sačuvaj državu" +# 126 # "Spremi kao ..." +# 127 # "Stanje opterećenja" +# 128 # "Učitavanje ..." +# 129 # "Trenutna ušteda i tata" +# 130 # "Trikovi ..." +# 131 # "GS dugme" +# 132 # "R & esume" +# 133 # "Meko resetiranje" +# 134 # "& Hard Reset" +# 135 # "Zamjena i disk" + +// Izbornik mogućnosti +# 140 # "Opcije" +# 141 # "i preko cijelog ekrana" +# 142 # "I uvijek u & vrhu" +# 143 # "Konfiguriranje grafičkog dodatka ..." +# 144 # "Konfiguriranje audio dodatka ..." +# 145 # "Konfiguriranje dodatka kontrolera ..." +# 146 # "Konfiguriranje RSP dodatka ..." +# 147 # "Prikaži upotrebu CPU-a" +# 148 # "& postavke ..." + +// Meni za uklanjanje pogrešaka +# 160 # "i ispravljanje pogrešaka" + +// Jezik meni +# 175 # "i jezik" + +// Izbornik pomoći +# 180 # "Pomoć" +# 181 # "O Conf & ig datotekama" +# 182 # "& O projektu64" +# 183 # "Podrška i forum" +# 184 # "i početna stranica" + +// Trenutni izbornik Slot za spremanje +# 190 # "Zadano" +# 191 # "Slot 1" +# 192 # "Slot 2" +# 193 # "Slot 3" +# 194 # "Slot 4" +# 195 # "Slot 5" +# 196 # "Slot 6" +# 197 # "Slot 7" +# 198 # "Slot 8" +# 199 # "Slot 9" +# 200 # "Slot 10" +# 201 # "Odabran je Slot (% ws)" + +// Pojavni meni +# 210 # "Igraj igru" +# 211 # "Informacije o ROM-u" +# 212 # "Uređivanje postavki igre" +# 213 # "Uredi šifre" +# 214 # "Grafički dodatak" +# 215 # "Igraj igru ​​s diskom" + +// Alternativno ime za spremanje mjesta +# 220 # "Spremanje utora - zadano" +# 221 # "Spremite utor - 1" +# 222 # "Spremite utor - 2" +# 223 # "Spremite utor - 3" +# 224 # "Spremite utor - 4" +# 225 # "Spremite utor - 5" +# 226 # "Spremite utor - 6" +# 227 # "Spremite utor - 7" +# 228 # "Spremite utor - 8" +# 229 # "Spremite utor - 9" +# 230 # "Spremite utor - 10" + +// Opisi menija +# 250 # "Otvori N64 ROM sliku" +# 251 # "Prikaži informacije o učitanoj slici" +# 252 # "Pokrenite emulaciju učitane ROM slike" +# 253 # "Zaustavljanje emulacije učitane ROM slike" +# 254 # "Odaberite ROM direktorijum" +# 255 # "Osveži trenutni popis ROM-a u pregledaču ROM-a" +# 256 # "Zatvorite ovu aplikaciju" +# 257 # "Ponovo pokrenite trenutnu ROM sliku (ponovno učitajte sve promjene postavki)" +# 258 # "Pauziranje / nastavak oponašanja trenutnog pokretačkog ROM-a" +# 259 # "Stvaranje bitmap slike trenutnog ekrana" +# 260 # "Ograniči FPS na ispravnu brzinu N64" +# 261 # "Spremanje trenutnog stanja sustava" +# 262 # "Spremanje trenutnog stanja sustava na odabranu lokaciju datoteke" +# 263 # "Učitavanje spremljenog stanja sustava" +# 264 # "Odaberite sačuvanu datoteku stanja sistema za učitavanje" +# 265 # "Omogući / onemogući GameShark cheats" +# 266 # "Gumb GameShark koristi se sa određenim varalicama." +# 267 # "Promjena emulacije iz prozora u režim preko cijelog ekrana." +# 268 # "Neka prozori ostanu iznad svih ostalih prozora" +# 269 # "Promjena postavki unutar grafičkog dodatka" +# 270 # "Promjena postavki unutar audio dodatka" +# 271 # "Promjena postavki unutar dodatka kontrolera (tj. Postavljanje tipki)" +# 272 # "Promjena postavki unutar RSP dodatka" +# 273 # "Prikaži korištenje emulatora CPU-a podijeljeno na različite resurse" +# 274 # "Pogledajte / promijenite postavke za ovu aplikaciju" +# 275 # "Pogledajte priručnik za aplikaciju" +# 276 # "Pogledajte FAQ za aplikaciju" +# 278 # "O aplikaciji i autorima" +# 277 # "O autorima datoteka za podršku" +# 279 # "Otvori prethodno otvorenu ROM sliku" +# 280 # "Odaberite ovaj direktorij kao svoj ROM direktorij" +# 281 # "Promjena aplikacije za upotrebu ovog jezika" +# 282 # "Odaberite ovu lokaciju za spremanje za sačuvano stanje" +# 283 # "Igraj odabranu igru" +# 284 # "Informacije o odabranoj igri" +# 285 # "Uređivanje postavki za odabranu igru" +# 286 # "Uredi varalice za odabranu igru" + +/ *************************************************** ******************************** +* ROM pregledač * +**************************************************** ******************************* / +// Polja preglednika ROM +# 300 # "Naziv datoteke" +# 301 # "Interno ime" +# 302 # "Dobro ime" +# 303 # "Status" +# 304 # "Veličina ROM-a" +# 305 # "Napomene (jezgro)" +# 306 # "Bilješke (zadani dodaci)" +# 307 # "Bilješke (korisnik)" +# 308 # "Cartridge ID" +# 309 # "proizvođač" +# 310 # "zemlja" +# 311 # "programer" +# 312 # "CRC1" +# 313 # "CRC2" +# 314 # "CIC čip" +# 315 # "Datum objavljivanja" +# 316 # "žanr" +# 317 # "Igrači" +# 318 # "Prisilne povratne informacije" +# 319 # "Format datoteke" +# 321 # "Ime" + +// Odaberite ROM +# 320 # "Odaberi trenutni direktorij ROM-a" + +// Poruke +# 340 # "Loš ROM? Upotrijebite GoodN64 i provjerite je li RDB ažuriran." + +/ *************************************************** ******************************** +* Opcije * +**************************************************** ******************************* / +// Opcije naslova +# 400 # "Podešavanja" + +// Kartice +# 401 # "Dodaci" +# 402 # "Katalozi" +# 403 # "Opcije" +# 404 # "Izbor ROM-a" +# 405 # "Napredno" +# 406 # "Opće postavke" +# 407 # "Integracija školjke" +# 408 # "Napomene" +# 409 # "Prečice na tastaturi" +# 410 # "Status" +# 411 # "Repipiler" +# 412 # "Zadane vrednosti" +# 413 # "64DD" + +// Dijalog dodataka +# 420 # "O" +# 421 # "RSP (procesor signala stvarnosti) dodatak:" +# 422 # "Video (grafički) dodatak:" +# 423 # "Audio (zvuk) dodatak:" +# 424 # "Ulazni (regulator) dodatak:" +# 425 # "Grafika HLE" +# 426 # "Audio HLE" +# 427 # "** Koristite sistemski dodatak **" + +// Dijalog direktorija +# 440 # "Imenik dodataka:" +# 441 # "ROM direktorij:" +# 442 # "N64 izvorni spremanje imenika:" +# 443 # "Imenik sačuvanih država:" +# 444 # "Snimak ekrana:" +# 445 # "Zadnja mapa iz koje je ROM otvoren" +# 446 # "Odaberite direktorij dodataka" +# 447 # "Odaberite ROM direktorijum" +# 448 # "Odaberite N64 direktorijum izvornih sprema" +# 449 # "Odabir direktorija spremljenih stanja" +# 450 # "Odaberite direktorij slike ekrana" +# 451 # "Imenik pakiranja teksture:" +# 452 # "Odaberite direktorij paketa teksture" + +// Opcije (općenito) Kartica +# 460 # "Pauziranje emulacije kada prozor nije aktivan" +# 461 # "Uđite u režim preko cijelog zaslona prilikom umetanja ROM-a" +# 462 # "Sakrij napredne postavke" +# 463 # "Zapamti odabrane varalice" +# 464 # "Onemogući čuvar zaslona prilikom pokretanja ROM-a" +# 465 # "Brzina prikaza" +# 466 # "Prikaz brzine:" +# 467 # "Provjeri da li se Project64 već pokreće" +# 468 # "Unique Game Save Directory" +# 469 # "Japanski maloprodajni put 64DD IPL ROM-a:" +# 470 # "Američki maloprodajni put 64DD IPL ROM-a:" +# 471 # "Razvoj 64DD IPL ROM putanje:" +# 472 # "Tip spremanja diska:" + +// Kartica Browser Browser +# 480 # "Maks. Broj zapamćenih ROM-a (0-10):" +# 481 # "ROM-ovi" +# 482 # "Maks. Broj zapamćenih ROM-ova (0-10):" +# 483 # "dirs" +# 484 # "Koristite ROM pretraživač" +# 485 # "Koristi rekurziju direktorija" +# 486 # "Dostupna polja:" +# 487 # "Redosled polja:" +# 488 # "Dodaj ->" +# 489 # "<- Ukloni" +# 490 # "Gore" +# 491 # "Dolje" +# 492 # "Automatski osvježi pretraživač" + +//Napredne opcije +# 500 # "Većina ovih promjena neće stupiti na snagu dok se ne otvori novi ROM ili ne resetira trenutni ROM." +# 501 # "Osnovne zadane postavke" +# 502 # "Jezgra CPU jezgre:" +# 503 # "Self mod metode" +# 504 # "Zadana veličina memorije:" +# 505 # "Napredno povezivanje blokova" +# 506 # "Pokrenite emulaciju kada se otvori ROM" +# 507 # "Uvek nadjačaj zadane postavke sa onima iz RDB-a" +# 508 # "Automatski komprimiranje spremljenih stanja" +# 509 # "Omogući uklanjanje pogrešaka" +# 510 # "Predmemorija" +# 511 # "PI DMA" +# 512 # "Početak promijenjen" +# 513 # "Zaštiti memoriju" +# 514 # "TLB uklanjanje" + +// Opcije ROM-a +# 520 # "Jezgra CPU jezgre:" +# 521 # "VI nivo osvežavanja:" +# 522 # "Veličina memorije:" +# 523 # "Napredno povezivanje blokova" +# 524 # "Podrazumevani tip čuvanja:" +# 525 # "Faktor brojača:" +# 526 # "Veći međuspremnik kompiliranja" +# 527 # "Koristi TLB" +# 528 # "Registriraj predmemoriju" +# 529 # "Odgoda prekida SI" +# 530 # "Brzi SP" +# 531 # "Zadano" +# 532 # "RSP audio signal" +# 533 # "Fiksni vremenski raspored zvuka" +# 534 # "Metoda pretraživanja funkcije:" +# 535 # "Prilagođena self mod metoda" +# 536 # "Sinkronizacija pomoću zvuka" +# 537 # "Broj AI po bajtu" +# 538 # "32-bitni motor" +# 539 # "Odgoda DP prekida" + + +// Osnovni stilovi +# 540 # "Interpreter" +# 541 # "Repipiler" +# 542 # "Sinkroniziranje jezgara" + +// Self Mod metode +# 560 # "Nema" +# 561 # "Predmemorija" +# 562 # "Zaštiti memoriju" +# 563 # "Provjera memorije i predmemorije" +# 564 # "Promjena memorije i predmemorije" +# 565 # "Provjera unaprijed memorije" +# 566 # "Izbriši kod u predmemoriji" + +// Metoda pretraživanja funkcije +# 570 # "Tablica fizičkog pretraživanja" +# 571 # "Virtualna tablica za pretraživanje" +# 572 # "Promenite memoriju" + +// Veličina RDRAM-a +# 580 # "4 MB" +# 581 # "8 MB" + +// Napredno povezivanje blokova +# 600 # "uključeno" +# 601 # "Isključeno" + +// Spremi tip +# 620 # "Koristi prvo korišten tip čuvanja" +# 621 # "4-kbitni EEPROM" +# 622 # "16-kbitni EEPROM" +# 623 # "SRAM" +# 624 # "Flash RAM-a" + +// Sheb Integration Shell +# 640 # "Udruženje za proširenje datoteka:" + +// Bilješke o ROM-u +# 660 # "ROM status:" +# 661 # "Osnovna napomena:" +# 662 # "Napomena o dodatku:" + +// Selektor ubrzivača +# 680 # "CPU stanje:" +# 681 # "Stavka iz menija:" +# 682 # "Trenutni tasteri:" +# 683 # "Odaberite novi prečac:" +# 684 # "Trenutno dodeljeno:" +# 685 # "Dodijeli" +# 686 # "Ukloni" +# 687 # "Poništi sve" +# 688 # "Igra se ne igra" +# 689 # "Igranje" +# 690 # "Igra (prozora)" +# 691 # "Igranje (preko cijelog ekrana)" +# 692 # "Ključ za otkrivanje" + +// Opcija brzine kadrova +# 700 # "Vertikalni prekidi u sekundi" +# 701 # "Prikaži liste u sekundi" +# 702 # "Postotak pune brzine" + +// Povećajte brzinu +# 710 # "Povećajte brzinu igre" +# 711 # "Smanjivanje brzine igre" + +// Dugmi na donjoj stranici +# 720 # "Poništi stranicu" +# 721 # "Poništi sve" +# 722 # "Primjeni" +# 723 # "Zatvori" + +// Disk Save Type +# 730 # "Puna kopija diska" +# 731 # "Samo sačuvaj područje" + +/ *************************************************** ******************************** +* Informacije o ROM-u * +**************************************************** ******************************* / +// Naslov informacije o ROM-u +# 800 # "Informacije o ROM-u" + +// Tekst s informacijama o ROM-u +# 801 # "Naziv ROM:" +# 802 # "Naziv datoteke:" +# 803 # "Lokacija:" +# 804 # "Veličina ROM-a:" +# 805 # "Cartridge ID:" +# 806 # "Proizvođač:" +# 807 # "Zemlja:" +# 808 # "CRC1:" +# 809 # "CRC2:" +# 810 # "CIC čip:" +# 811 # "MD5:" + +/ *************************************************** ******************************** +* Trikovi * +**************************************************** ******************************* / +// Cheat List +# 1000 # "Trikovi" +# 1001 # "Trikovi:" +# 1002 # "Napomene:" +# 1003 # "Označi sve" +# 1004 # "Označi sve" + +// Dodaj Cheat +# 1005 # "Dodaj šifru" +# 1006 # "Ime:" +# 1007 # "Kod:" +# 1008 # "Umetni" +# 1009 # "Obriši" +# 1010 # "Beležnice:" +# 1011 # "Dodaj u DB" + +// Proširenje koda +# 1012 # "Proširenja kodova" +# 1013 # "Molimo odaberite vrijednost koja će se koristiti za:" +# 1014 # "U redu" +# 1015 # "Otkaži" + +// Digitalna vrijednost +# 1016 # "Količina cifre" +# 1017 # "Molimo odaberite vrijednost za:" +# 1018 # "i vrednost" +# 1019 # "od" +# 1020 # "do" +# 1021 # "i napomene:" +# 1022 # "Dodaj šifru" +# 1023 # "Nova prevara" +# 1024 # " " +# 1025 # "Opcije:" +# 1026 # " " + +// Uredi Cheat +# 1027 # "Uredi varalica" +# 1028 # "Ažuriraj šifru" +# 1029 # "Varalica je promijenjena. \ N \ nŽelite li ažurirati?" +# 1030 # "Šifra ažurirana" + +// Cheat Popup Menu +# 1040 # "Dodaj novu šifru ..." +# 1041 # "Uredi" +# 1042 # "Obriši" + +// uređivač prečaca +# 1100 # "Poništi prečice" +# 1101 # "Jeste li sigurni da želite resetirati prečice? \ N \ nOva akcija se ne može poništiti." +# 1102 # "Meni datoteke" +# 1103 # "Sistemski meni" +# 1104 # "Opcije" +# 1105 # "Spremi slotove" + +/ *************************************************** ******************************** +* Prozor za podršku * +**************************************************** ******************************* / +# 1200 # "Projekt podrške64" +# 1201 # "Project64 je softverski paket dizajniran za oponašanje sistema Nintendo64 video igara na računaru sa sistemom Microsoft Windows. To vam omogućuje reprodukciju pravog N64 softvera na gotovo isti način kao što je to slučaj s originalnim hardverskim sistemom. \ N \ nAko vam se sviđa Project64 i izvukli ste neke vrijednosti iz toga, molimo vas da podržite project64 ili kao zahvalnost ili vašu želju da se stalno poboljšava. \ n \ nAko ste podržali project64: " +# 1202 # "Unesite kôd obavijesti" +# 1203 # "Projekt podrške64" +# 1204 # "Nastavi" +# 1205 # "Unesite kod za podršku" +# 1206 # "Netačan kod podrške" +# 1207 # "hvala" +# 1208 # "Unesite kod" +# 1209 # "Unesite kod u e-poštu" +# 1210 # "OK" +# 1211 # "Otkaži" + +/ *************************************************** ******************************** +* Poruke * +**************************************************** ******************************* / +# 2000 # "*** CPU PAUZIRAN ***" +# 2001 # "Nastavljen procesor" +# 2002 # "U stalnoj petlji koja se ne može izaći. \ NEmulacija će se sada zaustaviti. \ N \ nProvjerite ROM i njegove postavke." +# 2003 # "Nije uspela dodeliti memoriju" +# 2004 # "Zadani ili odabrani video dodatak nedostaje ili je nevažeći. \ N \ nTrebate ući u Postavke i odabrati video (grafički) dodatak. \ NProvjerite da li imate najmanje jednu kompatibilnu datoteku dodataka u svojoj mapi dodataka." +# 2005 # "Zadani ili odabrani audio dodatak nedostaje ili je neispravan. \ N \ nTrebate ući u Postavke i odabrati audio (zvučni) dodatak. \ NProverite da li imate mapu jedne kompatibilne datoteke dodataka u svojoj mapi dodataka." +# 2006 # "Zadani ili odabrani RSP dodatak nedostaje ili je nevažeći. \ N \ nTrebate ući u Postavke i odabrati RSP (Reality Signal Processor) dodatak. \ NProvjerite da li imate najmanje jednu kompatibilnu datoteku dodataka u svojoj mapi dodataka. . " +# 2007 # "Zadani ili odabrani ulazni dodatak nedostaje ili je neispravan. \ N \ nTrebate ući u Postavke i odabrati ulazni (regulator) dodatak. \ NProverite da li imate mapu jedne kompatibilne datoteke dodataka u svojoj mapi dodataka." +# 2008 # "Nije uspjelo učitavanje dodatka:" +# 2009 # "Nije uspjelo učitavanje riječi. \ N \ nProvjerite ROM i njegove postavke." +# 2010 # "Otvaranje datoteke za spremanje nije uspjelo" +# 2011 # "Nije uspio otvoriti EEPROM" +# 2012 # "Neuspešno otvaranje flash RAM-a" +# 2013 # "Nije uspelo otvaranje mempak-a" +# 2014 # "Pokušaj otvaranja zip datoteke nije uspio. \ N \ n Vjerojatno oštećena zip datoteka - pokušajte ručno raspakirati ROM." +# 2015 # "Pokušaj otvaranja datoteke nije uspio." +# 2016 # "Došlo je do pogreške prilikom pokušaja otvaranja zip datoteke." +# 2017 # "Datoteka učitana ne čini se valjanim N64 ROM-om. \ N \ nOvjerite svoje ROM-ove s GoodN64." +# 2018 # "Nepoznata zemlja" +# 2019. # "Nepoznati CIC čip" +# 2020 # "Nepoznati format datoteke" +# 2021 # "Nepoznata radnja memorije \ n \ nEmulacija je zaustavljena" +# 2022 # "Neodvršeni R4300i kod kod" +# 2023 # "Izvođenje iz nekarpiranog prostora. \ N \ nProvjerite ROM i njegove postavke." +# 2024 # "Čini se da ovo sačuvano stanje ne odgovara tekućem ROM-u. \ N \ nDržave moraju biti spremljene i učitane između 100% identičnih ROM-ova. \ NPosebno REGION i VERSION moraju biti isti. \ NUmetanje ovog stanja je vjerovatno će prouzrokovati pad igre i / ili emulatora. \ n \ n Jeste li sigurni da želite nastaviti s učitavanjem? " +# 2025 # "Greška" +# 2026 # "Slijed autorskih prava nije pronađen u LUT-u. Igra više neće funkcionirati." +# 2027 # "Neuspjeh u zaštiti od kopiranja" +# 2028 # "Promjena dodatka zahtijeva Project64 za resetiranje tekućeg ROM-a. \ NAko ne želite izgubiti svoje mjesto, odgovorite ne i prvo spremite trenutno stanje. \ N \ nPromijenite dodatke i resetirajte ROM sada?" +# 2029 # "Promjena dodataka" +# 2030 # "Emulacija je završena" +# 2031 # "Emulacija je započela" +# 2032 # "Nije moguće učitati stanje" +# 2033 # "Opterećeno stanje" +# 2034 # "Spremljeno trenutno stanje u" +# 2035 # "Državni utor" +# 2036 # "Slika zamjene bajtova" +# 2037 # "Odabir slike N64" +# 2038 # "Opterećen" +# 2039 # "Učitavanje slike" +# 2040 # "ROM se ne može otvoriti jer se dodaci nisu uspješno inicijalizirali." +# 2041 # "Jeste li sigurni da zaista želite ovo izbrisati?" +# 2042 # "Obriši varalice" +# 2043 # "Naziv varalice se već koristi." +# 2044 # "Dostigli ste maksimalnu količinu varalica za ovaj ROM." +# 2045 # "Dodatak inicijalizaciji" +# 2046 # "Niste odabrali virtualni ključ koji ćete dodijeliti stavci izbornika." +# 2047 # "Morate odabrati stavku menija kojoj ćete dodijeliti ovaj ključ." +# 2048 # "Prečac je već dodijeljen drugoj stavci izbornika." +# 2049 # "Nije odabrana nijedna prečica za uklanjanje." +# 2050 # "ROM učitan. Čeka da se pokrene emulacija." +# 2051 # "beta64 verzije Project64 su samo za članove. \ N \ nAko imate račun na www.pj64-emu.com, ne biste trebali vidjeti ovu pogrešku !! \ nPolite da nas kontaktirate na web mjestu." +# 2052 # "Greška u programu" +# 2053 # "Nije pronađeno ime datoteke u datoteci 7z" +# 2054 # "Grafička emulacija niskog nivoa" +# 2055 # "Grafički LLE nije za opću upotrebu !!! \ nSavjetuje se da ovo koristite samo za testiranje, a ne za igranje igara. \ N \ nPromijenite na grafički LLE?" +# 2056 # "Audio visoka emulacija" +# 2057 # "Audio HLE zahtijeva dodatak treće strane !!! \ nAko ne upotrebljavate audio dodatak treće strane koji podržava HLE, nećete čuti zvuk. \ N \ nPromijenite na audio HLE?" +# 2058 # "Učitana datoteka ne čini se valjanim 64DD IPL ROM-om. \ N \ nOvjerite svoje ROM-ove s GoodN64." +# 2059 # "Nintendo 64DD Japanski maloprodajni IPL ROM nije pronađen. \ NTreba se reproducirati slike diska sa japanskom regijom 64DD. \ N \ n Molimo odaberite željeni ROM u postavkama." +# 2061 # "Nintendo 64DD američki maloprodajni IPL ROM nije pronađen. \ NZatravan je za reprodukciju slika diska američke regije 64DD. \ N \ n Molimo odaberite željeni ROM u postavkama." +# 2062 # "Nintendo 64DD razvojni IPL ROM nije pronađen. \ NZatravan je za reprodukciju slika diska sa razvojem 64DD. \ N \ n Molimo odaberite željeni ROM u postavkama." + +/ *************************************************** ******************************** +* Android * +**************************************************** ******************************* / +# 3000 # "Podešavanja" +# 3001 # "Pomoć / Forum" +# 3002 # "Izveštaj o problemu" +# 3003 # "O" +# 3004 # "Nedavno odigrano" +# 3005 # "Igre" +# 3006 # "Igra Dir" +# 3007 # "Odaberite fasciklu za skeniranje" +# 3008 # "Uključi poddirektoriju" +# 3009 # "Roditeljska mapa" +# 3010 # "Katalozi" +# 3011 # "Interna memorija" +# 3012 # "Skeniranje ..." +# 3013 # "OK" +# 3014 # "Otkaži" +# 3015 # "Informacije" +# 3016 # "Project64 za Android" +# 3017 # "Licenca" +# 3018 # "Revizija" +# 3019 # "Project64 za Android \ u2122 je luka za Windows verziju projekta64. Verzija Android \ u2122 može igrati većinu N64 igara." +# 3020 # "Autori projekta64." +# 3021 # "Razmirica" + +// U meniju igre +# 3100 # "Podešavanja" +# 3101 # "Spremi državu" +# 3102 # "Stanje opterećenja" +# 3103 # "Kraj emulacije" +# 3104 # "Pauza" +# 3105 # "Nastavi" +# 3106 # "Brzina igre" +# 3107 # "Trenutno stanje uštede ..." +# 3108 # "Automatski" +# 3109 # "Slot" +# 3110 # "Poništi" +# 3111 # "Opcije za uklanjanje pogrešaka" +# 3112 # "Resetovanje funkcija vremena" +# 3113 # "Baci funkcija vremena" From 5c2aa06f7c1c989b2d14e262f37a97287893c464 Mon Sep 17 00:00:00 2001 From: shygoo Date: Sat, 30 Nov 2019 11:48:46 -0600 Subject: [PATCH 10/14] [Debugger] Rewrite memory viewer replace the list control with a custom hex editor control add ability to select/copy/paste/delete multiple bytes add byte group size option make window resizable fix DPI-related issues speed up auto-refresh remove option to disable auto-refresh (new control's cpu usage is insignificant) move the dump and search buttons into the context menu change colors of breakpoints to match the command window's highlight CPU read and write targets while stepping move address info into a status bar allow window to open before MMU is initialized add shortcut keys for various actions add "follow pointer" feature add "safe mode" feature add copy gameshark code feature add copy with row/group addresses feature add tabs feature add jump menu for hardware regions fix cartridge ROM addresses not being viewable allow writes to cartridge ROM use thread-safe functions for reading/writing memory --- Source/Project64-core/Settings.cpp | 1 - Source/Project64-core/Settings/SettingsID.h | 1 - Source/Project64/Project64.vcxproj | 4 + Source/Project64/Project64.vcxproj.filters | 12 + .../UserInterface/Debugger/DebugMMU.cpp | 304 +++ .../UserInterface/Debugger/DebugMMU.h | 15 + .../Debugger/Debugger-ViewMemory.cpp | 1749 ++++++++++------- .../Debugger/Debugger-ViewMemory.h | 314 ++- .../UserInterface/Debugger/Debugger.cpp | 190 -- .../UserInterface/Debugger/MemoryScanner.cpp | 6 +- .../UserInterface/Debugger/debugger.h | 8 +- Source/Project64/UserInterface/MainMenu.cpp | 1 - Source/Project64/UserInterface/UIResources.rc | 64 +- .../UserInterface/WTLControls/HexEditCtrl.cpp | 1747 ++++++++++++++++ .../UserInterface/WTLControls/HexEditCtrl.h | 309 +++ Source/Project64/UserInterface/resource.h | 33 +- 16 files changed, 3799 insertions(+), 959 deletions(-) create mode 100644 Source/Project64/UserInterface/Debugger/DebugMMU.cpp create mode 100644 Source/Project64/UserInterface/Debugger/DebugMMU.h create mode 100644 Source/Project64/UserInterface/WTLControls/HexEditCtrl.cpp create mode 100644 Source/Project64/UserInterface/WTLControls/HexEditCtrl.h diff --git a/Source/Project64-core/Settings.cpp b/Source/Project64-core/Settings.cpp index f487df6b7..abaedb785 100644 --- a/Source/Project64-core/Settings.cpp +++ b/Source/Project64-core/Settings.cpp @@ -350,7 +350,6 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory) AddHandler(Debugger_WriteBPExists, new CSettingTypeTempBool(false)); AddHandler(Debugger_ReadBPExists, new CSettingTypeTempBool(false)); AddHandler(Debugger_WaitingForStep, new CSettingTypeTempBool(false)); - AddHandler(Debugger_AutoRefreshMemoryView, new CSettingTypeApplication("Debugger", "Auto Refresh Memory View", true)); AddHandler(Debugger_CPULoggingEnabled, new CSettingTypeApplication("Debugger", "Enable CPU Logging", false)); AddHandler(Debugger_CPULogBufferSize, new CSettingTypeApplication("Debugger", "CPU Log Buffer Size", (uint32_t)1024)); AddHandler(Debugger_ExceptionBreakpoints, new CSettingTypeApplication("Debugger", "Exception Breakpoints", (uint32_t)0)); diff --git a/Source/Project64-core/Settings/SettingsID.h b/Source/Project64-core/Settings/SettingsID.h index 0992da1a2..0ecdd7971 100644 --- a/Source/Project64-core/Settings/SettingsID.h +++ b/Source/Project64-core/Settings/SettingsID.h @@ -260,7 +260,6 @@ enum SettingID Debugger_WriteBPExists, Debugger_ReadBPExists, Debugger_WaitingForStep, - Debugger_AutoRefreshMemoryView, Debugger_CPULoggingEnabled, Debugger_CPULogBufferSize, Debugger_ExceptionBreakpoints, diff --git a/Source/Project64/Project64.vcxproj b/Source/Project64/Project64.vcxproj index 769c032f2..3794474f6 100644 --- a/Source/Project64/Project64.vcxproj +++ b/Source/Project64/Project64.vcxproj @@ -99,6 +99,7 @@ + @@ -131,6 +132,7 @@ + @@ -166,6 +168,7 @@ + @@ -201,6 +204,7 @@ + diff --git a/Source/Project64/Project64.vcxproj.filters b/Source/Project64/Project64.vcxproj.filters index 3c6f1726f..81e4cb585 100644 --- a/Source/Project64/Project64.vcxproj.filters +++ b/Source/Project64/Project64.vcxproj.filters @@ -237,6 +237,12 @@ Source Files\User Interface Source\Settings Source + + Source Files\User Interface Source\WTL Controls Source + + + Source Files\User Interface Source\Debugger Source + @@ -455,6 +461,12 @@ Header Files\User Interface Headers\Settings Header + + Header Files\User Interface Headers\WTL Controls Headers + + + Header Files\User Interface Headers\Debugger Headers + diff --git a/Source/Project64/UserInterface/Debugger/DebugMMU.cpp b/Source/Project64/UserInterface/Debugger/DebugMMU.cpp new file mode 100644 index 000000000..ee817e9b0 --- /dev/null +++ b/Source/Project64/UserInterface/Debugger/DebugMMU.cpp @@ -0,0 +1,304 @@ +#include + +#include "DebugMMU.h" +#include + +uint32_t* CDebugMMU::PAddrWordPtr(uint32_t paddr) +{ + if (g_MMU == NULL) + { + return NULL; + } + + paddr = paddr & ~3; + + // RDRAM & DMEM/IMEM + if ((paddr < g_MMU->RdramSize()) || + (paddr >= 0x04000000 && paddr <= 0x04001FFF)) + { + return (uint32_t*)(g_MMU->Rdram() + paddr); + } + + // 64DD buffer + if (paddr >= 0x05000000 && paddr <= 0x050004FF) + { + // todo + return NULL; + } + + // Cartridge Domain 1 (Address 1) (64DD IPL ROM) + if (paddr >= 0x06000000 && paddr <= 0x06FFFFFF) + { + uint32_t iplRomOffset = paddr - 0x06000000; + + if (g_DDRom != NULL && iplRomOffset < g_DDRom->GetRomSize()) + { + return (uint32_t*)(g_MMU->Rdram() + paddr); + } + return NULL; + } + + // Cartridge Domain 2 (Address 2) (SRAM/FlashRAM) + if (paddr >= 0x08000000 && paddr < 0x08FFFFFF) + { + // stored in a file + return NULL; + } + + // Cartridge ROM + if (paddr >= 0x10000000 && paddr <= 0x15FFFFFF) + { + uint32_t cartRomOffset = paddr - 0x10000000; + if (g_Rom != NULL && cartRomOffset < g_Rom->GetRomSize()) + { + return (uint32_t*)(g_Rom->GetRomAddress() + cartRomOffset); + } + return false; + } + + // PIF ROM + if (paddr >= 0x1FC00000 && paddr <= 0x1FC007BF) + { + return NULL; + } + + // PIF RAM + if (paddr >= 0x1FC007C0 && paddr <= 0x1FC007FF) + { + uint32_t pifRamOffset = paddr - 0x1FC007C0; + return (uint32_t*)(g_MMU->PifRam() + pifRamOffset); + } + + switch (paddr) + { + case 0x03F00000: return &g_Reg->RDRAM_CONFIG_REG; + case 0x03F00004: return &g_Reg->RDRAM_DEVICE_ID_REG; + case 0x03F00008: return &g_Reg->RDRAM_DELAY_REG; + case 0x03F0000C: return &g_Reg->RDRAM_MODE_REG; + case 0x03F00010: return &g_Reg->RDRAM_REF_INTERVAL_REG; + case 0x03F00014: return &g_Reg->RDRAM_REF_ROW_REG; + case 0x03F00018: return &g_Reg->RDRAM_RAS_INTERVAL_REG; + case 0x03F0001C: return &g_Reg->RDRAM_MIN_INTERVAL_REG; + case 0x03F00020: return &g_Reg->RDRAM_ADDR_SELECT_REG; + case 0x03F00024: return &g_Reg->RDRAM_DEVICE_MANUF_REG; + case 0x04040010: return &g_Reg->SP_STATUS_REG; + case 0x04040014: return &g_Reg->SP_DMA_FULL_REG; + case 0x04040018: return &g_Reg->SP_DMA_BUSY_REG; + case 0x0404001C: return &g_Reg->SP_SEMAPHORE_REG; + case 0x04080000: return &g_Reg->SP_PC_REG; + case 0x0410000C: return &g_Reg->DPC_STATUS_REG; + case 0x04100010: return &g_Reg->DPC_CLOCK_REG; + case 0x04100014: return &g_Reg->DPC_BUFBUSY_REG; + case 0x04100018: return &g_Reg->DPC_PIPEBUSY_REG; + case 0x0410001C: return &g_Reg->DPC_TMEM_REG; + case 0x04300000: return &g_Reg->MI_MODE_REG; + case 0x04300004: return &g_Reg->MI_VERSION_REG; + case 0x04300008: return &g_Reg->MI_INTR_REG; + case 0x0430000C: return &g_Reg->MI_INTR_MASK_REG; + case 0x04400000: return &g_Reg->VI_STATUS_REG; + case 0x04400004: return &g_Reg->VI_ORIGIN_REG; + case 0x04400008: return &g_Reg->VI_WIDTH_REG; + case 0x0440000C: return &g_Reg->VI_INTR_REG; + case 0x04400010: return &g_Reg->VI_V_CURRENT_LINE_REG; + case 0x04400014: return &g_Reg->VI_BURST_REG; + case 0x04400018: return &g_Reg->VI_V_SYNC_REG; + case 0x0440001C: return &g_Reg->VI_H_SYNC_REG; + case 0x04400020: return &g_Reg->VI_LEAP_REG; + case 0x04400024: return &g_Reg->VI_H_START_REG; + case 0x04400028: return &g_Reg->VI_V_START_REG; + case 0x0440002C: return &g_Reg->VI_V_BURST_REG; + case 0x04400030: return &g_Reg->VI_X_SCALE_REG; + case 0x04400034: return &g_Reg->VI_Y_SCALE_REG; + case 0x04600000: return &g_Reg->PI_DRAM_ADDR_REG; + case 0x04600004: return &g_Reg->PI_CART_ADDR_REG; + case 0x04600008: return &g_Reg->PI_RD_LEN_REG; + case 0x0460000C: return &g_Reg->PI_WR_LEN_REG; + case 0x04600010: return &g_Reg->PI_STATUS_REG; + case 0x04600014: return &g_Reg->PI_DOMAIN1_REG; + case 0x04600018: return &g_Reg->PI_BSD_DOM1_PWD_REG; + case 0x0460001C: return &g_Reg->PI_BSD_DOM1_PGS_REG; + case 0x04600020: return &g_Reg->PI_BSD_DOM1_RLS_REG; + case 0x04600024: return &g_Reg->PI_DOMAIN2_REG; + case 0x04600028: return &g_Reg->PI_BSD_DOM2_PWD_REG; + case 0x0460002C: return &g_Reg->PI_BSD_DOM2_PGS_REG; + case 0x04600030: return &g_Reg->PI_BSD_DOM2_RLS_REG; + case 0x04700000: return &g_Reg->RI_MODE_REG; + case 0x04700004: return &g_Reg->RI_CONFIG_REG; + case 0x04700008: return &g_Reg->RI_CURRENT_LOAD_REG; + case 0x0470000C: return &g_Reg->RI_SELECT_REG; + case 0x04700010: return &g_Reg->RI_REFRESH_REG; + case 0x04700014: return &g_Reg->RI_LATENCY_REG; + case 0x04700018: return &g_Reg->RI_RERROR_REG; + case 0x0470001C: return &g_Reg->RI_WERROR_REG; + case 0x04800018: return &g_Reg->SI_STATUS_REG; + case 0x05000500: return &g_Reg->ASIC_DATA; + case 0x05000504: return &g_Reg->ASIC_MISC_REG; + case 0x05000508: return &g_Reg->ASIC_STATUS; + case 0x0500050C: return &g_Reg->ASIC_CUR_TK; + case 0x05000510: return &g_Reg->ASIC_BM_STATUS; + case 0x05000514: return &g_Reg->ASIC_ERR_SECTOR; + case 0x05000518: return &g_Reg->ASIC_SEQ_STATUS; + case 0x0500051C: return &g_Reg->ASIC_CUR_SECTOR; + case 0x05000520: return &g_Reg->ASIC_HARD_RESET; + case 0x05000524: return &g_Reg->ASIC_C1_S0; + case 0x05000528: return &g_Reg->ASIC_HOST_SECBYTE; + case 0x0500052C: return &g_Reg->ASIC_C1_S2; + case 0x05000530: return &g_Reg->ASIC_SEC_BYTE; + case 0x05000534: return &g_Reg->ASIC_C1_S4; + case 0x05000538: return &g_Reg->ASIC_C1_S6; + case 0x0500053C: return &g_Reg->ASIC_CUR_ADDR; + case 0x05000540: return &g_Reg->ASIC_ID_REG; + case 0x05000544: return &g_Reg->ASIC_TEST_REG; + case 0x05000548: return &g_Reg->ASIC_TEST_PIN_SEL; + } + + return NULL; +} + +bool CDebugMMU::DebugLW_PAddr(uint32_t paddr, uint32_t& value) +{ + if (g_MMU == NULL) + { + return false; + } + + uint32_t* ptr = PAddrWordPtr(paddr); + + if (ptr != NULL) + { + value = *ptr; + return true; + } + + if (paddr >= 0x08000000 && paddr < 0x08FFFFFF) // Cartridge Domain 2 (Address 2) + { + uint32_t saveOffset = paddr & 0x000FFFFF; + + if (g_System->m_SaveUsing == SaveChip_Sram && saveOffset <= 0x7FFF) // sram + { + uint8_t tmp[4] = ""; + CSram *sram = g_MMU->GetSram(); + sram->DmaFromSram(tmp, paddr - 0x08000000, 4); + value = tmp[3] << 24 | tmp[2] << 16 | tmp[1] << 8 | tmp[0]; + return true; + } + else if (g_System->m_SaveUsing == SaveChip_FlashRam && saveOffset == 0) // flash ram status + { + CFlashram* flashRam = g_MMU->GetFlashram(); + value = flashRam->ReadFromFlashStatus(0x08000000); + return true; + } + } + + if (paddr == 0x04500004) + { + if (g_System->bFixedAudio()) + { + value = g_Audio->GetLength(); + } + else + { + CAudioPlugin* audioPlg = g_Plugins->Audio(); + value = (audioPlg->AiReadLength != NULL) ? audioPlg->AiReadLength() : 0; + } + return true; + } + + if (paddr == 0x0450000C) + { + value = g_System->bFixedAudio() ? g_Audio->GetStatus() : g_Reg->AI_STATUS_REG; + return true; + } + + return false; +} + +bool CDebugMMU::DebugLW_VAddr(uint32_t vaddr, uint32_t& value) +{ + if (vaddr <= 0x7FFFFFFF || vaddr >= 0xC0000000) // KUSEG, KSEG2 (TLB) + { + if (g_MMU == NULL) + { + return false; + } + + return g_MMU->LW_VAddr(vaddr, value); + } + + uint32_t paddr = vaddr & 0x1FFFFFFF; + return DebugLW_PAddr(paddr, value); +} + +bool CDebugMMU::DebugLB_PAddr(uint32_t vaddr, uint8_t& value) +{ + uint32_t word; + if (!DebugLW_PAddr(vaddr & ~3, word)) + { + return false; + } + value = (word >> (24 - (vaddr & 3) * 8)) & 0xFF; + return true; +} + +bool CDebugMMU::DebugLB_VAddr(uint32_t vaddr, uint8_t& value) +{ + uint32_t word; + if (!DebugLW_VAddr(vaddr & ~3, word)) + { + return false; + } + value = (word >> (24 - (vaddr & 3) * 8)) & 0xFF; + return true; +} + +bool CDebugMMU::DebugSB_PAddr(uint32_t paddr, uint8_t value) +{ + bool bWriteToRom = false; + + if (paddr >= 0x10000000 && paddr <= 0x1FBFFFFF) + { + uint32_t romOffset = paddr - 0x10000000; + if (romOffset > g_Rom->GetRomSize()) + { + return false; + } + bWriteToRom = true; + } + + int nbyte = 3 - (paddr & 3); + uint8_t* ptr = (uint8_t*)PAddrWordPtr(paddr & ~3); + + if (ptr == NULL) + { + return false; + } + + if (bWriteToRom) + { + ProtectMemory(g_Rom->GetRomAddress(), g_Rom->GetRomSize(), MEM_READWRITE); + } + + ptr[nbyte] = value; + + if (bWriteToRom) + { + ProtectMemory(g_Rom->GetRomAddress(), g_Rom->GetRomSize(), MEM_READONLY); + } + return true; +} + +bool CDebugMMU::DebugSB_VAddr(uint32_t vaddr, uint8_t value) +{ + if (vaddr <= 0x7FFFFFFF || vaddr >= 0xC0000000) // KUSEG, KSEG2 (TLB) + { + if (g_MMU == NULL) + { + return false; + } + + return g_MMU->SB_VAddr(vaddr, value); + } + + uint32_t paddr = vaddr & 0x1FFFFFFF; + return DebugSB_PAddr(paddr, value); +} diff --git a/Source/Project64/UserInterface/Debugger/DebugMMU.h b/Source/Project64/UserInterface/Debugger/DebugMMU.h new file mode 100644 index 000000000..857a32340 --- /dev/null +++ b/Source/Project64/UserInterface/Debugger/DebugMMU.h @@ -0,0 +1,15 @@ +#pragma once +#include + +class CDebugMMU +{ +private: + uint32_t* PAddrWordPtr(uint32_t paddr); +public: + bool DebugLW_PAddr(uint32_t paddr, uint32_t& value); + bool DebugLW_VAddr(uint32_t vaddr, uint32_t& value); + bool DebugLB_PAddr(uint32_t paddr, uint8_t& value); + bool DebugLB_VAddr(uint32_t vaddr, uint8_t& value); + bool DebugSB_PAddr(uint32_t paddr, uint8_t value); + bool DebugSB_VAddr(uint32_t vaddr, uint8_t value); +}; \ No newline at end of file diff --git a/Source/Project64/UserInterface/Debugger/Debugger-ViewMemory.cpp b/Source/Project64/UserInterface/Debugger/Debugger-ViewMemory.cpp index fc7a87ea2..dceabfc7d 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger-ViewMemory.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger-ViewMemory.cpp @@ -12,23 +12,49 @@ #include #include +#include + #include "DebuggerUI.h" #include "Symbols.h" #include "DMALog.h" -CDebugMemoryView* CDebugMemoryView::_this = NULL; -HHOOK CDebugMemoryView::hWinMessageHook = NULL; +CDebugMemoryView::jump_item_t CDebugMemoryView::JumpItems[] = { + { 0x80000000, 0x00000000, 0x0800000, "RDRAM" }, + { 0xA3F00000, 0x03F00000, 0x0000028, "RDRAM Registers" }, + { 0xA4000000, 0x04000000, 0x0001000, "SP DMEM" }, + { 0xA4001000, 0x04001000, 0x0001000, "SP IMEM" }, + { 0xA4040000, 0x04040000, 0x0000020, "SP Registers" }, + { 0xA4080000, 0x04080000, 0x0000004, "SP PC Register" }, + { 0xA4100000, 0x04100000, 0x0000020, "DP Control Registers" }, + { 0xA4300000, 0x04300000, 0x0000010, "MI Registers" }, + { 0xA4400000, 0x04400000, 0x0000038, "VI Registers" }, + { 0xA4500000, 0x04500000, 0x0000018, "AI Registers" }, + { 0xA4600000, 0x04600000, 0x0000034, "PI Registers" }, + { 0xA4700000, 0x04700000, 0x0000020, "RI Registers" }, + { 0xA4800000, 0x04800000, 0x0000010, "SI Registers" }, + { 0xA5000500, 0x05000500, 0x000004C, "DD Registers" }, + { 0xA8000000, 0xA8000000, 0x0000000, "Cartridge Save Data" }, + { 0xB0000000, 0x10000000, 0xFC00000, "Cartridge ROM" }, + { 0xBFC00000, 0x1FC00000, 0x00007C0, "PIF ROM" }, + { 0xBFC007C0, 0x1FC007C0, 0x0000040, "PIF RAM" }, + { 0, NULL} +}; CDebugMemoryView::CDebugMemoryView(CDebuggerUI * debugger) : CDebugDialog(debugger), - m_MemoryList(NULL) + CDialogResize(), + CToolTipDialog(), + m_Breakpoints(NULL), + m_WriteTargetColorStride(0), + m_ReadTargetColorStride(0), + m_SymbolColorStride(0), + m_SymbolColorPhase(0), + m_bIgnoreAddressInput(false), + m_HotAddress(0), + m_bVirtualMemory(true), + m_ContextMenuAddress(0), + m_bSafeEditMode(false) { - if (m_MemoryList == NULL) - { - m_MemoryList = new CListCtrl; - m_MemoryList->RegisterClass(); - } - m_Breakpoints = m_Debugger->Breakpoints(); } @@ -36,16 +62,258 @@ CDebugMemoryView::~CDebugMemoryView() { } +void CDebugMemoryView::ShowAddress(uint32_t address, bool bVirtual) +{ + if (m_hWnd == NULL) + { + return; + } + + SendMessage(WM_SHOWADDRESS, (WPARAM)address, (LPARAM)bVirtual); +} + +bool CDebugMemoryView::GetByte(uint32_t address, uint8_t* value) +{ + if (m_bVirtualMemory) + { + return m_Debugger->DebugLB_VAddr(address, *value); + } + else + { + return m_Debugger->DebugLB_PAddr(address, *value); + } +} + +bool CDebugMemoryView::SetByte(uint32_t address, uint8_t value) +{ + if (m_bVirtualMemory) + { + return m_Debugger->DebugSB_VAddr(address, value); + } + else + { + return m_Debugger->DebugSB_PAddr(address, value); + } +} + +void CDebugMemoryView::CopyTextToClipboard(const char* text) +{ + size_t length = strlen(text); + HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, length + 1); + strcpy((char*)GlobalLock(hMem), text); + GlobalUnlock(hMem); + OpenClipboard(); + EmptyClipboard(); + SetClipboardData(CF_TEXT, hMem); + CloseClipboard(); +} + +void CDebugMemoryView::CopyBytesToClipboard(uint32_t startAddress, uint32_t endAddress, bool bHex, bool bIncludeAddresses, bool bRowAddresses) +{ + uint32_t baseAddress = m_HexEditCtrl.GetBaseAddress(); + int groupSize = m_HexEditCtrl.GetNumBytesPerGroup(); + int rowSize = m_HexEditCtrl.GetNumBytesPerRow(); + + stdstr str = ""; + + for (uint32_t address = startAddress; address <= endAddress; address++) + { + int offsetFromBase = address - baseAddress; + int offsetFromSelStart = address - startAddress; + + uint8_t value; + GetByte(address, &value); + + if (bIncludeAddresses) + { + if ((bRowAddresses && offsetFromBase % rowSize == 0) || + (!bRowAddresses && offsetFromBase % groupSize == 0) || + (offsetFromSelStart == 0)) + { + str += stdstr_f("%08X: ", address); + } + } + + if (bHex) + { + str += stdstr_f("%02X", value); + } + else + { + str += CHexEditCtrl::ByteAscii(value); + } + + if ((offsetFromBase + 1) % rowSize == 0 || (bIncludeAddresses && !bRowAddresses && (offsetFromBase + 1) % groupSize == 0)) + { + str += "\r\n"; + } + else if (bHex && (offsetFromBase + 1) % groupSize == 0) + { + str += " "; + } + } + + CopyTextToClipboard(str.Trim(" \r\n").c_str()); +} + +void CDebugMemoryView::CopyGameSharkCodeToClipboard(uint32_t startAddress, uint32_t endAddress) +{ + stdstr str = ""; + + if (startAddress & 1) + { + uint8_t value = 0; + GetByte(startAddress, &value); + str += stdstr_f("%08X %04X\r\n", startAddress, value); + startAddress++; + } + + for (uint32_t address = startAddress; address < endAddress; address += 2) + { + uint8_t value0 = 0, value1 = 0; + GetByte(address + 0, &value0); + GetByte(address + 1, &value1); + str += stdstr_f("%08X %02X%02X\r\n", address | 0x01000000, value0, value1); + } + + if (!(endAddress & 1)) + { + uint8_t value = 0; + GetByte(endAddress, &value); + str += stdstr_f("%08X %04X\r\n", endAddress, value); + } + + CopyTextToClipboard(str.Trim("\n").c_str()); +} + +void CDebugMemoryView::FillRange(uint32_t startAddress, uint32_t endAddress, uint8_t value) +{ + for (uint32_t address = startAddress; address <= endAddress; address++) + { + SetByte(address, value); + } +} + +void CDebugMemoryView::FollowPointer(bool bContextMenuAddress) +{ + uint32_t address; + + if (bContextMenuAddress) + { + address = m_ContextMenuAddress - (m_ContextMenuAddress % 4); + } + else + { + address = m_HexEditCtrl.GetCaretAddress(); + address -= (address % 4); + } + + address += (m_bVirtualMemory ? 0 : 0x80000000); + + uint32_t pointer; + if (m_Debugger->DebugLW_VAddr(address, pointer)) + { + OpenNewTab(pointer, m_bVirtualMemory, 4, true, true); + } +} + + +void CDebugMemoryView::JumpToSelection(void) +{ + uint32_t startAddress, endAddress; + bool bHaveSelection = m_HexEditCtrl.GetSelectionRange(&startAddress, &endAddress); + uint32_t targetAddress = bHaveSelection ? startAddress : m_HexEditCtrl.GetCaretAddress(); + m_MemAddr.SetValue(targetAddress, false, true); +} + +bool CDebugMemoryView::GetSafeEditValue(uint32_t address, uint8_t* value) +{ + if (m_SafeEditQueue.size() == 0) + { + return false; + } + + for(size_t i = m_SafeEditQueue.size(); i-- > 0;) + { + edit_t edit = m_SafeEditQueue[i]; + if (address >= edit.startAddress && address <= edit.endAddress) + { + *value = edit.value; + return true; + } + } + return false; +} + +void CDebugMemoryView::ApplySafeEdits(void) +{ + for (size_t i = 0; i < m_SafeEditQueue.size(); i++) + { + edit_t edit = m_SafeEditQueue[i]; + if (edit.type == SE_FILL) + { + FillRange(edit.startAddress, edit.endAddress, edit.value); + } + } + + m_SafeEditQueue.clear(); +} + +void CDebugMemoryView::SetupJumpMenu(bool bVirtual) +{ + m_CmbJump.SetRedraw(FALSE); + m_CmbJump.ResetContent(); + + for (int i = 0;; i++) + { + jump_item_t* item = &JumpItems[i]; + + if (item->caption == NULL) + { + break; + } + + m_CmbJump.AddString(stdstr_f("%08X %s", bVirtual ? item->vaddr : item->paddr, item->caption).c_str()); + } + + m_CmbJump.SetRedraw(TRUE); +} + +int CDebugMemoryView::GetJumpItemIndex(uint32_t address, bool bVirtual) +{ + for (int nItem = 0;; nItem++) + { + if (JumpItems[nItem].caption == NULL) + { + break; + } + + uint32_t start = bVirtual ? JumpItems[nItem].vaddr : JumpItems[nItem].paddr; + uint32_t end = start + JumpItems[nItem].size - 1; + + if (address >= start && address <= end) + { + return nItem; + } + } + return -1; +} + LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { + DlgResize_Init(false, true); DlgSavePos_Init(DebuggerUI_MemoryPos); + DlgToolTip_Init(); + + m_HexEditCtrl.Attach(GetDlgItem(IDC_HEXEDIT)); + m_TabCtrl.Attach(GetDlgItem(IDC_MEMTABS)); + m_MemAddr.Attach(GetDlgItem(IDC_ADDR_EDIT)); + m_VirtualCheckbox.Attach(GetDlgItem(IDC_CHK_VADDR)); + m_StatusBar.Attach(GetDlgItem(IDC_STATUSBAR)); + m_CmbJump.Attach(GetDlgItem(IDC_CMB_JUMP)); m_SymbolColorStride = 0; m_SymbolColorPhase = 0; - m_DataStartLoc = (DWORD)-1; - m_CompareStartLoc = (DWORD)-1; - memset(m_CompareData, 0, sizeof(m_CompareData)); - memset(m_CompareValid, 0, sizeof(m_CompareValid)); HWND hScrlBar = GetDlgItem(IDC_SCRL_BAR); if (hScrlBar) @@ -61,227 +329,574 @@ LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM ::SetScrollInfo(hScrlBar, SB_CTL, &si, TRUE); } - m_MemAddr.Attach(GetDlgItem(IDC_ADDR_EDIT)); m_MemAddr.SetDisplayType(CEditNumber32::DisplayHex); m_MemAddr.SetValue(0x80000000, false, true); - SendDlgItemMessage(IDC_CHK_VADDR, BM_SETCHECK, BST_CHECKED, 0); + m_VirtualCheckbox.SetCheck(BST_CHECKED); - if (m_MemoryList == NULL) - { - m_MemoryList = new CListCtrl; - m_MemoryList->RegisterClass(); - } - m_MemoryList->SubclassWindow(GetDlgItem(IDC_MEM_DETAILS)); - m_MemoryList->ShowHeader(false); - m_MemoryList->SetSortEnabled(FALSE); - m_MemoryList->AddColumn(_T("Address"), 90); - m_MemoryList->AddColumn(_T("1"), 20); - m_MemoryList->AddColumn(_T("2"), 20); - m_MemoryList->AddColumn(_T("3"), 20); - m_MemoryList->AddColumn(_T("4"), 20); - m_MemoryList->AddColumn(_T("-"), 10); - m_MemoryList->AddColumn(_T("5"), 20); - m_MemoryList->AddColumn(_T("6"), 20); - m_MemoryList->AddColumn(_T("7"), 20); - m_MemoryList->AddColumn(_T("8"), 20); - m_MemoryList->AddColumn(_T("-"), 10); - m_MemoryList->AddColumn(_T("9"), 20); - m_MemoryList->AddColumn(_T("10"), 20); - m_MemoryList->AddColumn(_T("11"), 20); - m_MemoryList->AddColumn(_T("12"), 20); - m_MemoryList->AddColumn(_T("-"), 10); - m_MemoryList->AddColumn(_T("13"), 20); - m_MemoryList->AddColumn(_T("14"), 20); - m_MemoryList->AddColumn(_T("15"), 20); - m_MemoryList->AddColumn(_T("16"), 35); - m_MemoryList->AddColumn(_T("Memory Ascii"), 140); - ::SetWindowLongPtr(m_MemoryList->m_hWnd, GWL_EXSTYLE, WS_EX_CLIENTEDGE); - RefreshMemory(false); - int height = m_MemoryList->GetTotalHeight(); + float dpiScale = CClientDC(m_hWnd).GetDeviceCaps(LOGPIXELSX) / 96.0f; - RECT MemoryListRect = { 0 }; - ::GetClientRect(GetDlgItem(IDC_MEM_DETAILS), &MemoryListRect); + int statusPaneWidths[MEMSB_NUM_PANES] = { + (int)(MEMSB_HOTADDR_W * dpiScale), + (int)(MEMSB_BLOCK_W * dpiScale), + (int)(MEMSB_BLOCKLEN_W * dpiScale), + (int)(MEMSB_DMAINFO_W * dpiScale), + (int)(MEMSB_SAFEMODE_W * dpiScale) + }; - if (height > MemoryListRect.bottom) - { - RECT MemoryListWindow = { 0 }; - GetWindowRect(&MemoryListWindow); - SetWindowPos(NULL, 0, 0, MemoryListWindow.right - MemoryListWindow.left, (MemoryListWindow.bottom - MemoryListWindow.top) + (height - MemoryListRect.bottom), SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOZORDER); + m_StatusBar.SetParts(MEMSB_NUM_PANES, statusPaneWidths); - RECT DlgItemRect = { 0 }; + SetupJumpMenu(true); + m_CmbJump.SetCurSel(0); + + AddTab(0x80000000, true, 4); - ::GetWindowRect(GetDlgItem(IDC_MEM_DETAILS), &DlgItemRect); - ::SetWindowPos(GetDlgItem(IDC_MEM_DETAILS), NULL, 0, 0, DlgItemRect.right - DlgItemRect.left, (DlgItemRect.bottom - DlgItemRect.top) + (height - MemoryListRect.bottom), SWP_NOMOVE); - - ::GetWindowRect(GetDlgItem(IDC_SCRL_BAR), &DlgItemRect); - ::SetWindowPos(GetDlgItem(IDC_SCRL_BAR), NULL, 0, 0, DlgItemRect.right - DlgItemRect.left, (DlgItemRect.bottom - DlgItemRect.top) + (height - MemoryListRect.bottom), SWP_NOMOVE); - } - - m_SymInfo.Attach(GetDlgItem(IDC_SYM_INFO)); - m_DMAInfo.Attach(GetDlgItem(IDC_DMA_INFO)); - - m_bAutoRefreshEnabled = g_Settings->LoadBool(Debugger_AutoRefreshMemoryView); - SendDlgItemMessage(IDC_CHK_AUTOREFRESH, BM_SETCHECK, m_bAutoRefreshEnabled ? BST_CHECKED : BST_UNCHECKED, 0); - - _this = this; - - DWORD dwThreadID = ::GetCurrentThreadId(); - hWinMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)HookProc, NULL, dwThreadID); + m_HexEditCtrl.Draw(); LoadWindowPos(); WindowCreated(); - m_AutoRefreshThread = CreateThread(NULL, 0, AutoRefreshProc, (void*)this, 0, NULL); - return TRUE; } -DWORD WINAPI CDebugMemoryView::AutoRefreshProc(void* _self) -{ - CDebugMemoryView* self = (CDebugMemoryView*)_self; - while (true) - { - if (self->m_bAutoRefreshEnabled) - { - self->RefreshMemory(true); - } - Sleep(100); - } -} - -void CDebugMemoryView::OnExitSizeMove() -{ - SaveWindowPos(0); -} - -void CDebugMemoryView::InterceptMouseWheel(WPARAM wParam, LPARAM /*lParam*/) -{ - uint32_t newAddress = m_DataStartLoc - ((short)HIWORD(wParam) / WHEEL_DELTA) * 16; - - m_DataStartLoc = newAddress; - - m_MemAddr.SetValue(m_DataStartLoc, false, true); -} - -LRESULT CALLBACK CDebugMemoryView::HookProc(int nCode, WPARAM wParam, LPARAM lParam) -{ - MSG *pMsg = (MSG*)lParam; - - if (pMsg->message == WM_MOUSEWHEEL) - { - _this->InterceptMouseWheel(pMsg->wParam, pMsg->lParam); - } - - if (nCode < 0) - { - return CallNextHookEx(hWinMessageHook, nCode, wParam, lParam); - } - - return 0; -} - LRESULT CDebugMemoryView::OnDestroy(void) { - if (m_AutoRefreshThread != NULL) - { - TerminateThread(m_AutoRefreshThread, 0); - CloseHandle(m_AutoRefreshThread); - } - if (m_MemoryList) - { - m_MemoryList->UnsubclassWindow(); - delete m_MemoryList; - m_MemoryList = NULL; - } + m_HexEditCtrl.Detach(); m_MemAddr.Detach(); - m_SymInfo.Detach(); - m_DMAInfo.Detach(); - UnhookWindowsHookEx(hWinMessageHook); + m_VirtualCheckbox.Detach(); + m_TabCtrl.Detach(); + m_StatusBar.Detach(); + m_CmbJump.Detach(); return 0; } +LRESULT CDebugMemoryView::OnShowAddress(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) +{ + uint32_t address = (uint32_t)wParam; + bool bVirtual = (lParam != 0); + m_CmbJump.SetCurSel(GetJumpItemIndex(address, bVirtual)); + OpenNewTab(address, bVirtual, 4, true, true); + return FALSE; +} + +void CDebugMemoryView::OnExitSizeMove() +{ + SaveWindowPos(true); +} + LRESULT CDebugMemoryView::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL& /*bHandled*/) { switch (wID) { - case IDC_REFRSH_MEM: - RefreshMemory(true); - break; case IDC_CHK_VADDR: - RefreshMemory(false); - break; - case IDC_DUMP_MEM: - m_Debugger->OpenMemoryDump(); - break; - case IDC_SEARCH_MEM: - m_Debugger->OpenMemorySearch(); + m_bVirtualMemory = (m_VirtualCheckbox.GetCheck() == BST_CHECKED); + SetupJumpMenu(m_bVirtualMemory); + UpdateCurrentTab(m_MemAddr.GetValue()); break; case IDC_SYMBOLS_BTN: m_Debugger->OpenSymbolsWindow(); break; - case IDC_CHK_AUTOREFRESH: - m_bAutoRefreshEnabled = (SendMessage(GetDlgItem(IDC_CHK_AUTOREFRESH), BM_GETSTATE, 0, 0) & BST_CHECKED) != 0; - g_Settings->SaveBool(Debugger_AutoRefreshMemoryView, m_bAutoRefreshEnabled); - break; case IDCANCEL: EndDialog(0); break; case ID_POPUPMENU_TOGGLERBP: - m_Breakpoints->RBPToggle(m_CtxMenuAddr); - RefreshMemory(true); + m_Breakpoints->RBPToggle(m_ContextMenuAddress); break; case ID_POPUPMENU_TOGGLEWBP: - m_Breakpoints->WBPToggle(m_CtxMenuAddr); - RefreshMemory(true); + m_Breakpoints->WBPToggle(m_ContextMenuAddress); break; case ID_POPUPMENU_CLEARALLBPS: m_Breakpoints->RBPClear(); m_Breakpoints->WBPClear(); - RefreshMemory(true); break; case ID_POPUPMENU_TOGGLELOCK: - m_Breakpoints->ToggleMemLock(m_CtxMenuAddr); - RefreshMemory(true); + m_Breakpoints->ToggleMemLock(m_ContextMenuAddress); break; case ID_POPUPMENU_CLEARLOCKS: m_Breakpoints->ClearMemLocks(); - RefreshMemory(true); + break; + case ID_POPUPMENU_JUMPHERE: + JumpToSelection(); + break; + case ID_POPUPMENU_FOLLOWPOINTER: + FollowPointer(); break; case ID_POPUPMENU_VIEWDISASM: - m_Debugger->Debug_ShowCommandsLocation(m_CtxMenuAddr, true); + m_Debugger->Debug_ShowCommandsLocation(m_ContextMenuAddress, true); break; case ID_POPUPMENU_ADDSYMBOL: - m_AddSymbolDlg.DoModal(m_Debugger, m_CtxMenuAddr); + m_AddSymbolDlg.DoModal(m_Debugger, m_ContextMenuAddress); break; - case ID_POPUPMENU_COPY_WORD: - CopyNumber(m_CtxMenuAddr, sizeof(uint32_t)); + case ID_POPUPMENU_COPY: + m_HexEditCtrl.Copy(); break; - case ID_POPUPMENU_COPY_HALFWORD: - CopyNumber(m_CtxMenuAddr, sizeof(uint16_t)); + case ID_POPUPMENU_COPYGAMESHARKCODE: + { + uint32_t startAddress, endAddress; + m_HexEditCtrl.GetSelectionRange(&startAddress, &endAddress); + CopyGameSharkCodeToClipboard(startAddress, endAddress); + } break; - case ID_POPUPMENU_COPY_BYTE: - CopyNumber(m_CtxMenuAddr, sizeof(uint8_t)); + case ID_POPUPMENU_COPYDATAWITHGROUPADDRESSES: + { + uint32_t startAddress, endAddress; + m_HexEditCtrl.GetSelectionRange(&startAddress, &endAddress); + CopyBytesToClipboard(startAddress, endAddress, m_HexEditCtrl.GetFocusedColumn() == HX_COL_HEXDATA, true, false); + } + break; + case ID_POPUPMENU_COPYDATAWITHROWADDRESSES: + { + uint32_t startAddress, endAddress; + m_HexEditCtrl.GetSelectionRange(&startAddress, &endAddress); + CopyBytesToClipboard(startAddress, endAddress, m_HexEditCtrl.GetFocusedColumn() == HX_COL_HEXDATA, true, true); + } + break; + case ID_POPUPMENU_PASTE: + m_HexEditCtrl.Paste(); + break; + case ID_POPUPMENU_SAFEMODE: + m_HexEditCtrl.SendMessage(WM_KEYDOWN, VK_INSERT, 0); + break; + case ID_POPUPMENU_ZEROFILL: + m_HexEditCtrl.SendMessage(WM_KEYDOWN, VK_DELETE, 0); + break; + case ID_POPUPMENU_BYTEGROUPSIZE_1: + m_HexEditCtrl.SetByteGroupSize(1); + break; + case ID_POPUPMENU_BYTEGROUPSIZE_2: + m_HexEditCtrl.SetByteGroupSize(2); + break; + case ID_POPUPMENU_BYTEGROUPSIZE_4: + m_HexEditCtrl.SetByteGroupSize(4); + break; + case ID_POPUPMENU_BYTEGROUPSIZE_8: + m_HexEditCtrl.SetByteGroupSize(8); + break; + case ID_POPUPMENU_DUMP: + m_Debugger->OpenMemoryDump(); + break; + case ID_POPUPMENU_SEARCH: + m_Debugger->OpenMemorySearch(); break; } return FALSE; } -LRESULT CDebugMemoryView::OnMemoryRightClicked(LPNMHDR lpNMHDR) +void CDebugMemoryView::OnAddrChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) { - uint32_t address; - bool bData = GetItemAddress(lpNMHDR, address); - - if (!bData) + if (m_bIgnoreAddressInput) { - return 0; + m_bIgnoreAddressInput = false; + return; } - m_CtxMenuAddr = address; + uint32_t address = m_MemAddr.GetValue(); + m_HexEditCtrl.SetBaseAddress(address); + UpdateCurrentTab(address); +} + +void CDebugMemoryView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar) +{ + if (pScrollBar != GetDlgItem(IDC_SCRL_BAR)) + { + return; + } + + uint32_t address = m_MemAddr.GetValue(); + int numBytesPerRow = m_HexEditCtrl.GetNumBytesPerRow(); + int numVisibleBytes = m_HexEditCtrl.GetNumVisibleBytes(); + + switch (nSBCode) + { + case SB_LINEDOWN: + m_MemAddr.SetValue(address < 0xFFFFFFEF ? address + numBytesPerRow : 0xFFFFFFFF, false, true); + break; + case SB_LINEUP: + m_MemAddr.SetValue(address > (uint32_t)numBytesPerRow ? address - numBytesPerRow : 0, false, true); + break; + case SB_PAGEDOWN: + m_MemAddr.SetValue(address < 0xFFFFFEFF ? address + numVisibleBytes : 0xFFFFFFFF, false, true); + break; + case SB_PAGEUP: + m_MemAddr.SetValue(address >(uint32_t)numVisibleBytes ? address - numVisibleBytes : 0, false, true); + break; + case SB_THUMBPOSITION: + m_MemAddr.SetValue((DWORD)nPos << 0x10, false, true); + break; + default: + break; + } + + m_CmbJump.SetCurSel(GetJumpItemIndex(address, m_bVirtualMemory)); +} + +LRESULT CDebugMemoryView::OnHxCtrlKeyPressed(LPNMHDR lpNMHDR) +{ + NMHXCTRLKEYPRESSED* nmck = reinterpret_cast(lpNMHDR); + uint32_t address = m_HexEditCtrl.GetCaretAddress(); + + if (nmck->nChar >= '1' && nmck->nChar <= '9') + { + int nBytes = nmck->nChar - '0'; + m_HexEditCtrl.SetByteGroupSize(nBytes); + return FALSE; + } + + switch (nmck->nChar) + { + case 'G': + { + JumpToSelection(); + } + break; + case 'W': + m_Breakpoints->WBPToggle(address); + break; + case 'R': + m_Breakpoints->RBPToggle(address); + break; + case 'E': + m_Breakpoints->ToggleMemLock(address); + break; + case 'Q': + m_Breakpoints->WBPClear(); + m_Breakpoints->RBPClear(); + m_Breakpoints->ClearMemLocks(); + break; + case 'F': + // todo put selection in the textbox + m_Debugger->OpenMemorySearch(); + break; + case 'S': + // todo set start and end addrs to selection + m_Debugger->OpenMemoryDump(); + break; + case 'T': + OpenDuplicateTab(); + break; + case 'Z': + if (m_SafeEditQueue.size() != 0) + { + m_SafeEditQueue.pop_back(); + } + break; + case VK_F4: + CloseCurrentTab(); + break; + case VK_SPACE: + FollowPointer(false); + break; + case VK_TAB: + { + int curSel = m_TabCtrl.GetCurSel(); + if (m_TabCtrl.SetCurSel(curSel + 1) == -1) + { + m_TabCtrl.SetCurSel(0); + } + TabSelChanged(); + } + break; + } + + return FALSE; +} + +LRESULT CDebugMemoryView::OnHxSetNibble(LPNMHDR lpNMHDR) +{ + if (g_MMU == NULL) + { + return FALSE; + } + + NMHXSETNIBBLE* nmsn = reinterpret_cast(lpNMHDR); + + uint8_t curValue; + bool bValid = GetByte(nmsn->address, &curValue); + + if (!bValid) + { + return false; + } + + uint8_t mask = (nmsn->bLoNibble ? 0xF0 : 0x0F); + uint8_t newValue = (curValue & mask) | (nmsn->value << (nmsn->bLoNibble ? 0 : 4)); + + if (nmsn->bInsert) + { + if (GetSafeEditValue(nmsn->address, &curValue)) + { + newValue = (curValue & mask) | (nmsn->value << (nmsn->bLoNibble ? 0 : 4)); + } + + m_SafeEditQueue.push_back({ SE_FILL, nmsn->address, nmsn->address, newValue }); + } + else + { + SetByte(nmsn->address, newValue); + } + + return FALSE; +} + +LRESULT CDebugMemoryView::OnHxSetByte(LPNMHDR lpNMHDR) +{ + NMHXSETBYTE* nmsb = reinterpret_cast(lpNMHDR); + + if (g_MMU == NULL) + { + return FALSE; + } + + if (nmsb->bInsert) + { + m_SafeEditQueue.push_back({ SE_FILL, nmsb->address, nmsb->address, nmsb->value }); + } + else + { + SetByte(nmsb->address, nmsb->value); + } + return FALSE; +} + +LRESULT CDebugMemoryView::OnHxFillRange(LPNMHDR lpNMHDR) +{ + NMHXFILLRANGE* nmfr = reinterpret_cast(lpNMHDR); + + if (nmfr->bInsert) + { + m_SafeEditQueue.push_back({ SE_FILL, nmfr->startAddress, nmfr->endAddress, nmfr->value }); + return FALSE; + } + + FillRange(nmfr->startAddress, nmfr->endAddress, nmfr->value); + return FALSE; +} + +LRESULT CDebugMemoryView::OnHxInsertModeChanged(LPNMHDR /*lpNMHDR*/) +{ + m_SafeEditQueue.clear(); + m_bSafeEditMode = m_HexEditCtrl.GetInsertMode(); + m_StatusBar.SetText(MEMSB_SAFEMODE, m_bSafeEditMode ? "Safe mode" : ""); + return FALSE; +} + +LRESULT CDebugMemoryView::OnHxSelectionChanged(LPNMHDR /*lpNMHDR*/) +{ + uint32_t startAddress, endAddress; + bool bHaveSelection = m_HexEditCtrl.GetSelectionRange(&startAddress, &endAddress); + + stdstr strBlock, strLength; + + if (bHaveSelection) + { + strBlock = stdstr_f("%08X:%08X", startAddress, endAddress); + strLength = stdstr_f("%X", endAddress - startAddress + 1); + m_StatusBar.SetText(MEMSB_BLOCK, strBlock.c_str()); + m_StatusBar.SetText(MEMSB_BLOCKLEN, strLength.c_str()); + } + else + { + strBlock = stdstr_f("%08X", startAddress); + m_StatusBar.SetText(MEMSB_BLOCK, strBlock.c_str()); + m_StatusBar.SetText(MEMSB_BLOCKLEN, ""); + } + + uint32_t romAddr, offset; + DMALOGENTRY* entry = m_Debugger->DMALog()->GetEntryByRamAddress(startAddress, &romAddr, &offset); + m_StatusBar.SetText(MEMSB_DMAINFO, entry != NULL ? "Have DMA" : ""); + + return FALSE; +} + +LRESULT CDebugMemoryView::OnHxGroupSizeChanged(LPNMHDR /*lpNMHDR*/) +{ + int groupSize = m_HexEditCtrl.GetNumBytesPerGroup(); + + int nItem = m_TabCtrl.GetCurSel(); + + if (nItem == -1) + { + return FALSE; + } + + m_TabData[nItem].numBytesPerGroup = groupSize; + return FALSE; +} + +LRESULT CDebugMemoryView::OnHxEnterPressed(LPNMHDR /*lpNMHDR*/) +{ + ApplySafeEdits(); + return FALSE; +} + +LRESULT CDebugMemoryView::OnHxRedrawStarted(LPNMHDR /*lpNMHDR*/) +{ + m_SymbolColorPhase = 0; + return FALSE; +} + +LRESULT CDebugMemoryView::OnHxGetByteInfo(LPNMHDR lpNMHDR) +{ + NMHXGETBYTEINFO *nmgbi = reinterpret_cast(lpNMHDR); + + bool bHaveWriteTarget = false, bHaveReadTarget = false; + uint32_t cpuReadWriteAddress = 0; + int cpuReadWriteNumBytes = 0; + + if (g_Settings->LoadBool(Debugger_SteppingOps)) + { + COpInfo opInfo(R4300iOp::m_Opcode); + if (opInfo.IsStoreCommand()) + { + cpuReadWriteAddress = opInfo.GetLoadStoreAddress(); + cpuReadWriteNumBytes = opInfo.NumBytesToStore(); + bHaveWriteTarget = true; + } + else if (opInfo.IsLoadCommand()) + { + cpuReadWriteAddress = opInfo.GetLoadStoreAddress(); + cpuReadWriteNumBytes = opInfo.NumBytesToLoad(); + bHaveReadTarget = true; + } + } + + for (uint32_t i = 0; i < nmgbi->numBytes; i++) + { + uint32_t address = nmgbi->address + i; + uint32_t paddress = address; + HXBYTEINFO* oldByte = &nmgbi->oldBytes[i]; + HXBYTEINFO* newByte = &nmgbi->newBytes[i]; + + newByte->bkColor = BKCOLOR_DEFAULT; + newByte->color = COLOR_DEFAULT; + + if (m_bVirtualMemory && (g_MMU == NULL || !g_MMU->TranslateVaddr(address, paddress))) + { + newByte->bValid = false; + continue; + } + + newByte->bValid = GetByte(address, &newByte->value); + + if (!newByte->bValid) + { + continue; + } + + // always use virtual addresses for breakpoint & symbol info + // todo should be the other way around + uint32_t vaddress = m_bVirtualMemory ? address : address + 0x80000000; + + CSymbols::EnterCriticalSection(); + CSymbolEntry* symbol = CSymbols::GetEntryByAddress(vaddress); + + if (symbol != NULL) + { + m_SymbolColorStride = symbol->TypeSize(); + m_SymbolColorPhase = m_SymbolColorPhase ? 0 : 1; + } + + CSymbols::LeaveCriticalSection(); + + if (bHaveWriteTarget && address == cpuReadWriteAddress) + { + m_WriteTargetColorStride = cpuReadWriteNumBytes; + } + else if (bHaveReadTarget && address == cpuReadWriteAddress) + { + m_ReadTargetColorStride = cpuReadWriteNumBytes; + } + + bool bLocked = m_Breakpoints->MemLockExists(vaddress, 1); + bool bReadBP = m_Breakpoints->ReadBPExists8(vaddress) == CBreakpoints::BP_SET; + bool bWriteBP = m_Breakpoints->WriteBPExists8(vaddress) == CBreakpoints::BP_SET; + + if (bLocked) + { + newByte->bkColor = BKCOLOR_LOCKED; + newByte->color = COLOR_BP; + } + else if (bReadBP && bWriteBP) + { + newByte->bkColor = BKCOLOR_RWBP; + newByte->color = COLOR_BP; + } + else if (bReadBP) + { + newByte->bkColor = BKCOLOR_RBP; + newByte->color = COLOR_BP; + } + else if (bWriteBP) + { + newByte->bkColor = BKCOLOR_WBP; + newByte->color = COLOR_BP; + } + else if (m_ReadTargetColorStride > 0) + { + newByte->bkColor = BKCOLOR_CPUREAD; + } + else if (m_WriteTargetColorStride > 0) + { + newByte->bkColor = BKCOLOR_CPUWRITE; + } + else if (m_SymbolColorStride > 0) + { + newByte->bkColor = m_SymbolColorPhase ? BKCOLOR_SYMBOL0 : BKCOLOR_SYMBOL1; + } + + if (g_Rom != NULL && paddress >= 0x10000000 && paddress < 0x10000000 + g_Rom->GetRomSize()) + { + newByte->color = COLOR_READONLY; + } + + if (!nmgbi->bIgnoreDiff && oldByte->value != newByte->value) + { + newByte->color = COLOR_CHANGED; + } + + if (m_SymbolColorStride > 0) + { + m_SymbolColorStride--; + } + + if (m_ReadTargetColorStride > 0) + { + m_ReadTargetColorStride--; + } + + if (m_WriteTargetColorStride > 0) + { + m_WriteTargetColorStride--; + } + + uint8_t safeEditValue; + if (GetSafeEditValue(address, &safeEditValue)) + { + newByte->bValid = true; + newByte->value = safeEditValue; + newByte->bkColor = RGB(0xFF, 0xCC, 0xFF); + newByte->color = RGB(0xFF, 0x00, 0xFF); + } + + newByte->bHidden = false; + } + + return FALSE; +} + +LRESULT CDebugMemoryView::OnHxRightClick(LPNMHDR lpNMHDR) +{ + NMHXRCLICK *nmrc = reinterpret_cast(lpNMHDR); + + m_ContextMenuAddress = nmrc->address; HMENU hMenu = LoadMenu(GetModuleHandle(NULL), MAKEINTRESOURCE(IDR_MEM_BP_POPUP)); HMENU hPopupMenu = GetSubMenu(hMenu, 0); + bool bHaveLock = m_Breakpoints->MemLockExists(m_ContextMenuAddress, 1); + bool bHaveReadBP = (m_Breakpoints->ReadBPExists8(m_ContextMenuAddress) != CBreakpoints::BPSTATE::BP_NOT_SET); + bool bHaveWriteBP = (m_Breakpoints->WriteBPExists8(m_ContextMenuAddress) != CBreakpoints::BPSTATE::BP_NOT_SET); + if (m_Breakpoints->ReadMem().size() == 0 && m_Breakpoints->WriteMem().size() == 0) { EnableMenuItem(hPopupMenu, ID_POPUPMENU_CLEARALLBPS, MF_DISABLED | MF_GRAYED); @@ -291,539 +906,349 @@ LRESULT CDebugMemoryView::OnMemoryRightClicked(LPNMHDR lpNMHDR) EnableMenuItem(hPopupMenu, ID_POPUPMENU_CLEARLOCKS, MF_DISABLED | MF_GRAYED); } + CheckMenuItem(hPopupMenu, ID_POPUPMENU_TOGGLELOCK, bHaveLock ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hPopupMenu, ID_POPUPMENU_TOGGLERBP, bHaveReadBP ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hPopupMenu, ID_POPUPMENU_TOGGLEWBP, bHaveWriteBP ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hPopupMenu, ID_POPUPMENU_SAFEMODE, m_bSafeEditMode ? MF_CHECKED : MF_UNCHECKED); + POINT mouse; GetCursorPos(&mouse); - TrackPopupMenu(hPopupMenu, TPM_LEFTALIGN, mouse.x, mouse.y, 0, m_hWnd, NULL); - DestroyMenu(hMenu); - - return 0; + return FALSE; } -LRESULT CDebugMemoryView::OnHotItemChanged(LPNMHDR lpNMHDR) +LRESULT CDebugMemoryView::OnHxHotAddrChanged(LPNMHDR /*lpNMHDR*/) { - uint32_t address; - bool bData = GetItemAddress(lpNMHDR, address); - - if (!bData) - { - return 0; - } + m_HotAddress = m_HexEditCtrl.GetHotAddress(); + stdstr strAddrInfo = ""; CSymbols::EnterCriticalSection(); + + CSymbolEntry* foundSymbol = NULL; + int numSymbols = CSymbols::GetCount(); - CSymbolEntry* lpSymbol = CSymbols::GetEntryByAddress(address); - - stdstr symbolInfo; - - if (lpSymbol != NULL) + for (int i = 0; i < numSymbols; i++) { - char* desc = lpSymbol->m_Description; - desc = desc ? desc : ""; - symbolInfo = stdstr_f("%08X: %s %s // %s", address, lpSymbol->TypeName(), lpSymbol->m_Name, desc); + CSymbolEntry* symbol = CSymbols::GetEntryByIndex(i); + if (m_HotAddress >= symbol->m_Address && m_HotAddress < symbol->m_Address + symbol->TypeSize()) + { + foundSymbol = symbol; + break; + } + } + + if (foundSymbol != NULL) + { + strAddrInfo += stdstr_f("%08X %s %s", foundSymbol->m_Address, foundSymbol->TypeName(), foundSymbol->m_Name); } else { - symbolInfo = stdstr_f("%08X", address); + strAddrInfo += stdstr_f("%08X\n", m_HotAddress); } + m_StatusBar.SetText(MEMSB_HOTADDR, strAddrInfo.c_str()); + CSymbols::LeaveCriticalSection(); - - m_SymInfo.SetWindowTextA(symbolInfo.c_str()); - - uint32_t romAddr, offset; - DMALOGENTRY* lpEntry = m_Debugger->DMALog()->GetEntryByRamAddress(address, &romAddr, &offset); - - stdstr dmaInfo; - - if (lpEntry != NULL) - { - dmaInfo = stdstr_f("Last DMA: %08X -> %08X [%X] (%08X, +%X) ", lpEntry->romAddr, lpEntry->ramAddr, lpEntry->length, romAddr, offset); - } - else - { - dmaInfo = stdstr_f("Last DMA: ?"); - } - - m_DMAInfo.SetWindowTextA(dmaInfo.c_str()); - - return 0; + return FALSE; } -LRESULT CDebugMemoryView::OnMemoryModified(LPNMHDR lpNMHDR) +LRESULT CDebugMemoryView::OnHxBaseAddrChanged(LPNMHDR /*lpNMHDR*/) { - uint32_t Pos = 0; - bool bData = GetItemOffset(lpNMHDR, Pos); - - if (!bData) - { - return 0; - } - - CListNotify *pListNotify = reinterpret_cast(lpNMHDR); - int LineNumber = pListNotify->m_nItem; - - LPCSTR strValue = m_MemoryList->GetItemText(pListNotify->m_nItem, pListNotify->m_nSubItem); - unsigned long long Value = strtoull(strValue, NULL, 16); - - if (m_CurrentData[Pos] == Value) - { - return 0; - } - - if (m_CompareStartLoc != m_DataStartLoc || - m_CompareVAddrr != m_DataVAddrr) - { - // copy current data for change comparison - m_CompareStartLoc = m_DataStartLoc; - m_CompareVAddrr = m_DataVAddrr; - memcpy(m_CompareData, m_CurrentData, sizeof(m_CurrentData)); - memcpy(m_CompareValid, m_DataValid, sizeof(m_CompareValid)); - } - - m_CompareData[Pos] = m_CurrentData[Pos]; - m_CurrentData[Pos] = (BYTE)Value; - - //sb - __except_try() - { - if (m_DataVAddrr) - { - if (!g_MMU->SB_VAddr(m_DataStartLoc + Pos, (BYTE)Value)) - { - WriteTrace(TraceUserInterface, TraceError, "failed to store at %X", m_DataStartLoc + Pos); - } - } - else - { - if (!g_MMU->SB_PAddr(m_DataStartLoc + Pos, (BYTE)Value)) - { - WriteTrace(TraceUserInterface, TraceError, "failed to store at %X", m_DataStartLoc + Pos); - } - } - uint32_t PhysicalAddress = m_DataStartLoc + Pos; - if (!m_DataVAddrr || g_MMU->TranslateVaddr(PhysicalAddress, PhysicalAddress)) - { - if (PhysicalAddress > 0x10000000 && (PhysicalAddress - 0x10000000) < g_Rom->GetRomSize()) - { - uint8_t * ROM = g_Settings->LoadBool(Game_LoadRomToMemory) ? g_MMU->Rdram() + 0x10000000: g_Rom->GetRomAddress(); - ProtectMemory(ROM, g_Rom->GetRomSize(), MEM_READWRITE); - ROM[(PhysicalAddress - 0x10000000) ^ 3] = (uint8_t)Value; - ProtectMemory(ROM, g_Rom->GetRomSize(), MEM_READONLY); - } - } - if (g_Recompiler != NULL) - { - g_Recompiler->ClearRecompCode_Phys(PhysicalAddress & ~0xFFF, 0x1000, CRecompiler::Remove_MemViewer); - } - } - __except_catch() - { - g_Notify->FatalError(GS(MSG_UNKNOWN_MEM_ACTION)); - } - Insert_MemoryLineDump(LineNumber); - - return 0; + // address was updated from the control + uint32_t address = m_HexEditCtrl.GetBaseAddress(); + m_bIgnoreAddressInput = true; + m_MemAddr.SetValue(address, false, true); + m_CmbJump.SetCurSel(GetJumpItemIndex(address, m_bVirtualMemory)); + UpdateCurrentTab(address); + return FALSE; } -void CDebugMemoryView::OnAddrChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/) +LRESULT CDebugMemoryView::OnHxCopy(LPNMHDR /*lpNMHDR*/) { - RefreshMemory(false); + HXCOLUMN column = m_HexEditCtrl.GetFocusedColumn(); + uint32_t startAddress, endAddress; + m_HexEditCtrl.GetSelectionRange(&startAddress, &endAddress); + CopyBytesToClipboard(startAddress, endAddress, column == HX_COL_HEXDATA); + return FALSE; } -void CDebugMemoryView::OnVScroll(int request, short Pos, HWND ctrl) +LRESULT CDebugMemoryView::OnHxPaste(LPNMHDR lpNMHDR) { - if (ctrl != GetDlgItem(IDC_SCRL_BAR)) - { - return; - } - DWORD Location = m_MemAddr.GetValue(); - switch (request) - { - case SB_LINEDOWN: - m_MemAddr.SetValue(Location < 0xFFFFFFEF ? Location + 0x10 : 0xFFFFFFFF, false, true); - break; - case SB_LINEUP: - m_MemAddr.SetValue(Location > 0x10 ? Location - 0x10 : 0, false, true); - break; - case SB_PAGEDOWN: - m_MemAddr.SetValue(Location < 0xFFFFFEFF ? Location + 0x100 : 0xFFFFFFFF, false, true); - break; - case SB_PAGEUP: - m_MemAddr.SetValue(Location > 0x100 ? Location - 0x100 : 0, false, true); - break; - case SB_THUMBPOSITION: - m_MemAddr.SetValue((DWORD)Pos << 0x10, false, true); - break; - default: - break; - } -} + NMHXPASTE *nmp = reinterpret_cast(lpNMHDR); -LRESULT CDebugMemoryView::OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/) -{ - WORD type = LOWORD(wParam); - - if (type == WA_INACTIVE) + if (g_MMU == NULL) { return FALSE; } - RefreshMemory(false); + OpenClipboard(); + HANDLE hData = GetClipboardData(CF_TEXT); + char* text = (char*)GlobalLock(hData); + int retDataLength = 0; + + if (nmp->column == HX_COL_HEXDATA) + { + char* data = NULL; + // todo move this function to some utility class + int length = CMemoryScanner::ParseHexString(NULL, text); + + if (length != 0) + { + data = (char*)malloc(length); + CMemoryScanner::ParseHexString(data, text); + + for (int i = 0; i < length; i++) + { + SetByte(nmp->address + i, data[i]); + } + + free(data); + } + + retDataLength = length; + } + else if (nmp->column == HX_COL_ASCII) + { + size_t length = strlen(text); + for (size_t i = 0; i < length; i++) + { + SetByte(nmp->address + i, text[i]); + } + + retDataLength = length; + } + + GlobalUnlock(hData); + CloseClipboard(); + + return retDataLength; +} + + +LRESULT CDebugMemoryView::OnTabSelChange(LPNMHDR /*lpNMHDR*/) +{ + TabSelChanged(); + return FALSE; +} + +void CDebugMemoryView::TabSelChanged(void) +{ + TCITEM item = { 0 }; + item.mask = TCIF_PARAM; + + int nItem = m_TabCtrl.GetCurSel(); + + if (m_TabCtrl.GetItem(nItem, &item)) + { + tab_info_t tabInfo = m_TabData[nItem]; + uint32_t address = tabInfo.address; + + m_MemAddr.SetValue(address, false, true); + + if (m_bVirtualMemory != tabInfo.bVirtual) + { + m_bVirtualMemory = tabInfo.bVirtual; + m_VirtualCheckbox.SetCheck(m_bVirtualMemory ? BST_CHECKED : BST_UNCHECKED); + SetupJumpMenu(m_bVirtualMemory); + } + + m_CmbJump.SetCurSel(GetJumpItemIndex(address, m_bVirtualMemory)); + m_HexEditCtrl.SetByteGroupSize(tabInfo.numBytesPerGroup); + } +} + +int CDebugMemoryView::AddTab(uint32_t address, bool bVirtual, int numBytesPerGroup) +{ + char szAddress[12]; + sprintf(szAddress, "%08X", address); + m_TabData.push_back({ address, bVirtual, numBytesPerGroup }); + return m_TabCtrl.AddItem(TCIF_TEXT | TCIF_PARAM, szAddress, 0, (LPARAM)address); +} + +int CDebugMemoryView::InsertTab(int nItem, uint32_t address, bool bVirtual, int numBytesPerGroup) +{ + m_TabData.insert(m_TabData.begin() + nItem + 1, { address, bVirtual, numBytesPerGroup }); + m_TabCtrl.SetRedraw(FALSE); + m_TabCtrl.DeleteAllItems(); + for (size_t i = 0; i < m_TabData.size(); i++) + { + m_TabCtrl.AddItem(TCIF_TEXT, stdstr_f("%08X", m_TabData[i].address).c_str(), 0, 0); + } + m_TabCtrl.SetRedraw(TRUE); + return nItem + 1; +} + +void CDebugMemoryView::DeleteTab(int nItem) +{ + m_TabData.erase(m_TabData.begin() + nItem); + m_TabCtrl.DeleteItem(nItem); +} + +void CDebugMemoryView::UpdateCurrentTab(uint32_t address) +{ + char szAddress[12]; + sprintf(szAddress, "%08X", address); + + int nItem = m_TabCtrl.GetCurSel(); + + if (nItem == -1) + { + return; + } + + TCITEM item = { 0 }; + item.mask = TCIF_TEXT; + item.pszText = szAddress; + + m_TabCtrl.SetRedraw(FALSE); + m_TabCtrl.SetItem(nItem, &item); + m_TabData[nItem].address = address; + m_TabData[nItem].bVirtual = m_bVirtualMemory; + m_TabCtrl.SetRedraw(TRUE); +} + +void CDebugMemoryView::OpenNewTab(uint32_t address, bool bVirtual, int numBytesPerGroup, bool bInsert, bool bOpenExisting) +{ + int nItem; + + if (bOpenExisting) + { + for (size_t i = 0; i < m_TabData.size(); i++) + { + if (m_TabData[i].address == address && m_TabData[i].bVirtual == bVirtual) + { + m_TabCtrl.SetCurSel(i); + TabSelChanged(); + return; + } + } + } + + if (bInsert) + { + int nCurSelItem = m_TabCtrl.GetCurSel(); + nItem = InsertTab(nCurSelItem, address, bVirtual, numBytesPerGroup); + } + else + { + nItem = AddTab(address, bVirtual, numBytesPerGroup); + } + + m_TabCtrl.SetCurSel(nItem); + TabSelChanged(); +} + +void CDebugMemoryView::OpenDuplicateTab(void) +{ + int nItem = m_TabCtrl.GetCurSel(); + tab_info_t tabInfo = m_TabData[nItem]; + int nItemNew = InsertTab(nItem, tabInfo.address, tabInfo.bVirtual, tabInfo.numBytesPerGroup); + m_TabCtrl.SetCurSel(nItemNew); + TabSelChanged(); +} + +void CDebugMemoryView::CloseTab(int nItem) +{ + int itemCount = m_TabCtrl.GetItemCount(); + int nSelItem = m_TabCtrl.GetCurSel(); + + if (itemCount < 2 || nItem == -1) + { + return; + } + + if (nItem == nSelItem) + { + if (nItem == m_TabCtrl.GetItemCount() - 1) + { + // last tab + m_TabCtrl.SetCurSel(nItem - 1); + } + else if (nItem == nSelItem) + { + m_TabCtrl.SetCurSel(nItem + 1); + } + + TabSelChanged(); + } + + DeleteTab(nItem); +} + +void CDebugMemoryView::CloseCurrentTab(void) +{ + CloseTab(m_TabCtrl.GetCurSel()); +} + +LRESULT CDebugMemoryView::OnTabDblClick(LPNMHDR /*lpNMHDR*/) +{ + OpenDuplicateTab(); + return FALSE; +} + +LRESULT CDebugMemoryView::OnTabRClick(LPNMHDR lpNMHDR) +{ + NMMTRCLICK *nmrc = reinterpret_cast(lpNMHDR); + CloseTab(nmrc->nItem); + return FALSE; +} + +LRESULT CDebugMemoryView::OnStatusBarClick(LPNMHDR lpNMHDR) +{ + NMMOUSE *nmm = reinterpret_cast(lpNMHDR); + + uint32_t startAddress, endAddress; + bool bHaveSelection = m_HexEditCtrl.GetSelectionRange(&startAddress, &endAddress); + + if (nmm->dwItemSpec == MEMSB_DMAINFO) + { + uint32_t romAddress, blockOffset; + DMALOGENTRY* entry = m_Debugger->DMALog()->GetEntryByRamAddress(startAddress, &romAddress, &blockOffset); + + if (entry == NULL) + { + return FALSE; + } + + stdstr strDmaTitle = stdstr_f("DMA Information for 0x%08X", startAddress); + stdstr strDmaInfo = stdstr_f("Block:\nROM 0x%08X -> RAM 0x%08X ( 0x%X bytes )\n\nROM address of byte:\n0x%08X ( 0x%08X + 0x%08X )", + entry->romAddr, entry->ramAddr, entry->length, romAddress, entry->romAddr, blockOffset); + MessageBox(strDmaInfo.c_str(), strDmaTitle.c_str(), MB_OK); + } + else if (nmm->dwItemSpec == MEMSB_BLOCK) + { + stdstr strAddrRange; + + if (bHaveSelection) + { + strAddrRange = stdstr_f("%08X:%08X", startAddress, endAddress); + } + else + { + strAddrRange = stdstr_f("%08X", startAddress); + } + + CopyTextToClipboard(strAddrRange.c_str()); + } return FALSE; } -void CDebugMemoryView::ShowAddress(DWORD Address, bool VAddr) +void CDebugMemoryView::OnJumpComboSelChange(UINT /*uNotifyCode*/, int /*nID*/, CWindow /*wndCtl*/) { - if (m_hWnd == NULL) - { - return; - } + int nItem = m_CmbJump.GetCurSel(); + uint32_t address; - SendDlgItemMessage(IDC_CHK_VADDR, BM_SETCHECK, VAddr ? BST_CHECKED : BST_UNCHECKED, 0); - m_MemAddr.SetValue(Address, false, true); - RefreshMemory(true); -} - -void CDebugMemoryView::Insert_MemoryLineDump(int LineNumber) -{ - if (m_MemoryList == NULL || m_MemoryList->GetColumnCount() == 0) + if (m_bVirtualMemory) { - return; - } - char Output[20], Hex[60], Ascii[20], AsciiAddOn[15]; - sprintf(Output, "0x%08X", m_DataStartLoc + (LineNumber << 4)); - if (m_MemoryList->GetItemCount() <= LineNumber) - { - HFONT hFont = (HFONT)GetStockObject(ANSI_FIXED_FONT); - m_MemoryList->AddItemAt(LineNumber, Output); - for (int i = 0; i < m_MemoryList->GetColumnCount(); i++) - { - m_MemoryList->SetItemFont(LineNumber, i, hFont); - if (i == 5 || i == 10 || i == 15) - { - m_MemoryList->SetItemText(LineNumber, i, "-"); - } - } + address = JumpItems[nItem].vaddr; } else { - if (strcmp(Output, m_MemoryList->GetItemText(LineNumber, 0)) != 0) - { - m_MemoryList->SetItemText(LineNumber, 0, Output); - } - } - - Hex[0] = 0; - Ascii[0] = 0; - int CompareStartPos = m_DataStartLoc - m_CompareStartLoc; - - for (int i = 0, col = 1; i < 0x10; i++, col++) - { - int Pos = ((LineNumber << 4) + i); - if (m_DataValid[Pos]) - { - int ComparePos = CompareStartPos + Pos; - bool Changed = false; - - if (ComparePos >= 0 && ComparePos < MemoryToDisplay && - m_DataVAddrr == m_CompareVAddrr && - m_DataValid[ComparePos] && - m_CurrentData[Pos] != m_CompareData[ComparePos]) - { - Changed = true; - } - - sprintf(Hex, "%02X", m_CurrentData[Pos]); - - m_MemoryList->SetItemText(LineNumber, col, Hex); - m_MemoryList->SetItemFormat(LineNumber, col, ITEM_FORMAT_EDIT, ITEM_FLAGS_EDIT_HEX); - m_MemoryList->SetItemMaxEditLen(LineNumber, col, 2); - - uint32_t vaddr = 0x80000000 | (m_DataStartLoc + Pos); - - COLORREF bgColor, fgColor, fgHiColor; - SelectColors(vaddr, Changed, bgColor, fgColor, fgHiColor); - - m_MemoryList->SetItemColours(LineNumber, col, bgColor, fgColor); - m_MemoryList->SetItemHighlightColours(LineNumber, col, fgHiColor); - - if (m_CurrentData[Pos] < 30) - { - strcat(Ascii, "."); - } - else - { - sprintf(AsciiAddOn, "%c", m_CurrentData[Pos]); - strcat(Ascii, AsciiAddOn); - } - } - else - { - m_MemoryList->SetItemText(LineNumber, col, "**"); - m_MemoryList->SetItemFormat(LineNumber, col, ITEM_FORMAT_NONE, ITEM_FLAGS_NONE); - m_MemoryList->SetItemColours(LineNumber, col, GetSysColor(COLOR_WINDOW), GetSysColor(COLOR_WINDOWTEXT)); - strcat(Ascii, "*"); - } - if (i != 0xF) - { - if ((i & 3) == 3) - { - col += 1; - } - } - } - - if (strcmp(Ascii, m_MemoryList->GetItemText(LineNumber, 20)) != 0) - { - m_MemoryList->SetItemText(LineNumber, 20, Ascii); + address = JumpItems[nItem].paddr; } -} - -void CDebugMemoryView::RefreshMemory(bool ResetCompare) -{ - m_SymbolColorPhase = 0; - - if (g_MMU == NULL) - { - return; - } - - if (m_MemoryList && m_MemoryList->GetHasEditItem()) - { - m_MemoryList->SetFocus(); - } - - DWORD NewAddress = m_MemAddr.GetValue(); - if (NewAddress != m_DataStartLoc) - { - HWND hScrlBar = GetDlgItem(IDC_SCRL_BAR); - if (hScrlBar) - { - SCROLLINFO si; - - si.cbSize = sizeof(si); - si.fMask = SIF_POS; - si.nPos = NewAddress >> 0x10; - ::SetScrollInfo(hScrlBar, SB_CTL, &si, TRUE); - } - } - - if (ResetCompare) - { - // copy current data for change comparison - m_CompareStartLoc = m_DataStartLoc; - m_CompareVAddrr = m_DataVAddrr; - memcpy(m_CompareData, m_CurrentData, sizeof(m_CurrentData)); - memcpy(m_CompareValid, m_DataValid, sizeof(m_CompareValid)); - } - - m_DataStartLoc = m_MemAddr.GetValue(); - if (m_DataStartLoc > 0xFFFFFF00) { m_DataStartLoc = 0xFFFFFF00; } - int WritePos = 0; - - m_DataVAddrr = (SendDlgItemMessage(IDC_CHK_VADDR, BM_GETCHECK, 0, 0) & BST_CHECKED) != 0; - - if ((m_DataStartLoc & 3) != 0) - { - MIPS_WORD word; - bool ValidData = true; - - if (m_DataVAddrr) - { - if (!m_Debugger->DebugLW_VAddr(m_DataStartLoc & ~3, word.UW)) - { - ValidData = false; - } - } - else - { - if (!m_Debugger->DebugLW_PAddr(m_DataStartLoc & ~3, word.UW)) - { - ValidData = false; - } - } - - int Offset = (m_DataStartLoc & 3); - for (int i = 0; i < (4 - Offset); i++) - { - if (WritePos >= MemoryToDisplay) - { - break; - } - m_DataValid[WritePos + i] = ValidData; - if (ValidData) - { - m_CurrentData[WritePos + i] = word.UB[3 - (i + Offset)]; - } - } - WritePos = 4 - Offset; - } - - for (DWORD Pos = ((m_DataStartLoc + 3) & ~3); Pos < (m_DataStartLoc + MemoryToDisplay); WritePos += 4, Pos += 4) - { - MIPS_WORD word; - bool ValidData = true; - - if (m_DataVAddrr) - { - if (!m_Debugger->DebugLW_VAddr(Pos, word.UW)) - { - ValidData = false; - } - } - else - { - if (!m_Debugger->DebugLW_PAddr(Pos, word.UW)) - { - ValidData = false; - } - } - - for (int i = 0; i < 4; i++) - { - if ((WritePos + i) >= MemoryToDisplay) - { - break; - } - m_DataValid[WritePos + i] = ValidData; - if (ValidData) - { - m_CurrentData[WritePos + i] = word.UB[3 - i]; - } - } - } - - for (int count = 0; count < 16; count++) - { - Insert_MemoryLineDump(count); - } -} - -bool CDebugMemoryView::GetItemOffset(LPNMHDR lpNMHDR, uint32_t &offset) -{ - CListNotify *pListNotify = reinterpret_cast(lpNMHDR); - - int nRow = pListNotify->m_nItem; - int nCol = pListNotify->m_nSubItem - 1; - - if (nCol < 0 || (nCol % 5) == 4) - { - return false; - } - - offset = (nRow * 0x10) + (nCol / 5) * 4 + (nCol % 5); - - return true; -} - -bool CDebugMemoryView::GetItemAddress(LPNMHDR lpNMHDR, uint32_t &address) -{ - uint32_t offset; - bool bData = GetItemOffset(lpNMHDR, offset); - - if (!bData) - { - return false; - } - - address = 0x80000000 | (m_DataStartLoc + offset); - - return true; -} - -void CDebugMemoryView::SelectColors(uint32_t vaddr, bool changed, COLORREF& bgColor, COLORREF& fgColor, COLORREF& fgHiColor) -{ - CSymbols::EnterCriticalSection(); - CSymbolEntry* lpSymbol = CSymbols::GetEntryByAddress(vaddr); - - if (lpSymbol != NULL) - { - m_SymbolColorStride = lpSymbol->TypeSize(); - m_SymbolColorPhase = m_SymbolColorPhase ? 0 : 1; - } - - CSymbols::LeaveCriticalSection(); - - bool bLocked = m_Breakpoints->MemLockExists(vaddr, 1); - bool bHaveReadBP = m_Breakpoints->ReadBPExists8(vaddr) == CBreakpoints::BP_SET; - bool bHaveWriteBP = m_Breakpoints->WriteBPExists8(vaddr) == CBreakpoints::BP_SET; - - fgHiColor = RGB(0x00, 0x00, 0x00); - - if (bLocked) - { - bgColor = RGB(0xDD, 0xAA, 0xAA); - } - else if (bHaveReadBP && bHaveWriteBP) - { - bgColor = RGB(0xAA, 0xDD, 0xDD); - } - else if (bHaveReadBP) - { - bgColor = RGB(0xDD, 0xDD, 0xAA); - } - else if (bHaveWriteBP) - { - bgColor = RGB(0xAA, 0xAA, 0xDD); - } - else if (m_SymbolColorStride > 0) - { - bgColor = m_SymbolColorPhase ? RGB(0xD0, 0xF0, 0xD0) : RGB(0xAA, 0xCC, 0xAA); - } - else - { - bgColor = GetSysColor(COLOR_WINDOW); - fgHiColor = (changed ? RGB(255, 0, 0) : GetSysColor(COLOR_HIGHLIGHTTEXT)); - fgColor = (changed ? RGB(255, 0, 0) : GetSysColor(COLOR_WINDOWTEXT)); - } - - if (m_SymbolColorStride > 0) - { - m_SymbolColorStride--; - } -} - -void CDebugMemoryView::CopyNumber(uint32_t address, int numBytes) -{ - stdstr str; - - uint32_t u32; - uint16_t u16; - uint8_t u8; - - switch (numBytes) - { - case 4: - address &= ~3; - g_MMU->LW_VAddr(address, u32); - str = stdstr_f("%08X", u32); - break; - case 2: - address &= ~1; - g_MMU->LH_VAddr(address, u16); - str = stdstr_f("%04X", u16); - break; - case 1: - g_MMU->LB_VAddr(address, u8); - str = stdstr_f("%02X", u8); - break; - default: - return; - } - - if (str.length() == 0) - { - return; - } - - HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, str.length() + 1); - str.copy((char*)GlobalLock(hMem), str.length() + 1); - GlobalUnlock(hMem); - OpenClipboard(); - EmptyClipboard(); - SetClipboardData(CF_TEXT, hMem); - CloseClipboard(); + + m_MemAddr.SetValue(address, false, true); + m_HexEditCtrl.SetFocus(); } diff --git a/Source/Project64/UserInterface/Debugger/Debugger-ViewMemory.h b/Source/Project64/UserInterface/Debugger/Debugger-ViewMemory.h index 3d0b26f01..36e59e88b 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger-ViewMemory.h +++ b/Source/Project64/UserInterface/Debugger/Debugger-ViewMemory.h @@ -11,9 +11,78 @@ #pragma once #include "Debugger-AddSymbol.h" +#include +#include + +typedef struct +{ + NMHDR nmh; + int nItem; +} NMMTRCLICK; + +enum +{ + MTCN_RCLICK +}; + +class CMemTabCtrl : + public CWindowImpl +{ +private: + int m_nItemRClick; + +public: + CMemTabCtrl() : + m_nItemRClick(-1) + { + } + + BOOL Attach(HWND hWndNew) + { + return SubclassWindow(hWndNew); + } + +private: + void OnLButtonDblClk(UINT /*nFlags*/, CPoint /*point*/) + { + NMHDR nmh = { m_hWnd, (UINT_PTR)::GetDlgCtrlID(m_hWnd), NM_DBLCLK }; + ::SendMessage(::GetParent(m_hWnd), WM_NOTIFY, NM_DBLCLK, (LPARAM)&nmh); + } + + void OnRButtonDown(UINT /*nFlags*/, CPoint point) + { + TCHITTESTINFO ht = { point, 0}; + int nItem = ::SendMessage(m_hWnd, TCM_HITTEST, 0, (LPARAM)&ht); + if (nItem != -1) + { + m_nItemRClick = nItem; + } + } + + void OnRButtonUp(UINT /*nFlags*/, CPoint point) + { + TCHITTESTINFO ht = { point, 0 }; + int nItem = ::SendMessage(m_hWnd, TCM_HITTEST, 0, (LPARAM)&ht); + if (nItem != -1 && nItem == m_nItemRClick) + { + NMMTRCLICK nmrc = { { m_hWnd, (UINT_PTR)::GetDlgCtrlID(m_hWnd), MTCN_RCLICK }, nItem }; + ::SendMessage(::GetParent(m_hWnd), WM_NOTIFY, MTCN_RCLICK, (LPARAM)&nmrc); + } + m_nItemRClick = -1; + } + + BEGIN_MSG_MAP_EX(CMemTabCtrl) + MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk) + MSG_WM_RBUTTONDOWN(OnRButtonDown) + MSG_WM_RBUTTONUP(OnRButtonUp) + MSG_WM_RBUTTONDBLCLK(OnRButtonDown) + END_MSG_MAP() +}; class CDebugMemoryView : - public CDebugDialog < CDebugMemoryView > + public CDebugDialog, + public CDialogResize, + public CToolTipDialog { public: enum { IDD = IDD_Debugger_Memory }; @@ -21,74 +90,201 @@ public: CDebugMemoryView(CDebuggerUI * debugger); virtual ~CDebugMemoryView(void); - void ShowAddress(DWORD Address, bool VAddr); + void ShowAddress(uint32_t address, bool bVirtual); private: + enum + { + WM_SHOWADDRESS = WM_USER + 1 + }; + + enum + { + COLOR_DEFAULT = RGB(0, 0, 0), + COLOR_READONLY = RGB(0, 100, 0), + BKCOLOR_DEFAULT = RGB(255, 255, 255), + COLOR_CHANGED = RGB(255, 0, 0), + BKCOLOR_HOT = RGB(240, 240, 240), + BKCOLOR_LOCKED = RGB(100, 100, 0), + COLOR_BP = RGB(255, 255, 255), + BKCOLOR_RWBP = RGB(100, 0, 100), + BKCOLOR_RBP = RGB(0, 0, 100), + BKCOLOR_WBP = RGB(100, 0, 0), + BKCOLOR_CPUREAD = RGB(200, 200, 255), + BKCOLOR_CPUWRITE = RGB(255, 200, 200), + BKCOLOR_SYMBOL0 = RGB(208, 240, 208), + BKCOLOR_SYMBOL1 = RGB(176, 208, 176), + BKCOLOR_SAFEEDIT = RGB(255, 230, 255), + COLOR_SAFEEDIT = RGB(255, 0, 255) + }; + + enum + { + MEMSB_HOTADDR, + MEMSB_BLOCK, + MEMSB_BLOCKLEN, + MEMSB_DMAINFO, + MEMSB_SAFEMODE, + MEMSB_NUM_PANES + }; + + enum + { + MEMSB_HOTADDR_W = 160, + MEMSB_BLOCK_W = 120 + MEMSB_HOTADDR_W, + MEMSB_BLOCKLEN_W = 60 + MEMSB_BLOCK_W, + MEMSB_DMAINFO_W = 60 + MEMSB_BLOCKLEN_W, + MEMSB_SAFEMODE_W = -1 + }; + + enum edit_type_t + { + SE_FILL, + //SE_DATA + }; + + typedef struct + { + edit_type_t type; + uint32_t startAddress; + uint32_t endAddress; + uint8_t value; + //uint8_t* data; + } edit_t; + + typedef struct + { + uint32_t vaddr; + uint32_t paddr; + uint32_t size; + const char* caption; + } jump_item_t; + + typedef struct + { + uint32_t address; + bool bVirtual; + int numBytesPerGroup; + } tab_info_t; + + static jump_item_t JumpItems[]; + static int GetJumpItemIndex(uint32_t address, bool bVirtual); + + CHexEditCtrl m_HexEditCtrl; + CEditNumber32 m_MemAddr; + CAddSymbolDlg m_AddSymbolDlg; + CButton m_VirtualCheckbox; + CMemTabCtrl m_TabCtrl; + CStatusBarCtrl m_StatusBar; + CComboBox m_CmbJump; + + std::vector m_TabData; + CBreakpoints* m_Breakpoints; + + int m_WriteTargetColorStride; + int m_ReadTargetColorStride; + int m_SymbolColorStride; + int m_SymbolColorPhase; + uint32_t m_ContextMenuAddress; + uint32_t m_HotAddress; + bool m_bIgnoreAddressInput; + bool m_bVirtualMemory; + + bool m_bSafeEditMode; + std::vector m_SafeEditQueue; + + bool GetByte(uint32_t address, uint8_t* value); + bool SetByte(uint32_t address, uint8_t value); + void SetupJumpMenu(bool bVirtual); + bool GetSafeEditValue(uint32_t address, uint8_t* value); + void ApplySafeEdits(void); + void CopyTextToClipboard(const char* text); + void CopyBytesToClipboard(uint32_t startAddress, uint32_t endAddress, bool bHex, bool bIncludeAddresses = false, bool bRowAddresses = false); + void CopyGameSharkCodeToClipboard(uint32_t startAddress, uint32_t endAddress); + void FillRange(uint32_t startAddress, uint32_t endAddress, uint8_t value); + void FollowPointer(bool bContextMenuAddress = true); + void JumpToSelection(void); + int AddTab(uint32_t address, bool bVirtual, int numBytesPerGroup); + int InsertTab(int nItem, uint32_t address, bool bVirtual, int numBytesPerGroup); + void DeleteTab(int index); + void UpdateCurrentTab(uint32_t address); + void OpenNewTab(uint32_t address, bool bVirtual, int numBytesPerGroup, bool bInsert = false, bool bOpenExisting = false); + void OpenDuplicateTab(void); + void CloseTab(int nItem); + void CloseCurrentTab(void); + void TabSelChanged(void); + + LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnShowAddress(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); + LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled); + void OnAddrChanged(UINT Code, int id, HWND ctl); + void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar); + void OnExitSizeMove(void); + LRESULT OnDestroy(void); + LRESULT OnHxGetByteInfo(LPNMHDR lpNMHDR); + LRESULT OnHxSetNibble(LPNMHDR lpNMHDR); + LRESULT OnHxSetByte(LPNMHDR lpNMHDR); + LRESULT OnHxRightClick(LPNMHDR lpNMHDR); + LRESULT OnHxEnterPressed(LPNMHDR lpNMHDR); + LRESULT OnHxRedrawStarted(LPNMHDR lpNMHDR); + LRESULT OnHxBaseAddrChanged(LPNMHDR lpNMHDR); + LRESULT OnHxHotAddrChanged(LPNMHDR lpNMHDR); + LRESULT OnHxCopy(LPNMHDR lpNMHDR); + LRESULT OnHxPaste(LPNMHDR lpNMHDR); + LRESULT OnHxCtrlKeyPressed(LPNMHDR lpNMHDR); + LRESULT OnHxFillRange(LPNMHDR lpNMHDR); + LRESULT OnHxInsertModeChanged(LPNMHDR lpNMHDR); + LRESULT OnHxSelectionChanged(LPNMHDR lpNMHDR); + LRESULT OnHxGroupSizeChanged(LPNMHDR lpNMHDR); + LRESULT OnTabSelChange(LPNMHDR lpNMHDR); + LRESULT OnTabDblClick(LPNMHDR lpNMHDR); + LRESULT OnTabRClick(LPNMHDR lpNMHDR); + LRESULT OnStatusBarClick(LPNMHDR lpNMHDR); + void OnJumpComboSelChange(UINT uNotifyCode, int nID, CWindow wndCtl); + BEGIN_MSG_MAP_EX(CDebugMemoryView) MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) + MESSAGE_HANDLER(WM_SHOWADDRESS, OnShowAddress) COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked) COMMAND_HANDLER_EX(IDC_ADDR_EDIT, EN_CHANGE, OnAddrChanged) - NOTIFY_HANDLER_EX(IDC_MEM_DETAILS, LCN_MODIFIED, OnMemoryModified) - NOTIFY_HANDLER_EX(IDC_MEM_DETAILS, LCN_RIGHTCLICK, OnMemoryRightClicked) - NOTIFY_HANDLER_EX(IDC_MEM_DETAILS, LCN_HOTITEMCHANGED, OnHotItemChanged) - MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) MSG_WM_EXITSIZEMOVE(OnExitSizeMove) MSG_WM_DESTROY(OnDestroy) MSG_WM_VSCROLL(OnVScroll) + COMMAND_HANDLER_EX(IDC_CMB_JUMP, CBN_SELCHANGE, OnJumpComboSelChange) + NOTIFY_HANDLER_EX(IDC_STATUSBAR, NM_CLICK, OnStatusBarClick) + NOTIFY_HANDLER_EX(IDC_MEMTABS, NM_DBLCLK, OnTabDblClick) + NOTIFY_HANDLER_EX(IDC_MEMTABS, TCN_SELCHANGE, OnTabSelChange) + NOTIFY_HANDLER_EX(IDC_MEMTABS, MTCN_RCLICK, OnTabRClick) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_GETBYTEINFO, OnHxGetByteInfo) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_SETNIBBLE, OnHxSetNibble) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_SETBYTE, OnHxSetByte) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_RCLICK, OnHxRightClick) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_HOTADDRCHANGED, OnHxHotAddrChanged) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_REDRAWSTARTED, OnHxRedrawStarted) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_BASEADDRCHANGED, OnHxBaseAddrChanged) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_HOTADDRCHANGED, OnHxHotAddrChanged) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_PASTE, OnHxPaste) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_CTRLKEYPRESSED, OnHxCtrlKeyPressed) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_FILLRANGE, OnHxFillRange) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_COPY, OnHxCopy) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_INSERTMODECHANGED, OnHxInsertModeChanged) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_ENTERPRESSED, OnHxEnterPressed) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_SELCHANGED, OnHxSelectionChanged) + NOTIFY_HANDLER_EX(IDC_HEXEDIT, HXN_GROUPSIZECHANGED, OnHxGroupSizeChanged) + CHAIN_MSG_MAP(CDialogResize) END_MSG_MAP() - LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/); - LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled); - void OnAddrChanged(UINT Code, int id, HWND ctl); - void OnVScroll(int request, short Pos, HWND ctrl); - void OnExitSizeMove(void); - LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); - LRESULT OnMemoryModified(LPNMHDR lpNMHDR); - LRESULT OnMemoryRightClicked(LPNMHDR lpNMHDR); - LRESULT OnHotItemChanged(LPNMHDR lpNMHDR); - LRESULT OnDestroy(void); + BEGIN_DLGRESIZE_MAP(CDebugMemoryView) + DLGRESIZE_CONTROL(IDC_CMB_JUMP, DLSZ_MOVE_X) + DLGRESIZE_CONTROL(IDC_STATUSBAR, DLSZ_SIZE_X | DLSZ_MOVE_Y) + DLGRESIZE_CONTROL(IDC_HEXEDIT, DLSZ_SIZE_X | DLSZ_SIZE_Y) + DLGRESIZE_CONTROL(IDC_MEMTABS, DLSZ_SIZE_X) + DLGRESIZE_CONTROL(IDC_SCRL_BAR, DLSZ_MOVE_X | DLSZ_SIZE_Y) + END_DLGRESIZE_MAP() - void Insert_MemoryLineDump(int LineNumber); - void RefreshMemory(bool ResetCompare); + BEGIN_TOOLTIP_MAP() + TOOLTIP(IDC_SYMBOLS_BTN, "Symbols...") + TOOLTIP(IDC_CHK_VADDR, "Checked = Use virtual address space (CPU), Unchecked = Use physical address space (RCP)") + END_TOOLTIP_MAP() +}; - HANDLE m_AutoRefreshThread; - static DWORD WINAPI AutoRefreshProc(void* _self); - - void SelectColors(uint32_t address, bool changed, COLORREF& bgColor, COLORREF& fgColor, COLORREF& fgHiColor); - bool GetItemOffset(LPNMHDR lpNMHDR, uint32_t &offset); - bool GetItemAddress(LPNMHDR lpNMHDR, uint32_t &address); - - void CopyNumber(uint32_t address, int numBytes); - - enum { MemoryToDisplay = 0x100 }; - - static CDebugMemoryView* _this; - static HHOOK hWinMessageHook; - static LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam); - - void InterceptMouseWheel(WPARAM wParam, LPARAM lParam); - - CEditNumber32 m_MemAddr; - CListCtrl * m_MemoryList; - CAddSymbolDlg m_AddSymbolDlg; - CStatic m_SymInfo; - CStatic m_DMAInfo; - - bool m_bAutoRefreshEnabled; - - CBreakpoints* m_Breakpoints; - - int m_SymbolColorStride; - int m_SymbolColorPhase; - DWORD m_CtxMenuAddr; - - DWORD m_DataStartLoc; - bool m_DataVAddrr; - BYTE m_CurrentData[MemoryToDisplay]; - bool m_DataValid[MemoryToDisplay]; - - DWORD m_CompareStartLoc; - bool m_CompareVAddrr; - BYTE m_CompareData[MemoryToDisplay]; - bool m_CompareValid[MemoryToDisplay]; -}; \ No newline at end of file diff --git a/Source/Project64/UserInterface/Debugger/Debugger.cpp b/Source/Project64/UserInterface/Debugger/Debugger.cpp index 37889575e..6882787d4 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger.cpp @@ -233,10 +233,6 @@ void CDebuggerUI::OpenMemoryDump() void CDebuggerUI::OpenMemoryWindow(void) { - if (g_MMU == NULL) - { - return; - } if (m_MemoryView == NULL) { m_MemoryView = new CDebugMemoryView(this); @@ -462,192 +458,6 @@ CCPULog* CDebuggerUI::CPULog() return m_CPULog; } -// thread safe LW_PAddr -// does not trigger application breakpoint if paddr is invalid -bool CDebuggerUI::DebugLW_PAddr(uint32_t paddr, uint32_t& value) -{ - if (g_MMU == NULL) - { - return false; - } - - if ((paddr < g_MMU->RdramSize()) || // RDRAM - (paddr >= 0x04000000 && paddr <= 0x04001FFF)) // DMEM/IMEM - { - value = *(uint32_t*)(g_MMU->Rdram() + paddr); - return true; - } - else if (paddr >= 0x05000000 && paddr <= 0x050004FF) // 64DD buffer - { - // todo - return false; - } - else if (paddr >= 0x06000000 && paddr <= 0x06FFFFFF) // Cartridge Domain 1 (Address 1) (64DD IPL ROM) - { - uint32_t iplRomOffset = paddr - 0x06000000; - - if (g_DDRom != NULL && iplRomOffset < g_DDRom->GetRomSize()) - { - value = *(uint32_t*)(g_MMU->Rdram() + paddr); - return true; - } - } - else if (paddr >= 0x08000000 && paddr < 0x08FFFFFF) // Cartridge Domain 2 (Address 2) - { - uint32_t saveOffset = paddr & 0x000FFFFF; - - if (g_System->m_SaveUsing == SaveChip_Sram && saveOffset <= 0x7FFF) // sram - { - uint8_t tmp[4] = ""; - CSram *sram = g_MMU->GetSram(); - sram->DmaFromSram(tmp, paddr - 0x08000000, 4); - value = tmp[3] << 24 | tmp[2] << 16 | tmp[1] << 8 | tmp[0]; - return true; - } - else if (g_System->m_SaveUsing == SaveChip_FlashRam && saveOffset == 0) // flash ram status - { - CFlashram* flashRam = g_MMU->GetFlashram(); - value = flashRam->ReadFromFlashStatus(0x08000000); - return true; - } - } - else if (paddr >= 0x10000000 && paddr <= 0x15FFFFFF) // Cartridge ROM - { - uint32_t cartRomOffset = paddr - 0x10000000; - if (g_Rom != NULL && paddr < g_Rom->GetRomSize()) - { - value = *(uint32_t*)(g_Rom->GetRomAddress() + cartRomOffset); - return true; - } - } - else if (paddr >= 0x1FC00000 && paddr <= 0x1FC007BF) // PIF ROM - { - return false; - } - else if (paddr >= 0x1FC007C0 && paddr <= 0x1FC007FF) // PIF RAM - { - uint32_t pifRamOffset = paddr - 0x1FC007C0; - value = *(uint32_t*)(g_MMU->PifRam() + pifRamOffset); - return true; - } - - // note: write-only registers are excluded - switch (paddr) - { - case 0x03F00000: value = g_Reg->RDRAM_CONFIG_REG; return true; - case 0x03F00004: value = g_Reg->RDRAM_DEVICE_ID_REG; return true; - case 0x03F00008: value = g_Reg->RDRAM_DELAY_REG; return true; - case 0x03F0000C: value = g_Reg->RDRAM_MODE_REG; return true; - case 0x03F00010: value = g_Reg->RDRAM_REF_INTERVAL_REG; return true; - case 0x03F00014: value = g_Reg->RDRAM_REF_ROW_REG; return true; - case 0x03F00018: value = g_Reg->RDRAM_RAS_INTERVAL_REG; return true; - case 0x03F0001C: value = g_Reg->RDRAM_MIN_INTERVAL_REG; return true; - case 0x03F00020: value = g_Reg->RDRAM_ADDR_SELECT_REG; return true; - case 0x03F00024: value = g_Reg->RDRAM_DEVICE_MANUF_REG; return true; - case 0x04040010: value = g_Reg->SP_STATUS_REG; return true; - case 0x04040014: value = g_Reg->SP_DMA_FULL_REG; return true; - case 0x04040018: value = g_Reg->SP_DMA_BUSY_REG; return true; - case 0x0404001C: value = g_Reg->SP_SEMAPHORE_REG; return true; - case 0x04080000: value = g_Reg->SP_PC_REG; return true; - case 0x0410000C: value = g_Reg->DPC_STATUS_REG; return true; - case 0x04100010: value = g_Reg->DPC_CLOCK_REG; return true; - case 0x04100014: value = g_Reg->DPC_BUFBUSY_REG; return true; - case 0x04100018: value = g_Reg->DPC_PIPEBUSY_REG; return true; - case 0x0410001C: value = g_Reg->DPC_TMEM_REG; return true; - case 0x04300000: value = g_Reg->MI_MODE_REG; return true; - case 0x04300004: value = g_Reg->MI_VERSION_REG; return true; - case 0x04300008: value = g_Reg->MI_INTR_REG; return true; - case 0x0430000C: value = g_Reg->MI_INTR_MASK_REG; return true; - case 0x04400000: value = g_Reg->VI_STATUS_REG; return true; - case 0x04400004: value = g_Reg->VI_ORIGIN_REG; return true; - case 0x04400008: value = g_Reg->VI_WIDTH_REG; return true; - case 0x0440000C: value = g_Reg->VI_INTR_REG; return true; - case 0x04400010: value = g_Reg->VI_V_CURRENT_LINE_REG; return true; - case 0x04400014: value = g_Reg->VI_BURST_REG; return true; - case 0x04400018: value = g_Reg->VI_V_SYNC_REG; return true; - case 0x0440001C: value = g_Reg->VI_H_SYNC_REG; return true; - case 0x04400020: value = g_Reg->VI_LEAP_REG; return true; - case 0x04400024: value = g_Reg->VI_H_START_REG; return true; - case 0x04400028: value = g_Reg->VI_V_START_REG; return true; - case 0x0440002C: value = g_Reg->VI_V_BURST_REG; return true; - case 0x04400030: value = g_Reg->VI_X_SCALE_REG; return true; - case 0x04400034: value = g_Reg->VI_Y_SCALE_REG; return true; - case 0x04600000: value = g_Reg->PI_DRAM_ADDR_REG; return true; - case 0x04600004: value = g_Reg->PI_CART_ADDR_REG; return true; - case 0x04600008: value = g_Reg->PI_RD_LEN_REG; return true; - case 0x0460000C: value = g_Reg->PI_WR_LEN_REG; return true; - case 0x04600010: value = g_Reg->PI_STATUS_REG; return true; - case 0x04600014: value = g_Reg->PI_DOMAIN1_REG; return true; - case 0x04600018: value = g_Reg->PI_BSD_DOM1_PWD_REG; return true; - case 0x0460001C: value = g_Reg->PI_BSD_DOM1_PGS_REG; return true; - case 0x04600020: value = g_Reg->PI_BSD_DOM1_RLS_REG; return true; - case 0x04600024: value = g_Reg->PI_DOMAIN2_REG; return true; - case 0x04600028: value = g_Reg->PI_BSD_DOM2_PWD_REG; return true; - case 0x0460002C: value = g_Reg->PI_BSD_DOM2_PGS_REG; return true; - case 0x04600030: value = g_Reg->PI_BSD_DOM2_RLS_REG; return true; - case 0x04700000: value = g_Reg->RI_MODE_REG; return true; - case 0x04700004: value = g_Reg->RI_CONFIG_REG; return true; - case 0x04700008: value = g_Reg->RI_CURRENT_LOAD_REG; return true; - case 0x0470000C: value = g_Reg->RI_SELECT_REG; return true; - case 0x04700010: value = g_Reg->RI_REFRESH_REG; return true; - case 0x04700014: value = g_Reg->RI_LATENCY_REG; return true; - case 0x04700018: value = g_Reg->RI_RERROR_REG; return true; - case 0x0470001C: value = g_Reg->RI_WERROR_REG; return true; - case 0x04800018: value = g_Reg->SI_STATUS_REG; return true; - case 0x05000500: value = g_Reg->ASIC_DATA; return true; - case 0x05000504: value = g_Reg->ASIC_MISC_REG; return true; - case 0x05000508: value = g_Reg->ASIC_STATUS; return true; - case 0x0500050C: value = g_Reg->ASIC_CUR_TK; return true; - case 0x05000510: value = g_Reg->ASIC_BM_STATUS; return true; - case 0x05000514: value = g_Reg->ASIC_ERR_SECTOR; return true; - case 0x05000518: value = g_Reg->ASIC_SEQ_STATUS; return true; - case 0x0500051C: value = g_Reg->ASIC_CUR_SECTOR; return true; - case 0x05000520: value = g_Reg->ASIC_HARD_RESET; return true; - case 0x05000524: value = g_Reg->ASIC_C1_S0; return true; - case 0x05000528: value = g_Reg->ASIC_HOST_SECBYTE; return true; - case 0x0500052C: value = g_Reg->ASIC_C1_S2; return true; - case 0x05000530: value = g_Reg->ASIC_SEC_BYTE; return true; - case 0x05000534: value = g_Reg->ASIC_C1_S4; return true; - case 0x05000538: value = g_Reg->ASIC_C1_S6; return true; - case 0x0500053C: value = g_Reg->ASIC_CUR_ADDR; return true; - case 0x05000540: value = g_Reg->ASIC_ID_REG; return true; - case 0x05000544: value = g_Reg->ASIC_TEST_REG; return true; - case 0x05000548: value = g_Reg->ASIC_TEST_PIN_SEL; return true; - case 0x04500004: - if (g_System->bFixedAudio()) - { - value = g_Audio->GetLength(); - } - else - { - CAudioPlugin* audioPlg = g_Plugins->Audio(); - value = (audioPlg->AiReadLength != NULL) ? audioPlg->AiReadLength() : 0; - } - return true; - case 0x0450000C: - value = g_System->bFixedAudio() ? g_Audio->GetStatus() : g_Reg->AI_STATUS_REG; - return true; - } - - return false; -} - -bool CDebuggerUI::DebugLW_VAddr(uint32_t vaddr, uint32_t& value) -{ - if (vaddr <= 0x7FFFFFFF || vaddr >= 0xC0000000) // KUSEG, KSEG2 (TLB) - { - if (g_MMU == NULL) - { - return false; - } - - return g_MMU->LW_VAddr(vaddr, value); - } - - uint32_t paddr = vaddr & 0x1FFFFFFF; - return DebugLW_PAddr(paddr, value); -} - // CDebugger implementation void CDebuggerUI::TLBChanged() diff --git a/Source/Project64/UserInterface/Debugger/MemoryScanner.cpp b/Source/Project64/UserInterface/Debugger/MemoryScanner.cpp index e7957bfc8..6e0207598 100644 --- a/Source/Project64/UserInterface/Debugger/MemoryScanner.cpp +++ b/Source/Project64/UserInterface/Debugger/MemoryScanner.cpp @@ -989,9 +989,9 @@ bool CMemoryScanner::NextScan() int CMemoryScanner::HexDigitVal(char c) { - if (c >= '0' && c < '9') return (c - '0'); - if (c >= 'A' && c < 'F') return (c - 'A') + 0x0A; - if (c >= 'a' && c < 'f') return (c - 'a') + 0x0A; + if (c >= '0' && c <= '9') return (c - '0'); + if (c >= 'A' && c <= 'F') return (c - 'A') + 0x0A; + if (c >= 'a' && c <= 'f') return (c - 'a') + 0x0A; return 0; } diff --git a/Source/Project64/UserInterface/Debugger/debugger.h b/Source/Project64/UserInterface/Debugger/debugger.h index 20e23ca83..89836b177 100644 --- a/Source/Project64/UserInterface/Debugger/debugger.h +++ b/Source/Project64/UserInterface/Debugger/debugger.h @@ -12,6 +12,7 @@ #include #include #include +#include "DebugMMU.h" class CDumpMemory; class CDebugMemoryView; @@ -33,7 +34,8 @@ class CScriptSystem; class CDebuggerUI : public CDebugger, - public CDebugSettings + public CDebugSettings, + public CDebugMMU { public: CDebuggerUI(); @@ -88,8 +90,8 @@ public: static void GameNameChanged(CDebuggerUI * _this); static void SteppingOpsChanged(CDebuggerUI * _this); - bool DebugLW_PAddr(uint32_t vaddr, uint32_t& value); - bool DebugLW_VAddr(uint32_t vaddr, uint32_t& value); + //bool DebugLW_PAddr(uint32_t vaddr, uint32_t& value); + //bool DebugLW_VAddr(uint32_t vaddr, uint32_t& value); protected: void TLBChanged(void); diff --git a/Source/Project64/UserInterface/MainMenu.cpp b/Source/Project64/UserInterface/MainMenu.cpp index de7e3ca79..c66139546 100644 --- a/Source/Project64/UserInterface/MainMenu.cpp +++ b/Source/Project64/UserInterface/MainMenu.cpp @@ -1252,7 +1252,6 @@ void CMainMenu::FillOutMenu(HMENU hMenu) Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugR4300Menu, L"&R4300i"); DebugMenu.push_back(Item); Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugMemoryMenu, L"Memory"); - Item.SetItemEnabled(CPURunning); DebugMenu.push_back(Item); DebugMenu.push_back(MENU_ITEM(SPLITER)); Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugProfileMenu, L"Profile"); diff --git a/Source/Project64/UserInterface/UIResources.rc b/Source/Project64/UserInterface/UIResources.rc index f20c5839f..727d35b84 100644 --- a/Source/Project64/UserInterface/UIResources.rc +++ b/Source/Project64/UserInterface/UIResources.rc @@ -509,24 +509,19 @@ BEGIN COMBOBOX IDC_LANG_SEL,105,77,112,120,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP END -IDD_Debugger_Memory DIALOGEX 0, 0, 435, 204 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +IDD_Debugger_Memory DIALOGEX 0, 0, 321, 199 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME CAPTION "Memory" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - EDITTEXT IDC_ADDR_EDIT,35,5,49,12,ES_AUTOHSCROLL - LTEXT "Address:",IDC_STATIC,4,6,29,11 - CONTROL "Is VAddr?",IDC_CHK_VADDR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,111,7,46,8 - PUSHBUTTON "Dump",IDC_DUMP_MEM,319,4,54,13 - PUSHBUTTON "Search",IDC_SEARCH_MEM,377,4,54,13 - SCROLLBAR IDC_SCRL_BAR,421,23,11,154,SBS_VERT - PUSHBUTTON "Refresh",IDC_REFRSH_MEM,161,4,54,13 - CONTROL "Mem Details",IDC_MEM_DETAILS,"ListCtrl",WS_TABSTOP,4,23,416,154 - PUSHBUTTON "...",IDC_SYMBOLS_BTN,86,4,21,13 - LTEXT "",IDC_SYM_INFO,8,198,418,8 - LTEXT "",IDC_DMA_INFO,8,208,415,8 - GROUPBOX "",IDC_STATIC,4,190,428,30 - CONTROL "Auto",IDC_CHK_AUTOREFRESH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,220,7,31,8 + EDITTEXT IDC_ADDR_EDIT,5,20,49,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_SYMBOLS_BTN,58,20,21,13 + CONTROL "Virtual",IDC_CHK_VADDR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,83,20,40,13 + CONTROL "HexEdit",IDC_HEXEDIT,"HexEditCtrl",WS_TABSTOP,0,36,310,147 + SCROLLBAR IDC_SCRL_BAR,310,36,11,147,SBS_VERT + CONTROL "",IDC_MEMTABS,"SysTabControl32",TCS_FOCUSNEVER,0,3,319,13 + COMBOBOX IDC_CMB_JUMP,194,20,123,12,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "",IDC_STATUSBAR,"msctls_statusbar32",WS_TABSTOP,0,188,321,11 END IDD_Debugger_Search DIALOGEX 0, 0, 357, 257 @@ -1597,8 +1592,7 @@ BEGIN IDD_Debugger_Memory, DIALOG BEGIN - RIGHTMARGIN, 431 - BOTTOMMARGIN, 203 + BOTTOMMARGIN, 196 END IDD_Debugger_Search, DIALOG @@ -1954,23 +1948,39 @@ IDR_MEM_BP_POPUP MENU BEGIN POPUP "PopupMenu" BEGIN - MENUITEM "Toggle read breakpoint", ID_POPUPMENU_TOGGLERBP - MENUITEM "Toggle write breakpoint", ID_POPUPMENU_TOGGLEWBP - MENUITEM "Clear all breakpoints", ID_POPUPMENU_CLEARALLBPS + MENUITEM "Read breakpoint\tCtrl+R", ID_POPUPMENU_TOGGLERBP + MENUITEM "Write breakpoint\tCtrl+W", ID_POPUPMENU_TOGGLEWBP + MENUITEM "Lock value\tCtrl+E", ID_POPUPMENU_TOGGLELOCK MENUITEM SEPARATOR - MENUITEM "Toggle lock", ID_POPUPMENU_TOGGLELOCK - MENUITEM "Clear locks", ID_POPUPMENU_CLEARLOCKS + MENUITEM "Clear breakpoints\tCtrl+Q", ID_POPUPMENU_CLEARALLBPS + MENUITEM "Clear locks\tCtrl+Q", ID_POPUPMENU_CLEARLOCKS MENUITEM SEPARATOR - MENUITEM "View disassembly...", ID_POPUPMENU_VIEWDISASM + MENUITEM "Jump here\tCtrl+G", ID_POPUPMENU_JUMPHERE + MENUITEM "Follow pointer\tCtrl+Space", ID_POPUPMENU_FOLLOWPOINTER + MENUITEM SEPARATOR + POPUP "Byte group size" + BEGIN + MENUITEM "1\tCtrl+1", ID_POPUPMENU_BYTEGROUPSIZE_1 + MENUITEM "2\tCtrl+2", ID_POPUPMENU_BYTEGROUPSIZE_2 + MENUITEM "4\tCtrl+4", ID_POPUPMENU_BYTEGROUPSIZE_4 + MENUITEM "8\tCtrl+8", ID_POPUPMENU_BYTEGROUPSIZE_8 + END + MENUITEM "Safe mode\tINS", ID_POPUPMENU_SAFEMODE MENUITEM SEPARATOR MENUITEM "Add symbol...", ID_POPUPMENU_ADDSYMBOL + MENUITEM "View disassembly...", ID_POPUPMENU_VIEWDISASM + MENUITEM "Dump...\tCtrl+S", ID_POPUPMENU_DUMP + MENUITEM "Search...\tCtrl+F", ID_POPUPMENU_SEARCH MENUITEM SEPARATOR - POPUP "Copy" + POPUP "Copy special" BEGIN - MENUITEM "Word", ID_POPUPMENU_COPY_WORD - MENUITEM "Halfword", ID_POPUPMENU_COPY_HALFWORD - MENUITEM "Byte", ID_POPUPMENU_COPY_BYTE + MENUITEM "Data with group addresses", ID_POPUPMENU_COPYDATAWITHGROUPADDRESSES + MENUITEM "Data with row addresses", ID_POPUPMENU_COPYDATAWITHROWADDRESSES + MENUITEM "GameShark code", ID_POPUPMENU_COPYGAMESHARKCODE END + MENUITEM "Copy\tCtrl+C", ID_POPUPMENU_COPY + MENUITEM "Paste\tCtrl+V", ID_POPUPMENU_PASTE + MENUITEM "Zero-fill\tDEL", ID_POPUPMENU_ZEROFILL END END diff --git a/Source/Project64/UserInterface/WTLControls/HexEditCtrl.cpp b/Source/Project64/UserInterface/WTLControls/HexEditCtrl.cpp new file mode 100644 index 000000000..e1497bb0d --- /dev/null +++ b/Source/Project64/UserInterface/WTLControls/HexEditCtrl.cpp @@ -0,0 +1,1747 @@ +#include "stdafx.h" +#include "HexEditCtrl.h" +#include + +CHexEditCtrl::CHexEditCtrl(void) : + m_BaseAddress(0x80000000), + m_DrawnBaseAddress(0xFFFFFFFF), + m_SelStartAddress(0), + m_SelEndAddress(0), + m_SelStartCellSide(HX_LEFT), + m_SelEndCellSide(HX_LEFT), + m_bInsertMode(false), + m_CaretAddress(0), + m_bCaretLoNibble(false), + m_bCaretVisible(false), + m_bHaveCaret(false), + m_bShowHotAddress(false), + m_HotAddress(0), + m_Font(NULL), + m_BackBMP(NULL), + m_BackDC(NULL), + m_CharWidth(0), + m_CharHeight(0), + m_FocusedColumn(HX_COL_NONE), + m_hCursorIBeam(NULL), + m_hCursorDefault(NULL), + m_DragScrollDelta(0), + m_AddressColumnRect({0}), + m_HexDataColumnRect({0}), + m_AsciiColumnRect({0}), + m_bDblClicked(false), + m_bLButtonDown(false), + m_bMouseDragging(false), + m_bLayoutChanged(false), + m_OldBytes(NULL), + m_NewBytes(NULL), + m_NumBytesPerGroup(4), + m_NumByteGroupsPerRow(0), + m_NumVisibleRows(0), + m_NumVisibleBytes(0), + m_RealSelStartAddress(0), + m_RealSelEndAddress(0), + m_bHaveRealSel(false) +{ + WNDCLASS wc; + if (!GetClassInfo(GetModuleHandle(NULL), _T("HexEditCtrl"), &wc)) + { + GetWndClassInfo().m_wc.lpfnWndProc = m_pfnSuperWindowProc; + GetWndClassInfo().Register(&m_pfnSuperWindowProc); + } +} + +CHexEditCtrl::~CHexEditCtrl(void) +{ +} + +int CALLBACK CHexEditCtrl::HaveFontCb(CONST LOGFONTA *lplf, CONST TEXTMETRICA *lptm, DWORD FontType, LPARAM lParam) +{ + const char* name = (const char*)lParam; + if (strcmp(lplf->lfFaceName, name) == 0) + { + return 0; + } + return 1; +} + +bool CHexEditCtrl::HaveFont(HDC hdc, const char* name) +{ + if (EnumFonts(hdc, name, HaveFontCb, (LPARAM)name) == 0) + { + return true; + } + return false; +} + +BOOL CHexEditCtrl::Attach(HWND hWnd) +{ + if (m_hWnd != NULL) + { + return FALSE; + } + + if (!CWindowImpl::SubclassWindow(hWnd)) + { + return FALSE; + } + + CRect wndRc; + if (!GetWindowRect(&wndRc)) + { + return FALSE; + } + + HDC hdc = GetDC(); + HBITMAP hOldBMP; + HFONT hOldFont; + + m_BackDC = CreateCompatibleDC(hdc); + m_BackBMP = CreateCompatibleBitmap(hdc, wndRc.Width(), wndRc.Height()); + hOldBMP = (HBITMAP)SelectObject(m_BackDC, m_BackBMP); + DeleteObject(hOldBMP); + + m_hCursorIBeam = LoadCursor(NULL, IDC_IBEAM); + m_hCursorDefault = LoadCursor(NULL, IDC_ARROW); + + float dpiScale = ::GetDeviceCaps(hdc, LOGPIXELSX) / 96.0f; + + if (HaveFont(hdc, "Consolas")) + { + m_Font = CreateFont((int)(14 * dpiScale), 0, 0, 0, + FW_DONTCARE, + FALSE, + FALSE, + FALSE, + DEFAULT_CHARSET, + OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, + DEFAULT_QUALITY, + FF_DONTCARE | FIXED_PITCH, + "Consolas"); + } + else + { + m_Font = (HFONT)GetStockObject(ANSI_FIXED_FONT); + } + + hOldFont = (HFONT)SelectObject(m_BackDC, m_Font); + DeleteObject(hOldFont); + + TEXTMETRIC tm; + GetTextMetrics(m_BackDC, &tm); + m_CharHeight = tm.tmHeight; + m_CharWidth = tm.tmAveCharWidth; + + UpdateLayoutInfo(); + ReallocByteBuffers(); + + CRect clrRc(0, 0, wndRc.Width(), wndRc.Height()); + HBRUSH hbrush = CreateSolidBrush(BKCOLOR_DEFAULT); + FillRect(m_BackDC, clrRc, hbrush); + DeleteObject(hbrush); + + SetTimer(TIMER_ID_AUTO_REFRESH, 20, NULL); + SetTimer(TIMER_ID_DRAG_SCROLL, 50, NULL); + + ReleaseDC(hdc); + + return TRUE; +} + +HWND CHexEditCtrl::Detach(void) +{ + if (m_hWnd == NULL) + { + return NULL; + } + + KillTimer(TIMER_ID_AUTO_REFRESH); + KillTimer(TIMER_ID_DRAG_SCROLL); + + if (m_BackBMP != NULL) + { + DeleteObject(m_BackBMP); + m_BackBMP = NULL; + } + + if (m_BackDC != NULL) + { + DeleteObject(m_BackDC); + m_BackDC = NULL; + } + + if (m_Font != NULL) + { + DeleteObject(m_Font); + m_Font = NULL; + } + + if (m_NewBytes != NULL) + { + free(m_NewBytes); + m_NewBytes = NULL; + } + + if (m_OldBytes != NULL) + { + free(m_OldBytes); + m_OldBytes = NULL; + } + + return CWindowImpl::UnsubclassWindow(); +} + +void CHexEditCtrl::Draw(void) +{ + Notify(HXN_REDRAWSTARTED); + + int startCellIndex = 0; + uint32_t startAddress = m_BaseAddress; + int numBytesToUpdate = m_NumVisibleBytes; + bool bIgnoreDiff = false; + + if (m_BaseAddress != m_DrawnBaseAddress) + { + m_bShowHotAddress = false; + int64_t addrDelta = (int64_t)m_BaseAddress - (int64_t)m_DrawnBaseAddress; + + // scroll optimization + if ((addrDelta % m_NumBytesPerRow) == 0 && abs(addrDelta) < (m_NumVisibleBytes - m_NumBytesPerRow)) + { + int rowDelta = (int)(addrDelta / m_NumBytesPerRow); + int numBytesScrolled = abs(rowDelta) * m_NumBytesPerRow; + int numBytesToShift = (m_NumVisibleBytes - numBytesScrolled) - m_NumBytesPerRow; + int shiftSrcIndex = 0, shiftDstIndex = 0; + + numBytesToUpdate = numBytesScrolled + m_NumBytesPerRow; + + CRect rcScrollArea; + rcScrollArea.left = m_HexDataColumnRect.left; + rcScrollArea.right = m_AsciiColumnRect.right; + rcScrollArea.top = m_HexDataColumnRect.top; + rcScrollArea.bottom = m_HexDataColumnRect.bottom; + + if (rowDelta > 0) + { + rcScrollArea.bottom -= m_CharHeight; + startCellIndex = m_NumVisibleBytes - numBytesToUpdate; + shiftSrcIndex = 0 + numBytesScrolled; + shiftDstIndex = 0; + } + else if (rowDelta < 0) + { + rcScrollArea.top += m_CharHeight; + startCellIndex = 0; + shiftSrcIndex = 0 + m_NumBytesPerRow; + shiftDstIndex = shiftSrcIndex + numBytesScrolled; + } + + startAddress = m_BaseAddress + startCellIndex; + + memmove(&m_OldBytes[shiftDstIndex], &m_OldBytes[shiftSrcIndex], numBytesToShift * sizeof(HXBYTEINFO)); + memmove(&m_NewBytes[shiftDstIndex], &m_NewBytes[shiftSrcIndex], numBytesToShift * sizeof(HXBYTEINFO)); + + ScrollDC(m_BackDC, 0, -rowDelta * m_CharHeight, &rcScrollArea, &rcScrollArea, NULL, NULL); + InvalidateRect(&rcScrollArea, false); + } + + DrawAddressColumn(); + DrawHeader(); + + m_DrawnBaseAddress = m_BaseAddress; + bIgnoreDiff = true; + } + + if (m_bLayoutChanged) + { + bIgnoreDiff = true; + m_bLayoutChanged = false; + } + + int numOverflowBytes = 0; + + if (startAddress + numBytesToUpdate < startAddress) + { + numOverflowBytes = (startAddress + numBytesToUpdate); + } + + for (int i = 0; i < numOverflowBytes; i++) + { + m_NewBytes[numBytesToUpdate - numOverflowBytes + i].bHidden = true; + } + + NotifyGetByteInfo(startAddress, numBytesToUpdate - numOverflowBytes, bIgnoreDiff, &m_OldBytes[startCellIndex], &m_NewBytes[startCellIndex]); + + std::unordered_map drawnByteRects; + + for (int i = 0; i < numBytesToUpdate; i++) + { + uint32_t address = startAddress + i; + + HXBYTEINFO* oldByte = &m_OldBytes[startCellIndex + i]; + HXBYTEINFO* newByte = &m_NewBytes[startCellIndex + i]; + + if (IsSelected(address)) + { + // override owner-provided colors if selected + if (newByte->bkColor != BKCOLOR_DEFAULT) + { + // blend owner color with selection color if bkcolor isn't default + newByte->bkColor = BlendColor(BKCOLOR_SEL_FOCUSED, newByte->bkColor); + newByte->color = COLOR_SEL_FOCUSED; + } + else + { + newByte->bkColor = BKCOLOR_SEL_FOCUSED; + newByte->color = COLOR_SEL_FOCUSED; + } + } + + if (address == m_HotAddress && m_bShowHotAddress && !m_bMouseDragging) + { + newByte->bkColor = BlendColor(BKCOLOR_HOT, newByte->bkColor); + } + + // redraw cell if value or colors have changed + if (*newByte != *oldByte) + { + CRect rcHex, rcAscii; + GetHexCellPos(startCellIndex + i, &rcHex); + GetAsciiCellPos(startCellIndex + i, &rcAscii); + + // check if a similar HXBYTEINFO has already been drawn + std::unordered_map::const_iterator drawnByte = drawnByteRects.find(*newByte); + + if (drawnByte != drawnByteRects.end()) + { + HXRECTPAIR src = drawnByte->second; + BitBlt(m_BackDC, rcHex.left, rcHex.top, src.rcHex.Width(), src.rcHex.Height(), + m_BackDC, src.rcHex.left, src.rcHex.top, SRCCOPY); + BitBlt(m_BackDC, rcAscii.left, rcAscii.top, src.rcAscii.Width(), src.rcAscii.Height(), + m_BackDC, src.rcAscii.left, src.rcAscii.top, SRCCOPY); + InvalidateRect(&rcHex, false); + InvalidateRect(&rcAscii, false); + } + else if (newByte->bHidden) + { + HXRECTPAIR rectPair; + Text(rcHex.left, rcHex.top, " ", BKCOLOR_DEFAULT, BKCOLOR_DEFAULT, &rectPair.rcHex); + Text(rcAscii.left, rcAscii.top, " ", BKCOLOR_DEFAULT, BKCOLOR_DEFAULT, &rectPair.rcAscii); + drawnByteRects[*newByte] = rectPair; + } + else + { + COLORREF hexBkColor = newByte->bkColor; + COLORREF hexColor = newByte->color; + COLORREF asciiBkColor = newByte->bkColor; + COLORREF asciiColor = newByte->color; + + if (IsSelected(address)) + { + if (m_FocusedColumn == HX_COL_ASCII) + { + hexBkColor = BKCOLOR_SEL_UNFOCUSED; + hexColor = COLOR_SEL_UNFOCUSED; + } + else + { + asciiBkColor = BKCOLOR_SEL_UNFOCUSED; + asciiColor = COLOR_SEL_UNFOCUSED; + } + } + + HXRECTPAIR rectPair; + + if (newByte->bValid) + { + char szHexByte[4], szAsciiByte[2]; + sprintf(szHexByte, "%02X", newByte->value); + sprintf(szAsciiByte, "%c", ByteAscii(newByte->value)); + Text(rcHex.left, rcHex.top, szHexByte, hexBkColor, hexColor, &rectPair.rcHex); + Text(rcAscii.left, rcAscii.top, szAsciiByte, asciiBkColor, asciiColor, &rectPair.rcAscii); + } + else + { + Text(rcHex.left, rcHex.top, "**", hexBkColor, hexColor, &rectPair.rcHex); + Text(rcAscii.left, rcAscii.top, ".", asciiBkColor, asciiColor, &rectPair.rcAscii); + } + + drawnByteRects[*newByte] = rectPair; + } + } + + *oldByte = *newByte; + } + + UpdateCaretUI(false); +} + +void CHexEditCtrl::HitTest(int x, int y, HXHITTEST* pht) +{ + memset(pht, 0, sizeof(HXHITTEST)); + pht->column = HX_COL_NONE; + + CPoint pt(x, y); + + if (PtInRect(&m_AddressColumnRect, pt)) + { + pht->column = HX_COL_ADDRESS; + } + + int headerHeight = m_CharHeight; + + // clamp row + int row = (y - headerHeight) / m_CharHeight; + row = max(0, row); + row = min(m_NumVisibleRows - 1, row); + + uint32_t rowAddress = SatAdd32(m_BaseAddress, row * m_NumBytesPerRow); + + if (x >= m_HexDataColumnRect.left && x < m_HexDataColumnRect.right) + { + if (PtInRect(&m_HexDataColumnRect, pt)) + { + pht->column = HX_COL_HEXDATA; + } + + int groupWidth = (m_NumBytesPerGroup * m_CharWidth * 2) + (m_CharWidth * 1); + int nGroup = (x - m_HexDataColumnRect.left) / groupWidth; + int groupX = m_HexDataColumnRect.left + nGroup * groupWidth; + int groupCharIdx = (x - groupX) / (m_CharWidth); + uint32_t address = SatAdd32(rowAddress, nGroup * m_NumBytesPerGroup + groupCharIdx / 2); + pht->hexAddress = address; + pht->hexCellSide = (groupCharIdx & 1) ? HX_RIGHT : HX_LEFT; // todo fix for wrap + pht->asciiAddress = address; // approximate + pht->asciiCellSide = HX_LEFT; + } + else if (x >= m_AsciiColumnRect.left && x < m_AsciiColumnRect.right) + { + if (PtInRect(&m_AsciiColumnRect, pt)) + { + pht->column = HX_COL_ASCII; + } + + int asciiX = x - m_AsciiColumnRect.left; + int idx = (asciiX / m_CharWidth); + pht->asciiAddress = SatAdd32(rowAddress, idx); + pht->asciiCellSide = ((asciiX % m_CharWidth) > (m_CharWidth / 2)) ? HX_RIGHT : HX_LEFT; + pht->hexAddress = SatAdd32(rowAddress, (m_NumBytesPerRow - 1)); // approximate + pht->hexCellSide = HX_RIGHT; + } + else if (x < m_HexDataColumnRect.left) + { + // approximate + pht->hexAddress = rowAddress; + pht->hexCellSide = HX_LEFT; + pht->asciiAddress = rowAddress; + pht->asciiCellSide = HX_LEFT; + } + else if (x >= m_AsciiColumnRect.right) + { + // approximate + pht->hexAddress = SatAdd32(rowAddress, (m_NumBytesPerRow - 1)); + pht->hexCellSide = HX_RIGHT; + pht->asciiAddress = SatAdd32(rowAddress, (m_NumBytesPerRow - 1)); + pht->asciiCellSide = HX_RIGHT; + } +} + +bool CHexEditCtrl::UpdateCaretUI(bool bEnsureVisible, bool bTop) +{ + if (bEnsureVisible) + { + EnsureCaretAddressVisible(bTop); + } + + if (!m_bHaveCaret) + { + return false; + } + + if (!IsCaretAddressVisible()) + { + HideCaret(); + return false; + } + + ShowCaret(); + int index = m_CaretAddress - m_BaseAddress; + CRect rcCell; + + int xoffs = 0; + + if (m_FocusedColumn == HX_COL_ASCII) + { + if ((int)((m_RealSelEndAddress - m_BaseAddress) % m_NumBytesPerRow) == m_NumBytesPerRow - 1) + { + // left-to-right selection ends on the end of a row + index--; + xoffs = m_CharWidth; + } + + GetAsciiCellPos(index, &rcCell); + SetCaretPos(rcCell.left + xoffs, rcCell.top); + } + else + { + if (GetSelDirection() > 0) + { + if ((int)((m_RealSelEndAddress - m_BaseAddress) % m_NumBytesPerRow) == m_NumBytesPerRow - 1) + { + // left-to-right selection ends on the end of a row + index--; + xoffs = m_CharWidth * 2; + } + else if ((int)((m_RealSelEndAddress - m_BaseAddress) % m_NumBytesPerGroup) == m_NumBytesPerGroup - 1) + { + // left-to-right selection ends on the end of a group + xoffs = -m_CharWidth; + } + } + + GetHexCellPos(index, &rcCell); + SetCaretPos(rcCell.left + (m_bCaretLoNibble ? m_CharWidth : 0) + xoffs, rcCell.top); + } + + return true; +} + +void CHexEditCtrl::Text(int x, int y, const char *text, COLORREF bg, COLORREF fg, CRect *rcOut) +{ + size_t length = strlen(text); + int calcWidth = length * m_CharWidth; + + CRect rc(x, y, 0, 0); + COLORREF orgBg = ::SetBkColor(m_BackDC, bg); + COLORREF orgFg = ::SetTextColor(m_BackDC, fg); + ::DrawText(m_BackDC, text, -1, &rc, DT_TOP | DT_NOPREFIX | DT_CALCRECT); + rc.right = rc.left + calcWidth; // just in case + ::DrawText(m_BackDC, text, -1, &rc, DT_TOP | DT_NOPREFIX); + InvalidateRect(&rc, false); + ::SetBkColor(m_BackDC, orgBg); + ::SetBkColor(m_BackDC, orgFg); + + *rcOut = rc; +} + +void CHexEditCtrl::UpdateRealSelection(void) +{ + uint32_t start = m_SelStartAddress; + uint32_t end = m_SelEndAddress; + bool bHaveSel = true; + + if (start < end) + { + if (m_SelEndCellSide == HX_LEFT) end--; + if (m_SelStartCellSide == HX_RIGHT) start++; + } + else if (end < start) + { + if (start - end == 1) + { + if (m_SelStartCellSide == HX_LEFT && m_SelEndCellSide == HX_RIGHT) + { + bHaveSel = false; + } + } + + if (m_SelStartCellSide == HX_LEFT) start--; + if (m_SelEndCellSide == HX_RIGHT) end++; + + swap(start, end); + } + else if(start == end) + { + if (m_SelStartCellSide == m_SelEndCellSide) + { + bHaveSel = false; + } + } + + if (m_RealSelStartAddress != start || + m_RealSelEndAddress != end || + m_bHaveRealSel != bHaveSel) + { + m_bHaveRealSel = bHaveSel; + m_RealSelStartAddress = start; + m_RealSelEndAddress = end; + Notify(HXN_SELCHANGED); + } +} + +bool CHexEditCtrl::IsSelected(uint32_t address) +{ + return m_bHaveRealSel && (address >= m_RealSelStartAddress && address <= m_RealSelEndAddress); +} + +void CHexEditCtrl::DrawAddressColumn() +{ + int headerHeight = m_CharHeight; + for (int nRow = 0; nRow < m_NumVisibleRows; nRow++) + { + CRect rcAddress; + uint32_t rowAddress = m_BaseAddress + (nRow * m_NumBytesPerRow); + int y = headerHeight + nRow * m_CharHeight; + + if (rowAddress >= m_BaseAddress) + { + Text(0, y, stdstr_f(" %08X ", rowAddress).c_str(), BKCOLOR_ADDR, COLOR_ADDR, &rcAddress); + } + else + { + // wrapped + Text(0, y, " ", BKCOLOR_ADDR, COLOR_ADDR, &rcAddress); + } + } +} + +void CHexEditCtrl::DrawHeader() +{ + CRect rcClient; + GetClientRect(&rcClient); + CRect rcHeader = { 0, 0, rcClient.Width(), m_CharHeight }; + HBRUSH br = CreateSolidBrush(BKCOLOR_ADDR); + FillRect(m_BackDC, &rcHeader, br); + DeleteObject(br); + + int groupWidth = m_NumBytesPerGroup * m_CharWidth * 2 + m_CharWidth; + + for (int nGroup = 0; nGroup < m_NumByteGroupsPerRow; nGroup++) + { + int groupX = m_HexDataColumnRect.left + nGroup * groupWidth; + int offs = nGroup * m_NumBytesPerGroup; + CRect dummy; + Text(groupX, 0, stdstr_f("%02X", offs).c_str(), BKCOLOR_ADDR, COLOR_ADDR, &dummy); + } + + InvalidateRect(&rcHeader, false); +} + +void CHexEditCtrl::GetHexCellPos(int index, CRect* rc) +{ + int nRow = index / m_NumBytesPerRow; + int rowOffs = (index % m_NumBytesPerRow); + int nGroup = rowOffs / m_NumBytesPerGroup; + int byteOffs = rowOffs % m_NumBytesPerGroup; + + int addrColumnWidth = (m_CharWidth * 11); + int byteWidth = (m_CharWidth * 2); + int hexGroupWidth = (byteWidth * m_NumBytesPerGroup) + (m_CharWidth * 1); + + int headerHeight = m_CharHeight; + + rc->left = addrColumnWidth + (nGroup * hexGroupWidth) + (byteOffs * byteWidth); + rc->top = headerHeight + nRow * m_CharHeight; + rc->right = rc->left + m_CharWidth * 2; + rc->bottom = rc->top + m_CharHeight; +} + +void CHexEditCtrl::GetAsciiCellPos(int index, CRect* rc) +{ + int nRow = index / m_NumBytesPerRow; + int rowOffs = (index % m_NumBytesPerRow); + + int addrColumnWidth = (m_CharWidth * 11); + int byteWidth = (m_CharWidth * 2); + int hexGroupWidth = (byteWidth * m_NumBytesPerGroup) + (m_CharWidth * 1); + int hexColumnWidth = (m_NumByteGroupsPerRow * hexGroupWidth); + int asciiColumnX = 0 + addrColumnWidth + hexColumnWidth; + int headerHeight = m_CharHeight; + + rc->left = asciiColumnX + (rowOffs * m_CharWidth); + rc->top = headerHeight + nRow * m_CharHeight; + rc->right = rc->left + m_CharWidth; + rc->bottom = rc->top + m_CharHeight; +} + +char CHexEditCtrl::ByteAscii(uint8_t value) +{ + if (value <= 0x1F) + { + return '.'; + } + + if (value >= 0x20 && value <= 0x7E) + { + return (char)value; + } + + switch (value) + { + case 0x7F: + case 0x81: + case 0x8D: + case 0x8F: + case 0x90: + case 0x9D: + // undefined in windows-1252 + return '.'; + } + + return (char)value; +} + +uint8_t CHexEditCtrl::HexCharValue(char c) +{ + if (!isxdigit(c)) + { + return 0; + } + + if (c >= '0' && c <= '9') return (c - '0'); + if (c >= 'A' && c <= 'F') return (c - 'A') + 0x0A; + if (c >= 'a' && c <= 'f') return (c - 'a') + 0x0A; + + return 0; +} + +void CHexEditCtrl::CaretIncrementNibble(void) +{ + if (!m_bCaretLoNibble) + { + m_bCaretLoNibble = true; + } + else + { + m_bCaretLoNibble = false; + m_CaretAddress++; + } +} + +void CHexEditCtrl::CaretDecrementNibble(void) +{ + if (m_bCaretLoNibble) + { + m_bCaretLoNibble = false; + } + else + { + m_bCaretLoNibble = true; + m_CaretAddress--; + } +} + +void CHexEditCtrl::OnTimer(UINT_PTR nIDEvent) +{ + if (nIDEvent == TIMER_ID_AUTO_REFRESH) + { + Draw(); + } + else if (nIDEvent == TIMER_ID_DRAG_SCROLL) + { + if (m_DragScrollDelta != 0) + { + int numBytesToScroll = m_DragScrollDelta * m_NumBytesPerRow; + int64_t newCaretAddress = (int64_t)m_CaretAddress + numBytesToScroll; + + if (newCaretAddress < 0 && m_BaseAddress == 0) + { + return; + } + + else if (newCaretAddress > UINT_MAX) + { + return; + } + + m_CaretAddress = SatAdd32(m_CaretAddress, numBytesToScroll); + m_SelEndAddress = SatAdd32(m_SelEndAddress, numBytesToScroll); + + UpdateRealSelection(); + UpdateCaretUI(true); + } + } +} + +void CHexEditCtrl::OnPaint(CDCHandle dc) +{ + PAINTSTRUCT ps; + HDC hdc = BeginPaint(&ps); + CRect rc = ps.rcPaint; + + BitBlt(hdc, + rc.left, rc.top, + rc.Width(), rc.Height(), + m_BackDC, + rc.left, rc.top, + SRCCOPY); + + EndPaint(&ps); +} + +void CHexEditCtrl::OnRButtonDown(UINT /*nFlags*/, CPoint point) +{ + SetFocus(); + + HXHITTEST ht; + HitTest(point.x, point.y, &ht); + + if (ht.column == HX_COL_HEXDATA) + { + if (!IsSelected(ht.hexAddress)) + { + m_CaretAddress = ht.hexAddress; + m_bCaretLoNibble = HX_LEFT; + CancelSelection(); + } + } + else if (ht.column == HX_COL_ASCII) + { + if (!IsSelected(ht.asciiAddress)) + { + m_CaretAddress = ht.asciiAddress; + CancelSelection(); + } + } +} + +void CHexEditCtrl::OnRButtonUp(UINT /*nFlags*/, CPoint point) +{ + HXHITTEST ht; + HitTest(point.x, point.y, &ht); + + if (ht.column == HX_COL_HEXDATA) + { + NotifyRightClick(ht.hexAddress); + } + else if (ht.column == HX_COL_ASCII) + { + NotifyRightClick(ht.asciiAddress); + } +} + +void CHexEditCtrl::OnLButtonDown(UINT nFlags, CPoint point) +{ + m_bLButtonDown = true; + + SetFocus(); + + HXHITTEST ht; + HitTest(point.x, point.y, &ht); + + m_FocusedColumn = ht.column; + + if (m_FocusedColumn == HX_COL_HEXDATA) + { + m_CaretAddress = ht.hexAddress; + m_bCaretLoNibble = (ht.hexCellSide == HX_RIGHT); + + if (nFlags & MK_SHIFT) + { + m_SelEndAddress = ht.hexAddress; + m_SelEndCellSide = ht.hexCellSide; + UpdateRealSelection(); + + if (GetSelDirection() > 0) + { + m_CaretAddress = m_RealSelEndAddress + 1; + } + else + { + m_CaretAddress = m_RealSelStartAddress; + } + m_bCaretLoNibble = false; + } + else + { + m_SelStartAddress = ht.hexAddress; + m_SelEndAddress = ht.hexAddress; + m_SelStartCellSide = ht.hexCellSide; + m_SelEndCellSide = ht.hexCellSide; + UpdateRealSelection(); + } + } + else if (m_FocusedColumn == HX_COL_ASCII) + { + m_CaretAddress = ht.asciiAddress; + + if (nFlags & MK_SHIFT) + { + m_SelEndAddress = ht.asciiAddress; + } + else + { + m_CaretAddress = ht.asciiAddress; + m_SelStartCellSide = ht.asciiCellSide; + m_SelEndCellSide = ht.asciiCellSide; + m_SelStartAddress = ht.asciiAddress; + m_SelEndAddress = ht.asciiAddress; + if (ht.asciiCellSide) + { + m_CaretAddress++; + } + } + + UpdateRealSelection(); + } + + UpdateCaretUI(false); + Draw(); + + SetCapture(); +} + +void CHexEditCtrl::OnLButtonDblClk(UINT /*nFlags*/, CPoint point) +{ + m_bDblClicked = true; + + HXHITTEST ht; + HitTest(point.x, point.y, &ht); + + if (m_FocusedColumn == HX_COL_HEXDATA) + { + // select word + uint32_t offset = (ht.hexAddress - m_BaseAddress); + uint32_t wordOffset = offset - (offset % m_NumBytesPerGroup); + uint32_t wordAddress = m_BaseAddress + wordOffset; + m_SelStartAddress = wordAddress; + m_SelEndAddress = wordAddress + (m_NumBytesPerGroup - 1); + m_SelStartCellSide = HX_LEFT; + m_SelEndCellSide = HX_RIGHT; + m_CaretAddress = m_SelEndAddress + 1; + m_bCaretLoNibble = false; + UpdateRealSelection(); + UpdateCaretUI(false); + } + if (m_FocusedColumn == HX_COL_ASCII) + { + // select row + uint32_t offset = (ht.asciiAddress - m_BaseAddress); + uint32_t rowOffset = (ht.asciiAddress - m_BaseAddress) - (offset % m_NumBytesPerRow); + uint32_t rowAddress = m_BaseAddress + rowOffset; + m_SelStartAddress = rowAddress; + m_SelEndAddress = rowAddress + (m_NumBytesPerRow - 1); + m_SelStartCellSide = HX_LEFT; + m_SelEndCellSide = HX_RIGHT; + m_CaretAddress = m_SelEndAddress + 1; + UpdateRealSelection(); + UpdateCaretUI(false); + } +} + +void CHexEditCtrl::OnLButtonUp(UINT /*nFlags*/, CPoint point) +{ + m_bLButtonDown = false; + m_bMouseDragging = false; + + if (m_DragScrollDelta != 0) + { + m_bDblClicked = false; + m_DragScrollDelta = 0; + ReleaseCapture(); + return; + } + + HXHITTEST ht; + HitTest(point.x, point.y, &ht); + + if (m_bDblClicked) + { + m_bDblClicked = false; + return; + } + + ReleaseCapture(); +} + +void CHexEditCtrl::OnMouseMove(UINT /*nFlags*/, CPoint point) +{ + if (m_bLButtonDown) + { + m_bMouseDragging = true; + } + + HXHITTEST ht; + HitTest(point.x, point.y, &ht); + + if (ht.column == HX_COL_NONE || ht.column == HX_COL_ADDRESS) + { + m_bShowHotAddress = false; + } + else + { + m_bShowHotAddress = true; + + if (ht.column == HX_COL_HEXDATA) + { + if (m_HotAddress != ht.hexAddress) + { + m_HotAddress = ht.hexAddress; + Notify(HXN_HOTADDRCHANGED); + } + } + else if (ht.column == HX_COL_ASCII) + { + if (m_HotAddress != ht.asciiAddress) + { + m_HotAddress = ht.asciiAddress; + Notify(HXN_HOTADDRCHANGED); + } + } + } + + if (!m_bLButtonDown) + { + return; + } + + m_DragScrollDelta = 0; + + if (point.y > m_HexDataColumnRect.bottom) + { + m_DragScrollDelta = 1 + (point.y - m_HexDataColumnRect.bottom) / m_CharHeight; + } + else if (point.y < m_HexDataColumnRect.top) + { + m_DragScrollDelta = -1 + (point.y - m_HexDataColumnRect.top) / m_CharHeight; + } + + if (m_FocusedColumn == HX_COL_HEXDATA) + { + m_CaretAddress = ht.hexAddress; + m_SelEndAddress = ht.hexAddress; + m_SelEndCellSide = ht.hexCellSide; + m_bCaretLoNibble = (ht.hexCellSide == HX_RIGHT); + + if (m_SelEndAddress - m_SelStartAddress == 1 && + m_SelStartCellSide == HX_RIGHT && + m_SelEndCellSide == HX_LEFT) + { + m_SelStartCellSide = HX_LEFT; + } + + if (GetSelDirection() != 0 && m_SelEndCellSide == HX_RIGHT) + { + m_bCaretLoNibble = false; + m_CaretAddress++; + } + } + else if (m_FocusedColumn == HX_COL_ASCII) + { + m_CaretAddress = ht.asciiAddress; + m_SelEndAddress = ht.asciiAddress; + m_SelEndCellSide = ht.asciiCellSide; + + if (GetSelDirection() != 0 && m_SelEndCellSide == HX_RIGHT) + { + m_CaretAddress++; + } + } + + UpdateRealSelection(); +} + +BOOL CHexEditCtrl::OnMouseWheel(UINT /*nFlags*/, short zDelta, CPoint /*pt*/) +{ + m_BaseAddress = SatAdd32(m_BaseAddress, -(zDelta / 120) * m_NumBytesPerRow); + Notify(HXN_BASEADDRCHANGED); + return FALSE; +} + +void CHexEditCtrl::OnSetFocus(CWindow /*wndOld*/) +{ + ::CreateCaret(m_hWnd, NULL, 2, m_CharHeight); + m_bHaveCaret = true; + UpdateCaretUI(false); +} + +void CHexEditCtrl::OnKillFocus(CWindow /*wndFocus*/) +{ + m_bCaretVisible = false; + m_bHaveCaret = false; + ::DestroyCaret(); +} + +UINT CHexEditCtrl::OnGetDlgCode(LPMSG /*lpMsg*/) +{ + return DLGC_WANTALLKEYS; +} + +void CHexEditCtrl::OnChar(UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/) +{ + if (::GetKeyState(VK_CONTROL) & 0x8000) + { + return; + } + + if (nChar == VK_BACK || nChar == VK_TAB || nChar == VK_RETURN) + { + return; + } + + if (m_FocusedColumn == HX_COL_HEXDATA) + { + if (isxdigit(nChar)) + { + int selDirection = GetSelDirection(); + + if (selDirection < 0) + { + m_CaretAddress = m_SelEndAddress; + m_bCaretLoNibble = false; + } + else if (selDirection > 0) + { + m_CaretAddress = m_SelStartAddress; + m_bCaretLoNibble = false; + } + + NotifySetNibble(m_CaretAddress, m_bCaretLoNibble, HexCharValue((char)nChar)); + + CancelSelection(); + CaretIncrementNibble(); + UpdateCaretUI(true); + } + } + else if (m_FocusedColumn == HX_COL_ASCII) + { + int selDirection = GetSelDirection(); + if (selDirection < 0) + { + m_CaretAddress = m_SelEndAddress; + } + else if(selDirection > 0) + { + m_CaretAddress = m_SelStartAddress; + } + + NotifySetByte(m_CaretAddress, (uint8_t)nChar); + + CancelSelection(); + m_CaretAddress++; + UpdateCaretUI(true); + } +} + +void CHexEditCtrl::Paste(bool bAdvanceCaret) +{ + uint32_t targetAddress = m_bHaveRealSel ? m_RealSelStartAddress : m_CaretAddress; + int retLength = NotifyPaste(targetAddress); + + if (retLength != 0) + { + if (bAdvanceCaret) + { + m_CaretAddress = targetAddress + retLength; + UpdateCaretUI(true); + } + CancelSelection(); + } +} + +void CHexEditCtrl::Copy(void) +{ + if (m_bHaveRealSel) + { + Notify(HXN_COPY); + } +} + +void CHexEditCtrl::SetBaseAddress(uint32_t address) +{ + if (m_BaseAddress != address) + { + m_BaseAddress = address; + Draw(); + } +} + +uint32_t CHexEditCtrl::GetCaretAddress(void) +{ + return m_CaretAddress; +} + +uint32_t CHexEditCtrl::GetHotAddress(void) +{ + return m_HotAddress; +} + +uint32_t CHexEditCtrl::GetBaseAddress(void) +{ + return m_BaseAddress; +} + +int CHexEditCtrl::GetNumBytesPerRow(void) +{ + return m_NumBytesPerRow; +} + +int CHexEditCtrl::GetNumVisibleBytes(void) +{ + return m_NumVisibleBytes; +} + +int CHexEditCtrl::GetNumBytesPerGroup(void) +{ + return m_NumBytesPerGroup; +} + +bool CHexEditCtrl::GetSelectionRange(uint32_t* startAddress, uint32_t* endAddress) +{ + *startAddress = m_RealSelStartAddress; + *endAddress = m_RealSelEndAddress; + return m_bHaveRealSel; +} + +bool CHexEditCtrl::GetInsertMode(void) +{ + return m_bInsertMode; +} + +HXCOLUMN CHexEditCtrl::GetFocusedColumn(void) +{ + return m_FocusedColumn; +} + +void CHexEditCtrl::OnKeyDown(UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/) +{ + if (nChar != VK_CONTROL && (GetKeyState(VK_CONTROL) & 0x8000)) + { + NotifyCtrlKeyPressed(nChar); + + if (nChar == 'V') + { + Paste(); + } + else if (nChar == 'B') + { + Paste(false); + } + else if (nChar == 'C') + { + Copy(); + } + else if (nChar == 'X') + { + Copy(); + if (m_bHaveRealSel) + { + NotifyFillRange(m_RealSelStartAddress, m_RealSelEndAddress, 0); + m_CaretAddress = m_RealSelStartAddress; + m_bCaretLoNibble = false; + CancelSelection(); + } + } + else if (nChar == 'A') + { + SelectAllVisible(); + } + } + + + if (nChar == VK_DOWN) + { + m_CaretAddress = SatAdd32(m_CaretAddress, m_NumBytesPerRow); + + if (GetKeyState(VK_SHIFT) & 0x8000) + { + m_SelEndAddress += m_NumBytesPerRow; + if (m_bCaretLoNibble) + { + m_SelStartCellSide = HX_LEFT; + m_SelEndCellSide = HX_LEFT; + m_bCaretLoNibble = false; + } + UpdateRealSelection(); + } + else + { + CancelSelection(); + } + + UpdateCaretUI(true); + } + else if (nChar == VK_UP) + { + m_CaretAddress -= m_NumBytesPerRow; + + if (GetKeyState(VK_SHIFT) & 0x8000) + { + m_SelEndAddress -= m_NumBytesPerRow; + if (m_bCaretLoNibble) + { + m_SelStartCellSide = HX_LEFT; + m_SelEndCellSide = HX_LEFT; + m_bCaretLoNibble = false; + } + UpdateRealSelection(); + } + else + { + CancelSelection(); + } + + UpdateCaretUI(true); + } + else if (nChar == VK_RIGHT) + { + if (m_FocusedColumn == HX_COL_HEXDATA) + { + if (GetKeyState(VK_SHIFT) & 0x8000) + { + if (m_SelStartAddress == m_SelEndAddress && + m_SelStartCellSide == HX_RIGHT && + m_SelEndCellSide == HX_RIGHT) + { + m_SelStartCellSide = HX_LEFT; + m_SelEndCellSide = HX_RIGHT; + } + else + { + m_SelEndAddress++; + } + + m_bCaretLoNibble = false; + m_CaretAddress++; + UpdateRealSelection(); + } + else if (GetKeyState(VK_CONTROL) & 0x8000) + { + CaretIncrementNibble(); + CancelSelection(); + } + else + { + m_bCaretLoNibble = false; + m_CaretAddress++; + m_SelStartAddress = m_CaretAddress; + m_SelEndAddress = m_CaretAddress; + m_SelStartCellSide = HX_LEFT; + m_SelEndCellSide = HX_LEFT; + CancelSelection(); + } + } + else if (m_FocusedColumn == HX_COL_ASCII) + { + m_CaretAddress++; + + if (GetKeyState(VK_SHIFT)) + { + m_SelEndCellSide = HX_LEFT; + m_SelEndAddress = m_CaretAddress; + UpdateRealSelection(); + } + else + { + CancelSelection(); + } + } + + UpdateCaretUI(true); + } + else if (nChar == VK_LEFT) + { + if (m_FocusedColumn == HX_COL_HEXDATA) + { + if(GetKeyState(VK_SHIFT) & 0x8000) + { + m_SelEndCellSide = HX_LEFT; + m_SelEndAddress--; + if (m_bCaretLoNibble) + { + m_SelStartCellSide = HX_LEFT; + } + m_CaretAddress--; + m_bCaretLoNibble = false; + UpdateRealSelection(); + } + else if (GetKeyState(VK_CONTROL) & 0x8000) + { + CaretDecrementNibble(); + CancelSelection(); + } + else + { + if (m_bCaretLoNibble) + { + CaretDecrementNibble(); + } + else + { + m_CaretAddress--; + } + + CancelSelection(); + } + } + else if (m_FocusedColumn == HX_COL_ASCII) + { + m_CaretAddress--; + + if (GetKeyState(VK_SHIFT)) + { + m_SelEndCellSide = HX_LEFT; + m_SelEndAddress = m_CaretAddress; + UpdateRealSelection(); + } + else + { + CancelSelection(); + } + } + + UpdateCaretUI(true); + } + else if (nChar == VK_NEXT || nChar == VK_PRIOR) // page down, page up + { + int delta = (nChar == VK_NEXT) ? m_NumVisibleBytes : -m_NumVisibleBytes; + + if (IsCaretAddressVisible()) + { + m_BaseAddress += delta; + m_CaretAddress += delta; + Notify(HXN_BASEADDRCHANGED); + } + else + { + m_CaretAddress += delta; + UpdateCaretUI(true, true); + } + + CancelSelection(); + } + else if (nChar == VK_INSERT) + { + m_bInsertMode = !m_bInsertMode; + Notify(HXN_INSERTMODECHANGED); + } + else if (nChar == VK_RETURN) + { + Notify(HXN_ENTERPRESSED); + } + else if (nChar == VK_HOME) + { + UpdateCaretUI(true); + } + else if (nChar == VK_BACK) + { + if (m_bHaveRealSel) + { + NotifyFillRange(m_RealSelStartAddress, m_RealSelEndAddress, 0); + CancelSelection(); + m_CaretAddress = m_RealSelStartAddress; + UpdateCaretUI(true); + } + else + { + if (m_FocusedColumn == HX_COL_HEXDATA) + { + uint32_t address = m_CaretAddress + (m_bCaretLoNibble ? 0 : -1); + NotifySetNibble(address, !m_bCaretLoNibble, 0); + CaretDecrementNibble(); + UpdateCaretUI(true); + } + else if (m_FocusedColumn == HX_COL_ASCII) + { + NotifySetByte(m_CaretAddress - 1, 0); + m_CaretAddress--; + UpdateCaretUI(true); + } + } + } + else if (nChar == VK_DELETE) + { + if (m_FocusedColumn == HX_COL_HEXDATA || m_FocusedColumn == HX_COL_ASCII) + { + if (!m_bHaveRealSel) + { + NotifySetByte(m_CaretAddress, 0); + } + else + { + NotifyFillRange(m_RealSelStartAddress, m_RealSelEndAddress, 0); + } + } + } +} + +int CHexEditCtrl::GetSelDirection(void) +{ + if (m_SelStartAddress < m_SelEndAddress) return 1; // right + if (m_SelStartAddress > m_SelEndAddress) return -1; // left + if (m_SelStartCellSide == m_SelEndCellSide) return 0; // no selection + if (m_SelStartCellSide == HX_LEFT && m_SelEndCellSide == HX_RIGHT) return 1; // right (single byte) + if (m_SelStartCellSide == HX_RIGHT && m_SelEndCellSide == HX_LEFT) return -1; // left (single byte) + return 0; +} + +void CHexEditCtrl::CancelSelection(void) +{ + m_SelStartAddress = m_CaretAddress; + m_SelEndAddress = m_CaretAddress; + m_SelStartCellSide = m_bCaretLoNibble ? HX_RIGHT : HX_LEFT; + m_SelEndCellSide = m_bCaretLoNibble ? HX_RIGHT : HX_LEFT; + UpdateRealSelection(); +} + +void CHexEditCtrl::SelectAllVisible(void) +{ + uint32_t lastVisibleByteAddress = (m_BaseAddress + m_NumVisibleBytes) - 1; + m_SelStartAddress = m_BaseAddress; + m_SelStartCellSide = HX_LEFT; + m_SelEndAddress = lastVisibleByteAddress; + m_SelEndCellSide = HX_RIGHT; + m_CaretAddress = lastVisibleByteAddress + 1; + m_bCaretLoNibble = false; + UpdateRealSelection(); +} + +bool CHexEditCtrl::IsCaretAddressVisible(void) +{ + return m_CaretAddress >= m_BaseAddress && m_CaretAddress <= SatAdd32(m_BaseAddress, m_NumVisibleBytes); +} + +uint32_t CHexEditCtrl::LineAddress(uint32_t address) +{ + return address - ((address - (m_BaseAddress % m_NumBytesPerRow)) % m_NumBytesPerRow); +} + +void CHexEditCtrl::EnsureCaretAddressVisible(bool bTop) +{ + uint32_t oldBaseAddress = m_BaseAddress; + uint32_t caretLineAddress = LineAddress(m_CaretAddress); + uint32_t lastVisibleLineAddress = m_BaseAddress + (m_NumVisibleBytes - m_NumBytesPerRow); + + if (bTop || caretLineAddress < m_BaseAddress) + { + m_BaseAddress = caretLineAddress; + } + else if (caretLineAddress >= lastVisibleLineAddress + m_NumBytesPerRow) + { + m_BaseAddress = SatAdd32(m_BaseAddress, caretLineAddress - lastVisibleLineAddress); + } + + if (oldBaseAddress != m_BaseAddress) + { + Notify(HXN_BASEADDRCHANGED); + } +} + +LRESULT CHexEditCtrl::Notify(UINT code) +{ + UINT_PTR nID = ::GetDlgCtrlID(m_hWnd); + NMHDR nmh = { m_hWnd, nID, code }; + return ::SendMessage(GetParent(), WM_NOTIFY, (WPARAM)nID, (LPARAM)&nmh); +} + +LRESULT CHexEditCtrl::NotifySetByte(uint32_t address, uint8_t value) +{ + UINT_PTR nID = ::GetDlgCtrlID(m_hWnd); + NMHXSETBYTE nmsb = { { m_hWnd, nID, HXN_SETBYTE }, m_bInsertMode, address, value }; + return ::SendMessage(GetParent(), WM_NOTIFY, (WPARAM)nID, (LPARAM)&nmsb); +} + +LRESULT CHexEditCtrl::NotifySetNibble(uint32_t address, bool bLoNibble, uint8_t value) +{ + UINT_PTR nID = ::GetDlgCtrlID(m_hWnd); + NMHXSETNIBBLE nmsn = { { m_hWnd, nID, HXN_SETNIBBLE }, m_bInsertMode, address, bLoNibble, value }; + return ::SendMessage(GetParent(), WM_NOTIFY, (WPARAM)nID, (LPARAM)&nmsn); +} + +LRESULT CHexEditCtrl::NotifyFillRange(uint32_t startAddress, uint32_t endAddress, uint8_t value) +{ + UINT_PTR nID = ::GetDlgCtrlID(m_hWnd); + NMHXFILLRANGE nmfr = { { m_hWnd, nID, HXN_FILLRANGE }, m_bInsertMode, startAddress, endAddress, value }; + return ::SendMessage(GetParent(), WM_NOTIFY, (WPARAM)nID, (LPARAM)&nmfr); +} + +LRESULT CHexEditCtrl::NotifyCtrlKeyPressed(int nChar) +{ + UINT_PTR nID = ::GetDlgCtrlID(m_hWnd); + NMHXCTRLKEYPRESSED nmck = { { m_hWnd, nID, HXN_CTRLKEYPRESSED }, nChar }; + return ::SendMessage(GetParent(), WM_NOTIFY, (WPARAM)nID, (LPARAM)&nmck); +} + +LRESULT CHexEditCtrl::NotifyPaste(uint32_t address) +{ + UINT_PTR nID = ::GetDlgCtrlID(m_hWnd); + NMHXPASTE nmp = { { m_hWnd, nID, HXN_PASTE }, address, m_FocusedColumn }; + return ::SendMessage(GetParent(), WM_NOTIFY, (WPARAM)nID, (LPARAM)&nmp); +} + +LRESULT CHexEditCtrl::NotifyRightClick(uint32_t address) +{ + UINT_PTR nID = ::GetDlgCtrlID(m_hWnd); + NMHXRCLICK nmrc = { { m_hWnd, nID, HXN_RCLICK }, address }; + return ::SendMessage(GetParent(), WM_NOTIFY, (WPARAM)nID, (LPARAM)&nmrc); +} + +LRESULT CHexEditCtrl::NotifyGetByteInfo(uint32_t address, size_t numBytes, bool bIgnoreDiff, HXBYTEINFO* oldBytes, HXBYTEINFO* newBytes) +{ + UINT_PTR nID = ::GetDlgCtrlID(m_hWnd); + NMHXGETBYTEINFO nmgbi = { { m_hWnd, nID, HXN_GETBYTEINFO }, address, numBytes, bIgnoreDiff, oldBytes, newBytes }; + return ::SendMessage(GetParent(), WM_NOTIFY, nmgbi.nmh.idFrom, (LPARAM)&nmgbi); +} + +BOOL CHexEditCtrl::OnSetCursor(CWindow /*wnd*/, UINT /*nHitTest*/, UINT /*message*/) +{ + CPoint point(::GetMessagePos()); + ScreenToClient(&point); + + HXHITTEST ht; + HitTest(point.x, point.y, &ht); + + if (ht.column == HX_COL_HEXDATA || ht.column == HX_COL_ASCII) + { + SetCursor(m_hCursorIBeam); + } + else + { + SetCursor(m_hCursorDefault); + } + return FALSE; +} + +void CHexEditCtrl::ShowCaret(void) +{ + if (!m_bCaretVisible) + { + ::ShowCaret(m_hWnd); + m_bCaretVisible = true; + } +} + +void CHexEditCtrl::HideCaret(void) +{ + if (m_bCaretVisible) + { + ::HideCaret(m_hWnd); + m_bCaretVisible = false; + } +} + +uint32_t CHexEditCtrl::SatAdd32(uint32_t a, int b) +{ + int64_t c = (int64_t)a + b; + if (c > UINT_MAX) + { + return UINT_MAX; + } + if (c < 0) + { + return 0; + } + return (uint32_t)c; +} + +uint32_t CHexEditCtrl::SatAdd32(uint32_t a, uint32_t b) +{ + uint32_t c = a + b; + if (c < a) + { + return (uint32_t)-1; + } + return c; +} + +COLORREF CHexEditCtrl::BlendColor(COLORREF c1, COLORREF c2) +{ + int r1 = GetRValue(c1); + int g1 = GetGValue(c1); + int b1 = GetBValue(c1); + int r2 = GetRValue(c2); + int g2 = GetGValue(c2); + int b2 = GetBValue(c2); + return RGB((r1+r2*2)/3, (g1+g2*2)/3, (b1+b2*2)/3); +} + +void CHexEditCtrl::UpdateLayoutInfo(void) +{ + CRect clientRect; + GetClientRect(&clientRect); + + int addressColumnWidth = 11 * m_CharWidth; + int byteWidth = m_CharWidth * 2; + int byteGroupWidth = (m_NumBytesPerGroup * byteWidth) + (m_CharWidth * 1); + int asciiGroupWidth = (m_NumBytesPerGroup * m_CharWidth); + int headerHeight = m_CharHeight; + + m_NumByteGroupsPerRow = (clientRect.Width() - addressColumnWidth) / (byteGroupWidth + asciiGroupWidth); + m_NumBytesPerRow = m_NumByteGroupsPerRow * m_NumBytesPerGroup; + m_NumVisibleRows = (clientRect.Height() - headerHeight) / m_CharHeight; + m_NumVisibleBytes = m_NumVisibleRows * m_NumBytesPerRow; + + int hexDataColumnWidth = m_NumByteGroupsPerRow * byteGroupWidth; + int asciiColumnWidth = m_NumBytesPerRow * m_CharWidth; + + int addressColumnLeft = 0; + int addressColumnRight = addressColumnLeft + addressColumnWidth; + int hexDataColumnLeft = addressColumnRight; + int hexDataColumnRight = hexDataColumnLeft + hexDataColumnWidth; + int asciiColumnLeft = hexDataColumnRight; + int asciiColumnRight = asciiColumnLeft + asciiColumnWidth; + + int columnsTop = 0 + headerHeight; + int columnsBottom = columnsTop + m_NumVisibleRows * m_CharHeight; + + m_AddressColumnRect = { addressColumnLeft, columnsTop, addressColumnRight, columnsBottom }; + m_HexDataColumnRect = { hexDataColumnLeft, columnsTop, hexDataColumnRight, columnsBottom }; + m_AsciiColumnRect = { asciiColumnLeft, columnsTop, asciiColumnRight, columnsBottom }; + + m_bLayoutChanged = true; +} + +void CHexEditCtrl::ReallocByteBuffers(void) +{ + m_NewBytes = (HXBYTEINFO*)realloc(m_NewBytes, m_NumVisibleBytes * sizeof(HXBYTEINFO)); + m_OldBytes = (HXBYTEINFO*)realloc(m_OldBytes, m_NumVisibleBytes * sizeof(HXBYTEINFO)); + + for (int i = 0; i < m_NumVisibleBytes; i++) + { + m_NewBytes[i] = { 0 }; + m_OldBytes[i] = { 0 }; + } +} + +void CHexEditCtrl::OnWindowPosChanged(LPWINDOWPOS /*lpWndPos*/) +{ + int oldNumRows = m_NumVisibleRows; + int oldNumGroups = m_NumByteGroupsPerRow; + + UpdateLayoutInfo(); + + if (oldNumRows != m_NumVisibleRows || oldNumGroups != m_NumByteGroupsPerRow) + { + ReallocByteBuffers(); + + CRect rc; + GetClientRect(&rc); + m_BackBMP = CreateCompatibleBitmap(m_BackDC, rc.Width(), rc.Height()); + HBITMAP hOldBMP = (HBITMAP)SelectObject(m_BackDC, m_BackBMP); + DeleteObject(hOldBMP); + + CRect clrRc(0, 0, rc.Width(), rc.Height()); + HBRUSH hbrush = CreateSolidBrush(BKCOLOR_DEFAULT); + FillRect(m_BackDC, clrRc, hbrush); + DeleteObject(hbrush); + + Draw(); + DrawAddressColumn(); + DrawHeader(); + } +} + +void CHexEditCtrl::SetByteGroupSize(int nBytes) +{ + m_NumBytesPerGroup = nBytes; + Notify(HXN_GROUPSIZECHANGED); + + UpdateLayoutInfo(); + ReallocByteBuffers(); + + CRect rc; + GetClientRect(&rc); + CRect clrRc(0, 0, rc.Width(), rc.Height()); + HBRUSH hbrush = CreateSolidBrush(BKCOLOR_DEFAULT); + FillRect(m_BackDC, clrRc, hbrush); + DeleteObject(hbrush); + + Draw(); + DrawAddressColumn(); + DrawHeader(); + + int addressColumnWidth = 11 * m_CharWidth; + int headerHeight = m_CharHeight; + CRect rcInv = { addressColumnWidth, headerHeight, rc.Width(), rc.Height() }; + InvalidateRect(&rcInv, true); +} diff --git a/Source/Project64/UserInterface/WTLControls/HexEditCtrl.h b/Source/Project64/UserInterface/WTLControls/HexEditCtrl.h new file mode 100644 index 000000000..4870a2620 --- /dev/null +++ b/Source/Project64/UserInterface/WTLControls/HexEditCtrl.h @@ -0,0 +1,309 @@ +#pragma once +#include + +enum +{ + HXN_REDRAWSTARTED, + HXN_GETBYTEINFO, + HXN_SETBYTE, + HXN_SETNIBBLE, + HXN_FILLRANGE, + HXN_RCLICK, + HXN_INSERTMODECHANGED, + HXN_HOTADDRCHANGED, + HXN_BASEADDRCHANGED, + HXN_GROUPSIZECHANGED, + HXN_SELCHANGED, + HXN_CTRLKEYPRESSED, + HXN_ENTERPRESSED, + HXN_COPY, + HXN_PASTE, +}; + +enum HXCOLUMN +{ + HX_COL_NONE = -1, + HX_COL_ADDRESS, + HX_COL_HEXDATA, + HX_COL_ASCII +}; + +typedef struct HXBYTEINFO_S +{ + bool bHidden; + bool bValid; + uint8_t value; + COLORREF color; + COLORREF bkColor; + + bool operator==(const HXBYTEINFO_S& b) const + { + return memcmp(this, &b, sizeof(HXBYTEINFO_S)) == 0; + } + + bool operator!=(const HXBYTEINFO_S& b) const + { + return memcmp(this, &b, sizeof(HXBYTEINFO_S)) != 0; + } +} HXBYTEINFO; + +template<> +struct std::hash +{ + std::size_t operator()(const HXBYTEINFO& k) const + { + return (size_t)(k.bValid * 0xFFFFFFFF) ^ (k.value * 0x1010101) ^ k.color ^ k.bkColor; + } +}; + +typedef struct +{ + NMHDR nmh; + uint32_t address; + size_t numBytes; + bool bIgnoreDiff; + HXBYTEINFO* oldBytes; + HXBYTEINFO* newBytes; +} NMHXGETBYTEINFO; + +typedef struct +{ + NMHDR nmh; + bool bInsert; + uint32_t address; + uint8_t value; +} NMHXSETBYTE; + +typedef struct +{ + NMHDR nmh; + bool bInsert; + uint32_t address; + bool bLoNibble; + uint8_t value; +} NMHXSETNIBBLE; + +typedef struct +{ + NMHDR nmh; + bool bInsert; + uint32_t startAddress; + uint32_t endAddress; + uint8_t value; +} NMHXFILLRANGE; + +typedef struct +{ + NMHDR nmh; + uint32_t address; + uint32_t length; + uint8_t* data; +} NMHXSETBYTES; + +typedef struct +{ + NMHDR nmh; + uint32_t address; +} NMHXRCLICK; + +typedef struct +{ + NMHDR nmh; + uint32_t address; + HXCOLUMN column; +} NMHXPASTE; + +typedef struct +{ + NMHDR nmh; + int nChar; +} NMHXCTRLKEYPRESSED; + +class CHexEditCtrl : + public CWindowImpl +{ +public: + CHexEditCtrl(void); + ~CHexEditCtrl(void); + DECLARE_WND_CLASS(_T("HexEditCtrl")) + BOOL Attach(HWND hWnd); + HWND Detach(void); + + static char ByteAscii(uint8_t value); + static uint8_t HexCharValue(char c); + static int CALLBACK HaveFontCb(CONST LOGFONTA *lplf, CONST TEXTMETRICA *lptm, DWORD FontType, LPARAM lParam); + static bool HaveFont(HDC hdc, const char* name); + + void Draw(void); + + void Copy(void); + void Paste(bool bAdvanceCaret = true); + + void SetBaseAddress(uint32_t address); + void SetByteGroupSize(int nBytes); + + uint32_t GetBaseAddress(void); + uint32_t GetCaretAddress(void); + uint32_t GetHotAddress(void); + int GetNumBytesPerGroup(void); + int GetNumBytesPerRow(void); + int GetNumVisibleBytes(void); + bool GetSelectionRange(uint32_t* startAddress, uint32_t* endAddress); + HXCOLUMN GetFocusedColumn(void); + bool GetInsertMode(void); + +private: + enum HXCELLSIDE + { + HX_LEFT, + HX_RIGHT + }; + + enum + { + TIMER_ID_AUTO_REFRESH, + TIMER_ID_DRAG_SCROLL + }; + + enum + { + BKCOLOR_DEFAULT = RGB(255, 255, 255), + BKCOLOR_ADDR = RGB(220, 220, 220), + COLOR_ADDR = RGB(40, 40, 40), + BKCOLOR_SEL_FOCUSED = RGB(51, 153, 255), + COLOR_SEL_FOCUSED = RGB(255, 255, 255), + BKCOLOR_SEL_UNFOCUSED = RGB(200, 200, 200), + COLOR_SEL_UNFOCUSED = RGB(0, 0, 0), + BKCOLOR_HOT = RGB(140, 140, 140) + }; + + typedef struct + { + HXCOLUMN column; + uint32_t asciiAddress; + HXCELLSIDE asciiCellSide; + uint32_t hexAddress; + HXCELLSIDE hexCellSide; + } HXHITTEST; + + typedef struct + { + CRect rcHex; + CRect rcAscii; + } HXRECTPAIR; + + uint32_t m_BaseAddress; + uint32_t m_DrawnBaseAddress; + uint32_t m_SelStartAddress; + HXCELLSIDE m_SelStartCellSide; + uint32_t m_SelEndAddress; + HXCELLSIDE m_SelEndCellSide; + uint32_t m_RealSelStartAddress; + uint32_t m_RealSelEndAddress; + bool m_bHaveRealSel; + bool m_bInsertMode; + bool m_bHaveCaret; + bool m_bCaretVisible; + uint32_t m_CaretAddress; + bool m_bCaretLoNibble; + bool m_bShowHotAddress; + uint32_t m_HotAddress; + HXCOLUMN m_FocusedColumn; + HFONT m_Font; + HBITMAP m_BackBMP; + HDC m_BackDC; + HCURSOR m_hCursorIBeam; + HCURSOR m_hCursorDefault; + int m_DragScrollDelta; + bool m_bDblClicked; + bool m_bLButtonDown; + bool m_bMouseDragging; + bool m_bLayoutChanged; + int m_CharWidth; + int m_CharHeight; + CRect m_AddressColumnRect; + CRect m_HexDataColumnRect; + CRect m_AsciiColumnRect; + int m_NumBytesPerGroup; + int m_NumByteGroupsPerRow; + int m_NumBytesPerRow; + int m_NumVisibleRows; + int m_NumVisibleBytes; + HXBYTEINFO* m_NewBytes; + HXBYTEINFO* m_OldBytes; + + static COLORREF BlendColor(COLORREF c1, COLORREF c2); + static uint32_t SatAdd32(uint32_t a, uint32_t b); + static uint32_t SatAdd32(uint32_t a, int b); + + void DrawAddressColumn(void); + void DrawHeader(void); + void Text(int x, int y, const char *text, COLORREF bg, COLORREF fg, CRect* rcOut); + bool IsSelected(uint32_t address); + int GetSelDirection(void); + void CancelSelection(void); + void SelectAllVisible(void); + void UpdateRealSelection(void); + + uint32_t LineAddress(uint32_t address); + + void GetHexCellPos(int index, CRect* rc); + void GetAsciiCellPos(int index, CRect* rc); + void HitTest(int x, int y, HXHITTEST* pht); + + void ShowCaret(void); + void HideCaret(void); + void CaretIncrementNibble(void); + void CaretDecrementNibble(void); + bool UpdateCaretUI(bool bEnsureVisible, bool bTop = false); + void EnsureCaretAddressVisible(bool bTop = false); + bool IsCaretAddressVisible(void); + + void UpdateLayoutInfo(void); + void ReallocByteBuffers(void); + + LRESULT Notify(UINT code); + LRESULT NotifyGetByteInfo(uint32_t address, size_t numBytes, bool bIgnoreDiff, HXBYTEINFO* oldBytes, HXBYTEINFO* newBytes); + LRESULT NotifySetByte(uint32_t address, uint8_t value); + LRESULT NotifySetNibble(uint32_t address, bool bLoNibble, uint8_t value); + LRESULT NotifyFillRange(uint32_t startAddress, uint32_t endAddress, uint8_t value); + LRESULT NotifyCtrlKeyPressed(int nChar); + LRESULT NotifyPaste(uint32_t address); + LRESULT NotifyRightClick(uint32_t address); + + void OnLButtonDown(UINT nFlags, CPoint point); + void OnLButtonDblClk(UINT nFlags, CPoint point); + void OnLButtonUp(UINT nFlags, CPoint point); + void OnRButtonDown(UINT nFlags, CPoint point); + void OnRButtonUp(UINT nFlags, CPoint point); + void OnMouseMove(UINT nFlags, CPoint point); + BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt); + void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); + void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags); + void OnSetFocus(CWindow wndOld); + void OnKillFocus(CWindow wndFocus); + void OnTimer(UINT_PTR nIDEvent); + UINT OnGetDlgCode(LPMSG lpMsg); + void OnPaint(CDCHandle dc); + BOOL OnSetCursor(CWindow wnd, UINT nHitTest, UINT message); + void OnWindowPosChanged(LPWINDOWPOS lpWndPos); + + BEGIN_MSG_MAP_EX(CHexEditCtrl) + MSG_WM_RBUTTONDOWN(OnRButtonDown) + MSG_WM_LBUTTONDOWN(OnLButtonDown) + MSG_WM_LBUTTONUP(OnLButtonUp) + MSG_WM_RBUTTONUP(OnRButtonUp) + MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk) + MSG_WM_MOUSEMOVE(OnMouseMove) + MSG_WM_MOUSEWHEEL(OnMouseWheel) + MSG_WM_KEYDOWN(OnKeyDown) + MSG_WM_CHAR(OnChar) + MSG_WM_SETFOCUS(OnSetFocus) + MSG_WM_KILLFOCUS(OnKillFocus) + MSG_WM_TIMER(OnTimer) + MSG_WM_GETDLGCODE(OnGetDlgCode) + MSG_WM_PAINT(OnPaint) + MSG_WM_SETCURSOR(OnSetCursor) + MSG_WM_WINDOWPOSCHANGED(OnWindowPosChanged) + END_MSG_MAP() +}; diff --git a/Source/Project64/UserInterface/resource.h b/Source/Project64/UserInterface/resource.h index 08b0cd062..3fc3dd405 100644 --- a/Source/Project64/UserInterface/resource.h +++ b/Source/Project64/UserInterface/resource.h @@ -91,10 +91,8 @@ #define RSP_ABOUT 1006 #define IDC_ASSIGN 1006 #define IDC_BTN_CHOOSE_FILE 1006 -#define IDC_DUMP_MEM 1006 #define IDC_INFO_FILENAME 1007 #define IDC_BTN_RDRAM 1007 -#define IDC_REFRSH_MEM 1007 #define IDC_INFO_ROMNAME 1008 #define IDC_RESET_PAGE 1008 #define IDC_INFO_CARTID 1009 @@ -194,7 +192,6 @@ #define IDC_DIRECT_READ 1057 #define IDC_DMA_READ 1058 #define IDC_CONT_PAK 1059 -#define IDC_SEARCH_MEM 1059 #define IDC_BTN_ROM 1061 #define IDC_TEXTURE_OTHER 1062 #define IDC_TEXTURE_DIR 1063 @@ -202,7 +199,6 @@ #define IDC_TEXTURE_DEFAULT 1064 #define IDC_LST_RESULTS 1064 #define IDC_SELECT_TEXTURE_DIR 1065 -#define IDC_MEM_DETAILS 1065 #define IDC_PLUGIN_OTHER 1066 #define IDC_PLUGIN_DIR 1067 #define IDC_PLUGIN_DEFAULT 1068 @@ -508,9 +504,7 @@ #define IDC_COP0_17_EDIT 1332 #define IDC_COP0_18_EDIT 1333 #define IDC_FILTER_STATIC 1339 -#define IDC_SYM_INFO 1348 #define IDC_BLOCK_INFO 1350 -#define IDC_DMA_INFO 1351 #define IDC_BACK_BTN 1352 #define IDC_FORWARD_BTN 1353 #define IDC_PC_EDIT 1354 @@ -604,7 +598,6 @@ #define IDC_DD44_EDIT 1443 #define IDC_DD48_EDIT 1444 #define IDC_ROM_FIXEDAUDIO 1445 -#define IDC_CHK_AUTOREFRESH 1446 #define IDC_SHOW_FILE_EXTENSIONS 1447 #define IDC_ENHANCEMENTLIST 1450 #define IDC_OVERCLOCK 1451 @@ -718,6 +711,10 @@ #define IDC_CHK_FP_CO 1566 #define IDC_CHK_FP_CU 1567 #define IDC_CHK_FP_CI 1568 +#define IDC_HEXEDIT 1569 +#define IDC_MEMTABS 1571 +#define IDC_STATUSBAR 1572 +#define IDC_CMB_JUMP 1573 #define ID_POPUPMENU_PLAYGAMEWITHDISK 40008 #define ID_POPUPMENU_ADDSYMBOL 40013 #define ID_POPUPMENU_VIEWDISASM 40017 @@ -757,9 +754,21 @@ #define ID_RESULTS_ADDALLTOWATCHLIST 40080 #define ID_WATCHLIST_CHANGE_ADDRESS 40082 #define ID_WATCHLIST_CHANGE_ADDRESSBY 40084 -#define ID_POPUPMENU_COPY_WORD 40089 -#define ID_POPUPMENU_COPY_HALFWORD 40090 -#define ID_POPUPMENU_COPY_BYTE 40091 +#define ID_POPUPMENU_PASTE 40092 +#define ID_POPUPMENU_COPY 40093 +#define ID_POPUPMENU_FOLLOWPOINTER 40095 +#define ID_POPUPMENU_ZEROFILL 40097 +#define ID_POPUPMENU_BYTEGROUPSIZE_1 40103 +#define ID_POPUPMENU_BYTEGROUPSIZE_2 40104 +#define ID_POPUPMENU_BYTEGROUPSIZE_4 40105 +#define ID_POPUPMENU_BYTEGROUPSIZE_8 40106 +#define ID_POPUPMENU_SAFEMODE 40107 +#define ID_POPUPMENU_DUMP 40108 +#define ID_POPUPMENU_SEARCH 40109 +#define ID_POPUPMENU_JUMPHERE 40113 +#define ID_POPUPMENU_COPYGAMESHARKCODE 40118 +#define ID_POPUPMENU_COPYDATAWITHROWADDRESSES 40119 +#define ID_POPUPMENU_COPYDATAWITHGROUPADDRESSES 40120 #define ID_POPUPMENU_ROMDIRECTORY 40137 #define ID_POPUPMENU_REFRESHROMLIST 40138 #define ID_POPUPMENU_PLAYGAME 40152 @@ -777,8 +786,8 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 219 -#define _APS_NEXT_COMMAND_VALUE 40092 -#define _APS_NEXT_CONTROL_VALUE 1569 +#define _APS_NEXT_COMMAND_VALUE 40121 +#define _APS_NEXT_CONTROL_VALUE 1574 #define _APS_NEXT_SYMED_VALUE 102 #endif #endif From d76d3e82c1362d833e2b776ac6f943ed64a0e269 Mon Sep 17 00:00:00 2001 From: shygoo Date: Sun, 1 Dec 2019 04:10:36 -0600 Subject: [PATCH 11/14] [Debugger] Optimize interpreter breakpoint and callback checks --- .../UserInterface/Debugger/Breakpoints.cpp | 26 ++-- .../UserInterface/Debugger/Breakpoints.h | 21 ++-- .../Debugger/Debugger-StackTrace.cpp | 22 ---- .../Debugger/Debugger-StackTrace.h | 24 +++- .../UserInterface/Debugger/Debugger.cpp | 117 +++++++++--------- .../UserInterface/Debugger/ScriptHook.cpp | 4 + .../UserInterface/Debugger/ScriptSystem.cpp | 16 ++- .../UserInterface/Debugger/ScriptSystem.h | 9 +- 8 files changed, 130 insertions(+), 109 deletions(-) diff --git a/Source/Project64/UserInterface/Debugger/Breakpoints.cpp b/Source/Project64/UserInterface/Debugger/Breakpoints.cpp index 86c367b19..2ede9595b 100644 --- a/Source/Project64/UserInterface/Debugger/Breakpoints.cpp +++ b/Source/Project64/UserInterface/Debugger/Breakpoints.cpp @@ -18,6 +18,7 @@ #include CBreakpoints::CBreakpoints() : + m_bHaveRegBP(false), m_GPRWriteBP(0), m_GPRReadBP(0), m_HIWriteBP(false), @@ -359,22 +360,17 @@ size_t CBreakpoints::NumMemLocks() return m_MemLocks.size(); } -bool CBreakpoints::HaveAnyGPRWriteBP(void) { return m_GPRWriteBP != 0; } -bool CBreakpoints::HaveAnyGPRReadBP(void) { return m_GPRReadBP != 0; } -bool CBreakpoints::HaveGPRWriteBP(int nReg) { return (m_GPRWriteBP & (1 << nReg)) != 0; } -bool CBreakpoints::HaveGPRReadBP(int nReg) { return (m_GPRReadBP & (1 << nReg)) != 0; } -void CBreakpoints::ToggleGPRWriteBP(int nReg) { m_GPRWriteBP ^= (1 << nReg); } -void CBreakpoints::ToggleGPRReadBP(int nReg) { m_GPRReadBP ^= (1 << nReg); } +void CBreakpoints::UpdateHaveRegBP(void) +{ + m_bHaveRegBP = HaveAnyGPRWriteBP() || HaveAnyGPRReadBP() || HaveHIWriteBP() || HaveHIReadBP() || HaveLOWriteBP() || HaveLOReadBP(); +} -bool CBreakpoints::HaveHIWriteBP(void) { return m_HIWriteBP; } -bool CBreakpoints::HaveHIReadBP(void) { return m_HIReadBP; } -bool CBreakpoints::HaveLOWriteBP(void) { return m_LOWriteBP; } -bool CBreakpoints::HaveLOReadBP(void) { return m_LOReadBP; } - -void CBreakpoints::ToggleHIWriteBP(void) { m_HIWriteBP = !m_HIWriteBP; } -void CBreakpoints::ToggleHIReadBP(void) { m_HIReadBP = !m_HIReadBP; } -void CBreakpoints::ToggleLOWriteBP(void) { m_LOWriteBP = !m_LOWriteBP; } -void CBreakpoints::ToggleLOReadBP(void) { m_LOReadBP = !m_LOReadBP; } +void CBreakpoints::ToggleGPRWriteBP(int nReg) { m_GPRWriteBP ^= (1 << nReg); UpdateHaveRegBP(); } +void CBreakpoints::ToggleGPRReadBP(int nReg) { m_GPRReadBP ^= (1 << nReg); UpdateHaveRegBP(); } +void CBreakpoints::ToggleHIWriteBP(void) { m_HIWriteBP = !m_HIWriteBP; UpdateHaveRegBP(); } +void CBreakpoints::ToggleHIReadBP(void) { m_HIReadBP = !m_HIReadBP; UpdateHaveRegBP(); } +void CBreakpoints::ToggleLOWriteBP(void) { m_LOWriteBP = !m_LOWriteBP; UpdateHaveRegBP(); } +void CBreakpoints::ToggleLOReadBP(void) { m_LOReadBP = !m_LOReadBP; UpdateHaveRegBP(); } void CBreakpoints::PreUpdateBP() { diff --git a/Source/Project64/UserInterface/Debugger/Breakpoints.h b/Source/Project64/UserInterface/Debugger/Breakpoints.h index 17a0a496e..a7576a055 100644 --- a/Source/Project64/UserInterface/Debugger/Breakpoints.h +++ b/Source/Project64/UserInterface/Debugger/Breakpoints.h @@ -67,17 +67,19 @@ public: void ClearMemLocks(void); size_t NumMemLocks(void); - bool HaveAnyGPRReadBP(void); - bool HaveAnyGPRWriteBP(void); - bool HaveGPRWriteBP(int nReg); - bool HaveGPRReadBP(int nReg); + inline bool HaveRegBP(void) { return m_bHaveRegBP; } + inline bool HaveAnyGPRWriteBP(void) { return m_GPRWriteBP != 0; } + inline bool HaveAnyGPRReadBP(void) { return m_GPRReadBP != 0; } + inline bool HaveGPRWriteBP(int nReg) { return (m_GPRWriteBP & (1 << nReg)) != 0; } + inline bool HaveGPRReadBP(int nReg) { return (m_GPRReadBP & (1 << nReg)) != 0; } + inline bool HaveHIWriteBP(void) { return m_HIWriteBP; } + inline bool HaveHIReadBP(void) { return m_HIReadBP; } + inline bool HaveLOWriteBP(void) { return m_LOWriteBP; } + inline bool HaveLOReadBP(void) { return m_LOReadBP; } + + void UpdateHaveRegBP(void); void ToggleGPRWriteBP(int nReg); void ToggleGPRReadBP(int nReg); - - bool HaveHIWriteBP(void); - bool HaveHIReadBP(void); - bool HaveLOWriteBP(void); - bool HaveLOReadBP(void); void ToggleHIWriteBP(void); void ToggleHIReadBP(void); void ToggleLOWriteBP(void); @@ -95,6 +97,7 @@ private: memlocks_t m_MemLocks; + bool m_bHaveRegBP; uint32_t m_GPRWriteBP, m_GPRReadBP; bool m_HIWriteBP, m_HIReadBP, m_LOWriteBP, m_LOReadBP; }; \ No newline at end of file diff --git a/Source/Project64/UserInterface/Debugger/Debugger-StackTrace.cpp b/Source/Project64/UserInterface/Debugger/Debugger-StackTrace.cpp index 9d7108242..54e8052f3 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger-StackTrace.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger-StackTrace.cpp @@ -24,28 +24,6 @@ CDebugStackTrace::~CDebugStackTrace() { } -void CDebugStackTrace::PushEntry(uint32_t routineAddress, uint32_t callingAddress) -{ - if (m_EntriesIndex < STACKTRACE_MAX_ENTRIES) - { - m_Entries[m_EntriesIndex] = { routineAddress, callingAddress }; - m_EntriesIndex++; - } -} - -void CDebugStackTrace::PopEntry() -{ - if (m_EntriesIndex > 0) - { - m_EntriesIndex--; - } -} - -void CDebugStackTrace::ClearEntries() -{ - m_EntriesIndex = 0; -} - LRESULT CDebugStackTrace::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { DlgResize_Init(); diff --git a/Source/Project64/UserInterface/Debugger/Debugger-StackTrace.h b/Source/Project64/UserInterface/Debugger/Debugger-StackTrace.h index a7f3f5681..0b63d94e1 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger-StackTrace.h +++ b/Source/Project64/UserInterface/Debugger/Debugger-StackTrace.h @@ -32,9 +32,27 @@ public: void Refresh(); - void PushEntry(uint32_t routineAddress, uint32_t callingAddress); - void PopEntry(); - void ClearEntries(); + inline void PushEntry(uint32_t routineAddress, uint32_t callingAddress) + { + if (m_EntriesIndex < STACKTRACE_MAX_ENTRIES) + { + m_Entries[m_EntriesIndex] = { routineAddress, callingAddress }; + m_EntriesIndex++; + } + } + + inline void PopEntry() + { + if (m_EntriesIndex > 0) + { + m_EntriesIndex--; + } + } + + inline void ClearEntries() + { + m_EntriesIndex = 0; + } private: diff --git a/Source/Project64/UserInterface/Debugger/Debugger.cpp b/Source/Project64/UserInterface/Debugger/Debugger.cpp index 6882787d4..bc1d83895 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger.cpp @@ -540,19 +540,19 @@ void CDebuggerUI::HandleCartToRamDMA(void) // Called from the interpreter core at the beginning of every CPU step void CDebuggerUI::CPUStepStarted() { + uint32_t pc = g_Reg->m_PROGRAM_COUNTER; + COpInfo opInfo(R4300iOp::m_Opcode); + bool bStoreOp = opInfo.IsStoreCommand(); + uint32_t storeAddress = bStoreOp ? opInfo.GetLoadStoreAddress() : 0; + if (isStepping() && bCPULoggingEnabled()) { Debug_RefreshCPULogWindow(); } - uint32_t pc = g_Reg->m_PROGRAM_COUNTER; - COpInfo opInfo(R4300iOp::m_Opcode); - - if (opInfo.IsStoreCommand()) + if(bStoreOp && m_Breakpoints->NumMemLocks() > 0) { - uint32_t memoryAddress = opInfo.GetLoadStoreAddress(); - - if (m_Breakpoints->MemLockExists(memoryAddress, opInfo.NumBytesToStore())) + if (m_Breakpoints->MemLockExists(storeAddress, opInfo.NumBytesToStore())) { // Memory is locked, skip op g_Settings->SaveBool(Debugger_SkipOp, true); @@ -560,37 +560,35 @@ void CDebuggerUI::CPUStepStarted() } } - m_ScriptSystem->HookCPUExec()->InvokeByAddressInRange(pc); - if (SkipOp()) { return; } - - m_ScriptSystem->HookCPUExecOpcode()->InvokeByAddressInRange_MaskedOpcode(pc, R4300iOp::m_Opcode.Hex); - if (SkipOp()) { return; } - - m_ScriptSystem->HookCPUGPRValue()->InvokeByAddressInRange_GPRValue(pc); - if (SkipOp()) { return; } - - // Memory events, pi cart -> ram dma - if (opInfo.IsLoadStoreCommand()) // Read and write instructions + if (m_ScriptSystem->HaveCallbacks()) { - uint32_t memoryAddress = opInfo.GetLoadStoreAddress(); + m_ScriptSystem->HookCPUExec()->InvokeByAddressInRange(pc); + if (SkipOp()) { return; } - if (opInfo.IsLoadCommand()) // Read instructions + m_ScriptSystem->HookCPUExecOpcode()->InvokeByAddressInRange_MaskedOpcode(pc, R4300iOp::m_Opcode.Hex); + if (SkipOp()) { return; } + + m_ScriptSystem->HookCPUGPRValue()->InvokeByAddressInRange_GPRValue(pc); + if (SkipOp()) { return; } + + if (bStoreOp) { - m_ScriptSystem->HookCPURead()->InvokeByAddressInRange(memoryAddress); + m_ScriptSystem->HookCPUWrite()->InvokeByAddressInRange(storeAddress); if (SkipOp()) { return; } } - else // Write instructions - { - m_ScriptSystem->HookCPUWrite()->InvokeByAddressInRange(memoryAddress); - if (SkipOp()) { return; } - if (memoryAddress == 0xA460000C) // PI_WR_LEN_REG - { - HandleCartToRamDMA(); - } + if (opInfo.IsLoadCommand()) + { + m_ScriptSystem->HookCPURead()->InvokeByAddressInRange(opInfo.GetLoadStoreAddress()); + if (SkipOp()) { return; } } } + if (bStoreOp && storeAddress == 0xA460000C) // PI_WR_LEN_REG + { + HandleCartToRamDMA(); + } + if (CDebugSettings::ExceptionBreakpoints() != 0) { if (pc == 0x80000000 || pc == 0x80000080 || @@ -603,36 +601,39 @@ void CDebuggerUI::CPUStepStarted() } } - if (m_Breakpoints->HaveAnyGPRWriteBP()) + if (m_Breakpoints->HaveRegBP()) { - int nReg = 0; - opInfo.WritesGPR(&nReg); + if (m_Breakpoints->HaveAnyGPRWriteBP()) + { + int nReg = 0; + opInfo.WritesGPR(&nReg); - if (nReg != 0 && m_Breakpoints->HaveGPRWriteBP(nReg)) + if (nReg != 0 && m_Breakpoints->HaveGPRWriteBP(nReg)) + { + g_Settings->SaveBool(Debugger_SteppingOps, true); + } + } + + if (m_Breakpoints->HaveAnyGPRReadBP()) + { + int nReg1 = 0, nReg2 = 0; + opInfo.ReadsGPR(&nReg1, &nReg2); + + if ((nReg1 != 0 && m_Breakpoints->HaveGPRReadBP(nReg1)) || + (nReg2 != 0 && m_Breakpoints->HaveGPRReadBP(nReg2))) + { + g_Settings->SaveBool(Debugger_SteppingOps, true); + } + } + + if (m_Breakpoints->HaveHIWriteBP() && opInfo.WritesHI() || + m_Breakpoints->HaveLOWriteBP() && opInfo.WritesLO() || + m_Breakpoints->HaveHIReadBP() && opInfo.ReadsHI() || + m_Breakpoints->HaveLOReadBP() && opInfo.ReadsLO()) { g_Settings->SaveBool(Debugger_SteppingOps, true); } } - - if (m_Breakpoints->HaveAnyGPRReadBP()) - { - int nReg1 = 0, nReg2 = 0; - opInfo.ReadsGPR(&nReg1, &nReg2); - - if ((nReg1 != 0 && m_Breakpoints->HaveGPRReadBP(nReg1)) || - (nReg2 != 0 && m_Breakpoints->HaveGPRReadBP(nReg2))) - { - g_Settings->SaveBool(Debugger_SteppingOps, true); - } - } - - if (m_Breakpoints->HaveHIWriteBP() && opInfo.WritesHI() || - m_Breakpoints->HaveLOWriteBP() && opInfo.WritesLO() || - m_Breakpoints->HaveHIReadBP() && opInfo.ReadsHI() || - m_Breakpoints->HaveLOReadBP() && opInfo.ReadsLO()) - { - g_Settings->SaveBool(Debugger_SteppingOps, true); - } } // Called before opcode is executed (not called if SkipOp is set) @@ -647,15 +648,15 @@ void CDebuggerUI::CPUStep() // Called after opcode has been executed void CDebuggerUI::CPUStepEnded() { + if (m_StackTrace == NULL) + { + return; + } + OPCODE Opcode = R4300iOp::m_Opcode; uint32_t op = Opcode.op; uint32_t funct = Opcode.funct; - if (m_StackTrace == NULL) - { - m_StackTrace = new CDebugStackTrace(this); - } - if (op == R4300i_JAL || ((op == R4300i_SPECIAL) && (funct == R4300i_SPECIAL_JALR) && (Opcode.rd == 31))) // JAL or JALR RA, x { m_StackTrace->PushEntry(R4300iOp::m_JumpToLocation, g_Reg->m_PROGRAM_COUNTER); diff --git a/Source/Project64/UserInterface/Debugger/ScriptHook.cpp b/Source/Project64/UserInterface/Debugger/ScriptHook.cpp index 9a9f616f6..6e0296e77 100644 --- a/Source/Project64/UserInterface/Debugger/ScriptHook.cpp +++ b/Source/Project64/UserInterface/Debugger/ScriptHook.cpp @@ -17,6 +17,7 @@ int CScriptHook::Add(CScriptInstance* scriptInstance, void* heapptr, uint32_t pa jsCallback.param4 = param4; jsCallback.bOnce = bOnce; m_Callbacks.push_back(jsCallback); + m_ScriptSystem->CallbackAdded(); return jsCallback.callbackId; } @@ -122,6 +123,7 @@ void CScriptHook::RemoveById(int callbackId) if (m_Callbacks[i].callbackId == callbackId) { m_Callbacks.erase(m_Callbacks.begin() + i); + m_ScriptSystem->CallbackRemoved(); return; } } @@ -135,6 +137,7 @@ void CScriptHook::RemoveByParam(uint32_t param) if (m_Callbacks[i].param == param) { m_Callbacks.erase(m_Callbacks.begin() + i); + m_ScriptSystem->CallbackRemoved(); return; } } @@ -148,6 +151,7 @@ void CScriptHook::RemoveByInstance(CScriptInstance* scriptInstance) if (m_Callbacks[i].scriptInstance == scriptInstance) { m_Callbacks.erase(m_Callbacks.begin() + i); + m_ScriptSystem->CallbackRemoved(); } } } diff --git a/Source/Project64/UserInterface/Debugger/ScriptSystem.cpp b/Source/Project64/UserInterface/Debugger/ScriptSystem.cpp index 22b4f2e36..e9d3b7fe2 100644 --- a/Source/Project64/UserInterface/Debugger/ScriptSystem.cpp +++ b/Source/Project64/UserInterface/Debugger/ScriptSystem.cpp @@ -21,6 +21,7 @@ CScriptSystem::CScriptSystem(CDebuggerUI* debugger) WSAStartup(MAKEWORD(2, 2), &wsaData); m_NextCallbackId = 0; + m_NumCallbacks = 0; m_Debugger = debugger; @@ -207,4 +208,17 @@ CScriptHook* CScriptSystem::GetHook(const char* hookId) int CScriptSystem::GetNextCallbackId() { return m_NextCallbackId++; -} \ No newline at end of file +} + +void CScriptSystem::CallbackAdded() +{ + m_NumCallbacks++; +} + +void CScriptSystem::CallbackRemoved() +{ + if (m_NumCallbacks > 0) + { + m_NumCallbacks--; + } +} diff --git a/Source/Project64/UserInterface/Debugger/ScriptSystem.h b/Source/Project64/UserInterface/Debugger/ScriptSystem.h index b95b6115f..356ff1f0e 100644 --- a/Source/Project64/UserInterface/Debugger/ScriptSystem.h +++ b/Source/Project64/UserInterface/Debugger/ScriptSystem.h @@ -43,7 +43,7 @@ private: } INSTANCE_ENTRY; CDebuggerUI* m_Debugger; - + int m_NumCallbacks; char* m_APIScript; vector m_Hooks; @@ -103,6 +103,13 @@ public: CScriptHook* GetHook(const char* hookId); int GetNextCallbackId(); + void CallbackAdded(); + void CallbackRemoved(); + + inline int HaveCallbacks() + { + return m_NumCallbacks != 0; + } void DeleteStoppedInstances(); INSTANCE_STATE GetInstanceState(char* scriptName); From b9be612ac5daa0557241975101665fca7a608052 Mon Sep 17 00:00:00 2001 From: KrimtonZ Date: Mon, 16 Dec 2019 14:15:26 -0600 Subject: [PATCH 12/14] add remaining trap instructions, properly implement traps for the interpreter core --- .../N64System/Interpreter/InterpreterOps.cpp | 137 ++++++++++++++++-- .../N64System/Interpreter/InterpreterOps.h | 11 ++ .../Interpreter/InterpreterOps32.cpp | 22 +-- .../N64System/Mips/RegisterClass.cpp | 16 ++ .../N64System/Mips/RegisterClass.h | 1 + 5 files changed, 164 insertions(+), 23 deletions(-) diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index 0bc60a890..b920bd947 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -250,13 +250,13 @@ R4300iOp::Func * R4300iOp::BuildInterpreter() Jump_Special[45] = SPECIAL_DADDU; Jump_Special[46] = SPECIAL_DSUB; Jump_Special[47] = SPECIAL_DSUBU; - Jump_Special[48] = UnknownOpcode; - Jump_Special[49] = UnknownOpcode; - Jump_Special[50] = UnknownOpcode; - Jump_Special[51] = UnknownOpcode; + Jump_Special[48] = SPECIAL_TGE; + Jump_Special[49] = SPECIAL_TGEU; + Jump_Special[50] = SPECIAL_TLT; + Jump_Special[51] = SPECIAL_TLTU; Jump_Special[52] = SPECIAL_TEQ; Jump_Special[53] = UnknownOpcode; - Jump_Special[54] = UnknownOpcode; + Jump_Special[54] = SPECIAL_TNE; Jump_Special[55] = UnknownOpcode; Jump_Special[56] = SPECIAL_DSLL; Jump_Special[57] = UnknownOpcode; @@ -275,13 +275,13 @@ R4300iOp::Func * R4300iOp::BuildInterpreter() Jump_Regimm[5] = UnknownOpcode; Jump_Regimm[6] = UnknownOpcode; Jump_Regimm[7] = UnknownOpcode; - Jump_Regimm[8] = UnknownOpcode; - Jump_Regimm[9] = UnknownOpcode; - Jump_Regimm[10] = UnknownOpcode; - Jump_Regimm[11] = UnknownOpcode; - Jump_Regimm[12] = UnknownOpcode; + Jump_Regimm[8] = REGIMM_TGEI; + Jump_Regimm[9] = REGIMM_TGEIU; + Jump_Regimm[10] = REGIMM_TLTI; + Jump_Regimm[11] = REGIMM_TLTIU; + Jump_Regimm[12] = REGIMM_TEQI; Jump_Regimm[13] = UnknownOpcode; - Jump_Regimm[14] = UnknownOpcode; + Jump_Regimm[14] = REGIMM_TNEI; Jump_Regimm[15] = UnknownOpcode; Jump_Regimm[16] = REGIMM_BLTZAL; Jump_Regimm[17] = REGIMM_BGEZAL; @@ -2050,7 +2050,59 @@ void R4300iOp::SPECIAL_TEQ() { if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW && HaveDebugger()) { - g_Notify->DisplayError("Should trap this ???"); + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::SPECIAL_TGE() +{ + if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::SPECIAL_TGEU() +{ + if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::SPECIAL_TLT() +{ + if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::SPECIAL_TLTU() +{ + if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::SPECIAL_TNE() +{ + if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); } } @@ -2220,6 +2272,67 @@ void R4300iOp::REGIMM_BGEZAL() } _GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8); } + +void R4300iOp::REGIMM_TEQI() +{ + if (_GPR[m_Opcode.rs].DW == m_Opcode.immediate && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::REGIMM_TGEI() +{ + if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::REGIMM_TGEIU() +{ + if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::REGIMM_TLTI() +{ + if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::REGIMM_TLTIU() +{ + if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + +void R4300iOp::REGIMM_TNEI() +{ + if (_GPR[m_Opcode.rs].DW != m_Opcode.immediate && HaveDebugger()) + { + g_Reg->DoTrapException(m_NextInstruction == JUMP); + m_NextInstruction = JUMP; + m_JumpToLocation = (*_PROGRAM_COUNTER); + } +} + /************************** COP0 functions **************************/ void R4300iOp::COP0_MF() { diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.h b/Source/Project64-core/N64System/Interpreter/InterpreterOps.h index 273d574bd..80fffa594 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.h +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.h @@ -110,7 +110,12 @@ public: static void SPECIAL_DADDU(); static void SPECIAL_DSUB(); static void SPECIAL_DSUBU(); + static void SPECIAL_TGE(); + static void SPECIAL_TGEU(); + static void SPECIAL_TLT(); + static void SPECIAL_TLTU(); static void SPECIAL_TEQ(); + static void SPECIAL_TNE(); static void SPECIAL_DSLL(); static void SPECIAL_DSRL(); static void SPECIAL_DSRA(); @@ -125,6 +130,12 @@ public: static void REGIMM_BGEZL(); static void REGIMM_BLTZAL(); static void REGIMM_BGEZAL(); + static void REGIMM_TEQI(); + static void REGIMM_TGEI(); + static void REGIMM_TGEIU(); + static void REGIMM_TLTI(); + static void REGIMM_TLTIU(); + static void REGIMM_TNEI(); /************************** COP0 functions **************************/ static void COP0_MF(); diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp index 53b2dc4ac..70cd0949b 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps32.cpp @@ -155,13 +155,13 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter() Jump_Special[45] = R4300iOp::SPECIAL_DADDU; Jump_Special[46] = R4300iOp::SPECIAL_DSUB; Jump_Special[47] = R4300iOp::SPECIAL_DSUBU; - Jump_Special[48] = R4300iOp::UnknownOpcode; - Jump_Special[49] = R4300iOp::UnknownOpcode; - Jump_Special[50] = R4300iOp::UnknownOpcode; - Jump_Special[51] = R4300iOp::UnknownOpcode; + Jump_Special[48] = R4300iOp::SPECIAL_TGE; + Jump_Special[49] = R4300iOp::SPECIAL_TGEU; + Jump_Special[50] = R4300iOp::SPECIAL_TLT; + Jump_Special[51] = R4300iOp::SPECIAL_TLTU; Jump_Special[52] = R4300iOp::SPECIAL_TEQ; Jump_Special[53] = R4300iOp::UnknownOpcode; - Jump_Special[54] = R4300iOp::UnknownOpcode; + Jump_Special[54] = R4300iOp::SPECIAL_TNE; Jump_Special[55] = R4300iOp::UnknownOpcode; Jump_Special[56] = R4300iOp::SPECIAL_DSLL; Jump_Special[57] = R4300iOp::UnknownOpcode; @@ -180,13 +180,13 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter() Jump_Regimm[5] = R4300iOp::UnknownOpcode; Jump_Regimm[6] = R4300iOp::UnknownOpcode; Jump_Regimm[7] = R4300iOp::UnknownOpcode; - Jump_Regimm[8] = R4300iOp::UnknownOpcode; - Jump_Regimm[9] = R4300iOp::UnknownOpcode; - Jump_Regimm[10] = R4300iOp::UnknownOpcode; - Jump_Regimm[11] = R4300iOp::UnknownOpcode; - Jump_Regimm[12] = R4300iOp::UnknownOpcode; + Jump_Regimm[8] = R4300iOp::REGIMM_TGEI; + Jump_Regimm[9] = R4300iOp::REGIMM_TGEIU; + Jump_Regimm[10] = R4300iOp::REGIMM_TLTI; + Jump_Regimm[11] = R4300iOp::REGIMM_TLTIU; + Jump_Regimm[12] = R4300iOp::REGIMM_TEQI; Jump_Regimm[13] = R4300iOp::UnknownOpcode; - Jump_Regimm[14] = R4300iOp::UnknownOpcode; + Jump_Regimm[14] = R4300iOp::REGIMM_TNEI; Jump_Regimm[15] = R4300iOp::UnknownOpcode; Jump_Regimm[16] = REGIMM_BLTZAL; Jump_Regimm[17] = REGIMM_BGEZAL; diff --git a/Source/Project64-core/N64System/Mips/RegisterClass.cpp b/Source/Project64-core/N64System/Mips/RegisterClass.cpp index ed175a744..28a994844 100644 --- a/Source/Project64-core/N64System/Mips/RegisterClass.cpp +++ b/Source/Project64-core/N64System/Mips/RegisterClass.cpp @@ -438,6 +438,22 @@ void CRegisters::DoBreakException(bool DelaySlot) m_PROGRAM_COUNTER = 0x80000180; } +void CRegisters::DoTrapException(bool DelaySlot) +{ + CAUSE_REGISTER = EXC_TRAP; + if (DelaySlot) + { + EPC_REGISTER = m_PROGRAM_COUNTER - 4; + CAUSE_REGISTER |= CAUSE_BD; + } + else + { + EPC_REGISTER = m_PROGRAM_COUNTER; + } + m_PROGRAM_COUNTER = 0x80000180; + +} + void CRegisters::DoCopUnusableException(bool DelaySlot, int Coprocessor) { if (HaveDebugger()) diff --git a/Source/Project64-core/N64System/Mips/RegisterClass.h b/Source/Project64-core/N64System/Mips/RegisterClass.h index ef6dd0345..ae266cd06 100644 --- a/Source/Project64-core/N64System/Mips/RegisterClass.h +++ b/Source/Project64-core/N64System/Mips/RegisterClass.h @@ -631,6 +631,7 @@ public: void CheckInterrupts (); void DoAddressError ( bool DelaySlot, uint32_t BadVaddr, bool FromRead ); void DoBreakException ( bool DelaySlot ); + void DoTrapException ( bool DelaySlot ); void DoCopUnusableException ( bool DelaySlot, int32_t Coprocessor ); bool DoIntrException ( bool DelaySlot ); void DoTLBReadMiss ( bool DelaySlot, uint32_t BadVaddr ); From 0e5c7714084f26c3712c384d7ea1f096feee6f14 Mon Sep 17 00:00:00 2001 From: KrimtonZ Date: Mon, 16 Dec 2019 14:59:40 -0600 Subject: [PATCH 13/14] remove HaveDebugger requirement, remove redundant code --- .../N64System/Interpreter/InterpreterOps.cpp | 48 +++++-------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index b920bd947..020e2c0de 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -2048,61 +2048,49 @@ void R4300iOp::SPECIAL_DSUBU() void R4300iOp::SPECIAL_TEQ() { - if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::SPECIAL_TGE() { - if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::SPECIAL_TGEU() { - if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].D) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::SPECIAL_TLT() { - if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::SPECIAL_TLTU() { - if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::SPECIAL_TNE() { - if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } @@ -2275,61 +2263,49 @@ void R4300iOp::REGIMM_BGEZAL() void R4300iOp::REGIMM_TEQI() { - if (_GPR[m_Opcode.rs].DW == m_Opcode.immediate && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW == m_Opcode.immediate) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::REGIMM_TGEI() { - if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::REGIMM_TGEIU() { - if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::REGIMM_TLTI() { - if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::REGIMM_TLTIU() { - if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } void R4300iOp::REGIMM_TNEI() { - if (_GPR[m_Opcode.rs].DW != m_Opcode.immediate && HaveDebugger()) + if (_GPR[m_Opcode.rs].DW != m_Opcode.immediate) { g_Reg->DoTrapException(m_NextInstruction == JUMP); - m_NextInstruction = JUMP; - m_JumpToLocation = (*_PROGRAM_COUNTER); } } From 0baf3ef263e16e8d5d4efc1e9f206f6fc2aa8321 Mon Sep 17 00:00:00 2001 From: KrimtonZ Date: Tue, 17 Dec 2019 09:08:15 -0600 Subject: [PATCH 14/14] Fix Trap Interpreter Functions, add recompiler trap functions --- .../N64System/Interpreter/InterpreterOps.cpp | 24 ++++-- .../Recompiler/Arm/ArmRecompilerOps.cpp | 71 +++++++++++++++++ .../Recompiler/Arm/ArmRecompilerOps.h | 3 + .../N64System/Recompiler/CodeBlock.cpp | 7 +- .../N64System/Recompiler/CodeSection.cpp | 13 ++++ .../N64System/Recompiler/LoopAnalysis.cpp | 6 ++ .../N64System/Recompiler/RecompilerOps.h | 18 +++++ .../Recompiler/x86/x86RecompilerOps.cpp | 78 +++++++++++++++++++ .../Recompiler/x86/x86RecompilerOps.h | 3 + 9 files changed, 214 insertions(+), 9 deletions(-) diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index 020e2c0de..d70241b6f 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -2064,7 +2064,7 @@ void R4300iOp::SPECIAL_TGE() void R4300iOp::SPECIAL_TGEU() { - if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].D) + if (_GPR[m_Opcode.rs].UDW >= _GPR[m_Opcode.rt].UDW) { g_Reg->DoTrapException(m_NextInstruction == JUMP); } @@ -2080,7 +2080,7 @@ void R4300iOp::SPECIAL_TLT() void R4300iOp::SPECIAL_TLTU() { - if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW) + if (_GPR[m_Opcode.rs].UDW < _GPR[m_Opcode.rt].UDW) { g_Reg->DoTrapException(m_NextInstruction == JUMP); } @@ -2263,7 +2263,7 @@ void R4300iOp::REGIMM_BGEZAL() void R4300iOp::REGIMM_TEQI() { - if (_GPR[m_Opcode.rs].DW == m_Opcode.immediate) + if (_GPR[m_Opcode.rs].DW == (int64_t)((int16_t)m_Opcode.immediate)) { g_Reg->DoTrapException(m_NextInstruction == JUMP); } @@ -2271,7 +2271,7 @@ void R4300iOp::REGIMM_TEQI() void R4300iOp::REGIMM_TGEI() { - if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate) + if (_GPR[m_Opcode.rs].DW >= (int64_t)((int16_t)m_Opcode.immediate)) { g_Reg->DoTrapException(m_NextInstruction == JUMP); } @@ -2279,7 +2279,11 @@ void R4300iOp::REGIMM_TGEI() void R4300iOp::REGIMM_TGEIU() { - if (_GPR[m_Opcode.rs].DW >= m_Opcode.immediate) + int32_t imm32 = (int16_t)m_Opcode.immediate; + int64_t imm64; + + imm64 = imm32; + if (_GPR[m_Opcode.rs].DW >= (uint64_t)imm64) { g_Reg->DoTrapException(m_NextInstruction == JUMP); } @@ -2287,7 +2291,7 @@ void R4300iOp::REGIMM_TGEIU() void R4300iOp::REGIMM_TLTI() { - if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate) + if (_GPR[m_Opcode.rs].DW < (int64_t)((int16_t)m_Opcode.immediate)) { g_Reg->DoTrapException(m_NextInstruction == JUMP); } @@ -2295,7 +2299,11 @@ void R4300iOp::REGIMM_TLTI() void R4300iOp::REGIMM_TLTIU() { - if (_GPR[m_Opcode.rs].DW < m_Opcode.immediate) + int32_t imm32 = (int16_t)m_Opcode.immediate; + int64_t imm64; + + imm64 = imm32; + if (_GPR[m_Opcode.rs].DW < (uint64_t)imm64) { g_Reg->DoTrapException(m_NextInstruction == JUMP); } @@ -2303,7 +2311,7 @@ void R4300iOp::REGIMM_TLTIU() void R4300iOp::REGIMM_TNEI() { - if (_GPR[m_Opcode.rs].DW != m_Opcode.immediate) + if (_GPR[m_Opcode.rs].DW != (int64_t)((int16_t)m_Opcode.immediate)) { g_Reg->DoTrapException(m_NextInstruction == JUMP); } diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp index 7feada20b..b9dc356f9 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.cpp @@ -105,6 +105,77 @@ CArmRecompilerOps::CArmRecompilerOps() : bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2); +void CArmRecompilerOps::Compile_TrapCompare(TRAP_COMPARE CompareType) +{ + void *FunctAddress = NULL; + const char *FunctName = NULL; + switch (CompareType) + { + case CompareTypeTEQ: + FunctAddress = (void*)R4300iOp::SPECIAL_TEQ; + FunctName = "R4300iOp::SPECIAL_TEQ"; + break; + case CompareTypeTNE: + FunctAddress = (void*)R4300iOp::SPECIAL_TNE; + FunctName = "R4300iOp::SPECIAL_TNE"; + break; + case CompareTypeTGE: + FunctAddress = (void*)R4300iOp::SPECIAL_TGE; + FunctName = "R4300iOp::SPECIAL_TGE"; + break; + case CompareTypeTGEU: + FunctAddress = (void*)R4300iOp::SPECIAL_TGEU; + FunctName = "R4300iOp::SPECIAL_TGEU"; + break; + case CompareTypeTLT: + FunctAddress = (void*)R4300iOp::SPECIAL_TLT; + FunctName = "R4300iOp::SPECIAL_TLT"; + break; + case CompareTypeTLTU: + FunctAddress = (void*)R4300iOp::SPECIAL_TLTU; + FunctName = "R4300iOp::SPECIAL_TLTU"; + break; + case CompareTypeTEQI: + FunctAddress = (void*)R4300iOp::REGIMM_TEQI; + FunctName = "R4300iOp::REGIMM_TEQI"; + break; + case CompareTypeTNEI: + FunctAddress = (void*)R4300iOp::REGIMM_TNEI; + FunctName = "R4300iOp::REGIMM_TNEI"; + break; + case CompareTypeTGEI: + FunctAddress = (void*)R4300iOp::REGIMM_TGEI; + FunctName = "R4300iOp::REGIMM_TGEI"; + break; + case CompareTypeTGEIU: + FunctAddress = (void*)R4300iOp::REGIMM_TGEIU; + FunctName = "R4300iOp::REGIMM_TGEIU"; + break; + case CompareTypeTLTI: + FunctAddress = (void*)R4300iOp::REGIMM_TLTI; + FunctName = "R4300iOp::REGIMM_TLTI"; + break; + case CompareTypeTLTIU: + FunctAddress = (void*)R4300iOp::REGIMM_TLTIU; + FunctName = "R4300iOp::REGIMM_TLTIU"; + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + if (FunctName != NULL && FunctAddress != NULL) + { + if (m_Opcode.rs != 0) { WriteBack_GPR(m_Opcode.rs, false); } + if (m_Opcode.rt != 0) { WriteBack_GPR(m_Opcode.rt, false); } + + CompileInterpterCall(FunctAddress, FunctName); + } + else + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + /************************** Branch functions ************************/ void CArmRecompilerOps::Compile_BranchCompare(BRANCH_COMPARE CompareType) { diff --git a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h index ab1aeb4c6..e0dd38ac4 100644 --- a/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/Arm/ArmRecompilerOps.h @@ -22,6 +22,9 @@ class CArmRecompilerOps : public: CArmRecompilerOps(); + /*************************** Trap functions *************************/ + void Compile_TrapCompare(TRAP_COMPARE CompareType); + /************************** Branch functions ************************/ void Compile_BranchCompare(BRANCH_COMPARE CompareType); void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link); diff --git a/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp b/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp index 7d0911f76..9babef77f 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeBlock.cpp @@ -475,7 +475,9 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t & case R4300i_SPECIAL_DSLL32: case R4300i_SPECIAL_DSRL32: case R4300i_SPECIAL_DSRA32: case R4300i_SPECIAL_MULT: case R4300i_SPECIAL_MULTU: case R4300i_SPECIAL_DIV: case R4300i_SPECIAL_DIVU: case R4300i_SPECIAL_DMULT: case R4300i_SPECIAL_DMULTU: - case R4300i_SPECIAL_DDIV: case R4300i_SPECIAL_DDIVU: + case R4300i_SPECIAL_DDIV: case R4300i_SPECIAL_DDIVU: case R4300i_SPECIAL_TEQ: + case R4300i_SPECIAL_TNE: case R4300i_SPECIAL_TGE: case R4300i_SPECIAL_TGEU: + case R4300i_SPECIAL_TLT: case R4300i_SPECIAL_TLTU: break; case R4300i_SPECIAL_JALR: case R4300i_SPECIAL_JR: @@ -556,6 +558,9 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t & LikelyBranch = true; IncludeDelaySlot = true; break; + case R4300i_REGIMM_TEQI: case R4300i_REGIMM_TNEI: case R4300i_REGIMM_TGEI: + case R4300i_REGIMM_TGEIU: case R4300i_REGIMM_TLTI: case R4300i_REGIMM_TLTIU: + break; default: if (Command.Hex == 0x0407000D) { diff --git a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp index b47186f34..082f6b0df 100644 --- a/Source/Project64-core/N64System/Recompiler/CodeSection.cpp +++ b/Source/Project64-core/N64System/Recompiler/CodeSection.cpp @@ -583,6 +583,13 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test) case R4300i_SPECIAL_DSLL32: m_RecompilerOps->SPECIAL_DSLL32(); break; case R4300i_SPECIAL_DSRL32: m_RecompilerOps->SPECIAL_DSRL32(); break; case R4300i_SPECIAL_DSRA32: m_RecompilerOps->SPECIAL_DSRA32(); break; + case R4300i_SPECIAL_TEQ: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTEQ); break; + case R4300i_SPECIAL_TNE: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTNE); break; + case R4300i_SPECIAL_TGE: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTGE); break; + case R4300i_SPECIAL_TGEU: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTGEU); break; + case R4300i_SPECIAL_TLT: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTLT); break; + case R4300i_SPECIAL_TLTU: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTLTU); break; + break; default: m_RecompilerOps->UnknownOpcode(); break; } @@ -596,6 +603,12 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test) case R4300i_REGIMM_BGEZL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeBGEZ, false); break; case R4300i_REGIMM_BLTZAL: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBLTZ, CRecompilerOps::BranchTypeRs, true); break; case R4300i_REGIMM_BGEZAL: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBGEZ, CRecompilerOps::BranchTypeRs, true); break; + case R4300i_REGIMM_TEQI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTEQI); break; + case R4300i_REGIMM_TNEI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTNEI); break; + case R4300i_REGIMM_TGEI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTGEI); break; + case R4300i_REGIMM_TGEIU: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTGEIU); break; + case R4300i_REGIMM_TLTI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTLTI); break; + case R4300i_REGIMM_TLTIU: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTLTIU); break; default: m_RecompilerOps->UnknownOpcode(); break; } diff --git a/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp b/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp index d25a4d5fa..1193c575b 100644 --- a/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp +++ b/Source/Project64-core/N64System/Recompiler/LoopAnalysis.cpp @@ -238,6 +238,9 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section) case R4300i_SPECIAL_DSLL32: SPECIAL_DSLL32(); break; case R4300i_SPECIAL_DSRL32: SPECIAL_DSRL32(); break; case R4300i_SPECIAL_DSRA32: SPECIAL_DSRA32(); break; + case R4300i_SPECIAL_TEQ: case R4300i_SPECIAL_TNE: case R4300i_SPECIAL_TGE: + case R4300i_SPECIAL_TGEU: case R4300i_SPECIAL_TLT: case R4300i_SPECIAL_TLTU: + break; default: g_Notify->BreakPoint(__FILE__, __LINE__); #ifdef legacycode @@ -252,6 +255,9 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section) case R4300i_REGIMM: switch (m_Command.rt) { + case R4300i_REGIMM_TEQI: case R4300i_REGIMM_TNEI: case R4300i_REGIMM_TGEI: + case R4300i_REGIMM_TGEIU: case R4300i_REGIMM_TLTI: case R4300i_REGIMM_TLTIU: + break; case R4300i_REGIMM_BLTZ: case R4300i_REGIMM_BGEZ: m_NextInstruction = DELAY_SLOT; diff --git a/Source/Project64-core/N64System/Recompiler/RecompilerOps.h b/Source/Project64-core/N64System/Recompiler/RecompilerOps.h index 392a74858..d126f80f0 100644 --- a/Source/Project64-core/N64System/Recompiler/RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/RecompilerOps.h @@ -35,6 +35,24 @@ public: CompareTypeCOP1BCF, CompareTypeCOP1BCT, }; + enum TRAP_COMPARE + { + CompareTypeTEQ, + CompareTypeTNE, + CompareTypeTGE, + CompareTypeTGEU, + CompareTypeTLT, + CompareTypeTLTU, + CompareTypeTEQI, + CompareTypeTNEI, + CompareTypeTGEI, + CompareTypeTGEIU, + CompareTypeTLTI, + CompareTypeTLTIU, + }; + + /*************************** Trap functions *************************/ + virtual void Compile_TrapCompare(TRAP_COMPARE CompareType) = 0; /************************** Branch functions ************************/ virtual void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link) = 0; diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index d5bedb821..9a0ee3605 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -361,6 +361,84 @@ void CX86RecompilerOps::CompileWriteTLBMiss(x86Reg AddressReg, x86Reg LookUpReg) bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2); +/*************************** Trap functions *************************/ +void CX86RecompilerOps::Compile_TrapCompare(TRAP_COMPARE CompareType) +{ + void *FunctAddress = NULL; + const char *FunctName = NULL; + switch (CompareType) + { + case CompareTypeTEQ: + FunctAddress = (void*)R4300iOp::SPECIAL_TEQ; + FunctName = "R4300iOp::SPECIAL_TEQ"; + break; + case CompareTypeTNE: + FunctAddress = (void*)R4300iOp::SPECIAL_TNE; + FunctName = "R4300iOp::SPECIAL_TNE"; + break; + case CompareTypeTGE: + FunctAddress = (void*)R4300iOp::SPECIAL_TGE; + FunctName = "R4300iOp::SPECIAL_TGE"; + break; + case CompareTypeTGEU: + FunctAddress = (void*)R4300iOp::SPECIAL_TGEU; + FunctName = "R4300iOp::SPECIAL_TGEU"; + break; + case CompareTypeTLT: + FunctAddress = (void*)R4300iOp::SPECIAL_TLT; + FunctName = "R4300iOp::SPECIAL_TLT"; + break; + case CompareTypeTLTU: + FunctAddress = (void*)R4300iOp::SPECIAL_TLTU; + FunctName = "R4300iOp::SPECIAL_TLTU"; + break; + case CompareTypeTEQI: + FunctAddress = (void*)R4300iOp::REGIMM_TEQI; + FunctName = "R4300iOp::REGIMM_TEQI"; + break; + case CompareTypeTNEI: + FunctAddress = (void*)R4300iOp::REGIMM_TNEI; + FunctName = "R4300iOp::REGIMM_TNEI"; + break; + case CompareTypeTGEI: + FunctAddress = (void*)R4300iOp::REGIMM_TGEI; + FunctName = "R4300iOp::REGIMM_TGEI"; + break; + case CompareTypeTGEIU: + FunctAddress = (void*)R4300iOp::REGIMM_TGEIU; + FunctName = "R4300iOp::REGIMM_TGEIU"; + break; + case CompareTypeTLTI: + FunctAddress = (void*)R4300iOp::REGIMM_TLTI; + FunctName = "R4300iOp::REGIMM_TLTI"; + break; + case CompareTypeTLTIU: + FunctAddress = (void*)R4300iOp::REGIMM_TLTIU; + FunctName = "R4300iOp::REGIMM_TLTIU"; + break; + default: + g_Notify->BreakPoint(__FILE__, __LINE__); + } + + if (FunctName != NULL && FunctAddress != NULL) + { + if (IsMapped(m_Opcode.rs)) { + UnMap_GPR(m_Opcode.rs, true); + } + if (IsMapped(m_Opcode.rt)) { + UnMap_GPR(m_Opcode.rt, true); + } + m_RegWorkingSet.BeforeCallDirect(); + MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); + Call_Direct(FunctAddress, FunctName); + m_RegWorkingSet.AfterCallDirect(); + } + else + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } +} + /************************** Branch functions ************************/ void CX86RecompilerOps::Compile_BranchCompare(BRANCH_COMPARE CompareType) { diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h index 8111de5f9..49f1711b9 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.h @@ -33,6 +33,9 @@ class CX86RecompilerOps : protected CRecompilerSettings { public: + /*************************** Trap functions *************************/ + void Compile_TrapCompare(TRAP_COMPARE CompareType); + /************************** Branch functions ************************/ void Compile_BranchCompare(BRANCH_COMPARE CompareType); void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link);