summaryrefslogtreecommitdiff
path: root/libf3m/f3m.h
blob: 4ae4e3551db327fe0d2ef5d45c005fff77897a09 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#ifndef _F3M_H
#define _F3M_H

#define F3M_FREQ 44100
#define F3M_BUFLEN 882
#define F3M_CHNS 2

#define F3M_VCHNS 20
#define F3M_PRIO_NORMAL 50
#define F3M_PRIO_MUSIC_OFF 100
#define F3M_PRIO_MUSIC 0x7FFF

typedef struct
{
	uint8_t name[28];
	uint8_t magic[4];
	uint16_t ord_num, ins_num, pat_num;
	uint16_t flags, ver, smptyp;
	uint8_t magic_scrm[4];
	uint8_t gvol, ispeed, itempo, mvol;
	uint8_t uclick, defpanFC;
	uint8_t unused1[8];
	uint16_t special;
	uint8_t cset[32];
	uint8_t extra[];
}__attribute__((__packed__)) mod_s;

typedef struct
{
	uint16_t spu_data;
	uint16_t spu_data_lpbeg;

	int32_t len;
	int32_t len_loop;

	int32_t period;
	int32_t gxx_period;

	int32_t freq;
	int32_t offs;
	uint16_t suboffs;
	int16_t priority;

	int8_t insvol; // assigned on note start
	int8_t midvol; // changed on slides
	int8_t outvol; // actual output	
	uint8_t pan;

	uint8_t vib_offs;
	uint8_t tre_offs;
	uint8_t rtg_count;

	uint8_t eft, efp, lefp, last_note;
	uint8_t lins;
	uint8_t mem_gxx, mem_hxx, mem_oxx;
} vchn_s;

typedef struct
{
	const mod_s *mod;
	const void *modbase;
	const uint16_t *ins_para;
	const uint16_t *pat_para;
	const uint8_t *ord_list;

	int32_t speed, tempo;
	int32_t gvol;
	int32_t ctick, tempo_samples, tempo_wait;
	int32_t cord, cpat, crow;
	const uint8_t *patptr;
	const uint8_t *patptr_next;
	int32_t repeat_row, repeat_count;	

	int sfxoffs;
	int ccount;

	uint16_t psx_spu_offset[99];
	uint16_t psx_spu_offset_lpbeg[99];
	
	uint32_t baseaddr;
	int basevoice;
	int monomode;
	uint16_t maxvolume;

	vchn_s vchn[F3M_VCHNS];
} player_s;

/**
 * Create a module file structure from a data buffer.
 * The data buffer must contain a valid S3M music module file.
 * @param d Pointer to buffer memory
 * @return Module file structure (NULL on error)
 */

mod_s *f3m_mod_load(uint32_t *d);

/**
 * Create a module file structure from a file with the given filename, 
 * The file must be a valid S3M music module file.
 * @param fname Module file filename
 * @return Module file structure (NULL on error)
 */

mod_s *f3m_mod_load_filename(const char *fname);

/**
 * Free the memory associated to a module file structure
 * @param mod Pointer to module file structure
 */

void f3m_mod_free(mod_s *mod);

/**
 * Initialize a music player from a module file structure.
 * This is just like calling f3m_player_init_ex(player, mod, 0, SPU_DATA_BASE_ADDR)
 * @param player Pointer to memory of music player structure
 * @param mod Pointer to module file structure
 * @return Address in SPU memory after uploaded samples
 */

unsigned int f3m_player_init(player_s *player, mod_s *mod);

/**
 * Initialize a music player from a module file structure.
 * @param player Pointer to memory of music player structure
 * @param mod Pointer to module file structure
 * @param basevoice Base voice to use to reproduce samples. Valid range is from 0 to (24 - F3M_VCHNS)
 * @param baseaddr Base address in SPU memory for uploading samples.
 * @return Address in SPU memory after uploaded samples
 */

unsigned int f3m_player_init_ex(player_s *player, mod_s *mod, int basevoice, unsigned int baseaddr);


/**
 * Make a music player play. 
 * This should be called roughly every 1/50th of a second on PAL systems,
 * or every 1/60th of a second on NTSC systems; you can set a flag in a VBlank
 * interrupt handler (see SetVBlankHandler()) to do this.
 * This function is probably not re-entrant, so it is not recommended to call it
 * directly from the VBlank handler.
 * @param player Pointer to music player structure
 */

void f3m_player_play(player_s *player);

/**
 * Stop a music player.
 * @param player Pointer to music player structure
 */

void f3m_player_stop(player_s *player);

/**
 * Set a music player to mono mode. Music players are by default in stereo mode.
 * @param player Pointer to music player structure
 * @param onoff Non-zero for mono mode, zero for stereo mode
 * @return Previous status of mono mode flag.
 */
 
int f3m_set_mono_mode(player_s *player, int onoff);

/**
 * Set maximum volume for a music player. 
 * Default volume for a music player is the maximum allowed by the SPU.
 * @param player Pointer to music player structure
 * @return Previous maximum volume.
 */

uint16_t f3m_set_max_volume(player_s *player, uint16_t maxvolume);

#endif