2 This file is part of xm2nes.
4 xm2nes is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 xm2nes is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with xm2nes. If not, see <http://www.gnu.org/licenses/>.
23 #define read_byte(fp) (unsigned char)fgetc(fp)
25 /* Reads a short (little-endian) */
26 static unsigned short read_ushort(FILE *fp
)
28 unsigned short result
;
29 result
= read_byte(fp
); /* Low byte */
30 result
|= read_byte(fp
) << 8; /* High byte */
33 /* Reads an int (little-endian) */
34 static unsigned int read_uint(FILE *fp
)
37 result
= read_byte(fp
); /* Low byte */
38 result
|= read_byte(fp
) << 8;
39 result
|= read_byte(fp
) << 16;
40 result
|= read_byte(fp
) << 24; /* High byte */
44 static int xm_read_header(FILE *fp
, struct xm_header
*out
)
46 fread(&out
->id_text
, 1, 17, fp
);
47 if (!strncmp(out
->id_text
, "Extended module: ", 17))
48 return XM_FORMAT_ERROR
;
49 fread(&out
->module_name
, 1, 20, fp
);
50 out
->pad1a
= read_byte(fp
);
51 assert(out
->pad1a
== 0x1A);
52 fread(&out
->tracker_name
, 1, 20, fp
);
53 out
->version
= read_ushort(fp
);
54 if (out
->version
< 0x0104)
55 return XM_VERSION_ERROR
;
56 out
->header_size
= read_uint(fp
);
57 if (out
->header_size
!= 0x0114)
58 return XM_HEADER_SIZE_ERROR
;
59 out
->song_length
= read_ushort(fp
);
60 out
->restart_position
= read_ushort(fp
);
61 out
->channel_count
= read_ushort(fp
);
62 out
->pattern_count
= read_ushort(fp
);
63 out
->instrument_count
= read_ushort(fp
);
64 out
->flags
= read_ushort(fp
);
65 out
->default_tempo
= read_ushort(fp
);
66 out
->default_bpm
= read_ushort(fp
);
67 fread(&out
->pattern_order_table
, 1, 256, fp
);
68 assert(ftell(fp
) == 0x150);
69 assert(ftell(fp
)-0x3C == out
->header_size
);
73 static int xm_read_pattern(FILE *fp
, int channel_count
, struct xm_pattern
*out
)
75 unsigned int header_length
;
76 unsigned char packing_type
;
77 unsigned short row_count
;
78 unsigned short packed_data_size
;
80 header_length
= read_uint(fp
);
81 assert(header_length
== 9);
82 packing_type
= read_byte(fp
);
83 assert(packing_type
== 0);
84 row_count
= read_ushort(fp
);
85 packed_data_size
= read_ushort(fp
);
86 pos_before
= ftell(fp
);
87 out
->row_count
= row_count
;
88 out
->data
= (struct xm_pattern_slot
*)malloc(channel_count
* row_count
* sizeof(struct xm_pattern_slot
));
89 memset(out
->data
, 0, channel_count
* row_count
* sizeof(struct xm_pattern_slot
));
90 if (packed_data_size
!= 0) {
91 /* unpack pattern data */
93 struct xm_pattern_slot
*slot
;
95 for (row
= 0; row
< row_count
; ++row
) {
96 for (column
= 0; column
< channel_count
; ++column
) {
97 unsigned char pattern_byte
;
98 unsigned char note
= 0, instrument
= 0, volume
= 0, effect_type
= 0, effect_param
= 0;
99 pattern_byte
= read_byte(fp
);
100 if (pattern_byte
& 0x80) {
102 if (pattern_byte
& 0x01)
103 note
= read_byte(fp
);
104 if (pattern_byte
& 0x02)
105 instrument
= read_byte(fp
);
106 if (pattern_byte
& 0x04)
107 volume
= read_byte(fp
);
108 if (pattern_byte
& 0x08)
109 effect_type
= read_byte(fp
);
110 if (pattern_byte
& 0x10)
111 effect_param
= read_byte(fp
);
115 instrument
= read_byte(fp
);
116 volume
= read_byte(fp
);
117 effect_type
= read_byte(fp
);
118 effect_param
= read_byte(fp
);
121 slot
->instrument
= instrument
;
122 slot
->volume
= volume
;
124 if ((effect_type
== 0) && (effect_param
!= 0)) effect_type
= 5; /* arpeggio */
125 slot
->effect_type
= effect_type
;
126 slot
->effect_param
= effect_param
;
130 assert(ftell(fp
) == pos_before
+ packed_data_size
);
135 int xm_read(FILE *fp
, struct xm
*xm
)
138 int ret
= xm_read_header(fp
, &xm
->header
);
142 xm
->patterns
= (struct xm_pattern
*)malloc(xm
->header
.pattern_count
* sizeof(struct xm_pattern
));
143 memset(xm
->patterns
, 0, xm
->header
.pattern_count
* sizeof(struct xm_pattern
));
146 for (i
= 0; i
< xm
->header
.pattern_count
; ++i
) {
147 ret
= xm_read_pattern(fp
, xm
->header
.channel_count
, &xm
->patterns
[i
]);
155 void xm_print_header(const struct xm_header
*head
, FILE *fp
)
160 strncpy(tmp
, head
->module_name
, 20);
161 fprintf(fp
, "Module name: '%s'\n", tmp
);
162 strncpy(tmp
, head
->tracker_name
, 20);
163 fprintf(fp
, "Tracker name: '%s'\n", tmp
);
165 fprintf(fp
, "Version: %.4X\n", head
->version
);
166 fprintf(fp
, "Song length: %d\n", head
->song_length
);
167 fprintf(fp
, "Restart position: %d\n", head
->restart_position
);
168 fprintf(fp
, "Number of channels: %d\n", head
->channel_count
);
169 fprintf(fp
, "Number of patterns: %d\n", head
->pattern_count
);
170 fprintf(fp
, "Number of instruments: %d\n", head
->instrument_count
);
171 fprintf(fp
, "Flags: %d\n", head
->flags
);
172 fprintf(fp
, "Default tempo: %d\n", head
->default_tempo
);
173 fprintf(fp
, "Default BPM: %d\n", head
->default_bpm
);
176 void xm_print_pattern(const struct xm
*xm
, int pindex
, FILE *fp
)
179 const struct xm_pattern
*pat
= &xm
->patterns
[pindex
];
180 for (row
= 0; row
< pat
->row_count
; ++row
) {
181 const struct xm_pattern_slot
*slot
= &pat
->data
[row
* xm
->header
.channel_count
];
182 fprintf(fp
, "%.2x: %.2x %.2x %.2x %.2x %.2x\n",
183 row
, slot
->note
, slot
->instrument
, slot
->volume
,
184 slot
->effect_type
, slot
->effect_param
);
188 void xm_destroy(struct xm
*xm
)
191 for (i
= 0; i
< xm
->header
.pattern_count
; ++i
)
192 free(xm
->patterns
[i
].data
);