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