2 Cantaveria - action adventure platform game
3 Copyright (C) 2009 2010 Evan Rinehart
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to
18 The Free Software Foundation, Inc.
19 51 Franklin Street, Fifth Floor
20 Boston, MA 02110-1301, USA
22 evanrinehart@gmail.com
34 event
* make_event(int tick
, int type
, int chan
, int val1
, int val2
){
35 event
* e
= malloc(sizeof(event
));
40 int get_delta(reader
* f
){
45 if(b
<0x80){return ((a
&0x7f)<<7) | b
;}
48 if(c
<0x80){return ((a
&0x7f)<<14) | ((b
&0x7f)<<7) | c
;}
51 return ((a
&0x7f)<<21) | ((b
&0x7f)<<14) | ((c
&0x7f)<<7) | d
;
54 list
* midi_load(char* filename
){
57 reader
* f
= data_open("music", filename
);
58 list
* events
= empty();
72 /*format type: 0x0000 0x0001 or 0x0002*/
76 short track_count
= read_short(f
);
80 //code to figure out time division
82 for(i
=0; i
<track_count
; i
++){
88 int chunk_size
= read_int(f
);
89 printf("%d\n",chunk_size
);
96 int delta
= get_delta(f
);
98 if(delta
< 0) return NULL
;
102 buf
[0] = read_byte(f
);
104 int type
= buf
[0] & 0xf0;
105 if(type
>= 0x80 && type
<= 0xe0){//normal event
107 int chan
= buf
[0] & 0x0f;
109 loader_read(f
,buf
,2);
112 append(events
, make_event(tick
, type
, chan
, val1
, val2
));
114 else if(type
< 0x80){//running status
116 buf
[0] = read_byte(f
);
118 append(events
, make_event(tick
, last_type
, last_chan
, val1
, val2
));
120 else if(type
== 0xff){//meta event
121 buf
[0] = read_byte(f
);
124 int len
= get_delta(f
);
127 case 0x2f: printf("end of track\n");
130 case 0x51:printf("tempo change\n"); /*tempo*/
131 loader_read(f
,buf
,3);
132 uspq
= (buf
[0]<<16) | (buf
[1]<<8) | buf
[2];
135 case 0x01: printf("text\n");/*text*/
136 if(len
>= 64){/*too big, skip ahead*/
137 loader_read(f
, NULL
, len
);
140 loader_read(f
,string
,len
);
142 if(strncmp(string
,"LoopStart",len
)==0){
143 push(events
, make_event(tick
, 0x100, 0, 1, 0));
145 else if(strncmp(string
,"LoopEnd",len
)==0){
146 push(events
, make_event(tick
, 0x100, 0, 0, 0));
151 loader_read(f
,NULL
,len
);
155 else{ //sysex and such...
156 int len
= get_delta(f
);
157 loader_read(f
, NULL
, len
);
160 if(end_of_track
) break;
166 //qsort(s->e, s->len, sizeof(event), event_cmp);
168 /* FIXME tempo change needs to be an event */