summaryrefslogtreecommitdiff
path: root/apps/plugins/pacbox/wsg3.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pacbox/wsg3.c')
-rw-r--r--apps/plugins/pacbox/wsg3.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/apps/plugins/pacbox/wsg3.c b/apps/plugins/pacbox/wsg3.c
new file mode 100644
index 0000000000..3c861312b9
--- /dev/null
+++ b/apps/plugins/pacbox/wsg3.c
@@ -0,0 +1,148 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Pacbox - a Pacman Emulator for Rockbox
11 *
12 * Based on PIE - Pacman Instructional Emulator
13 *
14 * Namco custom waveform sound generator 3 (Pacman hardware)
15 *
16 * Copyright (c) 2003,2004 Alessandro Scotti
17 * http://www.ascotti.org/
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
23 *
24 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
25 * KIND, either express or implied.
26 *
27 ****************************************************************************/
28#include "plugin.h"
29#include "wsg3.h"
30
31struct wsg3 wsg3;
32
33static bool wsg3_get_voice(struct wsg3_voice *voice, int index)
34{
35 int base = 5*index;
36 const unsigned char *regs = wsg3.sound_regs;
37 unsigned x;
38
39 x = regs[0x15 + base] & 0x0F;
40
41 if (x == 0)
42 return false;
43
44 voice->volume = x;
45
46 x = (regs[0x14 + base] & 0x0F);
47 x = (x << 4) | (regs[0x13 + base] & 0x0F);
48 x = (x << 4) | (regs[0x12 + base] & 0x0F);
49 x = (x << 4) | (regs[0x11 + base] & 0x0F);
50 x = (x << 4);
51
52 if (index == 0)
53 {
54 /* The first voice has an extra 4-bit of data */
55 x |= regs[0x10 + base] & 0x0F;
56 }
57
58 if (x == 0)
59 return false;
60
61 voice->frequency = x;
62
63 voice->waveform = regs[0x05 + base] & 0x07;
64
65 return true;
66}
67
68void wsg3_play_sound(int * buf, int len)
69{
70 struct wsg3_voice voice;
71
72 if (wsg3_get_voice(&voice, 0))
73 {
74 unsigned offset = wsg3.wave_offset[0];
75 unsigned step = voice.frequency * wsg3.resample_step;
76 int * wave_data = wsg3.sound_wave_data + 32 * voice.waveform;
77 int volume = voice.volume;
78 int i;
79
80 for (i = 0; i < len; i++)
81 {
82 /* Should be shifted right by 15, but we must also get rid
83 * of the 10 bits used for decimals */
84 buf[i] += wave_data[(offset >> 25) & 0x1F] * volume;
85 offset += step;
86 }
87
88 wsg3.wave_offset[0] = offset;
89 }
90
91 if (wsg3_get_voice(&voice, 1))
92 {
93 unsigned offset = wsg3.wave_offset[1];
94 unsigned step = voice.frequency * wsg3.resample_step;
95 int * wave_data = wsg3.sound_wave_data + 32 * voice.waveform;
96 int volume = voice.volume;
97 int i;
98
99 for (i = 0; i < len; i++)
100 {
101 /* Should be shifted right by 15, but we must also get rid
102 * of the 10 bits used for decimals */
103 buf[i] += wave_data[(offset >> 25) & 0x1F] * volume;
104 offset += step;
105 }
106
107 wsg3.wave_offset[1] = offset;
108 }
109
110 if (wsg3_get_voice(&voice, 2))
111 {
112 unsigned offset = wsg3.wave_offset[2];
113 unsigned step = voice.frequency * wsg3.resample_step;
114 int * wave_data = wsg3.sound_wave_data + 32 * voice.waveform;
115 int volume = voice.volume;
116 int i;
117
118 for (i = 0; i < len; i++)
119 {
120 /* Should be shifted right by 15, but we must also get rid
121 * of the 10 bits used for decimals */
122 buf[i] += wave_data[(offset >> 25) & 0x1F] * volume;
123 offset += step;
124 }
125
126 wsg3.wave_offset[2] = offset;
127 }
128}
129
130void wsg3_set_sampling_rate(unsigned sampling_rate)
131{
132 wsg3.sampling_rate = sampling_rate;
133 wsg3.resample_step = (wsg3.master_clock << 10) / sampling_rate;
134}
135
136void wsg3_set_sound_prom( const unsigned char * prom )
137{
138 int i;
139
140 for (i = 0; i < 32*8; i++)
141 wsg3.sound_wave_data[i] = (int)*prom++ - 8;
142}
143
144void wsg3_init(unsigned master_clock)
145{
146 memset(&wsg3, 0, sizeof (struct wsg3));
147 wsg3.master_clock = master_clock;
148}