1 #include <string.h>
2 #define _XOPEN_SOURCE 600
3 #include <stdlib.h>
4
5 #include "types.h"
6 #include "festalon.h"
7 #include "nes/nsf.h"
8 #include "pce/hes.h"
9
10 #include "driver.h"
11
uppow2(uint32 n)12 uint32 uppow2(uint32 n)
13 {
14 int x;
15
16 for(x=31;x>=0;x--)
17 if(n&(1<<x))
18 {
19 if((1<<x)!=n)
20 return(1<<(x+1));
21 break;
22 }
23 return n;
24 }
25
FESTA_FixString(char * str)26 char *FESTA_FixString(char *str)
27 {
28 char *orig = str;
29 if(str)
30 while(*str)
31 {
32 if(*str < 0x20) *str = 0x20;
33 str++;
34 }
35 return(orig);
36 }
37
38
FESTAI_Emulate(FESTALON * fe,int * Count)39 float *FESTAI_Emulate(FESTALON *fe, int *Count)
40 {
41 if(fe->nsf)
42 return(FESTANSF_Emulate(fe->nsf, Count));
43 else if(fe->hes)
44 return(FESTAHES_Emulate(fe->hes, Count));
45
46 return(0);
47 }
48
FESTAI_Disable(FESTALON * fe,int t)49 void FESTAI_Disable(FESTALON *fe, int t)
50 {
51 if(fe->nsf)
52 FESTANSF_Disable(fe->nsf, t);
53 else if(fe->hes)
54 FESTAHES_Disable(fe->hes, t);
55 }
56
FFI(FESTALON * fe)57 static void FFI(FESTALON *fe)
58 {
59 int x;
60
61 if(fe->GameName) free(fe->GameName);
62 if(fe->Artist) free(fe->Artist);
63 if(fe->Copyright) free(fe->Copyright);
64 if(fe->Ripper) free(fe->Ripper);
65 if(fe->SongNames)
66 {
67 for(x=0;x<fe->TotalSongs;x++)
68 if(fe->SongNames[x])
69 free(fe->SongNames[x]);
70 free(fe->SongNames);
71 }
72 if(fe->SongLengths)
73 free(fe->SongLengths);
74 if(fe->SongFades)
75 free(fe->SongFades);
76 }
77
FESTAI_FreeFileInfo(FESTALON * fe)78 void FESTAI_FreeFileInfo(FESTALON *fe)
79 {
80 if(fe->nsf)
81 FESTANSF_FreeFileInfo(fe->nsf);
82 FFI(fe);
83 free(fe);
84 }
85
86
FESTAI_Load(uint8 * buf,uint32 size)87 FESTALON *FESTAI_Load(uint8 *buf, uint32 size)
88 {
89 FESTALON *fe;
90
91 fe = malloc(sizeof(FESTALON));
92 memset(fe, 0, sizeof(FESTALON));
93
94 if(!memcmp(buf,"HESM",4))
95 {
96 if(!(fe->hes = FESTAHES_Load(fe, buf, size)))
97 {
98 free(fe);
99 return(0);
100 }
101 }
102 else
103 {
104 if(!(fe->nsf = FESTANSF_Load(fe, buf, size)))
105 {
106 free(fe);
107 return(0);
108 }
109 }
110 return(fe);
111 }
112
113
FESTAI_Close(FESTALON * fe)114 void FESTAI_Close(FESTALON *fe)
115 {
116 FFI(fe);
117 if(fe->nsf)
118 FESTANSF_Close(fe->nsf);
119 else if(fe->hes)
120 FESTAHES_Close(fe->hes);
121 free(fe);
122 }
123
FESTAI_SetVolume(FESTALON * fe,int32 volume)124 int32 FESTAI_SetVolume(FESTALON *fe, int32 volume)
125 {
126 if(volume > 999) volume = 999;
127 if(volume < -999) volume = -999;
128
129 if(fe->nsf)
130 FESTANSF_SetVolume(fe->nsf, volume);
131 else if(fe->hes)
132 FESTAHES_SetVolume(fe->hes, volume);
133
134 return(volume);
135 }
136
FESTAI_SetLowpass(FESTALON * fe,int on,uint32 corner,uint32 order)137 int FESTAI_SetLowpass(FESTALON *fe, int on, uint32 corner, uint32 order)
138 {
139 if(fe->nsf)
140 return(FESTANSF_SetLowpass(fe->nsf, on, corner, order));
141 else if(fe->hes)
142 return(FESTAHES_SetLowpass(fe->hes, on, corner, order));
143
144 return(0);
145 }
146
147
FESTAI_SongControl(FESTALON * fe,int z,int o)148 int FESTAI_SongControl(FESTALON *fe, int z, int o)
149 {
150 if(o)
151 fe->CurrentSong=z;
152 else
153 fe->CurrentSong+=z;
154
155 if(fe->CurrentSong<0) fe->CurrentSong=0;
156 else if(fe->CurrentSong>=fe->TotalSongs) fe->CurrentSong=fe->TotalSongs - 1;
157
158
159 if(fe->nsf)
160 FESTANSF_SongControl(fe->nsf, fe->CurrentSong);
161 else if(fe->hes)
162 FESTAHES_SongControl(fe->hes, fe->CurrentSong);
163 return(fe->CurrentSong);
164 }
165
FESTAI_SetSound(FESTALON * fe,uint32 rate,int quality)166 int FESTAI_SetSound(FESTALON *fe, uint32 rate, int quality)
167 {
168 if(fe->nsf)
169 return(FESTANSF_SetSound(fe->nsf, rate, quality));
170 else if(fe->hes)
171 return(FESTAHES_SetSound(fe->hes, rate, quality));
172
173 return(0);
174 }
175
176
FESTA_malloc(uint32 align,uint32 total)177 void *FESTA_malloc(uint32 align, uint32 total)
178 {
179 void *ret;
180
181 if(align < sizeof(void *))
182 align = sizeof(void *);
183
184 #if HAVE_POSIX_MEMALIGN
185 if(posix_memalign(&ret, align, total))
186 return(0);
187 #else /* Eh, we'll try our best! Assumes that memory has already been aligned to a sizeof(void *) boundary by malloc. */
188 void *real;
189 void *tmp;
190 int t;
191
192 t = align / sizeof(void *);
193
194 if(t * sizeof(void *) != align) // Erhm...
195 return(0);
196
197 real = malloc(total + align);
198
199 tmp = real;
200
201 do
202 {
203 memcpy(tmp, &real, sizeof(void *));
204 tmp += sizeof(void *);
205 } while((unsigned int)tmp & (align - 1));
206 ret = tmp;
207 //printf("%08x:%08x\n",real,ret);
208 #endif
209 return(ret);
210 }
211
FESTA_free(void * m)212 void FESTA_free(void *m)
213 {
214 #if HAVE_POSIX_MEMALIGN
215 free(m);
216 #else
217 void *meep;
218 m-=sizeof(void*);
219 memcpy(&meep, m, sizeof(void *));
220 //printf("Meep: %08x\n",meep);
221 free(meep);
222 #endif
223 }
224
225
FESTAI_GetFileInfo(uint8 * buf,uint32 size,int type)226 FESTALON *FESTAI_GetFileInfo(uint8 *buf, uint32 size, int type)
227 {
228 FESTALON *ret;
229
230 ret = malloc(sizeof(FESTALON));
231 memset(ret, 0, sizeof(FESTALON));
232
233 if(!memcmp(buf,"HESM",4))
234 {
235
236 }
237 else
238 {
239 ret->nsf = FESTANSF_GetFileInfo(ret, buf, size, type);
240 }
241 return(ret);
242 }
243