Hey hey.
Ce petit outil permet de calculer et fixer les bad checksum de vos roms sfc (eviter donc les "checksum: failed" de zsnes),
mais aussi lire, et modifier les informations qui se trouvent dans le header de la rom comme le nom du jeu (affiché par les emulateurs lorsque vous lancez un jeu),
la taille de la rom, l'editeur, le type de sauvegarde, le type de rom lui meme, etc etc).
Il permet enfin d'ajouter ou de supprimer le 512Header au debut des fichiers rom snes et de lister dans un fichier texte les infos de toutes les roms d'un dossier.
Je voulais mettre ce programme depuis longtemps puis comme d'hab j'ai arreté le projet (il etait devenu
un frontend pour zsnes et snes9x).
Mais etant donné que je trouve cette partie de code plus qu'interessante, je la met a disposition.
L'algo de calcul du checksum est un portage d'un code en C trouvé sur le net il y a longtemps (quand je ne comprenais pas
encore ce que c'etait... ^^)... mais je ne trouve plus la source :( Desolé pour l'auteur.
Ensuite la liste des editeurs vient de l'excellente doc "SNES KART" qui m'a beaucoup aidé pour pas mal de corrections.
Voila voila, j'espere que certains y verront une utilité (le programme vise, il est vrai, une minorité de gens... les FANS de la sfc qui
en plus, ont le framework .net v1.1 ... lol =D )
voyez le zip pour un exemple d'utilisation de la classe de calcul.
En esperant voir quelques commentaires.
EDIT :
Vous pouvez trouver le fichier executable compilé sur
http://batto.online.fr/Roms/HbSnesToolsv0.9.zip
Source / Exemple :
Imports System.IO
Public Class checksumcalc
Public formz1 As Form1
Public resultstrz As String
Const LO_ROM = 0
Const HIGH_ROM = 1
Const NUMB_VALUES = 39
Const LOROM_BANKSIZE = 32768
Const TRUEz = 1
Const FALSEz = 0
Const ARG_NUMB = 3
Const ROM_NAME_LOROM_ADDR = 33216
Const ROM_NAME_HIROM_ADDR = 65984
Const REVERSE_CHKSM_ADDR_LOROM = 33244
Const CHKSM_ADDR_LOROM = 33246
Const REVERSE_CHKSM_ADDR_HIROM = 66012
Const CHKSM_ADDR_HIROM = 66014
Const CPL_VALUE = &HFFFF&
Const SIZE_HEADER = 512
Const SMALL_SIZE = 1049088
Const MAJOR_SIZE = 2097664
Const MAX_SIZE = 4194816
Public rom As String
Public TailleFichier, TypeRom, Correction, Is512Header As Long
Public RomChecksum As Integer
Public ChecksumCpl As Integer
Public RealChecksum As Integer
Public tmpromchecksum As String
Public tmpchecksumcpl As String
Public romname As String
Public romtype As String
Public romsram As Integer
Public romvideo As Integer
Public romlicense As Integer
Public romversion As Integer
Public rommakeup As Integer
Public romsizeinrom As Integer
Dim titre As String = "Batto checksum algorithm"
Public Function DefineTypeRom() As Integer
'defini le type de rom
Dim tmpb As Boolean = False
Dim n As Integer
For n = 0 To 38
If StandardSizes(n).size = TailleFichier Then
tmpb = True
Exit For
End If
Next
tmpromchecksum = Convert.ToString(CLng(F_array(REVERSE_CHKSM_ADDR_HIROM - Correction + 1)), 16).PadLeft(2, "0") & Convert.ToString(CLng(F_array(REVERSE_CHKSM_ADDR_HIROM - Correction)), 16).PadLeft(2, "0")
If tmpromchecksum = "0000" Then
ChecksumCpl = 0
Else
ChecksumCpl = Convert.ToInt64(tmpromchecksum, 16)
End If
tmpchecksumcpl += Convert.ToString(CLng(F_array(REVERSE_CHKSM_ADDR_HIROM - Correction + 3)), 16).PadLeft(2, "0") & Convert.ToString(CLng(F_array(REVERSE_CHKSM_ADDR_HIROM - Correction + 2)), 16).PadLeft(2, "0")
RomChecksum = Convert.ToInt64(tmpchecksumcpl, 16)
If (RomChecksum + ChecksumCpl) = CPL_VALUE Then Return HIGH_ROM Else Return LO_ROM
If tmpb = True Then
Return LO_ROM
Else
End If
End Function
Sub GetRomInfos()
'on lit les infos contenues dans la rom et on place les offsets dans le tableau offsetz
Dim seekint As Integer
Dim n As Integer
Select Case TypeRom
Case LO_ROM
seekint = ROM_NAME_LOROM_ADDR - Correction
offsetz(0) = seekint
For n = 0 To 20
romname += Chr(F_array(seekint + n))
Next
offsetz(1) = seekint + 22
romtype = F_array(seekint + 22)
offsetz(2) = seekint + 24
romsram = F_array(seekint + 24)
offsetz(3) = seekint + 25
romvideo = F_array(seekint + 25)
offsetz(4) = seekint + 26
romlicense = F_array(seekint + 26)
offsetz(5) = seekint + 27
romversion = F_array(seekint + 27)
rommakeup = F_array(seekint + 21)
offsetz(6) = seekint + 21
romsizeinrom = F_array(seekint + 23)
offsetz(7) = seekint + 23
seekint = REVERSE_CHKSM_ADDR_LOROM - Correction
tmpchecksumcpl = Convert.ToString(CLng(F_array(seekint + 1)), 16).PadLeft(2, "0") & Convert.ToString(CLng(F_array(seekint)), 16).PadLeft(2, "0")
ChecksumCpl = Convert.ToInt64(tmpchecksumcpl, 16)
tmpromchecksum = Convert.ToString(CLng(F_array(seekint + 3)), 16).PadLeft(2, "0") & Convert.ToString(CLng(F_array(seekint + 2)), 16).PadLeft(2, "0")
RomChecksum = Convert.ToInt64(tmpromchecksum, 16)
Case HIGH_ROM
seekint = ROM_NAME_HIROM_ADDR - Correction
offsetz(0) = seekint
For n = 0 To 20
romname += Chr(F_array(seekint + n))
Next
rommakeup = F_array(seekint + 21)
romtype = F_array(seekint + 22)
romsizeinrom = F_array(seekint + 23)
romsram = F_array(seekint + 24)
romvideo = F_array(seekint + 25)
romlicense = F_array(seekint + 26)
romversion = F_array(seekint + 27)
offsetz(1) = seekint + 22
offsetz(2) = seekint + 24
offsetz(3) = seekint + 25
offsetz(4) = seekint + 26
offsetz(5) = seekint + 27
offsetz(6) = seekint + 21
offsetz(7) = seekint + 23
seekint = REVERSE_CHKSM_ADDR_HIROM - Correction
tmpchecksumcpl = ""
tmpromchecksum = ""
tmpchecksumcpl = Convert.ToString(CLng(F_array(seekint + 1)), 16).PadLeft(2, "0") & Convert.ToString(CLng(F_array(seekint)), 16).PadLeft(2, "0")
ChecksumCpl = Convert.ToInt64(tmpchecksumcpl, 16) 's
tmpromchecksum = Convert.ToString(CLng(F_array(seekint + 3)), 16).PadLeft(2, "0") & Convert.ToString(CLng(F_array(seekint + 2)), 16).PadLeft(2, "0")
RomChecksum = Convert.ToInt64(tmpromchecksum, 16)
End Select
End Sub
Public Function analyse_rom() As Boolean
'verifie que la rom est une roms snes par sa taille, avec ou sans headers
Dim lenfile As Integer = FileLen(rom)
hbread = New BinaryReader(File.OpenRead(rom))
'-1 back
ReDim F_array(lenfile) ' - 1)
hbread.Read(F_array, 0, lenfile)
hbread.BaseStream.Flush()
hbread.Close()
Dim seekint As Integer
Dim n As Integer
Dim i As Integer
TailleFichier = F_array.GetUpperBound(0) '+1
For i = 0 To NUMB_VALUES - 1
If StandardSizes(i).size = TailleFichier Then
InfosRom = StandardSizes(i)
Correction = 0
Is512Header = True
Exit For
ElseIf StandardSizes(i).size - SIZE_HEADER = TailleFichier Then
InfosRom = StandardSizes(i)
Correction = SIZE_HEADER
Is512Header = False
Exit For
End If
Next
If i = NUMB_VALUES Then Return False
TypeRom = DefineTypeRom()
GetRomInfos()
Return True
End Function
Sub CalculChecksum(ByVal TypeAlgo As Integer)
'calcul le checksum selon le type d'algo defini en argument
Dim bytez As Long
Dim rompart1 As Integer = 0
Dim seekint As Integer
Dim n As Integer
Dim tmprealchecksum As String
RealChecksum = 0
Select Case TypeAlgo
Case 1
seekint = SIZE_HEADER - Correction
For n = seekint To F_array.GetUpperBound(0)
bytez = F_array(n)
RealChecksum += Int(bytez)
Next
Case 2
seekint = SIZE_HEADER - Correction
For n = seekint To F_array.GetUpperBound(0)
bytez = F_array(n)
RealChecksum += bytez
Next
seekint = SMALL_SIZE - Correction
For n = seekint To F_array.GetUpperBound(0)
rompart1 += F_array(n)
Next
RealChecksum -= rompart1
RealChecksum += rompart1 * 4
Case 3
seekint = SIZE_HEADER - Correction
For n = seekint To F_array.GetUpperBound(0)
bytez = F_array(n)
RealChecksum += bytez
Next
seekint = SMALL_SIZE - Correction
For n = seekint To F_array.GetUpperBound(0)
rompart1 += F_array(n)
Next
RealChecksum -= rompart1
RealChecksum += rompart1 * 2
Case 4
seekint = SIZE_HEADER - Correction
For n = seekint To F_array.GetUpperBound(0)
bytez = F_array(n)
RealChecksum += bytez
Next
seekint = MAJOR_SIZE - Correction
For n = seekint To F_array.GetUpperBound(0)
rompart1 += F_array(n)
Next
RealChecksum -= rompart1
RealChecksum += rompart1 * 4
Case 5
seekint = SIZE_HEADER - Correction
For n = seekint To F_array.GetUpperBound(0)
bytez = F_array(n)
RealChecksum += bytez
Next
seekint = MAJOR_SIZE - Correction
For n = seekint To F_array.GetUpperBound(0)
rompart1 += F_array(n)
Next
RealChecksum -= rompart1
RealChecksum += rompart1 * 2
Case 6
seekint = SIZE_HEADER - Correction
For n = seekint To F_array.GetUpperBound(0)
bytez = F_array(n)
RealChecksum += bytez
Next
seekint = MAX_SIZE - Correction
For n = seekint To F_array.GetUpperBound(0)
rompart1 += F_array(n)
Next
RealChecksum -= rompart1
RealChecksum += rompart1 * 2
End Select
End Sub
End Class
Conclusion :
Il y a plein d'ammeliorations à faire, (à commencer par un design, un vrai ^^) mais pour l'instant
je n'ai pas trop le temps de le faire evoluer.
Je mettrais la version frontend si ça peut interesser quelqu'un, mais je dois revoir quelques problemes de configs avec zsnes.
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.