midi.c has better error checking and better error messages.
[cantaveria.git] / music.c
blob3da7d0d01c9aa03c36a2f46019ae8cca5c160899
1 /*
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
25 #include <stdio.h>
26 #include <stdlib.h>
28 #include <list.h>
29 #include <music.h>
30 #include <seq.h>
31 #include <midi.h>
32 #include <util.h>
34 mus_id current_id = MUS_NOTHING;
36 list* songs[32] = {
37 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
38 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
39 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
40 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
43 int positions[32];
45 static char* mus_name(mus_id id){
46 switch(id){
47 case MUS_NOTHING: return "MUS_NOTHING";
48 case MUS_COOL: return "MUS_COOL";
49 case MUS_TEST1: return "MUS_TEST1";
50 default: return "(?)";
54 static int is_id_invalid(mus_id id){
55 if(id >= 32) return 1;
56 else return 0;
60 int music_load(char* filename, mus_id id){
61 list* events;
63 if(id == MUS_NOTHING){
64 printf("music_load: you can't load a song into MUS_NOTHING\n");
65 return -1;
68 if(is_id_invalid(id)){
69 printf("music_load: music id out of range (%d)\n", id);
70 return -1;
73 if(songs[id] != NULL){
74 printf("music_load: slot %s not empty\n", mus_name(id));
75 return -1;
78 events = midi_load(filename);
79 if(events == NULL){
80 printf("music_load: unable to load \"%s\"\n", filename);
81 return -1;
84 songs[id] = events;
85 return 0;
88 void music_unload(mus_id id){
89 if(is_id_invalid(id)) return;
90 if(songs[id] == NULL) return;
92 if(music_current() == id) music_stop(id);
94 list* ptr = songs[id]->next;
95 while(ptr){
96 free(ptr->item);
97 ptr = ptr->next;
100 recycle(songs[id]->next);
101 songs[id] = NULL;
104 mus_id music_current(){
105 return current_id;
108 void music_play(mus_id id){
109 if(is_id_invalid(id)) return;
110 if(songs[id] == NULL) return;
111 if(music_current() == id) return;
113 music_stop(id);
114 seq_load(songs[id]);
115 seq_seek(positions[id]);
116 seq_enable();
118 current_id = id;
122 void music_stop(mus_id id){
123 if(is_id_invalid(id)) return;
124 if(songs[id] == NULL) return;
125 if(music_current() == id) seq_disable();
127 positions[id] = 0;
130 void music_pause(){
131 seq_disable();
132 positions[music_current()] = seq_tell();
135 void music_volume(int percent){
136 /* somehow enqueue a special event */
139 void music_fadeout(int seconds){
140 /* somehow enqueue a special event */
143 void music_print(mus_id id){
144 list* ptr;
146 if(is_id_invalid(id)){
147 printf("%d is an invalid id\n", id);
148 return;
151 if(songs[id] == NULL){
152 char* name = mus_name(id);
153 printf("%s is not loaded. use music_load(filename, %s)\n", name, name);
154 return;
157 ptr = songs[id]->next;
158 while(ptr){
159 event* e = ptr->item;
160 printf("(%d, %03x, %d, %d, %d)\n",
161 e->tick,
162 e->type,
163 e->chan,
164 e->val1,
165 e->val2
167 ptr = ptr->next;
171 void music_debug(){
172 int i;
173 printf("music:\n");
174 for(i=0; i<32; i++){
175 char* name = mus_name(i);
176 int pos = positions[i];
178 if(songs[i]){
179 int count = length(songs[i]);
180 printf("(%15s, %7de, %11d)\n", name, count, pos);
182 else{
183 printf("(%15s, %7s, %11d)\n", name, "_", pos);