R-PAGE
Resistance's Portable-Adventure-Game-Engine
ptracker.c
Go to the documentation of this file.
1 /* Resistance's Portable-Adventure-Game-Engine (R-PAGE), Copyright (C) 2019 François Gutherz, Resistance.no
2  Released under MIT License, see license.txt for details.
3 */
4 
5 #ifdef LATTICE
6 #include "rpage/aos/inc.prl"
7 #include <time.h>
8 #include <intuition/intuition.h>
9 #include <graphics/gfxbase.h>
10 #include <hardware/dmabits.h>
11 #include <hardware/intbits.h>
12 #include <hardware/custom.h>
13 #include <graphics/gfxmacros.h>
14 
15 #include "rpage/aos/sound.h"
16 #include "rpage/aos/ptreplay.h"
19 
20 #include "rpage/aos/bitmap.h"
21 #include "rpage/aos/io.h"
22 
23 #include "ext/tinfl.h"
24 #include "ext/aos/shrinkler.h"
25 #include "ext/aos/nrv2.h"
26 
27 #include "rpage/frwk.h"
28 #include "rpage/aos/ptracker.h"
29 #include "rpage/err.h"
30 
31 /* Music */
32 struct Library *PTReplayBase = NULL;
33 struct Module *protracker_mod_playing = NULL;
34 UBYTE *protracker_mod_data = NULL;
35 ULONG protracker_mod_size = 0;
36 BYTE protracker_SigBit;
37 ULONG protracker_SigMask;
38 
39 short protracker_mod_volume = 0;
40 short protracker_fade_min_volume = 0;
41 short protracker_fade_max_volume = 0;
42 short protracker_fade_speed = 0;
43 BOOL protracker_auto_stop = TRUE;
44 
45 // extern struct IntuitionBase *IntuitionBase;
46 // extern struct GfxBase *GfxBase;
47 extern struct ExecBase *SysBase;
48 extern struct DosLibrary *DOSBase;
49 extern struct Custom far custom;
50 
51 BOOL init_protracker_player(void)
52 {
53 #ifdef DEBUG_ENABLE_AUDIO
54  if (SysBase->LibNode.lib_Version >= 36)
55  if (!AssignPath("Libs","Libs"))
56  printf("/!\\Cannot assign local Libs: folder. The Ptreplay library might not load properly!\n");
57 
58  if (!(PTReplayBase = OpenLibrary((UBYTE *)"ptreplay.library", 0)))
59  {
60  rpage_system_alert("Cannot open ptreplay.library!");
61  PTReplayBase = NULL;
62  return FALSE;
63  }
64 
65  protracker_fade_speed = 0;
66  protracker_fade_min_volume = 0;
67  protracker_fade_max_volume = 64;
68  protracker_mod_volume = protracker_fade_max_volume;
69 
70  return TRUE;
71 #else
72  return FALSE;
73 #endif
74 }
75 
76 void uninit_protracker_player(void)
77 {
78 #ifdef DEBUG_ENABLE_AUDIO
79  unload_protacker_music();
80 
81  if (PTReplayBase)
82  {
83  CloseLibrary(PTReplayBase);
84  PTReplayBase = NULL;
85  }
86 #endif
87 }
88 
89 void load_protacker_music(char *filename, int filesize)
90 {
91 #ifdef DEBUG_ENABLE_AUDIO
92  if (filesize < 0)
93  {
94  filesize = file_get_size(filename);
95  printf("load_protacker_music(), guessed module file size : %d\n", filesize);
96  }
97 
98  protracker_mod_data = load_raw_to_mem((UBYTE *)filename, (ULONG)filesize, TRUE);
99  protracker_mod_size = filesize;
100  printf("load_protacker_music(%s) loaded at %x.\n", filename, (unsigned int)protracker_mod_data);
101 #endif
102 }
103 
104 void save_protracker_music(char *filename)
105 {
106 #ifdef DEBUG_ENABLE_AUDIO
107  rpage_file file;
108  if (protracker_mod_data != NULL)
109  {
110  file = rpage_file_open(filename, MODE_OPEN_OR_CREATE);
111  rpage_file_write(file, protracker_mod_data, protracker_mod_size);
112  rpage_file_close(file);
113  }
114 #endif
115 }
116 
117 void load_imploded_protracker_music(char *filename, UBYTE *unpacking_sample_buffer, char *asset_path)
118 {
119 #ifdef DEBUG_ENABLE_AUDIO
120  int unpacked_block_size, packed_block_size, i;
121  BYTE *packed_block, *unpacked_block, *smpl_list_ptr, *smpl_ptr_save;
122  BPTR fileHandle;
123  char tag[4];
124  char *spl_files[32];
125  UWORD mod_size;
126 
127  if ((fileHandle = Open(filename, MODE_OLDFILE)))
128  {
129  Read(fileHandle, &tag, 4);
130  if (strncmp(tag, "IMPK", 4) == 0)
131  {
132  Read(fileHandle, &tag, 4);
133  if (strncmp(tag, "SIZE", 4) == 0)
134  {
135  Read(fileHandle, &unpacked_block_size, 4);
136  unpacked_block = AllocMem(unpacked_block_size, MEMF_CHIP);
137 
138  Read(fileHandle, &tag, 4);
139  if (strncmp(tag, "MINZ", 4) == 0)
140  {
141  Read(fileHandle, &tag, 4);
142  if (strncmp(tag, "SIZE", 4) == 0)
143  {
144  Read(fileHandle, &packed_block_size, 4);
145  packed_block = AllocMem(packed_block_size, 0L);
146  Read(fileHandle, packed_block, packed_block_size);
147 #ifdef DEBUG_MACROS
148  printf("!!!!MINIZ block size: %d\n", packed_block_size);
149 #endif
150  tinfl_decompress_mem_to_mem(unpacked_block, unpacked_block_size, packed_block, packed_block_size, 1);
151  FreeMem(packed_block, packed_block_size);
152 
153  // look for the "SMPL" tag
154  smpl_list_ptr = unpacked_block;
155  while((int)(smpl_list_ptr - unpacked_block) < unpacked_block_size && strncmp(smpl_list_ptr, "SMPL", 4))
156  smpl_list_ptr++;
157 
158  smpl_ptr_save = smpl_list_ptr;
159 
160  // get the sample filenames
161  for(i = 0; i < 32; i++)
162  {
163  smpl_list_ptr += 4;
164  if (smpl_list_ptr[0] | smpl_list_ptr[1] | smpl_list_ptr[2] | smpl_list_ptr[3])
165  {
166  spl_files[i] = (char *)calloc(5, sizeof(char));
167  strncpy(spl_files[i], smpl_list_ptr, 4);
168  printf("Sample #%d: '%s.pak'.\n", i, spl_files[i]);
169  }
170  else
171  {
172  spl_files[i] = NULL;
173  }
174  }
175 
176  // back to the memory adress
177  // where the samples should be located
178  smpl_list_ptr = smpl_ptr_save;
179 
180  for(i = 0; i < 32; i++)
181  {
182  SoundInfo *sfx;
183 
184  // load each sample
185  if (spl_files[i])
186  {
187  char _file[256];
188  sprintf(_file, "%s%s.pak", asset_path, spl_files[i]);
189  sfx = LoadPackedSound(_file, unpacking_sample_buffer, smpl_list_ptr);
190  smpl_list_ptr += sfx->FileLength;
191  printf("Sample #%d: '%s.pak, %X bytes'.\n", i, spl_files[i], sfx->FileLength);
192  RemoveSoundStruct(sfx);
193  }
194  }
195 
196  protracker_mod_data = unpacked_block;
197  protracker_mod_size = unpacked_block_size;
198  }
199  else
200  {
201  printf(err_no_size_found);
202  }
203  }
204  }
205  }
206  }
207 #endif
208 }
209 
210 void load_packed_protacker_music(char *filename)
211 {
212 #ifdef DEBUG_ENABLE_AUDIO
213  int unpacked_block_size, packed_block_size;
214  BPTR fileHandle;
215  char tag[4];
216  UWORD mod_size;
217  BYTE *packed_block, *unpacked_block;
218 
219  if ((fileHandle = Open(filename, MODE_OLDFILE)))
220  {
221  Read(fileHandle, &tag, 4);
222  if (strncmp(tag, "PTPK", 4) == 0)
223  {
224  // read original module size
225  Read(fileHandle, &unpacked_block_size, 4);
226  unpacked_block = AllocMem(unpacked_block_size, MEMF_CHIP);
227 
228  Read(fileHandle, &tag, 4);
229  if (strncmp(tag, "MINZ", 4) == 0)
230  {
231  Read(fileHandle, &tag, 4);
232  if (strncmp(tag, "SIZE", 4) == 0)
233  {
234  Read(fileHandle, &packed_block_size, 4);
235  packed_block = AllocMem(packed_block_size, 0L);
236  Read(fileHandle, packed_block, packed_block_size);
237 #ifdef DEBUG_MACROS
238  printf("!!!!MINIZ block size: %d\n", packed_block_size);
239 #endif
240  tinfl_decompress_mem_to_mem(unpacked_block, unpacked_block_size, packed_block, packed_block_size, 1);
241  FreeMem(packed_block, packed_block_size);
242  }
243  else
244  printf(err_no_size_found);
245  }
246  else if (strncmp(tag, "SHRK", 4) == 0)
247  {
248  Read(fileHandle, &tag, 4);
249  if (strncmp(tag, "SIZE", 4) == 0)
250  {
251  Read(fileHandle, &packed_block_size, 4);
252  packed_block = AllocMem(packed_block_size, 0L);
253  Read(fileHandle, packed_block, packed_block_size);
254 #ifdef DEBUG_MACROS
255  printf("!!!!SHRK block size: %d\n", packed_block_size);
256 #endif
257  ShrinklerDecompress(packed_block, unpacked_block, NULL, NULL);
258  FreeMem(packed_block, packed_block_size);
259  }
260  else
261  printf(err_no_size_found);
262  }
263  else if (strncmp(tag, "NRV2", 4) == 0)
264  {
265  Read(fileHandle, &tag, 4);
266  if (strncmp(tag, "SIZE", 4) == 0)
267  {
268  Read(fileHandle, &packed_block_size, 4);
269  packed_block = AllocMem(packed_block_size, 0L);
270  Read(fileHandle, packed_block, packed_block_size);
271 #ifdef DEBUG_MACROS
272  printf("!!!!NRV2X block size: %d\n", packed_block_size);
273 #endif
274  nrv2s_unpack(packed_block, unpacked_block);
275  FreeMem(packed_block, packed_block_size);
276  }
277  else
278  printf(err_no_size_found);
279  }
280  else
281  {
282  printf(err_unknown_tag, tag);
283  FreeMem(unpacked_block, unpacked_block_size);
284  unpacked_block = NULL;
285  unpacked_block_size = 0;
286  }
287 
288  }
289  else
290  {
291  printf("!Not a Protracker Packed File!\n");
292  }
293 
294  }
295 
296  protracker_mod_data = unpacked_block;
297  protracker_mod_size = unpacked_block_size;
298 #endif
299 }
300 
301 void unload_protacker_music(void)
302 {
303 #ifdef DEBUG_ENABLE_AUDIO
304  if (protracker_mod_data != NULL && protracker_mod_playing != NULL)
305  {
306  // Stop music
307  PTStop(protracker_mod_playing);
308 
309  // Free signals
310  FreeSignal(protracker_SigBit);
311 
312  // Free allocated memory
313  PTFreeMod(protracker_mod_playing);
314  FreeMem(protracker_mod_data, protracker_mod_size);
315 
316  protracker_mod_playing = NULL;
317  protracker_mod_data = NULL;
318  }
319 #endif
320 }
321 
322 void play_protracker_music(void)
323 {
324 #ifdef DEBUG_ENABLE_AUDIO
325  if (PTReplayBase)
326  if (protracker_mod_data != NULL && protracker_mod_playing == NULL)
327  {
328  if((protracker_SigBit=AllocSignal(-1)) != -1)
329  {
330  protracker_mod_playing = PTSetupMod((APTR)protracker_mod_data);
331  PTInstallBits(protracker_mod_playing, protracker_SigBit, -1, -1, -1);
332  PTSetVolume(protracker_mod_playing, protracker_mod_volume);
333  PTPlay(protracker_mod_playing);
334  }
335  else
336  printf("play_protracker_music() Couldn't allocate signal!\n");
337 
338  }
339  else
340  rpage_system_alert("Ptreplay.library was not open!");
341 #endif
342 }
343 
344 void protracker_update_state(void)
345 {
346 #ifdef DEBUG_ENABLE_AUDIO
347  if (PTReplayBase)
348  {
349  if (protracker_mod_data != NULL)
350  {
351  if (protracker_fade_speed != 0)
352  {
353  protracker_mod_volume = min(protracker_fade_max_volume, max(protracker_fade_min_volume, protracker_mod_volume + protracker_fade_speed));
354  PTSetVolume(protracker_mod_playing, protracker_mod_volume);
355  if (protracker_auto_stop && protracker_mod_volume <= 0)
356  unload_protacker_music();
357  }
358  }
359  }
360 #endif
361 }
362 
363 void protracker_set_fade_speed(short fade_speed)
364 {
365 #ifdef DEBUG_ENABLE_AUDIO
366  protracker_fade_speed = fade_speed;
367 #endif
368 }
369 
370 #endif
#define FALSE
Definition: utils.h:41
const char * err_unknown_tag
Definition: err.c:5
ULONG PTStop(struct Module *)
void rpage_file_close(rpage_file file)
Close a current file.
void PTFreeMod(struct Module *)
const char * err_no_size_found
Definition: err.c:2
int BOOL
Definition: utils.h:32
struct Module * PTSetupMod(APTR)
rpage_file rpage_file_open(char *filename, long mode)
void rpage_system_alert(char *alert_message)
Opens a GURU MEDITATION message.
unsigned char UBYTE
Definition: utils.h:20
void PTInstallBits(struct Module *, BYTE, BYTE, BYTE, BYTE)
VOID PTSetVolume(struct Module *, UBYTE)
unsigned short UWORD
Definition: utils.h:28
#define min(x, y)
Definition: utils.h:45
struct DosLibrary * DOSBase
size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
Definition: tinfl.c:544
#define max(x, y)
Definition: utils.h:49
unsigned char BYTE
Definition: utils.h:16
unsigned long ULONG
Definition: utils.h:24
#define TRUE
Definition: utils.h:37
long rpage_file_write(rpage_file file, void *buffer, long len)
Write a data buffer into the file.
ULONG PTPlay(struct Module *)