6 #include "sifloader.fdh"
8 #define SIF_MAGICK 'SIF2' // SIF magick and version denotation; first 4 bytes of file
10 SIFLoader::SIFLoader()
15 SIFLoader::~SIFLoader()
22 void c------------------------------() {}
25 void SIFLoader::ClearIndex()
29 SIFIndexEntry
*entry
= (SIFIndexEntry
*)fIndex
.ItemAt(i
);
32 if (entry
->data
) free(entry
->data
);
39 void SIFLoader::CloseFile()
51 void c------------------------------() {}
54 bool SIFLoader::LoadHeader(const char *filename
)
62 fp
= fFP
= fileopen(filename
, "rb");
66 staterr("SIFLoader::LoadHeader: failed to open file '%s'", filename
);
70 if ((magick
= fgetl(fp
)) != SIF_MAGICK
)
72 staterr("SIFLoader::LoadHeader: magick check failed--this isn't a SIF file or is wrong version?");
73 staterr(" (expected %08x, got %08x)", SIF_MAGICK
, magick
);
77 int nsections
= fgetc(fp
);
78 stat("SIFLoader::LoadHeader: read index of %d sections", nsections
);
80 for(int i
=0;i
<nsections
;i
++)
82 SIFIndexEntry
*entry
= new SIFIndexEntry
;
84 entry
->type
= fgetc(fp
); // section type
85 entry
->foffset
= fgetl(fp
); // absolute offset in file
86 entry
->length
= fgetl(fp
); // length of section data
87 entry
->data
= NULL
; // we won't load it until asked
89 fIndex
.AddItem(entry
);
90 //stat(" - Sect%02d @ %04x", entry->type, entry->foffset);
93 // ..leave file handle open, its ok
97 // load into memory and return a pointer to the section of type 'type',
98 // or NULL if the file doesn't have a section of that type.
99 uint8_t *SIFLoader::FindSection(int type
, int *length_out
)
101 // try and find the section in the index
104 SIFIndexEntry
*entry
= (SIFIndexEntry
*)fIndex
.ItemAt(i
);
107 if (entry
->type
== type
)
110 // haven't loaded it yet? need to fetch it from file?
115 staterr("SIFLoader::FindSection: entry found and need to load it, but file handle closed");
116 if (length_out
) *length_out
= 0;
120 stat("Loading SIF section %d from address %04x", type
, entry
->foffset
);
122 entry
->data
= (uint8_t *)malloc(entry
->length
);
123 fseek(fFP
, entry
->foffset
, SEEK_SET
);
124 fread(entry
->data
, entry
->length
, 1, fFP
);
127 if (length_out
) *length_out
= entry
->length
;
132 if (length_out
) *length_out
= 0;
137 void c------------------------------() {}
140 bool SIFLoader::BeginSave()
143 if (fFP
) { fclose(fFP
); fFP
= NULL
; }
148 bool SIFLoader::AddSection(int type
, uint8_t *data
, int datalen
)
150 SIFIndexEntry
*entry
= new SIFIndexEntry
;
153 entry
->foffset
= fTotalDataAdded
; // not including index tables or header, yet
154 entry
->length
= datalen
;
157 fTotalDataAdded
+= datalen
;
158 fIndex
.AddItem(entry
);
162 bool SIFLoader::EndSave(const char *filename
)
166 fp
= fileopen(filename
, "wb");
169 stat("SIFLoader::EndSave: failed to open '%s' for writing", filename
);
173 // write header-header
174 fputl(SIF_MAGICK
, fp
);
175 fputc(fIndex
.CountItems(), fp
);
177 // compute fianl length of index table so we can write the correct foffsets
178 int indexlen
= 5 + (fIndex
.CountItems() * 9);
183 SIFIndexEntry
*entry
= (SIFIndexEntry
*)fIndex
.ItemAt(i
);
186 fputc(entry
->type
, fp
);
187 fputl(entry
->foffset
+ indexlen
, fp
);
188 fputl(entry
->length
, fp
);
191 // save actual section data
194 SIFIndexEntry
*entry
= (SIFIndexEntry
*)fIndex
.ItemAt(i
);
197 fwrite(entry
->data
, entry
->length
, 1, fp
);