Wing Commander II
Reconstructed Win32 source (1996)
Loading...
Searching...
No Matches
speech.c
Go to the documentation of this file.
1/*
2 * Speech packets and speech cache.
3 *
4 * Retail object 0x44F300-0x44FA6F (link order; see docs/ORDER.md).
5 */
6#define SPEECH_C
7#include "game.h"
8
9const int g_nDigiSampleBytes = 0xfffa; /* 0x0048e0e0 */
10const unsigned short g_wDmaHalfBytes = 0x0fa0; /* 0x0048e0e4 */
11
12unsigned short g_wSoundBlasterPort = 0x220; /* 0x0049bb58 */
13unsigned short g_wSoundBlasterIrq = 7; /* 0x0049bb5c */
14unsigned short g_wDigiPlaying = 0; /* 0x0049bb60 */
15unsigned short g_wDmaAddressA = 0; /* 0x0049bb64 */
16unsigned short g_wDmaAddressB = 0; /* 0x0049bb68 */
17unsigned short g_wDmaCountA = 0; /* 0x0049bb6c */
18unsigned short g_wDmaCountB = 0; /* 0x0049bb70 */
19int g_nDmaHalfSelect = 0; /* 0x0049bb74 */
20short g_nDigiLastBlock = 0; /* 0x0049bb78 */
21
22/* Function start: 0x44F300 */
23/* The DOS release wrote the Sound Blaster's I/O ports here; the Win32 port
24 * keeps the entry point and does nothing. */
25void SoundBlasterOut(unsigned short port, unsigned char value)
26{
27 return;
28}
29
30/* Function start: 0x44F310 */
31/* Port read counterpart of SoundBlasterOut; always reads 0. */
32unsigned char SoundBlasterIn(unsigned short port)
33{
34 return 0;
35}
36
37/* Function start: 0x44F322 */
38/* Waited for the DSP's write buffer to empty under DOS; a no-op on Win32. */
40{
41 return;
42}
43
44/* Function start: 0x44F332 */
45void *LoadSpeechPacketIntoBuffer(char *fileName, short section,
46 void *destination)
47{
48 void *packet;
49
50 packet = destination;
51 if (packet == 0) {
52 packet = AllocateTaggedMemory(
53 (unsigned short)g_nDigiSampleBytes, 0x44);
54 }
55 if (packet == 0)
56 return 0;
57 if (LoadPacketIntoBuffer(fileName, section, packet, 1) == 0)
58 return 0;
59 return packet;
60}
61
62#pragma function(memcpy)
63/* Function start: 0x44F3A4 */
64/* Plays a loaded speech packet through the Win32 speech player. The DOS
65 * DMA set-up that followed survives behind the early return, without its
66 * port writes. */
67void PlaySpeechPacketBuffer(void *packet, unsigned short packetSize,
68 int interrupt)
69{
70 void *src;
71
72 PlayRawSpeechBuffer(packet, packetSize, interrupt);
73 return;
74 if (packetSize > (unsigned short)g_nDigiSampleBytes)
75 return;
77 g_wDigiLeft = packetSize;
78 g_4_pDigiData = packet;
82 if (g_wDmaHalfBytes * 2 > g_wDigiLeft) {
85 g_wDmaCountB = 0;
86 } else {
90 }
91 } else {
94 }
95 src = (void *)IdentityDword((DwordPtr)g_4_pDigiData);
96 memcpy(g_4_pDmaBufferPointer, src, g_wDmaHalfBytes * 2);
99 return;
100}
101
102/* Function start: 0x44F52E */
103void LoadAndPlaySpeechPacket(char *fileName, short section)
104{
105 unsigned int packetSize;
106
107 packetSize = GetNamedPacketSize(fileName, section);
109 fileName, section, g_pDigiSample) != 0) {
111 g_pDigiSample, packetSize, 0);
112 }
113}
114
115/* Function start: 0x44F581 */
116/* Nothing in the shipped executable calls this. The DOS end-of-interrupt
117 * for the Sound Blaster IRQ, disabled by the Win32 port: it returns before
118 * restoring the EMS mapping and acknowledging the interrupt controller. */
120{
121 return;
123 if (g_105_nEmsIsrBusyValue == 0)
124 SoundBlasterOut(0x20, 0x20);
125}
126
127/* Function start: 0x44F5B1 */
128/* Marks the digitised sample as finished. */
130{
131 g_wDigiPlaying = 0;
132}
133
134/* Function start: 0x44F5C5 */
135/* Nothing in the shipped executable calls this. The DOS Sound Blaster DMA
136 * interrupt handler, disabled by the Win32 port: it returns before
137 * acknowledging the DSP, programming the other DMA half and refilling the
138 * half just played from the sample. */
140{
141 unsigned char *dmaHalf;
142 unsigned char *src;
143 unsigned char *resolved;
144 unsigned short dmaAddress;
145 unsigned short total;
146 unsigned short *slot;
147 unsigned short offset;
148
149 return;
152 if (g_nDigiLastBlock != 0 || g_wDigiPlaying == 0) {
155 return;
156 }
157 if (g_wDigiLeft == 0)
160 if (g_nDmaHalfSelect == 0) {
162 dmaAddress = g_wDmaAddressB;
163 total = g_wDmaCountB;
164 offset = 0;
165 } else {
167 dmaAddress = g_wDmaAddressA;
168 total = g_wDmaCountA;
169 offset = g_wDmaHalfBytes;
170 }
171 SoundBlasterOut(0x0a, 5);
172 SoundBlasterOut(0x0c, 0);
173 SoundBlasterOut(0x0b, 0x49);
174 SoundBlasterOut(2, (unsigned char)dmaAddress);
175 SoundBlasterOut(2, (unsigned char)(dmaAddress >> 8));
177 SoundBlasterOut(3, (unsigned char)total);
178 SoundBlasterOut(3, (unsigned char)(total >> 8));
179 SoundBlasterOut(0x0a, 1);
184 (unsigned char)(total - 1));
187 (unsigned char)((total - 1) >> 8));
188 resolved = (unsigned char *)IdentityDword((DwordPtr)g_4_pDigiData);
189 src = g_2_wDigiPosition + resolved;
190 dmaHalf = offset + (unsigned char *)g_4_pDmaBufferPointer;
191 if (g_nDmaHalfSelect == 0)
192 slot = &g_wDmaCountB;
193 else
194 slot = &g_wDmaCountA;
195 *slot = g_wDmaHalfBytes < g_wDigiLeft ?
197 g_wDigiLeft -= *slot;
198 g_2_wDigiPosition += *slot;
199 memcpy(dmaHalf, src, *slot);
201 return;
202}
203
204/* Function start: 0x44F84F */
205short InitializeSoundBlaster(short port, short irq)
206{
207 void *cacheMetadata;
208 unsigned int codeAddress;
209 unsigned int dmaEnd;
210 unsigned int codeLimit;
211 unsigned int dataSize;
212 void *oldBuffer;
213 unsigned int dmaAddress;
214
217 0x44);
218 if (g_pDigiSample == 0)
219 return 1;
220 codeAddress = IdentityDword((DwordPtr)g_pDigiSample);
221 codeLimit = (unsigned int)g_pDigiSample +
222 (unsigned short)g_nDigiSampleBytes;
223 if (codeLimit < codeAddress)
226 (unsigned short)(((unsigned short)port << 4) + 0x200);
227 g_wSoundBlasterIrq = (unsigned short)irq;
228 cacheMetadata = AllocateTaggedMemory(0x0c, 0x40);
229 if (cacheMetadata == 0)
230 return 2;
233 (unsigned int)g_wDmaHalfBytes * 2 + 0x0f,
234 0x42);
235 if (g_4_pDmaBufferPointer == 0)
236 return 1;
237 oldBuffer = 0;
238 do {
239 dmaAddress = (unsigned int)g_4_pDmaBufferPointer;
240 dmaEnd = dmaAddress +
241 ((int)((unsigned int)g_wDmaHalfBytes * 2) /
242 16);
243 if ((dmaEnd >> 12) != (dmaAddress >> 12)) {
244 oldBuffer =
248 (unsigned int)g_wDmaHalfBytes * 2 +
249 0x0f,
250 0x42);
251 if (g_4_pDmaBufferPointer == 0)
252 return 1;
253 ReleasePacketHandle(oldBuffer);
254 } else {
255 oldBuffer = 0;
256 }
258 } while (oldBuffer != 0);
259 g_1_ucDmaPageValue = (unsigned char)(dmaAddress >> 12);
260 dmaAddress -= (unsigned int)g_1_ucDmaPageValue << 12;
261 g_wDmaAddressA = (unsigned short)(dmaAddress << 4);
263 (unsigned short)(g_wDmaHalfBytes +
265 return 0;
266}
267
268/* Function start: 0x44FA31 */
275
276/* Linker commons defined here. LINK lays a unit's commons out by the
277 * identifiers' hash keys, so these spellings follow the original addresses. */
278void *g_4_pDmaBufferPointer; /* 0x005d1718 */
279unsigned short g_2_wDigiPosition; /* 0x005d171c */
280void *g_pDigiSample; /* 0x005d1720 */
281unsigned char g_1_ucDmaPageValue; /* 0x005d1724 */
void ShutdownSoundBlaster(void)
Definition speech.c:269
short InitializeSoundBlaster(short port, short irq)
Definition speech.c:205
void SoundBlasterDspInterrupt(void)
Definition speech.c:139
void StopDigiPlayback(void)
Definition speech.c:129
unsigned char SoundBlasterIn(unsigned short port)
Definition speech.c:32
long GetNamedPacketSize(const char *filename, short section)
Definition eventmgr.c:2164
void * LoadSpeechPacketIntoBuffer(char *fileName, short section, void *destination)
Definition speech.c:45
void ReportFatalErrorCode(const char *errorCode)
Definition message.c:29
void SoundBlasterWaitWrite(void)
Definition speech.c:39
unsigned int PumpWindowMessages(int skipMessages)
Definition winmain.c:292
void SoundBlasterOut(unsigned short port, unsigned char value)
Definition speech.c:25
void * AllocateTaggedMemory(unsigned int size, short flags)
Definition memapi.c:92
void LoadAndPlaySpeechPacket(char *fileName, short section)
Definition speech.c:103
void PlayRawSpeechBuffer(void *buffer, size_t size, int interrupt)
Definition sound.c:292
void PlaySpeechPacketBuffer(void *packet, unsigned short packetSize, int interrupt)
Definition speech.c:67
void * LoadPacketIntoBuffer(char *fileName, short section, void *destination, int registerHandle)
Definition disk.c:141
short EmsRestoreMapping(void)
Definition eventmgr.c:1578
void SoundBlasterEndOfInterrupt(void)
Definition speech.c:119
void ReleasePacketHandle(void *handle)
Definition memapi.c:108
short EmsSaveMapping(void)
Definition eventmgr.c:1571
void FreePacketAndClear(void *slot, unsigned short releaseFlags)
Definition disk.c:45
DwordPtr IdentityDword(DwordPtr value)
Definition eventmgr.c:1491
Shared Win32 declarations, types and library interfaces.
unsigned int DwordPtr
Definition game.h:45
void * g_4_pDmaBufferPointer
Definition speech.c:278
unsigned short g_wDmaCountA
Definition speech.c:17
unsigned short g_wDmaAddressB
Definition speech.c:16
const int g_nDigiSampleBytes
Definition speech.c:9
unsigned short g_wDmaAddressA
Definition speech.c:15
unsigned short g_wSoundBlasterIrq
Definition speech.c:13
short g_105_nEmsIsrBusyValue
Definition eventmgr.c:2528
unsigned short g_wSoundBlasterPort
Definition speech.c:12
unsigned short g_wDmaCountB
Definition speech.c:18
int g_nDmaHalfSelect
Definition speech.c:19
unsigned char g_1_ucDmaPageValue
Definition speech.c:281
void * g_pDigiSample
Definition speech.c:280
unsigned short g_wDigiPlaying
Definition speech.c:14
void * g_4_pDigiData
Definition nav.c:1249
const unsigned short g_wDmaHalfBytes
Definition speech.c:10
unsigned short g_2_wDigiPosition
Definition speech.c:279
short g_nDigiLastBlock
Definition speech.c:20
unsigned short g_wDigiLeft
Definition nav.c:1250