@@ -6,116 +6,140 @@
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<width>533</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Sega Saturn RAM Backup parser</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>30</x>
<y>240</y>
<width>341</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QWidget" name="formLayoutWidget">
<property name="geometry">
<rect>
<x>89</x>
<y>29</y>
<width>251</width>
<height>171</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_2"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Language code</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Comment</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_3"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Date/time</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QDateTimeEdit" name="dateTimeEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Counter</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="spinBox_2">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Size (bytes)</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="label_7">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
</layout>
</widget>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_2"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Language code</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Comment</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_3"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Date/time</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QDateTimeEdit" name="dateTimeEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Counter</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="spinBox_2">
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Size (bytes)</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="label_7">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="OptionalBox">
<property name="title">
<string>Optional fields</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Game ID</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Addtional comment</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QTextBrowser" name="textBrowser"/>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Get game ID</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
@@ -0,0 +1,266 @@
/* XPM */
static char * C:\Saturn\__repo\ss_save_parser\game_to_cart_xpm[] = {
"71 23 240 2",
" c None",
". c #1A2127",
"+ c #1B2228",
"@ c #1A2327",
"# c #383E42",
"$ c #252D32",
"% c #1A1C1D",
"& c #4A4A4A",
"* c #A5A5A5",
"= c #192C3D",
"- c #007EED",
"; c #008BFF",
"> c #0280F3",
", c #2592F1",
"' c #038BFF",
") c #008AFF",
"! c #066FCF",
"~ c #162C3F",
"{ c #142C41",
"] c #0676DB",
"^ c #14314A",
"/ c #F2F2F2",
"( c #262626",
"_ c #939393",
": c #1E3344",
"< c #056ECC",
"[ c #0086FF",
"} c #0F497F",
"| c #C5AC81",
"1 c #5BA3DA",
"2 c #0084FD",
"3 c #0085FE",
"4 c #0089FF",
"5 c #132F48",
"6 c #B6B6B6",
"7 c #CECECE",
"8 c #9E9E9E",
"9 c #666666",
"0 c #2A4257",
"a c #0569C1",
"b c #0F4A81",
"c c #C0AB85",
"d c #A0BEC9",
"e c #0084FC",
"f c #0084FE",
"g c #0B5596",
"h c #263640",
"i c #0000FF",
"j c #DADADA",
"k c #545454",
"l c #9C9C9C",
"m c #1D354C",
"n c #0767BE",
"o c #056AC7",
"p c #5997C9",
"q c #0987FA",
"r c #0086FE",
"s c #0080FC",
"t c #8EC8F9",
"u c #8FC8F9",
"v c #49A6F8",
"w c #0083FE",
"x c #122535",
"y c #D4E3FF",
"z c #C2C2C2",
"A c #213746",
"B c #076FCD",
"C c #B0D8F8",
"D c #FFFFFF",
"E c #E0F2FE",
"F c #44A5FB",
"G c #0081FE",
"H c #008DFF",
"I c #112433",
"J c #223646",
"K c #0382F6",
"L c #018BFF",
"M c #0187FF",
"N c #FDFEFE",
"O c #A4A3A3",
"P c #156AB7",
"Q c #AAD8FE",
"R c #3E5263",
"S c #E6E6E6",
"T c #373938",
"U c #282A29",
"V c #292A2A",
"W c #252626",
"X c #191A1A",
"Y c #0B5799",
"Z c #F9FBFB",
"` c #929292",
" . c #085EAC",
".. c #C5E6FF",
"+. c #464847",
"@. c #0D4C83",
"#. c #0088FF",
"$. c #2091F3",
"%. c #1F91F4",
"&. c #0B85F2",
"*. c #FEFFFF",
"=. c #A1A1A1",
"-. c #2970AF",
";. c #203D52",
">. c #1A1C19",
",. c #1E201F",
"'. c #0D4478",
"). c #0085FF",
"!. c #0286FD",
"~. c #FFE5A7",
"{. c #FFE1A4",
"]. c #FFE0A3",
"^. c #FDF8EC",
"/. c #FFFCF1",
"(. c #FFEBC0",
"_. c #FFEBB0",
":. c #464337",
"<. c #112737",
"[. c #0A68BC",
"}. c #0A64B4",
"|. c #0C64B6",
"1. c #B5A47F",
"2. c #F9DEA9",
"3. c #F9DDA6",
"4. c #C6B18A",
"5. c #4C4940",
"6. c #363737",
"7. c #393B39",
"8. c #3B3839",
"9. c #3B3938",
"0. c #3B3A37",
"a. c #3A3837",
"b. c #1F201F",
"c. c #7F735B",
"d. c #998A6C",
"e. c #998869",
"f. c #95866A",
"g. c #95866B",
"h. c #96886B",
"i. c #32312A",
"j. c #47494B",
"k. c #AA9B7D",
"l. c #69604D",
"m. c #131614",
"n. c #0A5DA6",
"o. c #A29374",
"p. c #A19272",
"q. c #605849",
"r. c #141616",
"s. c #121413",
"t. c #313332",
"u. c #4C4E4D",
"v. c #AEA081",
"w. c #4F493B",
"x. c #D0D0D0",
"y. c #CDCDCD",
"z. c #03213C",
"A. c #FEE4AE",
"B. c #F8DDA8",
"C. c #8E8066",
"D. c #909091",
"E. c #D2D2D2",
"F. c #3D3E3D",
"G. c #3D3E3F",
"H. c #1D1D1B",
"I. c #F6F7F7",
"J. c #33312B",
"K. c #FDE1AD",
"L. c #8E8167",
"M. c #B1B1B2",
"N. c #4C4D4D",
"O. c #363636",
"P. c #ECECEC",
"Q. c #F3F3F3",
"R. c #181A1A",
"S. c #464336",
"T. c #877B63",
"U. c #A6A7A7",
"V. c #3B3C3C",
"W. c #2B2C2C",
"X. c #E0E0E0",
"Y. c #DDDDDD",
"Z. c #0D2133",
"`. c #191D1D",
" + c #152431",
".+ c #191C1B",
"++ c #181919",
"@+ c #1C1E1D",
"#+ c #AAAAAA",
"$+ c #0B0D0C",
"%+ c #131413",
"&+ c #018AFF",
"*+ c #172329",
"=+ c #0B5A9F",
"-+ c #3C3B39",
";+ c #171B19",
">+ c #21181A",
",+ c #661018",
"'+ c #6F3D42",
")+ c #5B5B5B",
"!+ c #131716",
"~+ c #8C0F19",
"{+ c #7E468E",
"]+ c #1E1617",
"^+ c #AE0A1B",
"/+ c #CB081D",
"(+ c #8B686B",
"_+ c #646A69",
":+ c #4A5251",
"<+ c #2E2E2E",
"[+ c #BB091D",
"}+ c #FF001C",
"|+ c #FC0010",
"1+ c #B5B5B5",
"2+ c #9D0A1B",
"3+ c #59141B",
"4+ c #C13D48",
"5+ c #C91B2C",
"6+ c #BC081C",
"7+ c #3B2627",
"8+ c #383838",
"9+ c #2E2E2F",
"0+ c #FF031E",
"a+ c #FF021D",
"b+ c #FCEFF0",
"c+ c #F81C2F",
"d+ c #FB031D",
"e+ c #E9041E",
"f+ c #6F111A",
"g+ c #CA0A1E",
"h+ c #FF011C",
"i+ c #F8031C",
"j+ c #2F2929",
"k+ c #2F3030",
"l+ c #0F1B1A",
"m+ c #050707",
"n+ c #171C1B",
"o+ c #121C1A",
"p+ c #0E1B19",
"q+ c #212423",
" . + + @ + + + + + + # $ % & & & & & & & & & & & & & & & & & & & & & & & & & & & * ",
" = - ; ; > , ' ) ) ) ) ! ~ { ] ^ & / / / / / / / / / / / / / / / / / / / / / / / / / / / ( _ ",
" : < [ } | 1 2 3 3 3 [ 4 4 4 5 & 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 ( 9 * ",
" 0 a b c d e 3 3 f f f 3 [ g h i & / / 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 j 7 / / ( k l ",
" m n o p q r 3 s t u v w 3 ) x i i & 6 6 / 7 y y y y y y y y y y y y y y y y y y y z / 6 6 ( k l ",
" A B 3 3 3 3 3 3 C D D E F G H I i i i & / / 7 7 y y y y y y y y y y y y y y y y y y y z j / / ( k l ",
" J K L L M 3 3 3 3 N D D O P Q R i i i i & 6 6 / 7 / S S S S S S S S S S S S S S S S S / z / 6 6 ( k l ",
"T U V W X Y 3 3 3 r Z D D ` ...+. i i i i i & / / 7 7 / / / / / / / / / / / / / / / / / / / z j / / ( k l ",
" @.#.3 3 $.%.&.*.D =.-.;.>.,. i i i i i i & 6 6 / 7 / S S S S S S S S S S S S S S S S S / z / 6 6 ( k l ",
" '.#.r ).!.~.{.].^.^./.(._.:. i i i i i i i i i i i i i i i & j z 7 7 / / / / / / / / / / / / / / / / / / / z 7 7 8 ( k l ",
" <.[.}.}.}.|.1.2.2.3.3.3.2.4.5. i i i i i i i i i i i i i i i i & j z 7 7 / S S S S S S S S S S S S S S S S S / z 7 7 8 ( k l ",
" 6.7.8.9.0.a.b.c.d.e.f.g.h.d.i. i i i i i i i i i i i i i i i i & j z 7 7 / / / / / / / / / / / / / / / / / / / z 7 7 8 ( k l ",
" j.k.l.m.n.o.p.q.r.s.t. i i i i i i i i i i i i i i i & j z 7 7 / S S S S S S S S S S S S S S S S S / z 7 7 8 ( k l ",
" u.v.w.x.y.z.A.B.C.D.E.F. i i i i i i & j z 7 7 / / / / / / / / / / / / / / / / / / / z 7 7 8 ( k l ",
" G.H.I.D D D J.K.L.M.D N. i i i i i & j z 7 z z z z z z z z z z z z z z z z z z z z z 7 7 8 ( k l ",
" O.P.D D Q.R.S.T.U.V. i i i i & j z 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 ( k l ",
" W.X.Y.Z.`. +.+++@+ i i i & j z 7 7 7 7 7 7 7 7 7 #+/ #+/ #+/ 7 7 7 7 7 7 7 7 7 8 ( k l ",
" $+%+&+*+=+-+ i i & j z 7 7 7 7 7 7 7 7 #+/ #+/ #+/ 7 7 7 7 7 7 7 7 7 7 8 ( k l ",
" s.;+#.>+,+'+ i & j z 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 ( k l ",
" )+!+~+{+]+^+/+(+_+:+ & j z z z z z z z z z z z z z z z z z z z z z z z z z 8 ( k l ",
" <+[+}+|+1+2+3+4+5+6+7+ * ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 8+9 * ",
" 9+0+a+b+c+d+e+f+g+h+i+j+ _ 9 k k k k k k k k k k k k k k k k k k k k k k k k k 9 _ ",
" k+l+l+m+l+l+l+n+o+l+p+q+ * l l l l l l l l l l l l l l l l l l l l l l l l l * "};
@@ -28,9 +28,9 @@ void MyLittleScene::mousePressEvent(QGraphicsSceneMouseEvent * event)
{
if (pMap->SavesList->at(i).iStartCluster == iClusterNumber)
iFoundRow = i;
for (int j=0;j<pMap->SavesList->at(i).iSATSize-1;j++)
for (int j=0;j<pMap->SavesList->at(i).SAT.size()-1;j++)
{
if (pMap->SavesList->at(i).SAT[j]==iClusterNumber)
if (pMap->SavesList->at(i).SAT.at(j)==iClusterNumber)
iFoundRow = i;
}
}
@@ -104,10 +104,10 @@ void ImageMapWindow::UpdateData()
scene->addRect(QRect(iX*CELL_SIZE+1,iY*CELL_SIZE+1,CELL_SIZE-2,CELL_SIZE-2),QPen(color),QBrush(color,Qt::SolidPattern));
scene->addRect(QRect(iX*CELL_SIZE+3,iY*CELL_SIZE+3,CELL_SIZE-6,CELL_SIZE-6),QPen(Qt::white),QBrush(Qt::white,Qt::SolidPattern));
//other clusters
for (int j=0;j<SavesList->at(i).iSATSize-1;j++)
for (int j=0;j<SavesList->at(i).SAT.size()-1;j++)
{
iX = SavesList->at(i).SAT[j]%iMapWidth;
iY = SavesList->at(i).SAT[j]/iMapWidth;
iX = SavesList->at(i).SAT.at(j)%iMapWidth;
iY = SavesList->at(i).SAT.at(j)/iMapWidth;
scene->addRect(QRect(iX*CELL_SIZE+1,iY*CELL_SIZE+1,CELL_SIZE-2,CELL_SIZE-2),QPen(color),QBrush(color,Qt::SolidPattern));
}
//list
@@ -148,10 +148,10 @@ void ImageMapWindow::UpdateData(int iIndex)
scene->addRect(QRect(iX*CELL_SIZE+1,iY*CELL_SIZE+1,CELL_SIZE-2,CELL_SIZE-2),QPen(color),QBrush(color,Qt::SolidPattern));
scene->addRect(QRect(iX*CELL_SIZE+3,iY*CELL_SIZE+3,CELL_SIZE-6,CELL_SIZE-6),QPen(Qt::white),QBrush(Qt::white,Qt::SolidPattern));
//other clusters
for (int j=0;j<SavesList->at(iIndex).iSATSize-1;j++)
for (int j=0;j<SavesList->at(iIndex).SAT.size()-1;j++)
{
iX = SavesList->at(iIndex).SAT[j]%iMapWidth;
iY = SavesList->at(iIndex).SAT[j]/iMapWidth;
iX = SavesList->at(iIndex).SAT.at(j)%iMapWidth;
iY = SavesList->at(iIndex).SAT.at(j)/iMapWidth;
scene->addRect(QRect(iX*CELL_SIZE+1,iY*CELL_SIZE+1,CELL_SIZE-2,CELL_SIZE-2),QPen(color),QBrush(color,Qt::SolidPattern));
}
//list
@@ -183,10 +183,10 @@ void ImageMapWindow::blink()
scene->addLine(QLine(iX*CELL_SIZE+1,iY*CELL_SIZE+CELL_SIZE-1,iX*CELL_SIZE+CELL_SIZE-1,iY*CELL_SIZE+CELL_SIZE-1),QPen(Qt::white));
scene->addLine(QLine(iX*CELL_SIZE+1,iY*CELL_SIZE+1,iX*CELL_SIZE+1,iY*CELL_SIZE+CELL_SIZE-1),QPen(Qt::white));
scene->addLine(QLine(iX*CELL_SIZE+CELL_SIZE-1,iY*CELL_SIZE+1,iX*CELL_SIZE+CELL_SIZE-1,iY*CELL_SIZE+CELL_SIZE-1),QPen(Qt::white));
for (int j=0;j<SavesList->at(iCurrentRow).iSATSize-1;j++)
for (int j=0;j<SavesList->at(iCurrentRow).SAT.size()-1;j++)
{
iX = SavesList->at(iCurrentRow).SAT[j]%iMapWidth;
iY = SavesList->at(iCurrentRow).SAT[j]/iMapWidth;
iX = SavesList->at(iCurrentRow).SAT.at(j)%iMapWidth;
iY = SavesList->at(iCurrentRow).SAT.at(j)/iMapWidth;
scene->addLine(QLine(iX*CELL_SIZE+1,iY*CELL_SIZE+1,iX*CELL_SIZE+CELL_SIZE-1,iY*CELL_SIZE+1),QPen(Qt::white));
scene->addLine(QLine(iX*CELL_SIZE+1,iY*CELL_SIZE+CELL_SIZE-1,iX*CELL_SIZE+CELL_SIZE-1,iY*CELL_SIZE+CELL_SIZE-1),QPen(Qt::white));
scene->addLine(QLine(iX*CELL_SIZE+1,iY*CELL_SIZE+1,iX*CELL_SIZE+1,iY*CELL_SIZE+CELL_SIZE-1),QPen(Qt::white));
@@ -205,10 +205,10 @@ void ImageMapWindow::blink()
scene->addLine(QLine(iX*CELL_SIZE+1,iY*CELL_SIZE+CELL_SIZE-1,iX*CELL_SIZE+CELL_SIZE-1,iY*CELL_SIZE+CELL_SIZE-1),QPen(Qt::black));
scene->addLine(QLine(iX*CELL_SIZE+1,iY*CELL_SIZE+1,iX*CELL_SIZE+1,iY*CELL_SIZE+CELL_SIZE-1),QPen(Qt::black));
scene->addLine(QLine(iX*CELL_SIZE+CELL_SIZE-1,iY*CELL_SIZE+1,iX*CELL_SIZE+CELL_SIZE-1,iY*CELL_SIZE+CELL_SIZE-1),QPen(Qt::black));
for (int j=0;j<SavesList->at(iCurrentRow).iSATSize-1;j++)
for (int j=0;j<SavesList->at(iCurrentRow).SAT.size()-1;j++)
{
iX = SavesList->at(iCurrentRow).SAT[j]%iMapWidth;
iY = SavesList->at(iCurrentRow).SAT[j]/iMapWidth;
iX = SavesList->at(iCurrentRow).SAT.at(j)%iMapWidth;
iY = SavesList->at(iCurrentRow).SAT.at(j)/iMapWidth;
scene->addLine(QLine(iX*CELL_SIZE+1,iY*CELL_SIZE+1,iX*CELL_SIZE+CELL_SIZE-1,iY*CELL_SIZE+1),QPen(Qt::black));
scene->addLine(QLine(iX*CELL_SIZE+1,iY*CELL_SIZE+CELL_SIZE-1,iX*CELL_SIZE+CELL_SIZE-1,iY*CELL_SIZE+CELL_SIZE-1),QPen(Qt::black));
scene->addLine(QLine(iX*CELL_SIZE+1,iY*CELL_SIZE+1,iX*CELL_SIZE+1,iY*CELL_SIZE+CELL_SIZE-1),QPen(Qt::black));
@@ -0,0 +1,330 @@
#include <QByteArray>
#include <QMessageBox>
#include <QFile>
#include <mainwindow.h>
#include <import.h>
#include <math.h>

bool ProbeMemCardPlus(QFile * file_in)
{
//MemCardPlus contains "MEMORY CARTRIDGE" id at 0x50
file_in->seek(0);
QByteArray cbuf = file_in->read(256);
if (QByteArray(cbuf,96).right(16).startsWith("MEMORY CARTRIDGE"))
return true;
else
return false;
}

bool ProbeEMS8Meg(QFile * file_in)
{
//EMS 8 Meg card contains "NEW 8 MEG RAM CARD+" id at 0x60 and is compatible with MemCardPlus
file_in->seek(0);
QByteArray cbuf = file_in->read(256);
if (QByteArray(cbuf,115).right(19).startsWith("NEW 8 MEG RAM CARD+"))
return true;
else
return false;
}

bool ProbeActionReplay(QFile * file_in)
{
//ActionReplay contains "ACTION REPLAY +U" id at 0x50
file_in->seek(0);
QByteArray cbuf = file_in->read(256);
if (QByteArray(cbuf,96).right(16).startsWith("ACTION REPLAY"))
return true;
else
return false;
}

ImportResult ImportMemCardPlus(QByteArray *hugeram, QFile * file_in, int iClusterSize)
{
char cbuf[256];
char cbuf_prev[256];
SaveType tmpSave;
int iLastUsedCluster=2;
//searching every 256 bytes
file_in->seek(0);
file_in->read(cbuf_prev,256);
int iFileSize = file_in->size();
while (iFileSize - file_in->pos() > 256)
{
//read next 256 bytes
file_in->read(cbuf,40);
//check if save
if ( (cbuf_prev[255]==-1) && (cbuf_prev[254]==-1) && (cbuf[0]!=-1) && (cbuf[22]==0) && (cbuf[23]==0))
{
//check passed, inserting
//datel format is compression-key-based
//key is a unique 16-bit value at offset 34 in save
//it never appears in original save (datel searches this value from 0x0000 to 0xFFFF
// most of the time it's 0x000X or 0x001X)
//RLE sequences are 48-bit:
//0xKKKK 0xXXXX 0xYYYY - write YYYY copies of XXXX, KKKK is key
tmpSave.iBytes = (unsigned char)cbuf[31]+0x100*(unsigned char)cbuf[30]+0x10000*(unsigned char)cbuf[29]+0x1000000*(unsigned char)cbuf[28];
int iCompressionKey = (unsigned char)cbuf[35]+0x100*(unsigned char)cbuf[34];
int iCompressedBytes = (unsigned char)cbuf[39]+0x100*(unsigned char)cbuf[38]+0x10000*(unsigned char)cbuf[37]+0x1000000*(unsigned char)cbuf[36];
int iDecompressedSize = 0;
//check if we have enough space at the end of file
//making a brutal check for inserting size:
//each ClusterSize-4 requires additional 6 bytes (2 for SAT, 4 for header)
//plus 36 additional (34 header, 2 zero-sat-entry)
//if that won't fit into remaining clusters, boil out
int iClustersRequired = (tmpSave.iBytes)/(iClusterSize-4);
int iBytesRequired = tmpSave.iBytes+iClustersRequired*6+36;
iClustersRequired = iBytesRequired/(iClusterSize-4);
if ((iFileSize/iClusterSize - iLastUsedCluster) <= iClustersRequired)
{
//no space left in image to decompress into
QMessageBox msgBox;
msgBox.setText(QObject::tr("Not enough space in image to insert ")+QString(tmpSave.Name)+QObject::tr(" and possibly some other saves. Please retry with a bigger image size."));
msgBox.exec();
return ImportOk;
}
tmpSave.iStartCluster = iLastUsedCluster+1;

//check done, go on
hugeram[0][tmpSave.iStartCluster*iClusterSize] = 0x80;
hugeram[0][tmpSave.iStartCluster*iClusterSize+1] = 0x0;
hugeram[0][tmpSave.iStartCluster*iClusterSize+2] = 0x0;
hugeram[0][tmpSave.iStartCluster*iClusterSize+3] = 0x0;//making up counter
hugeram->replace(tmpSave.iStartCluster*iClusterSize+4,11,QByteArray(&cbuf[0],11));//name
hugeram[0][tmpSave.iStartCluster*iClusterSize+15] = cbuf[11];//lang code
hugeram->replace(tmpSave.iStartCluster*iClusterSize+16,10,QByteArray(&cbuf[12],10));//comment
hugeram->replace(tmpSave.iStartCluster*iClusterSize+26,4,QByteArray(&cbuf[24],4));//date
hugeram->replace(tmpSave.iStartCluster*iClusterSize+30,4,QByteArray(&cbuf[28],4));//size
//calculate sat
int iSatSize = 1;
tmpSave.Name = QByteArray(&cbuf[0],11);
while ( (30 + iSatSize*2 + 2 + tmpSave.iBytes)/(iClusterSize-4) > iSatSize)
iSatSize++;
//fill new sat
tmpSave.SAT.clear();
for (int i=0;i<iSatSize;i++)
tmpSave.SAT.append(tmpSave.iStartCluster+i+1);
//add terminator
tmpSave.SAT.append(0);
//copy SAT to hugeram
int iPointer = tmpSave.iStartCluster*iClusterSize + 34;
for (int i=0;i<tmpSave.SAT.size();i++)
{
if (iPointer % iClusterSize == 0)
{
hugeram[0][iPointer] = 0;
hugeram[0][iPointer+1] = 0;
hugeram[0][iPointer+2] = 0;
hugeram[0][iPointer+3] = (unsigned char)tmpSave.cCounter;
iPointer+=4;
}
hugeram[0][iPointer] = (char) ( tmpSave.SAT.at(i) / 0x100 );
hugeram[0][iPointer+1] = (char) ( tmpSave.SAT.at(i) % 0x100 );
iPointer+=2;
}
//copy data
int ic=0;
while (ic<iCompressedBytes)
{
if (iPointer % iClusterSize == 0)
{
hugeram[0][iPointer] = 0;
hugeram[0][iPointer+1] = 0;
hugeram[0][iPointer+2] = 0;
hugeram[0][iPointer+3] = 0;//make up counter
iPointer+=4;
}
file_in->read(cbuf,2);
ic+=2;
if ((unsigned char)cbuf[1]+0x100*(unsigned char)cbuf[0] == iCompressionKey)
{
//it's an RLE sequence!
file_in->read(cbuf,4);
ic+=4;
for (int j=0;j<((unsigned char)cbuf[3]+0x100*(unsigned char)cbuf[2]);j++)
{
hugeram[0][iPointer] = cbuf[0];
iPointer++;
hugeram[0][iPointer] = cbuf[1];
iPointer++;
iDecompressedSize+=2;
//if we catch cluster boundary while executing RLE sequence, insert sys header
if (iPointer % iClusterSize == 0)
{
hugeram[0][iPointer] = 0;
hugeram[0][iPointer+1] = 0;
hugeram[0][iPointer+2] = 0;
hugeram[0][iPointer+3] = 0;//make up counter
iPointer+=4;
}
}
}
else
{
hugeram[0][iPointer] = cbuf[0];
iPointer++;
hugeram[0][iPointer] = cbuf[1]; //this might be wrong for odd-sized saves, but cluster end is unused anyway, so who cares?
iPointer++;
iDecompressedSize+=2;
}
}
if (iDecompressedSize != tmpSave.iBytes)
{
//decompression result is different
QMessageBox msgBox;
msgBox.setText(QObject::tr("Decompression error for ")+QString(tmpSave.Name)+QObject::tr(". Size should be %2, but decompressed into %3").arg(tmpSave.iBytes).arg(iDecompressedSize));
msgBox.exec();
}
int iPos = file_in->pos() % 256;
for (int i=0;i<iPos;i++)
cbuf_prev[i] = hugeram[0][iPointer-iPos+i];
file_in->read(&cbuf_prev[iPos],256-iPos);
iLastUsedCluster+=tmpSave.SAT.size();
}
else
{
//not a save, just some 256 bytes of whatever
//we readed already 40 bytes, 216 to go
file_in->read(&cbuf[40],216);
for (int i=0;i<256;i++) cbuf_prev[i] = cbuf[i];
}
}
return ImportOk;
}

ImportResult ImportEMS8Meg(QByteArray *hugeram, QFile * file_in, int iClusterSize)
{
//same as MemCardPlus. probably.
return ImportMemCardPlus(hugeram,file_in,iClusterSize);
}

ImportResult ImportActionReplay(QByteArray *hugeram, QFile * file_in)
{
char cbuf[256];
//AR actually holds the full cart image in RLE-compressed format
//so we need to import it as-is, and then convert to user-provided
//cluster size and image size
//ok, off we go
//int iFileSize = file_in->size();
//parsing sequences
int iHeadersEnd = 0x20000;
file_in->seek(iHeadersEnd);
//check if it's an uncompressed AR image
file_in->read(cbuf,16);//get 16 bytes
file_in->seek(iHeadersEnd);//return to start
if (QByteArray(cbuf).startsWith("BackUpRam Format"))
{
//this is an uncompressed image, probably unpacked by Pseudo Saturn Kai, copy as-is
QByteArray b = file_in->readAll();
hugeram->replace(0,b.size(),b);
}
else
{
//compressed AR image
bool bHeaderFound;
int iPackedSize=-1;
int iUnpackedSize=-1;
unsigned char cActionReplayKey;
unsigned char cActionReplayKey2;
bool bKey2Used = false;
do
{
bHeaderFound = false;
file_in->read(cbuf,5);
if (QByteArray(cbuf).startsWith("RLE01"))
{
//RLE01 header, parsing
bHeaderFound = true;
file_in->read(cbuf,1);
cActionReplayKey = (unsigned char)cbuf[0];
file_in->read(cbuf,4);
iPackedSize = 0x1000000*(unsigned char)cbuf[0] + 0x10000*(unsigned char)cbuf[1] +
0x100*(unsigned char)cbuf[2] + (unsigned char)cbuf[3];
iHeadersEnd+=10;//size of RLE01 header
}
else if (QByteArray(cbuf).startsWith("DEF02"))
{
//DEF02 header, parsing
bHeaderFound = true;
file_in->read(cbuf,1);
cActionReplayKey2 = (unsigned char)cbuf[0];
bKey2Used = true;
file_in->read(cbuf,4);
iUnpackedSize = 0x1000000*(unsigned char)cbuf[0] + 0x10000*(unsigned char)cbuf[1] +
0x100*(unsigned char)cbuf[2] + (unsigned char)cbuf[3];
iHeadersEnd+=10;//size of RLE01 header
}
}while (bHeaderFound);

file_in->seek(iHeadersEnd);

//now brutally unpacking it as a full image
int iPointer = 0;
while (file_in->pos() < (0x20000+iPackedSize))
{
//AR format is compression-key-based
//key is a 8-bit value stored at the card beginning
//if it appears in uncompessed save, it is encoded as KK 00
//RLE sequences are 24-bit:
//0xKK 0xXX 0xYY - write XX copies of YY, KK is key
file_in->read(cbuf,1);
if ((unsigned char)cbuf[0] == cActionReplayKey)
{
//it's an RLE sequence! which one?
file_in->read(&(cbuf[1]),1);
if ((unsigned char)cbuf[1] == 0x00)
{
//it's a KK 00 sequence, inserting single KK character
hugeram[0][iPointer] = cbuf[0];//inserting KK
iPointer++;
}
else
{
//it's a KK XX YY sequence
file_in->read(&(cbuf[2]),1);
for (int j=0;j<((unsigned char)cbuf[1]);j++)
{
hugeram[0][iPointer] = cbuf[2];
iPointer++;
}
}
}
else if (bKey2Used && ((unsigned char)cbuf[0] == cActionReplayKey2))
{
//it's a key2 RLE sequence
file_in->read(&(cbuf[1]),1);
if ((unsigned char)cbuf[1] == 0x00)
{
//it's a KK 00 sequence, inserting single KK character
hugeram[0][iPointer] = cbuf[0];//inserting KK
iPointer++;
}
else
{
//it's a KK XX YY DD sequence
//DD is an unknown field.
//DD could be a dummy data, redundacy data, checksum, or something else
//but the fact is DD is not needed for decompression
file_in->read(&(cbuf[2]),2);
for (int j=0;j<((unsigned char)cbuf[1]);j++)
{
hugeram[0][iPointer] = cbuf[2];
iPointer++;
}
}
}
else
{
//it's not an RLE sequence, just a databyte
hugeram[0][iPointer] = cbuf[0];//inserting databyte
iPointer++;
}
}
}

//add header
for (int i=0;i<4;i++)
hugeram->replace(16*i,16,QByteArray("BackUpRam Format"));

return ImportOk;

}
@@ -0,0 +1,18 @@
#ifndef IMPORT_H
#define IMPORT_H

#include "mainwindow.h"

enum ProbeResult {ProbeOk,ProbeFailed};
enum ImportResult {ImportOk,ImportFailed};

bool ProbeMemCardPlus(QFile * file_in);
bool ProbeEMS8Meg(QFile * file_in);
bool ProbeActionReplay(QFile * file_in);

ImportResult ImportMemCardPlus(QByteArray *hugeram, QFile * file_in, int iClusterSize);
ImportResult ImportEMS8Meg(QByteArray *hugeram, QFile * file_in, int iClusterSize);
ImportResult ImportActionReplay(QByteArray *hugeram, QFile * file_in);

#endif // IMPORT_H

Large diffs are not rendered by default.

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>753</width>
<height>395</height>
<height>418</height>
</rect>
</property>
<property name="sizePolicy">
@@ -45,7 +45,7 @@
<item>
<widget class="QPushButton" name="LoadButton">
<property name="text">
<string>Load</string>
<string>Open</string>
</property>
</widget>
</item>
162 new.xpm
@@ -0,0 +1,162 @@
/* XPM */
static char * C:\Saturn\__repo\ss_save_parser\new_xpm[] = {
"47 64 95 2",
" c None",
". c #0F0F0F",
"+ c #2D2D2D",
"@ c #363636",
"# c #323232",
"$ c #313131",
"% c #303030",
"& c #2F2F2F",
"* c #2E2E2E",
"= c #2C2C2C",
"- c #2B2B2B",
"; c #2A2A2A",
"> c #282828",
", c #272727",
"' c #262626",
") c #252525",
"! c #242424",
"~ c #232323",
"{ c #1A1A1A",
"] c #0E0E0E",
"^ c #6E6E6E",
"/ c #636363",
"( c #4B4B4B",
"_ c #464646",
": c #454545",
"< c #444444",
"[ c #434343",
"} c #424242",
"| c #404040",
"1 c #3F3F3F",
"2 c #3E3E3E",
"3 c #3C3C3C",
"4 c #3A3A3A",
"5 c #383838",
"6 c #343434",
"7 c #101010",
"8 c #646464",
"9 c #131313",
"0 c #333333",
"a c #353535",
"b c #575757",
"c c #FFFFFF",
"d c #1E1E1E",
"e c #292929",
"f c #222222",
"g c #545454",
"h c #171717",
"i c #1F1F1F",
"j c #151515",
"k c #0D0D0D",
"l c #1C1C1C",
"m c #0C0C0C",
"n c #555555",
"o c #141414",
"p c #191919",
"q c #161616",
"r c #0A0A0A",
"s c #121212",
"t c #0B0B0B",
"u c #080808",
"v c #202020",
"w c #111111",
"x c #090909",
"y c #070707",
"z c #535353",
"A c #1D1D1D",
"B c #060606",
"C c #525252",
"D c #1B1B1B",
"E c #515151",
"F c #010101",
"G c #4F4F4F",
"H c #181818",
"I c #000000",
"J c #212121",
"K c #4E4E4E",
"L c #4A4A4A",
"M c #020202",
"N c #484848",
"O c #393939",
"P c #373737",
"Q c #A5A5A5",
"R c #F2F2F2",
"S c #939393",
"T c #B6B6B6",
"U c #CECECE",
"V c #9E9E9E",
"W c #666666",
"X c #DADADA",
"Y c #9C9C9C",
"Z c #D4E3FF",
"` c #C2C2C2",
" . c #E6E6E6",
".. c #050505",
"+. c #AAAAAA",
". + @ # # # # # # # # # $ % & * * + = - ; > , ' ) ! ~ ~ ! { ] ",
"~ ^ / ( _ _ _ _ _ _ : < < [ } | 1 2 3 3 4 5 @ 6 # $ $ 4 1 2 ; 7 ",
") 8 , 9 0 5 a ' . ",
"~ b . c c c c c c c c c c c c c c c c c c c c c c c c + ; d e f ] ",
"~ g . c c c c c c c c c c c c c c c c c c c c c c c c ; h . ~ i ] ",
"~ g ] c c c c c c c c c c c c c c c c c c c c c c c c > j k d l m ",
"~ n ] c c c c c c c c c c c c c c c c c c c c c c c c ' o c k p p m ",
"~ n ] c c c c c c c c c c c c c c c c c c c c c c c c ! 9 c c m h q r ",
"~ n ] c c c c c c c c c c c c c c c c c c c c c c c c f s c c c t o 9 u ",
"~ n ] c c c c c c c c c c c c c c c c c c c c c c c c v w c c c c r 9 s u ",
"~ g ] c c c c c c c c c c c c c c c c c c c c c c c c i 7 c c c c c x o s y ",
"~ z ] c c c c c c c c c c c c c c c c c c c c c c c c A . c c c c c c u o s B ",
"~ C ] c c c c c c c c c c c c c c c c c c c c c c c c D ] c c c c c c c u o w B ",
"f E k c c c c c c c c c c c c c c c c c c c c c c c c p ] c c c c c c c c u s x F ",
"f G ] c c c c c c c c c c c c c c c c c c c c c c c c H k c c c c c c c c c I I I I ",
"J K . c c c c c c c c c c c c c c c c c c c c c c c c q m c c c c c c c c c c I I I I ",
"v ( ] c c c c c c c c c c c c c c c c c c c c c c c c j 7 I I I I ",
"v L k c c c c c c c c c c c c c c c c c c c c c c c c 9 q . B M F I I I I I I I I I I I I I ",
"v N k c c c c c c c c c c c c c c c c c c c c c c c c r m y M I I I I I I I I I I I I I I I ",
"d : k c c c c c c c c c c c c c c c c c c c c c c c c I I I ",
"A [ m c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"l | t c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"l 2 t c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"D 3 m c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"{ O t c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"p P t c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"p 6 r c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"H $ r c c c c c c c L L L L L L L L L L L L L L L L L L L L L L L L L L L Q c c c c c c I I ",
"h * r c c c c c c L R R R R R R R R R R R R R R R R R R R R R R R R R R R ' S c c c c c I I ",
"q = r c c c c c c L T U U U U U U U U U U U U U U U U U U U U U U U U U V ' W Q c c c c I I ",
"j ; x c c c c c c L R R U U U U U U U U U U U U U U U U U U U U U X U R R ' g Y c c c c I I ",
"o , x c c c c c c L T T R U Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z ` R T T ' g Y c c c c I I ",
"o ) u c c c c c c L R R U U Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z ` X R R ' g Y c c c c I I ",
"9 ~ u c c c c c c L T T R U R . . . . . . . . . . . . . . . . .R ` R T T ' g Y c c c c I I ",
"s J u c c c c c c L R R U U R R R R R R R R R R R R R R R R R R R ` X R R ' g Y c c c c I I ",
"w i y c c c c c c L T T R U R . . . . . . . . . . . . . . . . .R ` R T T ' g Y c c c c I I ",
"7 A y c c c c c c L X ` U U R R R R R R R R R R R R R R R R R R R ` U U V ' g Y c c c c I I ",
". D y c c c c c c L X ` U U R . . . . . . . . . . . . . . . . .R ` U U V ' g Y c c c c I I ",
"] p y c c c c c c L X ` U U R R R R R R R R R R R R R R R R R R R ` U U V ' g Y c c c c I I ",
"] o M c c c c c c L X ` U U R . . . . . . . . . . . . . . . . .R ` U U V ' g Y c c c c I I ",
"r ..I c c c c c c L X ` U U R R R R R R R R R R R R R R R R R R R ` U U V ' g Y c c c c I I ",
"M I I c c c c c c L X ` U ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` U U V ' g Y c c c c I I ",
"I I I c c c c c c L X ` U U U U U U U U U U U U U U U U U U U U U U U U V ' g Y c c c c I I ",
"I I I c c c c c c L X ` U U U U U U U U U +.R +.R +.R U U U U U U U U U V ' g Y c c c c I I ",
"I I I c c c c c c L X ` U U U U U U U U +.R +.R +.R U U U U U U U U U U V ' g Y c c c c I I ",
"I I I c c c c c c L X ` U U U U U U U U U U U U U U U U U U U U U U U U V ' g Y c c c c I I ",
"I I I c c c c c c L X ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` V ' g Y c c c c I I ",
"I I I c c c c c c Q ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' 5 W Q c c c c I I ",
"I I I c c c c c c c S W g g g g g g g g g g g g g g g g g g g g g g g g g W S c c c c c I I ",
"I I I c c c c c c c c Q Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Q c c c c c c I I ",
"I I I c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"I I I c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"I I I c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"I I I c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"I I I c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"I I I c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"I I I c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"I I I c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"I I I c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"I I I c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"I I I c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c c I I ",
"I I I I I I ",
"I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I ",
"I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I "};
214 open.xpm
@@ -0,0 +1,214 @@
/* XPM */
static char * C:\Saturn\__repo\ss_save_parser\open_xpm[] = {
"64 48 163 2",
" c None",
". c #2A2A2A",
"+ c #2C2C2C",
"@ c #292929",
"# c #24262A",
"$ c #202329",
"% c #2D2D2C",
"& c #272727",
"* c #D4A756",
"= c #FEC561",
"- c #FDC561",
"; c #DCAD59",
"> c #28292B",
", c #F1BC5E",
"' c #F2BD5E",
") c #A0814A",
"! c #2B2B2B",
"~ c #F9C260",
"{ c #564B37",
"] c #282828",
"^ c #E7B55C",
"/ c #2A2B2C",
"( c #AC894D",
"_ c #26282A",
": c #F8C160",
"< c #866F43",
"[ c #22252A",
"} c #F4BE5F",
"| c #F0BC5E",
"1 c #D8AA58",
"2 c #D9AA58",
"3 c #DAAB58",
"4 c #A4844B",
"5 c #27292B",
"6 c #F5BF5F",
"7 c #212429",
"8 c #FCC461",
"9 c #FFC762",
"0 c #F7C060",
"a c #997C48",
"b c #2E2D2C",
"c c #1F2329",
"d c #262626",
"e c #A7864B",
"f c #26272A",
"g c #1F2228",
"h c #FBC360",
"i c #38352F",
"j c #27282B",
"k c #B69451",
"l c #FFD669",
"m c #FFD569",
"n c #B79552",
"o c #C09851",
"p c #26282B",
"q c #3D3930",
"r c #FFD368",
"s c #FFCB65",
"t c #1F2229",
"u c #68583B",
"v c #2B2B2C",
"w c #9C804A",
"x c #FFCC65",
"y c #BD9954",
"z c #ECB95D",
"A c #F7C563",
"B c #4A4A4A",
"C c #A5A5A5",
"D c #FFD067",
"E c #5B4F38",
"F c #987B48",
"G c #68593C",
"H c #FFCF66",
"I c #F2F2F2",
"J c #939393",
"K c #E9BB5F",
"L c #FBC361",
"M c #403B31",
"N c #C6A056",
"O c #B6B6B6",
"P c #CECECE",
"Q c #9E9E9E",
"R c #666666",
"S c #FFCD66",
"T c #867044",
"U c #C99F54",
"V c #25272A",
"W c #36342F",
"X c #DADADA",
"Y c #545454",
"Z c #9C9C9C",
"` c #715E3E",
" . c #927948",
".. c #D4E3FF",
"+. c #C2C2C2",
"@. c #B19050",
"#. c #292A2B",
"$. c #F0C061",
"%. c #FFD268",
"&. c #4D4535",
"*. c #2A2B2B",
"=. c #5F523A",
"-. c #E6E6E6",
";. c #DDB15C",
">. c #232529",
",. c #FAC360",
"'. c #484033",
"). c #BD9953",
"!. c #7A6641",
"~. c #D1A556",
"{. c #23262A",
"]. c #302F2D",
"^. c #FFD167",
"/. c #F3BE5F",
"(. c #796440",
"_. c #897345",
":. c #A4874C",
"<. c #2A2A2B",
"[. c #E8BA5F",
"}. c #413C32",
"|. c #A9874C",
"1. c #554B37",
"2. c #D0A758",
"3. c #514735",
"4. c #B49251",
"5. c #FFCE66",
"6. c #6D5D3D",
"7. c #222529",
"8. c #F8C563",
"9. c #F3BD5E",
"0. c #816A42",
"a. c #816C43",
"b. c #987D49",
"c. c #2E2E2D",
"d. c #DFB35D",
"e. c #37342F",
"f. c #B18D4E",
"g. c #4C4435",
"h. c #AAAAAA",
"i. c #C39E55",
"j. c #FFCA63",
"k. c #594D37",
"l. c #AB8C4E",
"m. c #60533A",
"n. c #EEBA5D",
"o. c #27282A",
"p. c #EEBE60",
"q. c #222429",
"r. c #967947",
"s. c #2B2C2C",
"t. c #786541",
"u. c #8B7446",
"v. c #D6AC5A",
"w. c #383838",
"x. c #2F2E2D",
"y. c #433D32",
"z. c #A2854C",
"A. c #534A37",
"B. c #FBC864",
"C. c #E2B65E",
"D. c #776540",
"E. c #FFD86A",
"F. c #705F3E",
" . . + + + + + + + + + + + + + + + + + + + + + + + . @ ",
". + # $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ # % & ",
". # * = - - - - - - - - - - - - - - - - - - - - - = ; > + ",
"+ $ = , , , , , , , , , , , , , , , , , , , , , , , ' ) > ! ",
"+ $ - , , , , , , , , , , , , , , , , , , , , , , , , ~ { + ] ",
"+ $ - , , , , , , , , , , , , , , , , , , , , , , , , , ^ / + ",
"+ $ - , , , , , , , , , , , , , , , , , , , , , , , , , , ( _ ! ! + + + + + + + + + + + + + + + + + + + + + ! ",
"+ $ - , , , , , , , , , , , , , , , , , , , , , , , , , , : < [ # # # # # # # # # # # # # # # # # # # # # # > + ",
"+ $ - , , , , , , , , , , , , , , , , , , , , , , , , , , , } | 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 4 5 @ ",
"+ $ - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , 6 7 . ",
"+ $ - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , } 7 . ",
"+ $ - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , } 7 . ",
"+ $ - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , } 7 . ",
"+ $ - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , } 7 . ",
"+ $ - , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , } 7 . ",
"+ $ - , , , , , , , , , ' 8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 9 $ . ",
"+ $ - , , , , , , , , 0 a b c $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ % + + + + + . d ",
"+ $ - , , , , , , , , e f _ g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g _ % ",
"+ $ - , , , , , , , h i j k l m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m l n 5 . ",
"+ $ - , , , , , , , o p q r s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s r t + ",
"+ $ - , , , , , , 6 u v w x s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s y > @ ",
"+ $ - , , , , , , z # [ A s s s s s B B B B B B B B B B B B B B B B B B B B B B B B B B B C s s s s s s s s s s s s s s D E + ",
"+ $ - , , , , , , F v G H s s s s B I I I I I I I I I I I I I I I I I I I I I I I I I I I d J s s s s s s s s s s s s s K 7 ! ",
"+ $ - , , , , , L M _ N s s s s s B O P P P P P P P P P P P P P P P P P P P P P P P P P Q d R C s s s s s s s s s s s S T + @ ",
"+ $ - , , , , , U V W r s s s s s B I I P P P P P P P P P P P P P P P P P P P P P X P I I d Y Z s s s s s s s s s s s H + + ",
"+ $ - , , , , } ` v .x s s s s s B O O I P ......................................+.I O O d Y Z s s s s s s s s s s s @.#.@ ",
"+ $ - , , , , , _ 7 $.s s s s s s B I I P P ......................................+.X I I d Y Z s s s s s s s s s s %.&.+ ",
"+ $ - , , , , ) *.=.D s s s s s s B O O I P I -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.I +.I O O d Y Z s s s s s s s s s s ;.>.! ",
"+ $ - , , , ,.'.> ).s s s s s s s B I I P P I I I I I I I I I I I I I I I I I I I +.X I I d Y Z s s s s s s s s s S !.+ ] ",
"+ $ - , , , ~.{.].^.s s s s s s s B O O I P I -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.I +.I O O d Y Z s s s s s s s s s s j + ",
"+ $ - , , /.(.+ _.x s s s s s s s B X +.P P I I I I I I I I I I I I I I I I I I I +.P P Q d Y Z s s s s s s s s s :.<.@ ",
"+ $ - , , 6 <.7 [.s s s s s s s s B X +.P P I -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.I +.P P Q d Y Z s s s s s s s s r }.+ ",
"+ $ - , , |.#.1.^.s s s s s s s s B X +.P P I I I I I I I I I I I I I I I I I I I +.P P Q d Y Z s s s s s s s s 2.V ! ",
"+ $ - , ~ 3.#.4.s s s s s s s s s B X +.P P I -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.I +.P P Q d Y Z s s s s s s s 5.6.+ ] ",
"+ $ - , 3 7.v H s s s s s s s s s B X +.P P I I I I I I I I I I I I I I I I I I I +.P P Q d Y Z s s s s s s s 8.>.! ",
"+ $ - 9.0.+ a.S s s s s s s s s s B X +.P +.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.P P Q d Y Z s s s s s s x b.v . ",
"+ $ - : c.7.d.s s s s s s s s s s B X +.P P P P P P P P P P P P P P P P P P P P P P P P Q d Y Z s s s s s s %.e.+ ",
"+ $ - f.> g.%.s s s s s s s s s s B X +.P P P P P P P P P h.I h.I h.I P P P P P P P P P Q d Y Z s s s s s s i.j . ",
"+ $ j.k.<.l.s s s s s s s s s s s B X +.P P P P P P P P h.I h.I h.I P P P P P P P P P P Q d Y Z s s s s s D m.+ ",
"+ $ n.7.o.x s s s s s s s s s s s B X +.P P P P P P P P P P P P P P P P P P P P P P P P Q d Y Z s s s s s p.q.. ",
"+ 7 r.s.t.S s s s s s s s s s s s B X +.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+.Q d Y Z s s s s x u.+ . ",
"+ <.M # v.s s s s s s s s s s s s C d d d d d d d d d d d d d d d d d d d d d d d d d d d w.R C s s s s ^.x.+ ",
"+ + + y.r s s s s s s s s s s s s s J R Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y R J s s s s s k > @ ",
"+ + / z.s s s s s s s s s s s s s s s C Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z C s s s s s ^.A.+ ",
"+ + # B.s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s s C.q.! ",
"+ + D.E.m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m m F.+ & ",
"+ + _ g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g g *.! ",
"+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @ "};
@@ -54,11 +54,11 @@ QDateTime GetDateTimeFromSSF4Byte(QByteArray buf)
QByteArray GetSSF4ByteFromDateTime(QDateTime dt)
{
char buf[4];
qint64 tim = 0;
//qint64 tim = 0;
QDateTime d;
d.setDate(QDate(1980,1,1));
d.setTime(QTime(0,0,0,0));
tim = (dt.toMSecsSinceEpoch() - d.toMSecsSinceEpoch() )/60000 + dt.offsetFromUtc()/60 ;
//tim = (dt.toMSecsSinceEpoch() - d.toMSecsSinceEpoch() )/60000 + dt.offsetFromUtc()/60 ;
buf[3] = (dt.date().year()-1980)/2;
buf[2] = 0x80*((dt.date().year()-1980)%2);
buf[2] |= 0x08*(dt.date().month()+1);
@@ -110,21 +110,27 @@ if (save->DateTime.date().year() < 1990) return NotAHeader; //now that's too neg
return ParseOk;
}

ParseResult ParseSAT(QByteArray buf, SaveType *save, int ClusterSize)
ParseResult ParseSAT(QByteArray * hugeram, SaveType *save, int iClusterSize)
{
//okay, now SAT stuff
//calculating SAT size
int i=0;
int i2=0;
short s = 1;
while (s)
int iCurrentCluster = save->iStartCluster;
int iCurrentClusterIndex = 0;
int iCurrentPointer = 34;
short sCurrentEntry = 1; //any nonzero will do
save->SAT.clear();
while (sCurrentEntry)
{
if (0 == ((i*2+34)%ClusterSize)) i+=2;//jumping over cluster header
s = (unsigned char)(buf.at(i*2))*0x100 + (unsigned char)(buf.at(1+i*2));
save->SAT[i2]=s;
i++;
i2++;
if (iCurrentPointer >= iClusterSize)//we hit end of cluster
{
iCurrentPointer = 4;//skipping header of the next cluster
iCurrentClusterIndex++;
iCurrentCluster = save->SAT.at(iCurrentClusterIndex-1);
}
sCurrentEntry = (unsigned char)(hugeram->at(iCurrentCluster*iClusterSize+iCurrentPointer))*0x100
+ (unsigned char)(hugeram->at(iCurrentCluster*iClusterSize+iCurrentPointer+1));
save->SAT.append(sCurrentEntry);
iCurrentPointer+=2;
}
save->iSATSize = i2;
return ParseOk;
}
@@ -11,7 +11,7 @@ QDateTime GetDateTimeFromSSF4Byte(QByteArray buf);
QByteArray GetSSF4ByteFromDateTime(QDateTime dt);

ParseResult ParseHeader(QByteArray buf, SaveType *save);
ParseResult ParseSAT(QByteArray buf, SaveType *save, int ClusterSize);
ParseResult ParseSAT(QByteArray *hugeram, SaveType *save, int iClusterSize);

#endif // PARSELIB_H

@@ -4,5 +4,10 @@
<file>sys_header_start.xpm</file>
<file>sys_header_counter.xpm</file>
<file>blue_arrow.xpm</file>
<file>save.xpm</file>
<file>open.xpm</file>
<file>new.xpm</file>
<file>cart_to_game.xpm</file>
<file>game_to_cart.xpm</file>
</qresource>
</RCC>
735 save.xpm

Large diffs are not rendered by default.