Enable game sounds in PacBox. Sound is OFF by default but can be enabled from the...
[kugel-rb.git] / apps / plugins / pacbox / wsg3.c
blob3c861312b9b020d3c51f0bc10ae8df7f5feb8962
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Pacbox - a Pacman Emulator for Rockbox
12 * Based on PIE - Pacman Instructional Emulator
14 * Namco custom waveform sound generator 3 (Pacman hardware)
16 * Copyright (c) 2003,2004 Alessandro Scotti
17 * http://www.ascotti.org/
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.
24 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
25 * KIND, either express or implied.
27 ****************************************************************************/
28 #include "plugin.h"
29 #include "wsg3.h"
31 struct wsg3 wsg3;
33 static bool wsg3_get_voice(struct wsg3_voice *voice, int index)
35 int base = 5*index;
36 const unsigned char *regs = wsg3.sound_regs;
37 unsigned x;
39 x = regs[0x15 + base] & 0x0F;
41 if (x == 0)
42 return false;
44 voice->volume = x;
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);
52 if (index == 0)
54 /* The first voice has an extra 4-bit of data */
55 x |= regs[0x10 + base] & 0x0F;
58 if (x == 0)
59 return false;
61 voice->frequency = x;
63 voice->waveform = regs[0x05 + base] & 0x07;
65 return true;
68 void wsg3_play_sound(int * buf, int len)
70 struct wsg3_voice voice;
72 if (wsg3_get_voice(&voice, 0))
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;
80 for (i = 0; i < len; i++)
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;
88 wsg3.wave_offset[0] = offset;
91 if (wsg3_get_voice(&voice, 1))
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;
99 for (i = 0; i < len; i++)
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;
107 wsg3.wave_offset[1] = offset;
110 if (wsg3_get_voice(&voice, 2))
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;
118 for (i = 0; i < len; i++)
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;
126 wsg3.wave_offset[2] = offset;
130 void wsg3_set_sampling_rate(unsigned sampling_rate)
132 wsg3.sampling_rate = sampling_rate;
133 wsg3.resample_step = (wsg3.master_clock << 10) / sampling_rate;
136 void wsg3_set_sound_prom( const unsigned char * prom )
138 int i;
140 for (i = 0; i < 32*8; i++)
141 wsg3.sound_wave_data[i] = (int)*prom++ - 8;
144 void wsg3_init(unsigned master_clock)
146 memset(&wsg3, 0, sizeof (struct wsg3));
147 wsg3.master_clock = master_clock;