7 #define MOD_NO_SAMPLE 31
17 static char *notenames
[] = {"C-", "C#", "D-", "D#", "E-", "F-", "F#", "G-",
18 "G#", "A-", "A#", "H-"};
20 struct sample_header
{
21 u8 name
[22]; //22 bytes
25 u16 loopstart
; //2 bytes
26 u16 looplength
; //2 bytes
27 signed char *smpdata
; //1 byte
30 struct pattern_entry
{
38 struct pattern_entry pattern_entry
[64][4];
43 struct sample_header sample
[31];
46 struct pattern
*patterns
;
51 int main(int argc
, char **argv
){
53 struct mod_header modheader
;
56 u8 highestPattern
= 0;
58 const u16 octave1Period
[12] = {
59 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453
62 u16 periodTable
[12*5];
66 for(octave
= 0; octave
< 5; octave
++){
67 for(note
= 0; note
< 12; note
++){
68 //*2 to get us into octave 0, then divide by 2 for each
70 periodTable
[octave
*12 + note
] =
71 (octave1Period
[note
]*2) >> octave
;
75 /* ~opening the modfile~ */
76 modfile
= fopen(argv
[1], "rb");
79 printf("Couldn't open file!\n");
84 // probably unnecessary
85 /*fseek(modfile, 1080, SEEK_SET);
86 fread(&sig, 1, 4, modfile);
87 if(strcmp(sig,"M.K.")){
88 printf("not a MOD\n");
95 /* ~what's its name?~ */
97 fread(modheader
.name
, 20, 1, modfile
);
98 modheader
.name
[19] = '\0';
100 /* ~ load samples ~*/
101 for(i
= 0; i
< 31; i
++){
102 fread(&modheader
.sample
[i
], 30, 1, modfile
);
103 modheader
.sample
[i
].smpdata
= NULL
;
105 modheader
.sample
[i
].length
=
106 ( ((modheader
.sample
[i
].length
& 0xff) << 8) |
107 (modheader
.sample
[i
].length
>> 8) );
109 modheader
.sample
[i
].loopstart
=
110 ( ((modheader
.sample
[i
].loopstart
& 0xff) << 8) |
111 (modheader
.sample
[i
].loopstart
>> 8) );
113 modheader
.sample
[i
].looplength
=
114 ( ((modheader
.sample
[i
].looplength
& 0xff) << 8) |
115 (modheader
.sample
[i
].looplength
>> 8) );
119 fread(&modheader
.orderCount
, 1, 1, modfile
);
121 fread(&trash
, 1, 1, modfile
); //useless byte
123 fread(&modheader
.order
, 128, 1 , modfile
);
125 /*~ load patterns ~*/
126 for(i
= 0; i
< modheader
.orderCount
; i
++){
127 if(modheader
.order
[i
] > highestPattern
)
128 highestPattern
= modheader
.order
[i
];
131 modheader
.patternCount
= highestPattern
+ 1;
133 // allocate space for patterns
134 modheader
.patterns
= malloc(sizeof(struct pattern
[modheader
.patternCount
]));
136 if(modheader
.patterns
==NULL
){
137 printf("out of memory!\n");
142 //initialize modheader.pattern to 0
144 //memset(modheader.pattern, 0, modheader.patternCount*sizeof(u8*));
146 u8 curPattern
, row
, column
;
148 for(curPattern
= 0; curPattern
< modheader
.patternCount
; curPattern
++){
149 //modheader.patterns[curPattern] = malloc(1024); //patterns are always 1k
150 /*modheader.patterns[curPattern] = malloc(sizeof(struct pattern));
151 if(!modheader.patterns[curPattern]){
152 printf("out of memory!\n");
156 memset(modheader.patterns[curPattern], 0, 1024);
159 for(row
= 0; row
< 64; row
++){
160 for(column
= 0; column
< 4; column
++){
167 fread(cell
, 4, 1, modfile
);
169 sample
= (cell
[0] & 0xf0) | (cell
[2] >> 4);
170 period
= cell
[1] | ((cell
[0] & 0xf) << 8);
171 effect
= cell
[2] & 0xf;
174 //looping through the period table
175 /*u8 closestNote = 0;
176 u16 closestDist = 0xffff; //make sure the first comparison sets the closet note
181 period
= MOD_NO_NOTE
; //period 0 is no note
185 for(i = 0; i < 12*5; i++){
186 newDist = abs(period = periodTable[i]);
187 if(newDist < closestDist){
189 closestDist = newDist;
196 sample
= MOD_NO_SAMPLE
;
201 //now that we have our note, we can store the data in our new pattern
202 //calculate the address of the cell to output to
203 // rowoffset = row * 4 columns per row * 4 bytes per cell
204 // columnoffset = column * 4 bytes per cell
206 /*u8 *outCell = &modheader.pattern[curPattern][row*4*4 + column*4];
207 outCell[0] = closestNote;
212 modheader
.patterns
[curPattern
].pattern_entry
[row
][column
].period
= period
;
213 modheader
.patterns
[curPattern
].pattern_entry
[row
][column
].sample
= sample
;
214 modheader
.patterns
[curPattern
].pattern_entry
[row
][column
].effect
= effect
;
215 modheader
.patterns
[curPattern
].pattern_entry
[row
][column
].param
= param
;
221 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
222 //done reading modfile
225 printf("%s\n", modheader
.name
);
227 for(i
= 0; i
< 31; i
++) {
228 printf("%i: %s\n", i
, modheader
.sample
[i
].name
);
229 printf("%i: length:%i\n", i
, modheader
.sample
[i
].length
);
232 printf("highest pattern: %i\n", highestPattern
);
234 printf("orderCount: %i\n", modheader
.orderCount
);
236 printf("patternCount: %i\n", modheader
.patternCount
);
238 //printf("%i\n", sizeof(u8*[modheader.patternCount])); //36
239 //printf("%i\n", sizeof(u8*)); //4
241 /*for(i = 0; i < modheader.patternCount+1; i++)
242 for(row = 0; row < 64; row++)
243 printf("%i\n", modheader.pattern[i][row]);
246 for(i
= 0; i
< modheader
.orderCount
; i
++)
247 printf("%i : %i\n", i
, modheader
.order
[i
]);
249 for(row
= 0; row
< 64; row
++){
250 printf("%i %x %x %x\n", modheader
.patterns
[7].pattern_entry
[row
][0].period
,
251 modheader
.patterns
[7].pattern_entry
[row
][0].sample
+ 1,
252 modheader
.patterns
[7].pattern_entry
[row
][0].effect
,
253 modheader
.patterns
[7].pattern_entry
[row
][0].param
);