summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/duke3d/Game/src
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2017-01-21 15:18:31 -0500
committerFranklin Wei <git@fwei.tk>2017-12-23 21:01:26 -0500
commita855d6202536ff28e5aae4f22a0f31d8f5b325d0 (patch)
tree8c75f224dd64ed360505afa8843d016b0d75000b /apps/plugins/sdl/progs/duke3d/Game/src
parent01c6dcf6c7b9bb1ad2fa0450f99bacc5f3d3e04b (diff)
downloadrockbox-a855d6202536ff28e5aae4f22a0f31d8f5b325d0.tar.gz
rockbox-a855d6202536ff28e5aae4f22a0f31d8f5b325d0.zip
Port of Duke Nukem 3D
This ports Fabien Sanglard's Chocolate Duke to run on a version of SDL for Rockbox. Change-Id: I8f2c4c78af19de10c1633ed7bb7a997b43256dd9
Diffstat (limited to 'apps/plugins/sdl/progs/duke3d/Game/src')
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/DbgHelp.h2437
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/Makefile942
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/Makefile.am14
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/Makefile.in942
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/_functio.h174
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/_rts.h54
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/actors.c7157
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/animlib.c352
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/animlib.h155
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/Makefile546
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/Makefile.am4
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/Makefile.in546
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_al_midi.h174
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_blaster.h133
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_guswave.h164
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_midi.h290
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_multivc.h318
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_pas16.h250
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_sndscap.h136
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/adlibfx.c552
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/adlibfx.h80
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/al_midi.c1510
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/al_midi.h58
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/assert.h49
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/awe32.c540
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/awe32.h58
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/blaster.c2330
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/blaster.h148
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/ctaweapi.h352
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/debugio.c251
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/debugio.h30
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dma.c379
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dma.h83
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dpmi.c250
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dpmi.h86
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dsl.c231
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dsl.h28
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/fx_man.c1058
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/fx_man.h140
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gmtimbre.c290
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gus.c283
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gusmidi.c561
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gusmidi.h59
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/guswave.c1773
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/guswave.h75
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/interrup.h50
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/irq.c325
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/irq.h54
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/leetimbr.c290
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/linklist.h118
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/ll_man.c173
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/ll_man.h76
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/memcheck.h20
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/midi.c2265
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/midi.h98
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mpu401.c451
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mpu401.h61
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/multivoc.c3404
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/multivoc.h130
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/music.c1035
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/music.h99
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix.asm505
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix.c483
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix16.asm524
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mvreverb.asm181
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mvreverb.c312
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/myprint.c310
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/myprint.h43
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/newgf1.h431
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/nodpmi.c166
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/nomusic.c115
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pas16.c1924
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pas16.h81
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pitch.c258
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pitch.h47
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndcards.h55
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndscape.c1661
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndscape.h73
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndsrc.c658
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndsrc.h70
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/standard.h72
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/task_man.c976
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/task_man.h68
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/user.c100
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/user.h38
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/usrhooks.c84
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/usrhooks.h57
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/audiolib/util.h13
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/config.c897
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/config.h46
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/console.c630
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/console.h19
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/control.c930
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/control.h265
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/cvar_defs.c357
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/cvar_defs.h43
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/cvars.c53
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/cvars.h29
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/develop.h65
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/duke3d.h695
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/dukerockbox.h94
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/dukeunix.h100
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/dukewin.h86
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/dummy_audiolib.c215
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/file_lib.h260
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/funct.h593
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/function.h106
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/game.c10966
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/game.h8
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/gamedef.c3316
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/gamedefs.h131
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/global.c931
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/global.h80
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/joystick.h19
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/keyboard.c441
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/keyboard.h224
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/menues.c4707
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/midi/sdl_midi.c191
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/mouse.h51
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/names.h754
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/player.c4462
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/premap.c1728
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/premap.h17
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/rts.c240
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/rts.h84
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/scriplib.c1065
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/scriplib.h373
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/sector.c3249
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/sounddebugdefs.h8
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/soundefs.h1233
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/sounds.c681
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/sounds.h62
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/types.h101
-rw-r--r--apps/plugins/sdl/progs/duke3d/Game/src/util_lib.h77
134 files changed, 84678 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/DbgHelp.h b/apps/plugins/sdl/progs/duke3d/Game/src/DbgHelp.h
new file mode 100644
index 0000000000..8783d39bd0
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/DbgHelp.h
@@ -0,0 +1,2437 @@
1/*++ BUILD Version: 0001 Increment this if a change has global effects
2
3Copyright (c) Microsoft Corporation. All rights reserved.
4
5Module Name:
6
7 dbghelp.h
8
9Abstract:
10
11 This module defines the prototypes and constants required for the image
12 help routines.
13
14 Contains debugging support routines that are redistributable.
15
16Revision History:
17
18--*/
19
20#ifndef _DBGHELP_
21#define _DBGHELP_
22
23#if _MSC_VER > 1020
24#pragma once
25#endif
26
27
28// As a general principal always call the 64 bit version
29// of every API, if a choice exists. The 64 bit version
30// works great on 32 bit platforms, and is forward
31// compatible to 64 bit platforms.
32
33#ifdef _WIN64
34#ifndef _IMAGEHLP64
35#define _IMAGEHLP64
36#endif
37#endif
38
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44#ifdef _IMAGEHLP_SOURCE_
45#define IMAGEAPI __stdcall
46#define DBHLP_DEPRECIATED
47#else
48#define IMAGEAPI DECLSPEC_IMPORT __stdcall
49#define DBHLP_DEPRECIATED DECLSPEC_DEPRECATED
50#endif
51#define DBHLPAPI IMAGEAPI
52
53#define IMAGE_SEPARATION (64*1024)
54
55typedef struct _LOADED_IMAGE {
56 PSTR ModuleName;
57 HANDLE hFile;
58 PUCHAR MappedAddress;
59#ifdef _IMAGEHLP64
60 PIMAGE_NT_HEADERS64 FileHeader;
61#else
62 PIMAGE_NT_HEADERS32 FileHeader;
63#endif
64 PIMAGE_SECTION_HEADER LastRvaSection;
65 Uint32_t NumberOfSections;
66 PIMAGE_SECTION_HEADER Sections;
67 Uint32_t Characteristics;
68 BOOLEAN fSystemImage;
69 BOOLEAN fDOSImage;
70 LIST_ENTRY Links;
71 Uint32_t SizeOfImage;
72} LOADED_IMAGE, *PLOADED_IMAGE;
73
74
75
76HANDLE
77IMAGEAPI
78FindDebugInfoFile (
79 PSTR FileName,
80 PSTR SymbolPath,
81 PSTR DebugFilePath
82 );
83
84typedef BOOL
85(CALLBACK *PFIND_DEBUG_FILE_CALLBACK)(
86 HANDLE FileHandle,
87 PSTR FileName,
88 PVOID CallerData
89 );
90
91HANDLE
92IMAGEAPI
93FindDebugInfoFileEx (
94 PSTR FileName,
95 PSTR SymbolPath,
96 PSTR DebugFilePath,
97 PFIND_DEBUG_FILE_CALLBACK Callback,
98 PVOID CallerData
99 );
100
101typedef BOOL
102(CALLBACK *PFINDFILEINPATHCALLBACK)(
103 PSTR filename,
104 PVOID context
105 );
106
107BOOL
108IMAGEAPI
109SymFindFileInPath(
110 HANDLE hprocess,
111 LPSTR SearchPath,
112 LPSTR FileName,
113 PVOID id,
114 DWORD two,
115 DWORD three,
116 DWORD flags,
117 LPSTR FilePath,
118 PFINDFILEINPATHCALLBACK callback,
119 PVOID context
120 );
121
122HANDLE
123IMAGEAPI
124FindExecutableImage(
125 PSTR FileName,
126 PSTR SymbolPath,
127 PSTR ImageFilePath
128 );
129
130typedef BOOL
131(CALLBACK *PFIND_EXE_FILE_CALLBACK)(
132 HANDLE FileHandle,
133 PSTR FileName,
134 PVOID CallerData
135 );
136
137HANDLE
138IMAGEAPI
139FindExecutableImageEx(
140 PSTR FileName,
141 PSTR SymbolPath,
142 PSTR ImageFilePath,
143 PFIND_EXE_FILE_CALLBACK Callback,
144 PVOID CallerData
145 );
146
147PIMAGE_NT_HEADERS
148IMAGEAPI
149ImageNtHeader (
150 IN PVOID Base
151 );
152
153PVOID
154IMAGEAPI
155ImageDirectoryEntryToDataEx (
156 IN PVOID Base,
157 IN BOOLEAN MappedAsImage,
158 IN USHORT DirectoryEntry,
159 OUT PUint32_t Size,
160 OUT PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL
161 );
162
163PVOID
164IMAGEAPI
165ImageDirectoryEntryToData (
166 IN PVOID Base,
167 IN BOOLEAN MappedAsImage,
168 IN USHORT DirectoryEntry,
169 OUT PUint32_t Size
170 );
171
172PIMAGE_SECTION_HEADER
173IMAGEAPI
174ImageRvaToSection(
175 IN PIMAGE_NT_HEADERS NtHeaders,
176 IN PVOID Base,
177 IN Uint32_t Rva
178 );
179
180PVOID
181IMAGEAPI
182ImageRvaToVa(
183 IN PIMAGE_NT_HEADERS NtHeaders,
184 IN PVOID Base,
185 IN Uint32_t Rva,
186 IN OUT PIMAGE_SECTION_HEADER *LastRvaSection
187 );
188
189// Symbol server exports
190
191typedef BOOL (*PSYMBOLSERVERPROC)(LPCSTR, LPCSTR, PVOID, DWORD, DWORD, LPSTR);
192typedef BOOL (*PSYMBOLSERVEROPENPROC)(VOID);
193typedef BOOL (*PSYMBOLSERVERCLOSEPROC)(VOID);
194typedef BOOL (*PSYMBOLSERVERSETOPTIONSPROC)(UINT_PTR, ULONG64);
195typedef BOOL (CALLBACK *PSYMBOLSERVERCALLBACKPROC)(UINT_PTR action, ULONG64 data, ULONG64 context);
196typedef UINT_PTR (*PSYMBOLSERVERGETOPTIONSPROC)();
197
198#define SSRVOPT_CALLBACK 0x01
199#define SSRVOPT_DWORD 0x02
200#define SSRVOPT_DWORDPTR 0x04
201#define SSRVOPT_GUIDPTR 0x08
202#define SSRVOPT_OLDGUIDPTR 0x10
203#define SSRVOPT_UNATTENDED 0x20
204#define SSRVOPT_RESET ((ULONG_PTR)-1)
205
206#define SSRVACTION_TRACE 1
207
208
209#ifndef _WIN64
210// This api won't be ported to Win64 - Fix your code.
211
212typedef struct _IMAGE_DEBUG_INFORMATION {
213 LIST_ENTRY List;
214 DWORD ReservedSize;
215 PVOID ReservedMappedBase;
216 USHORT ReservedMachine;
217 USHORT ReservedCharacteristics;
218 DWORD ReservedCheckSum;
219 DWORD ImageBase;
220 DWORD SizeOfImage;
221
222 DWORD ReservedNumberOfSections;
223 PIMAGE_SECTION_HEADER ReservedSections;
224
225 DWORD ReservedExportedNamesSize;
226 PSTR ReservedExportedNames;
227
228 DWORD ReservedNumberOfFunctionTableEntries;
229 PIMAGE_FUNCTION_ENTRY ReservedFunctionTableEntries;
230 DWORD ReservedLowestFunctionStartingAddress;
231 DWORD ReservedHighestFunctionEndingAddress;
232
233 DWORD ReservedNumberOfFpoTableEntries;
234 PFPO_DATA ReservedFpoTableEntries;
235
236 DWORD SizeOfCoffSymbols;
237 PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols;
238
239 DWORD ReservedSizeOfCodeViewSymbols;
240 PVOID ReservedCodeViewSymbols;
241
242 PSTR ImageFilePath;
243 PSTR ImageFileName;
244 PSTR ReservedDebugFilePath;
245
246 DWORD ReservedTimeDateStamp;
247
248 BOOL ReservedRomImage;
249 PIMAGE_DEBUG_DIRECTORY ReservedDebugDirectory;
250 DWORD ReservedNumberOfDebugDirectories;
251
252 DWORD ReservedOriginalFunctionTableBaseAddress;
253
254 DWORD Reserved[ 2 ];
255
256} IMAGE_DEBUG_INFORMATION, *PIMAGE_DEBUG_INFORMATION;
257
258
259PIMAGE_DEBUG_INFORMATION
260IMAGEAPI
261MapDebugInformation(
262 HANDLE FileHandle,
263 PSTR FileName,
264 PSTR SymbolPath,
265 DWORD ImageBase
266 );
267
268BOOL
269IMAGEAPI
270UnmapDebugInformation(
271 PIMAGE_DEBUG_INFORMATION DebugInfo
272 );
273
274#endif
275
276BOOL
277IMAGEAPI
278SearchTreeForFile(
279 PSTR RootPath,
280 PSTR InputPathName,
281 PSTR OutputPathBuffer
282 );
283
284BOOL
285IMAGEAPI
286MakeSureDirectoryPathExists(
287 PCSTR DirPath
288 );
289
290//
291// UnDecorateSymbolName Flags
292//
293
294#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration
295#define UNDNAME_NO_LEADING_UNDERSCORES (0x0001) // Remove leading underscores from MS extended keywords
296#define UNDNAME_NO_MS_KEYWORDS (0x0002) // Disable expansion of MS extended keywords
297#define UNDNAME_NO_FUNCTION_RETURNS (0x0004) // Disable expansion of return type for primary declaration
298#define UNDNAME_NO_ALLOCATION_MODEL (0x0008) // Disable expansion of the declaration model
299#define UNDNAME_NO_ALLOCATION_LANGUAGE (0x0010) // Disable expansion of the declaration language specifier
300#define UNDNAME_NO_MS_THISTYPE (0x0020) // NYI Disable expansion of MS keywords on the 'this' type for primary declaration
301#define UNDNAME_NO_CV_THISTYPE (0x0040) // NYI Disable expansion of CV modifiers on the 'this' type for primary declaration
302#define UNDNAME_NO_THISTYPE (0x0060) // Disable all modifiers on the 'this' type
303#define UNDNAME_NO_ACCESS_SPECIFIERS (0x0080) // Disable expansion of access specifiers for members
304#define UNDNAME_NO_THROW_SIGNATURES (0x0100) // Disable expansion of 'throw-signatures' for functions and pointers to functions
305#define UNDNAME_NO_MEMBER_TYPE (0x0200) // Disable expansion of 'static' or 'virtual'ness of members
306#define UNDNAME_NO_RETURN_UDT_MODEL (0x0400) // Disable expansion of MS model for UDT returns
307#define UNDNAME_32_BIT_DECODE (0x0800) // Undecorate 32-bit decorated names
308#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration;
309 // return just [scope::]name. Does expand template params
310#define UNDNAME_NO_ARGUMENTS (0x2000) // Don't undecorate arguments to function
311#define UNDNAME_NO_SPECIAL_SYMS (0x4000) // Don't undecorate special names (v-table, vcall, vector xxx, metatype, etc)
312
313DWORD
314IMAGEAPI
315WINAPI
316UnDecorateSymbolName(
317 PCSTR DecoratedName, // Name to undecorate
318 PSTR UnDecoratedName, // If NULL, it will be allocated
319 DWORD UndecoratedLength, // The maximym length
320 DWORD Flags // See above.
321 );
322
323
324//
325// these values are used for synthesized file types
326// that can be passed in as image headers instead of
327// the standard ones from ntimage.h
328//
329
330#define DBHHEADER_DEBUGDIRS 0x1
331
332typedef struct _DBGHELP_MODLOAD_DATA {
333 DWORD ssize; // size of this struct
334 DWORD ssig; // signature identifying the passed data
335 PVOID data; // pointer to passed data
336 DWORD size; // size of passed data
337 DWORD flags; // options
338} MODLOAD_DATA, *PMODLOAD_DATA;
339
340//
341// StackWalking API
342//
343
344typedef enum {
345 AddrMode1616,
346 AddrMode1632,
347 AddrModeReal,
348 AddrModeFlat
349} ADDRESS_MODE;
350
351typedef struct _tagADDRESS64 {
352 DWORD64 Offset;
353 WORD Segment;
354 ADDRESS_MODE Mode;
355} ADDRESS64, *LPADDRESS64;
356
357#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
358#define ADDRESS ADDRESS64
359#define LPADDRESS LPADDRESS64
360#else
361typedef struct _tagADDRESS {
362 DWORD Offset;
363 WORD Segment;
364 ADDRESS_MODE Mode;
365} ADDRESS, *LPADDRESS;
366
367__inline
368void
369Address32To64(
370 LPADDRESS a32,
371 LPADDRESS64 a64
372 )
373{
374 a64->Offset = (ULONG64)(LONG64)(int32_t)a32->Offset;
375 a64->Segment = a32->Segment;
376 a64->Mode = a32->Mode;
377}
378
379__inline
380void
381Address64To32(
382 LPADDRESS64 a64,
383 LPADDRESS a32
384 )
385{
386 a32->Offset = (ULONG)a64->Offset;
387 a32->Segment = a64->Segment;
388 a32->Mode = a64->Mode;
389}
390#endif
391
392//
393// This structure is included in the STACKFRAME structure,
394// and is used to trace through usermode callbacks in a thread's
395// kernel stack. The values must be copied by the kernel debugger
396// from the DBGKD_GET_VERSION and WAIT_STATE_CHANGE packets.
397//
398
399//
400// New KDHELP structure for 64 bit system support.
401// This structure is preferred in new code.
402//
403typedef struct _KDHELP64 {
404
405 //
406 // address of kernel thread object, as provided in the
407 // WAIT_STATE_CHANGE packet.
408 //
409 DWORD64 Thread;
410
411 //
412 // offset in thread object to pointer to the current callback frame
413 // in kernel stack.
414 //
415 DWORD ThCallbackStack;
416
417 //
418 // offset in thread object to pointer to the current callback backing
419 // store frame in kernel stack.
420 //
421 DWORD ThCallbackBStore;
422
423 //
424 // offsets to values in frame:
425 //
426 // address of next callback frame
427 DWORD NextCallback;
428
429 // address of saved frame pointer (if applicable)
430 DWORD FramePointer;
431
432
433 //
434 // Address of the kernel function that calls out to user mode
435 //
436 DWORD64 KiCallUserMode;
437
438 //
439 // Address of the user mode dispatcher function
440 //
441 DWORD64 KeUserCallbackDispatcher;
442
443 //
444 // Lowest kernel mode address
445 //
446 DWORD64 SystemRangeStart;
447
448 DWORD64 Reserved[8];
449
450} KDHELP64, *PKDHELP64;
451
452#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
453#define KDHELP KDHELP64
454#define PKDHELP PKDHELP64
455#else
456typedef struct _KDHELP {
457
458 //
459 // address of kernel thread object, as provided in the
460 // WAIT_STATE_CHANGE packet.
461 //
462 DWORD Thread;
463
464 //
465 // offset in thread object to pointer to the current callback frame
466 // in kernel stack.
467 //
468 DWORD ThCallbackStack;
469
470 //
471 // offsets to values in frame:
472 //
473 // address of next callback frame
474 DWORD NextCallback;
475
476 // address of saved frame pointer (if applicable)
477 DWORD FramePointer;
478
479 //
480 // Address of the kernel function that calls out to user mode
481 //
482 DWORD KiCallUserMode;
483
484 //
485 // Address of the user mode dispatcher function
486 //
487 DWORD KeUserCallbackDispatcher;
488
489 //
490 // Lowest kernel mode address
491 //
492 DWORD SystemRangeStart;
493
494 //
495 // offset in thread object to pointer to the current callback backing
496 // store frame in kernel stack.
497 //
498 DWORD ThCallbackBStore;
499
500 DWORD Reserved[8];
501
502} KDHELP, *PKDHELP;
503
504__inline
505void
506KdHelp32To64(
507 PKDHELP p32,
508 PKDHELP64 p64
509 )
510{
511 p64->Thread = p32->Thread;
512 p64->ThCallbackStack = p32->ThCallbackStack;
513 p64->NextCallback = p32->NextCallback;
514 p64->FramePointer = p32->FramePointer;
515 p64->KiCallUserMode = p32->KiCallUserMode;
516 p64->KeUserCallbackDispatcher = p32->KeUserCallbackDispatcher;
517 p64->SystemRangeStart = p32->SystemRangeStart;
518}
519#endif
520
521typedef struct _tagSTACKFRAME64 {
522 ADDRESS64 AddrPC; // program counter
523 ADDRESS64 AddrReturn; // return address
524 ADDRESS64 AddrFrame; // frame pointer
525 ADDRESS64 AddrStack; // stack pointer
526 ADDRESS64 AddrBStore; // backing store pointer
527 PVOID FuncTableEntry; // pointer to pdata/fpo or NULL
528 DWORD64 Params[4]; // possible arguments to the function
529 BOOL Far; // WOW far call
530 BOOL Virtual; // is this a virtual frame?
531 DWORD64 Reserved[3];
532 KDHELP64 KdHelp;
533} STACKFRAME64, *LPSTACKFRAME64;
534
535#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
536#define STACKFRAME STACKFRAME64
537#define LPSTACKFRAME LPSTACKFRAME64
538#else
539typedef struct _tagSTACKFRAME {
540 ADDRESS AddrPC; // program counter
541 ADDRESS AddrReturn; // return address
542 ADDRESS AddrFrame; // frame pointer
543 ADDRESS AddrStack; // stack pointer
544 PVOID FuncTableEntry; // pointer to pdata/fpo or NULL
545 DWORD Params[4]; // possible arguments to the function
546 BOOL Far; // WOW far call
547 BOOL Virtual; // is this a virtual frame?
548 DWORD Reserved[3];
549 KDHELP KdHelp;
550 ADDRESS AddrBStore; // backing store pointer
551} STACKFRAME, *LPSTACKFRAME;
552#endif
553
554
555typedef
556BOOL
557(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(
558 HANDLE hProcess,
559 DWORD64 qwBaseAddress,
560 PVOID lpBuffer,
561 DWORD nSize,
562 LPDWORD lpNumberOfBytesRead
563 );
564
565typedef
566PVOID
567(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)(
568 HANDLE hProcess,
569 DWORD64 AddrBase
570 );
571
572typedef
573DWORD64
574(__stdcall *PGET_MODULE_BASE_ROUTINE64)(
575 HANDLE hProcess,
576 DWORD64 Address
577 );
578
579typedef
580DWORD64
581(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(
582 HANDLE hProcess,
583 HANDLE hThread,
584 LPADDRESS64 lpaddr
585 );
586
587BOOL
588IMAGEAPI
589StackWalk64(
590 DWORD MachineType,
591 HANDLE hProcess,
592 HANDLE hThread,
593 LPSTACKFRAME64 StackFrame,
594 PVOID ContextRecord,
595 PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
596 PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
597 PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
598 PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
599 );
600
601#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
602
603#define PREAD_PROCESS_MEMORY_ROUTINE PREAD_PROCESS_MEMORY_ROUTINE64
604#define PFUNCTION_TABLE_ACCESS_ROUTINE PFUNCTION_TABLE_ACCESS_ROUTINE64
605#define PGET_MODULE_BASE_ROUTINE PGET_MODULE_BASE_ROUTINE64
606#define PTRANSLATE_ADDRESS_ROUTINE PTRANSLATE_ADDRESS_ROUTINE64
607
608#define StackWalk StackWalk64
609
610#else
611
612typedef
613BOOL
614(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE)(
615 HANDLE hProcess,
616 DWORD lpBaseAddress,
617 PVOID lpBuffer,
618 DWORD nSize,
619 PDWORD lpNumberOfBytesRead
620 );
621
622typedef
623PVOID
624(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE)(
625 HANDLE hProcess,
626 DWORD AddrBase
627 );
628
629typedef
630DWORD
631(__stdcall *PGET_MODULE_BASE_ROUTINE)(
632 HANDLE hProcess,
633 DWORD Address
634 );
635
636typedef
637DWORD
638(__stdcall *PTRANSLATE_ADDRESS_ROUTINE)(
639 HANDLE hProcess,
640 HANDLE hThread,
641 LPADDRESS lpaddr
642 );
643
644BOOL
645IMAGEAPI
646StackWalk(
647 DWORD MachineType,
648 HANDLE hProcess,
649 HANDLE hThread,
650 LPSTACKFRAME StackFrame,
651 PVOID ContextRecord,
652 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
653 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
654 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
655 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
656 );
657
658#endif
659
660
661#define API_VERSION_NUMBER 9
662
663typedef struct API_VERSION {
664 USHORT MajorVersion;
665 USHORT MinorVersion;
666 USHORT Revision;
667 USHORT Reserved;
668} API_VERSION, *LPAPI_VERSION;
669
670LPAPI_VERSION
671IMAGEAPI
672ImagehlpApiVersion(
673 VOID
674 );
675
676LPAPI_VERSION
677IMAGEAPI
678ImagehlpApiVersionEx(
679 LPAPI_VERSION AppVersion
680 );
681
682DWORD
683IMAGEAPI
684GetTimestampForLoadedLibrary(
685 HMODULE Module
686 );
687
688//
689// typedefs for function pointers
690//
691typedef BOOL
692(CALLBACK *PSYM_ENUMMODULES_CALLBACK64)(
693 PSTR ModuleName,
694 DWORD64 BaseOfDll,
695 PVOID UserContext
696 );
697
698typedef BOOL
699(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64)(
700 PSTR SymbolName,
701 DWORD64 SymbolAddress,
702 Uint32_t SymbolSize,
703 PVOID UserContext
704 );
705
706typedef BOOL
707(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64W)(
708 PWSTR SymbolName,
709 DWORD64 SymbolAddress,
710 Uint32_t SymbolSize,
711 PVOID UserContext
712 );
713
714typedef BOOL
715(CALLBACK *PENUMLOADED_MODULES_CALLBACK64)(
716 PSTR ModuleName,
717 DWORD64 ModuleBase,
718 Uint32_t ModuleSize,
719 PVOID UserContext
720 );
721
722typedef BOOL
723(CALLBACK *PSYMBOL_REGISTERED_CALLBACK64)(
724 HANDLE hProcess,
725 Uint32_t ActionCode,
726 ULONG64 CallbackData,
727 ULONG64 UserContext
728 );
729
730typedef
731PVOID
732(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK)(
733 HANDLE hProcess,
734 DWORD AddrBase,
735 PVOID UserContext
736 );
737
738typedef
739PVOID
740(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK64)(
741 HANDLE hProcess,
742 ULONG64 AddrBase,
743 ULONG64 UserContext
744 );
745
746#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
747
748#define PSYM_ENUMMODULES_CALLBACK PSYM_ENUMMODULES_CALLBACK64
749#define PSYM_ENUMSYMBOLS_CALLBACK PSYM_ENUMSYMBOLS_CALLBACK64
750#define PSYM_ENUMSYMBOLS_CALLBACKW PSYM_ENUMSYMBOLS_CALLBACK64W
751#define PENUMLOADED_MODULES_CALLBACK PENUMLOADED_MODULES_CALLBACK64
752#define PSYMBOL_REGISTERED_CALLBACK PSYMBOL_REGISTERED_CALLBACK64
753#define PSYMBOL_FUNCENTRY_CALLBACK PSYMBOL_FUNCENTRY_CALLBACK64
754
755#else
756
757typedef BOOL
758(CALLBACK *PSYM_ENUMMODULES_CALLBACK)(
759 PSTR ModuleName,
760 Uint32_t BaseOfDll,
761 PVOID UserContext
762 );
763
764typedef BOOL
765(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK)(
766 PSTR SymbolName,
767 Uint32_t SymbolAddress,
768 Uint32_t SymbolSize,
769 PVOID UserContext
770 );
771
772typedef BOOL
773(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACKW)(
774 PWSTR SymbolName,
775 Uint32_t SymbolAddress,
776 Uint32_t SymbolSize,
777 PVOID UserContext
778 );
779
780typedef BOOL
781(CALLBACK *PENUMLOADED_MODULES_CALLBACK)(
782 PSTR ModuleName,
783 Uint32_t ModuleBase,
784 Uint32_t ModuleSize,
785 PVOID UserContext
786 );
787
788typedef BOOL
789(CALLBACK *PSYMBOL_REGISTERED_CALLBACK)(
790 HANDLE hProcess,
791 Uint32_t ActionCode,
792 PVOID CallbackData,
793 PVOID UserContext
794 );
795
796#endif
797
798
799//
800// symbol flags
801//
802
803#define SYMF_OMAP_GENERATED 0x00000001
804#define SYMF_OMAP_MODIFIED 0x00000002
805#ifndef _DBGHELP_USER_GENERATED_SYMBOLS_NOTSUPPORTED
806 #define SYMF_USER_GENERATED 0x00000004
807#endif // !_DBGHELP_USER_GENERATED_SYMBOLS_NOTSUPPORTED
808#define SYMF_REGISTER 0x00000008
809#define SYMF_REGREL 0x00000010
810#define SYMF_FRAMEREL 0x00000020
811#define SYMF_PARAMETER 0x00000040
812#define SYMF_LOCAL 0x00000080
813#define SYMF_CONSTANT 0x00000100
814#define SYMF_EXPORT 0x00000200
815#define SYMF_FORWARDER 0x00000400
816#define SYMF_FUNCTION 0x00000800
817//
818// symbol type enumeration
819//
820typedef enum {
821 SymNone = 0,
822 SymCoff,
823 SymCv,
824 SymPdb,
825 SymExport,
826 SymDeferred,
827 SymSym, // .sym file
828 SymDia,
829 NumSymTypes
830} SYM_TYPE;
831
832//
833// symbol data structure
834//
835
836typedef struct _IMAGEHLP_SYMBOL64 {
837 DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64)
838 DWORD64 Address; // virtual address including dll base address
839 DWORD Size; // estimated size of symbol, can be zero
840 DWORD Flags; // info about the symbols, see the SYMF defines
841 DWORD MaxNameLength; // maximum size of symbol name in 'Name'
842 CHAR Name[1]; // symbol name (null terminated string)
843} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
844
845#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
846#define IMAGEHLP_SYMBOL IMAGEHLP_SYMBOL64
847#define PIMAGEHLP_SYMBOL PIMAGEHLP_SYMBOL64
848#else
849typedef struct _IMAGEHLP_SYMBOL {
850 DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL)
851 DWORD Address; // virtual address including dll base address
852 DWORD Size; // estimated size of symbol, can be zero
853 DWORD Flags; // info about the symbols, see the SYMF defines
854 DWORD MaxNameLength; // maximum size of symbol name in 'Name'
855 CHAR Name[1]; // symbol name (null terminated string)
856} IMAGEHLP_SYMBOL, *PIMAGEHLP_SYMBOL;
857#endif
858
859//
860// module data structure
861//
862
863typedef struct _IMAGEHLP_MODULE64 {
864 DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
865 DWORD64 BaseOfImage; // base load address of module
866 DWORD ImageSize; // virtual size of the loaded module
867 DWORD TimeDateStamp; // date/time stamp from pe header
868 DWORD CheckSum; // checksum from the pe header
869 DWORD NumSyms; // number of symbols in the symbol table
870 SYM_TYPE SymType; // type of symbols loaded
871 CHAR ModuleName[32]; // module name
872 CHAR ImageName[256]; // image name
873 CHAR LoadedImageName[256]; // symbol file name
874} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64;
875
876typedef struct _IMAGEHLP_MODULE64W {
877 DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64)
878 DWORD64 BaseOfImage; // base load address of module
879 DWORD ImageSize; // virtual size of the loaded module
880 DWORD TimeDateStamp; // date/time stamp from pe header
881 DWORD CheckSum; // checksum from the pe header
882 DWORD NumSyms; // number of symbols in the symbol table
883 SYM_TYPE SymType; // type of symbols loaded
884 WCHAR ModuleName[32]; // module name
885 WCHAR ImageName[256]; // image name
886 WCHAR LoadedImageName[256]; // symbol file name
887} IMAGEHLP_MODULEW64, *PIMAGEHLP_MODULEW64;
888
889#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
890#define IMAGEHLP_MODULE IMAGEHLP_MODULE64
891#define PIMAGEHLP_MODULE PIMAGEHLP_MODULE64
892#define IMAGEHLP_MODULEW IMAGEHLP_MODULEW64
893#define PIMAGEHLP_MODULEW PIMAGEHLP_MODULEW64
894#else
895typedef struct _IMAGEHLP_MODULE {
896 DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE)
897 DWORD BaseOfImage; // base load address of module
898 DWORD ImageSize; // virtual size of the loaded module
899 DWORD TimeDateStamp; // date/time stamp from pe header
900 DWORD CheckSum; // checksum from the pe header
901 DWORD NumSyms; // number of symbols in the symbol table
902 SYM_TYPE SymType; // type of symbols loaded
903 CHAR ModuleName[32]; // module name
904 CHAR ImageName[256]; // image name
905 CHAR LoadedImageName[256]; // symbol file name
906} IMAGEHLP_MODULE, *PIMAGEHLP_MODULE;
907
908typedef struct _IMAGEHLP_MODULEW {
909 DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE)
910 DWORD BaseOfImage; // base load address of module
911 DWORD ImageSize; // virtual size of the loaded module
912 DWORD TimeDateStamp; // date/time stamp from pe header
913 DWORD CheckSum; // checksum from the pe header
914 DWORD NumSyms; // number of symbols in the symbol table
915 SYM_TYPE SymType; // type of symbols loaded
916 WCHAR ModuleName[32]; // module name
917 WCHAR ImageName[256]; // image name
918 WCHAR LoadedImageName[256]; // symbol file name
919} IMAGEHLP_MODULEW, *PIMAGEHLP_MODULEW;
920#endif
921
922//
923// source file line data structure
924//
925
926typedef struct _IMAGEHLP_LINE64 {
927 DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64)
928 PVOID Key; // internal
929 DWORD LineNumber; // line number in file
930 PCHAR FileName; // full filename
931 DWORD64 Address; // first instruction of line
932} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
933
934#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
935#define IMAGEHLP_LINE IMAGEHLP_LINE64
936#define PIMAGEHLP_LINE PIMAGEHLP_LINE64
937#else
938typedef struct _IMAGEHLP_LINE {
939 DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE)
940 PVOID Key; // internal
941 DWORD LineNumber; // line number in file
942 PCHAR FileName; // full filename
943 DWORD Address; // first instruction of line
944} IMAGEHLP_LINE, *PIMAGEHLP_LINE;
945#endif
946
947//
948// source file structure
949//
950
951typedef struct _SOURCEFILE {
952 DWORD64 ModBase; // base address of loaded module
953 PCHAR FileName; // full filename of source
954} SOURCEFILE, *PSOURCEFILE;
955
956//
957// data structures used for registered symbol callbacks
958//
959
960#define CBA_DEFERRED_SYMBOL_LOAD_START 0x00000001
961#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE 0x00000002
962#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE 0x00000003
963#define CBA_SYMBOLS_UNLOADED 0x00000004
964#define CBA_DUPLICATE_SYMBOL 0x00000005
965#define CBA_READ_MEMORY 0x00000006
966#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL 0x00000007
967#define CBA_SET_OPTIONS 0x00000008
968#define CBA_EVENT 0x00000010
969#define CBA_DEBUG_INFO 0x10000000
970
971typedef struct _IMAGEHLP_CBA_READ_MEMORY {
972 DWORD64 addr; // address to read from
973 PVOID buf; // buffer to read to
974 DWORD bytes; // amount of bytes to read
975 DWORD *bytesread; // pointer to store amount of bytes read
976} IMAGEHLP_CBA_READ_MEMORY, *PIMAGEHLP_CBA_READ_MEMORY;
977
978enum {
979 sevInfo = 0,
980 sevProblem,
981 sevAttn,
982 sevFatal,
983 sevMax // unused
984};
985
986typedef struct _IMAGEHLP_CBA_EVENT {
987 DWORD severity; // values from sevInfo to sevFatal
988 DWORD code; // numerical code IDs the error
989 PCHAR desc; // may contain a text description of the error
990 PVOID object; // value dependant upon the error code
991} IMAGEHLP_CBA_EVENT, *PIMAGEHLP_CBA_EVENT;
992
993typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 {
994 DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64)
995 DWORD64 BaseOfImage; // base load address of module
996 DWORD CheckSum; // checksum from the pe header
997 DWORD TimeDateStamp; // date/time stamp from pe header
998 CHAR FileName[MAX_PATH]; // symbols file or image name
999 BOOLEAN Reparse; // load failure reparse
1000} IMAGEHLP_DEFERRED_SYMBOL_LOAD64, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD64;
1001
1002#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1003#define IMAGEHLP_DEFERRED_SYMBOL_LOAD IMAGEHLP_DEFERRED_SYMBOL_LOAD64
1004#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD PIMAGEHLP_DEFERRED_SYMBOL_LOAD64
1005#else
1006typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD {
1007 DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD)
1008 DWORD BaseOfImage; // base load address of module
1009 DWORD CheckSum; // checksum from the pe header
1010 DWORD TimeDateStamp; // date/time stamp from pe header
1011 CHAR FileName[MAX_PATH]; // symbols file or image name
1012 BOOLEAN Reparse; // load failure reparse
1013} IMAGEHLP_DEFERRED_SYMBOL_LOAD, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD;
1014#endif
1015
1016typedef struct _IMAGEHLP_DUPLICATE_SYMBOL64 {
1017 DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL64)
1018 DWORD NumberOfDups; // number of duplicates in the Symbol array
1019 PIMAGEHLP_SYMBOL64 Symbol; // array of duplicate symbols
1020 DWORD SelectedSymbol; // symbol selected (-1 to start)
1021} IMAGEHLP_DUPLICATE_SYMBOL64, *PIMAGEHLP_DUPLICATE_SYMBOL64;
1022
1023#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1024#define IMAGEHLP_DUPLICATE_SYMBOL IMAGEHLP_DUPLICATE_SYMBOL64
1025#define PIMAGEHLP_DUPLICATE_SYMBOL PIMAGEHLP_DUPLICATE_SYMBOL64
1026#else
1027typedef struct _IMAGEHLP_DUPLICATE_SYMBOL {
1028 DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL)
1029 DWORD NumberOfDups; // number of duplicates in the Symbol array
1030 PIMAGEHLP_SYMBOL Symbol; // array of duplicate symbols
1031 DWORD SelectedSymbol; // symbol selected (-1 to start)
1032} IMAGEHLP_DUPLICATE_SYMBOL, *PIMAGEHLP_DUPLICATE_SYMBOL;
1033#endif
1034
1035
1036//
1037// options that are set/returned by SymSetOptions() & SymGetOptions()
1038// these are used as a mask
1039//
1040#define SYMOPT_CASE_INSENSITIVE 0x00000001
1041#define SYMOPT_UNDNAME 0x00000002
1042#define SYMOPT_DEFERRED_LOADS 0x00000004
1043#define SYMOPT_NO_CPP 0x00000008
1044#define SYMOPT_LOAD_LINES 0x00000010
1045#define SYMOPT_OMAP_FIND_NEAREST 0x00000020
1046#define SYMOPT_LOAD_ANYTHING 0x00000040
1047#define SYMOPT_IGNORE_CVREC 0x00000080
1048#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100
1049#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200
1050#define SYMOPT_EXACT_SYMBOLS 0x00000400
1051#define SYMOPT_WILD_UNDERSCORE 0x00000800
1052#define SYMOPT_USE_DEFAULTS 0x00001000
1053#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000
1054
1055#define SYMOPT_DEBUG 0x80000000
1056
1057DWORD
1058IMAGEAPI
1059SymSetOptions(
1060 IN DWORD SymOptions
1061 );
1062
1063DWORD
1064IMAGEAPI
1065SymGetOptions(
1066 VOID
1067 );
1068
1069BOOL
1070IMAGEAPI
1071SymCleanup(
1072 IN HANDLE hProcess
1073 );
1074
1075BOOL
1076IMAGEAPI
1077SymMatchString(
1078 IN LPSTR string,
1079 IN LPSTR expression,
1080 IN BOOL fCase
1081 );
1082
1083typedef BOOL
1084(CALLBACK *PSYM_ENUMSOURCFILES_CALLBACK)(
1085 PSOURCEFILE pSourceFile,
1086 PVOID UserContext
1087 );
1088
1089BOOL
1090IMAGEAPI
1091SymEnumSourceFiles(
1092 IN HANDLE hProcess,
1093 IN ULONG64 ModBase,
1094 IN LPSTR Mask,
1095 IN PSYM_ENUMSOURCFILES_CALLBACK cbSrcFiles,
1096 IN PVOID UserContext
1097 );
1098
1099BOOL
1100IMAGEAPI
1101SymEnumerateModules64(
1102 IN HANDLE hProcess,
1103 IN PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback,
1104 IN PVOID UserContext
1105 );
1106
1107#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1108#define SymEnumerateModules SymEnumerateModules64
1109#else
1110BOOL
1111IMAGEAPI
1112SymEnumerateModules(
1113 IN HANDLE hProcess,
1114 IN PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,
1115 IN PVOID UserContext
1116 );
1117#endif
1118
1119BOOL
1120IMAGEAPI
1121SymEnumerateSymbols64(
1122 IN HANDLE hProcess,
1123 IN DWORD64 BaseOfDll,
1124 IN PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback,
1125 IN PVOID UserContext
1126 );
1127
1128BOOL
1129IMAGEAPI
1130SymEnumerateSymbolsW64(
1131 IN HANDLE hProcess,
1132 IN DWORD64 BaseOfDll,
1133 IN PSYM_ENUMSYMBOLS_CALLBACK64W EnumSymbolsCallback,
1134 IN PVOID UserContext
1135 );
1136
1137#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1138#define SymEnumerateSymbols SymEnumerateSymbols64
1139#define SymEnumerateSymbolsW SymEnumerateSymbolsW64
1140#else
1141BOOL
1142IMAGEAPI
1143SymEnumerateSymbols(
1144 IN HANDLE hProcess,
1145 IN DWORD BaseOfDll,
1146 IN PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback,
1147 IN PVOID UserContext
1148 );
1149
1150BOOL
1151IMAGEAPI
1152SymEnumerateSymbolsW(
1153 IN HANDLE hProcess,
1154 IN DWORD BaseOfDll,
1155 IN PSYM_ENUMSYMBOLS_CALLBACKW EnumSymbolsCallback,
1156 IN PVOID UserContext
1157 );
1158#endif
1159
1160BOOL
1161IMAGEAPI
1162EnumerateLoadedModules64(
1163 IN HANDLE hProcess,
1164 IN PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback,
1165 IN PVOID UserContext
1166 );
1167
1168#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1169#define EnumerateLoadedModules EnumerateLoadedModules64
1170#else
1171BOOL
1172IMAGEAPI
1173EnumerateLoadedModules(
1174 IN HANDLE hProcess,
1175 IN PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,
1176 IN PVOID UserContext
1177 );
1178#endif
1179
1180PVOID
1181IMAGEAPI
1182SymFunctionTableAccess64(
1183 HANDLE hProcess,
1184 DWORD64 AddrBase
1185 );
1186
1187#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1188#define SymFunctionTableAccess SymFunctionTableAccess64
1189#else
1190PVOID
1191IMAGEAPI
1192SymFunctionTableAccess(
1193 HANDLE hProcess,
1194 DWORD AddrBase
1195 );
1196#endif
1197
1198BOOL
1199IMAGEAPI
1200SymGetModuleInfo64(
1201 IN HANDLE hProcess,
1202 IN DWORD64 qwAddr,
1203 OUT PIMAGEHLP_MODULE64 ModuleInfo
1204 );
1205
1206BOOL
1207IMAGEAPI
1208SymGetModuleInfoW64(
1209 IN HANDLE hProcess,
1210 IN DWORD64 qwAddr,
1211 OUT PIMAGEHLP_MODULEW64 ModuleInfo
1212 );
1213
1214#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1215#define SymGetModuleInfo SymGetModuleInfo64
1216#define SymGetModuleInfoW SymGetModuleInfoW64
1217#else
1218BOOL
1219IMAGEAPI
1220SymGetModuleInfo(
1221 IN HANDLE hProcess,
1222 IN DWORD dwAddr,
1223 OUT PIMAGEHLP_MODULE ModuleInfo
1224 );
1225
1226BOOL
1227IMAGEAPI
1228SymGetModuleInfoW(
1229 IN HANDLE hProcess,
1230 IN DWORD dwAddr,
1231 OUT PIMAGEHLP_MODULEW ModuleInfo
1232 );
1233#endif
1234
1235DWORD64
1236IMAGEAPI
1237SymGetModuleBase64(
1238 IN HANDLE hProcess,
1239 IN DWORD64 qwAddr
1240 );
1241
1242#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1243#define SymGetModuleBase SymGetModuleBase64
1244#else
1245DWORD
1246IMAGEAPI
1247SymGetModuleBase(
1248 IN HANDLE hProcess,
1249 IN DWORD dwAddr
1250 );
1251#endif
1252
1253BOOL
1254IMAGEAPI
1255SymGetSymNext64(
1256 IN HANDLE hProcess,
1257 IN OUT PIMAGEHLP_SYMBOL64 Symbol
1258 );
1259
1260#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1261#define SymGetSymNext SymGetSymNext64
1262#else
1263BOOL
1264IMAGEAPI
1265SymGetSymNext(
1266 IN HANDLE hProcess,
1267 IN OUT PIMAGEHLP_SYMBOL Symbol
1268 );
1269#endif
1270
1271BOOL
1272IMAGEAPI
1273SymGetSymPrev64(
1274 IN HANDLE hProcess,
1275 IN OUT PIMAGEHLP_SYMBOL64 Symbol
1276 );
1277
1278#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1279#define SymGetSymPrev SymGetSymPrev64
1280#else
1281BOOL
1282IMAGEAPI
1283SymGetSymPrev(
1284 IN HANDLE hProcess,
1285 IN OUT PIMAGEHLP_SYMBOL Symbol
1286 );
1287#endif
1288
1289BOOL
1290IMAGEAPI
1291SymGetLineFromAddr64(
1292 IN HANDLE hProcess,
1293 IN DWORD64 qwAddr,
1294 OUT PDWORD pdwDisplacement,
1295 OUT PIMAGEHLP_LINE64 Line
1296 );
1297
1298#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1299#define SymGetLineFromAddr SymGetLineFromAddr64
1300#else
1301BOOL
1302IMAGEAPI
1303SymGetLineFromAddr(
1304 IN HANDLE hProcess,
1305 IN DWORD dwAddr,
1306 OUT PDWORD pdwDisplacement,
1307 OUT PIMAGEHLP_LINE Line
1308 );
1309#endif
1310
1311BOOL
1312IMAGEAPI
1313SymGetLineFromName64(
1314 IN HANDLE hProcess,
1315 IN PSTR ModuleName,
1316 IN PSTR FileName,
1317 IN DWORD dwLineNumber,
1318 OUT Pint32_t plDisplacement,
1319 IN OUT PIMAGEHLP_LINE64 Line
1320 );
1321
1322#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1323#define SymGetLineFromName SymGetLineFromName64
1324#else
1325BOOL
1326IMAGEAPI
1327SymGetLineFromName(
1328 IN HANDLE hProcess,
1329 IN PSTR ModuleName,
1330 IN PSTR FileName,
1331 IN DWORD dwLineNumber,
1332 OUT Pint32_t plDisplacement,
1333 IN OUT PIMAGEHLP_LINE Line
1334 );
1335#endif
1336
1337BOOL
1338IMAGEAPI
1339SymGetLineNext64(
1340 IN HANDLE hProcess,
1341 IN OUT PIMAGEHLP_LINE64 Line
1342 );
1343
1344#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1345#define SymGetLineNext SymGetLineNext64
1346#else
1347BOOL
1348IMAGEAPI
1349SymGetLineNext(
1350 IN HANDLE hProcess,
1351 IN OUT PIMAGEHLP_LINE Line
1352 );
1353#endif
1354
1355BOOL
1356IMAGEAPI
1357SymGetLinePrev64(
1358 IN HANDLE hProcess,
1359 IN OUT PIMAGEHLP_LINE64 Line
1360 );
1361
1362#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1363#define SymGetLinePrev SymGetLinePrev64
1364#else
1365BOOL
1366IMAGEAPI
1367SymGetLinePrev(
1368 IN HANDLE hProcess,
1369 IN OUT PIMAGEHLP_LINE Line
1370 );
1371#endif
1372
1373BOOL
1374IMAGEAPI
1375SymMatchFileName(
1376 IN PSTR FileName,
1377 IN PSTR Match,
1378 OUT PSTR *FileNameStop,
1379 OUT PSTR *MatchStop
1380 );
1381
1382BOOL
1383IMAGEAPI
1384SymInitialize(
1385 IN HANDLE hProcess,
1386 IN PSTR UserSearchPath,
1387 IN BOOL fInvadeProcess
1388 );
1389
1390BOOL
1391IMAGEAPI
1392SymGetSearchPath(
1393 IN HANDLE hProcess,
1394 OUT PSTR SearchPath,
1395 IN DWORD SearchPathLength
1396 );
1397
1398BOOL
1399IMAGEAPI
1400SymSetSearchPath(
1401 IN HANDLE hProcess,
1402 IN PSTR SearchPath
1403 );
1404
1405DWORD64
1406IMAGEAPI
1407SymLoadModule64(
1408 IN HANDLE hProcess,
1409 IN HANDLE hFile,
1410 IN PSTR ImageName,
1411 IN PSTR ModuleName,
1412 IN DWORD64 BaseOfDll,
1413 IN DWORD SizeOfDll
1414 );
1415
1416DWORD64
1417IMAGEAPI
1418SymLoadModuleEx(
1419 IN HANDLE hProcess,
1420 IN HANDLE hFile,
1421 IN PSTR ImageName,
1422 IN PSTR ModuleName,
1423 IN DWORD64 BaseOfDll,
1424 IN DWORD DllSize,
1425 IN PMODLOAD_DATA Data,
1426 IN DWORD Flags
1427 );
1428
1429#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1430#define SymLoadModule SymLoadModule64
1431#else
1432DWORD
1433IMAGEAPI
1434SymLoadModule(
1435 IN HANDLE hProcess,
1436 IN HANDLE hFile,
1437 IN PSTR ImageName,
1438 IN PSTR ModuleName,
1439 IN DWORD BaseOfDll,
1440 IN DWORD SizeOfDll
1441 );
1442#endif
1443
1444BOOL
1445IMAGEAPI
1446SymUnloadModule64(
1447 IN HANDLE hProcess,
1448 IN DWORD64 BaseOfDll
1449 );
1450
1451#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1452#define SymUnloadModule SymUnloadModule64
1453#else
1454BOOL
1455IMAGEAPI
1456SymUnloadModule(
1457 IN HANDLE hProcess,
1458 IN DWORD BaseOfDll
1459 );
1460#endif
1461
1462BOOL
1463IMAGEAPI
1464SymUnDName64(
1465 IN PIMAGEHLP_SYMBOL64 sym, // Symbol to undecorate
1466 OUT PSTR UnDecName, // Buffer to store undecorated name in
1467 IN DWORD UnDecNameLength // Size of the buffer
1468 );
1469
1470#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1471#define SymUnDName SymUnDName64
1472#else
1473BOOL
1474IMAGEAPI
1475SymUnDName(
1476 IN PIMAGEHLP_SYMBOL sym, // Symbol to undecorate
1477 OUT PSTR UnDecName, // Buffer to store undecorated name in
1478 IN DWORD UnDecNameLength // Size of the buffer
1479 );
1480#endif
1481
1482BOOL
1483IMAGEAPI
1484SymRegisterCallback64(
1485 IN HANDLE hProcess,
1486 IN PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
1487 IN ULONG64 UserContext
1488 );
1489
1490BOOL
1491IMAGEAPI
1492SymRegisterFunctionEntryCallback64(
1493 IN HANDLE hProcess,
1494 IN PSYMBOL_FUNCENTRY_CALLBACK64 CallbackFunction,
1495 IN ULONG64 UserContext
1496 );
1497
1498#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1499#define SymRegisterCallback SymRegisterCallback64
1500#define SymRegisterFunctionEntryCallback SymRegisterFunctionEntryCallback64
1501#else
1502BOOL
1503IMAGEAPI
1504SymRegisterCallback(
1505 IN HANDLE hProcess,
1506 IN PSYMBOL_REGISTERED_CALLBACK CallbackFunction,
1507 IN PVOID UserContext
1508 );
1509
1510BOOL
1511IMAGEAPI
1512SymRegisterFunctionEntryCallback(
1513 IN HANDLE hProcess,
1514 IN PSYMBOL_FUNCENTRY_CALLBACK CallbackFunction,
1515 IN PVOID UserContext
1516 );
1517#endif
1518
1519
1520typedef struct _IMAGEHLP_SYMBOL_SRC {
1521 DWORD sizeofstruct;
1522 DWORD type;
1523 uint8_t file[MAX_PATH];
1524} IMAGEHLP_SYMBOL_SRC, *PIMAGEHLP_SYMBOL_SRC;
1525
1526typedef struct _MODULE_TYPE_INFO { // AKA TYPTYP
1527 USHORT dataLength;
1528 USHORT leaf;
1529 BYTE data[1];
1530} MODULE_TYPE_INFO, *PMODULE_TYPE_INFO;
1531
1532#define IMAGEHLP_SYMBOL_INFO_VALUEPRESENT 1
1533#define IMAGEHLP_SYMBOL_INFO_REGISTER SYMF_REGISTER // 0x08
1534#define IMAGEHLP_SYMBOL_INFO_REGRELATIVE SYMF_REGREL // 0x10
1535#define IMAGEHLP_SYMBOL_INFO_FRAMERELATIVE SYMF_FRAMEREL // 0x20
1536#define IMAGEHLP_SYMBOL_INFO_PARAMETER SYMF_PARAMETER // 0x40
1537#define IMAGEHLP_SYMBOL_INFO_LOCAL SYMF_LOCAL // 0x80
1538#define IMAGEHLP_SYMBOL_INFO_CONSTANT SYMF_CONSTANT // 0x100
1539#define IMAGEHLP_SYMBOL_FUNCTION SYMF_FUNCTION // 0x800
1540
1541typedef struct _SYMBOL_INFO {
1542 Uint32_t SizeOfStruct;
1543 Uint32_t TypeIndex; // Type Index of symbol
1544 ULONG64 Reserved[2];
1545 Uint32_t Reserved2;
1546 Uint32_t Size;
1547 ULONG64 ModBase; // Base Address of module comtaining this symbol
1548 Uint32_t Flags;
1549 ULONG64 Value; // Value of symbol, ValuePresent should be 1
1550 ULONG64 Address; // Address of symbol including base address of module
1551 Uint32_t Register; // register holding value or pointer to value
1552 Uint32_t Scope; // scope of the symbol
1553 Uint32_t Tag; // pdb classification
1554 Uint32_t NameLen; // Actual length of name
1555 Uint32_t MaxNameLen;
1556 CHAR Name[1]; // Name of symbol
1557} SYMBOL_INFO, *PSYMBOL_INFO;
1558
1559typedef struct _IMAGEHLP_STACK_FRAME
1560{
1561 ULONG64 InstructionOffset;
1562 ULONG64 ReturnOffset;
1563 ULONG64 FrameOffset;
1564 ULONG64 StackOffset;
1565 ULONG64 BackingStoreOffset;
1566 ULONG64 FuncTableEntry;
1567 ULONG64 Params[4];
1568 ULONG64 Reserved[5];
1569 BOOL Virtual;
1570 Uint32_t Reserved2;
1571} IMAGEHLP_STACK_FRAME, *PIMAGEHLP_STACK_FRAME;
1572
1573typedef VOID IMAGEHLP_CONTEXT, *PIMAGEHLP_CONTEXT;
1574
1575
1576ULONG
1577IMAGEAPI
1578SymSetContext(
1579 HANDLE hProcess,
1580 PIMAGEHLP_STACK_FRAME StackFrame,
1581 PIMAGEHLP_CONTEXT Context
1582 );
1583
1584BOOL
1585IMAGEAPI
1586SymFromAddr(
1587 IN HANDLE hProcess,
1588 IN DWORD64 Address,
1589 OUT PDWORD64 Displacement,
1590 IN OUT PSYMBOL_INFO Symbol
1591 );
1592
1593// While SymFromName will provide a symbol from a name,
1594// SymEnumSymbols can provide the same matching information
1595// for ALL symbols with a matching name, even regular
1596// expressions. That way you can search across modules
1597// and differentiate between identically named symbols.
1598
1599BOOL
1600IMAGEAPI
1601SymFromName(
1602 IN HANDLE hProcess,
1603 IN LPSTR Name,
1604 OUT PSYMBOL_INFO Symbol
1605 );
1606
1607typedef BOOL
1608(CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACK)(
1609 PSYMBOL_INFO pSymInfo,
1610 Uint32_t SymbolSize,
1611 PVOID UserContext
1612 );
1613
1614BOOL
1615IMAGEAPI
1616SymEnumSymbols(
1617 IN HANDLE hProcess,
1618 IN ULONG64 BaseOfDll,
1619 IN PCSTR Mask,
1620 IN PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
1621 IN PVOID UserContext
1622 );
1623
1624typedef enum _IMAGEHLP_SYMBOL_TYPE_INFO {
1625 TI_GET_SYMTAG,
1626 TI_GET_SYMNAME,
1627 TI_GET_LENGTH,
1628 TI_GET_TYPE,
1629 TI_GET_TYPEID,
1630 TI_GET_BASETYPE,
1631 TI_GET_ARRAYINDEXTYPEID,
1632 TI_FINDCHILDREN,
1633 TI_GET_DATAKIND,
1634 TI_GET_ADDRESSOFFSET,
1635 TI_GET_OFFSET,
1636 TI_GET_VALUE,
1637 TI_GET_COUNT,
1638 TI_GET_CHILDRENCOUNT,
1639 TI_GET_BITPOSITION,
1640 TI_GET_VIRTUALBASECLASS,
1641 TI_GET_VIRTUALTABLESHAPEID,
1642 TI_GET_VIRTUALBASEPOINTEROFFSET,
1643 TI_GET_CLASSPARENTID,
1644 TI_GET_NESTED,
1645 TI_GET_SYMINDEX,
1646 TI_GET_LEXICALPARENT,
1647 TI_GET_ADDRESS,
1648 TI_GET_THISADJUST,
1649} IMAGEHLP_SYMBOL_TYPE_INFO;
1650
1651typedef struct _TI_FINDCHILDREN_PARAMS {
1652 Uint32_t Count;
1653 Uint32_t Start;
1654 Uint32_t ChildId[1];
1655} TI_FINDCHILDREN_PARAMS;
1656
1657BOOL
1658IMAGEAPI
1659SymGetTypeInfo(
1660 IN HANDLE hProcess,
1661 IN DWORD64 ModBase,
1662 IN Uint32_t TypeId,
1663 IN IMAGEHLP_SYMBOL_TYPE_INFO GetType,
1664 OUT PVOID pInfo
1665 );
1666
1667BOOL
1668IMAGEAPI
1669SymEnumTypes(
1670 IN HANDLE hProcess,
1671 IN ULONG64 BaseOfDll,
1672 IN PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
1673 IN PVOID UserContext
1674 );
1675
1676BOOL
1677IMAGEAPI
1678SymGetTypeFromName(
1679 IN HANDLE hProcess,
1680 IN ULONG64 BaseOfDll,
1681 IN LPSTR Name,
1682 OUT PSYMBOL_INFO Symbol
1683 );
1684
1685//
1686// Full user-mode dump creation.
1687//
1688
1689typedef BOOL (WINAPI *PDBGHELP_CREATE_USER_DUMP_CALLBACK)(
1690 DWORD DataType,
1691 PVOID* Data,
1692 LPDWORD DataLength,
1693 PVOID UserData
1694 );
1695
1696BOOL
1697WINAPI
1698DbgHelpCreateUserDump(
1699 IN LPSTR FileName,
1700 IN PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback,
1701 IN PVOID UserData
1702 );
1703
1704BOOL
1705WINAPI
1706DbgHelpCreateUserDumpW(
1707 IN LPWSTR FileName,
1708 IN PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback,
1709 IN PVOID UserData
1710 );
1711
1712// -----------------------------------------------------------------
1713// The following 4 legacy APIs are fully supported, but newer
1714// ones are recommended. SymFromName and SymFromAddr provide
1715// much more detailed info on the returned symbol.
1716
1717BOOL
1718IMAGEAPI
1719SymGetSymFromAddr64(
1720 IN HANDLE hProcess,
1721 IN DWORD64 qwAddr,
1722 OUT PDWORD64 pdwDisplacement,
1723 OUT PIMAGEHLP_SYMBOL64 Symbol
1724 );
1725
1726#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1727#define SymGetSymFromAddr SymGetSymFromAddr64
1728#else
1729BOOL
1730IMAGEAPI
1731SymGetSymFromAddr(
1732 IN HANDLE hProcess,
1733 IN DWORD dwAddr,
1734 OUT PDWORD pdwDisplacement,
1735 OUT PIMAGEHLP_SYMBOL Symbol
1736 );
1737#endif
1738
1739// While following two APIs will provide a symbol from a name,
1740// SymEnumSymbols can provide the same matching information
1741// for ALL symbols with a matching name, even regular
1742// expressions. That way you can search across modules
1743// and differentiate between identically named symbols.
1744
1745BOOL
1746IMAGEAPI
1747SymGetSymFromName64(
1748 IN HANDLE hProcess,
1749 IN PSTR Name,
1750 OUT PIMAGEHLP_SYMBOL64 Symbol
1751 );
1752
1753#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64)
1754#define SymGetSymFromName SymGetSymFromName64
1755#else
1756BOOL
1757IMAGEAPI
1758SymGetSymFromName(
1759 IN HANDLE hProcess,
1760 IN PSTR Name,
1761 OUT PIMAGEHLP_SYMBOL Symbol
1762 );
1763#endif
1764
1765
1766// -----------------------------------------------------------------
1767// The following APIs exist only for backwards compatibility
1768// with a pre-release version documented in an MSDN release.
1769
1770// You should use SymFindFileInPath if you want to maintain
1771// future compatibility.
1772
1773DBHLP_DEPRECIATED
1774BOOL
1775IMAGEAPI
1776FindFileInPath(
1777 HANDLE hprocess,
1778 LPSTR SearchPath,
1779 LPSTR FileName,
1780 PVOID id,
1781 DWORD two,
1782 DWORD three,
1783 DWORD flags,
1784 LPSTR FilePath
1785 );
1786
1787// You should use SymFindFileInPath if you want to maintain
1788// future compatibility.
1789
1790DBHLP_DEPRECIATED
1791BOOL
1792IMAGEAPI
1793FindFileInSearchPath(
1794 HANDLE hprocess,
1795 LPSTR SearchPath,
1796 LPSTR FileName,
1797 DWORD one,
1798 DWORD two,
1799 DWORD three,
1800 LPSTR FilePath
1801 );
1802
1803DBHLP_DEPRECIATED
1804BOOL
1805IMAGEAPI
1806SymEnumSym(
1807 IN HANDLE hProcess,
1808 IN ULONG64 BaseOfDll,
1809 IN PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
1810 IN PVOID UserContext
1811 );
1812
1813
1814#include <pshpack4.h>
1815
1816#pragma warning(disable:4200) // Zero length array
1817
1818
1819#define MINIDUMP_SIGNATURE ('PMDM')
1820#define MINIDUMP_VERSION (42899)
1821typedef DWORD RVA;
1822typedef ULONG64 RVA64;
1823
1824typedef struct _MINIDUMP_LOCATION_DESCRIPTOR {
1825 ULONG32 DataSize;
1826 RVA Rva;
1827} MINIDUMP_LOCATION_DESCRIPTOR;
1828
1829typedef struct _MINIDUMP_LOCATION_DESCRIPTOR64 {
1830 ULONG64 DataSize;
1831 RVA64 Rva;
1832} MINIDUMP_LOCATION_DESCRIPTOR64;
1833
1834
1835typedef struct _MINIDUMP_MEMORY_DESCRIPTOR {
1836 ULONG64 StartOfMemoryRange;
1837 MINIDUMP_LOCATION_DESCRIPTOR Memory;
1838} MINIDUMP_MEMORY_DESCRIPTOR, *PMINIDUMP_MEMORY_DESCRIPTOR;
1839
1840// DESCRIPTOR64 is used for full-memory minidumps where
1841// all of the raw memory is laid out sequentially at the
1842// end of the dump. There is no need for individual RVAs
1843// as the RVA is the base RVA plus the sum of the preceeding
1844// data blocks.
1845typedef struct _MINIDUMP_MEMORY_DESCRIPTOR64 {
1846 ULONG64 StartOfMemoryRange;
1847 ULONG64 DataSize;
1848} MINIDUMP_MEMORY_DESCRIPTOR64, *PMINIDUMP_MEMORY_DESCRIPTOR64;
1849
1850
1851typedef struct _MINIDUMP_HEADER {
1852 ULONG32 Signature;
1853 ULONG32 Version;
1854 ULONG32 NumberOfStreams;
1855 RVA StreamDirectoryRva;
1856 ULONG32 CheckSum;
1857 union {
1858 ULONG32 Reserved;
1859 ULONG32 TimeDateStamp;
1860 };
1861 ULONG64 Flags;
1862} MINIDUMP_HEADER, *PMINIDUMP_HEADER;
1863
1864//
1865// The MINIDUMP_HEADER field StreamDirectoryRva points to
1866// an array of MINIDUMP_DIRECTORY structures.
1867//
1868
1869typedef struct _MINIDUMP_DIRECTORY {
1870 ULONG32 StreamType;
1871 MINIDUMP_LOCATION_DESCRIPTOR Location;
1872} MINIDUMP_DIRECTORY, *PMINIDUMP_DIRECTORY;
1873
1874
1875typedef struct _MINIDUMP_STRING {
1876 ULONG32 Length; // Length in bytes of the string
1877 WCHAR Buffer [0]; // Variable size buffer
1878} MINIDUMP_STRING, *PMINIDUMP_STRING;
1879
1880
1881
1882//
1883// The MINIDUMP_DIRECTORY field StreamType may be one of the following types.
1884// Types will be added in the future, so if a program reading the minidump
1885// header encounters a stream type it does not understand it should ignore
1886// the data altogether. Any tag above LastReservedStream will not be used by
1887// the system and is reserved for program-specific information.
1888//
1889
1890typedef enum _MINIDUMP_STREAM_TYPE {
1891
1892 UnusedStream = 0,
1893 ReservedStream0 = 1,
1894 ReservedStream1 = 2,
1895 ThreadListStream = 3,
1896 ModuleListStream = 4,
1897 MemoryListStream = 5,
1898 ExceptionStream = 6,
1899 SystemInfoStream = 7,
1900 ThreadExListStream = 8,
1901 Memory64ListStream = 9,
1902 CommentStreamA = 10,
1903 CommentStreamW = 11,
1904 HandleDataStream = 12,
1905 FunctionTableStream = 13,
1906
1907 LastReservedStream = 0xffff
1908
1909} MINIDUMP_STREAM_TYPE;
1910
1911
1912//
1913// The minidump system information contains processor and
1914// Operating System specific information.
1915//
1916
1917typedef struct _MINIDUMP_SYSTEM_INFO {
1918
1919 //
1920 // ProcessorArchitecture, ProcessorLevel and ProcessorRevision are all
1921 // taken from the SYSTEM_INFO structure obtained by GetSystemInfo( ).
1922 //
1923
1924 USHORT ProcessorArchitecture;
1925 USHORT ProcessorLevel;
1926 USHORT ProcessorRevision;
1927
1928 USHORT Reserved0; // Reserved for future use. Must be zero.
1929
1930 //
1931 // MajorVersion, MinorVersion, BuildNumber, PlatformId and
1932 // CSDVersion are all taken from the OSVERSIONINFO structure
1933 // returned by GetVersionEx( ).
1934 //
1935
1936 ULONG32 MajorVersion;
1937 ULONG32 MinorVersion;
1938 ULONG32 BuildNumber;
1939 ULONG32 PlatformId;
1940
1941 //
1942 // RVA to a CSDVersion string in the string table.
1943 //
1944
1945 RVA CSDVersionRva;
1946
1947 ULONG32 Reserved1; // Reserved for future use.
1948
1949 //
1950 // CPU information is obtained from one of two places.
1951 //
1952 // 1) On x86 computers, CPU_INFORMATION is obtained from the CPUID
1953 // instruction. You must use the X86 portion of the union for X86
1954 // computers.
1955 //
1956 // 2) On non-x86 architectures, CPU_INFORMATION is obtained by calling
1957 // IsProcessorFeatureSupported().
1958 //
1959
1960 union _CPU_INFORMATION {
1961
1962 //
1963 // X86 platforms use CPUID function to obtain processor information.
1964 //
1965
1966 struct {
1967
1968 //
1969 // CPUID Subfunction 0, register EAX (VendorId [0]),
1970 // EBX (VendorId [1]) and ECX (VendorId [2]).
1971 //
1972
1973 ULONG32 VendorId [ 3 ];
1974
1975 //
1976 // CPUID Subfunction 1, register EAX
1977 //
1978
1979 ULONG32 VersionInformation;
1980
1981 //
1982 // CPUID Subfunction 1, register EDX
1983 //
1984
1985 ULONG32 FeatureInformation;
1986
1987
1988 //
1989 // CPUID, Subfunction 80000001, register EBX. This will only
1990 // be obtained if the vendor id is "AuthenticAMD".
1991 //
1992
1993 ULONG32 AMDExtendedCpuFeatures;
1994
1995 } X86CpuInfo;
1996
1997 //
1998 // Non-x86 platforms use processor feature flags.
1999 //
2000
2001 struct {
2002
2003 ULONG64 ProcessorFeatures [ 2 ];
2004
2005 } OtherCpuInfo;
2006
2007 } Cpu;
2008
2009} MINIDUMP_SYSTEM_INFO, *PMINIDUMP_SYSTEM_INFO;
2010
2011typedef union _CPU_INFORMATION CPU_INFORMATION, *PCPU_INFORMATION;
2012
2013
2014//
2015// The minidump thread contains standard thread
2016// information plus an RVA to the memory for this
2017// thread and an RVA to the CONTEXT structure for
2018// this thread.
2019//
2020
2021
2022//
2023// ThreadId must be 4 bytes on all architectures.
2024//
2025
2026C_ASSERT (sizeof ( ((PPROCESS_INFORMATION)0)->dwThreadId ) == 4);
2027
2028typedef struct _MINIDUMP_THREAD {
2029 ULONG32 ThreadId;
2030 ULONG32 SuspendCount;
2031 ULONG32 PriorityClass;
2032 ULONG32 Priority;
2033 ULONG64 Teb;
2034 MINIDUMP_MEMORY_DESCRIPTOR Stack;
2035 MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
2036} MINIDUMP_THREAD, *PMINIDUMP_THREAD;
2037
2038//
2039// The thread list is a container of threads.
2040//
2041
2042typedef struct _MINIDUMP_THREAD_LIST {
2043 ULONG32 NumberOfThreads;
2044 MINIDUMP_THREAD Threads [0];
2045} MINIDUMP_THREAD_LIST, *PMINIDUMP_THREAD_LIST;
2046
2047
2048typedef struct _MINIDUMP_THREAD_EX {
2049 ULONG32 ThreadId;
2050 ULONG32 SuspendCount;
2051 ULONG32 PriorityClass;
2052 ULONG32 Priority;
2053 ULONG64 Teb;
2054 MINIDUMP_MEMORY_DESCRIPTOR Stack;
2055 MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
2056 MINIDUMP_MEMORY_DESCRIPTOR BackingStore;
2057} MINIDUMP_THREAD_EX, *PMINIDUMP_THREAD_EX;
2058
2059//
2060// The thread list is a container of threads.
2061//
2062
2063typedef struct _MINIDUMP_THREAD_EX_LIST {
2064 ULONG32 NumberOfThreads;
2065 MINIDUMP_THREAD_EX Threads [0];
2066} MINIDUMP_THREAD_EX_LIST, *PMINIDUMP_THREAD_EX_LIST;
2067
2068
2069//
2070// The MINIDUMP_EXCEPTION is the same as EXCEPTION on Win64.
2071//
2072
2073typedef struct _MINIDUMP_EXCEPTION {
2074 ULONG32 ExceptionCode;
2075 ULONG32 ExceptionFlags;
2076 ULONG64 ExceptionRecord;
2077 ULONG64 ExceptionAddress;
2078 ULONG32 NumberParameters;
2079 ULONG32 __unusedAlignment;
2080 ULONG64 ExceptionInformation [ EXCEPTION_MAXIMUM_PARAMETERS ];
2081} MINIDUMP_EXCEPTION, *PMINIDUMP_EXCEPTION;
2082
2083
2084//
2085// The exception information stream contains the id of the thread that caused
2086// the exception (ThreadId), the exception record for the exception
2087// (ExceptionRecord) and an RVA to the thread context where the exception
2088// occured.
2089//
2090
2091typedef struct MINIDUMP_EXCEPTION_STREAM {
2092 ULONG32 ThreadId;
2093 ULONG32 __alignment;
2094 MINIDUMP_EXCEPTION ExceptionRecord;
2095 MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
2096} MINIDUMP_EXCEPTION_STREAM, *PMINIDUMP_EXCEPTION_STREAM;
2097
2098
2099//
2100// The MINIDUMP_MODULE contains information about a
2101// a specific module. It includes the CheckSum and
2102// the TimeDateStamp for the module so the module
2103// can be reloaded during the analysis phase.
2104//
2105
2106typedef struct _MINIDUMP_MODULE {
2107 ULONG64 BaseOfImage;
2108 ULONG32 SizeOfImage;
2109 ULONG32 CheckSum;
2110 ULONG32 TimeDateStamp;
2111 RVA ModuleNameRva;
2112 VS_FIXEDFILEINFO VersionInfo;
2113 MINIDUMP_LOCATION_DESCRIPTOR CvRecord;
2114 MINIDUMP_LOCATION_DESCRIPTOR MiscRecord;
2115 ULONG64 Reserved0; // Reserved for future use.
2116 ULONG64 Reserved1; // Reserved for future use.
2117} MINIDUMP_MODULE, *PMINIDUMP_MODULE;
2118
2119
2120//
2121// The minidump module list is a container for modules.
2122//
2123
2124typedef struct _MINIDUMP_MODULE_LIST {
2125 ULONG32 NumberOfModules;
2126 MINIDUMP_MODULE Modules [ 0 ];
2127} MINIDUMP_MODULE_LIST, *PMINIDUMP_MODULE_LIST;
2128
2129
2130//
2131// Memory Ranges
2132//
2133
2134typedef struct _MINIDUMP_MEMORY_LIST {
2135 ULONG32 NumberOfMemoryRanges;
2136 MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges [0];
2137} MINIDUMP_MEMORY_LIST, *PMINIDUMP_MEMORY_LIST;
2138
2139typedef struct _MINIDUMP_MEMORY64_LIST {
2140 ULONG64 NumberOfMemoryRanges;
2141 RVA64 BaseRva;
2142 MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges [0];
2143} MINIDUMP_MEMORY64_LIST, *PMINIDUMP_MEMORY64_LIST;
2144
2145
2146//
2147// Support for user supplied exception information.
2148//
2149
2150typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
2151 DWORD ThreadId;
2152 PEXCEPTION_POINTERS ExceptionPointers;
2153 BOOL ClientPointers;
2154} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
2155
2156
2157//
2158// Support for capturing system handle state at the time of the dump.
2159//
2160
2161typedef struct _MINIDUMP_HANDLE_DESCRIPTOR {
2162 ULONG64 Handle;
2163 RVA TypeNameRva;
2164 RVA ObjectNameRva;
2165 ULONG32 Attributes;
2166 ULONG32 GrantedAccess;
2167 ULONG32 HandleCount;
2168 ULONG32 PointerCount;
2169} MINIDUMP_HANDLE_DESCRIPTOR, *PMINIDUMP_HANDLE_DESCRIPTOR;
2170
2171typedef struct _MINIDUMP_HANDLE_DATA_STREAM {
2172 ULONG32 SizeOfHeader;
2173 ULONG32 SizeOfDescriptor;
2174 ULONG32 NumberOfDescriptors;
2175 ULONG32 Reserved;
2176} MINIDUMP_HANDLE_DATA_STREAM, *PMINIDUMP_HANDLE_DATA_STREAM;
2177
2178
2179//
2180// Support for capturing dynamic function table state at the time of the dump.
2181//
2182
2183typedef struct _MINIDUMP_FUNCTION_TABLE_DESCRIPTOR {
2184 ULONG64 MinimumAddress;
2185 ULONG64 MaximumAddress;
2186 ULONG64 BaseAddress;
2187 ULONG32 EntryCount;
2188 ULONG32 SizeOfAlignPad;
2189} MINIDUMP_FUNCTION_TABLE_DESCRIPTOR, *PMINIDUMP_FUNCTION_TABLE_DESCRIPTOR;
2190
2191typedef struct _MINIDUMP_FUNCTION_TABLE_STREAM {
2192 ULONG32 SizeOfHeader;
2193 ULONG32 SizeOfDescriptor;
2194 ULONG32 SizeOfNativeDescriptor;
2195 ULONG32 SizeOfFunctionEntry;
2196 ULONG32 NumberOfDescriptors;
2197 ULONG32 SizeOfAlignPad;
2198} MINIDUMP_FUNCTION_TABLE_STREAM, *PMINIDUMP_FUNCTION_TABLE_STREAM;
2199
2200
2201//
2202// Support for arbitrary user-defined information.
2203//
2204
2205typedef struct _MINIDUMP_USER_RECORD {
2206 ULONG32 Type;
2207 MINIDUMP_LOCATION_DESCRIPTOR Memory;
2208} MINIDUMP_USER_RECORD, *PMINIDUMP_USER_RECORD;
2209
2210
2211typedef struct _MINIDUMP_USER_STREAM {
2212 ULONG32 Type;
2213 Uint32_t BufferSize;
2214 PVOID Buffer;
2215
2216} MINIDUMP_USER_STREAM, *PMINIDUMP_USER_STREAM;
2217
2218
2219typedef struct _MINIDUMP_USER_STREAM_INFORMATION {
2220 Uint32_t UserStreamCount;
2221 PMINIDUMP_USER_STREAM UserStreamArray;
2222} MINIDUMP_USER_STREAM_INFORMATION, *PMINIDUMP_USER_STREAM_INFORMATION;
2223
2224//
2225// Callback support.
2226//
2227
2228typedef enum _MINIDUMP_CALLBACK_TYPE {
2229 ModuleCallback,
2230 ThreadCallback,
2231 ThreadExCallback,
2232 IncludeThreadCallback,
2233 IncludeModuleCallback,
2234} MINIDUMP_CALLBACK_TYPE;
2235
2236
2237typedef struct _MINIDUMP_THREAD_CALLBACK {
2238 Uint32_t ThreadId;
2239 HANDLE ThreadHandle;
2240 CONTEXT Context;
2241 Uint32_t SizeOfContext;
2242 ULONG64 StackBase;
2243 ULONG64 StackEnd;
2244} MINIDUMP_THREAD_CALLBACK, *PMINIDUMP_THREAD_CALLBACK;
2245
2246
2247typedef struct _MINIDUMP_THREAD_EX_CALLBACK {
2248 Uint32_t ThreadId;
2249 HANDLE ThreadHandle;
2250 CONTEXT Context;
2251 Uint32_t SizeOfContext;
2252 ULONG64 StackBase;
2253 ULONG64 StackEnd;
2254 ULONG64 BackingStoreBase;
2255 ULONG64 BackingStoreEnd;
2256} MINIDUMP_THREAD_EX_CALLBACK, *PMINIDUMP_THREAD_EX_CALLBACK;
2257
2258
2259typedef struct _MINIDUMP_INCLUDE_THREAD_CALLBACK {
2260 Uint32_t ThreadId;
2261} MINIDUMP_INCLUDE_THREAD_CALLBACK, *PMINIDUMP_INCLUDE_THREAD_CALLBACK;
2262
2263
2264typedef enum _THREAD_WRITE_FLAGS {
2265 ThreadWriteThread = 0x0001,
2266 ThreadWriteStack = 0x0002,
2267 ThreadWriteContext = 0x0004,
2268 ThreadWriteBackingStore = 0x0008,
2269 ThreadWriteInstructionWindow = 0x0010
2270} THREAD_WRITE_FLAGS;
2271
2272typedef struct _MINIDUMP_MODULE_CALLBACK {
2273 PWCHAR FullPath;
2274 ULONG64 BaseOfImage;
2275 Uint32_t SizeOfImage;
2276 Uint32_t CheckSum;
2277 Uint32_t TimeDateStamp;
2278 VS_FIXEDFILEINFO VersionInfo;
2279 PVOID CvRecord;
2280 Uint32_t SizeOfCvRecord;
2281 PVOID MiscRecord;
2282 Uint32_t SizeOfMiscRecord;
2283} MINIDUMP_MODULE_CALLBACK, *PMINIDUMP_MODULE_CALLBACK;
2284
2285
2286typedef struct _MINIDUMP_INCLUDE_MODULE_CALLBACK {
2287 ULONG64 BaseOfImage;
2288} MINIDUMP_INCLUDE_MODULE_CALLBACK, *PMINIDUMP_INCLUDE_MODULE_CALLBACK;
2289
2290
2291typedef enum _MODULE_WRITE_FLAGS {
2292 ModuleWriteModule = 0x0001,
2293 ModuleWriteDataSeg = 0x0002,
2294 ModuleWriteMiscRecord = 0x0004,
2295 ModuleWriteCvRecord = 0x0008,
2296 ModuleReferencedByMemory = 0x0010
2297} MODULE_WRITE_FLAGS;
2298
2299
2300typedef struct _MINIDUMP_CALLBACK_INPUT {
2301 Uint32_t ProcessId;
2302 HANDLE ProcessHandle;
2303 Uint32_t CallbackType;
2304 union {
2305 MINIDUMP_THREAD_CALLBACK Thread;
2306 MINIDUMP_THREAD_EX_CALLBACK ThreadEx;
2307 MINIDUMP_MODULE_CALLBACK Module;
2308 MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread;
2309 MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule;
2310 };
2311} MINIDUMP_CALLBACK_INPUT, *PMINIDUMP_CALLBACK_INPUT;
2312
2313typedef struct _MINIDUMP_CALLBACK_OUTPUT {
2314 union {
2315 Uint32_t ModuleWriteFlags;
2316 Uint32_t ThreadWriteFlags;
2317 };
2318} MINIDUMP_CALLBACK_OUTPUT, *PMINIDUMP_CALLBACK_OUTPUT;
2319
2320
2321//
2322// A normal minidump contains just the information
2323// necessary to capture stack traces for all of the
2324// existing threads in a process.
2325//
2326// A minidump with data segments includes all of the data
2327// sections from loaded modules in order to capture
2328// global variable contents. This can make the dump much
2329// larger if many modules have global data.
2330//
2331// A minidump with full memory includes all of the accessible
2332// memory in the process and can be very large. A minidump
2333// with full memory always has the raw memory data at the end
2334// of the dump so that the initial structures in the dump can
2335// be mapped directly without having to include the raw
2336// memory information.
2337//
2338// Stack and backing store memory can be filtered to remove
2339// data unnecessary for stack walking. This can improve
2340// compression of stacks and also deletes data that may
2341// be private and should not be stored in a dump.
2342// Memory can also be scanned to see what modules are
2343// referenced by stack and backing store memory to allow
2344// omission of other modules to reduce dump size.
2345// In either of these modes the ModuleReferencedByMemory flag
2346// is set for all modules referenced before the base
2347// module callbacks occur.
2348//
2349
2350typedef enum _MINIDUMP_TYPE {
2351 MiniDumpNormal = 0x0000,
2352 MiniDumpWithDataSegs = 0x0001,
2353 MiniDumpWithFullMemory = 0x0002,
2354 MiniDumpWithHandleData = 0x0004,
2355 MiniDumpFilterMemory = 0x0008,
2356 MiniDumpScanMemory = 0x0010,
2357} MINIDUMP_TYPE;
2358
2359
2360//
2361// The minidump callback should modify the FieldsToWrite parameter to reflect
2362// what portions of the specified thread or module should be written to the
2363// file.
2364//
2365
2366typedef
2367BOOL
2368(WINAPI * MINIDUMP_CALLBACK_ROUTINE) (
2369 IN PVOID CallbackParam,
2370 IN CONST PMINIDUMP_CALLBACK_INPUT CallbackInput,
2371 IN OUT PMINIDUMP_CALLBACK_OUTPUT CallbackOutput
2372 );
2373
2374typedef struct _MINIDUMP_CALLBACK_INFORMATION {
2375 MINIDUMP_CALLBACK_ROUTINE CallbackRoutine;
2376 PVOID CallbackParam;
2377} MINIDUMP_CALLBACK_INFORMATION, *PMINIDUMP_CALLBACK_INFORMATION;
2378
2379
2380
2381//++
2382//
2383// PVOID
2384// RVA_TO_ADDR(
2385// PVOID Mapping,
2386// Uint32_t Rva
2387// )
2388//
2389// Routine Description:
2390//
2391// Map an RVA that is contained within a mapped file to it's associated
2392// flat address.
2393//
2394// Arguments:
2395//
2396// Mapping - Base address of mapped file containing the RVA.
2397//
2398// Rva - An Rva to fixup.
2399//
2400// Return Values:
2401//
2402// A pointer to the desired data.
2403//
2404//--
2405
2406#define RVA_TO_ADDR(Mapping,Rva) ((PVOID)(((ULONG_PTR) (Mapping)) + (Rva)))
2407
2408BOOL
2409WINAPI
2410MiniDumpWriteDump(
2411 IN HANDLE hProcess,
2412 IN DWORD ProcessId,
2413 IN HANDLE hFile,
2414 IN MINIDUMP_TYPE DumpType,
2415 IN CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, OPTIONAL
2416 IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, OPTIONAL
2417 IN CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam OPTIONAL
2418 );
2419
2420BOOL
2421WINAPI
2422MiniDumpReadDumpStream(
2423 IN PVOID BaseOfDump,
2424 IN Uint32_t StreamNumber,
2425 OUT PMINIDUMP_DIRECTORY * Dir, OPTIONAL
2426 OUT PVOID * StreamPointer, OPTIONAL
2427 OUT Uint32_t * StreamSize OPTIONAL
2428 );
2429
2430#include <poppack.h>
2431
2432#ifdef __cplusplus
2433}
2434#endif
2435
2436
2437#endif // _DBGHELP_
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/Makefile b/apps/plugins/sdl/progs/duke3d/Game/src/Makefile
new file mode 100644
index 0000000000..e40b3d0311
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/Makefile
@@ -0,0 +1,942 @@
1# Makefile.in generated by automake 1.15.1 from Makefile.am.
2# Game/src/Makefile. Generated from Makefile.in by configure.
3
4# Copyright (C) 1994-2017 Free Software Foundation, Inc.
5
6# This Makefile.in is free software; the Free Software Foundation
7# gives unlimited permission to copy and/or distribute it,
8# with or without modifications, as long as this notice is preserved.
9
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
12# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13# PARTICULAR PURPOSE.
14
15
16
17
18am__is_gnu_make = { \
19 if test -z '$(MAKELEVEL)'; then \
20 false; \
21 elif test -n '$(MAKE_HOST)'; then \
22 true; \
23 elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
24 true; \
25 else \
26 false; \
27 fi; \
28}
29am__make_running_with_option = \
30 case $${target_option-} in \
31 ?) ;; \
32 *) echo "am__make_running_with_option: internal error: invalid" \
33 "target option '$${target_option-}' specified" >&2; \
34 exit 1;; \
35 esac; \
36 has_opt=no; \
37 sane_makeflags=$$MAKEFLAGS; \
38 if $(am__is_gnu_make); then \
39 sane_makeflags=$$MFLAGS; \
40 else \
41 case $$MAKEFLAGS in \
42 *\\[\ \ ]*) \
43 bs=\\; \
44 sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
45 | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
46 esac; \
47 fi; \
48 skip_next=no; \
49 strip_trailopt () \
50 { \
51 flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
52 }; \
53 for flg in $$sane_makeflags; do \
54 test $$skip_next = yes && { skip_next=no; continue; }; \
55 case $$flg in \
56 *=*|--*) continue;; \
57 -*I) strip_trailopt 'I'; skip_next=yes;; \
58 -*I?*) strip_trailopt 'I';; \
59 -*O) strip_trailopt 'O'; skip_next=yes;; \
60 -*O?*) strip_trailopt 'O';; \
61 -*l) strip_trailopt 'l'; skip_next=yes;; \
62 -*l?*) strip_trailopt 'l';; \
63 -[dEDm]) skip_next=yes;; \
64 -[JT]) skip_next=yes;; \
65 esac; \
66 case $$flg in \
67 *$$target_option*) has_opt=yes; break;; \
68 esac; \
69 done; \
70 test $$has_opt = yes
71am__make_dryrun = (target_option=n; $(am__make_running_with_option))
72am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
73pkgdatadir = $(datadir)/chocolate-duke3d
74pkgincludedir = $(includedir)/chocolate-duke3d
75pkglibdir = $(libdir)/chocolate-duke3d
76pkglibexecdir = $(libexecdir)/chocolate-duke3d
77am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
78install_sh_DATA = $(install_sh) -c -m 644
79install_sh_PROGRAM = $(install_sh) -c
80install_sh_SCRIPT = $(install_sh) -c
81INSTALL_HEADER = $(INSTALL_DATA)
82transform = $(program_transform_name)
83NORMAL_INSTALL = :
84PRE_INSTALL = :
85POST_INSTALL = :
86NORMAL_UNINSTALL = :
87PRE_UNINSTALL = :
88POST_UNINSTALL = :
89subdir = Game/src
90ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
91am__aclocal_m4_deps = $(top_srcdir)/configure.ac
92am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
93 $(ACLOCAL_M4)
94DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
95mkinstalldirs = $(install_sh) -d
96CONFIG_CLEAN_FILES =
97CONFIG_CLEAN_VPATH_FILES =
98LIBRARIES = $(noinst_LIBRARIES)
99AR = ar
100ARFLAGS = cru
101AM_V_AR = $(am__v_AR_$(V))
102am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY))
103am__v_AR_0 = @echo " AR " $@;
104am__v_AR_1 =
105libGame_a_AR = $(AR) $(ARFLAGS)
106libGame_a_DEPENDENCIES = premap.o
107am_libGame_a_OBJECTS = libGame_a-actors.$(OBJEXT) \
108 libGame_a-animlib.$(OBJEXT) libGame_a-config.$(OBJEXT) \
109 libGame_a-console.$(OBJEXT) libGame_a-control.$(OBJEXT) \
110 libGame_a-cvar_defs.$(OBJEXT) libGame_a-cvars.$(OBJEXT) \
111 libGame_a-dummy_audiolib.$(OBJEXT) libGame_a-game.$(OBJEXT) \
112 libGame_a-gamedef.$(OBJEXT) libGame_a-global.$(OBJEXT) \
113 libGame_a-keyboard.$(OBJEXT) libGame_a-menues.$(OBJEXT) \
114 libGame_a-player.$(OBJEXT) libGame_a-rts.$(OBJEXT) \
115 libGame_a-scriplib.$(OBJEXT) libGame_a-sector.$(OBJEXT) \
116 libGame_a-sounds.$(OBJEXT)
117libGame_a_OBJECTS = $(am_libGame_a_OBJECTS)
118AM_V_P = $(am__v_P_$(V))
119am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
120am__v_P_0 = false
121am__v_P_1 = :
122AM_V_GEN = $(am__v_GEN_$(V))
123am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
124am__v_GEN_0 = @echo " GEN " $@;
125am__v_GEN_1 =
126AM_V_at = $(am__v_at_$(V))
127am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
128am__v_at_0 = @
129am__v_at_1 =
130DEFAULT_INCLUDES = -I.
131depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
132am__depfiles_maybe = depfiles
133am__mv = mv -f
134AM_V_lt = $(am__v_lt_$(V))
135am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
136am__v_lt_0 = --silent
137am__v_lt_1 =
138COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
139 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
140AM_V_CC = $(am__v_CC_$(V))
141am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
142am__v_CC_0 = @echo " CC " $@;
143am__v_CC_1 =
144CCLD = $(CC)
145LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
146AM_V_CCLD = $(am__v_CCLD_$(V))
147am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
148am__v_CCLD_0 = @echo " CCLD " $@;
149am__v_CCLD_1 =
150SOURCES = $(libGame_a_SOURCES)
151DIST_SOURCES = $(libGame_a_SOURCES)
152RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
153 ctags-recursive dvi-recursive html-recursive info-recursive \
154 install-data-recursive install-dvi-recursive \
155 install-exec-recursive install-html-recursive \
156 install-info-recursive install-pdf-recursive \
157 install-ps-recursive install-recursive installcheck-recursive \
158 installdirs-recursive pdf-recursive ps-recursive \
159 tags-recursive uninstall-recursive
160am__can_run_installinfo = \
161 case $$AM_UPDATE_INFO_DIR in \
162 n|no|NO) false;; \
163 *) (install-info --version) >/dev/null 2>&1;; \
164 esac
165RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
166 distclean-recursive maintainer-clean-recursive
167am__recursive_targets = \
168 $(RECURSIVE_TARGETS) \
169 $(RECURSIVE_CLEAN_TARGETS) \
170 $(am__extra_recursive_targets)
171AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
172 distdir
173am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
174# Read a list of newline-separated strings from the standard input,
175# and print each of them once, without duplicates. Input order is
176# *not* preserved.
177am__uniquify_input = $(AWK) '\
178 BEGIN { nonempty = 0; } \
179 { items[$$0] = 1; nonempty = 1; } \
180 END { if (nonempty) { for (i in items) print i; }; } \
181'
182# Make sure the list of sources is unique. This is necessary because,
183# e.g., the same source file might be shared among _SOURCES variables
184# for different programs/libraries.
185am__define_uniq_tagged_files = \
186 list='$(am__tagged_files)'; \
187 unique=`for i in $$list; do \
188 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
189 done | $(am__uniquify_input)`
190ETAGS = etags
191CTAGS = ctags
192DIST_SUBDIRS = $(SUBDIRS)
193am__DIST_COMMON = $(srcdir)/Makefile.in \
194 $(top_srcdir)/build-aux/depcomp
195DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
196am__relativize = \
197 dir0=`pwd`; \
198 sed_first='s,^\([^/]*\)/.*$$,\1,'; \
199 sed_rest='s,^[^/]*/*,,'; \
200 sed_last='s,^.*/\([^/]*\)$$,\1,'; \
201 sed_butlast='s,/*[^/]*$$,,'; \
202 while test -n "$$dir1"; do \
203 first=`echo "$$dir1" | sed -e "$$sed_first"`; \
204 if test "$$first" != "."; then \
205 if test "$$first" = ".."; then \
206 dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
207 dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
208 else \
209 first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
210 if test "$$first2" = "$$first"; then \
211 dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
212 else \
213 dir2="../$$dir2"; \
214 fi; \
215 dir0="$$dir0"/"$$first"; \
216 fi; \
217 fi; \
218 dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
219 done; \
220 reldir="$$dir2"
221ACLOCAL = ${SHELL} /home/franklin/chocolate_duke3D/build-aux/missing aclocal-1.15
222AMTAR = $${TAR-tar}
223AM_DEFAULT_VERBOSITY = 0
224AUTOCONF = ${SHELL} /home/franklin/chocolate_duke3D/build-aux/missing autoconf
225AUTOHEADER = ${SHELL} /home/franklin/chocolate_duke3D/build-aux/missing autoheader
226AUTOMAKE = ${SHELL} /home/franklin/chocolate_duke3D/build-aux/missing automake-1.15
227AWK = gawk
228CC = gcc
229CCDEPMODE = depmode=gcc3
230CFLAGS = -Wall -Wno-pointer-sign -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -Wno-parentheses -Wno-maybe-uninitialized -Wno-unused-but-set-variable -Wno-unused-function -Wno-unused-result -fno-strict-aliasing -fno-aggressive-loop-optimizations -DPLATFORM_UNIX -D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/SDL -g -O2
231CPP = gcc -E
232CPPFLAGS =
233CYGPATH_W = echo
234DEFS = -DPACKAGE_NAME=\"Chocolate\ Duke3D\" -DPACKAGE_TARNAME=\"chocolate-duke3d\" -DPACKAGE_VERSION=\"1.0\" -DPACKAGE_STRING=\"Chocolate\ Duke3D\ 1.0\" -DPACKAGE_BUGREPORT=\"https://github.com/fabiensanglard/chocolate_duke3D/issues\" -DPACKAGE_URL=\"\" -DPACKAGE=\"chocolate-duke3d\" -DVERSION=\"1.0\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_ASSERT_H=1 -DHAVE_ENET_ENET_H=1
235DEPDIR = .deps
236ECHO_C =
237ECHO_N = -n
238ECHO_T =
239EGREP = /usr/bin/grep -E
240EXEEXT =
241GREP = /usr/bin/grep
242INSTALL = /usr/bin/install -c
243INSTALL_DATA = ${INSTALL} -m 644
244INSTALL_PROGRAM = ${INSTALL}
245INSTALL_SCRIPT = ${INSTALL}
246INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
247LDFLAGS = -lSDL -lpthread -lSDL_mixer -lSDL -lpthread
248LIBOBJS =
249LIBS =
250LTLIBOBJS =
251MAKEINFO = ${SHELL} /home/franklin/chocolate_duke3D/build-aux/missing makeinfo
252MKDIR_P = /usr/bin/mkdir -p
253OBJEXT = o
254PACKAGE = chocolate-duke3d
255PACKAGE_BUGREPORT = https://github.com/fabiensanglard/chocolate_duke3D/issues
256PACKAGE_NAME = Chocolate Duke3D
257PACKAGE_STRING = Chocolate Duke3D 1.0
258PACKAGE_TARNAME = chocolate-duke3d
259PACKAGE_URL =
260PACKAGE_VERSION = 1.0
261PATH_SEPARATOR = :
262PKG_CONFIG = /usr/bin/pkg-config
263PKG_CONFIG_LIBDIR =
264PKG_CONFIG_PATH =
265RANLIB = ranlib
266SDL_CFLAGS = -D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/SDL
267SDL_LIBS = -lSDL -lpthread
268SDL_MIXER_CFLAGS = -D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/SDL
269SDL_MIXER_LIBS = -lSDL_mixer -lSDL -lpthread
270SET_MAKE =
271SHELL = /bin/sh
272STRIP =
273VERSION = 1.0
274WINDRES =
275abs_builddir = /home/franklin/chocolate_duke3D/Game/src
276abs_srcdir = /home/franklin/chocolate_duke3D/Game/src
277abs_top_builddir = /home/franklin/chocolate_duke3D
278abs_top_srcdir = /home/franklin/chocolate_duke3D
279ac_ct_CC = gcc
280am__include = include
281am__leading_dot = .
282am__quote =
283am__tar = $${TAR-tar} chof - "$$tardir"
284am__untar = $${TAR-tar} xf -
285bindir = ${exec_prefix}/bin
286build_alias =
287builddir = .
288datadir = ${datarootdir}
289datarootdir = ${prefix}/share
290docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
291dvidir = ${docdir}
292exec_prefix = ${prefix}
293host_alias =
294htmldir = ${docdir}
295includedir = ${prefix}/include
296infodir = ${datarootdir}/info
297install_sh = ${SHELL} /home/franklin/chocolate_duke3D/build-aux/install-sh
298libdir = ${exec_prefix}/lib
299libexecdir = ${exec_prefix}/libexec
300localedir = ${datarootdir}/locale
301localstatedir = ${prefix}/var
302mandir = ${datarootdir}/man
303mkdir_p = $(MKDIR_P)
304oldincludedir = /usr/include
305pdfdir = ${docdir}
306prefix = /usr/local
307program_transform_name = s,x,x,
308psdir = ${docdir}
309sbindir = ${exec_prefix}/sbin
310sharedstatedir = ${prefix}/com
311srcdir = .
312sysconfdir = ${prefix}/etc
313target_alias =
314top_build_prefix = ../../
315top_builddir = ../..
316top_srcdir = ../..
317SUBDIRS = audiolib midi
318noinst_LIBRARIES = libGame.a
319libGame_a_SOURCES = \
320 actors.c animlib.c config.c console.c control.c cvar_defs.c cvars.c dummy_audiolib.c game.c \
321 gamedef.c global.c keyboard.c menues.c player.c rts.c scriplib.c sector.c sounds.c
322
323libGame_a_LIBADD = premap.o
324libGame_a_CFLAGS = -I$(top_srcdir)/Engine/src
325all: all-recursive
326
327.SUFFIXES:
328.SUFFIXES: .c .o .obj
329$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
330 @for dep in $?; do \
331 case '$(am__configure_deps)' in \
332 *$$dep*) \
333 ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
334 && { if test -f $@; then exit 0; else break; fi; }; \
335 exit 1;; \
336 esac; \
337 done; \
338 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Game/src/Makefile'; \
339 $(am__cd) $(top_srcdir) && \
340 $(AUTOMAKE) --foreign Game/src/Makefile
341Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
342 @case '$?' in \
343 *config.status*) \
344 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
345 *) \
346 echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
347 cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
348 esac;
349
350$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
351 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
352
353$(top_srcdir)/configure: $(am__configure_deps)
354 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
355$(ACLOCAL_M4): $(am__aclocal_m4_deps)
356 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
357$(am__aclocal_m4_deps):
358
359clean-noinstLIBRARIES:
360 -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
361
362libGame.a: $(libGame_a_OBJECTS) $(libGame_a_DEPENDENCIES) $(EXTRA_libGame_a_DEPENDENCIES)
363 $(AM_V_at)-rm -f libGame.a
364 $(AM_V_AR)$(libGame_a_AR) libGame.a $(libGame_a_OBJECTS) $(libGame_a_LIBADD)
365 $(AM_V_at)$(RANLIB) libGame.a
366
367mostlyclean-compile:
368 -rm -f *.$(OBJEXT)
369
370distclean-compile:
371 -rm -f *.tab.c
372
373include ./$(DEPDIR)/libGame_a-actors.Po
374include ./$(DEPDIR)/libGame_a-animlib.Po
375include ./$(DEPDIR)/libGame_a-config.Po
376include ./$(DEPDIR)/libGame_a-console.Po
377include ./$(DEPDIR)/libGame_a-control.Po
378include ./$(DEPDIR)/libGame_a-cvar_defs.Po
379include ./$(DEPDIR)/libGame_a-cvars.Po
380include ./$(DEPDIR)/libGame_a-dummy_audiolib.Po
381include ./$(DEPDIR)/libGame_a-game.Po
382include ./$(DEPDIR)/libGame_a-gamedef.Po
383include ./$(DEPDIR)/libGame_a-global.Po
384include ./$(DEPDIR)/libGame_a-keyboard.Po
385include ./$(DEPDIR)/libGame_a-menues.Po
386include ./$(DEPDIR)/libGame_a-player.Po
387include ./$(DEPDIR)/libGame_a-rts.Po
388include ./$(DEPDIR)/libGame_a-scriplib.Po
389include ./$(DEPDIR)/libGame_a-sector.Po
390include ./$(DEPDIR)/libGame_a-sounds.Po
391
392.c.o:
393 $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
394 $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
395# $(AM_V_CC)source='$<' object='$@' libtool=no \
396# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
397# $(AM_V_CC_no)$(COMPILE) -c -o $@ $<
398
399.c.obj:
400 $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
401 $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
402# $(AM_V_CC)source='$<' object='$@' libtool=no \
403# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
404# $(AM_V_CC_no)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
405
406libGame_a-actors.o: actors.c
407 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-actors.o -MD -MP -MF $(DEPDIR)/libGame_a-actors.Tpo -c -o libGame_a-actors.o `test -f 'actors.c' || echo '$(srcdir)/'`actors.c
408 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-actors.Tpo $(DEPDIR)/libGame_a-actors.Po
409# $(AM_V_CC)source='actors.c' object='libGame_a-actors.o' libtool=no \
410# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
411# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-actors.o `test -f 'actors.c' || echo '$(srcdir)/'`actors.c
412
413libGame_a-actors.obj: actors.c
414 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-actors.obj -MD -MP -MF $(DEPDIR)/libGame_a-actors.Tpo -c -o libGame_a-actors.obj `if test -f 'actors.c'; then $(CYGPATH_W) 'actors.c'; else $(CYGPATH_W) '$(srcdir)/actors.c'; fi`
415 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-actors.Tpo $(DEPDIR)/libGame_a-actors.Po
416# $(AM_V_CC)source='actors.c' object='libGame_a-actors.obj' libtool=no \
417# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
418# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-actors.obj `if test -f 'actors.c'; then $(CYGPATH_W) 'actors.c'; else $(CYGPATH_W) '$(srcdir)/actors.c'; fi`
419
420libGame_a-animlib.o: animlib.c
421 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-animlib.o -MD -MP -MF $(DEPDIR)/libGame_a-animlib.Tpo -c -o libGame_a-animlib.o `test -f 'animlib.c' || echo '$(srcdir)/'`animlib.c
422 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-animlib.Tpo $(DEPDIR)/libGame_a-animlib.Po
423# $(AM_V_CC)source='animlib.c' object='libGame_a-animlib.o' libtool=no \
424# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
425# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-animlib.o `test -f 'animlib.c' || echo '$(srcdir)/'`animlib.c
426
427libGame_a-animlib.obj: animlib.c
428 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-animlib.obj -MD -MP -MF $(DEPDIR)/libGame_a-animlib.Tpo -c -o libGame_a-animlib.obj `if test -f 'animlib.c'; then $(CYGPATH_W) 'animlib.c'; else $(CYGPATH_W) '$(srcdir)/animlib.c'; fi`
429 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-animlib.Tpo $(DEPDIR)/libGame_a-animlib.Po
430# $(AM_V_CC)source='animlib.c' object='libGame_a-animlib.obj' libtool=no \
431# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
432# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-animlib.obj `if test -f 'animlib.c'; then $(CYGPATH_W) 'animlib.c'; else $(CYGPATH_W) '$(srcdir)/animlib.c'; fi`
433
434libGame_a-config.o: config.c
435 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-config.o -MD -MP -MF $(DEPDIR)/libGame_a-config.Tpo -c -o libGame_a-config.o `test -f 'config.c' || echo '$(srcdir)/'`config.c
436 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-config.Tpo $(DEPDIR)/libGame_a-config.Po
437# $(AM_V_CC)source='config.c' object='libGame_a-config.o' libtool=no \
438# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
439# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-config.o `test -f 'config.c' || echo '$(srcdir)/'`config.c
440
441libGame_a-config.obj: config.c
442 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-config.obj -MD -MP -MF $(DEPDIR)/libGame_a-config.Tpo -c -o libGame_a-config.obj `if test -f 'config.c'; then $(CYGPATH_W) 'config.c'; else $(CYGPATH_W) '$(srcdir)/config.c'; fi`
443 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-config.Tpo $(DEPDIR)/libGame_a-config.Po
444# $(AM_V_CC)source='config.c' object='libGame_a-config.obj' libtool=no \
445# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
446# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-config.obj `if test -f 'config.c'; then $(CYGPATH_W) 'config.c'; else $(CYGPATH_W) '$(srcdir)/config.c'; fi`
447
448libGame_a-console.o: console.c
449 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-console.o -MD -MP -MF $(DEPDIR)/libGame_a-console.Tpo -c -o libGame_a-console.o `test -f 'console.c' || echo '$(srcdir)/'`console.c
450 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-console.Tpo $(DEPDIR)/libGame_a-console.Po
451# $(AM_V_CC)source='console.c' object='libGame_a-console.o' libtool=no \
452# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
453# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-console.o `test -f 'console.c' || echo '$(srcdir)/'`console.c
454
455libGame_a-console.obj: console.c
456 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-console.obj -MD -MP -MF $(DEPDIR)/libGame_a-console.Tpo -c -o libGame_a-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi`
457 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-console.Tpo $(DEPDIR)/libGame_a-console.Po
458# $(AM_V_CC)source='console.c' object='libGame_a-console.obj' libtool=no \
459# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
460# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi`
461
462libGame_a-control.o: control.c
463 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-control.o -MD -MP -MF $(DEPDIR)/libGame_a-control.Tpo -c -o libGame_a-control.o `test -f 'control.c' || echo '$(srcdir)/'`control.c
464 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-control.Tpo $(DEPDIR)/libGame_a-control.Po
465# $(AM_V_CC)source='control.c' object='libGame_a-control.o' libtool=no \
466# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
467# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-control.o `test -f 'control.c' || echo '$(srcdir)/'`control.c
468
469libGame_a-control.obj: control.c
470 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-control.obj -MD -MP -MF $(DEPDIR)/libGame_a-control.Tpo -c -o libGame_a-control.obj `if test -f 'control.c'; then $(CYGPATH_W) 'control.c'; else $(CYGPATH_W) '$(srcdir)/control.c'; fi`
471 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-control.Tpo $(DEPDIR)/libGame_a-control.Po
472# $(AM_V_CC)source='control.c' object='libGame_a-control.obj' libtool=no \
473# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
474# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-control.obj `if test -f 'control.c'; then $(CYGPATH_W) 'control.c'; else $(CYGPATH_W) '$(srcdir)/control.c'; fi`
475
476libGame_a-cvar_defs.o: cvar_defs.c
477 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-cvar_defs.o -MD -MP -MF $(DEPDIR)/libGame_a-cvar_defs.Tpo -c -o libGame_a-cvar_defs.o `test -f 'cvar_defs.c' || echo '$(srcdir)/'`cvar_defs.c
478 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-cvar_defs.Tpo $(DEPDIR)/libGame_a-cvar_defs.Po
479# $(AM_V_CC)source='cvar_defs.c' object='libGame_a-cvar_defs.o' libtool=no \
480# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
481# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-cvar_defs.o `test -f 'cvar_defs.c' || echo '$(srcdir)/'`cvar_defs.c
482
483libGame_a-cvar_defs.obj: cvar_defs.c
484 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-cvar_defs.obj -MD -MP -MF $(DEPDIR)/libGame_a-cvar_defs.Tpo -c -o libGame_a-cvar_defs.obj `if test -f 'cvar_defs.c'; then $(CYGPATH_W) 'cvar_defs.c'; else $(CYGPATH_W) '$(srcdir)/cvar_defs.c'; fi`
485 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-cvar_defs.Tpo $(DEPDIR)/libGame_a-cvar_defs.Po
486# $(AM_V_CC)source='cvar_defs.c' object='libGame_a-cvar_defs.obj' libtool=no \
487# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
488# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-cvar_defs.obj `if test -f 'cvar_defs.c'; then $(CYGPATH_W) 'cvar_defs.c'; else $(CYGPATH_W) '$(srcdir)/cvar_defs.c'; fi`
489
490libGame_a-cvars.o: cvars.c
491 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-cvars.o -MD -MP -MF $(DEPDIR)/libGame_a-cvars.Tpo -c -o libGame_a-cvars.o `test -f 'cvars.c' || echo '$(srcdir)/'`cvars.c
492 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-cvars.Tpo $(DEPDIR)/libGame_a-cvars.Po
493# $(AM_V_CC)source='cvars.c' object='libGame_a-cvars.o' libtool=no \
494# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
495# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-cvars.o `test -f 'cvars.c' || echo '$(srcdir)/'`cvars.c
496
497libGame_a-cvars.obj: cvars.c
498 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-cvars.obj -MD -MP -MF $(DEPDIR)/libGame_a-cvars.Tpo -c -o libGame_a-cvars.obj `if test -f 'cvars.c'; then $(CYGPATH_W) 'cvars.c'; else $(CYGPATH_W) '$(srcdir)/cvars.c'; fi`
499 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-cvars.Tpo $(DEPDIR)/libGame_a-cvars.Po
500# $(AM_V_CC)source='cvars.c' object='libGame_a-cvars.obj' libtool=no \
501# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
502# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-cvars.obj `if test -f 'cvars.c'; then $(CYGPATH_W) 'cvars.c'; else $(CYGPATH_W) '$(srcdir)/cvars.c'; fi`
503
504libGame_a-dummy_audiolib.o: dummy_audiolib.c
505 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-dummy_audiolib.o -MD -MP -MF $(DEPDIR)/libGame_a-dummy_audiolib.Tpo -c -o libGame_a-dummy_audiolib.o `test -f 'dummy_audiolib.c' || echo '$(srcdir)/'`dummy_audiolib.c
506 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-dummy_audiolib.Tpo $(DEPDIR)/libGame_a-dummy_audiolib.Po
507# $(AM_V_CC)source='dummy_audiolib.c' object='libGame_a-dummy_audiolib.o' libtool=no \
508# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
509# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-dummy_audiolib.o `test -f 'dummy_audiolib.c' || echo '$(srcdir)/'`dummy_audiolib.c
510
511libGame_a-dummy_audiolib.obj: dummy_audiolib.c
512 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-dummy_audiolib.obj -MD -MP -MF $(DEPDIR)/libGame_a-dummy_audiolib.Tpo -c -o libGame_a-dummy_audiolib.obj `if test -f 'dummy_audiolib.c'; then $(CYGPATH_W) 'dummy_audiolib.c'; else $(CYGPATH_W) '$(srcdir)/dummy_audiolib.c'; fi`
513 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-dummy_audiolib.Tpo $(DEPDIR)/libGame_a-dummy_audiolib.Po
514# $(AM_V_CC)source='dummy_audiolib.c' object='libGame_a-dummy_audiolib.obj' libtool=no \
515# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
516# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-dummy_audiolib.obj `if test -f 'dummy_audiolib.c'; then $(CYGPATH_W) 'dummy_audiolib.c'; else $(CYGPATH_W) '$(srcdir)/dummy_audiolib.c'; fi`
517
518libGame_a-game.o: game.c
519 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-game.o -MD -MP -MF $(DEPDIR)/libGame_a-game.Tpo -c -o libGame_a-game.o `test -f 'game.c' || echo '$(srcdir)/'`game.c
520 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-game.Tpo $(DEPDIR)/libGame_a-game.Po
521# $(AM_V_CC)source='game.c' object='libGame_a-game.o' libtool=no \
522# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
523# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-game.o `test -f 'game.c' || echo '$(srcdir)/'`game.c
524
525libGame_a-game.obj: game.c
526 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-game.obj -MD -MP -MF $(DEPDIR)/libGame_a-game.Tpo -c -o libGame_a-game.obj `if test -f 'game.c'; then $(CYGPATH_W) 'game.c'; else $(CYGPATH_W) '$(srcdir)/game.c'; fi`
527 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-game.Tpo $(DEPDIR)/libGame_a-game.Po
528# $(AM_V_CC)source='game.c' object='libGame_a-game.obj' libtool=no \
529# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
530# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-game.obj `if test -f 'game.c'; then $(CYGPATH_W) 'game.c'; else $(CYGPATH_W) '$(srcdir)/game.c'; fi`
531
532libGame_a-gamedef.o: gamedef.c
533 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-gamedef.o -MD -MP -MF $(DEPDIR)/libGame_a-gamedef.Tpo -c -o libGame_a-gamedef.o `test -f 'gamedef.c' || echo '$(srcdir)/'`gamedef.c
534 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-gamedef.Tpo $(DEPDIR)/libGame_a-gamedef.Po
535# $(AM_V_CC)source='gamedef.c' object='libGame_a-gamedef.o' libtool=no \
536# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
537# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-gamedef.o `test -f 'gamedef.c' || echo '$(srcdir)/'`gamedef.c
538
539libGame_a-gamedef.obj: gamedef.c
540 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-gamedef.obj -MD -MP -MF $(DEPDIR)/libGame_a-gamedef.Tpo -c -o libGame_a-gamedef.obj `if test -f 'gamedef.c'; then $(CYGPATH_W) 'gamedef.c'; else $(CYGPATH_W) '$(srcdir)/gamedef.c'; fi`
541 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-gamedef.Tpo $(DEPDIR)/libGame_a-gamedef.Po
542# $(AM_V_CC)source='gamedef.c' object='libGame_a-gamedef.obj' libtool=no \
543# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
544# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-gamedef.obj `if test -f 'gamedef.c'; then $(CYGPATH_W) 'gamedef.c'; else $(CYGPATH_W) '$(srcdir)/gamedef.c'; fi`
545
546libGame_a-global.o: global.c
547 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-global.o -MD -MP -MF $(DEPDIR)/libGame_a-global.Tpo -c -o libGame_a-global.o `test -f 'global.c' || echo '$(srcdir)/'`global.c
548 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-global.Tpo $(DEPDIR)/libGame_a-global.Po
549# $(AM_V_CC)source='global.c' object='libGame_a-global.o' libtool=no \
550# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
551# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-global.o `test -f 'global.c' || echo '$(srcdir)/'`global.c
552
553libGame_a-global.obj: global.c
554 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-global.obj -MD -MP -MF $(DEPDIR)/libGame_a-global.Tpo -c -o libGame_a-global.obj `if test -f 'global.c'; then $(CYGPATH_W) 'global.c'; else $(CYGPATH_W) '$(srcdir)/global.c'; fi`
555 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-global.Tpo $(DEPDIR)/libGame_a-global.Po
556# $(AM_V_CC)source='global.c' object='libGame_a-global.obj' libtool=no \
557# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
558# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-global.obj `if test -f 'global.c'; then $(CYGPATH_W) 'global.c'; else $(CYGPATH_W) '$(srcdir)/global.c'; fi`
559
560libGame_a-keyboard.o: keyboard.c
561 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-keyboard.o -MD -MP -MF $(DEPDIR)/libGame_a-keyboard.Tpo -c -o libGame_a-keyboard.o `test -f 'keyboard.c' || echo '$(srcdir)/'`keyboard.c
562 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-keyboard.Tpo $(DEPDIR)/libGame_a-keyboard.Po
563# $(AM_V_CC)source='keyboard.c' object='libGame_a-keyboard.o' libtool=no \
564# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
565# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-keyboard.o `test -f 'keyboard.c' || echo '$(srcdir)/'`keyboard.c
566
567libGame_a-keyboard.obj: keyboard.c
568 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-keyboard.obj -MD -MP -MF $(DEPDIR)/libGame_a-keyboard.Tpo -c -o libGame_a-keyboard.obj `if test -f 'keyboard.c'; then $(CYGPATH_W) 'keyboard.c'; else $(CYGPATH_W) '$(srcdir)/keyboard.c'; fi`
569 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-keyboard.Tpo $(DEPDIR)/libGame_a-keyboard.Po
570# $(AM_V_CC)source='keyboard.c' object='libGame_a-keyboard.obj' libtool=no \
571# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
572# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-keyboard.obj `if test -f 'keyboard.c'; then $(CYGPATH_W) 'keyboard.c'; else $(CYGPATH_W) '$(srcdir)/keyboard.c'; fi`
573
574libGame_a-menues.o: menues.c
575 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-menues.o -MD -MP -MF $(DEPDIR)/libGame_a-menues.Tpo -c -o libGame_a-menues.o `test -f 'menues.c' || echo '$(srcdir)/'`menues.c
576 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-menues.Tpo $(DEPDIR)/libGame_a-menues.Po
577# $(AM_V_CC)source='menues.c' object='libGame_a-menues.o' libtool=no \
578# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
579# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-menues.o `test -f 'menues.c' || echo '$(srcdir)/'`menues.c
580
581libGame_a-menues.obj: menues.c
582 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-menues.obj -MD -MP -MF $(DEPDIR)/libGame_a-menues.Tpo -c -o libGame_a-menues.obj `if test -f 'menues.c'; then $(CYGPATH_W) 'menues.c'; else $(CYGPATH_W) '$(srcdir)/menues.c'; fi`
583 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-menues.Tpo $(DEPDIR)/libGame_a-menues.Po
584# $(AM_V_CC)source='menues.c' object='libGame_a-menues.obj' libtool=no \
585# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
586# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-menues.obj `if test -f 'menues.c'; then $(CYGPATH_W) 'menues.c'; else $(CYGPATH_W) '$(srcdir)/menues.c'; fi`
587
588libGame_a-player.o: player.c
589 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-player.o -MD -MP -MF $(DEPDIR)/libGame_a-player.Tpo -c -o libGame_a-player.o `test -f 'player.c' || echo '$(srcdir)/'`player.c
590 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-player.Tpo $(DEPDIR)/libGame_a-player.Po
591# $(AM_V_CC)source='player.c' object='libGame_a-player.o' libtool=no \
592# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
593# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-player.o `test -f 'player.c' || echo '$(srcdir)/'`player.c
594
595libGame_a-player.obj: player.c
596 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-player.obj -MD -MP -MF $(DEPDIR)/libGame_a-player.Tpo -c -o libGame_a-player.obj `if test -f 'player.c'; then $(CYGPATH_W) 'player.c'; else $(CYGPATH_W) '$(srcdir)/player.c'; fi`
597 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-player.Tpo $(DEPDIR)/libGame_a-player.Po
598# $(AM_V_CC)source='player.c' object='libGame_a-player.obj' libtool=no \
599# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
600# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-player.obj `if test -f 'player.c'; then $(CYGPATH_W) 'player.c'; else $(CYGPATH_W) '$(srcdir)/player.c'; fi`
601
602libGame_a-rts.o: rts.c
603 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-rts.o -MD -MP -MF $(DEPDIR)/libGame_a-rts.Tpo -c -o libGame_a-rts.o `test -f 'rts.c' || echo '$(srcdir)/'`rts.c
604 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-rts.Tpo $(DEPDIR)/libGame_a-rts.Po
605# $(AM_V_CC)source='rts.c' object='libGame_a-rts.o' libtool=no \
606# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
607# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-rts.o `test -f 'rts.c' || echo '$(srcdir)/'`rts.c
608
609libGame_a-rts.obj: rts.c
610 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-rts.obj -MD -MP -MF $(DEPDIR)/libGame_a-rts.Tpo -c -o libGame_a-rts.obj `if test -f 'rts.c'; then $(CYGPATH_W) 'rts.c'; else $(CYGPATH_W) '$(srcdir)/rts.c'; fi`
611 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-rts.Tpo $(DEPDIR)/libGame_a-rts.Po
612# $(AM_V_CC)source='rts.c' object='libGame_a-rts.obj' libtool=no \
613# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
614# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-rts.obj `if test -f 'rts.c'; then $(CYGPATH_W) 'rts.c'; else $(CYGPATH_W) '$(srcdir)/rts.c'; fi`
615
616libGame_a-scriplib.o: scriplib.c
617 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-scriplib.o -MD -MP -MF $(DEPDIR)/libGame_a-scriplib.Tpo -c -o libGame_a-scriplib.o `test -f 'scriplib.c' || echo '$(srcdir)/'`scriplib.c
618 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-scriplib.Tpo $(DEPDIR)/libGame_a-scriplib.Po
619# $(AM_V_CC)source='scriplib.c' object='libGame_a-scriplib.o' libtool=no \
620# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
621# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-scriplib.o `test -f 'scriplib.c' || echo '$(srcdir)/'`scriplib.c
622
623libGame_a-scriplib.obj: scriplib.c
624 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-scriplib.obj -MD -MP -MF $(DEPDIR)/libGame_a-scriplib.Tpo -c -o libGame_a-scriplib.obj `if test -f 'scriplib.c'; then $(CYGPATH_W) 'scriplib.c'; else $(CYGPATH_W) '$(srcdir)/scriplib.c'; fi`
625 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-scriplib.Tpo $(DEPDIR)/libGame_a-scriplib.Po
626# $(AM_V_CC)source='scriplib.c' object='libGame_a-scriplib.obj' libtool=no \
627# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
628# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-scriplib.obj `if test -f 'scriplib.c'; then $(CYGPATH_W) 'scriplib.c'; else $(CYGPATH_W) '$(srcdir)/scriplib.c'; fi`
629
630libGame_a-sector.o: sector.c
631 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-sector.o -MD -MP -MF $(DEPDIR)/libGame_a-sector.Tpo -c -o libGame_a-sector.o `test -f 'sector.c' || echo '$(srcdir)/'`sector.c
632 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-sector.Tpo $(DEPDIR)/libGame_a-sector.Po
633# $(AM_V_CC)source='sector.c' object='libGame_a-sector.o' libtool=no \
634# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
635# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-sector.o `test -f 'sector.c' || echo '$(srcdir)/'`sector.c
636
637libGame_a-sector.obj: sector.c
638 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-sector.obj -MD -MP -MF $(DEPDIR)/libGame_a-sector.Tpo -c -o libGame_a-sector.obj `if test -f 'sector.c'; then $(CYGPATH_W) 'sector.c'; else $(CYGPATH_W) '$(srcdir)/sector.c'; fi`
639 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-sector.Tpo $(DEPDIR)/libGame_a-sector.Po
640# $(AM_V_CC)source='sector.c' object='libGame_a-sector.obj' libtool=no \
641# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
642# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-sector.obj `if test -f 'sector.c'; then $(CYGPATH_W) 'sector.c'; else $(CYGPATH_W) '$(srcdir)/sector.c'; fi`
643
644libGame_a-sounds.o: sounds.c
645 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-sounds.o -MD -MP -MF $(DEPDIR)/libGame_a-sounds.Tpo -c -o libGame_a-sounds.o `test -f 'sounds.c' || echo '$(srcdir)/'`sounds.c
646 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-sounds.Tpo $(DEPDIR)/libGame_a-sounds.Po
647# $(AM_V_CC)source='sounds.c' object='libGame_a-sounds.o' libtool=no \
648# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
649# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-sounds.o `test -f 'sounds.c' || echo '$(srcdir)/'`sounds.c
650
651libGame_a-sounds.obj: sounds.c
652 $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-sounds.obj -MD -MP -MF $(DEPDIR)/libGame_a-sounds.Tpo -c -o libGame_a-sounds.obj `if test -f 'sounds.c'; then $(CYGPATH_W) 'sounds.c'; else $(CYGPATH_W) '$(srcdir)/sounds.c'; fi`
653 $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-sounds.Tpo $(DEPDIR)/libGame_a-sounds.Po
654# $(AM_V_CC)source='sounds.c' object='libGame_a-sounds.obj' libtool=no \
655# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
656# $(AM_V_CC_no)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-sounds.obj `if test -f 'sounds.c'; then $(CYGPATH_W) 'sounds.c'; else $(CYGPATH_W) '$(srcdir)/sounds.c'; fi`
657
658# This directory's subdirectories are mostly independent; you can cd
659# into them and run 'make' without going through this Makefile.
660# To change the values of 'make' variables: instead of editing Makefiles,
661# (1) if the variable is set in 'config.status', edit 'config.status'
662# (which will cause the Makefiles to be regenerated when you run 'make');
663# (2) otherwise, pass the desired values on the 'make' command line.
664$(am__recursive_targets):
665 @fail=; \
666 if $(am__make_keepgoing); then \
667 failcom='fail=yes'; \
668 else \
669 failcom='exit 1'; \
670 fi; \
671 dot_seen=no; \
672 target=`echo $@ | sed s/-recursive//`; \
673 case "$@" in \
674 distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
675 *) list='$(SUBDIRS)' ;; \
676 esac; \
677 for subdir in $$list; do \
678 echo "Making $$target in $$subdir"; \
679 if test "$$subdir" = "."; then \
680 dot_seen=yes; \
681 local_target="$$target-am"; \
682 else \
683 local_target="$$target"; \
684 fi; \
685 ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
686 || eval $$failcom; \
687 done; \
688 if test "$$dot_seen" = "no"; then \
689 $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
690 fi; test -z "$$fail"
691
692ID: $(am__tagged_files)
693 $(am__define_uniq_tagged_files); mkid -fID $$unique
694tags: tags-recursive
695TAGS: tags
696
697tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
698 set x; \
699 here=`pwd`; \
700 if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
701 include_option=--etags-include; \
702 empty_fix=.; \
703 else \
704 include_option=--include; \
705 empty_fix=; \
706 fi; \
707 list='$(SUBDIRS)'; for subdir in $$list; do \
708 if test "$$subdir" = .; then :; else \
709 test ! -f $$subdir/TAGS || \
710 set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
711 fi; \
712 done; \
713 $(am__define_uniq_tagged_files); \
714 shift; \
715 if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
716 test -n "$$unique" || unique=$$empty_fix; \
717 if test $$# -gt 0; then \
718 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
719 "$$@" $$unique; \
720 else \
721 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
722 $$unique; \
723 fi; \
724 fi
725ctags: ctags-recursive
726
727CTAGS: ctags
728ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
729 $(am__define_uniq_tagged_files); \
730 test -z "$(CTAGS_ARGS)$$unique" \
731 || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
732 $$unique
733
734GTAGS:
735 here=`$(am__cd) $(top_builddir) && pwd` \
736 && $(am__cd) $(top_srcdir) \
737 && gtags -i $(GTAGS_ARGS) "$$here"
738cscopelist: cscopelist-recursive
739
740cscopelist-am: $(am__tagged_files)
741 list='$(am__tagged_files)'; \
742 case "$(srcdir)" in \
743 [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
744 *) sdir=$(subdir)/$(srcdir) ;; \
745 esac; \
746 for i in $$list; do \
747 if test -f "$$i"; then \
748 echo "$(subdir)/$$i"; \
749 else \
750 echo "$$sdir/$$i"; \
751 fi; \
752 done >> $(top_builddir)/cscope.files
753
754distclean-tags:
755 -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
756
757distdir: $(DISTFILES)
758 @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
759 topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
760 list='$(DISTFILES)'; \
761 dist_files=`for file in $$list; do echo $$file; done | \
762 sed -e "s|^$$srcdirstrip/||;t" \
763 -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
764 case $$dist_files in \
765 */*) $(MKDIR_P) `echo "$$dist_files" | \
766 sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
767 sort -u` ;; \
768 esac; \
769 for file in $$dist_files; do \
770 if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
771 if test -d $$d/$$file; then \
772 dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
773 if test -d "$(distdir)/$$file"; then \
774 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
775 fi; \
776 if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
777 cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
778 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
779 fi; \
780 cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
781 else \
782 test -f "$(distdir)/$$file" \
783 || cp -p $$d/$$file "$(distdir)/$$file" \
784 || exit 1; \
785 fi; \
786 done
787 @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
788 if test "$$subdir" = .; then :; else \
789 $(am__make_dryrun) \
790 || test -d "$(distdir)/$$subdir" \
791 || $(MKDIR_P) "$(distdir)/$$subdir" \
792 || exit 1; \
793 dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
794 $(am__relativize); \
795 new_distdir=$$reldir; \
796 dir1=$$subdir; dir2="$(top_distdir)"; \
797 $(am__relativize); \
798 new_top_distdir=$$reldir; \
799 echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
800 echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
801 ($(am__cd) $$subdir && \
802 $(MAKE) $(AM_MAKEFLAGS) \
803 top_distdir="$$new_top_distdir" \
804 distdir="$$new_distdir" \
805 am__remove_distdir=: \
806 am__skip_length_check=: \
807 am__skip_mode_fix=: \
808 distdir) \
809 || exit 1; \
810 fi; \
811 done
812check-am: all-am
813check: check-recursive
814all-am: Makefile $(LIBRARIES)
815installdirs: installdirs-recursive
816installdirs-am:
817install: install-recursive
818install-exec: install-exec-recursive
819install-data: install-data-recursive
820uninstall: uninstall-recursive
821
822install-am: all-am
823 @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
824
825installcheck: installcheck-recursive
826install-strip:
827 if test -z '$(STRIP)'; then \
828 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
829 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
830 install; \
831 else \
832 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
833 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
834 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
835 fi
836mostlyclean-generic:
837
838clean-generic:
839
840distclean-generic:
841 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
842 -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
843
844maintainer-clean-generic:
845 @echo "This command is intended for maintainers to use"
846 @echo "it deletes files that may require special tools to rebuild."
847clean: clean-recursive
848
849clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
850
851distclean: distclean-recursive
852 -rm -rf ./$(DEPDIR)
853 -rm -f Makefile
854distclean-am: clean-am distclean-compile distclean-generic \
855 distclean-tags
856
857dvi: dvi-recursive
858
859dvi-am:
860
861html: html-recursive
862
863html-am:
864
865info: info-recursive
866
867info-am:
868
869install-data-am:
870
871install-dvi: install-dvi-recursive
872
873install-dvi-am:
874
875install-exec-am:
876
877install-html: install-html-recursive
878
879install-html-am:
880
881install-info: install-info-recursive
882
883install-info-am:
884
885install-man:
886
887install-pdf: install-pdf-recursive
888
889install-pdf-am:
890
891install-ps: install-ps-recursive
892
893install-ps-am:
894
895installcheck-am:
896
897maintainer-clean: maintainer-clean-recursive
898 -rm -rf ./$(DEPDIR)
899 -rm -f Makefile
900maintainer-clean-am: distclean-am maintainer-clean-generic
901
902mostlyclean: mostlyclean-recursive
903
904mostlyclean-am: mostlyclean-compile mostlyclean-generic
905
906pdf: pdf-recursive
907
908pdf-am:
909
910ps: ps-recursive
911
912ps-am:
913
914uninstall-am:
915
916.MAKE: $(am__recursive_targets) install-am install-strip
917
918.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
919 check-am clean clean-generic clean-noinstLIBRARIES \
920 cscopelist-am ctags ctags-am distclean distclean-compile \
921 distclean-generic distclean-tags distdir dvi dvi-am html \
922 html-am info info-am install install-am install-data \
923 install-data-am install-dvi install-dvi-am install-exec \
924 install-exec-am install-html install-html-am install-info \
925 install-info-am install-man install-pdf install-pdf-am \
926 install-ps install-ps-am install-strip installcheck \
927 installcheck-am installdirs installdirs-am maintainer-clean \
928 maintainer-clean-generic mostlyclean mostlyclean-compile \
929 mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
930 uninstall-am
931
932.PRECIOUS: Makefile
933
934
935# Starting a new game will lead to a crash if premap.o was built with -O1/-O2/-O3,
936# that's why we're compiling it seperately with -O0
937premap.o: premap.c
938 $(AM_V_CC)$(CC) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -I$(top_srcdir)/Engine/src -O0 -c $^ -o $@
939
940# Tell versions [3.59,3.63) of GNU make to not export all variables.
941# Otherwise a system limit (for SysV at least) may be exceeded.
942.NOEXPORT:
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/Makefile.am b/apps/plugins/sdl/progs/duke3d/Game/src/Makefile.am
new file mode 100644
index 0000000000..78af7efb8d
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/Makefile.am
@@ -0,0 +1,14 @@
1SUBDIRS = audiolib midi
2
3noinst_LIBRARIES = libGame.a
4
5libGame_a_SOURCES = \
6 actors.c animlib.c config.c console.c control.c cvar_defs.c cvars.c dummy_audiolib.c game.c \
7 gamedef.c global.c keyboard.c menues.c player.c rts.c scriplib.c sector.c sounds.c
8libGame_a_LIBADD = premap.o
9libGame_a_CFLAGS = -I$(top_srcdir)/Engine/src
10
11# Starting a new game will lead to a crash if premap.o was built with -O1/-O2/-O3,
12# that's why we're compiling it seperately with -O0
13premap.o: premap.c
14 $(AM_V_CC)$(CC) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -I$(top_srcdir)/Engine/src -O0 -c $^ -o $@
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/Makefile.in b/apps/plugins/sdl/progs/duke3d/Game/src/Makefile.in
new file mode 100644
index 0000000000..8da6d6e357
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/Makefile.in
@@ -0,0 +1,942 @@
1# Makefile.in generated by automake 1.15.1 from Makefile.am.
2# @configure_input@
3
4# Copyright (C) 1994-2017 Free Software Foundation, Inc.
5
6# This Makefile.in is free software; the Free Software Foundation
7# gives unlimited permission to copy and/or distribute it,
8# with or without modifications, as long as this notice is preserved.
9
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
12# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13# PARTICULAR PURPOSE.
14
15@SET_MAKE@
16
17VPATH = @srcdir@
18am__is_gnu_make = { \
19 if test -z '$(MAKELEVEL)'; then \
20 false; \
21 elif test -n '$(MAKE_HOST)'; then \
22 true; \
23 elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
24 true; \
25 else \
26 false; \
27 fi; \
28}
29am__make_running_with_option = \
30 case $${target_option-} in \
31 ?) ;; \
32 *) echo "am__make_running_with_option: internal error: invalid" \
33 "target option '$${target_option-}' specified" >&2; \
34 exit 1;; \
35 esac; \
36 has_opt=no; \
37 sane_makeflags=$$MAKEFLAGS; \
38 if $(am__is_gnu_make); then \
39 sane_makeflags=$$MFLAGS; \
40 else \
41 case $$MAKEFLAGS in \
42 *\\[\ \ ]*) \
43 bs=\\; \
44 sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
45 | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
46 esac; \
47 fi; \
48 skip_next=no; \
49 strip_trailopt () \
50 { \
51 flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
52 }; \
53 for flg in $$sane_makeflags; do \
54 test $$skip_next = yes && { skip_next=no; continue; }; \
55 case $$flg in \
56 *=*|--*) continue;; \
57 -*I) strip_trailopt 'I'; skip_next=yes;; \
58 -*I?*) strip_trailopt 'I';; \
59 -*O) strip_trailopt 'O'; skip_next=yes;; \
60 -*O?*) strip_trailopt 'O';; \
61 -*l) strip_trailopt 'l'; skip_next=yes;; \
62 -*l?*) strip_trailopt 'l';; \
63 -[dEDm]) skip_next=yes;; \
64 -[JT]) skip_next=yes;; \
65 esac; \
66 case $$flg in \
67 *$$target_option*) has_opt=yes; break;; \
68 esac; \
69 done; \
70 test $$has_opt = yes
71am__make_dryrun = (target_option=n; $(am__make_running_with_option))
72am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
73pkgdatadir = $(datadir)/@PACKAGE@
74pkgincludedir = $(includedir)/@PACKAGE@
75pkglibdir = $(libdir)/@PACKAGE@
76pkglibexecdir = $(libexecdir)/@PACKAGE@
77am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
78install_sh_DATA = $(install_sh) -c -m 644
79install_sh_PROGRAM = $(install_sh) -c
80install_sh_SCRIPT = $(install_sh) -c
81INSTALL_HEADER = $(INSTALL_DATA)
82transform = $(program_transform_name)
83NORMAL_INSTALL = :
84PRE_INSTALL = :
85POST_INSTALL = :
86NORMAL_UNINSTALL = :
87PRE_UNINSTALL = :
88POST_UNINSTALL = :
89subdir = Game/src
90ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
91am__aclocal_m4_deps = $(top_srcdir)/configure.ac
92am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
93 $(ACLOCAL_M4)
94DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
95mkinstalldirs = $(install_sh) -d
96CONFIG_CLEAN_FILES =
97CONFIG_CLEAN_VPATH_FILES =
98LIBRARIES = $(noinst_LIBRARIES)
99AR = ar
100ARFLAGS = cru
101AM_V_AR = $(am__v_AR_@AM_V@)
102am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
103am__v_AR_0 = @echo " AR " $@;
104am__v_AR_1 =
105libGame_a_AR = $(AR) $(ARFLAGS)
106libGame_a_DEPENDENCIES = premap.o
107am_libGame_a_OBJECTS = libGame_a-actors.$(OBJEXT) \
108 libGame_a-animlib.$(OBJEXT) libGame_a-config.$(OBJEXT) \
109 libGame_a-console.$(OBJEXT) libGame_a-control.$(OBJEXT) \
110 libGame_a-cvar_defs.$(OBJEXT) libGame_a-cvars.$(OBJEXT) \
111 libGame_a-dummy_audiolib.$(OBJEXT) libGame_a-game.$(OBJEXT) \
112 libGame_a-gamedef.$(OBJEXT) libGame_a-global.$(OBJEXT) \
113 libGame_a-keyboard.$(OBJEXT) libGame_a-menues.$(OBJEXT) \
114 libGame_a-player.$(OBJEXT) libGame_a-rts.$(OBJEXT) \
115 libGame_a-scriplib.$(OBJEXT) libGame_a-sector.$(OBJEXT) \
116 libGame_a-sounds.$(OBJEXT)
117libGame_a_OBJECTS = $(am_libGame_a_OBJECTS)
118AM_V_P = $(am__v_P_@AM_V@)
119am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
120am__v_P_0 = false
121am__v_P_1 = :
122AM_V_GEN = $(am__v_GEN_@AM_V@)
123am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
124am__v_GEN_0 = @echo " GEN " $@;
125am__v_GEN_1 =
126AM_V_at = $(am__v_at_@AM_V@)
127am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
128am__v_at_0 = @
129am__v_at_1 =
130DEFAULT_INCLUDES = -I.@am__isrc@
131depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
132am__depfiles_maybe = depfiles
133am__mv = mv -f
134AM_V_lt = $(am__v_lt_@AM_V@)
135am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
136am__v_lt_0 = --silent
137am__v_lt_1 =
138COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
139 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
140AM_V_CC = $(am__v_CC_@AM_V@)
141am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
142am__v_CC_0 = @echo " CC " $@;
143am__v_CC_1 =
144CCLD = $(CC)
145LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
146AM_V_CCLD = $(am__v_CCLD_@AM_V@)
147am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
148am__v_CCLD_0 = @echo " CCLD " $@;
149am__v_CCLD_1 =
150SOURCES = $(libGame_a_SOURCES)
151DIST_SOURCES = $(libGame_a_SOURCES)
152RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
153 ctags-recursive dvi-recursive html-recursive info-recursive \
154 install-data-recursive install-dvi-recursive \
155 install-exec-recursive install-html-recursive \
156 install-info-recursive install-pdf-recursive \
157 install-ps-recursive install-recursive installcheck-recursive \
158 installdirs-recursive pdf-recursive ps-recursive \
159 tags-recursive uninstall-recursive
160am__can_run_installinfo = \
161 case $$AM_UPDATE_INFO_DIR in \
162 n|no|NO) false;; \
163 *) (install-info --version) >/dev/null 2>&1;; \
164 esac
165RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
166 distclean-recursive maintainer-clean-recursive
167am__recursive_targets = \
168 $(RECURSIVE_TARGETS) \
169 $(RECURSIVE_CLEAN_TARGETS) \
170 $(am__extra_recursive_targets)
171AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
172 distdir
173am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
174# Read a list of newline-separated strings from the standard input,
175# and print each of them once, without duplicates. Input order is
176# *not* preserved.
177am__uniquify_input = $(AWK) '\
178 BEGIN { nonempty = 0; } \
179 { items[$$0] = 1; nonempty = 1; } \
180 END { if (nonempty) { for (i in items) print i; }; } \
181'
182# Make sure the list of sources is unique. This is necessary because,
183# e.g., the same source file might be shared among _SOURCES variables
184# for different programs/libraries.
185am__define_uniq_tagged_files = \
186 list='$(am__tagged_files)'; \
187 unique=`for i in $$list; do \
188 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
189 done | $(am__uniquify_input)`
190ETAGS = etags
191CTAGS = ctags
192DIST_SUBDIRS = $(SUBDIRS)
193am__DIST_COMMON = $(srcdir)/Makefile.in \
194 $(top_srcdir)/build-aux/depcomp
195DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
196am__relativize = \
197 dir0=`pwd`; \
198 sed_first='s,^\([^/]*\)/.*$$,\1,'; \
199 sed_rest='s,^[^/]*/*,,'; \
200 sed_last='s,^.*/\([^/]*\)$$,\1,'; \
201 sed_butlast='s,/*[^/]*$$,,'; \
202 while test -n "$$dir1"; do \
203 first=`echo "$$dir1" | sed -e "$$sed_first"`; \
204 if test "$$first" != "."; then \
205 if test "$$first" = ".."; then \
206 dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
207 dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
208 else \
209 first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
210 if test "$$first2" = "$$first"; then \
211 dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
212 else \
213 dir2="../$$dir2"; \
214 fi; \
215 dir0="$$dir0"/"$$first"; \
216 fi; \
217 fi; \
218 dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
219 done; \
220 reldir="$$dir2"
221ACLOCAL = @ACLOCAL@
222AMTAR = @AMTAR@
223AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
224AUTOCONF = @AUTOCONF@
225AUTOHEADER = @AUTOHEADER@
226AUTOMAKE = @AUTOMAKE@
227AWK = @AWK@
228CC = @CC@
229CCDEPMODE = @CCDEPMODE@
230CFLAGS = @CFLAGS@
231CPP = @CPP@
232CPPFLAGS = @CPPFLAGS@
233CYGPATH_W = @CYGPATH_W@
234DEFS = @DEFS@
235DEPDIR = @DEPDIR@
236ECHO_C = @ECHO_C@
237ECHO_N = @ECHO_N@
238ECHO_T = @ECHO_T@
239EGREP = @EGREP@
240EXEEXT = @EXEEXT@
241GREP = @GREP@
242INSTALL = @INSTALL@
243INSTALL_DATA = @INSTALL_DATA@
244INSTALL_PROGRAM = @INSTALL_PROGRAM@
245INSTALL_SCRIPT = @INSTALL_SCRIPT@
246INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
247LDFLAGS = @LDFLAGS@
248LIBOBJS = @LIBOBJS@
249LIBS = @LIBS@
250LTLIBOBJS = @LTLIBOBJS@
251MAKEINFO = @MAKEINFO@
252MKDIR_P = @MKDIR_P@
253OBJEXT = @OBJEXT@
254PACKAGE = @PACKAGE@
255PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
256PACKAGE_NAME = @PACKAGE_NAME@
257PACKAGE_STRING = @PACKAGE_STRING@
258PACKAGE_TARNAME = @PACKAGE_TARNAME@
259PACKAGE_URL = @PACKAGE_URL@
260PACKAGE_VERSION = @PACKAGE_VERSION@
261PATH_SEPARATOR = @PATH_SEPARATOR@
262PKG_CONFIG = @PKG_CONFIG@
263PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
264PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
265RANLIB = @RANLIB@
266SDL_CFLAGS = @SDL_CFLAGS@
267SDL_LIBS = @SDL_LIBS@
268SDL_MIXER_CFLAGS = @SDL_MIXER_CFLAGS@
269SDL_MIXER_LIBS = @SDL_MIXER_LIBS@
270SET_MAKE = @SET_MAKE@
271SHELL = @SHELL@
272STRIP = @STRIP@
273VERSION = @VERSION@
274WINDRES = @WINDRES@
275abs_builddir = @abs_builddir@
276abs_srcdir = @abs_srcdir@
277abs_top_builddir = @abs_top_builddir@
278abs_top_srcdir = @abs_top_srcdir@
279ac_ct_CC = @ac_ct_CC@
280am__include = @am__include@
281am__leading_dot = @am__leading_dot@
282am__quote = @am__quote@
283am__tar = @am__tar@
284am__untar = @am__untar@
285bindir = @bindir@
286build_alias = @build_alias@
287builddir = @builddir@
288datadir = @datadir@
289datarootdir = @datarootdir@
290docdir = @docdir@
291dvidir = @dvidir@
292exec_prefix = @exec_prefix@
293host_alias = @host_alias@
294htmldir = @htmldir@
295includedir = @includedir@
296infodir = @infodir@
297install_sh = @install_sh@
298libdir = @libdir@
299libexecdir = @libexecdir@
300localedir = @localedir@
301localstatedir = @localstatedir@
302mandir = @mandir@
303mkdir_p = @mkdir_p@
304oldincludedir = @oldincludedir@
305pdfdir = @pdfdir@
306prefix = @prefix@
307program_transform_name = @program_transform_name@
308psdir = @psdir@
309sbindir = @sbindir@
310sharedstatedir = @sharedstatedir@
311srcdir = @srcdir@
312sysconfdir = @sysconfdir@
313target_alias = @target_alias@
314top_build_prefix = @top_build_prefix@
315top_builddir = @top_builddir@
316top_srcdir = @top_srcdir@
317SUBDIRS = audiolib midi
318noinst_LIBRARIES = libGame.a
319libGame_a_SOURCES = \
320 actors.c animlib.c config.c console.c control.c cvar_defs.c cvars.c dummy_audiolib.c game.c \
321 gamedef.c global.c keyboard.c menues.c player.c rts.c scriplib.c sector.c sounds.c
322
323libGame_a_LIBADD = premap.o
324libGame_a_CFLAGS = -I$(top_srcdir)/Engine/src
325all: all-recursive
326
327.SUFFIXES:
328.SUFFIXES: .c .o .obj
329$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
330 @for dep in $?; do \
331 case '$(am__configure_deps)' in \
332 *$$dep*) \
333 ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
334 && { if test -f $@; then exit 0; else break; fi; }; \
335 exit 1;; \
336 esac; \
337 done; \
338 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Game/src/Makefile'; \
339 $(am__cd) $(top_srcdir) && \
340 $(AUTOMAKE) --foreign Game/src/Makefile
341Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
342 @case '$?' in \
343 *config.status*) \
344 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
345 *) \
346 echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
347 cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
348 esac;
349
350$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
351 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
352
353$(top_srcdir)/configure: $(am__configure_deps)
354 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
355$(ACLOCAL_M4): $(am__aclocal_m4_deps)
356 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
357$(am__aclocal_m4_deps):
358
359clean-noinstLIBRARIES:
360 -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
361
362libGame.a: $(libGame_a_OBJECTS) $(libGame_a_DEPENDENCIES) $(EXTRA_libGame_a_DEPENDENCIES)
363 $(AM_V_at)-rm -f libGame.a
364 $(AM_V_AR)$(libGame_a_AR) libGame.a $(libGame_a_OBJECTS) $(libGame_a_LIBADD)
365 $(AM_V_at)$(RANLIB) libGame.a
366
367mostlyclean-compile:
368 -rm -f *.$(OBJEXT)
369
370distclean-compile:
371 -rm -f *.tab.c
372
373@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-actors.Po@am__quote@
374@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-animlib.Po@am__quote@
375@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-config.Po@am__quote@
376@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-console.Po@am__quote@
377@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-control.Po@am__quote@
378@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-cvar_defs.Po@am__quote@
379@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-cvars.Po@am__quote@
380@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-dummy_audiolib.Po@am__quote@
381@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-game.Po@am__quote@
382@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-gamedef.Po@am__quote@
383@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-global.Po@am__quote@
384@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-keyboard.Po@am__quote@
385@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-menues.Po@am__quote@
386@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-player.Po@am__quote@
387@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-rts.Po@am__quote@
388@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-scriplib.Po@am__quote@
389@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-sector.Po@am__quote@
390@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libGame_a-sounds.Po@am__quote@
391
392.c.o:
393@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
394@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
395@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
396@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
397@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
398
399.c.obj:
400@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
401@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
402@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
403@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
404@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
405
406libGame_a-actors.o: actors.c
407@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-actors.o -MD -MP -MF $(DEPDIR)/libGame_a-actors.Tpo -c -o libGame_a-actors.o `test -f 'actors.c' || echo '$(srcdir)/'`actors.c
408@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-actors.Tpo $(DEPDIR)/libGame_a-actors.Po
409@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='actors.c' object='libGame_a-actors.o' libtool=no @AMDEPBACKSLASH@
410@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
411@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-actors.o `test -f 'actors.c' || echo '$(srcdir)/'`actors.c
412
413libGame_a-actors.obj: actors.c
414@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-actors.obj -MD -MP -MF $(DEPDIR)/libGame_a-actors.Tpo -c -o libGame_a-actors.obj `if test -f 'actors.c'; then $(CYGPATH_W) 'actors.c'; else $(CYGPATH_W) '$(srcdir)/actors.c'; fi`
415@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-actors.Tpo $(DEPDIR)/libGame_a-actors.Po
416@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='actors.c' object='libGame_a-actors.obj' libtool=no @AMDEPBACKSLASH@
417@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
418@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-actors.obj `if test -f 'actors.c'; then $(CYGPATH_W) 'actors.c'; else $(CYGPATH_W) '$(srcdir)/actors.c'; fi`
419
420libGame_a-animlib.o: animlib.c
421@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-animlib.o -MD -MP -MF $(DEPDIR)/libGame_a-animlib.Tpo -c -o libGame_a-animlib.o `test -f 'animlib.c' || echo '$(srcdir)/'`animlib.c
422@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-animlib.Tpo $(DEPDIR)/libGame_a-animlib.Po
423@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='animlib.c' object='libGame_a-animlib.o' libtool=no @AMDEPBACKSLASH@
424@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
425@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-animlib.o `test -f 'animlib.c' || echo '$(srcdir)/'`animlib.c
426
427libGame_a-animlib.obj: animlib.c
428@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-animlib.obj -MD -MP -MF $(DEPDIR)/libGame_a-animlib.Tpo -c -o libGame_a-animlib.obj `if test -f 'animlib.c'; then $(CYGPATH_W) 'animlib.c'; else $(CYGPATH_W) '$(srcdir)/animlib.c'; fi`
429@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-animlib.Tpo $(DEPDIR)/libGame_a-animlib.Po
430@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='animlib.c' object='libGame_a-animlib.obj' libtool=no @AMDEPBACKSLASH@
431@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
432@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-animlib.obj `if test -f 'animlib.c'; then $(CYGPATH_W) 'animlib.c'; else $(CYGPATH_W) '$(srcdir)/animlib.c'; fi`
433
434libGame_a-config.o: config.c
435@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-config.o -MD -MP -MF $(DEPDIR)/libGame_a-config.Tpo -c -o libGame_a-config.o `test -f 'config.c' || echo '$(srcdir)/'`config.c
436@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-config.Tpo $(DEPDIR)/libGame_a-config.Po
437@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='config.c' object='libGame_a-config.o' libtool=no @AMDEPBACKSLASH@
438@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
439@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-config.o `test -f 'config.c' || echo '$(srcdir)/'`config.c
440
441libGame_a-config.obj: config.c
442@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-config.obj -MD -MP -MF $(DEPDIR)/libGame_a-config.Tpo -c -o libGame_a-config.obj `if test -f 'config.c'; then $(CYGPATH_W) 'config.c'; else $(CYGPATH_W) '$(srcdir)/config.c'; fi`
443@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-config.Tpo $(DEPDIR)/libGame_a-config.Po
444@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='config.c' object='libGame_a-config.obj' libtool=no @AMDEPBACKSLASH@
445@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
446@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-config.obj `if test -f 'config.c'; then $(CYGPATH_W) 'config.c'; else $(CYGPATH_W) '$(srcdir)/config.c'; fi`
447
448libGame_a-console.o: console.c
449@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-console.o -MD -MP -MF $(DEPDIR)/libGame_a-console.Tpo -c -o libGame_a-console.o `test -f 'console.c' || echo '$(srcdir)/'`console.c
450@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-console.Tpo $(DEPDIR)/libGame_a-console.Po
451@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='console.c' object='libGame_a-console.o' libtool=no @AMDEPBACKSLASH@
452@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
453@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-console.o `test -f 'console.c' || echo '$(srcdir)/'`console.c
454
455libGame_a-console.obj: console.c
456@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-console.obj -MD -MP -MF $(DEPDIR)/libGame_a-console.Tpo -c -o libGame_a-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi`
457@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-console.Tpo $(DEPDIR)/libGame_a-console.Po
458@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='console.c' object='libGame_a-console.obj' libtool=no @AMDEPBACKSLASH@
459@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
460@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi`
461
462libGame_a-control.o: control.c
463@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-control.o -MD -MP -MF $(DEPDIR)/libGame_a-control.Tpo -c -o libGame_a-control.o `test -f 'control.c' || echo '$(srcdir)/'`control.c
464@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-control.Tpo $(DEPDIR)/libGame_a-control.Po
465@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='control.c' object='libGame_a-control.o' libtool=no @AMDEPBACKSLASH@
466@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
467@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-control.o `test -f 'control.c' || echo '$(srcdir)/'`control.c
468
469libGame_a-control.obj: control.c
470@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-control.obj -MD -MP -MF $(DEPDIR)/libGame_a-control.Tpo -c -o libGame_a-control.obj `if test -f 'control.c'; then $(CYGPATH_W) 'control.c'; else $(CYGPATH_W) '$(srcdir)/control.c'; fi`
471@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-control.Tpo $(DEPDIR)/libGame_a-control.Po
472@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='control.c' object='libGame_a-control.obj' libtool=no @AMDEPBACKSLASH@
473@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
474@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-control.obj `if test -f 'control.c'; then $(CYGPATH_W) 'control.c'; else $(CYGPATH_W) '$(srcdir)/control.c'; fi`
475
476libGame_a-cvar_defs.o: cvar_defs.c
477@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-cvar_defs.o -MD -MP -MF $(DEPDIR)/libGame_a-cvar_defs.Tpo -c -o libGame_a-cvar_defs.o `test -f 'cvar_defs.c' || echo '$(srcdir)/'`cvar_defs.c
478@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-cvar_defs.Tpo $(DEPDIR)/libGame_a-cvar_defs.Po
479@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cvar_defs.c' object='libGame_a-cvar_defs.o' libtool=no @AMDEPBACKSLASH@
480@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
481@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-cvar_defs.o `test -f 'cvar_defs.c' || echo '$(srcdir)/'`cvar_defs.c
482
483libGame_a-cvar_defs.obj: cvar_defs.c
484@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-cvar_defs.obj -MD -MP -MF $(DEPDIR)/libGame_a-cvar_defs.Tpo -c -o libGame_a-cvar_defs.obj `if test -f 'cvar_defs.c'; then $(CYGPATH_W) 'cvar_defs.c'; else $(CYGPATH_W) '$(srcdir)/cvar_defs.c'; fi`
485@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-cvar_defs.Tpo $(DEPDIR)/libGame_a-cvar_defs.Po
486@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cvar_defs.c' object='libGame_a-cvar_defs.obj' libtool=no @AMDEPBACKSLASH@
487@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
488@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-cvar_defs.obj `if test -f 'cvar_defs.c'; then $(CYGPATH_W) 'cvar_defs.c'; else $(CYGPATH_W) '$(srcdir)/cvar_defs.c'; fi`
489
490libGame_a-cvars.o: cvars.c
491@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-cvars.o -MD -MP -MF $(DEPDIR)/libGame_a-cvars.Tpo -c -o libGame_a-cvars.o `test -f 'cvars.c' || echo '$(srcdir)/'`cvars.c
492@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-cvars.Tpo $(DEPDIR)/libGame_a-cvars.Po
493@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cvars.c' object='libGame_a-cvars.o' libtool=no @AMDEPBACKSLASH@
494@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
495@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-cvars.o `test -f 'cvars.c' || echo '$(srcdir)/'`cvars.c
496
497libGame_a-cvars.obj: cvars.c
498@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-cvars.obj -MD -MP -MF $(DEPDIR)/libGame_a-cvars.Tpo -c -o libGame_a-cvars.obj `if test -f 'cvars.c'; then $(CYGPATH_W) 'cvars.c'; else $(CYGPATH_W) '$(srcdir)/cvars.c'; fi`
499@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-cvars.Tpo $(DEPDIR)/libGame_a-cvars.Po
500@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cvars.c' object='libGame_a-cvars.obj' libtool=no @AMDEPBACKSLASH@
501@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
502@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-cvars.obj `if test -f 'cvars.c'; then $(CYGPATH_W) 'cvars.c'; else $(CYGPATH_W) '$(srcdir)/cvars.c'; fi`
503
504libGame_a-dummy_audiolib.o: dummy_audiolib.c
505@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-dummy_audiolib.o -MD -MP -MF $(DEPDIR)/libGame_a-dummy_audiolib.Tpo -c -o libGame_a-dummy_audiolib.o `test -f 'dummy_audiolib.c' || echo '$(srcdir)/'`dummy_audiolib.c
506@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-dummy_audiolib.Tpo $(DEPDIR)/libGame_a-dummy_audiolib.Po
507@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dummy_audiolib.c' object='libGame_a-dummy_audiolib.o' libtool=no @AMDEPBACKSLASH@
508@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
509@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-dummy_audiolib.o `test -f 'dummy_audiolib.c' || echo '$(srcdir)/'`dummy_audiolib.c
510
511libGame_a-dummy_audiolib.obj: dummy_audiolib.c
512@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-dummy_audiolib.obj -MD -MP -MF $(DEPDIR)/libGame_a-dummy_audiolib.Tpo -c -o libGame_a-dummy_audiolib.obj `if test -f 'dummy_audiolib.c'; then $(CYGPATH_W) 'dummy_audiolib.c'; else $(CYGPATH_W) '$(srcdir)/dummy_audiolib.c'; fi`
513@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-dummy_audiolib.Tpo $(DEPDIR)/libGame_a-dummy_audiolib.Po
514@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='dummy_audiolib.c' object='libGame_a-dummy_audiolib.obj' libtool=no @AMDEPBACKSLASH@
515@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
516@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-dummy_audiolib.obj `if test -f 'dummy_audiolib.c'; then $(CYGPATH_W) 'dummy_audiolib.c'; else $(CYGPATH_W) '$(srcdir)/dummy_audiolib.c'; fi`
517
518libGame_a-game.o: game.c
519@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-game.o -MD -MP -MF $(DEPDIR)/libGame_a-game.Tpo -c -o libGame_a-game.o `test -f 'game.c' || echo '$(srcdir)/'`game.c
520@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-game.Tpo $(DEPDIR)/libGame_a-game.Po
521@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='game.c' object='libGame_a-game.o' libtool=no @AMDEPBACKSLASH@
522@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
523@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-game.o `test -f 'game.c' || echo '$(srcdir)/'`game.c
524
525libGame_a-game.obj: game.c
526@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-game.obj -MD -MP -MF $(DEPDIR)/libGame_a-game.Tpo -c -o libGame_a-game.obj `if test -f 'game.c'; then $(CYGPATH_W) 'game.c'; else $(CYGPATH_W) '$(srcdir)/game.c'; fi`
527@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-game.Tpo $(DEPDIR)/libGame_a-game.Po
528@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='game.c' object='libGame_a-game.obj' libtool=no @AMDEPBACKSLASH@
529@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
530@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-game.obj `if test -f 'game.c'; then $(CYGPATH_W) 'game.c'; else $(CYGPATH_W) '$(srcdir)/game.c'; fi`
531
532libGame_a-gamedef.o: gamedef.c
533@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-gamedef.o -MD -MP -MF $(DEPDIR)/libGame_a-gamedef.Tpo -c -o libGame_a-gamedef.o `test -f 'gamedef.c' || echo '$(srcdir)/'`gamedef.c
534@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-gamedef.Tpo $(DEPDIR)/libGame_a-gamedef.Po
535@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gamedef.c' object='libGame_a-gamedef.o' libtool=no @AMDEPBACKSLASH@
536@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
537@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-gamedef.o `test -f 'gamedef.c' || echo '$(srcdir)/'`gamedef.c
538
539libGame_a-gamedef.obj: gamedef.c
540@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-gamedef.obj -MD -MP -MF $(DEPDIR)/libGame_a-gamedef.Tpo -c -o libGame_a-gamedef.obj `if test -f 'gamedef.c'; then $(CYGPATH_W) 'gamedef.c'; else $(CYGPATH_W) '$(srcdir)/gamedef.c'; fi`
541@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-gamedef.Tpo $(DEPDIR)/libGame_a-gamedef.Po
542@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gamedef.c' object='libGame_a-gamedef.obj' libtool=no @AMDEPBACKSLASH@
543@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
544@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-gamedef.obj `if test -f 'gamedef.c'; then $(CYGPATH_W) 'gamedef.c'; else $(CYGPATH_W) '$(srcdir)/gamedef.c'; fi`
545
546libGame_a-global.o: global.c
547@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-global.o -MD -MP -MF $(DEPDIR)/libGame_a-global.Tpo -c -o libGame_a-global.o `test -f 'global.c' || echo '$(srcdir)/'`global.c
548@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-global.Tpo $(DEPDIR)/libGame_a-global.Po
549@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='global.c' object='libGame_a-global.o' libtool=no @AMDEPBACKSLASH@
550@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
551@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-global.o `test -f 'global.c' || echo '$(srcdir)/'`global.c
552
553libGame_a-global.obj: global.c
554@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-global.obj -MD -MP -MF $(DEPDIR)/libGame_a-global.Tpo -c -o libGame_a-global.obj `if test -f 'global.c'; then $(CYGPATH_W) 'global.c'; else $(CYGPATH_W) '$(srcdir)/global.c'; fi`
555@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-global.Tpo $(DEPDIR)/libGame_a-global.Po
556@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='global.c' object='libGame_a-global.obj' libtool=no @AMDEPBACKSLASH@
557@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
558@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-global.obj `if test -f 'global.c'; then $(CYGPATH_W) 'global.c'; else $(CYGPATH_W) '$(srcdir)/global.c'; fi`
559
560libGame_a-keyboard.o: keyboard.c
561@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-keyboard.o -MD -MP -MF $(DEPDIR)/libGame_a-keyboard.Tpo -c -o libGame_a-keyboard.o `test -f 'keyboard.c' || echo '$(srcdir)/'`keyboard.c
562@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-keyboard.Tpo $(DEPDIR)/libGame_a-keyboard.Po
563@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keyboard.c' object='libGame_a-keyboard.o' libtool=no @AMDEPBACKSLASH@
564@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
565@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-keyboard.o `test -f 'keyboard.c' || echo '$(srcdir)/'`keyboard.c
566
567libGame_a-keyboard.obj: keyboard.c
568@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-keyboard.obj -MD -MP -MF $(DEPDIR)/libGame_a-keyboard.Tpo -c -o libGame_a-keyboard.obj `if test -f 'keyboard.c'; then $(CYGPATH_W) 'keyboard.c'; else $(CYGPATH_W) '$(srcdir)/keyboard.c'; fi`
569@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-keyboard.Tpo $(DEPDIR)/libGame_a-keyboard.Po
570@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='keyboard.c' object='libGame_a-keyboard.obj' libtool=no @AMDEPBACKSLASH@
571@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
572@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-keyboard.obj `if test -f 'keyboard.c'; then $(CYGPATH_W) 'keyboard.c'; else $(CYGPATH_W) '$(srcdir)/keyboard.c'; fi`
573
574libGame_a-menues.o: menues.c
575@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-menues.o -MD -MP -MF $(DEPDIR)/libGame_a-menues.Tpo -c -o libGame_a-menues.o `test -f 'menues.c' || echo '$(srcdir)/'`menues.c
576@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-menues.Tpo $(DEPDIR)/libGame_a-menues.Po
577@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='menues.c' object='libGame_a-menues.o' libtool=no @AMDEPBACKSLASH@
578@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
579@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-menues.o `test -f 'menues.c' || echo '$(srcdir)/'`menues.c
580
581libGame_a-menues.obj: menues.c
582@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-menues.obj -MD -MP -MF $(DEPDIR)/libGame_a-menues.Tpo -c -o libGame_a-menues.obj `if test -f 'menues.c'; then $(CYGPATH_W) 'menues.c'; else $(CYGPATH_W) '$(srcdir)/menues.c'; fi`
583@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-menues.Tpo $(DEPDIR)/libGame_a-menues.Po
584@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='menues.c' object='libGame_a-menues.obj' libtool=no @AMDEPBACKSLASH@
585@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
586@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-menues.obj `if test -f 'menues.c'; then $(CYGPATH_W) 'menues.c'; else $(CYGPATH_W) '$(srcdir)/menues.c'; fi`
587
588libGame_a-player.o: player.c
589@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-player.o -MD -MP -MF $(DEPDIR)/libGame_a-player.Tpo -c -o libGame_a-player.o `test -f 'player.c' || echo '$(srcdir)/'`player.c
590@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-player.Tpo $(DEPDIR)/libGame_a-player.Po
591@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='player.c' object='libGame_a-player.o' libtool=no @AMDEPBACKSLASH@
592@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
593@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-player.o `test -f 'player.c' || echo '$(srcdir)/'`player.c
594
595libGame_a-player.obj: player.c
596@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-player.obj -MD -MP -MF $(DEPDIR)/libGame_a-player.Tpo -c -o libGame_a-player.obj `if test -f 'player.c'; then $(CYGPATH_W) 'player.c'; else $(CYGPATH_W) '$(srcdir)/player.c'; fi`
597@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-player.Tpo $(DEPDIR)/libGame_a-player.Po
598@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='player.c' object='libGame_a-player.obj' libtool=no @AMDEPBACKSLASH@
599@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
600@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-player.obj `if test -f 'player.c'; then $(CYGPATH_W) 'player.c'; else $(CYGPATH_W) '$(srcdir)/player.c'; fi`
601
602libGame_a-rts.o: rts.c
603@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-rts.o -MD -MP -MF $(DEPDIR)/libGame_a-rts.Tpo -c -o libGame_a-rts.o `test -f 'rts.c' || echo '$(srcdir)/'`rts.c
604@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-rts.Tpo $(DEPDIR)/libGame_a-rts.Po
605@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rts.c' object='libGame_a-rts.o' libtool=no @AMDEPBACKSLASH@
606@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
607@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-rts.o `test -f 'rts.c' || echo '$(srcdir)/'`rts.c
608
609libGame_a-rts.obj: rts.c
610@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-rts.obj -MD -MP -MF $(DEPDIR)/libGame_a-rts.Tpo -c -o libGame_a-rts.obj `if test -f 'rts.c'; then $(CYGPATH_W) 'rts.c'; else $(CYGPATH_W) '$(srcdir)/rts.c'; fi`
611@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-rts.Tpo $(DEPDIR)/libGame_a-rts.Po
612@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rts.c' object='libGame_a-rts.obj' libtool=no @AMDEPBACKSLASH@
613@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
614@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-rts.obj `if test -f 'rts.c'; then $(CYGPATH_W) 'rts.c'; else $(CYGPATH_W) '$(srcdir)/rts.c'; fi`
615
616libGame_a-scriplib.o: scriplib.c
617@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-scriplib.o -MD -MP -MF $(DEPDIR)/libGame_a-scriplib.Tpo -c -o libGame_a-scriplib.o `test -f 'scriplib.c' || echo '$(srcdir)/'`scriplib.c
618@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-scriplib.Tpo $(DEPDIR)/libGame_a-scriplib.Po
619@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scriplib.c' object='libGame_a-scriplib.o' libtool=no @AMDEPBACKSLASH@
620@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
621@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-scriplib.o `test -f 'scriplib.c' || echo '$(srcdir)/'`scriplib.c
622
623libGame_a-scriplib.obj: scriplib.c
624@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-scriplib.obj -MD -MP -MF $(DEPDIR)/libGame_a-scriplib.Tpo -c -o libGame_a-scriplib.obj `if test -f 'scriplib.c'; then $(CYGPATH_W) 'scriplib.c'; else $(CYGPATH_W) '$(srcdir)/scriplib.c'; fi`
625@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-scriplib.Tpo $(DEPDIR)/libGame_a-scriplib.Po
626@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='scriplib.c' object='libGame_a-scriplib.obj' libtool=no @AMDEPBACKSLASH@
627@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
628@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-scriplib.obj `if test -f 'scriplib.c'; then $(CYGPATH_W) 'scriplib.c'; else $(CYGPATH_W) '$(srcdir)/scriplib.c'; fi`
629
630libGame_a-sector.o: sector.c
631@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-sector.o -MD -MP -MF $(DEPDIR)/libGame_a-sector.Tpo -c -o libGame_a-sector.o `test -f 'sector.c' || echo '$(srcdir)/'`sector.c
632@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-sector.Tpo $(DEPDIR)/libGame_a-sector.Po
633@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sector.c' object='libGame_a-sector.o' libtool=no @AMDEPBACKSLASH@
634@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
635@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-sector.o `test -f 'sector.c' || echo '$(srcdir)/'`sector.c
636
637libGame_a-sector.obj: sector.c
638@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-sector.obj -MD -MP -MF $(DEPDIR)/libGame_a-sector.Tpo -c -o libGame_a-sector.obj `if test -f 'sector.c'; then $(CYGPATH_W) 'sector.c'; else $(CYGPATH_W) '$(srcdir)/sector.c'; fi`
639@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-sector.Tpo $(DEPDIR)/libGame_a-sector.Po
640@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sector.c' object='libGame_a-sector.obj' libtool=no @AMDEPBACKSLASH@
641@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
642@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-sector.obj `if test -f 'sector.c'; then $(CYGPATH_W) 'sector.c'; else $(CYGPATH_W) '$(srcdir)/sector.c'; fi`
643
644libGame_a-sounds.o: sounds.c
645@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-sounds.o -MD -MP -MF $(DEPDIR)/libGame_a-sounds.Tpo -c -o libGame_a-sounds.o `test -f 'sounds.c' || echo '$(srcdir)/'`sounds.c
646@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-sounds.Tpo $(DEPDIR)/libGame_a-sounds.Po
647@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sounds.c' object='libGame_a-sounds.o' libtool=no @AMDEPBACKSLASH@
648@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
649@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-sounds.o `test -f 'sounds.c' || echo '$(srcdir)/'`sounds.c
650
651libGame_a-sounds.obj: sounds.c
652@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -MT libGame_a-sounds.obj -MD -MP -MF $(DEPDIR)/libGame_a-sounds.Tpo -c -o libGame_a-sounds.obj `if test -f 'sounds.c'; then $(CYGPATH_W) 'sounds.c'; else $(CYGPATH_W) '$(srcdir)/sounds.c'; fi`
653@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libGame_a-sounds.Tpo $(DEPDIR)/libGame_a-sounds.Po
654@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sounds.c' object='libGame_a-sounds.obj' libtool=no @AMDEPBACKSLASH@
655@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
656@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libGame_a_CFLAGS) $(CFLAGS) -c -o libGame_a-sounds.obj `if test -f 'sounds.c'; then $(CYGPATH_W) 'sounds.c'; else $(CYGPATH_W) '$(srcdir)/sounds.c'; fi`
657
658# This directory's subdirectories are mostly independent; you can cd
659# into them and run 'make' without going through this Makefile.
660# To change the values of 'make' variables: instead of editing Makefiles,
661# (1) if the variable is set in 'config.status', edit 'config.status'
662# (which will cause the Makefiles to be regenerated when you run 'make');
663# (2) otherwise, pass the desired values on the 'make' command line.
664$(am__recursive_targets):
665 @fail=; \
666 if $(am__make_keepgoing); then \
667 failcom='fail=yes'; \
668 else \
669 failcom='exit 1'; \
670 fi; \
671 dot_seen=no; \
672 target=`echo $@ | sed s/-recursive//`; \
673 case "$@" in \
674 distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
675 *) list='$(SUBDIRS)' ;; \
676 esac; \
677 for subdir in $$list; do \
678 echo "Making $$target in $$subdir"; \
679 if test "$$subdir" = "."; then \
680 dot_seen=yes; \
681 local_target="$$target-am"; \
682 else \
683 local_target="$$target"; \
684 fi; \
685 ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
686 || eval $$failcom; \
687 done; \
688 if test "$$dot_seen" = "no"; then \
689 $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
690 fi; test -z "$$fail"
691
692ID: $(am__tagged_files)
693 $(am__define_uniq_tagged_files); mkid -fID $$unique
694tags: tags-recursive
695TAGS: tags
696
697tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
698 set x; \
699 here=`pwd`; \
700 if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
701 include_option=--etags-include; \
702 empty_fix=.; \
703 else \
704 include_option=--include; \
705 empty_fix=; \
706 fi; \
707 list='$(SUBDIRS)'; for subdir in $$list; do \
708 if test "$$subdir" = .; then :; else \
709 test ! -f $$subdir/TAGS || \
710 set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
711 fi; \
712 done; \
713 $(am__define_uniq_tagged_files); \
714 shift; \
715 if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
716 test -n "$$unique" || unique=$$empty_fix; \
717 if test $$# -gt 0; then \
718 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
719 "$$@" $$unique; \
720 else \
721 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
722 $$unique; \
723 fi; \
724 fi
725ctags: ctags-recursive
726
727CTAGS: ctags
728ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
729 $(am__define_uniq_tagged_files); \
730 test -z "$(CTAGS_ARGS)$$unique" \
731 || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
732 $$unique
733
734GTAGS:
735 here=`$(am__cd) $(top_builddir) && pwd` \
736 && $(am__cd) $(top_srcdir) \
737 && gtags -i $(GTAGS_ARGS) "$$here"
738cscopelist: cscopelist-recursive
739
740cscopelist-am: $(am__tagged_files)
741 list='$(am__tagged_files)'; \
742 case "$(srcdir)" in \
743 [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
744 *) sdir=$(subdir)/$(srcdir) ;; \
745 esac; \
746 for i in $$list; do \
747 if test -f "$$i"; then \
748 echo "$(subdir)/$$i"; \
749 else \
750 echo "$$sdir/$$i"; \
751 fi; \
752 done >> $(top_builddir)/cscope.files
753
754distclean-tags:
755 -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
756
757distdir: $(DISTFILES)
758 @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
759 topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
760 list='$(DISTFILES)'; \
761 dist_files=`for file in $$list; do echo $$file; done | \
762 sed -e "s|^$$srcdirstrip/||;t" \
763 -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
764 case $$dist_files in \
765 */*) $(MKDIR_P) `echo "$$dist_files" | \
766 sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
767 sort -u` ;; \
768 esac; \
769 for file in $$dist_files; do \
770 if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
771 if test -d $$d/$$file; then \
772 dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
773 if test -d "$(distdir)/$$file"; then \
774 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
775 fi; \
776 if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
777 cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
778 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
779 fi; \
780 cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
781 else \
782 test -f "$(distdir)/$$file" \
783 || cp -p $$d/$$file "$(distdir)/$$file" \
784 || exit 1; \
785 fi; \
786 done
787 @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
788 if test "$$subdir" = .; then :; else \
789 $(am__make_dryrun) \
790 || test -d "$(distdir)/$$subdir" \
791 || $(MKDIR_P) "$(distdir)/$$subdir" \
792 || exit 1; \
793 dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
794 $(am__relativize); \
795 new_distdir=$$reldir; \
796 dir1=$$subdir; dir2="$(top_distdir)"; \
797 $(am__relativize); \
798 new_top_distdir=$$reldir; \
799 echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
800 echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
801 ($(am__cd) $$subdir && \
802 $(MAKE) $(AM_MAKEFLAGS) \
803 top_distdir="$$new_top_distdir" \
804 distdir="$$new_distdir" \
805 am__remove_distdir=: \
806 am__skip_length_check=: \
807 am__skip_mode_fix=: \
808 distdir) \
809 || exit 1; \
810 fi; \
811 done
812check-am: all-am
813check: check-recursive
814all-am: Makefile $(LIBRARIES)
815installdirs: installdirs-recursive
816installdirs-am:
817install: install-recursive
818install-exec: install-exec-recursive
819install-data: install-data-recursive
820uninstall: uninstall-recursive
821
822install-am: all-am
823 @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
824
825installcheck: installcheck-recursive
826install-strip:
827 if test -z '$(STRIP)'; then \
828 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
829 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
830 install; \
831 else \
832 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
833 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
834 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
835 fi
836mostlyclean-generic:
837
838clean-generic:
839
840distclean-generic:
841 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
842 -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
843
844maintainer-clean-generic:
845 @echo "This command is intended for maintainers to use"
846 @echo "it deletes files that may require special tools to rebuild."
847clean: clean-recursive
848
849clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
850
851distclean: distclean-recursive
852 -rm -rf ./$(DEPDIR)
853 -rm -f Makefile
854distclean-am: clean-am distclean-compile distclean-generic \
855 distclean-tags
856
857dvi: dvi-recursive
858
859dvi-am:
860
861html: html-recursive
862
863html-am:
864
865info: info-recursive
866
867info-am:
868
869install-data-am:
870
871install-dvi: install-dvi-recursive
872
873install-dvi-am:
874
875install-exec-am:
876
877install-html: install-html-recursive
878
879install-html-am:
880
881install-info: install-info-recursive
882
883install-info-am:
884
885install-man:
886
887install-pdf: install-pdf-recursive
888
889install-pdf-am:
890
891install-ps: install-ps-recursive
892
893install-ps-am:
894
895installcheck-am:
896
897maintainer-clean: maintainer-clean-recursive
898 -rm -rf ./$(DEPDIR)
899 -rm -f Makefile
900maintainer-clean-am: distclean-am maintainer-clean-generic
901
902mostlyclean: mostlyclean-recursive
903
904mostlyclean-am: mostlyclean-compile mostlyclean-generic
905
906pdf: pdf-recursive
907
908pdf-am:
909
910ps: ps-recursive
911
912ps-am:
913
914uninstall-am:
915
916.MAKE: $(am__recursive_targets) install-am install-strip
917
918.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
919 check-am clean clean-generic clean-noinstLIBRARIES \
920 cscopelist-am ctags ctags-am distclean distclean-compile \
921 distclean-generic distclean-tags distdir dvi dvi-am html \
922 html-am info info-am install install-am install-data \
923 install-data-am install-dvi install-dvi-am install-exec \
924 install-exec-am install-html install-html-am install-info \
925 install-info-am install-man install-pdf install-pdf-am \
926 install-ps install-ps-am install-strip installcheck \
927 installcheck-am installdirs installdirs-am maintainer-clean \
928 maintainer-clean-generic mostlyclean mostlyclean-compile \
929 mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
930 uninstall-am
931
932.PRECIOUS: Makefile
933
934
935# Starting a new game will lead to a crash if premap.o was built with -O1/-O2/-O3,
936# that's why we're compiling it seperately with -O0
937premap.o: premap.c
938 $(AM_V_CC)$(CC) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -I$(top_srcdir)/Engine/src -O0 -c $^ -o $@
939
940# Tell versions [3.59,3.63) of GNU make to not export all variables.
941# Otherwise a system limit (for SysV at least) may be exceeded.
942.NOEXPORT:
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/_functio.h b/apps/plugins/sdl/progs/duke3d/Game/src/_functio.h
new file mode 100644
index 0000000000..ec288015ed
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/_functio.h
@@ -0,0 +1,174 @@
1//-------------------------------------------------------------------------
2/*
3 Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5 This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7 Duke Nukem 3D is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 aint32_t with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 Original Source: 1996 - Todd Replogle
23 Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27// _functio.h
28
29// file created by makehead.exe
30// these headers contain default key assignments, as well as
31// default button assignments and game function names
32// axis defaults are also included
33
34
35#ifndef _function_private_
36#define _function_private_
37#ifdef __cplusplus
38extern "C" {
39#endif
40 char * gamefunctions[] =
41 {
42 "Move_Forward",
43 "Move_Backward",
44 "Turn_Left",
45 "Turn_Right",
46 "Strafe",
47 "Fire",
48 "Open",
49 "Run",
50 "AutoRun",
51 "Jump",
52 "Crouch",
53 "Look_Up",
54 "Look_Down",
55 "Look_Left",
56 "Look_Right",
57 "Strafe_Left",
58 "Strafe_Right",
59 "Aim_Up",
60 "Aim_Down",
61 "Weapon_1",
62 "Weapon_2",
63 "Weapon_3",
64 "Weapon_4",
65 "Weapon_5",
66 "Weapon_6",
67 "Weapon_7",
68 "Weapon_8",
69 "Weapon_9",
70 "Weapon_10",
71 "Inventory",
72 "Inventory_Left",
73 "Inventory_Right",
74 "Holo_Duke",
75 "Jetpack",
76 "NightVision",
77 "MedKit",
78 "TurnAround",
79 "SendMessage",
80 "Map",
81 "Shrink_Screen",
82 "Enlarge_Screen",
83 "Center_View",
84 "Holster_Weapon",
85 "Show_Opponents_Weapon",
86 "Map_Follow_Mode",
87 "See_Coop_View",
88 "Mouse_Aiming",
89 "Toggle_Crosshair",
90 "Steroids",
91 "Quick_Kick",
92 "Next_Weapon",
93 "Previous_Weapon",
94 "Hide_Weapon",
95 "Auto_Aim",
96 "Console"
97 };
98
99#define NUMKEYENTRIES 55 // Don't forget to change NUMGAMEFUNCTIONS as well
100
101// FIX_00011: duke3d.cfg not needed anymore to start the game. Will create a default one
102// if not found and use default keys.
103
104 struct keyEntry{
105 char * entryKey;
106 char * keyname1;
107 char * keyname2;
108 } ;
109
110
111 struct keyEntry keydefaults[] = {
112 { "Move_Forward", "Up", "" },
113 { "Move_Backward", "", "" },
114 { "Turn_Left", "Left", "" },
115 { "Turn_Right", "Right", "" },
116 { "Strafe", "", "" },
117 { "Fire", "Enter", "" },
118 { "Open", "Up", "" },
119 { "Run", "", "" },
120 { "AutoRun", "", "" },
121 { "Jump", "Down", "" },
122 { "Crouch", "", "" },
123 { "Look_Up", "", "" },
124 { "Look_Down", "", "" },
125 { "Look_Left", "", "" },
126 { "Look_Right", "", "" },
127 { "Strafe_Left", "A", "" },
128 { "Strafe_Right", "D", "" },
129 { "Aim_Up", "", "" },
130 { "Aim_Down", "", "" },
131 { "Weapon_1", "", "" },
132 { "Weapon_2", "", "" },
133 { "Weapon_3", "", "" },
134 { "Weapon_4", "", "" },
135 { "Weapon_5", "", "" },
136 { "Weapon_6", "", "" },
137 { "Weapon_7", "", "" },
138 { "Weapon_8", "", "" },
139 { "Weapon_9", "", "" },
140 { "Weapon_10", "", "" },
141 { "Inventory", "", "" },
142 { "Inventory_Left", "", "" },
143 { "Inventory_Right","]", "", "" },
144 { "Holo_Duke", "", "" },
145 { "Jetpack", "", "" },
146 { "NightVision", "", "" },
147 { "MedKit", "", "" },
148 { "TurnAround", "", "" },
149 { "SendMessage", "", "" },
150 { "Map", "", "" },
151 { "Shrink_Screen", "", "" },
152 { "Enlarge_Screen", "", "" },
153 { "Center_View", "", "" },
154 { "Holster_Weapon", "", "" },
155 { "Show_Opponents_Weapon", "", "" },
156 { "Map_Follow_Mode","F", "", "" },
157 { "See_Coop_View", "", "" },
158 { "Mouse_Aiming", "", "" },
159 { "Toggle_Crosshair", "", "" },
160 { "Steroids", "", "" },
161 { "Quick_Kick", "", "" },
162 { "Next_Weapon", "", "" },
163 { "Previous_Weapon",";", "", "" },
164 { "Hide_Weapon", "", "" },
165 { "Auto_Aim", "", "" },
166 { "Console", "", "" },
167 };
168
169
170
171#ifdef __cplusplus
172};
173#endif
174#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/_rts.h b/apps/plugins/sdl/progs/duke3d/Game/src/_rts.h
new file mode 100644
index 0000000000..0226c7b590
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/_rts.h
@@ -0,0 +1,54 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#ifndef __rts_private__
28#define __rts_private__
29
30//===============
31// TYPES
32//===============
33
34typedef struct
35 {
36 char name[8];
37 int32 handle,position,size;
38 } lumpinfo_t;
39
40typedef struct
41 {
42 char identification[4]; // should be IWAD
43 int32 numlumps;
44 int32 infotableofs;
45 } wadinfo_t;
46
47typedef struct
48 {
49 int32 filepos;
50 int32 size;
51 char name[8];
52 } filelump_t;
53
54#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/actors.c b/apps/plugins/sdl/progs/duke3d/Game/src/actors.c
new file mode 100644
index 0000000000..08361b5d3e
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/actors.c
@@ -0,0 +1,7157 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#include "duke3d.h"
28
29extern int32_t numenvsnds;
30uint8_t actor_tog;
31
32void updateinterpolations() //Stick at beginning of domovethings
33{
34 int32_t i;
35
36 for(i=numinterpolations-1;i>=0;i--) oldipos[i] = *curipos[i];
37}
38
39
40void setinterpolation(int32_t *posptr)
41{
42 int32_t i;
43
44 if (numinterpolations >= MAXINTERPOLATIONS) return;
45 for(i=numinterpolations-1;i>=0;i--)
46 if (curipos[i] == posptr) return;
47 curipos[numinterpolations] = posptr;
48 oldipos[numinterpolations] = *posptr;
49 numinterpolations++;
50}
51
52void stopinterpolation(int32_t *posptr)
53{
54 int32_t i;
55
56 for(i=numinterpolations-1;i>=startofdynamicinterpolations;i--)
57 if (curipos[i] == posptr)
58 {
59 numinterpolations--;
60 oldipos[i] = oldipos[numinterpolations];
61 bakipos[i] = bakipos[numinterpolations];
62 curipos[i] = curipos[numinterpolations];
63 }
64}
65
66void dointerpolations(int32_t smoothratio) //Stick at beginning of drawscreen
67{
68 int32_t i, j, odelta, ndelta;
69
70 ndelta = 0; j = 0;
71 for(i=numinterpolations-1;i>=0;i--)
72 {
73 bakipos[i] = *curipos[i];
74 odelta = ndelta; ndelta = (*curipos[i])-oldipos[i];
75 if (odelta != ndelta) j = mulscale16(ndelta,smoothratio);
76 *curipos[i] = oldipos[i]+j;
77 }
78}
79
80void restoreinterpolations() //Stick at end of drawscreen
81{
82 int32_t i;
83
84 for(i=numinterpolations-1;i>=0;i--) *curipos[i] = bakipos[i];
85}
86
87int32_t ceilingspace(int16_t sectnum)
88{
89 if( (sector[sectnum].ceilingstat&1) && sector[sectnum].ceilingpal == 0 )
90 {
91 switch(sector[sectnum].ceilingpicnum)
92 {
93 case MOONSKY1:
94 case BIGORBIT1:
95 return 1;
96 }
97 }
98 return 0;
99}
100
101int32_t floorspace(int16_t sectnum)
102{
103 if( (sector[sectnum].floorstat&1) && sector[sectnum].ceilingpal == 0 )
104 {
105 switch(sector[sectnum].floorpicnum)
106 {
107 case MOONSKY1:
108 case BIGORBIT1:
109 return 1;
110 }
111 }
112 return 0;
113}
114
115void addammo( int16_t weapon,struct player_struct *p,int16_t amount)
116{
117 p->ammo_amount[weapon] += amount;
118
119 if( p->ammo_amount[weapon] > max_ammo_amount[weapon] )
120 p->ammo_amount[weapon] = max_ammo_amount[weapon];
121}
122
123void addweapon( struct player_struct *p,int16_t weapon)
124{
125 int added_new_weapon = false;
126
127 if ( p->gotweapon[weapon] == 0 )
128 {
129 p->gotweapon[weapon] = 1;
130 if(weapon == SHRINKER_WEAPON)
131 p->gotweapon[GROW_WEAPON] = 1;
132
133 // FIX_00012: added "weapon autoswitch" toggle allowing to turn the autoswitch off
134 // when picking up new weapons. The weapon sound on pickup will remain on, to not
135 // affect the opponent's gameplay (so he can still hear you picking up new weapons)
136 if(p->weaponautoswitch) // Anti antiswitch ordered
137 added_new_weapon = true;
138 }
139
140 if (added_new_weapon==false ||
141 ud.playing_demo_rev == BYTEVERSION_27 ||
142 ud.playing_demo_rev == BYTEVERSION_28 ||
143 ud.playing_demo_rev == BYTEVERSION_116 ||
144 ud.playing_demo_rev == BYTEVERSION_117 )
145 // don't block the weapon change on 1st pick up if playing an old demo
146 {
147 p->random_club_frame = 0;
148
149 if(p->holster_weapon == 0)
150 {
151 p->weapon_pos = -1;
152 p->last_weapon = p->curr_weapon;
153 }
154 else
155 {
156 p->weapon_pos = 10;
157 p->holster_weapon = 0;
158 p->last_weapon = -1;
159 }
160
161 p->kickback_pic = 0;
162 p->curr_weapon = weapon;
163 }
164
165 switch(weapon)
166 {
167 case KNEE_WEAPON:
168 case TRIPBOMB_WEAPON:
169 case HANDREMOTE_WEAPON:
170 case HANDBOMB_WEAPON: break;
171 case SHOTGUN_WEAPON: spritesound(SHOTGUN_COCK,p->i);break;
172 case PISTOL_WEAPON: spritesound(INSERT_CLIP,p->i);break;
173 default: spritesound(SELECT_WEAPON,p->i);break;
174 }
175
176 vscrn(); // FIX_00056: Refresh issue w/FPS, small Weapon and custom FTA, when screen resized down
177
178}
179
180void checkavailinven( struct player_struct *p )
181{
182
183 if(p->firstaid_amount > 0)
184 p->inven_icon = 1;
185 else if(p->steroids_amount > 0)
186 p->inven_icon = 2;
187 else if(p->holoduke_amount > 0)
188 p->inven_icon = 3;
189 else if(p->jetpack_amount > 0)
190 p->inven_icon = 4;
191 else if(p->heat_amount > 0)
192 p->inven_icon = 5;
193 else if(p->scuba_amount > 0)
194 p->inven_icon = 6;
195 else if(p->boot_amount > 0)
196 p->inven_icon = 7;
197 else p->inven_icon = 0;
198}
199
200void checkavailweapon( struct player_struct *p )
201{
202 short i,snum;
203 int32 weap;
204
205 if(p->wantweaponfire >= 0)
206 {
207 weap = p->wantweaponfire;
208 p->wantweaponfire = -1;
209
210 if(weap == p->curr_weapon) return;
211 else if( p->gotweapon[weap] && p->ammo_amount[weap] > 0 )
212 {
213 addweapon(p,weap);
214 return;
215 }
216 }
217
218 weap = p->curr_weapon;
219 if( p->gotweapon[weap] && p->ammo_amount[weap] > 0 )
220 return;
221
222 snum = sprite[p->i].yvel;
223
224 for(i=0;i<10;i++)
225 {
226 weap = ud.wchoice[snum][i];
227 if (VOLUMEONE)
228 if(weap > 6) continue;
229
230 if(weap == 0) weap = 9;
231 else weap--;
232
233 if( weap == 0 || ( p->gotweapon[weap] && p->ammo_amount[weap] > 0 ) )
234 break;
235 }
236
237 if(i == 10) weap = 0;
238
239 // Found the weapon
240
241 p->last_weapon = p->curr_weapon;
242 p->random_club_frame = 0;
243 p->curr_weapon = weap;
244 p->kickback_pic = 0;
245 if(p->holster_weapon == 1)
246 {
247 p->holster_weapon = 0;
248 p->weapon_pos = 10;
249 }
250 else p->weapon_pos = -1;
251}
252
253 /*
254void checkavailweapon( struct player_struct *p )
255{
256 short i,okay,check_shoot,check_bombs;
257
258 if(p->ammo_amount[p->curr_weapon] > 0) return;
259 okay = check_shoot = check_bombs = 0;
260
261 switch(p->curr_weapon)
262 {
263 case PISTOL_WEAPON:
264 case CHAINGUN_WEAPON:
265 case SHOTGUN_WEAPON:
266#ifndef VOLUMEONE
267 case FREEZE_WEAPON:
268 case DEVISTATOR_WEAPON:
269 case SHRINKER_WEAPON:
270 case GROW_WEAPON:
271#endif
272 case RPG_WEAPON:
273 case KNEE_WEAPON:
274 check_shoot = 1;
275 break;
276 case HANDBOMB_WEAPON:
277 case HANDREMOTE_WEAPON:
278#ifndef VOLUMEONE
279 case TRIPBOMB_WEAPON:
280#endif
281 check_bombs = 1;
282 break;
283 }
284
285 CHECK_SHOOT:
286 if(check_shoot)
287 {
288 for(i = p->curr_weapon+1; i < MAX_WEAPONS;i++)
289 switch(i)
290 {
291 case PISTOL_WEAPON:
292 case CHAINGUN_WEAPON:
293 case SHOTGUN_WEAPON:
294#ifndef VOLUMEONE
295 case FREEZE_WEAPON:
296 case SHRINKER_WEAPON:
297 case GROW_WEAPON:
298 case DEVISTATOR_WEAPON:
299#endif
300 if ( p->gotweapon[i] && p->ammo_amount[i] > 0 )
301 {
302 okay = i;
303 goto OKAY_HERE;
304 }
305 break;
306 }
307
308 for(i = p->curr_weapon-1; i > 0;i--)
309 switch(i)
310 {
311 case PISTOL_WEAPON:
312 case CHAINGUN_WEAPON:
313 case SHOTGUN_WEAPON:
314#ifndef VOLUMEONE
315 case FREEZE_WEAPON:
316 case DEVISTATOR_WEAPON:
317 case SHRINKER_WEAPON:
318 case GROW_WEAPON:
319#endif
320 if ( p->gotweapon[i] && p->ammo_amount[i] > 0 )
321 {
322 okay = i;
323 goto OKAY_HERE;
324 }
325 break;
326 }
327
328 if( p->gotweapon[RPG_WEAPON] && p->ammo_amount[RPG_WEAPON] > 0 )
329 {
330 okay = RPG_WEAPON;
331 goto OKAY_HERE;
332 }
333
334 if(check_bombs == 0)
335 check_bombs = 1;
336 else
337 {
338 addweapon(p,KNEE_WEAPON);
339 return;
340 }
341 }
342
343 if(check_bombs)
344 {
345 for(i = p->curr_weapon-1; i > 0;i--)
346 switch(i)
347 {
348 case HANDBOMB_WEAPON:
349#ifndef VOLUMEONE
350 case TRIPBOMB_WEAPON:
351#endif
352 if ( p->gotweapon[i] && p->ammo_amount[i] > 0 )
353 {
354 okay = i;
355 goto OKAY_HERE;
356 }
357 break;
358 }
359
360 for(i = p->curr_weapon+1; i < MAX_WEAPONS;i++)
361 switch(i)
362 {
363 case HANDBOMB_WEAPON:
364#ifdef VOLUMEONE
365 case TRIPBOMB_WEAPON:
366#endif
367 if ( p->gotweapon[i] && p->ammo_amount[i] > 0 )
368 {
369 okay = i;
370 goto OKAY_HERE;
371 }
372 break;
373 }
374
375 if(check_shoot == 0)
376 {
377 check_shoot = 1;
378 goto CHECK_SHOOT;
379 }
380 else
381 {
382 addweapon(p,KNEE_WEAPON);
383 return;
384 }
385 }
386
387 OKAY_HERE:
388
389 if(okay)
390 {
391 p->last_weapon = p->curr_weapon;
392 p->random_club_frame = 0;
393 p->curr_weapon = okay;
394 p->kickback_pic = 0;
395 if(p->holster_weapon == 1)
396 {
397 p->holster_weapon = 0;
398 p->weapon_pos = 10;
399 }
400 else p->weapon_pos = -1;
401 return;
402 }
403}
404 */
405
406int32_t ifsquished(short i, short p)
407{
408 sectortype *sc;
409 uint8_t squishme;
410 int32_t floorceildist;
411
412 if(PN == APLAYER && ud.clipping)
413 return 0;
414
415 sc = &sector[SECT];
416 floorceildist = sc->floorz - sc->ceilingz;
417
418 if(sc->lotag != 23)
419 {
420 if(sprite[i].pal == 1)
421 squishme = floorceildist < (32<<8) && (sc->lotag&32768) == 0;
422 else
423 squishme = floorceildist < (12<<8); // && (sc->lotag&32768) == 0;
424 }
425 else squishme = 0;
426
427 if( squishme )
428 {
429 FTA(10,&ps[p],0);
430
431 if(badguy(&sprite[i])) sprite[i].xvel = 0;
432
433 if(sprite[i].pal == 1)
434 {
435 hittype[i].picnum = SHOTSPARK1;
436 hittype[i].extra = 1;
437 return 0;
438 }
439
440 return 1;
441 }
442 return 0;
443}
444
445void hitradius( short i, int32_t r, int32_t hp1, int32_t hp2, int32_t hp3, int32_t hp4 )
446{
447 spritetype *s,*sj;
448 walltype *wal;
449 int32_t d, q, x1, y1;
450 int32_t sectcnt, sectend, dasect, startwall, endwall, nextsect;
451 short j,k,p,x,nextj,sect;
452 uint8_t statlist[] = {0,1,6,10,12,2,5};
453 short *tempshort = (short *)tempbuf;
454
455 s = &sprite[i];
456
457 if(s->picnum == RPG && s->xrepeat < 11) goto SKIPWALLCHECK;
458
459 if(s->picnum != SHRINKSPARK)
460 {
461 tempshort[0] = s->sectnum;
462 dasect = s->sectnum;
463 sectcnt = 0; sectend = 1;
464
465 do
466 {
467 dasect = tempshort[sectcnt++];
468 if(((sector[dasect].ceilingz-s->z)>>8) < r)
469 {
470 d = klabs(wall[sector[dasect].wallptr].x-s->x)+klabs(wall[sector[dasect].wallptr].y-s->y);
471 if(d < r)
472 checkhitceiling(dasect);
473 else
474 {
475 d = klabs(wall[wall[wall[sector[dasect].wallptr].point2].point2].x-s->x)+klabs(wall[wall[wall[sector[dasect].wallptr].point2].point2].y-s->y);
476 if(d < r)
477 checkhitceiling(dasect);
478 }
479 }
480
481 startwall = sector[dasect].wallptr;
482 endwall = startwall+sector[dasect].wallnum;
483 for(x=startwall,wal=&wall[startwall];x<endwall;x++,wal++)
484 if( ( klabs(wal->x-s->x)+klabs(wal->y-s->y) ) < r)
485 {
486 nextsect = wal->nextsector;
487 if (nextsect >= 0)
488 {
489 for(dasect=sectend-1;dasect>=0;dasect--)
490 if (tempshort[dasect] == nextsect) break;
491 if (dasect < 0) tempshort[sectend++] = nextsect;
492 }
493 x1 = (((wal->x+wall[wal->point2].x)>>1)+s->x)>>1;
494 y1 = (((wal->y+wall[wal->point2].y)>>1)+s->y)>>1;
495 updatesector(x1,y1,&sect);
496 if( sect >= 0 && cansee(x1,y1,s->z,sect,s->x,s->y,s->z,s->sectnum ) )
497 checkhitwall(i,x,wal->x,wal->y,s->z,s->picnum);
498 }
499 }
500 while (sectcnt < sectend);
501 }
502
503 SKIPWALLCHECK:
504
505 q = -(16<<8)+(TRAND&((32<<8)-1));
506
507 for(x = 0;x<7;x++)
508 {
509 j = headspritestat[statlist[x]];
510 while(j >= 0)
511 {
512 nextj = nextspritestat[j];
513 sj = &sprite[j];
514
515 if( x == 0 || x >= 5 || AFLAMABLE(sj->picnum) )
516 {
517 if( s->picnum != SHRINKSPARK || (sj->cstat&257) )
518 if( dist( s, sj ) < r )
519 {
520 if( badguy(sj) && !cansee( sj->x, sj->y,sj->z+q, sj->sectnum, s->x, s->y, s->z+q, s->sectnum) )
521 goto BOLT;
522 checkhitsprite( j, i );
523 }
524 }
525 else if( sj->extra >= 0 && sj != s && ( sj->picnum == TRIPBOMB || badguy(sj) || sj->picnum == QUEBALL || sj->picnum == STRIPEBALL || (sj->cstat&257) || sj->picnum == DUKELYINGDEAD ) )
526 {
527 if( s->picnum == SHRINKSPARK && sj->picnum != SHARK && ( j == s->owner || sj->xrepeat < 24 ) )
528 {
529 j = nextj;
530 continue;
531 }
532 if( s->picnum == MORTER && j == s->owner)
533 {
534 j = nextj;
535 continue;
536 }
537
538 if(sj->picnum == APLAYER) sj->z -= PHEIGHT;
539 d = dist( s, sj );
540 if(sj->picnum == APLAYER) sj->z += PHEIGHT;
541
542 if ( d < r && cansee( sj->x, sj->y, sj->z-(8<<8), sj->sectnum, s->x, s->y, s->z-(12<<8), s->sectnum) )
543 {
544 hittype[j].ang = getangle(sj->x-s->x,sj->y-s->y);
545
546 if ( s->picnum == RPG && sj->extra > 0)
547 hittype[j].picnum = RPG;
548 else
549 {
550 if( s->picnum == SHRINKSPARK )
551 hittype[j].picnum = SHRINKSPARK;
552 else hittype[j].picnum = RADIUSEXPLOSION;
553 }
554
555 if(s->picnum != SHRINKSPARK)
556 {
557 if ( d < r/3 )
558 {
559 if(hp4 == hp3) hp4++;
560 hittype[j].extra = hp3 + (TRAND%(hp4-hp3));
561 }
562 else if ( d < 2*r/3 )
563 {
564 if(hp3 == hp2) hp3++;
565 hittype[j].extra = hp2 + (TRAND%(hp3-hp2));
566 }
567 else if ( d < r )
568 {
569 if(hp2 == hp1) hp2++;
570 hittype[j].extra = hp1 + (TRAND%(hp2-hp1));
571 }
572
573 if( sprite[j].picnum != TANK && sprite[j].picnum != ROTATEGUN && sprite[j].picnum != RECON && sprite[j].picnum != BOSS1 && sprite[j].picnum != BOSS2 && sprite[j].picnum != BOSS3 && sprite[j].picnum != BOSS4 )
574 {
575 if(sj->xvel < 0) sj->xvel = 0;
576 sj->xvel += (s->extra<<2);
577 }
578
579 if( sj->picnum == PODFEM1 || sj->picnum == FEM1 ||
580 sj->picnum == FEM2 || sj->picnum == FEM3 ||
581 sj->picnum == FEM4 || sj->picnum == FEM5 ||
582 sj->picnum == FEM6 || sj->picnum == FEM7 ||
583 sj->picnum == FEM8 || sj->picnum == FEM9 ||
584 sj->picnum == FEM10 || sj->picnum == STATUE ||
585 sj->picnum == STATUEFLASH || sj->picnum == SPACEMARINE || sj->picnum == QUEBALL || sj->picnum == STRIPEBALL)
586 checkhitsprite( j, i );
587 }
588 else if(s->extra == 0) hittype[j].extra = 0;
589
590 if ( sj->picnum != RADIUSEXPLOSION &&
591 s->owner >= 0 && sprite[s->owner].statnum < MAXSTATUS )
592 {
593 if(sj->picnum == APLAYER)
594 {
595 p = sj->yvel;
596 if(ps[p].newowner >= 0)
597 {
598 ps[p].newowner = -1;
599 ps[p].posx = ps[p].oposx;
600 ps[p].posy = ps[p].oposy;
601 ps[p].posz = ps[p].oposz;
602 ps[p].ang = ps[p].oang;
603 updatesector(ps[p].posx,ps[p].posy,&ps[p].cursectnum);
604 setpal(&ps[p]);
605
606 k = headspritestat[1];
607 while(k >= 0)
608 {
609 if(sprite[k].picnum==CAMERA1)
610 sprite[k].yvel = 0;
611 k = nextspritestat[k];
612 }
613 }
614 }
615 hittype[j].owner = s->owner;
616 }
617 }
618 }
619 BOLT:
620 j = nextj;
621 }
622 }
623}
624
625
626int movesprite(short spritenum, int32_t xchange, int32_t ychange, int32_t zchange, uint32_t cliptype)
627{
628 int32_t daz,h, oldx, oldy;
629 short retval, dasectnum, cd;
630 uint8_t bg;
631
632 bg = badguy(&sprite[spritenum]);
633
634 if(sprite[spritenum].statnum == 5 || (bg && sprite[spritenum].xrepeat < 4 ) )
635 {
636 sprite[spritenum].x += (xchange*TICSPERFRAME)>>2;
637 sprite[spritenum].y += (ychange*TICSPERFRAME)>>2;
638 sprite[spritenum].z += (zchange*TICSPERFRAME)>>2;
639 if(bg)
640 setsprite(spritenum,sprite[spritenum].x,sprite[spritenum].y,sprite[spritenum].z);
641 return 0;
642 }
643
644 dasectnum = sprite[spritenum].sectnum;
645
646 daz = sprite[spritenum].z;
647 h = ((tiles[sprite[spritenum].picnum].dim.height * sprite[spritenum].yrepeat)<<1);
648 daz -= h;
649
650 if( bg )
651 {
652 oldx = sprite[spritenum].x;
653 oldy = sprite[spritenum].y;
654
655 if( sprite[spritenum].xrepeat > 60 )
656 retval = clipmove(&sprite[spritenum].x,&sprite[spritenum].y,&daz,&dasectnum,((xchange*TICSPERFRAME)<<11),((ychange*TICSPERFRAME)<<11),1024L,(4<<8),(4<<8),cliptype);
657 else
658 {
659 if(sprite[spritenum].picnum == LIZMAN)
660 cd = 292L;
661 else if( (actortype[sprite[spritenum].picnum]&3) )
662 cd = sprite[spritenum].clipdist<<2;
663 else
664 cd = 192L;
665
666 retval = clipmove(&sprite[spritenum].x,&sprite[spritenum].y,&daz,&dasectnum,((xchange*TICSPERFRAME)<<11),((ychange*TICSPERFRAME)<<11),cd,(4<<8),(4<<8),cliptype);
667 }
668
669 if( dasectnum < 0 || ( dasectnum >= 0 &&
670 ( ( hittype[spritenum].actorstayput >= 0 && hittype[spritenum].actorstayput != dasectnum ) ||
671 ( ( sprite[spritenum].picnum == BOSS2 ) && sprite[spritenum].pal == 0 && sector[dasectnum].lotag != 3 ) ||
672 ( ( sprite[spritenum].picnum == BOSS1 || sprite[spritenum].picnum == BOSS2 ) && sector[dasectnum].lotag == 1 ) ||
673 ( sector[dasectnum].lotag == 1 && ( sprite[spritenum].picnum == LIZMAN || ( sprite[spritenum].picnum == LIZTROOP && sprite[spritenum].zvel == 0 ) ) )
674 ) )
675 )
676 {
677 sprite[spritenum].x = oldx;
678 sprite[spritenum].y = oldy;
679 if(sector[dasectnum].lotag == 1 && sprite[spritenum].picnum == LIZMAN)
680 sprite[spritenum].ang = (TRAND&2047);
681 else if( (hittype[spritenum].temp_data[0]&3) == 1 && sprite[spritenum].picnum != COMMANDER )
682 sprite[spritenum].ang = (TRAND&2047);
683 setsprite(spritenum,oldx,oldy,sprite[spritenum].z);
684 if(dasectnum < 0) dasectnum = 0;
685 return (16384+dasectnum);
686 }
687 if( (retval&49152) >= 32768 && (hittype[spritenum].cgg==0) ) sprite[spritenum].ang += 768;
688 }
689 else
690 {
691 if(sprite[spritenum].statnum == 4)
692 retval =
693 clipmove(&sprite[spritenum].x,&sprite[spritenum].y,&daz,&dasectnum,((xchange*TICSPERFRAME)<<11),((ychange*TICSPERFRAME)<<11),8L,(4<<8),(4<<8),cliptype);
694 else
695 retval =
696 clipmove(&sprite[spritenum].x,&sprite[spritenum].y,&daz,&dasectnum,((xchange*TICSPERFRAME)<<11),((ychange*TICSPERFRAME)<<11),(int32_t)(sprite[spritenum].clipdist<<2),(4<<8),(4<<8),cliptype);
697 }
698
699 if( dasectnum >= 0)
700 if ( (dasectnum != sprite[spritenum].sectnum) )
701 changespritesect(spritenum,dasectnum);
702 daz = sprite[spritenum].z + ((zchange*TICSPERFRAME)>>3);
703 if ((daz > hittype[spritenum].ceilingz) && (daz <= hittype[spritenum].floorz))
704 sprite[spritenum].z = daz;
705 else
706 if (retval == 0)
707 return(16384+dasectnum);
708
709 return(retval);
710}
711
712
713short ssp(short i,uint32_t cliptype) //The set sprite function
714{
715 spritetype *s;
716 int32_t movetype;
717
718 s = &sprite[i];
719
720 movetype = movesprite(i,
721 (s->xvel*(sintable[(s->ang+512)&2047]))>>14,
722 (s->xvel*(sintable[s->ang&2047]))>>14,s->zvel,
723 cliptype);
724
725 return (movetype==0);
726}
727
728void insertspriteq(short i)
729{
730 if(spriteqamount > 0)
731 {
732 if(spriteq[spriteqloc] >= 0)
733 sprite[spriteq[spriteqloc]].xrepeat = 0;
734 spriteq[spriteqloc] = i;
735 spriteqloc = (spriteqloc+1)%spriteqamount;
736 }
737 else sprite[i].xrepeat = sprite[i].yrepeat = 0;
738}
739
740void lotsofmoney(spritetype *s, short n)
741{
742 short i ,j;
743 for(i=n;i>0;i--)
744 {
745 j = EGS(s->sectnum,s->x,s->y,s->z-(TRAND%(47<<8)),MONEY,-32,8,8,TRAND&2047,0,0,0,5);
746 sprite[j].cstat = TRAND&12;
747 }
748}
749
750void lotsofmail(spritetype *s, short n)
751{
752 short i ,j;
753 for(i=n;i>0;i--)
754 {
755 j = EGS(s->sectnum,s->x,s->y,s->z-(TRAND%(47<<8)),MAIL,-32,8,8,TRAND&2047,0,0,0,5);
756 sprite[j].cstat = TRAND&12;
757 }
758}
759
760void lotsofpaper(spritetype *s, short n)
761{
762 short i ,j;
763 for(i=n;i>0;i--)
764 {
765 j = EGS(s->sectnum,s->x,s->y,s->z-(TRAND%(47<<8)),PAPER,-32,8,8,TRAND&2047,0,0,0,5);
766 sprite[j].cstat = TRAND&12;
767 }
768}
769
770
771
772void guts(spritetype *s,short gtype, short n, short p)
773{
774 int32_t gutz,floorz;
775 short i,a,j;
776 uint8_t sx,sy;
777 int8_t pal;
778
779 if(badguy(s) && s->xrepeat < 16)
780 sx = sy = 8;
781 else sx = sy = 32;
782
783 gutz = s->z-(8<<8);
784 floorz = getflorzofslope(s->sectnum,s->x,s->y);
785
786 if( gutz > ( floorz-(8<<8) ) )
787 gutz = floorz-(8<<8);
788
789 if(s->picnum == COMMANDER)
790 gutz -= (24<<8);
791
792 if( badguy(s) && s->pal == 6)
793 pal = 6;
794 else pal = 0;
795
796 for(j=0;j<n;j++)
797 {
798 a = TRAND&2047;
799 i = EGS(s->sectnum,s->x+(TRAND&255)-128,s->y+(TRAND&255)-128,gutz-(TRAND&8191),gtype,-32,sx,sy,a,48+(TRAND&31),-512-(TRAND&2047),ps[p].i,5);
800 if(PN == JIBS2)
801 {
802 sprite[i].xrepeat >>= 2;
803 sprite[i].yrepeat >>= 2;
804 }
805 if(pal == 6)
806 sprite[i].pal = 6;
807 }
808}
809
810void gutsdir(spritetype *s,short gtype, short n, short p)
811{
812 int32_t gutz,floorz;
813 short i,a,j;
814 uint8_t sx,sy;
815
816 if(badguy(s) && s->xrepeat < 16)
817 sx = sy = 8;
818 else sx = sy = 32;
819
820 gutz = s->z-(8<<8);
821 floorz = getflorzofslope(s->sectnum,s->x,s->y);
822
823 if( gutz > ( floorz-(8<<8) ) )
824 gutz = floorz-(8<<8);
825
826 if(s->picnum == COMMANDER)
827 gutz -= (24<<8);
828
829 for(j=0;j<n;j++)
830 {
831 a = TRAND&2047;
832 i = EGS(s->sectnum,s->x,s->y,gutz,gtype,-32,sx,sy,a,256+(TRAND&127),-512-(TRAND&2047),ps[p].i,5);
833 }
834}
835
836void setsectinterpolate(short i)
837{
838 int32_t j, k, startwall,endwall;
839
840 startwall = sector[SECT].wallptr;
841 endwall = startwall+sector[SECT].wallnum;
842
843 for(j=startwall;j<endwall;j++)
844 {
845 setinterpolation(&wall[j].x);
846 setinterpolation(&wall[j].y);
847 k = wall[j].nextwall;
848 if(k >= 0)
849 {
850 setinterpolation(&wall[k].x);
851 setinterpolation(&wall[k].y);
852 k = wall[k].point2;
853 setinterpolation(&wall[k].x);
854 setinterpolation(&wall[k].y);
855 }
856 }
857}
858
859void clearsectinterpolate(short i)
860{
861 short j,startwall,endwall;
862
863 startwall = sector[SECT].wallptr;
864 endwall = startwall+sector[SECT].wallnum;
865 for(j=startwall;j<endwall;j++)
866 {
867 stopinterpolation(&wall[j].x);
868 stopinterpolation(&wall[j].y);
869 if(wall[j].nextwall >= 0)
870 {
871 stopinterpolation(&wall[wall[j].nextwall].x);
872 stopinterpolation(&wall[wall[j].nextwall].y);
873 }
874 }
875}
876
877void ms(short i)
878{
879 //T1,T2 and T3 are used for all the sector moving stuff!!!
880
881 short startwall,endwall,x;
882 int32_t tx,ty,j,k;
883 spritetype *s;
884
885 s = &sprite[i];
886
887 s->x += (s->xvel*(sintable[(s->ang+512)&2047]))>>14;
888 s->y += (s->xvel*(sintable[s->ang&2047]))>>14;
889
890 j = T2;
891 k = T3;
892
893 startwall = sector[s->sectnum].wallptr;
894 endwall = startwall+sector[s->sectnum].wallnum;
895 for(x=startwall;x<endwall;x++)
896 {
897 rotatepoint(
898 0,0,
899 msx[j],msy[j],
900 k&2047,&tx,&ty);
901
902 dragpoint(x,s->x+tx,s->y+ty);
903
904 j++;
905 }
906}
907
908void movefta(void)
909{
910 int32_t x, px, py, sx, sy;
911 short i, j, p, psect, ssect, nexti;
912 spritetype *s;
913
914 i = headspritestat[2];
915 while(i >= 0)
916 {
917 nexti = nextspritestat[i];
918
919 s = &sprite[i];
920 p = findplayer(s,&x);
921
922 ssect = psect = s->sectnum;
923
924 if(sprite[ps[p].i].extra > 0 )
925 {
926 if( x < 30000 )
927 {
928 hittype[i].timetosleep++;
929 if( hittype[i].timetosleep >= (x>>8) )
930 {
931 if(badguy(s))
932 {
933 px = ps[p].oposx+64-(TRAND&127);
934 py = ps[p].oposy+64-(TRAND&127);
935 updatesector(px,py,&psect);
936 if(psect == -1)
937 {
938 i = nexti;
939 continue;
940 }
941 sx = s->x+64-(TRAND&127);
942 sy = s->y+64-(TRAND&127);
943 updatesector(px,py,&ssect);
944 if(ssect == -1)
945 {
946 i = nexti;
947 continue;
948 }
949 j = cansee(sx,sy,s->z-(TRAND%(52<<8)),s->sectnum,px,py,ps[p].oposz-(TRAND%(32<<8)),ps[p].cursectnum);
950 }
951 else
952 j = cansee(s->x,s->y,s->z-((TRAND&31)<<8),s->sectnum,ps[p].oposx,ps[p].oposy,ps[p].oposz-((TRAND&31)<<8),ps[p].cursectnum);
953
954 // j = 1;
955
956 if(j) switch(s->picnum)
957 {
958 case RUBBERCAN:
959 case EXPLODINGBARREL:
960 case WOODENHORSE:
961 case HORSEONSIDE:
962 case CANWITHSOMETHING:
963 case CANWITHSOMETHING2:
964 case CANWITHSOMETHING3:
965 case CANWITHSOMETHING4:
966 case FIREBARREL:
967 case FIREVASE:
968 case NUKEBARREL:
969 case NUKEBARRELDENTED:
970 case NUKEBARRELLEAKED:
971 case TRIPBOMB:
972 if (sector[s->sectnum].ceilingstat&1)
973 s->shade = sector[s->sectnum].ceilingshade;
974 else s->shade = sector[s->sectnum].floorshade;
975
976 hittype[i].timetosleep = 0;
977 changespritestat(i,6);
978 break;
979 default:
980 hittype[i].timetosleep = 0;
981 check_fta_sounds(i);
982 changespritestat(i,1);
983 break;
984 }
985 else hittype[i].timetosleep = 0;
986 }
987 }
988 if( badguy( s ) )
989 {
990 if (sector[s->sectnum].ceilingstat&1)
991 s->shade = sector[s->sectnum].ceilingshade;
992 else s->shade = sector[s->sectnum].floorshade;
993 }
994 }
995 i = nexti;
996 }
997}
998
999short ifhitsectors(short sectnum)
1000{
1001 short i;
1002
1003 i = headspritestat[5];
1004 while(i >= 0)
1005 {
1006 if( PN == EXPLOSION2 && sectnum == SECT )
1007 return i;
1008 i = nextspritestat[i];
1009 }
1010 return -1;
1011}
1012
1013short ifhitbyweapon(short sn)
1014{
1015 short j, p;
1016 spritetype *npc;
1017
1018 if( hittype[sn].extra >= 0 )
1019 {
1020 if(sprite[sn].extra >= 0 )
1021 {
1022 npc = &sprite[sn];
1023
1024 if(npc->picnum == APLAYER)
1025 {
1026 if(ud.god && hittype[sn].picnum != SHRINKSPARK ) return -1;
1027
1028 p = npc->yvel;
1029 j = hittype[sn].owner;
1030
1031 if( j >= 0 &&
1032 sprite[j].picnum == APLAYER &&
1033 ud.coop == 1 &&
1034 ud.ffire == 0 )
1035 return -1;
1036
1037 npc->extra -= hittype[sn].extra;
1038
1039 if(j >= 0)
1040 {
1041 if(npc->extra <= 0 && hittype[sn].picnum != FREEZEBLAST)
1042 {
1043 npc->extra = 0;
1044
1045 ps[p].wackedbyactor = j;
1046
1047 if( sprite[hittype[sn].owner].picnum == APLAYER && p != sprite[hittype[sn].owner].yvel )
1048 ps[p].frag_ps = sprite[j].yvel;
1049
1050 hittype[sn].owner = ps[p].i;
1051 }
1052 }
1053
1054 switch(hittype[sn].picnum)
1055 {
1056 case RADIUSEXPLOSION:
1057 case RPG:
1058 case HYDRENT:
1059 case HEAVYHBOMB:
1060 case SEENINE:
1061 case OOZFILTER:
1062 case EXPLODINGBARREL:
1063 ps[p].posxv +=
1064 hittype[sn].extra*(sintable[(hittype[sn].ang+512)&2047])<<2;
1065 ps[p].posyv +=
1066 hittype[sn].extra*(sintable[hittype[sn].ang&2047])<<2;
1067 break;
1068 default:
1069 ps[p].posxv +=
1070 hittype[sn].extra*(sintable[(hittype[sn].ang+512)&2047])<<1;
1071 ps[p].posyv +=
1072 hittype[sn].extra*(sintable[hittype[sn].ang&2047])<<1;
1073 break;
1074 }
1075 }
1076 else
1077 {
1078 if(hittype[sn].extra == 0 )
1079 if( hittype[sn].picnum == SHRINKSPARK && npc->xrepeat < 24 )
1080 return -1;
1081
1082 npc->extra -= hittype[sn].extra;
1083 if(npc->picnum != RECON && npc->owner >= 0 && sprite[npc->owner].statnum < MAXSTATUS )
1084 npc->owner = hittype[sn].owner;
1085 }
1086
1087 hittype[sn].extra = -1;
1088 return hittype[sn].picnum;
1089 }
1090 }
1091
1092 hittype[sn].extra = -1;
1093 return -1;
1094}
1095
1096void movecyclers(void)
1097{
1098 short q, j, x, t, s, *c;
1099 walltype *wal;
1100 uint8_t cshade;
1101
1102 for(q=numcyclers-1;q>=0;q--)
1103 {
1104
1105 c = &cyclers[q][0];
1106 s = c[0];
1107
1108 t = c[3];
1109 j = t+(sintable[c[1]&2047]>>10);
1110 cshade = c[2];
1111
1112 if( j < cshade ) j = cshade;
1113 else if( j > t ) j = t;
1114
1115 c[1] += sector[s].extra;
1116 if(c[5])
1117 {
1118 wal = &wall[sector[s].wallptr];
1119 for(x = sector[s].wallnum;x>0;x--,wal++)
1120 if( wal->hitag != 1 )
1121 {
1122 wal->shade = j;
1123
1124 if( (wal->cstat&2) && wal->nextwall >= 0)
1125 wall[wal->nextwall].shade = j;
1126
1127 }
1128 sector[s].floorshade = sector[s].ceilingshade = j;
1129 }
1130 }
1131}
1132
1133void movedummyplayers(void)
1134{
1135 short i, p, nexti;
1136
1137 i = headspritestat[13];
1138 while(i >= 0)
1139 {
1140 nexti = nextspritestat[i];
1141
1142 p = sprite[OW].yvel;
1143
1144 if( ps[p].on_crane >= 0 || sector[ps[p].cursectnum].lotag != 1 || sprite[ps[p].i].extra <= 0 )
1145 {
1146 ps[p].dummyplayersprite = -1;
1147 KILLIT(i);
1148 }
1149 else
1150 {
1151 if(ps[p].on_ground && ps[p].on_warping_sector == 1 && sector[ps[p].cursectnum].lotag == 1 )
1152 {
1153 CS = 257;
1154 SZ = sector[SECT].ceilingz+(27<<8);
1155 SA = ps[p].ang;
1156 if(T1 == 8)
1157 T1 = 0;
1158 else T1++;
1159 }
1160 else
1161 {
1162 if(sector[SECT].lotag != 2) SZ = sector[SECT].floorz;
1163 CS = (short) 32768;
1164 }
1165 }
1166
1167 SX += (ps[p].posx-ps[p].oposx);
1168 SY += (ps[p].posy-ps[p].oposy);
1169 setsprite(i,SX,SY,SZ);
1170
1171 BOLT:
1172
1173 i = nexti;
1174 }
1175}
1176
1177
1178short otherp;
1179void moveplayers(void) //Players
1180{
1181 short i , nexti;
1182 int32_t otherx;
1183 spritetype *s;
1184 struct player_struct *p;
1185
1186 i = headspritestat[10];
1187 while(i >= 0)
1188 {
1189 nexti = nextspritestat[i];
1190
1191 s = &sprite[i];
1192 p = &ps[s->yvel];
1193 if(s->owner >= 0)
1194 {
1195 if(p->newowner >= 0 ) //Looking thru the camera
1196 {
1197 s->x = p->oposx;
1198 s->y = p->oposy;
1199 hittype[i].bposz = s->z = p->oposz+PHEIGHT;
1200 s->ang = p->oang;
1201 setsprite(i,s->x,s->y,s->z);
1202 }
1203 else
1204 {
1205 if(ud.multimode > 1)
1206 otherp = findotherplayer(s->yvel,&otherx);
1207 else
1208 {
1209 otherp = s->yvel;
1210 otherx = 0;
1211 }
1212
1213 execute(i,s->yvel,otherx);
1214
1215 if(ud.multimode > 1)
1216 if( sprite[ps[otherp].i].extra > 0 )
1217 {
1218 if( s->yrepeat > 32 && sprite[ps[otherp].i].yrepeat < 32)
1219 {
1220 if( otherx < 1400 && p->knee_incs == 0 )
1221 {
1222 p->knee_incs = 1;
1223 p->weapon_pos = -1;
1224 p->actorsqu = ps[otherp].i;
1225 }
1226 }
1227 }
1228 if(ud.god)
1229 {
1230 s->extra = max_player_health;
1231 s->cstat = 257;
1232 p->jetpack_amount = 1599;
1233 }
1234
1235
1236 if( s->extra > 0 )
1237 {
1238 hittype[i].owner = i;
1239
1240 if(ud.god == 0)
1241 if( ceilingspace(s->sectnum) || floorspace(s->sectnum) )
1242 quickkill(p);
1243 }
1244 else
1245 {
1246
1247 p->posx = s->x;
1248 p->posy = s->y;
1249 p->posz = s->z-(20<<8);
1250
1251 p->newowner = -1;
1252
1253 if( p->wackedbyactor >= 0 && sprite[p->wackedbyactor].statnum < MAXSTATUS )
1254 {
1255 p->ang += getincangle(p->ang,getangle(sprite[p->wackedbyactor].x-p->posx,sprite[p->wackedbyactor].y-p->posy))>>1;
1256 p->ang &= 2047;
1257 }
1258
1259 }
1260 s->ang = p->ang;
1261 }
1262 }
1263 else
1264 {
1265 if(p->holoduke_on == -1)
1266 KILLIT(i);
1267
1268 hittype[i].bposx = s->x;
1269 hittype[i].bposy = s->y;
1270 hittype[i].bposz = s->z;
1271
1272 s->cstat = 0;
1273
1274 if(s->xrepeat < 42)
1275 {
1276 s->xrepeat += 4;
1277 s->cstat |= 2;
1278 }
1279 else s->xrepeat = 42;
1280 if(s->yrepeat < 36)
1281 s->yrepeat += 4;
1282 else
1283 {
1284 s->yrepeat = 36;
1285 if(sector[s->sectnum].lotag != 2)
1286 makeitfall(i);
1287 if(s->zvel == 0 && sector[s->sectnum].lotag == 1)
1288 s->z += (32<<8);
1289 }
1290
1291 if(s->extra < 8)
1292 {
1293 s->xvel = 128;
1294 s->ang = p->ang;
1295 s->extra++;
1296
1297 }
1298 else
1299 {
1300 s->ang = 2047-p->ang;
1301 setsprite(i,s->x,s->y,s->z);
1302 }
1303 }
1304
1305 if (sector[s->sectnum].ceilingstat&1)
1306 s->shade += (sector[s->sectnum].ceilingshade-s->shade)>>1;
1307 else
1308 s->shade += (sector[s->sectnum].floorshade-s->shade)>>1;
1309
1310 BOLT:
1311 i = nexti;
1312 }
1313}
1314
1315
1316void movefx(void)
1317{
1318 short i, j, nexti, p;
1319 int32_t x, ht;
1320 spritetype *s;
1321
1322 i = headspritestat[11];
1323 while(i >= 0)
1324 {
1325 s = &sprite[i];
1326
1327 nexti = nextspritestat[i];
1328
1329 switch(s->picnum)
1330 {
1331 case RESPAWN:
1332 if(sprite[i].extra == 66)
1333 {
1334 j = spawn(i,SHT);
1335// sprite[j].pal = sprite[i].pal;
1336 KILLIT(i);
1337 }
1338 else if(sprite[i].extra > (66-13))
1339 sprite[i].extra++;
1340 break;
1341
1342 case MUSICANDSFX:
1343
1344 ht = s->hitag;
1345
1346 if(T2 != SoundToggle)
1347 {
1348 T2 = SoundToggle;
1349 T1 = 0;
1350 }
1351
1352 if(s->lotag >= 1000 && s->lotag < 2000)
1353 {
1354 x = ldist(&sprite[ps[screenpeek].i],s);
1355 if( x < ht && T1 == 0 )
1356 {
1357 FX_SetReverb( s->lotag - 1000 );
1358 T1 = 1;
1359 }
1360 if( x >= ht && T1 == 1 )
1361 {
1362 FX_SetReverb(0);
1363 FX_SetReverbDelay(0);
1364 T1 = 0;
1365 }
1366 }
1367 else if(s->lotag < 999 && (uint32_t)sector[s->sectnum].lotag < 9 && AmbienceToggle && sector[SECT].floorz != sector[SECT].ceilingz)
1368 {
1369 if( (soundm[s->lotag]&2) )
1370 {
1371 x = dist(&sprite[ps[screenpeek].i],s);
1372 if( x < ht && T1 == 0 && FX_VoiceAvailable(soundpr[s->lotag]-1) )
1373 {
1374 if(numenvsnds == NumVoices)
1375 {
1376 j = headspritestat[11];
1377 while(j >= 0)
1378 {
1379 if( PN == MUSICANDSFX && j != i && sprite[j].lotag < 999 && hittype[j].temp_data[0] == 1 && dist(&sprite[j],&sprite[ps[screenpeek].i]) > x )
1380 {
1381 stopenvsound(sprite[j].lotag,j);
1382 break;
1383 }
1384 j = nextspritestat[j];
1385 }
1386 if(j == -1) goto BOLT;
1387 }
1388 spritesound(s->lotag,i);
1389 T1 = 1;
1390 }
1391 if( x >= ht && T1 == 1 )
1392 {
1393 T1 = 0;
1394 stopenvsound(s->lotag,i);
1395 }
1396 }
1397 if( (soundm[s->lotag]&16) )
1398 {
1399 if(T5 > 0) T5--;
1400 else for(p=connecthead;p>=0;p=connectpoint2[p])
1401 if( p == myconnectindex && ps[p].cursectnum == s->sectnum )
1402 {
1403 j = s->lotag+((uint32_t)global_random%(s->hitag+1));
1404 sound(j);
1405 T5 = 26*40 + (global_random%(26*40));
1406 }
1407 }
1408 }
1409 break;
1410 }
1411 BOLT:
1412 i = nexti;
1413 }
1414}
1415
1416
1417
1418void movefallers(void)
1419{
1420 short i, nexti, sect, j;
1421 spritetype *s;
1422 int32_t x;
1423
1424 i = headspritestat[12];
1425 while(i >= 0)
1426 {
1427 nexti = nextspritestat[i];
1428 s = &sprite[i];
1429
1430 sect = s->sectnum;
1431
1432 if( T1 == 0 )
1433 {
1434 s->z -= (16<<8);
1435 T2 = s->ang;
1436 x = s->extra;
1437 IFHIT
1438 {
1439 if( j == FIREEXT || j == RPG || j == RADIUSEXPLOSION || j == SEENINE || j == OOZFILTER )
1440 {
1441 if(s->extra <= 0)
1442 {
1443 T1 = 1;
1444 j = headspritestat[12];
1445 while(j >= 0)
1446 {
1447 if(sprite[j].hitag == SHT)
1448 {
1449 hittype[j].temp_data[0] = 1;
1450 sprite[j].cstat &= (65535-64);
1451 if(sprite[j].picnum == CEILINGSTEAM || sprite[j].picnum == STEAM)
1452 sprite[j].cstat |= 32768;
1453 }
1454 j = nextspritestat[j];
1455 }
1456 }
1457 }
1458 else
1459 {
1460 hittype[i].extra = 0;
1461 s->extra = x;
1462 }
1463 }
1464 s->ang = T2;
1465 s->z += (16<<8);
1466 }
1467 else if(T1 == 1)
1468 {
1469 if(s->lotag > 0)
1470 {
1471 s->lotag-=3;
1472 if(s->lotag <= 0)
1473 {
1474 s->xvel = (32+(TRAND&63));
1475 s->zvel = -(1024+(TRAND&1023));
1476 }
1477 }
1478 else
1479 {
1480 if( s->xvel > 0)
1481 {
1482 s->xvel -= 8;
1483 ssp(i,CLIPMASK0);
1484 }
1485
1486 if( floorspace(s->sectnum) ) x = 0;
1487 else
1488 {
1489 if(ceilingspace(s->sectnum))
1490 x = gc/6;
1491 else
1492 x = gc;
1493 }
1494
1495 if( s->z < (sector[sect].floorz-FOURSLEIGHT) )
1496 {
1497 s->zvel += x;
1498 if(s->zvel > 6144)
1499 s->zvel = 6144;
1500 s->z += s->zvel;
1501 }
1502 if( (sector[sect].floorz-s->z) < (16<<8) )
1503 {
1504 j = 1+(TRAND&7);
1505 for(x=0;x<j;x++) RANDOMSCRAP;
1506 KILLIT(i);
1507 }
1508 }
1509 }
1510
1511 BOLT:
1512 i = nexti;
1513 }
1514}
1515
1516void movestandables(void)
1517{
1518 short i, j, k, m, nexti, nextj, p, sect;
1519 int32_t l=0, x, *t;
1520 spritetype *s;
1521
1522 i = headspritestat[6];
1523 while(i >= 0)
1524 {
1525 nexti = nextspritestat[i];
1526
1527 t = &hittype[i].temp_data[0];
1528 s = &sprite[i];
1529 sect = s->sectnum;
1530
1531 if( sect < 0 ) KILLIT(i);
1532
1533 hittype[i].bposx = s->x;
1534 hittype[i].bposy = s->y;
1535 hittype[i].bposz = s->z;
1536
1537 IFWITHIN(CRANE,CRANE+3)
1538 {
1539 //t[0] = state
1540 //t[1] = checking sector number
1541
1542 if(s->xvel) getglobalz(i);
1543
1544 if( t[0] == 0 ) //Waiting to check the sector
1545 {
1546 j = headspritesect[t[1]];
1547 while(j>=0)
1548 {
1549 nextj = nextspritesect[j];
1550 switch( sprite[j].statnum )
1551 {
1552 case 1:
1553 case 2:
1554 case 6:
1555 case 10:
1556 s->ang = getangle(msx[t[4]+1]-s->x,msy[t[4]+1]-s->y);
1557 setsprite(j,msx[t[4]+1],msy[t[4]+1],sprite[j].z);
1558 t[0]++;
1559 goto BOLT;
1560 }
1561 j = nextj;
1562 }
1563 }
1564
1565 else if(t[0]==1)
1566 {
1567 if( s->xvel < 184 )
1568 {
1569 s->picnum = CRANE+1;
1570 s->xvel += 8;
1571 }
1572
1573 if(sect == t[1])
1574 t[0]++;
1575 }
1576 else if(t[0]==2 || t[0]==7)
1577 {
1578 s->z += (1024+512);
1579
1580 if(t[0]==2)
1581 {
1582 if( (sector[sect].floorz - s->z) < (64<<8) )
1583 if(s->picnum > CRANE) s->picnum--;
1584
1585 if( (sector[sect].floorz - s->z) < (4096+1024))
1586 t[0]++;
1587 }
1588 if(t[0]==7)
1589 {
1590 if( (sector[sect].floorz - s->z) < (64<<8) )
1591 {
1592 if(s->picnum > CRANE) s->picnum--;
1593 else
1594 {
1595 if(s->owner==-2)
1596 {
1597 spritesound(DUKE_GRUNT,ps[p].i);
1598 p = findplayer(s,&x);
1599 if(ps[p].on_crane == i)
1600 ps[p].on_crane = -1;
1601 }
1602 t[0]++;
1603 s->owner = -1;
1604 }
1605 }
1606 }
1607 }
1608 else if(t[0]==3)
1609 {
1610 s->picnum++;
1611 if( s->picnum == (CRANE+2) )
1612 {
1613 p = checkcursectnums(t[1]);
1614 if(p >= 0 && ps[p].on_ground)
1615 {
1616 s->owner = -2;
1617 ps[p].on_crane = i;
1618 spritesound(DUKE_GRUNT,ps[p].i);
1619 ps[p].ang = s->ang+1024;
1620 }
1621 else
1622 {
1623 j = headspritesect[t[1]];
1624 while(j>=0)
1625 {
1626 switch( sprite[j].statnum )
1627 {
1628 case 1:
1629 case 6:
1630 s->owner = j;
1631 break;
1632 }
1633 j = nextspritesect[j];
1634 }
1635 }
1636
1637 t[0]++;//Grabbed the sprite
1638 t[2]=0;
1639 goto BOLT;
1640 }
1641 }
1642 else if(t[0]==4) //Delay before going up
1643 {
1644 t[2]++;
1645 if(t[2] > 10)
1646 t[0]++;
1647 }
1648 else if(t[0]==5 || t[0] == 8)
1649 {
1650 if(t[0]==8 && s->picnum < (CRANE+2))
1651 if( (sector[sect].floorz-s->z) > 8192)
1652 s->picnum++;
1653
1654 if(s->z < msx[t[4]+2])
1655 {
1656 t[0]++;
1657 s->xvel = 0;
1658 }
1659 else
1660 s->z -= (1024+512);
1661 }
1662 else if(t[0]==6)
1663 {
1664 if( s->xvel < 192 )
1665 s->xvel += 8;
1666 s->ang = getangle(msx[t[4]]-s->x,msy[t[4]]-s->y);
1667
1668 if( ((s->x-msx[t[4]])*(s->x-msx[t[4]])+(s->y-msy[t[4]])*(s->y-msy[t[4]]) ) < (128*128) )
1669 t[0]++;
1670 }
1671
1672 else if(t[0]==9)
1673 t[0] = 0;
1674
1675 setsprite(msy[t[4]+2],s->x,s->y,s->z-(34<<8));
1676
1677 if(s->owner != -1)
1678 {
1679 p = findplayer(s,&x);
1680
1681 IFHIT
1682 {
1683 if(s->owner == -2)
1684 if(ps[p].on_crane == i)
1685 ps[p].on_crane = -1;
1686 s->owner = -1;
1687 s->picnum = CRANE;
1688 goto BOLT;
1689 }
1690
1691 if(s->owner >= 0)
1692 {
1693 setsprite(s->owner,s->x,s->y,s->z);
1694
1695 hittype[s->owner].bposx = s->x;
1696 hittype[s->owner].bposy = s->y;
1697 hittype[s->owner].bposz = s->z;
1698
1699 s->zvel = 0;
1700 }
1701 else if(s->owner == -2)
1702 {
1703 ps[p].oposx = ps[p].posx = s->x-(sintable[(ps[p].ang+512)&2047]>>6);
1704 ps[p].oposy = ps[p].posy = s->y-(sintable[ps[p].ang&2047]>>6);
1705 ps[p].oposz = ps[p].posz = s->z+(2<<8);
1706 setsprite(ps[p].i,ps[p].posx,ps[p].posy,ps[p].posz);
1707 ps[p].cursectnum = sprite[ps[p].i].sectnum;
1708 }
1709 }
1710
1711 goto BOLT;
1712 }
1713
1714 IFWITHIN(WATERFOUNTAIN,WATERFOUNTAIN+3)
1715 {
1716 if(t[0] > 0)
1717 {
1718 if( t[0] < 20 )
1719 {
1720 t[0]++;
1721
1722 s->picnum++;
1723
1724 if( s->picnum == ( WATERFOUNTAIN+3 ) )
1725 s->picnum = WATERFOUNTAIN+1;
1726 }
1727 else
1728 {
1729 p = findplayer(s,&x);
1730
1731 if(x > 512)
1732 {
1733 t[0] = 0;
1734 s->picnum = WATERFOUNTAIN;
1735 }
1736 else t[0] = 1;
1737 }
1738 }
1739 goto BOLT;
1740 }
1741
1742 if( AFLAMABLE(s->picnum) )
1743 {
1744 if(T1 == 1)
1745 {
1746 T2++;
1747 if( (T2&3) > 0) goto BOLT;
1748
1749 if( s->picnum == TIRE && T2 == 32 )
1750 {
1751 s->cstat = 0;
1752 j = spawn(i,BLOODPOOL);
1753 sprite[j].shade = 127;
1754 }
1755 else
1756 {
1757 if(s->shade < 64) s->shade++;
1758 else KILLIT(i);
1759 }
1760
1761 j = s->xrepeat-(TRAND&7);
1762 if(j < 10)
1763 {
1764 KILLIT(i);
1765 }
1766
1767 s->xrepeat = j;
1768
1769 j = s->yrepeat-(TRAND&7);
1770 if(j < 4) { KILLIT(i); }
1771 s->yrepeat = j;
1772 }
1773 if(s->picnum == BOX)
1774 {
1775 makeitfall(i);
1776 hittype[i].ceilingz = sector[s->sectnum].ceilingz;
1777 }
1778 goto BOLT;
1779 }
1780
1781 if(s->picnum == TRIPBOMB)
1782 {
1783 if(T3 > 0)
1784 {
1785 T3--;
1786 if(T3 == 8)
1787 {
1788 spritesound(LASERTRIP_EXPLODE,i);
1789 for(j=0;j<5;j++) RANDOMSCRAP;
1790 x = s->extra;
1791 hitradius( i, tripbombblastradius, x>>2,x>>1,x-(x>>2),x);
1792
1793 j = spawn(i,EXPLOSION2);
1794 sprite[j].ang = s->ang;
1795 sprite[j].xvel = 348;
1796 ssp(j,CLIPMASK0);
1797
1798 j = headspritestat[5];
1799 while(j >= 0)
1800 {
1801 if(sprite[j].picnum == LASERLINE && s->hitag == sprite[j].hitag)
1802 sprite[j].xrepeat = sprite[j].yrepeat = 0;
1803 j = nextspritestat[j];
1804 }
1805 KILLIT(i);
1806 }
1807 goto BOLT;
1808 }
1809 else
1810 {
1811 x = s->extra;
1812 s->extra = 1;
1813 l = s->ang;
1814 IFHIT { T3 = 16; }
1815 s->extra = x;
1816 s->ang = l;
1817 }
1818
1819 if( T1 < 32 )
1820 {
1821 p = findplayer(s,&x);
1822 if( x > 768 ) T1++;
1823 else if(T1 > 16) T1++;
1824 }
1825 if( T1 == 32 )
1826 {
1827 l = s->ang;
1828 s->ang = T6;
1829
1830 T4 = s->x;T5 = s->y;
1831 s->x += sintable[(T6+512)&2047]>>9;
1832 s->y += sintable[(T6)&2047]>>9;
1833 s->z -= (3<<8);
1834 setsprite(i,s->x,s->y,s->z);
1835
1836 x = hitasprite(i,&m);
1837
1838 hittype[i].lastvx = x;
1839
1840 s->ang = l;
1841
1842 k = 0;
1843
1844 while(x > 0)
1845 {
1846 j = spawn(i,LASERLINE);
1847 setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z);
1848 sprite[j].hitag = s->hitag;
1849 hittype[j].temp_data[1] = sprite[j].z;
1850
1851 s->x += sintable[(T6+512)&2047]>>4;
1852 s->y += sintable[(T6)&2047]>>4;
1853
1854 if( x < 1024 )
1855 {
1856 sprite[j].xrepeat = x>>5;
1857 break;
1858 }
1859 x -= 1024;
1860 }
1861
1862 T1++;
1863 s->x = T4;s->y = T5;
1864 s->z += (3<<8);
1865 setsprite(i,s->x,s->y,s->z);
1866 T4 = 0;
1867 if( m >= 0 )
1868 {
1869 T3 = 13;
1870 spritesound(LASERTRIP_ARMING,i);
1871 }
1872 else T3 = 0;
1873 }
1874 if(T1 == 33)
1875 {
1876 T2++;
1877
1878
1879 T4 = s->x;T5 = s->y;
1880 s->x += sintable[(T6+512)&2047]>>9;
1881 s->y += sintable[(T6)&2047]>>9;
1882 s->z -= (3<<8);
1883 setsprite(i,s->x,s->y,s->z);
1884
1885 x = hitasprite(i,&m);
1886
1887 s->x = T4;s->y = T5;
1888 s->z += (3<<8);
1889 setsprite(i,s->x,s->y,s->z);
1890
1891 if( hittype[i].lastvx != x )
1892 {
1893 T3 = 13;
1894 spritesound(LASERTRIP_ARMING,i);
1895 }
1896 }
1897 goto BOLT;
1898 }
1899
1900
1901 if( s->picnum >= CRACK1 && s->picnum <= CRACK4 )
1902 {
1903 if(s->hitag > 0)
1904 {
1905 t[0] = s->cstat;
1906 t[1] = s->ang;
1907 j = ifhitbyweapon(i);
1908 if(j == FIREEXT || j == RPG || j == RADIUSEXPLOSION || j == SEENINE || j == OOZFILTER )
1909 {
1910 j = headspritestat[6];
1911 while(j >= 0)
1912 {
1913 if(s->hitag == sprite[j].hitag && ( sprite[j].picnum == OOZFILTER || sprite[j].picnum == SEENINE ) )
1914 if(sprite[j].shade != -32)
1915 sprite[j].shade = -32;
1916 j = nextspritestat[j];
1917 }
1918
1919 goto DETONATE;
1920 }
1921 else
1922 {
1923 s->cstat = t[0];
1924 s->ang = t[1];
1925 s->extra = 0;
1926 }
1927 }
1928 goto BOLT;
1929 }
1930
1931 if( s->picnum == FIREEXT )
1932 {
1933 j = ifhitbyweapon(i);
1934 if( j == -1 ) goto BOLT;
1935
1936 for(k=0;k<16;k++)
1937 {
1938 j = EGS(SECT,SX,SY,SZ-(TRAND%(48<<8)),SCRAP3+(TRAND&3),-8,48,48,TRAND&2047,(TRAND&63)+64,-(TRAND&4095)-(sprite[i].zvel>>2),i,5);
1939 sprite[j].pal = 2;
1940 }
1941
1942 spawn(i,EXPLOSION2);
1943 spritesound(PIPEBOMB_EXPLODE,i);
1944 spritesound(GLASS_HEAVYBREAK,i);
1945
1946 if(s->hitag > 0)
1947 {
1948 j = headspritestat[6];
1949 while(j >= 0)
1950 {
1951 if(s->hitag == sprite[j].hitag && ( sprite[j].picnum == OOZFILTER || sprite[j].picnum == SEENINE ) )
1952 if(sprite[j].shade != -32)
1953 sprite[j].shade = -32;
1954 j = nextspritestat[j];
1955 }
1956
1957 x = s->extra;
1958 spawn(i,EXPLOSION2);
1959 hitradius( i, pipebombblastradius,x>>2, x-(x>>1),x-(x>>2), x);
1960 spritesound(PIPEBOMB_EXPLODE,i);
1961
1962 goto DETONATE;
1963 }
1964 else
1965 {
1966 hitradius(i,seenineblastradius,10,15,20,25);
1967 KILLIT(i);
1968 }
1969 goto BOLT;
1970 }
1971
1972 if(s->picnum == OOZFILTER || s->picnum == SEENINE || s->picnum == SEENINEDEAD || s->picnum == (SEENINEDEAD+1) )
1973 {
1974 if(s->shade != -32 && s->shade != -33)
1975 {
1976 if(s->xrepeat)
1977 j = (ifhitbyweapon(i) >= 0);
1978 else
1979 j = 0;
1980
1981 if( j || s->shade == -31 )
1982 {
1983 if(j) s->lotag = 0;
1984
1985 t[3] = 1;
1986
1987 j = headspritestat[6];
1988 while(j >= 0)
1989 {
1990 if(s->hitag == sprite[j].hitag && ( sprite[j].picnum == SEENINE || sprite[j].picnum == OOZFILTER ) )
1991 sprite[j].shade = -32;
1992 j = nextspritestat[j];
1993 }
1994 }
1995 }
1996 else
1997 {
1998 if(s->shade == -32)
1999 {
2000 if(s->lotag > 0)
2001 {
2002 s->lotag-=3;
2003 if(s->lotag <= 0) s->lotag = -99;
2004 }
2005 else
2006 s->shade = -33;
2007 }
2008 else
2009 {
2010 if( s->xrepeat > 0 )
2011 {
2012 T3++;
2013 if(T3 == 3)
2014 {
2015 if( s->picnum == OOZFILTER )
2016 {
2017 T3 = 0;
2018 goto DETONATE;
2019 }
2020 if( s->picnum != (SEENINEDEAD+1) )
2021 {
2022 T3 = 0;
2023
2024 if(s->picnum == SEENINEDEAD) s->picnum++;
2025 else if(s->picnum == SEENINE)
2026 s->picnum = SEENINEDEAD;
2027 }
2028 else goto DETONATE;
2029 }
2030 goto BOLT;
2031 }
2032
2033 DETONATE:
2034
2035 earthquaketime = 16;
2036
2037 j = headspritestat[3];
2038 while(j >= 0)
2039 {
2040 if( s->hitag == sprite[j].hitag )
2041 {
2042 if(sprite[j].lotag == 13)
2043 {
2044 if( hittype[j].temp_data[2] == 0 )
2045 hittype[j].temp_data[2] = 1;
2046 }
2047 else if(sprite[j].lotag == 8)
2048 hittype[j].temp_data[4] = 1;
2049 else if(sprite[j].lotag == 18)
2050 {
2051 if(hittype[j].temp_data[0] == 0)
2052 hittype[j].temp_data[0] = 1;
2053 }
2054 else if(sprite[j].lotag == 21)
2055 hittype[j].temp_data[0] = 1;
2056 }
2057 j = nextspritestat[j];
2058 }
2059
2060 s->z -= (32<<8);
2061
2062 if( ( t[3] == 1 && s->xrepeat ) || s->lotag == -99 )
2063 {
2064 x = s->extra;
2065 spawn(i,EXPLOSION2);
2066 hitradius( i,seenineblastradius,x>>2, x-(x>>1),x-(x>>2), x);
2067 spritesound(PIPEBOMB_EXPLODE,i);
2068 }
2069
2070 if(s->xrepeat)
2071 for(x=0;x<8;x++) RANDOMSCRAP;
2072
2073 KILLIT(i);
2074 }
2075 }
2076 goto BOLT;
2077 }
2078
2079 if(s->picnum == MASTERSWITCH)
2080 {
2081 if(s->yvel == 1)
2082 {
2083 s->hitag--;
2084 if(s->hitag <= 0)
2085 {
2086 operatesectors(sect,i);
2087
2088 j = headspritesect[sect];
2089 while(j >= 0)
2090 {
2091 if(sprite[j].statnum == 3)
2092 {
2093 switch(sprite[j].lotag)
2094 {
2095 case 2:
2096 case 21:
2097 case 31:
2098 case 32:
2099 case 36:
2100 hittype[j].temp_data[0] = 1;
2101 break;
2102 case 3:
2103 hittype[j].temp_data[4] = 1;
2104 break;
2105 }
2106 }
2107 else if(sprite[j].statnum == 6)
2108 {
2109 switch(sprite[j].picnum)
2110 {
2111 case SEENINE:
2112 case OOZFILTER:
2113 sprite[j].shade = -31;
2114 break;
2115 }
2116 }
2117 j = nextspritesect[j];
2118 }
2119 KILLIT(i);
2120 }
2121 }
2122 goto BOLT;
2123 }
2124
2125 switch(s->picnum)
2126 {
2127 case VIEWSCREEN:
2128 case VIEWSCREEN2:
2129
2130 if(s->xrepeat == 0) KILLIT(i);
2131
2132 p = findplayer(s, &x);
2133
2134 if( x < 2048 )
2135 {
2136 if( SP == 1 )
2137 camsprite = i;
2138 }
2139 else if( camsprite != -1 && T1 == 1)
2140 {
2141 camsprite = -1;
2142 T1 = 0;
2143 loadtile(s->picnum);
2144 }
2145
2146 goto BOLT;
2147
2148 case TRASH:
2149
2150 if(s->xvel == 0) s->xvel = 1;
2151 IFMOVING
2152 {
2153 makeitfall(i);
2154 if(TRAND&1) s->zvel -= 256;
2155 if( klabs(s->xvel) < 48 )
2156 s->xvel += (TRAND&3);
2157 }
2158 else KILLIT(i);
2159 break;
2160
2161 case SIDEBOLT1:
2162 case SIDEBOLT1+1:
2163 case SIDEBOLT1+2:
2164 case SIDEBOLT1+3:
2165 p = findplayer(s, &x);
2166 if( x > 20480 ) goto BOLT;
2167
2168 CLEAR_THE_BOLT2:
2169 if(t[2])
2170 {
2171 t[2]--;
2172 goto BOLT;
2173 }
2174 if( (s->xrepeat|s->yrepeat) == 0 )
2175 {
2176 s->xrepeat=t[0];
2177 s->yrepeat=t[1];
2178 }
2179 if( (TRAND&8) == 0 )
2180 {
2181 t[0]=s->xrepeat;
2182 t[1]=s->yrepeat;
2183 t[2] = global_random&4;
2184 s->xrepeat=s->yrepeat=0;
2185 goto CLEAR_THE_BOLT2;
2186 }
2187 s->picnum++;
2188
2189 if(l&1) s->cstat ^= 2; // l not defined here. Line is met in 2nd demo with l = 0.
2190
2191 if( (TRAND&1) && sector[sect].floorpicnum == HURTRAIL )
2192 spritesound(SHORT_CIRCUIT,i);
2193
2194 if(s->picnum == SIDEBOLT1+4) s->picnum = SIDEBOLT1;
2195
2196 goto BOLT;
2197
2198 case BOLT1:
2199 case BOLT1+1:
2200 case BOLT1+2:
2201 case BOLT1+3:
2202 p = findplayer(s, &x);
2203 if( x > 20480 ) goto BOLT;
2204
2205 if( t[3] == 0 )
2206 t[3]=sector[sect].floorshade;
2207
2208 CLEAR_THE_BOLT:
2209 if(t[2])
2210 {
2211 t[2]--;
2212 sector[sect].floorshade = 20;
2213 sector[sect].ceilingshade = 20;
2214 goto BOLT;
2215 }
2216 if( (s->xrepeat|s->yrepeat) == 0 )
2217 {
2218 s->xrepeat=t[0];
2219 s->yrepeat=t[1];
2220 }
2221 else if( (TRAND&8) == 0 )
2222 {
2223 t[0]=s->xrepeat;
2224 t[1]=s->yrepeat;
2225 t[2] = global_random&4;
2226 s->xrepeat=s->yrepeat=0;
2227 goto CLEAR_THE_BOLT;
2228 }
2229 s->picnum++;
2230
2231 l = global_random&7;
2232 s->xrepeat=l+8;
2233
2234 if(l&1) s->cstat ^= 2;
2235
2236 if( s->picnum == (BOLT1+1) && (TRAND&7) == 0 && sector[sect].floorpicnum == HURTRAIL )
2237 spritesound(SHORT_CIRCUIT,i);
2238
2239 if(s->picnum==BOLT1+4) s->picnum=BOLT1;
2240
2241 if(s->picnum&1)
2242 {
2243 sector[sect].floorshade = 0;
2244 sector[sect].ceilingshade = 0;
2245 }
2246 else
2247 {
2248 sector[sect].floorshade = 20;
2249 sector[sect].ceilingshade = 20;
2250 }
2251 goto BOLT;
2252
2253 case WATERDRIP:
2254
2255 if( t[1] )
2256 {
2257 t[1]--;
2258 if(t[1] == 0)
2259 s->cstat &= 32767;
2260 }
2261 else
2262 {
2263 makeitfall(i);
2264 ssp(i,CLIPMASK0);
2265 if(s->xvel > 0) s->xvel -= 2;
2266
2267 if(s->zvel == 0)
2268 {
2269 s->cstat |= 32768;
2270
2271 if(s->pal != 2 && s->hitag == 0)
2272 spritesound(SOMETHING_DRIPPING,i);
2273
2274 if(sprite[s->owner].picnum != WATERDRIP)
2275 {
2276 KILLIT(i);
2277 }
2278 else
2279 {
2280 hittype[i].bposz = s->z = t[0];
2281 t[1] = 48+(TRAND&31);
2282 }
2283 }
2284 }
2285
2286
2287 goto BOLT;
2288
2289 case DOORSHOCK:
2290 j = klabs(sector[sect].ceilingz-sector[sect].floorz)>>9;
2291 s->yrepeat = j+4;
2292 s->xrepeat = 16;
2293 s->z = sector[sect].floorz;
2294 goto BOLT;
2295
2296 case TOUCHPLATE:
2297 if( t[1] == 1 && s->hitag >= 0) //Move the sector floor
2298 {
2299 x = sector[sect].floorz;
2300
2301 if(t[3] == 1)
2302 {
2303 if(x >= t[2])
2304 {
2305 sector[sect].floorz = x;
2306 t[1] = 0;
2307 }
2308 else
2309 {
2310 sector[sect].floorz += sector[sect].extra;
2311 p = checkcursectnums(sect);
2312 if(p >= 0) ps[p].posz += sector[sect].extra;
2313 }
2314 }
2315 else
2316 {
2317 if(x <= s->z)
2318 {
2319 sector[sect].floorz = s->z;
2320 t[1] = 0;
2321 }
2322 else
2323 {
2324 sector[sect].floorz -= sector[sect].extra;
2325 p = checkcursectnums(sect);
2326 if(p >= 0)
2327 ps[p].posz -= sector[sect].extra;
2328 }
2329 }
2330 goto BOLT;
2331 }
2332
2333 if(t[5] == 1) goto BOLT;
2334
2335 p = checkcursectnums(sect);
2336 if( p >= 0 && ( ps[p].on_ground || s->ang == 512) )
2337 {
2338 if( t[0] == 0 && !check_activator_motion(s->lotag) )
2339 {
2340 t[0] = 1;
2341 t[1] = 1;
2342 t[3] = !t[3];
2343 operatemasterswitches(s->lotag);
2344 operateactivators(s->lotag,p);
2345 if(s->hitag > 0)
2346 {
2347 s->hitag--;
2348 if(s->hitag == 0) t[5] = 1;
2349 }
2350 }
2351 }
2352 else t[0] = 0;
2353
2354 if(t[1] == 1)
2355 {
2356 j = headspritestat[6];
2357 while(j >= 0)
2358 {
2359 if(j != i && sprite[j].picnum == TOUCHPLATE && sprite[j].lotag == s->lotag)
2360 {
2361 hittype[j].temp_data[1] = 1;
2362 hittype[j].temp_data[3] = t[3];
2363 }
2364 j = nextspritestat[j];
2365 }
2366 }
2367 goto BOLT;
2368
2369 case CANWITHSOMETHING:
2370 case CANWITHSOMETHING2:
2371 case CANWITHSOMETHING3:
2372 case CANWITHSOMETHING4:
2373 makeitfall(i);
2374 IFHIT
2375 {
2376 spritesound(VENT_BUST,i);
2377 for(j=0;j<10;j++)
2378 RANDOMSCRAP;
2379
2380 if(s->lotag) spawn(i,s->lotag);
2381
2382 KILLIT(i);
2383 }
2384 goto BOLT;
2385
2386 case EXPLODINGBARREL:
2387 case WOODENHORSE:
2388 case HORSEONSIDE:
2389 case FLOORFLAME:
2390 case FIREBARREL:
2391 case FIREVASE:
2392 case NUKEBARREL:
2393 case NUKEBARRELDENTED:
2394 case NUKEBARRELLEAKED:
2395 case TOILETWATER:
2396 case RUBBERCAN:
2397 case STEAM:
2398 case CEILINGSTEAM:
2399 p = findplayer(s, &x);
2400 execute(i,p,x);
2401 goto BOLT;
2402 case WATERBUBBLEMAKER:
2403 p = findplayer(s, &x);
2404 execute(i,p,x);
2405 goto BOLT;
2406 }
2407
2408 BOLT:
2409 i = nexti;
2410 }
2411}
2412
2413void bounce(short i)
2414{
2415 int32_t k, l, daang, dax, day, daz, xvect, yvect, zvect;
2416 short hitsect;
2417 spritetype *s = &sprite[i];
2418
2419 xvect = mulscale10(s->xvel,sintable[(s->ang+512)&2047]);
2420 yvect = mulscale10(s->xvel,sintable[s->ang&2047]);
2421 zvect = s->zvel;
2422
2423 hitsect = s->sectnum;
2424
2425 k = sector[hitsect].wallptr; l = wall[k].point2;
2426 daang = getangle(wall[l].x-wall[k].x,wall[l].y-wall[k].y);
2427
2428 if ( s->z < (hittype[i].floorz+hittype[i].ceilingz)>>1)
2429 k = sector[hitsect].ceilingheinum;
2430 else
2431 k = sector[hitsect].floorheinum;
2432
2433 dax = mulscale14(k,sintable[(daang)&2047]);
2434 day = mulscale14(k,sintable[(daang+1536)&2047]);
2435 daz = 4096;
2436
2437 k = xvect*dax+yvect*day+zvect*daz;
2438 l = dax*dax+day*day+daz*daz;
2439 if ((klabs(k)>>14) < l)
2440 {
2441 k = divscale17(k,l);
2442 xvect -= mulscale16(dax,k);
2443 yvect -= mulscale16(day,k);
2444 zvect -= mulscale16(daz,k);
2445 }
2446
2447 s->zvel = zvect;
2448 s->xvel = ksqrt(dmulscale8(xvect,xvect,yvect,yvect));
2449 s->ang = getangle(xvect,yvect);
2450}
2451
2452void moveweapons(void)
2453{
2454 short i, j, k, nexti, p, q;
2455 int32_t dax,day,daz, x, ll;
2456 uint32_t qq;
2457 spritetype *s;
2458
2459 i = headspritestat[4];
2460 while(i >= 0)
2461 {
2462 nexti = nextspritestat[i];
2463 s = &sprite[i];
2464
2465 if(s->sectnum < 0) KILLIT(i);
2466
2467 hittype[i].bposx = s->x;
2468 hittype[i].bposy = s->y;
2469 hittype[i].bposz = s->z;
2470
2471 switch(s->picnum)
2472 {
2473 case RADIUSEXPLOSION:
2474 case KNEE:
2475 KILLIT(i);
2476 case TONGUE:
2477 T1 = sintable[(T2)&2047]>>9;
2478 T2 += 32;
2479 if(T2 > 2047) KILLIT(i);
2480
2481 if(sprite[s->owner].statnum == MAXSTATUS)
2482 if(badguy(&sprite[s->owner]) == 0)
2483 KILLIT(i);
2484
2485 s->ang = sprite[s->owner].ang;
2486 s->x = sprite[s->owner].x;
2487 s->y = sprite[s->owner].y;
2488 if(sprite[s->owner].picnum == APLAYER)
2489 s->z = sprite[s->owner].z-(34<<8);
2490 for(k=0;k<T1;k++)
2491 {
2492 q = EGS(s->sectnum,
2493 s->x+((k*sintable[(s->ang+512)&2047])>>9),
2494 s->y+((k*sintable[s->ang&2047])>>9),
2495 s->z+((k*ksgn(s->zvel))*klabs(s->zvel/12)),TONGUE,-40+(k<<1),
2496 8,8,0,0,0,i,5);
2497 sprite[q].cstat = 128;
2498 sprite[q].pal = 8;
2499 }
2500 q = EGS(s->sectnum,
2501 s->x+((k*sintable[(s->ang+512)&2047])>>9),
2502 s->y+((k*sintable[s->ang&2047])>>9),
2503 s->z+((k*ksgn(s->zvel))*klabs(s->zvel/12)),INNERJAW,-40,
2504 32,32,0,0,0,i,5);
2505 sprite[q].cstat = 128;
2506 if( T2 > 512 && T2 < (1024) )
2507 sprite[q].picnum = INNERJAW+1;
2508
2509 goto BOLT;
2510
2511 case FREEZEBLAST:
2512 if(s->yvel < 1 || s->extra < 2 || (s->xvel|s->zvel) == 0)
2513 {
2514 j = spawn(i,TRANSPORTERSTAR);
2515 sprite[j].pal = 1;
2516 sprite[j].xrepeat = 32;
2517 sprite[j].yrepeat = 32;
2518 KILLIT(i);
2519 }
2520 case SHRINKSPARK:
2521 case RPG:
2522 case FIRELASER:
2523 case SPIT:
2524 case COOLEXPLOSION1:
2525
2526 if( s->picnum == COOLEXPLOSION1 )
2527 if( Sound[WIERDSHOT_FLY].num == 0 )
2528 spritesound(WIERDSHOT_FLY,i);
2529
2530 p = -1;
2531
2532 if(s->picnum == RPG && sector[s->sectnum].lotag == 2)
2533 {
2534 k = s->xvel>>1;
2535 ll = s->zvel>>1;
2536 }
2537 else
2538 {
2539 k = s->xvel;
2540 ll = s->zvel;
2541 }
2542
2543 dax = s->x; day = s->y; daz = s->z;
2544
2545 getglobalz(i);
2546 qq = CLIPMASK1;
2547
2548 switch(s->picnum)
2549 {
2550 case RPG:
2551 if(hittype[i].picnum != BOSS2 && s->xrepeat >= 10 && sector[s->sectnum].lotag != 2)
2552 {
2553 j = spawn(i,SMALLSMOKE);
2554 sprite[j].z += (1<<8);
2555 }
2556 break;
2557 }
2558
2559 j = movesprite(i,
2560 (k*(sintable[(s->ang+512)&2047]))>>14,
2561 (k*(sintable[s->ang&2047]))>>14,ll,qq);
2562
2563 if(s->picnum == RPG && s->yvel >= 0)
2564 if( FindDistance2D(s->x-sprite[s->yvel].x,s->y-sprite[s->yvel].y) < 256 )
2565 j = 49152|s->yvel;
2566
2567 if(s->sectnum < 0) { KILLIT(i); }
2568
2569 if( (j&49152) != 49152)
2570 if(s->picnum != FREEZEBLAST)
2571 {
2572 if(s->z < hittype[i].ceilingz)
2573 {
2574 j = 16384|(s->sectnum);
2575 s->zvel = -1;
2576 }
2577 else
2578 if( ( s->z > hittype[i].floorz && sector[s->sectnum].lotag != 1 ) ||
2579 ( s->z > hittype[i].floorz+(16<<8) && sector[s->sectnum].lotag == 1 ) )
2580 {
2581 j = 16384|(s->sectnum);
2582 if(sector[s->sectnum].lotag != 1)
2583 s->zvel = 1;
2584 }
2585 }
2586
2587 if(s->picnum == FIRELASER)
2588 {
2589 for(k=-3;k<2;k++)
2590 {
2591 x = EGS(s->sectnum,
2592 s->x+((k*sintable[(s->ang+512)&2047])>>9),
2593 s->y+((k*sintable[s->ang&2047])>>9),
2594 s->z+((k*ksgn(s->zvel))*klabs(s->zvel/24)),FIRELASER,-40+(k<<2),
2595 s->xrepeat,s->yrepeat,0,0,0,s->owner,5);
2596
2597 sprite[x].cstat = 128;
2598 sprite[x].pal = s->pal;
2599 }
2600 }
2601 else if(s->picnum == SPIT) if(s->zvel < 6144)
2602 s->zvel += gc-112;
2603
2604 if( j != 0 )
2605 {
2606 if(s->picnum == COOLEXPLOSION1)
2607 {
2608 if( (j&49152) == 49152 && sprite[j&(MAXSPRITES-1)].picnum != APLAYER)
2609 goto BOLT;
2610 s->xvel = 0;
2611 s->zvel = 0;
2612 }
2613
2614 if( (j&49152) == 49152 )
2615 {
2616 j &= (MAXSPRITES-1);
2617
2618 if(s->picnum == FREEZEBLAST && sprite[j].pal == 1 )
2619 if( badguy(&sprite[j]) || sprite[j].picnum == APLAYER )
2620 {
2621 j = spawn(i,TRANSPORTERSTAR);
2622 sprite[j].pal = 1;
2623 sprite[j].xrepeat = 32;
2624 sprite[j].yrepeat = 32;
2625
2626 KILLIT(i);
2627 }
2628
2629 checkhitsprite(j,i);
2630
2631 if(sprite[j].picnum == APLAYER)
2632 {
2633 p = sprite[j].yvel;
2634 spritesound(PISTOL_BODYHIT,j);
2635
2636 if(s->picnum == SPIT)
2637 {
2638 ps[p].horiz += 32;
2639 ps[p].return_to_center = 8;
2640
2641 if(ps[p].loogcnt == 0)
2642 {
2643 if(Sound[DUKE_LONGTERM_PAIN].num < 1)
2644 spritesound(DUKE_LONGTERM_PAIN,ps[p].i);
2645
2646 j = 3+(TRAND&3);
2647 ps[p].numloogs = j;
2648 ps[p].loogcnt = 24*4;
2649 for(x=0;x < j;x++)
2650 {
2651 ps[p].loogiex[x] = TRAND%xdim;
2652 ps[p].loogiey[x] = TRAND%ydim;
2653 }
2654 }
2655 }
2656 }
2657 }
2658 else if( (j&49152) == 32768 )
2659 {
2660 j &= (MAXWALLS-1);
2661
2662 if(s->picnum != RPG && s->picnum != FREEZEBLAST && s->picnum != SPIT && ( wall[j].overpicnum == MIRROR || wall[j].picnum == MIRROR ) )
2663 {
2664 k = getangle(
2665 wall[wall[j].point2].x-wall[j].x,
2666 wall[wall[j].point2].y-wall[j].y);
2667 s->ang = ((k<<1) - s->ang)&2047;
2668 s->owner = i;
2669 spawn(i,TRANSPORTERSTAR);
2670 goto BOLT;
2671 }
2672 else
2673 {
2674 setsprite(i,dax,day,daz);
2675 checkhitwall(i,j,s->x,s->y,s->z,s->picnum);
2676
2677 if(s->picnum == FREEZEBLAST)
2678 {
2679 if( wall[j].overpicnum != MIRROR && wall[j].picnum != MIRROR )
2680 {
2681 s->extra >>= 1;
2682 s->yvel--;
2683 }
2684
2685 k = getangle(
2686 wall[wall[j].point2].x-wall[j].x,
2687 wall[wall[j].point2].y-wall[j].y);
2688 s->ang = ((k<<1) - s->ang)&2047;
2689 goto BOLT;
2690 }
2691 }
2692 }
2693 else if( (j&49152) == 16384)
2694 {
2695 setsprite(i,dax,day,daz);
2696
2697 if(s->zvel < 0)
2698 {
2699 if( sector[s->sectnum].ceilingstat&1 )
2700 if(sector[s->sectnum].ceilingpal == 0)
2701 KILLIT(i);
2702
2703 checkhitceiling(s->sectnum);
2704 }
2705
2706 if(s->picnum == FREEZEBLAST)
2707 {
2708 bounce(i);
2709 ssp(i,qq);
2710 s->extra >>= 1;
2711 if(s->xrepeat > 8)
2712 s->xrepeat -= 2;
2713 if(s->yrepeat > 8)
2714 s->yrepeat -= 2;
2715 s->yvel--;
2716 goto BOLT;
2717 }
2718 }
2719
2720 if(s->picnum != SPIT)
2721 {
2722 if(s->picnum == RPG)
2723 {
2724 k = spawn(i,EXPLOSION2);
2725 sprite[k].x = dax;
2726 sprite[k].y = day;
2727 sprite[k].z = daz;
2728
2729 if(s->xrepeat < 10)
2730 {
2731 sprite[k].xrepeat = 6;
2732 sprite[k].yrepeat = 6;
2733 }
2734 else if( (j&49152) == 16384)
2735 {
2736 if( s->zvel > 0)
2737 spawn(i,EXPLOSION2BOT);
2738 else { sprite[k].cstat |= 8; sprite[k].z += (48<<8); }
2739 }
2740 }
2741 else if(s->picnum == SHRINKSPARK)
2742 {
2743 spawn(i,SHRINKEREXPLOSION);
2744 spritesound(SHRINKER_HIT,i);
2745 hitradius(i,shrinkerblastradius,0,0,0,0);
2746 }
2747 else if( s->picnum != COOLEXPLOSION1 && s->picnum != FREEZEBLAST && s->picnum != FIRELASER)
2748 {
2749 k = spawn(i,EXPLOSION2);
2750 sprite[k].xrepeat = sprite[k].yrepeat = s->xrepeat>>1;
2751 if( (j&49152) == 16384)
2752 {
2753 if( s->zvel < 0)
2754 { sprite[k].cstat |= 8; sprite[k].z += (72<<8); }
2755 }
2756 }
2757 if( s->picnum == RPG )
2758 {
2759 spritesound(RPG_EXPLODE,i);
2760
2761 if(s->xrepeat >= 10)
2762 {
2763 x = s->extra;
2764 hitradius( i,rpgblastradius, x>>2,x>>1,x-(x>>2),x);
2765 }
2766 else
2767 {
2768 x = s->extra+(global_random&3);
2769 hitradius( i,(rpgblastradius>>1),x>>2,x>>1,x-(x>>2),x);
2770 }
2771 }
2772 }
2773 if(s->picnum != COOLEXPLOSION1) KILLIT(i);
2774 }
2775 if(s->picnum == COOLEXPLOSION1)
2776 {
2777 s->shade++;
2778 if(s->shade >= 40) KILLIT(i);
2779 }
2780 else if(s->picnum == RPG && sector[s->sectnum].lotag == 2 && s->xrepeat >= 10 && rnd(140))
2781 spawn(i,WATERBUBBLE);
2782
2783 goto BOLT;
2784
2785
2786 case SHOTSPARK1:
2787 p = findplayer(s,&x);
2788 execute(i,p,x);
2789 goto BOLT;
2790 }
2791 BOLT:
2792 i = nexti;
2793 }
2794}
2795
2796
2797void movetransports(void)
2798{
2799 uint8_t warpspriteto;
2800 short i, j, k, l, p, sect, sectlotag, nexti, nextj;
2801 int32_t ll,onfloorz,q;
2802
2803 i = headspritestat[9]; //Transporters
2804
2805 while(i >= 0)
2806 {
2807 sect = SECT;
2808 sectlotag = sector[sect].lotag;
2809
2810 nexti = nextspritestat[i];
2811
2812 if(OW == i)
2813 {
2814 i = nexti;
2815 continue;
2816 }
2817
2818 onfloorz = T5;
2819
2820 if(T1 > 0) T1--;
2821
2822 j = headspritesect[sect];
2823 while(j >= 0)
2824 {
2825 nextj = nextspritesect[j];
2826
2827 switch(sprite[j].statnum)
2828 {
2829 case 10: // Player
2830
2831 if( sprite[j].owner != -1 )
2832 {
2833 p = sprite[j].yvel;
2834
2835 ps[p].on_warping_sector = 1;
2836
2837 if( ps[p].transporter_hold == 0 && ps[p].jumping_counter == 0 )
2838 {
2839 if(ps[p].on_ground && sectlotag == 0 && onfloorz && ps[p].jetpack_on == 0 )
2840 {
2841 if(sprite[i].pal == 0)
2842 {
2843 spawn(i,TRANSPORTERBEAM);
2844 spritesound(TELEPORTER,i);
2845 }
2846
2847 for(k=connecthead;k>=0;k=connectpoint2[k])
2848 if(ps[k].cursectnum == sprite[OW].sectnum)
2849 {
2850 ps[k].frag_ps = p;
2851 sprite[ps[k].i].extra = 0;
2852 }
2853
2854 ps[p].ang = sprite[OW].ang;
2855
2856 if(sprite[OW].owner != OW)
2857 {
2858 T1 = 13;
2859 hittype[OW].temp_data[0] = 13;
2860 ps[p].transporter_hold = 13;
2861 }
2862
2863 ps[p].bobposx = ps[p].oposx = ps[p].posx = sprite[OW].x;
2864 ps[p].bobposy = ps[p].oposy = ps[p].posy = sprite[OW].y;
2865 ps[p].oposz = ps[p].posz = sprite[OW].z-PHEIGHT;
2866
2867 changespritesect(j,sprite[OW].sectnum);
2868 ps[p].cursectnum = sprite[j].sectnum;
2869
2870 if(sprite[i].pal == 0)
2871 {
2872 k = spawn(OW,TRANSPORTERBEAM);
2873 spritesound(TELEPORTER,k);
2874 }
2875
2876 break;
2877 }
2878 }
2879 else if( !(sectlotag == 1 && ps[p].on_ground == 1) ) break;
2880
2881 if(onfloorz == 0 && klabs(SZ-ps[p].posz) < 6144 )
2882 if( (ps[p].jetpack_on == 0 ) || (ps[p].jetpack_on && (sync[p].bits&1) ) ||
2883 (ps[p].jetpack_on && (sync[p].bits&2) ) )
2884 {
2885 ps[p].oposx = ps[p].posx += sprite[OW].x-SX;
2886 ps[p].oposy = ps[p].posy += sprite[OW].y-SY;
2887
2888 if( ps[p].jetpack_on && ( (sync[p].bits&1) || ps[p].jetpack_on < 11 ) )
2889 ps[p].posz = sprite[OW].z-6144;
2890 else ps[p].posz = sprite[OW].z+6144;
2891 ps[p].oposz = ps[p].posz;
2892
2893 hittype[ps[p].i].bposx = ps[p].posx;
2894 hittype[ps[p].i].bposy = ps[p].posy;
2895 hittype[ps[p].i].bposz = ps[p].posz;
2896
2897 changespritesect(j,sprite[OW].sectnum);
2898 ps[p].cursectnum = sprite[OW].sectnum;
2899
2900 break;
2901 }
2902
2903 k = 0;
2904
2905 if( onfloorz && sectlotag == 1 && ps[p].on_ground && ps[p].posz > (sector[sect].floorz-(16<<8)) && ( (sync[p].bits&2) || ps[p].poszv > 2048 ) )
2906// if( onfloorz && sectlotag == 1 && ps[p].posz > (sector[sect].floorz-(6<<8)) )
2907 {
2908 k = 1;
2909 if(screenpeek == p)
2910 {
2911 FX_StopAllSounds();
2912 clearsoundlocks();
2913 }
2914 if(sprite[ps[p].i].extra > 0)
2915 spritesound(DUKE_UNDERWATER,j);
2916 ps[p].oposz = ps[p].posz =
2917 sector[sprite[OW].sectnum].ceilingz+(7<<8);
2918
2919 ps[p].posxv = 4096-(TRAND&8192);
2920 ps[p].posyv = 4096-(TRAND&8192);
2921
2922 }
2923
2924 if( onfloorz && sectlotag == 2 && ps[p].posz < (sector[sect].ceilingz+(6<<8)) )
2925 {
2926 k = 1;
2927// if( sprite[j].extra <= 0) break;
2928 if(screenpeek == p)
2929 {
2930 FX_StopAllSounds();
2931 clearsoundlocks();
2932 }
2933 spritesound(DUKE_GASP,j);
2934
2935 ps[p].oposz = ps[p].posz =
2936 sector[sprite[OW].sectnum].floorz-(7<<8);
2937
2938 ps[p].jumping_toggle = 1;
2939 ps[p].jumping_counter = 0;
2940 }
2941
2942 if(k == 1)
2943 {
2944 ps[p].oposx = ps[p].posx += sprite[OW].x-SX;
2945 ps[p].oposy = ps[p].posy += sprite[OW].y-SY;
2946
2947 if(sprite[OW].owner != OW)
2948 ps[p].transporter_hold = -2;
2949 ps[p].cursectnum = sprite[OW].sectnum;
2950
2951 changespritesect(j,sprite[OW].sectnum);
2952 setsprite(ps[p].i,ps[p].posx,ps[p].posy,ps[p].posz+PHEIGHT);
2953
2954 setpal(&ps[p]);
2955
2956 if( (TRAND&255) < 32 )
2957 spawn(j,WATERSPLASH2);
2958
2959 if(sectlotag == 1)
2960 for(l = 0;l < 9;l++)
2961 {
2962 q = spawn(ps[p].i,WATERBUBBLE);
2963 sprite[q].z += TRAND&16383;
2964 }
2965 }
2966 }
2967 break;
2968
2969 case 1:
2970 switch(sprite[j].picnum)
2971 {
2972 case SHARK:
2973 case COMMANDER:
2974 case OCTABRAIN:
2975 case GREENSLIME:
2976 case GREENSLIME+1:
2977 case GREENSLIME+2:
2978 case GREENSLIME+3:
2979 case GREENSLIME+4:
2980 case GREENSLIME+5:
2981 case GREENSLIME+6:
2982 case GREENSLIME+7:
2983 if(sprite[j].extra > 0)
2984 goto JBOLT;
2985 }
2986 case 4:
2987 case 5:
2988 case 12:
2989 case 13:
2990
2991 ll = klabs(sprite[j].zvel);
2992
2993 {
2994 warpspriteto = 0;
2995 if( ll && sectlotag == 2 && sprite[j].z < (sector[sect].ceilingz+ll) )
2996 warpspriteto = 1;
2997
2998 if( ll && sectlotag == 1 && sprite[j].z > (sector[sect].floorz-ll) )
2999 warpspriteto = 1;
3000
3001 if( sectlotag == 0 && ( onfloorz || klabs(sprite[j].z-SZ) < 4096) )
3002 {
3003 if( sprite[OW].owner != OW && onfloorz && T1 > 0 && sprite[j].statnum != 5 )
3004 {
3005 T1++;
3006 goto BOLT;
3007 }
3008 warpspriteto = 1;
3009 }
3010
3011 if( warpspriteto ) switch(sprite[j].picnum)
3012 {
3013 case TRANSPORTERSTAR:
3014 case TRANSPORTERBEAM:
3015 case TRIPBOMB:
3016 case BULLETHOLE:
3017 case WATERSPLASH2:
3018 case BURNING:
3019 case BURNING2:
3020 case FIRE:
3021 case FIRE2:
3022 case TOILETWATER:
3023 case LASERLINE:
3024 goto JBOLT;
3025 case PLAYERONWATER:
3026 if(sectlotag == 2)
3027 {
3028 sprite[j].cstat &= 32767;
3029 break;
3030 }
3031 default:
3032 if(sprite[j].statnum == 5 && !(sectlotag == 1 || sectlotag == 2) )
3033 break;
3034
3035 case WATERBUBBLE:
3036// if( rnd(192) && sprite[j].picnum == WATERBUBBLE)
3037 // break;
3038
3039 if(sectlotag > 0)
3040 {
3041 k = spawn(j,WATERSPLASH2);
3042 if( sectlotag == 1 && sprite[j].statnum == 4 )
3043 {
3044 sprite[k].xvel = sprite[j].xvel>>1;
3045 sprite[k].ang = sprite[j].ang;
3046 ssp(k,CLIPMASK0);
3047 }
3048 }
3049
3050 switch(sectlotag)
3051 {
3052 case 0:
3053 if(onfloorz)
3054 {
3055 if( sprite[j].statnum == 4 || ( checkcursectnums(sect) == -1 && checkcursectnums(sprite[OW].sectnum) == -1 ) )
3056 {
3057 sprite[j].x += (sprite[OW].x-SX);
3058 sprite[j].y += (sprite[OW].y-SY);
3059 sprite[j].z -= SZ - sector[sprite[OW].sectnum].floorz;
3060 sprite[j].ang = sprite[OW].ang;
3061
3062 hittype[j].bposx = sprite[j].x;
3063 hittype[j].bposy = sprite[j].y;
3064 hittype[j].bposz = sprite[j].z;
3065
3066 if(sprite[i].pal == 0)
3067 {
3068 k = spawn(i,TRANSPORTERBEAM);
3069 spritesound(TELEPORTER,k);
3070
3071 k = spawn(OW,TRANSPORTERBEAM);
3072 spritesound(TELEPORTER,k);
3073 }
3074
3075 if( sprite[OW].owner != OW )
3076 {
3077 T1 = 13;
3078 hittype[OW].temp_data[0] = 13;
3079 }
3080
3081 changespritesect(j,sprite[OW].sectnum);
3082 }
3083 }
3084 else
3085 {
3086 sprite[j].x += (sprite[OW].x-SX);
3087 sprite[j].y += (sprite[OW].y-SY);
3088 sprite[j].z = sprite[OW].z+4096;
3089
3090 hittype[j].bposx = sprite[j].x;
3091 hittype[j].bposy = sprite[j].y;
3092 hittype[j].bposz = sprite[j].z;
3093
3094 changespritesect(j,sprite[OW].sectnum);
3095 }
3096 break;
3097 case 1:
3098 sprite[j].x += (sprite[OW].x-SX);
3099 sprite[j].y += (sprite[OW].y-SY);
3100 sprite[j].z = sector[sprite[OW].sectnum].ceilingz+ll;
3101
3102 hittype[j].bposx = sprite[j].x;
3103 hittype[j].bposy = sprite[j].y;
3104 hittype[j].bposz = sprite[j].z;
3105
3106 changespritesect(j,sprite[OW].sectnum);
3107
3108 break;
3109 case 2:
3110 sprite[j].x += (sprite[OW].x-SX);
3111 sprite[j].y += (sprite[OW].y-SY);
3112 sprite[j].z = sector[sprite[OW].sectnum].floorz-ll;
3113
3114 hittype[j].bposx = sprite[j].x;
3115 hittype[j].bposy = sprite[j].y;
3116 hittype[j].bposz = sprite[j].z;
3117
3118 changespritesect(j,sprite[OW].sectnum);
3119
3120 break;
3121 }
3122
3123 break;
3124 }
3125 }
3126 break;
3127
3128 }
3129 JBOLT:
3130 j = nextj;
3131 }
3132 BOLT:
3133 i = nexti;
3134 }
3135}
3136
3137
3138
3139void moveactors(void)
3140{
3141 int32_t x, m, l, *t;
3142 short a, i, j, nexti, nextj, sect, p;
3143 spritetype *s;
3144 uint16_t k;
3145
3146 i = headspritestat[1];
3147 while(i >= 0)
3148 {
3149 nexti = nextspritestat[i];
3150
3151 s = &sprite[i];
3152
3153 sect = s->sectnum;
3154
3155 if( s->xrepeat == 0 || sect < 0 || sect >= MAXSECTORS)
3156 KILLIT(i);
3157
3158 t = &hittype[i].temp_data[0];
3159
3160 hittype[i].bposx = s->x;
3161 hittype[i].bposy = s->y;
3162 hittype[i].bposz = s->z;
3163
3164 switch(s->picnum)
3165 {
3166 case DUCK:
3167 case TARGET:
3168 if(s->cstat&32)
3169 {
3170 t[0]++;
3171 if(t[0] > 60)
3172 {
3173 t[0] = 0;
3174 s->cstat = 128+257+16;
3175 s->extra = 1;
3176 }
3177 }
3178 else
3179 {
3180 j = ifhitbyweapon(i);
3181 if( j >= 0 )
3182 {
3183 s->cstat = 32+128;
3184 k = 1;
3185
3186 j = headspritestat[1];
3187 while(j >= 0)
3188 {
3189 if( sprite[j].lotag == s->lotag &&
3190 sprite[j].picnum == s->picnum )
3191 {
3192 if( ( sprite[j].hitag && !(sprite[j].cstat&32) ) ||
3193 ( !sprite[j].hitag && (sprite[j].cstat&32) )
3194 )
3195 {
3196 k = 0;
3197 break;
3198 }
3199 }
3200
3201 j = nextspritestat[j];
3202 }
3203
3204 if(k == 1)
3205 {
3206 operateactivators(s->lotag,-1);
3207 operateforcefields(i,s->lotag);
3208 operatemasterswitches(s->lotag);
3209 }
3210 }
3211 }
3212 goto BOLT;
3213
3214 case RESPAWNMARKERRED:
3215 case RESPAWNMARKERYELLOW:
3216 case RESPAWNMARKERGREEN:
3217 T1++;
3218 if(T1 > respawnitemtime)
3219 {
3220 KILLIT(i);
3221 }
3222 if( T1 >= (respawnitemtime>>1) && T1 < ((respawnitemtime>>1)+(respawnitemtime>>2)) )
3223 PN = RESPAWNMARKERYELLOW;
3224 else if( T1 > ((respawnitemtime>>1)+(respawnitemtime>>2)) )
3225 PN = RESPAWNMARKERGREEN;
3226 makeitfall(i);
3227 break;
3228
3229 case HELECOPT:
3230 case DUKECAR:
3231
3232 s->z += s->zvel;
3233 t[0]++;
3234
3235 if(t[0] == 4) spritesound(WAR_AMBIENCE2,i);
3236
3237 if( t[0] > (26*8) )
3238 {
3239 sound(RPG_EXPLODE);
3240 for(j=0;j<32;j++) RANDOMSCRAP;
3241 earthquaketime = 16;
3242 KILLIT(i);
3243 }
3244 else if((t[0]&3) == 0)
3245 spawn(i,EXPLOSION2);
3246 ssp(i,CLIPMASK0);
3247 break;
3248 case RAT:
3249 makeitfall(i);
3250 IFMOVING
3251 {
3252 if( (TRAND&255) < 3 ) spritesound(RATTY,i);
3253 s->ang += (TRAND&31)-15+(sintable[(t[0]<<8)&2047]>>11);
3254 }
3255 else
3256 {
3257 T1++;
3258 if(T1 > 1) { KILLIT(i); }
3259 else s->ang = (TRAND&2047);
3260 }
3261 if(s->xvel < 128)
3262 s->xvel+=2;
3263 s->ang += (TRAND&3)-6;
3264 break;
3265 case QUEBALL:
3266 case STRIPEBALL:
3267 if(s->xvel)
3268 {
3269 j = headspritestat[0];
3270 while(j >= 0)
3271 {
3272 nextj = nextspritestat[j];
3273 if( sprite[j].picnum == POCKET && ldist(&sprite[j],s) < 52 ) KILLIT(i);
3274 j = nextj;
3275 }
3276
3277 j = clipmove(&s->x,&s->y,&s->z,&s->sectnum,
3278 (((s->xvel*(sintable[(s->ang+512)&2047]))>>14)*TICSPERFRAME)<<11,
3279 (((s->xvel*(sintable[s->ang&2047]))>>14)*TICSPERFRAME)<<11,
3280 24L,(4<<8),(4<<8),CLIPMASK1);
3281
3282 if(j&49152)
3283 {
3284 if( (j&49152) == 32768 )
3285 {
3286 j &= (MAXWALLS-1);
3287 k = getangle(
3288 wall[wall[j].point2].x-wall[j].x,
3289 wall[wall[j].point2].y-wall[j].y);
3290 s->ang = ((k<<1) - s->ang)&2047;
3291 }
3292 else if( (j&49152) == 49152 )
3293 {
3294 j &= (MAXSPRITES-1);
3295 checkhitsprite(i,j);
3296 }
3297 }
3298 s->xvel --;
3299 if(s->xvel < 0) s->xvel = 0;
3300 if( s->picnum == STRIPEBALL )
3301 {
3302 s->cstat = 257;
3303 s->cstat |= 4&s->xvel;
3304 s->cstat |= 8&s->xvel;
3305 }
3306 }
3307 else
3308 {
3309 p = findplayer(s,&x);
3310
3311 if( x < 1596)
3312 {
3313
3314// if(s->pal == 12)
3315 {
3316 j = getincangle(ps[p].ang,getangle(s->x-ps[p].posx,s->y-ps[p].posy));
3317 if( j > -64 && j < 64 && (sync[p].bits&(1<<29)) )
3318 if(ps[p].toggle_key_flag == 1)
3319 {
3320 a = headspritestat[1];
3321 while(a >= 0)
3322 {
3323 if(sprite[a].picnum == QUEBALL || sprite[a].picnum == STRIPEBALL)
3324 {
3325 j = getincangle(ps[p].ang,getangle(sprite[a].x-ps[p].posx,sprite[a].y-ps[p].posy));
3326 if( j > -64 && j < 64 )
3327 {
3328 findplayer(&sprite[a],&l);
3329 if(x > l) break;
3330 }
3331 }
3332 a = nextspritestat[a];
3333 }
3334 if(a == -1)
3335 {
3336 if(s->pal == 12)
3337 s->xvel = 164;
3338 else s->xvel = 140;
3339 s->ang = ps[p].ang;
3340 ps[p].toggle_key_flag = 2;
3341 }
3342 }
3343 }
3344 }
3345 if( x < 512 && s->sectnum == ps[p].cursectnum )
3346 {
3347 s->ang = getangle(s->x-ps[p].posx,s->y-ps[p].posy);
3348 s->xvel = 48;
3349 }
3350 }
3351
3352 break;
3353 case FORCESPHERE:
3354
3355 if(s->yvel == 0)
3356 {
3357 s->yvel = 1;
3358
3359 for(l=512;l<(2048-512);l+= 128)
3360 for(j=0;j<2048;j += 128)
3361 {
3362 k = spawn(i,FORCESPHERE);
3363 sprite[k].cstat = 257+128;
3364 sprite[k].clipdist = 64;
3365 sprite[k].ang = j;
3366 sprite[k].zvel = sintable[l&2047]>>5;
3367 sprite[k].xvel = sintable[(l+512)&2047]>>9;
3368 sprite[k].owner = i;
3369 }
3370 }
3371
3372 if(t[3] > 0)
3373 {
3374 if(s->zvel < 6144)
3375 s->zvel += 192;
3376 s->z += s->zvel;
3377 if(s->z > sector[sect].floorz)
3378 s->z = sector[sect].floorz;
3379 t[3]--;
3380 if(t[3] == 0)
3381 KILLIT(i);
3382 }
3383 else if(t[2] > 10)
3384 {
3385 j = headspritestat[5];
3386 while(j >= 0)
3387 {
3388 if(sprite[j].owner == i && sprite[j].picnum == FORCESPHERE)
3389 hittype[j].temp_data[1] = 1+(TRAND&63);
3390 j = nextspritestat[j];
3391 }
3392 t[3] = 64;
3393 }
3394
3395 goto BOLT;
3396
3397 case RECON:
3398
3399 getglobalz(i);
3400
3401 if (sector[s->sectnum].ceilingstat&1)
3402 s->shade += (sector[s->sectnum].ceilingshade-s->shade)>>1;
3403 else s->shade += (sector[s->sectnum].floorshade-s->shade)>>1;
3404
3405 if( s->z < sector[sect].ceilingz+(32<<8) )
3406 s->z = sector[sect].ceilingz+(32<<8);
3407
3408 if( ud.multimode < 2 )
3409 {
3410 if( actor_tog == 1)
3411 {
3412 s->cstat = (short)32768;
3413 goto BOLT;
3414 }
3415 else if(actor_tog == 2) s->cstat = 257;
3416 }
3417 IFHIT
3418 {
3419 if( s->extra < 0 && t[0] != -1 )
3420 {
3421 t[0] = -1;
3422 s->extra = 0;
3423 }
3424 spritesound(RECO_PAIN,i);
3425 RANDOMSCRAP;
3426 }
3427
3428 if(t[0] == -1)
3429 {
3430 s->z += 1024;
3431 t[2]++;
3432 if( (t[2]&3) == 0) spawn(i,EXPLOSION2);
3433 getglobalz(i);
3434 s->ang += 96;
3435 s->xvel = 128;
3436 j = ssp(i,CLIPMASK0);
3437 if(j != 1 || s->z > hittype[i].floorz)
3438 {
3439 for(l=0;l<16;l++)
3440 RANDOMSCRAP;
3441 spritesound(LASERTRIP_EXPLODE,i);
3442 spawn(i,PIGCOP);
3443 ps[myconnectindex].actors_killed++;
3444 KILLIT(i);
3445 }
3446 goto BOLT;
3447 }
3448 else
3449 {
3450 if( s->z > hittype[i].floorz-(48<<8) )
3451 s->z = hittype[i].floorz-(48<<8);
3452 }
3453
3454 p = findplayer(s,&x);
3455 j = s->owner;
3456
3457 // 3 = findplayerz, 4 = shoot
3458
3459 if( t[0] >= 4 )
3460 {
3461 t[2]++;
3462 if( (t[2]&15) == 0 )
3463 {
3464 a = s->ang;
3465 s->ang = hittype[i].tempang;
3466 spritesound(RECO_ATTACK,i);
3467 shoot(i,FIRELASER);
3468 s->ang = a;
3469 }
3470 if( t[2] > (26*3) || !cansee(s->x,s->y,s->z-(16<<8),s->sectnum, ps[p].posx,ps[p].posy,ps[p].posz,ps[p].cursectnum ) )
3471 {
3472 t[0] = 0;
3473 t[2] = 0;
3474 }
3475 else hittype[i].tempang +=
3476 getincangle(hittype[i].tempang,getangle(ps[p].posx-s->x,ps[p].posy-s->y))/3;
3477 }
3478 else if(t[0] == 2 || t[0] == 3)
3479 {
3480 t[3] = 0;
3481 if(s->xvel > 0) s->xvel -= 16;
3482 else s->xvel = 0;
3483
3484 if(t[0] == 2)
3485 {
3486 l = ps[p].posz-s->z;
3487 if( klabs(l) < (48<<8) ) t[0] = 3;
3488 else s->z += sgn(ps[p].posz-s->z)<<10;
3489 }
3490 else
3491 {
3492 t[2]++;
3493 if( t[2] > (26*3) || !cansee(s->x,s->y,s->z-(16<<8),s->sectnum, ps[p].posx,ps[p].posy,ps[p].posz,ps[p].cursectnum ) )
3494 {
3495 t[0] = 1;
3496 t[2] = 0;
3497 }
3498 else if( (t[2]&15) == 0 )
3499 {
3500 spritesound(RECO_ATTACK,i);
3501 shoot(i,FIRELASER);
3502 }
3503 }
3504 s->ang += getincangle(s->ang,getangle(ps[p].posx-s->x,ps[p].posy-s->y))>>2;
3505 }
3506
3507 if( t[0] != 2 && t[0] != 3 )
3508 {
3509 l = ldist(&sprite[j],s);
3510 if(l <= 1524)
3511 {
3512 a = s->ang;
3513 s->xvel >>= 1;
3514 }
3515 else a = getangle(sprite[j].x-s->x,sprite[j].y-s->y);
3516
3517 if(t[0] == 1 || t[0] == 4) // Found a locator and going with it
3518 {
3519 l = dist(&sprite[j],s);
3520
3521 if( l <= 1524 ) { if(t[0] == 1) t[0] = 0; else t[0] = 5; }
3522 else
3523 {
3524 // Control speed here
3525 if(l > 1524) { if( s->xvel < 256 ) s->xvel += 32; }
3526 else
3527 {
3528 if(s->xvel > 0) s->xvel -= 16;
3529 else s->xvel = 0;
3530 }
3531 }
3532
3533 if(t[0] < 2) t[2]++;
3534
3535 if( x < 6144 && t[0] < 2 && t[2] > (26*4) )
3536 {
3537 t[0] = 2+(TRAND&2);
3538 t[2] = 0;
3539 hittype[i].tempang = s->ang;
3540 }
3541 }
3542
3543 if(t[0] == 0 || t[0] == 5)
3544 {
3545 if(t[0] == 0)
3546 t[0] = 1;
3547 else t[0] = 4;
3548 j = s->owner = LocateTheLocator(s->hitag,-1);
3549 if(j == -1)
3550 {
3551 s->hitag = j = hittype[i].temp_data[5];
3552 s->owner = LocateTheLocator(j,-1);
3553 j = s->owner;
3554 if(j == -1) KILLIT(i);
3555 }
3556 else s->hitag++;
3557 }
3558
3559 t[3] = getincangle(s->ang,a);
3560 s->ang += t[3]>>3;
3561
3562 if(s->z < sprite[j].z)
3563 s->z += 1024;
3564 else s->z -= 1024;
3565 }
3566
3567 if(Sound[RECO_ROAM].num == 0 )
3568 spritesound(RECO_ROAM,i);
3569
3570 ssp(i,CLIPMASK0);
3571
3572 goto BOLT;
3573
3574 case OOZ:
3575 case OOZ2:
3576
3577 getglobalz(i);
3578
3579 j = (hittype[i].floorz-hittype[i].ceilingz)>>9;
3580 if(j > 255) j = 255;
3581
3582 x = 25-(j>>1);
3583 if(x < 8) x = 8;
3584 else if(x > 48) x = 48;
3585
3586 s->yrepeat = j;
3587 s->xrepeat = x;
3588 s->z = hittype[i].floorz;
3589
3590 goto BOLT;
3591
3592 case GREENSLIME:
3593 case GREENSLIME+1:
3594 case GREENSLIME+2:
3595 case GREENSLIME+3:
3596 case GREENSLIME+4:
3597 case GREENSLIME+5:
3598 case GREENSLIME+6:
3599 case GREENSLIME+7:
3600
3601// #ifndef VOLUMEONE
3602 if( ud.multimode < 2 )
3603 {
3604 if( actor_tog == 1)
3605 {
3606 s->cstat = (short)32768;
3607 goto BOLT;
3608 }
3609 else if(actor_tog == 2) s->cstat = 257;
3610 }
3611// #endif
3612
3613 t[1]+=128;
3614
3615 if(sector[sect].floorstat&1)
3616 KILLIT(i);
3617
3618 p = findplayer(s,&x);
3619
3620 if(x > 20480)
3621 {
3622 hittype[i].timetosleep++;
3623 if( hittype[i].timetosleep > SLEEPTIME )
3624 {
3625 hittype[i].timetosleep = 0;
3626 changespritestat(i,2);
3627 goto BOLT;
3628 }
3629 }
3630
3631 if(t[0] == -5) // FROZEN
3632 {
3633 t[3]++;
3634 if(t[3] > 280)
3635 {
3636 s->pal = 0;
3637 t[0] = 0;
3638 goto BOLT;
3639 }
3640 makeitfall(i);
3641 s->cstat = 257;
3642 s->picnum = GREENSLIME+2;
3643 s->extra = 1;
3644 s->pal = 1;
3645 IFHIT
3646 {
3647 if(j == FREEZEBLAST) goto BOLT;
3648 for(j=16; j >= 0 ;j--)
3649 {
3650 k = EGS(SECT,SX,SY,SZ,GLASSPIECES+(j%3),-32,36,36,TRAND&2047,32+(TRAND&63),1024-(TRAND&1023),i,5);
3651 sprite[k].pal = 1;
3652 }
3653 spritesound(GLASS_BREAKING,i);
3654 KILLIT(i);
3655 }
3656 else if(x < 1024 && ps[p].quick_kick == 0)
3657 {
3658 j = getincangle(ps[p].ang,getangle(SX-ps[p].posx,SY-ps[p].posy));
3659 if( j > -128 && j < 128 )
3660 ps[p].quick_kick = 14;
3661 }
3662
3663 goto BOLT;
3664 }
3665
3666 if(x < 1596)
3667 s->cstat = 0;
3668 else s->cstat = 257;
3669
3670 if(t[0] == -4) //On the player
3671 {
3672 if( sprite[ps[p].i].extra < 1 )
3673 {
3674 t[0] = 0;
3675 goto BOLT;
3676 }
3677
3678 setsprite(i,s->x,s->y,s->z);
3679
3680 s->ang = ps[p].ang;
3681
3682 if( ( (sync[p].bits&4) || (ps[p].quick_kick > 0) ) && sprite[ps[p].i].extra > 0 )
3683 if( ps[p].quick_kick > 0 || ( ps[p].curr_weapon != HANDREMOTE_WEAPON && ps[p].curr_weapon != HANDBOMB_WEAPON && ps[p].curr_weapon != TRIPBOMB_WEAPON && ps[p].ammo_amount[ps[p].curr_weapon] >= 0) )
3684 {
3685 for(x=0;x<8;x++)
3686 {
3687 j = EGS(sect,s->x,s->y,s->z-(8<<8),SCRAP3+(TRAND&3),-8,48,48,TRAND&2047,(TRAND&63)+64,-(TRAND&4095)-(s->zvel>>2),i,5);
3688 sprite[j].pal = 6;
3689 }
3690
3691 spritesound(SLIM_DYING,i);
3692 spritesound(SQUISHED,i);
3693 if( (TRAND&255) < 32 )
3694 {
3695 j = spawn(i,BLOODPOOL);
3696 sprite[j].pal = 0;
3697 }
3698 ps[p].actors_killed ++;
3699 t[0] = -3;
3700 if(ps[p].somethingonplayer == i)
3701 ps[p].somethingonplayer = -1;
3702 KILLIT(i);
3703 }
3704
3705 s->z = ps[p].posz+ps[p].pyoff-t[2]+(8<<8);
3706
3707 s->z += (100-ps[p].horiz)<<4;
3708
3709 if( t[2] > 512)
3710 t[2] -= 128;
3711
3712 if( t[2] < 348)
3713 t[2] += 128;
3714
3715 if(ps[p].newowner >= 0)
3716 {
3717 ps[p].newowner = -1;
3718 ps[p].posx = ps[p].oposx;
3719 ps[p].posy = ps[p].oposy;
3720 ps[p].posz = ps[p].oposz;
3721 ps[p].ang = ps[p].oang;
3722
3723 updatesector(ps[p].posx,ps[p].posy,&ps[p].cursectnum);
3724 setpal(&ps[p]);
3725
3726 j = headspritestat[1];
3727 while(j >= 0)
3728 {
3729 if(sprite[j].picnum==CAMERA1) sprite[j].yvel = 0;
3730 j = nextspritestat[j];
3731 }
3732 }
3733
3734 if(t[3]>0)
3735 {
3736 short frames[] = {5,5,6,6,7,7,6,5};
3737
3738 s->picnum = GREENSLIME+frames[t[3]];
3739
3740 if( t[3] == 5 )
3741 {
3742 sprite[ps[p].i].extra += -(5+(TRAND&3));
3743 spritesound(SLIM_ATTACK,i);
3744 }
3745
3746 if(t[3] < 7) t[3]++;
3747 else t[3] = 0;
3748
3749 }
3750 else
3751 {
3752 s->picnum = GREENSLIME+5;
3753 if(rnd(32))
3754 t[3] = 1;
3755 }
3756
3757 s->xrepeat = 20+(sintable[t[1]&2047]>>13);
3758 s->yrepeat = 15+(sintable[t[1]&2047]>>13);
3759
3760 s->x = ps[p].posx + (sintable[(ps[p].ang+512)&2047]>>7);
3761 s->y = ps[p].posy + (sintable[ps[p].ang&2047]>>7);
3762
3763 goto BOLT;
3764 }
3765
3766 else if(s->xvel < 64 && x < 768)
3767 {
3768 if(ps[p].somethingonplayer == -1)
3769 {
3770 ps[p].somethingonplayer = i;
3771 if(t[0] == 3 || t[0] == 2) //Falling downward
3772 t[2] = (12<<8);
3773 else t[2] = -(13<<8); //Climbing up duke
3774 t[0] = -4;
3775 }
3776 }
3777
3778 IFHIT
3779 {
3780 spritesound(SLIM_DYING,i);
3781
3782 ps[p].actors_killed ++;
3783 if(ps[p].somethingonplayer == i)
3784 ps[p].somethingonplayer = -1;
3785
3786 if(j == FREEZEBLAST)
3787 {
3788 spritesound(SOMETHINGFROZE,i); t[0] = -5 ; t[3] = 0 ;
3789 goto BOLT;
3790 }
3791
3792 if( (TRAND&255) < 32 )
3793 {
3794 j = spawn(i,BLOODPOOL);
3795 sprite[j].pal = 0;
3796 }
3797
3798 for(x=0;x<8;x++)
3799 {
3800 j = EGS(sect,s->x,s->y,s->z-(8<<8),SCRAP3+(TRAND&3),-8,48,48,TRAND&2047,(TRAND&63)+64,-(TRAND&4095)-(s->zvel>>2),i,5);
3801 sprite[j].pal = 6;
3802 }
3803 t[0] = -3;
3804 KILLIT(i);
3805 }
3806 // All weap
3807 if(t[0] == -1) //Shrinking down
3808 {
3809 makeitfall(i);
3810
3811 s->cstat &= 65535-8;
3812 s->picnum = GREENSLIME+4;
3813
3814// if(s->yrepeat > 62)
3815 // guts(s,JIBS6,5,myconnectindex);
3816
3817 if(s->xrepeat > 32) s->xrepeat -= TRAND&7;
3818 if(s->yrepeat > 16) s->yrepeat -= TRAND&7;
3819 else
3820 {
3821 s->xrepeat = 40;
3822 s->yrepeat = 16;
3823 t[5] = -1;
3824 t[0] = 0;
3825 }
3826
3827 goto BOLT;
3828 }
3829 else if(t[0] != -2) getglobalz(i);
3830
3831 if(t[0] == -2) //On top of somebody
3832 {
3833 makeitfall(i);
3834 sprite[t[5]].xvel = 0;
3835
3836 l = sprite[t[5]].ang;
3837
3838 s->z = sprite[t[5]].z;
3839 s->x = sprite[t[5]].x+(sintable[(l+512)&2047]>>11);
3840 s->y = sprite[t[5]].y+(sintable[l&2047]>>11);
3841
3842 s->picnum = GREENSLIME+2+(global_random&1);
3843
3844 if(s->yrepeat < 64) s->yrepeat+=2;
3845 else
3846 {
3847 if(s->xrepeat < 32) s->xrepeat += 4;
3848 else
3849 {
3850 t[0] = -1;
3851 x = ldist(s,&sprite[t[5]]);
3852 if(x < 768) sprite[t[5]].xrepeat = 0;
3853 }
3854 }
3855
3856 goto BOLT;
3857 }
3858
3859 //Check randomly to see of there is an actor near
3860 if(rnd(32))
3861 {
3862 j = headspritesect[sect];
3863 while(j>=0)
3864 {
3865 switch(sprite[j].picnum)
3866 {
3867 case LIZTROOP:
3868 case LIZMAN:
3869 case PIGCOP:
3870 case NEWBEAST:
3871 if( ldist(s,&sprite[j]) < 768 && (klabs(s->z-sprite[j].z)<8192) ) //Gulp them
3872 {
3873 t[5] = j;
3874 t[0] = -2;
3875 t[1] = 0;
3876 goto BOLT;
3877 }
3878 }
3879
3880 j = nextspritesect[j];
3881 }
3882 }
3883
3884 //Moving on the ground or ceiling
3885
3886 if(t[0] == 0 || t[0] == 2)
3887 {
3888 s->picnum = GREENSLIME;
3889
3890 if( (TRAND&511) == 0 )
3891 spritesound(SLIM_ROAM,i);
3892
3893 if(t[0]==2)
3894 {
3895 s->zvel = 0;
3896 s->cstat &= (65535-8);
3897
3898 if( (sector[sect].ceilingstat&1) || (hittype[i].ceilingz+6144) < s->z)
3899 {
3900 s->z += 2048;
3901 t[0] = 3;
3902 goto BOLT;
3903 }
3904 }
3905 else
3906 {
3907 s->cstat |= 8;
3908 makeitfall(i);
3909 }
3910
3911 if( everyothertime&1 ) ssp(i,CLIPMASK0);
3912
3913 if(s->xvel > 96)
3914 {
3915 s->xvel -= 2;
3916 goto BOLT;
3917 }
3918 else
3919 {
3920 if(s->xvel < 32) s->xvel += 4;
3921 s->xvel = 64 - (sintable[(t[1]+512)&2047]>>9);
3922
3923 s->ang += getincangle(s->ang,
3924 getangle(ps[p].posx-s->x,ps[p].posy-s->y))>>3;
3925// TJR
3926 }
3927
3928 s->xrepeat = 36 + (sintable[(t[1]+512)&2047]>>11);
3929 s->yrepeat = 16 + (sintable[t[1]&2047]>>13);
3930
3931 if(rnd(4) && (sector[sect].ceilingstat&1) == 0 &&
3932 klabs(hittype[i].floorz-hittype[i].ceilingz)
3933 < (192<<8) )
3934 {
3935 s->zvel = 0;
3936 t[0]++;
3937 }
3938
3939 }
3940
3941 if(t[0]==1)
3942 {
3943 s->picnum = GREENSLIME;
3944 if(s->yrepeat < 40) s->yrepeat+=8;
3945 if(s->xrepeat > 8) s->xrepeat-=4;
3946 if(s->zvel > -(2048+1024))
3947 s->zvel -= 348;
3948 s->z += s->zvel;
3949 if(s->z < hittype[i].ceilingz+4096)
3950 {
3951 s->z = hittype[i].ceilingz+4096;
3952 s->xvel = 0;
3953 t[0] = 2;
3954 }
3955 }
3956
3957 if(t[0]==3)
3958 {
3959 s->picnum = GREENSLIME+1;
3960
3961 makeitfall(i);
3962
3963 if(s->z > hittype[i].floorz-(8<<8))
3964 {
3965 s->yrepeat-=4;
3966 s->xrepeat+=2;
3967 }
3968 else
3969 {
3970 if(s->yrepeat < (40-4)) s->yrepeat+=8;
3971 if(s->xrepeat > 8) s->xrepeat-=4;
3972 }
3973
3974 if(s->z > hittype[i].floorz-2048)
3975 {
3976 s->z = hittype[i].floorz-2048;
3977 t[0] = 0;
3978 s->xvel = 0;
3979 }
3980 }
3981 goto BOLT;
3982
3983 case BOUNCEMINE:
3984 case MORTER:
3985 j = spawn(i,FRAMEEFFECT1);
3986 hittype[j].temp_data[0] = 3;
3987
3988 case HEAVYHBOMB:
3989
3990 if( (s->cstat&32768) )
3991 {
3992 t[2]--;
3993 if(t[2] <= 0)
3994 {
3995 spritesound(TELEPORTER,i);
3996 spawn(i,TRANSPORTERSTAR);
3997 s->cstat = 257;
3998 }
3999 goto BOLT;
4000 }
4001
4002 p = findplayer(s,&x);
4003
4004 if( x < 1220 ) s->cstat &= ~257;
4005 else s->cstat |= 257;
4006
4007 if(t[3] == 0 )
4008 {
4009 j = ifhitbyweapon(i);
4010 if(j >= 0)
4011 {
4012 t[3] = 1;
4013 t[4] = 0;
4014 l = 0;
4015 s->xvel = 0;
4016 goto DETONATEB;
4017 }
4018 }
4019
4020 if( s->picnum != BOUNCEMINE )
4021 {
4022 makeitfall(i);
4023
4024 if( sector[sect].lotag != 1 && s->z >= hittype[i].floorz-(FOURSLEIGHT) && s->yvel < 3 )
4025 {
4026 if( s->yvel > 0 || (s->yvel == 0 && hittype[i].floorz == sector[sect].floorz ))
4027 spritesound(PIPEBOMB_BOUNCE,i);
4028 s->zvel = -((4-s->yvel)<<8);
4029 if(sector[s->sectnum].lotag== 2)
4030 s->zvel >>= 2;
4031 s->yvel++;
4032 }
4033 if( s->z < hittype[i].ceilingz ) // && sector[sect].lotag != 2 )
4034 {
4035 s->z = hittype[i].ceilingz+(3<<8);
4036 s->zvel = 0;
4037 }
4038 }
4039
4040 j = movesprite(i,
4041 (s->xvel*(sintable[(s->ang+512)&2047]))>>14,
4042 (s->xvel*(sintable[s->ang&2047]))>>14,
4043 s->zvel,CLIPMASK0);
4044
4045 if(sector[SECT].lotag == 1 && s->zvel == 0)
4046 {
4047 s->z += (32<<8);
4048 if(t[5] == 0)
4049 {
4050 t[5] = 1;
4051 spawn(i,WATERSPLASH2);
4052 }
4053 }
4054 else t[5] = 0;
4055
4056 if(t[3] == 0 && ( s->picnum == BOUNCEMINE || s->picnum == MORTER ) && (j || x < 844) )
4057 {
4058 t[3] = 1;
4059 t[4] = 0;
4060 l = 0;
4061 s->xvel = 0;
4062 goto DETONATEB;
4063 }
4064
4065 if(sprite[s->owner].picnum == APLAYER)
4066 l = sprite[s->owner].yvel;
4067 else l = -1;
4068
4069 if(s->xvel > 0)
4070 {
4071 s->xvel -= 5;
4072 if(sector[sect].lotag == 2)
4073 s->xvel -= 10;
4074
4075 if(s->xvel < 0)
4076 s->xvel = 0;
4077 if(s->xvel&8) s->cstat ^= 4;
4078 }
4079
4080 if( (j&49152) == 32768 )
4081 {
4082 j &= (MAXWALLS-1);
4083
4084 checkhitwall(i,j,s->x,s->y,s->z,s->picnum);
4085
4086 k = getangle(
4087 wall[wall[j].point2].x-wall[j].x,
4088 wall[wall[j].point2].y-wall[j].y);
4089
4090 s->ang = ((k<<1) - s->ang)&2047;
4091 s->xvel >>= 1;
4092 }
4093
4094 DETONATEB:
4095
4096 if( ( l >= 0 && ps[l].hbomb_on == 0 ) || t[3] == 1)
4097 {
4098 t[4]++;
4099
4100 if(t[4] == 2)
4101 {
4102 x = s->extra;
4103 m = 0;
4104 switch(s->picnum)
4105 {
4106 case HEAVYHBOMB: m = pipebombblastradius;break;
4107 case MORTER: m = morterblastradius;break;
4108 case BOUNCEMINE: m = bouncemineblastradius;break;
4109 }
4110
4111 hitradius( i, m,x>>2,x>>1,x-(x>>2),x);
4112 spawn(i,EXPLOSION2);
4113 if( s->zvel == 0 )
4114 spawn(i,EXPLOSION2BOT);
4115 spritesound(PIPEBOMB_EXPLODE,i);
4116 for(x=0;x<8;x++)
4117 RANDOMSCRAP;
4118 }
4119
4120 if(s->yrepeat)
4121 {
4122 s->yrepeat = 0;
4123 goto BOLT;
4124 }
4125
4126 if(t[4] > 20)
4127 {
4128 if(s->owner != i || ud.respawn_items == 0)
4129 {
4130 KILLIT(i);
4131 }
4132 else
4133 {
4134 t[2] = respawnitemtime;
4135 spawn(i,RESPAWNMARKERRED);
4136 s->cstat = (short) 32768;
4137 s->yrepeat = 9;
4138 goto BOLT;
4139 }
4140 }
4141 }
4142 else if(s->picnum == HEAVYHBOMB && x < 788 && t[0] > 7 && s->xvel == 0)
4143 if( cansee(s->x,s->y,s->z-(8<<8),s->sectnum,ps[p].posx,ps[p].posy,ps[p].posz,ps[p].cursectnum) )
4144 if(ps[p].ammo_amount[HANDBOMB_WEAPON] < max_ammo_amount[HANDBOMB_WEAPON] )
4145 {
4146 if(ud.coop >= 1 && s->owner == i)
4147 {
4148 for(j=0;j<ps[p].weapreccnt;j++)
4149 if(ps[p].weaprecs[j] == s->picnum)
4150 goto BOLT;
4151
4152 if(ps[p].weapreccnt < 255)
4153 ps[p].weaprecs[ps[p].weapreccnt++] = s->picnum;
4154 }
4155
4156 addammo(HANDBOMB_WEAPON,&ps[p],1);
4157 spritesound(DUKE_GET,ps[p].i);
4158
4159 if( ps[p].gotweapon[HANDBOMB_WEAPON] == 0 || s->owner == ps[p].i )
4160 addweapon(&ps[p],HANDBOMB_WEAPON);
4161
4162 if( sprite[s->owner].picnum != APLAYER )
4163 {
4164 ps[p].pals[0] = 0;
4165 ps[p].pals[1] = 32;
4166 ps[p].pals[2] = 0;
4167 ps[p].pals_time = 32;
4168 }
4169
4170 if( s->owner != i || ud.respawn_items == 0 )
4171 {
4172 if(s->owner == i && ud.coop >= 1)
4173 goto BOLT;
4174 KILLIT(i);
4175 }
4176 else
4177 {
4178 t[2] = respawnitemtime;
4179 spawn(i,RESPAWNMARKERRED);
4180 s->cstat = (short) 32768;
4181 }
4182 }
4183
4184 if(t[0] < 8) t[0]++;
4185 goto BOLT;
4186
4187 case REACTORBURNT:
4188 case REACTOR2BURNT:
4189 goto BOLT;
4190
4191 case REACTOR:
4192 case REACTOR2:
4193
4194 if( t[4] == 1 )
4195 {
4196 j = headspritesect[sect];
4197 while(j >= 0)
4198 {
4199 switch(sprite[j].picnum)
4200 {
4201 case SECTOREFFECTOR:
4202 if(sprite[j].lotag == 1)
4203 {
4204 sprite[j].lotag = (short) 65535;
4205 sprite[j].hitag = (short) 65535;
4206 }
4207 break;
4208 case REACTOR:
4209 sprite[j].picnum = REACTORBURNT;
4210 break;
4211 case REACTOR2:
4212 sprite[j].picnum = REACTOR2BURNT;
4213 break;
4214 case REACTORSPARK:
4215 case REACTOR2SPARK:
4216 sprite[j].cstat = (short) 32768;
4217 break;
4218 }
4219 j = nextspritesect[j];
4220 }
4221 goto BOLT;
4222 }
4223
4224 if(t[1] >= 20)
4225 {
4226 t[4] = 1;
4227 goto BOLT;
4228 }
4229
4230 p = findplayer(s,&x);
4231
4232 t[2]++;
4233 if( t[2] == 4 ) t[2]=0;
4234
4235 if( x < 4096 )
4236 {
4237 if( (TRAND&255) < 16 )
4238 {
4239 if(Sound[DUKE_LONGTERM_PAIN].num < 1)
4240 spritesound(DUKE_LONGTERM_PAIN,ps[p].i);
4241
4242 spritesound(SHORT_CIRCUIT,i);
4243
4244 sprite[ps[p].i].extra --;
4245 ps[p].pals_time = 32;
4246 ps[p].pals[0] = 32;
4247 ps[p].pals[1] = 0;
4248 ps[p].pals[2] = 0;
4249 }
4250 t[0] += 128;
4251 if( t[3] == 0 )
4252 t[3] = 1;
4253 }
4254 else t[3] = 0;
4255
4256 if( t[1] )
4257 {
4258 t[1]++;
4259
4260 t[4] = s->z;
4261 s->z = sector[sect].floorz-(TRAND%(sector[sect].floorz-sector[sect].ceilingz));
4262
4263 switch( t[1] )
4264 {
4265 case 3:
4266 //Turn on all of those flashing sectoreffector.
4267 hitradius( i, 4096,
4268 impact_damage<<2,
4269 impact_damage<<2,
4270 impact_damage<<2,
4271 impact_damage<<2 );
4272/*
4273 j = headspritestat[3];
4274 while(j>=0)
4275 {
4276 if( sprite[j].lotag == 3 )
4277 hittype[j].temp_data[4]=1;
4278 else if(sprite[j].lotag == 12)
4279 {
4280 hittype[j].temp_data[4] = 1;
4281 sprite[j].lotag = 3;
4282 sprite[j].owner = 0;
4283 hittype[j].temp_data[0] = s->shade;
4284 }
4285 j = nextspritestat[j];
4286 }
4287*/
4288 j = headspritestat[6];
4289 while(j >= 0)
4290 {
4291 if(sprite[j].picnum == MASTERSWITCH)
4292 if(sprite[j].hitag == s->hitag)
4293 if(sprite[j].yvel == 0)
4294 sprite[j].yvel = 1;
4295 j = nextspritestat[j];
4296 }
4297 break;
4298
4299 case 4:
4300 case 7:
4301 case 10:
4302 case 15:
4303 j = headspritesect[sect];
4304 while(j >= 0)
4305 {
4306 l = nextspritesect[j];
4307
4308 if(j != i)
4309 {
4310 deletesprite(j);
4311 break;
4312 }
4313 j = l;
4314 }
4315 break;
4316 }
4317 for(x=0;x<16;x++)
4318 RANDOMSCRAP;
4319
4320 s->z = t[4];
4321 t[4] = 0;
4322
4323 }
4324 else
4325 {
4326 IFHIT
4327 {
4328 for(x=0;x<32;x++)
4329 RANDOMSCRAP;
4330 if(s->extra < 0)
4331 t[1] = 1;
4332 }
4333 }
4334 goto BOLT;
4335
4336 case CAMERA1:
4337
4338 if( t[0] == 0 )
4339 {
4340 t[1]+=8;
4341 if(camerashitable)
4342 {
4343 IFHIT
4344 {
4345 t[0] = 1; // static
4346 s->cstat = (short)32768;
4347 for(x=0;x<5;x++) RANDOMSCRAP;
4348 goto BOLT;
4349 }
4350 }
4351
4352 if(s->hitag > 0)
4353 {
4354 if(t[1]<s->hitag)
4355 s->ang+=8;
4356 else if(t[1]<(s->hitag*3))
4357 s->ang-=8;
4358 else if(t[1] < (s->hitag<<2) )
4359 s->ang+=8;
4360 else
4361 {
4362 t[1]=8;
4363 s->ang+=16;
4364 }
4365 }
4366 }
4367 goto BOLT;
4368 }
4369
4370
4371// #ifndef VOLOMEONE
4372 if( ud.multimode < 2 && badguy(s) )
4373 {
4374 if( actor_tog == 1)
4375 {
4376 s->cstat = (short)32768;
4377 goto BOLT;
4378 }
4379 else if(actor_tog == 2) s->cstat = 257;
4380 }
4381// #endif
4382
4383 p = findplayer(s,&x);
4384
4385 execute(i,p,x);
4386
4387 BOLT:
4388
4389 i = nexti;
4390 }
4391
4392}
4393
4394
4395void moveexplosions(void) // STATNUM 5
4396{
4397 short i, j, nexti, sect, p;
4398 int32_t l, x, *t;
4399 spritetype *s;
4400
4401 i = headspritestat[5];
4402 while(i >= 0)
4403 {
4404 nexti = nextspritestat[i];
4405
4406 t = &hittype[i].temp_data[0];
4407 s = &sprite[i];
4408 sect = s->sectnum;
4409
4410 if( sect < 0 || s->xrepeat == 0 ) KILLIT(i);
4411
4412 hittype[i].bposx = s->x;
4413 hittype[i].bposy = s->y;
4414 hittype[i].bposz = s->z;
4415
4416 switch(s->picnum)
4417 {
4418 case NEON1:
4419 case NEON2:
4420 case NEON3:
4421 case NEON4:
4422 case NEON5:
4423 case NEON6:
4424
4425 if( (global_random/(s->lotag+1)&31) > 4) s->shade = -127;
4426 else s->shade = 127;
4427 goto BOLT;
4428
4429 case BLOODSPLAT1:
4430 case BLOODSPLAT2:
4431 case BLOODSPLAT3:
4432 case BLOODSPLAT4:
4433
4434 if( t[0] == 7*26 ) goto BOLT;
4435 s->z += 16+(TRAND&15);
4436 t[0]++;
4437 if( (t[0]%9) == 0 ) s->yrepeat++;
4438 goto BOLT;
4439
4440 case NUKEBUTTON:
4441 case NUKEBUTTON+1:
4442 case NUKEBUTTON+2:
4443 case NUKEBUTTON+3:
4444
4445 if(t[0])
4446 {
4447 t[0]++;
4448 if(t[0] == 8) s->picnum = NUKEBUTTON+1;
4449 else if(t[0] == 16)
4450 {
4451 s->picnum = NUKEBUTTON+2;
4452 ps[sprite[s->owner].yvel].fist_incs = 1;
4453 }
4454 if( ps[sprite[s->owner].yvel].fist_incs == 26 )
4455 s->picnum = NUKEBUTTON+3;
4456 }
4457 goto BOLT;
4458
4459 case FORCESPHERE:
4460
4461 l = s->xrepeat;
4462 if(t[1] > 0)
4463 {
4464 t[1]--;
4465 if(t[1] == 0)
4466 {
4467 KILLIT(i);
4468 }
4469 }
4470 if(hittype[s->owner].temp_data[1] == 0)
4471 {
4472 if(t[0] < 64)
4473 {
4474 t[0]++;
4475 l += 3;
4476 }
4477 }
4478 else
4479 if(t[0] > 64)
4480 {
4481 t[0]--;
4482 l -= 3;
4483 }
4484
4485 s->x = sprite[s->owner].x;
4486 s->y = sprite[s->owner].y;
4487 s->z = sprite[s->owner].z;
4488 s->ang += hittype[s->owner].temp_data[0];
4489
4490 if(l > 64) l = 64;
4491 else if(l < 1) l = 1;
4492
4493 s->xrepeat = l;
4494 s->yrepeat = l;
4495 s->shade = (l>>1)-48;
4496
4497 for(j=t[0];j > 0;j--)
4498 ssp(i,CLIPMASK0);
4499 goto BOLT;
4500 case WATERSPLASH2:
4501
4502 t[0]++;
4503 if(t[0] == 1 )
4504 {
4505 if(sector[sect].lotag != 1 && sector[sect].lotag != 2)
4506 KILLIT(i);
4507/* else
4508 {
4509 l = getflorzofslope(sect,s->x,s->y)-s->z;
4510 if( l > (16<<8) ) KILLIT(i);
4511 }
4512 else */ if(Sound[ITEM_SPLASH].num == 0)
4513 spritesound(ITEM_SPLASH,i);
4514 }
4515 if(t[0] == 3)
4516 {
4517 t[0] = 0;
4518 t[1]++;
4519 }
4520 if(t[1] == 5)
4521 deletesprite(i);
4522 goto BOLT;
4523
4524 case FRAMEEFFECT1:
4525 case FRAMEEFFECT1_13CON:
4526 if(s->owner >= 0)
4527 {
4528 t[0]++;
4529
4530 if( t[0] > 7 )
4531 {
4532 KILLIT(i);
4533 }
4534 else if( t[0] > 4 )
4535 s->cstat |= 512+2;
4536 else if( t[0] > 2 )
4537 s->cstat |= 2;
4538 s->xoffset = sprite[s->owner].xoffset;
4539 s->yoffset = sprite[s->owner].yoffset;
4540 }
4541 goto BOLT;
4542 case INNERJAW:
4543 case INNERJAW+1:
4544
4545 p = findplayer(s,&x);
4546 if(x < 512)
4547 {
4548 ps[p].pals_time = 32;
4549 ps[p].pals[0] = 32;
4550 ps[p].pals[1] = 0;
4551 ps[p].pals[2] = 0;
4552 sprite[ps[p].i].extra -= 4;
4553 }
4554
4555 case FIRELASER:
4556 if(s->extra != 999)
4557 s->extra = 999;
4558 else KILLIT(i);
4559 break;
4560 case TONGUE:
4561 KILLIT(i);
4562 case MONEY+1:
4563 case MAIL+1:
4564 case PAPER+1:
4565 hittype[i].floorz = s->z = getflorzofslope(s->sectnum,s->x,s->y);
4566 break;
4567 case MONEY:
4568 case MAIL:
4569 case PAPER:
4570
4571 s->xvel = (TRAND&7)+(sintable[T1&2047]>>9);
4572 T1 += (TRAND&63);
4573 if( (T1&2047) > 512 && (T1&2047) < 1596)
4574 {
4575 if(sector[sect].lotag == 2)
4576 {
4577 if(s->zvel < 64)
4578 s->zvel += (gc>>5)+(TRAND&7);
4579 }
4580 else
4581 if(s->zvel < 144)
4582 s->zvel += (gc>>5)+(TRAND&7);
4583 }
4584
4585 ssp(i,CLIPMASK0);
4586
4587 if( (TRAND&3) == 0 )
4588 setsprite(i,s->x,s->y,s->z);
4589
4590 if(s->sectnum == -1) KILLIT(i);
4591 l = getflorzofslope(s->sectnum,s->x,s->y);
4592
4593 if( s->z > l )
4594 {
4595 s->z = l;
4596
4597 insertspriteq(i);
4598 PN ++;
4599
4600 j = headspritestat[5];
4601 while(j >= 0)
4602 {
4603 if(sprite[j].picnum == BLOODPOOL)
4604 if(ldist(s,&sprite[j]) < 348)
4605 {
4606 s->pal = 2;
4607 break;
4608 }
4609 j = nextspritestat[j];
4610 }
4611 }
4612
4613 break;
4614
4615 case JIBS1:
4616 case JIBS2:
4617 case JIBS3:
4618 case JIBS4:
4619 case JIBS5:
4620 case JIBS6:
4621 case HEADJIB1:
4622 case ARMJIB1:
4623 case LEGJIB1:
4624 case LIZMANHEAD1:
4625 case LIZMANARM1:
4626 case LIZMANLEG1:
4627 case DUKETORSO:
4628 case DUKEGUN:
4629 case DUKELEG:
4630
4631 if(s->xvel > 0) s->xvel--;
4632 else s->xvel = 0;
4633
4634 if( t[5] < 30*10 )
4635 t[5]++;
4636 else { KILLIT(i); }
4637
4638
4639 if(s->zvel > 1024 && s->zvel < 1280)
4640 {
4641 setsprite(i,s->x,s->y,s->z);
4642 sect = s->sectnum;
4643 }
4644
4645 l = getflorzofslope(sect,s->x,s->y);
4646 x = getceilzofslope(sect,s->x,s->y);
4647 if(x == l || sect < 0 || sect >= MAXSECTORS) KILLIT(i);
4648
4649 if( s->z < l-(2<<8) )
4650 {
4651 if(t[1] < 2) t[1]++;
4652 else if(sector[sect].lotag != 2)
4653 {
4654 t[1] = 0;
4655 if( s->picnum == DUKELEG || s->picnum == DUKETORSO || s->picnum == DUKEGUN )
4656 {
4657 if(t[0] > 6) t[0] = 0;
4658 else t[0]++;
4659 }
4660 else
4661 {
4662 if(t[0] > 2)
4663 t[0] = 0;
4664 else t[0]++;
4665 }
4666 }
4667
4668 if(s->zvel < 6144)
4669 {
4670 if(sector[sect].lotag == 2)
4671 {
4672 if(s->zvel < 1024)
4673 s->zvel += 48;
4674 else s->zvel = 1024;
4675 }
4676 else s->zvel += gc-50;
4677 }
4678
4679 s->x += (s->xvel*sintable[(s->ang+512)&2047])>>14;
4680 s->y += (s->xvel*sintable[s->ang&2047])>>14;
4681 s->z += s->zvel;
4682
4683 }
4684 else
4685 {
4686 if(t[2] == 0)
4687 {
4688 if( s->sectnum == -1) { KILLIT(i); }
4689 if( (sector[s->sectnum].floorstat&2) ) { KILLIT(i); }
4690 t[2]++;
4691 }
4692 l = getflorzofslope(s->sectnum,s->x,s->y);
4693
4694 s->z = l-(2<<8);
4695 s->xvel = 0;
4696
4697 if(s->picnum == JIBS6)
4698 {
4699 t[1]++;
4700 if( (t[1]&3) == 0 && t[0] < 7)
4701 t[0]++;
4702 if(t[1] > 20) KILLIT(i);
4703 }
4704 else { s->picnum = JIBS6; t[0] = 0; t[1] = 0; }
4705 }
4706 goto BOLT;
4707
4708 case BLOODPOOL:
4709 case PUKE:
4710
4711 if(t[0] == 0)
4712 {
4713 t[0] = 1;
4714 if(sector[sect].floorstat&2) { KILLIT(i); }
4715 else insertspriteq(i);
4716 }
4717
4718 makeitfall(i);
4719
4720 p = findplayer(s,&x);
4721
4722 s->z = hittype[i].floorz-(FOURSLEIGHT);
4723
4724 if(t[2] < 32)
4725 {
4726 t[2]++;
4727 if(hittype[i].picnum == TIRE)
4728 {
4729 if(s->xrepeat < 64 && s->yrepeat < 64)
4730 {
4731 s->xrepeat += TRAND&3;
4732 s->yrepeat += TRAND&3;
4733 }
4734 }
4735 else
4736 {
4737 if(s->xrepeat < 32 && s->yrepeat < 32)
4738 {
4739 s->xrepeat += TRAND&3;
4740 s->yrepeat += TRAND&3;
4741 }
4742 }
4743 }
4744
4745 if(x < 844 && s->xrepeat > 6 && s->yrepeat > 6)
4746 {
4747 if( s->pal == 0 && (TRAND&255) < 16 && s->picnum != PUKE)
4748 {
4749 if(ps[p].boot_amount > 0)
4750 ps[p].boot_amount--;
4751 else
4752 {
4753 if(Sound[DUKE_LONGTERM_PAIN].num < 1)
4754 spritesound(DUKE_LONGTERM_PAIN,ps[p].i);
4755 sprite[ps[p].i].extra --;
4756 ps[p].pals_time = 32;
4757 ps[p].pals[0] = 16;
4758 ps[p].pals[1] = 0;
4759 ps[p].pals[2] = 0;
4760 }
4761 }
4762
4763 if(t[1] == 1) goto BOLT;
4764 t[1] = 1;
4765
4766 if(hittype[i].picnum == TIRE)
4767 ps[p].footprintcount = 10;
4768 else ps[p].footprintcount = 3;
4769
4770 ps[p].footprintpal = s->pal;
4771 ps[p].footprintshade = s->shade;
4772
4773 if(t[2] == 32)
4774 {
4775 s->xrepeat -= 6;
4776 s->yrepeat -= 6;
4777 }
4778 }
4779 else t[1] = 0;
4780 goto BOLT;
4781
4782 case BURNING:
4783 case BURNING2:
4784 case FECES:
4785 case WATERBUBBLE:
4786 case SMALLSMOKE:
4787 case EXPLOSION2:
4788 case SHRINKEREXPLOSION:
4789 case EXPLOSION2BOT:
4790 case BLOOD:
4791 case LASERSITE:
4792 case FORCERIPPLE:
4793 case TRANSPORTERSTAR:
4794 case TRANSPORTERBEAM:
4795 p = findplayer(s,&x);
4796 execute(i,p,x);
4797 goto BOLT;
4798
4799 case SHELL:
4800 case SHOTGUNSHELL:
4801
4802 ssp(i,CLIPMASK0);
4803
4804 if(sect < 0 || ( sector[sect].floorz+(24<<8) ) < s->z ) KILLIT(i);
4805
4806 if(sector[sect].lotag == 2)
4807 {
4808 t[1]++;
4809 if(t[1] > 8)
4810 {
4811 t[1] = 0;
4812 t[0]++;
4813 t[0] &= 3;
4814 }
4815 if(s->zvel < 128) s->zvel += (gc/13); // 8
4816 else s->zvel -= 64;
4817 if(s->xvel > 0)
4818 s->xvel -= 4;
4819 else s->xvel = 0;
4820 }
4821 else
4822 {
4823 t[1]++;
4824 if(t[1] > 3)
4825 {
4826 t[1] = 0;
4827 t[0]++;
4828 t[0] &= 3;
4829 }
4830 if(s->zvel < 512) s->zvel += (gc/3); // 52;
4831 if(s->xvel > 0)
4832 s->xvel --;
4833 else KILLIT(i);
4834 }
4835
4836 goto BOLT;
4837
4838 case GLASSPIECES:
4839 case GLASSPIECES+1:
4840 case GLASSPIECES+2:
4841
4842 makeitfall(i);
4843
4844 if(s->zvel > 4096) s->zvel = 4096;
4845 if(sect < 0) KILLIT(i);
4846
4847 if( s->z == hittype[i].floorz-(FOURSLEIGHT) && t[0] < 3)
4848 {
4849 s->zvel = -((3-t[0])<<8)-(TRAND&511);
4850 if(sector[sect].lotag == 2)
4851 s->zvel >>= 1;
4852 s->xrepeat >>= 1;
4853 s->yrepeat >>= 1;
4854 if( rnd(96) )
4855 setsprite(i,s->x,s->y,s->z);
4856 t[0]++;//Number of bounces
4857 }
4858 else if( t[0] == 3 ) KILLIT(i);
4859
4860 if(s->xvel > 0)
4861 {
4862 s->xvel -= 2;
4863 s->cstat = ((s->xvel&3)<<2);
4864 }
4865 else s->xvel = 0;
4866
4867 ssp(i,CLIPMASK0);
4868
4869 goto BOLT;
4870 }
4871
4872 IFWITHIN(SCRAP6,SCRAP5+3)
4873 {
4874 if(s->xvel > 0)
4875 s->xvel--;
4876 else s->xvel = 0;
4877
4878 if(s->zvel > 1024 && s->zvel < 1280)
4879 {
4880 setsprite(i,s->x,s->y,s->z);
4881 sect = s->sectnum;
4882 }
4883
4884 if( s->z < sector[sect].floorz-(2<<8) )
4885 {
4886 if(t[1] < 1) t[1]++;
4887 else
4888 {
4889 t[1] = 0;
4890
4891 if(s->picnum < SCRAP6+8)
4892 {
4893 if(t[0] > 6)
4894 t[0] = 0;
4895 else t[0]++;
4896 }
4897 else
4898 {
4899 if(t[0] > 2)
4900 t[0] = 0;
4901 else t[0]++;
4902 }
4903 }
4904 if(s->zvel < 4096) s->zvel += gc-50;
4905 s->x += (s->xvel*sintable[(s->ang+512)&2047])>>14;
4906 s->y += (s->xvel*sintable[s->ang&2047])>>14;
4907 s->z += s->zvel;
4908 }
4909 else
4910 {
4911 if(s->picnum == SCRAP1 && s->yvel > 0)
4912 {
4913 j = spawn(i,s->yvel);
4914 setsprite(j,s->x,s->y,s->z);
4915 getglobalz(j);
4916 sprite[j].hitag = sprite[j].lotag = 0;
4917 }
4918 KILLIT(i);
4919 }
4920 goto BOLT;
4921 }
4922
4923 BOLT:
4924 i = nexti;
4925 }
4926}
4927
4928void moveeffectors(void) //STATNUM 3
4929{
4930 int32_t q=0, l, m, x, st, j, *t;
4931 short i, k, nexti, nextk, p, sh, nextj;
4932 spritetype *s;
4933 sectortype *sc;
4934 walltype *wal;
4935
4936 fricxv = fricyv = 0;
4937
4938 i = headspritestat[3];
4939 while(i >= 0)
4940 {
4941 nexti = nextspritestat[i];
4942 s = &sprite[i];
4943
4944 sc = &sector[s->sectnum];
4945 st = s->lotag;
4946 sh = s->hitag;
4947
4948 t = &hittype[i].temp_data[0];
4949
4950 switch(st)
4951 {
4952 case 0:
4953 {
4954 int32_t zchange = 0;
4955
4956 zchange = 0;
4957
4958 j = s->owner;
4959
4960 if( sprite[j].lotag == (short) 65535 )
4961 KILLIT(i);
4962
4963 q = sc->extra>>3;
4964 l = 0;
4965
4966 if(sc->lotag == 30)
4967 {
4968 q >>= 2;
4969
4970 if( sprite[i].extra == 1 )
4971 {
4972 if(hittype[i].tempang < 256)
4973 {
4974 hittype[i].tempang += 4;
4975 if(hittype[i].tempang >= 256)
4976 callsound(s->sectnum,i);
4977 if(s->clipdist) l = 1;
4978 else l = -1;
4979 }
4980 else hittype[i].tempang = 256;
4981
4982 if( sc->floorz > s->z ) //z's are touching
4983 {
4984 sc->floorz -= 512;
4985 zchange = -512;
4986 if( sc->floorz < s->z )
4987 sc->floorz = s->z;
4988 }
4989
4990 else if( sc->floorz < s->z ) //z's are touching
4991 {
4992 sc->floorz += 512;
4993 zchange = 512;
4994 if( sc->floorz > s->z )
4995 sc->floorz = s->z;
4996 }
4997 }
4998 else if(sprite[i].extra == 3)
4999 {
5000 if(hittype[i].tempang > 0)
5001 {
5002 hittype[i].tempang -= 4;
5003 if(hittype[i].tempang <= 0)
5004 callsound(s->sectnum,i);
5005 if( s->clipdist ) l = -1;
5006 else l = 1;
5007 }
5008 else hittype[i].tempang = 0;
5009
5010 if( sc->floorz > T4 ) //z's are touching
5011 {
5012 sc->floorz -= 512;
5013 zchange = -512;
5014 if( sc->floorz < T4 )
5015 sc->floorz = T4;
5016 }
5017
5018 else if( sc->floorz < T4 ) //z's are touching
5019 {
5020 sc->floorz += 512;
5021 zchange = 512;
5022 if( sc->floorz > T4 )
5023 sc->floorz = T4;
5024 }
5025 }
5026
5027 s->ang += (l*q);
5028 t[2] += (l*q);
5029 }
5030 else
5031 {
5032 if( hittype[j].temp_data[0] == 0 ) break;
5033 if( hittype[j].temp_data[0] == 2 ) KILLIT(i);
5034
5035 if( sprite[j].ang > 1024 )
5036 l = -1;
5037 else l = 1;
5038 if( t[3] == 0 )
5039 t[3] = ldist(s,&sprite[j]);
5040 s->xvel = t[3];
5041 s->x = sprite[j].x;
5042 s->y = sprite[j].y;
5043 s->ang += (l*q);
5044 t[2] += (l*q);
5045 }
5046
5047 if( l && (sc->floorstat&64) )
5048 {
5049 for(p=connecthead;p>=0;p=connectpoint2[p])
5050 {
5051 if( ps[p].cursectnum == s->sectnum && ps[p].on_ground == 1)
5052 {
5053
5054 ps[p].ang += (l*q);
5055 ps[p].ang &= 2047;
5056
5057 ps[p].posz += zchange;
5058
5059 rotatepoint( sprite[j].x,sprite[j].y,
5060 ps[p].posx,ps[p].posy,(q*l),
5061 &m,&x);
5062
5063 ps[p].bobposx += m-ps[p].posx;
5064 ps[p].bobposy += x-ps[p].posy;
5065
5066 ps[p].posx = m;
5067 ps[p].posy = x;
5068
5069 if(sprite[ps[p].i].extra <= 0)
5070 {
5071 sprite[ps[p].i].x = m;
5072 sprite[ps[p].i].y = x;
5073 }
5074 }
5075 }
5076
5077 p = headspritesect[s->sectnum];
5078 while(p >= 0)
5079 {
5080 if(sprite[p].statnum != 3 && sprite[p].statnum != 4)
5081 if( sprite[p].picnum != LASERLINE )
5082 {
5083 if(sprite[p].picnum == APLAYER && sprite[p].owner >= 0)
5084 {
5085 p = nextspritesect[p];
5086 continue;
5087 }
5088
5089 sprite[p].ang += (l*q);
5090 sprite[p].ang &= 2047;
5091
5092 sprite[p].z += zchange;
5093
5094 rotatepoint(sprite[j].x,sprite[j].y,
5095 sprite[p].x,sprite[p].y,(q*l),
5096 &sprite[p].x,&sprite[p].y);
5097
5098 }
5099 p = nextspritesect[p];
5100 }
5101
5102 }
5103
5104 ms(i);
5105 }
5106
5107 break;
5108 case 1: //Nothing for now used as the pivot
5109 if(s->owner == -1) //Init
5110 {
5111 s->owner = i;
5112
5113 j = headspritestat[3];
5114 while(j >= 0)
5115 {
5116 if( sprite[j].lotag == 19 && sprite[j].hitag == sh )
5117 {
5118 t[0] = 0;
5119 break;
5120 }
5121 j = nextspritestat[j];
5122 }
5123 }
5124
5125 break;
5126 case 6:
5127 k = sc->extra;
5128
5129 if(t[4] > 0)
5130 {
5131 t[4]--;
5132 if( t[4] >= (k-(k>>3)) )
5133 s->xvel -= (k>>5);
5134 if( t[4] > ((k>>1)-1) && t[4] < (k-(k>>3)) )
5135 s->xvel = 0;
5136 if( t[4] < (k>>1) )
5137 s->xvel += (k>>5);
5138 if( t[4] < ((k>>1)-(k>>3)) )
5139 {
5140 t[4] = 0;
5141 s->xvel = k;
5142 }
5143 }
5144 else s->xvel = k;
5145
5146 j = headspritestat[3];
5147 while( j >= 0)
5148 {
5149 if( (sprite[j].lotag == 14) && (sh == sprite[j].hitag) && (hittype[j].temp_data[0] == t[0]) )
5150 {
5151 sprite[j].xvel = s->xvel;
5152// if( t[4] == 1 )
5153 {
5154 if(hittype[j].temp_data[5] == 0)
5155 hittype[j].temp_data[5] = dist(&sprite[j],s);
5156 x = sgn( dist(&sprite[j],s)-hittype[j].temp_data[5] );
5157 if(sprite[j].extra)
5158 x = -x;
5159 s->xvel += x;
5160 }
5161 hittype[j].temp_data[4] = t[4];
5162 }
5163 j = nextspritestat[j];
5164 }
5165 x = 0;
5166
5167
5168 case 14:
5169 if(s->owner==-1)
5170 s->owner = LocateTheLocator((short)t[3],(short)t[0]);
5171
5172 if(s->owner == -1)
5173 {
5174 sprintf((char *)tempbuf,"Could not find any locators for SE# 6 and 14 with a hitag of %d.\n",t[3]);
5175 gameexit((char *)tempbuf);
5176 }
5177
5178 j = ldist(&sprite[s->owner],s);
5179
5180 if( j < 1024L )
5181 {
5182 if(st==6)
5183 if(sprite[s->owner].hitag&1)
5184 t[4]=sc->extra; //Slow it down
5185 t[3]++;
5186 s->owner = LocateTheLocator(t[3],t[0]);
5187 if(s->owner==-1)
5188 {
5189 t[3]=0;
5190 s->owner = LocateTheLocator(0,t[0]);
5191 }
5192 }
5193
5194 if(s->xvel)
5195 {
5196 x = getangle(sprite[s->owner].x-s->x,sprite[s->owner].y-s->y);
5197 q = getincangle(s->ang,x)>>3;
5198
5199 t[2] += q;
5200 s->ang += q;
5201
5202 if(s->xvel == sc->extra )
5203 {
5204 if( (sc->floorstat&1) == 0 && (sc->ceilingstat&1) == 0 )
5205 {
5206 if( Sound[hittype[i].lastvx].num == 0 )
5207 spritesound(hittype[i].lastvx,i);
5208 }
5209 else if( ud.monsters_off == 0 && sc->floorpal == 0 && (sc->floorstat&1) && rnd(8) )
5210 {
5211 p = findplayer(s,&x);
5212 if(x < 20480)
5213 {
5214 j = s->ang;
5215 s->ang = getangle(s->x-ps[p].posx,s->y-ps[p].posy);
5216 shoot(i,RPG);
5217 s->ang = j;
5218 }
5219 }
5220 }
5221
5222 if(s->xvel <= 64 && (sc->floorstat&1) == 0 && (sc->ceilingstat&1) == 0 )
5223 stopsound(hittype[i].lastvx);
5224
5225 if( (sc->floorz-sc->ceilingz) < (108<<8) )
5226 {
5227 if(ud.clipping == 0 && s->xvel >= 192)
5228 for(p=connecthead;p>=0;p=connectpoint2[p])
5229 if(sprite[ps[p].i].extra > 0)
5230 {
5231 k = ps[p].cursectnum;
5232 updatesector(ps[p].posx,ps[p].posy,&k);
5233 if( ( k == -1 && ud.clipping == 0 ) || ( k == s->sectnum && ps[p].cursectnum != s->sectnum ) )
5234 {
5235 ps[p].posx = s->x;
5236 ps[p].posy = s->y;
5237 ps[p].cursectnum = s->sectnum;
5238
5239 setsprite(ps[p].i,s->x,s->y,s->z);
5240 quickkill(&ps[p]);
5241 }
5242 }
5243 }
5244
5245 m = (s->xvel*sintable[(s->ang+512)&2047])>>14;
5246 x = (s->xvel*sintable[s->ang&2047])>>14;
5247
5248 for(p = connecthead;p >= 0;p=connectpoint2[p])
5249 if(sector[ps[p].cursectnum].lotag != 2)
5250 {
5251 if(po[p].os == s->sectnum)
5252 {
5253 po[p].ox += m;
5254 po[p].oy += x;
5255 }
5256
5257 if(s->sectnum == sprite[ps[p].i].sectnum)
5258 {
5259 rotatepoint(s->x,s->y,ps[p].posx,ps[p].posy,q,&ps[p].posx,&ps[p].posy);
5260
5261 ps[p].posx += m;
5262 ps[p].posy += x;
5263
5264 ps[p].bobposx += m;
5265 ps[p].bobposy += x;
5266
5267 ps[p].ang += q;
5268
5269 if(numplayers > 1)
5270 {
5271 ps[p].oposx = ps[p].posx;
5272 ps[p].oposy = ps[p].posy;
5273 }
5274 if( sprite[ps[p].i].extra <= 0 )
5275 {
5276 sprite[ps[p].i].x = ps[p].posx;
5277 sprite[ps[p].i].y = ps[p].posy;
5278 }
5279 }
5280 }
5281 j = headspritesect[s->sectnum];
5282 while(j >= 0)
5283 {
5284 if (sprite[j].statnum != 10 && sector[sprite[j].sectnum].lotag != 2 && sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS )
5285 {
5286 rotatepoint(s->x,s->y,
5287 sprite[j].x,sprite[j].y,q,
5288 &sprite[j].x,&sprite[j].y);
5289
5290 sprite[j].x+= m;
5291 sprite[j].y+= x;
5292
5293 sprite[j].ang+=q;
5294
5295 if(numplayers > 1)
5296 {
5297 hittype[j].bposx = sprite[j].x;
5298 hittype[j].bposy = sprite[j].y;
5299 }
5300 }
5301 j = nextspritesect[j];
5302 }
5303
5304 ms(i);
5305 setsprite(i,s->x,s->y,s->z);
5306
5307 if( (sc->floorz-sc->ceilingz) < (108<<8) )
5308 {
5309 if(ud.clipping == 0 && s->xvel >= 192)
5310 for(p=connecthead;p>=0;p=connectpoint2[p])
5311 if(sprite[ps[p].i].extra > 0)
5312 {
5313 k = ps[p].cursectnum;
5314 updatesector(ps[p].posx,ps[p].posy,&k);
5315 if( ( k == -1 && ud.clipping == 0 ) || ( k == s->sectnum && ps[p].cursectnum != s->sectnum ) )
5316 {
5317 ps[p].oposx = ps[p].posx = s->x;
5318 ps[p].oposy = ps[p].posy = s->y;
5319 ps[p].cursectnum = s->sectnum;
5320
5321 setsprite(ps[p].i,s->x,s->y,s->z);
5322 quickkill(&ps[p]);
5323 }
5324 }
5325
5326 j = headspritesect[sprite[OW].sectnum];
5327 while(j >= 0)
5328 {
5329 l = nextspritesect[j];
5330 if (sprite[j].statnum == 1 && badguy(&sprite[j]) && sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS )
5331 {
5332 k = sprite[j].sectnum;
5333 updatesector(sprite[j].x,sprite[j].y,&k);
5334 if( sprite[j].extra >= 0 && k == s->sectnum )
5335 {
5336 gutsdir(&sprite[j],JIBS6,72,myconnectindex);
5337 spritesound(SQUISHED,i);
5338 deletesprite(j);
5339 }
5340 }
5341 j = l;
5342 }
5343 }
5344 }
5345
5346 break;
5347
5348 case 30:
5349 if(s->owner == -1)
5350 {
5351 t[3] = !t[3];
5352 s->owner = LocateTheLocator(t[3],t[0]);
5353 }
5354 else
5355 {
5356
5357 if(t[4] == 1) // Starting to go
5358 {
5359 if( ldist( &sprite[s->owner],s ) < (2048-128) )
5360 t[4] = 2;
5361 else
5362 {
5363 if(s->xvel == 0)
5364 operateactivators(s->hitag+(!t[3]),-1);
5365 if(s->xvel < 256)
5366 s->xvel += 16;
5367 }
5368 }
5369 if(t[4] == 2)
5370 {
5371 l = FindDistance2D(sprite[s->owner].x-s->x,sprite[s->owner].y-s->y);
5372
5373 if(l <= 128)
5374 s->xvel = 0;
5375
5376 if( s->xvel > 0 )
5377 s->xvel -= 16;
5378 else
5379 {
5380 s->xvel = 0;
5381 operateactivators(s->hitag+(short)t[3],-1);
5382 s->owner = -1;
5383 s->ang += 1024;
5384 t[4] = 0;
5385 operateforcefields(i,s->hitag);
5386
5387 j = headspritesect[s->sectnum];
5388 while(j >= 0)
5389 {
5390 if(sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS )
5391 {
5392 hittype[j].bposx = sprite[j].x;
5393 hittype[j].bposy = sprite[j].y;
5394 }
5395 j = nextspritesect[j];
5396 }
5397
5398 }
5399 }
5400 }
5401
5402 if(s->xvel)
5403 {
5404 l = (s->xvel*sintable[(s->ang+512)&2047])>>14;
5405 x = (s->xvel*sintable[s->ang&2047])>>14;
5406
5407 if( (sc->floorz-sc->ceilingz) < (108<<8) )
5408 if(ud.clipping == 0)
5409 for(p=connecthead;p>=0;p=connectpoint2[p])
5410 if(sprite[ps[p].i].extra > 0)
5411 {
5412 k = ps[p].cursectnum;
5413 updatesector(ps[p].posx,ps[p].posy,&k);
5414 if( ( k == -1 && ud.clipping == 0 ) || ( k == s->sectnum && ps[p].cursectnum != s->sectnum ) )
5415 {
5416 ps[p].posx = s->x;
5417 ps[p].posy = s->y;
5418 ps[p].cursectnum = s->sectnum;
5419
5420 setsprite(ps[p].i,s->x,s->y,s->z);
5421 quickkill(&ps[p]);
5422 }
5423 }
5424
5425 for(p = connecthead;p >= 0;p = connectpoint2[p])
5426 {
5427 if( sprite[ps[p].i].sectnum == s->sectnum )
5428 {
5429 ps[p].posx += l;
5430 ps[p].posy += x;
5431
5432 if(numplayers > 1)
5433 {
5434 ps[p].oposx = ps[p].posx;
5435 ps[p].oposy = ps[p].posy;
5436 }
5437
5438 ps[p].bobposx += l;
5439 ps[p].bobposy += x;
5440 }
5441
5442 if( po[p].os == s->sectnum )
5443 {
5444 po[p].ox += l;
5445 po[p].oy += x;
5446 }
5447 }
5448
5449 j = headspritesect[s->sectnum];
5450 while(j >= 0)
5451 {
5452 if(sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS )
5453 {
5454 if(numplayers < 2)
5455 {
5456 hittype[j].bposx = sprite[j].x;
5457 hittype[j].bposy = sprite[j].y;
5458 }
5459
5460 sprite[j].x += l;
5461 sprite[j].y += x;
5462
5463 if(numplayers > 1)
5464 {
5465 hittype[j].bposx = sprite[j].x;
5466 hittype[j].bposy = sprite[j].y;
5467 }
5468 }
5469 j = nextspritesect[j];
5470 }
5471
5472 ms(i);
5473 setsprite(i,s->x,s->y,s->z);
5474
5475 if( (sc->floorz-sc->ceilingz) < (108<<8) )
5476 {
5477 if(ud.clipping == 0)
5478 for(p=connecthead;p>=0;p=connectpoint2[p])
5479 if(sprite[ps[p].i].extra > 0)
5480 {
5481 k = ps[p].cursectnum;
5482 updatesector(ps[p].posx,ps[p].posy,&k);
5483 if( ( k == -1 && ud.clipping == 0 ) || ( k == s->sectnum && ps[p].cursectnum != s->sectnum ) )
5484 {
5485 ps[p].posx = s->x;
5486 ps[p].posy = s->y;
5487
5488 ps[p].oposx = ps[p].posx;
5489 ps[p].oposy = ps[p].posy;
5490
5491 ps[p].cursectnum = s->sectnum;
5492
5493 setsprite(ps[p].i,s->x,s->y,s->z);
5494 quickkill(&ps[p]);
5495 }
5496 }
5497
5498 j = headspritesect[sprite[OW].sectnum];
5499 while(j >= 0)
5500 {
5501 l = nextspritesect[j];
5502 if (sprite[j].statnum == 1 && badguy(&sprite[j]) && sprite[j].picnum != SECTOREFFECTOR && sprite[j].picnum != LOCATORS )
5503 {
5504 // if(sprite[j].sectnum != s->sectnum)
5505 {
5506 k = sprite[j].sectnum;
5507 updatesector(sprite[j].x,sprite[j].y,&k);
5508 if( sprite[j].extra >= 0 && k == s->sectnum )
5509 {
5510 gutsdir(&sprite[j],JIBS6,24,myconnectindex);
5511 spritesound(SQUISHED,j);
5512 deletesprite(j);
5513 }
5514 }
5515
5516 }
5517 j = l;
5518 }
5519 }
5520 }
5521
5522 break;
5523
5524
5525 case 2://Quakes
5526 if(t[4] > 0 && t[0] == 0 )
5527 {
5528 if( t[4] < sh )
5529 t[4]++;
5530 else t[0] = 1;
5531 }
5532
5533 if(t[0] > 0)
5534 {
5535 t[0]++;
5536
5537 s->xvel = 3;
5538
5539 if(t[0] > 96)
5540 {
5541 t[0] = -1; //Stop the quake
5542 t[4] = -1;
5543 KILLIT(i);
5544 }
5545 else
5546 {
5547 if( (t[0]&31) == 8 )
5548 {
5549 earthquaketime = 48;
5550 spritesound(EARTHQUAKE,ps[screenpeek].i);
5551 }
5552
5553 if( klabs( sc->floorheinum-t[5] ) < 8 )
5554 sc->floorheinum = t[5];
5555 else sc->floorheinum += ( sgn(t[5]-sc->floorheinum)<<4 );
5556 }
5557
5558 m = (s->xvel*sintable[(s->ang+512)&2047])>>14;
5559 x = (s->xvel*sintable[s->ang&2047])>>14;
5560
5561
5562 for(p=connecthead;p>=0;p=connectpoint2[p])
5563 if(ps[p].cursectnum == s->sectnum && ps[p].on_ground)
5564 {
5565 ps[p].posx += m;
5566 ps[p].posy += x;
5567
5568 ps[p].bobposx += m;
5569 ps[p].bobposy += x;
5570 }
5571
5572 j = headspritesect[s->sectnum];
5573 while(j >= 0)
5574 {
5575 nextj = nextspritesect[j];
5576
5577 if (sprite[j].picnum != SECTOREFFECTOR)
5578 {
5579 sprite[j].x+=m;
5580 sprite[j].y+=x;
5581 setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z);
5582 }
5583 j = nextj;
5584 }
5585 ms(i);
5586 setsprite(i,s->x,s->y,s->z);
5587 }
5588 break;
5589
5590 //Flashing sector lights after reactor EXPLOSION2
5591
5592 case 3:
5593
5594 if( t[4] == 0 ) break;
5595 p = findplayer(s,&x);
5596
5597 // if(t[5] > 0) { t[5]--; break; }
5598
5599 if( (global_random/(sh+1)&31) < 4 && !t[2])
5600 {
5601 // t[5] = 4+(global_random&7);
5602 sc->ceilingpal = s->owner>>8;
5603 sc->floorpal = s->owner&0xff;
5604 t[0] = s->shade + (global_random&15);
5605 }
5606 else
5607 {
5608 // t[5] = 4+(global_random&3);
5609 sc->ceilingpal = s->pal;
5610 sc->floorpal = s->pal;
5611 t[0] = t[3];
5612 }
5613
5614 sc->ceilingshade = t[0];
5615 sc->floorshade = t[0];
5616
5617 wal = &wall[sc->wallptr];
5618
5619 for(x=sc->wallnum;x > 0;x--,wal++)
5620 {
5621 if( wal->hitag != 1 )
5622 {
5623 wal->shade = t[0];
5624 if((wal->cstat&2) && wal->nextwall >= 0)
5625 {
5626 wall[wal->nextwall].shade = wal->shade;
5627 }
5628 }
5629 }
5630
5631 break;
5632
5633 case 4:
5634
5635 if((global_random/(sh+1)&31) < 4 )
5636 {
5637 t[1] = s->shade + (global_random&15);//Got really bright
5638 t[0] = s->shade + (global_random&15);
5639 sc->ceilingpal = s->owner>>8;
5640 sc->floorpal = s->owner&0xff;
5641 j = 1;
5642 }
5643 else
5644 {
5645 t[1] = t[2];
5646 t[0] = t[3];
5647
5648 sc->ceilingpal = s->pal;
5649 sc->floorpal = s->pal;
5650
5651 j = 0;
5652 }
5653
5654 sc->floorshade = t[1];
5655 sc->ceilingshade = t[1];
5656
5657 wal = &wall[sc->wallptr];
5658
5659 for(x=sc->wallnum;x > 0; x--,wal++)
5660 {
5661 if(j) wal->pal = (s->owner&0xff);
5662 else wal->pal = s->pal;
5663
5664 if( wal->hitag != 1 )
5665 {
5666 wal->shade = t[0];
5667 if((wal->cstat&2) && wal->nextwall >= 0)
5668 wall[wal->nextwall].shade = wal->shade;
5669 }
5670 }
5671
5672 j = headspritesect[SECT];
5673 while(j >= 0)
5674 {
5675 if(sprite[j].cstat&16)
5676 {
5677 if (sc->ceilingstat&1)
5678 sprite[j].shade = sc->ceilingshade;
5679 else sprite[j].shade = sc->floorshade;
5680 }
5681
5682 j = nextspritesect[j];
5683 }
5684
5685 if(t[4]) KILLIT(i);
5686
5687 break;
5688
5689 //BOSS
5690 case 5:
5691 p = findplayer(s,&x);
5692 if(x < 8192)
5693 {
5694 j = s->ang;
5695 s->ang = getangle(s->x-ps[p].posx,s->y-ps[p].posy);
5696 shoot(i,FIRELASER);
5697 s->ang = j;
5698 }
5699
5700 if(s->owner==-1) //Start search
5701 {
5702 t[4]=0;
5703 l = 0x7fffffff;
5704 while(1) //Find the shortest dist
5705 {
5706 s->owner = LocateTheLocator((short)t[4],-1); //t[0] hold sectnum
5707
5708 if(s->owner==-1) break;
5709
5710 m = ldist(&sprite[ps[p].i],&sprite[s->owner]);
5711
5712 if(l > m)
5713 {
5714 q = s->owner;
5715 l = m;
5716 }
5717
5718 t[4]++;
5719 }
5720
5721 s->owner = q;
5722 s->zvel = ksgn(sprite[q].z-s->z)<<4;
5723 }
5724
5725 if(ldist(&sprite[s->owner],s) < 1024)
5726 {
5727 short ta;
5728 ta = s->ang;
5729 s->ang = getangle(ps[p].posx-s->x,ps[p].posy-s->y);
5730 s->ang = ta;
5731 s->owner = -1;
5732 goto BOLT;
5733
5734 }
5735 else s->xvel=256;
5736
5737 x = getangle(sprite[s->owner].x-s->x,sprite[s->owner].y-s->y);
5738 q = getincangle(s->ang,x)>>3;
5739 s->ang += q;
5740
5741 if(rnd(32))
5742 {
5743 t[2]+=q;
5744 sc->ceilingshade = 127;
5745 }
5746 else
5747 {
5748 t[2] +=
5749 getincangle(t[2]+512,getangle(ps[p].posx-s->x,ps[p].posy-s->y))>>2;
5750 sc->ceilingshade = 0;
5751 }
5752 IFHIT
5753 {
5754 t[3]++;
5755 if(t[3] == 5)
5756 {
5757 s->zvel += 1024;
5758 FTA(7,&ps[myconnectindex],0);
5759 }
5760 }
5761
5762 s->z += s->zvel;
5763 sc->ceilingz += s->zvel;
5764 sector[t[0]].ceilingz += s->zvel;
5765 ms(i);
5766 setsprite(i,s->x,s->y,s->z);
5767 break;
5768
5769
5770 case 8:
5771 case 9:
5772
5773 // work only if its moving
5774
5775 j = -1;
5776
5777 if(hittype[i].temp_data[4])
5778 {
5779 hittype[i].temp_data[4]++;
5780 if( hittype[i].temp_data[4] > 8 ) KILLIT(i);
5781 j = 1;
5782 }
5783 else j = getanimationgoal(&sc->ceilingz);
5784
5785 if( j >= 0 )
5786 {
5787 short sn;
5788
5789 if( (sc->lotag&0x8000) || hittype[i].temp_data[4] )
5790 x = -t[3];
5791 else
5792 x = t[3];
5793
5794 if ( st == 9 ) x = -x;
5795
5796 j = headspritestat[3];
5797 while(j >= 0)
5798 {
5799 if( ((sprite[j].lotag) == st ) && (sprite[j].hitag) == sh )
5800 {
5801 sn = sprite[j].sectnum;
5802 m = sprite[j].shade;
5803
5804 wal = &wall[sector[sn].wallptr];
5805
5806 for(l=sector[sn].wallnum;l>0;l--,wal++)
5807 {
5808 if( wal->hitag != 1 )
5809 {
5810 wal->shade+=x;
5811
5812 if(wal->shade < m)
5813 wal->shade = m;
5814 else if(wal->shade > hittype[j].temp_data[2])
5815 wal->shade = hittype[j].temp_data[2];
5816
5817 if(wal->nextwall >= 0)
5818 if(wall[wal->nextwall].hitag != 1)
5819 wall[wal->nextwall].shade = wal->shade;
5820 }
5821 }
5822
5823 sector[sn].floorshade += x;
5824 sector[sn].ceilingshade += x;
5825
5826 if(sector[sn].floorshade < m)
5827 sector[sn].floorshade = m;
5828 else if(sector[sn].floorshade > hittype[j].temp_data[0])
5829 sector[sn].floorshade = hittype[j].temp_data[0];
5830
5831 if(sector[sn].ceilingshade < m)
5832 sector[sn].ceilingshade = m;
5833 else if(sector[sn].ceilingshade > hittype[j].temp_data[1])
5834 sector[sn].ceilingshade = hittype[j].temp_data[1];
5835
5836 }
5837 j = nextspritestat[j];
5838 }
5839 }
5840 break;
5841 case 10:
5842
5843 if( (sc->lotag&0xff) == 27 || ( sc->floorz > sc->ceilingz && (sc->lotag&0xff) != 23 ) || sc->lotag == (short) 32791 )
5844 {
5845 j = 1;
5846
5847 if( (sc->lotag&0xff) != 27)
5848 for(p=connecthead;p>=0;p=connectpoint2[p])
5849 if( sc->lotag != 30 && sc->lotag != 31 && sc->lotag != 0 )
5850 if(s->sectnum == sprite[ps[p].i].sectnum)
5851 j = 0;
5852
5853 if(j == 1)
5854 {
5855 if(t[0] > sh )
5856 switch(sector[s->sectnum].lotag)
5857 {
5858 case 20:
5859 case 21:
5860 case 22:
5861 case 26:
5862 if( getanimationgoal(&sector[s->sectnum].ceilingz) >= 0 )
5863 break;
5864 default:
5865 activatebysector(s->sectnum,i);
5866 t[0] = 0;
5867 break;
5868 }
5869 else t[0]++;
5870 }
5871 }
5872 else t[0]=0;
5873 break;
5874 case 11: //Swingdoor
5875
5876 if( t[5] > 0)
5877 {
5878 t[5]--;
5879 break;
5880 }
5881
5882 if( t[4] )
5883 {
5884 short startwall,endwall;
5885
5886 startwall = sc->wallptr;
5887 endwall = startwall+sc->wallnum;
5888
5889 for(j=startwall;j<endwall;j++)
5890 {
5891 k = headspritestat[1];
5892 while(k >= 0)
5893 {
5894 if( sprite[k].extra > 0 && badguy(&sprite[k]) && clipinsidebox(sprite[k].x,sprite[k].y,j,256L) == 1 )
5895 goto BOLT;
5896 k = nextspritestat[k];
5897 }
5898
5899 k = headspritestat[10];
5900 while(k >= 0)
5901 {
5902 if( sprite[k].owner >= 0 && clipinsidebox(sprite[k].x,sprite[k].y,j,144L) == 1 )
5903 {
5904 t[5] = 8; // Delay
5905 k = (SP>>3)*t[3];
5906 t[2]-=k;
5907 t[4]-=k;
5908 ms(i);
5909 setsprite(i,s->x,s->y,s->z);
5910 goto BOLT;
5911 }
5912 k = nextspritestat[k];
5913 }
5914 }
5915
5916 k = (SP>>3)*t[3];
5917 t[2]+=k;
5918 t[4]+=k;
5919 ms(i);
5920 setsprite(i,s->x,s->y,s->z);
5921
5922 if(t[4] <= -511 || t[4] >= 512)
5923 {
5924 t[4] = 0;
5925 t[2] &= 0xffffff00;
5926 ms(i);
5927 setsprite(i,s->x,s->y,s->z);
5928 break;
5929 }
5930 }
5931 break;
5932 case 12:
5933 if( t[0] == 3 || t[3] == 1 ) //Lights going off
5934 {
5935 sc->floorpal = 0;
5936 sc->ceilingpal = 0;
5937
5938 wal = &wall[sc->wallptr];
5939 for(j = sc->wallnum;j > 0; j--, wal++)
5940 if(wal->hitag != 1)
5941 {
5942 wal->shade = t[1];
5943 wal->pal = 0;
5944 }
5945
5946 sc->floorshade = t[1];
5947 sc->ceilingshade = t[2];
5948 t[0]=0;
5949
5950 j = headspritesect[SECT];
5951 while(j >= 0)
5952 {
5953 if(sprite[j].cstat&16)
5954 {
5955 if (sc->ceilingstat&1)
5956 sprite[j].shade = sc->ceilingshade;
5957 else sprite[j].shade = sc->floorshade;
5958 }
5959 j = nextspritesect[j];
5960
5961 }
5962
5963 if(t[3] == 1) KILLIT(i);
5964 }
5965 if( t[0] == 1 ) //Lights flickering on
5966 {
5967 if( sc->floorshade > s->shade )
5968 {
5969 sc->floorpal = s->pal;
5970 sc->ceilingpal = s->pal;
5971
5972 sc->floorshade -= 2;
5973 sc->ceilingshade -= 2;
5974
5975 wal = &wall[sc->wallptr];
5976 for(j=sc->wallnum;j>0;j--,wal++)
5977 if(wal->hitag != 1)
5978 {
5979 wal->pal = s->pal;
5980 wal->shade -= 2;
5981 }
5982 }
5983 else t[0] = 2;
5984
5985 j = headspritesect[SECT];
5986 while(j >= 0)
5987 {
5988 if(sprite[j].cstat&16)
5989 {
5990 if (sc->ceilingstat&1)
5991 sprite[j].shade = sc->ceilingshade;
5992 else sprite[j].shade = sc->floorshade;
5993 }
5994 j = nextspritesect[j];
5995 }
5996 }
5997 break;
5998
5999
6000 case 13:
6001 if( t[2] )
6002 {
6003 j = (SP<<5)|1;
6004
6005 if( s->ang == 512 )
6006 {
6007 if( s->owner )
6008 {
6009 if( klabs(t[0]-sc->ceilingz) >= j )
6010 sc->ceilingz += sgn(t[0]-sc->ceilingz)*j;
6011 else sc->ceilingz = t[0];
6012 }
6013 else
6014 {
6015 if( klabs(t[1]-sc->floorz) >= j )
6016 sc->floorz += sgn(t[1]-sc->floorz)*j;
6017 else sc->floorz = t[1];
6018 }
6019 }
6020 else
6021 {
6022 if( klabs(t[1]-sc->floorz) >= j )
6023 sc->floorz += sgn(t[1]-sc->floorz)*j;
6024 else sc->floorz = t[1];
6025 if( klabs(t[0]-sc->ceilingz) >= j )
6026 sc->ceilingz += sgn(t[0]-sc->ceilingz)*j;
6027 sc->ceilingz = t[0];
6028 }
6029
6030 if( t[3] == 1 )
6031 {
6032 //Change the shades
6033
6034 t[3]++;
6035 sc->ceilingstat ^= 1;
6036
6037 if(s->ang == 512)
6038 {
6039 wal = &wall[sc->wallptr];
6040 for(j=sc->wallnum;j>0;j--,wal++)
6041 wal->shade = s->shade;
6042
6043 sc->floorshade = s->shade;
6044
6045 if(ps[0].one_parallax_sectnum >= 0)
6046 {
6047 sc->ceilingpicnum =
6048 sector[ps[0].one_parallax_sectnum].ceilingpicnum;
6049 sc->ceilingshade =
6050 sector[ps[0].one_parallax_sectnum].ceilingshade;
6051 }
6052 }
6053 }
6054 t[2]++;
6055 if(t[2] > 256)
6056 KILLIT(i);
6057 }
6058
6059
6060 if( t[2] == 4 && s->ang != 512)
6061 for(x=0;x<7;x++) RANDOMSCRAP;
6062 break;
6063
6064
6065 case 15:
6066
6067 if(t[4])
6068 {
6069 s->xvel = 16;
6070
6071 if(t[4] == 1) //Opening
6072 {
6073 if( t[3] >= (SP>>3) )
6074 {
6075 t[4] = 0; //Turn off the sliders
6076 callsound(s->sectnum,i);
6077 break;
6078 }
6079 t[3]++;
6080 }
6081 else if(t[4] == 2)
6082 {
6083 if(t[3]<1)
6084 {
6085 t[4] = 0;
6086 callsound(s->sectnum,i);
6087 break;
6088 }
6089 t[3]--;
6090 }
6091
6092 ms(i);
6093 setsprite(i,s->x,s->y,s->z);
6094 }
6095 break;
6096
6097 case 16: //Reactor
6098
6099 t[2]+=32;
6100 if(sc->floorz<sc->ceilingz) s->shade=0;
6101
6102 else if( sc->ceilingz < t[3] )
6103 {
6104
6105 //The following code check to see if
6106 //there is any other sprites in the sector.
6107 //If there isn't, then kill this sectoreffector
6108 //itself.....
6109
6110 j = headspritesect[s->sectnum];
6111 while(j >= 0)
6112 {
6113 if(sprite[j].picnum == REACTOR || sprite[j].picnum == REACTOR2)
6114 break;
6115 j = nextspritesect[j];
6116 }
6117 if(j == -1) { KILLIT(i); }
6118 else s->shade=1;
6119 }
6120
6121 if(s->shade) sc->ceilingz+=1024;
6122 else sc->ceilingz-=512;
6123
6124 ms(i);
6125 setsprite(i,s->x,s->y,s->z);
6126
6127 break;
6128
6129 case 17:
6130
6131 q = t[0]*(SP<<2);
6132
6133 sc->ceilingz += q;
6134 sc->floorz += q;
6135
6136 j = headspritesect[s->sectnum];
6137 while(j >= 0)
6138 {
6139 if(sprite[j].statnum == 10 && sprite[j].owner >= 0)
6140 {
6141 p = sprite[j].yvel;
6142 if(numplayers < 2)
6143 ps[p].oposz = ps[p].posz;
6144 ps[p].posz += q;
6145 ps[p].truefz += q;
6146 ps[p].truecz += q;
6147 if(numplayers > 1)
6148 ps[p].oposz = ps[p].posz;
6149 }
6150 if( sprite[j].statnum != 3 )
6151 {
6152 hittype[j].bposz = sprite[j].z;
6153 sprite[j].z += q;
6154 }
6155
6156 hittype[j].floorz = sc->floorz;
6157 hittype[j].ceilingz = sc->ceilingz;
6158
6159 j = nextspritesect[j];
6160 }
6161
6162 if( t[0] ) if(t[0]) //If in motion
6163 {
6164 if( klabs(sc->floorz-t[2]) <= SP)
6165 {
6166 activatewarpelevators(i,0);
6167 break;
6168 }
6169
6170 if(t[0]==-1)
6171 {
6172 if( sc->floorz > t[3] )
6173 break;
6174 }
6175 else if( sc->ceilingz < t[4] ) break;
6176
6177 if( t[1] == 0 ) break;
6178 t[1] = 0;
6179
6180 j = headspritestat[3];
6181 while(j >= 0)
6182 {
6183 if( i != j && (sprite[j].lotag) == 17)
6184 if( (sc->hitag-t[0]) ==
6185 (sector[sprite[j].sectnum].hitag)
6186 && sh == (sprite[j].hitag))
6187 break;
6188 j = nextspritestat[j];
6189 }
6190
6191 if(j == -1) break;
6192
6193 k = headspritesect[s->sectnum];
6194 while(k >= 0)
6195 {
6196 nextk = nextspritesect[k];
6197
6198 if(sprite[k].statnum == 10 && sprite[k].owner >= 0)
6199 {
6200 p = sprite[k].yvel;
6201
6202 ps[p].posx += sprite[j].x-s->x;
6203 ps[p].posy += sprite[j].y-s->y;
6204 ps[p].posz = sector[sprite[j].sectnum].floorz-(sc->floorz-ps[p].posz);
6205
6206 hittype[k].floorz = sector[sprite[j].sectnum].floorz;
6207 hittype[k].ceilingz = sector[sprite[j].sectnum].ceilingz;
6208
6209 ps[p].bobposx = ps[p].oposx = ps[p].posx;
6210 ps[p].bobposy = ps[p].oposy = ps[p].posy;
6211 ps[p].oposz = ps[p].posz;
6212
6213 ps[p].truefz = hittype[k].floorz;
6214 ps[p].truecz = hittype[k].ceilingz;
6215 ps[p].bobcounter = 0;
6216
6217 changespritesect(k,sprite[j].sectnum);
6218 ps[p].cursectnum = sprite[j].sectnum;
6219 }
6220 else if( sprite[k].statnum != 3 )
6221 {
6222 sprite[k].x +=
6223 sprite[j].x-s->x;
6224 sprite[k].y +=
6225 sprite[j].y-s->y;
6226 sprite[k].z = sector[sprite[j].sectnum].floorz-
6227 (sc->floorz-sprite[k].z);
6228
6229 hittype[k].bposx = sprite[k].x;
6230 hittype[k].bposy = sprite[k].y;
6231 hittype[k].bposz = sprite[k].z;
6232
6233 changespritesect(k,sprite[j].sectnum);
6234 setsprite(k,sprite[k].x,sprite[k].y,sprite[k].z);
6235
6236 hittype[k].floorz = sector[sprite[j].sectnum].floorz;
6237 hittype[k].ceilingz = sector[sprite[j].sectnum].ceilingz;
6238
6239 }
6240 k = nextk;
6241 }
6242 }
6243 break;
6244
6245 case 18:
6246 if(t[0])
6247 {
6248 if(s->pal)
6249 {
6250 if(s->ang == 512)
6251 {
6252 sc->ceilingz -= sc->extra;
6253 if(sc->ceilingz <= t[1])
6254 {
6255 sc->ceilingz = t[1];
6256 KILLIT(i);
6257 }
6258 }
6259 else
6260 {
6261 sc->floorz += sc->extra;
6262 j = headspritesect[s->sectnum];
6263 while(j >= 0)
6264 {
6265 if(sprite[j].picnum == APLAYER && sprite[j].owner >= 0)
6266 if( ps[sprite[j].yvel].on_ground == 1 )
6267 ps[sprite[j].yvel].posz += sc->extra;
6268 if( sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4)
6269 {
6270 hittype[j].bposz = sprite[j].z += sc->extra;
6271 hittype[j].floorz = sc->floorz;
6272 }
6273 j = nextspritesect[j];
6274 }
6275 if(sc->floorz >= t[1])
6276 {
6277 sc->floorz = t[1];
6278 KILLIT(i);
6279 }
6280 }
6281 }
6282 else
6283 {
6284 if(s->ang == 512)
6285 {
6286 sc->ceilingz += sc->extra;
6287 if(sc->ceilingz >= s->z)
6288 {
6289 sc->ceilingz = s->z;
6290 KILLIT(i);
6291 }
6292 }
6293 else
6294 {
6295 sc->floorz -= sc->extra;
6296 j = headspritesect[s->sectnum];
6297 while(j >= 0)
6298 {
6299 if(sprite[j].picnum == APLAYER && sprite[j].owner >= 0)
6300 if( ps[sprite[j].yvel].on_ground == 1 )
6301 ps[sprite[j].yvel].posz -= sc->extra;
6302 if( sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4)
6303 {
6304 hittype[j].bposz = sprite[j].z -= sc->extra;
6305 hittype[j].floorz = sc->floorz;
6306 }
6307 j = nextspritesect[j];
6308 }
6309 if(sc->floorz <= s->z)
6310 {
6311 sc->floorz = s->z;
6312 KILLIT(i);
6313 }
6314 }
6315 }
6316
6317 t[2]++;
6318 if(t[2] >= s->hitag)
6319 {
6320 t[2] = 0;
6321 t[0] = 0;
6322 }
6323 }
6324 break;
6325
6326 case 19: //Battlestar galactia shields
6327
6328 if(t[0])
6329 {
6330 if(t[0] == 1)
6331 {
6332 t[0]++;
6333 x = sc->wallptr;
6334 q = x+sc->wallnum;
6335 for(j=x;j<q;j++)
6336 if(wall[j].overpicnum == BIGFORCE)
6337 {
6338 wall[j].cstat &= (128+32+8+4+2);
6339 wall[j].overpicnum = 0;
6340 if(wall[j].nextwall >= 0)
6341 {
6342 wall[wall[j].nextwall].overpicnum = 0;
6343 wall[wall[j].nextwall].cstat &= (128+32+8+4+2);
6344 }
6345 }
6346 }
6347
6348 if(sc->ceilingz < sc->floorz)
6349 sc->ceilingz += SP;
6350 else
6351 {
6352 sc->ceilingz = sc->floorz;
6353
6354 j = headspritestat[3];
6355 while(j >= 0)
6356 {
6357 if(sprite[j].lotag == 0 && sprite[j].hitag==sh)
6358 {
6359 q = sprite[sprite[j].owner].sectnum;
6360 sector[sprite[j].sectnum].floorpal = sector[sprite[j].sectnum].ceilingpal =
6361 sector[q].floorpal;
6362 sector[sprite[j].sectnum].floorshade = sector[sprite[j].sectnum].ceilingshade =
6363 sector[q].floorshade;
6364
6365 hittype[sprite[j].owner].temp_data[0] = 2;
6366 }
6367 j = nextspritestat[j];
6368 }
6369 KILLIT(i);
6370 }
6371 }
6372 else //Not hit yet
6373 {
6374 IFHITSECT
6375 {
6376 FTA(8,&ps[myconnectindex],0);
6377
6378 l = headspritestat[3];
6379 while(l >= 0)
6380 {
6381 x = sprite[l].lotag&0x7fff;
6382 switch( x )
6383 {
6384 case 0:
6385 if(sprite[l].hitag == sh)
6386 {
6387 q = sprite[l].sectnum;
6388 sector[q].floorshade =
6389 sector[q].ceilingshade =
6390 sprite[sprite[l].owner].shade;
6391 sector[q].floorpal =
6392 sector[q].ceilingpal =
6393 sprite[sprite[l].owner].pal;
6394 }
6395 break;
6396
6397 case 1:
6398 case 12:
6399// case 18:
6400 case 19:
6401
6402 if( sh == sprite[l].hitag )
6403 if( hittype[l].temp_data[0] == 0 )
6404 {
6405 hittype[l].temp_data[0] = 1; //Shut them all on
6406 sprite[l].owner = i;
6407 }
6408
6409 break;
6410 }
6411 l = nextspritestat[l];
6412 }
6413 }
6414 }
6415
6416 break;
6417
6418 case 20: //Extend-o-bridge
6419
6420 if( t[0] == 0 ) break;
6421 if( t[0] == 1 ) s->xvel = 8;
6422 else s->xvel = -8;
6423
6424 if( s->xvel ) //Moving
6425 {
6426 x = (s->xvel*sintable[(s->ang+512)&2047])>>14;
6427 l = (s->xvel*sintable[s->ang&2047])>>14;
6428
6429 t[3] += s->xvel;
6430
6431 s->x += x;
6432 s->y += l;
6433
6434 if( t[3] <= 0 || (t[3]>>6) >= (SP>>6) )
6435 {
6436 s->x -= x;
6437 s->y -= l;
6438 t[0] = 0;
6439 callsound(s->sectnum,i);
6440 break;
6441 }
6442
6443 j = headspritesect[s->sectnum];
6444 while(j >= 0)
6445 {
6446 nextj = nextspritesect[j];
6447
6448 if( sprite[j].statnum != 3 && sprite[j].zvel == 0)
6449 {
6450 sprite[j].x += x;
6451 sprite[j].y += l;
6452 setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z);
6453 if( sector[sprite[j].sectnum].floorstat&2 )
6454 if(sprite[j].statnum == 2)
6455 makeitfall(j);
6456 }
6457 j = nextj;
6458 }
6459
6460 dragpoint((short)t[1],wall[t[1]].x+x,wall[t[1]].y+l);
6461 dragpoint((short)t[2],wall[t[2]].x+x,wall[t[2]].y+l);
6462
6463 for(p=connecthead;p>=0;p=connectpoint2[p])
6464 if(ps[p].cursectnum == s->sectnum && ps[p].on_ground)
6465 {
6466 ps[p].posx += x;
6467 ps[p].posy += l;
6468
6469 ps[p].oposx = ps[p].posx;
6470 ps[p].oposy = ps[p].posy;
6471
6472 setsprite(ps[p].i,ps[p].posx,ps[p].posy,ps[p].posz+PHEIGHT);
6473 }
6474
6475 sc->floorxpanning-=x>>3;
6476 sc->floorypanning-=l>>3;
6477
6478 sc->ceilingxpanning-=x>>3;
6479 sc->ceilingypanning-=l>>3;
6480 }
6481
6482 break;
6483
6484 case 21: // Cascading effect
6485
6486 if( t[0] == 0 ) break;
6487
6488 if( s->ang == 1536 )
6489 l = (int32_t) &sc->ceilingz;
6490 else
6491 l = (int32_t) &sc->floorz;
6492
6493 if( t[0] == 1 ) //Decide if the s->sectnum should go up or down
6494 {
6495 s->zvel = ksgn(s->z-*(int32_t *)l) * (SP<<4);
6496 t[0]++;
6497 }
6498
6499 if( sc->extra == 0 )
6500 {
6501 *(int32_t *)l += s->zvel;
6502
6503 if(klabs(*(int32_t *)l-s->z) < 1024)
6504 {
6505 *(int32_t *)l = s->z;
6506 KILLIT(i); //All done
6507 }
6508 }
6509 else sc->extra--;
6510 break;
6511
6512 case 22:
6513
6514 if( t[1] )
6515 {
6516 if(getanimationgoal(&sector[t[0]].ceilingz) >= 0)
6517 sc->ceilingz += sc->extra*9;
6518 else t[1] = 0;
6519 }
6520 break;
6521
6522 case 24:
6523 case 34:
6524
6525 if(t[4]) break;
6526
6527 x = (SP*sintable[(s->ang+512)&2047])>>18;
6528 l = (SP*sintable[s->ang&2047])>>18;
6529
6530 k = 0;
6531
6532 j = headspritesect[s->sectnum];
6533 while(j >= 0)
6534 {
6535 nextj = nextspritesect[j];
6536 if(sprite[j].zvel >= 0)
6537 switch(sprite[j].statnum)
6538 {
6539 case 5:
6540 switch(sprite[j].picnum)
6541 {
6542 case BLOODPOOL:
6543 case PUKE:
6544 case FOOTPRINTS:
6545 case FOOTPRINTS2:
6546 case FOOTPRINTS3:
6547 case FOOTPRINTS4:
6548 case BULLETHOLE:
6549 case BLOODSPLAT1:
6550 case BLOODSPLAT2:
6551 case BLOODSPLAT3:
6552 case BLOODSPLAT4:
6553 sprite[j].xrepeat = sprite[j].yrepeat = 0;
6554 j = nextj;
6555 continue;
6556 case LASERLINE:
6557 j = nextj;
6558 continue;
6559 }
6560 case 6:
6561 if(sprite[j].picnum == TRIPBOMB) break;
6562 case 1:
6563 case 0:
6564 if(
6565 sprite[j].picnum == BOLT1 ||
6566 sprite[j].picnum == BOLT1+1 ||
6567 sprite[j].picnum == BOLT1+2 ||
6568 sprite[j].picnum == BOLT1+3 ||
6569 sprite[j].picnum == SIDEBOLT1 ||
6570 sprite[j].picnum == SIDEBOLT1+1 ||
6571 sprite[j].picnum == SIDEBOLT1+2 ||
6572 sprite[j].picnum == SIDEBOLT1+3 ||
6573 wallswitchcheck(j)
6574 )
6575 break;
6576
6577 if( !(sprite[j].picnum >= CRANE && sprite[j].picnum <= (CRANE+3)))
6578 {
6579 if( sprite[j].z > (hittype[j].floorz-(16<<8)) )
6580 {
6581 hittype[j].bposx = sprite[j].x;
6582 hittype[j].bposy = sprite[j].y;
6583
6584 sprite[j].x += x>>2;
6585 sprite[j].y += l>>2;
6586
6587 setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z);
6588
6589 if( sector[sprite[j].sectnum].floorstat&2 )
6590 if(sprite[j].statnum == 2)
6591 makeitfall(j);
6592 }
6593 }
6594 break;
6595 }
6596 j = nextj;
6597 }
6598
6599 p = myconnectindex;
6600 if(ps[p].cursectnum == s->sectnum && ps[p].on_ground)
6601 if( klabs(ps[p].posz-ps[p].truefz) < PHEIGHT+(9<<8) )
6602 {
6603 fricxv += x<<3;
6604 fricyv += l<<3;
6605 }
6606
6607 sc->floorxpanning += SP>>7;
6608
6609 break;
6610
6611 case 35:
6612 if(sc->ceilingz > s->z)
6613 for(j = 0;j < 8;j++)
6614 {
6615 s->ang += TRAND&511;
6616 k = spawn(i,SMALLSMOKE);
6617 sprite[k].xvel = 96+(TRAND&127);
6618 ssp(k,CLIPMASK0);
6619 setsprite(k,sprite[k].x,sprite[k].y,sprite[k].z);
6620 if( rnd(16) )
6621 spawn(i,EXPLOSION2);
6622 }
6623
6624 switch(t[0])
6625 {
6626 case 0:
6627 sc->ceilingz += s->yvel;
6628 if(sc->ceilingz > sc->floorz)
6629 sc->floorz = sc->ceilingz;
6630 if(sc->ceilingz > s->z+(32<<8))
6631 t[0]++;
6632 break;
6633 case 1:
6634 sc->ceilingz-=(s->yvel<<2);
6635 if(sc->ceilingz < t[4])
6636 {
6637 sc->ceilingz = t[4];
6638 t[0] = 0;
6639 }
6640 break;
6641 }
6642 break;
6643
6644 case 25: //PISTONS
6645
6646 if( t[4] == 0 ) break;
6647
6648 if(sc->floorz <= sc->ceilingz)
6649 s->shade = 0;
6650 else if( sc->ceilingz <= t[3])
6651 s->shade = 1;
6652
6653 if(s->shade)
6654 {
6655 sc->ceilingz += SP<<4;
6656 if(sc->ceilingz > sc->floorz)
6657 sc->ceilingz = sc->floorz;
6658 }
6659 else
6660 {
6661 sc->ceilingz -= SP<<4;
6662 if(sc->ceilingz < t[3])
6663 sc->ceilingz = t[3];
6664 }
6665
6666 break;
6667
6668 case 26:
6669
6670 s->xvel = 32;
6671 l = (s->xvel*sintable[(s->ang+512)&2047])>>14;
6672 x = (s->xvel*sintable[s->ang&2047])>>14;
6673
6674 s->shade++;
6675 if( s->shade > 7 )
6676 {
6677 s->x = t[3];
6678 s->y = t[4];
6679 sc->floorz -= ((s->zvel*s->shade)-s->zvel);
6680 s->shade = 0;
6681 }
6682 else
6683 sc->floorz += s->zvel;
6684
6685 j = headspritesect[s->sectnum];
6686 while( j >= 0 )
6687 {
6688 nextj = nextspritesect[j];
6689 if(sprite[j].statnum != 3 && sprite[j].statnum != 10)
6690 {
6691 hittype[j].bposx = sprite[j].x;
6692 hittype[j].bposy = sprite[j].y;
6693
6694 sprite[j].x += l;
6695 sprite[j].y += x;
6696
6697 sprite[j].z += s->zvel;
6698 setsprite(j,sprite[j].x,sprite[j].y,sprite[j].z);
6699 }
6700 j = nextj;
6701 }
6702
6703 p = myconnectindex;
6704 if(sprite[ps[p].i].sectnum == s->sectnum && ps[p].on_ground)
6705 {
6706 fricxv += l<<5;
6707 fricyv += x<<5;
6708 }
6709
6710 for(p = connecthead;p >= 0;p = connectpoint2[p])
6711 if(sprite[ps[p].i].sectnum == s->sectnum && ps[p].on_ground)
6712 ps[p].posz += s->zvel;
6713
6714 ms(i);
6715 setsprite(i,s->x,s->y,s->z);
6716
6717 break;
6718
6719
6720 case 27:
6721
6722 if(ud.recstat == 0) break;
6723
6724 hittype[i].tempang = s->ang;
6725
6726 p = findplayer(s,&x);
6727
6728 // FIX_00013: 3rd person camera view during demo playback can now be
6729 // turned off (no need to use hacked no-camera maps anymore)
6730 if( /*sprite[ps[p].i].extra > 0 && myconnectindex == screenpeek */ 0) // xduke remove camera view for the 1st player (notice myconnectindex is == 1 when replaying, dosent matter who recorded)
6731 {
6732 if( t[0] < 0 )
6733 {
6734 ud.camerasprite = i;
6735 t[0]++;
6736 }
6737 else if(ud.recstat == 2 && ps[p].newowner == -1)
6738 {
6739 if(cansee(s->x,s->y,s->z,SECT,ps[p].posx,ps[p].posy,ps[p].posz,ps[p].cursectnum))
6740 {
6741 if(x < (uint32_t)sh)
6742 {
6743 ud.camerasprite = i;
6744 t[0] = 999;
6745 s->ang += getincangle(s->ang,getangle(ps[p].posx-s->x,ps[p].posy-s->y))>>3;
6746 SP = 100+((s->z-ps[p].posz)/257);
6747
6748 }
6749 else if(t[0] == 999)
6750 {
6751 if(ud.camerasprite == i)
6752 t[0] = 0;
6753 else t[0] = -10;
6754 ud.camerasprite = i;
6755
6756 }
6757 }
6758 else
6759 {
6760 s->ang = getangle(ps[p].posx-s->x,ps[p].posy-s->y);
6761
6762 if(t[0] == 999)
6763 {
6764 if(ud.camerasprite == i)
6765 t[0] = 0;
6766 else t[0] = -20;
6767 ud.camerasprite = i;
6768 }
6769 }
6770 }
6771 }
6772 break;
6773 case 28:
6774 if(t[5] > 0)
6775 {
6776 t[5]--;
6777 break;
6778 }
6779
6780 if(T1 == 0)
6781 {
6782 p = findplayer(s,&x);
6783 if( x > 15500 )
6784 break;
6785 T1 = 1;
6786 T2 = 64 + (TRAND&511);
6787 T3 = 0;
6788 }
6789 else
6790 {
6791 T3++;
6792 if(T3 > T2)
6793 {
6794 T1 = 0;
6795 ps[screenpeek].visibility = ud.const_visibility;
6796 break;
6797 }
6798 else if( T3 == (T2>>1) )
6799 spritesound(THUNDER,i);
6800 else if(T3 == (T2>>3) )
6801 spritesound(LIGHTNING_SLAP,i);
6802 else if( T3 == (T2>>2) )
6803 {
6804 j = headspritestat[0];
6805 while(j >= 0)
6806 {
6807 if( sprite[j].picnum == NATURALLIGHTNING && sprite[j].hitag == s->hitag)
6808 sprite[j].cstat |= 32768;
6809 j = nextspritestat[j];
6810 }
6811 }
6812 else if(T3 > (T2>>3) && T3 < (T2>>2) )
6813 {
6814 if( cansee(s->x,s->y,s->z,s->sectnum,ps[screenpeek].posx,ps[screenpeek].posy,ps[screenpeek].posz,ps[screenpeek].cursectnum ) )
6815 j = 1;
6816 else j = 0;
6817
6818 if( rnd(192) && (T3&1) )
6819 {
6820 if(j)
6821 ps[screenpeek].visibility = 0;
6822 }
6823 else if(j)
6824 ps[screenpeek].visibility = ud.const_visibility;
6825
6826 j = headspritestat[0];
6827 while(j >= 0)
6828 {
6829 if( sprite[j].picnum == NATURALLIGHTNING && sprite[j].hitag == s->hitag)
6830 {
6831 if ( rnd(32) && (T3&1) )
6832 {
6833 sprite[j].cstat &= 32767;
6834 spawn(j,SMALLSMOKE);
6835
6836 p = findplayer(s,&x);
6837 x = ldist(&sprite[ps[p].i], &sprite[j]);
6838 if( x < 768 )
6839 {
6840 if(Sound[DUKE_LONGTERM_PAIN].num < 1)
6841 spritesound(DUKE_LONGTERM_PAIN,ps[p].i);
6842 spritesound(SHORT_CIRCUIT,ps[p].i);
6843 sprite[ps[p].i].extra -= 8+(TRAND&7);
6844 ps[p].pals_time = 32;
6845 ps[p].pals[0] = 16;
6846 ps[p].pals[1] = 0;
6847 ps[p].pals[2] = 0;
6848 }
6849 break;
6850 }
6851 else sprite[j].cstat |= 32768;
6852 }
6853
6854 j = nextspritestat[j];
6855 }
6856 }
6857 }
6858 break;
6859 case 29:
6860 s->hitag += 64;
6861 l = mulscale12((int32_t)s->yvel,sintable[s->hitag&2047]);
6862 sc->floorz = s->z + l;
6863 break;
6864 case 31: // True Drop Floor
6865 if(t[0] == 1)
6866 {
6867 // Choose dir
6868
6869 if(t[3] > 0)
6870 {
6871 t[3]--;
6872 break;
6873 }
6874
6875 if(t[2] == 1) // Retract
6876 {
6877 if(SA != 1536)
6878 {
6879 if( klabs( sc->floorz - s->z ) < SP )
6880 {
6881 sc->floorz = s->z;
6882 t[2] = 0;
6883 t[0] = 0;
6884 t[3] = s->hitag;
6885 callsound(s->sectnum,i);
6886 }
6887 else
6888 {
6889 l = sgn(s->z-sc->floorz)*SP;
6890 sc->floorz += l;
6891
6892 j = headspritesect[s->sectnum];
6893 while(j >= 0)
6894 {
6895 if(sprite[j].picnum == APLAYER && sprite[j].owner >= 0)
6896 if( ps[sprite[j].yvel].on_ground == 1 )
6897 ps[sprite[j].yvel].posz += l;
6898 if( sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4)
6899 {
6900 hittype[j].bposz = sprite[j].z += l;
6901 hittype[j].floorz = sc->floorz;
6902 }
6903 j = nextspritesect[j];
6904 }
6905 }
6906 }
6907 else
6908 {
6909 if( klabs( sc->floorz - t[1] ) < SP )
6910 {
6911 sc->floorz = t[1];
6912 callsound(s->sectnum,i);
6913 t[2] = 0;
6914 t[0] = 0;
6915 t[3] = s->hitag;
6916 }
6917 else
6918 {
6919 l = sgn(t[1]-sc->floorz)*SP;
6920 sc->floorz += l;
6921
6922 j = headspritesect[s->sectnum];
6923 while(j >= 0)
6924 {
6925 if(sprite[j].picnum == APLAYER && sprite[j].owner >= 0)
6926 if( ps[sprite[j].yvel].on_ground == 1 )
6927 ps[sprite[j].yvel].posz += l;
6928 if( sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4 )
6929 {
6930 hittype[j].bposz = sprite[j].z += l;
6931 hittype[j].floorz = sc->floorz;
6932 }
6933 j = nextspritesect[j];
6934 }
6935 }
6936 }
6937 break;
6938 }
6939
6940 if( (s->ang&2047) == 1536)
6941 {
6942 if( klabs( s->z-sc->floorz ) < SP )
6943 {
6944 callsound(s->sectnum,i);
6945 t[0] = 0;
6946 t[2] = 1;
6947 t[3] = s->hitag;
6948 }
6949 else
6950 {
6951 l = sgn(s->z-sc->floorz)*SP;
6952 sc->floorz += l;
6953
6954 j = headspritesect[s->sectnum];
6955 while(j >= 0)
6956 {
6957 if(sprite[j].picnum == APLAYER && sprite[j].owner >= 0)
6958 if( ps[sprite[j].yvel].on_ground == 1 )
6959 ps[sprite[j].yvel].posz += l;
6960 if( sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4 )
6961 {
6962 hittype[j].bposz = sprite[j].z += l;
6963 hittype[j].floorz = sc->floorz;
6964 }
6965 j = nextspritesect[j];
6966 }
6967 }
6968 }
6969 else
6970 {
6971 if( klabs( sc->floorz-t[1] ) < SP )
6972 {
6973 t[0] = 0;
6974 callsound(s->sectnum,i);
6975 t[2] = 1;
6976 t[3] = s->hitag;
6977 }
6978 else
6979 {
6980 l = sgn(s->z-t[1])*SP;
6981 sc->floorz -= l;
6982
6983 j = headspritesect[s->sectnum];
6984 while(j >= 0)
6985 {
6986 if(sprite[j].picnum == APLAYER && sprite[j].owner >= 0)
6987 if( ps[sprite[j].yvel].on_ground == 1 )
6988 ps[sprite[j].yvel].posz -= l;
6989 if(sprite[j].zvel == 0 && sprite[j].statnum != 3 && sprite[j].statnum != 4 )
6990 {
6991 hittype[j].bposz = sprite[j].z -= l;
6992 hittype[j].floorz = sc->floorz;
6993 }
6994 j = nextspritesect[j];
6995 }
6996 }
6997 }
6998 }
6999 break;
7000
7001 case 32: // True Drop Ceiling
7002 if(t[0] == 1)
7003 {
7004 // Choose dir
7005
7006 if(t[2] == 1) // Retract
7007 {
7008 if(SA != 1536)
7009 {
7010 if( klabs( sc->ceilingz - s->z ) <
7011 (SP<<1) )
7012 {
7013 sc->ceilingz = s->z;
7014 callsound(s->sectnum,i);
7015 t[2] = 0;
7016 t[0] = 0;
7017 }
7018 else sc->ceilingz +=
7019 sgn(s->z-sc->ceilingz)*SP;
7020 }
7021 else
7022 {
7023 if( klabs( sc->ceilingz - t[1] ) <
7024 (SP<<1) )
7025 {
7026 sc->ceilingz = t[1];
7027 callsound(s->sectnum,i);
7028 t[2] = 0;
7029 t[0] = 0;
7030 }
7031 else sc->ceilingz +=
7032 sgn(t[1]-sc->ceilingz)*SP;
7033 }
7034 break;
7035 }
7036
7037 if( (s->ang&2047) == 1536)
7038 {
7039 if( klabs(sc->ceilingz-s->z ) <
7040 (SP<<1) )
7041 {
7042 t[0] = 0;
7043 t[2] = !t[2];
7044 callsound(s->sectnum,i);
7045 sc->ceilingz = s->z;
7046 }
7047 else sc->ceilingz +=
7048 sgn(s->z-sc->ceilingz)*SP;
7049 }
7050 else
7051 {
7052 if( klabs(sc->ceilingz-t[1] ) < (SP<<1) )
7053 {
7054 t[0] = 0;
7055 t[2] = !t[2];
7056 callsound(s->sectnum,i);
7057 }
7058 else sc->ceilingz -= sgn(s->z-t[1])*SP;
7059 }
7060 }
7061 break;
7062
7063 case 33:
7064 if( earthquaketime > 0 && (TRAND&7) == 0 )
7065 RANDOMSCRAP;
7066 break;
7067 case 36:
7068
7069 if( t[0] )
7070 {
7071 if( t[0] == 1 )
7072 shoot(i,sc->extra);
7073 else if( t[0] == 26*5 )
7074 t[0] = 0;
7075 t[0]++;
7076 }
7077 break;
7078
7079 case 128: //SE to control glass breakage
7080
7081 wal = &wall[t[2]];
7082
7083 if(wal->cstat|32)
7084 {
7085 wal->cstat &= (255-32);
7086 wal->cstat |= 16;
7087 if(wal->nextwall >= 0)
7088 {
7089 wall[wal->nextwall].cstat &= (255-32);
7090 wall[wal->nextwall].cstat |= 16;
7091 }
7092 }
7093 else break;
7094
7095 wal->overpicnum++;
7096 if(wal->nextwall >= 0)
7097 wall[wal->nextwall].overpicnum++;
7098
7099 if(t[0] < t[1]) t[0]++;
7100 else
7101 {
7102 wal->cstat &= (128+32+8+4+2);
7103 if(wal->nextwall >= 0)
7104 wall[wal->nextwall].cstat &= (128+32+8+4+2);
7105 KILLIT(i);
7106 }
7107 break;
7108
7109 case 130:
7110 if(t[0] > 80) { KILLIT(i); }
7111 else t[0]++;
7112
7113 x = sc->floorz-sc->ceilingz;
7114
7115 if( rnd(64) )
7116 {
7117 k = spawn(i,EXPLOSION2);
7118 sprite[k].xrepeat = sprite[k].yrepeat = 2+(TRAND&7);
7119 sprite[k].z = sc->floorz-(TRAND%x);
7120 sprite[k].ang += 256-(TRAND%511);
7121 sprite[k].xvel = TRAND&127;
7122 ssp(k,CLIPMASK0);
7123 }
7124 break;
7125 case 131:
7126 if(t[0] > 40) { KILLIT(i); }
7127 else t[0]++;
7128
7129 x = sc->floorz-sc->ceilingz;
7130
7131 if( rnd(32) )
7132 {
7133 k = spawn(i,EXPLOSION2);
7134 sprite[k].xrepeat = sprite[k].yrepeat = 2+(TRAND&3);
7135 sprite[k].z = sc->floorz-(TRAND%x);
7136 sprite[k].ang += 256-(TRAND%511);
7137 sprite[k].xvel = TRAND&127;
7138 ssp(k,CLIPMASK0);
7139 }
7140 break;
7141 }
7142 BOLT:
7143 i = nexti;
7144 }
7145
7146 //Sloped sin-wave floors!
7147 for(i=headspritestat[3];i>=0;i=nextspritestat[i])
7148 {
7149 s = &sprite[i];
7150 if (s->lotag != 29) continue;
7151 sc = &sector[s->sectnum];
7152 if (sc->wallnum != 4) continue;
7153 wal = &wall[sc->wallptr+2];
7154 alignflorslope(s->sectnum,wal->x,wal->y,sector[wal->nextsector].floorz);
7155 }
7156}
7157
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/animlib.c b/apps/plugins/sdl/progs/duke3d/Game/src/animlib.c
new file mode 100644
index 0000000000..32ef9861a6
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/animlib.c
@@ -0,0 +1,352 @@
1//-------------------------------------------------------------------------
2/*
3 Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5 This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7 Duke Nukem 3D is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 aint32_t with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 Original Source: 1996 - Todd Replogle
23 Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#include <SDL.h>
28
29#include "types.h"
30#include "develop.h"
31#include "util_lib.h"
32//#include "_animlib.h"
33#include "animlib.h"
34
35//****************************************************************************
36//
37// GLOBALS
38//
39//****************************************************************************
40
41//****************************************************************************
42//
43// LOCALS
44//
45//****************************************************************************
46anim_t * anim=NULL;
47static boolean Anim_Started = false;
48
49//****************************************************************************
50//
51// CheckAnimStarted ()
52//
53//****************************************************************************
54
55void CheckAnimStarted ( char * funcname )
56{
57 if (!Anim_Started)
58 Error(EXIT_FAILURE, "ANIMLIB_%s: Anim has not been initialized\n",funcname);
59}
60//****************************************************************************
61//
62// findpage ()
63// - given a frame number return the large page number it resides in
64//
65//****************************************************************************
66
67uint16 findpage (uint16 framenumber)
68{
69 uint16 i;
70
71 CheckAnimStarted ( "findpage" );
72 for(i=0; i<anim->lpheader.nLps; i++)
73 {
74 if
75 (
76 anim->LpArray[i].baseRecord <= framenumber &&
77 anim->LpArray[i].baseRecord + anim->LpArray[i].nRecords > framenumber
78 )
79 return(i);
80 }
81 return(i);
82}
83
84
85//****************************************************************************
86//
87// loadpage ()
88// - seek out and load in the large page specified
89//
90//****************************************************************************
91
92void loadpage (uint16 pagenumber, uint16 *pagepointer)
93{
94 int32 size;
95 byte * buffer;
96
97 CheckAnimStarted ( "loadpage" );
98 buffer = anim->buffer;
99 if (anim->curlpnum != pagenumber)
100 {
101 anim->curlpnum = pagenumber;
102 buffer += 0xb00 + (pagenumber*0x10000);
103 size = sizeof(lp_descriptor);
104 memcpy(&anim->curlp,buffer,size);
105 buffer += size + sizeof(uint16);
106 memcpy(pagepointer,buffer,anim->curlp.nBytes+(anim->curlp.nRecords*2));
107 }
108}
109
110
111//****************************************************************************
112//
113// CPlayRunSkipDump ()
114// - This version of the decompressor is here for portability to non PC's
115//
116//****************************************************************************
117
118void CPlayRunSkipDump (byte *srcP, byte *dstP)
119{
120 int8_t cnt;
121 uint16 wordCnt;
122 byte pixel;
123
124nextOp:
125 cnt = (int8_t ) *srcP++;
126 //printf("op %d", cnt);
127 if (cnt > 0)
128 goto dump; /* dump following bytes */
129 if (cnt == 0)
130 goto run; /* repeating sequence */
131 cnt -= 0x80;
132 if (cnt == 0)
133 goto longOp;
134/* shortSkip */
135 dstP += cnt; /* adding 7-bit count to 32-bit pointer */
136 goto nextOp;
137dump:
138 do
139 {
140 *dstP++ = *srcP++;
141 } while (--cnt);
142 goto nextOp;
143run:
144 wordCnt = (byte)*srcP++; /* 8-bit unsigned count */
145 pixel = *srcP++;
146 do
147 {
148 *dstP++ = pixel;
149 } while (--wordCnt);
150
151 goto nextOp;
152longOp:
153 //printf("longop");
154 //wordCnt = *((uint16 *)srcP);
155 wordCnt = *srcP | (*(srcP+1) << 8);
156 srcP += sizeof(uint16);
157 if ((int16)wordCnt <= 0)
158 goto notLongSkip; /* Do SIGNED test. */
159
160/* longSkip. */
161 dstP += wordCnt;
162 goto nextOp;
163
164notLongSkip:
165 if (wordCnt == 0)
166 goto stop;
167 wordCnt -= 0x8000; /* Remove sign bit. */
168 if (wordCnt >= 0x4000)
169 goto longRun;
170
171/* longDump. */
172 do
173 {
174 *dstP++ = *srcP++;
175 } while (--wordCnt);
176 goto nextOp;
177
178longRun:
179 wordCnt -= 0x4000; /* Clear "longRun" bit. */
180 pixel = *srcP++;
181 do
182 {
183 *dstP++ = pixel;
184 } while (--wordCnt);
185 goto nextOp;
186
187stop: /* all done */
188 ;
189}
190
191
192
193//****************************************************************************
194//
195// renderframe ()
196// - draw the frame sepcified from the large page in the buffer pointed to
197//
198//****************************************************************************
199
200void renderframe (uint16 framenumber, uint16 *pagepointer)
201{
202 uint16 offset=0;
203 uint16 i;
204 uint16 destframe;
205 byte *ppointer;
206
207 CheckAnimStarted ( "renderframe" );
208 destframe = framenumber - anim->curlp.baseRecord;
209
210 for(i = 0; i < destframe; i++)
211 offset += readLE16(pagepointer + i);
212
213 ppointer = (byte *)pagepointer;
214
215 ppointer+=anim->curlp.nRecords*2+offset;
216 //rb->splash(HZ, "point 1");
217 if(ppointer[1])
218 {
219 ppointer += 4;
220 uint16_t val = readLE16(ppointer + 2);
221 //rb->splashf(HZ, "val=%d", val);
222 ppointer += val + (val & 1);
223
224 //uint16_t val = readLE16(((uint16_t*)ppointer) + 1);
225 //ppointer += (4 + ( ( val + (val & 1 ))));
226 }
227 else
228 ppointer+=4;
229 //rb->splashf(HZ, "point 2 (d = %d)", (char*)ppointer - (char*)pagepointer);
230
231 CPlayRunSkipDump (ppointer, anim->imagebuffer);
232}
233
234
235//****************************************************************************
236//
237// drawframe ()
238// - high level frame draw routine
239//
240//****************************************************************************
241
242void drawframe (uint16 framenumber)
243{
244 //rb->splashf(HZ, "draw %d", framenumber);
245 CheckAnimStarted ( "drawframe" );
246 loadpage(findpage(framenumber), anim->thepage);
247 //rb->splashf(HZ, "page: %08x", crc32(anim->thepage, sizeof(anim->thepage)));
248 renderframe(framenumber, anim->thepage);
249 //rb->splashf(HZ, "image: %08x", crc32(anim->imagebuffer, sizeof(anim->imagebuffer)));
250}
251
252
253//****************************************************************************
254//
255// ANIM_LoadAnim ()
256//
257//****************************************************************************
258
259void ANIM_LoadAnim (byte * buffer)
260{
261 uint16 i;
262 int32 size;
263
264 if (!Anim_Started) Anim_Started = true;
265
266 anim->buffer = buffer;
267 anim->curlpnum = 0xffff;
268 anim->currentframe = -1;
269 size = sizeof(lpfileheader);
270
271 assert(sizeof(lpfileheader) == 128);
272 assert(sizeof(lp_descriptor) == 6);
273 assert(sizeof(anim->LpArray) == 1536);
274
275 memcpy(&anim->lpheader, buffer, size );
276 buffer += size+128;
277 // load the color palette
278 for (i = 0; i < 768; i += 3)
279 {
280 anim->pal[i+2] = *buffer++;
281 anim->pal[i+1] = *buffer++;
282 anim->pal[i] = *buffer++;
283 buffer++;
284 }
285 // read in large page descriptors
286 size = sizeof(anim->LpArray);
287 memcpy(&anim->LpArray,buffer,size);
288}
289
290//****************************************************************************
291//
292// ANIM_FreeAnim ()
293//
294//****************************************************************************
295
296void ANIM_FreeAnim ( void )
297{
298 if (Anim_Started)
299 {
300// SafeFree(anim);
301 Anim_Started = false;
302 }
303}
304
305//****************************************************************************
306//
307// ANIM_NumFrames ()
308//
309//****************************************************************************
310
311int32 ANIM_NumFrames ( void )
312{
313 CheckAnimStarted ( "NumFrames" );
314 return anim->lpheader.nRecords;
315}
316
317//****************************************************************************
318//
319// ANIM_DrawFrame ()
320//
321//****************************************************************************
322
323byte * ANIM_DrawFrame (int32 framenumber)
324{
325 int32 cnt;
326
327 CheckAnimStarted ( "DrawFrame" );
328 if ((anim->currentframe != -1) && (anim->currentframe<=framenumber))
329 {
330 for (cnt = anim->currentframe; cnt < framenumber; cnt++)
331 drawframe (cnt);
332 }
333 else
334 {
335 for (cnt = 0; cnt < framenumber; cnt++)
336 drawframe (cnt);
337 }
338 anim->currentframe = framenumber;
339 return anim->imagebuffer;
340}
341
342//****************************************************************************
343//
344// ANIM_GetPalette ()
345//
346//****************************************************************************
347
348byte * ANIM_GetPalette ( void )
349{
350 CheckAnimStarted ( "GetPalette" );
351 return anim->pal;
352}
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/animlib.h b/apps/plugins/sdl/progs/duke3d/Game/src/animlib.h
new file mode 100644
index 0000000000..6850fc75bd
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/animlib.h
@@ -0,0 +1,155 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27/////////////////////////////////////////////////////////////////////////////
28//
29// ANIMLIB.H
30//
31/////////////////////////////////////////////////////////////////////////////
32
33#ifndef _animlib_public_
34#define _animlib_public_
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39
40// structure declarations for deluxe animate large page files */
41
42typedef struct
43 {
44 uint32 id; // 4 character ID == "LPF " */
45 uint16 maxLps; // max # largePages allowed. 256 FOR NOW. */
46 uint16 nLps; // # largePages in this file. */
47 uint32 nRecords; // # records in this file. 65534 is current limit plus */
48 // one for last-to-first delta for looping the animation */
49 uint16 maxRecsPerLp; // # records permitted in an lp. 256 FOR NOW. */
50 uint16 lpfTableOffset; // Absolute Seek position of lpfTable. 1280 FOR NOW.
51 // The lpf Table is an array of 256 large page structures
52 // that is used to facilitate finding records in an anim
53 // file without having to seek through all of the Large
54 // Pages to find which one a specific record lives in. */
55 uint32 contentType; // 4 character ID == "ANIM" */
56 uint16 width; // Width of screen in pixels. */
57 uint16 height; // Height of screen in pixels. */
58 byte variant; // 0==ANIM. */
59 byte version; // 0==frame rate is multiple of 18 cycles/sec.
60 // 1==frame rate is multiple of 70 cycles/sec. */
61 byte hasLastDelta; // 1==Last record is a delta from last-to-first frame. */
62 byte lastDeltaValid; // 0==The last-to-first delta (if present) hasn't been
63 // updated to match the current first&last frames, so it
64 // should be ignored. */
65 byte pixelType; // /* 0==256 color. */
66 byte CompressionType;// /* 1==(RunSkipDump) Only one used FOR NOW. */
67 byte otherRecsPerFrm;// /* 0 FOR NOW. */
68 byte bitmaptype; // /* 1==320x200, 256-color. Only one implemented so far. */
69 byte recordTypes[32];// /* Not yet implemented. */
70 uint32 nFrames; // /* In case future version adds other records at end of
71 // file, we still know how many actual frames.
72 // NOTE: DOES include last-to-first delta when present. */
73 uint16 framesPerSecond; // Number of frames to play per second. */
74 uint16 pad2[29]; // 58 bytes of filler to round up to 128 bytes total. */
75} __attribute__ ((packed)) lpfileheader;
76
77// this is the format of a large page structure
78typedef struct
79 {
80 uint16 baseRecord; // Number of first record in this large page.
81 uint16 nRecords; // Number of records in lp.
82 // bit 15 of "nRecords" == "has continuation from previous lp".
83 // bit 14 of "nRecords" == "final record continues on next lp".
84 uint16 nBytes; // Total number of bytes of contents, excluding header.
85} __attribute__ ((packed)) lp_descriptor;
86
87typedef struct
88 {
89 uint16 framecount; // current frame of anim
90 lpfileheader lpheader; // file header will be loaded into this structure
91 lp_descriptor LpArray[256]; // arrays of large page structs used to find frames
92 uint16 curlpnum; // initialize to an invalid Large page number
93 lp_descriptor curlp; // header of large page currently in memory
94 uint16 thepage[0x8000]; // buffer where current large page is loaded
95 byte imagebuffer[0x10000]; // buffer where anim frame is decoded
96 byte * buffer;
97 byte pal[768];
98 int32 currentframe;
99} __attribute__ ((packed)) anim_t;
100
101//****************************************************************************
102//
103// ANIM_LoadAnim ()
104//
105// Setup internal anim data structure
106//
107//****************************************************************************
108
109void ANIM_LoadAnim (byte * buffer);
110
111//****************************************************************************
112//
113// ANIM_FreeAnim ()
114//
115// Free up internal anim data structure
116//
117//****************************************************************************
118
119void ANIM_FreeAnim ( void );
120
121//****************************************************************************
122//
123// ANIM_NumFrames ()
124//
125// returns the number of frames in the current anim
126//
127//****************************************************************************
128
129int32 ANIM_NumFrames ( void );
130
131//****************************************************************************
132//
133// ANIM_DrawFrame ()
134//
135// Draw the frame to a returned buffer
136//
137//****************************************************************************
138
139byte * ANIM_DrawFrame (int32 framenumber);
140
141//****************************************************************************
142//
143// ANIM_GetPalette ()
144//
145// return the palette of the anim
146//****************************************************************************
147
148byte * ANIM_GetPalette ( void );
149
150extern anim_t * anim;
151
152#ifdef __cplusplus
153};
154#endif
155#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/Makefile b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/Makefile
new file mode 100644
index 0000000000..d0edc07f8e
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/Makefile
@@ -0,0 +1,546 @@
1# Makefile.in generated by automake 1.15.1 from Makefile.am.
2# Game/src/audiolib/Makefile. Generated from Makefile.in by configure.
3
4# Copyright (C) 1994-2017 Free Software Foundation, Inc.
5
6# This Makefile.in is free software; the Free Software Foundation
7# gives unlimited permission to copy and/or distribute it,
8# with or without modifications, as long as this notice is preserved.
9
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
12# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13# PARTICULAR PURPOSE.
14
15
16
17
18am__is_gnu_make = { \
19 if test -z '$(MAKELEVEL)'; then \
20 false; \
21 elif test -n '$(MAKE_HOST)'; then \
22 true; \
23 elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
24 true; \
25 else \
26 false; \
27 fi; \
28}
29am__make_running_with_option = \
30 case $${target_option-} in \
31 ?) ;; \
32 *) echo "am__make_running_with_option: internal error: invalid" \
33 "target option '$${target_option-}' specified" >&2; \
34 exit 1;; \
35 esac; \
36 has_opt=no; \
37 sane_makeflags=$$MAKEFLAGS; \
38 if $(am__is_gnu_make); then \
39 sane_makeflags=$$MFLAGS; \
40 else \
41 case $$MAKEFLAGS in \
42 *\\[\ \ ]*) \
43 bs=\\; \
44 sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
45 | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
46 esac; \
47 fi; \
48 skip_next=no; \
49 strip_trailopt () \
50 { \
51 flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
52 }; \
53 for flg in $$sane_makeflags; do \
54 test $$skip_next = yes && { skip_next=no; continue; }; \
55 case $$flg in \
56 *=*|--*) continue;; \
57 -*I) strip_trailopt 'I'; skip_next=yes;; \
58 -*I?*) strip_trailopt 'I';; \
59 -*O) strip_trailopt 'O'; skip_next=yes;; \
60 -*O?*) strip_trailopt 'O';; \
61 -*l) strip_trailopt 'l'; skip_next=yes;; \
62 -*l?*) strip_trailopt 'l';; \
63 -[dEDm]) skip_next=yes;; \
64 -[JT]) skip_next=yes;; \
65 esac; \
66 case $$flg in \
67 *$$target_option*) has_opt=yes; break;; \
68 esac; \
69 done; \
70 test $$has_opt = yes
71am__make_dryrun = (target_option=n; $(am__make_running_with_option))
72am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
73pkgdatadir = $(datadir)/chocolate-duke3d
74pkgincludedir = $(includedir)/chocolate-duke3d
75pkglibdir = $(libdir)/chocolate-duke3d
76pkglibexecdir = $(libexecdir)/chocolate-duke3d
77am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
78install_sh_DATA = $(install_sh) -c -m 644
79install_sh_PROGRAM = $(install_sh) -c
80install_sh_SCRIPT = $(install_sh) -c
81INSTALL_HEADER = $(INSTALL_DATA)
82transform = $(program_transform_name)
83NORMAL_INSTALL = :
84PRE_INSTALL = :
85POST_INSTALL = :
86NORMAL_UNINSTALL = :
87PRE_UNINSTALL = :
88POST_UNINSTALL = :
89subdir = Game/src/audiolib
90ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
91am__aclocal_m4_deps = $(top_srcdir)/configure.ac
92am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
93 $(ACLOCAL_M4)
94DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
95mkinstalldirs = $(install_sh) -d
96CONFIG_CLEAN_FILES =
97CONFIG_CLEAN_VPATH_FILES =
98LIBRARIES = $(noinst_LIBRARIES)
99AR = ar
100ARFLAGS = cru
101AM_V_AR = $(am__v_AR_$(V))
102am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY))
103am__v_AR_0 = @echo " AR " $@;
104am__v_AR_1 =
105libaudio_a_AR = $(AR) $(ARFLAGS)
106libaudio_a_LIBADD =
107am_libaudio_a_OBJECTS = fx_man.$(OBJEXT) dsl.$(OBJEXT) \
108 ll_man.$(OBJEXT) multivoc.$(OBJEXT) mv_mix.$(OBJEXT) \
109 mvreverb.$(OBJEXT) nodpmi.$(OBJEXT) pitch.$(OBJEXT) \
110 user.$(OBJEXT) usrhooks.$(OBJEXT)
111libaudio_a_OBJECTS = $(am_libaudio_a_OBJECTS)
112AM_V_P = $(am__v_P_$(V))
113am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
114am__v_P_0 = false
115am__v_P_1 = :
116AM_V_GEN = $(am__v_GEN_$(V))
117am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
118am__v_GEN_0 = @echo " GEN " $@;
119am__v_GEN_1 =
120AM_V_at = $(am__v_at_$(V))
121am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
122am__v_at_0 = @
123am__v_at_1 =
124DEFAULT_INCLUDES = -I.
125depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
126am__depfiles_maybe = depfiles
127am__mv = mv -f
128COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
129 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
130AM_V_CC = $(am__v_CC_$(V))
131am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
132am__v_CC_0 = @echo " CC " $@;
133am__v_CC_1 =
134CCLD = $(CC)
135LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
136AM_V_CCLD = $(am__v_CCLD_$(V))
137am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
138am__v_CCLD_0 = @echo " CCLD " $@;
139am__v_CCLD_1 =
140SOURCES = $(libaudio_a_SOURCES)
141DIST_SOURCES = $(libaudio_a_SOURCES)
142am__can_run_installinfo = \
143 case $$AM_UPDATE_INFO_DIR in \
144 n|no|NO) false;; \
145 *) (install-info --version) >/dev/null 2>&1;; \
146 esac
147am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
148# Read a list of newline-separated strings from the standard input,
149# and print each of them once, without duplicates. Input order is
150# *not* preserved.
151am__uniquify_input = $(AWK) '\
152 BEGIN { nonempty = 0; } \
153 { items[$$0] = 1; nonempty = 1; } \
154 END { if (nonempty) { for (i in items) print i; }; } \
155'
156# Make sure the list of sources is unique. This is necessary because,
157# e.g., the same source file might be shared among _SOURCES variables
158# for different programs/libraries.
159am__define_uniq_tagged_files = \
160 list='$(am__tagged_files)'; \
161 unique=`for i in $$list; do \
162 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
163 done | $(am__uniquify_input)`
164ETAGS = etags
165CTAGS = ctags
166am__DIST_COMMON = $(srcdir)/Makefile.in \
167 $(top_srcdir)/build-aux/depcomp
168DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
169ACLOCAL = ${SHELL} /home/franklin/chocolate_duke3D/build-aux/missing aclocal-1.15
170AMTAR = $${TAR-tar}
171AM_DEFAULT_VERBOSITY = 0
172AUTOCONF = ${SHELL} /home/franklin/chocolate_duke3D/build-aux/missing autoconf
173AUTOHEADER = ${SHELL} /home/franklin/chocolate_duke3D/build-aux/missing autoheader
174AUTOMAKE = ${SHELL} /home/franklin/chocolate_duke3D/build-aux/missing automake-1.15
175AWK = gawk
176CC = gcc
177CCDEPMODE = depmode=gcc3
178CFLAGS = -Wall -Wno-pointer-sign -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -Wno-parentheses -Wno-maybe-uninitialized -Wno-unused-but-set-variable -Wno-unused-function -Wno-unused-result -fno-strict-aliasing -fno-aggressive-loop-optimizations -DPLATFORM_UNIX -D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/SDL -g -O2
179CPP = gcc -E
180CPPFLAGS =
181CYGPATH_W = echo
182DEFS = -DPACKAGE_NAME=\"Chocolate\ Duke3D\" -DPACKAGE_TARNAME=\"chocolate-duke3d\" -DPACKAGE_VERSION=\"1.0\" -DPACKAGE_STRING=\"Chocolate\ Duke3D\ 1.0\" -DPACKAGE_BUGREPORT=\"https://github.com/fabiensanglard/chocolate_duke3D/issues\" -DPACKAGE_URL=\"\" -DPACKAGE=\"chocolate-duke3d\" -DVERSION=\"1.0\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_ASSERT_H=1 -DHAVE_ENET_ENET_H=1
183DEPDIR = .deps
184ECHO_C =
185ECHO_N = -n
186ECHO_T =
187EGREP = /usr/bin/grep -E
188EXEEXT =
189GREP = /usr/bin/grep
190INSTALL = /usr/bin/install -c
191INSTALL_DATA = ${INSTALL} -m 644
192INSTALL_PROGRAM = ${INSTALL}
193INSTALL_SCRIPT = ${INSTALL}
194INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
195LDFLAGS = -lSDL -lpthread -lSDL_mixer -lSDL -lpthread
196LIBOBJS =
197LIBS =
198LTLIBOBJS =
199MAKEINFO = ${SHELL} /home/franklin/chocolate_duke3D/build-aux/missing makeinfo
200MKDIR_P = /usr/bin/mkdir -p
201OBJEXT = o
202PACKAGE = chocolate-duke3d
203PACKAGE_BUGREPORT = https://github.com/fabiensanglard/chocolate_duke3D/issues
204PACKAGE_NAME = Chocolate Duke3D
205PACKAGE_STRING = Chocolate Duke3D 1.0
206PACKAGE_TARNAME = chocolate-duke3d
207PACKAGE_URL =
208PACKAGE_VERSION = 1.0
209PATH_SEPARATOR = :
210PKG_CONFIG = /usr/bin/pkg-config
211PKG_CONFIG_LIBDIR =
212PKG_CONFIG_PATH =
213RANLIB = ranlib
214SDL_CFLAGS = -D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/SDL
215SDL_LIBS = -lSDL -lpthread
216SDL_MIXER_CFLAGS = -D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/SDL
217SDL_MIXER_LIBS = -lSDL_mixer -lSDL -lpthread
218SET_MAKE =
219SHELL = /bin/sh
220STRIP =
221VERSION = 1.0
222WINDRES =
223abs_builddir = /home/franklin/chocolate_duke3D/Game/src/audiolib
224abs_srcdir = /home/franklin/chocolate_duke3D/Game/src/audiolib
225abs_top_builddir = /home/franklin/chocolate_duke3D
226abs_top_srcdir = /home/franklin/chocolate_duke3D
227ac_ct_CC = gcc
228am__include = include
229am__leading_dot = .
230am__quote =
231am__tar = $${TAR-tar} chof - "$$tardir"
232am__untar = $${TAR-tar} xf -
233bindir = ${exec_prefix}/bin
234build_alias =
235builddir = .
236datadir = ${datarootdir}
237datarootdir = ${prefix}/share
238docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
239dvidir = ${docdir}
240exec_prefix = ${prefix}
241host_alias =
242htmldir = ${docdir}
243includedir = ${prefix}/include
244infodir = ${datarootdir}/info
245install_sh = ${SHELL} /home/franklin/chocolate_duke3D/build-aux/install-sh
246libdir = ${exec_prefix}/lib
247libexecdir = ${exec_prefix}/libexec
248localedir = ${datarootdir}/locale
249localstatedir = ${prefix}/var
250mandir = ${datarootdir}/man
251mkdir_p = $(MKDIR_P)
252oldincludedir = /usr/include
253pdfdir = ${docdir}
254prefix = /usr/local
255program_transform_name = s,x,x,
256psdir = ${docdir}
257sbindir = ${exec_prefix}/sbin
258sharedstatedir = ${prefix}/com
259srcdir = .
260sysconfdir = ${prefix}/etc
261target_alias =
262top_build_prefix = ../../../
263top_builddir = ../../..
264top_srcdir = ../../..
265noinst_LIBRARIES = libaudio.a
266libaudio_a_SOURCES = fx_man.c dsl.c ll_man.c multivoc.c mv_mix.c mvreverb.c nodpmi.c pitch.c user.c usrhooks.c
267AM_CFLAGS = -I$(top_srcdir)/Engine/src
268all: all-am
269
270.SUFFIXES:
271.SUFFIXES: .c .o .obj
272$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
273 @for dep in $?; do \
274 case '$(am__configure_deps)' in \
275 *$$dep*) \
276 ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
277 && { if test -f $@; then exit 0; else break; fi; }; \
278 exit 1;; \
279 esac; \
280 done; \
281 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Game/src/audiolib/Makefile'; \
282 $(am__cd) $(top_srcdir) && \
283 $(AUTOMAKE) --foreign Game/src/audiolib/Makefile
284Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
285 @case '$?' in \
286 *config.status*) \
287 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
288 *) \
289 echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
290 cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
291 esac;
292
293$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
294 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
295
296$(top_srcdir)/configure: $(am__configure_deps)
297 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
298$(ACLOCAL_M4): $(am__aclocal_m4_deps)
299 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
300$(am__aclocal_m4_deps):
301
302clean-noinstLIBRARIES:
303 -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
304
305libaudio.a: $(libaudio_a_OBJECTS) $(libaudio_a_DEPENDENCIES) $(EXTRA_libaudio_a_DEPENDENCIES)
306 $(AM_V_at)-rm -f libaudio.a
307 $(AM_V_AR)$(libaudio_a_AR) libaudio.a $(libaudio_a_OBJECTS) $(libaudio_a_LIBADD)
308 $(AM_V_at)$(RANLIB) libaudio.a
309
310mostlyclean-compile:
311 -rm -f *.$(OBJEXT)
312
313distclean-compile:
314 -rm -f *.tab.c
315
316include ./$(DEPDIR)/dsl.Po
317include ./$(DEPDIR)/fx_man.Po
318include ./$(DEPDIR)/ll_man.Po
319include ./$(DEPDIR)/multivoc.Po
320include ./$(DEPDIR)/mv_mix.Po
321include ./$(DEPDIR)/mvreverb.Po
322include ./$(DEPDIR)/nodpmi.Po
323include ./$(DEPDIR)/pitch.Po
324include ./$(DEPDIR)/user.Po
325include ./$(DEPDIR)/usrhooks.Po
326
327.c.o:
328 $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
329 $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
330# $(AM_V_CC)source='$<' object='$@' libtool=no \
331# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
332# $(AM_V_CC_no)$(COMPILE) -c -o $@ $<
333
334.c.obj:
335 $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
336 $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
337# $(AM_V_CC)source='$<' object='$@' libtool=no \
338# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
339# $(AM_V_CC_no)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
340
341ID: $(am__tagged_files)
342 $(am__define_uniq_tagged_files); mkid -fID $$unique
343tags: tags-am
344TAGS: tags
345
346tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
347 set x; \
348 here=`pwd`; \
349 $(am__define_uniq_tagged_files); \
350 shift; \
351 if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
352 test -n "$$unique" || unique=$$empty_fix; \
353 if test $$# -gt 0; then \
354 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
355 "$$@" $$unique; \
356 else \
357 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
358 $$unique; \
359 fi; \
360 fi
361ctags: ctags-am
362
363CTAGS: ctags
364ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
365 $(am__define_uniq_tagged_files); \
366 test -z "$(CTAGS_ARGS)$$unique" \
367 || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
368 $$unique
369
370GTAGS:
371 here=`$(am__cd) $(top_builddir) && pwd` \
372 && $(am__cd) $(top_srcdir) \
373 && gtags -i $(GTAGS_ARGS) "$$here"
374cscopelist: cscopelist-am
375
376cscopelist-am: $(am__tagged_files)
377 list='$(am__tagged_files)'; \
378 case "$(srcdir)" in \
379 [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
380 *) sdir=$(subdir)/$(srcdir) ;; \
381 esac; \
382 for i in $$list; do \
383 if test -f "$$i"; then \
384 echo "$(subdir)/$$i"; \
385 else \
386 echo "$$sdir/$$i"; \
387 fi; \
388 done >> $(top_builddir)/cscope.files
389
390distclean-tags:
391 -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
392
393distdir: $(DISTFILES)
394 @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
395 topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
396 list='$(DISTFILES)'; \
397 dist_files=`for file in $$list; do echo $$file; done | \
398 sed -e "s|^$$srcdirstrip/||;t" \
399 -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
400 case $$dist_files in \
401 */*) $(MKDIR_P) `echo "$$dist_files" | \
402 sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
403 sort -u` ;; \
404 esac; \
405 for file in $$dist_files; do \
406 if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
407 if test -d $$d/$$file; then \
408 dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
409 if test -d "$(distdir)/$$file"; then \
410 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
411 fi; \
412 if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
413 cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
414 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
415 fi; \
416 cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
417 else \
418 test -f "$(distdir)/$$file" \
419 || cp -p $$d/$$file "$(distdir)/$$file" \
420 || exit 1; \
421 fi; \
422 done
423check-am: all-am
424check: check-am
425all-am: Makefile $(LIBRARIES)
426installdirs:
427install: install-am
428install-exec: install-exec-am
429install-data: install-data-am
430uninstall: uninstall-am
431
432install-am: all-am
433 @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
434
435installcheck: installcheck-am
436install-strip:
437 if test -z '$(STRIP)'; then \
438 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
439 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
440 install; \
441 else \
442 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
443 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
444 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
445 fi
446mostlyclean-generic:
447
448clean-generic:
449
450distclean-generic:
451 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
452 -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
453
454maintainer-clean-generic:
455 @echo "This command is intended for maintainers to use"
456 @echo "it deletes files that may require special tools to rebuild."
457clean: clean-am
458
459clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
460
461distclean: distclean-am
462 -rm -rf ./$(DEPDIR)
463 -rm -f Makefile
464distclean-am: clean-am distclean-compile distclean-generic \
465 distclean-tags
466
467dvi: dvi-am
468
469dvi-am:
470
471html: html-am
472
473html-am:
474
475info: info-am
476
477info-am:
478
479install-data-am:
480
481install-dvi: install-dvi-am
482
483install-dvi-am:
484
485install-exec-am:
486
487install-html: install-html-am
488
489install-html-am:
490
491install-info: install-info-am
492
493install-info-am:
494
495install-man:
496
497install-pdf: install-pdf-am
498
499install-pdf-am:
500
501install-ps: install-ps-am
502
503install-ps-am:
504
505installcheck-am:
506
507maintainer-clean: maintainer-clean-am
508 -rm -rf ./$(DEPDIR)
509 -rm -f Makefile
510maintainer-clean-am: distclean-am maintainer-clean-generic
511
512mostlyclean: mostlyclean-am
513
514mostlyclean-am: mostlyclean-compile mostlyclean-generic
515
516pdf: pdf-am
517
518pdf-am:
519
520ps: ps-am
521
522ps-am:
523
524uninstall-am:
525
526.MAKE: install-am install-strip
527
528.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
529 clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \
530 distclean-compile distclean-generic distclean-tags distdir dvi \
531 dvi-am html html-am info info-am install install-am \
532 install-data install-data-am install-dvi install-dvi-am \
533 install-exec install-exec-am install-html install-html-am \
534 install-info install-info-am install-man install-pdf \
535 install-pdf-am install-ps install-ps-am install-strip \
536 installcheck installcheck-am installdirs maintainer-clean \
537 maintainer-clean-generic mostlyclean mostlyclean-compile \
538 mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
539 uninstall-am
540
541.PRECIOUS: Makefile
542
543
544# Tell versions [3.59,3.63) of GNU make to not export all variables.
545# Otherwise a system limit (for SysV at least) may be exceeded.
546.NOEXPORT:
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/Makefile.am b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/Makefile.am
new file mode 100644
index 0000000000..dbb38b352d
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/Makefile.am
@@ -0,0 +1,4 @@
1noinst_LIBRARIES = libaudio.a
2libaudio_a_SOURCES = fx_man.c dsl.c ll_man.c multivoc.c mv_mix.c mvreverb.c nodpmi.c pitch.c user.c usrhooks.c
3
4AM_CFLAGS = -I$(top_srcdir)/Engine/src
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/Makefile.in b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/Makefile.in
new file mode 100644
index 0000000000..d3428c053e
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/Makefile.in
@@ -0,0 +1,546 @@
1# Makefile.in generated by automake 1.15.1 from Makefile.am.
2# @configure_input@
3
4# Copyright (C) 1994-2017 Free Software Foundation, Inc.
5
6# This Makefile.in is free software; the Free Software Foundation
7# gives unlimited permission to copy and/or distribute it,
8# with or without modifications, as long as this notice is preserved.
9
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
12# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13# PARTICULAR PURPOSE.
14
15@SET_MAKE@
16
17VPATH = @srcdir@
18am__is_gnu_make = { \
19 if test -z '$(MAKELEVEL)'; then \
20 false; \
21 elif test -n '$(MAKE_HOST)'; then \
22 true; \
23 elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
24 true; \
25 else \
26 false; \
27 fi; \
28}
29am__make_running_with_option = \
30 case $${target_option-} in \
31 ?) ;; \
32 *) echo "am__make_running_with_option: internal error: invalid" \
33 "target option '$${target_option-}' specified" >&2; \
34 exit 1;; \
35 esac; \
36 has_opt=no; \
37 sane_makeflags=$$MAKEFLAGS; \
38 if $(am__is_gnu_make); then \
39 sane_makeflags=$$MFLAGS; \
40 else \
41 case $$MAKEFLAGS in \
42 *\\[\ \ ]*) \
43 bs=\\; \
44 sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
45 | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
46 esac; \
47 fi; \
48 skip_next=no; \
49 strip_trailopt () \
50 { \
51 flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
52 }; \
53 for flg in $$sane_makeflags; do \
54 test $$skip_next = yes && { skip_next=no; continue; }; \
55 case $$flg in \
56 *=*|--*) continue;; \
57 -*I) strip_trailopt 'I'; skip_next=yes;; \
58 -*I?*) strip_trailopt 'I';; \
59 -*O) strip_trailopt 'O'; skip_next=yes;; \
60 -*O?*) strip_trailopt 'O';; \
61 -*l) strip_trailopt 'l'; skip_next=yes;; \
62 -*l?*) strip_trailopt 'l';; \
63 -[dEDm]) skip_next=yes;; \
64 -[JT]) skip_next=yes;; \
65 esac; \
66 case $$flg in \
67 *$$target_option*) has_opt=yes; break;; \
68 esac; \
69 done; \
70 test $$has_opt = yes
71am__make_dryrun = (target_option=n; $(am__make_running_with_option))
72am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
73pkgdatadir = $(datadir)/@PACKAGE@
74pkgincludedir = $(includedir)/@PACKAGE@
75pkglibdir = $(libdir)/@PACKAGE@
76pkglibexecdir = $(libexecdir)/@PACKAGE@
77am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
78install_sh_DATA = $(install_sh) -c -m 644
79install_sh_PROGRAM = $(install_sh) -c
80install_sh_SCRIPT = $(install_sh) -c
81INSTALL_HEADER = $(INSTALL_DATA)
82transform = $(program_transform_name)
83NORMAL_INSTALL = :
84PRE_INSTALL = :
85POST_INSTALL = :
86NORMAL_UNINSTALL = :
87PRE_UNINSTALL = :
88POST_UNINSTALL = :
89subdir = Game/src/audiolib
90ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
91am__aclocal_m4_deps = $(top_srcdir)/configure.ac
92am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
93 $(ACLOCAL_M4)
94DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
95mkinstalldirs = $(install_sh) -d
96CONFIG_CLEAN_FILES =
97CONFIG_CLEAN_VPATH_FILES =
98LIBRARIES = $(noinst_LIBRARIES)
99AR = ar
100ARFLAGS = cru
101AM_V_AR = $(am__v_AR_@AM_V@)
102am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
103am__v_AR_0 = @echo " AR " $@;
104am__v_AR_1 =
105libaudio_a_AR = $(AR) $(ARFLAGS)
106libaudio_a_LIBADD =
107am_libaudio_a_OBJECTS = fx_man.$(OBJEXT) dsl.$(OBJEXT) \
108 ll_man.$(OBJEXT) multivoc.$(OBJEXT) mv_mix.$(OBJEXT) \
109 mvreverb.$(OBJEXT) nodpmi.$(OBJEXT) pitch.$(OBJEXT) \
110 user.$(OBJEXT) usrhooks.$(OBJEXT)
111libaudio_a_OBJECTS = $(am_libaudio_a_OBJECTS)
112AM_V_P = $(am__v_P_@AM_V@)
113am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
114am__v_P_0 = false
115am__v_P_1 = :
116AM_V_GEN = $(am__v_GEN_@AM_V@)
117am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
118am__v_GEN_0 = @echo " GEN " $@;
119am__v_GEN_1 =
120AM_V_at = $(am__v_at_@AM_V@)
121am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
122am__v_at_0 = @
123am__v_at_1 =
124DEFAULT_INCLUDES = -I.@am__isrc@
125depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
126am__depfiles_maybe = depfiles
127am__mv = mv -f
128COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
129 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
130AM_V_CC = $(am__v_CC_@AM_V@)
131am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
132am__v_CC_0 = @echo " CC " $@;
133am__v_CC_1 =
134CCLD = $(CC)
135LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
136AM_V_CCLD = $(am__v_CCLD_@AM_V@)
137am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
138am__v_CCLD_0 = @echo " CCLD " $@;
139am__v_CCLD_1 =
140SOURCES = $(libaudio_a_SOURCES)
141DIST_SOURCES = $(libaudio_a_SOURCES)
142am__can_run_installinfo = \
143 case $$AM_UPDATE_INFO_DIR in \
144 n|no|NO) false;; \
145 *) (install-info --version) >/dev/null 2>&1;; \
146 esac
147am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
148# Read a list of newline-separated strings from the standard input,
149# and print each of them once, without duplicates. Input order is
150# *not* preserved.
151am__uniquify_input = $(AWK) '\
152 BEGIN { nonempty = 0; } \
153 { items[$$0] = 1; nonempty = 1; } \
154 END { if (nonempty) { for (i in items) print i; }; } \
155'
156# Make sure the list of sources is unique. This is necessary because,
157# e.g., the same source file might be shared among _SOURCES variables
158# for different programs/libraries.
159am__define_uniq_tagged_files = \
160 list='$(am__tagged_files)'; \
161 unique=`for i in $$list; do \
162 if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
163 done | $(am__uniquify_input)`
164ETAGS = etags
165CTAGS = ctags
166am__DIST_COMMON = $(srcdir)/Makefile.in \
167 $(top_srcdir)/build-aux/depcomp
168DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
169ACLOCAL = @ACLOCAL@
170AMTAR = @AMTAR@
171AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
172AUTOCONF = @AUTOCONF@
173AUTOHEADER = @AUTOHEADER@
174AUTOMAKE = @AUTOMAKE@
175AWK = @AWK@
176CC = @CC@
177CCDEPMODE = @CCDEPMODE@
178CFLAGS = @CFLAGS@
179CPP = @CPP@
180CPPFLAGS = @CPPFLAGS@
181CYGPATH_W = @CYGPATH_W@
182DEFS = @DEFS@
183DEPDIR = @DEPDIR@
184ECHO_C = @ECHO_C@
185ECHO_N = @ECHO_N@
186ECHO_T = @ECHO_T@
187EGREP = @EGREP@
188EXEEXT = @EXEEXT@
189GREP = @GREP@
190INSTALL = @INSTALL@
191INSTALL_DATA = @INSTALL_DATA@
192INSTALL_PROGRAM = @INSTALL_PROGRAM@
193INSTALL_SCRIPT = @INSTALL_SCRIPT@
194INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
195LDFLAGS = @LDFLAGS@
196LIBOBJS = @LIBOBJS@
197LIBS = @LIBS@
198LTLIBOBJS = @LTLIBOBJS@
199MAKEINFO = @MAKEINFO@
200MKDIR_P = @MKDIR_P@
201OBJEXT = @OBJEXT@
202PACKAGE = @PACKAGE@
203PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
204PACKAGE_NAME = @PACKAGE_NAME@
205PACKAGE_STRING = @PACKAGE_STRING@
206PACKAGE_TARNAME = @PACKAGE_TARNAME@
207PACKAGE_URL = @PACKAGE_URL@
208PACKAGE_VERSION = @PACKAGE_VERSION@
209PATH_SEPARATOR = @PATH_SEPARATOR@
210PKG_CONFIG = @PKG_CONFIG@
211PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
212PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
213RANLIB = @RANLIB@
214SDL_CFLAGS = @SDL_CFLAGS@
215SDL_LIBS = @SDL_LIBS@
216SDL_MIXER_CFLAGS = @SDL_MIXER_CFLAGS@
217SDL_MIXER_LIBS = @SDL_MIXER_LIBS@
218SET_MAKE = @SET_MAKE@
219SHELL = @SHELL@
220STRIP = @STRIP@
221VERSION = @VERSION@
222WINDRES = @WINDRES@
223abs_builddir = @abs_builddir@
224abs_srcdir = @abs_srcdir@
225abs_top_builddir = @abs_top_builddir@
226abs_top_srcdir = @abs_top_srcdir@
227ac_ct_CC = @ac_ct_CC@
228am__include = @am__include@
229am__leading_dot = @am__leading_dot@
230am__quote = @am__quote@
231am__tar = @am__tar@
232am__untar = @am__untar@
233bindir = @bindir@
234build_alias = @build_alias@
235builddir = @builddir@
236datadir = @datadir@
237datarootdir = @datarootdir@
238docdir = @docdir@
239dvidir = @dvidir@
240exec_prefix = @exec_prefix@
241host_alias = @host_alias@
242htmldir = @htmldir@
243includedir = @includedir@
244infodir = @infodir@
245install_sh = @install_sh@
246libdir = @libdir@
247libexecdir = @libexecdir@
248localedir = @localedir@
249localstatedir = @localstatedir@
250mandir = @mandir@
251mkdir_p = @mkdir_p@
252oldincludedir = @oldincludedir@
253pdfdir = @pdfdir@
254prefix = @prefix@
255program_transform_name = @program_transform_name@
256psdir = @psdir@
257sbindir = @sbindir@
258sharedstatedir = @sharedstatedir@
259srcdir = @srcdir@
260sysconfdir = @sysconfdir@
261target_alias = @target_alias@
262top_build_prefix = @top_build_prefix@
263top_builddir = @top_builddir@
264top_srcdir = @top_srcdir@
265noinst_LIBRARIES = libaudio.a
266libaudio_a_SOURCES = fx_man.c dsl.c ll_man.c multivoc.c mv_mix.c mvreverb.c nodpmi.c pitch.c user.c usrhooks.c
267AM_CFLAGS = -I$(top_srcdir)/Engine/src
268all: all-am
269
270.SUFFIXES:
271.SUFFIXES: .c .o .obj
272$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
273 @for dep in $?; do \
274 case '$(am__configure_deps)' in \
275 *$$dep*) \
276 ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
277 && { if test -f $@; then exit 0; else break; fi; }; \
278 exit 1;; \
279 esac; \
280 done; \
281 echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Game/src/audiolib/Makefile'; \
282 $(am__cd) $(top_srcdir) && \
283 $(AUTOMAKE) --foreign Game/src/audiolib/Makefile
284Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
285 @case '$?' in \
286 *config.status*) \
287 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
288 *) \
289 echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
290 cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
291 esac;
292
293$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
294 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
295
296$(top_srcdir)/configure: $(am__configure_deps)
297 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
298$(ACLOCAL_M4): $(am__aclocal_m4_deps)
299 cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
300$(am__aclocal_m4_deps):
301
302clean-noinstLIBRARIES:
303 -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
304
305libaudio.a: $(libaudio_a_OBJECTS) $(libaudio_a_DEPENDENCIES) $(EXTRA_libaudio_a_DEPENDENCIES)
306 $(AM_V_at)-rm -f libaudio.a
307 $(AM_V_AR)$(libaudio_a_AR) libaudio.a $(libaudio_a_OBJECTS) $(libaudio_a_LIBADD)
308 $(AM_V_at)$(RANLIB) libaudio.a
309
310mostlyclean-compile:
311 -rm -f *.$(OBJEXT)
312
313distclean-compile:
314 -rm -f *.tab.c
315
316@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsl.Po@am__quote@
317@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fx_man.Po@am__quote@
318@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ll_man.Po@am__quote@
319@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multivoc.Po@am__quote@
320@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mv_mix.Po@am__quote@
321@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mvreverb.Po@am__quote@
322@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nodpmi.Po@am__quote@
323@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pitch.Po@am__quote@
324@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/user.Po@am__quote@
325@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usrhooks.Po@am__quote@
326
327.c.o:
328@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
329@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
330@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
331@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
332@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
333
334.c.obj:
335@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
336@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
337@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
338@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
339@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
340
341ID: $(am__tagged_files)
342 $(am__define_uniq_tagged_files); mkid -fID $$unique
343tags: tags-am
344TAGS: tags
345
346tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
347 set x; \
348 here=`pwd`; \
349 $(am__define_uniq_tagged_files); \
350 shift; \
351 if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
352 test -n "$$unique" || unique=$$empty_fix; \
353 if test $$# -gt 0; then \
354 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
355 "$$@" $$unique; \
356 else \
357 $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
358 $$unique; \
359 fi; \
360 fi
361ctags: ctags-am
362
363CTAGS: ctags
364ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
365 $(am__define_uniq_tagged_files); \
366 test -z "$(CTAGS_ARGS)$$unique" \
367 || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
368 $$unique
369
370GTAGS:
371 here=`$(am__cd) $(top_builddir) && pwd` \
372 && $(am__cd) $(top_srcdir) \
373 && gtags -i $(GTAGS_ARGS) "$$here"
374cscopelist: cscopelist-am
375
376cscopelist-am: $(am__tagged_files)
377 list='$(am__tagged_files)'; \
378 case "$(srcdir)" in \
379 [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
380 *) sdir=$(subdir)/$(srcdir) ;; \
381 esac; \
382 for i in $$list; do \
383 if test -f "$$i"; then \
384 echo "$(subdir)/$$i"; \
385 else \
386 echo "$$sdir/$$i"; \
387 fi; \
388 done >> $(top_builddir)/cscope.files
389
390distclean-tags:
391 -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
392
393distdir: $(DISTFILES)
394 @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
395 topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
396 list='$(DISTFILES)'; \
397 dist_files=`for file in $$list; do echo $$file; done | \
398 sed -e "s|^$$srcdirstrip/||;t" \
399 -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
400 case $$dist_files in \
401 */*) $(MKDIR_P) `echo "$$dist_files" | \
402 sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
403 sort -u` ;; \
404 esac; \
405 for file in $$dist_files; do \
406 if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
407 if test -d $$d/$$file; then \
408 dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
409 if test -d "$(distdir)/$$file"; then \
410 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
411 fi; \
412 if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
413 cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
414 find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
415 fi; \
416 cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
417 else \
418 test -f "$(distdir)/$$file" \
419 || cp -p $$d/$$file "$(distdir)/$$file" \
420 || exit 1; \
421 fi; \
422 done
423check-am: all-am
424check: check-am
425all-am: Makefile $(LIBRARIES)
426installdirs:
427install: install-am
428install-exec: install-exec-am
429install-data: install-data-am
430uninstall: uninstall-am
431
432install-am: all-am
433 @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
434
435installcheck: installcheck-am
436install-strip:
437 if test -z '$(STRIP)'; then \
438 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
439 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
440 install; \
441 else \
442 $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
443 install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
444 "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
445 fi
446mostlyclean-generic:
447
448clean-generic:
449
450distclean-generic:
451 -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
452 -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
453
454maintainer-clean-generic:
455 @echo "This command is intended for maintainers to use"
456 @echo "it deletes files that may require special tools to rebuild."
457clean: clean-am
458
459clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
460
461distclean: distclean-am
462 -rm -rf ./$(DEPDIR)
463 -rm -f Makefile
464distclean-am: clean-am distclean-compile distclean-generic \
465 distclean-tags
466
467dvi: dvi-am
468
469dvi-am:
470
471html: html-am
472
473html-am:
474
475info: info-am
476
477info-am:
478
479install-data-am:
480
481install-dvi: install-dvi-am
482
483install-dvi-am:
484
485install-exec-am:
486
487install-html: install-html-am
488
489install-html-am:
490
491install-info: install-info-am
492
493install-info-am:
494
495install-man:
496
497install-pdf: install-pdf-am
498
499install-pdf-am:
500
501install-ps: install-ps-am
502
503install-ps-am:
504
505installcheck-am:
506
507maintainer-clean: maintainer-clean-am
508 -rm -rf ./$(DEPDIR)
509 -rm -f Makefile
510maintainer-clean-am: distclean-am maintainer-clean-generic
511
512mostlyclean: mostlyclean-am
513
514mostlyclean-am: mostlyclean-compile mostlyclean-generic
515
516pdf: pdf-am
517
518pdf-am:
519
520ps: ps-am
521
522ps-am:
523
524uninstall-am:
525
526.MAKE: install-am install-strip
527
528.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
529 clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \
530 distclean-compile distclean-generic distclean-tags distdir dvi \
531 dvi-am html html-am info info-am install install-am \
532 install-data install-data-am install-dvi install-dvi-am \
533 install-exec install-exec-am install-html install-html-am \
534 install-info install-info-am install-man install-pdf \
535 install-pdf-am install-ps install-ps-am install-strip \
536 installcheck installcheck-am installdirs maintainer-clean \
537 maintainer-clean-generic mostlyclean mostlyclean-compile \
538 mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
539 uninstall-am
540
541.PRECIOUS: Makefile
542
543
544# Tell versions [3.59,3.63) of GNU make to not export all variables.
545# Otherwise a system limit (for SysV at least) may be exceeded.
546.NOEXPORT:
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_al_midi.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_al_midi.h
new file mode 100644
index 0000000000..4e58749882
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_al_midi.h
@@ -0,0 +1,174 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20#ifndef ___AL_MIDI_H
21#define ___AL_MIDI_H
22
23#define NO_ADLIB_DETECTION "NOAL"
24
25#define STEREO_DETUNE 5
26
27#define lobyte( num ) ( ( unsigned )*( ( char * )&( num ) ) )
28#define hibyte( num ) ( ( unsigned )*( ( ( char * )&( num ) ) + 1 ) )
29
30#define AL_VoiceNotFound -1
31
32#define alFreqH 0xb0
33#define alEffects 0xbd
34
35/* Number of slots for the voices on the chip */
36#define NumChipSlots 18
37
38#define NUM_VOICES 9
39#define NUM_CHANNELS 16
40
41#define NOTE_ON 0x2000 /* Used to turn note on or toggle note */
42#define NOTE_OFF 0x0000
43
44#define MAX_VELOCITY 0x7f
45#define MAX_OCTAVE 7
46#define MAX_NOTE ( MAX_OCTAVE * 12 + 11 )
47#define FINETUNE_MAX 31
48#define FINETUNE_RANGE ( FINETUNE_MAX + 1 )
49
50#define PITCHBEND_CENTER 1638400
51
52#define note_off 0x80
53#define note_on 0x90
54#define poly_aftertouch 0xa0
55#define control_change 0xb0
56#define program_chng 0xc0
57#define channel_aftertouch 0xd0
58#define pitch_wheel 0xe0
59
60#define MIDI_VOLUME 7
61#define MIDI_PAN 10
62#define MIDI_DETUNE 94
63#define MIDI_ALL_NOTES_OFF 0x7B
64#define MIDI_RESET_ALL_CONTROLLERS 0x79
65#define MIDI_RPN_MSB 100
66#define MIDI_RPN_LSB 101
67#define MIDI_DATAENTRY_MSB 6
68#define MIDI_DATAENTRY_LSB 38
69#define MIDI_PITCHBEND_RPN 0
70
71enum cromatic_scale
72 {
73 C = 0x157,
74 C_SHARP = 0x16B,
75 D_FLAT = 0x16B,
76 D = 0x181,
77 D_SHARP = 0x198,
78 E_FLAT = 0x198,
79 E = 0x1B0,
80 F_FLAT = 0x1B0,
81 E_SHARP = 0x1CA,
82 F = 0x1CA,
83 F_SHARP = 0x1E5,
84 G_FLAT = 0x1E5,
85 G = 0x202,
86 G_SHARP = 0x220,
87 A_FLAT = 0x220,
88 A = 0x241,
89 A_SHARP = 0x263,
90 B_FLAT = 0x263,
91 B = 0x287,
92 C_FLAT = 0x287,
93 B_SHARP = 0x2AE,
94 };
95
96/* Definition of octave information to be ORed onto F-Number */
97
98enum octaves
99 {
100 OCTAVE_0 = 0x0000,
101 OCTAVE_1 = 0x0400,
102 OCTAVE_2 = 0x0800,
103 OCTAVE_3 = 0x0C00,
104 OCTAVE_4 = 0x1000,
105 OCTAVE_5 = 0x1400,
106 OCTAVE_6 = 0x1800,
107 OCTAVE_7 = 0x1C00
108 };
109
110typedef struct VOICE
111 {
112 struct VOICE *next;
113 struct VOICE *prev;
114
115 unsigned num;
116 unsigned key;
117 unsigned velocity;
118 unsigned channel;
119 unsigned pitchleft;
120 unsigned pitchright;
121 int timbre;
122 int port;
123 unsigned status;
124 } VOICE;
125
126typedef struct
127 {
128 VOICE *start;
129 VOICE *end;
130 } VOICELIST;
131
132typedef struct
133 {
134 VOICELIST Voices;
135 int Timbre;
136 int Pitchbend;
137 int KeyOffset;
138 unsigned KeyDetune;
139 unsigned Volume;
140 unsigned EffectiveVolume;
141 int Pan;
142 int Detune;
143 unsigned RPN;
144 short PitchBendRange;
145 short PitchBendSemiTones;
146 short PitchBendHundreds;
147 } CHANNEL;
148
149typedef struct
150 {
151 unsigned char SAVEK[ 2 ];
152 unsigned char Level[ 2 ];
153 unsigned char Env1[ 2 ];
154 unsigned char Env2[ 2 ];
155 unsigned char Wave[ 2 ];
156 unsigned char Feedback;
157 signed char Transpose;
158 signed char Velocity;
159 } TIMBRE;
160
161extern TIMBRE ADLIB_TimbreBank[ 256 ];
162
163static void AL_ResetVoices( void );
164static void AL_CalcPitchInfo( void );
165static void AL_SetVoiceTimbre( int voice );
166static void AL_SetVoiceVolume( int voice );
167static int AL_AllocVoice( void );
168static int AL_GetVoice( int channel, int key );
169static void AL_SetVoicePitch( int voice );
170static void AL_SetChannelVolume( int channel, int volume );
171static void AL_SetChannelPan( int channel, int pan );
172static void AL_SetChannelDetune( int channel, int detune );
173
174#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_blaster.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_blaster.h
new file mode 100644
index 0000000000..49f8220a1c
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_blaster.h
@@ -0,0 +1,133 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: _BLASTER.H
22
23 author: James R. Dose
24 date: February 4, 1994
25
26 Private header for for BLASTER.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef ___BLASTER_H
32#define ___BLASTER_H
33
34#define VALID ( 1 == 1 )
35#define INVALID ( !VALID )
36
37#define TRUE ( 1 == 1 )
38#define FALSE ( !TRUE )
39
40#define YES ( 1 == 1 )
41#define NO ( !YES )
42
43#define lobyte( num ) ( ( int )*( ( char * )&( num ) ) )
44#define hibyte( num ) ( ( int )*( ( ( char * )&( num ) ) + 1 ) )
45
46#define BLASTER_MixerAddressPort 0x04
47#define BLASTER_MixerDataPort 0x05
48#define BLASTER_ResetPort 0x06
49#define BLASTER_ReadPort 0x0A
50#define BLASTER_WritePort 0x0C
51#define BLASTER_DataAvailablePort 0x0E
52#define BLASTER_Ready 0xAA
53#define BLASTER_16BitDMAAck 0x0F
54
55#define MIXER_DSP4xxISR_Ack 0x82
56#define MIXER_DSP4xxISR_Enable 0x83
57#define MIXER_MPU401_INT 0x4
58#define MIXER_16BITDMA_INT 0x2
59#define MIXER_8BITDMA_INT 0x1
60#define MIXER_DisableMPU401Interrupts 0xB
61#define MIXER_SBProOutputSetting 0x0E
62#define MIXER_SBProStereoFlag 0x02
63#define MIXER_SBProVoice 0x04
64#define MIXER_SBProMidi 0x26
65#define MIXER_SB16VoiceLeft 0x32
66#define MIXER_SB16VoiceRight 0x33
67#define MIXER_SB16MidiLeft 0x34
68#define MIXER_SB16MidiRight 0x35
69
70#define DSP_Version1xx 0x0100
71#define DSP_Version2xx 0x0200
72#define DSP_Version201 0x0201
73#define DSP_Version3xx 0x0300
74#define DSP_Version4xx 0x0400
75#define DSP_SB16Version DSP_Version4xx
76
77#define DSP_MaxNormalRate 22000
78#define DSP_MaxHighSpeedRate 44000
79
80#define DSP_8BitAutoInitRecord 0x2c
81#define DSP_8BitHighSpeedAutoInitRecord 0x98
82#define DSP_Old8BitADC 0x24
83#define DSP_8BitAutoInitMode 0x1c
84#define DSP_8BitHighSpeedAutoInitMode 0x90
85#define DSP_SetBlockLength 0x48
86#define DSP_Old8BitDAC 0x14
87#define DSP_16BitDAC 0xB6
88#define DSP_8BitDAC 0xC6
89#define DSP_8BitADC 0xCe
90#define DSP_SetTimeConstant 0x40
91#define DSP_Set_DA_Rate 0x41
92#define DSP_Set_AD_Rate 0x42
93#define DSP_Halt8bitTransfer 0xd0
94#define DSP_Continue8bitTransfer 0xd4
95#define DSP_Halt16bitTransfer 0xd5
96#define DSP_Continue16bitTransfer 0xd6
97#define DSP_SpeakerOn 0xd1
98#define DSP_SpeakerOff 0xd3
99#define DSP_GetVersion 0xE1
100#define DSP_Reset 0xFFFF
101
102#define DSP_SignedBit 0x10
103#define DSP_StereoBit 0x20
104
105#define DSP_UnsignedMonoData 0x00
106#define DSP_SignedMonoData ( DSP_SignedBit )
107#define DSP_UnsignedStereoData ( DSP_StereoBit )
108#define DSP_SignedStereoData ( DSP_SignedBit | DSP_StereoBit )
109
110#define BlasterEnv_Address 'A'
111#define BlasterEnv_Interrupt 'I'
112#define BlasterEnv_8bitDma 'D'
113#define BlasterEnv_16bitDma 'H'
114#define BlasterEnv_Type 'T'
115#define BlasterEnv_Midi 'P'
116#define BlasterEnv_EmuAddress 'E'
117
118#define CalcTimeConstant( rate, samplesize ) \
119 ( ( 65536L - ( 256000000L / ( ( samplesize ) * ( rate ) ) ) ) >> 8 )
120
121#define CalcSamplingRate( tc ) \
122 ( 256000000L / ( 65536L - ( tc << 8 ) ) )
123
124typedef struct
125 {
126 int IsSupported;
127 int HasMixer;
128 int MaxMixMode;
129 int MinSamplingRate;
130 int MaxSamplingRate;
131 } CARD_CAPABILITY;
132
133#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_guswave.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_guswave.h
new file mode 100644
index 0000000000..53cbb37460
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_guswave.h
@@ -0,0 +1,164 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 file: _GUSWAVE.H
22
23 author: James R. Dose
24 date: March 23, 1994
25
26 Private header for GUSWAVE.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef ___GUSWAVE_H
32#define ___GUSWAVE_H
33
34#define TRUE ( 1 == 1 )
35#define FALSE ( !TRUE )
36
37#define LOADDS _loadds
38
39#define VOC_8BIT 0x0
40#define VOC_CT4_ADPCM 0x1
41#define VOC_CT3_ADPCM 0x2
42#define VOC_CT2_ADPCM 0x3
43#define VOC_16BIT 0x4
44#define VOC_ALAW 0x6
45#define VOC_MULAW 0x7
46#define VOC_CREATIVE_ADPCM 0x200
47
48#define MAX_BLOCK_LENGTH 0x8000
49
50#define GF1BSIZE 896L /* size of buffer per wav on GUS */
51//#define GF1BSIZE 512L /* size of buffer per wav on GUS */
52
53//#define VOICES 8 /* maximum amount of concurrent wav files */
54#define VOICES 2 /* maximum amount of concurrent wav files */
55#define MAX_VOICES 32 /* This should always be 32 */
56#define MAX_VOLUME 4095
57#define BUFFER 2048U /* size of DMA buffer for patch loading */
58
59typedef enum
60 {
61 Raw,
62 VOC,
63 DemandFeed,
64 WAV
65 } wavedata;
66
67typedef enum
68 {
69 NoMoreData,
70 KeepPlaying,
71 SoundDone
72 } playbackstatus;
73
74
75typedef volatile struct VoiceNode
76 {
77 struct VoiceNode *next;
78 struct VoiceNode *prev;
79
80 wavedata wavetype;
81 int bits;
82 playbackstatus ( *GetSound )( struct VoiceNode *voice );
83
84 int num;
85
86 unsigned long mem; /* location in ultrasound memory */
87 int Active; /* this instance in use */
88 int GF1voice; /* handle to active voice */
89
90 char *NextBlock;
91 char *LoopStart;
92 char *LoopEnd;
93 unsigned LoopCount;
94 unsigned long LoopSize;
95 unsigned long BlockLength;
96
97 unsigned long PitchScale;
98
99 unsigned char *sound;
100 unsigned long length;
101 unsigned long SamplingRate;
102 unsigned long RateScale;
103 int Playing;
104
105 int handle;
106 int priority;
107
108 void ( *DemandFeed )( char **ptr, unsigned long *length );
109
110 unsigned long callbackval;
111
112 int Volume;
113 int Pan;
114 }
115VoiceNode;
116
117typedef struct
118 {
119 VoiceNode *start;
120 VoiceNode *end;
121 }
122voicelist;
123
124typedef volatile struct voicestatus
125 {
126 VoiceNode *Voice;
127 int playing;
128 }
129voicestatus;
130
131typedef struct
132 {
133 char RIFF[ 4 ];
134 unsigned long file_size;
135 char WAVE[ 4 ];
136 char fmt[ 4 ];
137 unsigned long format_size;
138} __attribute__((packed)) riff_header;
139
140typedef struct
141 {
142 unsigned short wFormatTag;
143 unsigned short nChannels;
144 unsigned long nSamplesPerSec;
145 unsigned long nAvgBytesPerSec;
146 unsigned short nBlockAlign;
147 unsigned short nBitsPerSample;
148 } __attribute__((packed)) format_header;
149
150typedef struct
151 {
152 unsigned char DATA[ 4 ];
153 unsigned long size;
154 } __attribute__((packed)) data_header;
155
156playbackstatus GUSWAVE_GetNextVOCBlock( VoiceNode *voice );
157VoiceNode *GUSWAVE_GetVoice( int handle );
158
159int GUSWAVE_Play( VoiceNode *voice, int angle, int volume, int channels );
160
161VoiceNode *GUSWAVE_AllocVoice( int priority );
162static int GUSWAVE_InitVoices( void );
163
164#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_midi.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_midi.h
new file mode 100644
index 0000000000..d96bd1e8c2
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_midi.h
@@ -0,0 +1,290 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: _MIDI.H
22
23 author: James R. Dose
24 date: May 25, 1994
25
26 Private header for MIDI.C. Midi song file playback routines.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef ___MIDI_H
32#define ___MIDI_H
33
34#define RELATIVE_BEAT( measure, beat, tick ) \
35 ( ( tick ) + ( ( beat ) << 9 ) + ( ( measure ) << 16 ) )
36
37//Bobby Prince thinks this may be 100
38//#define GENMIDI_DefaultVolume 100
39#define GENMIDI_DefaultVolume 90
40
41#define MAX_FORMAT 1
42
43#define NUM_MIDI_CHANNELS 16
44
45#define TIME_PRECISION 16
46
47#define MIDI_HEADER_SIGNATURE 0x6468544d // "MThd"
48#define MIDI_TRACK_SIGNATURE 0x6b72544d // "MTrk"
49
50#define MIDI_VOLUME 7
51#define MIDI_PAN 10
52#define MIDI_DETUNE 94
53#define MIDI_RHYTHM_CHANNEL 9
54#define MIDI_RPN_MSB 100
55#define MIDI_RPN_LSB 101
56#define MIDI_DATAENTRY_MSB 6
57#define MIDI_DATAENTRY_LSB 38
58#define MIDI_PITCHBEND_MSB 0
59#define MIDI_PITCHBEND_LSB 0
60#define MIDI_RUNNING_STATUS 0x80
61#define MIDI_NOTE_OFF 0x8
62#define MIDI_NOTE_ON 0x9
63#define MIDI_POLY_AFTER_TCH 0xA
64#define MIDI_CONTROL_CHANGE 0xB
65#define MIDI_PROGRAM_CHANGE 0xC
66#define MIDI_AFTER_TOUCH 0xD
67#define MIDI_PITCH_BEND 0xE
68#define MIDI_SPECIAL 0xF
69#define MIDI_SYSEX 0xF0
70#define MIDI_SYSEX_CONTINUE 0xF7
71#define MIDI_META_EVENT 0xFF
72#define MIDI_END_OF_TRACK 0x2F
73#define MIDI_TEMPO_CHANGE 0x51
74#define MIDI_TIME_SIGNATURE 0x58
75#define MIDI_RESET_ALL_CONTROLLERS 0x79
76#define MIDI_ALL_NOTES_OFF 0x7b
77#define MIDI_MONO_MODE_ON 0x7E
78#define MIDI_SYSTEM_RESET 0xFF
79
80#define GET_NEXT_EVENT( track, data ) \
81 ( data ) = *( track )->pos; \
82 ( track )->pos += 1
83
84#define GET_MIDI_CHANNEL( event ) ( ( event ) & 0xf )
85#define GET_MIDI_COMMAND( event ) ( ( event ) >> 4 )
86
87#define EMIDI_INFINITE -1
88#define EMIDI_END_LOOP_VALUE 127
89#define EMIDI_ALL_CARDS 127
90#define EMIDI_INCLUDE_TRACK 110
91#define EMIDI_EXCLUDE_TRACK 111
92#define EMIDI_PROGRAM_CHANGE 112
93#define EMIDI_VOLUME_CHANGE 113
94#define EMIDI_CONTEXT_START 114
95#define EMIDI_CONTEXT_END 115
96#define EMIDI_LOOP_START 116
97#define EMIDI_LOOP_END 117
98#define EMIDI_SONG_LOOP_START 118
99#define EMIDI_SONG_LOOP_END 119
100
101#define EMIDI_GeneralMIDI 0
102#define EMIDI_SoundCanvas 1
103#define EMIDI_AWE32 2
104#define EMIDI_WaveBlaster 3
105#define EMIDI_SoundBlaster 4
106#define EMIDI_ProAudio 5
107#define EMIDI_SoundMan16 6
108#define EMIDI_Adlib 7
109#define EMIDI_Soundscape 8
110#define EMIDI_Ultrasound 9
111
112#define EMIDI_AffectsCurrentCard( c, type ) \
113 ( ( ( c ) == EMIDI_ALL_CARDS ) || ( ( c ) == ( type ) ) )
114
115
116#define EMIDI_NUM_CONTEXTS 7
117typedef struct
118 {
119 unsigned char *pos;
120 unsigned char *loopstart;
121 short loopcount;
122 short RunningStatus;
123 unsigned time;
124 long FPSecondsPerTick;
125 short tick;
126 short beat;
127 short measure;
128 short BeatsPerMeasure;
129 short TicksPerBeat;
130 short TimeBase;
131 long delay;
132 short active;
133 } songcontext;
134
135typedef struct
136 {
137 unsigned char *start;
138 unsigned char *pos;
139
140 long delay;
141 short active;
142 short RunningStatus;
143
144 short currentcontext;
145 songcontext context[ EMIDI_NUM_CONTEXTS ];
146
147 char EMIDI_IncludeTrack;
148 char EMIDI_ProgramChange;
149 char EMIDI_VolumeChange;
150 } track;
151
152static long _MIDI_ReadNumber( void *from, size_t size );
153static long _MIDI_ReadDelta( track *ptr );
154static void _MIDI_ResetTracks( void );
155static void _MIDI_AdvanceTick( void );
156static void _MIDI_MetaEvent( track *Track );
157static void _MIDI_SysEx( track *Track );
158static int _MIDI_InterpretControllerInfo( track *Track, int TimeSet,
159 int channel, int c1, int c2 );
160//static
161 void _MIDI_ServiceRoutine( task *Task );
162static int _MIDI_SendControlChange( int channel, int c1, int c2 );
163static void _MIDI_SetChannelVolume( int channel, int volume );
164static void _MIDI_SendChannelVolumes( void );
165static int _MIDI_ProcessNextTick( void );
166static void _MIDI_InitEMIDI( void );
167
168/*
169 if ( c1 == EMIDI_LOOP_START )
170 {
171 if ( c2 == 0 )
172 {
173 Track->context[ 0 ].loopcount = EMIDI_INFINITE;
174 }
175 else
176 {
177 Track->context[ 0 ].loopcount = c2;
178 }
179
180 Track->context[ 0 ].pos = Track->pos;
181 Track->context[ 0 ].loopstart = Track->pos;
182 Track->context[ 0 ].RunningStatus = Track->RunningStatus;
183 Track->context[ 0 ].time = _MIDI_Time;
184 Track->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick;
185 Track->context[ 0 ].tick = _MIDI_Tick;
186 Track->context[ 0 ].beat = _MIDI_Beat;
187 Track->context[ 0 ].measure = _MIDI_Measure;
188 Track->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure;
189 Track->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat;
190 Track->context[ 0 ].TimeBase = _MIDI_TimeBase;
191 break;
192 }
193
194 if ( ( c1 == EMIDI_LOOP_END ) &&
195 ( c2 == EMIDI_END_LOOP_VALUE ) )
196 {
197 if ( ( Track->context[ 0 ].loopstart != NULL ) &&
198 ( Track->context[ 0 ].loopcount != 0 ) )
199 {
200 if ( Track->context[ 0 ].loopcount != EMIDI_INFINITE )
201 {
202 Track->context[ 0 ].loopcount--;
203 }
204
205 Track->pos = Track->context[ 0 ].loopstart;
206 Track->RunningStatus = Track->context[ 0 ].RunningStatus;
207
208 if ( !TimeSet )
209 {
210 _MIDI_Time = Track->context[ 0 ].time;
211 _MIDI_FPSecondsPerTick = Track->context[ 0 ].FPSecondsPerTick;
212 _MIDI_Tick = Track->context[ 0 ].tick;
213 _MIDI_Beat = Track->context[ 0 ].beat;
214 _MIDI_Measure = Track->context[ 0 ].measure;
215 _MIDI_BeatsPerMeasure = Track->context[ 0 ].BeatsPerMeasure;
216 _MIDI_TicksPerBeat = Track->context[ 0 ].TicksPerBeat;
217 _MIDI_TimeBase = Track->context[ 0 ].TimeBase;
218 TimeSet = TRUE;
219 }
220 }
221 break;
222 }
223
224 if ( c1 == MIDI_MONO_MODE_ON )
225 {
226 Track->pos++;
227 }
228
229 if ( ( c1 == MIDI_VOLUME ) && ( !Track->EMIDI_VolumeChange ) )
230 {
231 _MIDI_SetChannelVolume( channel, c2 );
232 break;
233 }
234 else if ( ( c1 == EMIDI_VOLUME_CHANGE ) &&
235 ( Track->EMIDI_VolumeChange ) )
236 {
237 _MIDI_SetChannelVolume( channel, c2 );
238 break;
239 }
240
241 if ( ( c1 == EMIDI_PROGRAM_CHANGE ) &&
242 ( Track->EMIDI_ProgramChange ) )
243 {
244 _MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c2 & 0x7f ] );
245 break;
246 }
247
248 if ( c1 == EMIDI_CONTEXT_START )
249 {
250 break;
251 }
252
253 if ( c1 == EMIDI_CONTEXT_END )
254 {
255 if ( ( Track->currentcontext != _MIDI_Context ) ||
256 ( Track->context[ _MIDI_Context ].pos == NULL )
257 {
258 break;
259 }
260
261 Track->currentcontext = _MIDI_Context;
262 Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart;
263 Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount;
264 Track->pos = Track->context[ _MIDI_Context ].pos;
265 Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus;
266
267 if ( TimeSet )
268 {
269 break;
270 }
271
272 _MIDI_Time = Track->context[ _MIDI_Context ].time;
273 _MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick;
274 _MIDI_Tick = Track->context[ _MIDI_Context ].tick;
275 _MIDI_Beat = Track->context[ _MIDI_Context ].beat;
276 _MIDI_Measure = Track->context[ _MIDI_Context ].measure;
277 _MIDI_BeatsPerMeasure = Track->context[ _MIDI_Context ].BeatsPerMeasure;
278 _MIDI_TicksPerBeat = Track->context[ _MIDI_Context ].TicksPerBeat;
279 _MIDI_TimeBase = Track->context[ _MIDI_Context ].TimeBase;
280 TimeSet = TRUE;
281 break;
282 }
283
284 if ( _MIDI_Funcs->ControlChange )
285 {
286 _MIDI_Funcs->ControlChange( channel, c1, c2 );
287 }
288 */
289
290#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_multivc.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_multivc.h
new file mode 100644
index 0000000000..27f8d30879
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_multivc.h
@@ -0,0 +1,318 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 file: _MULTIVC.H
22
23 author: James R. Dose
24 date: December 20, 1993
25
26 Private header for MULTIVOC.C
27
28 (c) Copyright 1993 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef ___MULTIVC_H
32#define ___MULTIVC_H
33
34#define TRUE ( 1 == 1 )
35#define FALSE ( !TRUE )
36
37#define VOC_8BIT 0x0
38#define VOC_CT4_ADPCM 0x1
39#define VOC_CT3_ADPCM 0x2
40#define VOC_CT2_ADPCM 0x3
41#define VOC_16BIT 0x4
42#define VOC_ALAW 0x6
43#define VOC_MULAW 0x7
44#define VOC_CREATIVE_ADPCM 0x200
45
46#define T_SIXTEENBIT_STEREO 0
47#define T_8BITS 1
48#define T_MONO 2
49#define T_16BITSOURCE 4
50#define T_LEFTQUIET 8
51#define T_RIGHTQUIET 16
52#define T_DEFAULT T_SIXTEENBIT_STEREO
53
54#define MV_MaxPanPosition 31
55#define MV_NumPanPositions ( MV_MaxPanPosition + 1 )
56#define MV_MaxTotalVolume 255
57//#define MV_MaxVolume 63
58//#define MV_NumVoices 8
59
60#define MIX_VOLUME( volume ) \
61 ( ( max( 0, min( ( volume ), 255 ) ) * ( MV_MaxVolume + 1 ) ) >> 8 )
62// ( ( max( 0, min( ( volume ), 255 ) ) ) >> 2 )
63
64//#define SILENCE_16BIT 0x80008000
65#define SILENCE_16BIT 0
66#define SILENCE_8BIT 0x80808080
67//#define SILENCE_16BIT_PAS 0
68
69#define MixBufferSize 256
70
71#define NumberOfBuffers 16
72#define TotalBufferSize ( MixBufferSize * NumberOfBuffers )
73
74#define PI 3.1415926536
75
76typedef enum
77 {
78 Raw,
79 VOC,
80 DemandFeed,
81 WAV
82 } wavedata;
83
84typedef enum
85 {
86 NoMoreData,
87 KeepPlaying
88 } playbackstatus;
89
90
91typedef struct VoiceNode
92 {
93 struct VoiceNode *next;
94 struct VoiceNode *prev;
95
96 wavedata wavetype;
97 char bits;
98
99 playbackstatus ( *GetSound )( struct VoiceNode *voice );
100
101 void ( *mix )( unsigned long position, unsigned long rate,
102 uint8_t *start, unsigned long length );
103
104 uint8_t *NextBlock;
105 uint8_t *LoopStart;
106 uint8_t *LoopEnd;
107 unsigned LoopCount;
108 unsigned long LoopSize;
109 unsigned long BlockLength;
110
111 unsigned long PitchScale;
112 unsigned long FixedPointBufferSize;
113
114 uint8_t *sound;
115 unsigned long length;
116 uint32_t SamplingRate;
117 unsigned long RateScale;
118 unsigned long position;
119 int Playing;
120
121 int handle;
122 int priority;
123
124 void ( *DemandFeed )( char **ptr, uint32_t *length );
125
126#if 0
127 short *LeftVolume;
128 short *RightVolume;
129#else
130 int LeftVolume;
131 int RightVolume;
132#endif
133
134 int GLast;
135 int GPos;
136 int GVal[4];
137
138 unsigned long callbackval;
139
140 } VoiceNode;
141
142typedef struct
143 {
144 VoiceNode *start;
145 VoiceNode *end;
146 } VList;
147
148typedef struct
149 {
150 unsigned char left;
151 unsigned char right;
152 } Pan;
153
154typedef signed short MONO16;
155typedef signed char MONO8;
156
157typedef struct
158 {
159 MONO16 left;
160 MONO16 right;
161// unsigned short left;
162// unsigned short right;
163 } STEREO16;
164
165typedef struct
166 {
167 MONO16 left;
168 MONO16 right;
169 } SIGNEDSTEREO16;
170
171typedef struct
172 {
173// MONO8 left;
174// MONO8 right;
175 char left;
176 char right;
177 } STEREO8;
178
179typedef struct
180 {
181 char RIFF[ 4 ];
182 unsigned long file_size;
183 char WAVE[ 4 ];
184 char fmt[ 4 ];
185 unsigned long format_size;
186 } riff_header;
187
188typedef struct
189 {
190 unsigned short wFormatTag;
191 unsigned short nChannels;
192 unsigned long nSamplesPerSec;
193 unsigned long nAvgBytesPerSec;
194 unsigned short nBlockAlign;
195 unsigned short nBitsPerSample;
196 } format_header;
197
198typedef struct
199 {
200 char DATA[ 4 ];
201 unsigned long size;
202 } data_header;
203
204typedef MONO8 VOLUME8[ 256 ];
205typedef MONO16 VOLUME16[ 256 ];
206
207// typedef char HARSH_CLIP_TABLE_8[ MV_NumVoices * 256 ];
208
209//static void MV_Mix( VoiceNode *voice);
210//static void MV_PlayVoice( VoiceNode *voice );
211//static void MV_StopVoice( VoiceNode *voice );
212//static void MV_ServiceVoc( void );
213
214//static playbackstatus MV_GetNextVOCBlock( VoiceNode *voice );
215//static playbackstatus MV_GetNextDemandFeedBlock( VoiceNode *voice );
216//static playbackstatus MV_GetNextRawBlock( VoiceNode *voice );
217//static playbackstatus MV_GetNextWAVBlock( VoiceNode *voice );
218
219//static void MV_ServiceRecord( void );
220//static VoiceNode *MV_GetVoice( int handle );
221//static VoiceNode *MV_AllocVoice( int priority );
222
223//#if 0
224//static short *MV_GetVolumeTable( int vol );
225//#else
226//static int MV_GetVolumeTable( int vol );
227//#endif
228
229void MV_SetVoiceMixMode( VoiceNode *voice );
230
231//static void MV_SetVoicePitch( VoiceNode *voice, unsigned long rate, int pitchoffset );
232//static void MV_CalcVolume( int MaxLevel );
233//static void MV_CalcPanTable( void );
234
235#ifdef PLAT_DOS
236#define ATR_INDEX 0x3c0
237#define STATUS_REGISTER_1 0x3da
238
239#define SetBorderColor(color) \
240 { \
241 inp (STATUS_REGISTER_1); \
242 outp (ATR_INDEX,0x31); \
243 outp (ATR_INDEX,color); \
244 }
245#endif
246
247void ClearBuffer_DW( void *ptr, unsigned data, int length );
248
249#ifdef PLAT_DOS
250#pragma aux ClearBuffer_DW = \
251 "cld", \
252 "push es", \
253 "push ds", \
254 "pop es", \
255 "rep stosd", \
256 "pop es", \
257parm [ edi ] [ eax ] [ ecx ] modify exact [ ecx edi ];
258#endif
259
260/*
261void MV_Mix8BitMono( unsigned long position, unsigned long rate,
262 const char *start, unsigned long length );
263
264void MV_Mix8BitStereo( unsigned long position,
265 unsigned long rate, const char *start, unsigned long length );
266
267void MV_Mix16BitMono( unsigned long position,
268 unsigned long rate, const char *start, unsigned long length );
269
270void MV_Mix16BitStereo( unsigned long position,
271 unsigned long rate, const char *start, unsigned long length );
272
273void MV_Mix16BitMono16( unsigned long position,
274 unsigned long rate, const char *start, unsigned long length );
275
276void MV_Mix8BitMono16( unsigned long position, unsigned long rate,
277 const char *start, unsigned long length );
278
279void MV_Mix8BitStereo16( unsigned long position,
280 unsigned long rate, const char *start, unsigned long length );
281
282void MV_Mix16BitStereo16( unsigned long position,
283 unsigned long rate, const char *start, unsigned long length );
284*/
285
286void MV_MixFPMono8( unsigned long position, unsigned long rate,
287 const char *start, unsigned long length );
288
289void MV_MixFPMono16( unsigned long position, unsigned long rate,
290 const char *start, unsigned long length );
291
292void MV_MixFPStereo8( unsigned long position, unsigned long rate,
293 const char *start, unsigned long length );
294
295void MV_MixFPStereo16( unsigned long position, unsigned long rate,
296 const char *start, unsigned long length );
297
298void MV_FPReverb(int volume);
299
300void MV_FPReverbFree(void);
301
302void MV_16BitDownmix(char *dest, int count);
303
304void MV_8BitDownmix(char *dest, int count);
305
306/*
307void MV_16BitReverbFast( const char *src, char *dest, int count, int shift );
308
309void MV_8BitReverbFast( const signed char *src, signed char *dest, int count, int shift );
310*/
311#ifdef PLAT_DOS
312#pragma aux MV_16BitReverb parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
313#pragma aux MV_8BitReverb parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
314#pragma aux MV_16BitReverbFast parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
315#pragma aux MV_8BitReverbFast parm [eax] [edx] [ebx] [ecx] modify exact [eax ebx ecx edx esi edi]
316#endif
317
318#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_pas16.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_pas16.h
new file mode 100644
index 0000000000..ad1827da10
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_pas16.h
@@ -0,0 +1,250 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: _PAS16.H
22
23 author: James R. Dose
24 date: March 27, 1994
25
26 Private header for for PAS16.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef ___PAS16_H
32#define ___PAS16_H
33
34#define TRUE ( 1 == 1 )
35#define FALSE ( !TRUE )
36
37#define VALID ( 1 == 1 )
38#define INVALID ( !VALID )
39
40#define lobyte( num ) ( ( int )*( ( char * )&( num ) ) )
41#define hibyte( num ) ( ( int )*( ( ( char * )&( num ) ) + 1 ) )
42
43#define STEREO 1
44#define SIXTEEN_BIT 2
45
46#define MONO_8BIT 0
47#define STEREO_8BIT ( STEREO )
48#define MONO_16BIT ( SIXTEEN_BIT )
49#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
50
51#define PAS_MaxMixMode STEREO_16BIT
52
53#define MONO_8BIT_SAMPLE_SIZE 1
54#define MONO_16BIT_SAMPLE_SIZE 2
55#define STEREO_8BIT_SAMPLE_SIZE ( 2 * MONO_8BIT_SAMPLE_SIZE )
56#define STEREO_16BIT_SAMPLE_SIZE ( 2 * MONO_16BIT_SAMPLE_SIZE )
57
58#define PAS_RevisionBits 0xe0
59
60#define AudioFilterControl 0xb8a
61#define InterruptControl 0xb8b
62#define InterruptStatus 0xb89
63#define PCMDataRegister 0xf88
64#define CrossChannelControl 0xf8a
65#define SampleRateTimer 0x1388
66#define SampleBufferCount 0x1389
67#define LocalSpeakerTimerCount 0x138a
68#define LocalTimerControl 0x138b
69#define SampleSizeConfiguration 0x8389
70
71#define AudioMuteFlag 0x20
72#define SampleRateTimerGateFlag 0x40
73#define SampleBufferCountGateFlag 0x80
74
75#define SampleRateInterruptFlag 0x04
76#define SampleBufferInterruptFlag 0x08
77
78#define PAS_SampleSizeMask 0xf3
79#define PAS_SignedSampleMask 0xe3
80#define PAS_16BitSampleFlag 0x04
81#define PAS_UnsignedSampleFlag 0x10
82//bSC2msbinv equ 00010000b ;; invert MSB from standard method
83
84#define PAS_OverSamplingMask 0xfc
85
86#define PAS_1xOverSampling 0x00
87#define PAS_2xOverSampling 0x01
88#define PAS_4xOverSampling 0x03
89
90#define PAS_StereoFlag 0x20
91
92#define PAS_AudioMuteFlag 0x20
93
94#define DEFAULT_BASE ( 0x0388 ^ 0x388 ) /* default base I/O address */
95#define ALT_BASE_1 ( 0x0384 ^ 0x388 ) /* first alternate address */
96#define ALT_BASE_2 ( 0x038C ^ 0x388 ) /* second alternate address */
97#define ALT_BASE_3 ( 0x0288 ^ 0x388 ) /* third alternate address */
98
99#define PAS_DMAEnable 0x80
100#define PAS_ChannelConnectMask 0x0f
101#define PAS_PCMStartDAC 0xD0
102#define PAS_PCMStartADC 0xC0
103#define PAS_PCMStopMask 0x3f
104
105#define RECORD 0
106#define PLAYBACK 1
107
108#define SelectSampleRateTimer 0x36 // 00110110b
109#define SelectSampleBufferCount 0x74 // 01110100b
110
111#define CalcTimeInterval( rate ) \
112 ( 1193180UL / ( rate ) )
113
114#define CalcSamplingRate( interval ) \
115 ( 1193180UL / ( interval ) )
116
117#define MV_Signature 0x4d56
118#define MV_SoundInt 0x2f
119#define MV_CheckForDriver 0xbc00
120#define MV_GetVersion 0xbc01
121#define MV_GetPointerToStateTable 0xbc02
122#define MV_GetPointerToFunctionTable 0xbc03
123#define MV_GetDmaIrqInt 0xbc04
124#define MV_SendCommandStructure 0xbc05
125#define MV_GetDriverMessage 0xbc06
126#define MV_SetHotkeyScanCodes 0xbc0a
127#define MV_GetPathToDriver 0xbc0b
128
129#define OUTPUTMIXER 0x00 /* output mixer H/W select */
130#define INPUTMIXER 0x40 /* input mixer select */
131#define DEFMIXER -1 /* use last mixer selected */
132
133/* left channel values */
134
135#define L_FM 0x01
136#define L_IMIXER 0x02
137#define L_EXT 0x03
138#define L_INT 0x04
139#define L_MIC 0x05
140#define L_PCM 0x06
141#define L_SPEAKER 0x07
142#define L_FREE 0x00
143#define L_SBDAC 0x00
144
145/* right channel values */
146
147#define R_FM 0x08
148#define R_IMIXER 0x09
149#define R_EXT 0x0A
150#define R_INT 0x0B
151#define R_MIC 0x0C
152#define R_PCM 0x0D
153#define R_SPEAKER 0x0E
154#define R_FREE 0x0F
155#define R_SBDAC 0x0F
156
157typedef struct
158 {
159 unsigned char sysspkrtmr; /* 42 System Speaker Timer Address */
160 unsigned char systmrctlr; /* 43 System Timer Control */
161 unsigned char sysspkrreg; /* 61 System Speaker Register */
162 unsigned char joystick; /* 201 Joystick Register */
163 unsigned char lfmaddr; /* 388 Left FM Synth Address */
164 unsigned char lfmdata; /* 389 Left FM Synth Data */
165 unsigned char rfmaddr; /* 38A Right FM Synth Address */
166 unsigned char rfmdata; /* 38B Right FM Synth Data */
167 unsigned char dfmaddr; /* 788 Dual FM Synth Address */
168 unsigned char dfmdata; /* 789 Dual FM Synth Data */
169 unsigned char RESRVD1[1]; /* reserved */
170 unsigned char paudiomixr; /* 78B Paralllel Audio Mixer Control*/
171 unsigned char audiomixr; /* B88 Audio Mixer Control */
172 unsigned char intrctlrst; /* B89 Interrupt Status */
173 unsigned char audiofilt; /* B8A Audio Filter Control */
174 unsigned char intrctlr; /* B8B Interrupt Control */
175 unsigned char pcmdata; /* F88 PCM Data I/O Register */
176 unsigned char RESRVD2; /* reserved */
177 unsigned char crosschannel; /* F8A Cross Channel */
178 unsigned char RESRVD3; /* reserved */
179 unsigned short samplerate; /* 1388 Sample Rate Timer */
180 unsigned short samplecnt; /* 1389 Sample Count Register */
181 unsigned short spkrtmr; /* 138A Shadow Speaker Timer Count */
182 unsigned char tmrctlr; /* 138B Shadow Speaker Timer Control */
183 unsigned char mdirqvect; /* 1788 MIDI IRQ Vector Register */
184 unsigned char mdsysctlr; /* 1789 MIDI System Control Register */
185 unsigned char mdsysstat; /* 178A MIDI IRQ Status Register */
186 unsigned char mdirqclr; /* 178B MIDI IRQ Clear Register */
187 unsigned char mdgroup1; /* 1B88 MIDI Group #1 Register */
188 unsigned char mdgroup2; /* 1B89 MIDI Group #2 Register */
189 unsigned char mdgroup3; /* 1B8A MIDI Group #3 Register */
190 unsigned char mdgroup4; /* 1B8B MIDI Group #4 Register */
191 } MVState;
192
193typedef struct
194 {
195 unsigned long SetMixer;
196 unsigned long SetVolume;
197 unsigned long SetFilter;
198 unsigned long SetCrossChannel;
199 unsigned long GetMixer;
200 unsigned long GetVolume;
201 unsigned long GetFilter;
202 unsigned long GetCrossChannel;
203 unsigned long ReadSound;
204 unsigned long FMSplit;
205 } MVFunc;
206
207int PAS_CheckForDriver( void );
208MVState *PAS_GetStateTable( void );
209MVFunc *PAS_GetFunctionTable( void );
210int PAS_GetCardSettings( void );
211void PAS_EnableInterrupt( void );
212void PAS_DisableInterrupt( void );
213void interrupt far PAS_ServiceInterrupt( void );
214//void interrupt PAS_ServiceInterrupt( void );
215void PAS_Write( int Register, int Data );
216int PAS_Read( int Register );
217void PAS_SetSampleRateTimer( void );
218void PAS_SetSampleBufferCount( void );
219int PAS_SetupDMABuffer( char *BufferPtr, int BufferSize, int mode );
220int PAS_GetFilterSetting( int rate );
221void PAS_BeginTransfer( int mode );
222int PAS_TestAddress( int address );
223int PAS_FindCard( void );
224int PAS_CallMVFunction( unsigned long function, int ebx, int ecx, int edx );
225void PAS_SaveState( void );
226void PAS_RestoreState( void );
227
228
229#pragma aux PAS_TestAddress = \
230 "mov dx, 0b8bh", \
231 "xor dx, ax", \
232 "in al, dx", \
233 "cmp al, 0ffh", \
234 "je TestExit", \
235 "mov ah, al", \
236 "xor al, 0e0h", \
237 "out dx, al", \
238 "jmp TestDelay1", \
239 "TestDelay1:", \
240 "jmp TestDelay2", \
241 "TestDelay2:", \
242 "in al, dx", \
243 "xchg al, ah", \
244 "out dx, al", \
245 "sub al, ah", \
246 "TestExit:", \
247 "and eax, 0ffh" \
248 parm [ eax ] modify exact [ eax dx ];
249
250#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_sndscap.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_sndscap.h
new file mode 100644
index 0000000000..7c1f02a0c8
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/_sndscap.h
@@ -0,0 +1,136 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: _SNDSCAP.H
22
23 author: James R. Dose
24 date: October 26, 1994
25
26 Private header for SNDSCAPE.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef ___SNDSCAP_H
32#define ___SNDSCAP_H
33
34#define VALID ( 1 == 1 )
35#define INVALID ( !VALID )
36
37#define TRUE ( 1 == 1 )
38#define FALSE ( !TRUE )
39
40#define lobyte( num ) ( ( int )*( ( char * )&( num ) ) )
41#define hibyte( num ) ( ( int )*( ( ( char * )&( num ) ) + 1 ) )
42
43#define STEREO 1
44#define SIXTEEN_BIT 2
45
46#define MONO_8BIT 0
47#define STEREO_8BIT ( STEREO )
48#define MONO_16BIT ( SIXTEEN_BIT )
49#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
50
51#define SOUNDSCAPE_MaxMixMode STEREO_16BIT
52
53#define MONO_8BIT_SAMPLE_SIZE 1
54#define MONO_16BIT_SAMPLE_SIZE 2
55#define STEREO_8BIT_SAMPLE_SIZE ( 2 * MONO_8BIT_SAMPLE_SIZE )
56#define STEREO_16BIT_SAMPLE_SIZE ( 2 * MONO_16BIT_SAMPLE_SIZE )
57
58#define SOUNDSCAPE_DefaultSampleRate 11000
59#define SOUNDSCAPE_DefaultMixMode MONO_8BIT
60#define SOUNDSCAPE_MaxIrq 15
61
62/* Ensoniq gate-array chip defines ... */
63#define ODIE 0 /* ODIE gate array */
64#define OPUS 1 /* OPUS gate array */
65#define MMIC 2 /* MiMIC gate array */
66
67/* relevant direct register defines - offsets from base address */
68#define GA_HOSTCSTAT 2 /* host port ctrl/stat reg */
69#define GA_HOSTDATA 3 /* host port data reg */
70#define GA_REGADDR 4 /* indirect address reg */
71#define GA_REGDATA 5 /* indirect data reg */
72#define SB_IACK 0x22e /* SoundBlaster IACK register */
73
74/* relevant indirect register defines */
75#define GA_DMACHB 3 /* DMA chan B assign reg */
76#define GA_INTCFG 4 /* interrupt configuration reg */
77#define GA_DMACFG 5 /* DMA config reg */
78#define GA_CDCFG 6 /* CD-ROM (AD-1848) config reg */
79#define GA_HMCTL 9 /* host master control reg */
80#define GA_CHIPSEL 10 /* programmable external chip select */
81
82/* AD-1848 chip defines ... */
83/* relevant direct register defines */
84#define AD_REGADDR 0 /* indirect address reg */
85#define AD_REGDATA 1 /* indirect data reg */
86#define AD_STATUS 2 /* status register */
87#define AD_OFFSET 8 /* for some boards, a fixed BasePort offset */
88
89/* relevant indirect register defines */
90#define AD_LEFTOUT 6 /* left DAC output control reg */
91#define AD_RIGHTOUT 7 /* right DAC output control reg */
92#define AD_FORMAT 8 /* clock and data format reg */
93#define AD_CONFIG 9 /* interface config register */
94#define AD_PINCTRL 10 /* external pin control reg */
95#define AD_UCOUNT 14 /* upper count reg */
96#define AD_LCOUNT 15 /* lower count reg */
97
98/* some firmware command and communication defines */
99#define SET_CTL 0x88 /* set a control value */
100#define GET_CTL 0x89 /* get a control value */
101#define SET_REV 0xb0 /* set synth reverb */
102#define SYNTH_VOL 0x04 /* Synth Vol control number */
103#define RXRDY 0x01 /* Receive-Ready bit mask */
104#define TXRDY 0x02 /* Transmit-Ready bit mask */
105
106/* some miscellaneous defines ... soundscape reg values, sytem int regs, ... */
107#define INTCONT1 0x20 /* Interrupt Controller 1 control register */
108#define INTCONT2 0xa0 /* Interrupt Controller 2 control register */
109#define INTMASK1 0x21 /* Interrupt Controller 1 mask register */
110#define INTMASK2 0xa1 /* Interrupt Controller 2 mask register */
111#define VECTBASE1 0x08 /* vector base for XT interrupts */
112#define VECTBASE2 0x70 /* vector base for AT extended interrupts */
113#define EOI 0x20 /* End Of Interrupt command */
114#define AUTO_OUT 0x58 /* DMA controller mode */
115
116static void SOUNDSCAPE_EnableInterrupt( void );
117static void SOUNDSCAPE_DisableInterrupt( void );
118static void __interrupt __far SOUNDSCAPE_ServiceInterrupt( void );
119static int ga_read( int rnum );
120static void ga_write( int rnum, int value );
121static int ad_read( int rnum );
122static void ad_write( int rnum, int value );
123static void tdelay( void );
124static void pcm_format( void );
125static int SOUNDSCAPE_SetupDMABuffer( char *BufferPtr, int BufferSize, int mode );
126static int SOUNDSCAPE_BeginPlayback( int length );
127static void SOUNDSCAPE_LockEnd( void );
128static void SOUNDSCAPE_UnlockMemory( void );
129static int SOUNDSCAPE_LockMemory( void );
130static unsigned short allocateTimerStack( unsigned short size );
131static void deallocateTimerStack( unsigned short selector );
132static int parse( char *val, char *str, FILE *p1 );
133static int SOUNDSCAPE_FindCard( void );
134static int SOUNDSCAPE_Setup( void );
135
136#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/adlibfx.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/adlibfx.c
new file mode 100644
index 0000000000..2e6618b79a
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/adlibfx.c
@@ -0,0 +1,552 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: ADLIBFX.C
22
23 author: James R. Dose
24 date: April 1, 1994
25
26 Low level routines to support Adlib sound effects created by Muse.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#include <dos.h>
32#include <stdlib.h>
33#include <conio.h>
34#include "dpmi.h"
35#include "task_man.h"
36#include "interrup.h"
37#include "al_midi.h"
38#include "adlibfx.h"
39
40#define TRUE ( 1 == 1 )
41#define FALSE ( !TRUE )
42
43static void ADLIBFX_SendOutput( int reg, int data );
44static void ADLIBFX_Service( task *Task );
45
46static long ADLIBFX_LengthLeft;
47static int ADLIBFX_Block;
48static ALSound *ADLIBFX_Sound = NULL;
49static char *ADLIBFX_SoundPtr = NULL;
50static int ADLIBFX_Priority;
51static unsigned long ADLIBFX_CallBackVal;
52static void ( *ADLIBFX_CallBackFunc )( unsigned long ) = NULL;
53static int ADLIBFX_SoundVolume;
54static int ADLIBFX_TotalVolume = ADLIBFX_MaxVolume;
55static task *ADLIBFX_ServiceTask = NULL;
56static int ADLIBFX_VoiceHandle = ADLIBFX_MinVoiceHandle;
57
58int ADLIBFX_Installed = FALSE;
59
60int ADLIBFX_ErrorCode = ADLIBFX_Ok;
61
62#define ADLIBFX_SetErrorCode( status ) \
63 ADLIBFX_ErrorCode = ( status );
64
65
66/*---------------------------------------------------------------------
67 Function: ADLIBFX_ErrorString
68
69 Returns a pointer to the error message associated with an error
70 number. A -1 returns a pointer the current error.
71---------------------------------------------------------------------*/
72
73char *ADLIBFX_ErrorString
74 (
75 int ErrorNumber
76 )
77
78 {
79 char *ErrorString;
80
81 switch( ErrorNumber )
82 {
83 case ADLIBFX_Warning :
84 case ADLIBFX_Error :
85 ErrorString = ADLIBFX_ErrorString( ADLIBFX_ErrorCode );
86 break;
87
88 case ADLIBFX_Ok :
89 ErrorString = "Adlib FX ok.";
90 break;
91
92 case ADLIBFX_NoVoices :
93 ErrorString = "No free voices available in Adlib FX.";
94 break;
95
96 case ADLIBFX_VoiceNotFound :
97 ErrorString = "No voice with matching handle found.";
98 break;
99
100 case ADLIBFX_DPMI_Error :
101 ErrorString = "DPMI Error in AdlibFX.";
102 break;
103
104 default :
105 ErrorString = "Unknown Adlib FX error code.";
106 break;
107 }
108
109 return( ErrorString );
110 }
111
112
113/**********************************************************************
114
115 Memory locked functions:
116
117**********************************************************************/
118
119
120#define ADLIBFX_LockStart ADLIBFX_SendOutput
121
122/*---------------------------------------------------------------------
123 Function: ADLIBFX_SendOutput
124
125 Writes a byte of data to the specified register on the Adlib card.
126---------------------------------------------------------------------*/
127
128static void ADLIBFX_SendOutput
129 (
130 int reg,
131 int data
132 )
133
134 {
135 int i;
136 int adlib_port = 0x388;
137 unsigned flags;
138
139 flags = DisableInterrupts();
140
141 outp( adlib_port, reg );
142
143 for( i = 6; i ; i-- )
144 {
145 inp( adlib_port );
146 }
147
148 outp( adlib_port + 1, data );
149
150 for( i = 35; i ; i-- )
151 {
152 inp( adlib_port );
153 }
154
155 RestoreInterrupts( flags );
156 }
157
158
159/*---------------------------------------------------------------------
160 Function: ADLIBFX_Stop
161
162 Halts playback of the currently playing sound effect.
163---------------------------------------------------------------------*/
164
165int ADLIBFX_Stop
166 (
167 int handle
168 )
169
170 {
171 unsigned flags;
172
173 if ( ( handle != ADLIBFX_VoiceHandle ) || ( ADLIBFX_Sound == NULL ) )
174 {
175 ADLIBFX_SetErrorCode( ADLIBFX_VoiceNotFound );
176 return( ADLIBFX_Warning );
177 }
178
179 flags = DisableInterrupts();
180
181 ADLIBFX_SendOutput( 0xb0, 0 );
182
183 ADLIBFX_Sound = NULL;
184 ADLIBFX_SoundPtr = NULL;
185 ADLIBFX_LengthLeft = 0;
186 ADLIBFX_Priority = 0;
187
188 RestoreInterrupts( flags );
189
190 if ( ADLIBFX_CallBackFunc )
191 {
192 ADLIBFX_CallBackFunc( ADLIBFX_CallBackVal );
193 }
194
195 return( ADLIBFX_Ok );
196 }
197
198
199/*---------------------------------------------------------------------
200 Function: ADLIBFX_Service
201
202 Task Manager routine to perform the playback of a sound effect.
203---------------------------------------------------------------------*/
204
205static void ADLIBFX_Service
206 (
207 task *Task
208 )
209
210 {
211 int value;
212
213 if ( ADLIBFX_SoundPtr )
214 {
215 value = *ADLIBFX_SoundPtr++;
216 if ( value != 0 )
217 {
218 ADLIBFX_SendOutput( 0xa0, value );
219 ADLIBFX_SendOutput( 0xb0, ADLIBFX_Block );
220 }
221 else
222 {
223 ADLIBFX_SendOutput( 0xb0, 0 );
224 }
225
226 ADLIBFX_LengthLeft--;
227 if ( ADLIBFX_LengthLeft <= 0 )
228 {
229 ADLIBFX_Stop( ADLIBFX_VoiceHandle );
230 }
231 }
232 }
233
234
235/*---------------------------------------------------------------------
236 Function: ADLIBFX_SetVolume
237
238 Sets the volume of the currently playing sound effect.
239---------------------------------------------------------------------*/
240
241int ADLIBFX_SetVolume
242 (
243 int handle,
244 int volume
245 )
246
247 {
248 unsigned flags;
249 int carrierlevel;
250
251 flags = DisableInterrupts();
252 if ( ( handle != ADLIBFX_VoiceHandle ) || ( ADLIBFX_Sound == NULL ) )
253 {
254 RestoreInterrupts( flags );
255 ADLIBFX_SetErrorCode( ADLIBFX_VoiceNotFound );
256 return( ADLIBFX_Warning );
257 }
258
259 volume = min( volume, ADLIBFX_MaxVolume );
260 volume = max( volume, 0 );
261 ADLIBFX_SoundVolume = volume;
262
263 volume *= ADLIBFX_TotalVolume;
264 volume /= ADLIBFX_MaxVolume;
265
266 carrierlevel = ADLIBFX_Sound->cScale & 0x3f;
267 carrierlevel ^= 0x3f;
268 carrierlevel *= ( volume / 2 ) + 0x80;
269 carrierlevel /= ADLIBFX_MaxVolume;
270 carrierlevel ^= 0x3f;
271 carrierlevel |= ADLIBFX_Sound->cScale & 0xc0;
272
273 ADLIBFX_SendOutput( 0x43, carrierlevel );
274
275 RestoreInterrupts( flags );
276 return( ADLIBFX_Ok );
277 }
278
279
280/*---------------------------------------------------------------------
281 Function: ADLIBFX_SetTotalVolume
282
283 Sets the total volume of the sound effect.
284---------------------------------------------------------------------*/
285
286int ADLIBFX_SetTotalVolume
287 (
288 int volume
289 )
290
291 {
292 volume = max( volume, 0 );
293 volume = min( volume, ADLIBFX_MaxVolume );
294
295 ADLIBFX_TotalVolume = volume;
296 ADLIBFX_SetVolume( ADLIBFX_VoiceHandle, ADLIBFX_SoundVolume );
297
298 return( ADLIBFX_Ok );
299 }
300
301
302/*---------------------------------------------------------------------
303 Function: ADLIBFX_GetTotalVolume
304
305 Returns the total volume of the sound effect.
306---------------------------------------------------------------------*/
307
308int ADLIBFX_GetTotalVolume
309 (
310 void
311 )
312
313 {
314 return( ADLIBFX_TotalVolume );
315 }
316
317
318/*---------------------------------------------------------------------
319 Function: ADLIBFX_VoiceAvailable
320
321 Checks if a voice can be play at the specified priority.
322---------------------------------------------------------------------*/
323
324int ADLIBFX_VoiceAvailable
325 (
326 int priority
327 )
328
329 {
330 if ( priority < ADLIBFX_Priority )
331 {
332 return( FALSE );
333 }
334
335 return( TRUE );
336 }
337
338
339/*---------------------------------------------------------------------
340 Function: ADLIBFX_Play
341
342 Starts playback of a Muse sound effect.
343---------------------------------------------------------------------*/
344
345int ADLIBFX_Play
346 (
347 ALSound *sound,
348 int volume,
349 int priority,
350 unsigned long callbackval
351 )
352
353 {
354 unsigned flags;
355 int carrierlevel;
356
357 if ( priority < ADLIBFX_Priority )
358 {
359 ADLIBFX_SetErrorCode( ADLIBFX_NoVoices );
360 return( ADLIBFX_Warning );
361 }
362
363 ADLIBFX_Stop( ADLIBFX_VoiceHandle );
364
365 ADLIBFX_VoiceHandle++;
366 if ( ADLIBFX_VoiceHandle < ADLIBFX_MinVoiceHandle )
367 {
368 ADLIBFX_VoiceHandle = ADLIBFX_MinVoiceHandle;
369 }
370
371 flags = DisableInterrupts();
372
373 ADLIBFX_LengthLeft = sound->length;
374 ADLIBFX_Priority = priority;
375 ADLIBFX_Sound = sound;
376 ADLIBFX_SoundPtr = &sound->data;
377 ADLIBFX_CallBackVal = callbackval;
378
379 ADLIBFX_Block = ( ( sound->block & 7 ) << 2 ) | 0x20;
380
381 volume = min( volume, ADLIBFX_MaxVolume );
382 volume = max( volume, 0 );
383 ADLIBFX_SoundVolume = volume;
384
385 volume *= ADLIBFX_TotalVolume;
386 volume /= ADLIBFX_MaxVolume;
387
388 carrierlevel = sound->cScale & 0x3f;
389 carrierlevel ^= 0x3f;
390 carrierlevel *= ( volume / 2 ) + 0x80;
391 carrierlevel /= ADLIBFX_MaxVolume;
392 carrierlevel ^= 0x3f;
393 carrierlevel |= sound->cScale & 0xc0;
394
395 ADLIBFX_SendOutput( 0x20, sound->mChar );
396 ADLIBFX_SendOutput( 0x40, sound->mScale );
397 ADLIBFX_SendOutput( 0x60, sound->mAttack );
398 ADLIBFX_SendOutput( 0x80, sound->mSus );
399 ADLIBFX_SendOutput( 0xe0, sound->mWave );
400
401 ADLIBFX_SendOutput( 0x23, sound->cChar );
402 ADLIBFX_SendOutput( 0x43, carrierlevel );
403 ADLIBFX_SendOutput( 0x63, sound->cAttack );
404 ADLIBFX_SendOutput( 0x83, sound->cSus );
405 ADLIBFX_SendOutput( 0xe3, sound->cWave );
406
407 ADLIBFX_SendOutput( 0xc0, 0 );
408
409 RestoreInterrupts( flags );
410
411 return( ADLIBFX_VoiceHandle );
412 }
413
414
415/*---------------------------------------------------------------------
416 Function: ADLIBFX_SoundPlaying
417
418 Checks if a sound effect is currently playing.
419---------------------------------------------------------------------*/
420
421int ADLIBFX_SoundPlaying
422 (
423 int handle
424 )
425
426 {
427 int status;
428
429 status = FALSE;
430 if ( ( handle == ADLIBFX_VoiceHandle ) && ( ADLIBFX_LengthLeft > 0 ) )
431 {
432 status = TRUE;
433 }
434
435 return( status );
436 }
437
438
439/*---------------------------------------------------------------------
440 Function: ADLIBFX_LockEnd
441
442 Used for determining the length of the functions to lock in memory.
443---------------------------------------------------------------------*/
444
445static void ADLIBFX_LockEnd
446 (
447 void
448 )
449
450 {
451 }
452
453
454/*---------------------------------------------------------------------
455 Function: ADLIBFX_SetCallBack
456
457 Set the function to call when a voice stops.
458---------------------------------------------------------------------*/
459
460void ADLIBFX_SetCallBack
461 (
462 void ( *function )( unsigned long )
463 )
464
465 {
466 ADLIBFX_CallBackFunc = function;
467 }
468
469
470/*---------------------------------------------------------------------
471 Function: ADLIBFX_Init
472
473 Initializes the sound effect engine.
474---------------------------------------------------------------------*/
475
476int ADLIBFX_Init
477 (
478 void
479 )
480
481 {
482 int status;
483
484 if ( ADLIBFX_Installed )
485 {
486 ADLIBFX_Shutdown();
487 }
488
489 status = DPMI_LockMemoryRegion( ADLIBFX_LockStart, ADLIBFX_LockEnd );
490 status |= DPMI_Lock( ADLIBFX_VoiceHandle );
491 status |= DPMI_Lock( ADLIBFX_Sound );
492 status |= DPMI_Lock( ADLIBFX_ErrorCode );
493 status |= DPMI_Lock( ADLIBFX_SoundPtr );
494 status |= DPMI_Lock( ADLIBFX_LengthLeft );
495 status |= DPMI_Lock( ADLIBFX_Priority );
496 status |= DPMI_Lock( ADLIBFX_CallBackFunc );
497 status |= DPMI_Lock( ADLIBFX_Block );
498
499 if ( status != DPMI_Ok )
500 {
501 ADLIBFX_SetErrorCode( ADLIBFX_DPMI_Error );
502 return( ADLIBFX_Error );
503 }
504
505//JIM
506// AL_ReserveVoice( 0 );
507 ADLIBFX_Stop( ADLIBFX_VoiceHandle );
508 ADLIBFX_ServiceTask = TS_ScheduleTask( &ADLIBFX_Service, 140, 2, NULL );
509 TS_Dispatch();
510 ADLIBFX_Installed = TRUE;
511 ADLIBFX_CallBackFunc = NULL;
512
513 ADLIBFX_SetErrorCode( ADLIBFX_Ok );
514 return( ADLIBFX_Ok );
515 }
516
517
518/*---------------------------------------------------------------------
519 Function: ADLIBFX_Shutdown
520
521 Ends the use of the sound effect engine.
522---------------------------------------------------------------------*/
523
524int ADLIBFX_Shutdown
525 (
526 void
527 )
528
529 {
530 if ( ADLIBFX_Installed )
531 {
532 ADLIBFX_Stop( ADLIBFX_VoiceHandle );
533 TS_Terminate( ADLIBFX_ServiceTask );
534 ADLIBFX_ServiceTask = NULL;
535//JIM
536// AL_ReleaseVoice( 0 );
537 ADLIBFX_Installed = FALSE;
538
539 DPMI_UnlockMemoryRegion( ADLIBFX_LockStart, ADLIBFX_LockEnd );
540 DPMI_Unlock( ADLIBFX_VoiceHandle );
541 DPMI_Unlock( ADLIBFX_Sound );
542 DPMI_Unlock( ADLIBFX_ErrorCode );
543 DPMI_Unlock( ADLIBFX_SoundPtr );
544 DPMI_Unlock( ADLIBFX_LengthLeft );
545 DPMI_Unlock( ADLIBFX_Priority );
546 DPMI_Unlock( ADLIBFX_CallBackFunc );
547 DPMI_Unlock( ADLIBFX_Block );
548 }
549
550 ADLIBFX_SetErrorCode( ADLIBFX_Ok );
551 return( ADLIBFX_Ok );
552 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/adlibfx.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/adlibfx.h
new file mode 100644
index 0000000000..d310a6e5c4
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/adlibfx.h
@@ -0,0 +1,80 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: ADLIBFX.H
22
23 author: James R. Dose
24 date: April 1, 1994
25
26 Public header for ADLIBFX.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __ADLIBFX_H
32#define __ADLIBFX_H
33
34enum ADLIBFX_Errors
35 {
36 ADLIBFX_Warning = -2,
37 ADLIBFX_Error = -1,
38 ADLIBFX_Ok = 0,
39 ADLIBFX_NoVoices,
40 ADLIBFX_VoiceNotFound,
41 ADLIBFX_DPMI_Error
42 };
43
44typedef struct
45 {
46 unsigned long length;
47 short int priority;
48 char mChar, cChar;
49 char mScale, cScale;
50 char mAttack, cAttack;
51 char mSus, cSus;
52 char mWave, cWave;
53 char nConn;
54 char voice;
55 char mode;
56 char unused[ 3 ];
57 char block;
58 char data[];
59 } ALSound;
60
61#define ADLIBFX_MaxVolume 255
62#define ADLIBFX_MinVoiceHandle 1
63
64char *ADLIBFX_ErrorString( int ErrorNumber );
65int ADLIBFX_Stop( int handle );
66int ADLIBFX_SetVolume( int handle, int volume );
67int ADLIBFX_SetTotalVolume( int volume );
68int ADLIBFX_GetTotalVolume( void );
69int ADLIBFX_VoiceAvailable( int priority );
70int ADLIBFX_Play( ALSound *sound, int volume, int priority, unsigned long callbackval );
71int ADLIBFX_SoundPlaying( int handle );
72void ADLIBFX_SetCallBack( void ( *function )( unsigned long ) );
73int ADLIBFX_Init( void );
74int ADLIBFX_Shutdown( void );
75 #pragma aux ADLIBFX_Shutdown frame;
76void PCFX_UnlockMemory( void );
77 #pragma aux ADLIBFX_UnlockMemory frame;
78int PCFX_LockMemory( void );
79
80#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/al_midi.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/al_midi.c
new file mode 100644
index 0000000000..871280c023
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/al_midi.c
@@ -0,0 +1,1510 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: AL_MIDI.C
22
23 author: James R. Dose
24 date: April 1, 1994
25
26 Low level routines to support General MIDI music on Adlib compatible
27 cards.
28
29 (c) Copyright 1994 James R. Dose. All Rights Reserved.
30**********************************************************************/
31
32#include <conio.h>
33#include <dos.h>
34#include <stddef.h>
35#include <stdlib.h>
36//#include <math.h>
37#include "dpmi.h"
38#include "interrup.h"
39#include "sndcards.h"
40#include "blaster.h"
41#include "user.h"
42#include "al_midi.h"
43#include "_al_midi.h"
44#include "ll_man.h"
45
46#define TRUE ( 1 == 1 )
47#define FALSE ( !TRUE )
48
49static unsigned OctavePitch[ MAX_OCTAVE + 1 ] =
50 {
51 OCTAVE_0, OCTAVE_1, OCTAVE_2, OCTAVE_3,
52 OCTAVE_4, OCTAVE_5, OCTAVE_6, OCTAVE_7,
53 };
54
55static unsigned NoteMod12[ MAX_NOTE + 1 ];
56static unsigned NoteDiv12[ MAX_NOTE + 1 ];
57
58// Pitch table
59
60//static unsigned NotePitch[ FINETUNE_MAX + 1 ][ 12 ] =
61// {
62// { C, C_SHARP, D, D_SHARP, E, F, F_SHARP, G, G_SHARP, A, A_SHARP, B },
63// };
64
65static unsigned NotePitch[ FINETUNE_MAX + 1 ][ 12 ] =
66 {
67 { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x241, 0x263, 0x287 },
68 { 0x157, 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x242, 0x264, 0x288 },
69 { 0x158, 0x16c, 0x182, 0x199, 0x1b1, 0x1cb, 0x1e6, 0x203, 0x221, 0x243, 0x265, 0x289 },
70 { 0x158, 0x16c, 0x183, 0x19a, 0x1b2, 0x1cc, 0x1e7, 0x204, 0x222, 0x244, 0x266, 0x28a },
71 { 0x159, 0x16d, 0x183, 0x19a, 0x1b3, 0x1cd, 0x1e8, 0x205, 0x223, 0x245, 0x267, 0x28b },
72 { 0x15a, 0x16e, 0x184, 0x19b, 0x1b3, 0x1ce, 0x1e9, 0x206, 0x224, 0x246, 0x268, 0x28c },
73 { 0x15a, 0x16e, 0x185, 0x19c, 0x1b4, 0x1ce, 0x1ea, 0x207, 0x225, 0x247, 0x269, 0x28e },
74 { 0x15b, 0x16f, 0x185, 0x19d, 0x1b5, 0x1cf, 0x1eb, 0x208, 0x226, 0x248, 0x26a, 0x28f },
75 { 0x15b, 0x170, 0x186, 0x19d, 0x1b6, 0x1d0, 0x1ec, 0x209, 0x227, 0x249, 0x26b, 0x290 },
76 { 0x15c, 0x170, 0x187, 0x19e, 0x1b7, 0x1d1, 0x1ec, 0x20a, 0x228, 0x24a, 0x26d, 0x291 },
77 { 0x15d, 0x171, 0x188, 0x19f, 0x1b7, 0x1d2, 0x1ed, 0x20b, 0x229, 0x24b, 0x26e, 0x292 },
78 { 0x15d, 0x172, 0x188, 0x1a0, 0x1b8, 0x1d3, 0x1ee, 0x20c, 0x22a, 0x24c, 0x26f, 0x293 },
79 { 0x15e, 0x172, 0x189, 0x1a0, 0x1b9, 0x1d4, 0x1ef, 0x20d, 0x22b, 0x24d, 0x270, 0x295 },
80 { 0x15f, 0x173, 0x18a, 0x1a1, 0x1ba, 0x1d4, 0x1f0, 0x20e, 0x22c, 0x24e, 0x271, 0x296 },
81 { 0x15f, 0x174, 0x18a, 0x1a2, 0x1bb, 0x1d5, 0x1f1, 0x20f, 0x22d, 0x24f, 0x272, 0x297 },
82 { 0x160, 0x174, 0x18b, 0x1a3, 0x1bb, 0x1d6, 0x1f2, 0x210, 0x22e, 0x250, 0x273, 0x298 },
83 { 0x161, 0x175, 0x18c, 0x1a3, 0x1bc, 0x1d7, 0x1f3, 0x211, 0x22f, 0x251, 0x274, 0x299 },
84 { 0x161, 0x176, 0x18c, 0x1a4, 0x1bd, 0x1d8, 0x1f4, 0x212, 0x230, 0x252, 0x276, 0x29b },
85 { 0x162, 0x176, 0x18d, 0x1a5, 0x1be, 0x1d9, 0x1f5, 0x212, 0x231, 0x254, 0x277, 0x29c },
86 { 0x162, 0x177, 0x18e, 0x1a6, 0x1bf, 0x1d9, 0x1f5, 0x213, 0x232, 0x255, 0x278, 0x29d },
87 { 0x163, 0x178, 0x18f, 0x1a6, 0x1bf, 0x1da, 0x1f6, 0x214, 0x233, 0x256, 0x279, 0x29e },
88 { 0x164, 0x179, 0x18f, 0x1a7, 0x1c0, 0x1db, 0x1f7, 0x215, 0x235, 0x257, 0x27a, 0x29f },
89 { 0x164, 0x179, 0x190, 0x1a8, 0x1c1, 0x1dc, 0x1f8, 0x216, 0x236, 0x258, 0x27b, 0x2a1 },
90 { 0x165, 0x17a, 0x191, 0x1a9, 0x1c2, 0x1dd, 0x1f9, 0x217, 0x237, 0x259, 0x27c, 0x2a2 },
91 { 0x166, 0x17b, 0x192, 0x1aa, 0x1c3, 0x1de, 0x1fa, 0x218, 0x238, 0x25a, 0x27e, 0x2a3 },
92 { 0x166, 0x17b, 0x192, 0x1aa, 0x1c3, 0x1df, 0x1fb, 0x219, 0x239, 0x25b, 0x27f, 0x2a4 },
93 { 0x167, 0x17c, 0x193, 0x1ab, 0x1c4, 0x1e0, 0x1fc, 0x21a, 0x23a, 0x25c, 0x280, 0x2a6 },
94 { 0x168, 0x17d, 0x194, 0x1ac, 0x1c5, 0x1e0, 0x1fd, 0x21b, 0x23b, 0x25d, 0x281, 0x2a7 },
95 { 0x168, 0x17d, 0x194, 0x1ad, 0x1c6, 0x1e1, 0x1fe, 0x21c, 0x23c, 0x25e, 0x282, 0x2a8 },
96 { 0x169, 0x17e, 0x195, 0x1ad, 0x1c7, 0x1e2, 0x1ff, 0x21d, 0x23d, 0x260, 0x283, 0x2a9 },
97 { 0x16a, 0x17f, 0x196, 0x1ae, 0x1c8, 0x1e3, 0x1ff, 0x21e, 0x23e, 0x261, 0x284, 0x2ab },
98 { 0x16a, 0x17f, 0x197, 0x1af, 0x1c8, 0x1e4, 0x200, 0x21f, 0x23f, 0x262, 0x286, 0x2ac }
99 };
100
101// Slot numbers as a function of the voice and the operator.
102// ( melodic only)
103
104static int slotVoice[ NUM_VOICES ][ 2 ] =
105 {
106 { 0, 3 }, // voice 0
107 { 1, 4 }, // 1
108 { 2, 5 }, // 2
109 { 6, 9 }, // 3
110 { 7, 10 }, // 4
111 { 8, 11 }, // 5
112 { 12, 15 }, // 6
113 { 13, 16 }, // 7
114 { 14, 17 }, // 8
115 };
116
117static int VoiceLevel[ NumChipSlots ][ 2 ];
118static int VoiceKsl[ NumChipSlots ][ 2 ];
119
120// This table gives the offset of each slot within the chip.
121// offset = fn( slot)
122
123static char offsetSlot[ NumChipSlots ] =
124 {
125 0, 1, 2, 3, 4, 5,
126 8, 9, 10, 11, 12, 13,
127 16, 17, 18, 19, 20, 21
128 };
129
130static int VoiceReserved[ NUM_VOICES * 2 ] =
131 {
132 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
133 FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
134 };
135
136static VOICE Voice[ NUM_VOICES * 2 ];
137static VOICELIST Voice_Pool;
138
139static CHANNEL Channel[ NUM_CHANNELS ];
140
141static int AL_LeftPort = 0x388;
142static int AL_RightPort = 0x388;
143static int AL_Stereo = FALSE;
144static int AL_SendStereo = FALSE;
145static int AL_OPL3 = FALSE;
146static int AL_MaxMidiChannel = 16;
147
148
149/**********************************************************************
150
151 Memory locked functions:
152
153**********************************************************************/
154
155
156#define AL_LockStart AL_SendOutputToPort
157
158
159/*---------------------------------------------------------------------
160 Function: AL_SendOutputToPort
161
162 Sends data to the Adlib using a specified port.
163---------------------------------------------------------------------*/
164
165void AL_SendOutputToPort
166 (
167 int port,
168 int reg,
169 int data
170 )
171
172 {
173 int delay;
174
175 outp( port, reg );
176
177 for( delay = 6; delay > 0 ; delay-- )
178// for( delay = 2; delay > 0 ; delay-- )
179 {
180 inp( port );
181 }
182
183 outp( port + 1, data );
184
185// for( delay = 35; delay > 0 ; delay-- )
186 for( delay = 27; delay > 0 ; delay-- )
187// for( delay = 2; delay > 0 ; delay-- )
188 {
189 inp( port );
190 }
191 }
192
193
194/*---------------------------------------------------------------------
195 Function: AL_SendOutput
196
197 Sends data to the Adlib.
198---------------------------------------------------------------------*/
199
200void AL_SendOutput
201 (
202 int voice,
203 int reg,
204 int data
205 )
206
207 {
208 int port;
209
210 if ( AL_SendStereo )
211 {
212 AL_SendOutputToPort( AL_LeftPort, reg, data );
213 AL_SendOutputToPort( AL_RightPort, reg, data );
214 }
215 else
216 {
217 port = ( voice == 0 ) ? AL_RightPort : AL_LeftPort;
218 AL_SendOutputToPort( port, reg, data );
219 }
220 }
221
222
223/*---------------------------------------------------------------------
224 Function: AL_SetVoiceTimbre
225
226 Programs the specified voice's timbre.
227---------------------------------------------------------------------*/
228
229static void AL_SetVoiceTimbre
230 (
231 int voice
232 )
233
234 {
235 int off;
236 int slot;
237 int port;
238 int voc;
239 int patch;
240 int channel;
241 TIMBRE *timbre;
242
243 channel = Voice[ voice ].channel;
244
245 if ( channel == 9 )
246 {
247 patch = Voice[ voice ].key + 128;
248 }
249 else
250 {
251 patch = Channel[ channel ].Timbre;
252 }
253
254 if ( Voice[ voice ].timbre == patch )
255 {
256 return;
257 }
258
259 Voice[ voice ].timbre = patch;
260 timbre = &ADLIB_TimbreBank[ patch ];
261
262 port = Voice[ voice ].port;
263 voc = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;
264 slot = slotVoice[ voc ][ 0 ];
265 off = offsetSlot[ slot ];
266
267 VoiceLevel[ slot ][ port ] = 63 - ( timbre->Level[ 0 ] & 0x3f );
268 VoiceKsl[ slot ][ port ] = timbre->Level[ 0 ] & 0xc0;
269
270 AL_SendOutput( port, 0xA0 + voc, 0 );
271 AL_SendOutput( port, 0xB0 + voc, 0 );
272
273 // Let voice clear the release
274 AL_SendOutput( port, 0x80 + off, 0xff );
275
276 AL_SendOutput( port, 0x60 + off, timbre->Env1[ 0 ] );
277 AL_SendOutput( port, 0x80 + off, timbre->Env2[ 0 ] );
278 AL_SendOutput( port, 0x20 + off, timbre->SAVEK[ 0 ] );
279 AL_SendOutput( port, 0xE0 + off, timbre->Wave[ 0 ] );
280
281 AL_SendOutput( port, 0x40 + off, timbre->Level[ 0 ] );
282 slot = slotVoice[ voc ][ 1 ];
283
284 if ( AL_SendStereo )
285 {
286 AL_SendOutputToPort( AL_LeftPort, 0xC0 + voice,
287 ( timbre->Feedback & 0x0f ) | 0x20 );
288 AL_SendOutputToPort( AL_RightPort, 0xC0 + voice,
289 ( timbre->Feedback & 0x0f ) | 0x10 );
290 }
291 else
292 {
293 if ( AL_OPL3 )
294 {
295 AL_SendOutput( port, 0xC0 + voc, ( timbre->Feedback & 0x0f ) |
296 0x30 );
297 }
298 else
299 {
300 AL_SendOutputToPort( ADLIB_PORT, 0xC0 + voice, timbre->Feedback );
301 }
302 }
303
304 off = offsetSlot[ slot ];
305
306 VoiceLevel[ slot ][ port ] = 63 - ( timbre->Level[ 1 ] & 0x3f );
307 VoiceKsl[ slot ][ port ] = timbre->Level[ 1 ] & 0xc0;
308 AL_SendOutput( port, 0x40 + off, 63 );
309
310 // Let voice clear the release
311 AL_SendOutput( port, 0x80 + off, 0xff );
312
313 AL_SendOutput( port, 0x60 + off, timbre->Env1[ 1 ] );
314 AL_SendOutput( port, 0x80 + off, timbre->Env2[ 1 ] );
315 AL_SendOutput( port, 0x20 + off, timbre->SAVEK[ 1 ] );
316 AL_SendOutput( port, 0xE0 + off, timbre->Wave[ 1 ] );
317 }
318
319
320/*---------------------------------------------------------------------
321 Function: AL_SetVoiceVolume
322
323 Sets the volume of the specified voice.
324---------------------------------------------------------------------*/
325
326static void AL_SetVoiceVolume
327 (
328 int voice
329 )
330
331 {
332 int channel;
333 int velocity;
334 int slot;
335 int port;
336 int voc;
337 unsigned long t1;
338 unsigned long t2;
339 unsigned long volume;
340 TIMBRE *timbre;
341
342 channel = Voice[ voice ].channel;
343
344 timbre = &ADLIB_TimbreBank[ Voice[ voice ].timbre ];
345
346 velocity = Voice[ voice ].velocity + timbre->Velocity;
347 velocity = min( velocity, MAX_VELOCITY );
348
349 voc = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;
350 slot = slotVoice[ voc ][ 1 ];
351 port = Voice[ voice ].port;
352
353 // amplitude
354 t1 = ( unsigned )VoiceLevel[ slot ][ port ];
355 t1 *= ( velocity + 0x80 );
356 t1 = ( Channel[ channel ].Volume * t1 ) >> 15;
357
358 if ( !AL_SendStereo )
359 {
360 volume = t1 ^ 63;
361 volume |= ( unsigned )VoiceKsl[ slot ][ port ];
362
363 AL_SendOutput( port, 0x40 + offsetSlot[ slot ], volume );
364
365 // Check if this timbre is Additive
366 if ( timbre->Feedback & 0x01 )
367 {
368 slot = slotVoice[ voc ][ 0 ];
369
370 // amplitude
371 t2 = ( unsigned )VoiceLevel[ slot ][ port ];
372 t2 *= ( velocity + 0x80 );
373 t2 = ( Channel[ channel ].Volume * t1 ) >> 15;
374
375 volume = t2 ^ 63;
376 volume |= ( unsigned )VoiceKsl[ slot ][ port ];
377
378 AL_SendOutput( port, 0x40 + offsetSlot[ slot ], volume );
379 }
380 }
381 else
382 {
383 // Set left channel volume
384 volume = t1;
385 if ( Channel[ channel ].Pan < 64 )
386 {
387 volume *= Channel[ channel ].Pan;
388 volume >>= 6;
389 }
390
391 volume ^= 63;
392 volume |= ( unsigned )VoiceKsl[ slot ][ port ];
393
394 AL_SendOutputToPort( AL_LeftPort, 0x40 + offsetSlot[ slot ], volume );
395
396 // Set right channel volume
397 volume = t1;
398 if ( Channel[ channel ].Pan > 64 )
399 {
400 volume *= 127 - Channel[ channel ].Pan;
401 volume >>= 6;
402 }
403
404 volume ^= 63;
405 volume |= ( unsigned )VoiceKsl[ slot ][ port ];
406
407 AL_SendOutputToPort( AL_RightPort, 0x40 + offsetSlot[ slot ], volume );
408
409 // Check if this timbre is Additive
410 if ( timbre->Feedback & 0x01 )
411 {
412 // amplitude
413 t2 = ( unsigned )VoiceLevel[ slot ][ port ];
414 t2 *= ( velocity + 0x80 );
415 t2 = ( Channel[ channel ].Volume * t1 ) >> 15;
416
417 slot = slotVoice[ voc ][ 0 ];
418
419 // Set left channel volume
420 volume = t2;
421 if ( Channel[ channel ].Pan < 64 )
422 {
423 volume *= Channel[ channel ].Pan;
424 volume >>= 6;
425 }
426
427 volume ^= 63;
428 volume |= ( unsigned )VoiceKsl[ slot ][ port ];
429
430 AL_SendOutputToPort( AL_LeftPort, 0x40 + offsetSlot[ slot ], volume );
431
432 // Set right channel volume
433 volume = t2;
434 if ( Channel[ channel ].Pan > 64 )
435 {
436 volume *= 127 - Channel[ channel ].Pan;
437 volume >>= 6;
438 }
439
440 volume ^= 63;
441 volume |= ( unsigned )VoiceKsl[ slot ][ port ];
442
443 AL_SendOutputToPort( AL_RightPort, 0x40 + offsetSlot[ slot ], volume );
444 }
445 }
446 }
447
448
449/*---------------------------------------------------------------------
450 Function: AL_AllocVoice
451
452 Retrieves a free voice from the voice pool.
453---------------------------------------------------------------------*/
454
455static int AL_AllocVoice
456 (
457 void
458 )
459
460 {
461 int voice;
462
463 if ( Voice_Pool.start )
464 {
465 voice = Voice_Pool.start->num;
466 LL_Remove( VOICE, &Voice_Pool, &Voice[ voice ] );
467 return( voice );
468 }
469
470 return( AL_VoiceNotFound );
471 }
472
473
474/*---------------------------------------------------------------------
475 Function: AL_GetVoice
476
477 Determines which voice is associated with a specified note and
478 MIDI channel.
479---------------------------------------------------------------------*/
480
481static int AL_GetVoice
482 (
483 int channel,
484 int key
485 )
486
487 {
488 VOICE *voice;
489
490 voice = Channel[ channel ].Voices.start;
491
492 while( voice != NULL )
493 {
494 if ( voice->key == key )
495 {
496 return( voice->num );
497 }
498 voice = voice->next;
499 }
500
501 return( AL_VoiceNotFound );
502 }
503
504
505/*---------------------------------------------------------------------
506 Function: AL_SetVoicePitch
507
508 Programs the pitch of the specified voice.
509---------------------------------------------------------------------*/
510
511static void AL_SetVoicePitch
512 (
513 int voice
514 )
515
516 {
517 int note;
518 int channel;
519 int patch;
520 int detune;
521 int ScaleNote;
522 int Octave;
523 int pitch;
524 int port;
525 int voc;
526
527 port = Voice[ voice ].port;
528 voc = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;
529 channel = Voice[ voice ].channel;
530
531 if ( channel == 9 )
532 {
533 patch = Voice[ voice ].key + 128;
534 note = ADLIB_TimbreBank[ patch ].Transpose;
535 }
536 else
537 {
538 patch = Channel[ channel ].Timbre;
539 note = Voice[ voice ].key + ADLIB_TimbreBank[ patch ].Transpose;
540 }
541
542 note += Channel[ channel ].KeyOffset - 12;
543 if ( note > MAX_NOTE )
544 {
545 note = MAX_NOTE;
546 }
547 if ( note < 0 )
548 {
549 note = 0;
550 }
551
552 detune = Channel[ channel ].KeyDetune;
553
554 ScaleNote = NoteMod12[ note ];
555 Octave = NoteDiv12[ note ];
556
557 pitch = OctavePitch[ Octave ] | NotePitch[ detune ][ ScaleNote ];
558
559 Voice[ voice ].pitchleft = pitch;
560
561 pitch |= Voice[ voice ].status;
562
563 if ( !AL_SendStereo )
564 {
565 AL_SendOutput( port, 0xA0 + voc, pitch );
566 AL_SendOutput( port, 0xB0 + voc, pitch >> 8 );
567 }
568 else
569 {
570 AL_SendOutputToPort( AL_LeftPort, 0xA0 + voice, pitch );
571 AL_SendOutputToPort( AL_LeftPort, 0xB0 + voice, pitch >> 8 );
572
573 if ( channel != 9 )
574 {
575 detune += STEREO_DETUNE;
576 }
577
578 if ( detune > FINETUNE_MAX )
579 {
580 detune -= FINETUNE_RANGE;
581 if ( note < MAX_NOTE )
582 {
583 note++;
584 ScaleNote = NoteMod12[ note ];
585 Octave = NoteDiv12[ note ];
586 }
587 }
588
589 pitch = OctavePitch[ Octave ] | NotePitch[ detune ][ ScaleNote ];
590
591 Voice[ voice ].pitchright = pitch;
592
593 pitch |= Voice[ voice ].status;
594
595 AL_SendOutputToPort( AL_RightPort, 0xA0 + voice, pitch );
596 AL_SendOutputToPort( AL_RightPort, 0xB0 + voice, pitch >> 8 );
597 }
598 }
599
600
601/*---------------------------------------------------------------------
602 Function: AL_SetChannelVolume
603
604 Sets the volume of the specified MIDI channel.
605---------------------------------------------------------------------*/
606
607static void AL_SetChannelVolume
608 (
609 int channel,
610 int volume
611 )
612
613 {
614 VOICE *voice;
615
616 volume = max( 0, volume );
617 volume = min( volume, AL_MaxVolume );
618 Channel[ channel ].Volume = volume;
619
620 voice = Channel[ channel ].Voices.start;
621 while( voice != NULL )
622 {
623 AL_SetVoiceVolume( voice->num );
624 voice = voice->next;
625 }
626 }
627
628
629/*---------------------------------------------------------------------
630 Function: AL_SetChannelPan
631
632 Sets the pan position of the specified MIDI channel.
633---------------------------------------------------------------------*/
634
635static void AL_SetChannelPan
636 (
637 int channel,
638 int pan
639 )
640
641 {
642 // Don't pan drum sounds
643 if ( channel != 9 )
644 {
645 Channel[ channel ].Pan = pan;
646 }
647 }
648
649
650/*---------------------------------------------------------------------
651 Function: AL_SetChannelDetune
652
653 Sets the stereo voice detune of the specified MIDI channel.
654---------------------------------------------------------------------*/
655
656static void AL_SetChannelDetune
657 (
658 int channel,
659 int detune
660 )
661
662 {
663 Channel[ channel ].Detune = detune;
664 }
665
666
667/*---------------------------------------------------------------------
668 Function: AL_ResetVoices
669
670 Sets all voice info to the default state.
671---------------------------------------------------------------------*/
672
673static void AL_ResetVoices
674 (
675 void
676 )
677
678 {
679 int index;
680 int numvoices;
681
682 Voice_Pool.start = NULL;
683 Voice_Pool.end = NULL;
684
685 numvoices = NUM_VOICES;
686 if ( ( AL_OPL3 ) && ( !AL_Stereo ) )
687 {
688 numvoices = NUM_VOICES * 2;
689 }
690 for( index = 0; index < numvoices; index++ )
691 {
692 if ( VoiceReserved[ index ] == FALSE )
693 {
694 Voice[ index ].num = index;
695 Voice[ index ].key = 0;
696 Voice[ index ].velocity = 0;
697 Voice[ index ].channel = -1;
698 Voice[ index ].timbre = -1;
699 Voice[ index ].port = ( index < NUM_VOICES ) ? 0 : 1;
700 Voice[ index ].status = NOTE_OFF;
701 LL_AddToTail( VOICE, &Voice_Pool, &Voice[ index ] );
702 }
703 }
704
705 for( index = 0; index < NUM_CHANNELS; index++ )
706 {
707 Channel[ index ].Voices.start = NULL;
708 Channel[ index ].Voices.end = NULL;
709 Channel[ index ].Timbre = 0;
710 Channel[ index ].Pitchbend = 0;
711 Channel[ index ].KeyOffset = 0;
712 Channel[ index ].KeyDetune = 0;
713 Channel[ index ].Volume = AL_DefaultChannelVolume;
714 Channel[ index ].Pan = 64;
715 Channel[ index ].RPN = 0;
716 Channel[ index ].PitchBendRange = AL_DefaultPitchBendRange;
717 Channel[ index ].PitchBendSemiTones = AL_DefaultPitchBendRange / 100;
718 Channel[ index ].PitchBendHundreds = AL_DefaultPitchBendRange % 100;
719 }
720 }
721
722
723/*---------------------------------------------------------------------
724 Function: AL_CalcPitchInfo
725
726 Calculates the pitch table.
727---------------------------------------------------------------------*/
728
729static void AL_CalcPitchInfo
730 (
731 void
732 )
733
734 {
735 int note;
736// int finetune;
737// double detune;
738
739 for( note = 0; note <= MAX_NOTE; note++ )
740 {
741 NoteMod12[ note ] = note % 12;
742 NoteDiv12[ note ] = note / 12;
743 }
744
745// for( finetune = 1; finetune <= FINETUNE_MAX; finetune++ )
746// {
747// detune = pow( 2, ( double )finetune / ( 12.0 * FINETUNE_RANGE ) );
748// for( note = 0; note < 12; note++ )
749// {
750// NotePitch[ finetune ][ note ] = ( ( double )NotePitch[ 0 ][ note ] * detune );
751// }
752// }
753 }
754
755
756/*---------------------------------------------------------------------
757 Function: AL_FlushCard
758
759 Sets all voices to a known (quiet) state.
760---------------------------------------------------------------------*/
761
762void AL_FlushCard
763 (
764 int port
765 )
766
767 {
768 int i;
769 unsigned slot1;
770 unsigned slot2;
771
772 for( i = 0 ; i < NUM_VOICES; i++ )
773 {
774 if ( VoiceReserved[ i ] == FALSE )
775 {
776 slot1 = offsetSlot[ slotVoice[ i ][ 0 ] ];
777 slot2 = offsetSlot[ slotVoice[ i ][ 1 ] ];
778
779 AL_SendOutputToPort( port, 0xA0 + i, 0 );
780 AL_SendOutputToPort( port, 0xB0 + i, 0 );
781
782 AL_SendOutputToPort( port, 0xE0 + slot1, 0 );
783 AL_SendOutputToPort( port, 0xE0 + slot2, 0 );
784
785 // Set the envelope to be fast and quiet
786 AL_SendOutputToPort( port, 0x60 + slot1, 0xff );
787 AL_SendOutputToPort( port, 0x60 + slot2, 0xff );
788 AL_SendOutputToPort( port, 0x80 + slot1, 0xff );
789 AL_SendOutputToPort( port, 0x80 + slot2, 0xff );
790
791 // Maximum attenuation
792 AL_SendOutputToPort( port, 0x40 + slot1, 0xff );
793 AL_SendOutputToPort( port, 0x40 + slot2, 0xff );
794 }
795 }
796 }
797
798
799/*---------------------------------------------------------------------
800 Function: AL_StereoOn
801
802 Sets the card send info in stereo.
803---------------------------------------------------------------------*/
804
805void AL_StereoOn
806 (
807 void
808 )
809
810 {
811 if ( ( AL_Stereo ) && ( !AL_SendStereo ) )
812 {
813 AL_SendStereo = TRUE;
814 if ( AL_OPL3 )
815 {
816 // Set card to OPL3 operation
817 AL_SendOutputToPort( AL_RightPort, 0x5, 1 );
818 }
819 }
820 else if ( AL_OPL3 )
821 {
822 // Set card to OPL3 operation
823 AL_SendOutputToPort( AL_RightPort, 0x5, 1 );
824 }
825 }
826
827
828/*---------------------------------------------------------------------
829 Function: AL_StereoOff
830
831 Sets the card send info in mono.
832---------------------------------------------------------------------*/
833
834void AL_StereoOff
835 (
836 void
837 )
838
839 {
840 if ( ( AL_Stereo ) && ( AL_SendStereo ) )
841 {
842 AL_SendStereo = FALSE;
843 if ( AL_OPL3 )
844 {
845 // Set card back to OPL2 operation
846 AL_SendOutputToPort( AL_RightPort, 0x5, 0 );
847 }
848 }
849 else if ( AL_OPL3 )
850 {
851 // Set card back to OPL2 operation
852 AL_SendOutputToPort( AL_RightPort, 0x5, 0 );
853 }
854 }
855
856
857/*---------------------------------------------------------------------
858 Function: AL_Reset
859
860 Sets the card to a known (quiet) state.
861---------------------------------------------------------------------*/
862
863void AL_Reset
864 (
865 void
866 )
867
868 {
869 AL_SendOutputToPort( ADLIB_PORT, 1, 0x20 );
870 AL_SendOutputToPort( ADLIB_PORT, 0x08, 0 );
871
872 // Set the values: AM Depth, VIB depth & Rhythm
873 AL_SendOutputToPort( ADLIB_PORT, 0xBD, 0 );
874
875 AL_StereoOn();
876
877 if ( ( AL_SendStereo ) || ( AL_OPL3 ) )
878 {
879 AL_FlushCard( AL_LeftPort );
880 AL_FlushCard( AL_RightPort );
881 }
882 else
883 {
884 AL_FlushCard( ADLIB_PORT );
885 }
886 }
887
888
889/*---------------------------------------------------------------------
890 Function: AL_ReserveVoice
891
892 Marks a voice as being not available for use. This allows the
893 driver to use the rest of the card while another driver uses the
894 reserved voice.
895---------------------------------------------------------------------*/
896
897int AL_ReserveVoice
898 (
899 int voice
900 )
901
902 {
903 unsigned flags;
904
905 if ( ( voice < 0 ) || ( voice >= NUM_VOICES ) )
906 {
907 return( AL_Error );
908 }
909
910 if ( VoiceReserved[ voice ] )
911 {
912 return( AL_Warning );
913 }
914
915 flags = DisableInterrupts();
916
917 if ( Voice[ voice ].status == NOTE_ON )
918 {
919 AL_NoteOff( Voice[ voice ].channel, Voice[ voice ].key, 0 );
920 }
921
922 VoiceReserved[ voice ] = TRUE;
923 LL_Remove( VOICE, &Voice_Pool, &Voice[ voice ] );
924
925 RestoreInterrupts( flags );
926 return( AL_Ok );
927 }
928
929
930/*---------------------------------------------------------------------
931 Function: AL_ReleaseVoice
932
933 Marks a previously reserved voice as being free to use.
934---------------------------------------------------------------------*/
935
936int AL_ReleaseVoice
937 (
938 int voice
939 )
940
941 {
942 unsigned flags;
943
944 if ( ( voice < 0 ) || ( voice >= NUM_VOICES ) )
945 {
946 return( AL_Error );
947 }
948
949 if ( !VoiceReserved[ voice ] )
950 {
951 return( AL_Warning );
952 }
953
954 flags = DisableInterrupts();
955
956 VoiceReserved[ voice ] = FALSE;
957 LL_AddToTail( VOICE, &Voice_Pool, &Voice[ voice ] );
958
959 RestoreInterrupts( flags );
960 return( AL_Ok );
961 }
962
963
964/*---------------------------------------------------------------------
965 Function: AL_NoteOff
966
967 Turns off a note on the specified MIDI channel.
968---------------------------------------------------------------------*/
969
970void AL_NoteOff
971 (
972 int channel,
973 int key,
974 int velocity
975 )
976
977 {
978 int voice;
979 int port;
980 int voc;
981
982 // We only play channels 1 through 10
983 if ( channel > AL_MaxMidiChannel )
984 {
985 return;
986 }
987
988 voice = AL_GetVoice( channel, key );
989
990 if ( voice == AL_VoiceNotFound )
991 {
992 return;
993 }
994
995 Voice[ voice ].status = NOTE_OFF;
996
997 port = Voice[ voice ].port;
998 voc = ( voice >= NUM_VOICES ) ? voice - NUM_VOICES : voice;
999
1000 if ( AL_SendStereo )
1001 {
1002 AL_SendOutputToPort( AL_LeftPort, 0xB0 + voice,
1003 hibyte( Voice[ voice ].pitchleft ) );
1004 AL_SendOutputToPort( AL_RightPort, 0xB0 + voice,
1005 hibyte( Voice[ voice ].pitchright ) );
1006 }
1007 else
1008 {
1009 AL_SendOutput( port, 0xB0 + voc, hibyte( Voice[ voice ].pitchleft ) );
1010 }
1011
1012 LL_Remove( VOICE, &Channel[ channel ].Voices, &Voice[ voice ] );
1013 LL_AddToTail( VOICE, &Voice_Pool, &Voice[ voice ] );
1014 }
1015
1016
1017/*---------------------------------------------------------------------
1018 Function: AL_NoteOn
1019
1020 Plays a note on the specified MIDI channel.
1021---------------------------------------------------------------------*/
1022
1023void AL_NoteOn
1024 (
1025 int channel,
1026 int key,
1027 int velocity
1028 )
1029
1030 {
1031 int voice;
1032
1033 // We only play channels 1 through 10
1034 if ( channel > AL_MaxMidiChannel )
1035 {
1036 return;
1037 }
1038
1039 if ( velocity == 0 )
1040 {
1041 AL_NoteOff( channel, key, velocity );
1042 return;
1043 }
1044
1045 voice = AL_AllocVoice();
1046
1047 if ( voice == AL_VoiceNotFound )
1048 {
1049 if ( Channel[ 9 ].Voices.start )
1050 {
1051 AL_NoteOff( 9, Channel[ 9 ].Voices.start->key, 0 );
1052 voice = AL_AllocVoice();
1053 }
1054 if ( voice == AL_VoiceNotFound )
1055 {
1056 return;
1057 }
1058 }
1059
1060 Voice[ voice ].key = key;
1061 Voice[ voice ].channel = channel;
1062 Voice[ voice ].velocity = velocity;
1063 Voice[ voice ].status = NOTE_ON;
1064
1065 LL_AddToTail( VOICE, &Channel[ channel ].Voices, &Voice[ voice ] );
1066
1067 AL_SetVoiceTimbre( voice );
1068 AL_SetVoiceVolume( voice );
1069 AL_SetVoicePitch( voice );
1070 }
1071
1072
1073/*---------------------------------------------------------------------
1074 Function: AL_AllNotesOff
1075
1076 Turns off all currently playing voices.
1077---------------------------------------------------------------------*/
1078
1079void AL_AllNotesOff
1080 (
1081 int channel
1082 )
1083
1084 {
1085 while( Channel[ channel ].Voices.start != NULL )
1086 {
1087 AL_NoteOff( channel, Channel[ channel ].Voices.start->key, 0 );
1088 }
1089 }
1090
1091
1092/*---------------------------------------------------------------------
1093 Function: AL_ControlChange
1094
1095 Sets the value of a controller on the specified MIDI channel.
1096---------------------------------------------------------------------*/
1097
1098void AL_ControlChange
1099 (
1100 int channel,
1101 int type,
1102 int data
1103 )
1104
1105 {
1106 // We only play channels 1 through 10
1107 if ( channel > AL_MaxMidiChannel )
1108 {
1109 return;
1110 }
1111
1112 switch( type )
1113 {
1114 case MIDI_VOLUME :
1115 AL_SetChannelVolume( channel, data );
1116 break;
1117
1118 case MIDI_PAN :
1119 AL_SetChannelPan( channel, data );
1120 break;
1121
1122 case MIDI_DETUNE :
1123 AL_SetChannelDetune( channel, data );
1124 break;
1125
1126 case MIDI_ALL_NOTES_OFF :
1127 AL_AllNotesOff( channel );
1128 break;
1129
1130 case MIDI_RESET_ALL_CONTROLLERS :
1131 AL_ResetVoices();
1132 AL_SetChannelVolume( channel, AL_DefaultChannelVolume );
1133 AL_SetChannelPan( channel, 64 );
1134 AL_SetChannelDetune( channel, 0 );
1135 break;
1136
1137 case MIDI_RPN_MSB :
1138 Channel[ channel ].RPN &= 0x00FF;
1139 Channel[ channel ].RPN |= ( data & 0xFF ) << 8;
1140 break;
1141
1142 case MIDI_RPN_LSB :
1143 Channel[ channel ].RPN &= 0xFF00;
1144 Channel[ channel ].RPN |= data & 0xFF;
1145 break;
1146
1147 case MIDI_DATAENTRY_MSB :
1148 if ( Channel[ channel ].RPN == MIDI_PITCHBEND_RPN )
1149 {
1150 Channel[ channel ].PitchBendSemiTones = data;
1151 Channel[ channel ].PitchBendRange =
1152 Channel[ channel ].PitchBendSemiTones * 100 +
1153 Channel[ channel ].PitchBendHundreds;
1154 }
1155 break;
1156
1157 case MIDI_DATAENTRY_LSB :
1158 if ( Channel[ channel ].RPN == MIDI_PITCHBEND_RPN )
1159 {
1160 Channel[ channel ].PitchBendHundreds = data;
1161 Channel[ channel ].PitchBendRange =
1162 Channel[ channel ].PitchBendSemiTones * 100 +
1163 Channel[ channel ].PitchBendHundreds;
1164 }
1165 break;
1166 }
1167 }
1168
1169
1170/*---------------------------------------------------------------------
1171 Function: AL_ProgramChange
1172
1173 Selects the instrument to use on the specified MIDI channel.
1174---------------------------------------------------------------------*/
1175
1176void AL_ProgramChange
1177 (
1178 int channel,
1179 int patch
1180 )
1181
1182 {
1183 // We only play channels 1 through 10
1184 if ( channel > AL_MaxMidiChannel )
1185 {
1186 return;
1187 }
1188
1189 Channel[ channel ].Timbre = patch;
1190 }
1191
1192
1193/*---------------------------------------------------------------------
1194 Function: AL_SetPitchBend
1195
1196 Sets the pitch bend amount on the specified MIDI channel.
1197---------------------------------------------------------------------*/
1198
1199void AL_SetPitchBend
1200 (
1201 int channel,
1202 int lsb,
1203 int msb
1204 )
1205
1206 {
1207 int pitchbend;
1208 unsigned long TotalBend;
1209 VOICE *voice;
1210
1211 // We only play channels 1 through 10
1212 if ( channel > AL_MaxMidiChannel )
1213 {
1214 return;
1215 }
1216
1217 pitchbend = lsb + ( msb << 8 );
1218 Channel[ channel ].Pitchbend = pitchbend;
1219
1220 TotalBend = pitchbend * Channel[ channel ].PitchBendRange;
1221 TotalBend /= ( PITCHBEND_CENTER / FINETUNE_RANGE );
1222
1223 Channel[ channel ].KeyOffset = ( int )( TotalBend / FINETUNE_RANGE );
1224 Channel[ channel ].KeyOffset -= Channel[ channel ].PitchBendSemiTones;
1225
1226 Channel[ channel ].KeyDetune = ( unsigned )( TotalBend % FINETUNE_RANGE );
1227
1228 voice = Channel[ channel ].Voices.start;
1229 while( voice != NULL )
1230 {
1231 AL_SetVoicePitch( voice->num );
1232 voice = voice->next;
1233 }
1234 }
1235
1236
1237/*---------------------------------------------------------------------
1238 Function: AL_DetectFM
1239
1240 Determines if an Adlib compatible card is installed in the machine.
1241---------------------------------------------------------------------*/
1242
1243int AL_DetectFM
1244 (
1245 void
1246 )
1247
1248 {
1249 int status1;
1250 int status2;
1251 int i;
1252
1253 if ( USER_CheckParameter( NO_ADLIB_DETECTION ) )
1254 {
1255 return( FALSE );
1256 }
1257
1258 AL_SendOutputToPort( ADLIB_PORT, 4, 0x60 ); // Reset T1 & T2
1259 AL_SendOutputToPort( ADLIB_PORT, 4, 0x80 ); // Reset IRQ
1260
1261 status1 = inp( ADLIB_PORT );
1262
1263 AL_SendOutputToPort( ADLIB_PORT, 2, 0xff ); // Set timer 1
1264 AL_SendOutputToPort( ADLIB_PORT, 4, 0x21 ); // Start timer 1
1265
1266 for( i = 100; i > 0; i-- )
1267 {
1268 inp( ADLIB_PORT );
1269 }
1270
1271 status2 = inp( ADLIB_PORT );
1272
1273 AL_SendOutputToPort( ADLIB_PORT, 4, 0x60 );
1274 AL_SendOutputToPort( ADLIB_PORT, 4, 0x80 );
1275
1276 return( ( ( status1 & 0xe0 ) == 0x00 ) && ( ( status2 & 0xe0 ) == 0xc0 ) );
1277 }
1278
1279
1280/*---------------------------------------------------------------------
1281 Function: AL_LockEnd
1282
1283 Used for determining the length of the functions to lock in memory.
1284---------------------------------------------------------------------*/
1285
1286static void AL_LockEnd
1287 (
1288 void
1289 )
1290
1291 {
1292 }
1293
1294
1295/*---------------------------------------------------------------------
1296 Function: AL_Shutdown
1297
1298 Ends use of the sound card and resets it to a quiet state.
1299---------------------------------------------------------------------*/
1300
1301void AL_Shutdown
1302 (
1303 void
1304 )
1305
1306 {
1307 AL_StereoOff();
1308
1309 AL_OPL3 = FALSE;
1310 AL_ResetVoices();
1311 AL_Reset();
1312
1313 DPMI_UnlockMemoryRegion( AL_LockStart, AL_LockEnd );
1314 DPMI_Unlock( slotVoice );
1315 DPMI_Unlock( VoiceLevel );
1316 DPMI_Unlock( VoiceKsl );
1317 DPMI_Unlock( offsetSlot );
1318 DPMI_Unlock( NotePitch );
1319 DPMI_Unlock( OctavePitch );
1320 DPMI_Unlock( NoteMod12 );
1321 DPMI_Unlock( NoteDiv12 );
1322 DPMI_Unlock( VoiceReserved );
1323 DPMI_Unlock( Voice );
1324 DPMI_Unlock( Voice_Pool );
1325 DPMI_Unlock( Channel );
1326 DPMI_Unlock( AL_LeftPort );
1327 DPMI_Unlock( AL_RightPort );
1328 DPMI_Unlock( AL_Stereo );
1329 DPMI_Unlock( AL_SendStereo );
1330 DPMI_Unlock( AL_OPL3 );
1331 DPMI_Unlock( AL_MaxMidiChannel );
1332 }
1333
1334
1335/*---------------------------------------------------------------------
1336 Function: AL_SetMaxMidiChannel
1337
1338 Sets the maximum MIDI channel that FM cards respond to.
1339---------------------------------------------------------------------*/
1340
1341void AL_SetMaxMidiChannel
1342 (
1343 int channel
1344 )
1345
1346 {
1347 AL_MaxMidiChannel = channel - 1;
1348 }
1349
1350/*---------------------------------------------------------------------
1351 Function: AL_Init
1352
1353 Begins use of the sound card.
1354---------------------------------------------------------------------*/
1355
1356int AL_Init
1357 (
1358 int soundcard
1359 )
1360
1361 {
1362 BLASTER_CONFIG Blaster;
1363 int status;
1364
1365 status = DPMI_LockMemoryRegion( AL_LockStart, AL_LockEnd );
1366 status |= DPMI_Lock( slotVoice );
1367 status |= DPMI_Lock( VoiceLevel );
1368 status |= DPMI_Lock( VoiceKsl );
1369 status |= DPMI_Lock( offsetSlot );
1370 status |= DPMI_Lock( NotePitch );
1371 status |= DPMI_Lock( OctavePitch );
1372 status |= DPMI_Lock( NoteMod12 );
1373 status |= DPMI_Lock( NoteDiv12 );
1374 status |= DPMI_Lock( VoiceReserved );
1375 status |= DPMI_Lock( Voice );
1376 status |= DPMI_Lock( Voice_Pool );
1377 status |= DPMI_Lock( Channel );
1378 status |= DPMI_Lock( AL_LeftPort );
1379 status |= DPMI_Lock( AL_RightPort );
1380 status |= DPMI_Lock( AL_Stereo );
1381 status |= DPMI_Lock( AL_SendStereo );
1382 status |= DPMI_Lock( AL_OPL3 );
1383 status |= DPMI_Lock( AL_MaxMidiChannel );
1384
1385 if ( status != DPMI_Ok )
1386 {
1387 return( AL_Error );
1388 }
1389
1390 AL_Stereo = FALSE;
1391 AL_OPL3 = FALSE;
1392 AL_LeftPort = 0x388;
1393 AL_RightPort = 0x388;
1394
1395 switch( soundcard )
1396 {
1397 case ProAudioSpectrum :
1398 case SoundMan16 :
1399 AL_OPL3 = TRUE;
1400 AL_LeftPort = 0x388;
1401 AL_RightPort = 0x38A;
1402 break;
1403
1404 case SoundBlaster :
1405 status = BLASTER_GetCardSettings( &Blaster );
1406 if ( status != BLASTER_Ok )
1407 {
1408 status = BLASTER_GetEnv( &Blaster );
1409 if ( status != BLASTER_Ok )
1410 {
1411 break;
1412 }
1413 }
1414
1415 switch( Blaster.Type )
1416 {
1417 case SBPro2 :
1418 case SB16 :
1419 AL_OPL3 = TRUE;
1420 AL_LeftPort = Blaster.Address;
1421 AL_RightPort = Blaster.Address + 2;
1422 break;
1423 }
1424 break;
1425 }
1426// Temporarally commented out for ROTT.
1427// Stereo FM seems to take too long on some computers and
1428// causes the mouse driver to miss interrupts.
1429
1430/*
1431 switch( soundcard )
1432 {
1433 case ProAudioSpectrum :
1434 case SoundMan16 :
1435 AL_OPL3 = TRUE;
1436 AL_Stereo = TRUE;
1437 AL_LeftPort = 0x388;
1438 AL_RightPort = 0x38A;
1439 break;
1440
1441 case SoundBlaster :
1442 status = BLASTER_GetCardSettings( &Blaster );
1443 if ( status != BLASTER_Ok )
1444 {
1445 status = BLASTER_GetEnv( &Blaster );
1446 if ( status != BLASTER_Ok )
1447 {
1448 break;
1449 }
1450 }
1451
1452 switch( Blaster.Type )
1453 {
1454 case SBPro2 :
1455 case SB16 :
1456 AL_OPL3 = TRUE;
1457 AL_Stereo = TRUE;
1458 AL_LeftPort = Blaster.Address;
1459 AL_RightPort = Blaster.Address + 2;
1460 break;
1461
1462 case SBPro :
1463 AL_Stereo = TRUE;
1464 AL_LeftPort = Blaster.Address;
1465 AL_RightPort = Blaster.Address + 2;
1466 break;
1467 }
1468 break;
1469 }
1470*/
1471
1472 AL_CalcPitchInfo();
1473 AL_Reset();
1474 AL_ResetVoices();
1475
1476 return( AL_Ok );
1477 }
1478
1479
1480/*---------------------------------------------------------------------
1481 Function: AL_RegisterTimbreBank
1482
1483 Copies user supplied timbres over the default timbre bank.
1484---------------------------------------------------------------------*/
1485
1486void AL_RegisterTimbreBank
1487 (
1488 unsigned char *timbres
1489 )
1490
1491 {
1492 int i;
1493
1494 for( i = 0; i < 256; i++ )
1495 {
1496 ADLIB_TimbreBank[ i ].SAVEK[ 0 ] = *( timbres++ );
1497 ADLIB_TimbreBank[ i ].SAVEK[ 1 ] = *( timbres++ );
1498 ADLIB_TimbreBank[ i ].Level[ 0 ] = *( timbres++ );
1499 ADLIB_TimbreBank[ i ].Level[ 1 ] = *( timbres++ );
1500 ADLIB_TimbreBank[ i ].Env1[ 0 ] = *( timbres++ );
1501 ADLIB_TimbreBank[ i ].Env1[ 1 ] = *( timbres++ );
1502 ADLIB_TimbreBank[ i ].Env2[ 0 ] = *( timbres++ );
1503 ADLIB_TimbreBank[ i ].Env2[ 1 ] = *( timbres++ );
1504 ADLIB_TimbreBank[ i ].Wave[ 0 ] = *( timbres++ );
1505 ADLIB_TimbreBank[ i ].Wave[ 1 ] = *( timbres++ );
1506 ADLIB_TimbreBank[ i ].Feedback = *( timbres++ );
1507 ADLIB_TimbreBank[ i ].Transpose = *( signed char * )( timbres++ );
1508 ADLIB_TimbreBank[ i ].Velocity = *( signed char * )( timbres++ );
1509 }
1510 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/al_midi.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/al_midi.h
new file mode 100644
index 0000000000..8f11adfd59
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/al_midi.h
@@ -0,0 +1,58 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20#ifndef __AL_MIDI_H
21#define __AL_MIDI_H
22
23enum AL_Errors
24 {
25 AL_Warning = -2,
26 AL_Error = -1,
27 AL_Ok = 0,
28 };
29
30#define AL_MaxVolume 127
31#define AL_DefaultChannelVolume 90
32//#define AL_DefaultPitchBendRange 2
33#define AL_DefaultPitchBendRange 200
34
35#define ADLIB_PORT 0x388
36
37void AL_SendOutputToPort( int port, int reg, int data );
38void AL_SendOutput( int voice, int reg, int data );
39void AL_StereoOn( void );
40void AL_StereoOff( void );
41int AL_ReserveVoice( int voice );
42int AL_ReleaseVoice( int voice );
43void AL_Shutdown( void );
44int AL_Init( int soundcard );
45void AL_SetMaxMidiChannel( int channel );
46void AL_Reset( void );
47void AL_NoteOff( int channel, int key, int velocity );
48void AL_NoteOn( int channel, int key, int vel );
49//Turned off to test if it works with Watcom 10a
50// #pragma aux AL_NoteOn frame;
51void AL_AllNotesOff( int channel );
52void AL_ControlChange( int channel, int type, int data );
53void AL_ProgramChange( int channel, int patch );
54void AL_SetPitchBend( int channel, int lsb, int msb );
55int AL_DetectFM( void );
56void AL_RegisterTimbreBank( unsigned char *timbres );
57
58#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/assert.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/assert.h
new file mode 100644
index 0000000000..5b8d221558
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/assert.h
@@ -0,0 +1,49 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20#if (HAVE_ASSERT_H != 1)
21
22#ifndef __ASSERT_H
23
24 #define __ASSERT_H
25
26 #ifdef NDEBUG
27
28 #define ASSERT(f)
29
30 #else
31
32 #pragma aux _Assert aborts; /* _Assert will not return */
33 extern void _Assert( char *strFile, unsigned uLine ); /*prototype */
34
35 #define ASSERT(f) \
36 if (f) \
37 ; \
38 else \
39 _Assert( __FILE__, __LINE__ )
40
41 #endif
42
43#else
44
45 #error Multiple definition of ASSERT()
46
47#endif
48
49#endif //HAVE_ASSERT_H
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/awe32.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/awe32.c
new file mode 100644
index 0000000000..9f014117cb
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/awe32.c
@@ -0,0 +1,540 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: AWE32.C
22
23 author: James R. Dose
24 date: August 23, 1994
25
26 Cover functions for calling the AWE32 low-level library.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#include <conio.h>
32#include <string.h>
33#include "dpmi.h"
34#include "blaster.h"
35#include "ctaweapi.h"
36#include "awe32.h"
37
38#define _inp inp
39#define _outp outp
40
41/* DSP defines */
42#define MPU_ACK_OK 0xfe
43#define MPU_RESET_CMD 0xff
44#define MPU_ENTER_UART 0x3f
45
46static WORD wSBCBaseAddx; /* Sound Blaster base address */
47static WORD wEMUBaseAddx; /* EMU8000 subsystem base address */
48static WORD wMpuBaseAddx; /* MPU401 base address */
49
50static unsigned short NoteFlags[ 128 ];
51
52/* macros */
53#define SBCPort( x ) ( ( x ) + wSBCBaseAddx )
54#define MPUPort( x ) ( ( x ) + wMpuBaseAddx )
55
56static SOUND_PACKET spSound =
57 {
58 0
59 };
60
61static LONG lBankSizes[ MAXBANKS ] =
62 {
63 0
64 };
65
66unsigned SetES( void );
67#pragma aux SetES = \
68 "xor eax, eax" \
69 "mov ax, es" \
70 "mov bx, ds" \
71 "mov es, bx" \
72 modify [ eax ebx ];
73
74void RestoreES( unsigned num );
75#pragma aux RestoreES = \
76 "mov es, ax" \
77 parm [ eax ];
78
79int AWE32_ErrorCode = AWE32_Ok;
80
81#define AWE32_SetErrorCode( status ) \
82 AWE32_ErrorCode = ( status );
83
84
85/*---------------------------------------------------------------------
86 Function: AWE32_ErrorString
87
88 Returns a pointer to the error message associated with an error
89 number. A -1 returns a pointer the current error.
90---------------------------------------------------------------------*/
91
92char *AWE32_ErrorString
93 (
94 int ErrorNumber
95 )
96
97 {
98 char *ErrorString;
99
100 switch( ErrorNumber )
101 {
102 case AWE32_Warning :
103 case AWE32_Error :
104 ErrorString = AWE32_ErrorString( AWE32_ErrorCode );
105 break;
106
107 case AWE32_Ok :
108 ErrorString = "AWE32 ok.";
109 break;
110
111 case AWE32_SoundBlasterError :
112 ErrorString = BLASTER_ErrorString( BLASTER_Error );
113 break;
114
115 case AWE32_NotDetected :
116 ErrorString = "Could not detect AWE32.";
117 break;
118
119 case AWE32_UnableToInitialize :
120 ErrorString = "Unable to initialize AWE32.";
121
122 case AWE32_MPU401Error :
123 ErrorString = "MPU-401 initialization failed in AWE32.";
124 break;
125
126 case AWE32_DPMI_Error :
127 ErrorString = "DPMI Error in AWE32.";
128 break;
129
130 default :
131 ErrorString = "Unknown AWE32 error code.";
132 break;
133 }
134
135 return( ErrorString );
136 }
137
138
139/**********************************************************************
140
141 Memory locked functions:
142
143**********************************************************************/
144
145
146#define AWE32_LockStart AWE32_NoteOff
147
148
149void AWE32_NoteOff
150 (
151 int channel,
152 int key,
153 int velocity
154 )
155
156 {
157 unsigned temp;
158
159 temp = SetES();
160 awe32NoteOff( channel, key, velocity );
161 RestoreES( temp );
162 NoteFlags[ key ] ^= ( 1 << channel );
163 }
164
165void AWE32_NoteOn
166 (
167 int channel,
168 int key,
169 int velocity
170 )
171
172 {
173 unsigned temp;
174
175 temp = SetES();
176 awe32NoteOn( channel, key, velocity );
177 RestoreES( temp );
178 NoteFlags[ key ] |= ( 1 << channel );
179 }
180
181void AWE32_PolyAftertouch
182 (
183 int channel,
184 int key,
185 int pressure
186 )
187
188 {
189 unsigned temp;
190
191 temp = SetES();
192 awe32PolyKeyPressure( channel, key, pressure );
193 RestoreES( temp );
194 }
195
196void AWE32_ChannelAftertouch
197 (
198 int channel,
199 int pressure
200 )
201
202 {
203 unsigned temp;
204
205 temp = SetES();
206 awe32ChannelPressure( channel, pressure );
207 RestoreES( temp );
208 }
209
210void AWE32_ControlChange
211 (
212 int channel,
213 int number,
214 int value
215 )
216
217 {
218 unsigned temp;
219 int i;
220 unsigned channelmask;
221
222 temp = SetES();
223
224 if ( number == 0x7b )
225 {
226 channelmask = 1 << channel;
227 for( i = 0; i < 128; i++ )
228 {
229 if ( NoteFlags[ i ] & channelmask )
230 {
231 awe32NoteOff( channel, i, 0 );
232 NoteFlags[ i ] ^= channelmask;
233 }
234 }
235 }
236 else
237 {
238 awe32Controller( channel, number, value );
239 }
240 RestoreES( temp );
241 }
242
243void AWE32_ProgramChange
244 (
245 int channel,
246 int program
247 )
248
249 {
250 unsigned temp;
251
252 temp = SetES();
253 awe32ProgramChange( channel, program );
254 RestoreES( temp );
255 }
256
257void AWE32_PitchBend
258 (
259 int channel,
260 int lsb,
261 int msb
262 )
263
264 {
265 unsigned temp;
266
267 temp = SetES();
268 awe32PitchBend( channel, lsb, msb );
269 RestoreES( temp );
270 }
271
272
273/*---------------------------------------------------------------------
274 Function: AWE32_LockEnd
275
276 Used for determining the length of the functions to lock in memory.
277---------------------------------------------------------------------*/
278
279static void AWE32_LockEnd
280 (
281 void
282 )
283
284 {
285 }
286
287
288/*
289static int InitMPU
290 (
291 void
292 )
293
294 {
295 volatile DWORD dwCount;
296
297 for (dwCount=0; dwCount<0x2000; dwCount++) ;
298 dwCount = 0x2000;
299 while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
300 _outp(MPUPort(1), MPU_RESET_CMD);
301
302 for (dwCount=0; dwCount<0x2000; dwCount++) ;
303 dwCount = 0x2000;
304 while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
305 _inp(MPUPort(0));
306
307 for (dwCount=0; dwCount<0x2000; dwCount++) ;
308 dwCount = 0x2000;
309 while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
310 _outp(MPUPort(1), MPU_RESET_CMD);
311
312 for (dwCount=0; dwCount<0x2000; dwCount++) ;
313 dwCount = 0x2000;
314 while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
315 _inp(MPUPort(0));
316
317 for (dwCount=0; dwCount<0x2000; dwCount++) ;
318 dwCount = 0x2000;
319 while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
320 _outp(MPUPort(1), MPU_ENTER_UART);
321
322 for (dwCount=0; dwCount<0x2000; dwCount++) ;
323 dwCount = 0x2000;
324 while (dwCount && _inp(MPUPort(1)) & 0x80) --dwCount;
325 if (!dwCount) return TRUE;
326 if (_inp(MPUPort(0)) != MPU_ACK_OK) return TRUE;
327
328 // mask MPU-401 interrupt
329 _outp(SBCPort(0x4), 0x83);
330 _outp(SBCPort(0x5), _inp(SBCPort(0x5)) & ~0x04);
331
332 return FALSE;
333 }
334*/
335
336/*ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸*/
337/*³ ShutdownMPU ³*/
338/*³ Cleans up Sound Blaster to normal state. ³*/
339/*ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;*/
340
341static void ShutdownMPU
342 (
343 void
344 )
345
346 {
347 volatile DWORD dwCount;
348
349 for (dwCount=0; dwCount<0x2000; dwCount++) ;
350 dwCount = 0x2000;
351 while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
352 _outp(MPUPort(1), MPU_RESET_CMD);
353 for (dwCount=0; dwCount<0x2000; dwCount++) ;
354 _inp(MPUPort(0));
355
356 for (dwCount=0; dwCount<0x2000; dwCount++) ;
357 dwCount = 0x2000;
358 while (dwCount && _inp(MPUPort(1)) & 0x40) --dwCount;
359 _outp(MPUPort(1), MPU_RESET_CMD);
360 for (dwCount=0; dwCount<0x2000; dwCount++) ;
361 _inp(MPUPort(0));
362 }
363
364
365/*ÕÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͸*/
366/*³ LoadSBK ³*/
367/*ÔÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ;*/
368
369static void LoadSBK
370 (
371 void
372 )
373
374 {
375 /* use embeded preset objects */
376 spSound.bank_no = 0; /* load as Bank 0 */
377 spSound.total_banks = 1; /* use 1 bank first */
378 lBankSizes[ 0 ] = 0; /* ram is not needed */
379
380 spSound.banksizes = lBankSizes;
381 awe32DefineBankSizes( &spSound );
382 awe32SoundPad.SPad1 = awe32SPad1Obj;
383 awe32SoundPad.SPad2 = awe32SPad2Obj;
384 awe32SoundPad.SPad3 = awe32SPad3Obj;
385 awe32SoundPad.SPad4 = awe32SPad4Obj;
386 awe32SoundPad.SPad5 = awe32SPad5Obj;
387 awe32SoundPad.SPad6 = awe32SPad6Obj;
388 awe32SoundPad.SPad7 = awe32SPad7Obj;
389 }
390
391
392int AWE32_Init
393 (
394 void
395 )
396
397 {
398 int status;
399 BLASTER_CONFIG Blaster;
400
401 wSBCBaseAddx = 0x220;
402 wEMUBaseAddx = 0x620;
403 wMpuBaseAddx = 0x330;
404
405 status = BLASTER_GetCardSettings( &Blaster );
406 if ( status != BLASTER_Ok )
407 {
408 status = BLASTER_GetEnv( &Blaster );
409 if ( status != BLASTER_Ok )
410 {
411 AWE32_SetErrorCode( AWE32_SoundBlasterError );
412 return( AWE32_Error );
413 }
414 }
415
416 wSBCBaseAddx = Blaster.Address;
417 if ( wSBCBaseAddx == UNDEFINED )
418 {
419 wSBCBaseAddx = 0x220;
420 }
421
422 wMpuBaseAddx = Blaster.Midi;
423 if ( wMpuBaseAddx == UNDEFINED )
424 {
425 wMpuBaseAddx = 0x330;
426 }
427
428 wEMUBaseAddx = Blaster.Emu;
429 if ( wEMUBaseAddx <= 0 )
430 {
431 wEMUBaseAddx = wSBCBaseAddx + 0x400;
432 }
433
434 status = awe32Detect( wEMUBaseAddx );
435 if ( status )
436 {
437 AWE32_SetErrorCode( AWE32_NotDetected );
438 return( AWE32_Error );
439 }
440
441 status = awe32InitHardware();
442 if ( status )
443 {
444 AWE32_SetErrorCode( AWE32_UnableToInitialize );
445 return( AWE32_Error );
446 }
447
448
449 status = awe32InitMIDI();
450 if ( status )
451 {
452 AWE32_Shutdown();
453 AWE32_SetErrorCode( AWE32_MPU401Error )
454 return( AWE32_Error );
455 }
456
457/*
458 status = InitMPU();
459 if ( status )
460 {
461 ShutdownMPU();
462 status = InitMPU();
463 if ( status )
464 {
465 ShutdownMPU();
466 status = InitMPU();
467 if ( status )
468 {
469 AWE32_Shutdown();
470 AWE32_SetErrorCode( AWE32_MPU401Error )
471 return( AWE32_Error );
472 }
473 }
474 }
475*/
476 status = DPMI_LockMemoryRegion( AWE32_LockStart, AWE32_LockEnd );
477 status |= DPMI_Lock( wSBCBaseAddx );
478 status |= DPMI_Lock( wEMUBaseAddx );
479 status |= DPMI_Lock( wMpuBaseAddx );
480 status |= DPMI_Lock( spSound );
481 status |= DPMI_Lock( lBankSizes );
482 status |= DPMI_LockMemory( NoteFlags, sizeof( NoteFlags ) );
483
484 // Lock awe32 library
485 status = DPMI_LockMemoryRegion( __midieng_code, __midieng_ecode );
486 status = DPMI_LockMemoryRegion( __midieng_code(), __midieng_ecode() );
487 status = DPMI_LockMemoryRegion( __nrpn_code, __nrpn_ecode );
488 status = DPMI_LockMemoryRegion( __nrpn_code(), __nrpn_ecode() );
489 status = DPMI_LockMemoryRegion( &__midivar_data, &__midivar_edata );
490 status = DPMI_LockMemoryRegion( &__nrpnvar_data, &__nrpnvar_edata );
491 status = DPMI_LockMemoryRegion( &__embed_data, &__embed_edata );
492
493 if ( status != DPMI_Ok )
494 {
495 ShutdownMPU();
496 awe32Terminate();
497 AWE32_SetErrorCode( AWE32_DPMI_Error );
498 return( AWE32_Error );
499 }
500
501 // Set the number of voices to use to 32
502 awe32NumG = 32;
503
504 awe32TotalPatchRam(&spSound);
505
506 LoadSBK();
507 awe32InitMIDI();
508 awe32InitNRPN();
509
510 memset( NoteFlags, 0, sizeof( NoteFlags ) );
511
512 return( AWE32_Ok );
513 }
514
515void AWE32_Shutdown
516 (
517 void
518 )
519
520 {
521 ShutdownMPU();
522 awe32Terminate();
523
524 DPMI_UnlockMemoryRegion( AWE32_LockStart, AWE32_LockEnd );
525 DPMI_Unlock( wSBCBaseAddx );
526 DPMI_Unlock( wEMUBaseAddx );
527 DPMI_Unlock( wMpuBaseAddx );
528 DPMI_Unlock( spSound );
529 DPMI_Unlock( lBankSizes );
530 DPMI_UnlockMemory( NoteFlags, sizeof( NoteFlags ) );
531
532 // Unlock awe32 library
533 DPMI_UnlockMemoryRegion( __midieng_code, __midieng_ecode );
534 DPMI_UnlockMemoryRegion( __midieng_code(), __midieng_ecode() );
535 DPMI_UnlockMemoryRegion( __nrpn_code, __nrpn_ecode );
536 DPMI_UnlockMemoryRegion( __nrpn_code(), __nrpn_ecode() );
537 DPMI_UnlockMemoryRegion( &__midivar_data, &__midivar_edata );
538 DPMI_UnlockMemoryRegion( &__nrpnvar_data, &__nrpnvar_edata );
539 DPMI_UnlockMemoryRegion( &__embed_data, &__embed_edata );
540 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/awe32.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/awe32.h
new file mode 100644
index 0000000000..a234b178c8
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/awe32.h
@@ -0,0 +1,58 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: AWE32.H
22
23 author: James R. Dose
24 date: August 23, 1994
25
26 Public header for AWE32.C Cover functions for calling the
27 AWE32 low-level library.
28
29 (c) Copyright 1994 James R. Dose. All Rights Reserved.
30**********************************************************************/
31
32#ifndef __AWE32_H
33#define __AWE32_H
34
35enum AWE32_ERRORS
36 {
37 AWE32_Warning = -2,
38 AWE32_Error = -1,
39 AWE32_Ok = 0,
40 AWE32_SoundBlasterError,
41 AWE32_NotDetected,
42 AWE32_UnableToInitialize,
43 AWE32_MPU401Error,
44 AWE32_DPMI_Error
45 };
46
47char *AWE32_ErrorString( int ErrorNumber );
48int AWE32_Init( void );
49void AWE32_Shutdown( void );
50void AWE32_NoteOff( int channel, int key, int velocity );
51void AWE32_NoteOn( int channel, int key, int velocity );
52void AWE32_PolyAftertouch( int channel, int key, int pressure );
53void AWE32_ChannelAftertouch( int channel, int pressure );
54void AWE32_ControlChange( int channel, int number, int value );
55void AWE32_ProgramChange( int channel, int program );
56void AWE32_PitchBend( int channel, int lsb, int msb );
57
58#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/blaster.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/blaster.c
new file mode 100644
index 0000000000..8ff3935d17
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/blaster.c
@@ -0,0 +1,2330 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: BLASTER.C
22
23 author: James R. Dose
24 date: February 4, 1994
25
26 Low level routines to support Sound Blaster, Sound Blaster Pro,
27 Sound Blaster 16, and compatible sound cards.
28
29 (c) Copyright 1994 James R. Dose. All Rights Reserved.
30**********************************************************************/
31
32#include <dos.h>
33#include <conio.h>
34#include <stdlib.h>
35#include <stdio.h>
36#include <string.h>
37#include <ctype.h>
38#include "dpmi.h"
39#include "dma.h"
40#include "irq.h"
41#include "blaster.h"
42#include "_blaster.h"
43
44#define USESTACK
45
46const int BLASTER_Interrupts[ BLASTER_MaxIrq + 1 ] =
47 {
48 INVALID, INVALID, 0xa, 0xb,
49 INVALID, 0xd, INVALID, 0xf,
50 INVALID, INVALID, 0x72, 0x73,
51 0x74, INVALID, INVALID, 0x77
52 };
53
54const int BLASTER_SampleSize[ BLASTER_MaxMixMode + 1 ] =
55 {
56 MONO_8BIT_SAMPLE_SIZE, STEREO_8BIT_SAMPLE_SIZE,
57 MONO_16BIT_SAMPLE_SIZE, STEREO_16BIT_SAMPLE_SIZE
58 };
59
60const CARD_CAPABILITY BLASTER_CardConfig[ BLASTER_MaxCardType + 1 ] =
61 {
62 { FALSE, INVALID, INVALID, INVALID, INVALID }, // Unsupported
63 { TRUE, NO, MONO_8BIT, 4000, 23000 }, // SB 1.0
64 { TRUE, YES, STEREO_8BIT, 4000, 44100 }, // SBPro
65 { TRUE, NO, MONO_8BIT, 4000, 23000 }, // SB 2.xx
66 { TRUE, YES, STEREO_8BIT, 4000, 44100 }, // SBPro 2
67 { FALSE, INVALID, INVALID, INVALID, INVALID }, // Unsupported
68 { TRUE, YES, STEREO_16BIT, 5000, 44100 }, // SB16
69 };
70
71CARD_CAPABILITY BLASTER_Card;
72
73static void ( __interrupt __far *BLASTER_OldInt )( void );
74
75BLASTER_CONFIG BLASTER_Config =
76 {
77 UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED, UNDEFINED
78 };
79
80static int BLASTER_Installed = FALSE;
81
82int BLASTER_Version;
83
84static char *BLASTER_DMABuffer;
85static char *BLASTER_DMABufferEnd;
86static char *BLASTER_CurrentDMABuffer;
87static int BLASTER_TotalDMABufferSize;
88
89static int BLASTER_TransferLength = 0;
90static int BLASTER_MixMode = BLASTER_DefaultMixMode;
91static int BLASTER_SamplePacketSize = MONO_16BIT_SAMPLE_SIZE;
92static unsigned BLASTER_SampleRate = BLASTER_DefaultSampleRate;
93
94static unsigned BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
95
96volatile int BLASTER_SoundPlaying;
97volatile int BLASTER_SoundRecording;
98
99void ( *BLASTER_CallBack )( void );
100
101static int BLASTER_IntController1Mask;
102static int BLASTER_IntController2Mask;
103
104static int BLASTER_MixerAddress = UNDEFINED;
105static int BLASTER_MixerType = 0;
106static int BLASTER_OriginalMidiVolumeLeft = 255;
107static int BLASTER_OriginalMidiVolumeRight = 255;
108static int BLASTER_OriginalVoiceVolumeLeft = 255;
109static int BLASTER_OriginalVoiceVolumeRight = 255;
110
111static int BLASTER_WaveBlasterState = 0x0F;
112
113// adequate stack size
114#define kStackSize 2048
115
116static unsigned short StackSelector = NULL;
117static unsigned long StackPointer;
118
119static unsigned short oldStackSelector;
120static unsigned long oldStackPointer;
121
122// This is defined because we can't create local variables in a
123// function that switches stacks.
124static int GlobalStatus;
125
126// These declarations are necessary to use the inline assembly pragmas.
127
128extern void GetStack(unsigned short *selptr,unsigned long *stackptr);
129extern void SetStack(unsigned short selector,unsigned long stackptr);
130
131// This function will get the current stack selector and pointer and save
132// them off.
133#pragma aux GetStack = \
134 "mov [edi],esp" \
135 "mov ax,ss" \
136 "mov [esi],ax" \
137 parm [esi] [edi] \
138 modify [eax esi edi];
139
140// This function will set the stack selector and pointer to the specified
141// values.
142#pragma aux SetStack = \
143 "mov ss,ax" \
144 "mov esp,edx" \
145 parm [ax] [edx] \
146 modify [eax edx];
147
148int BLASTER_DMAChannel;
149
150int BLASTER_ErrorCode = BLASTER_Ok;
151
152#define BLASTER_SetErrorCode( status ) \
153 BLASTER_ErrorCode = ( status );
154
155
156/*---------------------------------------------------------------------
157 Function: BLASTER_ErrorString
158
159 Returns a pointer to the error message associated with an error
160 number. A -1 returns a pointer the current error.
161---------------------------------------------------------------------*/
162
163char *BLASTER_ErrorString
164 (
165 int ErrorNumber
166 )
167
168 {
169 char *ErrorString;
170
171 switch( ErrorNumber )
172 {
173 case BLASTER_Warning :
174 case BLASTER_Error :
175 ErrorString = BLASTER_ErrorString( BLASTER_ErrorCode );
176 break;
177
178 case BLASTER_Ok :
179 ErrorString = "Sound Blaster ok.";
180 break;
181
182 case BLASTER_EnvNotFound :
183 ErrorString = "BLASTER environment variable not set.";
184 break;
185
186 case BLASTER_AddrNotSet :
187 ErrorString = "Sound Blaster address not set.";
188 break;
189
190 case BLASTER_DMANotSet :
191 ErrorString = "Sound Blaster 8-bit DMA channel not set.";
192 break;
193
194 case BLASTER_DMA16NotSet :
195 ErrorString = "Sound Blaster 16-bit DMA channel not set.";
196 break;
197
198 case BLASTER_InvalidParameter :
199 ErrorString = "Invalid parameter in BLASTER environment variable.";
200 break;
201
202 case BLASTER_CardNotReady :
203 ErrorString = "Sound Blaster not responding on selected port.";
204 break;
205
206 case BLASTER_NoSoundPlaying :
207 ErrorString = "No sound playing on Sound Blaster.";
208 break;
209
210 case BLASTER_InvalidIrq :
211 ErrorString = "Invalid Sound Blaster Irq.";
212 break;
213
214 case BLASTER_UnableToSetIrq :
215 ErrorString = "Unable to set Sound Blaster IRQ. Try selecting an IRQ of 7 or below.";
216 break;
217
218 case BLASTER_DmaError :
219 ErrorString = DMA_ErrorString( DMA_Error );
220 break;
221
222 case BLASTER_NoMixer :
223 ErrorString = "Mixer not available on selected Sound Blaster card.";
224 break;
225
226 case BLASTER_DPMI_Error :
227 ErrorString = "DPMI Error in Blaster.";
228 break;
229
230 case BLASTER_OutOfMemory :
231 ErrorString = "Out of conventional memory in Blaster.";
232 break;
233
234 default :
235 ErrorString = "Unknown Sound Blaster error code.";
236 break;
237 }
238
239 return( ErrorString );
240 }
241
242
243/**********************************************************************
244
245 Memory locked functions:
246
247**********************************************************************/
248
249
250#define BLASTER_LockStart BLASTER_EnableInterrupt
251
252
253/*---------------------------------------------------------------------
254 Function: BLASTER_EnableInterrupt
255
256 Enables the triggering of the sound card interrupt.
257---------------------------------------------------------------------*/
258
259void BLASTER_EnableInterrupt
260 (
261 void
262 )
263
264 {
265 int Irq;
266 int mask;
267
268 // Unmask system interrupt
269 Irq = BLASTER_Config.Interrupt;
270 if ( Irq < 8 )
271 {
272 mask = inp( 0x21 ) & ~( 1 << Irq );
273 outp( 0x21, mask );
274 }
275 else
276 {
277 mask = inp( 0xA1 ) & ~( 1 << ( Irq - 8 ) );
278 outp( 0xA1, mask );
279
280 mask = inp( 0x21 ) & ~( 1 << 2 );
281 outp( 0x21, mask );
282 }
283
284 }
285
286
287/*---------------------------------------------------------------------
288 Function: BLASTER_DisableInterrupt
289
290 Disables the triggering of the sound card interrupt.
291---------------------------------------------------------------------*/
292
293void BLASTER_DisableInterrupt
294 (
295 void
296 )
297
298 {
299 int Irq;
300 int mask;
301
302 // Restore interrupt mask
303 Irq = BLASTER_Config.Interrupt;
304 if ( Irq < 8 )
305 {
306 mask = inp( 0x21 ) & ~( 1 << Irq );
307 mask |= BLASTER_IntController1Mask & ( 1 << Irq );
308 outp( 0x21, mask );
309 }
310 else
311 {
312 mask = inp( 0x21 ) & ~( 1 << 2 );
313 mask |= BLASTER_IntController1Mask & ( 1 << 2 );
314 outp( 0x21, mask );
315
316 mask = inp( 0xA1 ) & ~( 1 << ( Irq - 8 ) );
317 mask |= BLASTER_IntController2Mask & ( 1 << ( Irq - 8 ) );
318 outp( 0xA1, mask );
319 }
320 }
321
322
323/*---------------------------------------------------------------------
324 Function: BLASTER_ServiceInterrupt
325
326 Handles interrupt generated by sound card at the end of a voice
327 transfer. Calls the user supplied callback function.
328---------------------------------------------------------------------*/
329
330void __interrupt __far BLASTER_ServiceInterrupt
331 (
332 void
333 )
334
335 {
336 #ifdef USESTACK
337 // save stack
338 GetStack( &oldStackSelector, &oldStackPointer );
339
340 // set our stack
341 SetStack( StackSelector, StackPointer );
342 #endif
343
344 // Acknowledge interrupt
345 // Check if this is this an SB16 or newer
346 if ( BLASTER_Version >= DSP_Version4xx )
347 {
348 outp( BLASTER_Config.Address + BLASTER_MixerAddressPort,
349 MIXER_DSP4xxISR_Ack );
350
351 GlobalStatus = inp( BLASTER_Config.Address + BLASTER_MixerDataPort );
352
353 // Check if a 16-bit DMA interrupt occurred
354 if ( GlobalStatus & MIXER_16BITDMA_INT )
355 {
356 // Acknowledge 16-bit transfer interrupt
357 inp( BLASTER_Config.Address + BLASTER_16BitDMAAck );
358 }
359 else if ( GlobalStatus & MIXER_8BITDMA_INT )
360 {
361 inp( BLASTER_Config.Address + BLASTER_DataAvailablePort );
362 }
363 else
364 {
365 #ifdef USESTACK
366 // restore stack
367 SetStack( oldStackSelector, oldStackPointer );
368 #endif
369
370 // Wasn't our interrupt. Call the old one.
371 _chain_intr( BLASTER_OldInt );
372 }
373 }
374 else
375 {
376 // Older card - can't detect if an interrupt occurred.
377 inp( BLASTER_Config.Address + BLASTER_DataAvailablePort );
378 }
379
380 // Keep track of current buffer
381 BLASTER_CurrentDMABuffer += BLASTER_TransferLength;
382
383 if ( BLASTER_CurrentDMABuffer >= BLASTER_DMABufferEnd )
384 {
385 BLASTER_CurrentDMABuffer = BLASTER_DMABuffer;
386 }
387
388 // Continue playback on cards without autoinit mode
389 if ( BLASTER_Version < DSP_Version2xx )
390 {
391 if ( BLASTER_SoundPlaying )
392 {
393 BLASTER_DSP1xx_BeginPlayback( BLASTER_TransferLength );
394 }
395
396 if ( BLASTER_SoundRecording )
397 {
398 BLASTER_DSP1xx_BeginRecord( BLASTER_TransferLength );
399 }
400 }
401
402 // Call the caller's callback function
403 if ( BLASTER_CallBack != NULL )
404 {
405 BLASTER_CallBack();
406 }
407
408 #ifdef USESTACK
409 // restore stack
410 SetStack( oldStackSelector, oldStackPointer );
411 #endif
412
413 // send EOI to Interrupt Controller
414 if ( BLASTER_Config.Interrupt > 7 )
415 {
416 outp( 0xA0, 0x20 );
417 }
418
419 outp( 0x20, 0x20 );
420 }
421
422
423/*---------------------------------------------------------------------
424 Function: BLASTER_WriteDSP
425
426 Writes a byte of data to the sound card's DSP.
427---------------------------------------------------------------------*/
428
429int BLASTER_WriteDSP
430 (
431 unsigned data
432 )
433
434 {
435 int port;
436 unsigned count;
437 int status;
438
439 port = BLASTER_Config.Address + BLASTER_WritePort;
440
441 status = BLASTER_Error;
442
443 count = 0xFFFF;
444
445 do
446 {
447 if ( ( inp( port ) & 0x80 ) == 0 )
448 {
449 outp( port, data );
450 status = BLASTER_Ok;
451 break;
452 }
453
454 count--;
455 }
456 while( count > 0 );
457
458 if ( status != BLASTER_Ok )
459 {
460 BLASTER_SetErrorCode( BLASTER_CardNotReady );
461 }
462
463 return( status );
464 }
465
466
467/*---------------------------------------------------------------------
468 Function: BLASTER_ReadDSP
469
470 Reads a byte of data from the sound card's DSP.
471---------------------------------------------------------------------*/
472
473int BLASTER_ReadDSP
474 (
475 void
476 )
477
478 {
479 int port;
480 unsigned count;
481 int status;
482
483 port = BLASTER_Config.Address + BLASTER_DataAvailablePort;
484
485 status = BLASTER_Error;
486
487 count = 0xFFFF;
488
489 do
490 {
491 if ( inp( port ) & 0x80 )
492 {
493 status = inp( BLASTER_Config.Address + BLASTER_ReadPort );
494 break;
495 }
496
497 count--;
498 }
499 while( count > 0 );
500
501 if ( status == BLASTER_Error )
502 {
503 BLASTER_SetErrorCode( BLASTER_CardNotReady );
504 }
505
506 return( status );
507 }
508
509
510/*---------------------------------------------------------------------
511 Function: BLASTER_ResetDSP
512
513 Sends a reset command to the sound card's Digital Signal Processor
514 (DSP), causing it to perform an initialization.
515---------------------------------------------------------------------*/
516
517int BLASTER_ResetDSP
518 (
519 void
520 )
521
522 {
523 volatile int count;
524 int port;
525 int status;
526
527 port = BLASTER_Config.Address + BLASTER_ResetPort;
528
529 status = BLASTER_CardNotReady;
530
531 outp( port, 1 );
532
533/* What the hell am I doing here?
534 count = 100;
535
536 do
537 {
538 if ( inp( port ) == 255 )
539 {
540 break;
541 }
542
543 count--;
544 }
545 while( count > 0 );
546*/
547
548 count = 0x100;
549 do
550 {
551 count--;
552 }
553 while( count > 0 );
554
555 outp( port, 0 );
556
557 count = 100;
558
559 do
560 {
561 if ( BLASTER_ReadDSP() == BLASTER_Ready )
562 {
563 status = BLASTER_Ok;
564 break;
565 }
566
567 count--;
568 }
569 while( count > 0 );
570
571 return( status );
572 }
573
574
575/*---------------------------------------------------------------------
576 Function: BLASTER_GetDSPVersion
577
578 Returns the version number of the sound card's DSP.
579---------------------------------------------------------------------*/
580
581int BLASTER_GetDSPVersion
582 (
583 void
584 )
585
586 {
587 int MajorVersion;
588 int MinorVersion;
589 int version;
590
591 BLASTER_WriteDSP( DSP_GetVersion );
592
593 MajorVersion = BLASTER_ReadDSP();
594 MinorVersion = BLASTER_ReadDSP();
595
596 if ( ( MajorVersion == BLASTER_Error ) ||
597 ( MinorVersion == BLASTER_Error ) )
598 {
599 BLASTER_SetErrorCode( BLASTER_CardNotReady );
600 return( BLASTER_Error );
601 }
602
603 version = ( MajorVersion << 8 ) + MinorVersion;
604
605 if ( version >= DSP_Version4xx )
606 {
607 BLASTER_Card.IsSupported = TRUE;
608 BLASTER_Card.HasMixer = YES;
609 BLASTER_Card.MaxMixMode = STEREO_16BIT;
610 BLASTER_Card.MinSamplingRate = 5000;
611 BLASTER_Card.MaxSamplingRate = 44100;
612 BLASTER_MixerType = SB16;
613 }
614 else if ( version >= DSP_Version3xx )
615 {
616 BLASTER_Card.IsSupported = TRUE;
617 BLASTER_Card.HasMixer = YES;
618 BLASTER_Card.MaxMixMode = STEREO_8BIT;
619 BLASTER_Card.MinSamplingRate = 4000;
620 BLASTER_Card.MaxSamplingRate = 44100;
621 BLASTER_MixerType = SBPro;
622 }
623 else if ( version >= DSP_Version2xx )
624 {
625 BLASTER_Card.IsSupported = TRUE;
626 BLASTER_Card.HasMixer = NO;
627 BLASTER_Card.MaxMixMode = MONO_8BIT;
628 BLASTER_Card.MinSamplingRate = 4000;
629 BLASTER_Card.MaxSamplingRate = 23000;
630 BLASTER_MixerType = 0;
631 }
632 else
633 {
634 // DSP_Version1xx
635 BLASTER_Card.IsSupported = TRUE;
636 BLASTER_Card.HasMixer = NO;
637 BLASTER_Card.MaxMixMode = MONO_8BIT;
638 BLASTER_Card.MinSamplingRate = 4000;
639 BLASTER_Card.MaxSamplingRate = 23000;
640 BLASTER_MixerType = 0;
641 }
642
643 return( version );
644 }
645
646
647/*---------------------------------------------------------------------
648 Function: BLASTER_SpeakerOn
649
650 Enables output from the DAC.
651---------------------------------------------------------------------*/
652
653void BLASTER_SpeakerOn
654 (
655 void
656 )
657
658 {
659 BLASTER_WriteDSP( DSP_SpeakerOn );
660 }
661
662
663/*---------------------------------------------------------------------
664 Function: BLASTER_SpeakerOff
665
666 Disables output from the DAC.
667---------------------------------------------------------------------*/
668
669void BLASTER_SpeakerOff
670 (
671 void
672 )
673
674 {
675 BLASTER_WriteDSP( DSP_SpeakerOff );
676 }
677
678
679/*---------------------------------------------------------------------
680 Function: BLASTER_SetPlaybackRate
681
682 Sets the rate at which the digitized sound will be played in
683 hertz.
684---------------------------------------------------------------------*/
685
686void BLASTER_SetPlaybackRate
687 (
688 unsigned rate
689 )
690
691 {
692 int LoByte;
693 int HiByte;
694
695 if ( BLASTER_Version < DSP_Version4xx )
696 {
697 int timeconstant;
698 long ActualRate;
699
700 // Send sampling rate as time constant for older Sound
701 // Blaster compatible cards.
702
703 ActualRate = rate * BLASTER_SamplePacketSize;
704 if ( ActualRate < BLASTER_Card.MinSamplingRate )
705 {
706 rate = BLASTER_Card.MinSamplingRate / BLASTER_SamplePacketSize;
707 }
708
709 if ( ActualRate > BLASTER_Card.MaxSamplingRate )
710 {
711 rate = BLASTER_Card.MaxSamplingRate / BLASTER_SamplePacketSize;
712 }
713
714 timeconstant = ( int )CalcTimeConstant( rate, BLASTER_SamplePacketSize );
715
716 // Keep track of what the actual rate is
717 BLASTER_SampleRate = ( unsigned )CalcSamplingRate( timeconstant );
718 BLASTER_SampleRate /= BLASTER_SamplePacketSize;
719
720 BLASTER_WriteDSP( DSP_SetTimeConstant );
721 BLASTER_WriteDSP( timeconstant );
722 }
723 else
724 {
725 // Send literal sampling rate for cards with DSP version
726 // 4.xx (Sound Blaster 16)
727
728 BLASTER_SampleRate = rate;
729
730 if ( BLASTER_SampleRate < BLASTER_Card.MinSamplingRate )
731 {
732 BLASTER_SampleRate = BLASTER_Card.MinSamplingRate;
733 }
734
735 if ( BLASTER_SampleRate > BLASTER_Card.MaxSamplingRate )
736 {
737 BLASTER_SampleRate = BLASTER_Card.MaxSamplingRate;
738 }
739
740 HiByte = hibyte( BLASTER_SampleRate );
741 LoByte = lobyte( BLASTER_SampleRate );
742
743 // Set playback rate
744 BLASTER_WriteDSP( DSP_Set_DA_Rate );
745 BLASTER_WriteDSP( HiByte );
746 BLASTER_WriteDSP( LoByte );
747
748 // Set recording rate
749 BLASTER_WriteDSP( DSP_Set_AD_Rate );
750 BLASTER_WriteDSP( HiByte );
751 BLASTER_WriteDSP( LoByte );
752 }
753 }
754
755
756/*---------------------------------------------------------------------
757 Function: BLASTER_GetPlaybackRate
758
759 Returns the rate at which the digitized sound will be played in
760 hertz.
761---------------------------------------------------------------------*/
762
763unsigned BLASTER_GetPlaybackRate
764 (
765 void
766 )
767
768 {
769 return( BLASTER_SampleRate );
770 }
771
772
773/*---------------------------------------------------------------------
774 Function: BLASTER_SetMixMode
775
776 Sets the sound card to play samples in mono or stereo.
777---------------------------------------------------------------------*/
778
779int BLASTER_SetMixMode
780 (
781 int mode
782 )
783
784 {
785 int port;
786 int data;
787 int CardType;
788
789 CardType = BLASTER_Config.Type;
790
791 mode &= BLASTER_MaxMixMode;
792
793 if ( !( BLASTER_Card.MaxMixMode & STEREO ) )
794 {
795 mode &= ~STEREO;
796 }
797
798 if ( !( BLASTER_Card.MaxMixMode & SIXTEEN_BIT ) )
799 {
800 mode &= ~SIXTEEN_BIT;
801 }
802
803 BLASTER_MixMode = mode;
804 BLASTER_SamplePacketSize = BLASTER_SampleSize[ mode ];
805
806 // For the Sound Blaster Pro, we have to set the mixer chip
807 // to play mono or stereo samples.
808
809 if ( ( CardType == SBPro ) || ( CardType == SBPro2 ) )
810 {
811 port = BLASTER_Config.Address + BLASTER_MixerAddressPort;
812 outp( port, MIXER_SBProOutputSetting );
813
814 port = BLASTER_Config.Address + BLASTER_MixerDataPort;
815
816 // Get current mode
817 data = inp( port );
818
819 // set stereo mode bit
820 if ( mode & STEREO )
821 {
822 data |= MIXER_SBProStereoFlag;
823 }
824 else
825 {
826 data &= ~MIXER_SBProStereoFlag;
827 }
828
829 // set the mode
830 outp( port, data );
831
832 BLASTER_SetPlaybackRate( BLASTER_SampleRate );
833 }
834
835 return( mode );
836 }
837
838
839/*---------------------------------------------------------------------
840 Function: BLASTER_StopPlayback
841
842 Ends the DMA transfer of digitized sound to the sound card.
843---------------------------------------------------------------------*/
844
845void BLASTER_StopPlayback
846 (
847 void
848 )
849
850 {
851 int DmaChannel;
852
853 // Don't allow anymore interrupts
854 BLASTER_DisableInterrupt();
855
856 if ( BLASTER_HaltTransferCommand == DSP_Reset )
857 {
858 BLASTER_ResetDSP();
859 }
860 else
861 {
862 BLASTER_WriteDSP( BLASTER_HaltTransferCommand );
863 }
864
865 // Disable the DMA channel
866 if ( BLASTER_MixMode & SIXTEEN_BIT )
867 {
868 DmaChannel = BLASTER_Config.Dma16;
869 }
870 else
871 {
872 DmaChannel = BLASTER_Config.Dma8;
873 }
874 DMA_EndTransfer( DmaChannel );
875
876 // Turn off speaker
877 BLASTER_SpeakerOff();
878
879 BLASTER_SoundPlaying = FALSE;
880 BLASTER_SoundRecording = FALSE;
881
882 BLASTER_DMABuffer = NULL;
883 }
884
885
886/*---------------------------------------------------------------------
887 Function: BLASTER_SetupDMABuffer
888
889 Programs the DMAC for sound transfer.
890---------------------------------------------------------------------*/
891
892int BLASTER_SetupDMABuffer
893 (
894 char *BufferPtr,
895 int BufferSize,
896 int mode
897 )
898
899 {
900 int DmaChannel;
901 int DmaStatus;
902 int errorcode;
903
904 if ( BLASTER_MixMode & SIXTEEN_BIT )
905 {
906 DmaChannel = BLASTER_Config.Dma16;
907 errorcode = BLASTER_DMA16NotSet;
908 }
909 else
910 {
911 DmaChannel = BLASTER_Config.Dma8;
912 errorcode = BLASTER_DMANotSet;
913 }
914
915 if ( DmaChannel == UNDEFINED )
916 {
917 BLASTER_SetErrorCode( errorcode );
918 return( BLASTER_Error );
919 }
920
921 DmaStatus = DMA_SetupTransfer( DmaChannel, BufferPtr, BufferSize, mode );
922 if ( DmaStatus == DMA_Error )
923 {
924 BLASTER_SetErrorCode( BLASTER_DmaError );
925 return( BLASTER_Error );
926 }
927
928 BLASTER_DMAChannel = DmaChannel;
929
930 BLASTER_DMABuffer = BufferPtr;
931 BLASTER_CurrentDMABuffer = BufferPtr;
932 BLASTER_TotalDMABufferSize = BufferSize;
933 BLASTER_DMABufferEnd = BufferPtr + BufferSize;
934
935 return( BLASTER_Ok );
936 }
937
938
939/*---------------------------------------------------------------------
940 Function: BLASTER_GetCurrentPos
941
942 Returns the offset within the current sound being played.
943---------------------------------------------------------------------*/
944
945int BLASTER_GetCurrentPos
946 (
947 void
948 )
949
950 {
951 char *CurrentAddr;
952 int DmaChannel;
953 int offset;
954
955 if ( !BLASTER_SoundPlaying )
956 {
957 BLASTER_SetErrorCode( BLASTER_NoSoundPlaying );
958 return( BLASTER_Error );
959 }
960
961 if ( BLASTER_MixMode & SIXTEEN_BIT )
962 {
963 DmaChannel = BLASTER_Config.Dma16;
964 }
965 else
966 {
967 DmaChannel = BLASTER_Config.Dma8;
968 }
969
970 if ( DmaChannel == UNDEFINED )
971 {
972 BLASTER_SetErrorCode( BLASTER_DMANotSet );
973 return( BLASTER_Error );
974 }
975
976 CurrentAddr = DMA_GetCurrentPos( DmaChannel );
977
978 offset = ( int )( ( ( unsigned long )CurrentAddr ) -
979 ( ( unsigned long )BLASTER_CurrentDMABuffer ) );
980
981 if ( BLASTER_MixMode & SIXTEEN_BIT )
982 {
983 offset >>= 1;
984 }
985
986 if ( BLASTER_MixMode & STEREO )
987 {
988 offset >>= 1;
989 }
990
991 return( offset );
992 }
993
994
995/*---------------------------------------------------------------------
996 Function: BLASTER_DSP1xx_BeginPlayback
997
998 Starts playback of digitized sound on cards compatible with DSP
999 version 1.xx.
1000---------------------------------------------------------------------*/
1001
1002int BLASTER_DSP1xx_BeginPlayback
1003 (
1004 int length
1005 )
1006
1007 {
1008 int SampleLength;
1009 int LoByte;
1010 int HiByte;
1011
1012 SampleLength = length - 1;
1013 HiByte = hibyte( SampleLength );
1014 LoByte = lobyte( SampleLength );
1015
1016 // Program DSP to play sound
1017 BLASTER_WriteDSP( DSP_Old8BitDAC );
1018 BLASTER_WriteDSP( LoByte );
1019 BLASTER_WriteDSP( HiByte );
1020
1021 BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
1022
1023 BLASTER_SoundPlaying = TRUE;
1024
1025 return( BLASTER_Ok );
1026 }
1027
1028
1029/*---------------------------------------------------------------------
1030 Function: BLASTER_DSP2xx_BeginPlayback
1031
1032 Starts playback of digitized sound on cards compatible with DSP
1033 version 2.xx.
1034---------------------------------------------------------------------*/
1035
1036int BLASTER_DSP2xx_BeginPlayback
1037 (
1038 int length
1039 )
1040
1041 {
1042 int SampleLength;
1043 int LoByte;
1044 int HiByte;
1045
1046 SampleLength = length - 1;
1047 HiByte = hibyte( SampleLength );
1048 LoByte = lobyte( SampleLength );
1049
1050 BLASTER_WriteDSP( DSP_SetBlockLength );
1051 BLASTER_WriteDSP( LoByte );
1052 BLASTER_WriteDSP( HiByte );
1053
1054 if ( ( BLASTER_Version >= DSP_Version201 ) && ( DSP_MaxNormalRate <
1055 ( BLASTER_SampleRate * BLASTER_SamplePacketSize ) ) )
1056 {
1057 BLASTER_WriteDSP( DSP_8BitHighSpeedAutoInitMode );
1058 BLASTER_HaltTransferCommand = DSP_Reset;
1059 }
1060 else
1061 {
1062 BLASTER_WriteDSP( DSP_8BitAutoInitMode );
1063 BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
1064 }
1065
1066 BLASTER_SoundPlaying = TRUE;
1067
1068 return( BLASTER_Ok );
1069 }
1070
1071
1072/*---------------------------------------------------------------------
1073 Function: BLASTER_DSP4xx_BeginPlayback
1074
1075 Starts playback of digitized sound on cards compatible with DSP
1076 version 4.xx, such as the Sound Blaster 16.
1077---------------------------------------------------------------------*/
1078
1079int BLASTER_DSP4xx_BeginPlayback
1080 (
1081 int length
1082 )
1083
1084 {
1085 int TransferCommand;
1086 int TransferMode;
1087 int SampleLength;
1088 int LoByte;
1089 int HiByte;
1090
1091 if ( BLASTER_MixMode & SIXTEEN_BIT )
1092 {
1093 TransferCommand = DSP_16BitDAC;
1094 SampleLength = ( length / 2 ) - 1;
1095 BLASTER_HaltTransferCommand = DSP_Halt16bitTransfer;
1096 if ( BLASTER_MixMode & STEREO )
1097 {
1098 TransferMode = DSP_SignedStereoData;
1099 }
1100 else
1101 {
1102 TransferMode = DSP_SignedMonoData;
1103 }
1104 }
1105 else
1106 {
1107 TransferCommand = DSP_8BitDAC;
1108 SampleLength = length - 1;
1109 BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
1110 if ( BLASTER_MixMode & STEREO )
1111 {
1112 TransferMode = DSP_UnsignedStereoData;
1113 }
1114 else
1115 {
1116 TransferMode = DSP_UnsignedMonoData;
1117 }
1118 }
1119
1120 HiByte = hibyte( SampleLength );
1121 LoByte = lobyte( SampleLength );
1122
1123 // Program DSP to play sound
1124 BLASTER_WriteDSP( TransferCommand );
1125 BLASTER_WriteDSP( TransferMode );
1126 BLASTER_WriteDSP( LoByte );
1127 BLASTER_WriteDSP( HiByte );
1128
1129 BLASTER_SoundPlaying = TRUE;
1130
1131 return( BLASTER_Ok );
1132 }
1133
1134
1135/*---------------------------------------------------------------------
1136 Function: BLASTER_BeginBufferedPlayback
1137
1138 Begins multibuffered playback of digitized sound on the sound card.
1139---------------------------------------------------------------------*/
1140
1141int BLASTER_BeginBufferedPlayback
1142 (
1143 char *BufferStart,
1144 int BufferSize,
1145 int NumDivisions,
1146 unsigned SampleRate,
1147 int MixMode,
1148 void ( *CallBackFunc )( void )
1149 )
1150
1151 {
1152 int DmaStatus;
1153 int TransferLength;
1154
1155//JIM
1156// if ( BLASTER_SoundPlaying || BLASTER_SoundRecording )
1157 {
1158 BLASTER_StopPlayback();
1159 }
1160
1161 BLASTER_SetMixMode( MixMode );
1162
1163 DmaStatus = BLASTER_SetupDMABuffer( BufferStart, BufferSize, DMA_AutoInitRead );
1164 if ( DmaStatus == BLASTER_Error )
1165 {
1166 return( BLASTER_Error );
1167 }
1168
1169 BLASTER_SetPlaybackRate( SampleRate );
1170
1171 BLASTER_SetCallBack( CallBackFunc );
1172
1173 BLASTER_EnableInterrupt();
1174
1175 // Turn on speaker
1176 BLASTER_SpeakerOn();
1177
1178 TransferLength = BufferSize / NumDivisions;
1179 BLASTER_TransferLength = TransferLength;
1180
1181 // Program the sound card to start the transfer.
1182 if ( BLASTER_Version < DSP_Version2xx )
1183 {
1184 BLASTER_DSP1xx_BeginPlayback( TransferLength );
1185 }
1186 else if ( BLASTER_Version < DSP_Version4xx )
1187 {
1188 BLASTER_DSP2xx_BeginPlayback( TransferLength );
1189 }
1190 else
1191 {
1192 BLASTER_DSP4xx_BeginPlayback( TransferLength );
1193 }
1194
1195 return( BLASTER_Ok );
1196 }
1197
1198
1199/*---------------------------------------------------------------------
1200 Function: BLASTER_DSP4xx_BeginRecord
1201
1202 Starts recording of digitized sound on cards compatible with DSP
1203 version 4.xx, such as the Sound Blaster 16.
1204---------------------------------------------------------------------*/
1205
1206int BLASTER_DSP4xx_BeginRecord
1207 (
1208 int length
1209 )
1210
1211 {
1212 int TransferCommand;
1213 int TransferMode;
1214 int SampleLength;
1215 int LoByte;
1216 int HiByte;
1217
1218 TransferCommand = DSP_8BitADC;
1219 SampleLength = length - 1;
1220 BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
1221
1222 TransferMode = DSP_UnsignedMonoData;
1223
1224 HiByte = hibyte( SampleLength );
1225 LoByte = lobyte( SampleLength );
1226
1227 // Program DSP to play sound
1228 BLASTER_WriteDSP( TransferCommand );
1229 BLASTER_WriteDSP( TransferMode );
1230 BLASTER_WriteDSP( LoByte );
1231 BLASTER_WriteDSP( HiByte );
1232
1233 BLASTER_SoundRecording = TRUE;
1234
1235 return( BLASTER_Ok );
1236 }
1237
1238
1239/*---------------------------------------------------------------------
1240 Function: BLASTER_DSP2xx_BeginRecord
1241
1242 Starts recording of digitized sound on cards compatible with DSP
1243 version 2.xx.
1244---------------------------------------------------------------------*/
1245
1246int BLASTER_DSP2xx_BeginRecord
1247 (
1248 int length
1249 )
1250
1251 {
1252 int SampleLength;
1253 int LoByte;
1254 int HiByte;
1255
1256 SampleLength = length - 1;
1257 HiByte = hibyte( SampleLength );
1258 LoByte = lobyte( SampleLength );
1259
1260 BLASTER_WriteDSP( DSP_SetBlockLength );
1261 BLASTER_WriteDSP( LoByte );
1262 BLASTER_WriteDSP( HiByte );
1263
1264 if ( ( BLASTER_Version >= DSP_Version201 ) && ( DSP_MaxNormalRate <
1265 ( BLASTER_SampleRate * BLASTER_SamplePacketSize ) ) )
1266 {
1267 BLASTER_WriteDSP( DSP_8BitHighSpeedAutoInitRecord );
1268 BLASTER_HaltTransferCommand = DSP_Reset;
1269 }
1270 else
1271 {
1272 BLASTER_WriteDSP( DSP_8BitAutoInitRecord );
1273 BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
1274 }
1275
1276 BLASTER_SoundRecording = TRUE;
1277
1278 return( BLASTER_Ok );
1279 }
1280
1281
1282/*---------------------------------------------------------------------
1283 Function: BLASTER_DSP1xx_BeginRecord
1284
1285 Starts recording of digitized sound on cards compatible with DSP
1286 version 1.xx.
1287---------------------------------------------------------------------*/
1288
1289int BLASTER_DSP1xx_BeginRecord
1290 (
1291 int length
1292 )
1293
1294 {
1295 int SampleLength;
1296 int LoByte;
1297 int HiByte;
1298
1299 SampleLength = length - 1;
1300 HiByte = hibyte( SampleLength );
1301 LoByte = lobyte( SampleLength );
1302
1303 // Program DSP to play sound
1304 BLASTER_WriteDSP( DSP_Old8BitADC );
1305 BLASTER_WriteDSP( LoByte );
1306 BLASTER_WriteDSP( HiByte );
1307
1308 BLASTER_HaltTransferCommand = DSP_Halt8bitTransfer;
1309
1310 BLASTER_SoundRecording = TRUE;
1311
1312 return( BLASTER_Ok );
1313 }
1314
1315
1316/*---------------------------------------------------------------------
1317 Function: BLASTER_BeginBufferedRecord
1318
1319 Begins multibuffered recording of digitized sound on the sound card.
1320---------------------------------------------------------------------*/
1321
1322int BLASTER_BeginBufferedRecord
1323 (
1324 char *BufferStart,
1325 int BufferSize,
1326 int NumDivisions,
1327 unsigned SampleRate,
1328 int MixMode,
1329 void ( *CallBackFunc )( void )
1330 )
1331
1332 {
1333 int DmaStatus;
1334 int TransferLength;
1335
1336//JIM
1337// if ( BLASTER_SoundPlaying || BLASTER_SoundRecording )
1338 {
1339 BLASTER_StopPlayback();
1340 }
1341
1342 BLASTER_SetMixMode( MixMode );
1343
1344 DmaStatus = BLASTER_SetupDMABuffer( BufferStart, BufferSize, DMA_AutoInitWrite );
1345 if ( DmaStatus == BLASTER_Error )
1346 {
1347 return( BLASTER_Error );
1348 }
1349
1350 BLASTER_SetPlaybackRate( SampleRate );
1351
1352 BLASTER_SetCallBack( CallBackFunc );
1353
1354 BLASTER_EnableInterrupt();
1355
1356 // Turn off speaker
1357 BLASTER_SpeakerOff();
1358
1359 TransferLength = BufferSize / NumDivisions;
1360 BLASTER_TransferLength = TransferLength;
1361
1362 // Program the sound card to start the transfer.
1363 if ( BLASTER_Version < DSP_Version2xx )
1364 {
1365 BLASTER_DSP1xx_BeginRecord( TransferLength );
1366 }
1367 else if ( BLASTER_Version < DSP_Version4xx )
1368 {
1369 BLASTER_DSP2xx_BeginRecord( TransferLength );
1370 }
1371 else
1372 {
1373 BLASTER_DSP4xx_BeginRecord( TransferLength );
1374 }
1375
1376 return( BLASTER_Ok );
1377 }
1378
1379
1380/*---------------------------------------------------------------------
1381 Function: BLASTER_WriteMixer
1382
1383 Writes a byte of data to the Sound Blaster's mixer chip.
1384---------------------------------------------------------------------*/
1385
1386void BLASTER_WriteMixer
1387 (
1388 int reg,
1389 int data
1390 )
1391
1392 {
1393 outp( BLASTER_MixerAddress + BLASTER_MixerAddressPort, reg );
1394 outp( BLASTER_MixerAddress + BLASTER_MixerDataPort, data );
1395 }
1396
1397
1398/*---------------------------------------------------------------------
1399 Function: BLASTER_ReadMixer
1400
1401 Reads a byte of data from the Sound Blaster's mixer chip.
1402---------------------------------------------------------------------*/
1403
1404int BLASTER_ReadMixer
1405 (
1406 int reg
1407 )
1408
1409 {
1410 int data;
1411
1412 outp( BLASTER_MixerAddress + BLASTER_MixerAddressPort, reg );
1413 data = inp( BLASTER_MixerAddress + BLASTER_MixerDataPort );
1414 return( data );
1415 }
1416
1417
1418/*---------------------------------------------------------------------
1419 Function: BLASTER_GetVoiceVolume
1420
1421 Reads the average volume of the digitized sound channel from the
1422 Sound Blaster's mixer chip.
1423---------------------------------------------------------------------*/
1424
1425int BLASTER_GetVoiceVolume
1426 (
1427 void
1428 )
1429
1430 {
1431 int volume;
1432 int left;
1433 int right;
1434
1435 switch( BLASTER_MixerType )
1436 {
1437 case SBPro :
1438 case SBPro2 :
1439 left = BLASTER_ReadMixer( MIXER_SBProVoice );
1440 right = ( left & 0x0f ) << 4;
1441 left &= 0xf0;
1442 volume = ( left + right ) / 2;
1443 break;
1444
1445 case SB16 :
1446 left = BLASTER_ReadMixer( MIXER_SB16VoiceLeft );
1447 right = BLASTER_ReadMixer( MIXER_SB16VoiceRight );
1448 volume = ( left + right ) / 2;
1449 break;
1450
1451 default :
1452 BLASTER_SetErrorCode( BLASTER_NoMixer );
1453 volume = BLASTER_Error;
1454 }
1455
1456 return( volume );
1457 }
1458
1459
1460/*---------------------------------------------------------------------
1461 Function: BLASTER_SetVoiceVolume
1462
1463 Sets the volume of the digitized sound channel on the Sound
1464 Blaster's mixer chip.
1465---------------------------------------------------------------------*/
1466
1467int BLASTER_SetVoiceVolume
1468 (
1469 int volume
1470 )
1471
1472 {
1473 int data;
1474 int status;
1475
1476 volume = min( 255, volume );
1477 volume = max( 0, volume );
1478
1479 status = BLASTER_Ok;
1480 switch( BLASTER_MixerType )
1481 {
1482 case SBPro :
1483 case SBPro2 :
1484 data = ( volume & 0xf0 ) + ( volume >> 4 );
1485 BLASTER_WriteMixer( MIXER_SBProVoice, data );
1486 break;
1487
1488 case SB16 :
1489 BLASTER_WriteMixer( MIXER_SB16VoiceLeft, volume & 0xf8 );
1490 BLASTER_WriteMixer( MIXER_SB16VoiceRight, volume & 0xf8 );
1491 break;
1492
1493 default :
1494 BLASTER_SetErrorCode( BLASTER_NoMixer );
1495 status = BLASTER_Error;
1496 }
1497
1498 return( status );
1499 }
1500
1501
1502/*---------------------------------------------------------------------
1503 Function: BLASTER_GetMidiVolume
1504
1505 Reads the average volume of the Midi sound channel from the
1506 Sound Blaster's mixer chip.
1507---------------------------------------------------------------------*/
1508
1509int BLASTER_GetMidiVolume
1510 (
1511 void
1512 )
1513
1514 {
1515 int volume;
1516 int left;
1517 int right;
1518
1519 switch( BLASTER_MixerType )
1520 {
1521 case SBPro :
1522 case SBPro2 :
1523 left = BLASTER_ReadMixer( MIXER_SBProMidi );
1524 right = ( left & 0x0f ) << 4;
1525 left &= 0xf0;
1526 volume = ( left + right ) / 2;
1527 break;
1528
1529 case SB16 :
1530 left = BLASTER_ReadMixer( MIXER_SB16MidiLeft );
1531 right = BLASTER_ReadMixer( MIXER_SB16MidiRight );
1532 volume = ( left + right ) / 2;
1533 break;
1534
1535 default :
1536 BLASTER_SetErrorCode( BLASTER_NoMixer );
1537 volume = BLASTER_Error;
1538 }
1539
1540 return( volume );
1541 }
1542
1543
1544/*---------------------------------------------------------------------
1545 Function: BLASTER_SetMidiVolume
1546
1547 Sets the volume of the Midi sound channel on the Sound
1548 Blaster's mixer chip.
1549---------------------------------------------------------------------*/
1550
1551int BLASTER_SetMidiVolume
1552 (
1553 int volume
1554 )
1555
1556 {
1557 int data;
1558 int status;
1559
1560 volume = min( 255, volume );
1561 volume = max( 0, volume );
1562
1563 status = BLASTER_Ok;
1564 switch( BLASTER_MixerType )
1565 {
1566 case SBPro :
1567 case SBPro2 :
1568 data = ( volume & 0xf0 ) + ( volume >> 4 );
1569 BLASTER_WriteMixer( MIXER_SBProMidi, data );
1570 break;
1571
1572 case SB16 :
1573 BLASTER_WriteMixer( MIXER_SB16MidiLeft, volume & 0xf8 );
1574 BLASTER_WriteMixer( MIXER_SB16MidiRight, volume & 0xf8 );
1575 break;
1576
1577 default :
1578 BLASTER_SetErrorCode( BLASTER_NoMixer );
1579 status = BLASTER_Error;
1580 }
1581
1582 return( status );
1583 }
1584
1585/*---------------------------------------------------------------------
1586 Function: BLASTER_CardHasMixer
1587
1588 Checks if the selected Sound Blaster card has a mixer.
1589---------------------------------------------------------------------*/
1590
1591int BLASTER_CardHasMixer
1592 (
1593 void
1594 )
1595
1596 {
1597 return( BLASTER_Card.HasMixer );
1598 }
1599
1600
1601/*---------------------------------------------------------------------
1602 Function: BLASTER_SaveVoiceVolume
1603
1604 Saves the user's voice mixer settings.
1605---------------------------------------------------------------------*/
1606
1607void BLASTER_SaveVoiceVolume
1608 (
1609 void
1610 )
1611
1612 {
1613 switch( BLASTER_MixerType )
1614 {
1615 case SBPro :
1616 case SBPro2 :
1617 BLASTER_OriginalVoiceVolumeLeft =
1618 BLASTER_ReadMixer( MIXER_SBProVoice );
1619 break;
1620
1621 case SB16 :
1622 BLASTER_OriginalVoiceVolumeLeft =
1623 BLASTER_ReadMixer( MIXER_SB16VoiceLeft );
1624 BLASTER_OriginalVoiceVolumeRight =
1625 BLASTER_ReadMixer( MIXER_SB16VoiceRight );
1626 break;
1627 }
1628 }
1629
1630
1631/*---------------------------------------------------------------------
1632 Function: BLASTER_RestoreVoiceVolume
1633
1634 Restores the user's voice mixer settings.
1635---------------------------------------------------------------------*/
1636
1637void BLASTER_RestoreVoiceVolume
1638 (
1639 void
1640 )
1641
1642 {
1643 switch( BLASTER_MixerType )
1644 {
1645 case SBPro :
1646 case SBPro2 :
1647 BLASTER_WriteMixer( MIXER_SBProVoice,
1648 BLASTER_OriginalVoiceVolumeLeft );
1649 break;
1650
1651 case SB16 :
1652 BLASTER_WriteMixer( MIXER_SB16VoiceLeft,
1653 BLASTER_OriginalVoiceVolumeLeft );
1654 BLASTER_WriteMixer( MIXER_SB16VoiceRight,
1655 BLASTER_OriginalVoiceVolumeRight );
1656 break;
1657 }
1658 }
1659
1660
1661/*---------------------------------------------------------------------
1662 Function: BLASTER_SaveMidiVolume
1663
1664 Saves the user's FM mixer settings.
1665---------------------------------------------------------------------*/
1666
1667void BLASTER_SaveMidiVolume
1668 (
1669 void
1670 )
1671
1672 {
1673 switch( BLASTER_MixerType )
1674 {
1675 case SBPro :
1676 case SBPro2 :
1677 BLASTER_OriginalMidiVolumeLeft =
1678 BLASTER_ReadMixer( MIXER_SBProMidi );
1679 break;
1680
1681 case SB16 :
1682 BLASTER_OriginalMidiVolumeLeft =
1683 BLASTER_ReadMixer( MIXER_SB16MidiLeft );
1684 BLASTER_OriginalMidiVolumeRight =
1685 BLASTER_ReadMixer( MIXER_SB16MidiRight );
1686 break;
1687 }
1688 }
1689
1690
1691/*---------------------------------------------------------------------
1692 Function: BLASTER_RestoreMidiVolume
1693
1694 Restores the user's FM mixer settings.
1695---------------------------------------------------------------------*/
1696
1697void BLASTER_RestoreMidiVolume
1698 (
1699 void
1700 )
1701
1702 {
1703 switch( BLASTER_MixerType )
1704 {
1705 case SBPro :
1706 case SBPro2 :
1707 BLASTER_WriteMixer( MIXER_SBProMidi,
1708 BLASTER_OriginalMidiVolumeLeft );
1709 break;
1710
1711 case SB16 :
1712 BLASTER_WriteMixer( MIXER_SB16MidiLeft,
1713 BLASTER_OriginalMidiVolumeLeft );
1714 BLASTER_WriteMixer( MIXER_SB16MidiRight,
1715 BLASTER_OriginalMidiVolumeRight );
1716 break;
1717 }
1718 }
1719
1720
1721/*---------------------------------------------------------------------
1722 Function: BLASTER_GetEnv
1723
1724 Retrieves the BLASTER environment settings and returns them to
1725 the caller.
1726---------------------------------------------------------------------*/
1727
1728int BLASTER_GetEnv
1729 (
1730 BLASTER_CONFIG *Config
1731 )
1732
1733 {
1734 char *Blaster;
1735 char parameter;
1736
1737 Config->Address = UNDEFINED;
1738 Config->Type = UNDEFINED;
1739 Config->Interrupt = UNDEFINED;
1740 Config->Dma8 = UNDEFINED;
1741 Config->Dma16 = UNDEFINED;
1742 Config->Midi = UNDEFINED;
1743 Config->Emu = UNDEFINED;
1744
1745 Blaster = getenv( "BLASTER" );
1746 if ( Blaster == NULL )
1747 {
1748 BLASTER_SetErrorCode( BLASTER_EnvNotFound );
1749 return( BLASTER_Error );
1750 }
1751
1752 while( *Blaster != 0 )
1753 {
1754 if ( *Blaster == ' ' )
1755 {
1756 Blaster++;
1757 continue;
1758 }
1759
1760 parameter = toupper( *Blaster );
1761 Blaster++;
1762
1763 if ( !isxdigit( *Blaster ) )
1764 {
1765 BLASTER_SetErrorCode( BLASTER_InvalidParameter );
1766 return( BLASTER_Error );
1767 }
1768
1769 switch( parameter )
1770 {
1771 case BlasterEnv_Address :
1772 sscanf( Blaster, "%x", &Config->Address );
1773 break;
1774 case BlasterEnv_Interrupt :
1775 sscanf( Blaster, "%d", &Config->Interrupt );
1776 break;
1777 case BlasterEnv_8bitDma :
1778 sscanf( Blaster, "%d", &Config->Dma8 );
1779 break;
1780 case BlasterEnv_Type :
1781 sscanf( Blaster, "%d", &Config->Type );
1782 break;
1783 case BlasterEnv_16bitDma :
1784 sscanf( Blaster, "%d", &Config->Dma16 );
1785 break;
1786 case BlasterEnv_Midi :
1787 sscanf( Blaster, "%x", &Config->Midi );
1788 break;
1789 case BlasterEnv_EmuAddress :
1790 sscanf( Blaster, "%x", &Config->Emu );
1791 break;
1792 default :
1793 // Skip the offending data
1794 // sscanf( Blaster, "%*s" );
1795 break;
1796 }
1797
1798 while( isxdigit( *Blaster ) )
1799 {
1800 Blaster++;
1801 }
1802 }
1803
1804 return( BLASTER_Ok );
1805 }
1806
1807
1808/*---------------------------------------------------------------------
1809 Function: BLASTER_SetCardSettings
1810
1811 Sets up the sound card's parameters.
1812---------------------------------------------------------------------*/
1813
1814int BLASTER_SetCardSettings
1815 (
1816 BLASTER_CONFIG Config
1817 )
1818
1819 {
1820 if ( BLASTER_Installed )
1821 {
1822 BLASTER_Shutdown();
1823 }
1824
1825 BLASTER_Config.Address = Config.Address;
1826 BLASTER_Config.Type = Config.Type;
1827 BLASTER_Config.Interrupt = Config.Interrupt;
1828 BLASTER_Config.Dma8 = Config.Dma8;
1829 BLASTER_Config.Dma16 = Config.Dma16;
1830 BLASTER_Config.Midi = Config.Midi;
1831 BLASTER_Config.Emu = Config.Emu;
1832 BLASTER_MixerAddress = Config.Address;
1833 BLASTER_MixerType = Config.Type;
1834
1835 if ( BLASTER_Config.Emu == UNDEFINED )
1836 {
1837 BLASTER_Config.Emu = BLASTER_Config.Address + 0x400;
1838 }
1839
1840 return( BLASTER_Ok );
1841 }
1842
1843
1844/*---------------------------------------------------------------------
1845 Function: BLASTER_GetCardSettings
1846
1847 Sets up the sound card's parameters.
1848---------------------------------------------------------------------*/
1849
1850int BLASTER_GetCardSettings
1851 (
1852 BLASTER_CONFIG *Config
1853 )
1854
1855 {
1856 if ( BLASTER_Config.Address == UNDEFINED )
1857 {
1858 return( BLASTER_Warning );
1859 }
1860 else
1861 {
1862 Config->Address = BLASTER_Config.Address;
1863 Config->Type = BLASTER_Config.Type;
1864 Config->Interrupt = BLASTER_Config.Interrupt;
1865 Config->Dma8 = BLASTER_Config.Dma8;
1866 Config->Dma16 = BLASTER_Config.Dma16;
1867 Config->Midi = BLASTER_Config.Midi;
1868 Config->Emu = BLASTER_Config.Emu;
1869 }
1870
1871 return( BLASTER_Ok );
1872 }
1873
1874
1875/*---------------------------------------------------------------------
1876 Function: BLASTER_GetCardInfo
1877
1878 Returns the maximum number of bits that can represent a sample
1879 (8 or 16) and the number of channels (1 for mono, 2 for stereo).
1880---------------------------------------------------------------------*/
1881
1882int BLASTER_GetCardInfo
1883 (
1884 int *MaxSampleBits,
1885 int *MaxChannels
1886 )
1887
1888 {
1889 if ( BLASTER_Card.MaxMixMode & STEREO )
1890 {
1891 *MaxChannels = 2;
1892 }
1893 else
1894 {
1895 *MaxChannels = 1;
1896 }
1897
1898 if ( BLASTER_Card.MaxMixMode & SIXTEEN_BIT )
1899 {
1900 *MaxSampleBits = 16;
1901 }
1902 else
1903 {
1904 *MaxSampleBits = 8;
1905 }
1906
1907 return( BLASTER_Ok );
1908 }
1909
1910
1911/*---------------------------------------------------------------------
1912 Function: BLASTER_SetCallBack
1913
1914 Specifies the user function to call at the end of a sound transfer.
1915---------------------------------------------------------------------*/
1916
1917void BLASTER_SetCallBack
1918 (
1919 void ( *func )( void )
1920 )
1921
1922 {
1923 BLASTER_CallBack = func;
1924 }
1925
1926
1927/*---------------------------------------------------------------------
1928 Function: BLASTER_LockEnd
1929
1930 Used for determining the length of the functions to lock in memory.
1931---------------------------------------------------------------------*/
1932
1933static void BLASTER_LockEnd
1934 (
1935 void
1936 )
1937
1938 {
1939 }
1940
1941
1942/*---------------------------------------------------------------------
1943 Function: BLASTER_UnlockMemory
1944
1945 Unlocks all neccessary data.
1946---------------------------------------------------------------------*/
1947
1948void BLASTER_UnlockMemory
1949 (
1950 void
1951 )
1952
1953 {
1954 DPMI_UnlockMemoryRegion( BLASTER_LockStart, BLASTER_LockEnd );
1955 DPMI_UnlockMemory( ( void * )&BLASTER_Interrupts[ 0 ],
1956 sizeof( BLASTER_Interrupts ) );
1957 DPMI_UnlockMemory( ( void * )&BLASTER_SampleSize[ 0 ],
1958 sizeof( BLASTER_SampleSize ) );
1959 DPMI_Unlock( BLASTER_Card );
1960 DPMI_Unlock( BLASTER_OldInt );
1961 DPMI_Unlock( BLASTER_Config );
1962 DPMI_Unlock( BLASTER_Installed );
1963 DPMI_Unlock( BLASTER_Version );
1964 DPMI_Unlock( BLASTER_DMABuffer );
1965 DPMI_Unlock( BLASTER_DMABufferEnd );
1966 DPMI_Unlock( BLASTER_CurrentDMABuffer );
1967 DPMI_Unlock( BLASTER_TotalDMABufferSize );
1968 DPMI_Unlock( BLASTER_TransferLength );
1969 DPMI_Unlock( BLASTER_MixMode );
1970 DPMI_Unlock( BLASTER_SamplePacketSize );
1971 DPMI_Unlock( BLASTER_SampleRate );
1972 DPMI_Unlock( BLASTER_HaltTransferCommand );
1973 DPMI_Unlock( ( int )BLASTER_SoundPlaying );
1974 DPMI_Unlock( ( int )BLASTER_SoundRecording );
1975 DPMI_Unlock( BLASTER_CallBack );
1976 DPMI_Unlock( BLASTER_IntController1Mask );
1977 DPMI_Unlock( BLASTER_IntController2Mask );
1978 DPMI_Unlock( BLASTER_MixerAddress );
1979 DPMI_Unlock( BLASTER_MixerType );
1980 DPMI_Unlock( BLASTER_OriginalMidiVolumeLeft );
1981 DPMI_Unlock( BLASTER_OriginalMidiVolumeRight );
1982 DPMI_Unlock( BLASTER_OriginalVoiceVolumeLeft );
1983 DPMI_Unlock( BLASTER_OriginalVoiceVolumeRight );
1984 DPMI_Unlock( GlobalStatus );
1985 }
1986
1987
1988/*---------------------------------------------------------------------
1989 Function: BLASTER_LockMemory
1990
1991 Locks all neccessary data.
1992---------------------------------------------------------------------*/
1993
1994int BLASTER_LockMemory
1995 (
1996 void
1997 )
1998
1999 {
2000 int status;
2001
2002 status = DPMI_LockMemoryRegion( BLASTER_LockStart, BLASTER_LockEnd );
2003 status |= DPMI_LockMemory( ( void * )&BLASTER_Interrupts[ 0 ],
2004 sizeof( BLASTER_Interrupts ) );
2005 status |= DPMI_LockMemory( ( void * )&BLASTER_SampleSize[ 0 ],
2006 sizeof( BLASTER_SampleSize ) );
2007 status |= DPMI_Lock( BLASTER_Card );
2008 status |= DPMI_Lock( BLASTER_OldInt );
2009 status |= DPMI_Lock( BLASTER_Config );
2010 status |= DPMI_Lock( BLASTER_Installed );
2011 status |= DPMI_Lock( BLASTER_Version );
2012 status |= DPMI_Lock( BLASTER_DMABuffer );
2013 status |= DPMI_Lock( BLASTER_DMABufferEnd );
2014 status |= DPMI_Lock( BLASTER_CurrentDMABuffer );
2015 status |= DPMI_Lock( BLASTER_TotalDMABufferSize );
2016 status |= DPMI_Lock( BLASTER_TransferLength );
2017 status |= DPMI_Lock( BLASTER_MixMode );
2018 status |= DPMI_Lock( BLASTER_SamplePacketSize );
2019 status |= DPMI_Lock( BLASTER_SampleRate );
2020 status |= DPMI_Lock( BLASTER_HaltTransferCommand );
2021 status |= DPMI_Lock( ( ( int )BLASTER_SoundPlaying ) );
2022 status |= DPMI_Lock( ( ( int )BLASTER_SoundRecording ) );
2023 status |= DPMI_Lock( BLASTER_CallBack );
2024 status |= DPMI_Lock( BLASTER_IntController1Mask );
2025 status |= DPMI_Lock( BLASTER_IntController2Mask );
2026 status |= DPMI_Lock( BLASTER_MixerAddress );
2027 status |= DPMI_Lock( BLASTER_MixerType );
2028 status |= DPMI_Lock( BLASTER_OriginalMidiVolumeLeft );
2029 status |= DPMI_Lock( BLASTER_OriginalMidiVolumeRight );
2030 status |= DPMI_Lock( BLASTER_OriginalVoiceVolumeLeft );
2031 status |= DPMI_Lock( BLASTER_OriginalVoiceVolumeRight );
2032 status |= DPMI_Lock( GlobalStatus );
2033
2034 if ( status != DPMI_Ok )
2035 {
2036 BLASTER_UnlockMemory();
2037 BLASTER_SetErrorCode( BLASTER_DPMI_Error );
2038 return( BLASTER_Error );
2039 }
2040
2041 return( BLASTER_Ok );
2042 }
2043
2044
2045/*---------------------------------------------------------------------
2046 Function: allocateTimerStack
2047
2048 Allocate a block of memory from conventional (low) memory and return
2049 the selector (which can go directly into a segment register) of the
2050 memory block or 0 if an error occured.
2051---------------------------------------------------------------------*/
2052
2053static unsigned short allocateTimerStack
2054 (
2055 unsigned short size
2056 )
2057
2058 {
2059 union REGS regs;
2060
2061 // clear all registers
2062 memset( &regs, 0, sizeof( regs ) );
2063
2064 // DPMI allocate conventional memory
2065 regs.w.ax = 0x100;
2066
2067 // size in paragraphs
2068 regs.w.bx = ( size + 15 ) / 16;
2069
2070 int386( 0x31, &regs, &regs );
2071 if (!regs.w.cflag)
2072 {
2073 // DPMI call returns selector in dx
2074 // (ax contains real mode segment
2075 // which is ignored here)
2076
2077 return( regs.w.dx );
2078 }
2079
2080 // Couldn't allocate memory.
2081 return( NULL );
2082 }
2083
2084
2085/*---------------------------------------------------------------------
2086 Function: deallocateTimerStack
2087
2088 Deallocate a block of conventional (low) memory given a selector to
2089 it. Assumes the block was allocated with DPMI function 0x100.
2090---------------------------------------------------------------------*/
2091
2092static void deallocateTimerStack
2093 (
2094 unsigned short selector
2095 )
2096
2097 {
2098 union REGS regs;
2099
2100 if ( selector != NULL )
2101 {
2102 // clear all registers
2103 memset( &regs, 0, sizeof( regs ) );
2104
2105 regs.w.ax = 0x101;
2106 regs.w.dx = selector;
2107 int386( 0x31, &regs, &regs );
2108 }
2109 }
2110
2111
2112/*---------------------------------------------------------------------
2113 Function: BLASTER_SetupWaveBlaster
2114
2115 Allows the WaveBlaster to play music while the Sound Blaster 16
2116 plays digital sound.
2117---------------------------------------------------------------------*/
2118
2119void BLASTER_SetupWaveBlaster
2120 (
2121 void
2122 )
2123
2124 {
2125
2126 if ( BLASTER_MixerType == SB16 )
2127 {
2128 // Disable MPU401 interrupts. If they are not disabled,
2129 // the SB16 will not produce sound or music.
2130 BLASTER_WaveBlasterState = BLASTER_ReadMixer( MIXER_DSP4xxISR_Enable );
2131 BLASTER_WriteMixer( MIXER_DSP4xxISR_Enable, MIXER_DisableMPU401Interrupts );
2132 }
2133 }
2134
2135
2136/*---------------------------------------------------------------------
2137 Function: BLASTER_ShutdownWaveBlaster
2138
2139 Restores WaveBlaster mixer to original state.
2140---------------------------------------------------------------------*/
2141
2142void BLASTER_ShutdownWaveBlaster
2143 (
2144 void
2145 )
2146
2147 {
2148 if ( BLASTER_MixerType == SB16 )
2149 {
2150 // Restore the state of MPU401 interrupts. If they are not disabled,
2151 // the SB16 will not produce sound or music.
2152 BLASTER_WriteMixer( MIXER_DSP4xxISR_Enable, BLASTER_WaveBlasterState );
2153 }
2154 }
2155
2156
2157/*---------------------------------------------------------------------
2158 Function: BLASTER_Init
2159
2160 Initializes the sound card and prepares the module to play
2161 digitized sounds.
2162---------------------------------------------------------------------*/
2163
2164int BLASTER_Init
2165 (
2166 void
2167 )
2168
2169 {
2170 int Irq;
2171 int Interrupt;
2172 int status;
2173
2174 if ( BLASTER_Installed )
2175 {
2176 BLASTER_Shutdown();
2177 }
2178
2179 if ( BLASTER_Config.Address == UNDEFINED )
2180 {
2181 BLASTER_SetErrorCode( BLASTER_AddrNotSet );
2182 return( BLASTER_Error );
2183 }
2184
2185 // Save the interrupt masks
2186 BLASTER_IntController1Mask = inp( 0x21 );
2187 BLASTER_IntController2Mask = inp( 0xA1 );
2188
2189 status = BLASTER_ResetDSP();
2190 if ( status == BLASTER_Ok )
2191 {
2192 BLASTER_SaveVoiceVolume();
2193
2194 BLASTER_SoundPlaying = FALSE;
2195
2196 BLASTER_SetCallBack( NULL );
2197
2198 BLASTER_DMABuffer = NULL;
2199
2200 BLASTER_Version = BLASTER_GetDSPVersion();
2201
2202 BLASTER_SetPlaybackRate( BLASTER_DefaultSampleRate );
2203 BLASTER_SetMixMode( BLASTER_DefaultMixMode );
2204
2205 if ( BLASTER_Config.Dma16 != UNDEFINED )
2206 {
2207 status = DMA_VerifyChannel( BLASTER_Config.Dma16 );
2208 if ( status == DMA_Error )
2209 {
2210 BLASTER_SetErrorCode( BLASTER_DmaError );
2211 return( BLASTER_Error );
2212 }
2213 }
2214
2215 if ( BLASTER_Config.Dma8 != UNDEFINED )
2216 {
2217 status = DMA_VerifyChannel( BLASTER_Config.Dma8 );
2218 if ( status == DMA_Error )
2219 {
2220 BLASTER_SetErrorCode( BLASTER_DmaError );
2221 return( BLASTER_Error );
2222 }
2223 }
2224
2225 // Install our interrupt handler
2226 Irq = BLASTER_Config.Interrupt;
2227 if ( !VALID_IRQ( Irq ) )
2228 {
2229 BLASTER_SetErrorCode( BLASTER_InvalidIrq );
2230 return( BLASTER_Error );
2231 }
2232
2233 Interrupt = BLASTER_Interrupts[ Irq ];
2234 if ( Interrupt == INVALID )
2235 {
2236 BLASTER_SetErrorCode( BLASTER_InvalidIrq );
2237 return( BLASTER_Error );
2238 }
2239
2240 status = BLASTER_LockMemory();
2241 if ( status != BLASTER_Ok )
2242 {
2243 BLASTER_UnlockMemory();
2244 return( status );
2245 }
2246
2247 StackSelector = allocateTimerStack( kStackSize );
2248 if ( StackSelector == NULL )
2249 {
2250 BLASTER_UnlockMemory();
2251 BLASTER_SetErrorCode( BLASTER_OutOfMemory );
2252 return( BLASTER_Error );
2253 }
2254
2255 // Leave a little room at top of stack just for the hell of it...
2256 StackPointer = kStackSize - sizeof( long );
2257
2258 BLASTER_OldInt = _dos_getvect( Interrupt );
2259 if ( Irq < 8 )
2260 {
2261 _dos_setvect( Interrupt, BLASTER_ServiceInterrupt );
2262 }
2263 else
2264 {
2265 status = IRQ_SetVector( Interrupt, BLASTER_ServiceInterrupt );
2266 if ( status != IRQ_Ok )
2267 {
2268 BLASTER_UnlockMemory();
2269 deallocateTimerStack( StackSelector );
2270 StackSelector = NULL;
2271 BLASTER_SetErrorCode( BLASTER_UnableToSetIrq );
2272 return( BLASTER_Error );
2273 }
2274 }
2275
2276 BLASTER_Installed = TRUE;
2277 status = BLASTER_Ok;
2278 }
2279
2280 BLASTER_SetErrorCode( status );
2281 return( status );
2282 }
2283
2284
2285/*---------------------------------------------------------------------
2286 Function: BLASTER_Shutdown
2287
2288 Ends transfer of sound data to the sound card and restores the
2289 system resources used by the card.
2290---------------------------------------------------------------------*/
2291
2292void BLASTER_Shutdown
2293 (
2294 void
2295 )
2296
2297 {
2298 int Irq;
2299 int Interrupt;
2300
2301 // Halt the DMA transfer
2302 BLASTER_StopPlayback();
2303
2304 BLASTER_RestoreVoiceVolume();
2305
2306 // Reset the DSP
2307 BLASTER_ResetDSP();
2308
2309 // Restore the original interrupt
2310 Irq = BLASTER_Config.Interrupt;
2311 Interrupt = BLASTER_Interrupts[ Irq ];
2312 if ( Irq >= 8 )
2313 {
2314 IRQ_RestoreVector( Interrupt );
2315 }
2316 _dos_setvect( Interrupt, BLASTER_OldInt );
2317
2318 BLASTER_SoundPlaying = FALSE;
2319
2320 BLASTER_DMABuffer = NULL;
2321
2322 BLASTER_SetCallBack( NULL );
2323
2324 BLASTER_UnlockMemory();
2325
2326 deallocateTimerStack( StackSelector );
2327 StackSelector = NULL;
2328
2329 BLASTER_Installed = FALSE;
2330 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/blaster.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/blaster.h
new file mode 100644
index 0000000000..f56324b765
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/blaster.h
@@ -0,0 +1,148 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: BLASTER.H
22
23 author: James R. Dose
24 date: February 4, 1994
25
26 Public header for BLASTER.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __BLASTER_H
32#define __BLASTER_H
33
34typedef struct
35 {
36 unsigned Address;
37 unsigned Type;
38 unsigned Interrupt;
39 unsigned Dma8;
40 unsigned Dma16;
41 unsigned Midi;
42 unsigned Emu;
43 } BLASTER_CONFIG;
44
45extern BLASTER_CONFIG BLASTER_Config;
46extern int BLASTER_DMAChannel;
47
48#define UNDEFINED -1
49
50enum BLASTER_ERRORS
51 {
52 BLASTER_Warning = -2,
53 BLASTER_Error = -1,
54 BLASTER_Ok = 0,
55 BLASTER_EnvNotFound,
56 BLASTER_AddrNotSet,
57 BLASTER_DMANotSet,
58 BLASTER_DMA16NotSet,
59 BLASTER_InvalidParameter,
60 BLASTER_CardNotReady,
61 BLASTER_NoSoundPlaying,
62 BLASTER_InvalidIrq,
63 BLASTER_UnableToSetIrq,
64 BLASTER_DmaError,
65 BLASTER_NoMixer,
66 BLASTER_DPMI_Error,
67 BLASTER_OutOfMemory
68 };
69
70enum BLASTER_Types
71 {
72 SB = 1,
73 SBPro = 2,
74 SB20 = 3,
75 SBPro2 = 4,
76 SB16 = 6
77 };
78
79#define BLASTER_MinCardType SB
80#define BLASTER_MaxCardType SB16
81
82#define STEREO 1
83#define SIXTEEN_BIT 2
84
85#define MONO_8BIT 0
86#define STEREO_8BIT ( STEREO )
87#define MONO_16BIT ( SIXTEEN_BIT )
88#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
89
90#define BLASTER_MaxMixMode STEREO_16BIT
91
92#define MONO_8BIT_SAMPLE_SIZE 1
93#define MONO_16BIT_SAMPLE_SIZE 2
94#define STEREO_8BIT_SAMPLE_SIZE ( 2 * MONO_8BIT_SAMPLE_SIZE )
95#define STEREO_16BIT_SAMPLE_SIZE ( 2 * MONO_16BIT_SAMPLE_SIZE )
96
97#define BLASTER_DefaultSampleRate 11000
98#define BLASTER_DefaultMixMode MONO_8BIT
99#define BLASTER_MaxIrq 15
100
101char *BLASTER_ErrorString( int ErrorNumber );
102void BLASTER_EnableInterrupt( void );
103void BLASTER_DisableInterrupt( void );
104int BLASTER_WriteDSP( unsigned data );
105int BLASTER_ReadDSP( void );
106int BLASTER_ResetDSP( void );
107int BLASTER_GetDSPVersion( void );
108void BLASTER_SpeakerOn( void );
109void BLASTER_SpeakerOff( void );
110void BLASTER_SetPlaybackRate( unsigned rate );
111unsigned BLASTER_GetPlaybackRate( void );
112int BLASTER_SetMixMode( int mode );
113void BLASTER_StopPlayback( void );
114int BLASTER_SetupDMABuffer( char *BufferPtr, int BufferSize, int mode );
115int BLASTER_GetCurrentPos( void );
116int BLASTER_DSP1xx_BeginPlayback( int length );
117int BLASTER_DSP2xx_BeginPlayback( int length );
118int BLASTER_DSP4xx_BeginPlayback( int length );
119int BLASTER_BeginBufferedRecord( char *BufferStart, int BufferSize,
120 int NumDivisions, unsigned SampleRate, int MixMode,
121 void ( *CallBackFunc )( void ) );
122int BLASTER_BeginBufferedPlayback( char *BufferStart,
123 int BufferSize, int NumDivisions, unsigned SampleRate,
124 int MixMode, void ( *CallBackFunc )( void ) );
125void BLASTER_WriteMixer( int reg, int data );
126int BLASTER_ReadMixer( int reg );
127int BLASTER_GetVoiceVolume( void );
128int BLASTER_SetVoiceVolume( int volume );
129int BLASTER_GetMidiVolume( void );
130int BLASTER_SetMidiVolume( int volume );
131int BLASTER_CardHasMixer( void );
132void BLASTER_SaveVoiceVolume( void );
133void BLASTER_RestoreVoiceVolume( void );
134void BLASTER_SaveMidiVolume( void );
135void BLASTER_RestoreMidiVolume( void );
136int BLASTER_GetEnv( BLASTER_CONFIG *Config );
137int BLASTER_SetCardSettings( BLASTER_CONFIG Config );
138int BLASTER_GetCardSettings( BLASTER_CONFIG *Config );
139int BLASTER_GetCardInfo( int *MaxSampleBits, int *MaxChannels );
140void BLASTER_SetCallBack( void ( *func )( void ) );
141void BLASTER_SetupWaveBlaster( void );
142void BLASTER_ShutdownWaveBlaster( void );
143int BLASTER_Init( void );
144void BLASTER_Shutdown( void );
145void BLASTER_UnlockMemory( void );
146int BLASTER_LockMemory( void );
147
148#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/ctaweapi.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/ctaweapi.h
new file mode 100644
index 0000000000..d398f4362a
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/ctaweapi.h
@@ -0,0 +1,352 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/****************************************************************************\
21* *
22* CTAWEAPI.H SB AWE32 DOS API header *
23* *
24* (C) Copyright Creative Technology Ltd. 1992-94. All rights reserved *
25* worldwide. *
26* *
27* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY *
28* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE *
29* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR *
30* PURPOSE. *
31* *
32* You have a royalty-free right to use, modify, reproduce and *
33* distribute the Sample Files (and/or any modified version) in *
34* any way you find useful, provided that you agree to *
35* the Creative's Software Licensing Aggreement and you also agree that *
36* Creative has no warranty obligations or liability for any Sample Files. *
37* *
38\****************************************************************************/
39
40/****************************************************************************\
41* File name : CTAWEAPI.H *
42* *
43* Programmer : Creative SB AWE32 Team *
44* Creative Technology Ltd, 1994. All rights reserved. *
45* *
46* Version : 2.0b *
47* *
48\****************************************************************************/
49
50#ifndef _CTAWEAPI
51#define _CTAWEAPI
52
53
54#define MAXBANKS 64 /* maximum number of banks */
55#define MAXNRPN 32 /* maximum number of NRPN */
56
57
58#if defined(__FLAT__) || defined(__HIGHC__) || defined(DOS386)
59#define PACKETSIZE 8192 /* packet size for 32bit libraries */
60#else
61#define PACKETSIZE 512 /* packet size for real mode libraries */
62#endif
63
64
65#if defined(__FLAT__)
66 #define NEAR
67 #define FAR
68#endif
69
70
71#if defined(__SC__)
72 #pragma pack(1)
73 #if defined(DOS386)
74 #define NEAR
75 #define FAR
76 #endif
77#endif
78
79
80#if defined(__WATCOMC__)
81 #pragma pack(1)
82#endif
83
84
85#if defined(__HIGHC__)
86 #define NEAR
87 #define FAR
88 #define PASCAL _DCC((_DEFAULT_CALLING_CONVENTION|_CALLEE_POPS_STACK) & \
89 ~ (_REVERSE_PARMS|_OVERLOADED))
90 #pragma Push_align_members(1)
91 #pragma Global_aliasing_convention("_%r")
92#endif
93
94
95typedef int BOOL;
96#define FALSE 0
97#define TRUE 1
98
99typedef unsigned char BYTE;
100typedef unsigned short WORD;
101typedef unsigned long DWORD;
102
103typedef short int SHORT;
104typedef unsigned int UINT;
105typedef signed long LONG;
106
107#ifndef FAR
108#define FAR __far
109#endif
110
111#ifndef HUGE
112#define HUGE __huge
113#endif
114
115#ifndef PASCAL
116#define PASCAL __pascal
117#endif
118
119typedef void FAR* LPVOID;
120typedef BYTE FAR* LPBYTE;
121typedef WORD FAR* LPWORD;
122typedef DWORD FAR* LPDWORD;
123
124#define LOBYTE(w) ((BYTE)(w))
125#define HIBYTE(w) ((BYTE)(((UINT)(w) >> 8) & 0xFF))
126
127#define LOWORD(l) ((WORD)(DWORD)(l))
128#define HIWORD(l) ((WORD)((((DWORD)(l)) >> 16) & 0xFFFF))
129
130
131#if defined(__cplusplus)
132extern "C" {
133#endif
134
135
136/* Start of modules */
137extern int* __midieng_code(void);
138extern int* __hardware_code(void);
139extern int* __sbkload_code(void);
140extern int* __nrpn_code(void);
141extern int __midivar_data;
142extern int __nrpnvar_data;
143extern int __embed_data;
144
145
146typedef char SCRATCH[702];
147typedef char SOUNDFONT[124];
148typedef char GCHANNEL[20];
149typedef char MIDICHANNEL[32];
150typedef char NRPNCHANNEL[96];
151
152typedef struct {
153 SHORT bank_no; /* Slot number being used */
154 SHORT total_banks; /* Total number of banks */
155 LONG FAR* banksizes; /* Pointer to a list of bank sizes */
156 LONG file_size; /* exact size of the sound font file */
157 char FAR* data; /* Address of buffer of size >= PACKETSIZE */
158 char FAR* presets; /* Allocated memory for preset data */
159
160 LONG total_patch_ram; /* Total patch ram available */
161 SHORT no_sample_packets;/* Number of packets of sound sample to stream */
162 LONG sample_seek; /* Start file location of sound sample */
163 LONG preset_seek; /* Address of preset_seek location */
164 LONG preset_read_size; /* Number of bytes from preset_seek to allocate and read */
165 LONG preset_size; /* Preset actual size */
166} SOUND_PACKET;
167
168typedef struct {
169 SHORT tag; /* Must be 0x100 or 0x101 */
170 SHORT preset_size; /* Preset table of this size is required */
171 SHORT no_wave_packets; /* Number of packets of Wave sample to stream. */
172 LONG reserved;
173
174 SHORT bank_no; /* bank number */
175 char FAR* data; /* Address of packet of size PACKETSIZE */
176 char FAR* presets; /* Allocated memory for preset data */
177 LONG sample_size; /* Sample size, i.e. number of samples */
178 LONG samples_per_sec; /* Samples per second */
179 SHORT bits_per_sample; /* Bits per sample, 8 or 16 */
180 SHORT no_channels; /* Number of channels, 1=mono, 2=stereo */
181 SHORT looping; /* Looping? 0=no, 1=yes */
182 LONG startloop; /* if looping, then these are the addresses */
183 LONG endloop;
184 SHORT release; /* release time, 0=24ms, 8191=23.78s */
185} WAVE_PACKET;
186
187typedef struct {
188 LPBYTE SPad1;
189 LPBYTE SPad2;
190 LPBYTE SPad3;
191 LPBYTE SPad4;
192 LPBYTE SPad5;
193 LPBYTE SPad6;
194 LPBYTE SPad7;
195} SOUNDPAD;
196
197/* AWE32 variables */
198extern WORD awe32NumG;
199extern WORD awe32BaseAddx;
200extern DWORD awe32DramSize;
201
202/* MIDI variables */
203extern SCRATCH awe32Scratch;
204extern SOUNDFONT awe32SFont[4];
205extern GCHANNEL awe32GChannel[32];
206extern MIDICHANNEL awe32MIDIChannel[16];
207extern SOUNDPAD awe32SoundPad;
208
209/* NRPN variables */
210extern NRPNCHANNEL awe32NRPNChannel[16];
211
212/* SoundFont objects */
213extern BYTE awe32SPad1Obj[];
214extern BYTE awe32SPad2Obj[];
215extern BYTE awe32SPad3Obj[];
216extern BYTE awe32SPad4Obj[];
217extern BYTE awe32SPad5Obj[];
218extern BYTE awe32SPad6Obj[];
219extern BYTE awe32SPad7Obj[];
220
221/* AWE register functions */
222extern void PASCAL awe32RegW(WORD, WORD);
223extern WORD PASCAL awe32RegRW(WORD);
224extern void PASCAL awe32RegDW(WORD, DWORD);
225extern DWORD PASCAL awe32RegRDW(WORD);
226
227/* MIDI support functions */
228extern WORD PASCAL awe32InitMIDI(void);
229extern WORD PASCAL awe32NoteOn(WORD, WORD, WORD);
230extern WORD PASCAL awe32NoteOff(WORD, WORD, WORD);
231extern WORD PASCAL awe32ProgramChange(WORD, WORD);
232extern WORD PASCAL awe32Controller(WORD, WORD, WORD);
233extern WORD PASCAL awe32PolyKeyPressure(WORD, WORD, WORD);
234extern WORD PASCAL awe32ChannelPressure(WORD, WORD);
235extern WORD PASCAL awe32PitchBend(WORD, WORD, WORD);
236extern WORD PASCAL awe32Sysex(WORD, LPBYTE, WORD);
237extern WORD PASCAL __awe32NoteOff(WORD, WORD, WORD, WORD);
238extern WORD PASCAL __awe32IsPlaying(WORD, WORD, WORD, WORD);
239
240/* NRPN support functions */
241extern WORD PASCAL awe32InitNRPN(void);
242
243/* Hardware support functions */
244extern WORD PASCAL awe32Detect(WORD);
245extern WORD PASCAL awe32InitHardware(void);
246extern WORD PASCAL awe32Terminate(void);
247
248/* SoundFont support functions */
249extern WORD PASCAL awe32TotalPatchRam(SOUND_PACKET FAR*);
250extern WORD PASCAL awe32DefineBankSizes(SOUND_PACKET FAR*);
251extern WORD PASCAL awe32SFontLoadRequest(SOUND_PACKET FAR*);
252extern WORD PASCAL awe32StreamSample(SOUND_PACKET FAR*);
253extern WORD PASCAL awe32SetPresets(SOUND_PACKET FAR*);
254extern WORD PASCAL awe32ReleaseBank(SOUND_PACKET FAR*);
255extern WORD PASCAL awe32ReleaseAllBanks(SOUND_PACKET FAR*);
256extern WORD PASCAL awe32WPLoadRequest(WAVE_PACKET FAR*);
257extern WORD PASCAL awe32WPLoadWave(WAVE_PACKET FAR*);
258extern WORD PASCAL awe32WPStreamWave(WAVE_PACKET FAR*);
259extern WORD PASCAL awe32WPBuildSFont(WAVE_PACKET FAR*);
260
261/* End of modules */
262extern int* __midieng_ecode(void);
263extern int* __hardware_ecode(void);
264extern int* __sbkload_ecode(void);
265extern int* __nrpn_ecode(void);
266extern int __midivar_edata;
267extern int __nrpnvar_edata;
268extern int __embed_edata;
269
270
271#if defined(__cplusplus)
272}
273#endif
274
275
276#if defined(__SC__)
277 #pragma pack()
278#endif
279
280
281#if defined(__HIGHC__)
282 #pragma Pop_align_members
283 #pragma Global_aliasing_convention()
284 #pragma Alias(awe32RegW,"AWE32REGW")
285 #pragma Alias(awe32RegRW,"AWE32REGRW")
286 #pragma Alias(awe32RegDW,"AWE32REGDW")
287 #pragma Alias(awe32RegRDW,"AWE32REGRDW")
288 #pragma Alias(awe32InitMIDI,"AWE32INITMIDI")
289 #pragma Alias(awe32NoteOn,"AWE32NOTEON")
290 #pragma Alias(awe32NoteOff,"AWE32NOTEOFF")
291 #pragma Alias(awe32ProgramChange,"AWE32PROGRAMCHANGE")
292 #pragma Alias(awe32Controller,"AWE32CONTROLLER")
293 #pragma Alias(awe32PolyKeyPressure,"AWE32POLYKEYPRESSURE")
294 #pragma Alias(awe32ChannelPressure,"AWE32CHANNELPRESSURE")
295 #pragma Alias(awe32PitchBend,"AWE32PITCHBEND")
296 #pragma Alias(awe32Sysex,"AWE32SYSEX")
297 #pragma Alias(__awe32NoteOff,"__AWE32NOTEOFF")
298 #pragma Alias(__awe32IsPlaying,"__AWE32ISPLAYING")
299 #pragma Alias(awe32InitNRPN,"AWE32INITNRPN")
300 #pragma Alias(awe32Detect,"AWE32DETECT")
301 #pragma Alias(awe32InitHardware,"AWE32INITHARDWARE")
302 #pragma Alias(awe32Terminate,"AWE32TERMINATE")
303 #pragma Alias(awe32TotalPatchRam,"AWE32TOTALPATCHRAM")
304 #pragma Alias(awe32DefineBankSizes,"AWE32DEFINEBANKSIZES")
305 #pragma Alias(awe32SFontLoadRequest,"AWE32SFONTLOADREQUEST")
306 #pragma Alias(awe32StreamSample,"AWE32STREAMSAMPLE")
307 #pragma Alias(awe32SetPresets,"AWE32SETPRESETS")
308 #pragma Alias(awe32ReleaseBank,"AWE32RELEASEBANK")
309 #pragma Alias(awe32ReleaseAllBanks,"AWE32RELEASEALLBANKS")
310 #pragma Alias(awe32WPLoadRequest,"AWE32WPLOADREQUEST")
311 #pragma Alias(awe32WPLoadWave,"AWE32WPLOADWAVE")
312 #pragma Alias(awe32WPStreamWave,"AWE32WPSTREAMWAVE")
313 #pragma Alias(awe32WPBuildSFont,"AWE32WPBUILDSFONT")
314#endif
315
316
317#if defined(__WATCOMC__)
318 #pragma pack()
319 #pragma aux awe32NumG "_*"
320 #pragma aux awe32BaseAddx "_*"
321 #pragma aux awe32DramSize "_*"
322 #pragma aux awe32Scratch "_*"
323 #pragma aux awe32SFont "_*"
324 #pragma aux awe32GChannel "_*"
325 #pragma aux awe32MIDIChannel "_*"
326 #pragma aux awe32SoundPad "_*"
327 #pragma aux awe32NRPNChannel "_*"
328 #pragma aux awe32SPad1Obj "_*"
329 #pragma aux awe32SPad2Obj "_*"
330 #pragma aux awe32SPad3Obj "_*"
331 #pragma aux awe32SPad4Obj "_*"
332 #pragma aux awe32SPad5Obj "_*"
333 #pragma aux awe32SPad6Obj "_*"
334 #pragma aux awe32SPad7Obj "_*"
335 #pragma aux __midieng_code "_*"
336 #pragma aux __midieng_ecode "_*"
337 #pragma aux __hardware_code "_*"
338 #pragma aux __hardware_ecode "_*"
339 #pragma aux __sbkload_code "_*"
340 #pragma aux __sbkload_ecode "_*"
341 #pragma aux __nrpn_code "_*"
342 #pragma aux __nrpn_ecode "_*"
343 #pragma aux __midivar_data "_*"
344 #pragma aux __midivar_edata "_*"
345 #pragma aux __nrpnvar_data "_*"
346 #pragma aux __nrpnvar_edata "_*"
347 #pragma aux __embed_data "_*"
348 #pragma aux __embed_edata "_*"
349#endif
350
351
352#endif /* _CTAWEAPI */
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/debugio.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/debugio.c
new file mode 100644
index 0000000000..fb96db544e
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/debugio.c
@@ -0,0 +1,251 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20#include <stdio.h>
21#include <stdarg.h>
22#include <stdlib.h>
23#include "debugio.h"
24
25static unsigned short disp_offset = 160 * 24;
26static void myutoa( unsigned num, char *string, int radix );
27static void myitoa( int num, char *string, int radix );
28
29void DB_SetXY
30 (
31 int x,
32 int y
33 )
34
35 {
36 disp_offset = ( x * 2 ) + ( y * 160 );
37 }
38
39void DB_PutChar
40 (
41 char ch
42 )
43
44 {
45 int j;
46 char *disp_start = (char *)( 0xb0000 );
47
48 if ( disp_offset >= 160 * 24 )
49 {
50 for ( j = 160; j < 160 * 24; j += 2 )
51 {
52 *( disp_start + j - 160 ) = *( disp_start + j );
53 }
54
55 disp_offset = 160 * 23;
56
57 for ( j = disp_offset; j < ( 160 * 24 ); j += 2 )
58 {
59 *( disp_start + j ) = ' ';
60 }
61 }
62
63 if ( ch >= 32 )
64 {
65 *( disp_start + disp_offset ) = ch;
66 disp_offset = disp_offset + 2;
67 }
68
69 if ( ch == '\r' )
70 {
71 disp_offset = disp_offset / 160;
72 disp_offset = disp_offset * 160;
73 }
74
75 if ( ch == '\n' )
76 {
77 disp_offset = disp_offset + 160;
78 if ( disp_offset < 160 * 24 )
79 {
80 for ( j = disp_offset; j < ( ( ( disp_offset / 160 ) + 1 ) *
81 160 ); j += 2 )
82 {
83 *( disp_start + j ) = ' ';
84 }
85 }
86 }
87 }
88
89int DB_PrintString
90 (
91 char *string
92 )
93
94 {
95 int count;
96 char *ptr;
97
98 ptr = string;
99 count = 0;
100
101 while ( *ptr )
102 {
103 DB_PutChar( *ptr );
104 count++;
105 ptr++;
106 }
107
108 return( count );
109 }
110
111static void myutoa
112 (
113 unsigned num,
114 char *string,
115 int radix
116 )
117
118 {
119 int val;
120 int length;
121 int pos;
122 char temp[ 100 ];
123
124 length = 0;
125 do
126 {
127 val = num % radix;
128 if ( val < 10 )
129 {
130 temp[ length ] = '0' + val;
131 }
132 else
133 {
134 temp[ length ] = 'A' + val - 10;
135 }
136 num /= radix;
137 length++;
138 }
139 while( num > 0 );
140
141 pos = 0;
142 while( length > 0 )
143 {
144 length--;
145 string[ length ] = temp[ pos ];
146 pos++;
147 }
148 string[ pos ] = 0;
149 }
150
151static void myitoa
152 (
153 int num,
154 char *string,
155 int radix
156 )
157
158 {
159 if ( num < 0 )
160 {
161 *string++ = '-';
162 num = -num;
163 }
164
165 myutoa( num, string, radix );
166 }
167
168int DB_PrintNum
169 (
170 int number
171 )
172
173 {
174 char string[ 100 ];
175 int count;
176
177 myitoa( number, &string[ 0 ], 10 );
178 count = DB_PrintString( &string[ 0 ] );
179
180 return( count );
181 }
182
183int DB_PrintUnsigned
184 (
185 unsigned long number,
186 int radix
187 )
188
189 {
190 char string[ 100 ];
191 int count;
192
193 myutoa( number, &string[ 0 ], radix );
194 count = DB_PrintString( &string[ 0 ] );
195
196 return( count );
197 }
198
199int DB_printf
200 (
201 char *fmt,
202 ...
203 )
204
205 {
206 va_list argptr;
207 int count;
208 char *ptr;
209
210 va_start( argptr, fmt );
211 ptr = fmt;
212 count = 0;
213
214 while( *ptr != 0 )
215 {
216 if ( *ptr == '%' )
217 {
218 ptr++;
219 switch( *ptr )
220 {
221 case 0 :
222 return( EOF );
223 break;
224 case 'd' :
225 count += DB_PrintNum( va_arg( argptr, int ) );
226 break;
227 case 's' :
228 count += DB_PrintString( va_arg( argptr, char * ) );
229 break;
230 case 'u' :
231 count += DB_PrintUnsigned( va_arg( argptr, int ), 10 );
232 break;
233 case 'x' :
234 case 'X' :
235 count += DB_PrintUnsigned( va_arg( argptr, int ), 16 );
236 break;
237 }
238 ptr++;
239 }
240 else
241 {
242 DB_PutChar( *ptr );
243 count++;
244 ptr++;
245 }
246 }
247
248 va_end( argptr );
249
250 return( count );
251 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/debugio.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/debugio.h
new file mode 100644
index 0000000000..a6510ba196
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/debugio.h
@@ -0,0 +1,30 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20#ifndef __DEBUGIO_H
21#define __DEBUGIO_H
22
23void DB_SetXY( int x, int y );
24void DB_PutChar( char ch );
25int DB_PrintString( char *string );
26int DB_PrintNum( int number );
27int DB_PrintUnsigned( unsigned long number, int radix );
28int DB_printf( char *fmt, ... );
29
30#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dma.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dma.c
new file mode 100644
index 0000000000..6a05872c30
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dma.c
@@ -0,0 +1,379 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: DMA.C
22
23 author: James R. Dose
24 date: February 4, 1994
25
26 Low level routines to for programming the DMA controller for 8 bit
27 and 16 bit transfers.
28
29 (c) Copyright 1994 James R. Dose. All Rights Reserved.
30**********************************************************************/
31
32#include <dos.h>
33#include <conio.h>
34#include <stdlib.h>
35#include "dma.h"
36
37#define DMA_MaxChannel 7
38
39#define VALID ( 1 == 1 )
40#define INVALID ( !VALID )
41
42#define BYTE 0
43#define WORD 1
44
45typedef struct
46 {
47 int Valid;
48 int Width;
49 int Mask;
50 int Mode;
51 int Clear;
52 int Page;
53 int Address;
54 int Length;
55 } DMA_PORT;
56
57static const DMA_PORT DMA_PortInfo[ DMA_MaxChannel + 1 ] =
58 {
59 { VALID, BYTE, 0xA, 0xB, 0xC, 0x87, 0x0, 0x1 },
60 { VALID, BYTE, 0xA, 0xB, 0xC, 0x83, 0x2, 0x3 },
61 { INVALID, BYTE, 0xA, 0xB, 0xC, 0x81, 0x4, 0x5 },
62 { VALID, BYTE, 0xA, 0xB, 0xC, 0x82, 0x6, 0x7 },
63 { INVALID, WORD, 0xD4, 0xD6, 0xD8, 0x8F, 0xC0, 0xC2 },
64 { VALID, WORD, 0xD4, 0xD6, 0xD8, 0x8B, 0xC4, 0xC6 },
65 { VALID, WORD, 0xD4, 0xD6, 0xD8, 0x89, 0xC8, 0xCA },
66 { VALID, WORD, 0xD4, 0xD6, 0xD8, 0x8A, 0xCC, 0xCE },
67 };
68
69int DMA_ErrorCode = DMA_Ok;
70
71#define DMA_SetErrorCode( status ) \
72 DMA_ErrorCode = ( status );
73
74
75/*---------------------------------------------------------------------
76 Function: DMA_ErrorString
77
78 Returns a pointer to the error message associated with an error
79 number. A -1 returns a pointer the current error.
80---------------------------------------------------------------------*/
81
82char *DMA_ErrorString
83 (
84 int ErrorNumber
85 )
86
87 {
88 char *ErrorString;
89
90 switch( ErrorNumber )
91 {
92 case DMA_Error :
93 ErrorString = DMA_ErrorString( DMA_ErrorCode );
94 break;
95
96 case DMA_Ok :
97 ErrorString = "DMA channel ok.";
98 break;
99
100 case DMA_ChannelOutOfRange :
101 ErrorString = "DMA channel out of valid range.";
102 break;
103
104 case DMA_InvalidChannel :
105 ErrorString = "Unsupported DMA channel.";
106 break;
107
108 default :
109 ErrorString = "Unknown DMA error code.";
110 break;
111 }
112
113 return( ErrorString );
114 }
115
116
117/*---------------------------------------------------------------------
118 Function: DMA_VerifyChannel
119
120 Verifies whether a DMA channel is available to transfer data.
121---------------------------------------------------------------------*/
122
123int DMA_VerifyChannel
124 (
125 int channel
126 )
127
128 {
129 int status;
130 int Error;
131
132 status = DMA_Ok;
133 Error = DMA_Ok;
134
135 if ( ( channel < 0 ) || ( DMA_MaxChannel < channel ) )
136 {
137 Error = DMA_ChannelOutOfRange;
138 status = DMA_Error;
139 }
140 else if ( DMA_PortInfo[ channel ].Valid == INVALID )
141 {
142 Error = DMA_InvalidChannel;
143 status = DMA_Error;
144 }
145
146 DMA_SetErrorCode( Error );
147 return( status );
148 }
149
150
151/*---------------------------------------------------------------------
152 Function: DMA_SetupTransfer
153
154 Programs the specified DMA channel to transfer data.
155---------------------------------------------------------------------*/
156
157int DMA_SetupTransfer
158 (
159 int channel,
160 char *address,
161 int length,
162 int mode
163 )
164
165 {
166 DMA_PORT *Port;
167 int addr;
168 int ChannelSelect;
169 int Page;
170 int HiByte;
171 int LoByte;
172 int TransferLength;
173 int status;
174
175 status = DMA_VerifyChannel( channel );
176
177 if ( status == DMA_Ok )
178 {
179 Port = &DMA_PortInfo[ channel ];
180 ChannelSelect = channel & 0x3;
181
182 addr = ( int )address;
183
184 if ( Port->Width == WORD )
185 {
186 Page = ( addr >> 16 ) & 255;
187 HiByte = ( addr >> 9 ) & 255;
188 LoByte = ( addr >> 1 ) & 255;
189
190 // Convert the length in bytes to the length in words
191 TransferLength = ( length + 1 ) >> 1;
192
193 // The length is always one less the number of bytes or words
194 // that we're going to send
195 TransferLength--;
196 }
197 else
198 {
199 Page = ( addr >> 16 ) & 255;
200 HiByte = ( addr >> 8 ) & 255;
201 LoByte = addr & 255;
202
203 // The length is always one less the number of bytes or words
204 // that we're going to send
205 TransferLength = length - 1;
206 }
207
208 // Mask off DMA channel
209 outp( Port->Mask, 4 | ChannelSelect );
210
211 // Clear flip-flop to lower byte with any data
212 outp( Port->Clear, 0 );
213
214 // Set DMA mode
215 switch( mode )
216 {
217 case DMA_SingleShotRead :
218 outp( Port->Mode, 0x48 | ChannelSelect );
219 break;
220
221 case DMA_SingleShotWrite :
222 outp( Port->Mode, 0x44 | ChannelSelect );
223 break;
224
225 case DMA_AutoInitRead :
226 outp( Port->Mode, 0x58 | ChannelSelect );
227 break;
228
229 case DMA_AutoInitWrite :
230 outp( Port->Mode, 0x54 | ChannelSelect );
231 break;
232 }
233
234 // Send address
235 outp( Port->Address, LoByte );
236 outp( Port->Address, HiByte );
237
238 // Send page
239 outp( Port->Page, Page );
240
241 // Send length
242 outp( Port->Length, TransferLength );
243 outp( Port->Length, TransferLength >> 8 );
244
245 // enable DMA channel
246 outp( Port->Mask, ChannelSelect );
247 }
248
249 return( status );
250 }
251
252
253/*---------------------------------------------------------------------
254 Function: DMA_EndTransfer
255
256 Ends use of the specified DMA channel.
257---------------------------------------------------------------------*/
258
259int DMA_EndTransfer
260 (
261 int channel
262 )
263
264 {
265 DMA_PORT *Port;
266 int ChannelSelect;
267 int status;
268
269 status = DMA_VerifyChannel( channel );
270 if ( status == DMA_Ok )
271 {
272 Port = &DMA_PortInfo[ channel ];
273 ChannelSelect = channel & 0x3;
274
275 // Mask off DMA channel
276 outp( Port->Mask, 4 | ChannelSelect );
277
278 // Clear flip-flop to lower byte with any data
279 outp( Port->Clear, 0 );
280 }
281
282 return( status );
283 }
284
285
286/*---------------------------------------------------------------------
287 Function: DMA_GetCurrentPos
288
289 Returns the position of the specified DMA transfer.
290---------------------------------------------------------------------*/
291
292char *DMA_GetCurrentPos
293 (
294 int channel
295 )
296
297 {
298 DMA_PORT *Port;
299 unsigned long addr;
300 int status;
301
302 addr = NULL;
303 status = DMA_VerifyChannel( channel );
304
305 if ( status == DMA_Ok )
306 {
307 Port = &DMA_PortInfo[ channel ];
308
309 if ( Port->Width == WORD )
310 {
311 // Get address
312 addr = inp( Port->Address ) << 1;
313 addr |= inp( Port->Address ) << 9;
314
315 // Get page
316 addr |= inp( Port->Page ) << 16;
317 }
318 else
319 {
320 // Get address
321 addr = inp( Port->Address );
322 addr |= inp( Port->Address ) << 8;
323
324 // Get page
325 addr |= inp( Port->Page ) << 16;
326 }
327 }
328
329 return( ( char * )addr );
330 }
331
332
333/*---------------------------------------------------------------------
334 Function: DMA_GetTransferCount
335
336 Returns how many bytes are left in the DMA's transfer.
337---------------------------------------------------------------------*/
338
339int DMA_GetTransferCount
340 (
341 int channel
342 )
343
344 {
345 DMA_PORT *Port;
346 int count;
347 int status;
348
349 status = DMA_Ok;
350
351 count = 0;
352
353 if ( ( channel < 0 ) || ( DMA_MaxChannel < channel ) )
354 {
355 status = DMA_ChannelOutOfRange;
356 }
357 else if ( DMA_PortInfo[ channel ].Valid == INVALID )
358 {
359 status = DMA_InvalidChannel;
360 }
361
362 if ( status == DMA_Ok )
363 {
364 Port = &DMA_PortInfo[ channel ];
365
366 outp( Port->Clear, 0 );
367 count = inp( Port->Length );
368 count += inp( Port->Length ) << 8;
369
370 if ( Port->Width == WORD )
371 {
372 count <<= 1;
373 }
374 }
375
376 DMA_SetErrorCode( status );
377
378 return( count );
379 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dma.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dma.h
new file mode 100644
index 0000000000..f68d4ea2e5
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dma.h
@@ -0,0 +1,83 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 file: DMA.H
22
23 author: James R. Dose
24 date: February 4, 1994
25
26 Public header file for DMA.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __DMA_H
32#define __DMA_H
33
34enum DMA_ERRORS
35 {
36 DMA_Error = -1,
37 DMA_Ok = 0,
38 DMA_ChannelOutOfRange,
39 DMA_InvalidChannel
40 };
41
42enum DMA_Modes
43 {
44 DMA_SingleShotRead,
45 DMA_SingleShotWrite,
46 DMA_AutoInitRead,
47 DMA_AutoInitWrite
48 };
49
50char *DMA_ErrorString
51 (
52 int ErrorNumber
53 );
54
55int DMA_VerifyChannel
56 (
57 int channel
58 );
59
60int DMA_SetupTransfer
61 (
62 int channel,
63 char *address,
64 int length,
65 int mode
66 );
67
68int DMA_EndTransfer
69 (
70 int channel
71 );
72
73char *DMA_GetCurrentPos
74 (
75 int channel
76 );
77
78int DMA_GetTransferCount
79 (
80 int channel
81 );
82
83#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dpmi.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dpmi.c
new file mode 100644
index 0000000000..ea87f517bf
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dpmi.c
@@ -0,0 +1,250 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: DPMI.C
22
23 author: James R. Dose
24 date: April 8, 1994
25
26 Functions for performing DPMI calls.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#include <dos.h>
32#include <string.h>
33#include "dpmi.h"
34
35#define TRUE ( 1 == 1 )
36#define FALSE ( !TRUE )
37
38static union REGS Regs;
39static struct SREGS SegRegs;
40
41
42/*---------------------------------------------------------------------
43 Function: DPMI_GetRealModeVector
44
45 Returns the vector of a real mode interrupt.
46---------------------------------------------------------------------*/
47
48unsigned long DPMI_GetRealModeVector
49 (
50 int num
51 )
52
53 {
54 unsigned long vector;
55
56 Regs.x.eax = 0x0200;
57 Regs.h.bl = num;
58 int386( 0x31, &Regs, &Regs );
59
60 vector = Regs.w.cx & 0xffff;
61 vector <<= 16;
62 vector |= Regs.w.dx & 0xffff;
63
64 return( vector );
65 }
66
67
68/*---------------------------------------------------------------------
69 Function: DPMI_SetRealModeVector
70
71 Sets the vector of a real mode interrupt.
72---------------------------------------------------------------------*/
73
74void DPMI_SetRealModeVector
75 (
76 int num,
77 unsigned long vector
78 )
79
80 {
81 Regs.x.eax = 0x0201;
82 Regs.h.bl = num;
83 Regs.w.dx = vector & 0xffff;
84 Regs.w.cx = ( vector >> 16 ) & 0xffff;
85
86 int386( 0x31, &Regs, &Regs );
87 }
88
89
90/*---------------------------------------------------------------------
91 Function: DPMI_CallRealModeFunction
92
93 Performs a call to a real mode function.
94---------------------------------------------------------------------*/
95
96int DPMI_CallRealModeFunction
97 (
98 dpmi_regs *callregs
99 )
100
101 {
102 // Setup our registers to call DPMI
103 Regs.w.ax = 0x0301;
104 Regs.h.bl = 0;
105 Regs.h.bh = 0;
106 Regs.w.cx = 0;
107
108 SegRegs.es = FP_SEG( callregs );
109 Regs.x.edi = FP_OFF( callregs );
110
111 // Call Real-mode procedure with Far Return Frame
112 int386x( 0x31, &Regs, &Regs, &SegRegs );
113
114 if ( Regs.x.cflag )
115 {
116 return( DPMI_Error );
117 }
118
119 return( DPMI_Ok );
120 }
121
122
123/*---------------------------------------------------------------------
124 Function: DPMI_LockMemory
125
126 Locks a region of memory to keep the virtual memory manager from
127 paging the region out.
128---------------------------------------------------------------------*/
129
130int DPMI_LockMemory
131 (
132 void *address,
133 unsigned length
134 )
135
136 {
137 unsigned linear;
138
139 // Thanks to DOS/4GW's zero-based flat memory model, converting
140 // a pointer of any type to a linear address is trivial.
141
142 linear = (unsigned) address;
143
144 // DPMI Lock Linear Region
145 Regs.w.ax = 0x600;
146
147 // Linear address in BX:CX
148 Regs.w.bx = (linear >> 16);
149 Regs.w.cx = (linear & 0xFFFF);
150
151 // Length in SI:DI
152 Regs.w.si = (length >> 16);
153 Regs.w.di = (length & 0xFFFF);
154
155 int386 (0x31, &Regs, &Regs);
156
157 // Return 0 if can't lock
158 if ( Regs.w.cflag )
159 {
160 return( DPMI_Error );
161 }
162
163 return ( DPMI_Ok );
164 }
165
166
167/*---------------------------------------------------------------------
168 Function: DPMI_LockMemoryRegion
169
170 Locks a region of memory to keep the virtual memory manager from
171 paging the region out.
172---------------------------------------------------------------------*/
173
174int DPMI_LockMemoryRegion
175 (
176 void *start,
177 void *end
178 )
179
180 {
181 int status;
182
183 status = DPMI_LockMemory( start, ( char * )end - ( char * )start );
184
185 return( status );
186 }
187
188
189/*---------------------------------------------------------------------
190 Function: DPMI_UnlockMemory
191
192 Unlocks a region of memory that was previously locked.
193---------------------------------------------------------------------*/
194
195int DPMI_UnlockMemory
196 (
197 void *address,
198 unsigned length
199 )
200
201 {
202 unsigned linear;
203
204 // Thanks to DOS/4GW's zero-based flat memory model, converting
205 // a pointer of any type to a linear address is trivial.
206
207 linear = (unsigned) address;
208
209 // DPMI Unlock Linear Region
210 Regs.w.ax = 0x601;
211
212 // Linear address in BX:CX
213 Regs.w.bx = (linear >> 16);
214 Regs.w.cx = (linear & 0xFFFF);
215
216 // Length in SI:DI
217 Regs.w.si = (length >> 16);
218 Regs.w.di = (length & 0xFFFF);
219
220 int386 (0x31, &Regs, &Regs);
221
222 // Return 0 if can't unlock
223 if ( Regs.w.cflag )
224 {
225 return( DPMI_Error );
226 }
227
228 return ( DPMI_Ok );
229 }
230
231
232/*---------------------------------------------------------------------
233 Function: DPMI_UnlockMemoryRegion
234
235 Unlocks a region of memory that was previously locked.
236---------------------------------------------------------------------*/
237
238int DPMI_UnlockMemoryRegion
239 (
240 void *start,
241 void *end
242 )
243
244 {
245 int status;
246
247 status = DPMI_UnlockMemory( start, ( char * )end - ( char * )start );
248
249 return( status );
250 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dpmi.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dpmi.h
new file mode 100644
index 0000000000..0ca6b93a6a
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dpmi.h
@@ -0,0 +1,86 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: DPMI.H
22
23 author: James R. Dose
24 date: March 31, 1994
25
26 Inline functions for performing DPMI calls.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __DPMI_H
32#define __DPMI_H
33
34#include "SDL.h"
35
36#ifdef _WIN32
37#include "../../../Engine/src/windows/inttypes.h"
38#else
39#include <inttypes.h>
40#endif
41
42enum DPMI_Errors
43 {
44 DPMI_Warning = -2,
45 DPMI_Error = -1,
46 DPMI_Ok = 0
47 };
48
49typedef struct
50 {
51 uint32_t EDI;
52 uint32_t ESI;
53 uint32_t EBP;
54 uint32_t Reserved;
55 uint32_t EBX;
56 uint32_t EDX;
57 uint32_t ECX;
58 uint32_t EAX;
59 uint32_t Flags;
60 uint32_t ES;
61 uint32_t DS;
62 uint32_t FS;
63 uint32_t GS;
64 uint32_t IP;
65 uint16_t CS;
66 uint16_t SP;
67 uint16_t SS;
68 } dpmi_regs;
69
70uint32_t DPMI_GetRealModeVector( int num );
71
72int DPMI_CallRealModeFunction( dpmi_regs *callregs );
73int DPMI_GetDOSMemory( void **ptr, int *descriptor, unsigned length );
74int DPMI_FreeDOSMemory( int descriptor );
75int DPMI_LockMemory( void *address, unsigned length );
76int DPMI_LockMemoryRegion( void *start, void *end );
77int DPMI_UnlockMemory( void *address, unsigned length );
78int DPMI_UnlockMemoryRegion( void *start, void *end );
79
80#define DPMI_Lock( variable ) \
81 ( DPMI_LockMemory( &( variable ), sizeof( variable ) ) )
82
83#define DPMI_Unlock( variable ) \
84 ( DPMI_UnlockMemory( &( variable ), sizeof( variable ) ) )
85
86#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dsl.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dsl.c
new file mode 100644
index 0000000000..ec4e5b7f70
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dsl.c
@@ -0,0 +1,231 @@
1#include <stdlib.h>
2#include <string.h>
3
4#include "dsl.h"
5#include "util.h"
6
7#include "SDL.h"
8#include "SDL_mixer.h"
9
10extern volatile int MV_MixPage;
11
12static int DSL_ErrorCode = DSL_Ok;
13
14static int mixer_initialized;
15
16static void ( *_CallBackFunc )( void );
17static volatile char *_BufferStart;
18static int _BufferSize;
19static int _NumDivisions;
20static int _SampleRate;
21static int _remainder;
22
23static Mix_Chunk *blank;
24static unsigned char *blank_buf;
25
26/*
27possible todo ideas: cache sdl/sdl mixer error messages.
28*/
29
30char *DSL_ErrorString( int ErrorNumber )
31{
32 char *ErrorString;
33
34 switch (ErrorNumber) {
35 case DSL_Warning:
36 case DSL_Error:
37 ErrorString = DSL_ErrorString(DSL_ErrorCode);
38 break;
39
40 case DSL_Ok:
41 ErrorString = "SDL Driver ok.";
42 break;
43
44 case DSL_SDLInitFailure:
45 ErrorString = "SDL Audio initialization failed.";
46 break;
47
48 case DSL_MixerActive:
49 ErrorString = "SDL Mixer already initialized.";
50 break;
51
52 case DSL_MixerInitFailure:
53 ErrorString = "SDL Mixer initialization failed.";
54 break;
55
56 default:
57 ErrorString = "Unknown SDL Driver error.";
58 break;
59 }
60
61 return ErrorString;
62}
63
64static void DSL_SetErrorCode(int ErrorCode)
65{
66 DSL_ErrorCode = ErrorCode;
67}
68
69int DSL_Init( void )
70{
71 DSL_SetErrorCode(DSL_Ok);
72
73 if (SDL_InitSubSystem(SDL_INIT_AUDIO|SDL_INIT_NOPARACHUTE) < 0) {
74 DSL_SetErrorCode(DSL_SDLInitFailure);
75
76 return DSL_Error;
77 }
78
79 return DSL_Ok;
80}
81
82void DSL_Shutdown( void )
83{
84 DSL_StopPlayback();
85}
86
87static void mixer_callback(int chan, void *stream, int len, void *udata)
88{
89 Uint8 *stptr;
90 Uint8 *fxptr;
91 int copysize;
92
93 /* len should equal _BufferSize, else this is screwed up */
94
95 stptr = (Uint8 *)stream;
96
97 if (_remainder > 0) {
98 copysize = min(len, _remainder);
99
100 fxptr = (Uint8 *)(&_BufferStart[MV_MixPage *
101 _BufferSize]);
102
103 memcpy(stptr, fxptr+(_BufferSize-_remainder), copysize);
104
105 len -= copysize;
106 _remainder -= copysize;
107
108 stptr += copysize;
109 }
110
111 while (len > 0) {
112 /* new buffer */
113
114 _CallBackFunc();
115
116 fxptr = (Uint8 *)(&_BufferStart[MV_MixPage *
117 _BufferSize]);
118
119 copysize = min(len, _BufferSize);
120
121 memcpy(stptr, fxptr, copysize);
122
123 len -= copysize;
124
125 stptr += copysize;
126 }
127
128 _remainder = len;
129}
130
131int DSL_BeginBufferedPlayback( char *BufferStart,
132 int BufferSize, int NumDivisions, unsigned SampleRate,
133 int MixMode, void ( *CallBackFunc )( void ) )
134{
135 Uint16 format;
136 int channels;
137 int chunksize;
138 int blah;
139
140 if (mixer_initialized) {
141 DSL_SetErrorCode(DSL_MixerActive);
142
143 return DSL_Error;
144 }
145
146 _CallBackFunc = CallBackFunc;
147 _BufferStart = BufferStart;
148 _BufferSize = (BufferSize / NumDivisions);
149 _NumDivisions = NumDivisions;
150 _SampleRate = SampleRate;
151
152 _remainder = 0;
153
154 format = (MixMode & SIXTEEN_BIT) ? AUDIO_S16LSB : AUDIO_U8;
155 channels = (MixMode & STEREO) ? 2 : 1;
156
157 /*
158 I find 50ms to be ideal, at least with my hardware. This clamping mechanism
159 was added because it seems the above remainder handling isn't so nice --kode54
160 */
161 chunksize = (5 * SampleRate) / 100;
162
163 blah = _BufferSize;
164 if (MixMode & SIXTEEN_BIT) blah >>= 1;
165 if (MixMode & STEREO) blah >>= 1;
166
167 if (chunksize % blah) chunksize += blah - (chunksize % blah);
168
169 if (Mix_OpenAudio(SampleRate, format, channels, chunksize) < 0) {
170 DSL_SetErrorCode(DSL_MixerInitFailure);
171
172 return DSL_Error;
173 }
174
175/*
176 Mix_SetPostMix(mixer_callback, NULL);
177*/
178 /* have to use a channel because postmix will overwrite the music... */
179 Mix_RegisterEffect(0, mixer_callback, NULL, NULL);
180
181 /* create a dummy sample just to allocate that channel */
182 blank_buf = (Uint8 *)malloc(4096);
183 memset(blank_buf, 0, 4096);
184
185 blank = Mix_QuickLoad_RAW(blank_buf, 4096);
186
187 Mix_PlayChannel(0, blank, -1);
188
189 mixer_initialized = 1;
190
191 return DSL_Ok;
192}
193
194void DSL_StopPlayback( void )
195{
196 if (mixer_initialized) {
197 Mix_HaltChannel(0);
198 }
199
200 if (blank != NULL) {
201 Mix_FreeChunk(blank);
202 }
203
204 blank = NULL;
205
206 if (blank_buf != NULL) {
207 free(blank_buf);
208 }
209
210 blank_buf = NULL;
211
212 if (mixer_initialized) {
213 Mix_CloseAudio();
214 }
215
216 mixer_initialized = 0;
217}
218
219unsigned DSL_GetPlaybackRate( void )
220{
221 return _SampleRate;
222}
223
224uint32_t DisableInterrupts( void )
225{
226 return 0;
227}
228
229void RestoreInterrupts( uint32_t flags )
230{
231}
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dsl.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dsl.h
new file mode 100644
index 0000000000..10670527a7
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/dsl.h
@@ -0,0 +1,28 @@
1#ifndef AUDIOLIB__DSL_H
2#define AUDIOLIB__DSL_H
3
4#define MONO_8BIT 0
5#define STEREO 1
6#define SIXTEEN_BIT 2
7#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
8
9enum DSL_ERRORS
10 {
11 DSL_Warning = -2,
12 DSL_Error = -1,
13 DSL_Ok = 0,
14 DSL_SDLInitFailure,
15 DSL_MixerActive,
16 DSL_MixerInitFailure
17 };
18
19char *DSL_ErrorString( int ErrorNumber );
20int DSL_Init( void );
21void DSL_StopPlayback( void );
22unsigned DSL_GetPlaybackRate( void );
23int DSL_BeginBufferedPlayback( char *BufferStart,
24 int BufferSize, int NumDivisions, unsigned SampleRate,
25 int MixMode, void ( *CallBackFunc )( void ) );
26void DSL_Shutdown( void );
27
28#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/fx_man.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/fx_man.c
new file mode 100644
index 0000000000..522ead524e
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/fx_man.c
@@ -0,0 +1,1058 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: FX_MAN.C
22
23 author: James R. Dose
24 date: March 17, 1994
25
26 Device independant sound effect routines.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#include <stdio.h>
32#include <stdlib.h>
33#include "sndcards.h"
34#include "multivoc.h"
35
36
37
38#include "dsl.h"
39
40#include "ll_man.h"
41#include "user.h"
42#include "fx_man.h"
43
44#define TRUE ( 1 == 1 )
45#define FALSE ( !TRUE )
46
47static unsigned FX_MixRate;
48
49int FX_SoundDevice = -1;
50int FX_ErrorCode = FX_Ok;
51int FX_Installed = FALSE;
52
53#define FX_SetErrorCode( status ) \
54 FX_ErrorCode = ( status );
55
56/*---------------------------------------------------------------------
57 Function: FX_ErrorString
58
59 Returns a pointer to the error message associated with an error
60 number. A -1 returns a pointer the current error.
61---------------------------------------------------------------------*/
62
63char *FX_ErrorString(int ErrorNumber)
64
65 {
66 char *ErrorString;
67
68 switch( ErrorNumber )
69 {
70 case FX_Warning :
71 case FX_Error :
72 ErrorString = FX_ErrorString( FX_ErrorCode );
73 break;
74
75 case FX_Ok :
76 ErrorString = "Fx ok\n";
77 break;
78
79 case FX_ASSVersion :
80 ErrorString = "Apogee Sound System Version " ASS_VERSION_STRING " "
81 "Programmed by Jim Dose\n"
82 "(c) Copyright 1995 James R. Dose. All Rights Reserved.\n";
83 break;
84
85
86 case FX_SoundCardError :
87 ErrorString = DSL_ErrorString( DSL_Error );
88 break;
89
90 case FX_InvalidCard :
91 ErrorString = "Invalid Sound Fx device.\n";
92 break;
93
94 case FX_MultiVocError :
95 ErrorString = MV_ErrorString( MV_Error );
96 break;
97
98 case FX_DPMI_Error :
99 ErrorString = "DPMI Error in FX_MAN.\n";
100 break;
101
102 default :
103 ErrorString = "Unknown Fx error code.\n";
104 break;
105 }
106
107 return( ErrorString );
108 }
109
110
111/*---------------------------------------------------------------------
112 Function: FX_SetupCard
113
114 Sets the configuration of a sound device.
115---------------------------------------------------------------------*/
116
117int FX_SetupCard
118 (
119 int SoundCard,
120 fx_device *device
121 )
122
123 {
124 int status;
125 int DeviceStatus;
126
127 if ( USER_CheckParameter( "ASSVER" ) )
128 {
129 FX_SetErrorCode( FX_ASSVersion );
130 return( FX_Error );
131 }
132
133 FX_SoundDevice = SoundCard;
134
135 status = FX_Ok;
136 FX_SetErrorCode( FX_Ok );
137
138
139 DeviceStatus = DSL_Init();
140 if ( DeviceStatus != DSL_Ok )
141 {
142 FX_SetErrorCode( FX_SoundCardError );
143 status = FX_Error;
144 }
145 else
146 {
147 device->MaxVoices = 32;
148 device->MaxSampleBits = 0;
149 device->MaxChannels = 0;
150 }
151
152
153 return( status );
154 }
155
156
157/*---------------------------------------------------------------------
158 Function: FX_GetBlasterSettings
159
160 Returns the current BLASTER environment variable settings.
161---------------------------------------------------------------------*/
162
163int FX_GetBlasterSettings
164 (
165 fx_blaster_config *blaster
166 )
167
168 {
169
170 return( FX_Ok );
171 }
172
173
174/*---------------------------------------------------------------------
175 Function: FX_SetupSoundBlaster
176
177 Handles manual setup of the Sound Blaster information.
178---------------------------------------------------------------------*/
179
180int FX_SetupSoundBlaster
181 (
182 fx_blaster_config blaster,
183 int *MaxVoices,
184 int *MaxSampleBits,
185 int *MaxChannels
186 )
187
188 {
189
190
191 return( FX_Ok );
192 }
193
194
195/*---------------------------------------------------------------------
196 Function: FX_Init
197
198 Selects which sound device to use.
199---------------------------------------------------------------------*/
200
201int FX_Init
202 (
203 int SoundCard,
204 int numvoices,
205 int numchannels,
206 int samplebits,
207 unsigned mixrate
208 )
209
210 {
211 int status;
212 int devicestatus;
213
214 if ( FX_Installed )
215 {
216 FX_Shutdown();
217 }
218
219 if ( USER_CheckParameter( "ASSVER" ) )
220 {
221 FX_SetErrorCode( FX_ASSVersion );
222 return( FX_Error );
223 }
224
225 status = LL_LockMemory();
226 if ( status != LL_Ok )
227 {
228 FX_SetErrorCode( FX_DPMI_Error );
229 return( FX_Error );
230 }
231
232 FX_MixRate = mixrate;
233
234 status = FX_Ok;
235 FX_SoundDevice = SoundCard;
236 switch( SoundCard )
237 {
238 case SoundBlaster :
239 case Awe32 :
240 case ProAudioSpectrum :
241 case SoundMan16 :
242 case SoundScape :
243 case SoundSource :
244 case TandySoundSource :
245 case UltraSound :
246 devicestatus = MV_Init( SoundCard, FX_MixRate, numvoices,
247 numchannels, samplebits );
248 if ( devicestatus != MV_Ok )
249 {
250 FX_SetErrorCode( FX_MultiVocError );
251 status = FX_Error;
252 }
253 break;
254
255 default :
256 FX_SetErrorCode( FX_InvalidCard );
257 status = FX_Error;
258 }
259
260 if ( status != FX_Ok )
261 {
262 LL_UnlockMemory();
263 }
264 else
265 {
266 FX_Installed = TRUE;
267 }
268
269 return( status );
270 }
271
272
273/*---------------------------------------------------------------------
274 Function: FX_Shutdown
275
276 Terminates use of sound device.
277---------------------------------------------------------------------*/
278
279int FX_Shutdown
280 (
281 void
282 )
283
284 {
285 int status;
286
287 if ( !FX_Installed )
288 {
289 return( FX_Ok );
290 }
291
292 status = FX_Ok;
293 switch( FX_SoundDevice )
294 {
295 case SoundBlaster :
296 case Awe32 :
297 case ProAudioSpectrum :
298 case SoundMan16 :
299 case SoundScape :
300 case SoundSource :
301 case TandySoundSource :
302 case UltraSound :
303 status = MV_Shutdown();
304 if ( status != MV_Ok )
305 {
306 FX_SetErrorCode( FX_MultiVocError );
307 status = FX_Error;
308 }
309 break;
310
311 default :
312 FX_SetErrorCode( FX_InvalidCard );
313 status = FX_Error;
314 }
315
316 FX_Installed = FALSE;
317 LL_UnlockMemory();
318
319 return( status );
320 }
321
322
323/*---------------------------------------------------------------------
324 Function: FX_SetCallback
325
326 Sets the function to call when a voice is done.
327---------------------------------------------------------------------*/
328
329int FX_SetCallBack(void ( *function )( int32_t ))
330
331 {
332 int status;
333
334 status = FX_Ok;
335
336 switch( FX_SoundDevice )
337 {
338 case SoundBlaster :
339 case Awe32 :
340 case ProAudioSpectrum :
341 case SoundMan16 :
342 case SoundScape :
343 case SoundSource :
344 case TandySoundSource :
345 case UltraSound :
346 MV_SetCallBack( function );
347 break;
348
349 default :
350 FX_SetErrorCode( FX_InvalidCard );
351 status = FX_Error;
352 }
353
354 return( status );
355 }
356
357
358/*---------------------------------------------------------------------
359 Function: FX_SetVolume
360
361 Sets the volume of the current sound device.
362---------------------------------------------------------------------*/
363
364void FX_SetVolume(int volume)
365 {
366
367 MV_SetVolume( volume );
368
369 }
370
371
372/*---------------------------------------------------------------------
373 Function: FX_GetVolume
374
375 Returns the volume of the current sound device.
376---------------------------------------------------------------------*/
377
378int FX_GetVolume(void)
379 {
380 int volume;
381
382
383 volume = MV_GetVolume();
384
385
386 return( volume );
387 }
388
389
390/*---------------------------------------------------------------------
391 Function: FX_SetReverseStereo
392
393 Set the orientation of the left and right channels.
394---------------------------------------------------------------------*/
395
396void FX_SetReverseStereo(int setting)
397
398 {
399 MV_SetReverseStereo( setting );
400 }
401
402
403/*---------------------------------------------------------------------
404 Function: FX_GetReverseStereo
405
406 Returns the orientation of the left and right channels.
407---------------------------------------------------------------------*/
408
409int FX_GetReverseStereo(void)
410
411 {
412 return MV_GetReverseStereo();
413 }
414
415
416/*---------------------------------------------------------------------
417 Function: FX_SetReverb
418
419 Sets the reverb level.
420---------------------------------------------------------------------*/
421
422void FX_SetReverb
423 (
424 int reverb
425 )
426
427 {
428 MV_SetReverb( reverb );
429 }
430
431
432/*---------------------------------------------------------------------
433 Function: FX_SetFastReverb
434
435 Sets the reverb level.
436---------------------------------------------------------------------*/
437
438void FX_SetFastReverb
439 (
440 int reverb
441 )
442
443 {
444 MV_SetFastReverb( reverb );
445 }
446
447
448/*---------------------------------------------------------------------
449 Function: FX_GetMaxReverbDelay
450
451 Returns the maximum delay time for reverb.
452---------------------------------------------------------------------*/
453
454int FX_GetMaxReverbDelay
455 (
456 void
457 )
458
459 {
460 return MV_GetMaxReverbDelay();
461 }
462
463
464/*---------------------------------------------------------------------
465 Function: FX_GetReverbDelay
466
467 Returns the current delay time for reverb.
468---------------------------------------------------------------------*/
469
470int FX_GetReverbDelay
471 (
472 void
473 )
474
475 {
476 return MV_GetReverbDelay();
477 }
478
479
480/*---------------------------------------------------------------------
481 Function: FX_SetReverbDelay
482
483 Sets the delay level of reverb to add to mix.
484---------------------------------------------------------------------*/
485
486void FX_SetReverbDelay
487 (
488 int delay
489 )
490
491 {
492 MV_SetReverbDelay( delay );
493 }
494
495
496/*---------------------------------------------------------------------
497 Function: FX_VoiceAvailable
498
499 Checks if a voice can be play at the specified priority.
500---------------------------------------------------------------------*/
501
502int FX_VoiceAvailable
503 (
504 int priority
505 )
506
507 {
508 return MV_VoiceAvailable( priority );
509 }
510
511/*---------------------------------------------------------------------
512 Function: FX_EndLooping
513
514 Stops the voice associated with the specified handle from looping
515 without stoping the sound.
516---------------------------------------------------------------------*/
517
518int FX_EndLooping
519 (
520 int handle
521 )
522
523 {
524 int status;
525
526 status = MV_EndLooping( handle );
527 if ( status == MV_Error )
528 {
529 FX_SetErrorCode( FX_MultiVocError );
530 status = FX_Warning;
531 }
532
533 return( status );
534 }
535
536/*---------------------------------------------------------------------
537 Function: FX_SetPan
538
539 Sets the stereo and mono volume level of the voice associated
540 with the specified handle.
541---------------------------------------------------------------------*/
542
543int FX_SetPan
544 (
545 int handle,
546 int vol,
547 int left,
548 int right
549 )
550
551 {
552 int status;
553
554 status = MV_SetPan( handle, vol, left, right );
555 if ( status == MV_Error )
556 {
557 FX_SetErrorCode( FX_MultiVocError );
558 status = FX_Warning;
559 }
560
561 return( status );
562 }
563
564
565/*---------------------------------------------------------------------
566 Function: FX_SetPitch
567
568 Sets the pitch of the voice associated with the specified handle.
569---------------------------------------------------------------------*/
570
571int FX_SetPitch
572 (
573 int handle,
574 int pitchoffset
575 )
576
577 {
578 int status;
579
580 status = MV_SetPitch( handle, pitchoffset );
581 if ( status == MV_Error )
582 {
583 FX_SetErrorCode( FX_MultiVocError );
584 status = FX_Warning;
585 }
586
587 return( status );
588 }
589
590
591/*---------------------------------------------------------------------
592 Function: FX_SetFrequency
593
594 Sets the frequency of the voice associated with the specified handle.
595---------------------------------------------------------------------*/
596
597int FX_SetFrequency
598 (
599 int handle,
600 int frequency
601 )
602
603 {
604 int status;
605
606 status = MV_SetFrequency( handle, frequency );
607 if ( status == MV_Error )
608 {
609 FX_SetErrorCode( FX_MultiVocError );
610 status = FX_Warning;
611 }
612
613 return( status );
614 }
615
616
617/*---------------------------------------------------------------------
618 Function: FX_PlayVOC
619
620 Begin playback of sound data with the given volume and priority.
621---------------------------------------------------------------------*/
622
623int FX_PlayVOC
624 (
625 uint8_t *ptr,
626 int pitchoffset,
627 int vol,
628 int left,
629 int right,
630 int priority,
631 uint32_t callbackval
632 )
633
634 {
635 int handle;
636
637 handle = MV_PlayVOC( ptr, pitchoffset, vol, left, right,
638 priority, callbackval );
639 if ( handle < MV_Ok )
640 {
641 FX_SetErrorCode( FX_MultiVocError );
642 handle = FX_Warning;
643 }
644
645 return( handle );
646 }
647
648
649/*---------------------------------------------------------------------
650 Function: FX_PlayLoopedVOC
651
652 Begin playback of sound data with the given volume and priority.
653---------------------------------------------------------------------*/
654
655int FX_PlayLoopedVOC
656 (
657 uint8_t *ptr,
658 int32_t loopstart,
659 int32_t loopend,
660 int32_t pitchoffset,
661 int32_t vol,
662 int32_t left,
663 int32_t right,
664 int32_t priority,
665 uint32_t callbackval
666 )
667
668 {
669 int handle;
670
671 handle = MV_PlayLoopedVOC( ptr, loopstart, loopend, pitchoffset,
672 vol, left, right, priority, callbackval );
673 if ( handle < MV_Ok )
674 {
675 FX_SetErrorCode( FX_MultiVocError );
676 handle = FX_Warning;
677 }
678
679 return( handle );
680 }
681
682
683/*---------------------------------------------------------------------
684 Function: FX_PlayWAV
685
686 Begin playback of sound data with the given volume and priority.
687---------------------------------------------------------------------*/
688
689int FX_PlayWAV( uint8_t *ptr, int pitchoffset, int vol, int left, int right,
690 int priority, uint32_t callbackval )
691
692 {
693 int handle;
694
695 handle = MV_PlayWAV( ptr, pitchoffset, vol, left, right,
696 priority, callbackval );
697 if ( handle < MV_Ok )
698 {
699 FX_SetErrorCode( FX_MultiVocError );
700 handle = FX_Warning;
701 }
702
703 return( handle );
704 }
705
706
707/*---------------------------------------------------------------------
708 Function: FX_PlayWAV
709
710 Begin playback of sound data with the given volume and priority.
711---------------------------------------------------------------------*/
712
713int FX_PlayLoopedWAV
714 (
715 uint8_t *ptr,
716 int32_t loopstart,
717 int32_t loopend,
718 int32_t pitchoffset,
719 int32_t vol,
720 int32_t left,
721 int32_t right,
722 int32_t priority,
723 uint32_t callbackval
724 )
725
726 {
727 int32_t handle;
728
729 handle = MV_PlayLoopedWAV( ptr, loopstart, loopend,
730 pitchoffset, vol, left, right, priority, callbackval );
731 if ( handle < MV_Ok )
732 {
733 FX_SetErrorCode( FX_MultiVocError );
734 handle = FX_Warning;
735 }
736
737 return( handle );
738 }
739
740
741/*---------------------------------------------------------------------
742 Function: FX_PlayVOC3D
743
744 Begin playback of sound data at specified angle and distance
745 from listener.
746---------------------------------------------------------------------*/
747
748int FX_PlayVOC3D
749 (
750 uint8_t *ptr,
751 int32_t pitchoffset,
752 int32_t angle,
753 int32_t distance,
754 int32_t priority,
755 uint32_t callbackval
756 )
757
758 {
759 int handle;
760
761 handle = MV_PlayVOC3D( ptr, pitchoffset, angle, distance,
762 priority, callbackval );
763 if ( handle < MV_Ok )
764 {
765 FX_SetErrorCode( FX_MultiVocError );
766 handle = FX_Warning;
767 }
768
769 return( handle );
770 }
771
772
773/*---------------------------------------------------------------------
774 Function: FX_PlayWAV3D
775
776 Begin playback of sound data at specified angle and distance
777 from listener.
778---------------------------------------------------------------------*/
779
780int FX_PlayWAV3D( uint8_t *ptr, int pitchoffset, int angle, int distance,
781 int priority, uint32_t callbackval )
782 {
783 int handle;
784
785 handle = MV_PlayWAV3D( ptr, pitchoffset, angle, distance,
786 priority, callbackval );
787 if ( handle < MV_Ok )
788 {
789 FX_SetErrorCode( FX_MultiVocError );
790 handle = FX_Warning;
791 }
792
793 return( handle );
794 }
795
796
797/*---------------------------------------------------------------------
798 Function: FX_PlayRaw
799
800 Begin playback of raw sound data with the given volume and priority.
801---------------------------------------------------------------------*/
802
803int FX_PlayRaw
804 (
805 uint8_t *ptr,
806 uint32_t length,
807 uint32_t rate,
808 int32_t pitchoffset,
809 int32_t vol,
810 int32_t left,
811 int32_t right,
812 int32_t priority,
813 uint32_t callbackval
814 )
815
816 {
817 int handle;
818
819 handle = MV_PlayRaw( ptr, length, rate, pitchoffset,
820 vol, left, right, priority, callbackval );
821 if ( handle < MV_Ok )
822 {
823 FX_SetErrorCode( FX_MultiVocError );
824 handle = FX_Warning;
825 }
826
827 return( handle );
828 }
829
830
831/*---------------------------------------------------------------------
832 Function: FX_PlayLoopedRaw
833
834 Begin playback of raw sound data with the given volume and priority.
835---------------------------------------------------------------------*/
836
837int FX_PlayLoopedRaw
838 (
839 uint8_t *ptr,
840 uint32_t length,
841 char *loopstart,
842 char *loopend,
843 uint32_t rate,
844 int32_t pitchoffset,
845 int32_t vol,
846 int32_t left,
847 int32_t right,
848 int32_t priority,
849 uint32_t callbackval
850 )
851
852 {
853 int handle;
854
855 handle = MV_PlayLoopedRaw( ptr, length, loopstart, loopend,
856 rate, pitchoffset, vol, left, right, priority, callbackval );
857 if ( handle < MV_Ok )
858 {
859 FX_SetErrorCode( FX_MultiVocError );
860 handle = FX_Warning;
861 }
862
863 return( handle );
864 }
865
866
867/*---------------------------------------------------------------------
868 Function: FX_Pan3D
869
870 Set the angle and distance from the listener of the voice associated
871 with the specified handle.
872---------------------------------------------------------------------*/
873
874int32_t FX_Pan3D( int handle, int angle, int distance )
875 {
876 int status;
877
878 status = MV_Pan3D( handle, angle, distance );
879 if ( status != MV_Ok )
880 {
881 FX_SetErrorCode( FX_MultiVocError );
882 status = FX_Warning;
883 }
884
885 return( status );
886 }
887
888
889/*---------------------------------------------------------------------
890 Function: FX_SoundActive
891
892 Tests if the specified sound is currently playing.
893---------------------------------------------------------------------*/
894
895int32_t FX_SoundActive( int32_t handle )
896 {
897 return( MV_VoicePlaying( handle ) );
898 }
899
900
901/*---------------------------------------------------------------------
902 Function: FX_SoundsPlaying
903
904 Reports the number of voices playing.
905---------------------------------------------------------------------*/
906
907int32_t FX_SoundsPlaying( void )
908 {
909 return( MV_VoicesPlaying() );
910 }
911
912
913/*---------------------------------------------------------------------
914 Function: FX_StopSound
915
916 Halts playback of a specific voice
917---------------------------------------------------------------------*/
918
919int32_t FX_StopSound
920 (
921 int handle
922 )
923
924 {
925 int status;
926
927 status = MV_Kill( handle );
928 if ( status != MV_Ok )
929 {
930 FX_SetErrorCode( FX_MultiVocError );
931 return( FX_Warning );
932 }
933
934 return( FX_Ok );
935 }
936
937
938/*---------------------------------------------------------------------
939 Function: FX_StopAllSounds
940
941 Halts playback of all sounds.
942---------------------------------------------------------------------*/
943
944int32_t FX_StopAllSounds
945 (
946 void
947 )
948
949 {
950 int status;
951
952 status = MV_KillAllVoices();
953 if ( status != MV_Ok )
954 {
955 FX_SetErrorCode( FX_MultiVocError );
956 return( FX_Warning );
957 }
958
959 return( FX_Ok );
960 }
961
962
963/*---------------------------------------------------------------------
964 Function: FX_StartDemandFeedPlayback
965
966 Plays a digitized sound from a user controlled buffering system.
967---------------------------------------------------------------------*/
968int32_t FX_StartDemandFeedPlayback( void ( *function )( char **ptr, uint32_t *length ),
969 int32_t rate, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right,
970 int32_t priority, uint32_t callbackval )
971{
972 int handle;
973
974 handle = MV_StartDemandFeedPlayback( function, rate,
975 pitchoffset, vol, left, right, priority, callbackval );
976 if ( handle < MV_Ok )
977 {
978 FX_SetErrorCode( FX_MultiVocError );
979 handle = FX_Warning;
980 }
981
982 return( handle );
983 }
984
985
986/*---------------------------------------------------------------------
987 Function: FX_StartRecording
988
989 Starts the sound recording engine.
990---------------------------------------------------------------------*/
991
992int FX_StartRecording
993 (
994 int MixRate,
995 void ( *function )( char *ptr, int length )
996 )
997
998 {
999 int status;
1000
1001#ifdef PLAT_DOS
1002 switch( FX_SoundDevice )
1003 {
1004 case SoundBlaster :
1005 case Awe32 :
1006 case ProAudioSpectrum :
1007 case SoundMan16 :
1008 status = MV_StartRecording( MixRate, function );
1009 if ( status != MV_Ok )
1010 {
1011 FX_SetErrorCode( FX_MultiVocError );
1012 status = FX_Warning;
1013 }
1014 else
1015 {
1016 status = FX_Ok;
1017 }
1018 break;
1019
1020 default :
1021 FX_SetErrorCode( FX_InvalidCard );
1022 status = FX_Warning;
1023 break;
1024 }
1025#else
1026 FX_SetErrorCode( FX_InvalidCard );
1027 status = FX_Warning;
1028#endif
1029
1030 return( status );
1031 }
1032
1033
1034/*---------------------------------------------------------------------
1035 Function: FX_StopRecord
1036
1037 Stops the sound record engine.
1038---------------------------------------------------------------------*/
1039
1040void FX_StopRecord
1041 (
1042 void
1043 )
1044
1045 {
1046#ifdef PLAT_DOS
1047 // Stop sound playback
1048 switch( FX_SoundDevice )
1049 {
1050 case SoundBlaster :
1051 case Awe32 :
1052 case ProAudioSpectrum :
1053 case SoundMan16 :
1054 MV_StopRecord();
1055 break;
1056 }
1057#endif
1058 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/fx_man.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/fx_man.h
new file mode 100644
index 0000000000..c8361716e3
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/fx_man.h
@@ -0,0 +1,140 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: FX_MAN.H
22
23 author: James R. Dose
24 date: March 17, 1994
25
26 Public header for FX_MAN.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __FX_MAN_H
32#define __FX_MAN_H
33
34#include "sndcards.h"
35#ifdef _WIN32
36 #include "../../Engine/src/windows/inttypes.h"
37#else
38 #include <inttypes.h>
39#endif
40
41typedef struct
42 {
43 int MaxVoices;
44 int MaxSampleBits;
45 int MaxChannels;
46 } fx_device;
47
48#define MonoFx 1
49#define StereoFx 2
50
51typedef struct
52 {
53 unsigned long Address;
54 unsigned long Type;
55 unsigned long Interrupt;
56 unsigned long Dma8;
57 unsigned long Dma16;
58 unsigned long Midi;
59 unsigned long Emu;
60 } fx_blaster_config;
61
62enum FX_ERRORS
63 {
64 FX_Warning = -2,
65 FX_Error = -1,
66 FX_Ok = 0,
67 FX_ASSVersion,
68 FX_BlasterError,
69 FX_SoundCardError,
70 FX_InvalidCard,
71 FX_MultiVocError,
72 FX_DPMI_Error
73 };
74
75enum fx_BLASTER_Types
76 {
77 fx_SB = 1,
78 fx_SBPro = 2,
79 fx_SB20 = 3,
80 fx_SBPro2 = 4,
81 fx_SB16 = 6
82 };
83
84
85char *FX_ErrorString( int ErrorNumber );
86int FX_SetupCard( int SoundCard, fx_device *device );
87int FX_GetBlasterSettings( fx_blaster_config *blaster );
88int FX_SetupSoundBlaster( fx_blaster_config blaster, int *MaxVoices, int *MaxSampleBits, int *MaxChannels );
89int FX_Init( int SoundCard, int numvoices, int numchannels, int samplebits, unsigned mixrate );
90int FX_Shutdown( void );
91int FX_SetCallBack( void ( *function )( int32_t ) );
92void FX_SetVolume( int volume );
93int FX_GetVolume( void );
94
95void FX_SetReverseStereo( int setting );
96int FX_GetReverseStereo( void );
97void FX_SetReverb( int reverb );
98void FX_SetFastReverb( int reverb );
99int FX_GetMaxReverbDelay( void );
100int FX_GetReverbDelay( void );
101void FX_SetReverbDelay( int delay );
102
103int FX_VoiceAvailable( int priority );
104int FX_EndLooping( int handle );
105int FX_SetPan( int handle, int vol, int left, int right );
106int FX_SetPitch( int handle, int pitchoffset );
107int FX_SetFrequency( int handle, int frequency );
108
109int FX_PlayVOC( uint8_t *ptr, int pitchoffset, int vol, int left, int right,
110 int priority, uint32_t callbackval );
111int FX_PlayLoopedVOC( uint8_t *ptr, int32_t loopstart, int32_t loopend,
112 int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority,
113 uint32_t callbackval );
114int FX_PlayWAV( uint8_t *ptr, int pitchoffset, int vol, int left, int right,
115 int priority, uint32_t callbackval );
116int FX_PlayLoopedWAV( uint8_t *ptr, int32_t loopstart, int32_t loopend,
117 int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority,
118 uint32_t callbackval );
119int FX_PlayVOC3D( uint8_t *ptr, int32_t pitchoffset, int32_t angle, int32_t distance,
120 int32_t priority, uint32_t callbackval );
121int FX_PlayWAV3D( uint8_t *ptr, int pitchoffset, int angle, int distance,
122 int priority, uint32_t callbackval );
123int FX_PlayRaw( uint8_t *ptr, uint32_t length, uint32_t rate,
124 int32_t pitchoffset, int32_t vol, int32_t left, int32_t right, int32_t priority,
125 uint32_t callbackval );
126int FX_PlayLoopedRaw( uint8_t *ptr, uint32_t length, char *loopstart,
127 char *loopend, uint32_t rate, int32_t pitchoffset, int32_t vol, int32_t left,
128 int32_t right, int32_t priority, uint32_t callbackval );
129int32_t FX_Pan3D( int handle, int angle, int distance );
130int32_t FX_SoundActive( int32_t handle );
131int32_t FX_SoundsPlaying( void );
132int32_t FX_StopSound( int handle );
133int32_t FX_StopAllSounds( void );
134int32_t FX_StartDemandFeedPlayback( void ( *function )( char **ptr, uint32_t *length ),
135 int32_t rate, int32_t pitchoffset, int32_t vol, int32_t left, int32_t right,
136 int32_t priority, uint32_t callbackval );
137int FX_StartRecording( int MixRate, void ( *function )( char *ptr, int length ) );
138void FX_StopRecord( void );
139
140#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gmtimbre.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gmtimbre.c
new file mode 100644
index 0000000000..fff88e0f92
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gmtimbre.c
@@ -0,0 +1,290 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20typedef struct
21 {
22 unsigned char SAVEK[ 2 ];
23 unsigned char Level[ 2 ];
24 unsigned char Env1[ 2 ];
25 unsigned char Env2[ 2 ];
26 unsigned char Wave[ 2 ];
27 unsigned char Feedback;
28 signed char Transpose;
29 signed char Velocity;
30 } TIMBRE;
31
32TIMBRE ADLIB_TimbreBank[ 256 ] =
33 {
34 { { 33, 33 }, { 143, 6 }, { 242, 242 }, { 69, 118 }, { 0, 0 }, 8, 0 },
35 { { 49, 33 }, { 75, 0 }, { 242, 242 }, { 84, 86 }, { 0, 0 }, 8, 0 },
36 { { 49, 33 }, { 73, 0 }, { 242, 242 }, { 85, 118 }, { 0, 0 }, 8, 0 },
37 { { 177, 97 }, { 14, 0 }, { 242, 243 }, { 59, 11 }, { 0, 0 }, 6, 0 },
38 { { 1, 33 }, { 87, 0 }, { 241, 241 }, { 56, 40 }, { 0, 0 }, 0, 0 },
39 { { 1, 33 }, { 147, 0 }, { 241, 241 }, { 56, 40 }, { 0, 0 }, 0, 0 },
40 { { 33, 54 }, { 128, 14 }, { 162, 241 }, { 1, 213 }, { 0, 0 }, 8, 0 },
41 { { 1, 1 }, { 146, 0 }, { 194, 194 }, { 168, 88 }, { 0, 0 }, 10, 0 },
42 { { 12, 129 }, { 92, 0 }, { 246, 243 }, { 84, 181 }, { 0, 0 }, 0, 0 },
43 { { 7, 17 }, { 151, 128 }, { 246, 245 }, { 50, 17 }, { 0, 0 }, 2, 0 },
44 { { 23, 1 }, { 33, 0 }, { 86, 246 }, { 4, 4 }, { 0, 0 }, 2, 0 },
45 { { 24, 129 }, { 98, 0 }, { 243, 242 }, { 230, 246 }, { 0, 0 }, 0, 0 },
46 { { 24, 33 }, { 35, 0 }, { 247, 229 }, { 85, 216 }, { 0, 0 }, 0, 0 },
47 { { 21, 1 }, { 145, 0 }, { 246, 246 }, { 166, 230 }, { 0, 0 }, 4, 0 },
48 { { 69, 129 }, { 89, 128 }, { 211, 163 }, { 130, 227 }, { 0, 0 }, 12, 0 },
49 { { 3, 129 }, { 73, 128 }, { 116, 179 }, { 85, 5 }, { 1, 0 }, 4, 0 },
50 { { 113, 49 }, { 146, 0 }, { 246, 241 }, { 20, 7 }, { 0, 0 }, 2, 0 },
51 { { 114, 48 }, { 20, 0 }, { 199, 199 }, { 88, 8 }, { 0, 0 }, 2, 0 },
52 { { 112, 177 }, { 68, 0 }, { 170, 138 }, { 24, 8 }, { 0, 0 }, 4, 0 },
53 { { 35, 177 }, { 147, 0 }, { 151, 85 }, { 35, 20 }, { 1, 0 }, 4, 0 },
54 { { 97, 177 }, { 19, 128 }, { 151, 85 }, { 4, 4 }, { 1, 0 }, 0, 0 },
55 { { 36, 177 }, { 72, 0 }, { 152, 70 }, { 42, 26 }, { 1, 0 }, 12, 0 },
56 { { 97, 33 }, { 19, 0 }, { 145, 97 }, { 6, 7 }, { 1, 0 }, 10, 0 },
57 { { 33, 161 }, { 19, 137 }, { 113, 97 }, { 6, 7 }, { 0, 0 }, 6, 0 },
58 { { 2, 65 }, { 156, 128 }, { 243, 243 }, { 148, 200 }, { 1, 0 }, 12, 0 },
59 { { 3, 17 }, { 84, 0 }, { 243, 241 }, { 154, 231 }, { 1, 0 }, 12, 0 },
60 { { 35, 33 }, { 95, 0 }, { 241, 242 }, { 58, 248 }, { 0, 0 }, 0, 0 },
61 { { 3, 33 }, { 135, 128 }, { 246, 243 }, { 34, 243 }, { 1, 0 }, 6, 0 },
62 { { 3, 33 }, { 71, 0 }, { 249, 246 }, { 84, 58 }, { 0, 0 }, 0, 0 },
63 { { 35, 33 }, { 72, 0 }, { 149, 132 }, { 25, 25 }, { 1, 0 }, 8, 0 },
64 { { 35, 33 }, { 74, 0 }, { 149, 148 }, { 25, 25 }, { 1, 0 }, 8, 0 },
65 { { 9, 132 }, { 161, 128 }, { 32, 209 }, { 79, 248 }, { 0, 0 }, 8, 0 },
66 { { 33, 162 }, { 30, 0 }, { 148, 195 }, { 6, 166 }, { 0, 0 }, 2, 0 },
67 { { 49, 49 }, { 18, 0 }, { 241, 241 }, { 40, 24 }, { 0, 0 }, 10, 0 },
68 { { 49, 49 }, { 141, 0 }, { 241, 241 }, { 232, 120 }, { 0, 0 }, 10, 0 },
69 { { 49, 50 }, { 91, 0 }, { 81, 113 }, { 40, 72 }, { 0, 0 }, 12, 0 },
70 { { 1, 33 }, { 139, 64 }, { 161, 242 }, { 154, 223 }, { 0, 0 }, 8, 0 },
71 { { 1, 33 }, { 137, 64 }, { 161, 242 }, { 154, 223 }, { 0, 0 }, 8, 0 },
72 { { 49, 49 }, { 139, 0 }, { 244, 241 }, { 232, 120 }, { 0, 0 }, 10, 0 },
73 { { 49, 49 }, { 18, 0 }, { 241, 241 }, { 40, 24 }, { 0, 0 }, 10, 0 },
74 { { 49, 33 }, { 21, 0 }, { 221, 86 }, { 19, 38 }, { 1, 0 }, 8, 0 },
75 { { 49, 33 }, { 22, 0 }, { 221, 102 }, { 19, 6 }, { 1, 0 }, 8, 0 },
76 { { 113, 49 }, { 73, 0 }, { 209, 97 }, { 28, 12 }, { 1, 0 }, 8, 0 },
77 { { 33, 35 }, { 77, 128 }, { 113, 114 }, { 18, 6 }, { 1, 0 }, 2, 0 },
78 { { 241, 225 }, { 64, 0 }, { 241, 111 }, { 33, 22 }, { 1, 0 }, 2, 0 },
79 { { 2, 1 }, { 26, 128 }, { 245, 133 }, { 117, 53 }, { 1, 0 }, 0, 0 },
80 { { 2, 1 }, { 29, 128 }, { 245, 243 }, { 117, 244 }, { 1, 0 }, 0, 0 },
81 { { 16, 17 }, { 65, 0 }, { 245, 242 }, { 5, 195 }, { 1, 0 }, 2, 0 },
82 { { 33, 162 }, { 155, 1 }, { 177, 114 }, { 37, 8 }, { 1, 0 }, 14, 0 },
83 { { 161, 33 }, { 152, 0 }, { 127, 63 }, { 3, 7 }, { 1, 1 }, 0, 0 },
84 { { 161, 97 }, { 147, 0 }, { 193, 79 }, { 18, 5 }, { 0, 0 }, 10, 0 },
85 { { 33, 97 }, { 24, 0 }, { 193, 79 }, { 34, 5 }, { 0, 0 }, 12, 0 },
86 { { 49, 114 }, { 91, 131 }, { 244, 138 }, { 21, 5 }, { 0, 0 }, 0, 0 },
87 { { 161, 97 }, { 144, 0 }, { 116, 113 }, { 57, 103 }, { 0, 0 }, 0, 0 },
88 { { 113, 114 }, { 87, 0 }, { 84, 122 }, { 5, 5 }, { 0, 0 }, 12, 0 },
89 { { 144, 65 }, { 0, 0 }, { 84, 165 }, { 99, 69 }, { 0, 0 }, 8, 0 },
90 { { 33, 33 }, { 146, 1 }, { 133, 143 }, { 23, 9 }, { 0, 0 }, 12, 0 },
91 { { 33, 33 }, { 148, 5 }, { 117, 143 }, { 23, 9 }, { 0, 0 }, 12, 0 },
92 { { 33, 97 }, { 148, 0 }, { 118, 130 }, { 21, 55 }, { 0, 0 }, 12, 0 },
93 { { 49, 33 }, { 67, 0 }, { 158, 98 }, { 23, 44 }, { 1, 1 }, 2, 0 },
94 { { 33, 33 }, { 155, 0 }, { 97, 127 }, { 106, 10 }, { 0, 0 }, 2, 0 },
95 { { 97, 34 }, { 138, 6 }, { 117, 116 }, { 31, 15 }, { 0, 0 }, 8, 0 },
96 { { 161, 33 }, { 134, 13 }, { 114, 113 }, { 85, 24 }, { 1, 0 }, 0, 0 },
97 { { 33, 33 }, { 77, 0 }, { 84, 166 }, { 60, 28 }, { 0, 0 }, 8, 0 },
98 { { 49, 97 }, { 143, 0 }, { 147, 114 }, { 2, 11 }, { 1, 0 }, 8, 0 },
99 { { 49, 97 }, { 142, 0 }, { 147, 114 }, { 3, 9 }, { 1, 0 }, 8, 0 },
100 { { 49, 97 }, { 145, 0 }, { 147, 130 }, { 3, 9 }, { 1, 0 }, 10, 0 },
101 { { 49, 97 }, { 142, 0 }, { 147, 114 }, { 15, 15 }, { 1, 0 }, 10, 0 },
102 { { 33, 33 }, { 75, 0 }, { 170, 143 }, { 22, 10 }, { 1, 0 }, 8, 0 },
103 { { 49, 33 }, { 144, 0 }, { 126, 139 }, { 23, 12 }, { 1, 1 }, 6, 0 },
104 { { 49, 50 }, { 129, 0 }, { 117, 97 }, { 25, 25 }, { 1, 0 }, 0, 0 },
105 { { 50, 33 }, { 144, 0 }, { 155, 114 }, { 33, 23 }, { 0, 0 }, 4, 0 },
106 { { 225, 225 }, { 31, 0 }, { 133, 101 }, { 95, 26 }, { 0, 0 }, 0, 0 },
107 { { 225, 225 }, { 70, 0 }, { 136, 101 }, { 95, 26 }, { 0, 0 }, 0, 0 },
108 { { 161, 33 }, { 156, 0 }, { 117, 117 }, { 31, 10 }, { 0, 0 }, 2, 0 },
109 { { 49, 33 }, { 139, 0 }, { 132, 101 }, { 88, 26 }, { 0, 0 }, 0, 0 },
110 { { 225, 161 }, { 76, 0 }, { 102, 101 }, { 86, 38 }, { 0, 0 }, 0, 0 },
111 { { 98, 161 }, { 203, 0 }, { 118, 85 }, { 70, 54 }, { 0, 0 }, 0, 0 },
112 { { 98, 161 }, { 153, 0 }, { 87, 86 }, { 7, 7 }, { 0, 0 }, 11, 0 },
113 { { 98, 161 }, { 147, 0 }, { 119, 118 }, { 7, 7 }, { 0, 0 }, 11, 0 },
114 { { 34, 33 }, { 89, 0 }, { 255, 255 }, { 3, 15 }, { 2, 0 }, 0, 0 },
115 { { 33, 33 }, { 14, 0 }, { 255, 255 }, { 15, 15 }, { 1, 1 }, 0, 0 },
116 { { 34, 33 }, { 70, 128 }, { 134, 100 }, { 85, 24 }, { 0, 0 }, 0, 0 },
117 { { 33, 161 }, { 69, 0 }, { 102, 150 }, { 18, 10 }, { 0, 0 }, 0, 0 },
118 { { 33, 34 }, { 139, 0 }, { 146, 145 }, { 42, 42 }, { 1, 0 }, 0, 0 },
119 { { 162, 97 }, { 158, 64 }, { 223, 111 }, { 5, 7 }, { 0, 0 }, 2, 0 },
120 { { 32, 96 }, { 26, 0 }, { 239, 143 }, { 1, 6 }, { 0, 2 }, 0, 0 },
121 { { 33, 33 }, { 143, 128 }, { 241, 244 }, { 41, 9 }, { 0, 0 }, 10, 0 },
122 { { 119, 161 }, { 165, 0 }, { 83, 160 }, { 148, 5 }, { 0, 0 }, 2, 0 },
123 { { 97, 177 }, { 31, 128 }, { 168, 37 }, { 17, 3 }, { 0, 0 }, 10, 0 },
124 { { 97, 97 }, { 23, 0 }, { 145, 85 }, { 52, 22 }, { 0, 0 }, 12, 0 },
125 { { 113, 114 }, { 93, 0 }, { 84, 106 }, { 1, 3 }, { 0, 0 }, 0, 0 },
126 { { 33, 162 }, { 151, 0 }, { 33, 66 }, { 67, 53 }, { 0, 0 }, 8, 0 },
127 { { 161, 33 }, { 28, 0 }, { 161, 49 }, { 119, 71 }, { 1, 1 }, 0, 0 },
128 { { 33, 97 }, { 137, 3 }, { 17, 66 }, { 51, 37 }, { 0, 0 }, 10, 0 },
129 { { 161, 33 }, { 21, 0 }, { 17, 207 }, { 71, 7 }, { 1, 0 }, 0, 0 },
130 { { 58, 81 }, { 206, 0 }, { 248, 134 }, { 246, 2 }, { 0, 0 }, 2, 0 },
131 { { 33, 33 }, { 21, 0 }, { 33, 65 }, { 35, 19 }, { 1, 0 }, 0, 0 },
132 { { 6, 1 }, { 91, 0 }, { 116, 165 }, { 149, 114 }, { 0, 0 }, 0, 0 },
133 { { 34, 97 }, { 146, 131 }, { 177, 242 }, { 129, 38 }, { 0, 0 }, 12, 0 },
134 { { 65, 66 }, { 77, 0 }, { 241, 242 }, { 81, 245 }, { 1, 0 }, 0, 0 },
135 { { 97, 163 }, { 148, 128 }, { 17, 17 }, { 81, 19 }, { 1, 0 }, 6, 0 },
136 { { 97, 161 }, { 140, 128 }, { 17, 29 }, { 49, 3 }, { 0, 0 }, 6, 0 },
137 { { 164, 97 }, { 76, 0 }, { 243, 129 }, { 115, 35 }, { 1, 0 }, 4, 0 },
138 { { 2, 7 }, { 133, 3 }, { 210, 242 }, { 83, 246 }, { 0, 1 }, 0, 0 },
139 { { 17, 19 }, { 12, 128 }, { 163, 162 }, { 17, 229 }, { 1, 0 }, 0, 0 },
140 { { 17, 17 }, { 6, 0 }, { 246, 242 }, { 65, 230 }, { 1, 2 }, 4, 0 },
141 { { 147, 145 }, { 145, 0 }, { 212, 235 }, { 50, 17 }, { 0, 1 }, 8, 0 },
142 { { 4, 1 }, { 79, 0 }, { 250, 194 }, { 86, 5 }, { 0, 0 }, 12, 0 },
143 { { 33, 34 }, { 73, 0 }, { 124, 111 }, { 32, 12 }, { 0, 1 }, 6, 0 },
144 { { 49, 33 }, { 133, 0 }, { 221, 86 }, { 51, 22 }, { 1, 0 }, 10, 0 },
145 { { 32, 33 }, { 4, 129 }, { 218, 143 }, { 5, 11 }, { 2, 0 }, 6, 0 },
146 { { 5, 3 }, { 106, 128 }, { 241, 195 }, { 229, 229 }, { 0, 0 }, 6, 0 },
147 { { 7, 2 }, { 21, 0 }, { 236, 248 }, { 38, 22 }, { 0, 0 }, 10, 0 },
148 { { 5, 1 }, { 157, 0 }, { 103, 223 }, { 53, 5 }, { 0, 0 }, 8, 0 },
149 { { 24, 18 }, { 150, 0 }, { 250, 248 }, { 40, 229 }, { 0, 0 }, 10, 0 },
150 { { 16, 0 }, { 134, 3 }, { 168, 250 }, { 7, 3 }, { 0, 0 }, 6, 0 },
151 { { 17, 16 }, { 65, 3 }, { 248, 243 }, { 71, 3 }, { 2, 0 }, 4, 0 },
152 { { 1, 16 }, { 142, 0 }, { 241, 243 }, { 6, 2 }, { 2, 0 }, 14, 0 },
153 { { 14, 192 }, { 0, 0 }, { 31, 31 }, { 0, 255 }, { 0, 3 }, 14, 0 },
154 { { 6, 3 }, { 128, 136 }, { 248, 86 }, { 36, 132 }, { 0, 2 }, 14, 0 },
155 { { 14, 208 }, { 0, 5 }, { 248, 52 }, { 0, 4 }, { 0, 3 }, 14, 0 },
156 { { 14, 192 }, { 0, 0 }, { 246, 31 }, { 0, 2 }, { 0, 3 }, 14, 0 },
157 { { 213, 218 }, { 149, 64 }, { 55, 86 }, { 163, 55 }, { 0, 0 }, 0, 0 },
158 { { 53, 20 }, { 92, 8 }, { 178, 244 }, { 97, 21 }, { 2, 0 }, 10, 0 },
159 { { 14, 208 }, { 0, 0 }, { 246, 79 }, { 0, 245 }, { 0, 3 }, 14, 0 },
160 { { 38, 228 }, { 0, 0 }, { 255, 18 }, { 1, 22 }, { 0, 1 }, 14, 0 },
161 { { 0, 0 }, { 0, 0 }, { 243, 246 }, { 240, 201 }, { 0, 2 }, 14, 0 },
162 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
163 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
164 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
165 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
166 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
167 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
168 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
169 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
170 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
171 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
172 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
173 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
174 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
175 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
176 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
177 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
178 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
179 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
180 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
181 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
182 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
183 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
184 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
185 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
186 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
187 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
188 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
189 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
190 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
191 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
192 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
193 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
194 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
195 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
196 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
197 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
198 { { 0, 0 }, { 0, 0 }, { 252, 250 }, { 5, 23 }, { 2, 0 }, 14, 52 },
199 { { 0, 1 }, { 2, 0 }, { 255, 255 }, { 7, 8 }, { 0, 0 }, 0, 48 },
200 { { 0, 0 }, { 0, 0 }, { 252, 250 }, { 5, 23 }, { 2, 0 }, 14, 58 },
201 { { 0, 0 }, { 0, 0 }, { 246, 246 }, { 12, 6 }, { 0, 0 }, 4, 60 },
202 { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 47 },
203 { { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 43 },
204 { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 49 },
205 { { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 43 },
206 { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 51 },
207 { { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 43 },
208 { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 54 },
209 { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 57 },
210 { { 0, 0 }, { 3, 0 }, { 248, 246 }, { 42, 69 }, { 0, 1 }, 4, 72 },
211 { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 60 },
212 { { 14, 208 }, { 0, 10 }, { 245, 159 }, { 48, 2 }, { 0, 0 }, 14, 76 },
213 { { 14, 7 }, { 10, 93 }, { 228, 245 }, { 228, 229 }, { 3, 1 }, 6, 84 },
214 { { 2, 5 }, { 3, 10 }, { 180, 151 }, { 4, 247 }, { 0, 0 }, 14, 36 },
215 { { 78, 158 }, { 0, 0 }, { 246, 159 }, { 0, 2 }, { 0, 3 }, 14, 76 },
216 { { 17, 16 }, { 69, 8 }, { 248, 243 }, { 55, 5 }, { 2, 0 }, 8, 84 },
217 { { 14, 208 }, { 0, 0 }, { 246, 159 }, { 0, 2 }, { 0, 3 }, 14, 83 },
218 { { 128, 16 }, { 0, 13 }, { 255, 255 }, { 3, 20 }, { 3, 0 }, 12, 84 },
219 { { 14, 7 }, { 8, 81 }, { 248, 244 }, { 66, 228 }, { 0, 3 }, 14, 24 },
220 { { 14, 208 }, { 0, 10 }, { 245, 159 }, { 48, 2 }, { 0, 0 }, 14, 77 },
221 { { 1, 2 }, { 0, 0 }, { 250, 200 }, { 191, 151 }, { 0, 0 }, 7, 60 },
222 { { 1, 1 }, { 81, 0 }, { 250, 250 }, { 135, 183 }, { 0, 0 }, 6, 65 },
223 { { 1, 2 }, { 84, 0 }, { 250, 248 }, { 141, 184 }, { 0, 0 }, 6, 59 },
224 { { 1, 2 }, { 89, 0 }, { 250, 248 }, { 136, 182 }, { 0, 0 }, 6, 51 },
225 { { 1, 0 }, { 0, 0 }, { 249, 250 }, { 10, 6 }, { 3, 0 }, 14, 45 },
226 { { 0, 0 }, { 128, 0 }, { 249, 246 }, { 137, 108 }, { 3, 0 }, 14, 71 },
227 { { 3, 12 }, { 128, 8 }, { 248, 246 }, { 136, 182 }, { 3, 0 }, 15, 60 },
228 { { 3, 12 }, { 133, 0 }, { 248, 246 }, { 136, 182 }, { 3, 0 }, 15, 58 },
229 { { 14, 0 }, { 64, 8 }, { 118, 119 }, { 79, 24 }, { 0, 2 }, 14, 53 },
230 { { 14, 3 }, { 64, 0 }, { 200, 155 }, { 73, 105 }, { 0, 2 }, 14, 64 },
231 { { 215, 199 }, { 220, 0 }, { 173, 141 }, { 5, 5 }, { 3, 0 }, 14, 71 },
232 { { 215, 199 }, { 220, 0 }, { 168, 136 }, { 4, 4 }, { 3, 0 }, 14, 61 },
233 { { 128, 17 }, { 0, 0 }, { 246, 103 }, { 6, 23 }, { 3, 3 }, 14, 61 },
234 { { 128, 17 }, { 0, 9 }, { 245, 70 }, { 5, 22 }, { 2, 3 }, 14, 48 },
235 { { 6, 21 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 48 },
236 { { 6, 18 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 3, 0 }, 0, 69 },
237 { { 6, 18 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 68 },
238 { { 1, 2 }, { 88, 0 }, { 103, 117 }, { 231, 7 }, { 0, 0 }, 0, 63 },
239 { { 65, 66 }, { 69, 8 }, { 248, 117 }, { 72, 5 }, { 0, 0 }, 0, 74 },
240 { { 10, 30 }, { 64, 78 }, { 224, 255 }, { 240, 5 }, { 3, 0 }, 8, 60 },
241 { { 10, 30 }, { 124, 82 }, { 224, 255 }, { 240, 2 }, { 3, 0 }, 8, 80 },
242 { { 14, 0 }, { 64, 8 }, { 122, 123 }, { 74, 27 }, { 0, 2 }, 14, 64 },
243 { { 14, 7 }, { 10, 64 }, { 228, 85 }, { 228, 57 }, { 3, 1 }, 6, 69 },
244 { { 5, 4 }, { 5, 64 }, { 249, 214 }, { 50, 165 }, { 3, 0 }, 14, 73 },
245 { { 2, 21 }, { 63, 0 }, { 0, 247 }, { 243, 245 }, { 3, 0 }, 8, 75 },
246 { { 1, 2 }, { 79, 0 }, { 250, 248 }, { 141, 181 }, { 0, 0 }, 7, 68 },
247 { { 0, 0 }, { 0, 0 }, { 246, 246 }, { 12, 6 }, { 0, 0 }, 4, 48 },
248 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 53 },
249 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
250 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
251 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
252 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
253 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
254 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
255 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
256 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
257 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
258 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
259 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
260 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
261 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
262 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
263 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
264 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
265 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
266 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
267 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
268 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
269 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
270 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
271 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
272 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
273 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
274 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
275 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
276 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
277 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
278 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
279 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
280 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
281 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
282 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
283 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
284 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
285 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
286 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
287 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
288 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 },
289 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 35 }
290 };
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gus.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gus.c
new file mode 100644
index 0000000000..26cdc92537
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gus.c
@@ -0,0 +1,283 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 file: GUS.C
22
23 author: James R. Dose
24 date: September 7, 1994
25
26 Gravis Ultrasound initialization routines.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#include <conio.h>
32#include <dos.h>
33#include <stdio.h>
34#include <io.h>
35#include <fcntl.h>
36#include <string.h>
37#include <stdlib.h>
38#include "usrhooks.h"
39#include "interrup.h"
40#include "newgf1.h"
41#include "gusmidi.h"
42#include "guswave.h"
43#include "_guswave.h"
44
45#define TRUE ( 1 == 1 )
46#define FALSE ( !TRUE )
47
48// size of DMA buffer for patch loading
49#define DMABUFFSIZE 2048U
50
51struct gf1_dma_buff GUS_HoldBuffer;
52static int HoldBufferAllocated = FALSE;
53
54static int GUS_Installed = 0;
55
56extern VoiceNode GUSWAVE_Voices[ VOICES ];
57extern int GUSWAVE_Installed;
58
59unsigned long GUS_TotalMemory;
60int GUS_MemConfig;
61
62int GUS_AuxError = 0;
63
64int GUS_ErrorCode = GUS_Ok;
65
66#define GUS_SetErrorCode( status ) \
67 GUS_ErrorCode = ( status );
68
69
70/*---------------------------------------------------------------------
71 Function: GUS_ErrorString
72
73 Returns a pointer to the error message associated with an error
74 number. A -1 returns a pointer the current error.
75---------------------------------------------------------------------*/
76
77char *GUS_ErrorString
78 (
79 int ErrorNumber
80 )
81
82 {
83 char *ErrorString;
84
85 switch( ErrorNumber )
86 {
87 case GUS_Warning :
88 case GUS_Error :
89 ErrorString = GUS_ErrorString( GUS_ErrorCode );
90 break;
91
92 case GUS_Ok :
93 ErrorString = "Ultrasound music ok.";
94 break;
95
96 case GUS_OutOfMemory :
97 ErrorString = "Out of memory in GusMidi.";
98 break;
99
100 case GUS_OutOfDosMemory :
101 ErrorString = "Out of conventional (640K) memory in GusMidi.";
102 break;
103
104 case GUS_GF1Error :
105 ErrorString = gf1_error_str( GUS_AuxError );
106 break;
107
108 case GUS_InvalidIrq :
109 ErrorString = "Ultrasound IRQ must be 7 or less.";
110 break;
111
112 case GUS_ULTRADIRNotSet :
113 ErrorString = "ULTRADIR environment variable not set.";
114 break;
115
116 case GUS_MissingConfig :
117// ErrorString = "Can't find GUSMIDI.INI file.";
118 ErrorString = "Can't find ULTRAMID.INI file.";
119 break;
120
121 case GUS_FileError :
122 ErrorString = strerror( GUS_AuxError );
123 break;
124
125 default :
126 ErrorString = "Unknown Ultrasound error code.";
127 break;
128 }
129
130 return( ErrorString );
131 }
132
133
134
135/*---------------------------------------------------------------------
136 Function: D32DosMemAlloc
137
138 Allocate a block of Conventional memory.
139---------------------------------------------------------------------*/
140
141void *D32DosMemAlloc
142 (
143 unsigned size
144 )
145
146 {
147 union REGS r;
148
149 // DPMI allocate DOS memory
150 r.x.eax = 0x0100;
151
152 // Number of paragraphs requested
153 r.x.ebx = ( size + 15 ) >> 4;
154 int386( 0x31, &r, &r );
155 if ( r.x.cflag )
156 {
157 // Failed
158 return( NULL );
159 }
160
161 return( ( void * )( ( r.x.eax & 0xFFFF ) << 4 ) );
162 }
163
164
165/*---------------------------------------------------------------------
166 Function: GUS_Init
167
168 Initializes the Gravis Ultrasound for sound and music playback.
169---------------------------------------------------------------------*/
170
171int GUS_Init
172 (
173 void
174 )
175
176 {
177 struct load_os os;
178 int ret;
179
180 if ( GUS_Installed > 0 )
181 {
182 GUS_Installed++;
183 return( GUS_Ok );
184 }
185
186 GUS_SetErrorCode( GUS_Ok );
187
188 GUS_Installed = 0;
189
190 GetUltraCfg( &os );
191
192 if ( os.forced_gf1_irq > 7 )
193 {
194 GUS_SetErrorCode( GUS_InvalidIrq );
195 return( GUS_Error );
196 }
197
198 if ( !HoldBufferAllocated )
199 {
200 GUS_HoldBuffer.vptr = D32DosMemAlloc( DMABUFFSIZE );
201 if ( GUS_HoldBuffer.vptr == NULL )
202 {
203 GUS_SetErrorCode( GUS_OutOfDosMemory );
204 return( GUS_Error );
205 }
206 GUS_HoldBuffer.paddr = ( unsigned long )GUS_HoldBuffer.vptr;
207
208 HoldBufferAllocated = TRUE;
209 }
210
211 os.voices = 24;
212 ret = gf1_load_os( &os );
213 if ( ret )
214 {
215 GUS_AuxError = ret;
216 GUS_SetErrorCode( GUS_GF1Error );
217 return( GUS_Error );
218 }
219
220 GUS_TotalMemory = gf1_mem_avail();
221 GUS_MemConfig = ( GUS_TotalMemory - 1 ) >> 18;
222
223 GUS_Installed = 1;
224 return( GUS_Ok );
225 }
226
227
228/*---------------------------------------------------------------------
229 Function: GUS_Shutdown
230
231 Ends use of the Gravis Ultrasound. Must be called the same number
232 of times as GUS_Init.
233---------------------------------------------------------------------*/
234
235void GUS_Shutdown
236 (
237 void
238 )
239
240 {
241 if ( GUS_Installed > 0 )
242 {
243 GUS_Installed--;
244 if ( GUS_Installed == 0 )
245 {
246 gf1_unload_os();
247 }
248 }
249 }
250
251
252/*---------------------------------------------------------------------
253 Function: GUSWAVE_Shutdown
254
255 Terminates use of the Gravis Ultrasound for digitized sound playback.
256---------------------------------------------------------------------*/
257
258void GUSWAVE_Shutdown
259 (
260 void
261 )
262
263 {
264 int i;
265
266 if ( GUSWAVE_Installed )
267 {
268 GUSWAVE_KillAllVoices();
269
270 // free memory
271 for ( i = 0; i < VOICES; i++ )
272 {
273 if ( GUSWAVE_Voices[ i ].mem != NULL )
274 {
275 gf1_free( GUSWAVE_Voices[ i ].mem );
276 GUSWAVE_Voices[ i ].mem = NULL;
277 }
278 }
279
280 GUS_Shutdown();
281 GUSWAVE_Installed = FALSE;
282 }
283 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gusmidi.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gusmidi.c
new file mode 100644
index 0000000000..9a23045386
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gusmidi.c
@@ -0,0 +1,561 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/*********** ***********************************************************
21 file: GUSMIDI.C
22
23 author: James R. Dose
24 date: March 23, 1994
25
26 General MIDI playback functions for the Gravis Ultrasound
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31// Module MUST be compiled with structure allignment set to a maximum
32// of 1 byte ( zp1 ).
33
34#include <conio.h>
35#include <dos.h>
36#include <stdio.h>
37#include <io.h>
38#include <fcntl.h>
39#include <string.h>
40#include <stdlib.h>
41#include "usrhooks.h"
42#include "interrup.h"
43#include "newgf1.h"
44#include "gusmidi.h"
45
46#define TRUE ( 1 == 1 )
47#define FALSE ( !TRUE )
48
49// size of DMA buffer for patch loading
50#define DMABUFFSIZE 2048U
51
52#define MAX_MEM_CONFIG 3
53
54// size of patch array (128 perc, 128 melodic)
55#define NUM_PATCHES 256
56
57// size of largest patch name
58#define BIGGEST_NAME 9
59
60#define UNUSED_PATCH -1
61
62static struct patch Patch[ NUM_PATCHES ];
63static unsigned char *PatchWaves[ NUM_PATCHES ];
64
65static int PatchMap[ NUM_PATCHES ][ MAX_MEM_CONFIG + 1 ];
66static char ProgramName[ NUM_PATCHES ][ BIGGEST_NAME ];
67static char PatchLoaded[ NUM_PATCHES ];
68
69static char ConfigFileName[] = "ULTRAMID.INI";
70static char ConfigDirectory[ 80 ] = { '\0' };
71
72// The name of the configuration directory
73static char InstrumentDirectory[ 80 ];
74
75extern struct gf1_dma_buff GUS_HoldBuffer;
76
77extern unsigned long GUS_TotalMemory;
78extern int GUS_MemConfig;
79
80static int GUSMIDI_Volume = 255;
81
82extern int GUS_AuxError;
83extern int GUS_ErrorCode;
84
85int GUSMIDI_Installed = FALSE;
86
87#define GUS_SetErrorCode( status ) \
88 GUS_ErrorCode = ( status );
89
90
91/*---------------------------------------------------------------------
92 Function: GUS_GetPatchMap
93
94 Reads the patch map from disk.
95---------------------------------------------------------------------*/
96
97int GUS_GetPatchMap
98 (
99 char *name
100 )
101
102 {
103 char text[ 80 ];
104 char *ud;
105 int index;
106 int ignore;
107 FILE *fp;
108
109 for( index = 0; index < NUM_PATCHES; index++ )
110 {
111 PatchMap[ index ][ 0 ] = UNUSED_PATCH;
112 PatchMap[ index ][ 1 ] = UNUSED_PATCH;
113 PatchMap[ index ][ 2 ] = UNUSED_PATCH;
114 PatchMap[ index ][ 3 ] = UNUSED_PATCH;
115 ProgramName[ index ][ 0 ] = 0;
116 }
117
118 ud = getenv( "ULTRADIR" );
119 if ( ud == NULL )
120 {
121 GUS_SetErrorCode( GUS_ULTRADIRNotSet );
122 return( GUS_Error );
123 }
124
125 strcpy( InstrumentDirectory, ud );
126 strcat( InstrumentDirectory, "\\midi\\" );
127 strcpy( ConfigDirectory, ud );
128 strcat( ConfigDirectory, "\\midi\\" );
129 strcpy( text, name );
130
131 fp = fopen( text, "r" );
132 if ( fp == NULL )
133 {
134 strcpy( text, InstrumentDirectory );
135 strcat( text, name );
136
137 fp = fopen( text, "r" );
138 if ( fp == NULL )
139 {
140 GUS_SetErrorCode( GUS_MissingConfig );
141 return( GUS_Error );
142 }
143 }
144
145 while( 1 )
146 {
147 if ( fgets( text, 80, fp ) == NULL )
148 {
149 break;
150 }
151
152 if ( text[ 0 ] == '#' )
153 {
154 continue;
155 }
156
157 if ( sscanf( text, "%d", &index ) != 1 )
158 {
159 continue;
160 }
161
162 sscanf( text, "%d, %d, %d, %d, %d, %s\n", &ignore,
163 &PatchMap[ index ][ 0 ],
164 &PatchMap[ index ][ 1 ],
165 &PatchMap[ index ][ 2 ],
166 &PatchMap[ index ][ 3 ],
167 ProgramName[ index ] );
168 }
169
170 fclose( fp );
171
172 return( GUS_Ok );
173 }
174
175
176/*---------------------------------------------------------------------
177 Function: GUSMIDI_UnloadPatch
178
179 Unloads a patch from the GUS's memory.
180---------------------------------------------------------------------*/
181
182int GUSMIDI_UnloadPatch
183 (
184 int prognum
185 )
186
187 {
188 int prog;
189 unsigned flags;
190
191 prog = PatchMap[ prognum ][ GUS_MemConfig ];
192
193 if ( PatchLoaded[ prog ] )
194 {
195 flags = DisableInterrupts();
196
197 gf1_unload_patch( &Patch[ prog ] );
198 if ( PatchWaves[ prog ] != NULL )
199 {
200 USRHOOKS_FreeMem( PatchWaves[ prog ] );
201 PatchWaves[ prog ] = NULL;
202 }
203
204 // just in case sequence is still playing
205 Patch[ prog ].nlayers = 0;
206 PatchLoaded[ prog ] = FALSE;
207
208 RestoreInterrupts( flags );
209 }
210
211 return( GUS_Ok );
212 }
213
214
215/*---------------------------------------------------------------------
216 Function: GUSMIDI_LoadPatch
217
218 Loads a patch into the GUS's memory.
219---------------------------------------------------------------------*/
220
221int GUSMIDI_LoadPatch
222 (
223 int prognum
224 )
225
226 {
227 int prog;
228 char text[ 80 ];
229 int ret;
230 unsigned char *wave_buff;
231 struct patchinfo patchi;
232 int status;
233
234 prog = PatchMap[ prognum ][ GUS_MemConfig ];
235
236 if ( ( PatchLoaded[ prog ] ) || ( prog == UNUSED_PATCH ) )
237 {
238 return( GUS_Ok );
239 }
240
241 if ( !ProgramName[ prog ][ 0 ] )
242 {
243 return( GUS_Ok );
244 }
245
246 strcpy( text, InstrumentDirectory );
247 strcat( text, ProgramName[ prog ] );
248 strcat( text, ".pat" );
249
250 ret = gf1_get_patch_info( text, &patchi );
251 if ( ret != OK )
252 {
253 GUS_AuxError = ret;
254 GUS_SetErrorCode( GUS_GF1Error );
255 return( GUS_Error );
256 }
257
258 status = USRHOOKS_GetMem( &wave_buff, patchi.header.wave_forms *
259 sizeof( struct wave_struct ) );
260 if ( status != USRHOOKS_Ok )
261 {
262 GUS_SetErrorCode( GUS_OutOfMemory );
263 return( GUS_Error );
264 }
265
266 ret = gf1_load_patch( text, &patchi, &Patch[ prog ], &GUS_HoldBuffer,
267 DMABUFFSIZE, ( unsigned char * )wave_buff, PATCH_LOAD_8_BIT );
268
269 if ( ret != OK )
270 {
271 USRHOOKS_FreeMem( wave_buff );
272 GUS_AuxError = ret;
273 GUS_SetErrorCode( GUS_GF1Error );
274 return( GUS_Error );
275 }
276
277 PatchWaves[ prog ] = wave_buff;
278 PatchLoaded[ prog ] = TRUE;
279
280 return( GUS_Ok );
281 }
282
283
284/*---------------------------------------------------------------------
285 Function: GUSMIDI_ProgramChange
286
287 Selects the instrument to use on the specified MIDI channel.
288---------------------------------------------------------------------*/
289
290void GUSMIDI_ProgramChange
291 (
292 int channel,
293 int prognum
294 )
295
296 {
297 int prog;
298
299 prog = PatchMap[ prognum ][ GUS_MemConfig ];
300
301 if ( PatchLoaded[ prog ] )
302 {
303 gf1_midi_change_program( &Patch[ prog ], channel );
304 }
305 else
306 {
307 gf1_midi_change_program( NULL, channel );
308 }
309 }
310
311
312/*---------------------------------------------------------------------
313 Function: GUSMIDI_NoteOn
314
315 Plays a note on the specified channel.
316---------------------------------------------------------------------*/
317
318void GUSMIDI_NoteOn
319 (
320 int chan,
321 int note,
322 int velocity
323 )
324
325 {
326 int prog;
327
328 if ( chan == 9 )
329 {
330 prog = PatchMap[ note + 128 ][ GUS_MemConfig ];
331
332 if ( PatchLoaded[ prog ] )
333 {
334 gf1_midi_note_on( &Patch[ note + 128 ], 1,
335 note, velocity, 9 );
336 }
337 }
338 else
339 {
340 gf1_midi_note_on( 0L, 1, note, velocity, chan );
341 }
342 }
343
344
345/*---------------------------------------------------------------------
346 Function: GUSMIDI_NoteOff
347
348 Turns off a note on the specified channel.
349---------------------------------------------------------------------*/
350#pragma warn -par
351void GUSMIDI_NoteOff
352 (
353 int chan,
354 int note,
355 int velocity
356 )
357
358 {
359 gf1_midi_note_off( note, chan );
360 }
361#pragma warn .par
362
363
364/*---------------------------------------------------------------------
365 Function: GUSMIDI_ControlChange
366
367 Sets the value of a controller on the specified channel.
368---------------------------------------------------------------------*/
369
370void GUSMIDI_ControlChange
371 (
372 int channel,
373 int number,
374 int value
375 )
376
377 {
378 gf1_midi_parameter( channel, number, value );
379 }
380
381
382/*---------------------------------------------------------------------
383 Function: GUSMIDI_PitchBend
384
385 Sets the pitch bend on the specified MIDI channel.
386---------------------------------------------------------------------*/
387
388void GUSMIDI_PitchBend
389 (
390 int channel,
391 int lsb,
392 int msb
393 )
394
395 {
396 gf1_midi_pitch_bend( channel, lsb, msb );
397 }
398
399
400/*---------------------------------------------------------------------
401 Function: GUSMIDI_ReleasePatches
402
403 Removes all the instruments from the GUS's memory.
404---------------------------------------------------------------------*/
405
406void GUSMIDI_ReleasePatches
407 (
408 void
409 )
410
411 {
412 int i;
413
414 for( i = 0; i < 256; i++ )
415 {
416 GUSMIDI_UnloadPatch( i );
417 }
418 }
419
420
421/*---------------------------------------------------------------------
422 Function: GUSMIDI_SetVolume
423
424 Sets the total music volume.
425---------------------------------------------------------------------*/
426
427void GUSMIDI_SetVolume
428 (
429 int volume
430 )
431
432 {
433 // Set the minimum to 2 because 0 has a tremolo problem
434 volume = max( 2, volume );
435 volume = min( volume, 255 );
436
437 GUSMIDI_Volume = volume;
438
439 // range = 0 to 127
440 gf1_midi_synth_volume( 0, volume >> 1 );
441 }
442
443
444/*---------------------------------------------------------------------
445 Function: GUSMIDI_GetVolume
446
447 Returns the total music volume.
448---------------------------------------------------------------------*/
449
450int GUSMIDI_GetVolume
451 (
452 void
453 )
454
455 {
456 return( GUSMIDI_Volume );
457 }
458
459
460/*---------------------------------------------------------------------
461 Function: GUSMIDI_Init
462
463 Initializes the Gravis Ultrasound for music playback.
464---------------------------------------------------------------------*/
465
466int GUSMIDI_Init
467 (
468 void
469 )
470
471 {
472 int ret;
473 int i;
474 int startmem;
475// unsigned long mem;
476 extern int GUSWAVE_Installed;
477
478 if ( GUSMIDI_Installed )
479 {
480 GUSMIDI_Shutdown();
481 }
482
483 ret = GUS_Init();
484 if ( ret != GUS_Ok )
485 {
486 return( ret );
487 }
488
489 if ( GUS_MemConfig < 0 )
490 {
491 GUS_MemConfig = 0;
492 }
493
494 if ( GUS_MemConfig > MAX_MEM_CONFIG )
495 {
496 GUS_MemConfig = MAX_MEM_CONFIG;
497 }
498
499 for( i = 0; i < NUM_PATCHES; i++ )
500 {
501 ProgramName[ i ][ 0 ] = '\0';
502 PatchWaves[ i ] = NULL;
503 PatchLoaded[ i ] = FALSE;
504 }
505
506 GUSMIDI_SetVolume( 255 );
507
508 GUSMIDI_Installed = TRUE;
509
510 ret = GUS_GetPatchMap( ConfigFileName );
511 if ( ret != GUS_Ok )
512 {
513 GUSMIDI_Shutdown();
514 return( ret );
515 }
516
517// if ( !GUSWAVE_Installed )
518// {
519// mem = gf1_malloc( 8192 );
520// }
521
522 startmem = gf1_mem_avail();
523 for( i = 0; i < NUM_PATCHES; i++ )
524 {
525 ret = GUSMIDI_LoadPatch( i );
526 if ( ret != GUS_Ok )
527 {
528 }
529// if ( ret != GUS_Ok )
530// {
531// return( ret );
532// }
533 }
534
535// if ( !GUSWAVE_Installed )
536// {
537// gf1_free( mem );
538// }
539
540 GUSMIDI_Installed = TRUE;
541
542 return( GUS_Ok );
543 }
544
545
546/*---------------------------------------------------------------------
547 Function: GUSMIDI_Shutdown
548
549 Ends use of the Gravis Ultrasound for music playback.
550---------------------------------------------------------------------*/
551
552void GUSMIDI_Shutdown
553 (
554 void
555 )
556
557 {
558 GUSMIDI_ReleasePatches();
559 GUS_Shutdown();
560 GUSMIDI_Installed = FALSE;
561 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gusmidi.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gusmidi.h
new file mode 100644
index 0000000000..12a5b9f588
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/gusmidi.h
@@ -0,0 +1,59 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20#ifndef __GUSMIDI_H
21#define __GUSMIDI_H
22
23extern struct gf1_dma_buff GUS_HoldBuffer;
24
25enum GUS_Errors
26 {
27 GUS_Warning = -2,
28 GUS_Error = -1,
29 GUS_Ok = 0,
30 GUS_OutOfMemory,
31 GUS_OutOfDosMemory,
32 GUS_OutOfDRAM,
33 GUS_GF1Error,
34 GUS_InvalidIrq,
35 GUS_ULTRADIRNotSet,
36 GUS_MissingConfig,
37 GUS_FileError
38 };
39
40char *GUS_ErrorString( int ErrorNumber );
41int GUS_GetPatchMap( char *name );
42int GUSMIDI_UnloadPatch( int prog );
43int GUSMIDI_LoadPatch( int prog );
44void GUSMIDI_ProgramChange( int channel, int prog );
45void GUSMIDI_NoteOn( int chan, int note, int velocity );
46void GUSMIDI_NoteOff( int chan, int note, int velocity );
47void GUSMIDI_ControlChange( int channel, int number, int value );
48void GUSMIDI_PitchBend( int channel, int lsb, int msb );
49void GUSMIDI_ReleasePatches( void );
50void GUSMIDI_SetVolume( int volume );
51int GUSMIDI_GetVolume( void );
52int GUS_Init( void );
53void GUS_Shutdown( void );
54#pragma aux GUS_Shutdown frame;
55int GUSMIDI_Init( void );
56void GUSMIDI_Shutdown( void );
57void *D32DosMemAlloc( unsigned size );
58
59#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/guswave.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/guswave.c
new file mode 100644
index 0000000000..4cd90bd8b3
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/guswave.c
@@ -0,0 +1,1773 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 file: GUSWAVE.C
22
23 author: James R. Dose
24 date: March 23, 1994
25
26 Digitized sound playback routines for the Gravis Ultrasound.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#include <stdlib.h>
32#include <conio.h>
33#include <dos.h>
34#include <stdio.h>
35#include <io.h>
36#include <string.h>
37#include "debugio.h"
38#include "interrup.h"
39#include "ll_man.h"
40#include "pitch.h"
41#include "user.h"
42#include "multivoc.h"
43#include "_guswave.h"
44#include "newgf1.h"
45#include "gusmidi.h"
46#include "guswave.h"
47
48#define ATR_INDEX 0x3c0
49#define STATUS_REGISTER_1 0x3da
50
51#define SetBorderColor(color) \
52 { \
53 inp (STATUS_REGISTER_1); \
54 outp (ATR_INDEX,0x31); \
55 outp (ATR_INDEX,color); \
56 }
57
58static const int GUSWAVE_PanTable[ 32 ] =
59 {
60 8, 9, 10, 11, 11, 12, 13, 14,
61 15, 14, 13, 12, 11, 10, 9, 8,
62 7, 6, 5, 4, 4, 3, 2, 1,
63 0, 1, 2, 3, 4, 5, 6, 7
64 };
65
66static voicelist VoiceList;
67static voicelist VoicePool;
68
69static voicestatus VoiceStatus[ MAX_VOICES ];
70//static
71VoiceNode GUSWAVE_Voices[ VOICES ];
72
73static int GUSWAVE_VoiceHandle = GUSWAVE_MinVoiceHandle;
74static int GUSWAVE_MaxVoices = VOICES;
75//static
76int GUSWAVE_Installed = FALSE;
77
78static void ( *GUSWAVE_CallBackFunc )( unsigned long ) = NULL;
79
80// current volume for dig audio - from 0 to 4095
81static int GUSWAVE_Volume = MAX_VOLUME;
82
83static int GUSWAVE_SwapLeftRight = FALSE;
84
85static int GUS_Debug = FALSE;
86
87extern int GUSMIDI_Installed;
88
89int GUSWAVE_ErrorCode = GUSWAVE_Ok;
90
91#define GUSWAVE_SetErrorCode( status ) \
92 GUSWAVE_ErrorCode = ( status );
93
94
95/*---------------------------------------------------------------------
96 Function: GUSWAVE_ErrorString
97
98 Returns a pointer to the error message associated with an error
99 number. A -1 returns a pointer the current error.
100---------------------------------------------------------------------*/
101
102char *GUSWAVE_ErrorString
103 (
104 int ErrorNumber
105 )
106
107 {
108 char *ErrorString;
109
110 switch( ErrorNumber )
111 {
112 case GUSWAVE_Warning :
113 case GUSWAVE_Error :
114 ErrorString = GUSWAVE_ErrorString( GUSWAVE_ErrorCode );
115 break;
116
117 case GUSWAVE_Ok :
118 ErrorString = "GUSWAVE ok.";
119 break;
120
121 case GUSWAVE_GUSError :
122 ErrorString = GUS_ErrorString( GUS_Error );
123 break;
124
125 case GUSWAVE_NotInstalled :
126 ErrorString = "GUSWAVE not installed.";
127 break;
128
129 case GUSWAVE_NoVoices :
130 ErrorString = "No free voices available to GUSWAVE.";
131 break;
132
133 case GUSWAVE_UltraNoMem :
134 ErrorString = "Not enough Ultrasound memory available for GUSWAVE.";
135 break;
136
137 case GUSWAVE_UltraNoMemMIDI :
138 ErrorString = "Not enough Ultrasound memory available for GUSWAVE. "
139 "Try initializing Sound FX before Music.";
140 break;
141
142 case GUSWAVE_VoiceNotFound :
143 ErrorString = "No voice with matching handle found.";
144 break;
145
146 case GUSWAVE_InvalidVOCFile :
147 ErrorString = "Invalid VOC file passed in to GUSWAVE.";
148 break;
149
150 case GUSWAVE_InvalidWAVFile :
151 ErrorString = "Invalid WAV file passed in to GUSWAVE.";
152 break;
153
154 default :
155 ErrorString = "Unknown GUSWAVE error code.";
156 break;
157 }
158
159 return( ErrorString );
160 }
161
162
163/*---------------------------------------------------------------------
164 Function: GUSWAVE_CallBack
165
166 GF1 callback service routine.
167---------------------------------------------------------------------*/
168
169char GUS_Silence8[ 1024 ] = //256 ] =
170 {
171 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
172 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
173 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
174 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
175 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
176 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
177 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
178 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
179 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
180 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
181 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
182 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
183 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
184 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
185 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
186 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
187
188 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
189 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
190 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
191 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
192 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
193 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
194 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
195 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
196 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
197 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
198 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
199 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
200 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
201 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
202 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
203 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
204 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
205 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
206 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
207 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
208 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
209 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
210 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
211 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
212 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
213 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
214 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
215 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
216 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
217 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
218 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
219 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
220 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
221 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
222 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
223 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
224 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
225 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
226 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
227 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
228 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
229 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
230 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
231 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
232 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
233 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
234 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
235 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
236
237
238 };
239
240//unsigned short GUS_Silence16[ 128 ] =
241unsigned short GUS_Silence16[ 512 ] =
242 {
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251
252
253
254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
259 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
260 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
265 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
278 };
279
280static int LOADDS GUSWAVE_CallBack
281 (
282 int reason,
283 int voice,
284 unsigned char **buf,
285 unsigned long *size
286 )
287
288 {
289 VoiceNode *Voice;
290 playbackstatus status;
291
292 // this function is called from an interrupt
293 // remember not to make any DOS or BIOS calls from here
294 // also don't call any C library functions unless you are sure that
295 // they are reentrant
296 // restore our DS register
297
298 if ( VoiceStatus[ voice ].playing == FALSE )
299 {
300 return( DIG_DONE );
301 }
302
303 if ( reason == DIG_MORE_DATA )
304 {
305// SetBorderColor(16);
306 Voice = VoiceStatus[ voice ].Voice;
307
308 if ( ( Voice != NULL ) && ( Voice->Playing ) )
309/*
310 {
311 *buf = ( unsigned char * )GUS_Silence16;
312 *size = 1024;
313
314 SetBorderColor(0);
315 return( DIG_MORE_DATA );
316 }
317 */
318 {
319 status = Voice->GetSound( Voice );
320 if ( status != SoundDone )
321 {
322 if ( ( Voice->sound == NULL ) || ( status == NoMoreData ) )
323 {
324 if ( Voice->bits == 8 )
325 {
326 *buf = GUS_Silence8;
327 }
328 else
329 {
330 *buf = ( unsigned char * )GUS_Silence16;
331 }
332 *size = 256;
333 }
334 else
335 {
336 *buf = Voice->sound;
337 *size = Voice->length;
338 }
339 return( DIG_MORE_DATA );
340 }
341 }
342// SetBorderColor(16);
343 return( DIG_DONE );
344 }
345
346 if ( reason == DIG_DONE )
347 {
348 Voice = VoiceStatus[ voice ].Voice;
349 VoiceStatus[ voice ].playing = FALSE;
350
351 if ( Voice != NULL )
352 {
353 Voice->Active = FALSE;
354 Voice->Playing = FALSE;
355
356// I'm commenting this out because a -1 could cause a crash if it
357// is sent to the GF1 code. This shouldn't be necessary since
358// Active should be false when GF1voice is -1, but this is just
359// a precaution. Adjust the pan on the wrong voice is a lot
360// more pleasant than a crash!
361// Voice->GF1voice = -1;
362
363 LL_Remove( VoiceNode, &VoiceList, Voice );
364 LL_AddToTail( VoiceNode, &VoicePool, Voice );
365 }
366
367 if ( GUSWAVE_CallBackFunc )
368 {
369 GUSWAVE_CallBackFunc( Voice->callbackval );
370 }
371 }
372
373 return( DIG_DONE );
374 }
375
376
377/*---------------------------------------------------------------------
378 Function: GUSWAVE_DebugCallBack
379
380 GF1 callback service routine with debugging info.
381---------------------------------------------------------------------*/
382
383static int LOADDS GUSWAVE_DebugCallBack
384 (
385 int reason,
386 int voice,
387 unsigned char **buf,
388 unsigned long *size
389 )
390
391 {
392 VoiceNode *Voice;
393
394 // this function is called from an interrupt
395 // remember not to make any DOS or BIOS calls from here
396 // also don't call any C library functions unless you are sure that
397 // they are reentrant
398 // restore our DS register
399
400 if ( VoiceStatus[ voice ].playing == FALSE )
401 {
402// DB_printf( "GUS Voice %d not playing.\n", voice );
403 DB_printf( "GUS Voice " );
404 DB_PrintNum( voice );
405 DB_printf( " not playing.\n" );
406 return( DIG_DONE );
407 }
408
409 if ( reason == DIG_MORE_DATA )
410 {
411 Voice = VoiceStatus[ voice ].Voice;
412
413// DB_printf( "Voice %d : More data -- ", Voice );
414 DB_printf( "Voice " );
415 DB_PrintNum( voice );
416 DB_printf( " : More data -- " );
417 if ( Voice != NULL )
418 {
419 if ( Voice->Playing )
420 {
421 GUSWAVE_GetNextVOCBlock( Voice );
422 if ( Voice->Playing )
423 {
424// DB_printf( "More data -- size = %u blocklength = %u\n",
425// Voice->length, Voice->BlockLength );
426 DB_printf( "More data -- size = " );
427 DB_PrintNum( Voice->length );
428 DB_printf( " blocklength = " );
429 DB_PrintNum( Voice->BlockLength );
430 DB_printf( "\n" );
431 *buf = Voice->sound;
432 *size = Voice->length;
433 return( DIG_MORE_DATA );
434 }
435 else
436 {
437 DB_printf( "Voice done.\n" );
438 }
439 }
440 else
441 {
442 DB_printf( "Voice not active.\n" );
443 }
444 }
445 else
446 {
447 DB_printf( " NULL Voice\n" );
448 }
449
450 return( DIG_DONE );
451 }
452
453 if ( reason == DIG_DONE )
454 {
455 VoiceStatus[ voice ].playing = FALSE;
456 Voice = VoiceStatus[ voice ].Voice;
457// DB_printf( "Voice %d : Done -- ", Voice );
458 DB_printf( "Voice " );
459 DB_PrintNum( voice );
460 DB_printf( " : Done -- " );
461
462 if ( Voice != NULL )
463 {
464 DB_printf( "Ok\n" );
465
466 Voice->Active = FALSE;
467 Voice->Playing = FALSE;
468
469// I'm commenting this out because a -1 could cause a crash if it
470// is sent to the GF1 code. This shouldn't be necessary since
471// Active should be false when GF1voice is -1, but this is just
472// a precaution. Adjust the pan on the wrong voice is a lot
473// more pleasant than a crash!
474// Voice->GF1voice = -1;
475
476 LL_Remove( VoiceNode, &VoiceList, Voice );
477 LL_AddToTail( VoiceNode, &VoicePool, Voice );
478 }
479 else
480 {
481 DB_printf( "Null voice\n" );
482 }
483
484 if ( GUSWAVE_CallBackFunc )
485 {
486 GUSWAVE_CallBackFunc( Voice->callbackval );
487 }
488 }
489
490 return( DIG_DONE );
491 }
492
493
494/*---------------------------------------------------------------------
495 Function: GUSWAVE_GetVoice
496
497 Locates the voice with the specified handle.
498---------------------------------------------------------------------*/
499
500static VoiceNode *GUSWAVE_GetVoice
501 (
502 int handle
503 )
504
505 {
506 VoiceNode *voice;
507 unsigned flags;
508
509 flags = DisableInterrupts();
510
511 voice = VoiceList.start;
512
513 while( voice != NULL )
514 {
515 if ( handle == voice->handle )
516 {
517 break;
518 }
519
520 voice = voice->next;
521 }
522
523 RestoreInterrupts( flags );
524
525 if ( voice == NULL )
526 {
527 GUSWAVE_SetErrorCode( GUSWAVE_VoiceNotFound );
528 }
529
530 return( voice );
531 }
532
533
534/*---------------------------------------------------------------------
535 Function: GUSWAVE_VoicePlaying
536
537 Checks if the voice associated with the specified handle is
538 playing.
539---------------------------------------------------------------------*/
540
541int GUSWAVE_VoicePlaying
542 (
543 int handle
544 )
545
546 {
547 VoiceNode *voice;
548
549 voice = GUSWAVE_GetVoice( handle );
550 if ( voice != NULL )
551 {
552 return( voice->Active );
553 }
554
555 return( FALSE );
556 }
557
558
559/*---------------------------------------------------------------------
560 Function: GUSWAVE_VoicesPlaying
561
562 Determines the number of currently active voices.
563---------------------------------------------------------------------*/
564
565int GUSWAVE_VoicesPlaying
566 (
567 void
568 )
569
570 {
571 int index;
572 int NumVoices = 0;
573 unsigned flags;
574
575 flags = DisableInterrupts();
576
577 for( index = 0; index < GUSWAVE_MaxVoices; index++ )
578 {
579 if ( GUSWAVE_Voices[ index ].Active )
580 {
581 NumVoices++;
582 }
583 }
584
585 RestoreInterrupts( flags );
586
587 if ( GUS_Debug )
588 {
589 DB_printf( "Number of voices = %d.\n", NumVoices );
590 }
591
592 return( NumVoices );
593 }
594
595
596/*---------------------------------------------------------------------
597 Function: GUSWAVE_Kill
598
599 Stops output of the voice associated with the specified handle.
600---------------------------------------------------------------------*/
601
602int GUSWAVE_Kill
603 (
604 int handle
605 )
606
607 {
608 VoiceNode *voice;
609 unsigned flags;
610
611 flags = DisableInterrupts();
612
613 voice = GUSWAVE_GetVoice( handle );
614
615 if ( voice == NULL )
616 {
617 RestoreInterrupts( flags );
618 GUSWAVE_SetErrorCode( GUSWAVE_VoiceNotFound );
619
620 if ( GUS_Debug )
621 {
622 DB_printf( "Could not find voice to kill.\n" );
623 }
624
625 return( GUSWAVE_Warning );
626 }
627
628 RestoreInterrupts( flags );
629
630 if ( !GUS_Debug )
631 {
632 if ( voice->Active )
633 {
634 gf1_stop_digital( voice->GF1voice );
635 }
636 }
637 else
638 {
639 DB_printf( "Kill - GUS Voice %d ", voice->GF1voice );
640 if ( voice->Active )
641 {
642 DB_printf( "active\n" );
643 gf1_stop_digital( voice->GF1voice );
644 }
645 else
646 {
647 DB_printf( "inactive\n" );
648 }
649 }
650
651// RestoreInterrupts( flags );
652
653 return( GUSWAVE_Ok );
654 }
655
656
657/*---------------------------------------------------------------------
658 Function: GUSWAVE_KillAllVoices
659
660 Stops output of all currently active voices.
661---------------------------------------------------------------------*/
662
663int GUSWAVE_KillAllVoices
664 (
665 void
666 )
667
668 {
669 int i;
670 unsigned flags;
671
672 if ( !GUSWAVE_Installed )
673 {
674 return( GUSWAVE_Ok );
675 }
676
677 if ( GUS_Debug )
678 {
679 DB_printf( "Kill All Voices\n" );
680 }
681
682 flags = DisableInterrupts();
683
684 // Remove all the voices from the list
685 for( i = 0; i < GUSWAVE_MaxVoices; i++ )
686 {
687 if ( GUSWAVE_Voices[ i ].Active )
688 {
689// GUSWAVE_Kill( GUSWAVE_Voices[ i ].handle );
690
691 gf1_stop_digital( GUSWAVE_Voices[ i ].GF1voice );
692 }
693 }
694
695 for( i = 0; i < MAX_VOICES; i++ )
696 {
697 VoiceStatus[ i ].playing = FALSE;
698 VoiceStatus[ i ].Voice = NULL;
699 }
700
701 VoicePool.start = NULL;
702 VoicePool.end = NULL;
703 VoiceList.start = NULL;
704 VoiceList.end = NULL;
705
706 for( i = 0; i < GUSWAVE_MaxVoices; i++ )
707 {
708 GUSWAVE_Voices[ i ].Active = FALSE;
709 if ( GUSWAVE_Voices[ i ].mem != NULL )
710 {
711 LL_AddToTail( VoiceNode, &VoicePool, &GUSWAVE_Voices[ i ] );
712 }
713 }
714
715 RestoreInterrupts( flags );
716
717 return( GUSWAVE_Ok );
718 }
719
720
721/*---------------------------------------------------------------------
722 Function: GUSWAVE_SetPitch
723
724 Sets the pitch for the voice associated with the specified handle.
725---------------------------------------------------------------------*/
726
727int GUSWAVE_SetPitch
728 (
729 int handle,
730 int pitchoffset
731 )
732
733 {
734 VoiceNode *voice;
735 unsigned flags;
736
737 flags = DisableInterrupts();
738
739 voice = GUSWAVE_GetVoice( handle );
740
741 if ( voice == NULL )
742 {
743 RestoreInterrupts( flags );
744
745 GUSWAVE_SetErrorCode( GUSWAVE_VoiceNotFound );
746 return( GUSWAVE_Warning );
747 }
748
749 if ( voice->Active )
750 {
751 voice->PitchScale = PITCH_GetScale( pitchoffset );
752 voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) >> 16;
753 gf1_dig_set_freq( voice->GF1voice, voice->RateScale );
754 }
755
756 RestoreInterrupts( flags );
757
758 return( GUSWAVE_Ok );
759 }
760
761
762/*---------------------------------------------------------------------
763 Function: GUSWAVE_SetPan3D
764
765 Sets the pan position of the voice with the specified handle.
766---------------------------------------------------------------------*/
767
768int GUSWAVE_SetPan3D
769 (
770 int handle,
771 int angle,
772 int distance
773 )
774
775 {
776 VoiceNode *voice;
777 int pan;
778 unsigned flags;
779
780 flags = DisableInterrupts();
781
782 voice = GUSWAVE_GetVoice( handle );
783
784 if ( voice == NULL )
785 {
786 RestoreInterrupts( flags );
787
788 GUSWAVE_SetErrorCode( GUSWAVE_VoiceNotFound );
789 return( GUSWAVE_Warning );
790 }
791
792 if ( voice->Active )
793 {
794 angle &= 31;
795
796 pan = GUSWAVE_PanTable[ angle ];
797 if ( GUSWAVE_SwapLeftRight )
798 {
799 pan = 15 - pan;
800 }
801
802 distance = max( 0, distance );
803 distance = min( 255, distance );
804
805 voice->Volume = 255 - distance;
806 voice->Pan = pan;
807
808 gf1_dig_set_pan( voice->GF1voice, pan );
809 gf1_dig_set_vol( voice->GF1voice, GUSWAVE_Volume - distance * 4 );
810 }
811
812 RestoreInterrupts( flags );
813
814 return( GUSWAVE_Ok );
815 }
816
817
818/*---------------------------------------------------------------------
819 Function: GUSWAVE_SetVolume
820
821 Sets the total volume of the digitized sounds.
822---------------------------------------------------------------------*/
823
824void GUSWAVE_SetVolume
825 (
826 int volume
827 )
828
829 {
830 int i;
831
832 volume = max( 0, volume );
833 volume = min( 255, volume );
834 GUSWAVE_Volume = MAX_VOLUME - ( 255 - volume ) * 4;
835
836 for( i = 0; i < GUSWAVE_MaxVoices; i++ )
837 {
838 if ( GUSWAVE_Voices[ i ].Active )
839 {
840 gf1_dig_set_vol( GUSWAVE_Voices[ i ].GF1voice,
841 GUSWAVE_Volume - ( 255 - GUSWAVE_Voices[ i ].Volume ) * 4 );
842 }
843 }
844 }
845
846
847/*---------------------------------------------------------------------
848 Function: GUSWAVE_GetVolume
849
850 Returns the total volume of the digitized sounds.
851---------------------------------------------------------------------*/
852
853int GUSWAVE_GetVolume
854 (
855 void
856 )
857
858 {
859 return( 255 - ( ( MAX_VOLUME - GUSWAVE_Volume ) / 4 ) );
860 }
861
862
863/*---------------------------------------------------------------------
864 Function: GUSWAVE_AllocVoice
865
866 Retrieve an inactive or lower priority voice for output.
867---------------------------------------------------------------------*/
868
869static VoiceNode *GUSWAVE_AllocVoice
870 (
871 int priority
872 )
873
874 {
875 VoiceNode *voice;
876 VoiceNode *node;
877 unsigned flags;
878
879 // If we don't have any free voices, check if we have a higher
880 // priority than one that is playing.
881 if ( GUSWAVE_VoicesPlaying() >= GUSWAVE_MaxVoices )
882 {
883 flags = DisableInterrupts();
884
885 node = VoiceList.start;
886 voice = node;
887 while( node != NULL )
888 {
889 if ( node->priority < voice->priority )
890 {
891 voice = node;
892 }
893
894 node = node->next;
895 }
896
897 RestoreInterrupts( flags );
898
899 if ( priority >= voice->priority )
900 {
901 GUSWAVE_Kill( voice->handle );
902 }
903 }
904
905 // Check if any voices are in the voice pool
906 flags = DisableInterrupts();
907
908 voice = VoicePool.start;
909 if ( voice != NULL )
910 {
911 LL_Remove( VoiceNode, &VoicePool, voice );
912 }
913
914 RestoreInterrupts( flags );
915
916 if ( voice != NULL )
917 {
918 do
919 {
920 GUSWAVE_VoiceHandle++;
921 if ( GUSWAVE_VoiceHandle < GUSWAVE_MinVoiceHandle )
922 {
923 GUSWAVE_VoiceHandle = GUSWAVE_MinVoiceHandle;
924 }
925 }
926 while( GUSWAVE_VoicePlaying( GUSWAVE_VoiceHandle ) );
927
928 voice->handle = GUSWAVE_VoiceHandle;
929 }
930
931 return( voice );
932 }
933
934
935/*---------------------------------------------------------------------
936 Function: GUSWAVE_VoiceAvailable
937
938 Checks if a voice can be play at the specified priority.
939---------------------------------------------------------------------*/
940
941int GUSWAVE_VoiceAvailable
942 (
943 int priority
944 )
945
946 {
947 VoiceNode *voice;
948 VoiceNode *node;
949 unsigned flags;
950
951 if ( GUSWAVE_VoicesPlaying() < GUSWAVE_MaxVoices )
952 {
953 return( TRUE );
954 }
955
956 flags = DisableInterrupts();
957
958 node = VoiceList.start;
959 voice = node;
960 while( node != NULL )
961 {
962 if ( node->priority < voice->priority )
963 {
964 voice = node;
965 }
966
967 node = node->next;
968 }
969
970 RestoreInterrupts( flags );
971
972 if ( priority >= voice->priority )
973 {
974 return( TRUE );
975 }
976
977 return( FALSE );
978 }
979
980
981/*---------------------------------------------------------------------
982 Function: GUSWAVE_GetNextVOCBlock
983
984 Interperate the information of a VOC format sound file.
985---------------------------------------------------------------------*/
986
987playbackstatus GUSWAVE_GetNextVOCBlock
988 (
989 VoiceNode *voice
990 )
991
992 {
993 unsigned char *ptr;
994 int blocktype;
995 int lastblocktype;
996 unsigned long blocklength;
997 unsigned long samplespeed;
998 unsigned int tc;
999 int packtype;
1000 int voicemode;
1001 int done;
1002 unsigned BitsPerSample;
1003 unsigned Channels;
1004 unsigned Format;
1005
1006 if ( voice->BlockLength > 0 )
1007 {
1008 voice->sound += MAX_BLOCK_LENGTH;
1009 voice->length = min( voice->BlockLength, MAX_BLOCK_LENGTH );
1010 voice->BlockLength -= voice->length;
1011 return( KeepPlaying );
1012 }
1013
1014 ptr = ( unsigned char * )voice->NextBlock;
1015
1016 voice->Playing = TRUE;
1017
1018 voicemode = 0;
1019 lastblocktype = 0;
1020 packtype = 0;
1021
1022 done = FALSE;
1023 while( !done )
1024 {
1025 // Stop playing if we get a NULL pointer
1026 if ( ptr == NULL )
1027 {
1028 voice->Playing = FALSE;
1029 done = TRUE;
1030 break;
1031 }
1032
1033 blocktype = ( int )*ptr;
1034 blocklength = ( readLE32( ptr + 1 ) ) & 0x00ffffff;
1035 ptr += 4;
1036
1037 switch( blocktype )
1038 {
1039 case 0 :
1040 // End of data
1041 voice->Playing = FALSE;
1042 done = TRUE;
1043 break;
1044
1045 case 1 :
1046 // Sound data block
1047 voice->bits = 8;
1048 if ( lastblocktype != 8 )
1049 {
1050 tc = ( unsigned int )*ptr << 8;
1051 packtype = *( ptr + 1 );
1052 }
1053
1054 ptr += 2;
1055 blocklength -= 2;
1056
1057 samplespeed = 256000000L / ( 65536 - tc );
1058
1059 // Skip packed or stereo data
1060 if ( ( packtype != 0 ) || ( voicemode != 0 ) )
1061 {
1062 ptr += blocklength;
1063 }
1064 else
1065 {
1066 done = TRUE;
1067 }
1068 voicemode = 0;
1069 break;
1070
1071 case 2 :
1072 // Sound continuation block
1073 samplespeed = voice->SamplingRate;
1074 done = TRUE;
1075 break;
1076
1077 case 3 :
1078 // Silence
1079 // Not implimented.
1080 ptr += blocklength;
1081 break;
1082
1083 case 4 :
1084 // Marker
1085 // Not implimented.
1086 ptr += blocklength;
1087 break;
1088
1089 case 5 :
1090 // ASCII string
1091 // Not implimented.
1092 ptr += blocklength;
1093 break;
1094
1095 case 6 :
1096 // Repeat begin
1097 voice->LoopCount = readLE16(ptr);
1098 ptr += blocklength;
1099 voice->LoopStart = ptr;
1100 break;
1101
1102 case 7 :
1103 // Repeat end
1104 ptr += blocklength;
1105 if ( lastblocktype == 6 )
1106 {
1107 voice->LoopCount = 0;
1108 }
1109 else
1110 {
1111 if ( ( voice->LoopCount > 0 ) && ( voice->LoopStart != NULL ) )
1112 {
1113 ptr = voice->LoopStart;
1114 if ( voice->LoopCount < 0xffff )
1115 {
1116 voice->LoopCount--;
1117 if ( voice->LoopCount == 0 )
1118 {
1119 voice->LoopStart = NULL;
1120 }
1121 }
1122 }
1123 }
1124 break;
1125
1126 case 8 :
1127 // Extended block
1128 voice->bits = 8;
1129 tc = readLE16(ptr);
1130 packtype = *( ptr + 2 );
1131 voicemode = *( ptr + 3 );
1132 ptr += blocklength;
1133 break;
1134
1135 case 9 :
1136 // New sound data block
1137 samplespeed = readLE32(ptr);
1138 BitsPerSample = ( unsigned )*( ptr + 4 );
1139 Channels = ( unsigned )*( ptr + 5 );
1140 Format = ( unsigned )readLE16( ptr + 6 );
1141
1142 if ( ( BitsPerSample == 8 ) && ( Channels == 1 ) &&
1143 ( Format == VOC_8BIT ) )
1144 {
1145 ptr += 12;
1146 blocklength -= 12;
1147 voice->bits = 8;
1148 done = TRUE;
1149 }
1150 else if ( ( BitsPerSample == 16 ) && ( Channels == 1 ) &&
1151 ( Format == VOC_16BIT ) )
1152 {
1153 ptr += 12;
1154 blocklength -= 12;
1155 voice->bits = 16;
1156 done = TRUE;
1157 }
1158 else
1159 {
1160 ptr += blocklength;
1161 }
1162 break;
1163
1164 default :
1165 // Unknown data. Probably not a VOC file.
1166 voice->Playing = FALSE;
1167 done = TRUE;
1168 break;
1169 }
1170
1171 lastblocktype = blocktype;
1172 }
1173
1174 if ( voice->Playing )
1175 {
1176 voice->NextBlock = ptr + blocklength;
1177 voice->sound = ptr;
1178
1179 voice->SamplingRate = samplespeed;
1180 voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) >> 16;
1181
1182 voice->length = min( blocklength, MAX_BLOCK_LENGTH );
1183 voice->BlockLength = blocklength - voice->length;
1184
1185 return( KeepPlaying );
1186 }
1187
1188 return( SoundDone );
1189 }
1190
1191
1192/*---------------------------------------------------------------------
1193 Function: GUSWAVE_GetNextWAVBlock
1194
1195 Controls playback of demand fed data.
1196---------------------------------------------------------------------*/
1197
1198playbackstatus GUSWAVE_GetNextWAVBlock
1199 (
1200 VoiceNode *voice
1201 )
1202
1203 {
1204 if ( voice->BlockLength <= 0 )
1205 {
1206 if ( voice->LoopStart == NULL )
1207 {
1208 voice->Playing = FALSE;
1209 return( SoundDone );
1210 }
1211
1212 voice->BlockLength = voice->LoopSize;
1213 voice->NextBlock = voice->LoopStart;
1214 voice->length = 0;
1215 }
1216
1217 voice->sound = voice->NextBlock;
1218 voice->length = min( voice->BlockLength, 0x8000 );
1219 voice->NextBlock += voice->length;
1220 voice->BlockLength -= voice->length;
1221
1222 return( KeepPlaying );
1223 }
1224
1225
1226/*---------------------------------------------------------------------
1227 Function: GUSWAVE_GetNextDemandFeedBlock
1228
1229 Controls playback of demand fed data.
1230---------------------------------------------------------------------*/
1231
1232playbackstatus GUSWAVE_GetNextDemandFeedBlock
1233 (
1234 VoiceNode *voice
1235 )
1236
1237 {
1238 if ( voice->BlockLength > 0 )
1239 {
1240 voice->sound += voice->length;
1241 voice->length = min( voice->BlockLength, 0x8000 );
1242 voice->BlockLength -= voice->length;
1243
1244 return( KeepPlaying );
1245 }
1246
1247 if ( voice->DemandFeed == NULL )
1248 {
1249 return( SoundDone );
1250 }
1251
1252 ( voice->DemandFeed )( &voice->sound, &voice->BlockLength );
1253// voice->sound = GUS_Silence16;
1254// voice->BlockLength = 256;
1255
1256 voice->length = min( voice->BlockLength, 0x8000 );
1257 voice->BlockLength -= voice->length;
1258
1259 if ( ( voice->length > 0 ) && ( voice->sound != NULL ) )
1260 {
1261 return( KeepPlaying );
1262 }
1263 return( NoMoreData );
1264 }
1265
1266
1267/*---------------------------------------------------------------------
1268 Function: GUSWAVE_Play
1269
1270 Begins playback of digitized sound.
1271---------------------------------------------------------------------*/
1272
1273int GUSWAVE_Play
1274 (
1275 VoiceNode *voice,
1276 int angle,
1277 int volume,
1278 int channels
1279 )
1280
1281 {
1282 int VoiceNumber;
1283 int type;
1284 int pan;
1285 unsigned flags;
1286 int ( *servicefunction )( int reason, int voice, unsigned char **buf, unsigned long *size );
1287
1288 type = 0;
1289 if ( channels != 1 )
1290 {
1291 type |= TYPE_STEREO;
1292 }
1293
1294 if ( voice->bits == 8 )
1295 {
1296 type |= TYPE_8BIT;
1297 type |= TYPE_INVERT_MSB;
1298 }
1299
1300 voice->GF1voice = -1;
1301
1302 angle &= 31;
1303 pan = GUSWAVE_PanTable[ angle ];
1304 if ( GUSWAVE_SwapLeftRight )
1305 {
1306 pan = 15 - pan;
1307 }
1308
1309 voice->Pan = pan;
1310
1311 volume = max( 0, volume );
1312 volume = min( 255, volume );
1313 voice->Volume = volume;
1314
1315 if ( !GUS_Debug )
1316 {
1317 servicefunction = GUSWAVE_CallBack;
1318 }
1319 else
1320 {
1321 servicefunction = GUSWAVE_DebugCallBack;
1322 }
1323
1324 VoiceNumber = gf1_play_digital( 0, voice->sound, voice->length,
1325 voice->mem, GUSWAVE_Volume - ( 255 - volume ) * 4, pan,
1326 voice->RateScale, type, &GUS_HoldBuffer, servicefunction );
1327
1328 if ( VoiceNumber == NO_MORE_VOICES )
1329 {
1330 if ( GUS_Debug )
1331 {
1332 DB_printf( "Out of voices.\n" );
1333 }
1334
1335 flags = DisableInterrupts();
1336 LL_AddToTail( VoiceNode, &VoicePool, voice );
1337 RestoreInterrupts( flags );
1338
1339 GUSWAVE_SetErrorCode( GUSWAVE_NoVoices );
1340 return( GUSWAVE_Warning );
1341 }
1342
1343 flags = DisableInterrupts();
1344 voice->GF1voice = VoiceNumber;
1345 voice->Active = TRUE;
1346 LL_AddToTail( VoiceNode, &VoiceList, voice );
1347 VoiceStatus[ VoiceNumber ].playing = TRUE;
1348 VoiceStatus[ VoiceNumber ].Voice = voice;
1349
1350 if ( GUS_Debug )
1351 {
1352 DB_printf( "GUS voice %d playing\n", VoiceNumber );
1353 }
1354
1355 RestoreInterrupts( flags );
1356
1357 return( voice->handle );
1358 }
1359
1360
1361/*---------------------------------------------------------------------
1362 Function: GUSWAVE_PlayVOC
1363
1364 Begins playback of digitized sound.
1365---------------------------------------------------------------------*/
1366
1367int GUSWAVE_PlayVOC
1368 (
1369 char *sample,
1370 int pitchoffset,
1371 int angle,
1372 int volume,
1373 int priority,
1374 unsigned long callbackval
1375 )
1376
1377 {
1378 int handle;
1379 int status;
1380 playbackstatus soundstatus;
1381 VoiceNode *voice;
1382 unsigned flags;
1383
1384 // Make sure it's a valid VOC file.
1385 status = strncmp( sample, "Creative Voice File", 19 );
1386 if ( status != 0 )
1387 {
1388 // Tell multivoc that we had a bad VOC file
1389 MV_ErrorCode = MV_InvalidVOCFile;
1390
1391 GUSWAVE_SetErrorCode( GUSWAVE_InvalidVOCFile );
1392 return( GUSWAVE_Error );
1393 }
1394
1395 // Request a voice from the voice pool
1396 voice = GUSWAVE_AllocVoice( priority );
1397 if ( voice == NULL )
1398 {
1399 if ( GUS_Debug )
1400 {
1401 DB_printf( "No more voices. Skipping sound.\n" );
1402 }
1403 GUSWAVE_SetErrorCode( GUSWAVE_NoVoices );
1404 return( GUSWAVE_Warning );
1405 }
1406
1407 voice->NextBlock = sample + readLE16( sample + 0x14 );
1408 voice->LoopStart = NULL;
1409 voice->LoopCount = 0;
1410 voice->BlockLength = 0;
1411 voice->PitchScale = PITCH_GetScale( pitchoffset );
1412 voice->wavetype = VOC;
1413 voice->bits = 8;
1414 voice->GetSound = GUSWAVE_GetNextVOCBlock;
1415 voice->length = 0;
1416 voice->next = NULL;
1417 voice->prev = NULL;
1418 voice->priority = priority;
1419 voice->callbackval = callbackval;
1420
1421 soundstatus = GUSWAVE_GetNextVOCBlock( voice );
1422 if ( soundstatus == SoundDone )
1423 {
1424 flags = DisableInterrupts();
1425 LL_AddToTail( VoiceNode, &VoicePool, voice );
1426 RestoreInterrupts( flags );
1427
1428 if ( GUS_Debug )
1429 {
1430 DB_printf( "Voice ended before playback.\n" );
1431 }
1432
1433 // Tell multivoc that we had a bad VOC file
1434 MV_ErrorCode = MV_InvalidVOCFile;
1435
1436 GUSWAVE_SetErrorCode( GUSWAVE_InvalidVOCFile );
1437 return( GUSWAVE_Error );
1438 }
1439
1440 handle = GUSWAVE_Play( voice, angle, volume, 1 );
1441 return( handle );
1442 }
1443
1444
1445/*---------------------------------------------------------------------
1446 Function: GUSWAVE_PlayWAV
1447
1448 Begins playback of digitized sound.
1449---------------------------------------------------------------------*/
1450
1451int GUSWAVE_PlayWAV
1452 (
1453 char *sample,
1454 int pitchoffset,
1455 int angle,
1456 int volume,
1457 int priority,
1458 unsigned long callbackval
1459 )
1460
1461 {
1462 VoiceNode *voice;
1463 int handle;
1464 int channels;
1465 int bits;
1466 int length;
1467 riff_header *riff;
1468 format_header *format;
1469 data_header *data;
1470
1471 riff = ( riff_header * )sample;
1472
1473 if ( ( strncmp( riff->RIFF, "RIFF", 4 ) != 0 ) ||
1474 ( strncmp( riff->WAVE, "WAVE", 4 ) != 0 ) ||
1475 ( strncmp( riff->fmt, "fmt ", 4) != 0 ) )
1476 {
1477 GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
1478 return( GUSWAVE_Error );
1479 }
1480
1481 format = ( format_header * )( riff + 1 );
1482 data = ( data_header * )( ( ( char * )format ) + riff->format_size );
1483
1484 if ( format->wFormatTag != 1 )
1485 {
1486 GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
1487 return( GUSWAVE_Error );
1488 }
1489
1490 channels = format->nChannels;
1491 if ( ( channels != 1 ) && ( channels != 2 ) )
1492 {
1493 GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
1494 return( GUSWAVE_Error );
1495 }
1496
1497 bits = format->nBitsPerSample;
1498 if ( ( bits != 8 ) && ( bits != 16 ) )
1499 {
1500 GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
1501 return( GUSWAVE_Error );
1502 }
1503
1504 if ( strncmp( data->DATA, "data", 4 ) != 0 )
1505 {
1506 GUSWAVE_SetErrorCode( GUSWAVE_InvalidWAVFile );
1507 return( GUSWAVE_Error );
1508 }
1509
1510 // Request a voice from the voice pool
1511 voice = GUSWAVE_AllocVoice( priority );
1512 if ( voice == NULL )
1513 {
1514 if ( GUS_Debug )
1515 {
1516 DB_printf( "No more voices. Skipping sound.\n" );
1517 }
1518 GUSWAVE_SetErrorCode( GUSWAVE_NoVoices );
1519 return( GUSWAVE_Warning );
1520 }
1521
1522 voice->wavetype = WAV;
1523 voice->bits = bits;
1524 voice->GetSound = GUSWAVE_GetNextWAVBlock;
1525
1526 length = data->size;
1527
1528 voice->Playing = TRUE;
1529 voice->DemandFeed = NULL;
1530 voice->LoopStart = NULL;
1531 voice->LoopCount = 0;
1532 voice->length = min( length, 0x8000 );
1533 voice->BlockLength = length - voice->length;// min( loopend + 1, data->size );
1534 voice->sound = ( char * )( data + 1 );
1535 voice->NextBlock = voice->sound + voice->length;
1536 voice->next = NULL;
1537 voice->prev = NULL;
1538 voice->priority = priority;
1539 voice->callbackval = callbackval;
1540 voice->LoopStart = NULL;// voice->NextBlock + loopstart;
1541 voice->LoopEnd = NULL;//voice->NextBlock + min( loopend, data->size - 1 );
1542 voice->LoopSize = 0;//( voice->LoopEnd - voice->LoopStart ) + 1;
1543 voice->PitchScale = PITCH_GetScale( pitchoffset );
1544 voice->SamplingRate = format->nSamplesPerSec;
1545 voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) >> 16;
1546
1547 handle = GUSWAVE_Play( voice, angle, volume, channels );
1548
1549 return( handle );
1550 }
1551
1552
1553/*---------------------------------------------------------------------
1554 Function: GUSWAVE_StartDemandFeedPlayback
1555
1556 Begins playback of digitized sound.
1557---------------------------------------------------------------------*/
1558
1559int GUSWAVE_StartDemandFeedPlayback
1560 (
1561 void ( *function )( char **ptr, unsigned long *length ),
1562 int channels,
1563 int bits,
1564 int rate,
1565 int pitchoffset,
1566 int angle,
1567 int volume,
1568 int priority,
1569 unsigned long callbackval
1570 )
1571
1572 {
1573 VoiceNode *voice;
1574 int handle;
1575
1576 // Request a voice from the voice pool
1577 voice = GUSWAVE_AllocVoice( priority );
1578 if ( voice == NULL )
1579 {
1580 if ( GUS_Debug )
1581 {
1582 DB_printf( "No more voices. Skipping sound.\n" );
1583 }
1584 GUSWAVE_SetErrorCode( GUSWAVE_NoVoices );
1585 return( GUSWAVE_Warning );
1586 }
1587
1588 voice->wavetype = DemandFeed;
1589 voice->bits = bits;
1590 voice->GetSound = GUSWAVE_GetNextDemandFeedBlock;
1591 voice->Playing = TRUE;
1592 voice->DemandFeed = function;
1593 voice->LoopStart = NULL;
1594 voice->LoopCount = 0;
1595 voice->BlockLength = 0;
1596 voice->length = 256;
1597 voice->sound = ( bits == 8 ) ? GUS_Silence8 : ( char * )GUS_Silence16;
1598 voice->NextBlock = NULL;
1599 voice->next = NULL;
1600 voice->prev = NULL;
1601 voice->priority = priority;
1602 voice->callbackval = callbackval;
1603 voice->PitchScale = PITCH_GetScale( pitchoffset );
1604 voice->SamplingRate = rate;
1605 voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) >> 16;
1606
1607 handle = GUSWAVE_Play( voice, angle, volume, channels );
1608
1609 return( handle );
1610 }
1611
1612
1613/*---------------------------------------------------------------------
1614 Function: GUSWAVE_SetReverseStereo
1615
1616 Set the orientation of the left and right channels.
1617---------------------------------------------------------------------*/
1618
1619void GUSWAVE_SetReverseStereo
1620 (
1621 int setting
1622 )
1623
1624 {
1625 GUSWAVE_SwapLeftRight = setting;
1626 }
1627
1628
1629/*---------------------------------------------------------------------
1630 Function: GUSWAVE_GetReverseStereo
1631
1632 Returns the orientation of the left and right channels.
1633---------------------------------------------------------------------*/
1634
1635int GUSWAVE_GetReverseStereo
1636 (
1637 void
1638 )
1639
1640 {
1641 return( GUSWAVE_SwapLeftRight );
1642 }
1643
1644
1645/*---------------------------------------------------------------------
1646 Function: GUSWAVE_InitVoices
1647
1648 Begins playback of digitized sound.
1649---------------------------------------------------------------------*/
1650
1651static int GUSWAVE_InitVoices
1652 (
1653 void
1654 )
1655
1656 {
1657 int i;
1658
1659 for( i = 0; i < MAX_VOICES; i++ )
1660 {
1661 VoiceStatus[ i ].playing = FALSE;
1662 VoiceStatus[ i ].Voice = NULL;
1663 }
1664
1665 VoicePool.start = NULL;
1666 VoicePool.end = NULL;
1667 VoiceList.start = NULL;
1668 VoiceList.end = NULL;
1669
1670 for( i = 0; i < VOICES; i++ )
1671 {
1672 GUSWAVE_Voices[ i ].num = -1;
1673 GUSWAVE_Voices[ i ].Active = FALSE;
1674 GUSWAVE_Voices[ i ].GF1voice = -1;
1675 GUSWAVE_Voices[ i ].mem = NULL;
1676 }
1677
1678 for( i = 0; i < VOICES; i++ )
1679 {
1680 GUSWAVE_Voices[ i ].num = i;
1681 GUSWAVE_Voices[ i ].Active = FALSE;
1682 GUSWAVE_Voices[ i ].GF1voice = 0;
1683
1684 GUSWAVE_Voices[ i ].mem = gf1_malloc( GF1BSIZE );
1685 if ( GUSWAVE_Voices[ i ].mem == NULL )
1686 {
1687 GUSWAVE_MaxVoices = i;
1688 if ( i < 1 )
1689 {
1690 if ( GUSMIDI_Installed )
1691 {
1692 GUSWAVE_SetErrorCode( GUSWAVE_UltraNoMemMIDI );
1693 }
1694 else
1695 {
1696 GUSWAVE_SetErrorCode( GUSWAVE_UltraNoMem );
1697 }
1698 return( GUSWAVE_Error );
1699 }
1700
1701 break;
1702 }
1703
1704 LL_AddToTail( VoiceNode, &VoicePool, &GUSWAVE_Voices[ i ] );
1705 }
1706
1707 return( GUSWAVE_Ok );
1708 }
1709
1710
1711/*---------------------------------------------------------------------
1712 Function: GUSWAVE_SetCallBack
1713
1714 Set the function to call when a voice stops.
1715---------------------------------------------------------------------*/
1716
1717void GUSWAVE_SetCallBack
1718 (
1719 void ( *function )( unsigned long )
1720 )
1721
1722 {
1723 GUSWAVE_CallBackFunc = function;
1724 }
1725
1726
1727/*---------------------------------------------------------------------
1728 Function: GUSWAVE_Init
1729
1730 Initializes the Gravis Ultrasound for digitized sound playback.
1731---------------------------------------------------------------------*/
1732
1733int GUSWAVE_Init
1734 (
1735 int numvoices
1736 )
1737
1738 {
1739 int status;
1740
1741 if ( GUSWAVE_Installed )
1742 {
1743 GUSWAVE_Shutdown();
1744 }
1745
1746 GUSWAVE_SetErrorCode( GUSWAVE_Ok );
1747
1748 status = GUS_Init();
1749 if ( status != GUS_Ok )
1750 {
1751 GUSWAVE_SetErrorCode( GUSWAVE_GUSError );
1752 return( GUSWAVE_Error );
1753 }
1754
1755 GUS_Debug = USER_CheckParameter( "DEBUGGUS" );
1756
1757 GUSWAVE_MaxVoices = min( numvoices, VOICES );
1758 GUSWAVE_MaxVoices = max( GUSWAVE_MaxVoices, 0 );
1759
1760 status = GUSWAVE_InitVoices();
1761 if ( status != GUSWAVE_Ok )
1762 {
1763 GUS_Shutdown();
1764 return( status );
1765 }
1766
1767 GUSWAVE_SetReverseStereo( FALSE );
1768
1769 GUSWAVE_CallBackFunc = NULL;
1770 GUSWAVE_Installed = TRUE;
1771
1772 return( GUSWAVE_Ok );
1773 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/guswave.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/guswave.h
new file mode 100644
index 0000000000..5d029e46bc
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/guswave.h
@@ -0,0 +1,75 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: GUSWAVE.H
22
23 author: James R. Dose
24 date: March 23, 1994
25
26 Public header for for GUSWAVE.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __GUSWAVE_H
32#define __GUSWAVE_H
33
34#define GUSWAVE_MinVoiceHandle 1
35
36enum GUSWAVE_Errors
37 {
38 GUSWAVE_Warning = -2,
39 GUSWAVE_Error = -1,
40 GUSWAVE_Ok = 0,
41 GUSWAVE_GUSError,
42 GUSWAVE_NotInstalled,
43 GUSWAVE_NoVoices,
44 GUSWAVE_UltraNoMem,
45 GUSWAVE_UltraNoMemMIDI,
46 GUSWAVE_VoiceNotFound,
47 GUSWAVE_InvalidVOCFile,
48 GUSWAVE_InvalidWAVFile
49 };
50
51char *GUSWAVE_ErrorString( int ErrorNumber );
52int GUSWAVE_VoicePlaying( int handle );
53int GUSWAVE_VoicesPlaying( void );
54int GUSWAVE_Kill( int handle );
55int GUSWAVE_KillAllVoices( void );
56int GUSWAVE_SetPitch( int handle, int pitchoffset );
57int GUSWAVE_SetPan3D( int handle, int angle, int distance );
58void GUSWAVE_SetVolume( int volume );
59int GUSWAVE_GetVolume( void );
60int GUSWAVE_VoiceAvailable( int priority );
61int GUSWAVE_PlayVOC( char *sample, int pitchoffset, int angle, int volume,
62 int priority, unsigned long callbackval );
63int GUSWAVE_PlayWAV( char *sample, int pitchoffset, int angle, int volume,
64 int priority, unsigned long callbackval );
65int GUSWAVE_StartDemandFeedPlayback( void ( *function )( char **ptr, unsigned long *length ),
66 int channels, int bits, int rate, int pitchoffset, int angle,
67 int volume, int priority, unsigned long callbackval );
68void GUSWAVE_SetCallBack( void ( *function )( unsigned long ) );
69void GUSWAVE_SetReverseStereo( int setting );
70int GUSWAVE_GetReverseStereo( void );
71int GUSWAVE_Init( int numvoices );
72void GUSWAVE_Shutdown( void );
73#pragma aux GUSWAVE_Shutdown frame;
74
75#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/interrup.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/interrup.h
new file mode 100644
index 0000000000..e8d78b90bd
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/interrup.h
@@ -0,0 +1,50 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: INTERRUP.H
22
23 author: James R. Dose
24 date: March 31, 1994
25
26 Inline functions for disabling and restoring the interrupt flag.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __INTERRUPT_H
32#define __INTERRUPT_H
33
34unsigned long DisableInterrupts( void );
35void RestoreInterrupts( unsigned long flags );
36
37#ifdef PLAT_DOS
38#pragma aux DisableInterrupts = \
39 "pushfd", \
40 "pop eax", \
41 "cli" \
42 modify [ eax ];
43
44#pragma aux RestoreInterrupts = \
45 "push eax", \
46 "popfd" \
47 parm [ eax ];
48#endif
49
50#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/irq.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/irq.c
new file mode 100644
index 0000000000..607abd7821
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/irq.c
@@ -0,0 +1,325 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: IRQ.C
22
23 author: James R. Dose
24 date: August 26, 1994
25
26 Low level routines to set and restore IRQ's through DPMI.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#include <dos.h>
32#include <stdlib.h>
33#include "irq.h"
34
35#define D32RealSeg(P) ( ( ( ( unsigned long )( P ) ) >> 4 ) & 0xFFFF )
36#define D32RealOff(P) ( ( ( unsigned long )( P ) ) & 0xF )
37
38typedef struct
39 {
40 unsigned long drdi;
41 unsigned long drsi;
42 unsigned long drbp;
43 unsigned long drxx;
44 unsigned long drbx;
45 unsigned long drdx;
46 unsigned long drcx;
47 unsigned long drax;
48
49 unsigned short drflags;
50 unsigned short dres;
51 unsigned short drds;
52 unsigned short drfs;
53 unsigned short drgs;
54 unsigned short drip;
55 unsigned short drcs;
56 unsigned short drsp;
57 unsigned short drss;
58 } DPMI_REGS;
59
60static DPMI_REGS rmregs = { 0 };
61static void ( __interrupt __far *IRQ_Callback )( void ) = NULL;
62
63static char *IRQ_RealModeCode = NULL;
64
65static unsigned short IRQ_CallBackSegment;
66static unsigned short IRQ_CallBackOffset;
67static unsigned short IRQ_RealModeSegment;
68static unsigned short IRQ_RealModeOffset;
69static unsigned long IRQ_ProtectedModeOffset;
70static unsigned short IRQ_ProtectedModeSelector;
71
72static union REGS Regs;
73static struct SREGS SegRegs;
74
75static void *D32DosMemAlloc
76 (
77 unsigned long size
78 )
79
80 {
81 // DPMI allocate DOS memory
82 Regs.x.eax = 0x0100;
83
84 // Number of paragraphs requested
85 Regs.x.ebx = ( size + 15 ) >> 4;
86
87 int386( 0x31, &Regs, &Regs );
88
89 if ( Regs.x.cflag != 0 )
90 {
91 // Failed
92 return ( ( unsigned long )0 );
93 }
94
95 return( ( void * )( ( Regs.x.eax & 0xFFFF ) << 4 ) );
96 }
97
98// Intermediary function: DPMI calls this, making it
99// easier to write in C
100// handle 16-bit incoming stack
101
102void fixebp
103 (
104 void
105 );
106
107#pragma aux fixebp = \
108 "mov bx, ss" \
109 "lar ebx, ebx" \
110 "bt ebx, 22" \
111 "jc bigstk" \
112 "movzx esp, sp" \
113 "mov ebp, esp" \
114 "bigstk:" \
115modify exact [ ebx ];
116
117#pragma aux rmcallback parm [];
118
119void rmcallback
120 (
121 unsigned short _far *stkp
122 )
123
124 {
125 // "Pop" the real mode return frame so we
126 // can resume where we left off
127 rmregs.drip = *stkp++;
128 rmregs.drcs = *stkp++;
129
130 rmregs.drsp = FP_OFF(stkp);
131
132 // Call protected-mode handler
133 IRQ_Callback();
134 }
135
136static void _interrupt _cdecl callback_x
137 (
138 // regs pushed in this order by prologue
139
140 int rgs,
141 int rfs,
142 int res,
143 int rds,
144 int rdi,
145 int rsi,
146 int rbp,
147 int rsp,
148 int rbx,
149 int rdx,
150 int rcx,
151 int rax
152 )
153
154 {
155// unsigned short _far *stkp;
156// return;
157
158 fixebp();
159 rmcallback (MK_FP(rds, rsi));
160 }
161
162/*
163static void _interrupt _cdecl callback_x
164 (
165 // regs pushed in this order by prologue
166
167 int rgs,
168 int rfs,
169 int res,
170 int rds,
171 int rdi,
172 int rsi,
173 int rbp,
174 int rsp,
175 int rbx,
176 int rdx,
177 int rcx,
178 int rax
179 )
180
181 {
182 unsigned short _far *stkp;
183
184 fixebp();
185 stkp = MK_FP(rds, rsi);
186
187 // "Pop" the real mode return frame so we
188 // can resume where we left off
189 rmregs.drip = *stkp++;
190 rmregs.drcs = *stkp++;
191
192 rmregs.drsp = FP_OFF(stkp);
193
194 // Call protected-mode handler
195 IRQ_Callback();
196 }
197*/
198
199
200int IRQ_SetVector
201 (
202 int vector,
203 void ( __interrupt __far *function )( void )
204 )
205
206 {
207 void far *fp;
208
209 IRQ_Callback = function;
210
211 // Save the starting real-mode and protected-mode handler addresses
212
213 // DPMI get protected mode vector */
214 Regs.w.ax = 0x0204;
215 Regs.w.bx = vector;
216 int386( 0x31, &Regs, &Regs );
217 IRQ_ProtectedModeSelector = Regs.w.cx;
218 IRQ_ProtectedModeOffset = Regs.x.edx;
219
220 // DPMI get real mode vector
221 Regs.w.ax = 0x0200;
222 Regs.w.bx = vector;
223 int386( 0x31, &Regs, &Regs );
224 IRQ_RealModeSegment = Regs.w.cx;
225 IRQ_RealModeOffset = Regs.w.dx;
226
227 // Set up callback
228 // DPMI allocate real mode callback
229 Regs.w.ax = 0x0303;
230 fp = ( void far * )callback_x;
231 SegRegs.ds = FP_SEG( fp );
232 Regs.x.esi = FP_OFF( fp );
233 fp = ( void _far * )&rmregs;
234 SegRegs.es = FP_SEG( fp );
235 Regs.x.edi = FP_OFF( fp );
236 int386x( 0x31, &Regs, &Regs, &SegRegs );
237
238 IRQ_CallBackSegment = Regs.w.cx;
239 IRQ_CallBackOffset = Regs.w.dx;
240
241 if ( Regs.x.cflag != 0 )
242 {
243 return( IRQ_Error );
244 }
245
246 if ( IRQ_RealModeCode == NULL )
247 {
248 // Allocate 6 bytes of low memory for real mode interrupt handler
249 IRQ_RealModeCode = D32DosMemAlloc( 6 );
250 if ( IRQ_RealModeCode == NULL )
251 {
252 // Free callback
253 Regs.w.ax = 0x304;
254 Regs.w.cx = IRQ_CallBackSegment;
255 Regs.w.dx = IRQ_CallBackOffset;
256 int386x( 0x31, &Regs, &Regs, &SegRegs );
257
258 return( IRQ_Error );
259 }
260 }
261
262 // Poke code (to call callback) into real mode handler
263
264 // CALL FAR PTR (callback)
265 IRQ_RealModeCode[ 0 ] = '\x9A';
266 *( ( unsigned short * )&IRQ_RealModeCode[ 1 ] ) = IRQ_CallBackOffset;
267 *( ( unsigned short * )&IRQ_RealModeCode[ 3 ] ) = IRQ_CallBackSegment;
268
269 // IRET
270 IRQ_RealModeCode[ 5 ] = '\xCF';
271
272 // Install protected mode handler
273 // DPMI set protected mode vector
274 Regs.w.ax = 0x0205;
275 Regs.w.bx = vector;
276 fp = function;
277
278 Regs.w.cx = FP_SEG( fp );
279 Regs.x.edx = FP_OFF( fp );
280 int386( 0x31, &Regs, &Regs );
281
282 // Install callback address as real mode handler
283 // DPMI set real mode vector
284 Regs.w.ax = 0x0201;
285 Regs.w.bx = vector;
286 Regs.w.cx = D32RealSeg( IRQ_RealModeCode );
287 Regs.w.dx = D32RealOff( IRQ_RealModeCode );
288 int386( 0x31, &Regs, &Regs );
289
290 return( IRQ_Ok );
291 }
292
293int IRQ_RestoreVector
294 (
295 int vector
296 )
297
298 {
299 // Restore original interrupt handlers
300 // DPMI set real mode vector
301 Regs.w.ax = 0x0201;
302 Regs.w.bx = vector;
303 Regs.w.cx = IRQ_RealModeSegment;
304 Regs.w.dx = IRQ_RealModeOffset;
305 int386( 0x31, &Regs, &Regs );
306
307 Regs.w.ax = 0x0205;
308 Regs.w.bx = vector;
309 Regs.w.cx = IRQ_ProtectedModeSelector;
310 Regs.x.edx = IRQ_ProtectedModeOffset;
311 int386( 0x31, &Regs, &Regs );
312
313 // Free callback
314 Regs.w.ax = 0x304;
315 Regs.w.cx = IRQ_CallBackSegment;
316 Regs.w.dx = IRQ_CallBackOffset;
317 int386x( 0x31, &Regs, &Regs, &SegRegs );
318
319 if ( Regs.x.cflag )
320 {
321 return( IRQ_Error );
322 }
323
324 return( IRQ_Ok );
325 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/irq.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/irq.h
new file mode 100644
index 0000000000..dc505a1655
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/irq.h
@@ -0,0 +1,54 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: IRQ.H
22
23 author: James R. Dose
24 date: August 8, 1994
25
26 Public header for IRQ.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __IRQ_H
32#define __IRQ_H
33
34enum IRQ_ERRORS
35 {
36 IRQ_Warning = -2,
37 IRQ_Error = -1,
38 IRQ_Ok = 0,
39 };
40
41#define VALID_IRQ( irq ) ( ( ( irq ) >= 0 ) && ( ( irq ) <= 15 ) )
42
43int IRQ_SetVector
44 (
45 int vector,
46 void ( __interrupt *function )( void )
47 );
48int IRQ_RestoreVector
49 (
50 int vector
51 );
52
53
54#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/leetimbr.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/leetimbr.c
new file mode 100644
index 0000000000..13f81633a4
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/leetimbr.c
@@ -0,0 +1,290 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20typedef struct
21 {
22 unsigned char SAVEK[ 2 ];
23 unsigned char Level[ 2 ];
24 unsigned char Env1[ 2 ];
25 unsigned char Env2[ 2 ];
26 unsigned char Wave[ 2 ];
27 unsigned char Feedback;
28 signed char Transpose;
29 signed char Velocity;
30 } TIMBRE;
31
32TIMBRE ADLIB_TimbreBank[ 256 ] =
33 {
34 { { 33, 49 }, { 79, 0 }, { 242, 210 }, { 82, 115 }, { 0, 0 }, 6, 0 },
35 { { 19, 17 }, { 198, 10 }, { 242, 241 }, { 245, 245 }, { 1, 0 }, 0, 0 },
36 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
37 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
38 { { 3, 18 }, { 48, 16 }, { 246, 242 }, { 25, 244 }, { 0, 0 }, 15, 0 },
39 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
40 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
41 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
42 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
43 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
44 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
45 { { 24, 129 }, { 98, 0 }, { 243, 242 }, { 230, 246 }, { 0, 0 }, 0, 0 },
46 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
47 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
48 { { 23, 2 }, { 79, 16 }, { 242, 242 }, { 96, 114 }, { 0, 0 }, 8, 0 },
49 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
50 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
51 { { 178, 176 }, { 192, 134 }, { 159, 148 }, { 6, 15 }, { 1, 1 }, 9, 0 },
52 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
53 { { 178, 176 }, { 192, 128 }, { 159, 148 }, { 6, 15 }, { 1, 1 }, 9, 0 },
54 { { 130, 128 }, { 192, 134 }, { 145, 145 }, { 246, 246 }, { 1, 1 }, 9, 0 },
55 { { 36, 49 }, { 79, 27 }, { 242, 82 }, { 11, 11 }, { 0, 0 }, 14, 0 },
56 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
57 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
58 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
59 { { 35, 33 }, { 72, 0 }, { 149, 132 }, { 25, 25 }, { 1, 0 }, 8, 0 },
60 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
61 { { 19, 49 }, { 150, 128 }, { 254, 242 }, { 33, 148 }, { 0, 0 }, 10, 0 },
62 { { 1, 17 }, { 77, 0 }, { 242, 245 }, { 83, 116 }, { 1, 1 }, 8, 0 },
63 { { 33, 40 }, { 1, 9 }, { 148, 148 }, { 25, 9 }, { 0, 0 }, 6, 0 },
64 { { 33, 40 }, { 1, 19 }, { 148, 148 }, { 25, 9 }, { 0, 0 }, 6, 0 },
65 { { 36, 194 }, { 138, 3 }, { 250, 145 }, { 111, 248 }, { 0, 0 }, 8, 0 },
66 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
67 { { 33, 33 }, { 26, 0 }, { 241, 246 }, { 207, 72 }, { 0, 0 }, 10, 0 },
68 { { 1, 34 }, { 29, 0 }, { 183, 196 }, { 34, 55 }, { 0, 0 }, 14, 0 },
69 { { 49, 34 }, { 30, 0 }, { 242, 241 }, { 239, 104 }, { 0, 0 }, 14, 0 },
70 { { 49, 34 }, { 30, 0 }, { 242, 245 }, { 239, 120 }, { 0, 0 }, 14, 0 },
71 { { 49, 34 }, { 30, 0 }, { 242, 245 }, { 239, 120 }, { 0, 0 }, 14, 0 },
72 { { 17, 49 }, { 5, 9 }, { 249, 241 }, { 37, 52 }, { 0, 0 }, 10, 0 },
73 { { 17, 49 }, { 5, 0 }, { 249, 241 }, { 37, 52 }, { 0, 0 }, 10, 0 },
74 { { 49, 114 }, { 138, 0 }, { 213, 97 }, { 25, 27 }, { 0, 0 }, 12, 0 },
75 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
76 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
77 { { 17, 17 }, { 150, 128 }, { 165, 245 }, { 85, 179 }, { 2, 1 }, 12, 0 },
78 { { 1, 17 }, { 156, 128 }, { 128, 240 }, { 5, 6 }, { 0, 0 }, 0, 0 },
79 { { 17, 17 }, { 150, 128 }, { 165, 245 }, { 85, 179 }, { 2, 1 }, 12, 0 },
80 { { 2, 1 }, { 153, 128 }, { 245, 246 }, { 85, 83 }, { 0, 0 }, 0, 0 },
81 { { 192, 0 }, { 13, 0 }, { 165, 212 }, { 67, 35 }, { 2, 1 }, 0, 0 },
82 { { 33, 32 }, { 88, 0 }, { 194, 97 }, { 227, 22 }, { 1, 3 }, 0, 0 },
83 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
84 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
85 { { 33, 34 }, { 22, 0 }, { 176, 179 }, { 129, 44 }, { 0, 1 }, 12, 0 },
86 { { 49, 114 }, { 91, 131 }, { 244, 138 }, { 21, 5 }, { 0, 0 }, 0, 0 },
87 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
88 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
89 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
90 { { 33, 33 }, { 29, 0 }, { 113, 129 }, { 174, 158 }, { 0, 0 }, 14, 0 },
91 { { 49, 97 }, { 28, 128 }, { 65, 146 }, { 11, 59 }, { 0, 0 }, 14, 0 },
92 { { 49, 241 }, { 28, 0 }, { 65, 146 }, { 11, 27 }, { 0, 0 }, 10, 0 },
93 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
94 { { 33, 33 }, { 155, 0 }, { 97, 127 }, { 106, 10 }, { 0, 0 }, 2, 0 },
95 { { 225, 226 }, { 21, 3 }, { 113, 129 }, { 174, 158 }, { 0, 0 }, 14, 0 },
96 { { 33, 33 }, { 29, 0 }, { 113, 129 }, { 174, 158 }, { 0, 0 }, 14, 0 },
97 { { 33, 33 }, { 77, 0 }, { 84, 166 }, { 60, 28 }, { 0, 0 }, 8, 0 },
98 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
99 { { 33, 50 }, { 79, 0 }, { 113, 82 }, { 83, 76 }, { 0, 0 }, 10, 0 },
100 { { 33, 50 }, { 79, 0 }, { 113, 82 }, { 83, 76 }, { 0, 0 }, 10, 0 },
101 { { 32, 49 }, { 78, 0 }, { 113, 82 }, { 104, 94 }, { 0, 0 }, 10, 0 },
102 { { 33, 33 }, { 75, 0 }, { 170, 143 }, { 22, 10 }, { 1, 0 }, 8, 0 },
103 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
104 { { 50, 97 }, { 154, 130 }, { 81, 162 }, { 27, 59 }, { 0, 0 }, 12, 0 },
105 { { 50, 33 }, { 192, 0 }, { 155, 114 }, { 33, 7 }, { 0, 0 }, 4, 0 },
106 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
107 { { 33, 162 }, { 131, 141 }, { 116, 101 }, { 23, 23 }, { 0, 0 }, 7, 0 },
108 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
109 { { 225, 98 }, { 236, 0 }, { 110, 101 }, { 143, 42 }, { 0, 0 }, 14, 0 },
110 { { 50, 33 }, { 144, 0 }, { 155, 114 }, { 33, 23 }, { 0, 0 }, 4, 0 },
111 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
112 { { 245, 242 }, { 154, 128 }, { 12, 96 }, { 199, 165 }, { 0, 0 }, 13, 0 },
113 { { 98, 161 }, { 147, 0 }, { 119, 118 }, { 7, 7 }, { 0, 0 }, 11, 0 },
114 { { 34, 33 }, { 89, 8 }, { 255, 255 }, { 3, 15 }, { 2, 0 }, 0, 0 },
115 { { 33, 33 }, { 29, 0 }, { 113, 129 }, { 14, 14 }, { 0, 0 }, 14, 0 },
116 { { 34, 33 }, { 70, 128 }, { 134, 100 }, { 85, 24 }, { 0, 0 }, 0, 0 },
117 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
118 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
119 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
120 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
121 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
122 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
123 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
124 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
125 { { 113, 114 }, { 93, 0 }, { 84, 106 }, { 1, 3 }, { 0, 0 }, 0, 0 },
126 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
127 { { 0, 17 }, { 13, 128 }, { 241, 80 }, { 255, 255 }, { 0, 0 }, 6, 0 },
128 { { 33, 97 }, { 137, 3 }, { 17, 66 }, { 51, 37 }, { 0, 0 }, 10, 0 },
129 { { 0, 49 }, { 16, 128 }, { 17, 176 }, { 239, 15 }, { 0, 0 }, 10, 0 },
130 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
131 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
132 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
133 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
134 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
135 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
136 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
137 { { 164, 97 }, { 76, 16 }, { 243, 129 }, { 115, 35 }, { 1, 0 }, 4, 0 },
138 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
139 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
140 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
141 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
142 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
143 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
144 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
145 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
146 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
147 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
148 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
149 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
150 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
151 { { 1, 1 }, { 0, 0 }, { 255, 255 }, { 7, 7 }, { 0, 0 }, 7, 0 },
152 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
153 { { 1, 221 }, { 0, 0 }, { 246, 31 }, { 0, 6 }, { 2, 3 }, 12, 0 },
154 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
155 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
156 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
157 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
158 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
159 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
160 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
161 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
162 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
163 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
164 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
165 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
166 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
167 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
168 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
169 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
170 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
171 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
172 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
173 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
174 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
175 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
176 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
177 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
178 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
179 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
180 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
181 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
182 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
183 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
184 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
185 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
186 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
187 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
188 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
189 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
190 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
191 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
192 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
193 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
194 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
195 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
196 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
197 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 36 },
198 { { 16, 17 }, { 68, 0 }, { 248, 243 }, { 119, 6 }, { 2, 0 }, 8, 36 },
199 { { 3, 15 }, { 0, 0 }, { 251, 245 }, { 43, 11 }, { 2, 0 }, 15, 36 },
200 { { 33, 0 }, { 128, 0 }, { 255, 249 }, { 7, 7 }, { 0, 1 }, 14, 36 },
201 { { 240, 229 }, { 192, 0 }, { 255, 251 }, { 255, 240 }, { 3, 0 }, 14, 48 },
202 { { 33, 0 }, { 128, 0 }, { 255, 248 }, { 10, 25 }, { 0, 1 }, 14, 36 },
203 { { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 48 },
204 { { 12, 18 }, { 0, 0 }, { 246, 251 }, { 8, 71 }, { 0, 2 }, 10, 69 },
205 { { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 52 },
206 { { 14, 0 }, { 64, 8 }, { 118, 119 }, { 79, 24 }, { 0, 2 }, 14, 48 },
207 { { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 55 },
208 { { 2, 5 }, { 3, 10 }, { 180, 151 }, { 4, 247 }, { 0, 0 }, 14, 57 },
209 { { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 58 },
210 { { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 60 },
211 { { 1, 221 }, { 12, 0 }, { 246, 159 }, { 0, 2 }, { 0, 3 }, 12, 62 },
212 { { 1, 0 }, { 0, 0 }, { 250, 242 }, { 124, 4 }, { 0, 0 }, 0, 63 },
213 { { 12, 18 }, { 0, 0 }, { 246, 203 }, { 2, 67 }, { 0, 2 }, 10, 70 },
214 { { 12, 18 }, { 0, 0 }, { 246, 203 }, { 2, 19 }, { 0, 2 }, 10, 70 },
215 { { 14, 7 }, { 6, 68 }, { 248, 244 }, { 66, 228 }, { 3, 3 }, 14, 53 },
216 { { 14, 0 }, { 64, 8 }, { 150, 183 }, { 79, 24 }, { 0, 2 }, 14, 48 },
217 { { 1, 221 }, { 0, 0 }, { 246, 159 }, { 0, 2 }, { 2, 3 }, 12, 84 },
218 { { 2, 9 }, { 27, 0 }, { 245, 246 }, { 118, 214 }, { 2, 0 }, 4, 43 },
219 { { 0, 223 }, { 9, 0 }, { 246, 147 }, { 0, 67 }, { 0, 2 }, 14, 56 },
220 { { 128, 144 }, { 13, 0 }, { 248, 159 }, { 0, 4 }, { 2, 3 }, 14, 24 },
221 { { 12, 18 }, { 0, 0 }, { 246, 203 }, { 2, 67 }, { 0, 2 }, 10, 65 },
222 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
223 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
224 { { 1, 2 }, { 84, 0 }, { 250, 248 }, { 141, 184 }, { 0, 0 }, 6, 48 },
225 { { 1, 2 }, { 84, 0 }, { 250, 248 }, { 141, 184 }, { 0, 0 }, 6, 51 },
226 { { 1, 2 }, { 84, 0 }, { 250, 248 }, { 141, 184 }, { 0, 0 }, 6, 54 },
227 { { 2, 4 }, { 0, 0 }, { 250, 200 }, { 191, 151 }, { 0, 0 }, 11, 42 },
228 { { 2, 4 }, { 0, 0 }, { 250, 200 }, { 191, 151 }, { 0, 0 }, 11, 39 },
229 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
230 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
231 { { 14, 0 }, { 64, 8 }, { 118, 119 }, { 79, 24 }, { 0, 2 }, 14, 64 },
232 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
233 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
234 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
235 { { 128, 17 }, { 0, 0 }, { 255, 111 }, { 6, 22 }, { 3, 0 }, 14, 52 },
236 { { 128, 17 }, { 0, 0 }, { 255, 79 }, { 6, 22 }, { 3, 0 }, 14, 52 },
237 { { 6, 21 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 60 },
238 { { 6, 21 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 66 },
239 { { 6, 21 }, { 63, 0 }, { 0, 247 }, { 244, 245 }, { 0, 0 }, 1, 59 },
240 { { 65, 66 }, { 69, 0 }, { 252, 105 }, { 69, 5 }, { 0, 0 }, 0, 91 },
241 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
242 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
243 { { 23, 2 }, { 79, 16 }, { 242, 242 }, { 96, 114 }, { 0, 0 }, 8, 109 },
244 { { 14, 0 }, { 64, 8 }, { 118, 119 }, { 79, 24 }, { 0, 2 }, 14, 64 },
245 { { 133, 132 }, { 5, 64 }, { 249, 214 }, { 50, 165 }, { 3, 0 }, 14, 79 },
246 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
247 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
248 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
249 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
250 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
251 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
252 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
253 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
254 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
255 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
256 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
257 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
258 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
259 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
260 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
261 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
262 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
263 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
264 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
265 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
266 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
267 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
268 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
269 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
270 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
271 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
272 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
273 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
274 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
275 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
276 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
277 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
278 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
279 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
280 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
281 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
282 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
283 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
284 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
285 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
286 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
287 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
288 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 },
289 { { 33, 17 }, { 17, 0 }, { 163, 196 }, { 67, 34 }, { 2, 0 }, 13, 0 }
290 };
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/linklist.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/linklist.h
new file mode 100644
index 0000000000..a0a581ffe6
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/linklist.h
@@ -0,0 +1,118 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20#ifndef __linklist_h
21#define __linklist_h
22#ifdef __cplusplus
23extern "C" {
24#endif
25
26
27#define NewNode(type) ((type*)SafeMalloc(sizeof(type)))
28
29
30#define LL_CreateNewLinkedList(rootnode,type,next,prev) \
31 { \
32 (rootnode) = NewNode(type); \
33 (rootnode)->prev = (rootnode); \
34 (rootnode)->next = (rootnode); \
35 }
36
37
38
39#define LL_AddNode(rootnode, newnode, next, prev) \
40 { \
41 (newnode)->next = (rootnode); \
42 (newnode)->prev = (rootnode)->prev; \
43 (rootnode)->prev->next = (newnode); \
44 (rootnode)->prev = (newnode); \
45 }
46
47#define LL_TransferList(oldroot,newroot,next,prev) \
48 { \
49 if ((oldroot)->prev != (oldroot)) \
50 { \
51 (oldroot)->prev->next = (newroot); \
52 (oldroot)->next->prev = (newroot)->prev; \
53 (newroot)->prev->next = (oldroot)->next; \
54 (newroot)->prev = (oldroot)->prev; \
55 (oldroot)->next = (oldroot); \
56 (oldroot)->prev = (oldroot); \
57 } \
58 }
59
60#define LL_ReverseList(root,type,next,prev) \
61 { \
62 type *newend,*trav,*tprev; \
63 \
64 newend = (root)->next; \
65 for(trav = (root)->prev; trav != newend; trav = tprev) \
66 { \
67 tprev = trav->prev; \
68 LL_MoveNode(trav,newend,next,prev); \
69 } \
70 }
71
72
73#define LL_RemoveNode(node,next,prev) \
74 { \
75 (node)->prev->next = (node)->next; \
76 (node)->next->prev = (node)->prev; \
77 (node)->next = (node); \
78 (node)->prev = (node); \
79 }
80
81
82#define LL_SortedInsertion(rootnode,insertnode,next,prev,type,sortparm) \
83 { \
84 type *hoya; \
85 \
86 hoya = (rootnode)->next; \
87 while((hoya != (rootnode)) && ((insertnode)->sortparm > hoya->sortparm)) \
88 { \
89 hoya = hoya->next; \
90 } \
91 LL_AddNode(hoya,(insertnode),next,prev); \
92 }
93
94#define LL_MoveNode(node,newroot,next,prev) \
95 { \
96 LL_RemoveNode((node),next,prev); \
97 LL_AddNode((newroot),(node),next,prev); \
98 }
99
100#define LL_ListEmpty(list,next,prev) \
101 ( \
102 ((list)->next == (list)) && \
103 ((list)->prev == (list)) \
104 )
105
106#define LL_Free(list) SafeFree(list)
107#define LL_Reset(list,next,prev) (list)->next = (list)->prev = (list)
108#define LL_New LL_CreateNewLinkedList
109#define LL_Remove LL_RemoveNode
110#define LL_Add LL_AddNode
111#define LL_Empty LL_ListEmpty
112#define LL_Move LL_MoveNode
113
114
115#ifdef __cplusplus
116};
117#endif
118#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/ll_man.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/ll_man.c
new file mode 100644
index 0000000000..56e97da8e9
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/ll_man.c
@@ -0,0 +1,173 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: LL_MAN.C
22
23 author: James R. Dose
24 date: January 1, 1994
25
26 Linked list management routines.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#define LOCKMEMORY
32
33#include <stddef.h>
34#include "ll_man.h"
35
36#ifdef LOCKMEMORY
37#include "dpmi.h"
38#endif
39
40#define OFFSET( structure, offset ) \
41 ( *( ( char ** )&( structure )[ offset ] ) )
42
43
44/**********************************************************************
45
46 Memory locked functions:
47
48**********************************************************************/
49
50
51#define LL_LockStart LL_AddNode
52
53
54void LL_AddNode
55 (
56 char *item,
57 char **head,
58 char **tail,
59 int next,
60 int prev
61 )
62
63 {
64 OFFSET( item, prev ) = NULL;
65 OFFSET( item, next ) = *head;
66
67 if ( *head )
68 {
69 OFFSET( *head, prev ) = item;
70 }
71 else
72 {
73 *tail = item;
74 }
75
76 *head = item;
77 }
78
79void LL_RemoveNode
80 (
81 char *item,
82 char **head,
83 char **tail,
84 int next,
85 int prev
86 )
87
88 {
89 if ( OFFSET( item, prev ) == NULL )
90 {
91 *head = OFFSET( item, next );
92 }
93 else
94 {
95 OFFSET( OFFSET( item, prev ), next ) = OFFSET( item, next );
96 }
97
98 if ( OFFSET( item, next ) == NULL )
99 {
100 *tail = OFFSET( item, prev );
101 }
102 else
103 {
104 OFFSET( OFFSET( item, next ), prev ) = OFFSET( item, prev );
105 }
106
107 OFFSET( item, next ) = NULL;
108 OFFSET( item, prev ) = NULL;
109 }
110
111
112/*---------------------------------------------------------------------
113 Function: LL_LockEnd
114
115 Used for determining the length of the functions to lock in memory.
116---------------------------------------------------------------------*/
117
118static void LL_LockEnd
119 (
120 void
121 )
122
123 {
124 }
125
126
127/*---------------------------------------------------------------------
128 Function: LL_UnlockMemory
129
130 Unlocks all neccessary data.
131---------------------------------------------------------------------*/
132
133void LL_UnlockMemory
134 (
135 void
136 )
137
138 {
139#ifdef LOCKMEMORY
140
141 DPMI_UnlockMemoryRegion( LL_LockStart, LL_LockEnd );
142
143#endif
144 }
145
146
147/*---------------------------------------------------------------------
148 Function: LL_LockMemory
149
150 Locks all neccessary data.
151---------------------------------------------------------------------*/
152
153int LL_LockMemory
154 (
155 void
156 )
157
158 {
159
160#ifdef LOCKMEMORY
161
162 int status;
163
164 status = DPMI_LockMemoryRegion( LL_LockStart, LL_LockEnd );
165 if ( status != DPMI_Ok )
166 {
167 return( LL_Error );
168 }
169
170#endif
171
172 return( LL_Ok );
173 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/ll_man.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/ll_man.h
new file mode 100644
index 0000000000..375b1e1b24
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/ll_man.h
@@ -0,0 +1,76 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: LL_MAN.H
22
23 author: James R. Dose
24 date: February 4, 1994
25
26 Public header for LL_MAN.C. Linked list management routines.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __LL_MAN_H
32#define __LL_MAN_H
33
34enum LL_Errors
35 {
36 LL_Warning = -2,
37 LL_Error = -1,
38 LL_Ok = 0
39 };
40
41typedef struct list
42 {
43 void *start;
44 void *end;
45 } list;
46
47void LL_AddNode( char *node, char **head, char **tail, int next, int prev );
48void LL_RemoveNode( char *node, char **head, char **tail, int next, int prev );
49void LL_UnlockMemory( void );
50int LL_LockMemory( void );
51
52#define LL_AddToHead( type, listhead, node ) \
53 LL_AddNode( ( char * )( node ), \
54 ( char ** )&( ( listhead )->start ), \
55 ( char ** )&( ( listhead )->end ), \
56 ( int )&( ( type * ) 0 )->next, \
57 ( int )&( ( type * ) 0 )->prev )
58
59#define LL_AddToTail( type, listhead, node ) \
60 LL_AddNode( ( char * )( node ), \
61 ( char ** )&( ( listhead )->end ), \
62 ( char ** )&( ( listhead )->start ), \
63 ( int )&( ( type * ) 0 )->prev, \
64 ( int )&( ( type * ) 0 )->next )
65
66#define LL_Remove( type, listhead, node ) \
67 LL_RemoveNode( ( char * )( node ), \
68 ( char ** )&( ( listhead )->start ), \
69 ( char ** )&( ( listhead )->end ), \
70 ( int )&( ( type * ) 0 )->next, \
71 ( int )&( ( type * ) 0 )->prev )
72
73#define LL_NextNode( node ) ( ( node )->next )
74#define LL_PreviousNode( node ) ( ( node )->prev )
75
76#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/memcheck.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/memcheck.h
new file mode 100644
index 0000000000..1b7e4f5102
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/memcheck.h
@@ -0,0 +1,20 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/midi.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/midi.c
new file mode 100644
index 0000000000..d71c5faca2
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/midi.c
@@ -0,0 +1,2265 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: MIDI.C
22
23 author: James R. Dose
24 date: May 25, 1994
25
26 Midi song file playback routines.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#include <stdlib.h>
32#include <time.h>
33#include <dos.h>
34#include <string.h>
35#include "sndcards.h"
36#include "interrup.h"
37#include "dpmi.h"
38#include "standard.h"
39#include "task_man.h"
40#include "ll_man.h"
41#include "usrhooks.h"
42#include "music.h"
43#include "_midi.h"
44#include "midi.h"
45#include "debugio.h"
46
47extern int MUSIC_SoundDevice;
48
49static const int _MIDI_CommandLengths[ NUM_MIDI_CHANNELS ] =
50 {
51 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 2, 0
52 };
53
54static int cdecl ( *_MIDI_RerouteFunctions[ NUM_MIDI_CHANNELS ] )
55 (
56 int event,
57 int c1,
58 int c2
59 ) = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
60 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
61
62static track *_MIDI_TrackPtr = NULL;
63static int _MIDI_TrackMemSize;
64static int _MIDI_NumTracks;
65
66static int _MIDI_SongActive = FALSE;
67static int _MIDI_SongLoaded = FALSE;
68static int _MIDI_Loop = FALSE;
69
70static task *_MIDI_PlayRoutine = NULL;
71
72static int _MIDI_Division;
73static int _MIDI_Tick = 0;
74static int _MIDI_Beat = 1;
75static int _MIDI_Measure = 1;
76static unsigned _MIDI_Time;
77static int _MIDI_BeatsPerMeasure;
78static int _MIDI_TicksPerBeat;
79static int _MIDI_TimeBase;
80static long _MIDI_FPSecondsPerTick;
81static unsigned _MIDI_TotalTime;
82static int _MIDI_TotalTicks;
83static int _MIDI_TotalBeats;
84static int _MIDI_TotalMeasures;
85
86static unsigned long _MIDI_PositionInTicks;
87
88static int _MIDI_Context;
89
90static int _MIDI_ActiveTracks;
91static int _MIDI_TotalVolume = MIDI_MaxVolume;
92
93static int _MIDI_ChannelVolume[ NUM_MIDI_CHANNELS ];
94static int _MIDI_UserChannelVolume[ NUM_MIDI_CHANNELS ] =
95 {
96 256, 256, 256, 256, 256, 256, 256, 256,
97 256, 256, 256, 256, 256, 256, 256, 256
98 };
99
100static midifuncs *_MIDI_Funcs = NULL;
101
102static int Reset = FALSE;
103
104int MIDI_Tempo = 120;
105
106char MIDI_PatchMap[ 128 ];
107
108
109/**********************************************************************
110
111 Memory locked functions:
112
113**********************************************************************/
114
115
116#define MIDI_LockStart _MIDI_ReadNumber
117
118
119/*---------------------------------------------------------------------
120 Function: _MIDI_ReadNumber
121
122 Reads a variable length number from a MIDI track.
123---------------------------------------------------------------------*/
124
125static long _MIDI_ReadNumber
126 (
127 void *from,
128 size_t size
129 )
130
131 {
132 unsigned char *FromPtr;
133 long value;
134
135 if ( size > 4 )
136 {
137 size = 4;
138 }
139
140 FromPtr = ( unsigned char * )from;
141
142 value = 0;
143 while( size-- )
144 {
145 value <<= 8;
146 value += *FromPtr++;
147 }
148
149 return( value );
150 }
151
152
153/*---------------------------------------------------------------------
154 Function: _MIDI_ReadDelta
155
156 Reads a variable length encoded delta delay time from the MIDI data.
157---------------------------------------------------------------------*/
158
159static long _MIDI_ReadDelta
160 (
161 track *ptr
162 )
163
164 {
165 long value;
166 unsigned char c;
167
168 GET_NEXT_EVENT( ptr, value );
169
170 if ( value & 0x80 )
171 {
172 value &= 0x7f;
173 do
174 {
175 GET_NEXT_EVENT( ptr, c );
176 value = ( value << 7 ) + ( c & 0x7f );
177 }
178 while ( c & 0x80 );
179 }
180
181 return( value );
182 }
183
184
185/*---------------------------------------------------------------------
186 Function: _MIDI_ResetTracks
187
188 Sets the track pointers to the beginning of the song.
189---------------------------------------------------------------------*/
190
191static void _MIDI_ResetTracks
192 (
193 void
194 )
195
196 {
197 int i;
198 track *ptr;
199
200 _MIDI_Tick = 0;
201 _MIDI_Beat = 1;
202 _MIDI_Measure = 1;
203 _MIDI_Time = 0;
204 _MIDI_BeatsPerMeasure = 4;
205 _MIDI_TicksPerBeat = _MIDI_Division;
206 _MIDI_TimeBase = 4;
207
208 _MIDI_PositionInTicks = 0;
209 _MIDI_ActiveTracks = 0;
210 _MIDI_Context = 0;
211
212 ptr = _MIDI_TrackPtr;
213 for( i = 0; i < _MIDI_NumTracks; i++ )
214 {
215 ptr->pos = ptr->start;
216 ptr->delay = _MIDI_ReadDelta( ptr );
217 ptr->active = ptr->EMIDI_IncludeTrack;
218 ptr->RunningStatus = 0;
219 ptr->currentcontext = 0;
220 ptr->context[ 0 ].loopstart = ptr->start;
221 ptr->context[ 0 ].loopcount = 0;
222
223 if ( ptr->active )
224 {
225 _MIDI_ActiveTracks++;
226 }
227
228 ptr++;
229 }
230 }
231
232
233/*---------------------------------------------------------------------
234 Function: _MIDI_AdvanceTick
235
236 Increment tick counters.
237---------------------------------------------------------------------*/
238
239static void _MIDI_AdvanceTick
240 (
241 void
242 )
243
244 {
245 _MIDI_PositionInTicks++;
246 _MIDI_Time += _MIDI_FPSecondsPerTick;
247
248 _MIDI_Tick++;
249 while( _MIDI_Tick > _MIDI_TicksPerBeat )
250 {
251 _MIDI_Tick -= _MIDI_TicksPerBeat;
252 _MIDI_Beat++;
253 }
254 while( _MIDI_Beat > _MIDI_BeatsPerMeasure )
255 {
256 _MIDI_Beat -= _MIDI_BeatsPerMeasure;
257 _MIDI_Measure++;
258 }
259 }
260
261
262/*---------------------------------------------------------------------
263 Function: _MIDI_SysEx
264
265 Interpret SysEx Event.
266---------------------------------------------------------------------*/
267
268static void _MIDI_SysEx
269 (
270 track *Track
271 )
272
273 {
274 int length;
275
276 length = _MIDI_ReadDelta( Track );
277 Track->pos += length;
278 }
279
280
281/*---------------------------------------------------------------------
282 Function: _MIDI_MetaEvent
283
284 Interpret Meta Event.
285---------------------------------------------------------------------*/
286
287static void _MIDI_MetaEvent
288 (
289 track *Track
290 )
291
292 {
293 int command;
294 int length;
295 int denominator;
296 long tempo;
297
298 GET_NEXT_EVENT( Track, command );
299 GET_NEXT_EVENT( Track, length );
300
301 switch( command )
302 {
303 case MIDI_END_OF_TRACK :
304 Track->active = FALSE;
305
306 _MIDI_ActiveTracks--;
307 break;
308
309 case MIDI_TEMPO_CHANGE :
310 tempo = 60000000L / _MIDI_ReadNumber( Track->pos, 3 );
311 MIDI_SetTempo( tempo );
312 break;
313
314 case MIDI_TIME_SIGNATURE :
315 if ( ( _MIDI_Tick > 0 ) || ( _MIDI_Beat > 1 ) )
316 {
317 _MIDI_Measure++;
318 }
319
320 _MIDI_Tick = 0;
321 _MIDI_Beat = 1;
322
323 _MIDI_BeatsPerMeasure = (int)*Track->pos;
324 denominator = (int)*( Track->pos + 1 );
325 _MIDI_TimeBase = 1;
326 while( denominator > 0 )
327 {
328 _MIDI_TimeBase += _MIDI_TimeBase;
329 denominator--;
330 }
331 _MIDI_TicksPerBeat = ( _MIDI_Division * 4 ) / _MIDI_TimeBase;
332 break;
333 }
334
335 Track->pos += length;
336 }
337
338
339/*---------------------------------------------------------------------
340 Function: _MIDI_InterpretControllerInfo
341
342 Interprets the MIDI controller info.
343---------------------------------------------------------------------*/
344
345static int _MIDI_InterpretControllerInfo
346 (
347 track *Track,
348 int TimeSet,
349 int channel,
350 int c1,
351 int c2
352 )
353
354 {
355 track *trackptr;
356 int tracknum;
357 int loopcount;
358
359 switch( c1 )
360 {
361 case MIDI_MONO_MODE_ON :
362 Track->pos++;
363 break;
364
365 case MIDI_VOLUME :
366 if ( !Track->EMIDI_VolumeChange )
367 {
368 _MIDI_SetChannelVolume( channel, c2 );
369 }
370 break;
371
372 case EMIDI_INCLUDE_TRACK :
373 case EMIDI_EXCLUDE_TRACK :
374 break;
375
376 case EMIDI_PROGRAM_CHANGE :
377 if ( Track->EMIDI_ProgramChange )
378 {
379 _MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c2 & 0x7f ] );
380 }
381 break;
382
383 case EMIDI_VOLUME_CHANGE :
384 if ( Track->EMIDI_VolumeChange )
385 {
386 _MIDI_SetChannelVolume( channel, c2 );
387 }
388 break;
389
390 case EMIDI_CONTEXT_START :
391 break;
392
393 case EMIDI_CONTEXT_END :
394 if ( ( Track->currentcontext == _MIDI_Context ) ||
395 ( _MIDI_Context < 0 ) ||
396 ( Track->context[ _MIDI_Context ].pos == NULL ) )
397 {
398 break;
399 }
400
401 Track->currentcontext = _MIDI_Context;
402 Track->context[ 0 ].loopstart = Track->context[ _MIDI_Context ].loopstart;
403 Track->context[ 0 ].loopcount = Track->context[ _MIDI_Context ].loopcount;
404 Track->pos = Track->context[ _MIDI_Context ].pos;
405 Track->RunningStatus = Track->context[ _MIDI_Context ].RunningStatus;
406
407 if ( TimeSet )
408 {
409 break;
410 }
411
412 _MIDI_Time = Track->context[ _MIDI_Context ].time;
413 _MIDI_FPSecondsPerTick = Track->context[ _MIDI_Context ].FPSecondsPerTick;
414 _MIDI_Tick = Track->context[ _MIDI_Context ].tick;
415 _MIDI_Beat = Track->context[ _MIDI_Context ].beat;
416 _MIDI_Measure = Track->context[ _MIDI_Context ].measure;
417 _MIDI_BeatsPerMeasure = Track->context[ _MIDI_Context ].BeatsPerMeasure;
418 _MIDI_TicksPerBeat = Track->context[ _MIDI_Context ].TicksPerBeat;
419 _MIDI_TimeBase = Track->context[ _MIDI_Context ].TimeBase;
420 TimeSet = TRUE;
421 break;
422
423 case EMIDI_LOOP_START :
424 case EMIDI_SONG_LOOP_START :
425 if ( c2 == 0 )
426 {
427 loopcount = EMIDI_INFINITE;
428 }
429 else
430 {
431 loopcount = c2;
432 }
433
434 if ( c1 == EMIDI_SONG_LOOP_START )
435 {
436 trackptr = _MIDI_TrackPtr;
437 tracknum = _MIDI_NumTracks;
438 }
439 else
440 {
441 trackptr = Track;
442 tracknum = 1;
443 }
444
445 while( tracknum > 0 )
446 {
447 trackptr->context[ 0 ].loopcount = loopcount;
448 trackptr->context[ 0 ].pos = trackptr->pos;
449 trackptr->context[ 0 ].loopstart = trackptr->pos;
450 trackptr->context[ 0 ].RunningStatus = trackptr->RunningStatus;
451 trackptr->context[ 0 ].active = trackptr->active;
452 trackptr->context[ 0 ].delay = trackptr->delay;
453 trackptr->context[ 0 ].time = _MIDI_Time;
454 trackptr->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick;
455 trackptr->context[ 0 ].tick = _MIDI_Tick;
456 trackptr->context[ 0 ].beat = _MIDI_Beat;
457 trackptr->context[ 0 ].measure = _MIDI_Measure;
458 trackptr->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure;
459 trackptr->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat;
460 trackptr->context[ 0 ].TimeBase = _MIDI_TimeBase;
461 trackptr++;
462 tracknum--;
463 }
464 break;
465
466 case EMIDI_LOOP_END :
467 case EMIDI_SONG_LOOP_END :
468 if ( ( c2 != EMIDI_END_LOOP_VALUE ) ||
469 ( Track->context[ 0 ].loopstart == NULL ) ||
470 ( Track->context[ 0 ].loopcount == 0 ) )
471 {
472 break;
473 }
474
475 if ( c1 == EMIDI_SONG_LOOP_END )
476 {
477 trackptr = _MIDI_TrackPtr;
478 tracknum = _MIDI_NumTracks;
479 _MIDI_ActiveTracks = 0;
480 }
481 else
482 {
483 trackptr = Track;
484 tracknum = 1;
485 _MIDI_ActiveTracks--;
486 }
487
488 while( tracknum > 0 )
489 {
490 if ( trackptr->context[ 0 ].loopcount != EMIDI_INFINITE )
491 {
492 trackptr->context[ 0 ].loopcount--;
493 }
494
495 trackptr->pos = trackptr->context[ 0 ].loopstart;
496 trackptr->RunningStatus = trackptr->context[ 0 ].RunningStatus;
497 trackptr->delay = trackptr->context[ 0 ].delay;
498 trackptr->active = trackptr->context[ 0 ].active;
499 if ( trackptr->active )
500 {
501 _MIDI_ActiveTracks++;
502 }
503
504 if ( !TimeSet )
505 {
506 _MIDI_Time = trackptr->context[ 0 ].time;
507 _MIDI_FPSecondsPerTick = trackptr->context[ 0 ].FPSecondsPerTick;
508 _MIDI_Tick = trackptr->context[ 0 ].tick;
509 _MIDI_Beat = trackptr->context[ 0 ].beat;
510 _MIDI_Measure = trackptr->context[ 0 ].measure;
511 _MIDI_BeatsPerMeasure = trackptr->context[ 0 ].BeatsPerMeasure;
512 _MIDI_TicksPerBeat = trackptr->context[ 0 ].TicksPerBeat;
513 _MIDI_TimeBase = trackptr->context[ 0 ].TimeBase;
514 TimeSet = TRUE;
515 }
516
517 trackptr++;
518 tracknum--;
519 }
520 break;
521
522 default :
523 if ( _MIDI_Funcs->ControlChange )
524 {
525 _MIDI_Funcs->ControlChange( channel, c1, c2 );
526 }
527 }
528
529 return TimeSet;
530 }
531
532
533/*---------------------------------------------------------------------
534 Function: _MIDI_ServiceRoutine
535
536 Task that interperates the MIDI data.
537---------------------------------------------------------------------*/
538// NOTE: We have to use a stack frame here because of a strange bug
539// that occurs with Watcom. This means that we cannot access Task!
540//Turned off to test if it works with Watcom 10a
541//#pragma aux _MIDI_ServiceRoutine frame;
542/*
543static void test
544 (
545 task *Task
546 )
547 {
548 _MIDI_ServiceRoutine( Task );
549 _MIDI_ServiceRoutine( Task );
550 _MIDI_ServiceRoutine( Task );
551 _MIDI_ServiceRoutine( Task );
552 }
553*/
554static void _MIDI_ServiceRoutine
555 (
556 task *Task
557 )
558
559 {
560 int event;
561 int channel;
562 int command;
563 track *Track;
564 int tracknum;
565 int status;
566 int c1;
567 int c2;
568 int TimeSet = FALSE;
569
570 if ( !_MIDI_SongActive )
571 {
572 return;
573 }
574
575 Track = _MIDI_TrackPtr;
576 tracknum = 0;
577 while( tracknum < _MIDI_NumTracks )
578 {
579 while ( ( Track->active ) && ( Track->delay == 0 ) )
580 {
581 GET_NEXT_EVENT( Track, event );
582
583 if ( GET_MIDI_COMMAND( event ) == MIDI_SPECIAL )
584 {
585 switch( event )
586 {
587 case MIDI_SYSEX :
588 case MIDI_SYSEX_CONTINUE :
589 _MIDI_SysEx( Track );
590 break;
591
592 case MIDI_META_EVENT :
593 _MIDI_MetaEvent( Track );
594 break;
595 }
596
597 if ( Track->active )
598 {
599 Track->delay = _MIDI_ReadDelta( Track );
600 }
601
602 continue;
603 }
604
605 if ( event & MIDI_RUNNING_STATUS )
606 {
607 Track->RunningStatus = event;
608 }
609 else
610 {
611 event = Track->RunningStatus;
612 Track->pos--;
613 }
614
615 channel = GET_MIDI_CHANNEL( event );
616 command = GET_MIDI_COMMAND( event );
617
618 if ( _MIDI_CommandLengths[ command ] > 0 )
619 {
620 GET_NEXT_EVENT( Track, c1 );
621 if ( _MIDI_CommandLengths[ command ] > 1 )
622 {
623 GET_NEXT_EVENT( Track, c2 );
624 }
625 }
626
627 if ( _MIDI_RerouteFunctions[ channel ] != NULL )
628 {
629 status = _MIDI_RerouteFunctions[ channel ]( event, c1, c2 );
630
631 if ( status == MIDI_DONT_PLAY )
632 {
633 Track->delay = _MIDI_ReadDelta( Track );
634 continue;
635 }
636 }
637
638 switch ( command )
639 {
640 case MIDI_NOTE_OFF :
641 if ( _MIDI_Funcs->NoteOff )
642 {
643 _MIDI_Funcs->NoteOff( channel, c1, c2 );
644 }
645 break;
646
647 case MIDI_NOTE_ON :
648 if ( _MIDI_Funcs->NoteOn )
649 {
650 _MIDI_Funcs->NoteOn( channel, c1, c2 );
651 }
652 break;
653
654 case MIDI_POLY_AFTER_TCH :
655 if ( _MIDI_Funcs->PolyAftertouch )
656 {
657 _MIDI_Funcs->PolyAftertouch( channel, c1, c2 );
658 }
659 break;
660
661 case MIDI_CONTROL_CHANGE :
662 TimeSet = _MIDI_InterpretControllerInfo( Track, TimeSet,
663 channel, c1, c2 );
664 break;
665
666 case MIDI_PROGRAM_CHANGE :
667 if ( ( _MIDI_Funcs->ProgramChange ) &&
668 ( !Track->EMIDI_ProgramChange ) )
669 {
670 _MIDI_Funcs->ProgramChange( channel, MIDI_PatchMap[ c1 & 0x7f ] );
671 }
672 break;
673
674 case MIDI_AFTER_TOUCH :
675 if ( _MIDI_Funcs->ChannelAftertouch )
676 {
677 _MIDI_Funcs->ChannelAftertouch( channel, c1 );
678 }
679 break;
680
681 case MIDI_PITCH_BEND :
682 if ( _MIDI_Funcs->PitchBend )
683 {
684 _MIDI_Funcs->PitchBend( channel, c1, c2 );
685 }
686 break;
687
688 default :
689 break;
690 }
691
692 Track->delay = _MIDI_ReadDelta( Track );
693 }
694
695 Track->delay--;
696 Track++;
697 tracknum++;
698
699 if ( _MIDI_ActiveTracks == 0 )
700 {
701 _MIDI_ResetTracks();
702 if ( _MIDI_Loop )
703 {
704 tracknum = 0;
705 Track = _MIDI_TrackPtr;
706 }
707 else
708 {
709 _MIDI_SongActive = FALSE;
710 break;
711 }
712 }
713 }
714
715 _MIDI_AdvanceTick();
716 }
717
718
719/*---------------------------------------------------------------------
720 Function: _MIDI_SendControlChange
721
722 Sends a control change to the proper device
723---------------------------------------------------------------------*/
724
725static int _MIDI_SendControlChange
726 (
727 int channel,
728 int c1,
729 int c2
730 )
731
732 {
733 int status;
734
735 if ( _MIDI_RerouteFunctions[ channel ] != NULL )
736 {
737 status = _MIDI_RerouteFunctions[ channel ]( 0xB0 + channel,
738 c1, c2 );
739 if ( status == MIDI_DONT_PLAY )
740 {
741 return( MIDI_Ok );
742 }
743 }
744
745 if ( _MIDI_Funcs == NULL )
746 {
747 return( MIDI_Error );
748 }
749
750 if ( _MIDI_Funcs->ControlChange == NULL )
751 {
752 return( MIDI_Error );
753 }
754
755 _MIDI_Funcs->ControlChange( channel, c1, c2 );
756
757 return( MIDI_Ok );
758 }
759
760
761/*---------------------------------------------------------------------
762 Function: MIDI_RerouteMidiChannel
763
764 Sets callback function to reroute MIDI commands from specified
765 function.
766---------------------------------------------------------------------*/
767
768void MIDI_RerouteMidiChannel
769 (
770 int channel,
771 int cdecl ( *function )( int event, int c1, int c2 )
772 )
773
774 {
775 if ( ( channel >= 1 ) && ( channel <= 16 ) )
776 {
777 _MIDI_RerouteFunctions[ channel - 1 ] = function;
778 }
779 }
780
781
782/*---------------------------------------------------------------------
783 Function: MIDI_AllNotesOff
784
785 Sends all notes off commands on all midi channels.
786---------------------------------------------------------------------*/
787
788int MIDI_AllNotesOff
789 (
790 void
791 )
792
793 {
794 int channel;
795
796 for( channel = 0; channel < NUM_MIDI_CHANNELS; channel++ )
797 {
798 _MIDI_SendControlChange( channel, 0x40, 0 );
799 _MIDI_SendControlChange( channel, MIDI_ALL_NOTES_OFF, 0 );
800 _MIDI_SendControlChange( channel, 0x78, 0 );
801 }
802
803 return( MIDI_Ok );
804 }
805
806
807/*---------------------------------------------------------------------
808 Function: _MIDI_SetChannelVolume
809
810 Sets the volume of the specified midi channel.
811---------------------------------------------------------------------*/
812
813static void _MIDI_SetChannelVolume
814 (
815 int channel,
816 int volume
817 )
818
819 {
820 int status;
821 int remotevolume;
822
823 _MIDI_ChannelVolume[ channel ] = volume;
824
825 if ( _MIDI_RerouteFunctions[ channel ] != NULL )
826 {
827 remotevolume = volume * _MIDI_TotalVolume;
828 remotevolume *= _MIDI_UserChannelVolume[ channel ];
829 remotevolume /= MIDI_MaxVolume;
830 remotevolume >>= 8;
831
832 status = _MIDI_RerouteFunctions[ channel ]( 0xB0 + channel,
833 MIDI_VOLUME, remotevolume );
834 if ( status == MIDI_DONT_PLAY )
835 {
836 return;
837 }
838 }
839
840 if ( _MIDI_Funcs == NULL )
841 {
842 return;
843 }
844
845 if ( _MIDI_Funcs->ControlChange == NULL )
846 {
847 return;
848 }
849
850 // For user volume
851 volume *= _MIDI_UserChannelVolume[ channel ];
852
853 if ( _MIDI_Funcs->SetVolume == NULL )
854 {
855 volume *= _MIDI_TotalVolume;
856 volume /= MIDI_MaxVolume;
857 }
858
859 // For user volume
860 volume >>= 8;
861
862 _MIDI_Funcs->ControlChange( channel, MIDI_VOLUME, volume );
863 }
864
865
866/*---------------------------------------------------------------------
867 Function: MIDI_SetUserChannelVolume
868
869 Sets the volume of the specified midi channel.
870---------------------------------------------------------------------*/
871
872void MIDI_SetUserChannelVolume
873 (
874 int channel,
875 int volume
876 )
877
878 {
879 // Convert channel from 1-16 to 0-15
880 channel--;
881
882 volume = max( 0, volume );
883 volume = min( volume, 256 );
884
885 if ( ( channel >= 0 ) && ( channel < NUM_MIDI_CHANNELS ) )
886 {
887 _MIDI_UserChannelVolume[ channel ] = volume;
888 _MIDI_SetChannelVolume( channel, _MIDI_ChannelVolume[ channel ] );
889 }
890 }
891
892
893/*---------------------------------------------------------------------
894 Function: MIDI_ResetUserChannelVolume
895
896 Sets the volume of the specified midi channel.
897---------------------------------------------------------------------*/
898
899void MIDI_ResetUserChannelVolume
900 (
901 void
902 )
903
904 {
905 int channel;
906
907 for( channel = 0; channel < NUM_MIDI_CHANNELS; channel++ )
908 {
909 _MIDI_UserChannelVolume[ channel ] = 256;
910 }
911
912 _MIDI_SendChannelVolumes();
913 }
914
915
916/*---------------------------------------------------------------------
917 Function: _MIDI_SendChannelVolumes
918
919 Sets the volume on all the midi channels.
920---------------------------------------------------------------------*/
921
922static void _MIDI_SendChannelVolumes
923 (
924 void
925 )
926
927 {
928 int channel;
929
930 for( channel = 0; channel < NUM_MIDI_CHANNELS; channel++ )
931 {
932 _MIDI_SetChannelVolume( channel, _MIDI_ChannelVolume[ channel ] );
933 }
934 }
935
936
937/*---------------------------------------------------------------------
938 Function: MIDI_Reset
939
940 Resets the MIDI device to General Midi defaults.
941---------------------------------------------------------------------*/
942
943int MIDI_Reset
944 (
945 void
946 )
947
948 {
949 int channel;
950 long time;
951 unsigned flags;
952
953 MIDI_AllNotesOff();
954
955 flags = DisableInterrupts();
956 _enable();
957 time = clock() + CLOCKS_PER_SEC/24;
958 while(clock() < time)
959 ;
960
961 RestoreInterrupts( flags );
962
963 for( channel = 0; channel < NUM_MIDI_CHANNELS; channel++ )
964 {
965 _MIDI_SendControlChange( channel, MIDI_RESET_ALL_CONTROLLERS, 0 );
966 _MIDI_SendControlChange( channel, MIDI_RPN_MSB, MIDI_PITCHBEND_MSB );
967 _MIDI_SendControlChange( channel, MIDI_RPN_LSB, MIDI_PITCHBEND_LSB );
968 _MIDI_SendControlChange( channel, MIDI_DATAENTRY_MSB, 2 ); /* Pitch Bend Sensitivity MSB */
969 _MIDI_SendControlChange( channel, MIDI_DATAENTRY_LSB, 0 ); /* Pitch Bend Sensitivity LSB */
970 _MIDI_ChannelVolume[ channel ] = GENMIDI_DefaultVolume;
971 }
972
973 _MIDI_SendChannelVolumes();
974
975 Reset = TRUE;
976
977 return( MIDI_Ok );
978 }
979
980
981/*---------------------------------------------------------------------
982 Function: MIDI_SetVolume
983
984 Sets the total volume of the music.
985---------------------------------------------------------------------*/
986
987int MIDI_SetVolume
988 (
989 int volume
990 )
991
992 {
993 int i;
994
995 if ( _MIDI_Funcs == NULL )
996 {
997 return( MIDI_NullMidiModule );
998 }
999
1000 volume = min( MIDI_MaxVolume, volume );
1001 volume = max( 0, volume );
1002
1003 _MIDI_TotalVolume = volume;
1004
1005 if ( _MIDI_Funcs->SetVolume )
1006 {
1007 _MIDI_Funcs->SetVolume( volume );
1008
1009 for( i = 0; i < NUM_MIDI_CHANNELS; i++ )
1010 {
1011 if ( _MIDI_RerouteFunctions[ i ] != NULL )
1012 {
1013 _MIDI_SetChannelVolume( i, _MIDI_ChannelVolume[ i ] );
1014 }
1015 }
1016 }
1017 else
1018 {
1019 _MIDI_SendChannelVolumes();
1020 }
1021
1022 return( MIDI_Ok );
1023 }
1024
1025
1026/*---------------------------------------------------------------------
1027 Function: MIDI_GetVolume
1028
1029 Returns the total volume of the music.
1030---------------------------------------------------------------------*/
1031
1032int MIDI_GetVolume
1033 (
1034 void
1035 )
1036
1037 {
1038 int volume;
1039
1040 if ( _MIDI_Funcs == NULL )
1041 {
1042 return( MIDI_NullMidiModule );
1043 }
1044
1045 if ( _MIDI_Funcs->GetVolume )
1046 {
1047 volume = _MIDI_Funcs->GetVolume();
1048 }
1049 else
1050 {
1051 volume = _MIDI_TotalVolume;
1052 }
1053
1054 return( volume );
1055 }
1056
1057
1058/*---------------------------------------------------------------------
1059 Function: MIDI_SetContext
1060
1061 Sets the song context.
1062---------------------------------------------------------------------*/
1063
1064void MIDI_SetContext
1065 (
1066 int context
1067 )
1068
1069 {
1070 if ( ( context > 0 ) && ( context < EMIDI_NUM_CONTEXTS ) )
1071 {
1072 _MIDI_Context = context;
1073 }
1074 }
1075
1076
1077/*---------------------------------------------------------------------
1078 Function: MIDI_GetContext
1079
1080 Returns the current song context.
1081---------------------------------------------------------------------*/
1082
1083int MIDI_GetContext
1084 (
1085 void
1086 )
1087
1088 {
1089 return _MIDI_Context;
1090 }
1091
1092
1093/*---------------------------------------------------------------------
1094 Function: MIDI_SetLoopFlag
1095
1096 Sets whether the song should loop when finished or not.
1097---------------------------------------------------------------------*/
1098
1099void MIDI_SetLoopFlag
1100 (
1101 int loopflag
1102 )
1103
1104 {
1105 _MIDI_Loop = loopflag;
1106 }
1107
1108
1109/*---------------------------------------------------------------------
1110 Function: MIDI_ContinueSong
1111
1112 Continues playback of a paused song.
1113---------------------------------------------------------------------*/
1114
1115void MIDI_ContinueSong
1116 (
1117 void
1118 )
1119
1120 {
1121 if ( _MIDI_SongLoaded )
1122 {
1123 _MIDI_SongActive = TRUE;
1124 }
1125 }
1126
1127
1128/*---------------------------------------------------------------------
1129 Function: MIDI_PauseSong
1130
1131 Pauses playback of the current song.
1132---------------------------------------------------------------------*/
1133
1134void MIDI_PauseSong
1135 (
1136 void
1137 )
1138
1139 {
1140 if ( _MIDI_SongLoaded )
1141 {
1142 _MIDI_SongActive = FALSE;
1143 MIDI_AllNotesOff();
1144 }
1145 }
1146
1147
1148/*---------------------------------------------------------------------
1149 Function: MIDI_SongPlaying
1150
1151 Returns whether a song is playing or not.
1152---------------------------------------------------------------------*/
1153
1154int MIDI_SongPlaying
1155 (
1156 void
1157 )
1158
1159 {
1160 return( _MIDI_SongActive );
1161 }
1162
1163
1164/*---------------------------------------------------------------------
1165 Function: MIDI_SetMidiFuncs
1166
1167 Selects the routines that send the MIDI data to the music device.
1168---------------------------------------------------------------------*/
1169
1170void MIDI_SetMidiFuncs
1171 (
1172 midifuncs *funcs
1173 )
1174
1175 {
1176 _MIDI_Funcs = funcs;
1177 }
1178
1179
1180/*---------------------------------------------------------------------
1181 Function: MIDI_StopSong
1182
1183 Stops playback of the currently playing song.
1184---------------------------------------------------------------------*/
1185
1186void MIDI_StopSong
1187 (
1188 void
1189 )
1190
1191 {
1192 if ( _MIDI_SongLoaded )
1193 {
1194 TS_Terminate( _MIDI_PlayRoutine );
1195
1196 _MIDI_PlayRoutine = NULL;
1197 _MIDI_SongActive = FALSE;
1198 _MIDI_SongLoaded = FALSE;
1199
1200 MIDI_Reset();
1201 _MIDI_ResetTracks();
1202
1203 if ( _MIDI_Funcs->ReleasePatches )
1204 {
1205 _MIDI_Funcs->ReleasePatches();
1206 }
1207
1208 DPMI_UnlockMemory( _MIDI_TrackPtr, _MIDI_TrackMemSize );
1209 USRHOOKS_FreeMem( _MIDI_TrackPtr );
1210
1211 _MIDI_TrackPtr = NULL;
1212 _MIDI_NumTracks = 0;
1213 _MIDI_TrackMemSize = 0;
1214
1215 _MIDI_TotalTime = 0;
1216 _MIDI_TotalTicks = 0;
1217 _MIDI_TotalBeats = 0;
1218 _MIDI_TotalMeasures = 0;
1219 }
1220 }
1221
1222
1223/*---------------------------------------------------------------------
1224 Function: MIDI_PlaySong
1225
1226 Begins playback of a MIDI song.
1227---------------------------------------------------------------------*/
1228
1229int MIDI_PlaySong
1230 (
1231 unsigned char *song,
1232 int loopflag
1233 )
1234
1235 {
1236 int numtracks;
1237 int format;
1238 long headersize;
1239 long tracklength;
1240 track *CurrentTrack;
1241 unsigned char *ptr;
1242 int status;
1243
1244 if ( _MIDI_SongLoaded )
1245 {
1246 MIDI_StopSong();
1247 }
1248
1249 _MIDI_Loop = loopflag;
1250
1251 if ( _MIDI_Funcs == NULL )
1252 {
1253 return( MIDI_NullMidiModule );
1254 }
1255
1256 if ( readLE32(song) != MIDI_HEADER_SIGNATURE )
1257 {
1258 return( MIDI_InvalidMidiFile );
1259 }
1260
1261 song += 4;
1262
1263 headersize = _MIDI_ReadNumber( song, 4 );
1264 song += 4;
1265 format = _MIDI_ReadNumber( song, 2 );
1266 _MIDI_NumTracks = _MIDI_ReadNumber( song + 2, 2 );
1267 _MIDI_Division = _MIDI_ReadNumber( song + 4, 2 );
1268 if ( _MIDI_Division < 0 )
1269 {
1270 // If a SMPTE time division is given, just set to 96 so no errors occur
1271 _MIDI_Division = 96;
1272 }
1273
1274 if ( format > MAX_FORMAT )
1275 {
1276 return( MIDI_UnknownMidiFormat );
1277 }
1278
1279 ptr = song + headersize;
1280
1281 if ( _MIDI_NumTracks == 0 )
1282 {
1283 return( MIDI_NoTracks );
1284 }
1285
1286 _MIDI_TrackMemSize = _MIDI_NumTracks * sizeof( track );
1287 status = USRHOOKS_GetMem( &_MIDI_TrackPtr, _MIDI_TrackMemSize );
1288 if ( status != USRHOOKS_Ok )
1289 {
1290 return( MIDI_NoMemory );
1291 }
1292
1293 status = DPMI_LockMemory( _MIDI_TrackPtr, _MIDI_TrackMemSize );
1294 if ( status != DPMI_Ok )
1295 {
1296 USRHOOKS_FreeMem( _MIDI_TrackPtr );
1297
1298 _MIDI_TrackPtr = NULL;
1299 _MIDI_TrackMemSize = 0;
1300 _MIDI_NumTracks = 0;
1301// MIDI_SetErrorCode( MIDI_DPMI_Error );
1302 return( MIDI_Error );
1303 }
1304
1305 CurrentTrack = _MIDI_TrackPtr;
1306 numtracks = _MIDI_NumTracks;
1307 while( numtracks-- )
1308 {
1309 if ( readLE32(ptr) != MIDI_TRACK_SIGNATURE )
1310 {
1311 DPMI_UnlockMemory( _MIDI_TrackPtr, _MIDI_TrackMemSize );
1312
1313 USRHOOKS_FreeMem( _MIDI_TrackPtr );
1314
1315 _MIDI_TrackPtr = NULL;
1316 _MIDI_TrackMemSize = 0;
1317
1318 return( MIDI_InvalidTrack );
1319 }
1320
1321 tracklength = _MIDI_ReadNumber( ptr + 4, 4 );
1322 ptr += 8;
1323 CurrentTrack->start = ptr;
1324 ptr += tracklength;
1325 CurrentTrack++;
1326 }
1327
1328 if ( _MIDI_Funcs->GetVolume != NULL )
1329 {
1330 _MIDI_TotalVolume = _MIDI_Funcs->GetVolume();
1331 }
1332
1333 _MIDI_InitEMIDI();
1334
1335 if ( _MIDI_Funcs->LoadPatch )
1336 {
1337 MIDI_LoadTimbres();
1338 }
1339
1340 _MIDI_ResetTracks();
1341
1342 if ( !Reset )
1343 {
1344 MIDI_Reset();
1345 }
1346
1347 Reset = FALSE;
1348
1349 _MIDI_PlayRoutine = TS_ScheduleTask( _MIDI_ServiceRoutine, 100, 1, NULL );
1350// _MIDI_PlayRoutine = TS_ScheduleTask( test, 100, 1, NULL );
1351 MIDI_SetTempo( 120 );
1352 TS_Dispatch();
1353
1354 _MIDI_SongLoaded = TRUE;
1355 _MIDI_SongActive = TRUE;
1356
1357 return( MIDI_Ok );
1358 }
1359
1360
1361/*---------------------------------------------------------------------
1362 Function: MIDI_SetTempo
1363
1364 Sets the song tempo.
1365---------------------------------------------------------------------*/
1366
1367void MIDI_SetTempo
1368 (
1369 int tempo
1370 )
1371
1372 {
1373 long tickspersecond;
1374
1375 MIDI_Tempo = tempo;
1376 tickspersecond = ( tempo * _MIDI_Division ) / 60;
1377 if ( _MIDI_PlayRoutine != NULL )
1378 {
1379 TS_SetTaskRate( _MIDI_PlayRoutine, tickspersecond );
1380// TS_SetTaskRate( _MIDI_PlayRoutine, tickspersecond / 4 );
1381 }
1382 _MIDI_FPSecondsPerTick = ( 1 << TIME_PRECISION ) / tickspersecond;
1383 }
1384
1385
1386/*---------------------------------------------------------------------
1387 Function: MIDI_GetTempo
1388
1389 Returns the song tempo.
1390---------------------------------------------------------------------*/
1391
1392int MIDI_GetTempo
1393 (
1394 void
1395 )
1396
1397 {
1398 return( MIDI_Tempo );
1399 }
1400
1401
1402/*---------------------------------------------------------------------
1403 Function: _MIDI_ProcessNextTick
1404
1405 Sets the position of the song pointer.
1406---------------------------------------------------------------------*/
1407
1408static int _MIDI_ProcessNextTick
1409 (
1410 void
1411 )
1412
1413 {
1414 int event;
1415 int channel;
1416 int command;
1417 track *Track;
1418 int tracknum;
1419 int status;
1420 int c1;
1421 int c2;
1422 int TimeSet = FALSE;
1423
1424 Track = _MIDI_TrackPtr;
1425 tracknum = 0;
1426 while( ( tracknum < _MIDI_NumTracks ) && ( Track != NULL ) )
1427 {
1428 while ( ( Track->active ) && ( Track->delay == 0 ) )
1429 {
1430 GET_NEXT_EVENT( Track, event );
1431
1432 if ( GET_MIDI_COMMAND( event ) == MIDI_SPECIAL )
1433 {
1434 switch( event )
1435 {
1436 case MIDI_SYSEX :
1437 case MIDI_SYSEX_CONTINUE :
1438 _MIDI_SysEx( Track );
1439 break;
1440
1441 case MIDI_META_EVENT :
1442 _MIDI_MetaEvent( Track );
1443 break;
1444 }
1445
1446 if ( Track->active )
1447 {
1448 Track->delay = _MIDI_ReadDelta( Track );
1449 }
1450
1451 continue;
1452 }
1453
1454 if ( event & MIDI_RUNNING_STATUS )
1455 {
1456 Track->RunningStatus = event;
1457 }
1458 else
1459 {
1460 event = Track->RunningStatus;
1461 Track->pos--;
1462 }
1463
1464 channel = GET_MIDI_CHANNEL( event );
1465 command = GET_MIDI_COMMAND( event );
1466
1467 if ( _MIDI_CommandLengths[ command ] > 0 )
1468 {
1469 GET_NEXT_EVENT( Track, c1 );
1470 if ( _MIDI_CommandLengths[ command ] > 1 )
1471 {
1472 GET_NEXT_EVENT( Track, c2 );
1473 }
1474 }
1475
1476 if ( _MIDI_RerouteFunctions[ channel ] != NULL )
1477 {
1478 status = _MIDI_RerouteFunctions[ channel ]( event, c1, c2 );
1479
1480 if ( status == MIDI_DONT_PLAY )
1481 {
1482 Track->delay = _MIDI_ReadDelta( Track );
1483 continue;
1484 }
1485 }
1486
1487 switch ( command )
1488 {
1489 case MIDI_NOTE_OFF :
1490 break;
1491
1492 case MIDI_NOTE_ON :
1493 break;
1494
1495 case MIDI_POLY_AFTER_TCH :
1496 if ( _MIDI_Funcs->PolyAftertouch )
1497 {
1498 _MIDI_Funcs->PolyAftertouch( channel, c1, c2 );
1499 }
1500 break;
1501
1502 case MIDI_CONTROL_CHANGE :
1503 TimeSet = _MIDI_InterpretControllerInfo( Track, TimeSet,
1504 channel, c1, c2 );
1505 break;
1506
1507 case MIDI_PROGRAM_CHANGE :
1508 if ( ( _MIDI_Funcs->ProgramChange ) &&
1509 ( !Track->EMIDI_ProgramChange ) )
1510 {
1511 _MIDI_Funcs->ProgramChange( channel, c1 );
1512 }
1513 break;
1514
1515 case MIDI_AFTER_TOUCH :
1516 if ( _MIDI_Funcs->ChannelAftertouch )
1517 {
1518 _MIDI_Funcs->ChannelAftertouch( channel, c1 );
1519 }
1520 break;
1521
1522 case MIDI_PITCH_BEND :
1523 if ( _MIDI_Funcs->PitchBend )
1524 {
1525 _MIDI_Funcs->PitchBend( channel, c1, c2 );
1526 }
1527 break;
1528
1529 default :
1530 break;
1531 }
1532
1533 Track->delay = _MIDI_ReadDelta( Track );
1534 }
1535
1536 Track->delay--;
1537 Track++;
1538 tracknum++;
1539
1540 if ( _MIDI_ActiveTracks == 0 )
1541 {
1542 break;
1543 }
1544 }
1545
1546 _MIDI_AdvanceTick();
1547
1548 return( TimeSet );
1549 }
1550
1551
1552/*---------------------------------------------------------------------
1553 Function: MIDI_SetSongTick
1554
1555 Sets the position of the song pointer.
1556---------------------------------------------------------------------*/
1557
1558void MIDI_SetSongTick
1559 (
1560 unsigned long PositionInTicks
1561 )
1562
1563 {
1564 if ( !_MIDI_SongLoaded )
1565 {
1566 return;
1567 }
1568
1569 MIDI_PauseSong();
1570
1571 if ( PositionInTicks < _MIDI_PositionInTicks )
1572 {
1573 _MIDI_ResetTracks();
1574 MIDI_Reset();
1575 }
1576
1577 while( _MIDI_PositionInTicks < PositionInTicks )
1578 {
1579 if ( _MIDI_ProcessNextTick() )
1580 {
1581 break;
1582 }
1583 if ( _MIDI_ActiveTracks == 0 )
1584 {
1585 _MIDI_ResetTracks();
1586 if ( !_MIDI_Loop )
1587 {
1588 return;
1589 }
1590 break;
1591 }
1592 }
1593
1594 MIDI_SetVolume( _MIDI_TotalVolume );
1595 MIDI_ContinueSong();
1596 }
1597
1598
1599/*---------------------------------------------------------------------
1600 Function: MIDI_SetSongTime
1601
1602 Sets the position of the song pointer.
1603---------------------------------------------------------------------*/
1604
1605void MIDI_SetSongTime
1606 (
1607 unsigned long milliseconds
1608 )
1609
1610 {
1611 unsigned long mil;
1612 unsigned long sec;
1613 unsigned long newtime;
1614
1615 if ( !_MIDI_SongLoaded )
1616 {
1617 return;
1618 }
1619
1620 MIDI_PauseSong();
1621
1622 mil = ( ( milliseconds % 1000 ) << TIME_PRECISION ) / 1000;
1623 sec = ( milliseconds / 1000 ) << TIME_PRECISION;
1624 newtime = sec + mil;
1625
1626 if ( newtime < _MIDI_Time )
1627 {
1628 _MIDI_ResetTracks();
1629 MIDI_Reset();
1630 }
1631
1632 while( _MIDI_Time < newtime )
1633 {
1634 if ( _MIDI_ProcessNextTick() )
1635 {
1636 break;
1637 }
1638 if ( _MIDI_ActiveTracks == 0 )
1639 {
1640 _MIDI_ResetTracks();
1641 if ( !_MIDI_Loop )
1642 {
1643 return;
1644 }
1645 break;
1646 }
1647 }
1648
1649 MIDI_SetVolume( _MIDI_TotalVolume );
1650 MIDI_ContinueSong();
1651 }
1652
1653
1654/*---------------------------------------------------------------------
1655 Function: MIDI_SetSongPosition
1656
1657 Sets the position of the song pointer.
1658---------------------------------------------------------------------*/
1659
1660void MIDI_SetSongPosition
1661 (
1662 int measure,
1663 int beat,
1664 int tick
1665 )
1666
1667 {
1668 unsigned long pos;
1669
1670 if ( !_MIDI_SongLoaded )
1671 {
1672 return;
1673 }
1674
1675 MIDI_PauseSong();
1676
1677 pos = RELATIVE_BEAT( measure, beat, tick );
1678
1679 if ( pos < RELATIVE_BEAT( _MIDI_Measure, _MIDI_Beat, _MIDI_Tick ) )
1680 {
1681 _MIDI_ResetTracks();
1682 MIDI_Reset();
1683 }
1684
1685 while( RELATIVE_BEAT( _MIDI_Measure, _MIDI_Beat, _MIDI_Tick ) < pos )
1686 {
1687 if ( _MIDI_ProcessNextTick() )
1688 {
1689 break;
1690 }
1691 if ( _MIDI_ActiveTracks == 0 )
1692 {
1693 _MIDI_ResetTracks();
1694 if ( !_MIDI_Loop )
1695 {
1696 return;
1697 }
1698 break;
1699 }
1700 }
1701
1702 MIDI_SetVolume( _MIDI_TotalVolume );
1703 MIDI_ContinueSong();
1704 }
1705
1706
1707/*---------------------------------------------------------------------
1708 Function: MIDI_GetSongPosition
1709
1710 Returns the position of the song pointer in Measures, beats, ticks.
1711---------------------------------------------------------------------*/
1712
1713void MIDI_GetSongPosition
1714 (
1715 songposition *pos
1716 )
1717
1718 {
1719 unsigned long mil;
1720 unsigned long sec;
1721
1722 mil = ( _MIDI_Time & ( ( 1 << TIME_PRECISION ) - 1 ) ) * 1000;
1723 sec = _MIDI_Time >> TIME_PRECISION;
1724 pos->milliseconds = ( mil >> TIME_PRECISION ) + ( sec * 1000 );
1725 pos->tickposition = _MIDI_PositionInTicks;
1726 pos->measure = _MIDI_Measure;
1727 pos->beat = _MIDI_Beat;
1728 pos->tick = _MIDI_Tick;
1729 }
1730
1731
1732/*---------------------------------------------------------------------
1733 Function: MIDI_GetSongLength
1734
1735 Returns the length of the song.
1736---------------------------------------------------------------------*/
1737
1738void MIDI_GetSongLength
1739 (
1740 songposition *pos
1741 )
1742
1743 {
1744 unsigned long mil;
1745 unsigned long sec;
1746
1747 mil = ( _MIDI_TotalTime & ( ( 1 << TIME_PRECISION ) - 1 ) ) * 1000;
1748 sec = _MIDI_TotalTime >> TIME_PRECISION;
1749
1750 pos->milliseconds = ( mil >> TIME_PRECISION ) + ( sec * 1000 );
1751 pos->measure = _MIDI_TotalMeasures;
1752 pos->beat = _MIDI_TotalBeats;
1753 pos->tick = _MIDI_TotalTicks;
1754 pos->tickposition = 0;
1755 }
1756
1757
1758/*---------------------------------------------------------------------
1759 Function: MIDI_InitEMIDI
1760
1761 Sets up the EMIDI
1762---------------------------------------------------------------------*/
1763
1764static void _MIDI_InitEMIDI
1765 (
1766 void
1767 )
1768
1769 {
1770 int event;
1771 int command;
1772 int channel;
1773 int length;
1774 int IncludeFound;
1775 track *Track;
1776 int tracknum;
1777 int type;
1778 int c1;
1779 int c2;
1780
1781 type = EMIDI_GeneralMIDI;
1782 switch( MUSIC_SoundDevice )
1783 {
1784 case SoundBlaster :
1785 type = EMIDI_SoundBlaster;
1786 break;
1787
1788 case ProAudioSpectrum :
1789 type = EMIDI_ProAudio;
1790 break;
1791
1792 case SoundMan16 :
1793 type = EMIDI_SoundMan16;
1794 break;
1795
1796 case Adlib :
1797 type = EMIDI_Adlib;
1798 break;
1799
1800 case GenMidi :
1801 type = EMIDI_GeneralMIDI;
1802 break;
1803
1804 case SoundCanvas :
1805 type = EMIDI_SoundCanvas;
1806 break;
1807
1808 case Awe32 :
1809 type = EMIDI_AWE32;
1810 break;
1811
1812 case WaveBlaster :
1813 type = EMIDI_WaveBlaster;
1814 break;
1815
1816 case SoundScape :
1817 type = EMIDI_Soundscape;
1818 break;
1819
1820 case UltraSound :
1821 type = EMIDI_Ultrasound;
1822 break;
1823 }
1824
1825 _MIDI_ResetTracks();
1826
1827 _MIDI_TotalTime = 0;
1828 _MIDI_TotalTicks = 0;
1829 _MIDI_TotalBeats = 0;
1830 _MIDI_TotalMeasures = 0;
1831
1832 Track = _MIDI_TrackPtr;
1833 tracknum = 0;
1834 while( ( tracknum < _MIDI_NumTracks ) && ( Track != NULL ) )
1835 {
1836 _MIDI_Tick = 0;
1837 _MIDI_Beat = 1;
1838 _MIDI_Measure = 1;
1839 _MIDI_Time = 0;
1840 _MIDI_BeatsPerMeasure = 4;
1841 _MIDI_TicksPerBeat = _MIDI_Division;
1842 _MIDI_TimeBase = 4;
1843
1844 _MIDI_PositionInTicks = 0;
1845 _MIDI_ActiveTracks = 0;
1846 _MIDI_Context = -1;
1847
1848 Track->RunningStatus = 0;
1849 Track->active = TRUE;
1850
1851 Track->EMIDI_ProgramChange = FALSE;
1852 Track->EMIDI_VolumeChange = FALSE;
1853 Track->EMIDI_IncludeTrack = TRUE;
1854
1855 memset( Track->context, 0, sizeof( Track->context ) );
1856
1857 while( Track->delay > 0 )
1858 {
1859 _MIDI_AdvanceTick();
1860 Track->delay--;
1861 }
1862
1863 IncludeFound = FALSE;
1864 while ( Track->active )
1865 {
1866 GET_NEXT_EVENT( Track, event );
1867
1868 if ( GET_MIDI_COMMAND( event ) == MIDI_SPECIAL )
1869 {
1870 switch( event )
1871 {
1872 case MIDI_SYSEX :
1873 case MIDI_SYSEX_CONTINUE :
1874 _MIDI_SysEx( Track );
1875 break;
1876
1877 case MIDI_META_EVENT :
1878 _MIDI_MetaEvent( Track );
1879 break;
1880 }
1881
1882 if ( Track->active )
1883 {
1884 Track->delay = _MIDI_ReadDelta( Track );
1885 while( Track->delay > 0 )
1886 {
1887 _MIDI_AdvanceTick();
1888 Track->delay--;
1889 }
1890 }
1891
1892 continue;
1893 }
1894
1895 if ( event & MIDI_RUNNING_STATUS )
1896 {
1897 Track->RunningStatus = event;
1898 }
1899 else
1900 {
1901 event = Track->RunningStatus;
1902 Track->pos--;
1903 }
1904
1905 channel = GET_MIDI_CHANNEL( event );
1906 command = GET_MIDI_COMMAND( event );
1907 length = _MIDI_CommandLengths[ command ];
1908
1909 if ( command == MIDI_CONTROL_CHANGE )
1910 {
1911 if ( *Track->pos == MIDI_MONO_MODE_ON )
1912 {
1913 length++;
1914 }
1915 GET_NEXT_EVENT( Track, c1 );
1916 GET_NEXT_EVENT( Track, c2 );
1917 length -= 2;
1918
1919 switch( c1 )
1920 {
1921 case EMIDI_LOOP_START :
1922 case EMIDI_SONG_LOOP_START :
1923 if ( c2 == 0 )
1924 {
1925 Track->context[ 0 ].loopcount = EMIDI_INFINITE;
1926 }
1927 else
1928 {
1929 Track->context[ 0 ].loopcount = c2;
1930 }
1931
1932 Track->context[ 0 ].pos = Track->pos;
1933 Track->context[ 0 ].loopstart = Track->pos;
1934 Track->context[ 0 ].RunningStatus = Track->RunningStatus;
1935 Track->context[ 0 ].time = _MIDI_Time;
1936 Track->context[ 0 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick;
1937 Track->context[ 0 ].tick = _MIDI_Tick;
1938 Track->context[ 0 ].beat = _MIDI_Beat;
1939 Track->context[ 0 ].measure = _MIDI_Measure;
1940 Track->context[ 0 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure;
1941 Track->context[ 0 ].TicksPerBeat = _MIDI_TicksPerBeat;
1942 Track->context[ 0 ].TimeBase = _MIDI_TimeBase;
1943 break;
1944
1945 case EMIDI_LOOP_END :
1946 case EMIDI_SONG_LOOP_END :
1947 if ( c2 == EMIDI_END_LOOP_VALUE )
1948 {
1949 Track->context[ 0 ].loopstart = NULL;
1950 Track->context[ 0 ].loopcount = 0;
1951 }
1952 break;
1953
1954 case EMIDI_INCLUDE_TRACK :
1955 if ( EMIDI_AffectsCurrentCard( c2, type ) )
1956 {
1957 //printf( "Include track %d on card %d\n", tracknum, c2 );
1958 IncludeFound = TRUE;
1959 Track->EMIDI_IncludeTrack = TRUE;
1960 }
1961 else if ( !IncludeFound )
1962 {
1963 //printf( "Track excluded %d on card %d\n", tracknum, c2 );
1964 IncludeFound = TRUE;
1965 Track->EMIDI_IncludeTrack = FALSE;
1966 }
1967 break;
1968
1969 case EMIDI_EXCLUDE_TRACK :
1970 if ( EMIDI_AffectsCurrentCard( c2, type ) )
1971 {
1972 //printf( "Exclude track %d on card %d\n", tracknum, c2 );
1973 Track->EMIDI_IncludeTrack = FALSE;
1974 }
1975 break;
1976
1977 case EMIDI_PROGRAM_CHANGE :
1978 if ( !Track->EMIDI_ProgramChange )
1979 //printf( "Program change on track %d\n", tracknum );
1980 Track->EMIDI_ProgramChange = TRUE;
1981 break;
1982
1983 case EMIDI_VOLUME_CHANGE :
1984 if ( !Track->EMIDI_VolumeChange )
1985 //printf( "Volume change on track %d\n", tracknum );
1986 Track->EMIDI_VolumeChange = TRUE;
1987 break;
1988
1989 case EMIDI_CONTEXT_START :
1990 if ( ( c2 > 0 ) && ( c2 < EMIDI_NUM_CONTEXTS ) )
1991 {
1992 Track->context[ c2 ].pos = Track->pos;
1993 Track->context[ c2 ].loopstart = Track->context[ 0 ].loopstart;
1994 Track->context[ c2 ].loopcount = Track->context[ 0 ].loopcount;
1995 Track->context[ c2 ].RunningStatus = Track->RunningStatus;
1996 Track->context[ c2 ].time = _MIDI_Time;
1997 Track->context[ c2 ].FPSecondsPerTick = _MIDI_FPSecondsPerTick;
1998 Track->context[ c2 ].tick = _MIDI_Tick;
1999 Track->context[ c2 ].beat = _MIDI_Beat;
2000 Track->context[ c2 ].measure = _MIDI_Measure;
2001 Track->context[ c2 ].BeatsPerMeasure = _MIDI_BeatsPerMeasure;
2002 Track->context[ c2 ].TicksPerBeat = _MIDI_TicksPerBeat;
2003 Track->context[ c2 ].TimeBase = _MIDI_TimeBase;
2004 }
2005 break;
2006
2007 case EMIDI_CONTEXT_END :
2008 break;
2009 }
2010 }
2011
2012 Track->pos += length;
2013 Track->delay = _MIDI_ReadDelta( Track );
2014
2015 while( Track->delay > 0 )
2016 {
2017 _MIDI_AdvanceTick();
2018 Track->delay--;
2019 }
2020 }
2021
2022 _MIDI_TotalTime = max( _MIDI_TotalTime, _MIDI_Time );
2023 if ( RELATIVE_BEAT( _MIDI_Measure, _MIDI_Beat, _MIDI_Tick ) >
2024 RELATIVE_BEAT( _MIDI_TotalMeasures, _MIDI_TotalBeats,
2025 _MIDI_TotalTicks ) )
2026 {
2027 _MIDI_TotalTicks = _MIDI_Tick;
2028 _MIDI_TotalBeats = _MIDI_Beat;
2029 _MIDI_TotalMeasures = _MIDI_Measure;
2030 }
2031
2032 Track++;
2033 tracknum++;
2034 }
2035
2036 _MIDI_ResetTracks();
2037 }
2038
2039
2040/*---------------------------------------------------------------------
2041 Function: MIDI_LoadTimbres
2042
2043 Preloads the timbres on cards that use patch-caching.
2044---------------------------------------------------------------------*/
2045
2046void MIDI_LoadTimbres
2047 (
2048 void
2049 )
2050
2051 {
2052 int event;
2053 int command;
2054 int channel;
2055 int length;
2056 int Finished;
2057 track *Track;
2058 int tracknum;
2059
2060 Track = _MIDI_TrackPtr;
2061 tracknum = 0;
2062 while( ( tracknum < _MIDI_NumTracks ) && ( Track != NULL ) )
2063 {
2064 Finished = FALSE;
2065 while ( !Finished )
2066 {
2067 GET_NEXT_EVENT( Track, event );
2068
2069 if ( GET_MIDI_COMMAND( event ) == MIDI_SPECIAL )
2070 {
2071 switch( event )
2072 {
2073 case MIDI_SYSEX :
2074 case MIDI_SYSEX_CONTINUE :
2075 length = _MIDI_ReadDelta( Track );
2076 Track->pos += length;
2077 break;
2078
2079 case MIDI_META_EVENT :
2080 GET_NEXT_EVENT( Track, command );
2081 GET_NEXT_EVENT( Track, length );
2082
2083 if ( command == MIDI_END_OF_TRACK )
2084 {
2085 Finished = TRUE;
2086 }
2087
2088 Track->pos += length;
2089 break;
2090 }
2091
2092 if ( !Finished )
2093 {
2094 _MIDI_ReadDelta( Track );
2095 }
2096
2097 continue;
2098 }
2099
2100 if ( event & MIDI_RUNNING_STATUS )
2101 {
2102 Track->RunningStatus = event;
2103 }
2104 else
2105 {
2106 event = Track->RunningStatus;
2107 Track->pos--;
2108 }
2109
2110 channel = GET_MIDI_CHANNEL( event );
2111 command = GET_MIDI_COMMAND( event );
2112 length = _MIDI_CommandLengths[ command ];
2113
2114 if ( command == MIDI_CONTROL_CHANGE )
2115 {
2116 if ( *Track->pos == MIDI_MONO_MODE_ON )
2117 {
2118 length++;
2119 }
2120
2121 if ( *Track->pos == EMIDI_PROGRAM_CHANGE )
2122 {
2123 _MIDI_Funcs->LoadPatch( *( Track->pos + 1 ) );
2124 }
2125 }
2126
2127 if ( channel == MIDI_RHYTHM_CHANNEL )
2128 {
2129 if ( command == MIDI_NOTE_ON )
2130 {
2131 _MIDI_Funcs->LoadPatch( 128 + *Track->pos );
2132 }
2133 }
2134 else
2135 {
2136 if ( command == MIDI_PROGRAM_CHANGE )
2137 {
2138 _MIDI_Funcs->LoadPatch( *Track->pos );
2139 }
2140 }
2141 Track->pos += length;
2142 _MIDI_ReadDelta( Track );
2143 }
2144 Track++;
2145 tracknum++;
2146 }
2147
2148 _MIDI_ResetTracks();
2149 }
2150
2151
2152/*---------------------------------------------------------------------
2153 Function: MIDI_LockEnd
2154
2155 Used for determining the length of the functions to lock in memory.
2156---------------------------------------------------------------------*/
2157
2158static void MIDI_LockEnd
2159 (
2160 void
2161 )
2162
2163 {
2164 }
2165
2166
2167/*---------------------------------------------------------------------
2168 Function: MIDI_UnlockMemory
2169
2170 Unlocks all neccessary data.
2171---------------------------------------------------------------------*/
2172
2173void MIDI_UnlockMemory
2174 (
2175 void
2176 )
2177
2178 {
2179 DPMI_UnlockMemoryRegion( MIDI_LockStart, MIDI_LockEnd );
2180 DPMI_UnlockMemory( ( void * )&_MIDI_CommandLengths[ 0 ],
2181 sizeof( _MIDI_CommandLengths ) );
2182 DPMI_Unlock( _MIDI_TrackPtr );
2183 DPMI_Unlock( _MIDI_NumTracks );
2184 DPMI_Unlock( _MIDI_SongActive );
2185 DPMI_Unlock( _MIDI_SongLoaded );
2186 DPMI_Unlock( _MIDI_Loop );
2187 DPMI_Unlock( _MIDI_PlayRoutine );
2188 DPMI_Unlock( _MIDI_Division );
2189 DPMI_Unlock( _MIDI_ActiveTracks );
2190 DPMI_Unlock( _MIDI_TotalVolume );
2191 DPMI_Unlock( _MIDI_ChannelVolume );
2192 DPMI_Unlock( _MIDI_Funcs );
2193 DPMI_Unlock( _MIDI_PositionInTicks );
2194 DPMI_Unlock( _MIDI_Division );
2195 DPMI_Unlock( _MIDI_Tick );
2196 DPMI_Unlock( _MIDI_Beat );
2197 DPMI_Unlock( _MIDI_Measure );
2198 DPMI_Unlock( _MIDI_Time );
2199 DPMI_Unlock( _MIDI_BeatsPerMeasure );
2200 DPMI_Unlock( _MIDI_TicksPerBeat );
2201 DPMI_Unlock( _MIDI_TimeBase );
2202 DPMI_Unlock( _MIDI_FPSecondsPerTick );
2203 DPMI_Unlock( _MIDI_Context );
2204 DPMI_Unlock( _MIDI_TotalTime );
2205 DPMI_Unlock( _MIDI_TotalTicks );
2206 DPMI_Unlock( _MIDI_TotalBeats );
2207 DPMI_Unlock( _MIDI_TotalMeasures );
2208 DPMI_Unlock( MIDI_Tempo );
2209 }
2210
2211
2212/*---------------------------------------------------------------------
2213 Function: MIDI_LockMemory
2214
2215 Locks all neccessary data.
2216---------------------------------------------------------------------*/
2217
2218int MIDI_LockMemory
2219 (
2220 void
2221 )
2222
2223 {
2224 int status;
2225
2226 status = DPMI_LockMemoryRegion( MIDI_LockStart, MIDI_LockEnd );
2227 status |= DPMI_LockMemory( ( void * )&_MIDI_CommandLengths[ 0 ],
2228 sizeof( _MIDI_CommandLengths ) );
2229 status |= DPMI_Lock( _MIDI_TrackPtr );
2230 status |= DPMI_Lock( _MIDI_NumTracks );
2231 status |= DPMI_Lock( _MIDI_SongActive );
2232 status |= DPMI_Lock( _MIDI_SongLoaded );
2233 status |= DPMI_Lock( _MIDI_Loop );
2234 status |= DPMI_Lock( _MIDI_PlayRoutine );
2235 status |= DPMI_Lock( _MIDI_Division );
2236 status |= DPMI_Lock( _MIDI_ActiveTracks );
2237 status |= DPMI_Lock( _MIDI_TotalVolume );
2238 status |= DPMI_Lock( _MIDI_ChannelVolume );
2239 status |= DPMI_Lock( _MIDI_Funcs );
2240 status |= DPMI_Lock( _MIDI_PositionInTicks );
2241 status |= DPMI_Lock( _MIDI_Division );
2242 status |= DPMI_Lock( _MIDI_Tick );
2243 status |= DPMI_Lock( _MIDI_Beat );
2244 status |= DPMI_Lock( _MIDI_Measure );
2245 status |= DPMI_Lock( _MIDI_Time );
2246 status |= DPMI_Lock( _MIDI_BeatsPerMeasure );
2247 status |= DPMI_Lock( _MIDI_TicksPerBeat );
2248 status |= DPMI_Lock( _MIDI_TimeBase );
2249 status |= DPMI_Lock( _MIDI_FPSecondsPerTick );
2250 status |= DPMI_Lock( _MIDI_Context );
2251 status |= DPMI_Lock( _MIDI_TotalTime );
2252 status |= DPMI_Lock( _MIDI_TotalTicks );
2253 status |= DPMI_Lock( _MIDI_TotalBeats );
2254 status |= DPMI_Lock( _MIDI_TotalMeasures );
2255 status |= DPMI_Lock( MIDI_Tempo );
2256
2257 if ( status != DPMI_Ok )
2258 {
2259 MIDI_UnlockMemory();
2260// MIDI_SetErrorCode( MIDI_DPMI_Error );
2261 return( MIDI_Error );
2262 }
2263
2264 return( MIDI_Ok );
2265 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/midi.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/midi.h
new file mode 100644
index 0000000000..7de1e2e1d1
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/midi.h
@@ -0,0 +1,98 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: MIDI.H
22
23 author: James R. Dose
24 date: May 25, 1994
25
26 Public header for MIDI.C. Midi song file playback routines.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __MIDI_H
32#define __MIDI_H
33
34enum MIDI_Errors
35 {
36 MIDI_Warning = -2,
37 MIDI_Error = -1,
38 MIDI_Ok = 0,
39 MIDI_NullMidiModule,
40 MIDI_InvalidMidiFile,
41 MIDI_UnknownMidiFormat,
42 MIDI_NoTracks,
43 MIDI_InvalidTrack,
44 MIDI_NoMemory,
45 MIDI_DPMI_Error
46 };
47
48
49#define MIDI_PASS_THROUGH 1
50#define MIDI_DONT_PLAY 0
51
52#define MIDI_MaxVolume 255
53
54extern char MIDI_PatchMap[ 128 ];
55
56typedef struct
57 {
58 void ( *NoteOff )( int channel, int key, int velocity );
59 void ( *NoteOn )( int channel, int key, int velocity );
60 void ( *PolyAftertouch )( int channel, int key, int pressure );
61 void ( *ControlChange )( int channel, int number, int value );
62 void ( *ProgramChange )( int channel, int program );
63 void ( *ChannelAftertouch )( int channel, int pressure );
64 void ( *PitchBend )( int channel, int lsb, int msb );
65 void ( *ReleasePatches )( void );
66 void ( *LoadPatch )( int number );
67 void ( *SetVolume )( int volume );
68 int ( *GetVolume )( void );
69 } midifuncs;
70
71void MIDI_RerouteMidiChannel( int channel, int cdecl ( *function )( int event, int c1, int c2 ) );
72int MIDI_AllNotesOff( void );
73void MIDI_SetUserChannelVolume( int channel, int volume );
74void MIDI_ResetUserChannelVolume( void );
75int MIDI_Reset( void );
76int MIDI_SetVolume( int volume );
77int MIDI_GetVolume( void );
78void MIDI_SetMidiFuncs( midifuncs *funcs );
79void MIDI_SetContext( int context );
80int MIDI_GetContext( void );
81void MIDI_SetLoopFlag( int loopflag );
82void MIDI_ContinueSong( void );
83void MIDI_PauseSong( void );
84int MIDI_SongPlaying( void );
85void MIDI_StopSong( void );
86int MIDI_PlaySong( unsigned char *song, int loopflag );
87void MIDI_SetTempo( int tempo );
88int MIDI_GetTempo( void );
89void MIDI_SetSongTick( unsigned long PositionInTicks );
90void MIDI_SetSongTime( unsigned long milliseconds );
91void MIDI_SetSongPosition( int measure, int beat, int tick );
92void MIDI_GetSongPosition( songposition *pos );
93void MIDI_GetSongLength( songposition *pos );
94void MIDI_LoadTimbres( void );
95void MIDI_UnlockMemory( void );
96int MIDI_LockMemory( void );
97
98#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mpu401.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mpu401.c
new file mode 100644
index 0000000000..e812b70e3c
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mpu401.c
@@ -0,0 +1,451 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: MPU401.C
22
23 author: James R. Dose
24 date: January 1, 1994
25
26 Low level routines to support sending of MIDI data to MPU401
27 compatible MIDI interfaces.
28
29 (c) Copyright 1994 James R. Dose. All Rights Reserved.
30**********************************************************************/
31
32#include <conio.h>
33#include <dos.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include "dpmi.h"
37#include "user.h"
38#include "mpu401.h"
39
40#define MIDI_NOTE_OFF 0x80
41#define MIDI_NOTE_ON 0x90
42#define MIDI_POLY_AFTER_TCH 0xA0
43#define MIDI_CONTROL_CHANGE 0xB0
44#define MIDI_PROGRAM_CHANGE 0xC0
45#define MIDI_AFTER_TOUCH 0xD0
46#define MIDI_PITCH_BEND 0xE0
47#define MIDI_META_EVENT 0xFF
48#define MIDI_END_OF_TRACK 0x2F
49#define MIDI_TEMPO_CHANGE 0x51
50#define MIDI_MONO_MODE_ON 0x7E
51#define MIDI_ALL_NOTES_OFF 0x7B
52
53int MPU_BaseAddr = MPU_DefaultAddress;
54
55//unsigned MPU_Delay = 500;
56//unsigned MPU_Delay = 5000;
57unsigned MPU_Delay = 0x5000;
58
59
60/**********************************************************************
61
62 Memory locked functions:
63
64**********************************************************************/
65
66
67#define MPU_LockStart MPU_SendMidi
68
69
70/*---------------------------------------------------------------------
71 Function: MPU_SendMidi
72
73 Sends a byte of MIDI data to the music device.
74---------------------------------------------------------------------*/
75
76void MPU_SendMidi
77 (
78 int data
79 )
80
81 {
82 int port = MPU_BaseAddr + 1;
83 unsigned count;
84
85 count = MPU_Delay;
86 while( count > 0 )
87 {
88 // check if status port says we're ready for write
89 if ( !( inp( port ) & MPU_ReadyToWrite ) )
90 {
91 break;
92 }
93
94 count--;
95 }
96
97 port--;
98
99 // Send the midi data
100 outp( port, data );
101 }
102
103
104/*---------------------------------------------------------------------
105 Function: MPU_NoteOff
106
107 Sends a full MIDI note off event out to the music device.
108---------------------------------------------------------------------*/
109
110void MPU_NoteOff
111 (
112 int channel,
113 int key,
114 int velocity
115 )
116
117 {
118 MPU_SendMidi( MIDI_NOTE_OFF | channel );
119 MPU_SendMidi( key );
120 MPU_SendMidi( velocity );
121 }
122
123
124/*---------------------------------------------------------------------
125 Function: MPU_NoteOn
126
127 Sends a full MIDI note on event out to the music device.
128---------------------------------------------------------------------*/
129
130void MPU_NoteOn
131 (
132 int channel,
133 int key,
134 int velocity
135 )
136
137 {
138 MPU_SendMidi( MIDI_NOTE_ON | channel );
139 MPU_SendMidi( key );
140 MPU_SendMidi( velocity );
141 }
142
143
144/*---------------------------------------------------------------------
145 Function: MPU_PolyAftertouch
146
147 Sends a full MIDI polyphonic aftertouch event out to the music device.
148---------------------------------------------------------------------*/
149
150void MPU_PolyAftertouch
151 (
152 int channel,
153 int key,
154 int pressure
155 )
156
157 {
158 MPU_SendMidi( MIDI_POLY_AFTER_TCH | channel );
159 MPU_SendMidi( key );
160 MPU_SendMidi( pressure );
161 }
162
163
164/*---------------------------------------------------------------------
165 Function: MPU_ControlChange
166
167 Sends a full MIDI control change event out to the music device.
168---------------------------------------------------------------------*/
169
170void MPU_ControlChange
171 (
172 int channel,
173 int number,
174 int value
175 )
176
177 {
178 MPU_SendMidi( MIDI_CONTROL_CHANGE | channel );
179 MPU_SendMidi( number );
180 MPU_SendMidi( value );
181 }
182
183
184/*---------------------------------------------------------------------
185 Function: MPU_ProgramChange
186
187 Sends a full MIDI program change event out to the music device.
188---------------------------------------------------------------------*/
189
190void MPU_ProgramChange
191 (
192 int channel,
193 int program
194 )
195
196 {
197 MPU_SendMidi( MIDI_PROGRAM_CHANGE | channel );
198 MPU_SendMidi( program );
199 }
200
201
202/*---------------------------------------------------------------------
203 Function: MPU_ChannelAftertouch
204
205 Sends a full MIDI channel aftertouch event out to the music device.
206---------------------------------------------------------------------*/
207
208void MPU_ChannelAftertouch
209 (
210 int channel,
211 int pressure
212 )
213
214 {
215 MPU_SendMidi( MIDI_AFTER_TOUCH | channel );
216 MPU_SendMidi( pressure );
217 }
218
219
220/*---------------------------------------------------------------------
221 Function: MPU_PitchBend
222
223 Sends a full MIDI pitch bend event out to the music device.
224---------------------------------------------------------------------*/
225
226void MPU_PitchBend
227 (
228 int channel,
229 int lsb,
230 int msb
231 )
232
233 {
234 MPU_SendMidi( MIDI_PITCH_BEND | channel );
235 MPU_SendMidi( lsb );
236 MPU_SendMidi( msb );
237 }
238
239
240/*---------------------------------------------------------------------
241 Function: MPU_SendCommand
242
243 Sends a command to the MPU401 card.
244---------------------------------------------------------------------*/
245
246void MPU_SendCommand
247 (
248 int data
249 )
250
251 {
252 int port = MPU_BaseAddr + 1;
253 unsigned count;
254
255 count = 0xffff;
256 while( count > 0 )
257 {
258 // check if status port says we're ready for write
259 if ( !( inp( port ) & MPU_ReadyToWrite ) )
260 {
261 break;
262 }
263 count--;
264 }
265
266 outp( port, data );
267 }
268
269
270/*---------------------------------------------------------------------
271 Function: MPU_Reset
272
273 Resets the MPU401 card.
274---------------------------------------------------------------------*/
275
276int MPU_Reset
277 (
278 void
279 )
280
281 {
282 int port = MPU_BaseAddr + 1;
283 unsigned count;
284
285 // Output "Reset" command via Command port
286 MPU_SendCommand( MPU_CmdReset );
287
288 // Wait for status port to be ready for read
289 count = 0xffff;
290 while( count > 0 )
291 {
292 if ( !( inp( port ) & MPU_ReadyToRead ) )
293 {
294 port--;
295
296 // Check for a successful reset
297 if ( inp( port ) == MPU_CmdAcknowledge )
298 {
299 return( MPU_Ok );
300 }
301
302 port++;
303 }
304 count--;
305 }
306
307 // Failed to reset : MPU-401 not detected
308 return( MPU_NotFound );
309 }
310
311
312/*---------------------------------------------------------------------
313 Function: MPU_EnterUART
314
315 Sets the MPU401 card to operate in UART mode.
316---------------------------------------------------------------------*/
317
318int MPU_EnterUART
319 (
320 void
321 )
322
323 {
324 int port = MPU_BaseAddr + 1;
325 unsigned count;
326
327 // Output "Enter UART" command via Command port
328 MPU_SendCommand( MPU_CmdEnterUART );
329
330 // Wait for status port to be ready for read
331 count = 0xffff;
332 while( count > 0 )
333 {
334 if ( !( inp( port ) & MPU_ReadyToRead ) )
335 {
336 port--;
337
338 // Check for a successful reset
339 if ( inp( port ) == MPU_CmdAcknowledge )
340 {
341 return( MPU_Ok );
342 }
343
344 port++;
345 }
346 count--;
347 }
348
349 // Failed to reset : MPU-401 not detected
350 return( MPU_UARTFailed );
351 }
352
353
354/*---------------------------------------------------------------------
355 Function: MPU_Init
356
357 Detects and initializes the MPU401 card.
358---------------------------------------------------------------------*/
359
360int MPU_Init
361 (
362 int addr
363 )
364
365 {
366 int status;
367 int count;
368 char *ptr;
369
370 ptr = USER_GetText( "MPUDELAY" );
371 if ( ptr != NULL )
372 {
373 MPU_Delay = ( unsigned )atol( ptr );
374 }
375
376 MPU_BaseAddr = addr;
377
378 count = 4;
379 while( count > 0 )
380 {
381 status = MPU_Reset();
382 if ( status == MPU_Ok )
383 {
384 return( MPU_EnterUART() );
385 }
386 count--;
387 }
388
389 return( status );
390 }
391
392
393/*---------------------------------------------------------------------
394 Function: MPU_LockEnd
395
396 Used for determining the length of the functions to lock in memory.
397---------------------------------------------------------------------*/
398
399static void MPU_LockEnd
400 (
401 void
402 )
403
404 {
405 }
406
407
408/*---------------------------------------------------------------------
409 Function: MPU_UnlockMemory
410
411 Locks all neccessary data.
412---------------------------------------------------------------------*/
413
414void MPU_UnlockMemory
415 (
416 void
417 )
418
419 {
420 DPMI_UnlockMemoryRegion( MPU_LockStart, MPU_LockEnd );
421 DPMI_Unlock( MPU_BaseAddr );
422 DPMI_Unlock( MPU_Delay );
423 }
424
425
426/*---------------------------------------------------------------------
427 Function: MPU_LockMemory
428
429 Locks all neccessary data.
430---------------------------------------------------------------------*/
431
432int MPU_LockMemory
433 (
434 void
435 )
436
437 {
438 int status;
439
440 status = DPMI_LockMemoryRegion( MPU_LockStart, MPU_LockEnd );
441 status |= DPMI_Lock( MPU_BaseAddr );
442 status |= DPMI_Lock( MPU_Delay );
443
444 if ( status != DPMI_Ok )
445 {
446 MPU_UnlockMemory();
447 return( MPU_Error );
448 }
449
450 return( MPU_Ok );
451 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mpu401.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mpu401.h
new file mode 100644
index 0000000000..c66f6a2e1e
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mpu401.h
@@ -0,0 +1,61 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20#ifndef __MPU401_H
21#define __MPU401_H
22
23#define MPU_DefaultAddress 0x330
24
25enum MPU_ERRORS
26 {
27 MPU_Warning = -2,
28 MPU_Error = -1,
29 MPU_Ok = 0,
30 MPU_DPMI_Error
31 };
32
33#define MPU_NotFound -1
34#define MPU_UARTFailed -2
35
36#define MPU_ReadyToWrite 0x40
37#define MPU_ReadyToRead 0x80
38#define MPU_CmdEnterUART 0x3f
39#define MPU_CmdReset 0xff
40#define MPU_CmdAcknowledge 0xfe
41
42extern int MPU_BaseAddr;
43extern unsigned MPU_Delay;
44
45void MPU_SendCommand( int data );
46void MPU_SendMidi( int data );
47int MPU_Reset( void );
48int MPU_EnterUART( void );
49int MPU_Init( int addr );
50void MPU_ResetMidi( void );
51void MPU_NoteOff( int channel, int key, int velocity );
52void MPU_NoteOn( int channel, int key, int velocity );
53void MPU_PolyAftertouch( int channel, int key, int pressure );
54void MPU_ControlChange( int channel, int number, int value );
55void MPU_ProgramChange( int channel, int program );
56void MPU_ChannelAftertouch( int channel, int pressure );
57void MPU_PitchBend( int channel, int lsb, int msb );
58void MPU_UnlockMemory( void );
59int MPU_LockMemory( void );
60
61#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/multivoc.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/multivoc.c
new file mode 100644
index 0000000000..9a47f0e247
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/multivoc.c
@@ -0,0 +1,3404 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: MULTIVOC.C
22
23 author: James R. Dose
24 date: December 20, 1993
25
26 Routines to provide multichannel digitized sound playback for
27 Sound Blaster compatible sound cards.
28
29 (c) Copyright 1993 James R. Dose. All Rights Reserved.
30**********************************************************************/
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
35#include <time.h>
36
37#ifdef PLAT_DOS
38#include <dos.h>
39#include <conio.h>
40#endif
41
42#include "util.h"
43#include "dpmi.h"
44#include "usrhooks.h"
45#include "interrup.h"
46#include "dma.h"
47#include "linklist.h"
48#include "sndcards.h"
49
50#ifdef PLAT_DOS
51#include "blaster.h"
52#include "sndscape.h"
53#include "sndsrc.h"
54#include "pas16.h"
55#include "guswave.h"
56#else
57#include "dsl.h"
58#endif
59
60#include "pitch.h"
61#include "multivoc.h"
62#include "_multivc.h"
63#include "debugio.h"
64#include "../sounddebugdefs.h"
65
66// for the Mutex
67#include <SDL.h>
68
69#define RoundFixed( fixedval, bits ) \
70 ( \
71 ( \
72 (fixedval) + ( 1 << ( (bits) - 1 ) )\
73 ) >> (bits) \
74 )
75
76// #define IS_QUIET( ptr ) ( ( void * )( ptr ) == ( void * )&MV_VolumeTable[ 0 ] )
77#define IS_QUIET( vol ) ( ( vol ) == 0 )
78
79static int MV_ReverbLevel;
80int MV_ReverbDelay;
81#if 0
82static VOLUME16 *MV_ReverbTable = NULL;
83#else
84static int MV_ReverbTable = -1;
85#endif
86
87//static signed short MV_VolumeTable[ MV_MaxVolume + 1 ][ 256 ];
88//static signed short MV_VolumeTable[ 63 + 1 ][ 256 ];
89
90//static Pan MV_PanTable[ MV_NumPanPositions ][ MV_MaxVolume + 1 ];
91static Pan MV_PanTable[ MV_NumPanPositions ][ 63 + 1 ];
92
93static int MV_Installed = FALSE;
94static int MV_SoundCard = SoundBlaster;
95static int MV_TotalVolume = MV_MaxTotalVolume;
96static int MV_MaxVoices = 1;
97static int MV_Recording;
98
99int MV_BufferSize = MixBufferSize;
100static int MV_BufferLength;
101
102static int MV_NumberOfBuffers = NumberOfBuffers;
103
104static int MV_MixMode = MONO_8BIT;
105int MV_Channels = 1;
106static int MV_Bits = 8;
107
108static int MV_Silence = SILENCE_8BIT;
109static int MV_SwapLeftRight = FALSE;
110
111static int MV_RequestedMixRate;
112int MV_MixRate;
113
114static int MV_DMAChannel = -1;
115static int MV_BuffShift;
116
117static int MV_TotalMemory;
118static int MV_FooMemory;
119
120static int MV_BufferDescriptor;
121static int MV_BufferEmpty[ NumberOfBuffers ];
122char *MV_MixBuffer[ NumberOfBuffers + 1 ];
123double *MV_FooBuffer = NULL;
124
125static VoiceNode *MV_Voices = NULL;
126
127static volatile VoiceNode VoiceList;
128static volatile VoiceNode VoicePool;
129
130/*static*/ int MV_MixPage = 0;
131static int MV_VoiceHandle = MV_MinVoiceHandle;
132
133static void ( *MV_CallBackFunc )( unsigned long ) = NULL;
134static void ( *MV_RecordFunc )( char *ptr, int length ) = NULL;
135static void ( *MV_MixFunction )( VoiceNode *voice);
136
137int MV_MaxVolume = 63;
138
139int *MV_GLast, *MV_GPos, *MV_GVal;
140
141// char *MV_HarshClipTable;
142char *MV_MixDestination;
143#if 0
144short *MV_LeftVolume;
145short *MV_RightVolume;
146#else
147int MV_LeftVolume;
148int MV_RightVolume;
149#endif
150int MV_SampleSize = 1;
151int MV_RightChannelOffset;
152
153unsigned long MV_MixPosition;
154
155int MV_ErrorCode = MV_Ok;
156
157#define MV_SetErrorCode( status ) \
158 MV_ErrorCode = ( status );
159
160
161/*---------------------------------------------------------------------
162 Function: MV_ErrorString
163
164 Returns a pointer to the error message associated with an error
165 number. A -1 returns a pointer the current error.
166---------------------------------------------------------------------*/
167
168char *MV_ErrorString
169 (
170 int ErrorNumber
171 )
172
173 {
174 char *ErrorString;
175
176 switch( ErrorNumber )
177 {
178 case MV_Warning :
179 case MV_Error :
180 ErrorString = MV_ErrorString( MV_ErrorCode );
181 break;
182
183 case MV_Ok :
184 ErrorString = "Multivoc ok.\n";
185 break;
186
187 case MV_UnsupportedCard :
188 ErrorString = "Selected sound card is not supported by Multivoc.\n";
189 break;
190
191 case MV_NotInstalled :
192 ErrorString = "Multivoc not installed.\n";
193 break;
194
195 case MV_NoVoices :
196 ErrorString = "No free voices available to Multivoc.\n";
197 break;
198
199 case MV_NoMem :
200 ErrorString = "Out of memory in Multivoc.\n";
201 break;
202
203 case MV_VoiceNotFound :
204 ErrorString = "No voice with matching handle found.\n";
205 break;
206
207#ifdef PLAT_DOS
208 case MV_BlasterError :
209 ErrorString = BLASTER_ErrorString( BLASTER_Error );
210 break;
211
212 case MV_PasError :
213 ErrorString = PAS_ErrorString( PAS_Error );
214 break;
215
216 case MV_SoundScapeError :
217 ErrorString = SOUNDSCAPE_ErrorString( SOUNDSCAPE_Error );
218 break;
219
220 #ifndef SOUNDSOURCE_OFF
221 case MV_SoundSourceError :
222 ErrorString = SS_ErrorString( SS_Error );
223 break;
224 #endif
225#endif
226
227 case MV_DPMI_Error :
228 ErrorString = "DPMI Error in Multivoc.\n";
229 break;
230
231 case MV_InvalidVOCFile :
232 ErrorString = "Invalid VOC file passed in to Multivoc.\n";
233 break;
234
235 case MV_InvalidWAVFile :
236 ErrorString = "Invalid WAV file passed in to Multivoc.\n";
237 break;
238
239 case MV_InvalidMixMode :
240 ErrorString = "Invalid mix mode request in Multivoc.\n";
241 break;
242
243 case MV_SoundSourceFailure :
244 ErrorString = "Sound Source playback failed.\n";
245 break;
246
247 case MV_IrqFailure :
248 ErrorString = "Playback failed, possibly due to an invalid or conflicting IRQ.\n";
249 break;
250
251 case MV_DMAFailure :
252 ErrorString = "Playback failed, possibly due to an invalid or conflicting DMA channel.\n";
253 break;
254
255 case MV_DMA16Failure :
256 ErrorString = "Playback failed, possibly due to an invalid or conflicting DMA channel. \n"
257 "Make sure the 16-bit DMA channel is correct.\n";
258 break;
259
260 case MV_NullRecordFunction :
261 ErrorString = "Null record function passed to MV_StartRecording.\n";
262 break;
263
264 default :
265 ErrorString = "Unknown Multivoc error code.\n";
266 break;
267 }
268
269 return( ErrorString );
270 }
271
272
273/**********************************************************************
274
275 Memory locked functions:
276
277**********************************************************************/
278
279
280#define MV_LockStart MV_Mix
281
282
283/*---------------------------------------------------------------------
284 Function: MV_Mix
285
286 Mixes the sound into the buffer.
287---------------------------------------------------------------------*/
288
289static void MV_Mix( VoiceNode *voice )
290{
291 uint8_t *start;
292 int length;
293 long voclength;
294 unsigned long position;
295 unsigned long rate;
296 unsigned long FixedPointBufferSize;
297
298 if ( ( voice->length == 0 )
299 && ( voice->GetSound( voice ) != KeepPlaying ) )
300 {
301 return;
302 }
303
304 length = MixBufferSize;
305 FixedPointBufferSize = voice->FixedPointBufferSize;
306
307 MV_MixDestination = (char*)MV_FooBuffer;
308 MV_LeftVolume = voice->LeftVolume;
309 MV_RightVolume = voice->RightVolume;
310 MV_GLast = &voice->GLast;
311 MV_GPos = &voice->GPos;
312 MV_GVal = (int*)&voice->GVal;
313
314 if ( ( MV_Channels == 2 ) && ( IS_QUIET( MV_LeftVolume ) ) )
315 {
316 MV_LeftVolume = MV_RightVolume;
317 MV_MixDestination += 8;
318 }
319
320 // Add this voice to the mix
321 while( length > 0 )
322 {
323 start = voice->sound;
324 rate = voice->RateScale;
325 position = voice->position;
326
327 // Check if the last sample in this buffer would be
328 // beyond the length of the sample block
329 if ( ( position + FixedPointBufferSize ) >= voice->length )
330 {
331 if ( position < voice->length )
332 {
333 voclength = ( voice->length - position + rate - 1 ) / rate;
334 }
335 else
336 {
337 voice->GetSound( voice );
338 return;
339 }
340 }
341 else
342 {
343 voclength = length;
344 }
345
346 voice->mix( position, rate, start, voclength );
347
348 if ( voclength & 1 )
349 {
350 MV_MixPosition += rate;
351 voclength -= 1;
352 }
353 voice->position = MV_MixPosition;
354
355 length -= voclength;
356
357 if ( voice->position >= voice->length )
358 {
359 // Get the next block of sound
360 if ( voice->GetSound( voice ) != KeepPlaying )
361 {
362 return;
363 }
364
365 if ( length > 0 )
366 {
367 // Get the position of the last sample in the buffer
368 FixedPointBufferSize = voice->RateScale * ( length - 1 );
369 }
370 }
371 }
372}
373
374
375/*---------------------------------------------------------------------
376 Function: MV_PlayVoice
377
378 Adds a voice to the play list.
379---------------------------------------------------------------------*/
380
381void MV_PlayVoice( VoiceNode *voice )
382{
383 unsigned flags;
384
385 flags = DisableInterrupts();
386 LL_SortedInsertion( &VoiceList, voice, prev, next, VoiceNode, priority );
387
388 ++sounddebugActiveSounds;
389 ++sounddebugAllocateSoundCalls;
390
391 RestoreInterrupts( flags );
392}
393
394
395/*---------------------------------------------------------------------
396 Function: MV_StopVoice
397
398 Removes the voice from the play list and adds it to the free list.
399---------------------------------------------------------------------*/
400
401void MV_StopVoice( VoiceNode *voice )
402{
403 VoiceNode* pPrev;
404 VoiceNode* pNext;
405
406 unsigned flags;
407
408 flags = DisableInterrupts();
409
410
411 pPrev = voice->prev;
412 pNext = voice->next;
413
414 // move the voice from the play list to the free list
415 LL_Remove( voice, next, prev );
416 LL_Add( &VoicePool, voice, next, prev );
417
418 if(pPrev == NULL)
419 {
420 printf("(MV_StopVoice) pPrev is NULL, this could be a problem.\n");
421 }
422
423 if(pNext == NULL)
424 {
425 printf("(MV_StopVoice) pNext is NULL, this could be a problem.\n");
426 }
427
428 --sounddebugActiveSounds;
429 ++sounddebugDeallocateSoundCalls;
430
431
432 RestoreInterrupts( flags );
433}
434
435
436/*---------------------------------------------------------------------
437 Function: MV_ServiceVoc
438
439 Starts playback of the waiting buffer and mixes the next one.
440---------------------------------------------------------------------*/
441
442// static int backcolor = 1;
443
444void MV_ServiceVoc
445(
446 void
447 )
448
449{
450 VoiceNode *voice;
451 VoiceNode *next;
452
453
454 // Toggle which buffer we'll mix next
455 MV_MixPage++;
456 if ( MV_MixPage >= MV_NumberOfBuffers )
457 {
458 MV_MixPage -= MV_NumberOfBuffers;
459 }
460
461 {
462 ClearBuffer_DW( MV_FooBuffer, 0, sizeof(double) / 4 * MV_BufferSize / MV_SampleSize * MV_Channels);
463 MV_BufferEmpty[ MV_MixPage ] = TRUE;
464 }
465
466 // Play any waiting voices
467 for( voice = VoiceList.next; voice != &VoiceList; voice = next )
468 {
469 // if ( ( voice < &MV_Voices[ 0 ] ) || ( voice > &MV_Voices[ 8 ] ) )
470 // {
471 // SetBorderColor(backcolor++);
472 // break;
473 // }
474
475 if(NULL == voice->GetSound)
476 {
477 #ifdef _DEBUG
478 printf("MV_ServiceVoc() voice->GetSound == NULL, break;\n");
479 #endif
480
481 // This sound is null, early out, or face a nasty crash.
482 break;
483 }
484
485 MV_BufferEmpty[ MV_MixPage ] = FALSE;
486
487 MV_MixFunction( voice );
488
489 next = voice->next;
490
491 // Is this voice done?
492 if ( !voice->Playing )
493 {
494 MV_StopVoice( voice );
495
496 if ( MV_CallBackFunc )
497 {
498 MV_CallBackFunc( voice->callbackval );
499 }
500 }
501 }
502
503 if ( MV_ReverbLevel > 0)
504 {
505 if (MV_ReverbTable != -1) MV_FPReverb(MV_ReverbTable);
506 }
507
508 {
509 char *dest;
510 int count;
511
512 dest = MV_MixBuffer[ MV_MixPage ];
513 count = MV_BufferSize / MV_SampleSize * MV_Channels;
514 if ( MV_Bits == 16 )
515 {
516 MV_16BitDownmix(dest, count);
517 }
518 else
519 {
520 MV_8BitDownmix(dest, count);
521 }
522
523 }
524}
525
526/*---------------------------------------------------------------------
527 Function: MV_GetNextVOCBlock
528
529 Interperate the information of a VOC format sound file.
530---------------------------------------------------------------------*/
531
532playbackstatus MV_GetNextVOCBlock
533 (
534 VoiceNode *voice
535 )
536
537 {
538 unsigned char *ptr;
539 int blocktype;
540 int lastblocktype;
541 uint32_t blocklength;
542 unsigned long samplespeed;
543 unsigned int tc;
544 int packtype;
545 int voicemode;
546 int done;
547 unsigned BitsPerSample;
548 unsigned Channels;
549 unsigned Format;
550
551 if ( voice->BlockLength > 0 )
552 {
553 voice->position -= voice->length;
554 voice->sound += voice->length >> 16;
555 if ( voice->bits == 16 )
556 {
557 voice->sound += voice->length >> 16;
558 }
559 voice->length = min( voice->BlockLength, 0x8000 );
560 voice->BlockLength -= voice->length;
561 voice->length <<= 16;
562 return( KeepPlaying );
563 }
564
565 if ( ( voice->length > 0 ) && ( voice->LoopEnd != NULL ) &&
566 ( voice->LoopStart != NULL ) )
567 {
568 voice->BlockLength = voice->LoopSize;
569 voice->sound = voice->LoopStart;
570 voice->position = 0;
571 voice->length = min( voice->BlockLength, 0x8000 );
572 voice->BlockLength -= voice->length;
573 voice->length <<= 16;
574 return( KeepPlaying );
575 }
576
577 ptr = ( unsigned char * )voice->NextBlock;
578
579 voice->Playing = TRUE;
580
581 voicemode = 0;
582 lastblocktype = 0;
583 packtype = 0;
584
585 done = FALSE;
586 while( !done )
587 {
588 // Stop playing if we get a NULL pointer
589 if ( ptr == NULL )
590 {
591 voice->Playing = FALSE;
592 done = TRUE;
593 break;
594 }
595
596 blocktype = ( int )*ptr;
597 blocklength = ( readLE32( ptr + 1 ) ) & 0x00ffffff;
598 ptr += 4;
599
600 switch( blocktype )
601 {
602 case 0 :
603 // End of data
604 if ( ( voice->LoopStart == NULL ) ||
605 ( voice->LoopStart >= ( ptr - 4 ) ) )
606 {
607 voice->Playing = FALSE;
608 done = TRUE;
609 }
610 else
611 {
612 voice->BlockLength = ( ptr - 4 ) - (unsigned char *)voice->LoopStart;
613 voice->sound = voice->LoopStart;
614 voice->position = 0;
615 voice->length = min( voice->BlockLength, 0x8000 );
616 voice->BlockLength -= voice->length;
617 voice->length <<= 16;
618 return( KeepPlaying );
619 }
620 break;
621
622 case 1 :
623 // Sound data block
624 voice->bits = 8;
625 if ( lastblocktype != 8 )
626 {
627 tc = ( unsigned int )*ptr << 8;
628 packtype = *( ptr + 1 );
629 }
630
631 ptr += 2;
632 blocklength -= 2;
633
634 samplespeed = 256000000L / ( 65536 - tc );
635
636 // Skip packed or stereo data
637 if ( ( packtype != 0 ) || ( voicemode != 0 ) )
638 {
639 ptr += blocklength;
640 }
641 else
642 {
643 done = TRUE;
644 }
645 voicemode = 0;
646 break;
647
648 case 2 :
649 // Sound continuation block
650 samplespeed = voice->SamplingRate;
651 done = TRUE;
652 break;
653
654 case 3 :
655 // Silence
656 // Not implimented.
657 ptr += blocklength;
658 break;
659
660 case 4 :
661 // Marker
662 // Not implimented.
663 ptr += blocklength;
664 break;
665
666 case 5 :
667 // ASCII string
668 // Not implimented.
669 ptr += blocklength;
670 break;
671
672 case 6 :
673 // Repeat begin
674 if ( voice->LoopEnd == NULL )
675 {
676 voice->LoopCount = readLE16(ptr);
677 voice->LoopStart = ptr + blocklength;
678 }
679 ptr += blocklength;
680 break;
681
682 case 7 :
683 // Repeat end
684 ptr += blocklength;
685 if ( lastblocktype == 6 )
686 {
687 voice->LoopCount = 0;
688 }
689 else
690 {
691 if ( ( voice->LoopCount > 0 ) && ( voice->LoopStart != NULL ) )
692 {
693 ptr = voice->LoopStart;
694 if ( voice->LoopCount < 0xffff )
695 {
696 voice->LoopCount--;
697 if ( voice->LoopCount == 0 )
698 {
699 voice->LoopStart = NULL;
700 }
701 }
702 }
703 }
704 break;
705
706 case 8 :
707 // Extended block
708 voice->bits = 8;
709 tc = readLE16(ptr);
710 packtype = *( ptr + 2 );
711 voicemode = *( ptr + 3 );
712 ptr += blocklength;
713 break;
714
715 case 9 :
716 // New sound data block
717
718 samplespeed = readLE32(ptr);
719 BitsPerSample = ( unsigned )*( ptr + 4 );
720 Channels = (unsigned)*( ptr + 5 );
721 Format = ( unsigned )readLE16( ptr + 6 );
722
723 if ( ( BitsPerSample == 8 ) && ( Channels == 1 ) &&
724 ( Format == VOC_8BIT ) )
725 {
726 ptr += 12;
727 blocklength -= 12;
728 voice->bits = 8;
729 done = TRUE;
730 }
731 else if ( ( BitsPerSample == 16 ) && ( Channels == 1 ) &&
732 ( Format == VOC_16BIT ) )
733 {
734 ptr += 12;
735 blocklength -= 12;
736 voice->bits = 16;
737 done = TRUE;
738 }
739 else
740 {
741 ptr += blocklength;
742 }
743 break;
744
745 default :
746 // Unknown data. Probably not a VOC file.
747 voice->Playing = FALSE;
748 done = TRUE;
749 break;
750 }
751
752 lastblocktype = blocktype;
753 }
754
755 if ( voice->Playing )
756 {
757 voice->NextBlock = ptr + blocklength;
758 voice->sound = ptr;
759
760 voice->SamplingRate = samplespeed;
761 voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate;
762
763 // Multiply by MixBufferSize - 1
764 voice->FixedPointBufferSize = ( voice->RateScale * MixBufferSize ) -
765 voice->RateScale;
766
767 if ( voice->LoopEnd != NULL )
768 {
769 if ( blocklength > ( unsigned long )voice->LoopEnd )
770 {
771 blocklength = ( unsigned long )voice->LoopEnd;
772 }
773 else
774 {
775 voice->LoopEnd = ( char * )blocklength;
776 }
777
778 voice->LoopStart = voice->sound + ( unsigned long )voice->LoopStart;
779 voice->LoopEnd = voice->sound + ( unsigned long )voice->LoopEnd;
780 voice->LoopSize = voice->LoopEnd - voice->LoopStart;
781 }
782
783 if ( voice->bits == 16 )
784 {
785 blocklength /= 2;
786 }
787
788 voice->position = 0;
789 voice->length = min( blocklength, 0x8000 );
790 voice->BlockLength = blocklength - voice->length;
791 voice->length <<= 16;
792
793 MV_SetVoiceMixMode( voice );
794
795 return( KeepPlaying );
796 }
797
798 return( NoMoreData );
799 }
800
801
802/*---------------------------------------------------------------------
803 Function: MV_GetNextDemandFeedBlock
804
805 Controls playback of demand fed data.
806---------------------------------------------------------------------*/
807
808playbackstatus MV_GetNextDemandFeedBlock
809 (
810 VoiceNode *voice
811 )
812
813 {
814 if ( voice->BlockLength > 0 )
815 {
816 voice->position -= voice->length;
817 voice->sound += voice->length >> 16;
818 voice->length = min( voice->BlockLength, 0x8000 );
819 voice->BlockLength -= voice->length;
820 voice->length <<= 16;
821
822 return( KeepPlaying );
823 }
824
825 if ( voice->DemandFeed == NULL )
826 {
827 return( NoMoreData );
828 }
829
830 voice->position = 0;
831 ( voice->DemandFeed )( &voice->sound, &voice->BlockLength );
832 voice->length = min( voice->BlockLength, 0x8000 );
833 voice->BlockLength -= voice->length;
834 voice->length <<= 16;
835
836 if ( ( voice->length > 0 ) && ( voice->sound != NULL ) )
837 {
838 return( KeepPlaying );
839 }
840 return( NoMoreData );
841 }
842
843
844/*---------------------------------------------------------------------
845 Function: MV_GetNextRawBlock
846
847 Controls playback of demand fed data.
848---------------------------------------------------------------------*/
849
850playbackstatus MV_GetNextRawBlock
851 (
852 VoiceNode *voice
853 )
854
855 {
856 if ( voice->BlockLength <= 0 )
857 {
858 if ( voice->LoopStart == NULL )
859 {
860 voice->Playing = FALSE;
861 return( NoMoreData );
862 }
863
864 voice->BlockLength = voice->LoopSize;
865 voice->NextBlock = voice->LoopStart;
866 voice->length = 0;
867 voice->position = 0;
868 }
869
870 voice->sound = voice->NextBlock;
871 voice->position -= voice->length;
872 voice->length = min( voice->BlockLength, 0x8000 );
873 voice->NextBlock += voice->length;
874 if ( voice->bits == 16 )
875 {
876 voice->NextBlock += voice->length;
877 }
878 voice->BlockLength -= voice->length;
879 voice->length <<= 16;
880
881 return( KeepPlaying );
882 }
883
884
885/*---------------------------------------------------------------------
886 Function: MV_GetNextWAVBlock
887
888 Controls playback of demand fed data.
889---------------------------------------------------------------------*/
890
891playbackstatus MV_GetNextWAVBlock
892 (
893 VoiceNode *voice
894 )
895
896 {
897 if ( voice->BlockLength <= 0 )
898 {
899 if ( voice->LoopStart == NULL )
900 {
901 voice->Playing = FALSE;
902 return( NoMoreData );
903 }
904
905 voice->BlockLength = voice->LoopSize;
906 voice->NextBlock = voice->LoopStart;
907 voice->length = 0;
908 voice->position = 0;
909 }
910
911 voice->sound = voice->NextBlock;
912 voice->position -= voice->length;
913 voice->length = min( voice->BlockLength, 0x8000 );
914 voice->NextBlock += voice->length;
915 if ( voice->bits == 16 )
916 {
917 voice->NextBlock += voice->length;
918 }
919 voice->BlockLength -= voice->length;
920 voice->length <<= 16;
921
922 return( KeepPlaying );
923 }
924
925
926/*---------------------------------------------------------------------
927 Function: MV_ServiceRecord
928
929 Starts recording of the waiting buffer.
930---------------------------------------------------------------------*/
931
932#ifdef PLAT_DOS
933static void MV_ServiceRecord
934 (
935 void
936 )
937
938 {
939 if ( MV_RecordFunc )
940 {
941 MV_RecordFunc( MV_MixBuffer[ 0 ] + MV_MixPage * MixBufferSize,
942 MixBufferSize );
943 }
944
945 // Toggle which buffer we'll mix next
946 MV_MixPage++;
947 if ( MV_MixPage >= NumberOfBuffers )
948 {
949 MV_MixPage = 0;
950 }
951 }
952#endif
953
954
955/*---------------------------------------------------------------------
956 Function: MV_GetVoice
957
958 Locates the voice with the specified handle.
959---------------------------------------------------------------------*/
960
961VoiceNode *MV_GetVoice
962 (
963 int handle
964 )
965
966 {
967 VoiceNode *voice;
968 unsigned flags;
969
970 flags = DisableInterrupts();
971
972 for( voice = VoiceList.next; voice != &VoiceList; voice = voice->next )
973 {
974 if ( handle == voice->handle )
975 {
976 break;
977 }
978 }
979
980 RestoreInterrupts( flags );
981
982 if ( voice == &VoiceList )
983 {
984 MV_SetErrorCode( MV_VoiceNotFound );
985
986 // SBF - should this return null?
987 return NULL;
988 }
989
990 return( voice );
991 }
992
993
994/*---------------------------------------------------------------------
995 Function: MV_VoicePlaying
996
997 Checks if the voice associated with the specified handle is
998 playing.
999---------------------------------------------------------------------*/
1000
1001int MV_VoicePlaying
1002 (
1003 int handle
1004 )
1005
1006 {
1007 VoiceNode *voice;
1008
1009 if ( !MV_Installed )
1010 {
1011 MV_SetErrorCode( MV_NotInstalled );
1012 return( FALSE );
1013 }
1014
1015 voice = MV_GetVoice( handle );
1016
1017 if ( voice == NULL )
1018 {
1019 return( FALSE );
1020 }
1021
1022 return( TRUE );
1023 }
1024
1025
1026/*---------------------------------------------------------------------
1027 Function: MV_KillAllVoices
1028
1029 Stops output of all currently active voices.
1030---------------------------------------------------------------------*/
1031
1032int MV_KillAllVoices
1033 (
1034 void
1035 )
1036
1037 {
1038 if ( !MV_Installed )
1039 {
1040 MV_SetErrorCode( MV_NotInstalled );
1041 return( MV_Error );
1042 }
1043
1044 // Remove all the voices from the list
1045 while( VoiceList.next != &VoiceList )
1046 {
1047 MV_Kill( VoiceList.next->handle );
1048 }
1049
1050 return( MV_Ok );
1051 }
1052
1053
1054/*---------------------------------------------------------------------
1055 Function: MV_Kill
1056
1057 Stops output of the voice associated with the specified handle.
1058---------------------------------------------------------------------*/
1059
1060int MV_Kill
1061 (
1062 int handle
1063 )
1064
1065 {
1066 VoiceNode *voice;
1067 unsigned flags;
1068 unsigned long callbackval;
1069
1070 if ( !MV_Installed )
1071 {
1072 MV_SetErrorCode( MV_NotInstalled );
1073 return( MV_Error );
1074 }
1075
1076 flags = DisableInterrupts();
1077
1078 voice = MV_GetVoice( handle );
1079 if ( voice == NULL )
1080 {
1081 RestoreInterrupts( flags );
1082 MV_SetErrorCode( MV_VoiceNotFound );
1083 return( MV_Error );
1084 }
1085
1086 callbackval = voice->callbackval;
1087
1088 MV_StopVoice( voice );
1089
1090 RestoreInterrupts( flags );
1091
1092 if ( MV_CallBackFunc )
1093 {
1094 MV_CallBackFunc( callbackval );
1095 }
1096
1097 return( MV_Ok );
1098 }
1099
1100
1101/*---------------------------------------------------------------------
1102 Function: MV_VoicesPlaying
1103
1104 Determines the number of currently active voices.
1105---------------------------------------------------------------------*/
1106
1107int MV_VoicesPlaying
1108 (
1109 void
1110 )
1111
1112 {
1113 VoiceNode *voice;
1114 int NumVoices = 0;
1115 unsigned flags;
1116
1117 if ( !MV_Installed )
1118 {
1119 MV_SetErrorCode( MV_NotInstalled );
1120 return( 0 );
1121 }
1122
1123 flags = DisableInterrupts();
1124
1125 for( voice = VoiceList.next; voice != &VoiceList; voice = voice->next )
1126 {
1127 NumVoices++;
1128 }
1129
1130 RestoreInterrupts( flags );
1131
1132 return( NumVoices );
1133 }
1134
1135
1136/*---------------------------------------------------------------------
1137 Function: MV_AllocVoice
1138
1139 Retrieve an inactive or lower priority voice for output.
1140---------------------------------------------------------------------*/
1141
1142VoiceNode *MV_AllocVoice
1143 (
1144 int priority
1145 )
1146
1147 {
1148 VoiceNode *voice;
1149 VoiceNode *node;
1150 unsigned flags;
1151
1152//return( NULL );
1153 if ( MV_Recording )
1154 {
1155 return( NULL );
1156 }
1157
1158 flags = DisableInterrupts();
1159
1160 // Check if we have any free voices
1161 if ( LL_Empty( &VoicePool, next, prev ) )
1162 {
1163 // check if we have a higher priority than a voice that is playing.
1164 voice = VoiceList.next;
1165 for( node = voice->next; node != &VoiceList; node = node->next )
1166 {
1167 if ( node->priority < voice->priority )
1168 {
1169 voice = node;
1170 }
1171 }
1172
1173 if ( priority >= voice->priority )
1174 {
1175 MV_Kill( voice->handle );
1176 }
1177 }
1178
1179 // Check if any voices are in the voice pool
1180 if ( LL_Empty( &VoicePool, next, prev ) )
1181 {
1182 // No free voices
1183 RestoreInterrupts( flags );
1184 return( NULL );
1185 }
1186
1187 voice = VoicePool.next;
1188 LL_Remove( voice, next, prev );
1189 RestoreInterrupts( flags );
1190
1191 // Find a free voice handle
1192 do
1193 {
1194 MV_VoiceHandle++;
1195 if ( MV_VoiceHandle < MV_MinVoiceHandle )
1196 {
1197 MV_VoiceHandle = MV_MinVoiceHandle;
1198 }
1199 }
1200 while( MV_VoicePlaying( MV_VoiceHandle ) );
1201
1202 voice->handle = MV_VoiceHandle;
1203
1204 return( voice );
1205 }
1206
1207
1208/*---------------------------------------------------------------------
1209 Function: MV_VoiceAvailable
1210
1211 Checks if a voice can be play at the specified priority.
1212---------------------------------------------------------------------*/
1213
1214int MV_VoiceAvailable
1215 (
1216 int priority
1217 )
1218
1219 {
1220 VoiceNode *voice;
1221 VoiceNode *node;
1222 unsigned flags;
1223
1224 // Check if we have any free voices
1225 if ( !LL_Empty( &VoicePool, next, prev ) )
1226 {
1227 return( TRUE );
1228 }
1229
1230 flags = DisableInterrupts();
1231
1232 // check if we have a higher priority than a voice that is playing.
1233 voice = VoiceList.next;
1234 for( node = VoiceList.next; node != &VoiceList; node = node->next )
1235 {
1236 if ( node->priority < voice->priority )
1237 {
1238 voice = node;
1239 }
1240 }
1241
1242 RestoreInterrupts( flags );
1243
1244 if ( ( voice != &VoiceList ) && ( priority >= voice->priority ) )
1245 {
1246 return( TRUE );
1247 }
1248
1249 return( FALSE );
1250 }
1251
1252
1253/*---------------------------------------------------------------------
1254 Function: MV_SetVoicePitch
1255
1256 Sets the pitch for the specified voice.
1257---------------------------------------------------------------------*/
1258
1259void MV_SetVoicePitch
1260 (
1261 VoiceNode *voice,
1262 unsigned long rate,
1263 int pitchoffset
1264 )
1265
1266 {
1267 voice->SamplingRate = rate;
1268 voice->PitchScale = PITCH_GetScale( pitchoffset );
1269 voice->RateScale = ( rate * voice->PitchScale ) / MV_MixRate;
1270
1271 // Multiply by MixBufferSize - 1
1272 voice->FixedPointBufferSize = ( voice->RateScale * MixBufferSize ) -
1273 voice->RateScale;
1274 }
1275
1276
1277/*---------------------------------------------------------------------
1278 Function: MV_SetPitch
1279
1280 Sets the pitch for the voice associated with the specified handle.
1281---------------------------------------------------------------------*/
1282
1283int MV_SetPitch
1284 (
1285 int handle,
1286 int pitchoffset
1287 )
1288
1289 {
1290 VoiceNode *voice;
1291
1292 if ( !MV_Installed )
1293 {
1294 MV_SetErrorCode( MV_NotInstalled );
1295 return( MV_Error );
1296 }
1297
1298 voice = MV_GetVoice( handle );
1299 if ( voice == NULL )
1300 {
1301 MV_SetErrorCode( MV_VoiceNotFound );
1302 return( MV_Error );
1303 }
1304
1305 MV_SetVoicePitch( voice, voice->SamplingRate, pitchoffset );
1306
1307 return( MV_Ok );
1308 }
1309
1310
1311/*---------------------------------------------------------------------
1312 Function: MV_SetFrequency
1313
1314 Sets the frequency for the voice associated with the specified handle.
1315---------------------------------------------------------------------*/
1316
1317int MV_SetFrequency
1318 (
1319 int handle,
1320 int frequency
1321 )
1322
1323 {
1324 VoiceNode *voice;
1325
1326 if ( !MV_Installed )
1327 {
1328 MV_SetErrorCode( MV_NotInstalled );
1329 return( MV_Error );
1330 }
1331
1332 voice = MV_GetVoice( handle );
1333 if ( voice == NULL )
1334 {
1335 MV_SetErrorCode( MV_VoiceNotFound );
1336 return( MV_Error );
1337 }
1338
1339 MV_SetVoicePitch( voice, frequency, 0 );
1340
1341 return( MV_Ok );
1342 }
1343
1344
1345/*---------------------------------------------------------------------
1346 Function: MV_GetVolumeTable
1347
1348 Returns a pointer to the volume table associated with the specified
1349 volume.
1350---------------------------------------------------------------------*/
1351
1352#if 0
1353static short *MV_GetVolumeTable
1354 (
1355 int vol
1356 )
1357
1358 {
1359 int volume;
1360 short *table;
1361
1362 volume = MIX_VOLUME( vol );
1363
1364 table = &MV_VolumeTable[ volume ];
1365
1366 return( table );
1367 }
1368#else
1369static int MV_GetVolumeTable
1370 (
1371 int vol
1372 )
1373
1374 {
1375 int volume;
1376
1377 volume = MIX_VOLUME( vol );
1378
1379 return ( volume * MV_TotalVolume ) / MV_MaxTotalVolume;
1380 }
1381#endif
1382
1383/*---------------------------------------------------------------------
1384 Function: MV_SetVoiceMixMode
1385
1386 Selects which method should be used to mix the voice.
1387---------------------------------------------------------------------*/
1388
1389void MV_SetVoiceMixMode
1390 (
1391 VoiceNode *voice
1392 )
1393
1394 {
1395 unsigned flags;
1396 int test;
1397
1398 flags = DisableInterrupts();
1399
1400 test = T_DEFAULT;
1401 if ( voice->bits == 16 )
1402 {
1403 test |= T_16BITSOURCE;
1404 }
1405
1406 if ( MV_Channels == 1 )
1407 {
1408 test |= T_MONO;
1409 }
1410 else
1411 {
1412 if ( IS_QUIET( voice->RightVolume ) )
1413 {
1414 test |= T_RIGHTQUIET;
1415 }
1416 else if ( IS_QUIET( voice->LeftVolume ) )
1417 {
1418 test |= T_LEFTQUIET;
1419 }
1420 }
1421
1422 switch( test )
1423 {
1424 case T_MONO | T_16BITSOURCE :
1425 voice->mix = MV_MixFPMono16;
1426 break;
1427
1428 case T_MONO :
1429 voice->mix = MV_MixFPMono8;
1430 break;
1431
1432 case T_16BITSOURCE | T_LEFTQUIET :
1433 MV_LeftVolume = MV_RightVolume;
1434 voice->mix = MV_MixFPMono16;
1435 break;
1436
1437 case T_LEFTQUIET :
1438 MV_LeftVolume = MV_RightVolume;
1439 voice->mix = MV_MixFPMono8;
1440 break;
1441
1442 case T_16BITSOURCE | T_RIGHTQUIET :
1443 voice->mix = MV_MixFPMono16;
1444 break;
1445
1446 case T_RIGHTQUIET :
1447 voice->mix = MV_MixFPMono8;
1448 break;
1449
1450 case T_16BITSOURCE :
1451 voice->mix = MV_MixFPStereo16;
1452 break;
1453
1454 case T_SIXTEENBIT_STEREO :
1455 voice->mix = MV_MixFPStereo8;
1456 break;
1457
1458 default :
1459 voice->mix = MV_MixFPMono8;
1460 }
1461 RestoreInterrupts( flags );
1462 }
1463
1464
1465/*---------------------------------------------------------------------
1466 Function: MV_SetVoiceVolume
1467
1468 Sets the stereo and mono volume level of the voice associated
1469 with the specified handle.
1470---------------------------------------------------------------------*/
1471
1472void MV_SetVoiceVolume
1473 (
1474 VoiceNode *voice,
1475 int vol,
1476 int left,
1477 int right
1478 )
1479
1480 {
1481 if ( MV_Channels == 1 )
1482 {
1483 left = vol;
1484 right = vol;
1485 }
1486
1487 if ( MV_SwapLeftRight )
1488 {
1489 // SBPro uses reversed panning
1490 voice->LeftVolume = MV_GetVolumeTable( right );
1491 voice->RightVolume = MV_GetVolumeTable( left );
1492 }
1493 else
1494 {
1495 voice->LeftVolume = MV_GetVolumeTable( left );
1496 voice->RightVolume = MV_GetVolumeTable( right );
1497 }
1498
1499 MV_SetVoiceMixMode( voice );
1500 }
1501
1502
1503/*---------------------------------------------------------------------
1504 Function: MV_EndLooping
1505
1506 Stops the voice associated with the specified handle from looping
1507 without stoping the sound.
1508---------------------------------------------------------------------*/
1509
1510int MV_EndLooping
1511 (
1512 int handle
1513 )
1514
1515 {
1516 VoiceNode *voice;
1517 unsigned flags;
1518
1519 if ( !MV_Installed )
1520 {
1521 MV_SetErrorCode( MV_NotInstalled );
1522 return( MV_Error );
1523 }
1524
1525 flags = DisableInterrupts();
1526
1527 voice = MV_GetVoice( handle );
1528 if ( voice == NULL )
1529 {
1530 RestoreInterrupts( flags );
1531 MV_SetErrorCode( MV_VoiceNotFound );
1532 return( MV_Warning );
1533 }
1534
1535 voice->LoopCount = 0;
1536 voice->LoopStart = NULL;
1537 voice->LoopEnd = NULL;
1538
1539 RestoreInterrupts( flags );
1540
1541 return( MV_Ok );
1542 }
1543
1544
1545/*---------------------------------------------------------------------
1546 Function: MV_SetPan
1547
1548 Sets the stereo and mono volume level of the voice associated
1549 with the specified handle.
1550---------------------------------------------------------------------*/
1551
1552int MV_SetPan
1553 (
1554 int handle,
1555 int vol,
1556 int left,
1557 int right
1558 )
1559
1560 {
1561 VoiceNode *voice;
1562
1563 if ( !MV_Installed )
1564 {
1565 MV_SetErrorCode( MV_NotInstalled );
1566 return( MV_Error );
1567 }
1568
1569 voice = MV_GetVoice( handle );
1570 if ( voice == NULL )
1571 {
1572 MV_SetErrorCode( MV_VoiceNotFound );
1573 return( MV_Warning );
1574 }
1575
1576 MV_SetVoiceVolume( voice, vol, left, right );
1577
1578 return( MV_Ok );
1579 }
1580
1581
1582/*---------------------------------------------------------------------
1583 Function: MV_Pan3D
1584
1585 Set the angle and distance from the listener of the voice associated
1586 with the specified handle.
1587---------------------------------------------------------------------*/
1588
1589int MV_Pan3D
1590 (
1591 int handle,
1592 int angle,
1593 int distance
1594 )
1595
1596 {
1597 int left;
1598 int right;
1599 int mid;
1600 int volume;
1601 int status;
1602
1603 if ( distance < 0 )
1604 {
1605 distance = -distance;
1606 angle += MV_NumPanPositions / 2;
1607 }
1608
1609 volume = MIX_VOLUME( distance );
1610
1611 // Ensure angle is within 0 - 31
1612 angle &= MV_MaxPanPosition;
1613
1614 left = MV_PanTable[ angle ][ volume ].left;
1615 right = MV_PanTable[ angle ][ volume ].right;
1616 mid = max( 0, 255 - distance );
1617
1618 status = MV_SetPan( handle, mid, left, right );
1619
1620 return( status );
1621 }
1622
1623
1624/*---------------------------------------------------------------------
1625 Function: MV_SetReverb
1626
1627 Sets the level of reverb to add to mix.
1628---------------------------------------------------------------------*/
1629
1630void MV_SetReverb
1631 (
1632 int reverb
1633 )
1634
1635 {
1636 MV_ReverbLevel = MIX_VOLUME( reverb );
1637 MV_ReverbTable = ( MV_ReverbLevel * MV_TotalVolume ) / MV_MaxTotalVolume;// &MV_VolumeTable[ MV_ReverbLevel ];
1638 if (!reverb) MV_FPReverbFree();
1639 }
1640
1641
1642/*---------------------------------------------------------------------
1643 Function: MV_SetFastReverb
1644
1645 Sets the level of reverb to add to mix.
1646---------------------------------------------------------------------*/
1647
1648void MV_SetFastReverb
1649 (
1650 int reverb
1651 )
1652
1653 {
1654 MV_ReverbLevel = max( 0, min( 16, reverb ) );
1655 MV_ReverbTable = -1;
1656 }
1657
1658
1659/*---------------------------------------------------------------------
1660 Function: MV_GetMaxReverbDelay
1661
1662 Returns the maximum delay time for reverb.
1663---------------------------------------------------------------------*/
1664
1665int MV_GetMaxReverbDelay
1666 (
1667 void
1668 )
1669
1670 {
1671 int maxdelay;
1672
1673 maxdelay = 65536; //MixBufferSize * MV_NumberOfBuffers;
1674
1675 return maxdelay;
1676 }
1677
1678
1679/*---------------------------------------------------------------------
1680 Function: MV_GetReverbDelay
1681
1682 Returns the current delay time for reverb.
1683---------------------------------------------------------------------*/
1684
1685int MV_GetReverbDelay
1686 (
1687 void
1688 )
1689
1690 {
1691 return MV_ReverbDelay; // / MV_SampleSize;
1692 }
1693
1694
1695/*---------------------------------------------------------------------
1696 Function: MV_SetReverbDelay
1697
1698 Sets the delay level of reverb to add to mix.
1699---------------------------------------------------------------------*/
1700
1701void MV_SetReverbDelay
1702 (
1703 int delay
1704 )
1705
1706 {
1707 int maxdelay;
1708
1709 if (!delay) // blah, ignore
1710 return;
1711 maxdelay = MV_GetMaxReverbDelay();
1712 MV_ReverbDelay = max( MixBufferSize, min( delay, maxdelay ) );
1713 // MV_ReverbDelay *= MV_SampleSize;
1714 }
1715
1716
1717/*---------------------------------------------------------------------
1718 Function: MV_SetMixMode
1719
1720 Prepares Multivoc to play stereo of mono digitized sounds.
1721---------------------------------------------------------------------*/
1722
1723int MV_SetMixMode
1724 (
1725 int numchannels,
1726 int samplebits
1727 )
1728
1729 {
1730 int mode;
1731
1732 if ( !MV_Installed )
1733 {
1734 MV_SetErrorCode( MV_NotInstalled );
1735 return( MV_Error );
1736 }
1737
1738 mode = 0;
1739 if ( numchannels == 2 )
1740 {
1741 mode |= STEREO;
1742 }
1743 if ( samplebits == 16 )
1744 {
1745 mode |= SIXTEEN_BIT;
1746 }
1747
1748#ifdef PLAT_DOS
1749 switch( MV_SoundCard )
1750 {
1751 case UltraSound :
1752 MV_MixMode = mode;
1753 break;
1754
1755 case SoundBlaster :
1756 case Awe32 :
1757 MV_MixMode = BLASTER_SetMixMode( mode );
1758 break;
1759
1760 case ProAudioSpectrum :
1761 case SoundMan16 :
1762 MV_MixMode = PAS_SetMixMode( mode );
1763 break;
1764
1765 case SoundScape :
1766 MV_MixMode = SOUNDSCAPE_SetMixMode( mode );
1767 break;
1768
1769 #ifndef SOUNDSOURCE_OFF
1770 case SoundSource :
1771 case TandySoundSource :
1772 MV_MixMode = SS_SetMixMode( mode );
1773 break;
1774 #endif
1775 }
1776#else
1777 MV_MixMode = mode;
1778#endif
1779
1780 MV_Channels = 1;
1781 if ( MV_MixMode & STEREO )
1782 {
1783 MV_Channels = 2;
1784 }
1785
1786 MV_Bits = 8;
1787 if ( MV_MixMode & SIXTEEN_BIT )
1788 {
1789 MV_Bits = 16;
1790 }
1791
1792 MV_BuffShift = 7 + MV_Channels;
1793 MV_SampleSize = sizeof( MONO8 ) * MV_Channels;
1794
1795 if ( MV_Bits == 8 )
1796 {
1797 MV_Silence = SILENCE_8BIT;
1798 }
1799 else
1800 {
1801 MV_Silence = SILENCE_16BIT;
1802 MV_BuffShift += 1;
1803 MV_SampleSize *= 2;
1804 }
1805
1806 MV_BufferSize = MixBufferSize * MV_SampleSize;
1807 MV_NumberOfBuffers = TotalBufferSize / MV_BufferSize;
1808 MV_BufferLength = TotalBufferSize;
1809
1810 MV_RightChannelOffset = MV_SampleSize / 2;
1811
1812#ifdef PLAT_DOS
1813 if ( ( MV_SoundCard == UltraSound ) && ( MV_Channels == 2 ) )
1814 {
1815 MV_SampleSize /= 2;
1816 MV_BufferSize /= 2;
1817 MV_RightChannelOffset = MV_BufferSize * MV_NumberOfBuffers;
1818 MV_BufferLength /= 2;
1819 }
1820#endif
1821
1822 return( MV_Ok );
1823 }
1824
1825
1826/*---------------------------------------------------------------------
1827 Function: MV_StartPlayback
1828
1829 Starts the sound playback engine.
1830---------------------------------------------------------------------*/
1831
1832int MV_StartPlayback()
1833
1834 {
1835 int status;
1836 int buffer;
1837
1838 // Initialize the buffers
1839 ClearBuffer_DW( MV_MixBuffer[ 0 ], MV_Silence, TotalBufferSize >> 2 );
1840 for( buffer = 0; buffer < MV_NumberOfBuffers; buffer++ )
1841 {
1842 MV_BufferEmpty[ buffer ] = TRUE;
1843 }
1844
1845 // Set the mix buffer variables
1846 MV_MixPage = 1;
1847
1848 MV_MixFunction = MV_Mix;
1849
1850//JIM
1851// MV_MixRate = MV_RequestedMixRate;
1852// return( MV_Ok );
1853
1854 // Start playback
1855 status = DSL_BeginBufferedPlayback( MV_MixBuffer[ 0 ],
1856 TotalBufferSize,
1857 MV_NumberOfBuffers,
1858 MV_RequestedMixRate,
1859 MV_MixMode,
1860 MV_ServiceVoc );
1861
1862 if ( status != DSL_Ok )
1863 {
1864 MV_SetErrorCode( MV_BlasterError );
1865 return( MV_Error );
1866 }
1867
1868 MV_MixRate = DSL_GetPlaybackRate();
1869
1870 return( MV_Ok );
1871 }
1872
1873
1874/*---------------------------------------------------------------------
1875 Function: MV_StopPlayback
1876
1877 Stops the sound playback engine.
1878---------------------------------------------------------------------*/
1879
1880void MV_StopPlayback
1881 (
1882 void
1883 )
1884
1885 {
1886 VoiceNode *voice;
1887 VoiceNode *next;
1888 unsigned flags;
1889
1890#ifdef PLAT_DOS
1891 // Stop sound playback
1892 switch( MV_SoundCard )
1893 {
1894 case SoundBlaster :
1895 case Awe32 :
1896 BLASTER_StopPlayback();
1897 break;
1898
1899 case UltraSound :
1900 GUSWAVE_KillAllVoices();
1901 break;
1902
1903 case ProAudioSpectrum :
1904 case SoundMan16 :
1905 PAS_StopPlayback();
1906 break;
1907
1908 case SoundScape :
1909 SOUNDSCAPE_StopPlayback();
1910 break;
1911
1912 #ifndef SOUNDSOURCE_OFF
1913 case SoundSource :
1914 case TandySoundSource :
1915 SS_StopPlayback();
1916 break;
1917 #endif
1918 }
1919#else
1920 DSL_StopPlayback();
1921#endif
1922
1923 // Make sure all callbacks are done.
1924 flags = DisableInterrupts();
1925
1926 for( voice = VoiceList.next; voice != &VoiceList; voice = next )
1927 {
1928 next = voice->next;
1929
1930 MV_StopVoice( voice );
1931
1932 if ( MV_CallBackFunc )
1933 {
1934 MV_CallBackFunc( voice->callbackval );
1935 }
1936 }
1937
1938 RestoreInterrupts( flags );
1939 }
1940
1941
1942/*---------------------------------------------------------------------
1943 Function: MV_StartRecording
1944
1945 Starts the sound recording engine.
1946---------------------------------------------------------------------*/
1947
1948int MV_StartRecording
1949 (
1950 int MixRate,
1951 void ( *function )( char *ptr, int length )
1952 )
1953
1954 {
1955#ifdef PLAT_DOS
1956 int status;
1957
1958 switch( MV_SoundCard )
1959 {
1960 case SoundBlaster :
1961 case Awe32 :
1962 case ProAudioSpectrum :
1963 case SoundMan16 :
1964 break;
1965
1966 default :
1967 MV_SetErrorCode( MV_UnsupportedCard );
1968 return( MV_Error );
1969 break;
1970 }
1971
1972 if ( function == NULL )
1973 {
1974 MV_SetErrorCode( MV_NullRecordFunction );
1975 return( MV_Error );
1976 }
1977
1978 MV_StopPlayback();
1979
1980 // Initialize the buffers
1981 ClearBuffer_DW( MV_MixBuffer[ 0 ], SILENCE_8BIT, TotalBufferSize >> 2 );
1982
1983 // Set the mix buffer variables
1984 MV_MixPage = 0;
1985
1986 MV_RecordFunc = function;
1987
1988 // Start playback
1989 switch( MV_SoundCard )
1990 {
1991 case SoundBlaster :
1992 case Awe32 :
1993 status = BLASTER_BeginBufferedRecord( MV_MixBuffer[ 0 ],
1994 TotalBufferSize, NumberOfBuffers, MixRate, MONO_8BIT,
1995 MV_ServiceRecord );
1996
1997 if ( status != BLASTER_Ok )
1998 {
1999 MV_SetErrorCode( MV_BlasterError );
2000 return( MV_Error );
2001 }
2002 break;
2003
2004 case ProAudioSpectrum :
2005 case SoundMan16 :
2006 status = PAS_BeginBufferedRecord( MV_MixBuffer[ 0 ],
2007 TotalBufferSize, NumberOfBuffers, MixRate, MONO_8BIT,
2008 MV_ServiceRecord );
2009
2010 if ( status != PAS_Ok )
2011 {
2012 MV_SetErrorCode( MV_PasError );
2013 return( MV_Error );
2014 }
2015 break;
2016 }
2017
2018 MV_Recording = TRUE;
2019 return( MV_Ok );
2020#else
2021 MV_SetErrorCode( MV_UnsupportedCard );
2022 return( MV_Error );
2023#endif
2024 }
2025
2026
2027/*---------------------------------------------------------------------
2028 Function: MV_StopRecord
2029
2030 Stops the sound record engine.
2031---------------------------------------------------------------------*/
2032
2033void MV_StopRecord
2034 (
2035 void
2036 )
2037
2038 {
2039#ifdef PLAT_DOS
2040 // Stop sound playback
2041 switch( MV_SoundCard )
2042 {
2043 case SoundBlaster :
2044 case Awe32 :
2045 BLASTER_StopPlayback();
2046 break;
2047
2048 case ProAudioSpectrum :
2049 case SoundMan16 :
2050 PAS_StopPlayback();
2051 break;
2052 }
2053
2054 MV_Recording = FALSE;
2055 MV_StartPlayback();
2056#endif
2057 }
2058
2059
2060/*---------------------------------------------------------------------
2061 Function: MV_StartDemandFeedPlayback
2062
2063 Plays a digitized sound from a user controlled buffering system.
2064---------------------------------------------------------------------*/
2065
2066int MV_StartDemandFeedPlayback
2067 (
2068 void ( *function )( char **ptr, uint32_t *length ),
2069 int rate,
2070 int pitchoffset,
2071 int vol,
2072 int left,
2073 int right,
2074 int priority,
2075 unsigned long callbackval
2076 )
2077
2078 {
2079 VoiceNode *voice;
2080
2081 if ( !MV_Installed )
2082 {
2083 MV_SetErrorCode( MV_NotInstalled );
2084 return( MV_Error );
2085 }
2086
2087 // Request a voice from the voice pool
2088 voice = MV_AllocVoice( priority );
2089 if ( voice == NULL )
2090 {
2091 MV_SetErrorCode( MV_NoVoices );
2092 return( MV_Error );
2093 }
2094
2095 voice->wavetype = DemandFeed;
2096 voice->bits = 8;
2097 voice->GetSound = MV_GetNextDemandFeedBlock;
2098 voice->NextBlock = NULL;
2099 voice->DemandFeed = function;
2100 voice->LoopStart = NULL;
2101 voice->LoopCount = 0;
2102 voice->GLast = -1;
2103 voice->GPos = 0;
2104 voice->GVal[0] = 0;
2105 voice->GVal[1] = 0;
2106 voice->GVal[2] = 0;
2107 voice->GVal[3] = 0;
2108 voice->BlockLength = 0;
2109 voice->position = 0;
2110 voice->sound = NULL;
2111 voice->length = 0;
2112 voice->BlockLength = 0;
2113 voice->Playing = TRUE;
2114 voice->next = NULL;
2115 voice->prev = NULL;
2116 voice->priority = priority;
2117 voice->callbackval = callbackval;
2118
2119 MV_SetVoicePitch( voice, rate, pitchoffset );
2120 MV_SetVoiceVolume( voice, vol, left, right );
2121 MV_PlayVoice( voice );
2122
2123 return( voice->handle );
2124 }
2125
2126
2127/*---------------------------------------------------------------------
2128 Function: MV_PlayRaw
2129
2130 Begin playback of sound data with the given sound levels and
2131 priority.
2132---------------------------------------------------------------------*/
2133
2134int MV_PlayRaw
2135 (
2136 uint8_t *ptr,
2137 unsigned long length,
2138 unsigned rate,
2139 int pitchoffset,
2140 int vol,
2141 int left,
2142 int right,
2143 int priority,
2144 unsigned long callbackval
2145 )
2146
2147 {
2148 int status;
2149
2150 status = MV_PlayLoopedRaw( ptr, length, NULL, NULL, rate, pitchoffset,
2151 vol, left, right, priority, callbackval );
2152
2153 return( status );
2154 }
2155
2156
2157/*---------------------------------------------------------------------
2158 Function: MV_PlayLoopedRaw
2159
2160 Begin playback of sound data with the given sound levels and
2161 priority.
2162---------------------------------------------------------------------*/
2163
2164int MV_PlayLoopedRaw
2165 (
2166 uint8_t *ptr,
2167 unsigned long length,
2168 uint8_t *loopstart,
2169 uint8_t *loopend,
2170 unsigned rate,
2171 int pitchoffset,
2172 int vol,
2173 int left,
2174 int right,
2175 int priority,
2176 unsigned long callbackval
2177 )
2178
2179 {
2180 VoiceNode *voice;
2181
2182 if ( !MV_Installed )
2183 {
2184 MV_SetErrorCode( MV_NotInstalled );
2185 return( MV_Error );
2186 }
2187
2188 // Request a voice from the voice pool
2189 voice = MV_AllocVoice( priority );
2190 if ( voice == NULL )
2191 {
2192 MV_SetErrorCode( MV_NoVoices );
2193 return( MV_Error );
2194 }
2195
2196 voice->wavetype = Raw;
2197 voice->bits = 8;
2198 voice->GetSound = MV_GetNextRawBlock;
2199 voice->Playing = TRUE;
2200 voice->NextBlock = ptr;
2201 voice->position = 0;
2202 voice->BlockLength = length;
2203 voice->length = 0;
2204 voice->next = NULL;
2205 voice->prev = NULL;
2206 voice->priority = priority;
2207 voice->GLast = -1;
2208 voice->GPos = 0;
2209 voice->GVal[0] = 0;
2210 voice->GVal[1] = 0;
2211 voice->GVal[2] = 0;
2212 voice->GVal[3] = 0;
2213 voice->callbackval = callbackval;
2214 voice->LoopStart = loopstart;
2215 voice->LoopEnd = loopend;
2216 voice->LoopSize = ( voice->LoopEnd - voice->LoopStart ) + 1;
2217
2218 MV_SetVoicePitch( voice, rate, pitchoffset );
2219 MV_SetVoiceVolume( voice, vol, left, right );
2220 MV_PlayVoice( voice );
2221
2222 return( voice->handle );
2223 }
2224
2225
2226/*---------------------------------------------------------------------
2227 Function: MV_PlayWAV
2228
2229 Begin playback of sound data with the given sound levels and
2230 priority.
2231---------------------------------------------------------------------*/
2232
2233int MV_PlayWAV
2234 (
2235 uint8_t *ptr,
2236 int pitchoffset,
2237 int vol,
2238 int left,
2239 int right,
2240 int priority,
2241 unsigned long callbackval
2242 )
2243
2244 {
2245 int status;
2246
2247 status = MV_PlayLoopedWAV( ptr, -1, -1, pitchoffset, vol, left, right,
2248 priority, callbackval );
2249
2250 return( status );
2251 }
2252
2253
2254/*---------------------------------------------------------------------
2255 Function: MV_PlayWAV3D
2256
2257 Begin playback of sound data at specified angle and distance
2258 from listener.
2259---------------------------------------------------------------------*/
2260
2261int MV_PlayWAV3D
2262 (
2263 uint8_t *ptr,
2264 int pitchoffset,
2265 int angle,
2266 int distance,
2267 int priority,
2268 unsigned long callbackval
2269 )
2270
2271 {
2272 int left;
2273 int right;
2274 int mid;
2275 int volume;
2276 int status;
2277
2278 if ( !MV_Installed )
2279 {
2280 MV_SetErrorCode( MV_NotInstalled );
2281 return( MV_Error );
2282 }
2283
2284 if ( distance < 0 )
2285 {
2286 distance = -distance;
2287 angle += MV_NumPanPositions / 2;
2288 }
2289
2290 volume = MIX_VOLUME( distance );
2291
2292 // Ensure angle is within 0 - 31
2293 angle &= MV_MaxPanPosition;
2294
2295 left = MV_PanTable[ angle ][ volume ].left;
2296 right = MV_PanTable[ angle ][ volume ].right;
2297 mid = max( 0, 255 - distance );
2298
2299 status = MV_PlayWAV( ptr, pitchoffset, mid, left, right, priority,
2300 callbackval );
2301
2302 return( status );
2303 }
2304
2305
2306/*---------------------------------------------------------------------
2307 Function: MV_PlayLoopedWAV
2308
2309 Begin playback of sound data with the given sound levels and
2310 priority.
2311---------------------------------------------------------------------*/
2312
2313int MV_PlayLoopedWAV
2314 (
2315 uint8_t *ptr,
2316 long loopstart,
2317 long loopend,
2318 int pitchoffset,
2319 int vol,
2320 int left,
2321 int right,
2322 int priority,
2323 unsigned long callbackval
2324 )
2325
2326 {
2327 riff_header *riff;
2328 format_header *format;
2329 data_header *data;
2330 VoiceNode *voice;
2331 int length;
2332 int absloopend;
2333 int absloopstart;
2334
2335 if ( !MV_Installed )
2336 {
2337 MV_SetErrorCode( MV_NotInstalled );
2338 return( MV_Error );
2339 }
2340
2341 riff = ( riff_header * )ptr;
2342
2343 if ( ( strncmp( riff->RIFF, "RIFF", 4 ) != 0 ) ||
2344 ( strncmp( riff->WAVE, "WAVE", 4 ) != 0 ) ||
2345 ( strncmp( riff->fmt, "fmt ", 4) != 0 ) )
2346 {
2347 MV_SetErrorCode( MV_InvalidWAVFile );
2348 return( MV_Error );
2349 }
2350
2351 format = ( format_header * )( riff + 1 );
2352 data = ( data_header * )( ( ( char * )format ) + riff->format_size );
2353
2354 // Check if it's PCM data.
2355 if ( format->wFormatTag != 1 )
2356 {
2357 MV_SetErrorCode( MV_InvalidWAVFile );
2358 return( MV_Error );
2359 }
2360
2361 if ( format->nChannels != 1 )
2362 {
2363 MV_SetErrorCode( MV_InvalidWAVFile );
2364 return( MV_Error );
2365 }
2366
2367 if ( ( format->nBitsPerSample != 8 ) &&
2368 ( format->nBitsPerSample != 16 ) )
2369 {
2370 MV_SetErrorCode( MV_InvalidWAVFile );
2371 return( MV_Error );
2372 }
2373
2374 if ( strncmp( data->DATA, "data", 4 ) != 0 )
2375 {
2376 MV_SetErrorCode( MV_InvalidWAVFile );
2377 return( MV_Error );
2378 }
2379
2380 // Request a voice from the voice pool
2381 voice = MV_AllocVoice( priority );
2382 if ( voice == NULL )
2383 {
2384 MV_SetErrorCode( MV_NoVoices );
2385 return( MV_Error );
2386 }
2387
2388 voice->wavetype = WAV;
2389 voice->bits = format->nBitsPerSample;
2390 voice->GetSound = MV_GetNextWAVBlock;
2391
2392 length = data->size;
2393 absloopstart = loopstart;
2394 absloopend = loopend;
2395 if ( voice->bits == 16 )
2396 {
2397 loopstart *= 2;
2398 data->size &= ~1;
2399 loopend *= 2;
2400 length /= 2;
2401 }
2402
2403 loopend = min( loopend, data->size );
2404 absloopend = min( absloopend, length );
2405
2406 voice->Playing = TRUE;
2407 voice->DemandFeed = NULL;
2408 voice->LoopStart = NULL;
2409 voice->LoopCount = 0;
2410 voice->position = 0;
2411 voice->length = 0;
2412 voice->BlockLength = absloopend;
2413 voice->NextBlock = ( char * )( data + 1 );
2414 voice->next = NULL;
2415 voice->prev = NULL;
2416 voice->priority = priority;
2417 voice->GLast = -1;
2418 voice->GPos = 0;
2419 voice->GVal[0] = 0;
2420 voice->GVal[1] = 0;
2421 voice->GVal[2] = 0;
2422 voice->GVal[3] = 0;
2423 voice->callbackval = callbackval;
2424 voice->LoopStart = voice->NextBlock + loopstart;
2425 voice->LoopEnd = voice->NextBlock + loopend;
2426 voice->LoopSize = absloopend - absloopstart;
2427
2428 if ( ( loopstart >= data->size ) || ( loopstart < 0 ) )
2429 {
2430 voice->LoopStart = NULL;
2431 voice->LoopEnd = NULL;
2432 voice->BlockLength = length;
2433 }
2434
2435 MV_SetVoicePitch( voice, format->nSamplesPerSec, pitchoffset );
2436 MV_SetVoiceVolume( voice, vol, left, right );
2437 MV_PlayVoice( voice );
2438
2439 return( voice->handle );
2440 }
2441
2442
2443/*---------------------------------------------------------------------
2444 Function: MV_PlayVOC3D
2445
2446 Begin playback of sound data at specified angle and distance
2447 from listener.
2448---------------------------------------------------------------------*/
2449
2450int MV_PlayVOC3D
2451 (
2452 uint8_t *ptr,
2453 int pitchoffset,
2454 int angle,
2455 int distance,
2456 int priority,
2457 unsigned long callbackval
2458 )
2459
2460 {
2461 int left;
2462 int right;
2463 int mid;
2464 int volume;
2465 int status;
2466
2467 if ( !MV_Installed )
2468 {
2469 MV_SetErrorCode( MV_NotInstalled );
2470 return( MV_Error );
2471 }
2472
2473 if ( distance < 0 )
2474 {
2475 distance = -distance;
2476 angle += MV_NumPanPositions / 2;
2477 }
2478
2479 volume = MIX_VOLUME( distance );
2480
2481 // Ensure angle is within 0 - 31
2482 angle &= MV_MaxPanPosition;
2483
2484 left = MV_PanTable[ angle ][ volume ].left;
2485 right = MV_PanTable[ angle ][ volume ].right;
2486 mid = max( 0, 255 - distance );
2487
2488 status = MV_PlayVOC( ptr, pitchoffset, mid, left, right, priority,
2489 callbackval );
2490
2491 return( status );
2492 }
2493
2494
2495/*---------------------------------------------------------------------
2496 Function: MV_PlayVOC
2497
2498 Begin playback of sound data with the given sound levels and
2499 priority.
2500---------------------------------------------------------------------*/
2501
2502int MV_PlayVOC
2503 (
2504 uint8_t *ptr,
2505 int pitchoffset,
2506 int vol,
2507 int left,
2508 int right,
2509 int priority,
2510 unsigned long callbackval
2511 )
2512
2513 {
2514 int status;
2515
2516 status = MV_PlayLoopedVOC( ptr, -1, -1, pitchoffset, vol, left, right,
2517 priority, callbackval );
2518
2519 return( status );
2520 }
2521
2522
2523/*---------------------------------------------------------------------
2524 Function: MV_PlayLoopedVOC
2525
2526 Begin playback of sound data with the given sound levels and
2527 priority.
2528---------------------------------------------------------------------*/
2529
2530int MV_PlayLoopedVOC
2531 (
2532 uint8_t *ptr,
2533 long loopstart,
2534 long loopend,
2535 int pitchoffset,
2536 int vol,
2537 int left,
2538 int right,
2539 int priority,
2540 uint32_t callbackval
2541 )
2542
2543 {
2544 VoiceNode *voice;
2545 int status;
2546
2547 if ( !MV_Installed )
2548 {
2549 MV_SetErrorCode( MV_NotInstalled );
2550 return( MV_Error );
2551 }
2552
2553 // Make sure it's a valid VOC file.
2554 status = strncmp( (char*)ptr, "Creative Voice File", 19 );
2555 if ( status != 0 )
2556 {
2557 MV_SetErrorCode( MV_InvalidVOCFile );
2558 return( MV_Error );
2559 }
2560
2561 // Request a voice from the voice pool
2562 voice = MV_AllocVoice( priority );
2563 if ( voice == NULL )
2564 {
2565 MV_SetErrorCode( MV_NoVoices );
2566 return( MV_Error );
2567 }
2568
2569 voice->wavetype = VOC;
2570 voice->bits = 8;
2571 voice->GetSound = MV_GetNextVOCBlock;
2572 voice->NextBlock = ptr + readLE16( ptr + 0x14 );
2573 voice->DemandFeed = NULL;
2574 voice->LoopStart = NULL;
2575 voice->LoopCount = 0;
2576 voice->BlockLength = 0;
2577 voice->PitchScale = PITCH_GetScale( pitchoffset );
2578 voice->length = 0;
2579 voice->next = NULL;
2580 voice->prev = NULL;
2581 voice->priority = priority;
2582 voice->GLast = -1;
2583 voice->GPos = 0;
2584 voice->GVal[0] = 0;
2585 voice->GVal[1] = 0;
2586 voice->GVal[2] = 0;
2587 voice->GVal[3] = 0;
2588 voice->callbackval = callbackval;
2589 voice->LoopStart = ( char * )loopstart;
2590 voice->LoopEnd = ( char * )loopend;
2591 voice->LoopSize = loopend - loopstart + 1;
2592
2593 if ( loopstart < 0 )
2594 {
2595 voice->LoopStart = NULL;
2596 voice->LoopEnd = NULL;
2597 }
2598
2599 MV_SetVoiceVolume( voice, vol, left, right );
2600 MV_PlayVoice( voice );
2601
2602 return( voice->handle );
2603 }
2604
2605
2606/*---------------------------------------------------------------------
2607 Function: MV_LockEnd
2608
2609 Used for determining the length of the functions to lock in memory.
2610---------------------------------------------------------------------*/
2611
2612static void MV_LockEnd
2613 (
2614 void
2615 )
2616
2617 {
2618 }
2619
2620#if 0
2621/*---------------------------------------------------------------------
2622 Function: MV_CreateVolumeTable
2623
2624 Create the table used to convert sound data to a specific volume
2625 level.
2626---------------------------------------------------------------------*/
2627
2628void MV_CreateVolumeTable
2629 (
2630 int index,
2631 int volume,
2632 int MaxVolume
2633 )
2634
2635 {
2636 int val;
2637 int level;
2638 int i;
2639
2640 level = ( volume * MaxVolume ) / MV_MaxTotalVolume;
2641 if ( MV_Bits == 16 )
2642 {
2643 for( i = 0; i < 65536; i += 256 )
2644 {
2645 val = i - 0x8000;
2646 val *= level;
2647 val /= MV_MaxVolume;
2648 MV_VolumeTable[ index ][ i / 256 ] = val;
2649 }
2650 }
2651 else
2652 {
2653 for( i = 0; i < 256; i++ )
2654 {
2655 val = i - 0x80;
2656 val *= level;
2657 val /= MV_MaxVolume;
2658 MV_VolumeTable[ volume ][ i ] = val;
2659 }
2660 }
2661 }
2662#endif
2663
2664/*---------------------------------------------------------------------
2665 Function: MV_CalcVolume
2666
2667 Create the table used to convert sound data to a specific volume
2668 level.
2669---------------------------------------------------------------------*/
2670
2671void MV_CalcVolume(int MaxVolume)
2672 {
2673 }
2674
2675
2676/*---------------------------------------------------------------------
2677 Function: MV_CalcPanTable
2678
2679 Create the table used to determine the stereo volume level of
2680 a sound located at a specific angle and distance from the listener.
2681---------------------------------------------------------------------*/
2682
2683void MV_CalcPanTable
2684 (
2685 void
2686 )
2687
2688 {
2689 int level;
2690 int angle;
2691 int distance;
2692 int HalfAngle;
2693 int ramp;
2694
2695 HalfAngle = ( MV_NumPanPositions / 2 );
2696
2697 for( distance = 0; distance <= MV_MaxVolume; distance++ )
2698 {
2699 level = ( 255 * ( MV_MaxVolume - distance ) ) / MV_MaxVolume;
2700 for( angle = 0; angle <= HalfAngle / 2; angle++ )
2701 {
2702 ramp = level - ( ( level * angle ) /
2703 ( MV_NumPanPositions / 4 ) );
2704
2705 MV_PanTable[ angle ][ distance ].left = ramp;
2706 MV_PanTable[ HalfAngle - angle ][ distance ].left = ramp;
2707 MV_PanTable[ HalfAngle + angle ][ distance ].left = level;
2708 MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].left = level;
2709
2710 MV_PanTable[ angle ][ distance ].right = level;
2711 MV_PanTable[ HalfAngle - angle ][ distance ].right = level;
2712 MV_PanTable[ HalfAngle + angle ][ distance ].right = ramp;
2713 MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].right = ramp;
2714 }
2715 }
2716 }
2717
2718
2719/*---------------------------------------------------------------------
2720 Function: MV_SetVolume
2721
2722 Sets the volume of digitized sound playback.
2723---------------------------------------------------------------------*/
2724
2725void MV_SetVolume
2726 (
2727 int volume
2728 )
2729
2730 {
2731 volume = max( 0, volume );
2732 volume = min( volume, MV_MaxTotalVolume );
2733
2734 MV_TotalVolume = volume;
2735
2736 // Calculate volume table
2737 MV_CalcVolume( volume );
2738 }
2739
2740
2741/*---------------------------------------------------------------------
2742 Function: MV_GetVolume
2743
2744 Returns the volume of digitized sound playback.
2745---------------------------------------------------------------------*/
2746
2747int MV_GetVolume
2748 (
2749 void
2750 )
2751
2752 {
2753 return( MV_TotalVolume );
2754 }
2755
2756
2757/*---------------------------------------------------------------------
2758 Function: MV_SetCallBack
2759
2760 Set the function to call when a voice stops.
2761---------------------------------------------------------------------*/
2762
2763void MV_SetCallBack
2764 (
2765 void ( *function )( int32_t )
2766 )
2767
2768 {
2769 MV_CallBackFunc = function;
2770 }
2771
2772
2773/*---------------------------------------------------------------------
2774 Function: MV_SetReverseStereo
2775
2776 Set the orientation of the left and right channels.
2777---------------------------------------------------------------------*/
2778
2779void MV_SetReverseStereo
2780 (
2781 int setting
2782 )
2783
2784 {
2785 MV_SwapLeftRight = setting;
2786 }
2787
2788
2789/*---------------------------------------------------------------------
2790 Function: MV_GetReverseStereo
2791
2792 Returns the orientation of the left and right channels.
2793---------------------------------------------------------------------*/
2794
2795int MV_GetReverseStereo
2796 (
2797 void
2798 )
2799
2800 {
2801 return( MV_SwapLeftRight );
2802 }
2803
2804
2805/*---------------------------------------------------------------------
2806 Function: MV_TestPlayback
2807
2808 Checks if playback has started.
2809---------------------------------------------------------------------*/
2810
2811int MV_TestPlayback
2812 (
2813 void
2814 )
2815
2816 {
2817#ifdef PLAT_DOS
2818 unsigned flags;
2819 long time;
2820 int start;
2821 int status;
2822 int pos;
2823
2824 if ( MV_SoundCard == UltraSound )
2825 {
2826 return( MV_Ok );
2827 }
2828
2829 flags = DisableInterrupts();
2830 _enable();
2831
2832 status = MV_Error;
2833 start = MV_MixPage;
2834 time = clock() + CLOCKS_PER_SEC * 2;
2835
2836 while( clock() < time )
2837 {
2838 if ( MV_MixPage != start )
2839 {
2840 status = MV_Ok;
2841 }
2842 }
2843
2844 RestoreInterrupts( flags );
2845
2846 if ( status != MV_Ok )
2847 {
2848 // Just in case an error doesn't get reported
2849 MV_SetErrorCode( MV_DMAFailure );
2850
2851 switch( MV_SoundCard )
2852 {
2853 case SoundBlaster :
2854 case Awe32 :
2855 pos = BLASTER_GetCurrentPos();
2856 break;
2857
2858 case ProAudioSpectrum :
2859 case SoundMan16 :
2860 pos = PAS_GetCurrentPos();
2861 break;
2862
2863 case SoundScape :
2864 pos = SOUNDSCAPE_GetCurrentPos();
2865 break;
2866
2867 #ifndef SOUNDSOURCE_OFF
2868 case SoundSource :
2869 case TandySoundSource :
2870 MV_SetErrorCode( MV_SoundSourceFailure );
2871 pos = -1;
2872 break;
2873 #endif
2874
2875 default :
2876 MV_SetErrorCode( MV_UnsupportedCard );
2877 pos = -2;
2878 break;
2879 }
2880
2881 if ( pos > 0 )
2882 {
2883 MV_SetErrorCode( MV_IrqFailure );
2884 }
2885 else if ( pos == 0 )
2886 {
2887 if ( MV_Bits == 16 )
2888 {
2889 MV_SetErrorCode( MV_DMA16Failure );
2890 }
2891 else
2892 {
2893 MV_SetErrorCode( MV_DMAFailure );
2894 }
2895 }
2896 }
2897
2898 return( status );
2899#else
2900 return MV_Ok;
2901#endif
2902 }
2903
2904
2905/*---------------------------------------------------------------------
2906 Function: MV_Init
2907
2908 Perform the initialization of variables and memory used by
2909 Multivoc.
2910---------------------------------------------------------------------*/
2911
2912int MV_Init
2913 (
2914 int soundcard,
2915 int MixRate,
2916 int Voices,
2917 int numchannels,
2918 int samplebits
2919 )
2920
2921 {
2922 char *ptr;
2923 int status;
2924 int buffer;
2925 int index;
2926
2927 if ( MV_Installed )
2928 {
2929 MV_Shutdown();
2930 }
2931
2932 MV_SetErrorCode( MV_Ok );
2933
2934 status = MV_LockMemory();
2935 if ( status != MV_Ok )
2936 {
2937 return( status );
2938 }
2939
2940 MV_TotalMemory = Voices * sizeof( VoiceNode ); // + sizeof( HARSH_CLIP_TABLE_8 );
2941 status = USRHOOKS_GetMem( ( void ** )&ptr, MV_TotalMemory );
2942 if ( status != USRHOOKS_Ok )
2943 {
2944 MV_UnlockMemory();
2945 MV_SetErrorCode( MV_NoMem );
2946 return( MV_Error );
2947 }
2948
2949 status = DPMI_LockMemory( ptr, MV_TotalMemory );
2950 if ( status != DPMI_Ok )
2951 {
2952 USRHOOKS_FreeMem( ptr );
2953 MV_UnlockMemory();
2954 MV_SetErrorCode( MV_DPMI_Error );
2955 return( MV_Error );
2956 }
2957
2958 MV_Voices = ( VoiceNode * )ptr;
2959// MV_HarshClipTable = ptr + ( MV_TotalMemory - sizeof( HARSH_CLIP_TABLE_8 ) );
2960
2961 // Set number of voices before calculating volume table
2962 MV_MaxVoices = Voices;
2963
2964 LL_Reset( &VoiceList, next, prev );
2965 LL_Reset( &VoicePool, next, prev );
2966
2967 for( index = 0; index < Voices; index++ )
2968 {
2969 LL_Add( &VoicePool, &MV_Voices[ index ], next, prev );
2970 }
2971
2972 // Allocate mix buffer within 1st megabyte
2973 status = DPMI_GetDOSMemory( ( void ** )&ptr, &MV_BufferDescriptor,
2974 2 * TotalBufferSize);
2975
2976 if ( status )
2977 {
2978 DPMI_UnlockMemory( MV_Voices, MV_TotalMemory );
2979 USRHOOKS_FreeMem( MV_Voices );
2980 MV_Voices = NULL;
2981 MV_TotalMemory = 0;
2982 MV_UnlockMemory();
2983
2984 MV_SetErrorCode( MV_NoMem );
2985 return( MV_Error );
2986 }
2987
2988 MV_SetReverseStereo( FALSE );
2989
2990 // Initialize the sound card
2991#ifdef PLAT_DOS
2992 switch( soundcard )
2993 {
2994 case UltraSound :
2995 status = GUSWAVE_Init( 2 );
2996 if ( status != GUSWAVE_Ok )
2997 {
2998 //JIM
2999 MV_SetErrorCode( MV_BlasterError );
3000 }
3001 break;
3002
3003 case SoundBlaster :
3004 case Awe32 :
3005 status = BLASTER_Init();
3006 if ( status != BLASTER_Ok )
3007 {
3008 MV_SetErrorCode( MV_BlasterError );
3009 }
3010
3011 if ( ( BLASTER_Config.Type == SBPro ) ||
3012 ( BLASTER_Config.Type == SBPro2 ) )
3013 {
3014 MV_SetReverseStereo( TRUE );
3015 }
3016 break;
3017
3018 case ProAudioSpectrum :
3019 case SoundMan16 :
3020 status = PAS_Init();
3021 if ( status != PAS_Ok )
3022 {
3023 MV_SetErrorCode( MV_PasError );
3024 }
3025 break;
3026
3027 case SoundScape :
3028 status = SOUNDSCAPE_Init();
3029 if ( status != SOUNDSCAPE_Ok )
3030 {
3031 MV_SetErrorCode( MV_SoundScapeError );
3032 }
3033 break;
3034
3035 #ifndef SOUNDSOURCE_OFF
3036 case SoundSource :
3037 case TandySoundSource :
3038 status = SS_Init( soundcard );
3039 if ( status != SS_Ok )
3040 {
3041 MV_SetErrorCode( MV_SoundSourceError );
3042 }
3043 break;
3044 #endif
3045
3046 default :
3047 MV_SetErrorCode( MV_UnsupportedCard );
3048 break;
3049 }
3050#else
3051 status = DSL_Init();
3052 if ( status != DSL_Ok )
3053 {
3054 MV_SetErrorCode( MV_BlasterError );
3055 }
3056#endif
3057
3058 if ( MV_ErrorCode != MV_Ok )
3059 {
3060 status = MV_ErrorCode;
3061
3062 DPMI_UnlockMemory( MV_Voices, MV_TotalMemory );
3063 USRHOOKS_FreeMem( MV_Voices );
3064 MV_Voices = NULL;
3065 MV_TotalMemory = 0;
3066
3067 DPMI_FreeDOSMemory( MV_BufferDescriptor );
3068 MV_UnlockMemory();
3069
3070 MV_SetErrorCode( status );
3071 return( MV_Error );
3072 }
3073
3074 MV_SoundCard = soundcard;
3075 MV_Installed = TRUE;
3076 MV_CallBackFunc = NULL;
3077 MV_RecordFunc = NULL;
3078 MV_Recording = FALSE;
3079 MV_ReverbLevel = 0;
3080 MV_ReverbTable = -1;
3081
3082 // Set the sampling rate
3083 MV_RequestedMixRate = MixRate;
3084
3085 // Set Mixer to play stereo digitized sound
3086 MV_SetMixMode( numchannels, samplebits );
3087 MV_ReverbDelay = 14320; // MV_BufferSize * 3;
3088 //InitializeCriticalSection(&reverbCS);
3089 reverbMutex = SDL_CreateMutex();
3090
3091#ifdef PLAT_DOS
3092 // Make sure we don't cross a physical page
3093 if ( ( ( unsigned long )ptr & 0xffff ) + TotalBufferSize > 0x10000 )
3094 {
3095 ptr = ( char * )( ( ( unsigned long )ptr & 0xff0000 ) + 0x10000 );
3096 }
3097#endif
3098
3099 MV_MixBuffer[ MV_NumberOfBuffers ] = ptr;
3100 for( buffer = 0; buffer < MV_NumberOfBuffers; buffer++ )
3101 {
3102 MV_MixBuffer[ buffer ] = ptr;
3103 ptr += MV_BufferSize;
3104 }
3105
3106 // Calculate pan table
3107 MV_CalcPanTable();
3108
3109 MV_SetVolume( MV_MaxTotalVolume );
3110
3111
3112 MV_FooMemory = sizeof(double) * MixBufferSize * numchannels + 1024;
3113 status = USRHOOKS_GetMem( ( void ** )&ptr, MV_FooMemory);
3114 if ( status != USRHOOKS_Ok )
3115 {
3116 DPMI_UnlockMemory( MV_Voices, MV_TotalMemory );
3117 USRHOOKS_FreeMem( MV_Voices );
3118 MV_Voices = NULL;
3119 MV_TotalMemory = 0;
3120 MV_UnlockMemory();
3121 MV_SetErrorCode( MV_NoMem );
3122 return( MV_Error);
3123 }
3124
3125 status = DPMI_LockMemory( ptr, MV_FooMemory );
3126 if ( status != DPMI_Ok )
3127 {
3128 USRHOOKS_FreeMem( ptr );
3129 DPMI_UnlockMemory( MV_Voices, MV_TotalMemory );
3130 USRHOOKS_FreeMem( MV_Voices );
3131 MV_Voices = NULL;
3132 MV_TotalMemory = 0;
3133 MV_UnlockMemory();
3134 MV_SetErrorCode( MV_DPMI_Error );
3135 return( MV_Error );
3136 }
3137
3138 MV_FooBuffer = ptr;
3139
3140// Start the playback engine
3141 status = MV_StartPlayback();
3142 if ( status != MV_Ok )
3143 {
3144 // Preserve error code while we shutdown.
3145 status = MV_ErrorCode;
3146 MV_Shutdown();
3147 MV_SetErrorCode( status );
3148 return( MV_Error );
3149 }
3150
3151 if ( MV_TestPlayback() != MV_Ok )
3152 {
3153 status = MV_ErrorCode;
3154 MV_Shutdown();
3155 MV_SetErrorCode( status );
3156 return( MV_Error );
3157 }
3158
3159 return( MV_Ok );
3160 }
3161
3162
3163/*---------------------------------------------------------------------
3164 Function: MV_Shutdown
3165
3166 Restore any resources allocated by Multivoc back to the system.
3167---------------------------------------------------------------------*/
3168
3169int MV_Shutdown
3170 (
3171 void
3172 )
3173
3174 {
3175 int buffer;
3176 unsigned flags;
3177
3178 if ( !MV_Installed )
3179 {
3180 return( MV_Ok );
3181 }
3182
3183 flags = DisableInterrupts();
3184
3185 MV_KillAllVoices();
3186
3187 MV_Installed = FALSE;
3188
3189 // Stop the sound recording engine
3190 if ( MV_Recording )
3191 {
3192 MV_StopRecord();
3193 }
3194
3195 // Stop the sound playback engine
3196 MV_StopPlayback();
3197
3198 // Free reverb buffer, if allocated
3199 MV_FPReverbFree();
3200 //DeleteCriticalSection(&reverbCS);
3201 SDL_DestroyMutex(reverbMutex);
3202
3203 // Shutdown the sound card
3204#ifdef PLAT_DOS
3205 switch( MV_SoundCard )
3206 {
3207 case UltraSound :
3208 GUSWAVE_Shutdown();
3209 break;
3210
3211 case SoundBlaster :
3212 case Awe32 :
3213 BLASTER_Shutdown();
3214 break;
3215
3216 case ProAudioSpectrum :
3217 case SoundMan16 :
3218 PAS_Shutdown();
3219 break;
3220
3221 case SoundScape :
3222 SOUNDSCAPE_Shutdown();
3223 break;
3224
3225 #ifndef SOUNDSOURCE_OFF
3226 case SoundSource :
3227 case TandySoundSource :
3228 SS_Shutdown();
3229 break;
3230 #endif
3231 }
3232#else
3233 DSL_Shutdown();
3234#endif
3235
3236 RestoreInterrupts( flags );
3237
3238 // Free any voices we allocated
3239 DPMI_UnlockMemory( MV_FooBuffer, MV_FooMemory );
3240 USRHOOKS_FreeMem( MV_FooBuffer );
3241 MV_FooBuffer = NULL;
3242 MV_FooMemory = 0;
3243
3244 DPMI_UnlockMemory( MV_Voices, MV_TotalMemory );
3245 USRHOOKS_FreeMem( MV_Voices );
3246 MV_Voices = NULL;
3247 MV_TotalMemory = 0;
3248
3249 LL_Reset( &VoiceList, next, prev );
3250 LL_Reset( &VoicePool, next, prev );
3251
3252 MV_MaxVoices = 1;
3253
3254 // Release the descriptor from our mix buffer
3255 DPMI_FreeDOSMemory( MV_BufferDescriptor );
3256 for( buffer = 0; buffer < NumberOfBuffers; buffer++ )
3257 {
3258 MV_MixBuffer[ buffer ] = NULL;
3259 }
3260
3261 return( MV_Ok );
3262 }
3263
3264
3265/*---------------------------------------------------------------------
3266 Function: MV_UnlockMemory
3267
3268 Unlocks all neccessary data.
3269---------------------------------------------------------------------*/
3270
3271void MV_UnlockMemory
3272 (
3273 void
3274 )
3275
3276 {
3277 PITCH_UnlockMemory();
3278
3279 DPMI_UnlockMemoryRegion( MV_LockStart, MV_LockEnd );
3280// DPMI_Unlock( MV_VolumeTable );
3281 DPMI_Unlock( MV_PanTable );
3282 DPMI_Unlock( MV_Installed );
3283 DPMI_Unlock( MV_SoundCard );
3284 DPMI_Unlock( MV_TotalVolume );
3285 DPMI_Unlock( MV_MaxVoices );
3286 DPMI_Unlock( MV_BufferSize );
3287 DPMI_Unlock( MV_BufferLength );
3288 DPMI_Unlock( MV_SampleSize );
3289 DPMI_Unlock( MV_NumberOfBuffers );
3290 DPMI_Unlock( MV_MixMode );
3291 DPMI_Unlock( MV_Channels );
3292 DPMI_Unlock( MV_Bits );
3293 DPMI_Unlock( MV_Silence );
3294 DPMI_Unlock( MV_SwapLeftRight );
3295 DPMI_Unlock( MV_RequestedMixRate );
3296 DPMI_Unlock( MV_MixRate );
3297 DPMI_Unlock( MV_BufferDescriptor );
3298 DPMI_Unlock( MV_MixBuffer );
3299 DPMI_Unlock( MV_BufferEmpty );
3300 DPMI_Unlock( MV_Voices );
3301 DPMI_Unlock( MV_FooBuffer );
3302 DPMI_Unlock( VoiceList );
3303 DPMI_Unlock( VoicePool );
3304 DPMI_Unlock( MV_MixPage );
3305 DPMI_Unlock( MV_VoiceHandle );
3306 DPMI_Unlock( MV_CallBackFunc );
3307 DPMI_Unlock( MV_RecordFunc );
3308 DPMI_Unlock( MV_Recording );
3309 DPMI_Unlock( MV_MixFunction );
3310// DPMI_Unlock( MV_HarshClipTable );
3311 DPMI_Unlock( MV_MixDestination );
3312 DPMI_Unlock( MV_LeftVolume );
3313 DPMI_Unlock( MV_RightVolume );
3314 DPMI_Unlock( MV_MixPosition );
3315 DPMI_Unlock( MV_ErrorCode );
3316 DPMI_Unlock( MV_DMAChannel );
3317 DPMI_Unlock( MV_BuffShift );
3318 DPMI_Unlock( MV_ReverbLevel );
3319 DPMI_Unlock( MV_ReverbDelay );
3320 DPMI_Unlock( MV_ReverbTable );
3321 }
3322
3323
3324/*---------------------------------------------------------------------
3325 Function: MV_LockMemory
3326
3327 Locks all neccessary data.
3328---------------------------------------------------------------------*/
3329
3330int MV_LockMemory
3331 (
3332 void
3333 )
3334
3335 {
3336 int status;
3337 int pitchstatus;
3338
3339 status = DPMI_LockMemoryRegion( MV_LockStart, MV_LockEnd );
3340// status |= DPMI_Lock( MV_VolumeTable );
3341 status |= DPMI_Lock( MV_PanTable );
3342 status |= DPMI_Lock( MV_Installed );
3343 status |= DPMI_Lock( MV_SoundCard );
3344 status |= DPMI_Lock( MV_TotalVolume );
3345 status |= DPMI_Lock( MV_MaxVoices );
3346 status |= DPMI_Lock( MV_BufferSize );
3347 status |= DPMI_Lock( MV_BufferLength );
3348 status |= DPMI_Lock( MV_SampleSize );
3349 status |= DPMI_Lock( MV_NumberOfBuffers );
3350 status |= DPMI_Lock( MV_MixMode );
3351 status |= DPMI_Lock( MV_Channels );
3352 status |= DPMI_Lock( MV_Bits );
3353 status |= DPMI_Lock( MV_Silence );
3354 status |= DPMI_Lock( MV_SwapLeftRight );
3355 status |= DPMI_Lock( MV_RequestedMixRate );
3356 status |= DPMI_Lock( MV_MixRate );
3357 status |= DPMI_Lock( MV_BufferDescriptor );
3358 status |= DPMI_Lock( MV_MixBuffer );
3359 status |= DPMI_Lock( MV_BufferEmpty );
3360 status |= DPMI_Lock( MV_Voices );
3361 status |= DPMI_Lock( MV_FooBuffer );
3362 status |= DPMI_Lock( VoiceList );
3363 status |= DPMI_Lock( VoicePool );
3364 status |= DPMI_Lock( MV_MixPage );
3365 status |= DPMI_Lock( MV_VoiceHandle );
3366 status |= DPMI_Lock( MV_CallBackFunc );
3367 status |= DPMI_Lock( MV_RecordFunc );
3368 status |= DPMI_Lock( MV_Recording );
3369 status |= DPMI_Lock( MV_MixFunction );
3370// status |= DPMI_Lock( MV_HarshClipTable );
3371 status |= DPMI_Lock( MV_MixDestination );
3372 status |= DPMI_Lock( MV_LeftVolume );
3373 status |= DPMI_Lock( MV_RightVolume );
3374 status |= DPMI_Lock( MV_MixPosition );
3375 status |= DPMI_Lock( MV_ErrorCode );
3376 status |= DPMI_Lock( MV_DMAChannel );
3377 status |= DPMI_Lock( MV_BuffShift );
3378 status |= DPMI_Lock( MV_ReverbLevel );
3379 status |= DPMI_Lock( MV_ReverbDelay );
3380 status |= DPMI_Lock( MV_ReverbTable );
3381
3382 pitchstatus = PITCH_LockMemory();
3383 if ( ( pitchstatus != PITCH_Ok ) || ( status != DPMI_Ok ) )
3384 {
3385 MV_UnlockMemory();
3386 MV_SetErrorCode( MV_DPMI_Error );
3387 return( MV_Error );
3388 }
3389
3390 return( MV_Ok );
3391 }
3392
3393#ifndef PLAT_DOS
3394void ClearBuffer_DW( void *ptr, unsigned data, int length )
3395{
3396 unsigned *d = (unsigned *)ptr;
3397
3398 while (length--) {
3399 *d = data;
3400
3401 d++;
3402 }
3403}
3404#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/multivoc.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/multivoc.h
new file mode 100644
index 0000000000..6e6dd8e684
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/multivoc.h
@@ -0,0 +1,130 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 file: MULTIVOC.H
22
23 author: James R. Dose
24 date: December 20, 1993
25
26 Public header for MULTIVOC.C
27
28 (c) Copyright 1993 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __MULTIVOC_H
32#define __MULTIVOC_H
33
34//#include <windows.h>
35#include <SDL.h>
36
37// forward declare
38//struct SDL_mutex;
39
40
41#define MV_MinVoiceHandle 1
42
43extern int MV_ErrorCode;
44
45enum MV_Errors
46 {
47 MV_Warning = -2,
48 MV_Error = -1,
49 MV_Ok = 0,
50 MV_UnsupportedCard,
51 MV_NotInstalled,
52 MV_NoVoices,
53 MV_NoMem,
54 MV_VoiceNotFound,
55 MV_BlasterError,
56 MV_PasError,
57 MV_SoundScapeError,
58 MV_SoundSourceError,
59 MV_DPMI_Error,
60 MV_InvalidVOCFile,
61 MV_InvalidWAVFile,
62 MV_InvalidMixMode,
63 MV_SoundSourceFailure,
64 MV_IrqFailure,
65 MV_DMAFailure,
66 MV_DMA16Failure,
67 MV_NullRecordFunction
68 };
69
70char *MV_ErrorString( int ErrorNumber );
71int MV_VoicePlaying( int handle );
72int MV_KillAllVoices( void );
73int MV_Kill( int handle );
74int MV_VoicesPlaying( void );
75int MV_VoiceAvailable( int priority );
76int MV_SetPitch( int handle, int pitchoffset );
77int MV_SetFrequency( int handle, int frequency );
78int MV_EndLooping( int handle );
79int MV_SetPan( int handle, int vol, int left, int right );
80int MV_Pan3D( int handle, int angle, int distance );
81void MV_SetReverb( int reverb );
82void MV_SetFastReverb( int reverb );
83int MV_GetMaxReverbDelay( void );
84int MV_GetReverbDelay( void );
85void MV_SetReverbDelay( int delay );
86int MV_SetMixMode( int numchannels, int samplebits );
87int MV_StartPlayback( void );
88void MV_StopPlayback( void );
89int MV_StartRecording( int MixRate, void ( *function )( char *ptr, int length ) );
90void MV_StopRecord( void );
91int MV_StartDemandFeedPlayback( void ( *function )( char **ptr, uint32_t *length ),
92 int rate, int pitchoffset, int vol, int left, int right,
93 int priority, unsigned long callbackval );
94int MV_PlayRaw( uint8_t *ptr, unsigned long length,
95 unsigned rate, int pitchoffset, int vol, int left,
96 int right, int priority, unsigned long callbackval );
97int MV_PlayLoopedRaw( uint8_t *ptr, unsigned long length,
98 uint8_t *loopstart, uint8_t *loopend, unsigned rate, int pitchoffset,
99 int vol, int left, int right, int priority,
100 unsigned long callbackval );
101int MV_PlayWAV( uint8_t *ptr, int pitchoffset, int vol, int left,
102 int right, int priority, unsigned long callbackval );
103int MV_PlayWAV3D( uint8_t *ptr, int pitchoffset, int angle, int distance,
104 int priority, unsigned long callbackval );
105int MV_PlayLoopedWAV( uint8_t *ptr, long loopstart, long loopend,
106 int pitchoffset, int vol, int left, int right, int priority,
107 unsigned long callbackval );
108int MV_PlayVOC3D( uint8_t *ptr, int pitchoffset, int angle, int distance,
109 int priority, unsigned long callbackval );
110int MV_PlayVOC( uint8_t * ptr, int pitchoffset, int vol, int left, int right,
111 int priority, unsigned long callbackval );
112int MV_PlayLoopedVOC( uint8_t *ptr, long loopstart, long loopend,
113 int pitchoffset, int vol, int left, int right, int priority,
114 uint32_t callbackval );
115void MV_CreateVolumeTable( int index, int volume, int MaxVolume );
116void MV_SetVolume( int volume );
117int MV_GetVolume( void );
118void MV_SetCallBack( void ( *function )( int32_t ) );
119void MV_SetReverseStereo( int setting );
120int MV_GetReverseStereo( void );
121int MV_Init( int soundcard, int MixRate, int Voices, int numchannels,
122 int samplebits );
123int MV_Shutdown( void );
124void MV_UnlockMemory( void );
125int MV_LockMemory( void );
126
127//CRITICAL_SECTION reverbCS;
128SDL_mutex* reverbMutex;
129
130#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/music.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/music.c
new file mode 100644
index 0000000000..e9397e1421
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/music.c
@@ -0,0 +1,1035 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: MUSIC.C
22
23 author: James R. Dose
24 date: March 25, 1994
25
26 Device independant music playback routines.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#include <stdio.h>
32#include <stdlib.h>
33#include "task_man.h"
34#include "sndcards.h"
35#include "music.h"
36#include "midi.h"
37#include "al_midi.h"
38#include "pas16.h"
39#include "blaster.h"
40#include "gusmidi.h"
41#include "mpu401.h"
42#include "awe32.h"
43#include "sndscape.h"
44#include "ll_man.h"
45#include "user.h"
46
47#define TRUE ( 1 == 1 )
48#define FALSE ( !TRUE )
49
50void TextMode( void );
51#pragma aux TextMode = \
52 "mov ax, 0003h", \
53 "int 10h" \
54 modify [ ax ];
55
56int MUSIC_SoundDevice = -1;
57int MUSIC_ErrorCode = MUSIC_Ok;
58
59static midifuncs MUSIC_MidiFunctions;
60
61static int MUSIC_FadeLength;
62static int MUSIC_FadeRate;
63static unsigned MUSIC_CurrentFadeVolume;
64static unsigned MUSIC_LastFadeVolume;
65static int MUSIC_EndingFadeVolume;
66static task *MUSIC_FadeTask = NULL;
67
68int MUSIC_InitAWE32( midifuncs *Funcs );
69int MUSIC_InitFM( int card, midifuncs *Funcs );
70int MUSIC_InitMidi( int card, midifuncs *Funcs, int Address );
71int MUSIC_InitGUS( midifuncs *Funcs );
72
73#define MUSIC_SetErrorCode( status ) \
74 MUSIC_ErrorCode = ( status );
75
76/*---------------------------------------------------------------------
77 Function: MUSIC_ErrorString
78
79 Returns a pointer to the error message associated with an error
80 number. A -1 returns a pointer the current error.
81---------------------------------------------------------------------*/
82
83char *MUSIC_ErrorString
84 (
85 int ErrorNumber
86 )
87
88 {
89 char *ErrorString;
90
91 switch( ErrorNumber )
92 {
93 case MUSIC_Warning :
94 case MUSIC_Error :
95 ErrorString = MUSIC_ErrorString( MUSIC_ErrorCode );
96 break;
97
98 case MUSIC_Ok :
99 ErrorString = "Music ok.";
100 break;
101
102 case MUSIC_ASSVersion :
103 ErrorString = "Apogee Sound System Version " ASS_VERSION_STRING " "
104 "Programmed by Jim Dose\n"
105 "(c) Copyright 1996 James R. Dose. All Rights Reserved.\n";
106 break;
107
108 case MUSIC_SoundCardError :
109 switch( MUSIC_SoundDevice )
110 {
111 case SoundBlaster :
112 case WaveBlaster :
113 ErrorString = BLASTER_ErrorString( BLASTER_Error );
114 break;
115
116 case ProAudioSpectrum :
117 case SoundMan16 :
118 ErrorString = PAS_ErrorString( PAS_Error );
119 break;
120
121 case Adlib :
122 ErrorString = "Adlib error.";
123 break;
124
125 case GenMidi :
126 case SoundCanvas :
127 ErrorString = "Could not detect MPU-401.";
128 break;
129
130 case SoundScape :
131 ErrorString = SOUNDSCAPE_ErrorString( SOUNDSCAPE_Error );
132 break;
133
134 case Awe32 :
135 ErrorString = AWE32_ErrorString( AWE32_Error );
136 break;
137
138 case UltraSound :
139 ErrorString = GUS_ErrorString( GUS_Error );
140 break;
141
142 default :
143 ErrorString = MUSIC_ErrorString( MUSIC_InvalidCard );
144 break;
145 }
146 break;
147
148 case MUSIC_MPU401Error :
149 ErrorString = "Could not detect MPU-401.";
150 break;
151
152 case MUSIC_InvalidCard :
153 ErrorString = "Invalid Music device.";
154 break;
155
156 case MUSIC_MidiError :
157 ErrorString = "Error playing MIDI file.";
158 break;
159
160 case MUSIC_TaskManError :
161 ErrorString = "TaskMan error.";
162 break;
163
164 case MUSIC_FMNotDetected :
165 ErrorString = "Could not detect FM chip.";
166 break;
167
168 case MUSIC_DPMI_Error :
169 ErrorString = "DPMI Error in MUSIC.";
170 break;
171
172 default :
173 ErrorString = "Unknown Music error code.";
174 break;
175 }
176
177 return( ErrorString );
178 }
179
180
181/*---------------------------------------------------------------------
182 Function: MUSIC_Init
183
184 Selects which sound device to use.
185---------------------------------------------------------------------*/
186
187int MUSIC_Init
188 (
189 int SoundCard,
190 int Address
191 )
192
193 {
194 int i;
195 int status;
196
197 if ( USER_CheckParameter( "ASSVER" ) )
198 {
199 MUSIC_SetErrorCode( MUSIC_ASSVersion );
200 return( MUSIC_Error );
201 }
202
203 status = LL_LockMemory();
204 if ( status != LL_Ok )
205 {
206 MUSIC_SetErrorCode( MUSIC_DPMI_Error );
207 return( MUSIC_Error );
208 }
209
210 for( i = 0; i < 128; i++ )
211 {
212 MIDI_PatchMap[ i ] = i;
213 }
214
215 status = MUSIC_Ok;
216 MUSIC_SoundDevice = SoundCard;
217
218 switch( SoundCard )
219 {
220 case SoundBlaster :
221 case Adlib :
222 case ProAudioSpectrum :
223 case SoundMan16 :
224 status = MUSIC_InitFM( SoundCard, &MUSIC_MidiFunctions );
225 break;
226
227 case GenMidi :
228 case SoundCanvas :
229 case WaveBlaster :
230 case SoundScape :
231 status = MUSIC_InitMidi( SoundCard, &MUSIC_MidiFunctions, Address );
232 break;
233
234 case Awe32 :
235 status = MUSIC_InitAWE32( &MUSIC_MidiFunctions );
236 break;
237
238 case UltraSound :
239 status = MUSIC_InitGUS( &MUSIC_MidiFunctions );
240 break;
241
242 case SoundSource :
243 case PC :
244 default :
245 MUSIC_SetErrorCode( MUSIC_InvalidCard );
246 status = MUSIC_Error;
247 }
248
249 if ( status != MUSIC_Ok )
250 {
251 LL_UnlockMemory();
252 }
253
254 return( status );
255 }
256
257
258/*---------------------------------------------------------------------
259 Function: MUSIC_Shutdown
260
261 Terminates use of sound device.
262---------------------------------------------------------------------*/
263
264int MUSIC_Shutdown
265 (
266 void
267 )
268
269 {
270 int status;
271
272 status = MUSIC_Ok;
273
274 MIDI_StopSong();
275
276 if ( MUSIC_FadeTask != NULL )
277 {
278 MUSIC_StopFade();
279 }
280
281 switch ( MUSIC_SoundDevice )
282 {
283 case Adlib :
284 AL_Shutdown();
285 break;
286
287 case SoundBlaster :
288 AL_Shutdown();
289 BLASTER_RestoreMidiVolume();
290 break;
291
292 case GenMidi :
293 case SoundCanvas :
294 case SoundScape :
295 MPU_Reset();
296 break;
297
298 case WaveBlaster :
299 BLASTER_ShutdownWaveBlaster();
300 MPU_Reset();
301 BLASTER_RestoreMidiVolume();
302 break;
303
304 case Awe32 :
305 AWE32_Shutdown();
306 BLASTER_RestoreMidiVolume();
307 break;
308
309 case ProAudioSpectrum :
310 case SoundMan16 :
311 AL_Shutdown();
312 PAS_RestoreMusicVolume();
313 break;
314
315 case UltraSound :
316 GUSMIDI_Shutdown();
317 break;
318 }
319
320 LL_UnlockMemory();
321
322 return( status );
323 }
324
325
326/*---------------------------------------------------------------------
327 Function: MUSIC_SetMaxFMMidiChannel
328
329 Sets the maximum MIDI channel that FM cards respond to.
330---------------------------------------------------------------------*/
331
332void MUSIC_SetMaxFMMidiChannel
333 (
334 int channel
335 )
336
337 {
338 AL_SetMaxMidiChannel( channel );
339 }
340
341
342/*---------------------------------------------------------------------
343 Function: MUSIC_SetVolume
344
345 Sets the volume of music playback.
346---------------------------------------------------------------------*/
347
348void MUSIC_SetVolume
349 (
350 int volume
351 )
352
353 {
354 volume = max( 0, volume );
355 volume = min( volume, 255 );
356
357 if ( MUSIC_SoundDevice != -1 )
358 {
359 MIDI_SetVolume( volume );
360 }
361 }
362
363
364/*---------------------------------------------------------------------
365 Function: MUSIC_SetMidiChannelVolume
366
367 Sets the volume of music playback on the specified MIDI channel.
368---------------------------------------------------------------------*/
369
370void MUSIC_SetMidiChannelVolume
371 (
372 int channel,
373 int volume
374 )
375
376 {
377 MIDI_SetUserChannelVolume( channel, volume );
378 }
379
380
381/*---------------------------------------------------------------------
382 Function: MUSIC_ResetMidiChannelVolumes
383
384 Sets the volume of music playback on all MIDI channels to full volume.
385---------------------------------------------------------------------*/
386
387void MUSIC_ResetMidiChannelVolumes
388 (
389 void
390 )
391
392 {
393 MIDI_ResetUserChannelVolume();
394 }
395
396
397/*---------------------------------------------------------------------
398 Function: MUSIC_GetVolume
399
400 Returns the volume of music playback.
401---------------------------------------------------------------------*/
402
403int MUSIC_GetVolume
404 (
405 void
406 )
407
408 {
409 if ( MUSIC_SoundDevice == -1 )
410 {
411 return( 0 );
412 }
413 return( MIDI_GetVolume() );
414 }
415
416
417/*---------------------------------------------------------------------
418 Function: MUSIC_SetLoopFlag
419
420 Set whether the music will loop or end when it reaches the end of
421 the song.
422---------------------------------------------------------------------*/
423
424void MUSIC_SetLoopFlag
425 (
426 int loopflag
427 )
428
429 {
430 MIDI_SetLoopFlag( loopflag );
431 }
432
433
434/*---------------------------------------------------------------------
435 Function: MUSIC_SongPlaying
436
437 Returns whether there is a song playing.
438---------------------------------------------------------------------*/
439
440int MUSIC_SongPlaying
441 (
442 void
443 )
444
445 {
446 return( MIDI_SongPlaying() );
447 }
448
449
450/*---------------------------------------------------------------------
451 Function: MUSIC_Continue
452
453 Continues playback of a paused song.
454---------------------------------------------------------------------*/
455
456void MUSIC_Continue
457 (
458 void
459 )
460
461 {
462 MIDI_ContinueSong();
463 }
464
465
466/*---------------------------------------------------------------------
467 Function: MUSIC_Pause
468
469 Pauses playback of a song.
470---------------------------------------------------------------------*/
471
472void MUSIC_Pause
473 (
474 void
475 )
476
477 {
478 MIDI_PauseSong();
479 }
480
481
482/*---------------------------------------------------------------------
483 Function: MUSIC_StopSong
484
485 Stops playback of current song.
486---------------------------------------------------------------------*/
487
488int MUSIC_StopSong
489 (
490 void
491 )
492
493 {
494 MUSIC_StopFade();
495 MIDI_StopSong();
496 MUSIC_SetErrorCode( MUSIC_Ok );
497 return( MUSIC_Ok );
498 }
499
500
501/*---------------------------------------------------------------------
502 Function: MUSIC_PlaySong
503
504 Begins playback of MIDI song.
505---------------------------------------------------------------------*/
506
507int MUSIC_PlaySong
508 (
509 unsigned char *song,
510 int loopflag
511 )
512
513 {
514 int status;
515
516 switch( MUSIC_SoundDevice )
517 {
518 case SoundBlaster :
519 case Adlib :
520 case ProAudioSpectrum :
521 case SoundMan16 :
522 case GenMidi :
523 case SoundCanvas :
524 case WaveBlaster :
525 case SoundScape :
526 case Awe32 :
527 case UltraSound :
528 MIDI_StopSong();
529 status = MIDI_PlaySong( song, loopflag );
530 if ( status != MIDI_Ok )
531 {
532 MUSIC_SetErrorCode( MUSIC_MidiError );
533 return( MUSIC_Warning );
534 }
535 break;
536
537 case SoundSource :
538 case PC :
539 default :
540 MUSIC_SetErrorCode( MUSIC_InvalidCard );
541 return( MUSIC_Warning );
542 break;
543 }
544
545 return( MUSIC_Ok );
546 }
547
548
549/*---------------------------------------------------------------------
550 Function: MUSIC_SetContext
551
552 Sets the song context.
553---------------------------------------------------------------------*/
554
555void MUSIC_SetContext
556 (
557 int context
558 )
559
560 {
561 MIDI_SetContext( context );
562 }
563
564
565/*---------------------------------------------------------------------
566 Function: MUSIC_GetContext
567
568 Returns the current song context.
569---------------------------------------------------------------------*/
570
571int MUSIC_GetContext
572 (
573 void
574 )
575
576 {
577 return MIDI_GetContext();
578 }
579
580
581/*---------------------------------------------------------------------
582 Function: MUSIC_SetSongTick
583
584 Sets the position of the song pointer.
585---------------------------------------------------------------------*/
586
587void MUSIC_SetSongTick
588 (
589 unsigned long PositionInTicks
590 )
591
592 {
593 MIDI_SetSongTick( PositionInTicks );
594 }
595
596
597/*---------------------------------------------------------------------
598 Function: MUSIC_SetSongTime
599
600 Sets the position of the song pointer.
601---------------------------------------------------------------------*/
602
603void MUSIC_SetSongTime
604 (
605 unsigned long milliseconds
606 )
607
608 {
609 MIDI_SetSongTime( milliseconds );
610 }
611
612
613/*---------------------------------------------------------------------
614 Function: MUSIC_SetSongPosition
615
616 Sets the position of the song pointer.
617---------------------------------------------------------------------*/
618
619void MUSIC_SetSongPosition
620 (
621 int measure,
622 int beat,
623 int tick
624 )
625
626 {
627 MIDI_SetSongPosition( measure, beat, tick );
628 }
629
630
631/*---------------------------------------------------------------------
632 Function: MUSIC_GetSongPosition
633
634 Returns the position of the song pointer.
635---------------------------------------------------------------------*/
636
637void MUSIC_GetSongPosition
638 (
639 songposition *pos
640 )
641
642 {
643 MIDI_GetSongPosition( pos );
644 }
645
646
647/*---------------------------------------------------------------------
648 Function: MUSIC_GetSongLength
649
650 Returns the length of the song.
651---------------------------------------------------------------------*/
652
653void MUSIC_GetSongLength
654 (
655 songposition *pos
656 )
657
658 {
659 MIDI_GetSongLength( pos );
660 }
661
662
663int MUSIC_InitAWE32
664 (
665 midifuncs *Funcs
666 )
667
668 {
669 int status;
670
671 status = AWE32_Init();
672 if ( status != AWE32_Ok )
673 {
674 MUSIC_SetErrorCode( MUSIC_SoundCardError );
675 return( MUSIC_Error );
676 }
677
678 Funcs->NoteOff = AWE32_NoteOff;
679 Funcs->NoteOn = AWE32_NoteOn;
680 Funcs->PolyAftertouch = AWE32_PolyAftertouch;
681 Funcs->ControlChange = AWE32_ControlChange;
682 Funcs->ProgramChange = AWE32_ProgramChange;
683 Funcs->ChannelAftertouch = AWE32_ChannelAftertouch;
684 Funcs->PitchBend = AWE32_PitchBend;
685 Funcs->ReleasePatches = NULL;
686 Funcs->LoadPatch = NULL;
687 Funcs->SetVolume = NULL;
688 Funcs->GetVolume = NULL;
689
690 if ( BLASTER_CardHasMixer() )
691 {
692 BLASTER_SaveMidiVolume();
693 Funcs->SetVolume = BLASTER_SetMidiVolume;
694 Funcs->GetVolume = BLASTER_GetMidiVolume;
695 }
696
697 status = MUSIC_Ok;
698 MIDI_SetMidiFuncs( Funcs );
699
700 return( status );
701 }
702
703
704int MUSIC_InitFM
705 (
706 int card,
707 midifuncs *Funcs
708 )
709
710 {
711 int status;
712 int passtatus;
713
714 status = MIDI_Ok;
715
716 if ( !AL_DetectFM() )
717 {
718 MUSIC_SetErrorCode( MUSIC_FMNotDetected );
719 return( MUSIC_Error );
720 }
721
722 // Init the fm routines
723 AL_Init( card );
724
725 Funcs->NoteOff = AL_NoteOff;
726 Funcs->NoteOn = AL_NoteOn;
727 Funcs->PolyAftertouch = NULL;
728 Funcs->ControlChange = AL_ControlChange;
729 Funcs->ProgramChange = AL_ProgramChange;
730 Funcs->ChannelAftertouch = NULL;
731 Funcs->PitchBend = AL_SetPitchBend;
732 Funcs->ReleasePatches = NULL;
733 Funcs->LoadPatch = NULL;
734 Funcs->SetVolume = NULL;
735 Funcs->GetVolume = NULL;
736
737 switch( card )
738 {
739 case SoundBlaster :
740 if ( BLASTER_CardHasMixer() )
741 {
742 BLASTER_SaveMidiVolume();
743 Funcs->SetVolume = BLASTER_SetMidiVolume;
744 Funcs->GetVolume = BLASTER_GetMidiVolume;
745 }
746 else
747 {
748 Funcs->SetVolume = NULL;
749 Funcs->GetVolume = NULL;
750 }
751 break;
752
753 case Adlib :
754 Funcs->SetVolume = NULL;
755 Funcs->GetVolume = NULL;
756 break;
757
758 case ProAudioSpectrum :
759 case SoundMan16 :
760 Funcs->SetVolume = NULL;
761 Funcs->GetVolume = NULL;
762
763 passtatus = PAS_SaveMusicVolume();
764 if ( passtatus == PAS_Ok )
765 {
766 Funcs->SetVolume = PAS_SetFMVolume;
767 Funcs->GetVolume = PAS_GetFMVolume;
768 }
769 break;
770 }
771
772 MIDI_SetMidiFuncs( Funcs );
773
774 return( status );
775 }
776
777int MUSIC_InitMidi
778 (
779 int card,
780 midifuncs *Funcs,
781 int Address
782 )
783
784 {
785 int status;
786
787 status = MUSIC_Ok;
788
789 if ( ( card == WaveBlaster ) || ( card == SoundCanvas ) ||
790 ( card == GenMidi ) )
791 {
792 // Setup WaveBlaster Daughterboard clone
793 // (ie. SoundCanvas DB, TurtleBeach Rio)
794 BLASTER_SetupWaveBlaster();
795 }
796
797 if ( card == SoundScape )
798 {
799 Address = SOUNDSCAPE_GetMIDIPort();
800 if ( Address < SOUNDSCAPE_Ok )
801 {
802 MUSIC_SetErrorCode( MUSIC_SoundCardError );
803 return( MUSIC_Error );
804 }
805 }
806
807 if ( MPU_Init( Address ) != MPU_Ok )
808 {
809 MUSIC_SetErrorCode( MUSIC_MPU401Error );
810 return( MUSIC_Error );
811 }
812
813 Funcs->NoteOff = MPU_NoteOff;
814 Funcs->NoteOn = MPU_NoteOn;
815 Funcs->PolyAftertouch = MPU_PolyAftertouch;
816 Funcs->ControlChange = MPU_ControlChange;
817 Funcs->ProgramChange = MPU_ProgramChange;
818 Funcs->ChannelAftertouch = MPU_ChannelAftertouch;
819 Funcs->PitchBend = MPU_PitchBend;
820 Funcs->ReleasePatches = NULL;
821 Funcs->LoadPatch = NULL;
822 Funcs->SetVolume = NULL;
823 Funcs->GetVolume = NULL;
824
825 if ( card == WaveBlaster )
826 {
827 if ( BLASTER_CardHasMixer() )
828 {
829 BLASTER_SaveMidiVolume();
830 Funcs->SetVolume = BLASTER_SetMidiVolume;
831 Funcs->GetVolume = BLASTER_GetMidiVolume;
832 }
833 }
834
835 MIDI_SetMidiFuncs( Funcs );
836
837 return( status );
838 }
839
840int MUSIC_InitGUS
841 (
842 midifuncs *Funcs
843 )
844
845 {
846 int status;
847
848 status = MUSIC_Ok;
849
850 if ( GUSMIDI_Init() != GUS_Ok )
851 {
852 MUSIC_SetErrorCode( MUSIC_SoundCardError );
853 return( MUSIC_Error );
854 }
855
856 Funcs->NoteOff = GUSMIDI_NoteOff;
857 Funcs->NoteOn = GUSMIDI_NoteOn;
858 Funcs->PolyAftertouch = NULL;
859 Funcs->ControlChange = GUSMIDI_ControlChange;
860 Funcs->ProgramChange = GUSMIDI_ProgramChange;
861 Funcs->ChannelAftertouch = NULL;
862 Funcs->PitchBend = GUSMIDI_PitchBend;
863 Funcs->ReleasePatches = NULL;//GUSMIDI_ReleasePatches;
864 Funcs->LoadPatch = NULL;//GUSMIDI_LoadPatch;
865 Funcs->SetVolume = GUSMIDI_SetVolume;
866 Funcs->GetVolume = GUSMIDI_GetVolume;
867
868 MIDI_SetMidiFuncs( Funcs );
869
870 return( status );
871 }
872
873
874/*---------------------------------------------------------------------
875 Function: MUSIC_FadeRoutine
876
877 Fades music volume from current level to another over a specified
878 period of time.
879---------------------------------------------------------------------*/
880
881static void MUSIC_FadeRoutine
882 (
883 task *Task
884 )
885
886 {
887 int volume;
888
889 MUSIC_CurrentFadeVolume += MUSIC_FadeRate;
890 if ( MUSIC_FadeLength == 0 )
891 {
892 MIDI_SetVolume( MUSIC_EndingFadeVolume );
893 TS_Terminate( Task );
894 MUSIC_FadeTask = NULL;
895 }
896 else
897 {
898 MUSIC_FadeLength--;
899// if ( ( MUSIC_SoundDevice == GenMidi ) &&
900// ( ( MUSIC_FadeLength % 12 ) != 0 ) )
901// {
902// return;
903// }
904
905 volume = MUSIC_CurrentFadeVolume >> 7;
906 if ( MUSIC_LastFadeVolume != volume )
907 {
908 MUSIC_LastFadeVolume = volume;
909 MIDI_SetVolume( volume );
910 }
911 }
912 }
913
914
915/*---------------------------------------------------------------------
916 Function: MUSIC_FadeVolume
917
918 Fades music volume from current level to another over a specified
919 period of time.
920---------------------------------------------------------------------*/
921
922int MUSIC_FadeVolume
923 (
924 int tovolume,
925 int milliseconds
926 )
927
928 {
929 int fromvolume;
930
931 if ( ( MUSIC_SoundDevice == ProAudioSpectrum ) ||
932 ( MUSIC_SoundDevice == SoundMan16 ) ||
933 ( MUSIC_SoundDevice == GenMidi ) ||
934 ( MUSIC_SoundDevice == SoundScape ) ||
935 ( MUSIC_SoundDevice == SoundCanvas ) )
936 {
937 MIDI_SetVolume( tovolume );
938 return( MUSIC_Ok );
939 }
940
941 if ( MUSIC_FadeTask != NULL )
942 {
943 MUSIC_StopFade();
944 }
945
946 tovolume = max( 0, tovolume );
947 tovolume = min( 255, tovolume );
948 fromvolume = MUSIC_GetVolume();
949
950 MUSIC_FadeLength = milliseconds / 25;
951 MUSIC_FadeRate = ( ( tovolume - fromvolume ) << 7 ) / MUSIC_FadeLength;
952 MUSIC_LastFadeVolume = fromvolume;
953 MUSIC_CurrentFadeVolume = fromvolume << 7;
954 MUSIC_EndingFadeVolume = tovolume;
955
956 MUSIC_FadeTask = TS_ScheduleTask( MUSIC_FadeRoutine, 40, 1, NULL );
957 if ( MUSIC_FadeTask == NULL )
958 {
959 MUSIC_SetErrorCode( MUSIC_TaskManError );
960 return( MUSIC_Warning );
961 }
962
963 TS_Dispatch();
964 return( MUSIC_Ok );
965 }
966
967
968/*---------------------------------------------------------------------
969 Function: MUSIC_FadeActive
970
971 Returns whether the fade routine is active.
972---------------------------------------------------------------------*/
973
974int MUSIC_FadeActive
975 (
976 void
977 )
978
979 {
980 return( MUSIC_FadeTask != NULL );
981 }
982
983
984/*---------------------------------------------------------------------
985 Function: MUSIC_StopFade
986
987 Stops fading the music.
988---------------------------------------------------------------------*/
989
990void MUSIC_StopFade
991 (
992 void
993 )
994
995 {
996 if ( MUSIC_FadeTask != NULL )
997 {
998 TS_Terminate( MUSIC_FadeTask );
999 MUSIC_FadeTask = NULL;
1000 }
1001 }
1002
1003
1004/*---------------------------------------------------------------------
1005 Function: MUSIC_RerouteMidiChannel
1006
1007 Sets callback function to reroute MIDI commands from specified
1008 function.
1009---------------------------------------------------------------------*/
1010
1011void MUSIC_RerouteMidiChannel
1012 (
1013 int channel,
1014 int cdecl ( *function )( int event, int c1, int c2 )
1015 )
1016
1017 {
1018 MIDI_RerouteMidiChannel( channel, function );
1019 }
1020
1021
1022/*---------------------------------------------------------------------
1023 Function: MUSIC_RegisterTimbreBank
1024
1025 Halts playback of all sounds.
1026---------------------------------------------------------------------*/
1027
1028void MUSIC_RegisterTimbreBank
1029 (
1030 unsigned char *timbres
1031 )
1032
1033 {
1034 AL_RegisterTimbreBank( timbres );
1035 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/music.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/music.h
new file mode 100644
index 0000000000..83c967b1b1
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/music.h
@@ -0,0 +1,99 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: MUSIC.H
22
23 author: James R. Dose
24 date: March 25, 1994
25
26 Public header for MUSIC.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __MUSIC_H
32#define __MUSIC_H
33
34#include "../duke3d.h"
35
36#include "sndcards.h"
37
38#ifndef PLAT_DOS
39#define cdecl
40#endif
41
42extern int MUSIC_ErrorCode;
43
44enum MUSIC_ERRORS
45 {
46 MUSIC_Warning = -2,
47 MUSIC_Error = -1,
48 MUSIC_Ok = 0,
49 MUSIC_ASSVersion,
50 MUSIC_SoundCardError,
51 MUSIC_MPU401Error,
52 MUSIC_InvalidCard,
53 MUSIC_MidiError,
54 MUSIC_TaskManError,
55 MUSIC_FMNotDetected,
56 MUSIC_DPMI_Error
57 };
58
59typedef struct
60 {
61 uint32_t tickposition;
62 uint32_t milliseconds;
63 unsigned int measure;
64 unsigned int beat;
65 unsigned int tick;
66 } songposition;
67
68#define MUSIC_LoopSong ( 1 == 1 )
69#define MUSIC_PlayOnce ( !MUSIC_LoopSong )
70
71char *MUSIC_ErrorString( int ErrorNumber );
72int MUSIC_Init( int SoundCard, int Address );
73int MUSIC_Shutdown( void );
74void MUSIC_SetMaxFMMidiChannel( int channel );
75void MUSIC_SetVolume( int volume );
76void MUSIC_SetMidiChannelVolume( int channel, int volume );
77void MUSIC_ResetMidiChannelVolumes( void );
78int MUSIC_GetVolume( void );
79void MUSIC_SetLoopFlag( int loopflag );
80int MUSIC_SongPlaying( void );
81void MUSIC_Continue( void );
82void MUSIC_Pause( void );
83int MUSIC_StopSong( void );
84int MUSIC_PlaySong( char* songData, int loopflag );
85void MUSIC_SetContext( int context );
86int MUSIC_GetContext( void );
87void MUSIC_SetSongTick( uint32_t PositionInTicks );
88void MUSIC_SetSongTime( uint32_t milliseconds );
89void MUSIC_SetSongPosition( int measure, int beat, int tick );
90void MUSIC_GetSongPosition( songposition *pos );
91void MUSIC_GetSongLength( songposition *pos );
92int MUSIC_FadeVolume( int tovolume, int milliseconds );
93int MUSIC_FadeActive( void );
94void MUSIC_StopFade( void );
95void MUSIC_RerouteMidiChannel( int channel, int cdecl ( *function )( int event, int c1, int c2 ) );
96void MUSIC_RegisterTimbreBank( unsigned char *timbres );
97void PlayMusic(char* filename);
98
99#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix.asm b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix.asm
new file mode 100644
index 0000000000..2bd398d8db
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix.asm
@@ -0,0 +1,505 @@
1 IDEAL
2
3 p386
4 MODEL flat
5
6 dataseg
7 CODESEG
8
9 MASM
10 ALIGN 4
11
12EXTRN _MV_HarshClipTable:DWORD
13EXTRN _MV_MixDestination:DWORD
14EXTRN _MV_MixPosition:DWORD
15EXTRN _MV_LeftVolume:DWORD
16EXTRN _MV_RightVolume:DWORD
17EXTRN _MV_SampleSize:DWORD
18EXTRN _MV_RightChannelOffset:DWORD
19
20;================
21;
22; MV_Mix8BitMono
23;
24;================
25
26; eax - position
27; edx - rate
28; ebx - start
29; ecx - number of samples to mix
30
31PROC MV_Mix8BitMono_
32PUBLIC MV_Mix8BitMono_
33; Two at once
34 pushad
35
36 mov ebp, eax
37
38 mov esi, ebx ; Source pointer
39
40 ; Sample size
41 mov ebx, _MV_SampleSize
42 mov eax,OFFSET apatch7+2 ; convice tasm to modify code...
43 mov [eax],bl
44 mov eax,OFFSET apatch8+2 ; convice tasm to modify code...
45 mov [eax],bl
46 mov eax,OFFSET apatch9+3 ; convice tasm to modify code...
47 mov [eax],bl
48
49 ; Volume table ptr
50 mov ebx, _MV_LeftVolume ; Since we're mono, use left volume
51 mov eax,OFFSET apatch1+4 ; convice tasm to modify code...
52 mov [eax],ebx
53 mov eax,OFFSET apatch2+4 ; convice tasm to modify code...
54 mov [eax],ebx
55
56 ; Harsh Clip table ptr
57 mov ebx, _MV_HarshClipTable
58 add ebx, 128
59 mov eax,OFFSET apatch3+2 ; convice tasm to modify code...
60 mov [eax],ebx
61 mov eax,OFFSET apatch4+2 ; convice tasm to modify code...
62 mov [eax],ebx
63
64 ; Rate scale ptr
65 mov eax,OFFSET apatch5+2 ; convice tasm to modify code...
66 mov [eax],edx
67 mov eax,OFFSET apatch6+2 ; convice tasm to modify code...
68 mov [eax],edx
69
70 mov edi, _MV_MixDestination ; Get the position to write to
71
72 ; Number of samples to mix
73 shr ecx, 1 ; double sample count
74 cmp ecx, 0
75 je short exit8m
76
77; eax - scratch
78; ebx - scratch
79; edx - scratch
80; ecx - count
81; edi - destination
82; esi - source
83; ebp - frac pointer
84; apatch1 - volume table
85; apatch2 - volume table
86; apatch3 - harsh clip table
87; apatch4 - harsh clip table
88; apatch5 - sample rate
89; apatch6 - sample rate
90
91 mov eax,ebp ; begin calculating first sample
92 add ebp,edx ; advance frac pointer
93 shr eax,16 ; finish calculation for first sample
94
95 mov ebx,ebp ; begin calculating second sample
96 add ebp,edx ; advance frac pointer
97 shr ebx,16 ; finish calculation for second sample
98
99 movzx eax, byte ptr [esi+eax] ; get first sample
100 movzx ebx, byte ptr [esi+ebx] ; get second sample
101
102 ALIGN 4
103mix8Mloop:
104 movzx edx, byte ptr [edi] ; get current sample from destination
105apatch1:
106 movsx eax, byte ptr [2*eax+12345678h] ; volume translate first sample
107apatch2:
108 movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample
109 add eax, edx ; mix first sample
110apatch9:
111 movzx edx, byte ptr [edi + 1] ; get current sample from destination
112apatch3:
113 mov eax, [eax + 12345678h] ; harsh clip new sample
114 add ebx, edx ; mix second sample
115 mov [edi], al ; write new sample to destination
116 mov edx, ebp ; begin calculating third sample
117apatch4:
118 mov ebx, [ebx + 12345678h] ; harsh clip new sample
119apatch5:
120 add ebp,12345678h ; advance frac pointer
121 shr edx, 16 ; finish calculation for third sample
122 mov eax, ebp ; begin calculating fourth sample
123apatch7:
124 add edi, 1 ; move destination to second sample
125 shr eax, 16 ; finish calculation for fourth sample
126 mov [edi], bl ; write new sample to destination
127apatch6:
128 add ebp,12345678h ; advance frac pointer
129 movzx ebx, byte ptr [esi+eax] ; get fourth sample
130 movzx eax, byte ptr [esi+edx] ; get third sample
131apatch8:
132 add edi, 2 ; move destination to third sample
133 dec ecx ; decrement count
134 jnz mix8Mloop ; loop
135
136 mov _MV_MixDestination, edi ; Store the current write position
137 mov _MV_MixPosition, ebp ; return position
138exit8m:
139 popad
140 ret
141ENDP MV_Mix8BitMono_
142
143;================
144;
145; MV_Mix8BitStereo
146;
147;================
148
149; eax - position
150; edx - rate
151; ebx - start
152; ecx - number of samples to mix
153
154PROC MV_Mix8BitStereo_
155PUBLIC MV_Mix8BitStereo_
156
157 pushad
158 mov ebp, eax
159
160 mov esi, ebx ; Source pointer
161
162 ; Sample size
163 mov ebx, _MV_SampleSize
164 mov eax,OFFSET bpatch8+2 ; convice tasm to modify code...
165 mov [eax],bl
166
167 ; Right channel offset
168 mov ebx, _MV_RightChannelOffset
169 mov eax,OFFSET bpatch6+3 ; convice tasm to modify code...
170 mov [eax],ebx
171 mov eax,OFFSET bpatch7+2 ; convice tasm to modify code...
172 mov [eax],ebx
173
174 ; Volume table ptr
175 mov ebx, _MV_LeftVolume
176 mov eax,OFFSET bpatch1+4 ; convice tasm to modify code...
177 mov [eax],ebx
178
179 mov ebx, _MV_RightVolume
180 mov eax,OFFSET bpatch2+4 ; convice tasm to modify code...
181 mov [eax],ebx
182
183 ; Rate scale ptr
184 mov eax,OFFSET bpatch3+2 ; convice tasm to modify code...
185 mov [eax],edx
186
187 ; Harsh Clip table ptr
188 mov ebx, _MV_HarshClipTable
189 add ebx,128
190 mov eax,OFFSET bpatch4+2 ; convice tasm to modify code...
191 mov [eax],ebx
192 mov eax,OFFSET bpatch5+2 ; convice tasm to modify code...
193 mov [eax],ebx
194
195 mov edi, _MV_MixDestination ; Get the position to write to
196
197 ; Number of samples to mix
198 cmp ecx, 0
199 je short exit8S
200
201; eax - scratch
202; ebx - scratch
203; edx - scratch
204; ecx - count
205; edi - destination
206; esi - source
207; ebp - frac pointer
208; bpatch1 - left volume table
209; bpatch2 - right volume table
210; bpatch3 - sample rate
211; bpatch4 - harsh clip table
212; bpatch5 - harsh clip table
213
214 mov eax,ebp ; begin calculating first sample
215 shr eax,16 ; finish calculation for first sample
216
217 movzx ebx, byte ptr [esi+eax] ; get first sample
218
219 ALIGN 4
220mix8Sloop:
221bpatch1:
222 movsx eax, byte ptr [2*ebx+12345678h] ; volume translate left sample
223 movzx edx, byte ptr [edi] ; get current sample from destination
224bpatch2:
225 movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample
226 add eax, edx ; mix left sample
227bpatch3:
228 add ebp,12345678h ; advance frac pointer
229bpatch6:
230 movzx edx, byte ptr [edi+12345678h] ; get current sample from destination
231bpatch4:
232 mov eax, [eax + 12345678h] ; harsh clip left sample
233 add ebx, edx ; mix right sample
234 mov [edi], al ; write left sample to destination
235bpatch5:
236 mov ebx, [ebx + 12345678h] ; harsh clip right sample
237 mov edx, ebp ; begin calculating second sample
238bpatch7:
239 mov [edi+12345678h], bl ; write right sample to destination
240 shr edx, 16 ; finish calculation for second sample
241bpatch8:
242 add edi, 2 ; move destination to second sample
243 movzx ebx, byte ptr [esi+edx] ; get second sample
244 dec ecx ; decrement count
245 jnz mix8Sloop ; loop
246
247 mov _MV_MixDestination, edi ; Store the current write position
248 mov _MV_MixPosition, ebp ; return position
249
250EXIT8S:
251 popad
252 ret
253ENDP MV_Mix8BitStereo_
254
255;================
256;
257; MV_Mix16BitMono
258;
259;================
260
261; eax - position
262; edx - rate
263; ebx - start
264; ecx - number of samples to mix
265
266PROC MV_Mix16BitMono_
267PUBLIC MV_Mix16BitMono_
268; Two at once
269 pushad
270
271 mov ebp, eax
272
273 mov esi, ebx ; Source pointer
274
275 ; Sample size
276 mov ebx, _MV_SampleSize
277 mov eax,OFFSET cpatch5+3 ; convice tasm to modify code...
278 mov [eax],bl
279 mov eax,OFFSET cpatch6+3 ; convice tasm to modify code...
280 mov [eax],bl
281 mov eax,OFFSET cpatch7+2 ; convice tasm to modify code...
282 add bl,bl
283 mov [eax],bl
284
285 ; Volume table ptr
286 mov ebx, _MV_LeftVolume
287 mov eax,OFFSET cpatch1+4 ; convice tasm to modify code...
288 mov [eax],ebx
289 mov eax,OFFSET cpatch2+4 ; convice tasm to modify code...
290 mov [eax],ebx
291
292 ; Rate scale ptr
293 mov eax,OFFSET cpatch3+2 ; convice tasm to modify code...
294 mov [eax],edx
295 mov eax,OFFSET cpatch4+2 ; convice tasm to modify code...
296 mov [eax],edx
297
298 mov edi, _MV_MixDestination ; Get the position to write to
299
300 ; Number of samples to mix
301 shr ecx, 1 ; double sample count
302 cmp ecx, 0
303 je exit16M
304
305; eax - scratch
306; ebx - scratch
307; edx - scratch
308; ecx - count
309; edi - destination
310; esi - source
311; ebp - frac pointer
312; cpatch1 - volume table
313; cpatch2 - volume table
314; cpatch3 - sample rate
315; cpatch4 - sample rate
316
317 mov eax,ebp ; begin calculating first sample
318 add ebp,edx ; advance frac pointer
319 shr eax,16 ; finish calculation for first sample
320
321 mov ebx,ebp ; begin calculating second sample
322 add ebp,edx ; advance frac pointer
323 shr ebx,16 ; finish calculation for second sample
324
325 movzx eax, byte ptr [esi+eax] ; get first sample
326 movzx ebx, byte ptr [esi+ebx] ; get second sample
327
328 ALIGN 4
329mix16Mloop:
330 movsx edx, word ptr [edi] ; get current sample from destination
331cpatch1:
332 movsx eax, word ptr [2*eax+12345678h] ; volume translate first sample
333cpatch2:
334 movsx ebx, word ptr [2*ebx+12345678h] ; volume translate second sample
335 add eax, edx ; mix first sample
336cpatch5:
337 movsx edx, word ptr [edi + 2] ; get current sample from destination
338
339 cmp eax, -32768 ; Harsh clip sample
340 jge short m16skip1
341 mov eax, -32768
342 jmp short m16skip2
343m16skip1:
344 cmp eax, 32767
345 jle short m16skip2
346 mov eax, 32767
347m16skip2:
348 add ebx, edx ; mix second sample
349 mov [edi], ax ; write new sample to destination
350 mov edx, ebp ; begin calculating third sample
351
352 cmp ebx, -32768 ; Harsh clip sample
353 jge short m16skip3
354 mov ebx, -32768
355 jmp short m16skip4
356m16skip3:
357 cmp ebx, 32767
358 jle short m16skip4
359 mov ebx, 32767
360m16skip4:
361cpatch3:
362 add ebp,12345678h ; advance frac pointer
363 shr edx, 16 ; finish calculation for third sample
364 mov eax, ebp ; begin calculating fourth sample
365cpatch6:
366 mov [edi + 2], bx ; write new sample to destination
367 shr eax, 16 ; finish calculation for fourth sample
368
369cpatch4:
370 add ebp,12345678h ; advance frac pointer
371 movzx ebx, byte ptr [esi+eax] ; get fourth sample
372cpatch7:
373 add edi, 4 ; move destination to third sample
374 movzx eax, byte ptr [esi+edx] ; get third sample
375 dec ecx ; decrement count
376 jnz mix16Mloop ; loop
377
378 mov _MV_MixDestination, edi ; Store the current write position
379 mov _MV_MixPosition, ebp ; return position
380EXIT16M:
381 popad
382 ret
383ENDP MV_Mix16BitMono_
384
385;================
386;
387; MV_Mix16BitStereo
388;
389;================
390
391; eax - position
392; edx - rate
393; ebx - start
394; ecx - number of samples to mix
395
396PROC MV_Mix16BitStereo_
397PUBLIC MV_Mix16BitStereo_
398
399 pushad
400 mov ebp, eax
401
402 mov esi, ebx ; Source pointer
403
404 ; Sample size
405 mov ebx, _MV_SampleSize
406 mov eax,OFFSET dpatch6+2 ; convice tasm to modify code...
407 mov [eax],bl
408
409 ; Right channel offset
410 mov ebx, _MV_RightChannelOffset
411 mov eax,OFFSET dpatch4+3 ; convice tasm to modify code...
412 mov [eax],ebx
413 mov eax,OFFSET dpatch5+3 ; convice tasm to modify code...
414 mov [eax],ebx
415
416 ; Volume table ptr
417 mov ebx, _MV_LeftVolume
418 mov eax,OFFSET dpatch1+4 ; convice tasm to modify code...
419 mov [eax],ebx
420
421 mov ebx, _MV_RightVolume
422 mov eax,OFFSET dpatch2+4 ; convice tasm to modify code...
423 mov [eax],ebx
424
425 ; Rate scale ptr
426 mov eax,OFFSET dpatch3+2 ; convice tasm to modify code...
427 mov [eax],edx
428
429 mov edi, _MV_MixDestination ; Get the position to write to
430
431 ; Number of samples to mix
432 cmp ecx, 0
433 je exit16S
434
435; eax - scratch
436; ebx - scratch
437; edx - scratch
438; ecx - count
439; edi - destination
440; esi - source
441; ebp - frac pointer
442; dpatch1 - left volume table
443; dpatch2 - right volume table
444; dpatch3 - sample rate
445
446 mov eax,ebp ; begin calculating first sample
447 shr eax,16 ; finish calculation for first sample
448
449 movzx ebx, byte ptr [esi+eax] ; get first sample
450
451 ALIGN 4
452mix16Sloop:
453dpatch1:
454 movsx eax, word ptr [2*ebx+12345678h] ; volume translate left sample
455 movsx edx, word ptr [edi] ; get current sample from destination
456dpatch2:
457 movsx ebx, word ptr [2*ebx+12345678h] ; volume translate right sample
458 add eax, edx ; mix left sample
459dpatch3:
460 add ebp,12345678h ; advance frac pointer
461dpatch4:
462 movsx edx, word ptr [edi+12345678h] ; get current sample from destination
463
464 cmp eax, -32768 ; Harsh clip sample
465 jge short s16skip1
466 mov eax, -32768
467 jmp short s16skip2
468s16skip1:
469 cmp eax, 32767
470 jle short s16skip2
471 mov eax, 32767
472s16skip2:
473 add ebx, edx ; mix right sample
474 mov [edi], ax ; write left sample to destination
475
476 cmp ebx, -32768 ; Harsh clip sample
477 jge short s16skip3
478 mov ebx, -32768
479 jmp short s16skip4
480s16skip3:
481 cmp ebx, 32767
482 jle short s16skip4
483 mov ebx, 32767
484s16skip4:
485
486 mov edx, ebp ; begin calculating second sample
487dpatch5:
488 mov [edi+12345678h], bx ; write right sample to destination
489 shr edx, 16 ; finish calculation for second sample
490dpatch6:
491 add edi, 4 ; move destination to second sample
492 movzx ebx, byte ptr [esi+edx] ; get second sample
493 dec ecx ; decrement count
494 jnz mix16Sloop ; loop
495
496 mov _MV_MixDestination, edi ; Store the current write position
497 mov _MV_MixPosition, ebp ; return position
498exit16S:
499 popad
500 ret
501ENDP MV_Mix16BitStereo_
502
503 ENDS
504
505 END
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix.c
new file mode 100644
index 0000000000..ea5c0e47bb
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix.c
@@ -0,0 +1,483 @@
1#include "multivoc.h"
2
3#include "../global.h" /* for readLE16 */
4
5extern char *MV_MixDestination;
6extern uint32_t MV_MixPosition;
7extern int *MV_GLast, *MV_GPos, *MV_GVal;
8
9extern int MV_LeftVolume;
10extern int MV_RightVolume;
11extern int MV_MaxVolume;
12
13// extern unsigned char *MV_HarshClipTable;
14
15extern int MV_RightChannelOffset;
16extern int MV_SampleSize;
17extern int MV_Channels;
18
19//int do_cubic = 1;
20
21extern int g_CV_CubicInterpolation;
22
23#define do_cubic (g_CV_CubicInterpolation)
24
25#define gval0 MV_GVal[*MV_GPos&3]
26#define gval(x) MV_GVal[(*MV_GPos+x)&3]
27
28int MV_cubic(int position)
29{
30 int xd, fa;
31 xd = (position >> 1) & 0x7FFF;
32
33 fa = gval(3) - 3*gval(2) + 3*gval(1) - gval0;
34 fa *= (xd - (2<<15)) / 6;
35 fa >>= 15;
36 fa += gval(2) - gval(1) - gval(1) + gval0;
37 fa *= (xd - (1<<15)) >> 1;
38 fa >>= 15;
39 fa += gval(1) - gval0;
40 fa *= xd;
41 fa >>= 15;
42 fa += gval0;
43 return fa;
44}
45
46/*
47static int MV_cubic8(const unsigned char *src, int position, int rate)
48{
49 int temp, hpos = position >> 16;
50
51 if (abs(hpos - *MV_GLast) > 3) *MV_GLast = hpos;
52
53 temp = hpos;
54
55 while (hpos > *MV_GLast)
56 {
57 gval0 = ((int)src[temp++] - 0x80) << 8;
58 *MV_GPos = (*MV_GPos + 1) & 3;
59 (*MV_GLast)++;
60 }
61
62 return do_cubic ? (MV_cubic(position) >> 8) + 0x80 : (gval(3) >> 8) + 0x80;
63}
64*/
65
66static int MV_cubic16(const short *src, int position, int rate)
67{
68 int temp, hpos = position >> 16;
69
70 if (abs(hpos - *MV_GLast) > 3) *MV_GLast = hpos;
71
72 temp = hpos;
73
74 while (hpos > *MV_GLast)
75 {
76 /* readLE16 returns unsigned short, but it won't be casted
77 * implicitly, since gval0 is of type int. */
78 gval0 = (short) readLE16(src + temp++);
79
80 *MV_GPos = (*MV_GPos + 1) & 3;
81 (*MV_GLast)++;
82 }
83
84 return do_cubic ? MV_cubic(position) : gval(3);
85}
86
87static int MV_cubic8to16(const unsigned char *src, int position, int rate)
88{
89 int temp, hpos = position >> 16;
90
91 if (abs(hpos - *MV_GLast) > 3) *MV_GLast = hpos;
92
93 temp = hpos;
94
95 while (hpos > *MV_GLast)
96 {
97 gval0 = ((int)src[temp++] - 0x80) << 8;
98 *MV_GPos = (*MV_GPos + 1) & 3;
99 (*MV_GLast)++;
100 }
101
102 return do_cubic ? MV_cubic(position) : gval(3);
103}
104
105/*
106static int MV_cubic16to8(const short *src, int position, int rate)
107{
108 int temp, hpos = position >> 16;
109
110 if (abs(hpos - *MV_GLast) > 3) *MV_GLast = hpos;
111
112 temp = hpos;
113
114 while (hpos > *MV_GLast)
115 {
116 gval0 = src[temp++];
117 *MV_GPos = (*MV_GPos + 1) & 3;
118 (*MV_GLast)++;
119 }
120
121 return do_cubic ? (MV_cubic(position) >> 8) + 0x80 : (gval(3) >> 8) + 0x80;
122}
123*/
124
125void MV_Mix8BitMono( uint32_t position, uint32_t rate,
126 const char *start, uint32_t length )
127{
128 const unsigned char *src;
129 unsigned char *dest;
130 unsigned int i;
131
132 src = (const unsigned char *)start;
133 dest = (unsigned char *)MV_MixDestination;
134
135 for (i = 0; i < length; i++) {
136 int s = MV_cubic8to16(src, position, rate);
137 int d = (*dest - 0x80) << 8;
138
139 d += (s * MV_LeftVolume) / MV_MaxVolume;
140
141 if (d < -32768) *dest = 0;
142 else if (d > 32767) *dest = 255;
143 else *dest = (d >> 8) + 128;
144
145 position += rate;
146 dest += MV_SampleSize;
147 }
148
149 MV_MixPosition = position;
150 MV_MixDestination = (char *)dest;
151}
152
153void MV_Mix8BitStereo( uint32_t position,
154 uint32_t rate, const char *start, uint32_t length )
155{
156 const unsigned char *src;
157 unsigned char *dest;
158 unsigned int i;
159
160 src = (const unsigned char *)start;
161 dest = (unsigned char *)MV_MixDestination;
162
163 for (i = 0; i < length; i++) {
164 int s = MV_cubic8to16(src, position, rate);
165 int dl = (dest[0] - 0x80) << 8;
166 int dr = (dest[MV_RightChannelOffset] - 0x80) << 8;
167
168 dl += (MV_LeftVolume * s) / MV_MaxVolume;
169 dr += (MV_RightVolume * s) / MV_MaxVolume;
170
171 if (dl < -32768) dest[0] = 0;
172 else if (dl > 32767) dest[0] = 255;
173 else dest[0] = (dl >> 8) + 128;
174
175 if (dr < -32768) dest[MV_RightChannelOffset] = 0;
176 else if (dr > 32767) dest[MV_RightChannelOffset] = 255;
177 else dest[MV_RightChannelOffset] = (dl >> 8) + 128;
178
179 position += rate;
180 dest += MV_SampleSize;
181 }
182
183 MV_MixPosition = position;
184 MV_MixDestination = (char *)dest;
185}
186
187void MV_Mix16BitMono( uint32_t position,
188 uint32_t rate, const char *start, uint32_t length )
189{
190 const unsigned char *src;
191 short *dest;
192 unsigned int i;
193
194 src = (const unsigned char *)start;
195 dest = (short *)MV_MixDestination;
196
197 for (i = 0; i < length; i++) {
198 int s = MV_cubic8to16(src, position, rate);
199 int d = readLE16(dest);
200
201 d += (MV_LeftVolume * s) / MV_MaxVolume;
202
203 if (d < -32768) *dest = -32768;
204 else if (d > 32767) *dest = 32767;
205 else *dest = d;
206
207 position += rate;
208 dest += MV_SampleSize/2;
209 }
210
211 MV_MixPosition = position;
212 MV_MixDestination = (char *)dest;
213}
214
215void MV_Mix16BitStereo( uint32_t position,
216 uint32_t rate, const char *start, uint32_t length )
217{
218 const unsigned char *src;
219 short *dest;
220 unsigned int i;
221
222 src = (unsigned char *)start;
223 dest = (short *)MV_MixDestination;
224
225 for (i = 0; i < length; i++) {
226 int s = MV_cubic8to16(src, position, rate);
227 int dl = readLE16(dest);
228 int dr = readLE16(dest + MV_RightChannelOffset/2);
229
230 dl += (MV_LeftVolume * s) / MV_MaxVolume;
231 dr += (MV_RightVolume * s) / MV_MaxVolume;
232
233 if (dl < -32768) dest[0] = -32768;
234 else if (dl > 32767) dest[0] = 32767;
235 else dest[0] = dl;
236
237 if (dr < -32768) dest[MV_RightChannelOffset/2] = -32768;
238 else if (dr > 32767) dest[MV_RightChannelOffset/2] = 32767;
239 else dest[MV_RightChannelOffset/2] = dr;
240
241 position += rate;
242 dest += MV_SampleSize/2;
243 }
244
245 MV_MixPosition = position;
246 MV_MixDestination = (char *)dest;
247}
248
249void MV_Mix8BitMono16( uint32_t position, uint32_t rate,
250 const char *start, uint32_t length )
251{
252 const short *src;
253 unsigned char *dest;
254 unsigned int i;
255
256 src = (const short *)start;
257 dest = (unsigned char *)MV_MixDestination;
258
259 for (i = 0; i < length; i++) {
260 int s = MV_cubic16(src, position, rate);
261 int d = (*dest - 0x80) << 8;
262
263 d += (MV_LeftVolume * s) / MV_MaxVolume;
264
265 if (d < -32768) *dest = 0;
266 else if (d > 32767) *dest = 255;
267 else *dest = (d >> 8) + 128;
268
269 position += rate;
270 dest += MV_SampleSize;
271 }
272
273 MV_MixPosition = position;
274 MV_MixDestination = (char *)dest;
275}
276
277void MV_Mix8BitStereo16( uint32_t position,
278 uint32_t rate, const char *start, uint32_t length )
279{
280 const short *src;
281 unsigned char *dest;
282 unsigned int i;
283
284 src = (const short *)start;
285 dest = (unsigned char *)MV_MixDestination;
286
287 for (i = 0; i < length; i++) {
288 int s = MV_cubic16(src, position, rate);
289 int dl = (dest[0] - 0x80) << 8;
290 int dr = (dest[MV_RightChannelOffset/2] - 0x80) << 8;
291
292 dl += (MV_LeftVolume * s) / MV_MaxVolume;
293 dr += (MV_RightVolume * s) / MV_MaxVolume;
294
295 if (dl < -32768) dest[0] = 0;
296 else if (dl > 32767) dest[0] = 255;
297 else dest[0] = (dl >> 8) + 128;
298
299 if (dr < -32768) dest[MV_RightChannelOffset] = 0;
300 else if (dr > 32767) dest[MV_RightChannelOffset] = 255;
301 else dest[MV_RightChannelOffset] = (dl >> 8) + 128;
302
303 position += rate;
304 dest += MV_SampleSize;
305 }
306
307 MV_MixPosition = position;
308 MV_MixDestination = (char *)dest;
309}
310
311void MV_Mix16BitMono16( uint32_t position,
312 uint32_t rate, const char *start, uint32_t length )
313{
314 const short *src;
315 short *dest;
316 unsigned int i;
317
318 src = (const short *)start;
319 dest = (short *)MV_MixDestination;
320
321 for (i = 0; i < length; i++) {
322 int s = MV_cubic16(src, position, rate);
323 int d = readLE16(dest);
324
325 d += (MV_LeftVolume * s) / MV_MaxVolume;
326
327 if (d < -32768) *dest = -32768;
328 else if (d > 32767) *dest = 32767;
329 else *dest = d;
330
331 position += rate;
332 dest += MV_SampleSize/2;
333 }
334
335 MV_MixPosition = position;
336 MV_MixDestination = (char *)dest;
337}
338
339void MV_Mix16BitStereo16( uint32_t position,
340 uint32_t rate, const char *start, uint32_t length )
341{
342 const short *src;
343 short *dest;
344 unsigned int i;
345
346 src = (const short *)start;
347 dest = (short *)MV_MixDestination;
348
349 for (i = 0; i < length; i++) {
350 int s = MV_cubic16(src, position, rate);
351 int dl = readLE16(dest);
352 int dr = readLE16(dest + MV_RightChannelOffset/2);
353
354 dl += (MV_LeftVolume * s) / MV_MaxVolume;
355 dr += (MV_RightVolume * s) / MV_MaxVolume;
356
357 if (dl < -32768) dest[0] = -32768;
358 else if (dl > 32767) dest[0] = 32767;
359 else dest[0] = dl;
360
361 if (dr < -32768) dest[MV_RightChannelOffset/2] = -32768;
362 else if (dr > 32767) dest[MV_RightChannelOffset/2] = 32767;
363 else dest[MV_RightChannelOffset/2] = dl;
364
365 position += rate;
366 dest += MV_SampleSize/2;
367 }
368
369 MV_MixPosition = position;
370 MV_MixDestination = (char *)dest;
371}
372
373void MV_MixFPMono8( uint32_t position,
374 uint32_t rate, const char *start, uint32_t length )
375{
376 const unsigned char *src;
377 double *dest;
378 unsigned int i;
379
380 src = (const unsigned char *)start;
381 dest = (double *)MV_MixDestination;
382
383 for (i = 0; i < length; i++) {
384 int s = MV_cubic8to16(src, position, rate);
385 double out;
386
387 out = (double)s * (double)MV_LeftVolume / (double)MV_MaxVolume;
388 out = out / ((double)0x8000);
389 *dest += out;
390
391 position += rate;
392 dest += MV_Channels;
393 }
394
395 MV_MixPosition = position;
396 MV_MixDestination = (char *)dest;
397}
398
399void MV_MixFPStereo8( uint32_t position,
400 uint32_t rate, const char *start, uint32_t length )
401{
402 const unsigned char *src;
403 double *dest;
404 unsigned int i;
405
406 src = (const unsigned char *)start;
407 dest = (double *)MV_MixDestination;
408
409 for (i = 0; i < length; i++) {
410 int s = MV_cubic8to16(src, position, rate);
411 double left, right;
412
413 left = (double)MV_LeftVolume * (double)s / (double)MV_MaxVolume;
414 left = left / ((double)0x8000);
415 right = (double)(MV_RightVolume * s) / MV_MaxVolume;
416 right = right / ((double)0x8000);
417 dest[0] += left;
418 dest[1] += right;
419
420 position += rate;
421 dest += MV_Channels;
422 }
423
424 MV_MixPosition = position;
425 MV_MixDestination = (char *)dest;
426
427}
428
429void MV_MixFPMono16( uint32_t position,
430 uint32_t rate, const char *start, uint32_t length )
431{
432 const short *src;
433 double *dest;
434 unsigned int i;
435
436 src = (const short *)start;
437 dest = (double *)MV_MixDestination;
438
439 for (i = 0; i < length; i++) {
440 int s = MV_cubic16(src, position, rate);
441 double out;
442
443 out = (double)s * (double)MV_LeftVolume / (double)MV_MaxVolume;
444 out = out / ((double)0x8000);
445 *dest += out;
446
447 position += rate;
448 dest += MV_Channels;
449 }
450
451 MV_MixPosition = position;
452 MV_MixDestination = (char *)dest;
453}
454
455void MV_MixFPStereo16( uint32_t position,
456 uint32_t rate, const char *start, uint32_t length )
457{
458 const short *src;
459 double *dest;
460 unsigned int i;
461
462 src = (const short *)start;
463 dest = (double *)MV_MixDestination;
464
465 for (i = 0; i < length; i++) {
466 int s = MV_cubic16(src, position, rate);
467 double left, right;
468
469 left = (double)MV_LeftVolume * (double)s / (double)MV_MaxVolume;
470 left = left / ((double)0x8000);
471 right = (double)(MV_RightVolume * s) / MV_MaxVolume;
472 right = right / ((double)0x8000);
473 dest[0] += left;
474 dest[1] += right;
475
476 position += rate;
477 dest += MV_Channels;
478 }
479
480 MV_MixPosition = position;
481 MV_MixDestination = (char *)dest;
482
483}
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix16.asm b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix16.asm
new file mode 100644
index 0000000000..f36cf47437
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mv_mix16.asm
@@ -0,0 +1,524 @@
1 IDEAL
2
3 p386
4 MODEL flat
5
6 dataseg
7 CODESEG
8
9 MASM
10 ALIGN 4
11
12EXTRN _MV_HarshClipTable:DWORD
13EXTRN _MV_MixDestination:DWORD
14EXTRN _MV_MixPosition:DWORD
15EXTRN _MV_LeftVolume:DWORD
16EXTRN _MV_RightVolume:DWORD
17EXTRN _MV_SampleSize:DWORD
18EXTRN _MV_RightChannelOffset:DWORD
19
20;================
21;
22; MV_Mix8BitMono16
23;
24;================
25
26; eax - position
27; edx - rate
28; ebx - start
29; ecx - number of samples to mix
30
31PROC MV_Mix8BitMono16_
32PUBLIC MV_Mix8BitMono16_
33; Two at once
34 pushad
35 mov ebp, eax
36
37 mov esi, ebx ; Source pointer
38 inc esi
39
40 ; Sample size
41 mov ebx, _MV_SampleSize
42 mov eax,OFFSET apatch7+2 ; convice tasm to modify code...
43 mov [eax],bl
44 mov eax,OFFSET apatch8+2 ; convice tasm to modify code...
45 mov [eax],bl
46 mov eax,OFFSET apatch9+3 ; convice tasm to modify code...
47 mov [eax],bl
48
49 ; Volume table ptr
50 mov ebx, _MV_LeftVolume ; Since we're mono, use left volume
51 mov eax,OFFSET apatch1+4 ; convice tasm to modify code...
52 mov [eax],ebx
53 mov eax,OFFSET apatch2+4 ; convice tasm to modify code...
54 mov [eax],ebx
55
56 ; Harsh Clip table ptr
57 mov ebx, _MV_HarshClipTable
58 add ebx, 128
59 mov eax,OFFSET apatch3+2 ; convice tasm to modify code...
60 mov [eax],ebx
61 mov eax,OFFSET apatch4+2 ; convice tasm to modify code...
62 mov [eax],ebx
63
64 ; Rate scale ptr
65 mov eax,OFFSET apatch5+2 ; convice tasm to modify code...
66 mov [eax],edx
67 mov eax,OFFSET apatch6+2 ; convice tasm to modify code...
68 mov [eax],edx
69
70 mov edi, _MV_MixDestination ; Get the position to write to
71
72 ; Number of samples to mix
73 shr ecx, 1 ; double sample count
74 cmp ecx, 0
75 je exit8m
76
77; eax - scratch
78; ebx - scratch
79; edx - scratch
80; ecx - count
81; edi - destination
82; esi - source
83; ebp - frac pointer
84; apatch1 - volume table
85; apatch2 - volume table
86; apatch3 - harsh clip table
87; apatch4 - harsh clip table
88; apatch5 - sample rate
89; apatch6 - sample rate
90
91 mov eax,ebp ; begin calculating first sample
92 add ebp,edx ; advance frac pointer
93 shr eax,16 ; finish calculation for first sample
94
95 mov ebx,ebp ; begin calculating second sample
96 add ebp,edx ; advance frac pointer
97 shr ebx,16 ; finish calculation for second sample
98
99 movsx eax, byte ptr [esi+2*eax] ; get first sample
100 movsx ebx, byte ptr [esi+2*ebx] ; get second sample
101 add eax, 80h
102 add ebx, 80h
103
104 ALIGN 4
105mix8Mloop:
106 movzx edx, byte ptr [edi] ; get current sample from destination
107apatch1:
108 movsx eax, byte ptr [2*eax+12345678h] ; volume translate first sample
109apatch2:
110 movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate second sample
111 add eax, edx ; mix first sample
112apatch9:
113 movzx edx, byte ptr [edi + 1] ; get current sample from destination
114apatch3:
115 mov eax, [eax + 12345678h] ; harsh clip new sample
116 add ebx, edx ; mix second sample
117 mov [edi], al ; write new sample to destination
118 mov edx, ebp ; begin calculating third sample
119apatch4:
120 mov ebx, [ebx + 12345678h] ; harsh clip new sample
121apatch5:
122 add ebp,12345678h ; advance frac pointer
123 shr edx, 16 ; finish calculation for third sample
124 mov eax, ebp ; begin calculating fourth sample
125apatch7:
126 add edi, 2 ; move destination to second sample
127 shr eax, 16 ; finish calculation for fourth sample
128 mov [edi], bl ; write new sample to destination
129apatch6:
130 add ebp,12345678h ; advance frac pointer
131 movsx ebx, byte ptr [esi+2*eax] ; get fourth sample
132 movsx eax, byte ptr [esi+2*edx] ; get third sample
133 add ebx, 80h
134 add eax, 80h
135apatch8:
136 add edi, 2 ; move destination to third sample
137 dec ecx ; decrement count
138 jnz mix8Mloop ; loop
139
140 mov _MV_MixDestination, edi ; Store the current write position
141 mov _MV_MixPosition, ebp ; return position
142exit8m:
143 popad
144 ret
145ENDP MV_Mix8BitMono16_
146
147;================
148;
149; MV_Mix8BitStereo16
150;
151;================
152
153; eax - position
154; edx - rate
155; ebx - start
156; ecx - number of samples to mix
157
158PROC MV_Mix8BitStereo16_
159PUBLIC MV_Mix8BitStereo16_
160
161 pushad
162 mov ebp, eax
163
164 mov esi, ebx ; Source pointer
165 inc esi
166
167 ; Sample size
168 mov ebx, _MV_SampleSize
169 mov eax,OFFSET bpatch8+2 ; convice tasm to modify code...
170 mov [eax],bl
171 ; mov eax,OFFSET bpatch9+2 ; convice tasm to modify code...
172 ; mov [eax],bl
173
174 ; Right channel offset
175 mov ebx, _MV_RightChannelOffset
176 mov eax,OFFSET bpatch6+3 ; convice tasm to modify code...
177 mov [eax],ebx
178 mov eax,OFFSET bpatch7+2 ; convice tasm to modify code...
179 mov [eax],ebx
180
181 ; Volume table ptr
182 mov ebx, _MV_LeftVolume
183 mov eax,OFFSET bpatch1+4 ; convice tasm to modify code...
184 mov [eax],ebx
185
186 mov ebx, _MV_RightVolume
187 mov eax,OFFSET bpatch2+4 ; convice tasm to modify code...
188 mov [eax],ebx
189
190 ; Rate scale ptr
191 mov eax,OFFSET bpatch3+2 ; convice tasm to modify code...
192 mov [eax],edx
193
194 ; Harsh Clip table ptr
195 mov ebx, _MV_HarshClipTable
196 add ebx,128
197 mov eax,OFFSET bpatch4+2 ; convice tasm to modify code...
198 mov [eax],ebx
199 mov eax,OFFSET bpatch5+2 ; convice tasm to modify code...
200 mov [eax],ebx
201
202 mov edi, _MV_MixDestination ; Get the position to write to
203
204 ; Number of samples to mix
205 cmp ecx, 0
206 je short exit8S
207
208; eax - scratch
209; ebx - scratch
210; edx - scratch
211; ecx - count
212; edi - destination
213; esi - source
214; ebp - frac pointer
215; bpatch1 - left volume table
216; bpatch2 - right volume table
217; bpatch3 - sample rate
218; bpatch4 - harsh clip table
219; bpatch5 - harsh clip table
220
221 mov eax,ebp ; begin calculating first sample
222 shr eax,16 ; finish calculation for first sample
223
224 movsx ebx, byte ptr [esi+2*eax] ; get first sample
225 add ebx, 80h
226
227 ALIGN 4
228mix8Sloop:
229bpatch1:
230 movsx eax, byte ptr [2*ebx+12345678h] ; volume translate left sample
231 movzx edx, byte ptr [edi] ; get current sample from destination
232bpatch2:
233 movsx ebx, byte ptr [2*ebx+12345678h] ; volume translate right sample
234 add eax, edx ; mix left sample
235bpatch3:
236 add ebp,12345678h ; advance frac pointer
237bpatch6:
238 movzx edx, byte ptr [edi+12345678h] ; get current sample from destination
239bpatch4:
240 mov eax, [eax + 12345678h] ; harsh clip left sample
241 add ebx, edx ; mix right sample
242 mov [edi], al ; write left sample to destination
243bpatch5:
244 mov ebx, [ebx + 12345678h] ; harsh clip right sample
245 mov edx, ebp ; begin calculating second sample
246bpatch7:
247 mov [edi+12345678h], bl ; write right sample to destination
248 shr edx, 16 ; finish calculation for second sample
249bpatch8:
250 add edi, 1 ; move destination to second sample
251 movsx ebx, byte ptr [esi+2*edx] ; get second sample
252 add ebx, 80h
253 dec ecx ; decrement count
254 jnz mix8Sloop ; loop
255
256 mov _MV_MixDestination, edi ; Store the current write position
257 mov _MV_MixPosition, ebp ; return position
258
259EXIT8S:
260 popad
261 ret
262ENDP MV_Mix8BitStereo16_
263
264;================
265;
266; MV_Mix16BitMono16
267;
268;================
269
270; eax - position
271; edx - rate
272; ebx - start
273; ecx - number of samples to mix
274
275PROC MV_Mix16BitMono16_
276PUBLIC MV_Mix16BitMono16_
277
278 pushad
279 mov ebp, eax
280
281 mov esi, ebx ; Source pointer
282
283 ; Sample size
284 mov ebx, _MV_SampleSize
285 mov eax,OFFSET cpatch4+2 ; convice tasm to modify code...
286 mov [eax],bl
287 mov eax,OFFSET cpatch5+3 ; convice tasm to modify code...
288 mov [eax],bl
289
290 ; Volume table ptr
291 mov ebx, _MV_LeftVolume
292 mov eax,OFFSET cpatch2+4 ; convice tasm to modify code...
293 mov [eax],ebx
294 mov eax,OFFSET cpatch1+4 ; convice tasm to modify code...
295 inc ebx
296 mov [eax],ebx
297
298 ; Rate scale ptr
299 mov eax,OFFSET cpatch3+2 ; convice tasm to modify code...
300 mov [eax],edx
301
302 mov edi, _MV_MixDestination ; Get the position to write to
303
304 ; Number of samples to mix
305 cmp ecx, 0
306 je exit16M
307
308; eax - scratch
309; ebx - scratch
310; edx - scratch
311; ecx - count
312; edi - destination
313; esi - source
314; ebp - frac pointer
315; cpatch1 - volume table
316; cpatch2 - volume table
317; cpatch3 - sample rate
318; cpatch4 - sample rate
319
320 mov ebx,ebp ; begin calculating first sample
321 add ebp,edx ; advance frac pointer
322 shr ebx,16 ; finish calculation for first sample
323 movzx eax, word ptr [esi+2*ebx] ; get low byte of sample
324 xor eax, 8000h
325 movzx ebx, ah
326 sub ah, ah
327
328 movsx edx, word ptr [edi] ; get current sample from destination
329
330 ALIGN 4
331mix16Mloop:
332cpatch1:
333 movsx eax, byte ptr [2*eax+12345678h] ; volume translate low byte of sample
334cpatch2:
335 movsx ebx, word ptr [2*ebx+12345678h] ; volume translate high byte of sample
336 lea eax, [ eax + ebx + 80h ] ; mix high byte of sample
337 add eax, edx ; mix low byte of sample
338cpatch5:
339 movsx edx, word ptr [edi + 2] ; get current sample from destination
340
341 cmp eax, -32768 ; Harsh clip sample
342 jge short m16skip1
343 mov eax, -32768
344 jmp short m16skip2
345m16skip1:
346 cmp eax, 32767
347 jle short m16skip2
348 mov eax, 32767
349m16skip2:
350 mov ebx, ebp ; begin calculating second sample
351 mov [edi], ax ; write new sample to destination
352
353 shr ebx, 16 ; finish calculation for second sample
354cpatch3:
355 add ebp, 12345678h ; advance frac pointer
356
357 movzx eax, word ptr [esi+2*ebx] ; get second sample
358cpatch4:
359 add edi, 2 ; move destination to second sample
360 xor eax, 8000h
361 movzx ebx, ah
362 sub ah, ah
363
364 dec ecx ; decrement count
365 jnz mix16Mloop ; loop
366
367 mov _MV_MixDestination, edi ; Store the current write position
368 mov _MV_MixPosition, ebp ; return position
369EXIT16M:
370 popad
371 ret
372ENDP MV_Mix16BitMono16_
373
374;================
375;
376; MV_Mix16BitStereo16
377;
378;================
379
380; eax - position
381; edx - rate
382; ebx - start
383; ecx - number of samples to mix
384
385PROC MV_Mix16BitStereo16_
386PUBLIC MV_Mix16BitStereo16_
387
388 pushad
389 mov ebp, eax
390
391 mov esi, ebx ; Source pointer
392
393 ; Sample size
394 mov ebx, _MV_SampleSize
395 mov eax,OFFSET dpatch9+2 ; convice tasm to modify code...
396 mov [eax],bl
397
398 ; Right channel offset
399 mov ebx, _MV_RightChannelOffset
400 mov eax,OFFSET dpatch7+3 ; convice tasm to modify code...
401 mov [eax],ebx
402 mov eax,OFFSET dpatch8+3 ; convice tasm to modify code...
403 mov [eax],ebx
404
405 ; Volume table ptr
406 mov ebx, _MV_LeftVolume
407 mov eax,OFFSET dpatch1+4 ; convice tasm to modify code...
408 mov [eax],ebx
409 mov eax,OFFSET dpatch2+4 ; convice tasm to modify code...
410 inc ebx
411 mov [eax],ebx
412
413 mov ebx, _MV_RightVolume
414 mov eax,OFFSET dpatch3+4 ; convice tasm to modify code...
415 mov [eax],ebx
416 mov eax,OFFSET dpatch4+4 ; convice tasm to modify code...
417 inc ebx
418 mov [eax],ebx
419
420 ; Rate scale ptr
421 mov eax,OFFSET dpatch5+2 ; convice tasm to modify code...
422 mov [eax],edx
423
424 ; Source ptr
425 mov eax,OFFSET dpatch6+4 ; convice tasm to modify code...
426 mov [eax],esi
427
428 mov edi, _MV_MixDestination ; Get the position to write to
429
430 ; Number of samples to mix
431 cmp ecx, 0
432 je exit16S
433
434; eax - scratch
435; ebx - scratch
436; edx - scratch
437; esi - scratch
438; ecx - count
439; edi - destination
440; ebp - frac pointer
441; dpatch1 - left volume table
442; dpatch2 - right volume table
443; dpatch3 - sample rate
444
445 mov ebx,ebp ; begin calculating first sample
446 shr ebx,16 ; finish calculation for first sample
447
448 movzx edx, word ptr [esi+2*ebx] ; get first sample
449 xor edx, 8000h ; Change from signed to unsigned
450 movzx esi, dh ; put high byte in esi
451 sub dh, dh ; lo byte in edx
452
453 ALIGN 4
454mix16Sloop:
455 ; Left channel
456dpatch1:
457 movsx eax, word ptr [2*esi+12345678h] ; volume translate high byte of sample
458dpatch2:
459 movsx ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample
460 lea eax, [ eax + ebx + 80h ] ; mix high byte of sample
461
462 ; Right channel
463dpatch3:
464 movsx esi, word ptr [2*esi+12345678h] ; volume translate high byte of sample
465dpatch4:
466 movsx ebx, byte ptr [2*edx+12345678h] ; volume translate low byte of sample
467 lea ebx, [ esi + ebx + 80h ] ; mix high byte of sample
468
469dpatch7:
470 movsx edx, word ptr [edi+12345678h] ; get current sample from destination
471dpatch5:
472 add ebp,12345678h ; advance frac pointer
473
474 add eax, edx ; mix left sample
475
476 cmp eax, -32768 ; Harsh clip sample
477 jge short s16skip1
478 mov eax, -32768
479 jmp short s16skip2
480s16skip1:
481 cmp eax, 32767
482 jle short s16skip2
483 mov eax, 32767
484s16skip2:
485 movsx edx, word ptr [edi+2] ; get current sample from destination
486 mov [edi], ax ; write left sample to destination
487 add ebx, edx ; mix right sample
488
489 cmp ebx, -32768 ; Harsh clip sample
490 jge short s16skip3
491 mov ebx, -32768
492 jmp short s16skip4
493s16skip3:
494 cmp ebx, 32767
495 jle short s16skip4
496 mov ebx, 32767
497s16skip4:
498
499 mov edx, ebp ; begin calculating second sample
500dpatch8:
501 mov [edi+12345678h], bx ; write right sample to destination
502 shr edx, 16 ; finish calculation for second sample
503dpatch9:
504 add edi, 4 ; move destination to second sample
505
506dpatch6:
507 movzx edx, word ptr [2*edx+12345678h] ; get second sample
508 xor edx, 8000h ; Change from signed to unsigned
509 movzx esi, dh ; put high byte in esi
510 sub dh, dh ; lo byte in edx
511
512 dec ecx ; decrement count
513 jnz mix16Sloop ; loop
514
515 mov _MV_MixDestination, edi ; Store the current write position
516 mov _MV_MixPosition, ebp ; return position
517exit16S:
518 popad
519 ret
520ENDP MV_Mix16BitStereo16_
521
522 ENDS
523
524 END
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mvreverb.asm b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mvreverb.asm
new file mode 100644
index 0000000000..8a23ccca3d
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mvreverb.asm
@@ -0,0 +1,181 @@
1 IDEAL
2
3 p386
4 MODEL flat
5
6 dataseg
7 CODESEG
8
9 MASM
10 ALIGN 4
11
12;================
13;
14; MV_16BitReverb
15;
16;================
17
18; eax - source position
19; edx - destination position
20; ebx - Volume table
21; ecx - number of samples
22
23PROC MV_16BitReverb_
24PUBLIC MV_16BitReverb_
25
26 mov esi, eax
27 lea edi, [edx - 2]
28
29 ALIGN 4
30rev16loop:
31 movzx eax, word ptr [esi] ; get sample
32 add edi, 2
33
34 movzx edx, ah
35 sub ah, ah
36
37 movsx eax, byte ptr [2*eax+ebx+1] ; volume translate low byte of sample
38 xor edx, 80h
39
40 movsx edx, word ptr [2*edx+ebx] ; volume translate high byte of sample
41 add esi, 2
42
43 lea eax, [ eax + edx + 80h ] ; mix high byte of sample
44 dec ecx ; decrement count
45
46 mov [edi], ax ; write new sample to destination
47 jnz rev16loop ; loop
48
49 ret
50ENDP MV_16BitReverb_
51
52;================
53;
54; MV_8BitReverb
55;
56;================
57
58; eax - source position
59; edx - destination position
60; ebx - Volume table
61; ecx - number of samples
62
63PROC MV_8BitReverb_
64PUBLIC MV_8BitReverb_
65
66 mov esi, eax
67 lea edi, [edx - 1]
68
69 xor eax, eax
70
71 ALIGN 4
72rev8loop:
73; movzx eax, byte ptr [esi] ; get sample
74 mov al, byte ptr [esi] ; get sample
75 inc edi
76
77; movsx eax, byte ptr [2*eax+ebx] ; volume translate sample
78 mov al, byte ptr [2*eax+ebx] ; volume translate sample
79 inc esi
80
81; add eax, 80h
82 add al, 80h
83 dec ecx ; decrement count
84
85 mov [edi], al ; write new sample to destination
86 jnz rev8loop ; loop
87
88 ret
89ENDP MV_8BitReverb_
90
91;================
92;
93; MV_16BitReverbFast
94;
95;================
96
97; eax - source position
98; edx - destination position
99; ebx - number of samples
100; ecx - shift
101
102PROC MV_16BitReverbFast_
103PUBLIC MV_16BitReverbFast_
104
105 mov esi, eax
106 mov eax,OFFSET rpatch16+3
107
108 mov [eax],cl
109 lea edi, [edx - 2]
110
111 ALIGN 4
112frev16loop:
113 mov ax, word ptr [esi] ; get sample
114 add edi, 2
115
116rpatch16:
117 sar ax, 5 ;;;;Add 1 before shift
118 add esi, 2
119
120 mov [edi], ax ; write new sample to destination
121 dec ebx ; decrement count
122
123 jnz frev16loop ; loop
124
125 ret
126ENDP MV_16BITREVERBFAST_
127
128;================
129;
130; MV_8BitReverbFast
131;
132;================
133
134; eax - source position
135; edx - destination position
136; ebx - number of samples
137; ecx - shift
138
139PROC MV_8BitReverbFast_
140PUBLIC MV_8BitReverbFast_
141 mov esi, eax
142 mov eax,OFFSET rpatch8+2
143
144 mov edi, edx
145 mov edx, 80h
146
147 mov [eax],cl
148 mov eax, 80h
149
150 shr eax, cl
151
152 dec edi
153 sub edx, eax
154
155 ALIGN 4
156frev8loop:
157 mov al, byte ptr [esi] ; get sample
158 inc esi
159
160 mov ecx, eax
161 inc edi
162
163rpatch8:
164 shr eax, 3
165 xor ecx, 80h ; flip the sign bit
166
167 shr ecx, 7 ; shift the sign down to 1
168 add eax, edx
169
170 add eax, ecx ; add sign bit to round to 0
171 dec ebx ; decrement count
172
173 mov [edi], al ; write new sample to destination
174 jnz frev8loop ; loop
175
176 ret
177ENDP MV_8BITREVERBFAST_
178
179 ENDS
180
181 END
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mvreverb.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mvreverb.c
new file mode 100644
index 0000000000..0d058d85ee
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/mvreverb.c
@@ -0,0 +1,312 @@
1#include "multivoc.h"
2#include "_multivc.h"
3
4extern double *MV_FooBuffer;
5extern int MV_BufferSize;
6extern int MV_SampleSize;
7extern int MV_MaxVolume;
8extern int MV_ReverbDelay;
9extern int MV_MixRate;
10extern int MV_Channels;
11
12static double * reverbBuffer = 0;
13static int delay = 0, CurrAddr;
14
15static int FB_SRC_A, FB_SRC_B, IIR_DEST_A0, IIR_DEST_A1, ACC_SRC_A0, ACC_SRC_A1, ACC_SRC_B0,
16 ACC_SRC_B1, IIR_SRC_A0, IIR_SRC_A1, IIR_DEST_B0, IIR_DEST_B1, ACC_SRC_C0,
17 ACC_SRC_C1, ACC_SRC_D0, ACC_SRC_D1, IIR_SRC_B1, IIR_SRC_B0, MIX_DEST_A0,
18 MIX_DEST_A1, MIX_DEST_B0, MIX_DEST_B1;
19
20static double IIR_ALPHA, ACC_COEF_A, ACC_COEF_B, ACC_COEF_C, ACC_COEF_D, IIR_COEF, FB_ALPHA, FB_X,
21 IN_COEF_L, IN_COEF_R;
22
23static double iRVBLeft, iRVBRight;
24
25static int cnv_offset(int src)
26{
27 int64_t temp = ((int64_t)src * (int64_t)MV_MixRate) / 22050;
28 return (int)temp;
29}
30
31// static char err[256];
32
33// extern __stdcall OutputDebugStringA(char *);
34
35static void check_buffer()
36{
37 int new_delay = cnv_offset(MV_ReverbDelay);
38
39 if (!delay || new_delay != delay)
40 {
41// sprintf(err + strlen(err), ", new_delay: %d, MV_ReverbDelay: %d", new_delay, MV_ReverbDelay);
42 FB_SRC_A = cnv_offset(0xE3);
43 FB_SRC_B = cnv_offset(0xA9);
44 IIR_DEST_A0 = cnv_offset(0xDFB);
45 IIR_DEST_A1 = cnv_offset(0xB58);
46 ACC_SRC_A0 = cnv_offset(0xD09);
47 ACC_SRC_A1 = cnv_offset(0xA3C);
48 ACC_SRC_B0 = cnv_offset(0xBD9);
49 ACC_SRC_B1 = cnv_offset(0x973);
50 IIR_SRC_A0 = cnv_offset(0xB59);
51 IIR_SRC_A1 = cnv_offset(0x8DA);
52 IIR_DEST_B0 = cnv_offset(0x8D9);
53 IIR_DEST_B1 = cnv_offset(0x5E9);
54 ACC_SRC_C0 = cnv_offset(0x7EC);
55 ACC_SRC_C1 = cnv_offset(0x4B0);
56 ACC_SRC_D0 = cnv_offset(0x6EF);
57 ACC_SRC_D1 = cnv_offset(0x3D2);
58 IIR_SRC_B1 = cnv_offset(0x5EA);
59 IIR_SRC_B0 = cnv_offset(0x31D);
60 MIX_DEST_A0 = cnv_offset(0x31C);
61 MIX_DEST_A1 = cnv_offset(0x238);
62 MIX_DEST_B0 = cnv_offset(0x154);
63 MIX_DEST_B1 = cnv_offset(0xAA);
64 IIR_ALPHA = 0.8701171875;
65 ACC_COEF_A = 0.622314453125;
66 ACC_COEF_B = -0.5244140625;
67 ACC_COEF_C = 0.53955078125;
68 ACC_COEF_D = -0.50830078125;
69 IIR_COEF = -0.69921875;
70 FB_ALPHA = 0.67578125;
71 FB_X = 0.646484375;
72 IN_COEF_L = -2.;
73 IN_COEF_R = -2.;
74 if (reverbBuffer) reverbBuffer = (double*) realloc(reverbBuffer, new_delay * sizeof(double));
75 else reverbBuffer = (double*) malloc(new_delay * sizeof(double));
76 memset(reverbBuffer, 0, new_delay * sizeof(double));
77 delay = new_delay;
78 CurrAddr = 0;
79 }
80
81}
82
83double g_buffer(int iOff, double *ptr) // get_buffer content helper: takes care about wraps
84{
85 int correctDelay = delay;
86 if(!correctDelay)
87 {
88 printf("Error! Reverb race on g_buffer\n");
89 correctDelay = cnv_offset(14320);
90 }
91
92 iOff=(iOff*4)+CurrAddr;
93 while(iOff>correctDelay-1)
94 {
95 iOff=iOff-correctDelay;
96 }
97 while(iOff<0)
98 {
99 iOff=correctDelay-(0-iOff);
100 }
101 return (double)*(ptr+iOff);
102}
103
104void s_buffer(int iOff,double iVal, double *ptr) // set_buffer content helper: takes care about wraps and clipping
105{
106 int correctDelay = delay;
107 if(!correctDelay)
108 {
109 printf("Error! Reverb race on s_buffer\n");
110 correctDelay = cnv_offset(14320);
111 }
112
113 iOff=(iOff*4)+CurrAddr;
114 while(iOff>correctDelay-1)
115 {
116 iOff=iOff-correctDelay;
117 }
118 while(iOff<0)
119 {
120 iOff=correctDelay-(0-iOff);
121 }
122 *(ptr+iOff)=iVal;
123}
124
125void s_buffer1(int iOff,double iVal, double *ptr) // set_buffer (+1 sample) content helper: takes care about wraps and clipping
126{
127 int correctDelay = delay;
128 if(!correctDelay)
129 {
130 printf("Error! Reverb race on s_buffer1\n");
131 correctDelay = cnv_offset(14320);
132 }
133
134 iOff=(iOff*4)+CurrAddr+1;
135 while(iOff>correctDelay-1)
136 {
137 iOff=iOff-correctDelay;
138 }
139 while(iOff<0)
140 {
141 iOff=correctDelay-(0-iOff);
142 }
143 *(ptr+iOff)=iVal;
144}
145
146double MixREVERBLeft(double INPUT_SAMPLE_L, double INPUT_SAMPLE_R, double *ptr)
147{
148 double ACC0,ACC1,FB_A0,FB_A1,FB_B0,FB_B1;
149
150 const double IIR_INPUT_A0 = (g_buffer(IIR_SRC_A0, ptr) * IIR_COEF) + (INPUT_SAMPLE_L * IN_COEF_L);
151 const double IIR_INPUT_A1 = (g_buffer(IIR_SRC_A1, ptr) * IIR_COEF) + (INPUT_SAMPLE_R * IN_COEF_R);
152 const double IIR_INPUT_B0 = (g_buffer(IIR_SRC_B0, ptr) * IIR_COEF) + (INPUT_SAMPLE_L * IN_COEF_L);
153 const double IIR_INPUT_B1 = (g_buffer(IIR_SRC_B1, ptr) * IIR_COEF) + (INPUT_SAMPLE_R * IN_COEF_R);
154
155 const double IIR_A0 = (IIR_INPUT_A0 * IIR_ALPHA) + (g_buffer(IIR_DEST_A0, ptr) * (1.f - IIR_ALPHA));
156 const double IIR_A1 = (IIR_INPUT_A1 * IIR_ALPHA) + (g_buffer(IIR_DEST_A1, ptr) * (1.f - IIR_ALPHA));
157 const double IIR_B0 = (IIR_INPUT_B0 * IIR_ALPHA) + (g_buffer(IIR_DEST_B0, ptr) * (1.f - IIR_ALPHA));
158 const double IIR_B1 = (IIR_INPUT_B1 * IIR_ALPHA) + (g_buffer(IIR_DEST_B1, ptr) * (1.f - IIR_ALPHA));
159
160 s_buffer1(IIR_DEST_A0, IIR_A0, ptr);
161 s_buffer1(IIR_DEST_A1, IIR_A1, ptr);
162 s_buffer1(IIR_DEST_B0, IIR_B0, ptr);
163 s_buffer1(IIR_DEST_B1, IIR_B1, ptr);
164
165 ACC0 = (g_buffer(ACC_SRC_A0, ptr) * ACC_COEF_A) +
166 (g_buffer(ACC_SRC_B0, ptr) * ACC_COEF_B) +
167 (g_buffer(ACC_SRC_C0, ptr) * ACC_COEF_C) +
168 (g_buffer(ACC_SRC_D0, ptr) * ACC_COEF_D);
169 ACC1 = (g_buffer(ACC_SRC_A1, ptr) * ACC_COEF_A) +
170 (g_buffer(ACC_SRC_B1, ptr) * ACC_COEF_B) +
171 (g_buffer(ACC_SRC_C1, ptr) * ACC_COEF_C) +
172 (g_buffer(ACC_SRC_D1, ptr) * ACC_COEF_D);
173
174 FB_A0 = g_buffer(MIX_DEST_A0 - FB_SRC_A, ptr);
175 FB_A1 = g_buffer(MIX_DEST_A1 - FB_SRC_A, ptr);
176 FB_B0 = g_buffer(MIX_DEST_B0 - FB_SRC_B, ptr);
177 FB_B1 = g_buffer(MIX_DEST_B1 - FB_SRC_B, ptr);
178
179 s_buffer(MIX_DEST_A0, ACC0 - (FB_A0 * FB_ALPHA), ptr);
180 s_buffer(MIX_DEST_A1, ACC1 - (FB_A1 * FB_ALPHA), ptr);
181
182 s_buffer(MIX_DEST_B0, (FB_ALPHA * ACC0) - (FB_A0 * (FB_ALPHA - 1.f)) - (FB_B0 * FB_X), ptr);
183 s_buffer(MIX_DEST_B1, (FB_ALPHA * ACC1) - (FB_A1 * (FB_ALPHA - 1.f)) - (FB_B1 * FB_X), ptr);
184
185 iRVBLeft = (g_buffer(MIX_DEST_A0, ptr)+g_buffer(MIX_DEST_B0, ptr))/3.f;
186 iRVBRight = (g_buffer(MIX_DEST_A1, ptr)+g_buffer(MIX_DEST_B1, ptr))/3.f;
187
188 CurrAddr++;
189 if(CurrAddr>delay-1) CurrAddr=0;
190
191 return (double)iRVBLeft;
192}
193
194double MixREVERBRight(void)
195{
196 return (double)iRVBRight;
197}
198
199void MV_FPReverb(int volume)
200{
201 int i, count = MV_BufferSize / MV_SampleSize * MV_Channels;
202
203// sprintf(err, "count: %d, old_delay: %d", count, delay);
204 //EnterCriticalSection(&reverbCS);
205 SDL_mutexP(reverbMutex);
206
207 check_buffer();
208
209 // DAVE
210 if(delay == 0)
211 {
212 //get out now!!!
213 printf("Error! MV_FPReverb() delay==0\n");
214 return;
215 }
216
217// OutputDebugStringA(err);
218
219 if (MV_Channels == 1)
220 {
221 for (i = 0; i < count; i++)
222 {
223 double temp = MV_FooBuffer[i];
224 MV_FooBuffer[i] += ((MixREVERBLeft(temp, temp, reverbBuffer) + MixREVERBRight()) * .5) * (double)volume / (double)MV_MaxVolume;
225 }
226 }
227 else
228 {
229 count >>= 1;
230 for (i = 0; i < count; i++)
231 {
232 double left = MV_FooBuffer[i*2];
233 double right = MV_FooBuffer[i*2+1];
234 double scale = (double)volume / (double)MV_MaxVolume;
235 left += MixREVERBLeft(left, right, reverbBuffer) * scale;
236 right += MixREVERBRight() * scale;
237 MV_FooBuffer[i*2] = left;
238 MV_FooBuffer[i*2+1] = right;
239 }
240 }
241
242 //LeaveCriticalSection(&reverbCS);
243 SDL_mutexV(reverbMutex);
244}
245
246void MV_FPReverbFree(void)
247{
248 SDL_mutexP(reverbMutex);
249 //EnterCriticalSection(&reverbCS);
250 delay = 0;
251 if (reverbBuffer)
252 {
253 free(reverbBuffer);
254 reverbBuffer = 0;
255 }
256 //LeaveCriticalSection(&reverbCS);
257 SDL_mutexV(reverbMutex);
258}
259
260void MV_16BitDownmix(char *dest, int count)
261{
262 int i;
263
264 short *pdest = (short *)dest;
265
266 for (i = 0; i < count; i++)
267 {
268 int out = (int)((MV_FooBuffer[i] * (double)0x8000));
269 if (out < -32768) pdest[i] = -32768;
270 else if (out > 32767) pdest[i] = 32767;
271 else pdest[i] = out;
272 }
273}
274
275void MV_8BitDownmix(char *dest, int count)
276{
277 int i;
278
279 for (i = 0; i < count; i++)
280 {
281 int out = ((int)((MV_FooBuffer[i] * (double)0x80)));
282 if (out < -128) dest[i] = 0;
283 else if (out > 127) dest[i] = 255;
284 else dest[i] = out + 0x80;
285 }
286}
287
288void MV_16BitReverbFast( const char *src, char *dest, int count, int shift )
289{
290 int i;
291
292 short *pdest = (short *)dest;
293 const short *psrc = (const short *)src;
294
295 for (i = 0; i < count; i++) {
296 pdest[i] = readLE16(psrc + i) >> shift;
297 }
298}
299
300void MV_8BitReverbFast( const signed char *src, signed char *dest, int count, int shift )
301{
302 int i;
303
304 unsigned char sh = 0x80 - (0x80 >> shift);
305
306 for (i = 0; i < count; i++) {
307 unsigned char a = ((unsigned char) src[i]) >> shift;
308 unsigned char c = (((unsigned char) src[i]) ^ 0x80) >> 7;
309
310 dest[i] = (signed char) (a + sh + c);
311 }
312}
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/myprint.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/myprint.c
new file mode 100644
index 0000000000..e8b2c45f60
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/myprint.c
@@ -0,0 +1,310 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20#include <stdio.h>
21#include <stdarg.h>
22#include <stdlib.h>
23#include "myprint.h"
24
25static unsigned short disp_offset = 160 * 24;
26
27void DrawText
28 (
29 int x,
30 int y,
31 int ch,
32 int foreground,
33 int background
34 )
35
36 {
37 char *vid;
38
39 vid = ( char * )( 0xb0000 );
40 vid += y * 160;
41 vid += x * 2;
42
43 if ( ch != NONE )
44 {
45 *vid = ch;
46 }
47 vid++;
48 *vid = ( ( background & 0x0f ) << 4 ) | ( foreground & 0x0f );
49 }
50
51void TextBox
52 (
53 int x1,
54 int y1,
55 int x2,
56 int y2,
57 int ch,
58 int foreground,
59 int background
60 )
61
62 {
63 int x;
64 int y;
65
66 for( x = x1; x <= x2; x++ )
67 {
68 for( y = y1; y <= y2; y++ )
69 {
70 DrawText( x, y, ch, foreground, background );
71 }
72 }
73 }
74
75void TextFrame
76 (
77 int x1,
78 int y1,
79 int x2,
80 int y2,
81 int type,
82 int foreground,
83 int background
84 )
85
86 {
87 int x;
88 int y;
89
90 if ( type == 0 )
91 {
92 for( x = x1 + 1; x < x2; x++ )
93 {
94 DrawText( x, y1, type, foreground, background );
95 DrawText( x, y2, type, foreground, background );
96 }
97 for( y = y1 + 1; y < y2; y++ )
98 {
99 DrawText( x1, y, type, foreground, background );
100 DrawText( x2, y, type, foreground, background );
101 }
102 }
103 if ( type == SINGLE_FRAME )
104 {
105 DrawText( x1, y1, 'Ú', foreground, background );
106 DrawText( x2, y1, '¿', foreground, background );
107 DrawText( x1, y2, 'À', foreground, background );
108 DrawText( x2, y2, 'Ù', foreground, background );
109 for( x = x1 + 1; x < x2; x++ )
110 {
111 DrawText( x, y1, 'Ä', foreground, background );
112 DrawText( x, y2, 'Ä', foreground, background );
113 }
114 for( y = y1 + 1; y < y2; y++ )
115 {
116 DrawText( x1, y, '³', foreground, background );
117 DrawText( x2, y, '³', foreground, background );
118 }
119 }
120 if ( type == DOUBLE_FRAME )
121 {
122 DrawText( x1, y1, 'É', foreground, background );
123 DrawText( x2, y1, '»', foreground, background );
124 DrawText( x1, y2, 'È', foreground, background );
125 DrawText( x2, y2, '¼', foreground, background );
126 for( x = x1 + 1; x < x2; x++ )
127 {
128 DrawText( x, y1, 'Í', foreground, background );
129 DrawText( x, y2, 'Í', foreground, background );
130 }
131 for( y = y1 + 1; y < y2; y++ )
132 {
133 DrawText( x1, y, 'º', foreground, background );
134 DrawText( x2, y, 'º', foreground, background );
135 }
136 }
137 }
138
139void mysetxy
140 (
141 int x,
142 int y
143 )
144
145 {
146 disp_offset = ( x * 2 ) + ( y * 160 );
147 }
148
149void myputch
150 (
151 char ch
152 )
153
154 {
155 int j;
156 char *disp_start = (char *)( 0xb0000 );
157
158 if ( disp_offset >= 160 * 24 )
159 {
160 for ( j = 160; j < 160 * 24; j += 2 )
161 {
162 *( disp_start + j - 160 ) = *( disp_start + j );
163 }
164
165 disp_offset = 160 * 23;
166
167 for ( j = disp_offset; j < ( 160 * 24 ); j += 2 )
168 {
169 *( disp_start + j ) = ' ';
170 }
171 }
172
173 if ( ch >= 32 )
174 {
175 *( disp_start + disp_offset ) = ch;
176 disp_offset = disp_offset + 2;
177 }
178
179 if ( ch == '\r' )
180 {
181 disp_offset = disp_offset / 160;
182 disp_offset = disp_offset * 160;
183 }
184
185 if ( ch == '\n' )
186 {
187 disp_offset = disp_offset + 160;
188 if ( disp_offset < 160 * 24 )
189 {
190 for ( j = disp_offset; j < ( ( ( disp_offset / 160 ) + 1 ) *
191 160 ); j += 2 )
192 {
193 *( disp_start + j ) = ' ';
194 }
195 }
196 }
197 }
198
199int printstring
200 (
201 char *string
202 )
203
204 {
205 int count;
206 char *ptr;
207
208 ptr = string;
209 count = 0;
210
211 while ( *ptr )
212 {
213 myputch( *ptr );
214 count++;
215 ptr++;
216 }
217
218 return( count );
219 }
220
221
222int printnum
223 (
224 int number
225 )
226
227 {
228 char string[ 100 ];
229 int count;
230
231 itoa( number, string, 10 );
232 count = printstring( string );
233
234 return( count );
235 }
236
237int printunsigned
238 (
239 unsigned long number,
240 int radix
241 )
242
243 {
244 char string[ 100 ];
245 int count;
246
247 ultoa( number, string, radix );
248 count = printstring( string );
249
250 return( count );
251 }
252
253int myprintf
254 (
255 char *fmt,
256 ...
257 )
258
259 {
260 va_list argptr;
261 int count;
262 char *ptr;
263
264 return( 0 );
265
266 // DEBUG
267 mysetxy( 0, 0 );
268
269 va_start( argptr, fmt );
270 ptr = fmt;
271 count = 0;
272
273 while( *ptr != 0 )
274 {
275 if ( *ptr == '%' )
276 {
277 ptr++;
278 switch( *ptr )
279 {
280 case 0 :
281 return( EOF );
282 break;
283 case 'd' :
284 count += printnum( va_arg( argptr, int ) );
285 break;
286 case 's' :
287 count += printstring( va_arg( argptr, char * ) );
288 break;
289 case 'u' :
290 count += printunsigned( va_arg( argptr, int ), 10 );
291 break;
292 case 'x' :
293 case 'X' :
294 count += printunsigned( va_arg( argptr, int ), 16 );
295 break;
296 }
297 ptr++;
298 }
299 else
300 {
301 myputch( *ptr );
302 count++;
303 ptr++;
304 }
305 }
306
307 va_end( argptr );
308
309 return( count );
310 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/myprint.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/myprint.h
new file mode 100644
index 0000000000..19a5d0f93d
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/myprint.h
@@ -0,0 +1,43 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20#ifndef __MYPRINT_H
21#define __MYPRINT_H
22
23enum COLORS
24 {
25 BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHTGRAY, DARKGRAY,
26 LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE
27 };
28
29#define NONE -1
30#define SINGLE_FRAME -1
31#define DOUBLE_FRAME -2
32
33void DrawText( int x, int y, int ch, int foreground, int background );
34void TextBox( int x1, int y1, int x2, int y2, int ch, int foreground, int background );
35void TextFrame( int x1, int y1, int x2, int y2, int type, int foreground, int background );
36void mysetxy( int x, int y );
37void myputch( char ch );
38int printstring( char *string );
39int printnum( int number );
40int printunsigned( unsigned long number, int radix );
41int myprintf( char *fmt, ... );
42
43#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/newgf1.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/newgf1.h
new file mode 100644
index 0000000000..fe9c857f7e
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/newgf1.h
@@ -0,0 +1,431 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/***************************************************************************
21* NAME: GF1.H
22** COPYRIGHT:
23** "Copyright (c) 1991,1992, by FORTE
24**
25** "This software is furnished under a license and may be used,
26** copied, or disclosed only in accordance with the terms of such
27** license and with the inclusion of the above copyright notice.
28** This software or any other copies thereof may not be provided or
29** otherwise made available to any other person. No title to and
30** ownership of the software is hereby transfered."
31****************************************************************************
32* CREATION DATE: 07/01/92
33*--------------------------------------------------------------------------*
34* VERSION DATE NAME DESCRIPTION
35*> 1.0 07/01/92 Original
36***************************************************************************/
37
38#ifndef _GF1_H /* allow header to be processed only once */
39#define _GF1_H
40
41/* error codes */
42#define OK 0
43#define NO_MORE_VOICES -1
44#define BASE_NOT_FOUND 1
45#define BAD_IRQ 2
46#define BAD_DMA 3
47#define OS_LOADED 4
48#define NOT_LOADED 5
49#define NO_MEMORY 6
50#define DMA_BUSY 7
51#define NO_MORE_HANDLERS 8
52#define DMA_HUNG 9
53#define CARD_NOT_FOUND 10
54#define CARD_BEING_USED 11
55#define NO_MORE_INTERRUPTS 12
56#define BAD_TIMER 13
57#define BAD_PATCH 14
58#define OLD_PATCH 15
59#define DOS_ERROR 16
60#define FILE_NOT_FOUND 17
61
62/* bits */
63#define BIT0 0x01
64#define BIT1 0x02
65#define BIT2 0x04
66#define BIT3 0x08
67#define BIT4 0x10
68#define BIT5 0x20
69#define BIT6 0x40
70#define BIT7 0x80
71
72/* bounds for volume enveloping functions */
73#define MIN_OFFSET 5U
74#define MAX_OFFSET 251U
75
76/* bounds for voice allocation */
77#define MIN_VOICES 14
78#define MAX_VOICES 32
79
80/* DMA control bits */
81#define DMA_ENABLE BIT0
82#define DMA_READ BIT1
83#define DMA_WIDTH_16 BIT2 /* width of DMA channel */
84#define DMA_RATE_DIV_1 BIT3
85#define DMA_RATE_DIV_2 BIT4
86#define DMA_IRQ_ENABLE BIT5
87#define DMA_IRQ_PRESENT BIT6
88#define DMA_DATA_16 BIT6 /* width of data */
89#define DMA_INVERT_MSB BIT7
90
91/* SAMPLE control bits */
92#define DMA_STEREO 2
93
94/* DMA flags */
95#define GF1_RECORD 0 /* use dma control or sample control */
96#define GF1_DMA 1
97
98/* MIDI control register */
99#define MIDI_RESET (BIT0|BIT1)
100#define MIDI_TD_INT BIT5
101#define MIDI_RD_INT BIT7
102
103/* MIDI_STATUS_REGISTER */
104#define MIDI_RD BIT0
105#define MIDI_TD BIT1
106#define MIDI_ERR_FRAMING BIT4
107#define MIDI_ERR_OVERRUN BIT5
108
109/* digital playback flags */
110#define TYPE_8BIT BIT0 /* 1 use 8 bit data */
111 /* 0 use 16 bit data */
112#define TYPE_PRELOAD BIT1 /* preload data */
113#define TYPE_INVERT_MSB BIT2 /* invert most significant bit during dma */
114#define TYPE_STEREO BIT3 /* 1 for stereo data */
115
116/* sound effects and digital music types */
117#define SND_LOOP_MASK (BIT0|BIT1)
118#define SND_LOOP_NONE 0
119#define SND_LOOP 1
120#define SND_LOOP_BIDIR 2
121#define SND_8BIT (BIT2)
122#define SND_BACKWARD (BIT3)
123
124#define SOUND_PLAYING 2
125#define SOUND_ACTIVE 1
126
127/* patch macros */
128#define HEADER_SIZE 12
129#define ID_SIZE 10
130#define DESC_SIZE 60
131#define RESERVED_SIZE 40
132#define PATCH_HEADER_RESERVED_SIZE 36
133#define LAYER_RESERVED_SIZE 40
134#define PATCH_DATA_RESERVED_SIZE 36
135#define GF1_HEADER_TEXT "GF1PATCH110"
136#define INST_NAME_SIZE 16
137#define ENVELOPES 6
138#define MAX_LAYERS 4
139
140/* patch modes */
141#define PATCH_16 BIT0
142#define PATCH_UNSIGNED BIT1
143#define PATCH_LOOPEN BIT2
144#define PATCH_BIDIR BIT3
145#define PATCH_BACKWARD BIT4
146#define PATCH_SUSTAIN BIT5
147#define PATCH_NO_SRELEASE BIT6
148#define PATCH_FAST_REL BIT7
149
150/* flags for patch loading */
151#define PATCH_LOAD_8_BIT BIT0
152
153/* digital playback callback reasons & return values */
154#define DIG_DONE 0
155#define DIG_MORE_DATA 1
156#define DIG_BUFFER_DONE 2
157#define DIG_PAUSE 3
158
159/* log table used for vibrato and pitch bend. log table made public for
160** developers use */
161#define LOG_TAB_SIZE 12
162extern long gf1_log_table[LOG_TAB_SIZE];
163
164#if defined(__BORLANDC__)
165#undef RFAR
166#define RFAR far
167#elif defined(_MSC_VER) && (_MSC_VER <= 600)
168#define RFAR far
169#elif defined(_MSC_VER) && (_MSC_VER > 600)
170#define RFAR __far
171#else
172#undef RFAR
173#define RFAR
174#endif
175
176/* structure definitions */
177struct load_os
178{
179 unsigned short voices;
180 unsigned short forced_base_port;
181 unsigned char forced_gf1_irq;
182 unsigned char forced_midi_irq;
183 unsigned char forced_channel_in;
184 unsigned char forced_channel_out;
185};
186
187struct patchheader
188{
189 char header[ HEADER_SIZE ];
190 char gravis_id[ ID_SIZE ]; /* Id = "ID#000002" */
191 char description[ DESC_SIZE ];
192 unsigned char instruments;
193 char voices;
194 char channels;
195 unsigned short wave_forms;
196 unsigned short master_volume;
197 unsigned long data_size;
198 char reserved[ PATCH_HEADER_RESERVED_SIZE ];
199};
200
201struct instrumentdata
202{
203 unsigned short instrument;
204 char instrument_name[ INST_NAME_SIZE ];
205 long instrument_size;
206 char layers;
207 char reserved[ RESERVED_SIZE ];
208};
209
210struct layerdata
211{
212 char layer_duplicate;
213 char layer;
214 long layer_size;
215 char samples;
216 char reserved[ LAYER_RESERVED_SIZE ];
217};
218
219struct patchdata
220{
221 char wave_name[7];
222 unsigned char fractions;
223 long wave_size;
224 long start_loop;
225 long end_loop;
226 unsigned short sample_rate;
227 long low_frequency;
228 long high_frequency;
229 long root_frequency;
230 short tune;
231 unsigned char balance;
232 unsigned char envelope_rate[ ENVELOPES ];
233 unsigned char envelope_offset[ ENVELOPES ];
234 unsigned char tremolo_sweep;
235 unsigned char tremolo_rate;
236 unsigned char tremolo_depth;
237 unsigned char vibrato_sweep;
238 unsigned char vibrato_rate;
239 unsigned char vibrato_depth;
240 char modes;
241 short scale_frequency;
242 unsigned short scale_factor; /* from 0 to 2048 or 0 to 2 */
243 char reserved[ PATCH_DATA_RESERVED_SIZE ];
244};
245
246struct wave_struct
247{
248 unsigned long start_loop;
249 unsigned long end_loop;
250 long low_frequency;
251 long high_frequency;
252 long root_frequency;
253 unsigned long mem;
254 unsigned short scale_frequency;
255 unsigned short sample_rate;
256 unsigned short scale_factor;
257 unsigned short start_acc_low;
258 unsigned short start_acc_high;
259 unsigned short start_low;
260 unsigned short start_high;
261 unsigned short end_low;
262 unsigned short end_high;
263 unsigned short end_acc_low;
264 unsigned short end_acc_high;
265 unsigned short sample_ratio;
266 unsigned long wave_size;
267 unsigned char fractions;
268 unsigned char balance;
269 unsigned char envelope_rate[ ENVELOPES ];
270 unsigned char envelope_offset[ ENVELOPES ];
271 unsigned char tremolo_sweep;
272 unsigned char tremolo_rate;
273 unsigned char tremolo_depth;
274 unsigned char vibrato_sweep;
275 unsigned char vibrato_rate;
276 unsigned char vibrato_depth;
277 unsigned char modes;
278};
279
280struct patchinfo {
281 struct patchheader header;
282 struct instrumentdata idata;
283};
284
285struct patch {
286 short nlayers;
287 struct wave_struct RFAR *layer_waves[MAX_LAYERS];
288 short layer_nwaves[MAX_LAYERS];
289 unsigned short detune;
290};
291
292struct gf1_dma_buff {
293 unsigned char RFAR *vptr;
294 unsigned long paddr;
295};
296
297struct gf1_sound {
298 unsigned long mem_pos;
299 unsigned long start_loop;
300 unsigned long end_loop;
301 unsigned char type;
302};
303
304/* GLOBAL VARIABLES (flags) */
305extern char gf1_linear_volumes;
306extern char gf1_dig_use_extra_voice;
307
308/* FUNCTION PROTOTYPES */
309/* Initializeation routines */
310int gf1_init_ports(int);
311int gf1_load_os(struct load_os RFAR *os);
312int gf1_unload_os(void);
313void gf1_set_appname(char RFAR *);
314void reset_ultra(int);
315int gf1_asm_init(void);
316unsigned char gf1_peek(unsigned long address);
317void gf1_poke(unsigned long address, unsigned char data);
318void gf1_poke_block(unsigned char RFAR *data, unsigned long address, unsigned long len, unsigned char dma_control);
319char gf1_good_dram(unsigned long address);
320int GetUltraCfg(struct load_os RFAR *os);
321unsigned long gf1_malloc(unsigned long);
322void gf1_free(unsigned long);
323unsigned long gf1_mem_avail(void);
324unsigned long gf1_mem_largest_avail(void);
325void gf1_delay(void);
326int gf1_allocate_voice(int priority, void (RFAR *steal_notify)(int));
327void gf1_free_voice(unsigned int i);
328void gf1_adjust_priority(int voice, int priority);
329int gf1_dram_xfer(struct gf1_dma_buff RFAR *dptr, unsigned long size, unsigned long dram_address, unsigned char dma_control, unsigned short flags);
330void gf1_stop_dma(void);
331long convert_to_16bit(long address);
332int gf1_wait_dma(void);
333int gf1_dma_ready(void);
334unsigned long gf1_amount_xferred(void);
335int gf1_detect_card(unsigned short port);
336char *gf1_error_str(int);
337int gf1_play_digital(unsigned short priority, unsigned char RFAR *buffer,
338 unsigned long size, unsigned long gf1_addr, unsigned short volume,
339 unsigned short pan, unsigned short frequency, unsigned char type,
340 struct gf1_dma_buff RFAR *dptr,
341 int (RFAR *callback)(int, int, unsigned char RFAR * RFAR *, unsigned long RFAR *));
342void gf1_restart_digital(int voice);
343void gf1_start_digital(int voice);
344void gf1_pause_digital(int voice);
345void RFAR gf1_stop_digital(int voice);
346void gf1_dig_set_dma_rate(unsigned short rate);
347unsigned long gf1_digital_position(int voice);
348int gf1_myatoi(void);
349int gf1_update_waveform(struct wave_struct RFAR *wave_info);
350int gf1_get_patch_info(char RFAR *patch_file, struct patchinfo RFAR *patch);
351int gf1_load_patch(char RFAR *patch_file, struct patchinfo RFAR *patchinfo,
352 struct patch RFAR *patch,
353 struct gf1_dma_buff RFAR *dptr, unsigned short size,
354 unsigned char RFAR *wavemem, int flags);
355void gf1_unload_patch(struct patch RFAR *patch);
356void gf1_detune_patch(struct patch RFAR *patch, unsigned short detune);
357unsigned short gf1_calc_fc(unsigned int sample_ratio,long root,long frequency);
358void gf1_midi_stop_voice(int voice);
359void gf1_midi_wait_voice(int voice);
360unsigned short gf1_midi_status_note(int voice);
361unsigned short gf1_midi_status_voice(int voice);
362void RFAR gf1_midi_stop_note(int note_voice);
363void gf1_midi_note_on(struct patch RFAR *patch, int priority, int note, int velocity, int channel);
364void gf1_midi_note_off(int note, int channel);
365void gf1_midi_silence_patch_notes(struct patch RFAR *patch);
366void gf1_midi_patch_removed(struct patch RFAR *patch);
367int gf1_enable_timer1(int (RFAR *callback)(void), int resolution);
368int gf1_enable_timer2(int (RFAR *callback)(void), int resolution);
369void gf1_disable_timer1(void);
370void gf1_disable_timer2(void);
371void gf1_channel_pitch_bend(int channel, unsigned int bend);
372void gf1_midi_synth_volume(unsigned short synth, int master_volume);
373void gf1_midi_change_program(struct patch RFAR *patch, int channel);
374void gf1_midi_set_vibrato(int channel, int value);
375void gf1_midi_change_volume(int channel, unsigned int volume);
376void gf1_midi_set_balance(int balance, int channel);
377void gf1_midi_channel_sustain(int channel, int sustain);
378void gf1_midi_all_notes_off(int channel);
379void gf1_midi_pitch_bend(int channel, int lsb, int msb);
380void gf1_midi_parameter(int channel, int control, int value);
381int gf1_midi_get_channel_notes(int channel, int notes[]);
382int gf1_midi_get_channel_volume(int channel);
383int gf1_midi_get_master_volume(void);
384int gf1_midi_get_volume(int voice);
385unsigned short gf1_read(int handle, void RFAR *io_buffer, unsigned short size);
386unsigned short gf1_close_file(int handle);
387unsigned int gf1_seek(int handle, unsigned long offset, int method);
388int gf1_open(char RFAR *name);
389#ifdef __FLAT__
390int gf1_atoi(char RFAR **str, int base);
391#else
392int gf1_atoi(void);
393#endif
394void gf1_leave(void);
395short gf1_enter(void);
396void gf1_enter1(void);
397int gf1_play_next_buffer(int voice, unsigned char RFAR *buff, unsigned long size);
398void gf1_dig_set_vol(unsigned short voice, unsigned short vol);
399void gf1_dig_set_pan(unsigned short voice, unsigned short pan);
400int gf1_set_external_semaphore(void RFAR *addr);
401int gf1_clear_external_semaphore(void RFAR *addr);
402void gf1_midi_reset(int c);
403int gf1_add_midi_recv_handler(int (RFAR *handler)());
404int gf1_add_dma_handler(int (*handler)());
405int gf1_add_voice_handler(int (*handler)(int));
406int gf1_add_volume_handler(int (*handler)(int));
407int gf1_add_timer_handler(int timer, int (RFAR *handler)(void));
408void gf1_set_record_rate(unsigned long rate);
409void gf1_create_patch(struct patch RFAR *patch);
410int gf1_add_layer(struct patch RFAR *patch, int layer, char RFAR *wavemem);
411void gf1_get_waveform_info(struct patch RFAR *patch, int layer, int waven,
412 struct wave_struct RFAR *wave);
413void gf1_set_waveform_info(struct patch RFAR *patch, int layer, int waven,
414 struct wave_struct RFAR *wave);
415void gf1_enable_line_in(void);
416void gf1_disable_line_in(void);
417void gf1_enable_mic_in(void);
418void gf1_disable_mic_in(void);
419void gf1_enable_output(void);
420void gf1_disable_output(void);
421void gf1_sound_volume(unsigned short voice, int volume,
422 unsigned long period /* us*10 */);
423void gf1_sound_pan(unsigned short voice, unsigned short pan);
424void gf1_sound_frequency(unsigned short voice, unsigned long freq);
425void RFAR gf1_sound_stop(int voice);
426void gf1_sound_mode(int voice, struct gf1_sound RFAR *sound,
427 unsigned char type);
428int gf1_sound_start(unsigned short priority, struct gf1_sound RFAR *sound,
429 short volume, unsigned long period, short pan, unsigned long freq);
430int gf1_sound_playing(int voice);
431#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/nodpmi.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/nodpmi.c
new file mode 100644
index 0000000000..82187e79b6
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/nodpmi.c
@@ -0,0 +1,166 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: DPMI.C
22
23 author: James R. Dose
24 date: April 8, 1994
25
26 Functions for performing DPMI calls.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#include <stdlib.h>
32#include <string.h>
33#include "dpmi.h"
34
35#define TRUE ( 1 == 1 )
36#define FALSE ( !TRUE )
37
38/*---------------------------------------------------------------------
39 Function: DPMI_GetRealModeVector
40
41 Returns the vector of a real mode interrupt.
42---------------------------------------------------------------------*/
43
44uint32_t DPMI_GetRealModeVector
45 (
46 int num
47 )
48
49 {
50 return 0;
51 }
52
53
54
55
56
57/*---------------------------------------------------------------------
58 Function: DPMI_CallRealModeFunction
59
60 Performs a call to a real mode function.
61---------------------------------------------------------------------*/
62
63int DPMI_CallRealModeFunction
64 (
65 dpmi_regs *callregs
66 )
67
68 {
69 return( DPMI_Ok );
70 }
71
72
73/*---------------------------------------------------------------------
74 Function: DPMI_LockMemory
75
76 Locks a region of memory to keep the virtual memory manager from
77 paging the region out.
78---------------------------------------------------------------------*/
79
80int DPMI_LockMemory
81 (
82 void *address,
83 unsigned length
84 )
85
86 {
87 return ( DPMI_Ok );
88 }
89
90
91/*---------------------------------------------------------------------
92 Function: DPMI_LockMemoryRegion
93
94 Locks a region of memory to keep the virtual memory manager from
95 paging the region out.
96---------------------------------------------------------------------*/
97
98int DPMI_LockMemoryRegion
99 (
100 void *start,
101 void *end
102 )
103
104 {
105 int status;
106
107 status = DPMI_LockMemory( start, ( char * )end - ( char * )start );
108
109 return( status );
110 }
111
112
113/*---------------------------------------------------------------------
114 Function: DPMI_UnlockMemory
115
116 Unlocks a region of memory that was previously locked.
117---------------------------------------------------------------------*/
118
119int DPMI_UnlockMemory
120 (
121 void *address,
122 unsigned length
123 )
124
125 {
126 return ( DPMI_Ok );
127 }
128
129
130/*---------------------------------------------------------------------
131 Function: DPMI_UnlockMemoryRegion
132
133 Unlocks a region of memory that was previously locked.
134---------------------------------------------------------------------*/
135
136int DPMI_UnlockMemoryRegion
137 (
138 void *start,
139 void *end
140 )
141
142 {
143 int status;
144
145 status = DPMI_UnlockMemory( start, ( char * )end - ( char * )start );
146
147 return( status );
148 }
149
150int DPMI_GetDOSMemory( void **ptr, int *descriptor, unsigned length )
151{
152 /* Lovely... */
153
154 *ptr = (void *)malloc(length);
155
156 *descriptor = (int) *ptr;
157
158 return (descriptor == 0) ? DPMI_Error : DPMI_Ok;
159}
160
161int DPMI_FreeDOSMemory( int descriptor )
162{
163 free((void *)descriptor);
164
165 return (descriptor == 0) ? DPMI_Error : DPMI_Ok;
166}
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/nomusic.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/nomusic.c
new file mode 100644
index 0000000000..d65594427d
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/nomusic.c
@@ -0,0 +1,115 @@
1#include "music.h"
2
3char *MUSIC_ErrorString(int ErrorNumber)
4{
5 return "";
6}
7
8int MUSIC_Init(int SoundCard, int Address)
9{
10 return 0;
11}
12
13int MUSIC_Shutdown(void)
14{
15 return 0;
16}
17
18void MUSIC_SetMaxFMMidiChannel(int channel)
19{
20}
21
22void MUSIC_SetVolume(int volume)
23{
24}
25
26void MUSIC_SetMidiChannelVolume(int channel, int volume)
27{
28}
29
30void MUSIC_ResetMidiChannelVolumes(void)
31{
32}
33
34int MUSIC_GetVolume(void)
35{
36 return 0;
37}
38
39void MUSIC_SetLoopFlag(int loopflag)
40{
41}
42
43int MUSIC_SongPlaying(void)
44{
45 return 0;
46}
47
48void MUSIC_Continue(void)
49{
50}
51
52void MUSIC_Pause(void)
53{
54}
55
56int MUSIC_StopSong(void)
57{
58 return 0;
59}
60
61int MUSIC_PlaySong(unsigned char *song, int loopflag)
62{
63 return 0;
64}
65
66void MUSIC_SetContext(int context)
67{
68}
69
70int MUSIC_GetContext(void)
71{
72 return 0;
73}
74
75void MUSIC_SetSongTick(unsigned long PositionInTicks)
76{
77}
78
79void MUSIC_SetSongTime(unsigned long milliseconds)
80{
81}
82
83void MUSIC_SetSongPosition(int measure, int beat, int tick)
84{
85}
86
87void MUSIC_GetSongPosition(songposition *pos)
88{
89}
90
91void MUSIC_GetSongLength(songposition *pos)
92{
93}
94
95int MUSIC_FadeVolume(int tovolume, int milliseconds)
96{
97 return 0;
98}
99
100int MUSIC_FadeActive(void)
101{
102 return 0;
103}
104
105void MUSIC_StopFade(void)
106{
107}
108
109void MUSIC_RerouteMidiChannel(int channel, int cdecl function( int event, int c1, int c2 ))
110{
111}
112
113void MUSIC_RegisterTimbreBank(unsigned char *timbres)
114{
115}
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pas16.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pas16.c
new file mode 100644
index 0000000000..d8097398e4
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pas16.c
@@ -0,0 +1,1924 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: PAS16.C
22
23 author: James R. Dose
24 date: March 27, 1994
25
26 Low level routines to support Pro AudioSpectrum and compatible
27 sound cards.
28
29 (c) Copyright 1994 James R. Dose. All Rights Reserved.
30**********************************************************************/
31
32#include <dos.h>
33#include <conio.h>
34#include <stdlib.h>
35#include <stdio.h>
36#include <string.h>
37#include "dpmi.h"
38#include "dma.h"
39#include "interrup.h"
40#include "irq.h"
41#include "pas16.h"
42#include "_pas16.h"
43
44#define USESTACK
45
46static const int PAS_Interrupts[ PAS_MaxIrq + 1 ] =
47 {
48 INVALID, INVALID, 0xa, 0xb,
49 INVALID, 0xd, INVALID, 0xf,
50 INVALID, INVALID, 0x72, 0x73,
51 0x74, INVALID, INVALID, 0x77
52 };
53
54static void ( interrupt far *PAS_OldInt )( void );
55
56static int PAS_IntController1Mask;
57static int PAS_IntController2Mask;
58
59static int PAS_Installed = FALSE;
60static int PAS_TranslateCode = DEFAULT_BASE;
61
62static int PAS_OriginalPCMLeftVolume = 75;
63static int PAS_OriginalPCMRightVolume = 75;
64
65static int PAS_OriginalFMLeftVolume = 75;
66static int PAS_OriginalFMRightVolume = 75;
67
68unsigned int PAS_DMAChannel;
69static int PAS_Irq;
70
71static MVState *PAS_State = NULL;
72static MVFunc *PAS_Func = NULL;
73
74static MVState PAS_OriginalState;
75static int PAS_SampleSizeConfig;
76
77static char *PAS_DMABuffer;
78static char *PAS_DMABufferEnd;
79static char *PAS_CurrentDMABuffer;
80static int PAS_TotalDMABufferSize;
81
82static int PAS_TransferLength = 0;
83static int PAS_MixMode = PAS_DefaultMixMode;
84static unsigned PAS_SampleRate = PAS_DefaultSampleRate;
85static int PAS_TimeInterval = 0;
86
87volatile int PAS_SoundPlaying;
88
89void ( *PAS_CallBack )( void );
90
91// adequate stack size
92#define kStackSize 2048
93
94static unsigned short StackSelector = NULL;
95static unsigned long StackPointer;
96
97static unsigned short oldStackSelector;
98static unsigned long oldStackPointer;
99
100// This is defined because we can't create local variables in a
101// function that switches stacks.
102static int irqstatus;
103
104// These declarations are necessary to use the inline assembly pragmas.
105
106extern void GetStack(unsigned short *selptr,unsigned long *stackptr);
107extern void SetStack(unsigned short selector,unsigned long stackptr);
108
109// This function will get the current stack selector and pointer and save
110// them off.
111#pragma aux GetStack = \
112 "mov [edi],esp" \
113 "mov ax,ss" \
114 "mov [esi],ax" \
115 parm [esi] [edi] \
116 modify [eax esi edi];
117
118// This function will set the stack selector and pointer to the specified
119// values.
120#pragma aux SetStack = \
121 "mov ss,ax" \
122 "mov esp,edx" \
123 parm [ax] [edx] \
124 modify [eax edx];
125
126int PAS_ErrorCode = PAS_Ok;
127
128#define PAS_SetErrorCode( status ) \
129 PAS_ErrorCode = ( status );
130
131/*---------------------------------------------------------------------
132 Function: PAS_ErrorString
133
134 Returns a pointer to the error message associated with an error
135 number. A -1 returns a pointer the current error.
136---------------------------------------------------------------------*/
137
138char *PAS_ErrorString
139 (
140 int ErrorNumber
141 )
142
143 {
144 char *ErrorString;
145
146 switch( ErrorNumber )
147 {
148 case PAS_Warning :
149 case PAS_Error :
150 ErrorString = PAS_ErrorString( PAS_ErrorCode );
151 break;
152
153 case PAS_Ok :
154 ErrorString = "Pro AudioSpectrum ok.";
155 break;
156
157 case PAS_DriverNotFound :
158 ErrorString = "MVSOUND.SYS not loaded.";
159 break;
160
161 case PAS_DmaError :
162 ErrorString = DMA_ErrorString( DMA_Error );
163 break;
164
165 case PAS_InvalidIrq :
166 ErrorString = "Invalid Pro AudioSpectrum Irq.";
167 break;
168
169 case PAS_UnableToSetIrq :
170 ErrorString = "Unable to set Pro AudioSpectrum IRQ. Try selecting an IRQ of 7 or below.";
171 break;
172
173 case PAS_Dos4gwIrqError :
174 ErrorString = "Unsupported Pro AudioSpectrum Irq.";
175 break;
176
177 case PAS_NoSoundPlaying :
178 ErrorString = "No sound playing on Pro AudioSpectrum.";
179 break;
180
181 case PAS_CardNotFound :
182 ErrorString = "Could not find Pro AudioSpectrum.";
183 break;
184
185 case PAS_DPMI_Error :
186 ErrorString = "DPMI Error in PAS16.";
187 break;
188
189 case PAS_OutOfMemory :
190 ErrorString = "Out of conventional memory in PAS16.";
191 break;
192
193 default :
194 ErrorString = "Unknown Pro AudioSpectrum error code.";
195 break;
196 }
197
198 return( ErrorString );
199 }
200
201
202/**********************************************************************
203
204 Memory locked functions:
205
206**********************************************************************/
207
208
209#define PAS_LockStart PAS_CheckForDriver
210
211
212/*---------------------------------------------------------------------
213 Function: PAS_CheckForDriver
214
215 Checks to see if MVSOUND.SYS is installed.
216---------------------------------------------------------------------*/
217
218int PAS_CheckForDriver
219 (
220 void
221 )
222
223 {
224 union REGS regs;
225 unsigned result;
226
227 regs.w.ax = MV_CheckForDriver;
228 regs.w.bx = 0x3f3f;
229
230 #ifdef __386__
231 int386( MV_SoundInt, &regs, &regs );
232 #else
233 int86( MV_SoundInt, &regs, &regs );
234 #endif
235
236 if ( regs.w.ax != MV_CheckForDriver )
237 {
238 PAS_SetErrorCode( PAS_DriverNotFound );
239 return( PAS_Error );
240 }
241
242 result = regs.w.bx ^ regs.w.cx ^ regs.w.dx;
243 if ( result != MV_Signature )
244 {
245 PAS_SetErrorCode( PAS_DriverNotFound );
246 return( PAS_Error );
247 }
248
249 return( PAS_Ok );
250 }
251
252
253/*---------------------------------------------------------------------
254 Function: PAS_GetStateTable
255
256 Returns a pointer to the state table containing hardware state
257 information. The state table is necessary because the Pro Audio-
258 Spectrum contains only write-only registers.
259---------------------------------------------------------------------*/
260
261MVState *PAS_GetStateTable
262 (
263 void
264 )
265
266 {
267 union REGS regs;
268 MVState *ptr;
269
270 regs.w.ax = MV_GetPointerToStateTable;
271
272 #ifdef __386__
273 int386( MV_SoundInt, &regs, &regs );
274 #else
275 int86( MV_SoundInt, &regs, &regs );
276 #endif
277
278 if ( regs.w.ax != MV_Signature )
279 {
280 PAS_SetErrorCode( PAS_DriverNotFound );
281 return( NULL );
282 }
283
284 #if defined(__WATCOMC__) && defined(__FLAT__)
285 ptr = ( MVState * )( ( ( ( unsigned )regs.w.dx ) << 4 ) +
286 ( ( unsigned )regs.w.bx ) );
287 #else
288 ptr = MK_FP( regs.w.dx, regs.w.bx );
289 #endif
290
291 return( ptr );
292 }
293
294
295/*---------------------------------------------------------------------
296 Function: PAS_GetFunctionTable
297
298 Returns a pointer to the function table containing addresses of
299 driver functions.
300---------------------------------------------------------------------*/
301
302MVFunc *PAS_GetFunctionTable
303 (
304 void
305 )
306
307 {
308 union REGS regs;
309 MVFunc *ptr;
310
311 regs.w.ax = MV_GetPointerToFunctionTable;
312
313 #ifdef __386__
314 int386( MV_SoundInt, &regs, &regs );
315 #else
316 int86( MV_SoundInt, &regs, &regs );
317 #endif
318
319 if ( regs.w.ax != MV_Signature )
320 {
321 PAS_SetErrorCode( PAS_DriverNotFound );
322 return( NULL );
323 }
324
325 #if defined(__WATCOMC__) && defined(__FLAT__)
326 ptr = ( MVFunc * )( ( ( ( unsigned )regs.w.dx ) << 4 ) +
327 ( ( unsigned )regs.w.bx ) );
328 #else
329 ptr = MK_FP( regs.w.dx, regs.w.bx );
330 #endif
331
332 return( ptr );
333 }
334
335
336/*---------------------------------------------------------------------
337 Function: PAS_GetCardSettings
338
339 Returns the DMA and the IRQ channels of the sound card.
340---------------------------------------------------------------------*/
341
342int PAS_GetCardSettings
343 (
344 void
345 )
346
347 {
348 union REGS regs;
349 int status;
350
351 regs.w.ax = MV_GetDmaIrqInt;
352
353 #ifdef __386__
354 int386( MV_SoundInt, &regs, &regs );
355 #else
356 int86( MV_SoundInt, &regs, &regs );
357 #endif
358
359 if ( regs.w.ax != MV_Signature )
360 {
361 PAS_SetErrorCode( PAS_DriverNotFound );
362 return( PAS_Error );
363 }
364
365 PAS_DMAChannel = regs.w.bx;
366 PAS_Irq = regs.w.cx;
367
368 if ( PAS_Irq > PAS_MaxIrq )
369 {
370 PAS_SetErrorCode( PAS_Dos4gwIrqError );
371 return( PAS_Error );
372 }
373
374 if ( !VALID_IRQ( PAS_Irq ) )
375 {
376 PAS_SetErrorCode( PAS_InvalidIrq );
377 return( PAS_Error );
378 }
379
380 if ( PAS_Interrupts[ PAS_Irq ] == INVALID )
381 {
382 PAS_SetErrorCode( PAS_InvalidIrq );
383 return( PAS_Error );
384 }
385
386 status = DMA_VerifyChannel( PAS_DMAChannel );
387 if ( status == DMA_Error )
388 {
389 PAS_SetErrorCode( PAS_DmaError );
390 return( PAS_Error );
391 }
392
393 return( PAS_Ok );
394 }
395
396
397/*---------------------------------------------------------------------
398 Function: PAS_EnableInterrupt
399
400 Enables the triggering of the sound card interrupt.
401---------------------------------------------------------------------*/
402
403void PAS_EnableInterrupt
404 (
405 void
406 )
407
408 {
409 int mask;
410 int data;
411 unsigned flags;
412
413 flags = DisableInterrupts();
414
415 if ( PAS_Irq < 8 )
416 {
417 mask = inp( 0x21 ) & ~( 1 << PAS_Irq );
418 outp( 0x21, mask );
419 }
420 else
421 {
422 mask = inp( 0xA1 ) & ~( 1 << ( PAS_Irq - 8 ) );
423 outp( 0xA1, mask );
424
425 mask = inp( 0x21 ) & ~( 1 << 2 );
426 outp( 0x21, mask );
427 }
428
429 // Flush any pending interrupts
430 PAS_Write( InterruptStatus, PAS_Read( InterruptStatus ) & 0x40 );
431
432 // Enable the interrupt on the PAS
433 data = PAS_State->intrctlr;
434 data |= SampleBufferInterruptFlag;
435 PAS_Write( InterruptControl, data );
436 PAS_State->intrctlr = data;
437
438 RestoreInterrupts( flags );
439 }
440
441
442/*---------------------------------------------------------------------
443 Function: PAS_DisableInterrupt
444
445 Disables the triggering of the sound card interrupt.
446---------------------------------------------------------------------*/
447
448void PAS_DisableInterrupt
449 (
450 void
451 )
452
453 {
454 int mask;
455 int data;
456 unsigned flags;
457
458 flags = DisableInterrupts();
459
460 // Disable the interrupt on the PAS
461 data = PAS_State->intrctlr;
462 data &= ~( SampleRateInterruptFlag | SampleBufferInterruptFlag );
463 PAS_Write( InterruptControl, data );
464 PAS_State->intrctlr = data;
465
466 // Restore interrupt mask
467 if ( PAS_Irq < 8 )
468 {
469 mask = inp( 0x21 ) & ~( 1 << PAS_Irq );
470 mask |= PAS_IntController1Mask & ( 1 << PAS_Irq );
471 outp( 0x21, mask );
472 }
473 else
474 {
475 mask = inp( 0x21 ) & ~( 1 << 2 );
476 mask |= PAS_IntController1Mask & ( 1 << 2 );
477 outp( 0x21, mask );
478
479 mask = inp( 0xA1 ) & ~( 1 << ( PAS_Irq - 8 ) );
480 mask |= PAS_IntController2Mask & ( 1 << ( PAS_Irq - 8 ) );
481 outp( 0xA1, mask );
482 }
483
484 RestoreInterrupts( flags );
485 }
486
487
488/*---------------------------------------------------------------------
489 Function: PAS_ServiceInterrupt
490
491 Handles interrupt generated by sound card at the end of a voice
492 transfer. Calls the user supplied callback function.
493---------------------------------------------------------------------*/
494
495void interrupt far PAS_ServiceInterrupt
496 (
497 void
498 )
499
500 {
501 #ifdef USESTACK
502 // save stack
503 GetStack( &oldStackSelector, &oldStackPointer );
504
505 // set our stack
506 SetStack( StackSelector, StackPointer );
507 #endif
508
509 irqstatus = PAS_Read( InterruptStatus );
510 if ( ( irqstatus & SampleBufferInterruptFlag ) == 0 )
511 {
512 #ifdef USESTACK
513 // restore stack
514 SetStack( oldStackSelector, oldStackPointer );
515 #endif
516
517 _chain_intr( PAS_OldInt );
518 }
519
520 // Clear the interrupt
521 irqstatus &= ~SampleBufferInterruptFlag;
522 PAS_Write( InterruptStatus, irqstatus );
523
524 // send EOI to Interrupt Controller
525 if ( PAS_Irq > 7 )
526 {
527 outp( 0xA0, 0x20 );
528 }
529 outp( 0x20, 0x20 );
530
531
532 // Keep track of current buffer
533 PAS_CurrentDMABuffer += PAS_TransferLength;
534 if ( PAS_CurrentDMABuffer >= PAS_DMABufferEnd )
535 {
536 PAS_CurrentDMABuffer = PAS_DMABuffer;
537 }
538
539 // Call the caller's callback function
540 if ( PAS_CallBack != NULL )
541 {
542 PAS_CallBack();
543 }
544
545 #ifdef USESTACK
546 // restore stack
547 SetStack( oldStackSelector, oldStackPointer );
548 #endif
549 }
550
551
552/*---------------------------------------------------------------------
553 Function: PAS_Write
554
555 Writes a byte of data to the sound card.
556---------------------------------------------------------------------*/
557
558void PAS_Write
559 (
560 int Register,
561 int Data
562 )
563
564 {
565 int port;
566
567 port = Register ^ PAS_TranslateCode;
568 outp( port, Data );
569 }
570
571
572/*---------------------------------------------------------------------
573 Function: PAS_Read
574
575 Reads a byte of data from the sound card.
576---------------------------------------------------------------------*/
577
578int PAS_Read
579 (
580 int Register
581 )
582
583 {
584 int port;
585 int data;
586
587 port = Register ^ PAS_TranslateCode;
588 data = inp( port );
589 return( data );
590 }
591
592
593/*---------------------------------------------------------------------
594 Function: PAS_SetSampleRateTimer
595
596 Programs the Sample Rate Timer.
597---------------------------------------------------------------------*/
598
599void PAS_SetSampleRateTimer
600 (
601 void
602 )
603
604 {
605 int LoByte;
606 int HiByte;
607 int data;
608 unsigned flags;
609
610 flags = DisableInterrupts();
611
612 // Disable the Sample Rate Timer
613 data = PAS_State->audiofilt;
614 data &= ~SampleRateTimerGateFlag;
615 PAS_Write( AudioFilterControl, data );
616 PAS_State->audiofilt = data;
617
618 // Select the Sample Rate Timer
619 data = SelectSampleRateTimer;
620 PAS_Write( LocalTimerControl, data );
621 PAS_State->tmrctlr = data;
622
623 LoByte = lobyte( PAS_TimeInterval );
624 HiByte = hibyte( PAS_TimeInterval );
625
626 // Program the Sample Rate Timer
627 PAS_Write( SampleRateTimer, LoByte );
628 PAS_Write( SampleRateTimer, HiByte );
629 PAS_State->samplerate = PAS_TimeInterval;
630
631 RestoreInterrupts( flags );
632 }
633
634
635/*---------------------------------------------------------------------
636 Function: PAS_SetSampleBufferCount
637
638 Programs the Sample Buffer Count.
639---------------------------------------------------------------------*/
640
641void PAS_SetSampleBufferCount
642 (
643 void
644 )
645
646 {
647 int LoByte;
648 int HiByte;
649 int count;
650 int data;
651 unsigned flags;
652
653 flags = DisableInterrupts();
654
655 // Disable the Sample Buffer Count
656 data = PAS_State->audiofilt;
657 data &= ~SampleBufferCountGateFlag;
658 PAS_Write( AudioFilterControl, data );
659 PAS_State->audiofilt = data;
660
661 // Select the Sample Buffer Count
662 data = SelectSampleBufferCount;
663 PAS_Write( LocalTimerControl, data );
664 PAS_State->tmrctlr = data;
665
666 count = PAS_TransferLength;
667
668 // Check if we're using a 16-bit DMA channel
669 if ( PAS_DMAChannel > 3 )
670 {
671 count >>= 1;
672 }
673
674 LoByte = lobyte( count );
675 HiByte = hibyte( count );
676
677 // Program the Sample Buffer Count
678 PAS_Write( SampleBufferCount, LoByte );
679 PAS_Write( SampleBufferCount, HiByte );
680 PAS_State->samplecnt = count;
681
682 RestoreInterrupts( flags );
683 }
684
685
686/*---------------------------------------------------------------------
687 Function: PAS_SetPlaybackRate
688
689 Sets the rate at which the digitized sound will be played in
690 hertz.
691---------------------------------------------------------------------*/
692
693void PAS_SetPlaybackRate
694 (
695 unsigned rate
696 )
697
698 {
699 if ( rate < PAS_MinSamplingRate )
700 {
701 rate = PAS_MinSamplingRate;
702 }
703
704 if ( rate > PAS_MaxSamplingRate )
705 {
706 rate = PAS_MaxSamplingRate;
707 }
708
709 PAS_TimeInterval = ( unsigned )CalcTimeInterval( rate );
710 if ( PAS_MixMode & STEREO )
711 {
712 PAS_TimeInterval /= 2;
713 }
714
715 // Keep track of what the actual rate is
716 PAS_SampleRate = CalcSamplingRate( PAS_TimeInterval );
717 if ( PAS_MixMode & STEREO )
718 {
719 PAS_SampleRate /= 2;
720 }
721 }
722
723
724/*---------------------------------------------------------------------
725 Function: PAS_GetPlaybackRate
726
727 Returns the rate at which the digitized sound will be played in
728 hertz.
729---------------------------------------------------------------------*/
730
731unsigned PAS_GetPlaybackRate
732 (
733 void
734 )
735
736 {
737 return( PAS_SampleRate );
738 }
739
740
741/*---------------------------------------------------------------------
742 Function: PAS_SetMixMode
743
744 Sets the sound card to play samples in mono or stereo.
745---------------------------------------------------------------------*/
746
747int PAS_SetMixMode
748 (
749 int mode
750 )
751
752 {
753 mode &= PAS_MaxMixMode;
754
755 // Check board revision. Revision # 0 can't play 16-bit data.
756 if ( ( PAS_State->intrctlr & 0xe0 ) == 0 )
757 {
758 // Force the mode to 8-bit data.
759 mode &= ~SIXTEEN_BIT;
760 }
761
762 PAS_MixMode = mode;
763
764 PAS_SetPlaybackRate( PAS_SampleRate );
765
766 return( mode );
767 }
768
769
770/*---------------------------------------------------------------------
771 Function: PAS_StopPlayback
772
773 Ends the DMA transfer of digitized sound to the sound card.
774---------------------------------------------------------------------*/
775
776void PAS_StopPlayback
777 (
778 void
779 )
780
781 {
782 int data;
783
784 // Don't allow anymore interrupts
785 PAS_DisableInterrupt();
786
787 // Stop the transfer of digital data
788 data = PAS_State->crosschannel;
789 data &= PAS_PCMStopMask;
790 PAS_Write( CrossChannelControl, data );
791 PAS_State->crosschannel = data;
792
793 // Turn off 16-bit unsigned data
794 data = PAS_Read( SampleSizeConfiguration );
795 data &= PAS_SampleSizeMask;
796 PAS_Write( SampleSizeConfiguration, data );
797
798 // Disable the DMA channel
799 DMA_EndTransfer( PAS_DMAChannel );
800
801 PAS_SoundPlaying = FALSE;
802
803 PAS_DMABuffer = NULL;
804 }
805
806
807/*---------------------------------------------------------------------
808 Function: PAS_SetupDMABuffer
809
810 Programs the DMAC for sound transfer.
811---------------------------------------------------------------------*/
812
813int PAS_SetupDMABuffer
814 (
815 char *BufferPtr,
816 int BufferSize,
817 int mode
818 )
819
820 {
821 int DmaStatus;
822 int data;
823
824 // Enable PAS Dma
825 data = PAS_State->crosschannel;
826 data |= PAS_DMAEnable;
827 PAS_Write( CrossChannelControl, data );
828 PAS_State->crosschannel = data;
829
830 DmaStatus = DMA_SetupTransfer( PAS_DMAChannel, BufferPtr, BufferSize, mode );
831 if ( DmaStatus == DMA_Error )
832 {
833 PAS_SetErrorCode( PAS_DmaError );
834 return( PAS_Error );
835 }
836
837 PAS_DMABuffer = BufferPtr;
838 PAS_CurrentDMABuffer = BufferPtr;
839 PAS_TotalDMABufferSize = BufferSize;
840 PAS_DMABufferEnd = BufferPtr + BufferSize;
841
842 return( PAS_Ok );
843 }
844
845
846/*---------------------------------------------------------------------
847 Function: PAS_GetCurrentPos
848
849 Returns the offset within the current sound being played.
850---------------------------------------------------------------------*/
851
852int PAS_GetCurrentPos
853 (
854 void
855 )
856
857 {
858 char *CurrentAddr;
859 int offset;
860
861 if ( !PAS_SoundPlaying )
862 {
863 PAS_SetErrorCode( PAS_NoSoundPlaying );
864 return( PAS_Error );
865 }
866
867 CurrentAddr = DMA_GetCurrentPos( PAS_DMAChannel );
868 if ( CurrentAddr == NULL )
869 {
870 PAS_SetErrorCode( PAS_DmaError );
871 return( PAS_Error );
872 }
873
874 offset = ( int )( ( ( unsigned long )CurrentAddr ) -
875 ( ( unsigned long )PAS_CurrentDMABuffer ) );
876
877 if ( PAS_MixMode & SIXTEEN_BIT )
878 {
879 offset >>= 1;
880 }
881
882 if ( PAS_MixMode & STEREO )
883 {
884 offset >>= 1;
885 }
886
887 return( offset );
888 }
889
890
891/*---------------------------------------------------------------------
892 Function: PAS_GetFilterSetting
893
894 Returns the bit settings for the appropriate filter level.
895---------------------------------------------------------------------*/
896
897int PAS_GetFilterSetting
898 (
899 int rate
900 )
901
902 {
903 /* CD Quality 17897hz */
904 if ( ( unsigned long )rate > ( unsigned long )17897L * 2 )
905 {
906 /* 00001b 20hz to 17.8khz */
907 return( 0x01 );
908 }
909
910 /* Cassette Quality 15090hz */
911 if ( ( unsigned long )rate > ( unsigned long )15909L * 2 )
912 {
913 /* 00010b 20hz to 15.9khz */
914 return( 0x02 );
915 }
916
917 /* FM Radio Quality 11931hz */
918 if ( ( unsigned long )rate > ( unsigned long )11931L * 2 )
919 {
920 /* 01001b 20hz to 11.9khz */
921 return( 0x09 );
922 }
923
924 /* AM Radio Quality 8948hz */
925 if ( ( unsigned long )rate > ( unsigned long )8948L * 2 )
926 {
927 /* 10001b 20hz to 8.9khz */
928 return( 0x11 );
929 }
930
931 /* Telphone Quality 5965hz */
932 if ( ( unsigned long )rate > ( unsigned long )5965L * 2 )
933 {
934 /* 00100b 20hz to 5.9khz */
935 return( 0x19 );
936 }
937
938 /* Male voice quality 2982hz */
939 /* 111001b 20hz to 2.9khz */
940 return( 0x04 );
941 }
942
943
944/*---------------------------------------------------------------------
945 Function: PAS_BeginTransfer
946
947 Starts playback of digitized sound on the sound card.
948---------------------------------------------------------------------*/
949
950void PAS_BeginTransfer
951 (
952 int mode
953 )
954
955 {
956 int data;
957
958 PAS_SetSampleRateTimer();
959
960 PAS_SetSampleBufferCount();
961
962 PAS_EnableInterrupt();
963
964 // Get sample size configuration
965 data = PAS_Read( SampleSizeConfiguration );
966
967 // Check board revision. Revision # 0 can't play 16-bit data.
968 if ( PAS_State->intrctlr & 0xe0 )
969 {
970 data &= PAS_SampleSizeMask;
971
972 // set sample size bit
973 if ( PAS_MixMode & SIXTEEN_BIT )
974 {
975 data |= PAS_16BitSampleFlag;
976 }
977 }
978
979 // set oversampling rate
980 data &= PAS_OverSamplingMask;
981 data |= PAS_4xOverSampling;
982
983 // Set sample size configuration
984 PAS_Write( SampleSizeConfiguration, data );
985
986 // Get Cross channel setting
987 data = PAS_State->crosschannel;
988 data &= PAS_ChannelConnectMask;
989 if ( mode == RECORD )
990 {
991 data |= PAS_PCMStartADC;
992 }
993 else
994 {
995 data |= PAS_PCMStartDAC;
996 }
997
998 // set stereo mode bit
999 if ( !( PAS_MixMode & STEREO ) )
1000 {
1001 data |= PAS_StereoFlag;
1002 }
1003
1004 PAS_Write( CrossChannelControl, data );
1005 PAS_State->crosschannel = data;
1006
1007 // Get the filter appropriate filter setting
1008 data = PAS_GetFilterSetting( PAS_SampleRate );
1009
1010 // Enable the Sample Rate Timer and Sample Buffer Count
1011 data |= SampleRateTimerGateFlag | SampleBufferCountGateFlag;
1012
1013 if ( mode != RECORD )
1014 {
1015 // Enable audio (not Audio Mute)
1016 data |= PAS_AudioMuteFlag;
1017 }
1018
1019 PAS_Write( AudioFilterControl, data );
1020 PAS_State->audiofilt = data;
1021
1022 PAS_SoundPlaying = TRUE;
1023 }
1024
1025
1026/*---------------------------------------------------------------------
1027 Function: PAS_BeginBufferedPlayback
1028
1029 Begins multibuffered playback of digitized sound on the sound card.
1030---------------------------------------------------------------------*/
1031
1032int PAS_BeginBufferedPlayback
1033 (
1034 char *BufferStart,
1035 int BufferSize,
1036 int NumDivisions,
1037 unsigned SampleRate,
1038 int MixMode,
1039 void ( *CallBackFunc )( void )
1040 )
1041
1042 {
1043 int DmaStatus;
1044
1045 PAS_StopPlayback();
1046
1047 PAS_SetMixMode( MixMode );
1048 PAS_SetPlaybackRate( SampleRate );
1049
1050 PAS_TransferLength = BufferSize / NumDivisions;
1051 PAS_SetCallBack( CallBackFunc );
1052
1053 DmaStatus = PAS_SetupDMABuffer( BufferStart, BufferSize, DMA_AutoInitRead );
1054 if ( DmaStatus == PAS_Error )
1055 {
1056 return( PAS_Error );
1057 }
1058
1059 PAS_BeginTransfer( PLAYBACK );
1060
1061 return( PAS_Ok );
1062 }
1063
1064
1065/*---------------------------------------------------------------------
1066 Function: PAS_BeginBufferedRecord
1067
1068 Begins multibuffered recording of digitized sound on the sound card.
1069---------------------------------------------------------------------*/
1070
1071int PAS_BeginBufferedRecord
1072 (
1073 char *BufferStart,
1074 int BufferSize,
1075 int NumDivisions,
1076 unsigned SampleRate,
1077 int MixMode,
1078 void ( *CallBackFunc )( void )
1079 )
1080
1081 {
1082 int DmaStatus;
1083
1084 PAS_StopPlayback();
1085
1086 PAS_SetMixMode( MixMode );
1087 PAS_SetPlaybackRate( SampleRate );
1088
1089 PAS_TransferLength = BufferSize / NumDivisions;
1090 PAS_SetCallBack( CallBackFunc );
1091
1092 DmaStatus = PAS_SetupDMABuffer( BufferStart, BufferSize, DMA_AutoInitWrite );
1093 if ( DmaStatus == PAS_Error )
1094 {
1095 return( PAS_Error );
1096 }
1097
1098 PAS_BeginTransfer( RECORD );
1099
1100 return( PAS_Ok );
1101 }
1102
1103
1104/*---------------------------------------------------------------------
1105 Function: PAS_CallInt
1106
1107 Calls interrupt 2fh.
1108---------------------------------------------------------------------*/
1109
1110int PAS_CallInt( int ebx, int ecx, int edx );
1111#pragma aux PAS_CallInt = \
1112 "int 2fh", \
1113 parm [ ebx ] [ ecx ] [ edx ] modify exact [ eax ebx ecx edx esi edi ] value [ ebx ];
1114
1115
1116/*---------------------------------------------------------------------
1117 Function: PAS_CallMVFunction
1118
1119 Performs a call to a real mode function.
1120---------------------------------------------------------------------*/
1121
1122int PAS_CallMVFunction
1123 (
1124 unsigned long function,
1125 int ebx,
1126 int ecx,
1127 int edx
1128 )
1129
1130 {
1131 dpmi_regs callregs;
1132 int status;
1133
1134 callregs.EBX = ebx;
1135 callregs.ECX = ecx;
1136 callregs.EDX = edx;
1137
1138 callregs.SS = 0;
1139 callregs.SP = 0;
1140
1141 callregs.DS = 0;
1142 callregs.ES = 0;
1143 callregs.FS = 0;
1144 callregs.GS = 0;
1145
1146 callregs.IP = function;
1147 callregs.CS = function >> 16;
1148
1149 status = DPMI_CallRealModeFunction( &callregs );
1150 if ( status != DPMI_Ok )
1151 {
1152 return( PAS_Error );
1153 }
1154
1155 return( callregs.EBX & 0xff );
1156 }
1157
1158
1159/*---------------------------------------------------------------------
1160 Function: PAS_SetPCMVolume
1161
1162 Sets the volume of digitized sound playback.
1163---------------------------------------------------------------------*/
1164
1165int PAS_SetPCMVolume
1166 (
1167 int volume
1168 )
1169
1170 {
1171 int status;
1172
1173 volume = max( 0, volume );
1174 volume = min( volume, 255 );
1175
1176 volume *= 100;
1177 volume /= 255;
1178
1179 status = PAS_CallMVFunction( PAS_Func->SetMixer, volume,
1180 OUTPUTMIXER, L_PCM );
1181 if ( status == PAS_Error )
1182 {
1183 return( status );
1184 }
1185
1186 status = PAS_CallMVFunction( PAS_Func->SetMixer, volume,
1187 OUTPUTMIXER, R_PCM );
1188 if ( status == PAS_Error )
1189 {
1190 return( status );
1191 }
1192
1193 return( PAS_Ok );
1194 }
1195
1196
1197/*---------------------------------------------------------------------
1198 Function: PAS_GetPCMVolume
1199
1200 Returns the current volume of digitized sound playback.
1201---------------------------------------------------------------------*/
1202
1203int PAS_GetPCMVolume
1204 (
1205 void
1206 )
1207
1208 {
1209 int leftvolume;
1210 int rightvolume;
1211 int totalvolume;
1212
1213 if ( PAS_Func == NULL )
1214 {
1215 return( PAS_Error );
1216 }
1217
1218 leftvolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
1219 OUTPUTMIXER, L_PCM );
1220 rightvolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
1221 OUTPUTMIXER, R_PCM );
1222
1223 if ( ( leftvolume == PAS_Error ) || ( rightvolume == PAS_Error ) )
1224 {
1225 return( PAS_Error );
1226 }
1227
1228 leftvolume &= 0xff;
1229 rightvolume &= 0xff;
1230
1231 totalvolume = ( rightvolume + leftvolume ) / 2;
1232 totalvolume *= 255;
1233 totalvolume /= 100;
1234 return( totalvolume );
1235 }
1236
1237
1238/*---------------------------------------------------------------------
1239 Function: PAS_SetFMVolume
1240
1241 Sets the volume of FM sound playback.
1242---------------------------------------------------------------------*/
1243
1244void PAS_SetFMVolume
1245 (
1246 int volume
1247 )
1248
1249 {
1250 volume = max( 0, volume );
1251 volume = min( volume, 255 );
1252
1253 volume *= 100;
1254 volume /= 255;
1255 if ( PAS_Func )
1256 {
1257 PAS_CallMVFunction( PAS_Func->SetMixer, volume, OUTPUTMIXER, L_FM );
1258 PAS_CallMVFunction( PAS_Func->SetMixer, volume, OUTPUTMIXER, R_FM );
1259 }
1260 }
1261
1262
1263/*---------------------------------------------------------------------
1264 Function: PAS_GetFMVolume
1265
1266 Returns the current volume of FM sound playback.
1267---------------------------------------------------------------------*/
1268
1269int PAS_GetFMVolume
1270 (
1271 void
1272 )
1273
1274 {
1275 int leftvolume;
1276 int rightvolume;
1277 int totalvolume;
1278
1279 if ( PAS_Func == NULL )
1280 {
1281 return( 255 );
1282 }
1283
1284 leftvolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
1285 OUTPUTMIXER, L_FM ) & 0xff;
1286 rightvolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
1287 OUTPUTMIXER, R_FM ) & 0xff;
1288
1289 totalvolume = ( rightvolume + leftvolume ) / 2;
1290 totalvolume *= 255;
1291 totalvolume /= 100;
1292 totalvolume = min( 255, totalvolume );
1293
1294 return( totalvolume );
1295 }
1296
1297
1298/*---------------------------------------------------------------------
1299 Function: PAS_GetCardInfo
1300
1301 Returns the maximum number of bits that can represent a sample
1302 (8 or 16) and the number of channels (1 for mono, 2 for stereo).
1303---------------------------------------------------------------------*/
1304
1305int PAS_GetCardInfo
1306 (
1307 int *MaxSampleBits,
1308 int *MaxChannels
1309 )
1310
1311 {
1312 int status;
1313
1314 if ( PAS_State == NULL )
1315 {
1316 status = PAS_CheckForDriver();
1317 if ( status != PAS_Ok )
1318 {
1319 return( status );
1320 }
1321
1322 PAS_State = PAS_GetStateTable();
1323 if ( PAS_State == NULL )
1324 {
1325 return( PAS_Error );
1326 }
1327 }
1328
1329 *MaxChannels = 2;
1330
1331 // Check board revision. Revision # 0 can't play 16-bit data.
1332 if ( ( PAS_State->intrctlr & 0xe0 ) == 0 )
1333 {
1334 *MaxSampleBits = 8;
1335 }
1336 else
1337 {
1338 *MaxSampleBits = 16;
1339 }
1340
1341 return( PAS_Ok );
1342 }
1343
1344
1345/*---------------------------------------------------------------------
1346 Function: PAS_SetCallBack
1347
1348 Specifies the user function to call at the end of a sound transfer.
1349---------------------------------------------------------------------*/
1350
1351void PAS_SetCallBack
1352 (
1353 void ( *func )( void )
1354 )
1355
1356 {
1357 PAS_CallBack = func;
1358 }
1359
1360
1361/*---------------------------------------------------------------------
1362 Function: PAS_FindCard
1363
1364 Auto-detects the port the Pro AudioSpectrum is set for.
1365---------------------------------------------------------------------*/
1366
1367int PAS_FindCard
1368 (
1369 void
1370 )
1371
1372 {
1373 int status;
1374
1375 status = PAS_TestAddress( DEFAULT_BASE );
1376 if ( status == 0 )
1377 {
1378 PAS_TranslateCode = DEFAULT_BASE;
1379 return( PAS_Ok );
1380 }
1381
1382 status = PAS_TestAddress( ALT_BASE_1 );
1383 if ( status == 0 )
1384 {
1385 PAS_TranslateCode = ALT_BASE_1;
1386 return( PAS_Ok );
1387 }
1388
1389 status = PAS_TestAddress( ALT_BASE_2 );
1390 if ( status == 0 )
1391 {
1392 PAS_TranslateCode = ALT_BASE_2;
1393 return( PAS_Ok );
1394 }
1395
1396 status = PAS_TestAddress( ALT_BASE_3 );
1397 if ( status == 0 )
1398 {
1399 PAS_TranslateCode = ALT_BASE_3;
1400 return( PAS_Ok );
1401 }
1402
1403 PAS_SetErrorCode( PAS_CardNotFound );
1404 return( PAS_Error );
1405 }
1406
1407
1408/*---------------------------------------------------------------------
1409 Function: PAS_SaveMusicVolume
1410
1411 Saves the user's FM mixer settings.
1412---------------------------------------------------------------------*/
1413
1414int PAS_SaveMusicVolume
1415 (
1416 void
1417 )
1418
1419 {
1420 int status;
1421 int data;
1422
1423 if ( !PAS_Installed )
1424 {
1425 status = PAS_CheckForDriver();
1426 if ( status != PAS_Ok )
1427 {
1428 return( status );
1429 }
1430
1431 PAS_State = PAS_GetStateTable();
1432 if ( PAS_State == NULL )
1433 {
1434 return( PAS_Error );
1435 }
1436
1437 PAS_Func = PAS_GetFunctionTable();
1438 if ( PAS_Func == NULL )
1439 {
1440 return( PAS_Error );
1441 }
1442
1443 status = PAS_GetCardSettings();
1444 if ( status != PAS_Ok )
1445 {
1446 return( status );
1447 }
1448
1449 status = PAS_FindCard();
1450 if ( status != PAS_Ok )
1451 {
1452 return( status );
1453 }
1454
1455 // Enable PAS Sound
1456 data = PAS_State->audiofilt;
1457 data |= PAS_AudioMuteFlag;
1458
1459 PAS_Write( AudioFilterControl, data );
1460 PAS_State->audiofilt = data;
1461 }
1462
1463 status = PAS_CallMVFunction( PAS_Func->GetMixer, 0, OUTPUTMIXER, L_FM );
1464 if ( status != PAS_Error )
1465 {
1466 PAS_OriginalFMLeftVolume = PAS_CallMVFunction( PAS_Func->GetMixer,
1467 0, OUTPUTMIXER, L_FM ) & 0xff;
1468
1469 PAS_OriginalFMRightVolume = PAS_CallMVFunction( PAS_Func->GetMixer,
1470 0, OUTPUTMIXER, R_FM ) & 0xff;
1471
1472 return( PAS_Ok );
1473 }
1474
1475 return( PAS_Warning );
1476 }
1477
1478
1479/*---------------------------------------------------------------------
1480 Function: PAS_RestoreMusicVolume
1481
1482 Restores the user's FM mixer settings.
1483---------------------------------------------------------------------*/
1484
1485void PAS_RestoreMusicVolume
1486 (
1487 void
1488 )
1489
1490 {
1491 if ( PAS_Func )
1492 {
1493 PAS_CallMVFunction( PAS_Func->SetMixer, PAS_OriginalFMLeftVolume,
1494 OUTPUTMIXER, L_FM );
1495 PAS_CallMVFunction( PAS_Func->SetMixer, PAS_OriginalFMRightVolume,
1496 OUTPUTMIXER, R_FM );
1497 }
1498 }
1499
1500
1501/*---------------------------------------------------------------------
1502 Function: PAS_SaveState
1503
1504 Saves the original state of the PAS prior to use.
1505---------------------------------------------------------------------*/
1506
1507void PAS_SaveState
1508 (
1509 void
1510 )
1511
1512 {
1513 PAS_OriginalState.intrctlr = PAS_State->intrctlr;
1514 PAS_OriginalState.audiofilt = PAS_State->audiofilt;
1515 PAS_OriginalState.tmrctlr = PAS_State->tmrctlr;
1516 PAS_OriginalState.samplerate = PAS_State->samplerate;
1517 PAS_OriginalState.samplecnt = PAS_State->samplecnt;
1518 PAS_OriginalState.crosschannel = PAS_State->crosschannel;
1519 PAS_SampleSizeConfig = PAS_Read( SampleSizeConfiguration );
1520 }
1521
1522
1523/*---------------------------------------------------------------------
1524 Function: PAS_RestoreState
1525
1526 Restores the original state of the PAS after use.
1527---------------------------------------------------------------------*/
1528
1529void PAS_RestoreState
1530 (
1531 void
1532 )
1533
1534 {
1535 int LoByte;
1536 int HiByte;
1537
1538 // Select the Sample Rate Timer
1539 PAS_Write( LocalTimerControl, SelectSampleRateTimer );
1540 PAS_State->tmrctlr = SelectSampleRateTimer;
1541
1542 PAS_Write( SampleRateTimer, PAS_OriginalState.samplerate );
1543 PAS_State->samplerate = PAS_OriginalState.samplerate;
1544
1545 // Select the Sample Buffer Count
1546 PAS_Write( LocalTimerControl, SelectSampleBufferCount );
1547 PAS_State->tmrctlr = SelectSampleBufferCount;
1548
1549 LoByte = lobyte( PAS_OriginalState.samplecnt );
1550 HiByte = hibyte( PAS_OriginalState.samplecnt );
1551 PAS_Write( SampleRateTimer, LoByte );
1552 PAS_Write( SampleRateTimer, HiByte );
1553 PAS_State->samplecnt = PAS_OriginalState.samplecnt;
1554
1555 PAS_Write( CrossChannelControl, PAS_OriginalState.crosschannel );
1556 PAS_State->crosschannel = PAS_OriginalState.crosschannel;
1557
1558 PAS_Write( SampleSizeConfiguration, PAS_SampleSizeConfig );
1559
1560 PAS_Write( InterruptControl, PAS_OriginalState.intrctlr );
1561 PAS_State->intrctlr = PAS_OriginalState.intrctlr;
1562
1563 PAS_Write( AudioFilterControl, PAS_OriginalState.audiofilt );
1564 PAS_State->audiofilt = PAS_OriginalState.audiofilt;
1565
1566 PAS_Write( LocalTimerControl, PAS_OriginalState.tmrctlr );
1567 PAS_State->tmrctlr = PAS_OriginalState.tmrctlr;
1568 }
1569
1570
1571/*---------------------------------------------------------------------
1572 Function: PAS_LockEnd
1573
1574 Used for determining the length of the functions to lock in memory.
1575---------------------------------------------------------------------*/
1576
1577static void PAS_LockEnd
1578 (
1579 void
1580 )
1581
1582 {
1583 }
1584
1585
1586/*---------------------------------------------------------------------
1587 Function: allocateTimerStack
1588
1589 Allocate a block of memory from conventional (low) memory and return
1590 the selector (which can go directly into a segment register) of the
1591 memory block or 0 if an error occured.
1592---------------------------------------------------------------------*/
1593
1594static unsigned short allocateTimerStack
1595 (
1596 unsigned short size
1597 )
1598
1599 {
1600 union REGS regs;
1601
1602 // clear all registers
1603 memset( &regs, 0, sizeof( regs ) );
1604
1605 // DPMI allocate conventional memory
1606 regs.w.ax = 0x100;
1607
1608 // size in paragraphs
1609 regs.w.bx = ( size + 15 ) / 16;
1610
1611 int386( 0x31, &regs, &regs );
1612 if (!regs.w.cflag)
1613 {
1614 // DPMI call returns selector in dx
1615 // (ax contains real mode segment
1616 // which is ignored here)
1617
1618 return( regs.w.dx );
1619 }
1620
1621 // Couldn't allocate memory.
1622 return( NULL );
1623 }
1624
1625
1626/*---------------------------------------------------------------------
1627 Function: deallocateTimerStack
1628
1629 Deallocate a block of conventional (low) memory given a selector to
1630 it. Assumes the block was allocated with DPMI function 0x100.
1631---------------------------------------------------------------------*/
1632
1633static void deallocateTimerStack
1634 (
1635 unsigned short selector
1636 )
1637
1638 {
1639 union REGS regs;
1640
1641 if ( selector != NULL )
1642 {
1643 // clear all registers
1644 memset( &regs, 0, sizeof( regs ) );
1645
1646 regs.w.ax = 0x101;
1647 regs.w.dx = selector;
1648 int386( 0x31, &regs, &regs );
1649 }
1650 }
1651
1652
1653/*---------------------------------------------------------------------
1654 Function: PAS_Init
1655
1656 Initializes the sound card and prepares the module to play
1657 digitized sounds.
1658---------------------------------------------------------------------*/
1659
1660int PAS_Init
1661 (
1662 void
1663 )
1664
1665 {
1666 int Interrupt;
1667 int status;
1668 int data;
1669
1670 if ( PAS_Installed )
1671 {
1672 return( PAS_Ok );
1673 }
1674
1675 PAS_IntController1Mask = inp( 0x21 );
1676 PAS_IntController2Mask = inp( 0xA1 );
1677
1678 status = PAS_CheckForDriver();
1679 if ( status != PAS_Ok )
1680 {
1681 return( status );
1682 }
1683
1684 PAS_State = PAS_GetStateTable();
1685 if ( PAS_State == NULL )
1686 {
1687 return( PAS_Error );
1688 }
1689
1690 PAS_Func = PAS_GetFunctionTable();
1691 if ( PAS_Func == NULL )
1692 {
1693 return( PAS_Error );
1694 }
1695
1696 status = PAS_GetCardSettings();
1697 if ( status != PAS_Ok )
1698 {
1699 return( status );
1700 }
1701
1702 status = PAS_FindCard();
1703 if ( status != PAS_Ok )
1704 {
1705 return( status );
1706 }
1707
1708 PAS_SaveState();
1709
1710 PAS_OriginalPCMLeftVolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
1711 OUTPUTMIXER, L_PCM ) & 0xff;
1712 PAS_OriginalPCMRightVolume = PAS_CallMVFunction( PAS_Func->GetMixer, 0,
1713 OUTPUTMIXER, R_PCM ) & 0xff;
1714
1715 PAS_SoundPlaying = FALSE;
1716
1717 PAS_SetCallBack( NULL );
1718
1719 PAS_DMABuffer = NULL;
1720
1721 status = PAS_LockMemory();
1722 if ( status != PAS_Ok )
1723 {
1724 PAS_UnlockMemory();
1725 return( status );
1726 }
1727
1728 StackSelector = allocateTimerStack( kStackSize );
1729 if ( StackSelector == NULL )
1730 {
1731 PAS_UnlockMemory();
1732 PAS_SetErrorCode( PAS_OutOfMemory );
1733 return( PAS_Error );
1734 }
1735
1736 // Leave a little room at top of stack just for the hell of it...
1737 StackPointer = kStackSize - sizeof( long );
1738
1739 // Install our interrupt handler
1740 Interrupt = PAS_Interrupts[ PAS_Irq ];
1741 PAS_OldInt = _dos_getvect( Interrupt );
1742 if ( PAS_Irq < 8 )
1743 {
1744 _dos_setvect( Interrupt, PAS_ServiceInterrupt );
1745 }
1746 else
1747 {
1748 status = IRQ_SetVector( Interrupt, PAS_ServiceInterrupt );
1749 if ( status != IRQ_Ok )
1750 {
1751 PAS_UnlockMemory();
1752 deallocateTimerStack( StackSelector );
1753 StackSelector = NULL;
1754 PAS_SetErrorCode( PAS_UnableToSetIrq );
1755 return( PAS_Error );
1756 }
1757 }
1758
1759 // Enable PAS Sound
1760 data = PAS_State->audiofilt;
1761 data |= PAS_AudioMuteFlag;
1762
1763 PAS_Write( AudioFilterControl, data );
1764 PAS_State->audiofilt = data;
1765
1766 PAS_SetPlaybackRate( PAS_DefaultSampleRate );
1767 PAS_SetMixMode( PAS_DefaultMixMode );
1768
1769 PAS_Installed = TRUE;
1770
1771 PAS_SetErrorCode( PAS_Ok );
1772 return( PAS_Ok );
1773 }
1774
1775
1776/*---------------------------------------------------------------------
1777 Function: PAS_Shutdown
1778
1779 Ends transfer of sound data to the sound card and restores the
1780 system resources used by the card.
1781---------------------------------------------------------------------*/
1782
1783void PAS_Shutdown
1784 (
1785 void
1786 )
1787
1788 {
1789 int Interrupt;
1790
1791 if ( PAS_Installed )
1792 {
1793 // Halt the DMA transfer
1794 PAS_StopPlayback();
1795
1796 // Restore the original interrupt
1797 Interrupt = PAS_Interrupts[ PAS_Irq ];
1798 if ( PAS_Irq >= 8 )
1799 {
1800 IRQ_RestoreVector( Interrupt );
1801 }
1802 _dos_setvect( Interrupt, PAS_OldInt );
1803
1804 PAS_SoundPlaying = FALSE;
1805
1806 PAS_DMABuffer = NULL;
1807
1808 PAS_SetCallBack( NULL );
1809
1810 PAS_CallMVFunction( PAS_Func->SetMixer, PAS_OriginalPCMLeftVolume,
1811 OUTPUTMIXER, L_PCM );
1812 PAS_CallMVFunction( PAS_Func->SetMixer, PAS_OriginalPCMRightVolume,
1813 OUTPUTMIXER, R_PCM );
1814
1815// DEBUG
1816// PAS_RestoreState();
1817
1818 PAS_UnlockMemory();
1819
1820 deallocateTimerStack( StackSelector );
1821 StackSelector = NULL;
1822
1823 PAS_Installed = FALSE;
1824 }
1825 }
1826
1827
1828/*---------------------------------------------------------------------
1829 Function: PAS_UnlockMemory
1830
1831 Unlocks all neccessary data.
1832---------------------------------------------------------------------*/
1833
1834void PAS_UnlockMemory
1835 (
1836 void
1837 )
1838
1839 {
1840 DPMI_UnlockMemoryRegion( PAS_LockStart, PAS_LockEnd );
1841 DPMI_Unlock( PAS_Interrupts );
1842 DPMI_Unlock( PAS_OldInt );
1843 DPMI_Unlock( PAS_IntController1Mask );
1844 DPMI_Unlock( PAS_IntController2Mask );
1845 DPMI_Unlock( PAS_Installed );
1846 DPMI_Unlock( PAS_TranslateCode );
1847 DPMI_Unlock( PAS_OriginalPCMLeftVolume );
1848 DPMI_Unlock( PAS_OriginalPCMRightVolume );
1849 DPMI_Unlock( PAS_OriginalFMLeftVolume );
1850 DPMI_Unlock( PAS_OriginalFMRightVolume );
1851 DPMI_Unlock( PAS_DMAChannel );
1852 DPMI_Unlock( PAS_Irq );
1853 DPMI_Unlock( PAS_State );
1854 DPMI_Unlock( PAS_Func );
1855 DPMI_Unlock( PAS_OriginalState );
1856 DPMI_Unlock( PAS_SampleSizeConfig );
1857 DPMI_Unlock( PAS_DMABuffer );
1858 DPMI_Unlock( PAS_DMABufferEnd );
1859 DPMI_Unlock( PAS_CurrentDMABuffer );
1860 DPMI_Unlock( PAS_TotalDMABufferSize );
1861 DPMI_Unlock( PAS_TransferLength );
1862 DPMI_Unlock( PAS_MixMode );
1863 DPMI_Unlock( PAS_SampleRate );
1864 DPMI_Unlock( PAS_TimeInterval );
1865 DPMI_Unlock( PAS_SoundPlaying );
1866 DPMI_Unlock( PAS_CallBack );
1867 DPMI_Unlock( PAS_ErrorCode );
1868 DPMI_Unlock( irqstatus );
1869 }
1870
1871
1872/*---------------------------------------------------------------------
1873 Function: PAS_LockMemory
1874
1875 Locks all neccessary data.
1876---------------------------------------------------------------------*/
1877
1878int PAS_LockMemory
1879 (
1880 void
1881 )
1882
1883 {
1884 int status;
1885
1886 status = DPMI_LockMemoryRegion( PAS_LockStart, PAS_LockEnd );
1887 status |= DPMI_Lock( PAS_Interrupts );
1888 status |= DPMI_Lock( PAS_OldInt );
1889 status |= DPMI_Lock( PAS_IntController1Mask );
1890 status |= DPMI_Lock( PAS_IntController2Mask );
1891 status |= DPMI_Lock( PAS_Installed );
1892 status |= DPMI_Lock( PAS_TranslateCode );
1893 status |= DPMI_Lock( PAS_OriginalPCMLeftVolume );
1894 status |= DPMI_Lock( PAS_OriginalPCMRightVolume );
1895 status |= DPMI_Lock( PAS_OriginalFMLeftVolume );
1896 status |= DPMI_Lock( PAS_OriginalFMRightVolume );
1897 status |= DPMI_Lock( PAS_DMAChannel );
1898 status |= DPMI_Lock( PAS_Irq );
1899 status |= DPMI_Lock( PAS_State );
1900 status |= DPMI_Lock( PAS_Func );
1901 status |= DPMI_Lock( PAS_OriginalState );
1902 status |= DPMI_Lock( PAS_SampleSizeConfig );
1903 status |= DPMI_Lock( PAS_DMABuffer );
1904 status |= DPMI_Lock( PAS_DMABufferEnd );
1905 status |= DPMI_Lock( PAS_CurrentDMABuffer );
1906 status |= DPMI_Lock( PAS_TotalDMABufferSize );
1907 status |= DPMI_Lock( PAS_TransferLength );
1908 status |= DPMI_Lock( PAS_MixMode );
1909 status |= DPMI_Lock( PAS_SampleRate );
1910 status |= DPMI_Lock( PAS_TimeInterval );
1911 status |= DPMI_Lock( PAS_SoundPlaying );
1912 status |= DPMI_Lock( PAS_CallBack );
1913 status |= DPMI_Lock( PAS_ErrorCode );
1914 status |= DPMI_Lock( irqstatus );
1915
1916 if ( status != DPMI_Ok )
1917 {
1918 PAS_UnlockMemory();
1919 PAS_SetErrorCode( PAS_DPMI_Error );
1920 return( PAS_Error );
1921 }
1922
1923 return( PAS_Ok );
1924 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pas16.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pas16.h
new file mode 100644
index 0000000000..5d63b6c30e
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pas16.h
@@ -0,0 +1,81 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: PAS16.H
22
23 author: James R. Dose
24 date: March 27, 1994
25
26 Public header for for PAS16.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __PAS16_H
32#define __PAS16_H
33
34enum PAS_ERRORS
35 {
36 PAS_Warning = -2,
37 PAS_Error = -1,
38 PAS_Ok = 0,
39 PAS_DriverNotFound,
40 PAS_DmaError,
41 PAS_InvalidIrq,
42 PAS_UnableToSetIrq,
43 PAS_Dos4gwIrqError,
44 PAS_NoSoundPlaying,
45 PAS_CardNotFound,
46 PAS_DPMI_Error,
47 PAS_OutOfMemory
48 };
49
50#define PAS_MaxMixMode STEREO_16BIT
51#define PAS_DefaultSampleRate 11000
52#define PAS_DefaultMixMode MONO_8BIT
53#define PAS_MaxIrq 15
54
55#define PAS_MinSamplingRate 4000
56#define PAS_MaxSamplingRate 44000
57
58extern unsigned int PAS_DMAChannel;
59
60char *PAS_ErrorString( int ErrorNumber );
61void PAS_SetPlaybackRate( unsigned rate );
62unsigned PAS_GetPlaybackRate( void );
63int PAS_SetMixMode( int mode );
64void PAS_StopPlayback( void );
65int PAS_GetCurrentPos( void );
66int PAS_BeginBufferedPlayback( char *BufferStart, int BufferSize, int NumDivisions, unsigned SampleRate, int MixMode, void ( *CallBackFunc )( void ) );
67int PAS_BeginBufferedRecord( char *BufferStart, int BufferSize, int NumDivisions, unsigned SampleRate, int MixMode, void ( *CallBackFunc )( void ) );
68int PAS_SetPCMVolume( int volume );
69int PAS_GetPCMVolume( void );
70void PAS_SetFMVolume( int volume );
71int PAS_GetFMVolume( void );
72int PAS_GetCardInfo( int *MaxSampleBits, int *MaxChannels );
73void PAS_SetCallBack( void ( *func )( void ) );
74int PAS_SaveMusicVolume( void );
75void PAS_RestoreMusicVolume( void );
76int PAS_Init( void );
77void PAS_Shutdown( void );
78void PAS_UnlockMemory( void );
79int PAS_LockMemory( void );
80
81#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pitch.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pitch.c
new file mode 100644
index 0000000000..fa8ddc4213
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pitch.c
@@ -0,0 +1,258 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: PITCH.C
22
23 author: James R. Dose
24 date: June 14, 1993
25
26 Routines for pitch scaling.
27
28 (c) Copyright 1993 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#include <stdlib.h>
32//#include <math.h>
33#include "dpmi.h"
34#include "standard.h"
35#include "pitch.h"
36
37#define MAXDETUNE 25
38
39static uint32_t PitchTable[ 12 ][ MAXDETUNE ] =
40 {
41 { 0x10000, 0x10097, 0x1012f, 0x101c7, 0x10260, 0x102f9, 0x10392, 0x1042c,
42 0x104c6, 0x10561, 0x105fb, 0x10696, 0x10732, 0x107ce, 0x1086a, 0x10907,
43 0x109a4, 0x10a41, 0x10adf, 0x10b7d, 0x10c1b, 0x10cba, 0x10d59, 0x10df8,
44 0x10e98 },
45 { 0x10f38, 0x10fd9, 0x1107a, 0x1111b, 0x111bd, 0x1125f, 0x11302, 0x113a5,
46 0x11448, 0x114eb, 0x1158f, 0x11634, 0x116d8, 0x1177e, 0x11823, 0x118c9,
47 0x1196f, 0x11a16, 0x11abd, 0x11b64, 0x11c0c, 0x11cb4, 0x11d5d, 0x11e06,
48 0x11eaf },
49 { 0x11f59, 0x12003, 0x120ae, 0x12159, 0x12204, 0x122b0, 0x1235c, 0x12409,
50 0x124b6, 0x12563, 0x12611, 0x126bf, 0x1276d, 0x1281c, 0x128cc, 0x1297b,
51 0x12a2b, 0x12adc, 0x12b8d, 0x12c3e, 0x12cf0, 0x12da2, 0x12e55, 0x12f08,
52 0x12fbc },
53 { 0x1306f, 0x13124, 0x131d8, 0x1328d, 0x13343, 0x133f9, 0x134af, 0x13566,
54 0x1361d, 0x136d5, 0x1378d, 0x13846, 0x138fe, 0x139b8, 0x13a72, 0x13b2c,
55 0x13be6, 0x13ca1, 0x13d5d, 0x13e19, 0x13ed5, 0x13f92, 0x1404f, 0x1410d,
56 0x141cb },
57 { 0x1428a, 0x14349, 0x14408, 0x144c8, 0x14588, 0x14649, 0x1470a, 0x147cc,
58 0x1488e, 0x14951, 0x14a14, 0x14ad7, 0x14b9b, 0x14c5f, 0x14d24, 0x14dea,
59 0x14eaf, 0x14f75, 0x1503c, 0x15103, 0x151cb, 0x15293, 0x1535b, 0x15424,
60 0x154ee },
61 { 0x155b8, 0x15682, 0x1574d, 0x15818, 0x158e4, 0x159b0, 0x15a7d, 0x15b4a,
62 0x15c18, 0x15ce6, 0x15db4, 0x15e83, 0x15f53, 0x16023, 0x160f4, 0x161c5,
63 0x16296, 0x16368, 0x1643a, 0x1650d, 0x165e1, 0x166b5, 0x16789, 0x1685e,
64 0x16934 },
65 { 0x16a09, 0x16ae0, 0x16bb7, 0x16c8e, 0x16d66, 0x16e3e, 0x16f17, 0x16ff1,
66 0x170ca, 0x171a5, 0x17280, 0x1735b, 0x17437, 0x17513, 0x175f0, 0x176ce,
67 0x177ac, 0x1788a, 0x17969, 0x17a49, 0x17b29, 0x17c09, 0x17cea, 0x17dcc,
68 0x17eae },
69 { 0x17f91, 0x18074, 0x18157, 0x1823c, 0x18320, 0x18406, 0x184eb, 0x185d2,
70 0x186b8, 0x187a0, 0x18888, 0x18970, 0x18a59, 0x18b43, 0x18c2d, 0x18d17,
71 0x18e02, 0x18eee, 0x18fda, 0x190c7, 0x191b5, 0x192a2, 0x19391, 0x19480,
72 0x1956f },
73 { 0x1965f, 0x19750, 0x19841, 0x19933, 0x19a25, 0x19b18, 0x19c0c, 0x19d00,
74 0x19df4, 0x19ee9, 0x19fdf, 0x1a0d5, 0x1a1cc, 0x1a2c4, 0x1a3bc, 0x1a4b4,
75 0x1a5ad, 0x1a6a7, 0x1a7a1, 0x1a89c, 0x1a998, 0x1aa94, 0x1ab90, 0x1ac8d,
76 0x1ad8b },
77 { 0x1ae89, 0x1af88, 0x1b088, 0x1b188, 0x1b289, 0x1b38a, 0x1b48c, 0x1b58f,
78 0x1b692, 0x1b795, 0x1b89a, 0x1b99f, 0x1baa4, 0x1bbaa, 0x1bcb1, 0x1bdb8,
79 0x1bec0, 0x1bfc9, 0x1c0d2, 0x1c1dc, 0x1c2e6, 0x1c3f1, 0x1c4fd, 0x1c609,
80 0x1c716 },
81 { 0x1c823, 0x1c931, 0x1ca40, 0x1cb50, 0x1cc60, 0x1cd70, 0x1ce81, 0x1cf93,
82 0x1d0a6, 0x1d1b9, 0x1d2cd, 0x1d3e1, 0x1d4f6, 0x1d60c, 0x1d722, 0x1d839,
83 0x1d951, 0x1da69, 0x1db82, 0x1dc9c, 0x1ddb6, 0x1ded1, 0x1dfec, 0x1e109,
84 0x1e225 },
85 { 0x1e343, 0x1e461, 0x1e580, 0x1e6a0, 0x1e7c0, 0x1e8e0, 0x1ea02, 0x1eb24,
86 0x1ec47, 0x1ed6b, 0x1ee8f, 0x1efb4, 0x1f0d9, 0x1f1ff, 0x1f326, 0x1f44e,
87 0x1f576, 0x1f69f, 0x1f7c9, 0x1f8f3, 0x1fa1e, 0x1fb4a, 0x1fc76, 0x1fda3,
88 0x1fed1 }
89 };
90
91
92//static int PITCH_Installed = FALSE;
93
94
95/*---------------------------------------------------------------------
96 Function: PITCH_Init
97
98 Initializes pitch table.
99---------------------------------------------------------------------*/
100/*
101void PITCH_Init
102 (
103 void
104 )
105
106 {
107 int note;
108 int detune;
109
110 if ( !PITCH_Installed )
111 {
112 for( note = 0; note < 12; note++ )
113 {
114 for( detune = 0; detune < MAXDETUNE; detune++ )
115 {
116 PitchTable[ note ][ detune ] = 0x10000 *
117 pow( 2, ( note * MAXDETUNE + detune ) / ( 12.0 * MAXDETUNE ) );
118 }
119 }
120
121 PITCH_Installed = TRUE;
122 }
123 }
124*/
125
126/**********************************************************************
127
128 Memory locked functions:
129
130**********************************************************************/
131
132
133#define PITCH_LockStart PITCH_GetScale
134
135
136/*---------------------------------------------------------------------
137 Function: PITCH_GetScale
138
139 Returns a fixed-point value to scale number the specified amount.
140---------------------------------------------------------------------*/
141
142uint32_t PITCH_GetScale
143 (
144 int pitchoffset
145 )
146
147 {
148 uint32_t scale;
149 int octaveshift;
150 int noteshift;
151 int note;
152 int detune;
153
154// if ( !PITCH_Installed )
155// {
156// PITCH_Init();
157// }
158
159 if ( pitchoffset == 0 )
160 {
161 return( PitchTable[ 0 ][ 0 ] );
162 }
163
164 noteshift = pitchoffset % 1200;
165 if ( noteshift < 0 )
166 {
167 noteshift += 1200;
168 }
169
170 note = noteshift / 100;
171 detune = ( noteshift % 100 ) / ( 100 / MAXDETUNE );
172 octaveshift = ( pitchoffset - noteshift ) / 1200;
173
174 if ( detune < 0 )
175 {
176 detune += ( 100 / MAXDETUNE );
177 note--;
178 if ( note < 0 )
179 {
180 note += 12;
181 octaveshift--;
182 }
183 }
184
185 scale = PitchTable[ note ][ detune ];
186
187 if ( octaveshift < 0 )
188 {
189 scale >>= -octaveshift;
190 }
191 else
192 {
193 scale <<= octaveshift;
194 }
195
196 return( scale );
197 }
198
199
200/*---------------------------------------------------------------------
201 Function: PITCH_LockEnd
202
203 Used for determining the length of the functions to lock in memory.
204---------------------------------------------------------------------*/
205
206static void PITCH_LockEnd
207 (
208 void
209 )
210
211 {
212 }
213
214
215/*---------------------------------------------------------------------
216 Function: PITCH_UnlockMemory
217
218 Unlocks all neccessary data.
219---------------------------------------------------------------------*/
220
221void PITCH_UnlockMemory
222 (
223 void
224 )
225
226 {
227 DPMI_UnlockMemoryRegion( PITCH_LockStart, PITCH_LockEnd );
228 DPMI_Unlock( PitchTable );
229// DPMI_Unlock( PITCH_Installed );
230 }
231
232
233/*---------------------------------------------------------------------
234 Function: PITCH_LockMemory
235
236 Unlocks all neccessary data.
237---------------------------------------------------------------------*/
238
239int PITCH_LockMemory
240 (
241 void
242 )
243
244 {
245 int status;
246
247 status = DPMI_LockMemoryRegion( PITCH_LockStart, PITCH_LockEnd );
248 status |= DPMI_Lock( PitchTable );
249// status |= DPMI_Lock( PITCH_Installed );
250
251 if ( status != DPMI_Ok )
252 {
253 PITCH_UnlockMemory();
254 return( PITCH_Error );
255 }
256
257 return( PITCH_Ok );
258 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pitch.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pitch.h
new file mode 100644
index 0000000000..bbae659b54
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/pitch.h
@@ -0,0 +1,47 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: PITCH.H
22
23 author: James R. Dose
24 date: June 14, 1994
25
26 Public header for PITCH.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __PITCH_H
32#define __PITCH_H
33
34#include "../duke3d.h"
35
36enum PITCH_ERRORS
37 {
38 PITCH_Warning = -2,
39 PITCH_Error = -1,
40 PITCH_Ok = 0,
41 };
42
43//void PITCH_Init( void );
44uint32_t PITCH_GetScale( int pitchoffset );
45void PITCH_UnlockMemory( void );
46int PITCH_LockMemory( void );
47#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndcards.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndcards.h
new file mode 100644
index 0000000000..39878b759f
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndcards.h
@@ -0,0 +1,55 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: SNDCARDS.H
22
23 author: James R. Dose
24 date: March 31, 1994
25
26 Contains enumerated type definitions for sound cards.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __SNDCARDS_H
32#define __SNDCARDS_H
33
34#define ASS_VERSION_STRING "1.12"
35
36typedef enum
37 {
38// ASS_NoSound,
39 SoundBlaster,
40 ProAudioSpectrum,
41 SoundMan16,
42 Adlib,
43 GenMidi,
44 SoundCanvas,
45 Awe32,
46 WaveBlaster,
47 SoundScape,
48 UltraSound,
49 SoundSource,
50 TandySoundSource,
51 PC,
52 NumSoundCards
53 } soundcardnames;
54
55#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndscape.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndscape.c
new file mode 100644
index 0000000000..a177265c5c
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndscape.c
@@ -0,0 +1,1661 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: SNDSCAPE.C
22
23 author: James R. Dose
24 date: October 25, 1994
25
26 Low level routines to support the Ensoniq Soundscape.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#include <dos.h>
32#include <conio.h>
33#include <stdlib.h>
34#include <stdio.h>
35#include <string.h>
36#include <ctype.h>
37#include <time.h>
38#include "interrup.h"
39#include "dpmi.h"
40#include "dma.h"
41#include "irq.h"
42#include "sndscape.h"
43#include "_sndscap.h"
44
45const int SOUNDSCAPE_Interrupts[ SOUNDSCAPE_MaxIrq + 1 ] =
46 {
47 INVALID, INVALID, 0xa, INVALID,
48 INVALID, 0xd, INVALID, 0xf,
49 INVALID, INVALID, 0x72, INVALID,
50 INVALID, INVALID, INVALID, INVALID
51 };
52
53const int SOUNDSCAPE_SampleSize[ SOUNDSCAPE_MaxMixMode + 1 ] =
54 {
55 MONO_8BIT_SAMPLE_SIZE, STEREO_8BIT_SAMPLE_SIZE,
56 MONO_16BIT_SAMPLE_SIZE, STEREO_16BIT_SAMPLE_SIZE
57 };
58
59static void ( __interrupt __far *SOUNDSCAPE_OldInt )( void );
60
61static int SOUNDSCAPE_Installed = FALSE;
62static int SOUNDSCAPE_FoundCard = FALSE;
63
64static char *SOUNDSCAPE_DMABuffer;
65static char *SOUNDSCAPE_DMABufferEnd;
66static char *SOUNDSCAPE_CurrentDMABuffer;
67static int SOUNDSCAPE_TotalDMABufferSize;
68
69static int SOUNDSCAPE_TransferLength = 0;
70static int SOUNDSCAPE_MixMode = SOUNDSCAPE_DefaultMixMode;
71static int SOUNDSCAPE_SamplePacketSize = MONO_16BIT_SAMPLE_SIZE;
72static unsigned SOUNDSCAPE_SampleRate = SOUNDSCAPE_DefaultSampleRate;
73
74volatile int SOUNDSCAPE_SoundPlaying;
75
76void ( *SOUNDSCAPE_CallBack )( void );
77
78static int SOUNDSCAPE_IntController1Mask;
79static int SOUNDSCAPE_IntController2Mask;
80
81// some globals for chip type, ports, DMA, IRQs ... and stuff
82static struct
83 {
84 int BasePort; // base address of the Ensoniq gate-array chip
85 int WavePort; // the AD-1848 base address
86 int DMAChan; // the DMA channel used for PCM
87 int WaveIRQ; // the PCM IRQ
88 int MIDIIRQ; // the MPU-401 IRQ
89 int ChipID; // the Ensoniq chip type
90 int SBEmul; // SoundBlaster emulation flag
91 int CDROM; // CD-ROM flag
92 int IRQIndx; // the Wave IRQ index - for hardware regs
93 int OldIRQs; // Old IRQs flag to support older HW
94 } SOUNDSCAPE_Config;
95
96// adequate stack size
97#define kStackSize 2048
98
99static unsigned short StackSelector = NULL;
100static unsigned long StackPointer;
101
102static unsigned short oldStackSelector;
103static unsigned long oldStackPointer;
104
105// These declarations are necessary to use the inline assembly pragmas.
106
107extern void GetStack(unsigned short *selptr,unsigned long *stackptr);
108extern void SetStack(unsigned short selector,unsigned long stackptr);
109
110// This function will get the current stack selector and pointer and save
111// them off.
112#pragma aux GetStack = \
113 "mov [edi],esp" \
114 "mov ax,ss" \
115 "mov [esi],ax" \
116 parm [esi] [edi] \
117 modify [eax esi edi];
118
119// This function will set the stack selector and pointer to the specified
120// values.
121#pragma aux SetStack = \
122 "mov ss,ax" \
123 "mov esp,edx" \
124 parm [ax] [edx] \
125 modify [eax edx];
126
127int SOUNDSCAPE_DMAChannel = -1;
128
129int SOUNDSCAPE_ErrorCode = SOUNDSCAPE_Ok;
130
131#define SOUNDSCAPE_SetErrorCode( status ) \
132 SOUNDSCAPE_ErrorCode = ( status );
133
134
135/*---------------------------------------------------------------------
136 Function: SOUNDSCAPE_ErrorString
137
138 Returns a pointer to the error message associated with an error
139 number. A -1 returns a pointer the current error.
140---------------------------------------------------------------------*/
141
142char *SOUNDSCAPE_ErrorString
143 (
144 int ErrorNumber
145 )
146
147 {
148 char *ErrorString;
149
150 switch( ErrorNumber )
151 {
152 case SOUNDSCAPE_Warning :
153 case SOUNDSCAPE_Error :
154 ErrorString = SOUNDSCAPE_ErrorString( SOUNDSCAPE_ErrorCode );
155 break;
156
157 case SOUNDSCAPE_Ok :
158 ErrorString = "SoundScape ok.";
159 break;
160
161 case SOUNDSCAPE_EnvNotFound :
162 ErrorString = "SNDSCAPE environment variable not set. This is used to locate \n"
163 "SNDSCAPE.INI which is used to describe your sound card setup.";
164 break;
165
166 case SOUNDSCAPE_InitFileNotFound :
167 ErrorString = "Missing SNDSCAPE.INI file for SoundScape. This file should be \n"
168 "located in the directory indicated by the SNDSCAPE environment \n"
169 "variable or in 'C:\SNDSCAPE' if SNDSCAPE is not set.";
170 break;
171
172 case SOUNDSCAPE_MissingProductInfo :
173 ErrorString = "Missing 'Product' field in SNDSCAPE.INI file for SoundScape.";
174 break;
175
176 case SOUNDSCAPE_MissingPortInfo :
177 ErrorString = "Missing 'Port' field in SNDSCAPE.INI file for SoundScape.";
178 break;
179
180 case SOUNDSCAPE_MissingDMAInfo :
181 ErrorString = "Missing 'DMA' field in SNDSCAPE.INI file for SoundScape.";
182 break;
183
184 case SOUNDSCAPE_MissingIRQInfo :
185 ErrorString = "Missing 'IRQ' field in SNDSCAPE.INI file for SoundScape.";
186 break;
187
188 case SOUNDSCAPE_MissingSBIRQInfo :
189 ErrorString = "Missing 'SBIRQ' field in SNDSCAPE.INI file for SoundScape.";
190 break;
191
192 case SOUNDSCAPE_MissingSBENABLEInfo :
193 ErrorString = "Missing 'SBEnable' field in SNDSCAPE.INI file for SoundScape.";
194 break;
195
196 case SOUNDSCAPE_MissingWavePortInfo :
197 ErrorString = "Missing 'WavePort' field in SNDSCAPE.INI file for SoundScape.";
198 break;
199
200 case SOUNDSCAPE_HardwareError :
201 ErrorString = "Could not detect SoundScape. Make sure your SNDSCAPE.INI file \n"
202 "contains correct information about your hardware setup.";
203 break;
204
205 case SOUNDSCAPE_NoSoundPlaying :
206 ErrorString = "No sound playing on SoundScape.";
207 break;
208
209 case SOUNDSCAPE_InvalidSBIrq :
210 ErrorString = "Invalid SoundScape Irq in SBIRQ field of SNDSCAPE.INI.";
211 break;
212
213 case SOUNDSCAPE_UnableToSetIrq :
214 ErrorString = "Unable to set SoundScape IRQ. Try selecting an IRQ of 7 or below.";
215 break;
216
217 case SOUNDSCAPE_DmaError :
218 ErrorString = DMA_ErrorString( DMA_Error );
219 break;
220
221 case SOUNDSCAPE_DPMI_Error :
222 ErrorString = "DPMI Error in SoundScape.";
223 break;
224
225 case SOUNDSCAPE_OutOfMemory :
226 ErrorString = "Out of conventional memory in SoundScape.";
227 break;
228
229 default :
230 ErrorString = "Unknown SoundScape error code.";
231 break;
232 }
233
234 return( ErrorString );
235 }
236
237
238/**********************************************************************
239
240 Memory locked functions:
241
242**********************************************************************/
243
244
245#define SOUNDSCAPE_LockStart SOUNDSCAPE_EnableInterrupt
246
247
248/*---------------------------------------------------------------------
249 Function: SOUNDSCAPE_EnableInterrupt
250
251 Enables the triggering of the sound card interrupt.
252---------------------------------------------------------------------*/
253
254static void SOUNDSCAPE_EnableInterrupt
255 (
256 void
257 )
258
259 {
260 int mask;
261
262 // Unmask system interrupt
263 if ( SOUNDSCAPE_Config.WaveIRQ < 8 )
264 {
265 mask = inp( 0x21 ) & ~( 1 << SOUNDSCAPE_Config.WaveIRQ );
266 outp( 0x21, mask );
267 }
268 else
269 {
270 mask = inp( 0xA1 ) & ~( 1 << ( SOUNDSCAPE_Config.WaveIRQ - 8 ) );
271 outp( 0xA1, mask );
272
273 mask = inp( 0x21 ) & ~( 1 << 2 );
274 outp( 0x21, mask );
275 }
276
277 }
278
279
280/*---------------------------------------------------------------------
281 Function: SOUNDSCAPE_DisableInterrupt
282
283 Disables the triggering of the sound card interrupt.
284---------------------------------------------------------------------*/
285
286static void SOUNDSCAPE_DisableInterrupt
287 (
288 void
289 )
290
291 {
292 int mask;
293
294 // Restore interrupt mask
295 if ( SOUNDSCAPE_Config.WaveIRQ < 8 )
296 {
297 mask = inp( 0x21 ) & ~( 1 << SOUNDSCAPE_Config.WaveIRQ );
298 mask |= SOUNDSCAPE_IntController1Mask & ( 1 << SOUNDSCAPE_Config.WaveIRQ );
299 outp( 0x21, mask );
300 }
301 else
302 {
303 mask = inp( 0x21 ) & ~( 1 << 2 );
304 mask |= SOUNDSCAPE_IntController1Mask & ( 1 << 2 );
305 outp( 0x21, mask );
306
307 mask = inp( 0xA1 ) & ~( 1 << ( SOUNDSCAPE_Config.WaveIRQ - 8 ) );
308 mask |= SOUNDSCAPE_IntController2Mask & ( 1 << ( SOUNDSCAPE_Config.WaveIRQ - 8 ) );
309 outp( 0xA1, mask );
310 }
311 }
312
313
314/*---------------------------------------------------------------------
315 Function: SOUNDSCAPE_ServiceInterrupt
316
317 Handles interrupt generated by sound card at the end of a voice
318 transfer. Calls the user supplied callback function.
319---------------------------------------------------------------------*/
320
321static void __interrupt __far SOUNDSCAPE_ServiceInterrupt
322 (
323 void
324 )
325
326 {
327 // save stack
328 GetStack( &oldStackSelector, &oldStackPointer );
329
330 // set our stack
331 SetStack( StackSelector, StackPointer );
332
333 if ( !( inp( SOUNDSCAPE_Config.WavePort + AD_STATUS ) & 0x01 ) )
334 {
335 // restore stack
336 SetStack( oldStackSelector, oldStackPointer );
337
338 // Wasn't our interrupt. Call the old one.
339 _chain_intr( SOUNDSCAPE_OldInt );
340 }
341
342 // clear the AD-1848 interrupt
343 outp( SOUNDSCAPE_Config.WavePort + AD_STATUS, 0x00 );
344
345 // Keep track of current buffer
346 SOUNDSCAPE_CurrentDMABuffer += SOUNDSCAPE_TransferLength;
347 if ( SOUNDSCAPE_CurrentDMABuffer >= SOUNDSCAPE_DMABufferEnd )
348 {
349 SOUNDSCAPE_CurrentDMABuffer = SOUNDSCAPE_DMABuffer;
350 }
351
352 // Call the caller's callback function
353 if ( SOUNDSCAPE_CallBack != NULL )
354 {
355 SOUNDSCAPE_CallBack();
356 }
357
358 // restore stack
359 SetStack( oldStackSelector, oldStackPointer );
360
361 // send EOI to Interrupt Controller
362 if ( SOUNDSCAPE_Config.WaveIRQ > 7 )
363 {
364 outp( 0xA0, 0x20 );
365 }
366 outp( 0x20, 0x20 );
367 }
368
369
370/*---------------------------------------------------------------------
371 Function: ga_read
372
373 Reads Ensoniq indirect registers.
374---------------------------------------------------------------------*/
375
376static int ga_read
377 (
378 int rnum
379 )
380
381 {
382 int data;
383
384 outp( SOUNDSCAPE_Config.BasePort + GA_REGADDR, rnum );
385 data = inp( SOUNDSCAPE_Config.BasePort + GA_REGDATA );
386 return( data );
387 }
388
389
390/*---------------------------------------------------------------------
391 Function: ga_write
392
393 Writes to Ensoniq indirect registers.
394---------------------------------------------------------------------*/
395
396static void ga_write
397 (
398 int rnum,
399 int value
400 )
401
402 {
403 outp( SOUNDSCAPE_Config.BasePort + GA_REGADDR, rnum );
404 outp( SOUNDSCAPE_Config.BasePort + GA_REGDATA, value );
405 }
406
407
408/*---------------------------------------------------------------------
409 Function: ad_read
410
411 Reads the AD-1848 indirect registers. This function should not be
412 used while the AD-1848 mode change is enabled
413---------------------------------------------------------------------*/
414
415static int ad_read
416 (
417 int rnum
418 )
419
420 {
421 int data;
422
423 outp( SOUNDSCAPE_Config.WavePort + AD_REGADDR, rnum );
424 data = inp( SOUNDSCAPE_Config.WavePort + AD_REGDATA );
425 return( data );
426 }
427
428
429/*---------------------------------------------------------------------
430 Function: ad_write
431
432 Writes to the AD-1848 indirect registers. This function should
433 not be used while the AD-1848 mode change is enabled.
434---------------------------------------------------------------------*/
435
436static void ad_write
437 (
438 int rnum,
439 int value
440 )
441
442 {
443 outp( SOUNDSCAPE_Config.WavePort + AD_REGADDR, rnum );
444 outp( SOUNDSCAPE_Config.WavePort + AD_REGDATA, value );
445 }
446
447
448/*---------------------------------------------------------------------
449 Function: tdelay
450
451 Delay function - 250ms - for AD-1848 re-synch and autocalibration.
452---------------------------------------------------------------------*/
453
454static void tdelay
455 (
456 void
457 )
458
459 {
460 long time;
461 unsigned flags;
462
463 flags = DisableInterrupts();
464 _enable();
465 time = clock() + CLOCKS_PER_SEC/4;
466 while(clock() < time)
467 ;
468
469 RestoreInterrupts( flags );
470 }
471
472
473/*---------------------------------------------------------------------
474 Function: pcm_format
475
476 Sets the PCM data format.
477---------------------------------------------------------------------*/
478
479static void pcm_format
480 (
481 void
482 )
483
484 {
485 int format;
486
487 // build the register value based on format
488 format = 0;
489
490 switch( SOUNDSCAPE_SampleRate )
491 {
492 case 11025:
493 format = 0x03;
494 break;
495
496 case 22050:
497 format = 0x07;
498 break;
499
500 case 44100:
501 format = 0x0b;
502 break;
503
504 default:
505 // Set it to 11025 hz
506 format = 0x03;
507 break;
508 }
509
510 // set other format bits and format globals
511 if ( SOUNDSCAPE_MixMode & SIXTEEN_BIT )
512 {
513 format |= 0x40;
514 }
515
516 if ( SOUNDSCAPE_MixMode & STEREO )
517 {
518 format |= 0x10;
519 }
520
521 // enable mode change, point to format reg
522 outp( SOUNDSCAPE_Config.WavePort + AD_REGADDR, 0x40 | AD_FORMAT );
523
524 // write the format
525 outp( SOUNDSCAPE_Config.WavePort + AD_REGDATA, format );
526
527 // delay for internal re-synch
528 tdelay();
529
530 // exit mode change state
531 outp( SOUNDSCAPE_Config.WavePort + AD_REGADDR, 0x00 );
532
533 // delay for autocalibration
534 tdelay();
535 }
536
537
538/*---------------------------------------------------------------------
539 Function: SOUNDSCAPE_SetPlaybackRate
540
541 Sets the rate at which the digitized sound will be played in
542 hertz.
543---------------------------------------------------------------------*/
544
545void SOUNDSCAPE_SetPlaybackRate
546 (
547 unsigned rate
548 )
549
550 {
551 if ( rate < 20000 )
552 {
553 rate = 11025;
554 }
555 else if ( rate < 30000 )
556 {
557 rate = 22050;
558 }
559 else
560 {
561 rate = 44100;
562 }
563
564 SOUNDSCAPE_SampleRate = rate;
565
566 // Set the rate
567 pcm_format();
568 }
569
570
571/*---------------------------------------------------------------------
572 Function: SOUNDSCAPE_GetPlaybackRate
573
574 Returns the rate at which the digitized sound will be played in
575 hertz.
576---------------------------------------------------------------------*/
577
578unsigned SOUNDSCAPE_GetPlaybackRate
579 (
580 void
581 )
582
583 {
584 return( SOUNDSCAPE_SampleRate );
585 }
586
587
588/*---------------------------------------------------------------------
589 Function: SOUNDSCAPE_SetMixMode
590
591 Sets the sound card to play samples in mono or stereo.
592---------------------------------------------------------------------*/
593
594int SOUNDSCAPE_SetMixMode
595 (
596 int mode
597 )
598
599 {
600 SOUNDSCAPE_MixMode = mode & SOUNDSCAPE_MaxMixMode;
601 SOUNDSCAPE_SamplePacketSize = SOUNDSCAPE_SampleSize[ SOUNDSCAPE_MixMode ];
602
603 // Set the mixmode
604 pcm_format();
605
606 return( mode );
607 }
608
609
610/*---------------------------------------------------------------------
611 Function: SOUNDSCAPE_StopPlayback
612
613 Ends the DMA transfer of digitized sound to the sound card.
614---------------------------------------------------------------------*/
615
616void SOUNDSCAPE_StopPlayback
617 (
618 void
619 )
620
621 {
622 // Don't allow anymore interrupts
623 SOUNDSCAPE_DisableInterrupt();
624
625 /* stop the AD-1848 */
626 ad_write( AD_CONFIG, 0x00 );
627
628 /* let it finish it's cycles */
629 tdelay();
630
631 // Disable the DMA channel
632 DMA_EndTransfer( SOUNDSCAPE_Config.DMAChan );
633
634 SOUNDSCAPE_SoundPlaying = FALSE;
635
636 SOUNDSCAPE_DMABuffer = NULL;
637 }
638
639
640/*---------------------------------------------------------------------
641 Function: SOUNDSCAPE_SetupDMABuffer
642
643 Programs the DMAC for sound transfer.
644---------------------------------------------------------------------*/
645
646static int SOUNDSCAPE_SetupDMABuffer
647 (
648 char *BufferPtr,
649 int BufferSize,
650 int mode
651 )
652
653 {
654 int DmaStatus;
655
656 DmaStatus = DMA_SetupTransfer( SOUNDSCAPE_Config.DMAChan, BufferPtr, BufferSize, mode );
657 if ( DmaStatus == DMA_Error )
658 {
659 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_DmaError );
660 return( SOUNDSCAPE_Error );
661 }
662
663 SOUNDSCAPE_DMAChannel = SOUNDSCAPE_Config.DMAChan;
664 SOUNDSCAPE_DMABuffer = BufferPtr;
665 SOUNDSCAPE_CurrentDMABuffer = BufferPtr;
666 SOUNDSCAPE_TotalDMABufferSize = BufferSize;
667 SOUNDSCAPE_DMABufferEnd = BufferPtr + BufferSize;
668
669 return( SOUNDSCAPE_Ok );
670 }
671
672
673/*---------------------------------------------------------------------
674 Function: SOUNDSCAPE_GetCurrentPos
675
676 Returns the offset within the current sound being played.
677---------------------------------------------------------------------*/
678
679int SOUNDSCAPE_GetCurrentPos
680 (
681 void
682 )
683
684 {
685 char *CurrentAddr;
686 int offset;
687
688 if ( !SOUNDSCAPE_SoundPlaying )
689 {
690 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_NoSoundPlaying );
691 return( SOUNDSCAPE_Error );
692 }
693
694 CurrentAddr = DMA_GetCurrentPos( SOUNDSCAPE_Config.DMAChan );
695
696 offset = ( int )( ( ( unsigned long )CurrentAddr ) -
697 ( ( unsigned long )SOUNDSCAPE_CurrentDMABuffer ) );
698
699 if ( SOUNDSCAPE_MixMode & SIXTEEN_BIT )
700 {
701 offset >>= 1;
702 }
703
704 if ( SOUNDSCAPE_MixMode & STEREO )
705 {
706 offset >>= 1;
707 }
708
709 return( offset );
710 }
711
712
713/*---------------------------------------------------------------------
714 Function: SOUNDSCAPE_BeginPlayback
715
716 Starts playback of digitized sound.
717---------------------------------------------------------------------*/
718
719static int SOUNDSCAPE_BeginPlayback
720 (
721 int length
722 )
723
724 {
725 int SampleLength;
726 int LoByte;
727 int HiByte;
728
729 if ( SOUNDSCAPE_MixMode & SIXTEEN_BIT )
730 {
731 SampleLength = length / 2;
732 }
733 else
734 {
735 SampleLength = length;
736 }
737
738 if ( SOUNDSCAPE_MixMode & STEREO )
739 {
740 SampleLength >>= 1;
741 }
742
743 SampleLength--;
744
745 // setup the AD-1848 interrupt count
746 // set the interrupt count value based on the format.
747 // count will decrement every sample period and generate
748 // an interrupt when in rolls over. we want this always
749 // to be at every 1/2 buffer, regardless of the data format,
750 // so the count must be adjusted accordingly.
751 HiByte = hibyte( SampleLength );
752 LoByte = lobyte( SampleLength );
753 ad_write( AD_LCOUNT, LoByte );
754 ad_write( AD_UCOUNT, HiByte );
755
756 /* unmask the host DMA controller */
757 SOUNDSCAPE_EnableInterrupt();
758
759 /* start the AD-1848 */
760 ad_write(AD_CONFIG, 0x01);
761
762 SOUNDSCAPE_SoundPlaying = TRUE;
763
764 return( SOUNDSCAPE_Ok );
765 }
766
767
768/*---------------------------------------------------------------------
769 Function: SOUNDSCAPE_BeginBufferedPlayback
770
771 Begins multibuffered playback of digitized sound on the sound card.
772---------------------------------------------------------------------*/
773
774int SOUNDSCAPE_BeginBufferedPlayback
775 (
776 char *BufferStart,
777 int BufferSize,
778 int NumDivisions,
779 unsigned SampleRate,
780 int MixMode,
781 void ( *CallBackFunc )( void )
782 )
783
784 {
785 int DmaStatus;
786 int TransferLength;
787
788 if ( SOUNDSCAPE_SoundPlaying )
789 {
790 SOUNDSCAPE_StopPlayback();
791 }
792
793 SOUNDSCAPE_SetMixMode( MixMode );
794
795 DmaStatus = SOUNDSCAPE_SetupDMABuffer( BufferStart, BufferSize,
796 DMA_AutoInitRead );
797 if ( DmaStatus == SOUNDSCAPE_Error )
798 {
799 return( SOUNDSCAPE_Error );
800 }
801
802 SOUNDSCAPE_SetPlaybackRate( SampleRate );
803
804 SOUNDSCAPE_SetCallBack( CallBackFunc );
805
806 SOUNDSCAPE_EnableInterrupt();
807
808 TransferLength = BufferSize / NumDivisions;
809 SOUNDSCAPE_TransferLength = TransferLength;
810
811 SOUNDSCAPE_BeginPlayback( TransferLength );
812
813 return( SOUNDSCAPE_Ok );
814 }
815
816
817/*---------------------------------------------------------------------
818 Function: SOUNDSCAPE_GetCardInfo
819
820 Returns the maximum number of bits that can represent a sample
821 (8 or 16) and the number of channels (1 for mono, 2 for stereo).
822---------------------------------------------------------------------*/
823
824int SOUNDSCAPE_GetCardInfo
825 (
826 int *MaxSampleBits,
827 int *MaxChannels
828 )
829
830 {
831 int status;
832
833 status = SOUNDSCAPE_FindCard();
834 if ( status == SOUNDSCAPE_Ok )
835 {
836 *MaxChannels = 2;
837 *MaxSampleBits = 16;
838 return( SOUNDSCAPE_Ok );
839 }
840
841 return( status );
842 }
843
844
845/*---------------------------------------------------------------------
846 Function: SOUNDSCAPE_SetCallBack
847
848 Specifies the user function to call at the end of a sound transfer.
849---------------------------------------------------------------------*/
850
851void SOUNDSCAPE_SetCallBack
852 (
853 void ( *func )( void )
854 )
855
856 {
857 SOUNDSCAPE_CallBack = func;
858 }
859
860
861/*---------------------------------------------------------------------
862 Function: SOUNDSCAPE_LockEnd
863
864 Used for determining the length of the functions to lock in memory.
865---------------------------------------------------------------------*/
866
867static void SOUNDSCAPE_LockEnd
868 (
869 void
870 )
871
872 {
873 }
874
875
876/*---------------------------------------------------------------------
877 Function: SOUNDSCAPE_UnlockMemory
878
879 Unlocks all neccessary data.
880---------------------------------------------------------------------*/
881
882static void SOUNDSCAPE_UnlockMemory
883 (
884 void
885 )
886
887 {
888 DPMI_UnlockMemoryRegion( SOUNDSCAPE_LockStart, SOUNDSCAPE_LockEnd );
889 DPMI_Unlock( SOUNDSCAPE_Config );
890 DPMI_Unlock( SOUNDSCAPE_OldInt );
891 DPMI_Unlock( SOUNDSCAPE_Installed );
892 DPMI_Unlock( SOUNDSCAPE_DMABuffer );
893 DPMI_Unlock( SOUNDSCAPE_DMABufferEnd );
894 DPMI_Unlock( SOUNDSCAPE_CurrentDMABuffer );
895 DPMI_Unlock( SOUNDSCAPE_TotalDMABufferSize );
896 DPMI_Unlock( SOUNDSCAPE_TransferLength );
897 DPMI_Unlock( SOUNDSCAPE_MixMode );
898 DPMI_Unlock( SOUNDSCAPE_SamplePacketSize );
899 DPMI_Unlock( SOUNDSCAPE_SampleRate );
900 DPMI_Unlock( SOUNDSCAPE_SoundPlaying );
901 DPMI_Unlock( SOUNDSCAPE_CallBack );
902 DPMI_Unlock( SOUNDSCAPE_IntController1Mask );
903 DPMI_Unlock( SOUNDSCAPE_IntController2Mask );
904 }
905
906
907/*---------------------------------------------------------------------
908 Function: SOUNDSCAPE_LockMemory
909
910 Locks all neccessary data.
911---------------------------------------------------------------------*/
912
913static int SOUNDSCAPE_LockMemory
914 (
915 void
916 )
917
918 {
919 int status;
920
921 status = DPMI_LockMemoryRegion( SOUNDSCAPE_LockStart, SOUNDSCAPE_LockEnd );
922 status |= DPMI_Lock( SOUNDSCAPE_Config );
923 status |= DPMI_Lock( SOUNDSCAPE_OldInt );
924 status |= DPMI_Lock( SOUNDSCAPE_Installed );
925 status |= DPMI_Lock( SOUNDSCAPE_DMABuffer );
926 status |= DPMI_Lock( SOUNDSCAPE_DMABufferEnd );
927 status |= DPMI_Lock( SOUNDSCAPE_CurrentDMABuffer );
928 status |= DPMI_Lock( SOUNDSCAPE_TotalDMABufferSize );
929 status |= DPMI_Lock( SOUNDSCAPE_TransferLength );
930 status |= DPMI_Lock( SOUNDSCAPE_MixMode );
931 status |= DPMI_Lock( SOUNDSCAPE_SamplePacketSize );
932 status |= DPMI_Lock( SOUNDSCAPE_SampleRate );
933 status |= DPMI_Lock( SOUNDSCAPE_SoundPlaying );
934 status |= DPMI_Lock( SOUNDSCAPE_CallBack );
935 status |= DPMI_Lock( SOUNDSCAPE_IntController1Mask );
936 status |= DPMI_Lock( SOUNDSCAPE_IntController2Mask );
937
938 if ( status != DPMI_Ok )
939 {
940 SOUNDSCAPE_UnlockMemory();
941 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_DPMI_Error );
942 return( SOUNDSCAPE_Error );
943 }
944
945 return( SOUNDSCAPE_Ok );
946 }
947
948
949/*---------------------------------------------------------------------
950 Function: allocateTimerStack
951
952 Allocate a block of memory from conventional (low) memory and return
953 the selector (which can go directly into a segment register) of the
954 memory block or 0 if an error occured.
955---------------------------------------------------------------------*/
956
957static unsigned short allocateTimerStack
958 (
959 unsigned short size
960 )
961
962 {
963 union REGS regs;
964
965 // clear all registers
966 memset( &regs, 0, sizeof( regs ) );
967
968 // DPMI allocate conventional memory
969 regs.w.ax = 0x100;
970
971 // size in paragraphs
972 regs.w.bx = ( size + 15 ) / 16;
973
974 int386( 0x31, &regs, &regs );
975 if (!regs.w.cflag)
976 {
977 // DPMI call returns selector in dx
978 // (ax contains real mode segment
979 // which is ignored here)
980
981 return( regs.w.dx );
982 }
983
984 // Couldn't allocate memory.
985 return( NULL );
986 }
987
988
989/*---------------------------------------------------------------------
990 Function: deallocateTimerStack
991
992 Deallocate a block of conventional (low) memory given a selector to
993 it. Assumes the block was allocated with DPMI function 0x100.
994---------------------------------------------------------------------*/
995
996static void deallocateTimerStack
997 (
998 unsigned short selector
999 )
1000
1001 {
1002 union REGS regs;
1003
1004 if ( selector != NULL )
1005 {
1006 // clear all registers
1007 memset( &regs, 0, sizeof( regs ) );
1008
1009 regs.w.ax = 0x101;
1010 regs.w.dx = selector;
1011 int386( 0x31, &regs, &regs );
1012 }
1013 }
1014
1015
1016/*---------------------------------------------------------------------
1017 Function: parse
1018
1019 Parses for the right hand string of an .INI file equate.
1020---------------------------------------------------------------------*/
1021
1022static int parse
1023 (
1024 char *val,
1025 char *str,
1026 FILE *p1
1027 )
1028
1029 {
1030 int i;
1031 int j;
1032 char tmpstr[ 81 ];
1033
1034 rewind( p1 );
1035
1036 while( !feof( p1 ) )
1037 {
1038 // get a new string
1039 fgets( tmpstr, 81, p1 );
1040 if( ( tmpstr[ 0 ] == '[' ) || ( tmpstr[ 0 ] == ';' ) ||
1041 ( tmpstr[ 0 ] == '\n' ) )
1042 {
1043 continue;
1044 }
1045
1046 // parse up to the '='
1047 i = 0;
1048 while( ( tmpstr[ i ] != '=' ) && ( tmpstr[ i ] != '\n' ) )
1049 {
1050 i++;
1051 }
1052
1053 if( tmpstr[ i ] != '=' )
1054 {
1055 continue;
1056 }
1057
1058 tmpstr[ i ] = '\0';
1059
1060 // see if it's the one we want
1061 if ( strcmp( tmpstr, str ) )
1062 {
1063 continue;
1064 }
1065
1066 // copy the right hand value to the destination string
1067 i++;
1068 for( j = 0; j < 32; j++ )
1069 {
1070 if ( ( tmpstr[ i ] == ' ' ) || ( tmpstr[ i ] == '\t' ) ||
1071 ( tmpstr[ i ] == ',' ) || ( tmpstr[ i ] == '\n' ) )
1072 {
1073 break;
1074 }
1075
1076 val[ j ] = tmpstr[ i ];
1077 i++;
1078 }
1079 val[j] = '\0';
1080
1081 return( TRUE );
1082 }
1083
1084 return( FALSE );
1085 }
1086
1087
1088/*---------------------------------------------------------------------
1089 Function: SOUNDSCAPE_FindCard
1090
1091 Determines if a SoundScape is present and where it is located.
1092---------------------------------------------------------------------*/
1093
1094static int SOUNDSCAPE_FindCard
1095 (
1096 void
1097 )
1098
1099 {
1100 int found;
1101 int status;
1102 int tmp;
1103 char *cp;
1104 char str[ 33 ];
1105 FILE *fp;
1106
1107 if ( SOUNDSCAPE_FoundCard )
1108 {
1109 return( SOUNDSCAPE_Ok );
1110 }
1111
1112 cp = getenv( "SNDSCAPE" );
1113 if ( cp == NULL )
1114 {
1115 strcpy( str, "C:\\SNDSCAPE" );
1116 }
1117 else
1118 {
1119 strcpy( str, cp );
1120 }
1121
1122 strcat(str, "\\SNDSCAPE.INI");
1123
1124 fp = fopen( str, "r" );
1125 if ( fp == NULL )
1126 {
1127 if ( cp == NULL )
1128 {
1129 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_EnvNotFound );
1130 return( SOUNDSCAPE_Error );
1131 }
1132
1133 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_InitFileNotFound );
1134 return( SOUNDSCAPE_Error );
1135 }
1136
1137 found = parse( str, "Product", fp );
1138 if ( !found )
1139 {
1140 fclose( fp );
1141 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingProductInfo );
1142 return( SOUNDSCAPE_Error );
1143 }
1144
1145 if( strstr( str, "SoundFX" ) == NULL )
1146 {
1147 SOUNDSCAPE_Config.OldIRQs = FALSE;
1148 }
1149 else
1150 {
1151 SOUNDSCAPE_Config.OldIRQs = TRUE;
1152 }
1153
1154 found = parse( str, "Port", fp );
1155 if ( !found )
1156 {
1157 fclose( fp );
1158 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingPortInfo );
1159 return( SOUNDSCAPE_Error );
1160 }
1161
1162 SOUNDSCAPE_Config.BasePort = strtol( str, ( char ** )0, 16);
1163
1164 found = parse( str, "DMA", fp );
1165 if ( !found )
1166 {
1167 fclose( fp );
1168 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingDMAInfo );
1169 return( SOUNDSCAPE_Error );
1170 }
1171
1172 SOUNDSCAPE_Config.DMAChan = ( int )strtol( str, ( char ** )0, 10 );
1173 status = DMA_VerifyChannel( SOUNDSCAPE_Config.DMAChan );
1174 if ( status == DMA_Error )
1175 {
1176 fclose( fp );
1177 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_DmaError );
1178 return( SOUNDSCAPE_Error );
1179 }
1180
1181 found = parse( str, "IRQ", fp );
1182 if ( !found )
1183 {
1184 fclose( fp );
1185 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingIRQInfo );
1186 return( SOUNDSCAPE_Error );
1187 }
1188
1189 SOUNDSCAPE_Config.MIDIIRQ = ( int )strtol( str, ( char ** )0, 10 );
1190 if ( SOUNDSCAPE_Config.MIDIIRQ == 2 )
1191 {
1192 SOUNDSCAPE_Config.MIDIIRQ = 9;
1193 }
1194
1195 found = parse( str, "SBIRQ", fp );
1196 if ( !found )
1197 {
1198 fclose( fp );
1199 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingSBIRQInfo );
1200 return( SOUNDSCAPE_Error );
1201 }
1202
1203 SOUNDSCAPE_Config.WaveIRQ = ( int )strtol( str, ( char ** )0, 10 );
1204 if ( SOUNDSCAPE_Config.WaveIRQ == 2 )
1205 {
1206 SOUNDSCAPE_Config.WaveIRQ = 9;
1207 }
1208
1209 if ( !VALID_IRQ( SOUNDSCAPE_Config.WaveIRQ ) )
1210 {
1211 fclose( fp );
1212 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_InvalidSBIrq );
1213 return( SOUNDSCAPE_Error );
1214 }
1215
1216 if ( SOUNDSCAPE_Interrupts[ SOUNDSCAPE_Config.WaveIRQ ] == INVALID )
1217 {
1218 fclose( fp );
1219 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_InvalidSBIrq );
1220 return( SOUNDSCAPE_Error );
1221 }
1222
1223 found = parse( str, "SBEnable", fp );
1224 if ( !found )
1225 {
1226 fclose( fp );
1227 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingSBENABLEInfo );
1228 return( SOUNDSCAPE_Error );
1229 }
1230
1231 if( !strcmp( str, "false" ) )
1232 {
1233 SOUNDSCAPE_Config.SBEmul = FALSE;
1234 }
1235 else
1236 {
1237 SOUNDSCAPE_Config.SBEmul = TRUE;
1238 }
1239
1240 // do a hardware test
1241 outp( SOUNDSCAPE_Config.BasePort + GA_REGADDR, 0x00f5 );
1242 tmp = inp( SOUNDSCAPE_Config.BasePort + GA_REGADDR );
1243 if ( ( tmp & 0x000f ) != 0x0005 )
1244 {
1245 fclose( fp );
1246 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_HardwareError );
1247 return( SOUNDSCAPE_Error );
1248 }
1249
1250 if( ( tmp & 0x00f0 ) == 0x00f0 )
1251 {
1252 fclose( fp );
1253 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_HardwareError );
1254 return( SOUNDSCAPE_Error );
1255 }
1256
1257 // formulate the chip ID
1258 tmp >>= 4;
1259 if( tmp == 0 )
1260 {
1261 SOUNDSCAPE_Config.ChipID = ODIE;
1262 }
1263 else if ( !( tmp & 0x0008 ) )
1264 {
1265 SOUNDSCAPE_Config.ChipID = OPUS;
1266 }
1267 else
1268 {
1269 SOUNDSCAPE_Config.ChipID = MMIC;
1270 }
1271
1272 // parse for the AD-1848 address if necessary
1273 if( SOUNDSCAPE_Config.ChipID == ODIE )
1274 {
1275 found = parse( str, "WavePort", fp );
1276 if ( !found )
1277 {
1278 fclose( fp );
1279 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_MissingWavePortInfo );
1280 return( SOUNDSCAPE_Error );
1281 }
1282
1283 SOUNDSCAPE_Config.WavePort = strtol( str, ( char ** )0, 16 );
1284 }
1285 else
1286 {
1287 // otherwise, the base address is fixed
1288 SOUNDSCAPE_Config.WavePort = SOUNDSCAPE_Config.BasePort + AD_OFFSET;
1289 }
1290
1291 // we're done with the file
1292 fclose( fp );
1293
1294 // if it's an ODIE board, note CD-ROM decode enable
1295 if ( SOUNDSCAPE_Config.ChipID == ODIE )
1296 {
1297 SOUNDSCAPE_Config.CDROM = ga_read( GA_CDCFG ) & 0x80;
1298 }
1299
1300 // build the Wave IRQ index value
1301 if( !SOUNDSCAPE_Config.OldIRQs )
1302 {
1303 switch( SOUNDSCAPE_Config.WaveIRQ )
1304 {
1305 case 9 :
1306 SOUNDSCAPE_Config.IRQIndx = 0;
1307 break;
1308
1309 case 5 :
1310 SOUNDSCAPE_Config.IRQIndx = 1;
1311 break;
1312
1313 case 7 :
1314 SOUNDSCAPE_Config.IRQIndx = 2;
1315 break;
1316
1317 default :
1318 SOUNDSCAPE_Config.IRQIndx = 3;
1319 break;
1320 }
1321 }
1322 else
1323 {
1324 switch( SOUNDSCAPE_Config.WaveIRQ )
1325 {
1326 case 9 :
1327 SOUNDSCAPE_Config.IRQIndx = 0;
1328 break;
1329
1330 case 5 :
1331 SOUNDSCAPE_Config.IRQIndx = 2;
1332 break;
1333
1334 case 7 :
1335 SOUNDSCAPE_Config.IRQIndx = 1;
1336 break;
1337
1338 default :
1339 SOUNDSCAPE_Config.IRQIndx = 3;
1340 break;
1341 }
1342 }
1343
1344 SOUNDSCAPE_FoundCard = TRUE;
1345 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_Ok );
1346 return( SOUNDSCAPE_Ok );
1347 }
1348
1349
1350/*---------------------------------------------------------------------
1351 Function: SOUNDSCAPE_Setup
1352
1353 Setup the Soundscape card for native mode PCM.
1354---------------------------------------------------------------------*/
1355
1356static int SOUNDSCAPE_Setup
1357 (
1358 void
1359 )
1360
1361 {
1362 int tmp;
1363 int Interrupt;
1364 int status;
1365
1366 // if necessary, clear any pending SB ints
1367 if ( SOUNDSCAPE_Config.SBEmul )
1368 {
1369 inp( SB_IACK );
1370 }
1371
1372 SOUNDSCAPE_DisableInterrupt();
1373
1374 // make sure the AD-1848 is not running
1375 if ( ad_read( AD_CONFIG ) & 0x01 )
1376 {
1377 SOUNDSCAPE_StopPlayback();
1378 }
1379
1380 // if necessary, do some signal re-routing
1381 if( SOUNDSCAPE_Config.ChipID != MMIC )
1382 {
1383 // get the gate-array off of the DMA channel
1384 ga_write( GA_DMACHB, 0x20 );
1385
1386 if ( !SOUNDSCAPE_Config.OldIRQs )
1387 {
1388 switch( SOUNDSCAPE_Config.MIDIIRQ )
1389 {
1390 case 5 :
1391 tmp = 1;
1392 break;
1393
1394 case 7 :
1395 tmp = 2;
1396 break;
1397
1398 case 9 :
1399 tmp = 0;
1400 break;
1401
1402 default :
1403 tmp = 3;
1404 break;
1405 }
1406 }
1407 else
1408 {
1409 switch( SOUNDSCAPE_Config.MIDIIRQ )
1410 {
1411 case 5 :
1412 tmp = 2;
1413 break;
1414
1415 case 7 :
1416 tmp = 1;
1417 break;
1418
1419 case 9 :
1420 tmp = 0;
1421 break;
1422
1423 default :
1424 tmp = 3;
1425 break;
1426 }
1427 }
1428
1429 // set HostIRQ to MIDIIRQ for now
1430 ga_write( GA_INTCFG, 0xf0 | ( tmp << 2 ) | tmp );
1431
1432 // now, route the AD-1848 stuff ...
1433 if ( SOUNDSCAPE_Config.ChipID == OPUS )
1434 {
1435 // set the AD-1848 chip decode
1436 ga_write( GA_HMCTL, ( ga_read( GA_HMCTL ) & 0xcf ) | 0x10 );
1437 }
1438 // setup the DMA polarity
1439 ga_write( GA_DMACFG, 0x50 );
1440
1441 // init the CD-ROM (AD-1848) config register
1442 ga_write( GA_CDCFG, 0x89 | ( SOUNDSCAPE_Config.DMAChan << 4 ) | ( SOUNDSCAPE_Config.IRQIndx << 1 ) );
1443
1444 // enable mode change, point to config reg
1445 outp( SOUNDSCAPE_Config.WavePort + AD_REGADDR, 0x40 | AD_CONFIG );
1446
1447 // set interf cnfg reg for DMA mode, single chan, autocal on
1448 outp( SOUNDSCAPE_Config.WavePort + AD_REGDATA, 0x0c );
1449
1450 // exit mode change state
1451 outp( SOUNDSCAPE_Config.WavePort + AD_REGADDR, 0x00 );
1452
1453 // delay for autocalibration
1454 tdelay();
1455 }
1456
1457 // Install our interrupt handler
1458 Interrupt = SOUNDSCAPE_Interrupts[ SOUNDSCAPE_Config.WaveIRQ ];
1459 SOUNDSCAPE_OldInt = _dos_getvect( Interrupt );
1460 if ( SOUNDSCAPE_Config.WaveIRQ < 8 )
1461 {
1462 _dos_setvect( Interrupt, SOUNDSCAPE_ServiceInterrupt );
1463 }
1464 else
1465 {
1466 status = IRQ_SetVector( Interrupt, SOUNDSCAPE_ServiceInterrupt );
1467 if ( status != IRQ_Ok )
1468 {
1469 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_UnableToSetIrq );
1470 return( SOUNDSCAPE_Error );
1471 }
1472 }
1473
1474 // max left and right volumes
1475 ad_write( AD_LEFTOUT, 0 );
1476 ad_write( AD_RIGHTOUT, 0 );
1477
1478 // clear any pending interrupt condition
1479 outp( SOUNDSCAPE_Config.WavePort + AD_STATUS, 0x00 );
1480
1481 // enable the interrupt pin
1482 ad_write( AD_PINCTRL, ad_read( AD_PINCTRL ) | 0x02 );
1483
1484 SOUNDSCAPE_EnableInterrupt();
1485
1486 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_Ok );
1487 return( SOUNDSCAPE_Ok );
1488 }
1489
1490
1491/*---------------------------------------------------------------------
1492 Function: SOUNDSCAPE_GetMIDIPort
1493
1494 Gets the address of the SoundScape MIDI port.
1495---------------------------------------------------------------------*/
1496
1497int SOUNDSCAPE_GetMIDIPort
1498 (
1499 void
1500 )
1501
1502 {
1503 int status;
1504
1505 status = SOUNDSCAPE_FindCard();
1506 if ( status != SOUNDSCAPE_Ok )
1507 {
1508 return( status );
1509 }
1510
1511 return( SOUNDSCAPE_Config.BasePort );
1512 }
1513
1514
1515/*---------------------------------------------------------------------
1516 Function: SOUNDSCAPE_Init
1517
1518 Initializes the sound card and prepares the module to play
1519 digitized sounds.
1520---------------------------------------------------------------------*/
1521
1522int SOUNDSCAPE_Init
1523 (
1524 void
1525 )
1526
1527 {
1528 int status;
1529
1530 if ( SOUNDSCAPE_Installed )
1531 {
1532 SOUNDSCAPE_Shutdown();
1533 }
1534
1535 // Save the interrupt masks
1536 SOUNDSCAPE_IntController1Mask = inp( 0x21 );
1537 SOUNDSCAPE_IntController2Mask = inp( 0xA1 );
1538
1539 SOUNDSCAPE_SoundPlaying = FALSE;
1540 SOUNDSCAPE_SetCallBack( NULL );
1541 SOUNDSCAPE_DMABuffer = NULL;
1542
1543 status = SOUNDSCAPE_FindCard();
1544 if ( status != SOUNDSCAPE_Ok )
1545 {
1546 return( status );
1547 }
1548
1549 status = SOUNDSCAPE_LockMemory();
1550 if ( status != SOUNDSCAPE_Ok )
1551 {
1552 SOUNDSCAPE_UnlockMemory();
1553 return( status );
1554 }
1555
1556 StackSelector = allocateTimerStack( kStackSize );
1557 if ( StackSelector == NULL )
1558 {
1559 SOUNDSCAPE_UnlockMemory();
1560 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_OutOfMemory );
1561 return( SOUNDSCAPE_Error );
1562 }
1563
1564 // Leave a little room at top of stack just for the hell of it...
1565 StackPointer = kStackSize - sizeof( long );
1566
1567 SOUNDSCAPE_Installed = TRUE;
1568
1569 status = SOUNDSCAPE_Setup();
1570 if ( status != SOUNDSCAPE_Ok )
1571 {
1572 SOUNDSCAPE_Shutdown();
1573 return( status );
1574 }
1575
1576// printf("Testing DMA and IRQ ...\n");
1577// if( test_dma_irq() )
1578// {
1579// printf("\t\007Hardware Not Responding\n\n");
1580// close_soundscape();
1581// return( SOUNDSCAPE_Error );
1582// }
1583
1584 SOUNDSCAPE_SetPlaybackRate( SOUNDSCAPE_DefaultSampleRate );
1585 SOUNDSCAPE_SetMixMode( SOUNDSCAPE_DefaultMixMode );
1586
1587 SOUNDSCAPE_SetErrorCode( SOUNDSCAPE_Ok );
1588 return( SOUNDSCAPE_Ok );
1589 }
1590
1591
1592/*---------------------------------------------------------------------
1593 Function: SOUNDSCAPE_Shutdown
1594
1595 Ends transfer of sound data to the sound card and restores the
1596 system resources used by the card.
1597---------------------------------------------------------------------*/
1598
1599void SOUNDSCAPE_Shutdown
1600 (
1601 void
1602 )
1603
1604 {
1605 int Interrupt;
1606
1607 // Halt the DMA transfer
1608 SOUNDSCAPE_StopPlayback();
1609
1610 // disable the AD-1848 interrupt pin
1611 ad_write( AD_PINCTRL, ad_read( AD_PINCTRL ) & 0xfd );
1612
1613 // if necessary, do some signal re-routing
1614 if ( SOUNDSCAPE_Config.ChipID != MMIC )
1615 {
1616 // re-init the CD-ROM (AD-1848) config register as needed.
1617 // this will disable the AD-1848 interface.
1618 if ( SOUNDSCAPE_Config.ChipID == ODIE )
1619 {
1620 ga_write( GA_CDCFG, SOUNDSCAPE_Config.CDROM );
1621 }
1622 else
1623 {
1624 ga_write( GA_CDCFG, ga_read( GA_CDCFG ) & 0x7f);
1625 }
1626
1627 // if necessary, reset the SoundBlaster IRQ
1628 if ( SOUNDSCAPE_Config.SBEmul )
1629 {
1630 ga_write( GA_INTCFG, ( ga_read( GA_INTCFG ) & 0xf3 ) |
1631 ( SOUNDSCAPE_Config.IRQIndx << 2 ) );
1632 }
1633
1634 // re-assign the gate-array DMA channel
1635 ga_write( GA_DMACHB, 0x80 | ( SOUNDSCAPE_Config.DMAChan << 4 ) );
1636 }
1637
1638 // Restore the original interrupt
1639 Interrupt = SOUNDSCAPE_Interrupts[ SOUNDSCAPE_Config.WaveIRQ ];
1640 if ( SOUNDSCAPE_Config.WaveIRQ >= 8 )
1641 {
1642 IRQ_RestoreVector( Interrupt );
1643 }
1644 _dos_setvect( Interrupt, SOUNDSCAPE_OldInt );
1645
1646 SOUNDSCAPE_SoundPlaying = FALSE;
1647
1648 SOUNDSCAPE_DMABuffer = NULL;
1649
1650 SOUNDSCAPE_SetCallBack( NULL );
1651
1652 SOUNDSCAPE_UnlockMemory();
1653
1654 if ( StackSelector != NULL )
1655 {
1656 deallocateTimerStack( StackSelector );
1657 StackSelector = NULL;
1658 }
1659
1660 SOUNDSCAPE_Installed = FALSE;
1661 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndscape.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndscape.h
new file mode 100644
index 0000000000..18cd705b3b
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndscape.h
@@ -0,0 +1,73 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: SNDSCAPE.H
22
23 author: James R. Dose
24 date: October 26, 1994
25
26 Public header for SNDSCAPE.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __SNDSCAPE_H
32#define __SNDSCAPE_H
33
34extern int SOUNDSCAPE_DMAChannel;
35extern int SOUNDSCAPE_ErrorCode;
36
37enum SOUNDSCAPE_ERRORS
38 {
39 SOUNDSCAPE_Warning = -2,
40 SOUNDSCAPE_Error = -1,
41 SOUNDSCAPE_Ok = 0,
42 SOUNDSCAPE_EnvNotFound,
43 SOUNDSCAPE_InitFileNotFound,
44 SOUNDSCAPE_MissingProductInfo,
45 SOUNDSCAPE_MissingPortInfo,
46 SOUNDSCAPE_MissingDMAInfo,
47 SOUNDSCAPE_MissingIRQInfo,
48 SOUNDSCAPE_MissingSBIRQInfo,
49 SOUNDSCAPE_MissingSBENABLEInfo,
50 SOUNDSCAPE_MissingWavePortInfo,
51 SOUNDSCAPE_HardwareError,
52 SOUNDSCAPE_NoSoundPlaying,
53 SOUNDSCAPE_InvalidSBIrq,
54 SOUNDSCAPE_UnableToSetIrq,
55 SOUNDSCAPE_DmaError,
56 SOUNDSCAPE_DPMI_Error,
57 SOUNDSCAPE_OutOfMemory
58 };
59
60char *SOUNDSCAPE_ErrorString( int ErrorNumber );
61void SOUNDSCAPE_SetPlaybackRate( unsigned rate );
62unsigned SOUNDSCAPE_GetPlaybackRate( void );
63int SOUNDSCAPE_SetMixMode( int mode );
64void SOUNDSCAPE_StopPlayback( void );
65int SOUNDSCAPE_GetCurrentPos( void );
66int SOUNDSCAPE_BeginBufferedPlayback( char *BufferStart, int BufferSize, int NumDivisions, unsigned SampleRate, int MixMode, void ( *CallBackFunc )( void ) );
67int SOUNDSCAPE_GetCardInfo( int *MaxSampleBits, int *MaxChannels );
68void SOUNDSCAPE_SetCallBack( void ( *func )( void ) );
69int SOUNDSCAPE_GetMIDIPort( void );
70int SOUNDSCAPE_Init( void );
71void SOUNDSCAPE_Shutdown( void );
72
73#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndsrc.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndsrc.c
new file mode 100644
index 0000000000..771fa6d600
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndsrc.c
@@ -0,0 +1,658 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: SNDSRC.C
22
23 author: James R. Dose
24 date: March 26, 1994
25
26 Low level routines to support the Disney Sound Source.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#define STEREO 1
32#define SIXTEEN_BIT 2
33
34#define MONO_8BIT 0
35#define STEREO_8BIT ( STEREO )
36#define MONO_16BIT ( SIXTEEN_BIT )
37#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
38
39#include <stdlib.h>
40#include <dos.h>
41#include <conio.h>
42#include "dpmi.h"
43#include "task_man.h"
44#include "sndcards.h"
45#include "user.h"
46#include "sndsrc.h"
47
48#define TRUE ( 1 == 1 )
49#define FALSE ( !TRUE )
50
51static int SS_Installed = FALSE;
52
53static int SS_Port = SS_DefaultPort;
54static int SS_OffCommand = 0xc;
55
56static char *SS_BufferStart;
57static char *SS_BufferEnd;
58static char *SS_CurrentBuffer;
59static int SS_BufferNum = 0;
60static int SS_NumBuffers = 0;
61static int SS_TotalBufferSize = 0;
62static int SS_TransferLength = 0;
63static int SS_CurrentLength = 0;
64
65static char *SS_SoundPtr;
66volatile int SS_SoundPlaying;
67
68static task *SS_Timer;
69
70void ( *SS_CallBack )( void );
71
72int SS_ErrorCode = SS_Ok;
73
74#define SS_SetErrorCode( status ) \
75 SS_ErrorCode = ( status );
76
77/*---------------------------------------------------------------------
78 Function: SS_ErrorString
79
80 Returns a pointer to the error message associated with an error
81 number. A -1 returns a pointer the current error.
82---------------------------------------------------------------------*/
83
84char *SS_ErrorString
85 (
86 int ErrorNumber
87 )
88
89 {
90 char *ErrorString;
91
92 switch( ErrorNumber )
93 {
94 case SS_Error :
95 ErrorString = SS_ErrorString( SS_ErrorCode );
96 break;
97
98 case SS_Ok :
99 ErrorString = "Sound Source ok.";
100 break;
101
102 case SS_NotFound :
103 ErrorString = "Could not detect Sound Source.";
104 break;
105
106 case SS_NoSoundPlaying :
107 ErrorString = "No sound playing in SndSrc.";
108 break;
109
110 case SS_DPMI_Error :
111 ErrorString = "DPMI Error in SndSrc.";
112 break;
113
114 default :
115 ErrorString = "Unknown Sound Source error code.";
116 break;
117 }
118
119 return( ErrorString );
120 }
121
122
123/**********************************************************************
124
125 Memory locked functions:
126
127**********************************************************************/
128
129
130#define SS_LockStart SS_ServiceInterrupt
131
132
133/*---------------------------------------------------------------------
134 Function: SS_ServiceInterrupt
135
136 Handles interrupt generated by sound card at the end of a voice
137 transfer. Calls the user supplied callback function.
138---------------------------------------------------------------------*/
139
140static void SS_ServiceInterrupt
141 (
142 task *Task
143 )
144
145 {
146 int port = SS_Port;
147 int count;
148
149 count = 0;
150 while( ( inp( port + 1 ) & 0x40 ) == 0 )
151 {
152 outp( port, *SS_SoundPtr++ );
153 outp( port + 2, SS_OffCommand );
154 outp( port + 2, 4 );
155
156 SS_CurrentLength--;
157 if ( SS_CurrentLength == 0 )
158 {
159 // Keep track of current buffer
160 SS_CurrentBuffer += SS_TransferLength;
161 SS_BufferNum++;
162 if ( SS_BufferNum >= SS_NumBuffers )
163 {
164 SS_BufferNum = 0;
165 SS_CurrentBuffer = SS_BufferStart;
166 }
167
168 SS_CurrentLength = SS_TransferLength;
169 SS_SoundPtr = SS_CurrentBuffer;
170
171 // Call the caller's callback function
172 if ( SS_CallBack != NULL )
173 {
174 SS_CallBack();
175 }
176 }
177
178 count++;
179 // Only do at most 14 samples per tick
180 if ( count > 13 )
181 {
182 break;
183 }
184 }
185 }
186
187
188/*---------------------------------------------------------------------
189 Function: SS_StopPlayback
190
191 Ends the transfer of digitized sound to the Sound Source.
192---------------------------------------------------------------------*/
193
194void SS_StopPlayback
195 (
196 void
197 )
198
199 {
200 if ( SS_SoundPlaying )
201 {
202 TS_Terminate( SS_Timer );
203
204 outp( SS_Port, 0x80 );
205 outp( SS_Port + 2, SS_OffCommand );
206 outp( SS_Port + 2, 4 );
207
208 SS_SoundPlaying = FALSE;
209
210 SS_BufferStart = NULL;
211 }
212 }
213
214
215/*---------------------------------------------------------------------
216 Function: SS_GetCurrentPos
217
218 Returns the offset within the current sound being played.
219---------------------------------------------------------------------*/
220
221int SS_GetCurrentPos
222 (
223 void
224 )
225
226 {
227 int offset;
228
229 if ( !SS_SoundPlaying )
230 {
231 SS_SetErrorCode( SS_NoSoundPlaying );
232 return( SS_Warning );
233 }
234
235 offset = ( int )( ( ( unsigned long )SS_SoundPtr ) -
236 ( ( unsigned long )SS_CurrentBuffer ) );
237
238 return( offset );
239 }
240
241
242/*---------------------------------------------------------------------
243 Function: SS_LockEnd
244
245 Used for determining the length of the functions to lock in memory.
246---------------------------------------------------------------------*/
247
248static void SS_LockEnd
249 (
250 void
251 )
252
253 {
254 }
255
256
257/*---------------------------------------------------------------------
258 Function: SS_BeginBufferedPlayback
259
260 Begins multibuffered playback of digitized sound on the Sound Source.
261---------------------------------------------------------------------*/
262
263int SS_BeginBufferedPlayback
264 (
265 char *BufferStart,
266 int BufferSize,
267 int NumDivisions,
268 void ( *CallBackFunc )( void )
269 )
270
271 {
272 if ( SS_SoundPlaying )
273 {
274 SS_StopPlayback();
275 }
276
277 SS_SetCallBack( CallBackFunc );
278
279 SS_BufferStart = BufferStart;
280 SS_CurrentBuffer = BufferStart;
281 SS_SoundPtr = BufferStart;
282 SS_TotalBufferSize = BufferSize;
283 SS_BufferEnd = BufferStart + BufferSize;
284 SS_TransferLength = BufferSize / NumDivisions;
285 SS_CurrentLength = SS_TransferLength;
286 SS_BufferNum = 0;
287 SS_NumBuffers = NumDivisions;
288
289 SS_SoundPlaying = TRUE;
290
291// SS_Timer = TS_ScheduleTask( SS_ServiceInterrupt, 438, 1, NULL );
292 SS_Timer = TS_ScheduleTask( SS_ServiceInterrupt, 510, 1, NULL );
293 TS_Dispatch();
294
295 return( SS_Ok );
296 }
297
298
299/*---------------------------------------------------------------------
300 Function: SS_GetPlaybackRate
301
302 Returns the rate at which the digitized sound will be played in
303 hertz.
304---------------------------------------------------------------------*/
305
306int SS_GetPlaybackRate
307 (
308 void
309 )
310
311 {
312 return( SS_SampleRate );
313 }
314
315
316/*---------------------------------------------------------------------
317 Function: SS_SetMixMode
318
319 Sets the sound card to play samples in mono or stereo.
320---------------------------------------------------------------------*/
321
322int SS_SetMixMode
323 (
324 int mode
325 )
326
327 {
328 mode = MONO_8BIT;
329 return( mode );
330 }
331
332
333/*---------------------------------------------------------------------
334 Function: SS_SetPort
335
336 Selects which port to use to write to the Sound Source.
337---------------------------------------------------------------------*/
338
339int SS_SetPort
340 (
341 int port
342 )
343
344 {
345 if ( SS_Installed )
346 {
347 SS_Shutdown();
348 }
349
350 SS_Port = port;
351
352 return( SS_Ok );
353 }
354
355
356/*---------------------------------------------------------------------
357 Function: SS_SetCallBack
358
359 Specifies the user function to call at the end of a sound transfer.
360---------------------------------------------------------------------*/
361
362void SS_SetCallBack
363 (
364 void ( *func )( void )
365 )
366
367 {
368 SS_CallBack = func;
369 }
370
371
372/*---------------------------------------------------------------------
373 Function: SS_TestTimer
374
375 Used as a delay in SS_TestSoundSource.
376---------------------------------------------------------------------*/
377
378void SS_TestTimer
379 (
380 task *Task
381 )
382
383 {
384 ( *( int * )( Task->data ) )++;
385 }
386
387
388/*---------------------------------------------------------------------
389 Function: SS_TestSoundSource
390
391 Detect if the Sound Source is located at the specified port.
392---------------------------------------------------------------------*/
393
394int SS_TestSoundSource
395 (
396 int port
397 )
398
399 {
400 int present;
401 task *timer;
402 volatile int ticks;
403 int i;
404
405 present = FALSE;
406
407 timer = TS_ScheduleTask( SS_TestTimer, 140, 1, &ticks );
408 TS_Dispatch();
409
410 outp( port + 2, 4 );
411
412 ticks = 0;
413
414 while( ticks < 4 )
415 {
416 // Do nothing for a while
417 }
418
419 TS_Terminate( timer );
420
421 if ( ( inp( port + 1 ) & 0x40 ) == 0 )
422 {
423 for( i = 32; i > 0; i-- )
424 {
425 outp( port, 0x80 );
426 outp( port + 2, SS_OffCommand );
427 outp( port + 2, 4 );
428 }
429
430 if ( inp( port + 1 ) & 0x40 )
431 {
432 present = TRUE;
433 }
434 }
435
436 outp( port + 2, SS_OffCommand );
437
438 return( present );
439 }
440
441
442/*---------------------------------------------------------------------
443 Function: SS_DetectSoundSource
444
445 Detects which port the Sound Source is located.
446---------------------------------------------------------------------*/
447
448int SS_DetectSoundSource
449 (
450 void
451 )
452
453 {
454 if ( USER_CheckParameter( SELECT_SOUNDSOURCE_PORT1 ) )
455 {
456 SS_Port = SS_Port1;
457 return( TRUE );
458 }
459
460 if ( USER_CheckParameter( SELECT_SOUNDSOURCE_PORT2 ) )
461 {
462 SS_Port = SS_Port2;
463 return( TRUE );
464 }
465
466 if ( USER_CheckParameter( SELECT_SOUNDSOURCE_PORT3 ) )
467 {
468 SS_Port = SS_Port3;
469 return( TRUE );
470 }
471
472 if ( SS_TestSoundSource( SS_Port1 ) )
473 {
474 SS_Port = SS_Port1;
475 return( TRUE );
476 }
477
478 if ( SS_TestSoundSource( SS_Port2 ) )
479 {
480 SS_Port = SS_Port2;
481 return( TRUE );
482 }
483
484 if ( SS_TestSoundSource( SS_Port3 ) )
485 {
486 SS_Port = SS_Port3;
487 return( TRUE );
488 }
489
490 return( FALSE );
491 }
492
493
494/*---------------------------------------------------------------------
495 Function: SS_Init
496
497 Initializes the Sound Source prepares the module to play digitized
498 sounds.
499---------------------------------------------------------------------*/
500
501int SS_Init
502 (
503 int soundcard
504 )
505
506 {
507 int status;
508
509 if ( SS_Installed )
510 {
511 SS_Shutdown();
512 }
513
514 if ( ( soundcard == TandySoundSource ) ||
515 ( USER_CheckParameter( SELECT_TANDY_SOUNDSOURCE ) ) )
516 {
517 // Tandy
518 SS_OffCommand = 0x0e;
519 }
520 else
521 {
522 // Disney
523 SS_OffCommand = 0x0c;
524 }
525
526 status = SS_DetectSoundSource();
527 if ( !status )
528 {
529 SS_SetErrorCode( SS_NotFound );
530 return( SS_Warning );
531 }
532
533 status = SS_LockMemory();
534 if ( status != SS_Ok )
535 {
536 SS_UnlockMemory();
537 return( status );
538 }
539
540 status = SS_Ok;
541
542 outp( SS_Port + 2, 4 );
543
544 SS_SoundPlaying = FALSE;
545
546 SS_SetCallBack( NULL );
547
548 SS_BufferStart = NULL;
549
550 SS_Installed = TRUE;
551
552 SS_SetErrorCode( status );
553 return( status );
554 }
555
556
557/*---------------------------------------------------------------------
558 Function: SS_Shutdown
559
560 Ends transfer of sound data to the Sound Source.
561---------------------------------------------------------------------*/
562
563void SS_Shutdown
564 (
565 void
566 )
567
568 {
569 // Halt the transfer
570 SS_StopPlayback();
571
572 outp( SS_Port + 2, SS_OffCommand );
573
574 SS_SoundPlaying = FALSE;
575
576 SS_BufferStart = NULL;
577
578 SS_SetCallBack( NULL );
579
580 SS_UnlockMemory();
581
582 SS_Installed = FALSE;
583 }
584
585
586/*---------------------------------------------------------------------
587 Function: SS_UnlockMemory
588
589 Unlocks all neccessary data.
590---------------------------------------------------------------------*/
591
592void SS_UnlockMemory
593 (
594 void
595 )
596
597 {
598 DPMI_UnlockMemoryRegion( SS_LockStart, SS_LockEnd );
599 DPMI_Unlock( SS_Installed );
600 DPMI_Unlock( SS_Port );
601 DPMI_Unlock( SS_OffCommand );
602 DPMI_Unlock( SS_BufferStart );
603 DPMI_Unlock( SS_BufferEnd );
604 DPMI_Unlock( SS_CurrentBuffer );
605 DPMI_Unlock( SS_BufferNum );
606 DPMI_Unlock( SS_NumBuffers );
607 DPMI_Unlock( SS_TotalBufferSize );
608 DPMI_Unlock( SS_TransferLength );
609 DPMI_Unlock( SS_CurrentLength );
610 DPMI_Unlock( SS_SoundPtr );
611 DPMI_Unlock( SS_SoundPlaying );
612 DPMI_Unlock( SS_Timer );
613 DPMI_Unlock( SS_CallBack );
614 DPMI_Unlock( SS_ErrorCode );
615 }
616
617
618/*---------------------------------------------------------------------
619 Function: SS_LockMemory
620
621 Locks all neccessary data.
622---------------------------------------------------------------------*/
623
624int SS_LockMemory
625 (
626 void
627 )
628
629 {
630 int status;
631
632 status = DPMI_LockMemoryRegion( SS_LockStart, SS_LockEnd );
633 status |= DPMI_Lock( SS_Installed );
634 status |= DPMI_Lock( SS_Port );
635 status |= DPMI_Lock( SS_OffCommand );
636 status |= DPMI_Lock( SS_BufferStart );
637 status |= DPMI_Lock( SS_BufferEnd );
638 status |= DPMI_Lock( SS_CurrentBuffer );
639 status |= DPMI_Lock( SS_BufferNum );
640 status |= DPMI_Lock( SS_NumBuffers );
641 status |= DPMI_Lock( SS_TotalBufferSize );
642 status |= DPMI_Lock( SS_TransferLength );
643 status |= DPMI_Lock( SS_CurrentLength );
644 status |= DPMI_Lock( SS_SoundPtr );
645 status |= DPMI_Lock( SS_SoundPlaying );
646 status |= DPMI_Lock( SS_Timer );
647 status |= DPMI_Lock( SS_CallBack );
648 status |= DPMI_Lock( SS_ErrorCode );
649
650 if ( status != DPMI_Ok )
651 {
652 SS_UnlockMemory();
653 SS_SetErrorCode( SS_DPMI_Error );
654 return( SS_Error );
655 }
656
657 return( SS_Ok );
658 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndsrc.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndsrc.h
new file mode 100644
index 0000000000..fbb82c5ddf
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/sndsrc.h
@@ -0,0 +1,70 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: SNDSRC.H
22
23 author: James R. Dose
24 date: March 26, 1994
25
26 Public header for for SNDSRC.C
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __SNDSRC_H
32#define __SNDSRC_H
33
34enum SS_ERRORS
35 {
36 SS_Warning = -2,
37 SS_Error = -1,
38 SS_Ok = 0,
39 SS_NotFound,
40 SS_NoSoundPlaying,
41 SS_DPMI_Error
42 };
43
44#define SELECT_SOUNDSOURCE_PORT1 "ss1"
45#define SELECT_SOUNDSOURCE_PORT2 "ss2"
46#define SELECT_SOUNDSOURCE_PORT3 "ss3"
47#define SELECT_TANDY_SOUNDSOURCE "sst"
48
49#define SS_Port1 0x3bc
50#define SS_Port2 0x378
51#define SS_Port3 0x278
52
53#define SS_DefaultPort 0x378
54#define SS_SampleRate 7000
55#define SS_DMAChannel -1
56
57char *SS_ErrorString( int ErrorNumber );
58void SS_StopPlayback( void );
59int SS_GetCurrentPos( void );
60int SS_BeginBufferedPlayback( char *BufferStart, int BufferSize, int NumDivisions, void ( *CallBackFunc )( void ) );
61int SS_GetPlaybackRate( void );
62int SS_SetMixMode( int mode );
63int SS_SetPort( int port );
64void SS_SetCallBack( void ( *func )( void ) );
65int SS_Init( int soundcard );
66void SS_Shutdown( void );
67void SS_UnlockMemory( void );
68int SS_LockMemory( void );
69
70#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/standard.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/standard.h
new file mode 100644
index 0000000000..e9344e336c
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/standard.h
@@ -0,0 +1,72 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: STANDARD.H
22
23 author: James R. Dose
24 date: May 25, 1994
25
26 Header containing standard definitions.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __STANDARD_H
32#define __STANDARD_H
33
34typedef int boolean;
35typedef int errorcode;
36
37#ifndef TRUE
38 #define TRUE ( 1 == 1 )
39 #define FALSE ( !TRUE )
40#endif
41
42enum STANDARD_ERRORS
43 {
44 Warning = -2,
45 FatalError = -1,
46 Success = 0
47 };
48
49#define BITSET( data, bit ) \
50 ( ( ( data ) & ( bit ) ) == ( bit ) )
51
52#define ARRAY_LENGTH( array ) \
53 ( sizeof( array ) / sizeof( ( array )[ 0 ] ) )
54
55#define WITHIN_BOUNDS( array, index ) \
56 ( ( 0 <= ( index ) ) && ( ( index ) < ARRAY_LENGTH( array ) ) )
57
58#define FOREVER for( ; ; )
59
60#ifdef NDEBUG
61 #define DEBUGGING 0
62#else
63 #define DEBUGGING 1
64#endif
65
66#define DEBUG_CODE \
67 if ( DEBUGGING == 0 ) \
68 { \
69 } \
70 else
71
72#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/task_man.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/task_man.c
new file mode 100644
index 0000000000..c39135fedb
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/task_man.c
@@ -0,0 +1,976 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: TASK_MAN.C
22
23 author: James R. Dose
24 date: July 25, 1994
25
26 Low level timer task scheduler.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#define TRUE ( 1 == 1 )
32#define FALSE ( !TRUE )
33
34//#define USESTACK
35#define LOCKMEMORY
36#define NOINTS
37#define USE_USRHOOKS
38
39#include <stdlib.h>
40#include <dos.h>
41#include <conio.h>
42#include <string.h>
43#include "interrup.h"
44#include "linklist.h"
45#include "task_man.h"
46
47#ifdef USESTACK
48#include "dpmi.h"
49#endif
50#ifdef LOCKMEMORY
51#include "dpmi.h"
52#endif
53
54#ifdef USE_USRHOOKS
55#include "usrhooks.h"
56#define FreeMem( ptr ) USRHOOKS_FreeMem( ( ptr ) )
57#else
58#define FreeMem( ptr ) free( ( ptr ) )
59#endif
60
61typedef struct
62 {
63 task *start;
64 task *end;
65 } tasklist;
66
67
68/*---------------------------------------------------------------------
69 Global variables
70---------------------------------------------------------------------*/
71
72#ifdef USESTACK
73
74// adequate stack size
75#define kStackSize 2048
76
77static unsigned short StackSelector = NULL;
78static unsigned long StackPointer;
79
80static unsigned short oldStackSelector;
81static unsigned long oldStackPointer;
82
83#endif
84
85static task HeadTask;
86static task *TaskList = &HeadTask;
87
88static void ( __interrupt __far *OldInt8 )( void );
89
90static volatile long TaskServiceRate = 0x10000L;
91static volatile long TaskServiceCount = 0;
92
93#ifndef NOINTS
94static volatile int TS_TimesInInterrupt;
95#endif
96
97static char TS_Installed = FALSE;
98
99volatile int TS_InInterrupt = FALSE;
100
101/*---------------------------------------------------------------------
102 Function prototypes
103---------------------------------------------------------------------*/
104
105static void TS_FreeTaskList( void );
106static void TS_SetClockSpeed( long speed );
107static long TS_SetTimer( long TickBase );
108static void TS_SetTimerToMaxTaskRate( void );
109static void __interrupt __far TS_ServiceSchedule( void );
110static void __interrupt __far TS_ServiceScheduleIntEnabled( void );
111static void TS_AddTask( task *ptr );
112static int TS_Startup( void );
113static void RestoreRealTimeClock( void );
114
115// These declarations are necessary to use the inline assembly pragmas.
116
117extern void GetStack(unsigned short *selptr,unsigned long *stackptr);
118extern void SetStack(unsigned short selector,unsigned long stackptr);
119
120// This function will get the current stack selector and pointer and save
121// them off.
122#pragma aux GetStack = \
123 "mov [edi],esp" \
124 "mov ax,ss" \
125 "mov [esi],ax" \
126 parm [esi] [edi] \
127 modify [eax esi edi];
128
129// This function will set the stack selector and pointer to the specified
130// values.
131#pragma aux SetStack = \
132 "mov ss,ax" \
133 "mov esp,edx" \
134 parm [ax] [edx] \
135 modify [eax edx];
136
137
138/**********************************************************************
139
140 Memory locked functions:
141
142**********************************************************************/
143
144
145#define TS_LockStart TS_FreeTaskList
146
147
148/*---------------------------------------------------------------------
149 Function: TS_FreeTaskList
150
151 Terminates all tasks and releases any memory used for control
152 structures.
153---------------------------------------------------------------------*/
154
155static void TS_FreeTaskList
156 (
157 void
158 )
159
160 {
161 task *node;
162 task *next;
163 unsigned flags;
164
165 flags = DisableInterrupts();
166
167 node = TaskList->next;
168 while( node != TaskList )
169 {
170 next = node->next;
171 FreeMem( node );
172 node = next;
173 }
174
175 TaskList->next = TaskList;
176 TaskList->prev = TaskList;
177
178 RestoreInterrupts( flags );
179 }
180
181
182/*---------------------------------------------------------------------
183 Function: TS_SetClockSpeed
184
185 Sets the rate of the 8253 timer.
186---------------------------------------------------------------------*/
187
188static void TS_SetClockSpeed
189 (
190 long speed
191 )
192
193 {
194 unsigned flags;
195
196 flags = DisableInterrupts();
197
198 if ( ( speed > 0 ) && ( speed < 0x10000L ) )
199 {
200 TaskServiceRate = speed;
201 }
202 else
203 {
204 TaskServiceRate = 0x10000L;
205 }
206
207 outp( 0x43, 0x36 );
208 outp( 0x40, TaskServiceRate );
209 outp( 0x40, TaskServiceRate >> 8 );
210
211 RestoreInterrupts( flags );
212 }
213
214
215/*---------------------------------------------------------------------
216 Function: TS_SetTimer
217
218 Calculates the rate at which a task will occur and sets the clock
219 speed if necessary.
220---------------------------------------------------------------------*/
221
222static long TS_SetTimer
223 (
224 long TickBase
225 )
226
227 {
228 long speed;
229
230 speed = 1192030L / TickBase;
231 if ( speed < TaskServiceRate )
232 {
233 TS_SetClockSpeed( speed );
234 }
235
236 return( speed );
237 }
238
239
240/*---------------------------------------------------------------------
241 Function: TS_SetTimerToMaxTaskRate
242
243 Finds the fastest running task and sets the clock to operate at
244 that speed.
245---------------------------------------------------------------------*/
246
247static void TS_SetTimerToMaxTaskRate
248 (
249 void
250 )
251
252 {
253 task *ptr;
254 long MaxServiceRate;
255 unsigned flags;
256
257 flags = DisableInterrupts();
258
259 MaxServiceRate = 0x10000L;
260
261 ptr = TaskList->next;
262 while( ptr != TaskList )
263 {
264 if ( ptr->rate < MaxServiceRate )
265 {
266 MaxServiceRate = ptr->rate;
267 }
268
269 ptr = ptr->next;
270 }
271
272 if ( TaskServiceRate != MaxServiceRate )
273 {
274 TS_SetClockSpeed( MaxServiceRate );
275 }
276
277 RestoreInterrupts( flags );
278 }
279
280
281#ifdef NOINTS
282/*---------------------------------------------------------------------
283 Function: TS_ServiceSchedule
284
285 Interrupt service routine
286---------------------------------------------------------------------*/
287
288static void __interrupt __far TS_ServiceSchedule
289 (
290 void
291 )
292
293 {
294 task *ptr;
295 task *next;
296
297
298 TS_InInterrupt = TRUE;
299
300 #ifdef USESTACK
301 // save stack
302 GetStack( &oldStackSelector, &oldStackPointer );
303
304 // set our stack
305 SetStack( StackSelector, StackPointer );
306 #endif
307
308 ptr = TaskList->next;
309 while( ptr != TaskList )
310 {
311 next = ptr->next;
312
313 if ( ptr->active )
314 {
315 ptr->count += TaskServiceRate;
316//JIM
317// if ( ptr->count >= ptr->rate )
318 while( ptr->count >= ptr->rate )
319 {
320 ptr->count -= ptr->rate;
321 ptr->TaskService( ptr );
322 }
323 }
324 ptr = next;
325 }
326
327 #ifdef USESTACK
328 // restore stack
329 SetStack( oldStackSelector, oldStackPointer );
330 #endif
331
332 TaskServiceCount += TaskServiceRate;
333 if ( TaskServiceCount > 0xffffL )
334 {
335 TaskServiceCount &= 0xffff;
336 _chain_intr( OldInt8 );
337 }
338
339 outp( 0x20,0x20 );
340
341 TS_InInterrupt = FALSE;
342 }
343
344#else
345
346/*---------------------------------------------------------------------
347 Function: TS_ServiceScheduleIntEnabled
348
349 Interrupt service routine with interrupts enabled.
350---------------------------------------------------------------------*/
351
352static void __interrupt __far TS_ServiceScheduleIntEnabled
353 (
354 void
355 )
356
357 {
358 task *ptr;
359 task *next;
360
361 TS_TimesInInterrupt++;
362 TaskServiceCount += TaskServiceRate;
363 if ( TaskServiceCount > 0xffffL )
364 {
365 TaskServiceCount &= 0xffff;
366 _chain_intr( OldInt8 );
367 }
368
369 outp( 0x20,0x20 );
370
371 if ( TS_InInterrupt )
372 {
373 return;
374 }
375
376 TS_InInterrupt = TRUE;
377 _enable();
378
379 #ifdef USESTACK
380 // save stack
381 GetStack( &oldStackSelector, &oldStackPointer );
382
383 // set our stack
384 SetStack( StackSelector, StackPointer );
385 #endif
386
387 while( TS_TimesInInterrupt )
388 {
389 ptr = TaskList->next ;
390 while( ptr != TaskList )
391 {
392 next = ptr->next;
393
394 if ( ptr->active )
395 {
396 ptr->count += TaskServiceRate;
397 if ( ptr->count >= ptr->rate )
398 {
399 ptr->count -= ptr->rate;
400 ptr->TaskService( ptr );
401 }
402 }
403 ptr = next;
404 }
405 TS_TimesInInterrupt--;
406 }
407
408 _disable();
409
410 #ifdef USESTACK
411 // restore stack
412 SetStack( oldStackSelector, oldStackPointer );
413 #endif
414
415 TS_InInterrupt = FALSE;
416 }
417#endif
418
419
420#ifdef USESTACK
421
422/*---------------------------------------------------------------------
423 Function: allocateTimerStack
424
425 Allocate a block of memory from conventional (low) memory and return
426 the selector (which can go directly into a segment register) of the
427 memory block or 0 if an error occured.
428---------------------------------------------------------------------*/
429
430static unsigned short allocateTimerStack
431 (
432 unsigned short size
433 )
434
435 {
436 union REGS regs;
437
438 // clear all registers
439 memset( &regs, 0, sizeof( regs ) );
440
441 // DPMI allocate conventional memory
442 regs.w.ax = 0x100;
443
444 // size in paragraphs
445 regs.w.bx = ( size + 15 ) / 16;
446
447 int386( 0x31, &regs, &regs );
448 if (!regs.w.cflag)
449 {
450 // DPMI call returns selector in dx
451 // (ax contains real mode segment
452 // which is ignored here)
453
454 return( regs.w.dx );
455 }
456
457 // Couldn't allocate memory.
458 return( NULL );
459 }
460
461
462/*---------------------------------------------------------------------
463 Function: deallocateTimerStack
464
465 Deallocate a block of conventional (low) memory given a selector to
466 it. Assumes the block was allocated with DPMI function 0x100.
467---------------------------------------------------------------------*/
468
469static void deallocateTimerStack
470 (
471 unsigned short selector
472 )
473
474 {
475 union REGS regs;
476
477 if ( selector != NULL )
478 {
479 // clear all registers
480 memset( &regs, 0, sizeof( regs ) );
481
482 regs.w.ax = 0x101;
483 regs.w.dx = selector;
484 int386( 0x31, &regs, &regs );
485 }
486 }
487
488#endif
489
490/*---------------------------------------------------------------------
491 Function: TS_Startup
492
493 Sets up the task service routine.
494---------------------------------------------------------------------*/
495
496static int TS_Startup
497 (
498 void
499 )
500
501 {
502 if ( !TS_Installed )
503 {
504#ifdef LOCKMEMORY
505
506 int status;
507
508 status = TS_LockMemory();
509 if ( status != TASK_Ok )
510 {
511 TS_UnlockMemory();
512 return( status );
513 }
514
515#endif
516
517#ifdef USESTACK
518
519 StackSelector = allocateTimerStack( kStackSize );
520 if ( StackSelector == NULL )
521 {
522
523#ifdef LOCKMEMORY
524
525 TS_UnlockMemory();
526
527#endif
528 return( TASK_Error );
529 }
530
531 // Leave a little room at top of stack just for the hell of it...
532 StackPointer = kStackSize - sizeof( long );
533
534#endif
535
536//static const task *TaskList = &HeadTask;
537 TaskList->next = TaskList;
538 TaskList->prev = TaskList;
539
540 TaskServiceRate = 0x10000L;
541 TaskServiceCount = 0;
542
543#ifndef NOINTS
544 TS_TimesInInterrupt = 0;
545#endif
546
547 OldInt8 = _dos_getvect( 0x08 );
548 #ifdef NOINTS
549 _dos_setvect( 0x08, TS_ServiceSchedule );
550 #else
551 _dos_setvect( 0x08, TS_ServiceScheduleIntEnabled );
552 #endif
553
554 TS_Installed = TRUE;
555 }
556
557 return( TASK_Ok );
558 }
559
560
561/*---------------------------------------------------------------------
562 Function: TS_Shutdown
563
564 Ends processing of all tasks.
565---------------------------------------------------------------------*/
566
567void TS_Shutdown
568 (
569 void
570 )
571
572 {
573 if ( TS_Installed )
574 {
575 TS_FreeTaskList();
576
577 TS_SetClockSpeed( 0 );
578
579 _dos_setvect( 0x08, OldInt8 );
580
581#ifdef USESTACK
582
583 deallocateTimerStack( StackSelector );
584 StackSelector = NULL;
585
586#endif
587
588 // Set Date and Time from CMOS
589// RestoreRealTimeClock();
590
591#ifdef LOCKMEMORY
592
593 TS_UnlockMemory();
594
595#endif
596 TS_Installed = FALSE;
597 }
598 }
599
600
601/*---------------------------------------------------------------------
602 Function: TS_ScheduleTask
603
604 Schedules a new task for processing.
605---------------------------------------------------------------------*/
606
607task *TS_ScheduleTask
608 (
609 void ( *Function )( task * ),
610 int rate,
611 int priority,
612 void *data
613 )
614
615 {
616 task *ptr;
617
618#ifdef USE_USRHOOKS
619 int status;
620
621 ptr = NULL;
622
623 status = USRHOOKS_GetMem( &ptr, sizeof( task ) );
624 if ( status == USRHOOKS_Ok )
625#else
626 ptr = malloc( sizeof( task ) );
627 if ( ptr != NULL )
628#endif
629 {
630 if ( !TS_Installed )
631 {
632 status = TS_Startup();
633 if ( status != TASK_Ok )
634 {
635 FreeMem( ptr );
636 return( NULL );
637 }
638 }
639
640 ptr->TaskService = Function;
641 ptr->data = data;
642 ptr->rate = TS_SetTimer( rate );
643 ptr->count = 0;
644 ptr->priority = priority;
645 ptr->active = FALSE;
646
647 TS_AddTask( ptr );
648 }
649
650 return( ptr );
651 }
652
653
654/*---------------------------------------------------------------------
655 Function: TS_AddTask
656
657 Adds a new task to our list of tasks.
658---------------------------------------------------------------------*/
659
660static void TS_AddTask
661 (
662 task *node
663 )
664
665 {
666 LL_SortedInsertion( TaskList, node, next, prev, task, priority );
667 }
668
669
670/*---------------------------------------------------------------------
671 Function: TS_Terminate
672
673 Ends processing of a specific task.
674---------------------------------------------------------------------*/
675
676int TS_Terminate
677 (
678 task *NodeToRemove
679 )
680
681 {
682 task *ptr;
683 task *next;
684 unsigned flags;
685
686 flags = DisableInterrupts();
687
688 ptr = TaskList->next;
689 while( ptr != TaskList )
690 {
691 next = ptr->next;
692
693 if ( ptr == NodeToRemove )
694 {
695 LL_RemoveNode( NodeToRemove, next, prev );
696 NodeToRemove->next = NULL;
697 NodeToRemove->prev = NULL;
698 FreeMem( NodeToRemove );
699
700 TS_SetTimerToMaxTaskRate();
701
702 RestoreInterrupts( flags );
703
704 return( TASK_Ok );
705 }
706
707 ptr = next;
708 }
709
710 RestoreInterrupts( flags );
711
712 return( TASK_Warning );
713 }
714
715
716/*---------------------------------------------------------------------
717 Function: TS_Dispatch
718
719 Begins processing of all inactive tasks.
720---------------------------------------------------------------------*/
721
722void TS_Dispatch
723 (
724 void
725 )
726
727 {
728 task *ptr;
729 unsigned flags;
730
731 flags = DisableInterrupts();
732
733 ptr = TaskList->next;
734 while( ptr != TaskList )
735 {
736 ptr->active = TRUE;
737 ptr = ptr->next;
738 }
739
740 RestoreInterrupts( flags );
741 }
742
743
744/*---------------------------------------------------------------------
745 Function: TS_SetTaskRate
746
747 Sets the rate at which the specified task is serviced.
748---------------------------------------------------------------------*/
749
750void TS_SetTaskRate
751 (
752 task *Task,
753 int rate
754 )
755
756 {
757 unsigned flags;
758
759 flags = DisableInterrupts();
760
761 Task->rate = TS_SetTimer( rate );
762 TS_SetTimerToMaxTaskRate();
763
764 RestoreInterrupts( flags );
765 }
766
767
768#ifdef LOCKMEMORY
769
770/*---------------------------------------------------------------------
771 Function: TS_LockEnd
772
773 Used for determining the length of the functions to lock in memory.
774---------------------------------------------------------------------*/
775
776static void TS_LockEnd
777 (
778 void
779 )
780
781 {
782 }
783
784
785/*---------------------------------------------------------------------
786 Function: TS_UnlockMemory
787
788 Unlocks all neccessary data.
789---------------------------------------------------------------------*/
790
791void TS_UnlockMemory
792 (
793 void
794 )
795
796 {
797 DPMI_UnlockMemoryRegion( TS_LockStart, TS_LockEnd );
798 DPMI_Unlock( TaskList );
799 DPMI_Unlock( OldInt8 );
800 DPMI_Unlock( TaskServiceRate );
801 DPMI_Unlock( TaskServiceCount );
802 DPMI_Unlock( TS_Installed );
803
804#ifndef NOINTS
805 DPMI_Unlock( TS_TimesInInterrupt );
806#endif
807
808#ifdef USESTACK
809 DPMI_Unlock( StackSelector );
810 DPMI_Unlock( StackPointer );
811 DPMI_Unlock( oldStackSelector );
812 DPMI_Unlock( oldStackPointer );
813#endif
814 }
815
816
817/*---------------------------------------------------------------------
818 Function: TS_LockMemory
819
820 Locks all neccessary data.
821---------------------------------------------------------------------*/
822
823int TS_LockMemory
824 (
825 void
826 )
827
828 {
829 int status;
830
831 status = DPMI_LockMemoryRegion( TS_LockStart, TS_LockEnd );
832 status |= DPMI_Lock( TaskList );
833 status |= DPMI_Lock( OldInt8 );
834 status |= DPMI_Lock( TaskServiceRate );
835 status |= DPMI_Lock( TaskServiceCount );
836 status |= DPMI_Lock( TS_Installed );
837
838#ifndef NOINTS
839 status |= DPMI_Lock( TS_TimesInInterrupt );
840#endif
841
842#ifdef USESTACK
843 status |= DPMI_Lock( StackSelector );
844 status |= DPMI_Lock( StackPointer );
845 status |= DPMI_Lock( oldStackSelector );
846 status |= DPMI_Lock( oldStackPointer );
847#endif
848
849 if ( status != DPMI_Ok )
850 {
851 TS_UnlockMemory();
852 return( TASK_Error );
853 }
854
855 return( TASK_Ok );
856 }
857
858#endif
859
860/*
861// Converts a hex byte to an integer
862
863static int btoi
864 (
865 unsigned char bcd
866 )
867
868 {
869 unsigned b;
870 unsigned c;
871 unsigned d;
872
873 b = bcd / 16;
874 c = bcd - b * 16;
875 d = b * 10 + c;
876 return( d );
877 }
878
879
880static void RestoreRealTimeClock
881 (
882 void
883 )
884
885 {
886 int read;
887 int i;
888 int hr;
889 int min;
890 int sec;
891 int cent;
892 int yr;
893 int mo;
894 int day;
895 int year;
896 union REGS inregs;
897
898 // Read Real Time Clock Time.
899 read = FALSE;
900 inregs.h.ah = 0x02;
901 for( i = 1; i <= 3; i++ )
902 {
903 int386( 0x1A, &inregs, &inregs );
904 if ( inregs.x.cflag == 0 )
905 {
906 read = TRUE;
907 }
908 }
909
910 if ( read )
911 {
912 //and convert BCD to integer format
913 hr = btoi( inregs.h.ch );
914 min = btoi( inregs.h.cl );
915 sec = btoi( inregs.h.dh );
916
917 // Read Real Time Clock Date.
918 inregs.h.ah = 0x04;
919 int386( 0x1A, &inregs, &inregs );
920 if ( inregs.x.cflag == 0 )
921 {
922 //and convert BCD to integer format
923 cent = btoi( inregs.h.ch );
924 yr = btoi( inregs.h.cl );
925 mo = btoi( inregs.h.dh );
926 day = btoi( inregs.h.dl );
927 year = cent * 100 + yr;
928
929 // Set System Time.
930 inregs.h.ch = hr;
931 inregs.h.cl = min;
932 inregs.h.dh = sec;
933 inregs.h.dl = 0;
934 inregs.h.ah = 0x2D;
935 int386( 0x21, &inregs, &inregs );
936
937 // Set System Date.
938 inregs.w.cx = year;
939 inregs.h.dh = mo;
940 inregs.h.dl = day;
941 inregs.h.ah = 0x2B;
942 int386( 0x21, &inregs, &inregs );
943 }
944 }
945 }
946*/
947/*
948 struct dostime_t time;
949 struct dosdate_t date;
950
951 outp(0x70,0);
952 time.second=inp(0x71);
953 outp(0x70,2);
954 time.minute=inp(0x71);
955 outp(0x70,4);
956 time.hour=inp(0x71);
957
958 outp(0x70,7);
959 date.day=inp(0x71);
960 outp(0x70,8);
961 date.month=inp(0x71);
962 outp(0x70,9);
963 date.year=inp(0x71);
964
965 time.second=(time.second&0x0f)+((time.second>>4)*10);
966 time.minute=(time.minute&0x0f)+((time.minute>>4)*10);
967 time.hour=(time.hour&0x0f)+((time.hour>>4)*10);
968
969 date.day=(date.day&0x0f)+((date.day>>4)*10);
970 date.month=(date.month&0x0f)+((date.month>>4)*10);
971 date.year=(date.year&0x0f)+((date.year>>4)*10);
972
973 _dos_settime(&time);
974 _dos_setdate(&date);
975
976*/
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/task_man.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/task_man.h
new file mode 100644
index 0000000000..7e2460631c
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/task_man.h
@@ -0,0 +1,68 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: TASK_MAN.C
22
23 author: James R. Dose
24 date: July 25, 1994
25
26 Public header for TASK_MAN.C, a low level timer task scheduler.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#ifndef __TASK_MAN_H
32#define __TASK_MAN_H
33
34enum TASK_ERRORS
35 {
36 TASK_Warning = -2,
37 TASK_Error = -1,
38 TASK_Ok = 0
39 };
40
41typedef struct task
42{
43 struct task *next;
44 struct task *prev;
45 void ( *TaskService )( struct task * );
46 void *data;
47 long rate;
48 volatile long count;
49 int priority;
50 int active;
51} task;
52
53// TS_InInterrupt is TRUE during a taskman interrupt.
54// Use this if you have code that may be used both outside
55// and within interrupts.
56
57extern volatile int TS_InInterrupt;
58
59void TS_Shutdown( void );
60task *TS_ScheduleTask( void ( *Function )( task * ), int rate,
61 int priority, void *data );
62int TS_Terminate( task *ptr );
63void TS_Dispatch( void );
64void TS_SetTaskRate( task *Task, int rate );
65void TS_UnlockMemory( void );
66int TS_LockMemory( void );
67
68#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/user.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/user.c
new file mode 100644
index 0000000000..46d02f5c36
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/user.c
@@ -0,0 +1,100 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: USER.C
22
23 author: James R. Dose
24 date: April 26, 1994
25
26 Routines to parse command line options.
27
28 (c) Copyright 1994 James R. Dose. All Rights Reserved.
29**********************************************************************/
30
31#include <string.h>
32#include "user.h"
33
34#define TRUE ( 1 == 1 )
35#define FALSE ( !TRUE )
36
37#ifdef PLAT_DOS
38extern int _argc;
39extern char **_argv;
40#endif
41
42/*---------------------------------------------------------------------
43 Function: USER_CheckParameter
44
45 Checks if the specified string is present in the command line.
46---------------------------------------------------------------------*/
47
48int USER_CheckParameter
49 (
50 const char *parameter
51 )
52
53 {
54#ifdef PLAT_DOS
55 int i;
56 int found;
57 char *ptr;
58
59 found = FALSE;
60 i = 1;
61 while( i < _argc )
62 {
63 ptr = _argv[ i ];
64
65 // Only check parameters preceded by - or /
66 if ( ( *ptr == '-' ) || ( *ptr == '/' ) )
67 {
68 ptr++;
69 if ( stricmp( parameter, ptr ) == 0 )
70 {
71 found = TRUE;
72 break;
73 }
74 }
75
76 i++;
77 }
78
79 return( found );
80#else
81 return FALSE;
82#endif
83 }
84
85
86/*---------------------------------------------------------------------
87 Function: USER_GetText
88
89 Checks if the specified string is present in the command line
90 and returns a pointer to the text following it.
91---------------------------------------------------------------------*/
92
93char *USER_GetText
94 (
95 const char *parameter
96 )
97
98 {
99 return NULL;
100 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/user.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/user.h
new file mode 100644
index 0000000000..b81b3cfb2b
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/user.h
@@ -0,0 +1,38 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: USER.H
22
23 author: James R. Dose
24 phone: (214)-271-1365 Ext #221
25 date: April 26, 1994
26
27 Public header for USER.C
28
29 (c) Copyright 1994 James R. Dose. All Rights Reserved.
30**********************************************************************/
31
32#ifndef __USER_H
33#define __USER_H
34
35int USER_CheckParameter( const char *parameter );
36char *USER_GetText( const char *parameter );
37
38#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/usrhooks.c b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/usrhooks.c
new file mode 100644
index 0000000000..67890e4a07
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/usrhooks.c
@@ -0,0 +1,84 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: USRHOOKS.C
22
23 author: James R. Dose
24 date: July 26, 1994
25
26 This module contains cover functions for operations the library
27 needs that may be restricted by the calling program. This code
28 is left public for you to modify.
29**********************************************************************/
30
31#include <stdlib.h>
32#include "usrhooks.h"
33
34
35/*---------------------------------------------------------------------
36 Function: USRHOOKS_GetMem
37
38 Allocates the requested amount of memory and returns a pointer to
39 its location, or NULL if an error occurs. NOTE: pointer is assumed
40 to be dword aligned.
41---------------------------------------------------------------------*/
42
43int USRHOOKS_GetMem
44 (
45 void **ptr,
46 uint32_t size
47 )
48
49 {
50 void *memory;
51
52 memory = malloc( size );
53 if ( memory == NULL )
54 {
55 return( USRHOOKS_Error );
56 }
57
58 *ptr = memory;
59
60 return( USRHOOKS_Ok );
61 }
62
63
64/*---------------------------------------------------------------------
65 Function: USRHOOKS_FreeMem
66
67 Deallocates the memory associated with the specified pointer.
68---------------------------------------------------------------------*/
69
70int USRHOOKS_FreeMem
71 (
72 void *ptr
73 )
74
75 {
76 if ( ptr == NULL )
77 {
78 return( USRHOOKS_Error );
79 }
80
81 free( ptr );
82
83 return( USRHOOKS_Ok );
84 }
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/usrhooks.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/usrhooks.h
new file mode 100644
index 0000000000..ef465f331b
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/usrhooks.h
@@ -0,0 +1,57 @@
1/*
2Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20/**********************************************************************
21 module: USRHOOKS.H
22
23 author: James R. Dose
24 date: July 26, 1994
25
26 Public header file for USRHOOKS.C.
27
28 This module contains cover functions for operations the library
29 needs that may be restricted by the calling program. The function
30 prototypes in this header should not be modified.
31**********************************************************************/
32
33#ifndef __USRHOOKS_H
34#define __USRHOOKS_H
35
36#include "../duke3d.h"
37
38/*---------------------------------------------------------------------
39 Error definitions
40---------------------------------------------------------------------*/
41
42enum USRHOOKS_Errors
43 {
44 USRHOOKS_Warning = -2,
45 USRHOOKS_Error = -1,
46 USRHOOKS_Ok = 0
47 };
48
49
50/*---------------------------------------------------------------------
51 Function Prototypes
52---------------------------------------------------------------------*/
53
54int USRHOOKS_GetMem( void **ptr, uint32_t size );
55int USRHOOKS_FreeMem( void *ptr );
56
57#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/util.h b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/util.h
new file mode 100644
index 0000000000..2960501897
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/audiolib/util.h
@@ -0,0 +1,13 @@
1#ifndef AUDIOLIB__UTIL_H
2#define AUDIOLIB__UTIL_H
3
4#ifndef min
5#define min(a, b) ((a) < (b) ? (a) : (b))
6#endif
7
8#ifndef max
9#define max(a, b) ((a) > (b) ? (a) : (b))
10#endif
11
12#endif
13
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/config.c b/apps/plugins/sdl/progs/duke3d/Game/src/config.c
new file mode 100644
index 0000000000..038875a4e5
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/config.c
@@ -0,0 +1,897 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#if PLATFORM_DOS
28#include <conio.h>
29#include <dos.h>
30#endif
31
32#include <stdio.h>
33#include <string.h>
34#include <stdlib.h>
35#include <ctype.h>
36#include <time.h>
37#include "duke3d.h"
38#include "scriplib.h"
39#include "../../Engine/src/build.h"
40
41
42// we load this in to get default button and key assignments
43// as well as setting up function mappings
44
45#include "_functio.h"
46
47//
48// Sound variables
49//
50int32_t FXDevice;
51int32_t MusicDevice;
52int32_t FXVolume;
53int32_t MusicVolume;
54int32_t SoundToggle;
55int32_t MusicToggle;
56int32_t VoiceToggle;
57int32_t AmbienceToggle;
58int32_t OpponentSoundToggle; // xduke to toggle opponent's sounds on/off in DM (duke 1.3d scheme)
59fx_blaster_config BlasterConfig;
60int32_t NumVoices;
61int32_t NumChannels;
62int32_t NumBits;
63int32_t MixRate;
64int32_t MidiPort;
65int32_t ReverseStereo;
66
67int32_t ControllerType;
68int32_t MouseAiming = 0;
69int32_t BFullScreen = 0;
70
71//
72// Screen variables
73//
74
75int32 ScreenMode=2;
76int32 ScreenWidth = LCD_WIDTH;
77int32 ScreenHeight = LCD_HEIGHT;
78
79//
80// Mouse variables
81//
82int32 mouseSensitivity_X;
83int32 mouseSensitivity_Y;
84
85static char setupfilename[512] = "/.rockbox/duke3d/duke3d.cfg";
86static int32 scripthandle;
87static int32 setupread=0;
88/*
89===================
90=
91= CONFIG_GetSetupFilename
92=
93===================
94*/
95#define MAXSETUPFILES 20
96void CONFIG_GetSetupFilename( void )
97 {
98 int32 i;
99
100
101 setupfilename[0] = '\0';
102
103 // Are we trying to load a mod?
104#if 0
105 if(getGameDir()[0] != '\0'){
106 FILE *fp = NULL;
107
108 //Yes
109 sprintf(setupfilename, "%s/%s", getGameDir(), SETUPFILENAME);
110
111 // let's make sure it's actually there
112 fp = fopen(setupfilename, "r");
113 if(fp)
114 fclose(fp);
115 else{
116 // It doesn't exist, so revert to the main one.
117 printf("Config file: %s does not exist, using main config.\n", setupfilename);
118 sprintf(setupfilename, "%s", SETUPFILENAME);
119 }
120
121 }else{
122#endif
123 //No
124 sprintf(setupfilename, "%s/%s", getGameDir(), SETUPFILENAME);
125 //}
126
127 printf("Using Setup file: '%s'\n",setupfilename);
128// i=clock()+(3*CLOCKS_PER_SEC/4);
129// while (clock()<i){
130// ;
131 // }
132}
133
134/*
135===================
136=
137= CONFIG_FunctionNameToNum
138=
139===================
140*/
141
142int32 CONFIG_FunctionNameToNum( char * func )
143 {
144 int32 i;
145
146 for (i=0;i<NUMGAMEFUNCTIONS;i++)
147 {
148 if (!stricmp(func,gamefunctions[i]))
149 {
150 return i;
151 }
152 }
153 return -1;
154 }
155
156/*
157===================
158=
159= CONFIG_FunctionNumToName
160=
161===================
162*/
163
164char * CONFIG_FunctionNumToName( int32 func )
165{
166 if (-1 < func && func < NUMGAMEFUNCTIONS)
167 {
168 return gamefunctions[func];
169 }
170 else
171 {
172 return NULL;
173 }
174}
175
176/*
177===================
178=
179= CONFIG_AnalogNameToNum
180=
181===================
182*/
183
184
185int32 CONFIG_AnalogNameToNum( char * func )
186 {
187
188 if (!stricmp(func,"analog_turning"))
189 {
190 return analog_turning;
191 }
192 if (!stricmp(func,"analog_strafing"))
193 {
194 return analog_strafing;
195 }
196 if (!stricmp(func,"analog_moving"))
197 {
198 return analog_moving;
199 }
200 if (!stricmp(func,"analog_lookingupanddown"))
201 {
202 return analog_lookingupanddown;
203 }
204
205 return -1;
206 }
207
208/*
209===================
210=
211= CONFIG_SetDefaults
212=
213===================
214*/
215
216void CONFIG_SetDefaults( void )
217{
218 // sound
219 SoundToggle = 1;
220 MusicToggle = 1;
221 VoiceToggle = 1;
222 AmbienceToggle = 1;
223 OpponentSoundToggle = 1;
224 FXVolume = 220;
225 MusicVolume = 200;
226 FXDevice = SoundScape;
227 MusicDevice = -1;
228 ReverseStereo = 0;
229
230 // mouse
231 mouseSensitivity_X = 16;
232 mouseSensitivity_Y = mouseSensitivity_X;
233
234 // game
235 ps[0].aim_mode = 0;
236 ud.screen_size = 8;
237 ud.extended_screen_size = 0;
238 ud.screen_tilting = 1;
239 ud.brightness = 16;
240 ud.auto_run = 1;
241 ud.showweapons = 0;
242 ud.tickrate = 0;
243 ud.scrollmode = 0;
244 ud.shadows = 1;
245 ud.detail = 1;
246 ud.lockout = 0;
247 ud.pwlockout[0] = '\0';
248 ud.crosshair = 1;
249 ud.m_marker = 1; // for multiplayer
250 ud.m_ffire = 1;
251 ud.showcinematics = 1;
252 ud.weaponautoswitch = 0;
253 ud.hideweapon = 0;
254 ud.auto_aim = 2; // full by default
255 ud.gitdat_mdk = 0;
256 ud.playing_demo_rev = 0;
257
258 // com
259 strcpy(ud.rtsname,"DUKE.RTS");
260 strcpy(ud.ridecule[0],"An inspiration for birth control.");
261 strcpy(ud.ridecule[1],"You're gonna die for that!");
262 strcpy(ud.ridecule[2],"It hurts to be you.");
263 strcpy(ud.ridecule[3],"Lucky Son of a Bitch.");
264 strcpy(ud.ridecule[4],"Hmmm....Payback time.");
265 strcpy(ud.ridecule[5],"You bottom dwelling scum sucker.");
266 strcpy(ud.ridecule[6],"Damn, you're ugly.");
267 strcpy(ud.ridecule[7],"Ha ha ha...Wasted!");
268 strcpy(ud.ridecule[8],"You suck!");
269 strcpy(ud.ridecule[9],"AARRRGHHHHH!!!");
270
271 // Controller
272 ControllerType = controltype_keyboardandmouse;
273}
274
275/*
276===================
277=
278= CONFIG_ReadKeys
279=
280===================
281*/
282
283void CONFIG_ReadKeys( void )
284 {
285 printf("CONFIG_ReadKeys\n");
286 int32 i;
287 int32 numkeyentries;
288 int32 function;
289 char keyname1[80];
290 char keyname2[80];
291 kb_scancode key1,key2;
292
293 // set default keys in case duke3d.cfg was not found
294
295 // FIX_00011: duke3d.cfg not needed anymore to start the game. Will create a default one
296 // if not found and use default keys.
297
298 for(i=0; i<NUMKEYENTRIES; i++){
299 function = CONFIG_FunctionNameToNum(keydefaults[i].entryKey);
300 key1 = (byte) KB_StringToScanCode( keydefaults[i].keyname1 );
301 key2 = (byte) KB_StringToScanCode( keydefaults[i].keyname2 );
302 CONTROL_MapKey( function, key1, key2 );
303 }
304
305
306 numkeyentries = SCRIPT_NumberEntries( scripthandle, "KeyDefinitions" );
307
308 for (i=0;i<numkeyentries;i++) // i = number in which the functions appear in duke3d.cfg
309 {
310 function = CONFIG_FunctionNameToNum(SCRIPT_Entry( scripthandle, "KeyDefinitions", i ));
311 if (function != -1) // ensure it is in the list gamefunctions[function]
312 {
313 memset(keyname1,0,sizeof(keyname1));
314 memset(keyname2,0,sizeof(keyname2));
315 SCRIPT_GetDoubleString
316 (
317 scripthandle,
318 "KeyDefinitions",
319 SCRIPT_Entry( scripthandle,"KeyDefinitions", i ),
320 keyname1,
321 keyname2
322 );
323 key1 = 0;
324 key2 = 0;
325 if (keyname1[0])
326 {
327 key1 = (byte) KB_StringToScanCode( keyname1 );
328 }
329 if (keyname2[0])
330 {
331 key2 = (byte) KB_StringToScanCode( keyname2 );
332 }
333 CONTROL_MapKey( function, key1, key2 );
334 }
335 }
336 }
337
338
339/*
340===================
341=
342= CONFIG_SetupMouse
343=
344===================
345*/
346
347void CONFIG_SetupMouse( int32 scripthandle )
348 {
349 int32 i;
350 char str[80];
351 char temp[80];
352 int32 function, scale;
353
354 for (i=0;i<MAXMOUSEBUTTONS;i++)
355 {
356 sprintf(str,"MouseButton%d",i);
357 memset(temp,0,sizeof(temp));
358 SCRIPT_GetString( scripthandle,"Controls", str,temp);
359 function = CONFIG_FunctionNameToNum(temp);
360 CONTROL_MapButton( function, i, false );
361 sprintf(str,"MouseButtonClicked%d",i);
362 memset(temp,0,sizeof(temp));
363 SCRIPT_GetString( scripthandle,"Controls", str,temp);
364 function = CONFIG_FunctionNameToNum(temp);
365 CONTROL_MapButton( function, i, true );
366 }
367 // map over the axes
368 for (i=0;i<MAXMOUSEAXES;i++)
369 {
370 sprintf(str,"MouseAnalogAxes%d",i);
371 memset(temp,0,sizeof(temp));
372 SCRIPT_GetString(scripthandle, "Controls", str,temp);
373 function = CONFIG_AnalogNameToNum(temp);
374 if (function != -1)
375 {
376 //TODO Fix the Analog mouse axis issue. Just make a new function for registering them.
377 //CONTROL_MapAnalogAxis(i,function);
378 }
379 sprintf(str,"MouseDigitalAxes%d_0",i);
380 memset(temp,0,sizeof(temp));
381 SCRIPT_GetString(scripthandle, "Controls", str,temp);
382 function = CONFIG_FunctionNameToNum(temp);
383 CONTROL_MapDigitalAxis( i, function, 0 );
384 sprintf(str,"MouseDigitalAxes%d_1",i);
385 memset(temp,0,sizeof(temp));
386 SCRIPT_GetString(scripthandle, "Controls", str,temp);
387 function = CONFIG_FunctionNameToNum(temp);
388 CONTROL_MapDigitalAxis( i, function, 1 );
389 sprintf(str,"MouseAnalogScale%d",i);
390 SCRIPT_GetNumber(scripthandle, "Controls", str,&scale);
391 //TODO: Fix the Analog mouse scale issue. Just make a new function for registering them.
392 //CONTROL_SetAnalogAxisScale( i, scale );
393 }
394
395 SCRIPT_GetNumber( scripthandle, "Controls","MouseSensitivity_X_Rancid",&mouseSensitivity_X);
396 if(mouseSensitivity_X>63 || mouseSensitivity_X < 0)
397 mouseSensitivity_X = 15;
398 // FIX_00014: Added Y cursor setup for mouse sensitivity in the menus
399 // Copy Sensitivity_X into Sensitivity_Y in case it is not set.
400 mouseSensitivity_Y = mouseSensitivity_X;
401 SCRIPT_GetNumber( scripthandle, "Controls","MouseSensitivity_Y_Rancid",&mouseSensitivity_Y);
402 if(mouseSensitivity_Y>63 || mouseSensitivity_Y < 0)
403 mouseSensitivity_Y = 15;
404
405 }
406
407/*
408===================
409=
410= CONFIG_SetupGamePad
411=
412===================
413*/
414
415void CONFIG_SetupGamePad( int32 scripthandle )
416 {
417 int32 i;
418 char str[80];
419 char temp[80];
420 int32 function;
421
422
423 for (i=0;i<MAXJOYBUTTONS;i++)
424 {
425 sprintf(str,"JoystickButton%d",i);
426 memset(temp,0,sizeof(temp));
427 SCRIPT_GetString( scripthandle,"Controls", str,temp);
428 function = CONFIG_FunctionNameToNum(temp);
429 if (function != -1)
430 CONTROL_MapButton( function, i, false );
431 sprintf(str,"JoystickButtonClicked%d",i);
432 memset(temp,0,sizeof(temp));
433 SCRIPT_GetString( scripthandle,"Controls", str,temp);
434 function = CONFIG_FunctionNameToNum(temp);
435 if (function != -1)
436 CONTROL_MapButton( function, i, true );
437 }
438 // map over the axes
439 for (i=0;i<MAXGAMEPADAXES;i++)
440 {
441 sprintf(str,"GamePadDigitalAxes%d_0",i);
442 memset(temp,0,sizeof(temp));
443 SCRIPT_GetString(scripthandle, "Controls", str,temp);
444 function = CONFIG_FunctionNameToNum(temp);
445 if (function != -1)
446 CONTROL_MapDigitalAxis( i, function, 0 );
447 sprintf(str,"GamePadDigitalAxes%d_1",i);
448 memset(temp,0,sizeof(temp));
449 SCRIPT_GetString(scripthandle, "Controls", str,temp);
450 function = CONFIG_FunctionNameToNum(temp);
451 if (function != -1)
452 CONTROL_MapDigitalAxis( i, function, 1 );
453 }
454 SCRIPT_GetNumber( scripthandle, "Controls","JoystickPort",&function);
455 CONTROL_JoystickPort = function;
456 }
457
458/*
459===================
460=
461= CONFIG_SetupJoystick
462=
463===================
464*/
465
466void CONFIG_SetupJoystick( int32 scripthandle )
467{
468 int32 i, j;
469 char str[80];
470 char temp[80];
471 int32 function, deadzone;
472 float scale;
473
474 for (i=0;i<MAXJOYBUTTONS;i++)
475 {
476 sprintf(str,"JoystickButton%d",i);
477 memset(temp,0,sizeof(temp));
478 SCRIPT_GetString( scripthandle,"Controls", str,temp);
479 function = CONFIG_FunctionNameToNum(temp);
480 if (function != -1)
481 CONTROL_MapJoyButton( function, i, false );
482 sprintf(str,"JoystickButtonClicked%d",i);
483 memset(temp,0,sizeof(temp));
484 SCRIPT_GetString( scripthandle,"Controls", str,temp);
485 function = CONFIG_FunctionNameToNum(temp);
486 if (function != -1)
487 CONTROL_MapJoyButton( function, i, true );
488 }
489 // map over the axes
490 for (i=0;i<MAXJOYAXES;i++)
491 {
492 sprintf(str,"JoystickAnalogAxes%d",i);
493 memset(temp,0,sizeof(temp));
494 SCRIPT_GetString(scripthandle, "Controls", str,temp);
495 function = CONFIG_AnalogNameToNum(temp);
496 //if (function != -1)
497 //{
498 CONTROL_MapAnalogAxis(i,function);
499 //}
500 sprintf(str,"JoystickDigitalAxes%d_0",i);
501 memset(temp,0,sizeof(temp));
502 SCRIPT_GetString(scripthandle, "Controls", str,temp);
503 function = CONFIG_FunctionNameToNum(temp);
504 if (function != -1)
505 CONTROL_MapDigitalAxis( i, function, 0 );
506 sprintf(str,"JoystickDigitalAxes%d_1",i);
507 memset(temp,0,sizeof(temp));
508 SCRIPT_GetString(scripthandle, "Controls", str,temp);
509 function = CONFIG_FunctionNameToNum(temp);
510 if (function != -1)
511 CONTROL_MapDigitalAxis( i, function, 1 );
512 sprintf(str,"JoystickAnalogScale%d",i);
513 SCRIPT_GetFloat(scripthandle, "Controls", str,&scale);
514 CONTROL_SetAnalogAxisScale( i, scale );
515 deadzone = 0;
516 sprintf(str,"JoystickAnalogDeadzone%d",i);
517 SCRIPT_GetNumber(scripthandle, "Controls", str, &deadzone);
518 CONTROL_SetAnalogAxisDeadzone( i, deadzone);
519 }
520
521 // map over the "top hats"
522 for (i=0; i < MAXJOYHATS; i++)
523 {
524 for(j=0; j < 8; j++) // 8? because hats can have 8 different values
525 {
526 sprintf(str,"JoystickHat%d_%d",i, j);
527 memset(temp,0,sizeof(temp));
528 SCRIPT_GetString( scripthandle,"Controls", str,temp);
529 function = CONFIG_FunctionNameToNum(temp);
530 if (function != -1)
531 {
532 CONTROL_MapJoyHat( function, i, j);
533 }
534 }
535 }
536
537 // read in JoystickPort
538 SCRIPT_GetNumber( scripthandle, "Controls","JoystickPort",&function);
539 CONTROL_JoystickPort = function;
540 // read in rudder state
541 SCRIPT_GetNumber( scripthandle, "Controls","EnableRudder",(int32_t*)&CONTROL_RudderEnabled);
542}
543
544void readsavenames(void)
545{
546 int32_t dummy;
547 short i;
548 uint8_t fn[] = "game_.sav";
549 FILE *fil;
550 char fullpathsavefilename[256];
551
552
553 for (i=0;i<10;i++)
554 {
555
556 fn[4] = i+'0';
557
558 // Are we loading a TC?
559 if(getGameDir()[0] != '\0')
560 {
561 // Yes
562 sprintf(fullpathsavefilename, "%s/%s", getGameDir(), fn);
563 }
564 else
565 {
566 // No
567 sprintf(fullpathsavefilename, "%s", fn);
568 }
569
570
571 if ((fil = fopen(fullpathsavefilename,"rb")) == NULL ) continue;
572 dfread(&dummy,4,1,fil);
573
574 // FIX_00015: Backward compliance with older demos (down to demos v27, 28, 116 and 117 only)
575 if( dummy != BYTEVERSION &&
576 dummy != BYTEVERSION_27 &&
577 dummy != BYTEVERSION_28 &&
578 dummy != BYTEVERSION_116 &&
579 dummy != BYTEVERSION_117) continue;
580 // FIX_00092: corrupted saved files making the following saved files invisible (Bryzian)
581 dfread(&dummy,4,1,fil);
582 dfread(&ud.savegame[i][0],19,1,fil);
583 fclose(fil);
584 }
585}
586
587/*
588===================
589=
590= CONFIG_ReadSetup
591=
592===================
593*/
594
595//int32 dukever13;
596
597void CONFIG_ReadSetup( void )
598{
599 int32 dummy;
600 char commmacro[] = COMMMACRO;
601 FILE* setup_file_hdl;
602
603 printf("CONFIG_ReadSetup...\n");
604
605 if (!SafeFileExists(setupfilename))
606 {
607 // FIX_00011: duke3d.cfg not needed anymore to start the game. Will create a default one
608 // if not found and use default keys.
609 printf("%s does not exist. Don't forget to set it up!\n" ,setupfilename);
610 setup_file_hdl = fopen (setupfilename, "w"); // create it...
611 if(setup_file_hdl)
612 fclose(setup_file_hdl);
613 }
614
615 CONFIG_SetDefaults();
616 scripthandle = SCRIPT_Load( setupfilename );
617
618 for(dummy = 0;dummy < 10;dummy++)
619 {
620 commmacro[13] = dummy+'0';
621 SCRIPT_GetString( scripthandle, "Comm Setup",commmacro,ud.ridecule[dummy]);
622 }
623
624
625
626 SCRIPT_GetString( scripthandle, "Comm Setup","PlayerName",&myname[0]);
627
628 dummy = CheckParm("NAME");
629 if( dummy ) strcpy(myname,_argv[dummy+1]);
630 dummy = CheckParm("MAP");
631
632
633
634 if( dummy )
635 {
636 if (!VOLUMEONE)
637 {
638 //boardfilename might be set from commandline only zero if we are replacing
639 boardfilename[0] = 0;
640 strcpy(boardfilename,_argv[dummy+1]);
641 if( strchr(boardfilename,'.') == 0)
642 strcat(boardfilename,".map");
643 printf("Using level: '%s'.\n",boardfilename);
644 }
645 else
646 {
647 Error(EXIT_SUCCESS, "The -map option does not work with the Shareware version of duke3d.grp\n"
648 "Change your duke3d.grp file to the 1.3d version or 1.5 Atomic version\n");
649 }
650 }
651
652 SCRIPT_GetString( scripthandle, "Comm Setup","RTSName",&ud.rtsname[0]);
653 SCRIPT_GetNumber( scripthandle, "Screen Setup", "Shadows",&ud.shadows);
654 SCRIPT_GetString( scripthandle, "Screen Setup","Password",&ud.pwlockout[0]);
655 SCRIPT_GetNumber( scripthandle, "Screen Setup", "Detail",&ud.detail);
656 SCRIPT_GetNumber( scripthandle, "Screen Setup", "Tilt",&ud.screen_tilting);
657 SCRIPT_GetNumber( scripthandle, "Screen Setup", "Messages",&ud.fta_on);
658 SCRIPT_GetNumber( scripthandle, "Screen Setup", "ScreenWidth",&ScreenWidth);
659 SCRIPT_GetNumber( scripthandle, "Screen Setup", "ScreenHeight",&ScreenHeight);
660 // SCRIPT_GetNumber( scripthandle, "Screen Setup", "ScreenMode",&ScreenMode);
661 SCRIPT_GetNumber( scripthandle, "Screen Setup", "ScreenGamma",&ud.brightness);
662 SCRIPT_GetNumber( scripthandle, "Screen Setup", "ScreenSize",&ud.screen_size);
663 SCRIPT_GetNumber( scripthandle, "Screen Setup", "ExtScreenSize",&ud.extended_screen_size);
664 SCRIPT_GetNumber( scripthandle, "Screen Setup", "Out",&ud.lockout);
665 SCRIPT_GetNumber( scripthandle, "Screen Setup", "ShowFPS",&ud.tickrate);
666 ud.tickrate &= 1;
667 SCRIPT_GetNumber( scripthandle, "Misc", "Executions",&ud.executions);
668 ud.executions++;
669 SCRIPT_GetNumber( scripthandle, "Misc", "RunMode",&ud.auto_run);
670 SCRIPT_GetNumber( scripthandle, "Misc", "Crosshairs",&ud.crosshair);
671 SCRIPT_GetNumber( scripthandle, "Misc", "ShowCinematics",&ud.showcinematics);
672 SCRIPT_GetNumber( scripthandle, "Misc", "WeaponAutoSwitch",&ud.weaponautoswitch);
673 SCRIPT_GetNumber( scripthandle, "Misc", "HideWeapon",&ud.hideweapon);
674 SCRIPT_GetNumber( scripthandle, "Misc", "ShowWeapon",&ud.showweapons);
675 SCRIPT_GetNumber( scripthandle, "Misc", "AutoAim",&ud.auto_aim);
676 if(ud.auto_aim!=1 && ud.auto_aim != 2)
677 ud.auto_aim = 2; // avoid people missing with the cfg to go in a deadlock
678 SCRIPT_GetNumber( scripthandle, "Misc", "GitDatMdk",&ud.gitdat_mdk);
679
680 if(ud.mywchoice[0] == 0 && ud.mywchoice[1] == 0)
681 {
682 ud.mywchoice[0] = 3;
683 ud.mywchoice[1] = 4;
684 ud.mywchoice[2] = 5;
685 ud.mywchoice[3] = 7;
686 ud.mywchoice[4] = 8;
687 ud.mywchoice[5] = 6;
688 ud.mywchoice[6] = 0;
689 ud.mywchoice[7] = 2;
690 ud.mywchoice[8] = 9;
691 ud.mywchoice[9] = 1;
692
693 for(dummy=0;dummy<10;dummy++)
694 {
695 sprintf(buf,"WeaponChoice%d",dummy);
696 SCRIPT_GetNumber( scripthandle, "Misc", buf, &ud.mywchoice[dummy]);
697 }
698 }
699 SCRIPT_GetNumber( scripthandle, "Sound Setup", "FXDevice",&FXDevice);
700
701 #if !PLATFORM_DOS // reimplementation of ASS expects a "SoundScape".
702 if (FXDevice != NumSoundCards)
703 FXDevice = SoundScape;
704 #endif
705
706 SCRIPT_GetNumber( scripthandle, "Sound Setup", "MusicDevice",&MusicDevice);
707
708 //#if !PLATFORM_DOS // reimplementation of ASS expects a "SoundScape".
709 // if (MusicDevice != NumSoundCards)
710 // MusicDevice = SoundScape;
711 //#endif
712
713// FIX_00015: Forced NumVoices=8, NumChannels=2, NumBits=16, MixRate=44100, ScreenMode = x(
714// (ScreenMode has no meaning anymore)
715
716 SCRIPT_GetNumber( scripthandle, "Sound Setup", "FXVolume",&FXVolume);
717 SCRIPT_GetNumber( scripthandle, "Sound Setup", "MusicVolume",&MusicVolume);
718 SCRIPT_GetNumber( scripthandle, "Sound Setup", "SoundToggle",&SoundToggle);
719 SCRIPT_GetNumber( scripthandle, "Sound Setup", "MusicToggle",&MusicToggle);
720 SCRIPT_GetNumber( scripthandle, "Sound Setup", "VoiceToggle",&VoiceToggle);
721 SCRIPT_GetNumber( scripthandle, "Sound Setup", "AmbienceToggle",&AmbienceToggle);
722 SCRIPT_GetNumber( scripthandle, "Sound Setup", "OpponentSoundToggle",&OpponentSoundToggle);
723 SCRIPT_GetNumber( scripthandle, "Sound Setup", "NumVoices",&NumVoices);
724 NumVoices = 32;
725 SCRIPT_GetNumber( scripthandle, "Sound Setup", "NumChannels",&NumChannels);
726 NumChannels = 2;
727 SCRIPT_GetNumber( scripthandle, "Sound Setup", "NumBits",&NumBits);
728 NumBits = 16;
729 SCRIPT_GetNumber( scripthandle, "Sound Setup", "MixRate",&MixRate);
730 MixRate = RB_SAMPR;
731 SCRIPT_GetNumber( scripthandle, "Sound Setup", "MidiPort",&MidiPort);
732 SCRIPT_GetNumber( scripthandle, "Sound Setup", "BlasterAddress",&dummy);
733 BlasterConfig.Address = dummy;
734 SCRIPT_GetNumber( scripthandle, "Sound Setup", "BlasterType",&dummy);
735 BlasterConfig.Type = dummy;
736 SCRIPT_GetNumber( scripthandle, "Sound Setup", "BlasterInterrupt",&dummy);
737 BlasterConfig.Interrupt = dummy;
738 SCRIPT_GetNumber( scripthandle, "Sound Setup", "BlasterDma8",&dummy);
739 BlasterConfig.Dma8 = dummy;
740 SCRIPT_GetNumber( scripthandle, "Sound Setup", "BlasterDma16",&dummy);
741 BlasterConfig.Dma16 = dummy;
742 SCRIPT_GetNumber( scripthandle, "Sound Setup", "BlasterEmu",&dummy);
743 BlasterConfig.Emu = dummy;
744 SCRIPT_GetNumber( scripthandle, "Sound Setup", "ReverseStereo",&ReverseStereo);
745
746 SCRIPT_GetNumber( scripthandle, "Controls","ControllerType",&ControllerType);
747 SCRIPT_GetNumber( scripthandle, "Controls","MouseAimingFlipped",&ud.mouseflip);
748 SCRIPT_GetNumber( scripthandle, "Controls","MouseAiming",&MouseAiming);
749 SCRIPT_GetNumber( scripthandle, "Controls","GameMouseAiming",(int32 *)&ps[0].aim_mode);
750 SCRIPT_GetNumber( scripthandle, "Controls","AimingFlag",(int32 *)&myaimmode);
751
752 CONTROL_ClearAssignments();
753
754 CONFIG_ReadKeys();
755
756 switch (ControllerType)
757 {
758 case controltype_keyboardandmouse:
759 {
760 CONFIG_SetupMouse(scripthandle);
761 }
762 break;
763 case controltype_keyboardandjoystick:
764 case controltype_keyboardandflightstick:
765 case controltype_keyboardandthrustmaster:
766 {
767 CONTROL_JoystickEnabled = 1;
768 CONFIG_SetupJoystick(scripthandle);
769 }
770 break;
771 case controltype_keyboardandgamepad:
772 {
773 CONFIG_SetupGamePad(scripthandle);
774 }
775 break;
776 case controltype_joystickandmouse:
777 {
778
779 CONTROL_JoystickEnabled = 1;
780 CONFIG_SetupJoystick(scripthandle);
781 CONFIG_SetupMouse(scripthandle);
782 }
783 break;
784 default:
785 {
786 CONFIG_SetupMouse(scripthandle);
787 }
788 }
789 setupread = 1;
790 }
791
792/*
793===================
794=
795= CONFIG_WriteSetup
796=
797===================
798*/
799
800void CONFIG_WriteSetup( void )
801 {
802 int32 dummy, i;
803 char commmacro[] = COMMMACRO;
804
805 if (!setupread) return;
806
807 printf("CONFIG_WriteSetup...\n");
808
809 SCRIPT_PutNumber( scripthandle, "Screen Setup", "Shadows",ud.shadows,false,false);
810 SCRIPT_PutString( scripthandle, "Screen Setup", "Password",ud.pwlockout);
811 SCRIPT_PutNumber( scripthandle, "Screen Setup", "Detail",ud.detail,false,false);
812 SCRIPT_PutNumber( scripthandle, "Screen Setup", "Tilt",ud.screen_tilting,false,false);
813 SCRIPT_PutNumber( scripthandle, "Screen Setup", "Messages",ud.fta_on,false,false);
814 SCRIPT_PutNumber( scripthandle, "Screen Setup", "Out",ud.lockout,false,false);
815 SCRIPT_PutNumber( scripthandle, "Screen Setup", "ShowFPS",ud.tickrate&1,false,false);
816 SCRIPT_PutNumber( scripthandle, "Screen Setup", "ScreenWidth",xdim,false,false);
817 SCRIPT_PutNumber( scripthandle, "Screen Setup", "ScreenHeight",ydim,false,false);
818 SCRIPT_PutNumber( scripthandle, "Screen Setup", "Fullscreen",BFullScreen,false,false);
819 SCRIPT_PutNumber( scripthandle, "Sound Setup", "FXVolume",FXVolume,false,false);
820 SCRIPT_PutNumber( scripthandle, "Sound Setup", "MusicVolume",MusicVolume,false,false);
821 SCRIPT_PutNumber( scripthandle, "Sound Setup", "FXDevice",FXDevice,false,false);
822 SCRIPT_PutNumber( scripthandle, "Sound Setup", "MusicDevice",MusicDevice,false,false);
823 SCRIPT_PutNumber( scripthandle, "Sound Setup", "SoundToggle",SoundToggle,false,false);
824 SCRIPT_PutNumber( scripthandle, "Sound Setup", "VoiceToggle",VoiceToggle,false,false);
825 SCRIPT_PutNumber( scripthandle, "Sound Setup", "AmbienceToggle",AmbienceToggle,false,false);
826 SCRIPT_PutNumber( scripthandle, "Sound Setup", "OpponentSoundToggle",OpponentSoundToggle,false,false);
827 SCRIPT_PutNumber( scripthandle, "Sound Setup", "MusicToggle",MusicToggle,false,false);
828 SCRIPT_PutNumber( scripthandle, "Sound Setup", "ReverseStereo",ReverseStereo,false,false);
829 SCRIPT_PutNumber( scripthandle, "Screen Setup", "ScreenSize",ud.screen_size,false,false);
830 SCRIPT_PutNumber( scripthandle, "Screen Setup", "ExtScreenSize",ud.extended_screen_size,false,false);
831 SCRIPT_PutNumber( scripthandle, "Screen Setup", "ScreenGamma",ud.brightness,false,false);
832 SCRIPT_PutNumber( scripthandle, "Misc", "Executions",ud.executions,false,false);
833 SCRIPT_PutNumber( scripthandle, "Misc", "RunMode",ud.auto_run,false,false);
834 SCRIPT_PutNumber( scripthandle, "Misc", "Crosshairs",ud.crosshair,false,false);
835 SCRIPT_PutNumber( scripthandle, "Misc", "ShowCinematics",ud.showcinematics,false,false);
836 SCRIPT_PutNumber( scripthandle, "Misc", "HideWeapon",ud.hideweapon,false,false);
837 SCRIPT_PutNumber( scripthandle, "Misc", "ShowWeapon",ud.showweapons,false,false);
838 SCRIPT_PutNumber( scripthandle, "Misc", "WeaponAutoSwitch",ud.weaponautoswitch,false,false);
839 if( nHostForceDisableAutoaim == 0) // do not save Host request to have AutoAim Off.
840 SCRIPT_PutNumber( scripthandle, "Misc", "AutoAim",ud.auto_aim,false,false);
841 SCRIPT_PutNumber( scripthandle, "Controls", "MouseAimingFlipped",ud.mouseflip,false,false);
842 SCRIPT_PutNumber( scripthandle, "Controls","MouseAiming",MouseAiming,false,false);
843 SCRIPT_PutNumber( scripthandle, "Controls","GameMouseAiming",(int32) ps[myconnectindex].aim_mode,false,false);
844 SCRIPT_PutNumber( scripthandle, "Controls","AimingFlag",(int32_t) myaimmode,false,false);
845
846 // FIX_00016: Build in Keyboard/mouse setup. Mouse now faster.
847 for(i=0; i<MAXMOUSEBUTTONS; i++)
848 {
849 sprintf((char *)tempbuf, "MouseButton%d", i);
850 SCRIPT_PutString(scripthandle, "Controls", (char *)tempbuf,
851 (MouseMapping[i]!=-1)?CONFIG_FunctionNumToName(MouseMapping[i]):"");
852 }
853
854 for (i=0;i<MAXMOUSEAXES*2;i++)
855 {
856 sprintf((char *)tempbuf, "MouseDigitalAxes%d_%d", i>>1, i&1);
857 SCRIPT_PutString(scripthandle, "Controls", (char *)tempbuf,
858 (MouseDigitalAxeMapping[i>>1][i&1]!=-1)?CONFIG_FunctionNumToName(MouseDigitalAxeMapping[i>>1][i&1]):"");
859 }
860
861 for(i=0; i<NUMGAMEFUNCTIONS; i++) // write keys
862 {
863 SCRIPT_PutDoubleString(
864 scripthandle,
865 "KeyDefinitions",
866 gamefunctions[i],
867 KB_ScanCodeToString( KeyMapping[i].key1 )?KB_ScanCodeToString( KeyMapping[i].key1 ):"",
868 KB_ScanCodeToString( KeyMapping[i].key2 )?KB_ScanCodeToString( KeyMapping[i].key2 ):"");
869 }
870
871 for(dummy=0;dummy<10;dummy++)
872 {
873 sprintf(buf,"WeaponChoice%d",dummy);
874 SCRIPT_PutNumber( scripthandle, "Misc",buf,ud.mywchoice[dummy],false,false);
875 }
876
877 dummy = CONTROL_GetMouseSensitivity_X();
878 SCRIPT_PutNumber( scripthandle, "Controls","MouseSensitivity_X_Rancid",dummy,false,false);
879
880 dummy = CONTROL_GetMouseSensitivity_Y();
881 SCRIPT_PutNumber( scripthandle, "Controls","MouseSensitivity_Y_Rancid",dummy,false,false);
882
883 SCRIPT_PutNumber( scripthandle, "Controls","ControllerType",ControllerType,false,false);
884
885 SCRIPT_PutString( scripthandle, "Comm Setup","PlayerName",myname);
886 SCRIPT_PutString( scripthandle, "Comm Setup","RTSName",ud.rtsname);
887
888 for(dummy = 0;dummy < 10;dummy++)
889 {
890 commmacro[13] = dummy+'0';
891 SCRIPT_PutString( scripthandle, "Comm Setup",commmacro,ud.ridecule[dummy]);
892 }
893
894 SCRIPT_Save (scripthandle, setupfilename);
895 SCRIPT_Free (scripthandle);
896 }
897
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/config.h b/apps/plugins/sdl/progs/duke3d/Game/src/config.h
new file mode 100644
index 0000000000..7e0852b20a
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/config.h
@@ -0,0 +1,46 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#ifndef _config_public
28#define _config_public
29
30#include <SDL.h>
31
32#define SETUPNAMEPARM "SETUPFILE"
33#define COMMMACRO "CommbatMacro# "
34
35extern int32_t ControllerType;
36extern int32_t MouseAiming;
37extern int32_t ScreenMode;
38extern int32_t ScreenWidth;
39extern int32_t ScreenHeight;
40extern int32_t BFullScreen;
41
42void CONFIG_ReadSetup( void );
43void CONFIG_GetSetupFilename( void );
44void CONFIG_WriteSetup( void );
45
46#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/console.c b/apps/plugins/sdl/progs/duke3d/Game/src/console.c
new file mode 100644
index 0000000000..229bb3b564
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/console.c
@@ -0,0 +1,630 @@
1#include "duke3d.h"
2#include "console.h"
3#include "cvars.h"
4#include "cvar_defs.h"
5#include <stdarg.h>
6
7// For autoexec.cfg
8#include <stdio.h>
9
10#define MAX_STRING_LENGTH 64
11#define MAX_CONSOLE_STRING_LENGTH 70
12#define MAX_CVAR_ARGS 10
13#define MAX_CONSOLE_VIEWABLE 10
14
15#define BUILD_NUMBER "Build 19"
16
17typedef struct console_element
18{
19 char text[MAX_CONSOLE_STRING_LENGTH];
20 void* prev;
21 void* next;
22}CONSOLEELEMENT;
23
24// Private member functions
25void CONSOLE_InsertUsedCommand(const char * szUsedCommand);
26void CONSOLE_ClearUsedCommandList();
27void CONSOLE_RecalculateDirtyBuffer();
28
29// console argument tracker
30int argc;
31char argv[MAX_CVAR_ARGS][MAX_CONSOLE_STRING_LENGTH];
32// Console entries, prepending linked list
33CONSOLEELEMENT *console_buffer = NULL;
34// Current viewed setion of the console
35CONSOLEELEMENT *p_console_current_view = NULL;
36// Previously entered commands:
37CONSOLEELEMENT *console_used_command_list = NULL;
38// Previously entered commands:
39CONSOLEELEMENT *console_used_command_list_current = NULL;
40
41// dirty buffer
42char dirty_buffer[MAX_CONSOLE_STRING_LENGTH];
43
44// dirty buffer control vars
45int console_cursor_pos = 0; //without spaces
46int console_num_spaces = 0; //number of spaces
47
48// Toggle for the console state
49int nConsole_Active = 0;
50
51void CVAR_RegisterDefaultCvarBindings(void);
52// Initialize the console
53void CONSOLE_Init()
54{
55 CONSOLE_Reset();
56
57 // Console Variable init
58 CVAR_RegisterDefaultCvarBindings();
59
60 // read in our startup.txt
61 CONSOLE_ParseStartupScript();
62
63 CONSOLE_Printf("Type \'HELP\' for help with console Commands.");
64}
65
66void CONSOLE_Reset()
67{
68 CONSOLEELEMENT *pElement;
69 CONSOLEELEMENT *pDelElement;
70
71 // Free the list if it exists
72 pElement = console_buffer;
73 while(pElement)
74 {
75 pDelElement = pElement;
76 pElement = (CONSOLEELEMENT*)pElement->next;
77
78 free(pDelElement);
79 }
80
81 console_buffer = NULL;
82 p_console_current_view = NULL;
83}
84
85void CONSOLE_Term()
86{
87 // Do any clean up releasing to the console
88 CONSOLE_Reset();
89 CONSOLE_ClearUsedCommandList();
90}
91
92void CONSOLE_ParseStartupScript()
93{
94 // FIX_00017: heavy autoexec.cfg not needed anymore.
95 char *sStartupScript = ENGINE_DIR "startup.cfg";
96
97 FILE* fp = fopen(sStartupScript, "r");
98
99 // If the file exists
100 if(NULL != fp)
101 {
102 char line[128];
103 memset(line, 0, 128);
104
105 while(fgets(line ,128-1, fp) != NULL)
106 {
107 CONSOLE_ParseCommand(line);
108
109 memset(line, 0, 128);
110 }
111 fclose(fp);
112 }
113}
114
115void CONSOLE_HandleInput()
116{
117 char * lastKey;
118 int tmp;
119
120 if(g_CV_classic)
121 {
122 nConsole_Active = 0;
123 return;
124 }
125
126 // See if we should toggle the console
127 if(ACTION(gamefunc_Console))
128 {
129 nConsole_Active = !nConsole_Active;
130
131 CONTROL_ClearAction(gamefunc_Console);
132 //KB_ClearKeyDown(sc_Tilde);
133
134
135 if(nConsole_Active)
136 {
137 // If this is a singleplayer game, let's pause the game when the console is active
138 if (numplayers == 1)
139 {
140 if (!ud.recstat) //check if we are not playing a Demo and console is active
141 {
142 ud.pause_on = 1;
143 }else
144 {
145 ud.pause_on = 0;
146 }
147 }
148 }
149 else
150 // Bug fix: make sure the frag bar displays after console
151 // is hidden
152 //if(!nConsole_Active)
153 {
154 if ( ud.multimode > 1 && ud.coop != 1 )
155 {
156 displayfragbar();
157 }
158 if(numplayers<2)
159 ud.pause_on = 0;
160 // FIX_00078: Out Of Synch error (multiplayer) when using console in pause mode
161 }
162
163 return;
164 }
165
166 // If the console is not active, there's no need to process input
167 if(!nConsole_Active)
168 {
169 return;
170 }
171
172 switch(KB_GetLastScanCode())
173 {
174 case sc_Space:
175 {
176 if(strlen(dirty_buffer) < MAX_CONSOLE_STRING_LENGTH-2)
177 {
178 strncat(dirty_buffer, " ", 1);
179 console_num_spaces++;
180 }
181 }
182 break;
183 case sc_Delete:
184 case sc_BackSpace:
185 {
186 tmp = strlen(dirty_buffer);
187 if(tmp > 0)
188 {
189 if( dirty_buffer[tmp - 1] == ' ' )
190 {
191 dirty_buffer[tmp - 1] = '\0';
192 console_num_spaces--;
193 }
194 else
195 {
196 dirty_buffer[tmp - 1] = '\0';
197 console_cursor_pos--;
198 }
199 }
200 }
201 break;
202 //Ignore list
203 case sc_LeftShift:
204 case sc_RightShift:
205 case sc_PrintScreen:
206 case sc_Tab:
207 case sc_NumLock:
208 case sc_LeftAlt:
209 case sc_LeftControl:
210 case sc_CapsLock:
211 case sc_Bad:
212 case sc_LeftArrow:
213 case sc_RightArrow:
214 case sc_Insert:
215 case sc_Home: //this should take us to the top of the list
216 case sc_RightAlt:
217 case sc_RightControl:
218 case sc_Tilde: //ignore
219 {
220 }break;
221 case sc_kpad_Enter:
222 case sc_Enter:
223 {
224 //If console_buffer[0] strlen() != 0
225 //1. Push the dirty_buffer unto the console_buffer
226 //2. parse the text
227 rb->kbd_input(dirty_buffer, sizeof(dirty_buffer));
228
229 CONSOLE_Printf("%s", dirty_buffer);
230 console_cursor_pos = 0;
231 console_num_spaces = 0;
232
233 CONSOLE_InsertUsedCommand(dirty_buffer);
234 CONSOLE_ParseCommand(dirty_buffer);
235
236 memset(dirty_buffer, 0, MAX_CONSOLE_STRING_LENGTH);
237
238 }break;
239 case sc_UpArrow:
240 {
241 /*
242 if(p_console_current_view->next != NULL)
243 {
244 p_console_current_view = p_console_current_view->next;
245 }
246 */
247 if(console_used_command_list_current == NULL)
248 {
249 if(NULL == console_used_command_list)
250 {
251 break;
252 }
253 console_used_command_list_current = console_used_command_list;
254 sprintf(dirty_buffer, "%s", console_used_command_list_current->text);
255 CONSOLE_RecalculateDirtyBuffer();
256 break;
257 }
258
259 if(console_used_command_list_current->next != NULL)
260 {
261 console_used_command_list_current = console_used_command_list_current->next;
262 sprintf(dirty_buffer, "%s", console_used_command_list_current->text);
263 CONSOLE_RecalculateDirtyBuffer();
264 }else
265 if(console_used_command_list_current != NULL)
266 {
267 sprintf(dirty_buffer, "%s", console_used_command_list_current->text);
268 CONSOLE_RecalculateDirtyBuffer();
269 }
270
271 }break;
272 case sc_PgUp:
273 case sc_A:
274 {
275 int i;
276 for(i = 0; i < MAX_CONSOLE_VIEWABLE; i++)
277 {
278 if(p_console_current_view->next != NULL)
279 {
280 p_console_current_view = p_console_current_view->next;
281 }
282 else
283 {
284 break;
285 }
286 }
287 }break;
288 case sc_DownArrow:
289 {
290 /*
291 if(p_console_current_view->prev != NULL)
292 {
293 p_console_current_view = p_console_current_view->prev;
294 }
295 */
296 if(console_used_command_list_current != NULL)
297 {
298 if(console_used_command_list_current->prev != NULL)
299 {
300 console_used_command_list_current = console_used_command_list_current->prev;
301 sprintf(dirty_buffer, "%s", console_used_command_list_current->text);
302 CONSOLE_RecalculateDirtyBuffer();
303 }
304 }
305 }break;
306 case sc_PgDn:
307 case sc_D:
308 {
309 int i;
310 for(i = 0; i < MAX_CONSOLE_VIEWABLE; i++)
311 {
312 if(p_console_current_view->prev != NULL)
313 {
314 p_console_current_view = p_console_current_view->prev;
315 }
316 else
317 {
318 break;
319 }
320 }
321 }break;
322 case sc_End:
323 {
324 p_console_current_view = console_buffer;
325 }break;
326 case sc_Escape:
327 {
328 nConsole_Active = 0;
329 KB_ClearKeyDown(sc_Escape);
330 // FIX_00057: Using ESC to get out of the console mode wouldn't take pause mode off
331 if(numplayers<2)
332 ud.pause_on = 0;
333 // FIX_00078: Out Of Synch error (multiplayer) when using console in pause mode
334 }break;
335 default:
336 {
337 if(strlen(dirty_buffer) < MAX_CONSOLE_STRING_LENGTH-2)
338 {
339 lastKey = KB_ScanCodeToString(KB_GetLastScanCode());
340
341 if(lastKey)
342 {
343 strncat(dirty_buffer, lastKey, 1);
344 console_cursor_pos++;
345 //printf("Key %s : %s\n", lastKey, console_buffer[0]);
346 }
347 }
348
349 }
350 break;
351 }
352
353
354 KB_ClearLastScanCode();
355}
356
357void CONSOLE_Render()
358{
359 if(g_CV_classic)
360 {
361 return;
362 }
363
364 // Let the Cvars draw something if they need to.
365 CVAR_Render();
366
367 if(nConsole_Active)
368 {
369 int x,y, y1, y2;
370 int i, iCurHeight = 0, iCurWidth = 0;
371 int iYOffset = 3; //offset for the console text
372 CONSOLEELEMENT *pElement;
373
374 y1 = 0;
375 y2 = (ydim / 2) - ((ydim / 2)/12);
376
377 // Draw console background
378 for(y=y1;y<y2;y+=128)
379 {
380 for(x=0;x<xdim;x+=128)
381 {
382 rotatesprite(x<<16,y<<16,65536L,0,BIGHOLE,8,0,(g_CV_TransConsole ? 1:0)+8+16+64+128,0,y1,xdim-1,y2-1);
383 }
384 }
385
386 // Draw bottom egde of console
387 rotatesprite(78<<16,94<<16,65536L,512,WINDOWBORDER1,24,0,2+8,0,0,xdim-1,ydim-1);
388 rotatesprite(238<<16,94<<16,65536L,512,WINDOWBORDER1,24,0,2+8,0,0,xdim-1,ydim-1);
389
390 // Draw the contents of the console buffer
391 pElement = p_console_current_view;//console_buffer;
392 for(i = 0; i < MAX_CONSOLE_VIEWABLE; i++)
393 {
394 if(!pElement)
395 {
396 break;
397 }
398
399 minitext(5,(8*(9-i)) + iYOffset,
400 pElement->text,
401 g_CV_console_text_color,
402 10+16);
403
404 pElement = (CONSOLEELEMENT*)pElement->next;
405
406 }
407
408 // Set the height of the new line
409 iCurHeight = (8*10) + iYOffset;
410
411 // Draw dirty buffer
412 minitext(5, iCurHeight, dirty_buffer, 0,10+16);
413
414 // Calculate the location of the cursor
415 iCurWidth = (console_cursor_pos*4) + (console_num_spaces*5) +5;
416
417 //Draw the version number
418 minitext(283, iCurHeight, BUILD_NUMBER, 17,10+16);
419
420 // Draw the cursor //Change the color every second
421 minitext(iCurWidth, iCurHeight,"_",(time(NULL)%2)+1,10+16);
422 }
423 else
424 if(g_CV_num_console_lines > 0)
425 {
426 int i, iYOffset = 3; //offset for the console text
427 CONSOLEELEMENT *pElement;
428 // Draw the contents of the console buffer
429 pElement = console_buffer;
430 for(i = 0; i < g_CV_num_console_lines; i++)
431 {
432 if(!pElement)
433 {
434 break;
435 }
436
437 minitext(5,(8*((g_CV_num_console_lines-1)-i)) + iYOffset,
438 pElement->text,
439 g_CV_console_text_color,
440 10+16);
441
442 pElement = (CONSOLEELEMENT*)pElement->next;
443 }
444 }
445}
446
447void CONSOLE_ParseCommand(char * command)
448{
449 char *cvar;
450 char *token;
451 int i, numCvars;
452 argc = 0;
453
454 if( strlen(command) < 1)
455 {
456 return;
457 }
458
459 // Split the command into cvar and args
460 cvar = strtok(command, " \r\n");
461
462 for(i = 0; i < MAX_CVAR_ARGS; i++)
463 {
464 token = strtok(NULL, " ");
465
466 if(!token)
467 {
468 break;
469 }
470
471 sprintf(argv[i], "%s", token);
472 argc++;
473 }
474
475 // Cycle through our cvar list and look for this keyword
476 numCvars = CVAR_GetNumCvarBindings();
477 for(i = 0; i < numCvars; i++)
478 {
479 cvar_binding* binding = CVAR_GetCvarBinding(i);
480
481 // Did we find it?
482 if ( strcmpi(cvar, binding->name) == 0 )
483 {
484 binding->function(binding);
485 break;
486 }
487 }
488
489}
490
491
492void CONSOLE_InsertUsedCommand(const char * szUsedCommand)
493{
494 //create a new element in the list, and add it to the front
495 CONSOLEELEMENT *pElement = (CONSOLEELEMENT*)malloc(sizeof(CONSOLEELEMENT));
496 if(pElement)
497 {
498 //Store our newly created member as the prev address
499 if(NULL != console_used_command_list)
500 {
501 console_used_command_list->prev = pElement;
502 }
503 // Set the next pointer to the front of the list
504 pElement->next = console_used_command_list;
505
506 console_used_command_list_current = NULL;//pElement;
507
508 // Prepend the entry. This entry is now the head of the list.
509 console_used_command_list = pElement;
510
511 // Make sure we NULL out the prev for our top level element
512 pElement->prev = NULL;
513
514 //sprintf(console_buffer->text, "%s", msg);
515 memset(console_used_command_list->text, 0, MAX_CONSOLE_STRING_LENGTH);
516 strncpy(console_used_command_list->text, szUsedCommand, MAX_CONSOLE_STRING_LENGTH-2);
517 }
518}
519
520void CONSOLE_ClearUsedCommandList()
521{
522 CONSOLEELEMENT *pElement;
523 CONSOLEELEMENT *pDelElement;
524
525 // Free the list if it exists
526 pElement = console_used_command_list;
527 while(pElement)
528 {
529 pDelElement = pElement;
530 pElement = (CONSOLEELEMENT*)pElement->next;
531
532 free(pDelElement);
533 }
534
535 console_used_command_list = NULL;
536 console_used_command_list_current = NULL;
537}
538
539
540void CONSOLE_RecalculateDirtyBuffer()
541{
542 int len;
543 int l;
544
545 console_cursor_pos = 0; //without spaces
546 console_num_spaces = 0; //number of spac
547
548 len = strlen(dirty_buffer);
549
550 for(l = 0; l < len; ++l)
551 {
552 if(dirty_buffer[l] == ' ')
553 {
554 ++console_num_spaces;
555 }
556 else
557 {
558 ++console_cursor_pos;
559 }
560 }
561}
562
563
564void CONSOLE_Printf(const char *newmsg, ...)
565{
566 CONSOLEELEMENT *pElement;
567 va_list argptr;
568 char msg[512];//[MAX_CONSOLE_STRING_LENGTH];
569 va_start (argptr,newmsg);
570 vsprintf (msg, newmsg, argptr);
571 va_end (argptr);
572
573 //create a new element in the list, and add it to the front
574 pElement = (CONSOLEELEMENT*)malloc(sizeof(CONSOLEELEMENT));
575 if(pElement)
576 {
577 //Store our newly created member as the prev address
578 if(NULL != console_buffer)
579 {
580 console_buffer->prev = pElement;
581 }
582 // Set the next pointer to the front of the list
583 pElement->next = console_buffer;
584
585 // Set our view, if they are at the bottom of the list.
586 // Otherwise, if we set it everytime, Folks might lose
587 // what they were looking for in the output, if they
588 // were using pgup and pgdn to scroll through the entries.
589 if(p_console_current_view == console_buffer)
590 {
591 p_console_current_view = pElement;
592 }
593
594 // Prepend the entry. This entry is now the head of the list.
595 console_buffer = pElement;
596
597 // Make sure we NULL out the prev for our top level element
598 pElement->prev = NULL;
599
600 //sprintf(console_buffer->text, "%s", msg);
601 memset(console_buffer->text, 0, MAX_CONSOLE_STRING_LENGTH);
602 strncpy(console_buffer->text, msg, MAX_CONSOLE_STRING_LENGTH-2);
603 }
604
605}
606
607// Get the current number of args for this keyword
608int CONSOLE_GetArgc()
609{
610 return argc;
611}
612
613// Get the current list of args for this keyword
614char * CONSOLE_GetArgv(unsigned int var)
615{
616 return argv[var];
617}
618
619// Is our console showing?
620int CONSOLE_IsActive()
621{
622
623 return nConsole_Active;
624}
625
626// Set our consople active or not.
627void CONSOLE_SetActive(int i)
628{
629 nConsole_Active = (i == 0) ? 0 : 1;
630} \ No newline at end of file
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/console.h b/apps/plugins/sdl/progs/duke3d/Game/src/console.h
new file mode 100644
index 0000000000..58c0e34b25
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/console.h
@@ -0,0 +1,19 @@
1#ifndef _CONSOLE_H_
2#define _CONSOLE_H_
3
4
5// Public member functions
6void CONSOLE_Init();
7void CONSOLE_Reset();
8void CONSOLE_Term();
9void CONSOLE_ParseStartupScript();
10void CONSOLE_HandleInput();
11void CONSOLE_Render();
12void CONSOLE_ParseCommand(char * command);
13void CONSOLE_Printf(const char *newmsg, ...);
14int CONSOLE_GetArgc();
15char * CONSOLE_GetArgv(unsigned int var);
16int CONSOLE_IsActive();
17void CONSOLE_SetActive(int i);
18
19#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/control.c b/apps/plugins/sdl/progs/duke3d/Game/src/control.c
new file mode 100644
index 0000000000..8cd332660a
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/control.c
@@ -0,0 +1,930 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26#include "duke3d.h"
27#include "control.h"
28#include "mouse.h"
29#include "joystick.h"
30
31//***************************************************************************
32//
33// GLOBALS
34//
35//***************************************************************************
36
37// FIX_00018: Removed the "smoothmouse" option. This was just a bad fix. Mouse is now faster,
38// smoother.
39// extern int g_CV_EnableSmoothMouse;
40// extern int g_CV_SmoothMouseSensX;
41// extern int g_CV_SmoothMouseSensY;
42
43uint32 CONTROL_RudderEnabled;
44boolean CONTROL_MousePresent;
45boolean CONTROL_JoysPresent[ MaxJoys ];
46boolean CONTROL_MouseEnabled;
47boolean CONTROL_JoystickEnabled;
48byte CONTROL_JoystickPort;
49uint32 CONTROL_MouseButtonState1;
50uint32 CONTROL_MouseButtonState2;
51// FIX_00019: DigitalAxis Handling now supported. (cool for medkit use)
52uint32 CONTROL_MouseDigitalAxisState1;
53uint32 CONTROL_MouseDigitalAxisState2;
54//uint32 CONTROL_ButtonHeldState1;
55//uint32 CONTROL_ButtonHeldState2;
56uint32 CONTROL_JoyButtonState1;
57uint32 CONTROL_JoyButtonState2;
58
59uint32 CONTROL_JoyHatState1; //[MAXJOYHATS];
60uint32 CONTROL_JoyHatState2; //[MAXJOYHATS];
61
62
63static short mouseButtons = 0;
64static short lastmousebuttons = 0;
65
66static short joyHats[MAXJOYHATS];
67static short lastjoyHats[MAXJOYHATS];
68
69static int32 mousePositionX = 0;
70static int32 mousePositionY = 0;
71static int32 mouseRelativeX = 0;
72static int32 mouseRelativeY = 0;
73
74//***************************************************************************
75//
76// FUNCTIONS
77//
78//***************************************************************************
79
80// Joystick/Gamepad bindings
81static int32 JoyAxisMapping[MAXJOYAXES];
82static int32 JoyHatMapping[MAXJOYHATS][8];
83static int32 JoyButtonMapping[MAXJOYBUTTONS];
84static float JoyAnalogScale[MAXJOYAXES];
85static int32 JoyAnalogDeadzone[MAXJOYAXES];
86
87
88
89int ACTION(int i)
90{
91
92 //Keyboard input
93 if( (KB_KeyDown[KeyMapping[i].key1]) ||
94 (KB_KeyDown[KeyMapping[i].key2])
95 )
96 {
97 return 1;
98 }
99
100
101 // Check mouse
102 if((ControllerType == controltype_keyboardandmouse) ||
103 (ControllerType == controltype_joystickandmouse))
104 {
105 //Mouse buttons
106 if ((i)>31)
107 {
108 if((CONTROL_MouseButtonState2>>( (i) - 32) ) & 1)
109 {
110 return 1;
111 }
112 }
113 else
114 {
115 if((CONTROL_MouseButtonState1>> (i) ) & 1)
116 {
117 return 1;
118 }
119 }
120
121 // FIX_00019: DigitalAxis Handling now supported. (cool for medkit use)
122
123 //Mouse Digital Axes
124 if ((i)>31)
125 {
126 if((CONTROL_MouseDigitalAxisState2>>( (i) - 32) ) & 1)
127 {
128 return 1;
129 }
130 }
131 else
132 {
133 if((CONTROL_MouseDigitalAxisState1>> (i) ) & 1)
134 {
135 return 1;
136 }
137 }
138 }
139
140
141 // Check joystick
142 if((ControllerType == controltype_keyboardandjoystick) ||
143 (ControllerType == controltype_joystickandmouse)
144 )
145 {
146
147 if ((i)>31)
148 {
149 // Check the joystick
150 if( (CONTROL_JoyButtonState2 >> (i - 32)) & 1)
151 {
152 return 1;
153 }
154
155 // Check the hats
156 if( (CONTROL_JoyHatState2 >> (i - 32)) & 1)
157 {
158 return 1;
159 }
160
161 }
162 else
163 {
164 if( (CONTROL_JoyButtonState1 >> i) & 1)
165 {
166 return 1;
167 }
168
169 // Check the hats
170 if( (CONTROL_JoyHatState1 >> i) & 1)
171 {
172 return 1;
173 }
174 }
175
176 }
177
178 return 0;
179}
180
181
182int RESET_ACTION(int i)
183{
184 KB_KeyDown[KeyMapping[i].key1] = 0;
185 KB_KeyDown[KeyMapping[i].key2] = 0;
186
187 return 0;
188}
189
190static void SETMOUSEBUTTON(int i)
191{
192
193 //CONTROL_MouseButtonState1 |= (1<<i);
194
195 int b;
196
197 if (i < 32)
198 {
199 b = 1 << i;
200
201 CONTROL_MouseButtonState1 |= b;
202 }
203 else
204 {
205 i -= 32;
206
207 b = 1 << i;
208
209 CONTROL_MouseButtonState2 |= b;
210 }
211
212}
213
214void RESMOUSEBUTTON(int i)
215{
216
217 //CONTROL_MouseButtonState1 &= ~(1<<i);
218
219 int b;
220
221 if (i < 32) {
222 b = 1 << i;
223
224 CONTROL_MouseButtonState1 &= ~b;
225 } else {
226 i -= 32;
227
228 b = 1 << i;
229
230 CONTROL_MouseButtonState2 &= ~b;
231 }
232
233}
234
235// FIX_00019: DigitalAxis Handling now supported. (cool for medkit use)
236
237void SETMOUSEDIGITALAXIS(int i)
238{
239
240 int b;
241
242 if (i<0)
243 return;
244
245 if (i < 32)
246 {
247 b = 1 << i;
248 CONTROL_MouseDigitalAxisState1 |= b;
249 }
250 else
251 {
252 i -= 32;
253 b = 1 << i;
254 CONTROL_MouseDigitalAxisState2 |= b;
255 }
256}
257
258void RESMOUSEDIGITALAXIS(int i)
259{
260
261 int b;
262
263 if (i<0)
264 return;
265
266 if (i < 32)
267 {
268 b = 1 << i;
269 CONTROL_MouseDigitalAxisState1 &= ~b;
270 }
271 else
272 {
273 i -= 32;
274 b = 1 << i;
275 CONTROL_MouseDigitalAxisState2 &= ~b;
276 }
277}
278
279static void SETJOYBUTTON(int i)
280{
281 //CONTROL_JoyButtonState |= (1<<i);
282 int b;
283
284 if (i < 32)
285 {
286 b = 1 << i;
287
288 CONTROL_JoyButtonState1 |= b;
289 }
290 else
291 {
292 i -= 32;
293
294 b = 1 << i;
295
296 CONTROL_JoyButtonState2 |= b;
297 }
298}
299static void RESJOYBUTTON(int i)
300{
301 int b;
302
303 if (i < 32) {
304 b = 1 << i;
305
306 CONTROL_JoyButtonState1 &= ~b;
307 } else {
308 i -= 32;
309
310 b = 1 << i;
311
312 CONTROL_JoyButtonState2 &= ~b;
313 }
314}
315
316static void SETHATBUTTON(int i)
317{
318 //CONTROL_JoyHatState1 |= (1<<i);
319
320 int b;
321
322 if (i < 32)
323 {
324 b = 1 << i;
325
326 CONTROL_JoyHatState1 |= b;
327 }
328 else
329 {
330 i -= 32;
331
332 b = 1 << i;
333
334 CONTROL_JoyHatState2 |= b;
335 }
336}
337
338static void RESHATBUTTON(int i)
339{
340
341 //CONTROL_JoyHatState1 &= ~(1<<i);
342 int b;
343
344 if (i < 32) {
345 b = 1 << i;
346
347 CONTROL_JoyHatState1 &= ~b;
348 } else {
349 i -= 32;
350
351 b = 1 << i;
352
353 CONTROL_JoyHatState2 &= ~b;
354 }
355}
356
357void CONTROL_UpdateKeyboardState(int key, int pressed)
358{
359 /*
360
361 if(pressed)
362 {
363 CONTROL_KeyStates[key] = 1;
364 }
365 else
366 {
367 CONTROL_KeyStates[key] = 0;
368 }
369 */
370 /*
371 int i;
372
373 for (i = 0; i < MAXGAMEBUTTONS; i++)
374 {
375 if (KeyMapping[i].key_active == false)
376 {
377 continue;
378 }
379
380 if (KeyMapping[i].key1 == key ||
381 KeyMapping[i].key2 == key)
382 {
383
384 if (pressed)
385 {
386 SETBUTTON(i);
387 }
388 else
389 {
390 RESBUTTON(i);
391 }
392 }
393 }
394 */
395}
396
397void CONTROL_MapKey( int32 which, kb_scancode key1, kb_scancode key2 )
398{
399 // FIX_00020: Protect you from assigning a function to the ESC key through duke3d.cfg
400 if(key1==sc_Escape || key2==sc_Escape)
401 {
402 if(key1==sc_Escape)
403 key1=0;
404 else
405 key2=0;
406
407 printf("Discarding ESCAPE key for function : %s\n", gamefunctions[which]);
408 }
409
410 if(key1 || key2)
411 KeyMapping[which].key_active = true;
412 else
413 KeyMapping[which].key_active = false;
414
415 KeyMapping[which].key1 = key1;
416 KeyMapping[which].key2 = key2;
417}
418
419void CONTROL_MapButton
420 (
421 int32 whichfunction,
422 int32 whichbutton,
423 boolean clicked_or_doubleclicked
424 )
425{
426 if(clicked_or_doubleclicked)
427 return; // TODO
428
429 if(whichbutton < 0 || whichbutton >= MAXMOUSEBUTTONS)
430 return;
431
432 MouseMapping[whichbutton] = whichfunction;
433}
434
435void CONTROL_MapJoyButton(int32 whichfunction, int32 whichbutton, boolean doubleclicked)
436{
437 if(whichbutton < 0 || whichbutton >= MAXJOYBUTTONS)
438 {
439 return;
440 }
441
442 if(doubleclicked)
443 return; // TODO
444
445 JoyButtonMapping[whichbutton] = whichfunction;
446}
447
448void CONTROL_MapJoyHat(int32 whichfunction, int32 whichhat, int32 whichvalue)
449{
450 if(whichhat < 0 || whichhat >= MAXJOYHATS)
451 {
452 return;
453 }
454
455 JoyHatMapping[whichhat][whichvalue] = whichfunction;
456}
457
458void CONTROL_DefineFlag( int32 which, boolean toggle )
459{
460 // STUBBED("CONTROL_DefineFlag");
461}
462
463boolean CONTROL_FlagActive( int32 which )
464{
465 STUBBED("CONTROL_FlagActive");
466 return false;
467}
468
469void CONTROL_ClearAssignments( void )
470{
471 STUBBED("CONTROL_ClearAssignments");
472}
473
474void CONTROL_GetUserInput( UserInput *info )
475{
476 STUBBED("CONTROL_GetUserInput");
477}
478
479void CONTROL_GetInput( ControlInfo *info )
480{
481 int32 sens_X = CONTROL_GetMouseSensitivity_X();
482 int32 sens_Y = CONTROL_GetMouseSensitivity_Y();
483 int32 mx = 0, my = 0;
484 int i, j;
485
486 memset(info, '\0', sizeof (ControlInfo));
487
488 //info->dx = info->dz = 0;
489
490 _handle_events(); // get the very last mouse position before reading it.
491 MOUSE_GetDelta(&mx,&my);
492
493 //GetCursorPos(&point);
494 // SDL_GetMouseState(&x, &y);
495 // SDL_WarpMouse(160, 100);
496 //mx = (-xx+point.x)<<2;
497 //my = (-yy+point.y)<<2;
498 //xx=point.x; yy=point.y;
499
500 info->dyaw = (mx * sens_X);
501
502 switch(ControllerType)
503 {
504 case controltype_keyboardandjoystick:
505 {
506 }
507 break;
508
509 case controltype_joystickandmouse:
510 // Not sure what I was thinking here...
511 // Commented this out because it totally breaks smooth mouse etc...
512 /*
513 {
514 // Mouse should use pitch instead of forward movement.
515 info->dpitch = my * sens*2;
516 }
517 break;
518 */
519
520 default:
521 {
522 // If mouse aim is active
523 if( myaimmode )
524 {
525 // FIX_00052: Y axis for the mouse is now twice as sensitive as before
526 info->dpitch = (my * sens_Y * 2);
527 }
528 else
529 {
530 info->dz = (my * sens_Y * 2);
531 }
532 }
533 break;
534 }
535
536
537 // TODO: releasing the mouse button does not honor if a keyboard key with
538 // the same function is still pressed. how should it?
539 for(i=0; i<MAXMOUSEBUTTONS;++i)
540 {
541 if( MouseMapping[i] != -1 )
542 {
543 if(!(lastmousebuttons & (1<<i)) && mouseButtons & (1<<i))
544 {
545 SETMOUSEBUTTON(MouseMapping[i]); //MouseMapping[i]
546 //printf("mouse button: %d\n", i);
547 }
548 else if(lastmousebuttons & (1<<i) && !(mouseButtons & (1<<i)))
549 {
550 RESMOUSEBUTTON(MouseMapping[i]);//MouseMapping[i]
551 }
552 }
553 }
554 lastmousebuttons = mouseButtons;
555
556 // FIX_00019: DigitalAxis Handling now supported. (cool for medkit use)
557 // update digital axis
558 RESMOUSEDIGITALAXIS(MouseDigitalAxeMapping[0][0]);
559 RESMOUSEDIGITALAXIS(MouseDigitalAxeMapping[0][1]);
560 RESMOUSEDIGITALAXIS(MouseDigitalAxeMapping[1][0]);
561 RESMOUSEDIGITALAXIS(MouseDigitalAxeMapping[1][1]);
562
563 if (mx < 0)
564 {
565 SETMOUSEDIGITALAXIS(MouseDigitalAxeMapping[0][0]);
566 }
567 else if (mx > 0)
568 {
569 SETMOUSEDIGITALAXIS(MouseDigitalAxeMapping[0][1]);
570 }
571
572 if (my < 0)
573 {
574 SETMOUSEDIGITALAXIS(MouseDigitalAxeMapping[1][0]);
575 }
576 else if (my > 0)
577 {
578 SETMOUSEDIGITALAXIS(MouseDigitalAxeMapping[1][1]);
579 }
580
581 // update stick state.
582 if ((CONTROL_JoystickEnabled) && (_joystick_update()))
583 {
584
585 // Check the hats
586 JOYSTICK_UpdateHats();
587
588 // TODO: make this NOT use the BUTTON() system for storing the hat input. (requires much game code changing)
589 for(i=0; i<MAXJOYHATS; i++)
590 {
591
592 for(j=0; j<8; j++)
593 {
594 if(!(lastjoyHats[i] & (1<<j)) && (joyHats[i] & (1<<j)))
595 {
596 SETHATBUTTON(JoyHatMapping[i][j]);
597 }
598 else if((lastjoyHats[i] & (1<<j)) && !(joyHats[i] & (1<<j)))
599 {
600 RESHATBUTTON(JoyHatMapping[i][j]);
601 }
602 }
603
604 lastjoyHats[i] = joyHats[i];
605 }
606
607
608 for(i=0; i<MAXJOYAXES;i++)
609 {
610 switch(JoyAxisMapping[i])
611 {
612 case analog_turning:
613 {
614 info->dyaw += (int32)((float)CONTROL_FilterDeadzone
615 (
616 _joystick_axis(i),
617 JoyAnalogDeadzone[i]
618 )
619 * JoyAnalogScale[i]
620 );
621 }
622 break;
623 case analog_strafing:
624 {
625 info->dx += (int32)((float)CONTROL_FilterDeadzone
626 (
627 _joystick_axis(i),
628 JoyAnalogDeadzone[i]
629 )
630 * JoyAnalogScale[i]
631 );
632 //printf("Joy %d = %d\n", i, info->dx);
633 }
634 break;
635 case analog_lookingupanddown:
636 info->dpitch += (int32)((float)CONTROL_FilterDeadzone
637 (
638 _joystick_axis(i),
639 JoyAnalogDeadzone[i]
640 )
641 * JoyAnalogScale[i]
642 );
643 break;
644 case analog_elevation: //STUB
645 break;
646 case analog_rolling: //STUB
647 break;
648 case analog_moving:
649 {
650 info->dz += (int32)((float)CONTROL_FilterDeadzone
651 (
652 _joystick_axis(i),
653 JoyAnalogDeadzone[i]
654 )
655 * JoyAnalogScale[i]
656 );
657 }
658 break;
659 default:
660 break;
661 }
662 }
663
664 // !!! FIXME: Do this.
665 //SETBUTTON based on _joystick_button().
666 for(i=0; i<MAXJOYBUTTONS;++i)
667 {
668 if(_joystick_button(i))
669 {
670 SETJOYBUTTON(JoyButtonMapping[i]);
671 }
672 else
673 {
674 RESJOYBUTTON(JoyButtonMapping[i]);
675 }
676 }
677
678 }
679}
680
681void CONTROL_ClearAction( int32 whichbutton )
682{
683 //RESBUTTON(whichbutton);
684 KB_KeyDown[KeyMapping[whichbutton].key1] = 0;
685 KB_KeyDown[KeyMapping[whichbutton].key2] = 0;
686
687 RESJOYBUTTON(whichbutton);
688 RESHATBUTTON(whichbutton);
689
690 RESMOUSEDIGITALAXIS(whichbutton);
691
692}
693
694void CONTROL_ClearUserInput( UserInput *info )
695{
696 STUBBED("CONTROL_ClearUserInput");
697}
698
699void CONTROL_WaitRelease( void )
700{
701 STUBBED("CONTROL_WaitRelease");
702}
703
704void CONTROL_Ack( void )
705{
706 STUBBED("CONTROL_Ack");
707}
708
709void CONTROL_CenterJoystick
710 (
711 void ( *CenterCenter )( void ),
712 void ( *UpperLeft )( void ),
713 void ( *LowerRight )( void ),
714 void ( *CenterThrottle )( void ),
715 void ( *CenterRudder )( void )
716 )
717{
718 STUBBED("CONTROL_CenterJoystick");
719}
720
721
722int32 CONTROL_GetMouseSensitivity_X( void )
723{
724 return mouseSensitivity_X;
725}
726
727void CONTROL_SetMouseSensitivity_X( int32 newsensitivity )
728{
729 mouseSensitivity_X = newsensitivity;
730}
731
732// FIX_00014: Added Y cursor setup for mouse sensitivity in the menus
733int32 CONTROL_GetMouseSensitivity_Y( void )
734{
735 return mouseSensitivity_Y;
736}
737
738void CONTROL_SetMouseSensitivity_Y( int32 newsensitivity )
739{
740 mouseSensitivity_Y = newsensitivity;
741}
742
743void CONTROL_Startup
744 (
745 controltype which,
746 int32 ( *TimeFunction )( void ),
747 int32 ticspersecond
748 )
749{
750 int i;
751
752 // Init the joystick
753 _joystick_init();
754
755 for(i=0; i < MAXJOYHATS; i++)
756 {
757 joyHats[i] = 0;
758 lastjoyHats[i] = 0;
759 }
760
761 CONTROL_MouseButtonState1 = 0;
762 CONTROL_MouseButtonState2 = 0;
763 CONTROL_MouseDigitalAxisState1 = 0;
764 CONTROL_MouseDigitalAxisState2 = 0;
765 CONTROL_JoyButtonState1 = 0;
766 CONTROL_JoyButtonState2 = 0;
767 CONTROL_JoyHatState1 = 0;
768 CONTROL_JoyHatState2 = 0;
769}
770
771void CONTROL_Shutdown( void )
772{
773 _joystick_deinit();
774}
775
776
777void CONTROL_MapAnalogAxis
778 (
779 int32 whichaxis,
780 int32 whichanalog
781 )
782{
783 //STUBBED("CONTROL_MapAnalogAxis");
784 if(whichaxis < MAXJOYAXES)
785 {
786 JoyAxisMapping[whichaxis] = whichanalog;
787 }
788}
789
790// FIX_00019: DigitalAxis Handling now supported. (cool for medkit use)
791void CONTROL_MapDigitalAxis
792 (
793 int32 whichaxis,
794 int32 whichfunction,
795 int32 direction
796 )
797{
798 if(whichaxis < 0 || whichaxis >= MAXMOUSEAXES || direction < 0 || direction >= 2)
799 return;
800
801 MouseDigitalAxeMapping[whichaxis][direction] = whichfunction;
802
803}
804
805void CONTROL_SetAnalogAxisScale
806 (
807 int32 whichaxis,
808 float axisscale
809 )
810{
811 if(whichaxis < MAXJOYAXES)
812 {
813 // Set it... make sure we don't let them set it to 0.. div by 0 is bad.
814 JoyAnalogScale[whichaxis] = (axisscale == 0) ? 1.0f : axisscale;
815 }
816}
817
818void CONTROL_SetAnalogAxisDeadzone
819 (
820 int32 whichaxis,
821 int32 axisdeadzone
822 )
823{
824 if(whichaxis < MAXJOYAXES)
825 {
826 // Set it...
827 JoyAnalogDeadzone[whichaxis] = axisdeadzone;
828 }
829}
830
831int32 CONTROL_FilterDeadzone
832 (
833 int32 axisvalue,
834 int32 axisdeadzone
835 )
836{
837 if((axisvalue < axisdeadzone) && (axisvalue > -axisdeadzone))
838 {
839 return 0;
840 }
841
842 return axisvalue;
843}
844
845int32 CONTROL_GetFilteredAxisValue(int32 axis)
846{
847return (int32)((float)CONTROL_FilterDeadzone
848 (
849 _joystick_axis(axis),
850 JoyAnalogDeadzone[axis]
851 )
852 * JoyAnalogScale[axis]
853 );
854}
855
856
857void CONTROL_PrintAxes( void )
858{
859 STUBBED("CONTROL_PrintAxes");
860}
861
862boolean MOUSE_Init( void )
863{
864 memset(MouseMapping,-1,sizeof(MouseMapping));
865 memset(MouseDigitalAxeMapping, -1, sizeof(MouseDigitalAxeMapping));
866 return true;
867}
868
869void MOUSE_Shutdown( void )
870{
871 STUBBED("MOUSE_Shutdown");
872}
873
874void MOUSE_ShowCursor( void )
875{
876 STUBBED("MOUSE_ShowCursor");
877}
878
879void MOUSE_HideCursor( void )
880{
881 STUBBED("MOUSE_HideCursor");
882}
883
884static void updateMouse(void)
885{
886 // this is in buildengine.
887 short x, y;
888 getmousevalues(&x, &y, &mouseButtons);
889
890 mouseRelativeX += x;
891 mouseRelativeY += y;
892 mousePositionX += x;
893 mousePositionY += y;
894}
895
896int32 MOUSE_GetButtons( void )
897{
898 //updateMouse();
899 return ((int32) mouseButtons);
900}
901
902void MOUSE_GetPosition( int32*x, int32*y )
903{
904 if (x) *x = mousePositionX;
905 if (y) *y = mousePositionY;
906}
907
908void MOUSE_GetDelta( int32*x, int32*y )
909{
910 updateMouse();
911
912 if (x) *x = mouseRelativeX;
913 if (y) *y = mouseRelativeY;
914
915 mouseRelativeX = 0;
916 mouseRelativeY = 0;
917}
918
919void JOYSTICK_UpdateHats()
920{
921 int i;
922
923 for(i=0; i<MAXJOYHATS; i++)
924 {
925 //for(j=0; j<8; j++)
926 //{
927 joyHats[i] = _joystick_hat(i);
928 //}
929 }
930}
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/control.h b/apps/plugins/sdl/progs/duke3d/Game/src/control.h
new file mode 100644
index 0000000000..27445d227e
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/control.h
@@ -0,0 +1,265 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27//***************************************************************************
28//
29// Public header for CONTROL.C.
30//
31//***************************************************************************
32
33#ifndef _control_public
34#define _control_public
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39
40//***************************************************************************
41//
42// DEFINES
43//
44//***************************************************************************
45
46#define MaxJoys 2
47#define MAXGAMEBUTTONS 64
48
49 /*
50#define BUTTON(x) \
51 ( \
52 ((x)>31) ? \
53 ((CONTROL_ButtonState2>>( (x) - 32) ) & 1) :\
54 ((CONTROL_ButtonState1>> (x) ) & 1) \
55 )
56 */
57 /*
58#define BUTTONHELD(x) \
59 ( \
60 ((x)>31) ? \
61 ((CONTROL_ButtonHeldState2>>((x)-32)) & 1) :\
62 ((CONTROL_ButtonHeldState1>>(x)) & 1)\
63 )
64#define BUTTONJUSTPRESSED(x) \
65 ( BUTTON( x ) && !BUTTONHELD( x ) )
66#define BUTTONRELEASED(x) \
67 ( !BUTTON( x ) && BUTTONHELD( x ) )
68#define BUTTONSTATECHANGED(x) \
69 ( BUTTON( x ) != BUTTONHELD( x ) )
70 */
71
72//***************************************************************************
73//
74// TYPEDEFS
75//
76//***************************************************************************
77typedef enum
78 {
79 axis_up,
80 axis_down,
81 axis_left,
82 axis_right
83 } axisdirection;
84
85typedef enum
86 {
87 analog_turning=0,
88 analog_strafing=1,
89 analog_lookingupanddown=2,
90 analog_elevation=3,
91 analog_rolling=4,
92 analog_moving=5,
93 analog_maxtype
94 } analogcontrol;
95
96typedef enum
97 {
98 dir_North,
99 dir_NorthEast,
100 dir_East,
101 dir_SouthEast,
102 dir_South,
103 dir_SouthWest,
104 dir_West,
105 dir_NorthWest,
106 dir_None
107 } direction;
108
109typedef struct
110 {
111 boolean button0;
112 boolean button1;
113 direction dir;
114 } UserInput;
115
116
117typedef struct
118 {
119 fixed dx;
120 fixed dy;
121 fixed dz;
122 fixed dyaw;
123 fixed dpitch;
124 fixed droll;
125 } ControlInfo;
126
127/*
128typedef struct
129 {
130 float dx;
131 float dy;
132 float dz;
133 float dyaw;
134 float dpitch;
135 float droll;
136 } ControlInfo;
137*/
138
139typedef enum
140 {
141 controltype_keyboard,
142 controltype_keyboardandmouse,
143 controltype_keyboardandjoystick,
144 controltype_keyboardandexternal,
145 controltype_keyboardandgamepad,
146 controltype_keyboardandflightstick,
147 controltype_keyboardandthrustmaster,
148 controltype_joystickandmouse
149 } controltype;
150
151
152//***************************************************************************
153//
154// GLOBALS
155//
156//***************************************************************************
157
158extern uint32 CONTROL_RudderEnabled;
159extern boolean CONTROL_MousePresent;
160extern boolean CONTROL_JoysPresent[ MaxJoys ];
161extern boolean CONTROL_MouseEnabled;
162extern boolean CONTROL_JoystickEnabled;
163extern byte CONTROL_JoystickPort;
164extern uint32 CONTROL_MouseButtonState1;
165extern uint32 CONTROL_MouseButtonState2;
166//extern uint32 CONTROL_ButtonHeldState1;
167//extern uint32 CONTROL_ButtonHeldState2;
168extern uint32 CONTROL_JoyButtonState;
169
170//***************************************************************************
171//
172// PROTOTYPES
173//
174//***************************************************************************
175struct _KeyMapping
176{
177 boolean key_active;
178 kb_scancode key1;
179 kb_scancode key2;
180
181 /* other mappings go here */
182} KeyMapping[MAXGAMEBUTTONS];
183
184int32 MouseMapping[MAXMOUSEBUTTONS];
185int32 MouseDigitalAxeMapping[MAXMOUSEAXES][2]; // [axesX/Y][directionLeft/Right or directionUp/Down]
186
187
188int ACTION(int i);
189int RESET_ACTION(int i);
190void RESBUTTON(int i);
191void CONTROL_MapKey( int32 which, kb_scancode key1, kb_scancode key2 );
192void CONTROL_MapButton
193 (
194 int32 whichfunction,
195 int32 whichbutton,
196 boolean clicked_or_doubleclicked
197 );
198void CONTROL_MapJoyButton(int32 whichfunction, int32 whichbutton, boolean doubleclicked);
199void CONTROL_MapJoyHat(int32 whichfunction, int32 whichhat, int32 whichvalue);
200void CONTROL_DefineFlag( int32 which, boolean toggle );
201boolean CONTROL_FlagActive( int32 which );
202void CONTROL_ClearAssignments( void );
203void CONTROL_GetUserInput( UserInput *info );
204void CONTROL_GetInput( ControlInfo *info );
205void CONTROL_ClearAction( int32 whichbutton );
206void CONTROL_ClearUserInput( UserInput *info );
207void CONTROL_WaitRelease( void );
208void CONTROL_Ack( void );
209void CONTROL_CenterJoystick
210 (
211 void ( *CenterCenter )( void ),
212 void ( *UpperLeft )( void ),
213 void ( *LowerRight )( void ),
214 void ( *CenterThrottle )( void ),
215 void ( *CenterRudder )( void )
216 );
217int32 CONTROL_GetMouseSensitivity_X( void );
218void CONTROL_SetMouseSensitivity_X( int32 newsensitivity );
219int32 CONTROL_GetMouseSensitivity_Y( void );
220void CONTROL_SetMouseSensitivity_Y( int32 newsensitivity );
221void CONTROL_Startup
222 (
223 controltype which,
224 int32 ( *TimeFunction )( void ),
225 int32 ticspersecond
226 );
227void CONTROL_Shutdown( void );
228
229void CONTROL_MapAnalogAxis
230 (
231 int32 whichaxis,
232 int32 whichanalog
233 );
234
235void CONTROL_MapDigitalAxis
236 (
237 int32 whichaxis,
238 int32 whichfunction,
239 int32 direction
240 );
241void CONTROL_SetAnalogAxisScale
242 (
243 int32 whichaxis,
244 float axisscale
245 );
246void CONTROL_SetAnalogAxisDeadzone
247 (
248 int32 whichaxis,
249 int32 axisdeadzone
250 );
251int32 CONTROL_FilterDeadzone
252 (
253 int32 axisvalue,
254 int32 axisdeadzone
255 );
256int32 CONTROL_GetFilteredAxisValue(int32 axis);
257void CONTROL_PrintAxes( void );
258
259void CONTROL_UpdateKeyboardState(int key, int pressed);
260
261#ifdef __cplusplus
262};
263#endif
264#endif
265
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/cvar_defs.c b/apps/plugins/sdl/progs/duke3d/Game/src/cvar_defs.c
new file mode 100644
index 0000000000..3703e142a7
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/cvar_defs.c
@@ -0,0 +1,357 @@
1#include <stdlib.h>
2
3#include "cvars.h"
4#include "cvar_defs.h"
5#include "console.h"
6
7// Required for certain cvars
8#include "../../Game/src/types.h"
9#include "../../Engine/src/build.h"
10#include "funct.h"
11
12//We need a way to access duke to change the level
13#include "duke3d.h"
14
15
16//We need to access debug soundinfo
17#include "sounddebugdefs.h"
18
19#include "joystick.h"
20
21#include "audiolib/music.h"
22
23// Bind our Cvars at startup. You can still add bindings after this call, but
24// it is recommanded that you bind your default CVars here.
25void CVARDEFS_Init()
26{
27 g_CV_console_text_color = 0; // Set default value
28 REGCONVAR("SetConsoleColor", " - Change console color.",g_CV_console_text_color, CVARDEFS_DefaultFunction);
29
30 g_CV_num_console_lines = 0; // Set default value
31 REGCONVAR("NumConsoleLines", " - Number of visible console lines.", g_CV_num_console_lines, CVARDEFS_DefaultFunction);
32
33 g_CV_classic = 0; // Set default value
34 REGCONVAR("Classic", " - Enable Classic Mode.", g_CV_classic, CVARDEFS_DefaultFunction);
35
36 // FIX_00022b: Sound effects are now sharper and they sound as in the real DOS duke3d.
37 g_CV_CubicInterpolation = 0; // Set default value
38 REGCONVAR("EnableCubic", " - Turn on/off Cubic Interpolation for VOCs.", g_CV_CubicInterpolation, CVARDEFS_DefaultFunction);
39
40 g_CV_TransConsole = 1; // Set default value
41 REGCONVAR("TransConsole", " - Toggle the transparency of the console", g_CV_TransConsole, CVARDEFS_DefaultFunction);
42
43 g_CV_DebugJoystick = 0;
44 REGCONVAR("DebugJoystick", " - Displays info on the active Joystick", g_CV_DebugJoystick, CVARDEFS_DefaultFunction);
45
46 sounddebugActiveSounds = 0;
47 sounddebugAllocateSoundCalls = 0;
48 sounddebugDeallocateSoundCalls = 0;
49 g_CV_DebugSound = 0;
50 REGCONVAR("DebugSound", " - Displays info on the active Sounds", g_CV_DebugSound, CVARDEFS_DefaultFunction);
51
52 g_CV_DebugFileAccess = 0;
53 REGCONVAR("DebugFileAccess", " - Displays info on file access", g_CV_DebugFileAccess, CVARDEFS_DefaultFunction);
54
55 REGCONVAR("TickRate", " - Changes the tick rate", g_iTickRate, CVARDEFS_DefaultFunction);
56 REGCONVAR("TicksPerFrame", " - Changes the ticks per frame", g_iTicksPerFrame, CVARDEFS_DefaultFunction);
57
58 REGCONFUNC("Quit", " - Quit game.", CVARDEFS_FunctionQuit);
59 REGCONFUNC("Clear", " - Clear the console.", CVARDEFS_FunctionClear);
60 REGCONFUNC("Name", " - Change player name.", CVARDEFS_FunctionName);
61 REGCONFUNC("Level", " - Change level. Args: Level <episode> <mission>", CVARDEFS_FunctionLevel);
62 REGCONFUNC("PlayMidi"," - Plays a MIDI file", CVARDEFS_FunctionPlayMidi);
63
64 REGCONFUNC("Help"," - Print out help commands for console", CVARDEFS_FunctionHelp);
65}
66
67// I any of the Cvars need to render.. to it here.
68void CVARDEFS_Render()
69{
70 if(g_CV_DebugJoystick)
71 {
72 int i;
73 char buf[128];
74 minitext(2, 2, "Debug Joystick", 17,10+16);
75
76 for(i = 0; i < MAXJOYAXES; i++)
77 {
78 sprintf(buf, "Joystick Axis%d: Raw: %d Used:%d", i,_joystick_axis(i), CONTROL_GetFilteredAxisValue(i));
79 minitext(2, (i*8)+12, buf, 23,10+16);
80 }
81
82 for(i = 0; i < MAXJOYBUTTONS; i++)
83 {
84 sprintf(buf, "Button%d: %d", i, _joystick_button(i));
85 if(i < (MAXJOYBUTTONS/2))
86 {
87 minitext(2, (i*8)+(MAXJOYAXES*8)+12, buf, 23,10+16);
88 }
89 else
90 {
91 minitext(55, ((i-16)*8)+(MAXJOYAXES*8)+12, buf, 23,10+16);
92 }
93 }
94
95 for(i = 0; i < MAXJOYHATS; i++)
96 {
97 sprintf(buf, "Hat%d: %d", i, _joystick_hat(i));
98 minitext(110, (i*8)+(MAXJOYAXES*8)+12, buf, 23,10+16);
99 }
100
101
102 }
103
104 if(g_CV_DebugSound)
105 {
106 char buf[128];
107 minitext(2, 2, "Debug Sound", 17,10+16);
108
109 sprintf(buf, "Active sounds: %u", sounddebugActiveSounds);
110 minitext(2, 10, buf, 23,10+16);
111
112 sprintf(buf, "Allocate Calls: %u", sounddebugAllocateSoundCalls);
113 minitext(2, 18, buf, 23,10+16);
114
115 sprintf(buf, "Deallocate Calls: %d", sounddebugDeallocateSoundCalls);
116 minitext(2, 26, buf, 23,10+16);
117 }
118
119}
120
121// For default int functions
122// If your CVAR should simply change a global 'int' variable,
123// Then, use this function.
124void CVARDEFS_DefaultFunction(void* var)
125{
126 int argc;
127 cvar_binding* binding = (cvar_binding*)var;
128
129 argc = CONSOLE_GetArgc();
130
131 if(argc < 1)
132 {
133 //print out the current state of the var if no args are given
134 CONSOLE_Printf("%s %d", binding->name, *(int*)binding->variable);
135 return;
136 }
137
138 //change the var
139 *((int*)binding->variable) = atoi( CONSOLE_GetArgv(0) );
140
141}
142
143// This function will quit the game
144void CVARDEFS_FunctionQuit(void* var)
145{
146 if( numplayers > 1 )
147 {
148 if(ps[myconnectindex].gm&MODE_GAME)
149 {
150 gamequit = 1;
151 CONSOLE_SetActive(0);
152 }
153 else
154 {
155 sendlogoff();
156 gameexit(" ");
157 }
158 }
159 else if( numplayers < 2 )
160 gameexit(" ");
161}
162
163// This function will quit the game
164void CVARDEFS_FunctionClear(void* var)
165{
166 CONSOLE_Reset();
167}
168
169//And the game will reflect the changes. Will also return the current name of
170//The player
171void CVARDEFS_FunctionName(void* var)
172{
173 int argc, length,i;
174
175 argc = CONSOLE_GetArgc();
176
177 //Check to see if we're changing name's, or checking the name
178 if (argc==1) {
179
180 //The Fragbar up the top doesn't look very good with more than
181 //10 characters, so limit it to that
182 if (strlen(CONSOLE_GetArgv(0)) > 10) {
183 CONSOLE_Printf("User name must be 10 characters or less");
184 return;
185 }
186
187 //Loop through the length of the new name
188 for (i=0;CONSOLE_GetArgv(0)[i];i++)
189 {
190 //Copy it to the local copy of the name
191 ud.user_name[myconnectindex][i] = toupper(CONSOLE_GetArgv(0)[i]);
192 //And the packet we're going to send the other players
193 tempbuf[i+2] = toupper(CONSOLE_GetArgv(0)[i]);
194 }
195
196 //Delimit the local copy with a null character
197 ud.user_name[myconnectindex][i] = 0;
198
199 //If we are online
200 if(numplayers > 1)
201 {
202 //The packet descriptor is 6
203 tempbuf[0] = 6;
204 //We need to send the version of the game we're running
205 //Since names used to be only sent once, this was where they
206 //Checked that everyone was running the same version
207 tempbuf[1] = grpVersion;
208 //Delimit the buffer with a null character.
209 tempbuf[i+2] =0;
210 //The length will be 1 more than the last index
211 length = i +3;
212
213 for(i=connecthead;i>=0;i=connectpoint2[i])
214 {
215 if (i != myconnectindex)
216 //Send it to everyone
217 sendpacket(i,(uint8_t*)tempbuf,length);
218 }
219 }
220 }
221 else
222 {
223 //If there's no arguement, just print out our name
224 CONSOLE_Printf("Current Name: %s", ud.user_name[myconnectindex]);
225 }
226
227
228}
229
230
231// This function loads a new level
232void CVARDEFS_FunctionLevel(void* var)
233{
234 int argc;
235 short volnume,levnume, i;
236
237 //Find out how many arguements were passed
238 argc = CONSOLE_GetArgc();
239
240 //If there's 2
241 if (argc == 2) {
242 //The episode number is the first arguement
243 volnume = atoi(CONSOLE_GetArgv(0));
244
245 //The level is the second
246 levnume = atoi(CONSOLE_GetArgv(1));
247 volnume--;
248 levnume--;
249
250 // Make sure the number aren't out of range.
251 // This is based on the 1.5 data files.
252 if(levnume<0 || volnume<0)
253 {return;}
254 if(volnume>3)
255 {return;}
256 switch(volnume)
257 {
258 case 0: // ep1
259 {
260 if(levnume > 7)
261 {
262 CONSOLE_Printf("Invalid Level Selection");
263 return;
264 }
265 }
266 break;
267 case 1: // ep2
268 case 2: // ep3
269 case 3: // ep4
270 {
271 if(levnume > 10)
272 {
273 CONSOLE_Printf("Invalid Level Selection");
274 return;
275 }
276 }
277 break;
278
279 default:
280 break;
281 }
282
283 ud.m_volume_number = ud.volume_number = volnume; //update the current volume
284 ud.m_level_number = ud.level_number = levnume; //And level
285
286 //If we're playing online
287 if(numplayers > 1 && myconnectindex == connecthead)
288 {
289 //Fill out the game data
290 tempbuf[0] = 5;
291 tempbuf[1] = ud.m_level_number;
292 tempbuf[2] = ud.m_volume_number;
293 tempbuf[3] = ud.m_player_skill;
294 tempbuf[4] = ud.m_monsters_off;
295 tempbuf[5] = ud.m_respawn_monsters;
296 tempbuf[6] = ud.m_respawn_items;
297 tempbuf[7] = ud.m_respawn_inventory;
298 tempbuf[8] = ud.m_coop;
299 tempbuf[9] = ud.m_marker;
300 tempbuf[10] = ud.m_ffire;
301
302 for(i=connecthead;i>=0;i=connectpoint2[i])
303 {
304 sendpacket(i,(uint8_t *)tempbuf,11); //And send the packet to everyone
305 }
306 }
307 else ps[myconnectindex].gm |= MODE_RESTART; //Otherwise just restart the game
308
309 }
310 else
311 {
312 //If there's not 2 arguements, print out the error message
313 CONSOLE_Printf("Level (Episode Number) (Level Number)");
314 }
315}
316
317// Tries to load a external mid file... :)
318void CVARDEFS_FunctionPlayMidi(void* var)
319{
320 if(CONSOLE_GetArgc() < 1)
321 {
322 return;
323 }
324
325 PlayMusic(CONSOLE_GetArgv(0)); // Gets the first parameter and tries to load it in ( Doesn't crash if invalided )
326}
327
328
329// Help function and finds specific help commands...
330void CVARDEFS_FunctionHelp(void* var)
331{
332 int i, numArgs, numCvars;
333 char *helpcmd = CONSOLE_GetArgv(0);
334 numCvars = CVAR_GetNumCvarBindings();
335 numArgs = CONSOLE_GetArgc();
336
337 if(numArgs < 1)// If no extra arugment was passed print below..
338 CONSOLE_Printf("Console Command List:\n\n");
339 for(i = 0; i < numCvars; i++)
340 {
341 cvar_binding* binding = CVAR_GetCvarBinding(i);
342 if(numArgs < 1)
343 {
344 CONSOLE_Printf("%s\t%5s",binding->name,binding->help);
345 }
346 else
347 {
348 // Did we find it?
349 if ( strcmpi(helpcmd, binding->name) == 0 )
350 {
351 CONSOLE_Printf("%s\t%5s",binding->name,binding->help);
352 break;
353 }
354 }
355 }
356
357}
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/cvar_defs.h b/apps/plugins/sdl/progs/duke3d/Game/src/cvar_defs.h
new file mode 100644
index 0000000000..054cb96914
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/cvar_defs.h
@@ -0,0 +1,43 @@
1#ifndef _CVARDEFS_H_
2#define _CVARDEFS_H_
3
4#ifdef _WIN32
5 #include "../../Engine/src/windows/inttypes.h"
6#else
7 #include <inttypes.h>
8#endif
9
10void CVARDEFS_Init();
11void CVARDEFS_Render();
12//
13// Function declarations
14//
15void CVARDEFS_DefaultFunction(void* var);
16void CVARDEFS_FunctionQuit(void* var);
17void CVARDEFS_FunctionClear(void* var);
18void CVARDEFS_FunctionLevel(void* var);
19void CVARDEFS_FunctionName(void* var);
20void CVARDEFS_FunctionPlayMidi(void* var);
21void CVARDEFS_FunctionFOV(void* var);
22void CVARDEFS_FunctionTickRate(void* var);
23void CVARDEFS_FunctionTicksPerFrame(void* var);
24void CVARDEFS_FunctionHelp(void* var);
25
26//
27// Variable declarations
28//
29int g_CV_console_text_color;
30int g_CV_num_console_lines;
31int g_CV_classic;
32int g_CV_TransConsole;
33int g_CV_DebugJoystick;
34int g_CV_DebugSound;
35int g_CV_DebugFileAccess;
36uint32_t sounddebugActiveSounds;
37uint32_t sounddebugAllocateSoundCalls;
38uint32_t sounddebugDeallocateSoundCalls;
39
40
41int g_CV_CubicInterpolation;
42
43#endif \ No newline at end of file
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/cvars.c b/apps/plugins/sdl/progs/duke3d/Game/src/cvars.c
new file mode 100644
index 0000000000..db9ede288b
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/cvars.c
@@ -0,0 +1,53 @@
1#include "cvars.h"
2#include "cvar_defs.h"
3#include <stdlib.h>
4
5#include <string.h>
6
7#define MAX_CVARS 32
8
9cvar_binding cvar_binding_list[MAX_CVARS];
10int num_cvar_bindings = 0;
11
12void CVAR_RegisterCvar(const char * varname, const char * varhelp, void* variable, function_t function)
13{
14 if(NULL == function)
15 {
16 return;
17 }
18
19 cvar_binding_list[num_cvar_bindings].variable = variable;
20 cvar_binding_list[num_cvar_bindings].function = function;
21 memset(cvar_binding_list[num_cvar_bindings].name, 0, 64);
22 strncpy(cvar_binding_list[num_cvar_bindings].name, varname, 63);
23 memset(cvar_binding_list[num_cvar_bindings].help, 0, 64);
24 strncpy(cvar_binding_list[num_cvar_bindings].help, varhelp, 63);
25 num_cvar_bindings++;
26}
27
28int CVAR_GetNumCvarBindings()
29{
30 return num_cvar_bindings;
31}
32
33cvar_binding* CVAR_GetCvarBinding(unsigned int nBinding)
34{
35 if(nBinding > num_cvar_bindings -1)
36 {
37 return NULL;
38 }
39
40 return &cvar_binding_list[nBinding];
41}
42
43// Bind all standard CVars here
44void CVAR_RegisterDefaultCvarBindings(void)
45{
46 CVARDEFS_Init();
47}
48
49void CVAR_Render(void)
50{
51 CVARDEFS_Render();
52}
53
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/cvars.h b/apps/plugins/sdl/progs/duke3d/Game/src/cvars.h
new file mode 100644
index 0000000000..2ad341e58e
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/cvars.h
@@ -0,0 +1,29 @@
1#ifndef _CVARS_H_
2#define _CVARS_H_
3
4#define REGCONVAR(varname, varhelp, variable, function) CVAR_RegisterCvar(varname, varhelp, &variable, &function)
5#define REGCONFUNC(varname, varhelp, function) CVAR_RegisterCvar(varname, varhelp, NULL, &function)
6
7#ifdef _WIN32
8 #include "../../Engine/src/windows/inttypes.h"
9#else
10 #include <inttypes.h>
11#endif
12
13typedef void (*function_t) (void* binding);
14
15typedef struct t_cvar_binding
16{
17 char name[64];
18 char help[64];
19 void* variable;
20 function_t function;
21} cvar_binding;
22
23
24void CVAR_RegisterCvar(const char * varname, const char * varhelp, void* variable, function_t function);
25int CVAR_GetNumCvarBindings();
26cvar_binding* CVAR_GetCvarBinding(unsigned int nBinding);
27void CVAR_Render();
28
29#endif \ No newline at end of file
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/develop.h b/apps/plugins/sdl/progs/duke3d/Game/src/develop.h
new file mode 100644
index 0000000000..0c4c8460fd
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/develop.h
@@ -0,0 +1,65 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#ifndef _develop_public
28#define _develop_public
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33#define DEVELOPMENT 0
34#define SHAREWARE 0
35#define LOCATIONINFO 1
36#define SOFTWAREERROR 1
37#define MEMORYCORRUPTIONTEST 1
38#define PRECACHETEST 0
39#define DATACORRUPTIONTEST 0
40#define RANDOMNUMBERTEST 0
41
42
43#if ( LOCATIONINFO == 1 )
44
45#define funcstart() \
46 { \
47 SoftError( "funcstart : module '%s' at line %d.\n", __FILE__, __LINE__ );\
48 }
49
50#define funcend() \
51 { \
52 SoftError( " funcend : module '%s' at line %d.\n", __FILE__, __LINE__ );\
53 }
54
55#else
56
57#define funcstart()
58#define funcend()
59
60#endif
61
62#ifdef __cplusplus
63};
64#endif
65#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/duke3d.h b/apps/plugins/sdl/progs/duke3d/Game/src/duke3d.h
new file mode 100644
index 0000000000..fee94d961a
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/duke3d.h
@@ -0,0 +1,695 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26#ifndef _INCL_DUKE3D_H_
27#define _INCL_DUKE3D_H_
28
29#include "platform.h"
30
31#ifdef _WIN32
32#include "../../Engine/src/windows/inttypes.h"
33#else
34#include <inttypes.h>
35#endif
36
37#include <fcntl.h>
38#include <time.h>
39#include <ctype.h>
40
41#include "../../Engine/src/build.h"
42
43#if (!defined MAX_PATH)
44 #if (defined MAXPATHLEN)
45 #define MAX_PATH MAXPATHLEN
46 #elif (defined PATH_MAX)
47 #define MAX_PATH PATH_MAX
48 #else
49 #define MAX_PATH 256
50 #endif
51#endif
52
53#if PLATFORM_DOS
54#include <dos.h>
55#include <bios.h>
56#include <io.h>
57#define PATH_SEP_CHAR '\\'
58#define PATH_SEP_STR "\\"
59#endif
60
61#if PLATFORM_UNIX && !defined(ROCKBOX)
62#include "dukeunix.h"
63#endif
64
65#if PLATFORM_MACOSX
66#include "dukeunix.h"
67#endif
68
69#if PLATFORM_WIN32
70#include "dukewin.h"
71#endif
72
73#ifdef ROCKBOX
74#define PLATFORM_ROCKBOX 1
75#endif
76
77#if PLATFORM_ROCKBOX
78#include "dukerockbox.h"
79#endif
80
81#if USE_SDL
82#include "SDL.h"
83#include "SDL_mixer.h"
84#endif
85
86#include "function.h"
87
88// FIX_00022: Automatically recognize the shareware grp (v1.3) + full version (1.3d) +
89// atomic (1.4/1.5 grp) and the con files version (either 1.3 or 1.4) (JonoF's idea)
90
91extern uint8_t conVersion;
92extern uint8_t grpVersion;
93
94
95#define RANCID_ID 1
96#define XDUKE_ID 2
97#define JONOF_ID 3
98
99//Chocolate DukeNukem3D is a fork of xDuke v17.9
100
101#define DUKE_ID XDUKE_ID
102#define CHOCOLATE_DUKE_REV_X 1
103#define CHOCOLATE_DUKE_REV_DOT_Y 0 // rev is: CHOCOLATE_DUKE_REV_X.CHOCOLATE_DUKE_REV_DOT_Y
104
105#define MAX_KNOWN_GRP 4
106
107enum
108{
109 UNKNOWN_GRP = 0,
110 SHAREWARE_GRP13,
111 REGULAR_GRP13D,
112 ATOMIC_GRP14_15,
113 DUKEITOUTINDC_GRP
114};
115
116#define CRC_BASE_GRP_SHAREWARE_13 0x983AD923
117#define CRC_BASE_GRP_FULL_13 0xBBC9CE44
118#define CRC_BASE_GRP_PLUTONIUM_14 0xF514A6AC
119#define CRC_BASE_GRP_ATOMIC_15 0xFD3DCFF1
120
121// implies conVersion == 14 or conVersion == 15
122#define PLUTOPAK (!VOLUMEONE && !VOLUMEALL)
123#define VOLUMEONE (getGRPcrc32(0)==CRC_BASE_GRP_SHAREWARE_13)
124// VOLUMEALL = 1.3d full
125#define VOLUMEALL (getGRPcrc32(0)==CRC_BASE_GRP_FULL_13 || (conVersion == 13 && getGRPcrc32(0)!=CRC_BASE_GRP_SHAREWARE_13 && getGRPcrc32(0)!=CRC_BASE_GRP_PLUTONIUM_14 && getGRPcrc32(0)!=CRC_BASE_GRP_ATOMIC_15))
126
127#define SCREENSHOTPATH "screenshots"
128
129
130
131// #define TEN
132// #define BETA
133
134// #define AUSTRALIA
135
136#define MAXSLEEPDIST 16384
137#define SLEEPTIME 24*64
138
139extern int BYTEVERSION;
140
141extern int BYTEVERSION_27;
142extern int BYTEVERSION_28;
143extern int BYTEVERSION_29; // really needed???
144extern int BYTEVERSION_116;
145extern int BYTEVERSION_117;
146extern int BYTEVERSION_118;
147extern int BYTEVERSION_1_3;
148
149
150#define NUMPAGES 1
151
152#define AUTO_AIM_ANGLE 48
153#define RECSYNCBUFSIZ 2520 //2520 is the (LCM of 1-8)*3
154#define MOVEFIFOSIZ 256
155
156#define FOURSLEIGHT (1<<8)
157
158struct player_struct;
159
160#include "../../Game/src/types.h"
161#include "file_lib.h"
162#include "develop.h"
163#include "gamedefs.h"
164#include "keyboard.h"
165#include "util_lib.h"
166#include "function.h"
167#include "audiolib/fx_man.h"
168#include "config.h"
169#include "sounds.h"
170#include "control.h"
171#include "_rts.h"
172#include "rts.h"
173#include "soundefs.h"
174
175#include "audiolib/music.h"
176
177#include "names.h"
178
179#include "../../Engine/src/engine.h"
180#include "../../Engine/src/fixedPoint_math.h"
181
182//#define TICRATE (120)
183//#define TICSPERFRAME (TICRATE/26)
184
185extern int g_iTickRate;
186extern int g_iTicksPerFrame;
187
188#define TICRATE g_iTickRate
189#define TICSPERFRAME (TICRATE/g_iTicksPerFrame)
190
191// #define GC (TICSPERFRAME*44)
192
193#define NUM_SOUNDS 450
194
195#define ALT_IS_PRESSED ( KB_KeyPressed( sc_RightAlt ) || KB_KeyPressed( sc_LeftAlt ) )
196#define SHIFTS_IS_PRESSED ( KB_KeyPressed( sc_RightShift ) || KB_KeyPressed( sc_LeftShift ) )
197#define RANDOMSCRAP EGS(s->sectnum,s->x+(TRAND&255)-128,s->y+(TRAND&255)-128,s->z-(8<<8)-(TRAND&8191),SCRAP6+(TRAND&15),-8,48,48,TRAND&2047,(TRAND&63)+64,-512-(TRAND&2047),i,5)
198
199#define BLACK 0
200#define DARKBLUE 1
201#define DARKGREEN 2
202#define DARKCYAN 3
203#define DARKRED 4
204#define DARKPURPLE 5
205#define BROWN 6
206#define LIGHTGRAY 7
207
208#define DARKGRAY 8
209#define BLUE 9
210#define GREEN 10
211#define CYAN 11
212#define RED 12
213#define PURPLE 13
214#define YELLOW 14
215#define WHITE 15
216
217#define PHEIGHT (38<<8)
218
219#define WAIT(X) ototalclock=totalclock+(X);while(totalclock<ototalclock)
220
221
222#define MODE_MENU 1
223#define MODE_DEMO 2
224#define MODE_GAME 4
225#define MODE_EOL 8
226#define MODE_TYPE 16
227#define MODE_RESTART 32
228#define MODE_SENDTOWHOM 64
229#define MODE_END 128
230
231
232#define MAXANIMWALLS 512
233#define MAXINTERPOLATIONS 2048
234#define NUMOFFIRSTTIMEACTIVE 192
235
236#define MAXCYCLERS 256
237#define MAXSCRIPTSIZE 20460
238#define MAXANIMATES 64
239
240#define SP sprite[i].yvel
241#define SX sprite[i].x
242#define SY sprite[i].y
243#define SZ sprite[i].z
244#define SS sprite[i].shade
245#define PN sprite[i].picnum
246#define SA sprite[i].ang
247#define SV sprite[i].xvel
248#define ZV sprite[i].zvel
249#define RX sprite[i].xrepeat
250#define RY sprite[i].yrepeat
251#define OW sprite[i].owner
252#define CS sprite[i].cstat
253#define SH sprite[i].extra
254#define CX sprite[i].xoffset
255#define CY sprite[i].yoffset
256#define CD sprite[i].clipdist
257#define PL sprite[i].pal
258#define SLT sprite[i].lotag
259#define SHT sprite[i].hitag
260#define SECT sprite[i].sectnum
261
262#define face_player 1
263#define geth 2
264#define getv 4
265#define random_angle 8
266#define face_player_slow 16
267#define spin 32
268#define face_player_smart 64
269#define fleeenemy 128
270#define jumptoplayer 257
271#define seekplayer 512
272#define furthestdir 1024
273#define dodgebullet 4096
274
275#define TRAND krand()
276
277#define MAX_WEAPONS 12
278
279#define KNEE_WEAPON 0
280#define PISTOL_WEAPON 1
281#define SHOTGUN_WEAPON 2
282#define CHAINGUN_WEAPON 3
283#define RPG_WEAPON 4
284#define HANDBOMB_WEAPON 5
285#define SHRINKER_WEAPON 6
286#define DEVISTATOR_WEAPON 7
287#define TRIPBOMB_WEAPON 8
288#define FREEZE_WEAPON 9
289#define HANDREMOTE_WEAPON 10
290#define GROW_WEAPON 11
291
292#define T1 hittype[i].temp_data[0]
293#define T2 hittype[i].temp_data[1]
294#define T3 hittype[i].temp_data[2]
295#define T4 hittype[i].temp_data[3]
296#define T5 hittype[i].temp_data[4]
297#define T6 hittype[i].temp_data[5]
298
299#define IFWITHIN(B,E) if((PN)>=(B) && (PN)<=(E))
300#define KILLIT(KX) {deletesprite(KX);goto BOLT;}
301
302
303#define IFMOVING if(ssp(i,CLIPMASK0))
304#define IFHIT j=ifhitbyweapon(i);if(j >= 0)
305#define IFHITSECT j=ifhitsectors(s->sectnum);if(j >= 0)
306
307#define AFLAMABLE(X) (X==BOX||X==TREE1||X==TREE2||X==TIRE||X==CONE)
308
309
310#define IFSKILL1 if(player_skill<1)
311#define IFSKILL2 if(player_skill<2)
312#define IFSKILL3 if(player_skill<3)
313#define IFSKILL4 if(player_skill<4)
314
315#define rnd(X) ((TRAND>>8)>=(255-(X)))
316
317typedef struct
318{
319 short i;
320 int voice;
321} SOUNDOWNER;
322
323#include "audiolib/usrhooks.h"
324/*
325
326
327#define __USRHOOKS_H
328
329enum USRHOOKS_Errors
330 {
331 USRHOOKS_Warning = -2,
332 USRHOOKS_Error = -1,
333 USRHOOKS_Ok = 0
334 };
335*/
336
337#pragma pack(push)
338#pragma pack(1)
339
340typedef struct
341{
342 int8_t avel, horz;
343 short fvel, svel;
344 uint32_t bits;
345} input;
346
347#pragma pack(pop)
348
349/* !!! FIXME: "sync" is defined in unistd.h ... :( --ryan. */
350#define sync duke_sync
351extern input inputfifo[MOVEFIFOSIZ][MAXPLAYERS], sync[MAXPLAYERS];
352extern input recsync[RECSYNCBUFSIZ];
353
354extern int32_t movefifosendplc;
355
356typedef struct
357{
358 uint8_t *ptr;
359 uint8_t lock;
360 int length, num;
361} SAMPLE;
362
363struct animwalltype
364{
365 short wallnum;
366 int32_t tag;
367};
368extern struct animwalltype animwall[MAXANIMWALLS];
369extern short numanimwalls,probey,lastprobey;
370
371char *mymembuf;
372extern uint8_t typebuflen;
373char typebuf[41];
374extern uint8_t MusicPtr[72000];
375extern int32_t msx[2048],msy[2048];
376extern short cyclers[MAXCYCLERS][6],numcyclers;
377extern char myname[2048];
378
379struct user_defs
380{
381 uint8_t god,warp_on,cashman,eog,showallmap;
382 uint8_t show_help,scrollmode,clipping;
383 char user_name[MAXPLAYERS][32];
384 char ridecule[10][40];
385 char savegame[10][22];
386 char pwlockout[128],rtsname[128];
387 uint8_t overhead_on,last_overhead;
388
389 short pause_on,from_bonus;
390 short camerasprite,last_camsprite;
391 short last_level,secretlevel;
392
393 int32_t const_visibility,uw_framerate;
394 int32_t camera_time,folfvel,folavel,folx,foly,fola;
395 int32_t reccnt;
396
397 int32 entered_name,screen_tilting,shadows,fta_on,executions,auto_run;
398 int32 coords,tickrate,m_coop,coop,screen_size,extended_screen_size,lockout,crosshair,showweapons;
399 int32 mywchoice[MAX_WEAPONS],wchoice[MAXPLAYERS][MAX_WEAPONS],playerai;
400
401 int32 respawn_monsters,respawn_items,respawn_inventory,recstat,monsters_off,brightness;
402 int32 m_respawn_items,m_respawn_monsters,m_respawn_inventory,m_recstat,m_monsters_off,detail;
403 // FIX_00082: /q option taken off when playing a demo (multimode_bot)
404 int32 m_ffire,ffire,m_player_skill,m_level_number,m_volume_number,multimode,multimode_bot;
405 int32 player_skill,level_number,volume_number,m_marker,marker,mouseflip;
406
407 int32 showcinematics, hideweapon;
408 int32 auto_aim, gitdat_mdk; //AutoAim toggle variable.
409 int32 weaponautoswitch;
410
411 // FIX_00015: Backward compliance with older demos (down to demos v27, 28, 116 and 117 only)
412 uint8_t playing_demo_rev;
413
414 uint32_t groupefil_crc32[MAXPLAYERS][4];
415 uint16_t conSize[MAXPLAYERS];
416
417#ifdef CHECK_XDUKE_REV
418 uint8_t rev[MAXPLAYERS][10];
419#endif
420 uint32_t mapCRC[MAXPLAYERS];
421 uint32_t exeCRC[MAXPLAYERS];
422 uint32_t conCRC[MAXPLAYERS];
423};
424
425struct player_orig
426{
427 int32_t ox,oy,oz;
428 short oa,os;
429};
430
431
432extern uint8_t numplayersprites;
433
434
435typedef struct
436{
437 unsigned int crc32;
438 char * name;
439 uint32_t size;
440} crc32_t;
441
442extern crc32_t crc32lookup[];
443
444void add_ammo( short, short, short, short );
445
446
447extern int32_t fricxv,fricyv;
448
449struct player_struct
450{
451 int32_t zoom,exitx,exity,loogiex[64],loogiey[64],numloogs,loogcnt;
452 int32_t posx, posy, posz, horiz, ohoriz, ohorizoff, invdisptime;
453 int32_t bobposx,bobposy,oposx,oposy,oposz,pyoff,opyoff;
454 int32_t posxv,posyv,poszv,last_pissed_time,truefz,truecz;
455 int32_t player_par,visibility;
456 int32_t bobcounter,weapon_sway;
457 int32_t pals_time,randomflamex,crack_time;
458
459 int32 aim_mode;
460
461 short ang,oang,angvel,cursectnum,look_ang,last_extra,subweapon;
462 short ammo_amount[MAX_WEAPONS],wackedbyactor,frag,fraggedself;
463
464 short curr_weapon, last_weapon, tipincs, horizoff, wantweaponfire;
465 short holoduke_amount,newowner,hurt_delay,hbomb_hold_delay;
466 short jumping_counter,airleft,knee_incs,access_incs;
467 short fta,ftq,access_wallnum,access_spritenum;
468 short kickback_pic,got_access,weapon_ang,firstaid_amount;
469 short somethingonplayer,on_crane,i,one_parallax_sectnum;
470 short over_shoulder_on,random_club_frame,fist_incs;
471 short one_eighty_count,cheat_phase;
472 short dummyplayersprite,extra_extra8,quick_kick;
473 short heat_amount,actorsqu,timebeforeexit,customexitsound;
474
475 short weaprecs[16],weapreccnt;
476 uint32_t interface_toggle_flag;
477
478 short rotscrnang,dead_flag,show_empty_weapon;
479 short scuba_amount,jetpack_amount,steroids_amount,shield_amount;
480 short holoduke_on,pycount,weapon_pos,frag_ps;
481 short transporter_hold,last_full_weapon,footprintshade,boot_amount;
482
483 int scream_voice;
484
485 uint8_t gm,on_warping_sector,footprintcount;
486 uint8_t hbomb_on,jumping_toggle,rapid_fire_hold,on_ground;
487 uint8_t name[32],inven_icon,buttonpalette;
488
489 uint8_t jetpack_on,spritebridge,lastrandomspot;
490 uint8_t scuba_on,footprintpal,heat_on;
491
492 uint8_t holster_weapon,falling_counter;
493 uint8_t gotweapon[MAX_WEAPONS],refresh_inventory,*palette;
494
495 uint8_t toggle_key_flag,knuckle_incs; // ,select_dir;
496 uint8_t walking_snd_toggle, palookup, hard_landing;
497 uint8_t max_secret_rooms,secret_rooms,/*fire_flag,*/pals[3];
498 uint8_t max_actors_killed,actors_killed,return_to_center;
499
500 // local but synch variables (ud is local but not synch):
501
502 // FIX_00023: Moved Addfaz's autoaim handler to synch variables (to avoid out of synch)
503 int32 auto_aim; //AutoAim toggle variable.
504
505 // FIX_00012: added "weapon autoswitch" toggle allowing to turn the autoswitch off
506 // when picking up new weapons. The weapon sound on pickup will remain on, to not
507 // affect the opponent's gameplay (so he can still hear you picking up new weapons)
508 int32 weaponautoswitch;
509
510 uint8_t fakeplayer;
511};
512
513extern uint8_t tempbuf[2048];
514extern uint8_t packbuf[576];
515
516extern int32_t gc,max_player_health,max_armour_amount,max_ammo_amount[MAX_WEAPONS];
517
518extern int32_t impact_damage,respawnactortime,respawnitemtime;
519
520#define MOVFIFOSIZ 256
521
522extern short spriteq[1024],spriteqloc,spriteqamount;
523extern struct player_struct ps[MAXPLAYERS];
524extern struct player_orig po[MAXPLAYERS];
525extern struct user_defs ud;
526
527// ported build engine has this, too. --ryan.
528#if PLATFORM_DOS
529extern short int moustat;
530#endif
531
532extern short int global_random;
533extern int32_t scaredfallz;
534extern char buf[80]; //My own generic input buffer
535
536extern char fta_quotes[NUMOFFIRSTTIMEACTIVE][64];
537extern uint8_t scantoasc[128],ready2send;
538extern uint8_t scantoascwithshift[128];
539
540extern fx_device device;
541extern SAMPLE Sound[ NUM_SOUNDS ];
542extern int32 VoiceToggle,AmbienceToggle, OpponentSoundToggle;
543extern int32 mouseSensitivity_X, mouseSensitivity_Y;
544extern SOUNDOWNER SoundOwner[NUM_SOUNDS][4];
545
546extern uint8_t playerreadyflag[MAXPLAYERS],playerquitflag[MAXPLAYERS];
547extern char sounds[NUM_SOUNDS][14];
548
549extern int32_t script[MAXSCRIPTSIZE],*scriptptr,*insptr,*labelcode,labelcnt;
550extern char *label,*textptr,error,warning;
551extern uint8_t killit_flag;
552extern int32_t *actorscrptr[MAXTILES],*parsing_actor;
553extern uint8_t actortype[MAXTILES];
554extern uint8_t *music_pointer;
555
556extern uint8_t ipath[80],opath[80];
557
558extern char music_fn[4][11][13];
559extern uint8_t music_select;
560extern char env_music_fn[4][13];
561extern short camsprite;
562
563// extern uint8_t gotz;
564extern uint8_t inspace(short sectnum);
565
566
567struct weaponhit
568{
569 uint8_t cgg;
570 short picnum,ang,extra,owner,movflag;
571 short tempang,actorstayput,dispicnum;
572 short timetosleep;
573 int32_t floorz,ceilingz,lastvx,lastvy,bposx,bposy,bposz;
574 int32_t temp_data[6];
575};
576
577extern struct weaponhit hittype[MAXSPRITES];
578
579extern input loc;
580extern input recsync[RECSYNCBUFSIZ];
581extern int32_t avgfvel, avgsvel, avgavel, avghorz, avgbits;
582
583extern short numplayers, myconnectindex;
584extern short connecthead, connectpoint2[MAXPLAYERS]; //Player linked list variables (indeces, not connection numbers)
585extern short screenpeek;
586
587extern int current_menu;
588extern int32_t tempwallptr,animatecnt;
589extern int32_t lockclock;
590extern uint8_t display_mirror,rtsplaying;
591
592extern int32_t movefifoend[MAXPLAYERS];
593extern int32_t ototalclock;
594
595extern int32_t *animateptr[MAXANIMATES], animategoal[MAXANIMATES];
596extern int32_t animatevel[MAXANIMATES];
597// extern int32_t oanimateval[MAXANIMATES];
598extern short neartagsector, neartagwall, neartagsprite;
599extern int32_t neartaghitdist;
600extern short animatesect[MAXANIMATES];
601extern int32_t movefifoplc, vel,svel,angvel,horiz;
602
603extern short mirrorwall[64], mirrorsector[64], mirrorcnt;
604
605#define NUMKEYS 19
606
607extern int32_t chainplace, chainnumpages;
608extern volatile int32_t checksume;
609
610#include "funct.h"
611//#include "engine_protos.h"
612
613extern uint8_t screencapt;
614extern short soundps[NUM_SOUNDS],soundpe[NUM_SOUNDS],soundvo[NUM_SOUNDS];
615extern uint8_t soundpr[NUM_SOUNDS],soundm[NUM_SOUNDS];
616extern int32_t soundsiz[NUM_SOUNDS];
617extern char level_names[44][33];
618extern int32_t partime[44],designertime[44];
619extern char volume_names[4][33];
620extern char skill_names[5][33];
621extern char level_file_names[44][128];
622
623extern int32_t SoundToggle,MusicToggle;
624extern short last_threehundred,lastsavedpos;
625extern uint8_t restorepalette;
626
627extern short buttonstat;
628extern int32_t cachecount;
629extern uint8_t waterpal[768],slimepal[768],titlepal[768],drealms[768],endingpal[768];
630extern char boardfilename[128];
631extern uint8_t betaname[80];
632extern uint8_t earthquaketime;
633extern uint8_t networkmode;
634extern uint8_t lumplockbyte[11];
635
636 //DUKE3D.H - replace the end "my's" with this
637extern int32_t myx, omyx, myxvel, myy, omyy, myyvel, myz, omyz, myzvel;
638extern short myhoriz, omyhoriz, myhorizoff, omyhorizoff, globalskillsound;
639extern short myang, omyang, mycursectnum, myjumpingcounter;
640extern uint8_t myjumpingtoggle, myonground, myhardlanding,myreturntocenter;
641extern int32_t fakemovefifoplc;
642extern int32_t myxbak[MOVEFIFOSIZ], myybak[MOVEFIFOSIZ], myzbak[MOVEFIFOSIZ];
643extern int32_t myhorizbak[MOVEFIFOSIZ];
644extern short myangbak[MOVEFIFOSIZ];
645
646extern short weaponsandammosprites[15];
647
648
649
650
651//DUKE3D.H:
652typedef struct
653{
654 short frag[MAXPLAYERS], got_access, last_extra, shield_amount, curr_weapon;
655 short ammo_amount[MAX_WEAPONS], holoduke_on;
656 uint8_t gotweapon[MAX_WEAPONS], inven_icon, jetpack_on, heat_on;
657 short firstaid_amount, steroids_amount, holoduke_amount, jetpack_amount;
658 short heat_amount, scuba_amount, boot_amount;
659 short last_weapon, weapon_pos, kickback_pic;
660
661} STATUSBARTYPE;
662
663extern STATUSBARTYPE sbar;
664extern short frags[MAXPLAYERS][MAXPLAYERS];
665extern int32_t cameradist, cameraclock, dukefriction,show_shareware;
666extern uint8_t networkmode, movesperpacket;
667extern uint8_t gamequit;
668
669extern uint8_t pus,pub,camerashitable,freezerhurtowner,lasermode;
670extern uint8_t syncstat, syncval[MAXPLAYERS][MOVEFIFOSIZ];
671extern int8_t multiwho, multipos, multiwhat, multiflag;
672extern int32_t syncvalhead[MAXPLAYERS], syncvaltail, syncvaltottail;
673extern int32_t numfreezebounces,rpgblastradius,pipebombblastradius,tripbombblastradius,shrinkerblastradius,morterblastradius,bouncemineblastradius,seenineblastradius;
674// CTW - MODIFICATION
675// extern uint8_t stereo,eightytwofifty,playerswhenstarted,playonten,everyothertime;
676extern uint8_t stereo,eightytwofifty,playerswhenstarted,everyothertime;
677// CTW END - MODIFICATION
678extern int32_t myminlag[MAXPLAYERS], mymaxlag, otherminlag, bufferjitter;
679
680extern int32_t numinterpolations, startofdynamicinterpolations;
681extern int32_t oldipos[MAXINTERPOLATIONS];
682extern int32_t bakipos[MAXINTERPOLATIONS];
683extern int32_t *curipos[MAXINTERPOLATIONS];
684
685extern short numclouds,clouds[128],cloudx[128],cloudy[128];
686extern int32_t cloudtotalclock,totalmemory;
687
688
689
690extern int32_t myaimmode, myaimstat, omyaimstat;
691
692extern uint8_t nHostForceDisableAutoaim;
693
694#endif // include-once header.
695
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/dukerockbox.h b/apps/plugins/sdl/progs/duke3d/Game/src/dukerockbox.h
new file mode 100644
index 0000000000..9035336b8a
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/dukerockbox.h
@@ -0,0 +1,94 @@
1//
2// dukerockbox.h
3// Duke3D
4//
5// Created by fabien sanglard on 12-12-12.
6// Copyright (c) 2012 fabien sanglard. All rights reserved.
7//
8
9#ifndef Duke3D_dukerb_h
10#define Duke3D_dukerb_h
11
12#include "SDL.h"
13
14#define cdecl
15#define __far
16#define __interrupt
17
18
19#define STUBBED(x)
20#ifdef __SUNPRO_C
21//#define STUBBED(x) fprintf(stderr,"STUB: %s (??? %s:%d)\n",x,__FILE__,__LINE__)
22#else
23//#define STUBBED(x) fprintf(stderr,"STUB: %s (%s, %s:%d)\n",x,__FUNCTION__,__FILE__,__LINE__)
24#endif
25
26#define PATH_SEP_CHAR '/'
27#define PATH_SEP_STR "/"
28#define ROOTDIR "/"
29#define CURDIR "/"
30
31#ifndef O_BINARY
32#define O_BINARY 0
33#endif
34
35struct find_t
36{
37 DIR *dir;
38 char pattern[MAX_PATH];
39 char name[MAX_PATH];
40};
41int _dos_findfirst(char *filename, int x, struct find_t *f);
42int _dos_findnext(struct find_t *f);
43
44struct dosdate_t
45{
46 uint8_t day;
47 uint8_t month;
48 unsigned int year;
49 uint8_t dayofweek;
50};
51
52void _dos_getdate(struct dosdate_t *date);
53
54#ifndef min
55#define min(x, y) ((x) < (y) ? (x) : (y))
56#endif
57
58#ifndef max
59#define max(x, y) ((x) > (y) ? (x) : (y))
60#endif
61
62
63
64#ifndef strcmpi
65#define strcmpi(x, y) strcasecmp(x, y)
66#endif
67
68#ifdef DC
69#undef stderr
70#undef stdout
71#undef getchar
72/* kos compat */
73#define stderr ((FILE*)2)
74#define stdout ((FILE*)2)
75#define Z_AvailHeap() ((10 * 1024) * 1024)
76#else
77// 64 megs should be enough for anybody. :) --ryan.
78#define Z_AvailHeap() ((64 * 1024) * 1024)
79#endif
80
81#define printchrasm(x,y,ch) printf("%c", (uint8_t ) (ch & 0xFF))
82
83#ifdef __GNUC__
84#define GCC_PACK1_EXT __attribute__((packed,aligned(1)))
85#endif
86
87
88// FCS: Game.c features calls to mkdir without the proper flags.
89// Giving all access is ugly but it is just game OK !
90//#define mkdir(X) mkdir(X,0777)
91
92#define getch getchar
93
94#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/dukeunix.h b/apps/plugins/sdl/progs/duke3d/Game/src/dukeunix.h
new file mode 100644
index 0000000000..451d174785
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/dukeunix.h
@@ -0,0 +1,100 @@
1//
2// dukeunix.h
3// Duke3D
4//
5// Created by fabien sanglard on 12-12-12.
6// Copyright (c) 2012 fabien sanglard. All rights reserved.
7//
8
9#ifndef Duke3D_dukeunix_h
10#define Duke3D_dukeunix_h
11
12
13#define cdecl
14#define __far
15#define __interrupt
16
17
18//#define STUBBED(x)
19#ifdef __SUNPRO_C
20#define STUBBED(x) fprintf(stderr,"STUB: %s (??? %s:%d)\n",x,__FILE__,__LINE__)
21#else
22#define STUBBED(x) fprintf(stderr,"STUB: %s (%s, %s:%d)\n",x,__FUNCTION__,__FILE__,__LINE__)
23#endif
24
25#define PATH_SEP_CHAR '/'
26#define PATH_SEP_STR "/"
27#define ROOTDIR "/"
28#define CURDIR "./"
29
30#ifndef O_BINARY
31#define O_BINARY 0
32#endif
33
34#include <unistd.h>
35#include <fcntl.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38#include <dirent.h>
39#include <assert.h>
40
41struct find_t
42{
43 DIR *dir;
44 char pattern[MAX_PATH];
45 char name[MAX_PATH];
46};
47int _dos_findfirst(char *filename, int x, struct find_t *f);
48int _dos_findnext(struct find_t *f);
49
50struct dosdate_t
51{
52 uint8_t day;
53 uint8_t month;
54 unsigned int year;
55 uint8_t dayofweek;
56};
57
58void _dos_getdate(struct dosdate_t *date);
59
60#ifndef min
61#define min(x, y) ((x) < (y) ? (x) : (y))
62#endif
63
64#ifndef max
65#define max(x, y) ((x) > (y) ? (x) : (y))
66#endif
67
68
69
70#ifndef strcmpi
71#define strcmpi(x, y) strcasecmp(x, y)
72#endif
73
74#ifdef DC
75#undef stderr
76#undef stdout
77#undef getchar
78/* kos compat */
79#define stderr ((FILE*)2)
80#define stdout ((FILE*)2)
81#define Z_AvailHeap() ((10 * 1024) * 1024)
82#else
83// 64 megs should be enough for anybody. :) --ryan.
84#define Z_AvailHeap() ((64 * 1024) * 1024)
85#endif
86
87#define printchrasm(x,y,ch) printf("%c", (uint8_t ) (ch & 0xFF))
88
89#ifdef __GNUC__
90#define GCC_PACK1_EXT __attribute__((packed,aligned(1)))
91#endif
92
93
94// FCS: Game.c features calls to mkdir without the proper flags.
95// Giving all access is ugly but it is just game OK !
96#define mkdir(X) mkdir(X,0777)
97
98#define getch getchar
99
100#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/dukewin.h b/apps/plugins/sdl/progs/duke3d/Game/src/dukewin.h
new file mode 100644
index 0000000000..f35becb401
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/dukewin.h
@@ -0,0 +1,86 @@
1#ifndef _INCL_DUKEWIN_H_
2#define _INCL_DUKEWIN_H_ 1
3
4#ifndef _MSC_VER /* might need this. */
5typedef int32_t int32_t __int64;
6#endif
7
8#pragma warning(disable:4761)
9
10#if USE_SDL
11#include "SDL.h"
12#endif
13
14#ifdef _DEBUG
15#define STUBBED(x) printf("STUB: %s in %s:%d\n", x, __FILE__, __LINE__)
16#else
17#define STUBBED(x)
18#endif
19
20#define PATH_SEP_CHAR '\\'
21#define PATH_SEP_STR "\\"
22
23#include <sys/stat.h>
24#include <io.h>
25#include <assert.h>
26
27struct find_t
28{
29 int32_t handle;
30 struct _finddata_t data;
31 uint8_t name[MAX_PATH];
32};
33int _dos_findfirst(uint8_t *filename, int x, struct find_t *f);
34int _dos_findnext(struct find_t *f);
35
36struct dosdate_t
37{
38 uint8_t day;
39 uint8_t month;
40 unsigned int year;
41 uint8_t dayofweek;
42};
43
44void _dos_getdate(struct dosdate_t *date);
45
46#ifndef min
47#define min(x, y) ((x) < (y) ? (x) : (y))
48#endif
49
50#ifndef max
51#define max(x, y) ((x) > (y) ? (x) : (y))
52#endif
53
54#ifdef FP_OFF
55#undef FP_OFF
56#endif
57#define FP_OFF(x) ((int32_t) (x))
58
59// 64 megs should be enough for anybody. :) --ryan.
60#define Z_AvailHeap() ((64 * 1024) * 1024)
61
62#define printchrasm(x,y,ch) printf("%c", (uint8_t ) (ch & 0xFF))
63
64#define cdecl
65
66#define open _open
67#define O_BINARY _O_BINARY
68#define O_RDONLY _O_RDONLY
69#define O_WRONLY _O_WRONLY
70#define O_RDWR _O_RDWR
71#define O_TRUNC _O_TRUNC
72#define O_CREAT _O_CREAT
73#define S_IREAD _S_IREAD
74#define S_IWRITE _S_IWRITE
75#define S_IRDWR _S_IRDWR
76
77#define S_IRUSR S_IREAD
78#define S_IWUSR S_IWRITE
79#define S_IRGRP 0
80#define S_IWGRP 0
81
82#define F_OK 0
83
84#define HAVE_PRAGMA_PACK 1
85
86#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/dummy_audiolib.c b/apps/plugins/sdl/progs/duke3d/Game/src/dummy_audiolib.c
new file mode 100644
index 0000000000..460eaac718
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/dummy_audiolib.c
@@ -0,0 +1,215 @@
1//
2// dummy_audiolib.c
3// Duke3D
4//
5// Created by fabien sanglard on 12-12-12.
6// Copyright (c) 2012 fabien sanglard. All rights reserved.
7//
8
9#include "audiolib/fx_man.h"
10#include <inttypes.h>
11#include <stdio.h>
12//#include "engine_protos.h"
13#include "audiolib/music.h"
14
15//Dummy sound system for when a system has no sound system yet.
16/*
17uint8_t *FX_ErrorString( int ErrorNumber ){
18 static uint8_t nope = '\0';
19 return &nope;
20}
21
22int FX_SetupCard( int SoundCard, fx_device *device ){return 1;}
23int FX_GetBlasterSettings( fx_blaster_config *blaster ){return 1;}
24int FX_SetupSoundBlaster( fx_blaster_config blaster, int *MaxVoices, int *MaxSampleBits, int *MaxChannels ){return 1;}
25int FX_Init( int SoundCard, int numvoices, int numchannels, int samplebits, unsigned mixrate ){return FX_Ok;}
26int FX_Shutdown( void ){return 1;}
27int FX_SetCallBack( void ( *function )( uint32_t ) ){return FX_Ok;}
28void FX_SetVolume( int volume ){}
29int FX_GetVolume( void ){return 1;}
30
31void FX_SetReverseStereo( int setting ){}
32int FX_GetReverseStereo( void ){return 1;}
33void FX_SetReverb( int reverb ){}
34void FX_SetFastReverb( int reverb ){}
35int FX_GetMaxReverbDelay( void ){return 0;}
36int FX_GetReverbDelay( void ){return 1;}
37void FX_SetReverbDelay( int delay ){}
38
39int FX_VoiceAvailable( int priority ){return 1;}
40int FX_EndLooping( int handle ){return 1;}
41int FX_SetPan( int handle, int vol, int left, int right ){return 1;}
42int FX_SetPitch( int handle, int pitchoffset ){return 1;}
43int FX_SetFrequency( int handle, int frequency ){return 1;}
44
45int FX_PlayVOC( char *ptr, int pitchoffset, int vol, int left, int right,
46 int priority, uint32_t callbackval ){return FX_Ok;}
47int FX_PlayLoopedVOC( uint8_t *ptr, int32_t loopstart, int32_t loopend,
48 int pitchoffset, int vol, int left, int right, int priority,
49 uint32_t callbackval ){return FX_Ok;}
50int FX_PlayWAV( uint8_t *ptr, int pitchoffset, int vol, int left, int right,
51 int priority, uint32_t callbackval ){return FX_Ok;}
52int FX_PlayLoopedWAV( uint8_t *ptr, int32_t loopstart, int32_t loopend,
53 int pitchoffset, int vol, int left, int right, int priority,
54 uint32_t callbackval ){return FX_Ok;}
55int FX_PlayVOC3D( uint8_t *ptr, int pitchoffset, int angle, int distance,
56 int priority, uint32_t callbackval ){return FX_Ok;}
57int FX_PlayWAV3D( uint8_t *ptr, int pitchoffset, int angle, int distance,
58 int priority, uint32_t callbackval ){return FX_Ok;}
59int FX_PlayRaw( uint8_t *ptr, uint32_t length, unsigned rate,
60 int pitchoffset, int vol, int left, int right, int priority,
61 uint32_t callbackval ){return FX_Ok;}
62int FX_PlayLoopedRaw( uint8_t *ptr, uint32_t length, uint8_t *loopstart,
63 uint8_t *loopend, unsigned rate, int pitchoffset, int vol, int left,
64 int right, int priority, uint32_t callbackval ){return FX_Ok;}
65int FX_Pan3D( int handle, int angle, int distance ){return FX_Ok;}
66int FX_SoundActive( int handle ){return 1;}
67int FX_SoundsPlaying( void ){return 0;}
68int FX_StopSound( int handle ){return 1;}
69int FX_StopAllSounds( void ){return 1;}
70int FX_StartDemandFeedPlayback( void ( *function )( uint8_t **ptr, uint32_t *length ),
71 int rate, int pitchoffset, int vol, int left, int right,
72 int priority, uint32_t callbackval ){return 1;}
73int FX_StartRecording( int MixRate, void ( *function )( char *ptr, int length ) ){return 1;}
74void FX_StopRecord( void ){}
75
76 */
77
78
79//Dummy music for when a system has no music system yet.
80
81/*
82char *MUSIC_ErrorString(int ErrorNumber)
83{
84 return "";
85}
86
87int MUSIC_Init(int SoundCard, int Address)
88{
89 return 0;
90}
91
92int MUSIC_Shutdown(void)
93{
94 return 0;
95}
96
97void MUSIC_SetMaxFMMidiChannel(int channel)
98{
99}
100
101void MUSIC_SetVolume(int volume)
102{
103}
104
105void MUSIC_SetMidiChannelVolume(int channel, int volume)
106{
107}
108
109void MUSIC_ResetMidiChannelVolumes(void)
110{
111}
112
113int MUSIC_GetVolume(void)
114{
115 return 0;
116}
117
118void MUSIC_SetLoopFlag(int loopflag)
119{
120}
121
122int MUSIC_SongPlaying(void)
123{
124 return 0;
125}
126
127void MUSIC_Continue(void)
128{
129}
130
131void MUSIC_Pause(void)
132{
133}
134
135int MUSIC_StopSong(void)
136{
137 return 0;
138}
139
140int MUSIC_PlaySong(uint8_t *song, int loopflag)
141{
142 return 0;
143}
144
145
146void MUSIC_SetContext(int context)
147{
148}
149
150int MUSIC_GetContext(void)
151{
152 return 0;
153}
154
155void MUSIC_SetSongTick(uint32_t PositionInTicks)
156{
157}
158
159void MUSIC_SetSongTime(uint32_t milliseconds)
160{
161}
162
163void MUSIC_SetSongPosition(int measure, int beat, int tick)
164{
165}
166
167void MUSIC_GetSongPosition(songposition *pos)
168{
169}
170
171void MUSIC_GetSongLength(songposition *pos)
172{
173}
174
175int MUSIC_FadeVolume(int tovolume, int milliseconds)
176{
177 return 0;
178}
179
180int MUSIC_FadeActive(void)
181{
182 return 0;
183}
184
185void MUSIC_StopFade(void)
186{
187}
188
189void MUSIC_RerouteMidiChannel(int channel, int cdecl function( int event, int c1, int c2 ))
190{
191}
192
193void MUSIC_RegisterTimbreBank(uint8_t *timbres)
194{
195}
196
197void PlayMusic(char* filename)
198{
199 char magicNumber[5];
200 printf("Play music '%s'.\n",filename);
201 int32_t fd = kopen4load(filename,1);
202 if (fd > 0)
203 printf("Found the music size='%d'!\n",kfilelength(fd));
204
205 kread(fd, magicNumber, 4);
206 magicNumber[4] = 0;
207
208 //If midi this should be 'MThd' !
209 printf("Magic number='%s'!\n",magicNumber);
210
211
212 kclose(fd);
213}
214*/
215
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/file_lib.h b/apps/plugins/sdl/progs/duke3d/Game/src/file_lib.h
new file mode 100644
index 0000000000..1f6964b955
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/file_lib.h
@@ -0,0 +1,260 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#ifndef _file_lib_public
28#define _file_lib_public
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33enum
34 {
35 filetype_binary,
36 filetype_text
37 };
38
39enum
40 {
41 access_read,
42 access_write,
43 access_append
44 };
45
46//==========================================================================
47//
48// SafeOpenWrite - Opens a file for writing, returns handle
49//
50//==========================================================================
51int32 SafeOpenWrite ( const char * filename, int32 filetype );
52
53//==========================================================================
54//
55// SafeOpenRead - Opens a file for reading, returns handle
56//
57//==========================================================================
58int32 SafeOpenRead ( const char * filename, int32 filetype );
59
60//==========================================================================
61//
62// SafeOpenAppend - Opens a file for appending, returns handle
63//
64//==========================================================================
65int32 SafeOpenAppend ( const char * filename, int32 filetype );
66
67//==========================================================================
68//
69// SafeClose - Close a file denoted by the file handle
70//
71//==========================================================================
72void SafeClose ( int32 handle );
73
74//==========================================================================
75//
76// SafeFileExists - Checks for existence of file
77//
78//==========================================================================
79boolean SafeFileExists ( const char * filename );
80
81//==========================================================================
82//
83// SafeFileLength - Get length of a file pointed to by handle
84//
85//==========================================================================
86int32 SafeFileLength ( int32 handle );
87
88//==========================================================================
89//
90// SafeRead - reads from a handle
91//
92// handle - handle of file to read from
93//
94// buffer - pointer of buffer to read into
95//
96// count - number of bytes to read
97//
98//==========================================================================
99void SafeRead (int32 handle, void *buffer, int32 count);
100
101//==========================================================================
102//
103// SafeWrite - writes to a handle
104//
105// handle - handle of file to write to
106//
107// buffer - pointer of buffer to write from
108//
109// count - number of bytes to write
110//
111//==========================================================================
112void SafeWrite (int32 handle, void *buffer, int32 count);
113
114//==========================================================================
115//
116// LoadFile - Load a file
117//
118// filename - name of file
119//
120// bufferptr - pointer to pointer of buffer to read into
121//
122// returns number of bytes read
123//
124//==========================================================================
125int32 LoadFile ( const uint8_t * filename, void ** bufferptr );
126
127//==========================================================================
128//
129// SaveFile - Save a file
130//
131// filename - name of file
132//
133// bufferptr - pointer to buffer to write from
134//
135// count - number of bytes to write
136//
137//==========================================================================
138void SaveFile ( const uint8_t * filename, void * bufferptr, int32 count );
139
140//==========================================================================
141//
142// GetPathFromEnvironment - Add a pathname described in an environment
143// variable to a standard filename.
144//
145// fullname - final string containing entire path
146//
147// envname - string naming enivronment variable
148//
149// filename - standard filename
150//
151//==========================================================================
152void GetPathFromEnvironment( uint8_t *fullname, const uint8_t *envname, const uint8_t *filename );
153
154//==========================================================================
155//
156// DefaultExtension - Add a default extension to a path
157//
158// path - a path
159//
160// extension - default extension should include '.'
161//
162//==========================================================================
163void DefaultExtension (uint8_t *path, const uint8_t *extension);
164
165//==========================================================================
166//
167// DefaultPath - Add the default path to a filename if it doesn't have one
168//
169// path - filename
170//
171// extension - default path
172//
173//==========================================================================
174void DefaultPath (uint8_t *path, const uint8_t *basepath);
175
176//==========================================================================
177//
178// ExtractFileBase - Extract the base filename from a path
179//
180// path - the path
181//
182// dest - where the file base name will be placed
183//
184//==========================================================================
185void ExtractFileBase (uint8_t *path, uint8_t *dest);
186
187//==========================================================================
188//
189// GetExtension - Extract the extension from a name
190// returns true if an extension is found
191// returns false otherwise
192//
193//==========================================================================
194boolean GetExtension( uint8_t *filename, uint8_t *extension );
195
196//==========================================================================
197//
198// SetExtension - Sets the extension from a name. Assumes that enough
199// space is left at the end of the string to hold an extension.
200//
201//==========================================================================
202void SetExtension( uint8_t *filename, const uint8_t *extension );
203
204#ifdef __MSDOS__
205//******************************************************************************
206//
207// GetPath
208//
209// Purpose
210// To parse the directory entered by the user to make the directory.
211//
212// Parms
213// Path - the path to be parsed.
214//
215// Returns
216// Pointer to next path
217//
218//******************************************************************************
219uint8_t * GetPath (uint8_t * path, uint8_t *dir);
220
221//******************************************************************************
222//
223// ChangeDirectory ()
224//
225// Purpose
226// To change to a directory. Checks for drive changes.
227//
228// Parms
229// path - The path to change to.
230//
231// Returns
232// TRUE - If successful.
233// FALSE - If unsuccessful.
234//
235//******************************************************************************
236boolean ChangeDirectory (uint8_t * path);
237
238//******************************************************************************
239//
240// ChangeDrive ()
241//
242// Purpose
243// To change drives.
244//
245// Parms
246// drive - The drive to change to.
247//
248// Returns
249// TRUE - If drive change successful.
250// FALSE - If drive change unsuccessful.
251//
252//******************************************************************************
253boolean ChangeDrive (uint8_t *drive);
254
255#endif
256
257#ifdef __cplusplus
258};
259#endif
260#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/funct.h b/apps/plugins/sdl/progs/duke3d/Game/src/funct.h
new file mode 100644
index 0000000000..96cf1989db
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/funct.h
@@ -0,0 +1,593 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#ifndef FUNCT_H
28#define FUNCT_H
29
30#include "duke3d.h"
31
32extern void sendscore(char *s);
33//#line "sounds.c" 25
34extern void SoundStartup(void );
35//#line "sounds.c" 95
36extern void SoundShutdown(void );
37//#line "sounds.c" 118
38extern void MusicStartup(void );
39//#line "sounds.c" 166
40extern void MusicShutdown(void );
41//#line "sounds.c" 181
42extern int USRHOOKS_GetMem(void **ptr,uint32_t size);
43//#line "sounds.c" 192
44extern int USRHOOKS_FreeMem(void *ptr);
45//#line "sounds.c" 200
46extern void intomenusounds(void );
47//#line "sounds.c" 227
48extern void playmusic(char *fn);
49//#line "sounds.c" 251
50extern uint8_t loadsound(uint16_t num);
51//#line "sounds.c" 277
52extern int xyzsound(short num,short i,int32_t x,int32_t y,int32_t z);
53//#line "sounds.c" 407
54extern void sound(short num);
55//#line "sounds.c" 463
56extern int spritesound(uint16_t num,short i);
57//#line "sounds.c" 469
58extern void stopsound(short num);
59//#line "sounds.c" 478
60extern void stopenvsound(short num,short i);
61//#line "sounds.c" 494
62extern void pan3dsound(void );
63//#line "sounds.c" 571
64extern void TestCallBack(int32_t num);
65//#line "sector.c" 9
66extern short callsound(short sn,short whatsprite);
67//#line "sector.c" 56
68extern short check_activator_motion(short lotag);
69//#line "sector.c" 93
70extern uint8_t isadoorwall(short dapic);
71//#line "sector.c" 124
72extern uint8_t isanunderoperator(short lotag);
73//#line "sector.c" 139
74extern uint8_t isanearoperator(short lotag);
75//#line "sector.c" 161
76extern short checkcursectnums(short sect);
77//#line "sector.c" 169
78extern int32_t ldist(spritetype *s1,spritetype *s2);
79//#line "sector.c" 177
80extern int32_t dist(spritetype *s1,spritetype *s2);
81//#line "sector.c" 186
82extern short findplayer(spritetype *s,int32_t *d);
83//#line "sector.c" 214
84extern short findotherplayer(short p,int32_t *d);
85//#line "sector.c" 240
86extern void doanimations(void );
87//#line "sector.c" 301
88extern int32_t getanimationgoal(int32_t *animptr);
89//#line "sector.c" 315
90extern int32_t setanimation(short animsect,int32_t *animptr,int32_t thegoal,int32_t thevel);
91//#line "sector.c" 348
92extern void animatecamsprite(void );
93//#line "sector.c" 369
94extern void animatewalls(void );
95//#line "sector.c" 457
96extern uint8_t activatewarpelevators(short s,short d);
97//#line "sector.c" 504
98extern void operatesectors(short sn,short ii);
99//#line "sector.c" 997
100extern void operaterespawns(short low);
101//#line "sector.c" 1020
102extern void operateactivators(short low,short snum);
103//#line "sector.c" 1089
104extern void operatemasterswitches(short low);
105//#line "sector.c" 1104
106extern void operateforcefields(short s,short low);
107//#line "sector.c" 1140
108extern uint8_t checkhitswitch(short snum,int32_t w,uint8_t switchtype);
109//#line "sector.c" 1515
110extern void activatebysector(short sect,short j);
111//#line "sector.c" 1532
112extern void checkhitwall(short spr,short dawallnum,int32_t x,int32_t y,int32_t z,short atwith);
113//#line "sector.c" 1746
114extern void checkplayerhurt(struct player_struct *p,short j);
115//#line "sector.c" 1816
116extern uint8_t checkhitceiling(short sn);
117//#line "sector.c" 1891
118extern void checkhitsprite(short i,short sn);
119//#line "sector.c" 2326
120extern void allignwarpelevators(void );
121//#line "sector.c" 2357
122extern void cheatkeys(short snum);
123//#line "sector.c" 2766
124extern void checksectors(short snum);
125//#line "rts.c" 36
126extern void RTS_AddFile(char *filename);
127//#line "rts.c" 93
128extern void RTS_Init(char *filename);
129//#line "rts.c" 126
130extern int32 RTS_NumSounds(void );
131//#line "rts.c" 141
132extern int32 RTS_SoundLength(int32 lump);
133//#line "rts.c" 157
134extern char *RTS_GetSoundName(int32 i);
135//#line "rts.c" 174
136extern void RTS_ReadLump(int32 lump,void *dest);
137//#line "rts.c" 194
138extern void *RTS_GetSound(int32 lump);
139//#line "premap.c" 7
140extern void xyzmirror(short i,short wn);
141//#line "premap.c" 20
142extern void vscrn(void );
143//#line "premap.c" 58
144int countfragbars(void);
145extern void pickrandomspot(short snum);
146//#line "premap.c" 80
147extern void resetplayerstats(short snum);
148//#line "premap.c" 187
149extern void resetweapons(short snum);
150//#line "premap.c" 212
151extern void resetinventory(short snum);
152//#line "premap.c" 232
153extern void resetprestat(short snum,uint8_t g);
154//#line "premap.c" 294
155extern void setupbackdrop(short backpicnum);
156//#line "premap.c" 329
157extern void cachespritenum(short i);
158//#line "premap.c" 443
159extern void cachegoodsprites(void );
160//#line "premap.c" 516
161extern void prelevel(uint8_t g);
162//#line "premap.c" 823
163extern void newgame(uint8_t vn,uint8_t ln,uint8_t sk);
164//#line "premap.c" 874
165extern void resetpspritevars(uint8_t g);
166//#line "premap.c" 1012
167extern void resettimevars(void );
168//#line "premap.c" 1043
169extern void genspriteremaps(void );
170//#line "premap.c" 1077
171extern void waitforeverybody(void);
172//#line "premap.c" 1131
173extern uint8_t checksum(int32_t sum);
174//#line "premap.c" 1163
175extern uint8_t getsound(uint16_t num);
176//#line "premap.c" 1189
177extern void precachenecessarysounds(void );
178//#line "premap.c" 1201
179extern void cacheit(void );
180//#line "premap.c" 1244
181extern void dofrontscreens(void );
182//#line "premap.c" 1285
183extern void enterlevel(uint8_t g);
184//#line "player.c" 10
185extern void setpal(struct player_struct *p);
186//#line "player.c" 28
187extern void incur_damage(struct player_struct *p);
188//#line "player.c" 59
189extern void quickkill(struct player_struct *p);
190//#line "player.c" 73
191extern void forceplayerangle(struct player_struct *p);
192//#line "player.c" 85
193extern void tracers(int32_t x1,int32_t y1,int32_t z1,int32_t x2,int32_t y2,int32_t z2,int32_t n);
194//#line "player.c" 114
195extern int32_t hits(short i);
196//#line "player.c" 131
197extern int32_t hitasprite(short i,short *hitsp);
198//#line "player.c" 152
199extern int32_t hitawall(struct player_struct *p,short *hitw);
200//#line "player.c" 163
201extern short aim(spritetype *s,short aang, short auto_aim);
202//#line "player.c" 234
203extern void shoot(short i,short atwith);
204//#line "player.c" 939
205extern void displayloogie(short snum);
206//#line "player.c" 958
207extern uint8_t animatefist(short gs,short snum);
208//#line "player.c" 986
209extern uint8_t animateknee(short gs,short snum);
210//#line "player.c" 1002
211extern uint8_t animateknuckles(short gs,short snum);
212//#line "player.c" 1022
213extern void displaymasks(short snum);
214//#line "player.c" 1043
215extern uint8_t animatetip(short gs,short snum);
216//#line "player.c" 1064
217extern uint8_t animateaccess(short gs,short snum);
218//#line "player.c" 1090
219extern void displayweapon(short snum);
220//#line "player.c" 1501
221extern void getinput(short snum);
222//#line "player.c" 1742
223extern uint8_t doincrements(struct player_struct *p);
224//#line "player.c" 1935
225extern void checkweapons(struct player_struct *p);
226//#line "player.c" 1951
227extern void processinput(short snum);
228//#line "menues.c" 18
229extern void cmenu(short cm);
230//#line "menues.c" 38
231extern void savetemp(char *fn,uint8_t* daptr,int32_t dasiz);
232//#line "menues.c" 49
233extern void getangplayers(short snum);
234//#line "menues.c" 67
235extern int loadpheader(uint8_t spot,int32 *vn,int32 *ln,int32 *psk,int32 *numplr);
236//#line "menues.c" 105
237extern int loadplayer(int8_t spot);
238//#line "menues.c" 276
239extern int saveplayer(int8_t spot);
240//#line "menues.c" 421
241extern void sendgameinfo(void );
242//#line "menues.c" 434
243extern int probe(int x,int y,int i,int n);
244extern int probeXduke(int x,int y,int i,int n, int32_t spriteSize);
245//#line "menues.c" 521
246extern int menutext(int x,int y,short s,short p,char *t);
247//#line "menues.c" 630
248extern int menutextc(int x,int y,short s,short p,char *t);
249//#line "menues.c" 727
250extern void bar(int x,int y,short *p,short dainc,uint8_t damodify,short s,short pa);
251//#line "menues.c" 806
252extern void dispnames(void );
253//#line "menues.c" 832
254extern int getfilenames(char kind[]);
255//#line "menues.c" 865
256extern void sortfilenames(void);
257//#line "menues.c" 886
258extern void menus(void );
259void gameexitanycase(void);
260//#line "menues.c" 2414
261extern void palto(uint8_t r,uint8_t g,uint8_t b,int32_t e);
262//#line "menues.c" 2436
263extern void drawoverheadmap(int32_t cposx,int32_t cposy,int32_t czoom,short cang);
264//#line "menues.c" 2685
265extern void playanm(char *fn,uint8_t );
266//#line "gamedef.c" 122
267extern short getincangle(short a,short na);
268//#line "gamedef.c" 140
269extern uint8_t ispecial(uint8_t c);
270//#line "gamedef.c" 154
271extern uint8_t isaltok(uint8_t c);
272//#line "gamedef.c" 159
273extern void getglobalz(short i);
274//#line "gamedef.c" 203
275extern void makeitfall(short i);
276//#line "gamedef.c" 243
277extern void getlabel(void );
278//#line "gamedef.c" 267
279extern int32_t keyword(void );
280//#line "gamedef.c" 300
281extern int32_t transword(void );
282//#line "gamedef.c" 342
283extern void transnum(void );
284//#line "gamedef.c" 402
285extern uint8_t parsecommand(int readfromGRP );
286//#line "gamedef.c" 1227
287extern void passone(int readfromGRP);
288//#line "gamedef.c" 1239
289extern void loadefs(char *fn,char *mptr, int readfromGRP);
290//#line "gamedef.c" 1342
291extern uint8_t dodge(spritetype *s);
292//#line "gamedef.c" 1374
293extern short furthestangle(short i,short angs);
294//#line "gamedef.c" 1404
295extern short furthestcanseepoint(short i,spritetype *ts,int32_t *dax,int32_t *day);
296//#line "gamedef.c" 1444
297extern void alterang(short a);
298//#line "gamedef.c" 1512
299extern void move(void);
300//#line "gamedef.c" 1711
301extern void parseifelse(int32_t condition);
302//#line "gamedef.c" 1729
303extern uint8_t parse(void );
304//#line "gamedef.c" 2699
305extern void execute(short i,short p,int32_t x);
306//#line "game.c" 63
307extern void overwritesprite(int32_t thex,int32_t they,short tilenum,int8_t shade,uint8_t stat,uint8_t dapalnum);
308//#line "game.c" 70
309extern void timerhandler(void);
310//#line "game.c" 75
311extern int inittimer(int);
312//#line "game.c" 81
313extern void uninittimer(void );
314//#line "game.c" 89
315extern int gametext(int x,int y,char *t,uint8_t s,short dabits);
316//#line "game.c" 136
317extern int gametextpart(int x,int y,char *t,uint8_t s,short p);
318//#line "game.c" 192
319extern int minitext(int x,int y,char *t,uint8_t p,uint8_t sb);
320//#line "game.c" 231
321extern void gamenumber(int32_t x,int32_t y,int32_t n,uint8_t s);
322//#line "game.c" 248
323extern void ShutDown(void );
324//#line "game.c" 260
325extern void allowtimetocorrecterrorswhenquitting(void );
326//#line "game.c" 280
327extern void getpackets(void );
328//#line "game.c" 502
329extern void faketimerhandler(void);
330//#line "game.c" 788
331extern void checksync(void );
332//#line "game.c" 815
333extern void check_fta_sounds(short i);
334//#line "game.c" 869
335extern short inventory(spritetype *s);
336//#line "game.c" 886
337extern short badguy(spritetype *s);
338//#line "game.c" 924
339extern short badguypic(short pn);
340//#line "game.c" 963
341extern void myos(int32_t x,int32_t y,short tilenum,int8_t shade,uint8_t orientation);
342//#line "game.c" 976
343extern void myospal(int32_t x,int32_t y,short tilenum,int8_t shade,uint8_t orientation,uint8_t p);
344//#line "game.c" 991
345extern void invennum(int32_t x,int32_t y,uint8_t num1,uint8_t ha,uint8_t sbits);
346//#line "game.c" 1021
347extern void weaponnum(short ind,int32_t x,int32_t y,int32_t num1,int32_t num2,uint8_t ha);
348//#line "game.c" 1049
349extern void weaponnum999(uint8_t ind,int32_t x,int32_t y,int32_t num1,int32_t num2,uint8_t ha);
350//#line "game.c" 1088
351extern void weapon_amounts(struct player_struct *p,int32_t x,int32_t y,int32_t u);
352//#line "game.c" 1197
353extern void digitalnumber(int32_t x,int32_t y,int32_t n,uint8_t s,uint8_t cs);
354//#line "game.c" 1223
355extern void scratchmarks(int32_t x,int32_t y,int32_t n,uint8_t s,uint8_t p);
356//#line "game.c" 1238
357extern void displayinventory(struct player_struct *p);
358//#line "game.c" 1296
359extern void displayfragbar(void );
360//#line "game.c" 1318
361void drawsmallweapon(short weapon, float scale, short x, short y); // xduke
362extern void coolgaugetext(short snum);
363//#line "game.c" 1557
364extern void tics(short offx, short offy , short color);
365//#line "game.c" 1572
366extern void clocks(void );
367//#line "game.c" 1582
368extern void coords(short snum);
369//#line "game.c" 1607
370extern void operatefta(void);
371//#line "game.c" 1654
372extern void FTA(short q,struct player_struct *p, int mode);
373//#line "game.c" 1668
374extern void showtwoscreens(void );
375
376//#line "game.c" 1705
377extern void gameexit(char *t);
378//#line "game.c" 1752
379extern short strget(short x,short y,char *t,short dalen,short c);
380//#line "game.c" 1819
381extern void displayrest(int32_t smoothratio);
382//#line "game.c" 2047
383extern void updatesectorz(int32_t x,int32_t y,int32_t z,short *sectnum);
384//#line "game.c" 2085
385extern void view(struct player_struct *pp,int32_t *vx,int32_t *vy,int32_t *vz,short *vsectnum,short ang,short horiz);
386//#line "game.c" 2137
387extern void drawbackground(void );
388//#line "game.c" 2200
389extern void displayrooms(short snum,int32_t smoothratio);
390//#line "game.c" 2445
391extern short LocateTheLocator(short n,short sn);
392//#line "game.c" 2459
393extern short EGS(short whatsect,int32_t s_x,int32_t s_y,int32_t s_z,short s_pn,int8_t s_s,int8_t s_xr,int8_t s_yr,short s_a,short s_ve,int32_t s_zv,short s_ow,int8_t s_ss);
394//#line "game.c" 2537
395extern uint8_t wallswitchcheck(short i);
396//#line "game.c" 2588
397extern short spawn(short j,short pn);
398//#line "game.c" 4181
399extern void animatesprites(int32_t x,int32_t y,short a,int32_t smoothratio);
400//#line "game.c" 4859
401extern void cheats(void );
402//#line "game.c" 5303
403extern void nonsharedkeys(void );
404//#line "game.c" 5863
405extern void comlinehelp(char **argv);
406//#line "game.c" 5889
407extern void checkcommandline(int argc,char **argv);
408//#line "game.c" 6078
409extern void printstr(short x,short y,uint8_t string[],uint8_t attribute);
410//#line "game.c" 6104
411extern void Logo(void );
412//#line "game.c" 6187
413extern void loadtmb(void );
414//#line "game.c" 6210
415extern void compilecons(void );
416//#line "game.c" 6230
417extern void Startup(void );
418//#line "game.c" 6284
419extern void getnames(void );
420//#line "game.c" 6309
421extern int main(int argc,char **argv);
422//#line "game.c" 6563
423extern uint8_t opendemoread(uint8_t which_demo);
424//#line "game.c" 6589
425extern void opendemowrite(void );
426//#line "game.c" 6608
427extern void record(void );
428//#line "game.c" 6626
429extern void closedemowrite(void );
430//#line "game.c" 6642
431extern int32_t playback(void );
432//#line "game.c" 6777
433extern uint8_t moveloop(void);
434//#line "game.c" 6796
435extern void fakedomovethingscorrect(void);
436//#line "game.c" 6829
437extern void fakedomovethings(void );
438//#line "game.c" 7247
439extern uint8_t domovethings(void );
440//#line "game.c" 7373
441extern void displaybonuspics(short x,short y,short p);
442//#line "game.c" 7396
443extern void doorders(void );
444//#line "game.c" 7432
445extern void dobonus(uint8_t bonusonly);
446//#line "game.c" 7846
447extern void cameratext(short i);
448//#line "game.c" 7869
449extern void vglass(int32_t x,int32_t y,short a,short wn,short n);
450//#line "game.c" 7882
451extern void lotsofglass(short i,short wallnum,short n);
452//#line "game.c" 7924
453extern void spriteglass(short i,short n);
454//#line "game.c" 7937
455extern void ceilingglass(short i,short sectnum,short n);
456//#line "game.c" 7966
457extern void lotsofcolourglass(short i,short wallnum,short n);
458//#line "game.c" 8004
459extern void SetupGameButtons(void );
460//#line "game.c" 8068
461extern int32_t GetTime(void );
462//#line "game.c" 8082
463extern void CenterCenter(void );
464//#line "game.c" 8095
465extern void UpperLeft(void );
466//#line "game.c" 8108
467extern void LowerRight(void );
468//#line "game.c" 8121
469extern void CenterThrottle(void );
470//#line "game.c" 8134
471extern void CenterRudder(void );
472//#line "game.c" ????
473extern void takescreenshot(void );
474//#line "config.c" 57
475extern void CONFIG_GetSetupFilename(void );
476//#line "config.c" 170
477extern int32 CONFIG_FunctionNameToNum(char *func);
478//#line "config.c" 192
479extern char *CONFIG_FunctionNumToName(int32 func);
480//#line "config.c" 211
481extern int32 CONFIG_AnalogNameToNum(char *func);
482//#line "config.c" 240
483extern void CONFIG_SetDefaults(void );
484//#line "config.c" 264
485extern void CONFIG_ReadKeys(void );
486//#line "config.c" 314
487extern void CONFIG_SetupMouse(int32 scripthandle);
488//#line "config.c" 376
489extern void CONFIG_SetupGamePad(int32 scripthandle);
490//#line "config.c" 427
491extern void CONFIG_SetupJoystick(int32 scripthandle);
492//#line "config.c" 485
493extern void readsavenames(void );
494//#line "config.c" 512
495extern void CONFIG_ReadSetup(void );
496//#line "config.c" 613
497extern void CONFIG_WriteSetup(void );
498//#line "animlib.c" 34
499extern void CheckAnimStarted(uint8_t *funcname);
500//#line "animlib.c" 46
501extern uint16 findpage(uint16 framenumber);
502//#line "animlib.c" 71
503extern void loadpage(uint16 pagenumber,uint16 *pagepointer);
504//#line "animlib.c" 97
505extern void CPlayRunSkipDump(byte *srcP,byte *dstP);
506//#line "animlib.c" 177
507extern void renderframe(uint16 framenumber,uint16 *pagepointer);
508//#line "animlib.c" 214
509extern void drawframe(uint16 framenumber);
510//#line "animlib.c" 228
511extern void ANIM_LoadAnim(byte *buffer);
512//#line "animlib.c" 260
513extern void ANIM_FreeAnim(void );
514//#line "animlib.c" 275
515extern int32 ANIM_NumFrames(void );
516//#line "animlib.c" 287
517extern byte *ANIM_DrawFrame(int32 framenumber);
518//#line "animlib.c" 312
519extern byte *ANIM_GetPalette(void );
520//#line "actors.c" 7
521extern void updateinterpolations(void);
522//#line "actors.c" 15
523extern void setinterpolation(int32_t *posptr);
524//#line "actors.c" 27
525extern void stopinterpolation(int32_t *posptr);
526//#line "actors.c" 41
527extern void dointerpolations(int32_t smoothratio);
528//#line "actors.c" 55
529extern void restoreinterpolations(void);
530//#line "actors.c" 63
531extern int32_t ceilingspace(short sectnum);
532//#line "actors.c" 77
533extern int32_t floorspace(short sectnum);
534//#line "actors.c" 91
535extern void addammo(short weapon,struct player_struct *p,short amount);
536//#line "actors.c" 99
537extern void addweapon(struct player_struct *p,short weapon);
538//#line "actors.c" 132
539extern void checkavailinven(struct player_struct *p);
540//#line "actors.c" 152
541extern void checkavailweapon(struct player_struct *p);
542//#line "actors.c" 301
543extern int32_t ifsquished(short i,short p);
544//#line "actors.c" 326
545extern void hitradius(short i,int32_t r,int32_t hp1,int32_t hp2,int32_t hp3,int32_t hp4);
546//#line "actors.c" 556
547extern int movesprite(short spritenum,int32_t xchange,int32_t ychange,int32_t zchange,uint32_t cliptype);
548//#line "actors.c" 643
549extern short ssp(short i,uint32_t cliptype);
550//#line "actors.c" 658
551extern void insertspriteq(short i);
552//#line "actors.c" 666
553extern void lotsofmoney(spritetype *s,short n);
554//#line "actors.c" 676
555extern void guts(spritetype *s,short gtype,short n,short p);
556//#line "actors.c" 718
557extern void setsectinterpolate(short i);
558//#line "actors.c" 742
559extern void clearsectinterpolate(short i);
560//#line "actors.c" 760
561extern void ms(short i);
562//#line "actors.c" 791
563extern void movefta(void );
564//#line "actors.c" 882
565extern short ifhitsectors(short sectnum);
566//#line "actors.c" 896
567extern short ifhitbyweapon(short sn);
568//#line "actors.c" 970
569extern void movecyclers(void );
570//#line "actors.c" 1007
571extern void movedummyplayers(void );
572//#line "actors.c" 1053
573extern void moveplayers(void );
574//#line "actors.c" 1192
575extern void movefx(void );
576//#line "actors.c" 1294
577extern void movefallers(void );
578//#line "actors.c" 1389
579extern void movestandables(void );
580//#line "actors.c" 2234
581extern void bounce(short i);
582//#line "actors.c" 2273
583extern void moveweapons(void );
584//#line "actors.c" 2613
585extern void movetransports(void );
586//#line "actors.c" 2887
587extern void moveeffectors(void );
588//#line "actors.c" 4840
589extern void moveactors(void );
590//#line "actors.c" 6005
591extern void moveexplosions(void );
592
593#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/function.h b/apps/plugins/sdl/progs/duke3d/Game/src/function.h
new file mode 100644
index 0000000000..3895f0f4ac
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/function.h
@@ -0,0 +1,106 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27// function.h
28
29// file created by makehead.exe
30// these headers contain default key assignments, as well as
31// default button assignments and game function names
32// axis defaults are also included
33
34
35#ifndef _function_public_
36#define _function_public_
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41 #define NUMGAMEFUNCTIONS 55 //dont forget to check NUMKEYENTRIES
42
43extern char * gamefunctions[];
44
45enum
46 {
47 gamefunc_Move_Forward,
48 gamefunc_Move_Backward,
49 gamefunc_Turn_Left,
50 gamefunc_Turn_Right,
51 gamefunc_Strafe,
52 gamefunc_Fire,
53 gamefunc_Open,
54 gamefunc_Run,
55 gamefunc_AutoRun,
56 gamefunc_Jump,
57 gamefunc_Crouch,
58 gamefunc_Look_Up,
59 gamefunc_Look_Down,
60 gamefunc_Look_Left,
61 gamefunc_Look_Right,
62 gamefunc_Strafe_Left,
63 gamefunc_Strafe_Right,
64 gamefunc_Aim_Up,
65 gamefunc_Aim_Down,
66 gamefunc_Weapon_1,
67 gamefunc_Weapon_2,
68 gamefunc_Weapon_3,
69 gamefunc_Weapon_4,
70 gamefunc_Weapon_5,
71 gamefunc_Weapon_6,
72 gamefunc_Weapon_7,
73 gamefunc_Weapon_8,
74 gamefunc_Weapon_9,
75 gamefunc_Weapon_10,
76 gamefunc_Inventory,
77 gamefunc_Inventory_Left,
78 gamefunc_Inventory_Right,
79 gamefunc_Holo_Duke,
80 gamefunc_Jetpack,
81 gamefunc_NightVision,
82 gamefunc_MedKit,
83 gamefunc_TurnAround,
84 gamefunc_SendMessage,
85 gamefunc_Map,
86 gamefunc_Shrink_Screen,
87 gamefunc_Enlarge_Screen,
88 gamefunc_Center_View,
89 gamefunc_Holster_Weapon,
90 gamefunc_Show_Opponents_Weapon,
91 gamefunc_Map_Follow_Mode,
92 gamefunc_See_Coop_View,
93 gamefunc_Mouse_Aiming,
94 gamefunc_Toggle_Crosshair,
95 gamefunc_Steroids,
96 gamefunc_Quick_Kick,
97 gamefunc_Next_Weapon,
98 gamefunc_Previous_Weapon,
99 gamefunc_Hide_Weapon,
100 gamefunc_Auto_Aim,
101 gamefunc_Console
102 };
103#ifdef __cplusplus
104};
105#endif
106#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/game.c b/apps/plugins/sdl/progs/duke3d/Game/src/game.c
new file mode 100644
index 0000000000..303ac56ea9
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/game.c
@@ -0,0 +1,10966 @@
1//-------------------------------------------------------------------------
2/*
3 Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5 This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7 Duke Nukem 3D is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 aint32_t with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 Original Source: 1996 - Todd Replogle
23 Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#ifdef _WIN32
28#include <windows.h>
29#else
30#include "SDL.h"
31#endif
32
33#include "types.h"
34
35#include "develop.h"
36#include "scriplib.h"
37#include "file_lib.h"
38#include "gamedefs.h"
39#include "keyboard.h"
40#include "util_lib.h"
41#include "function.h"
42#include "control.h"
43#include "sounds.h"
44#include "config.h"
45#include "audiolib/sndcards.h"
46
47#include "duke3d.h"
48
49#include "console.h"
50#include "cvars.h"
51#include "cvar_defs.h"
52
53#include "global.h"
54
55
56#define MINITEXT_BLUE 0
57#define MINITEXT_RED 2
58#define MINITEXT_YELLOW 23
59#define MINITEXT_GRAY 17
60
61#define COLOR_ON MINITEXT_YELLOW
62#define COLOR_OFF MINITEXT_BLUE
63
64#define IDFSIZE 479985668
65// #define IDFSIZE 9961476
66// #define IDFSIZE 16384
67#define IDFILENAME "DUKE3D.IDF"
68
69#define TIMERUPDATESIZ 32
70
71int32_t cameradist = 0, cameraclock = 0;
72uint8_t eightytwofifty = 0;
73uint8_t playerswhenstarted;
74uint8_t qe,cp;
75
76uint8_t nHostForceDisableAutoaim = 0;
77
78// Game play speed
79int g_iTickRate = 120;
80int g_iTicksPerFrame = 26;
81
82int32 CommandSoundToggleOff = 0;
83int32 CommandMusicToggleOff = 0;
84
85// For addfaz's stun server. use /stun to activate
86uint16_t g_bStun = 0;
87
88char confilename[128] = {"GAME.CON"};
89char boardfilename[128] = {0};
90uint8_t waterpal[768], slimepal[768], titlepal[768], drealms[768], endingpal[768];
91char firstdemofile[80] = { '\0' };
92
93#define patchstatusbar(x1,y1,x2,y2) \
94 { \
95 rotatesprite(0,(200-34)<<16,65536L,0,BOTTOMSTATUSBAR,4,0,10+16+64+128, \
96 scale(x1,xdim,320),scale(y1,ydim,200), \
97 scale(x2,xdim,320)-1,scale(y2,ydim,200)-1); \
98 }
99
100void newint24( int errval, int ax, int bp, int si );
101
102int recfilep,totalreccnt;
103uint8_t debug_on = 0,actor_tog = 0,memorycheckoveride=0;
104uint8_t *rtsptr;
105
106
107extern uint8_t syncstate;
108extern int32 numlumps;
109
110FILE *frecfilep = (FILE *)NULL;
111void pitch_test( void );
112
113uint8_t restorepalette,screencapt,nomorelogohack;
114int sendmessagecommand = -1;
115
116#if PLATFORM_DOS
117task *TimerPtr=NULL;
118#endif
119
120extern int32_t lastvisinc;
121
122// Build Engine port implements this. --ryan.
123#if PLATFORM_DOS
124static void timerhandler(task *unused)
125{
126 totalclock++;
127}
128
129void inittimer()
130{
131 TimerPtr = TS_ScheduleTask( timerhandler,TICRATE, 1, NULL );
132 TS_Dispatch();
133}
134
135void uninittimer(void)
136{
137 if (TimerPtr)
138 TS_Terminate( TimerPtr );
139 TimerPtr = NULL;
140 TS_Shutdown();
141}
142#else
143void timerhandler(void)
144{
145 totalclock++;
146}
147#endif
148
149int gametext(int x,int y,char *t,uint8_t s,short dabits)
150{
151 short ac,newx;
152 char* oldt;
153 uint8_t centre;
154
155 centre = ( x == (320>>1) );
156 newx = 0;
157 oldt = t;
158
159 if(centre)
160 {
161 while(*t)
162 {
163 if(*t == 32) {newx+=5;t++;continue;}
164 else ac = *t - '!' + STARTALPHANUM;
165
166 if( ac < STARTALPHANUM || ac > ENDALPHANUM ) break;
167
168 if(*t >= '0' && *t <= '9')
169 newx += 8;
170 else newx += tiles[ac].dim.width;
171 t++;
172 }
173
174 t = oldt;
175 x = (320>>1)-(newx>>1);
176 }
177
178 while(*t)
179 {
180 if(*t == 32) {x+=5;t++;continue;}
181 else ac = *t - '!' + STARTALPHANUM;
182
183 if( ac < STARTALPHANUM || ac > ENDALPHANUM )
184 break;
185
186 rotatesprite(x<<16,y<<16,65536L,0,ac,s,0,dabits,0,0,xdim-1,ydim-1);
187
188 if(*t >= '0' && *t <= '9')
189 x += 8;
190 else x += tiles[ac].dim.width;
191
192 t++;
193 }
194
195 return (x);
196}
197
198int gametextpal(int x,int y,char *t,uint8_t s,uint8_t p)
199{
200 short ac,newx;
201 uint8_t centre;
202 char* oldt;
203
204 centre = ( x == (320>>1) );
205 newx = 0;
206 oldt = t;
207
208 if(centre)
209 {
210 while(*t)
211 {
212 if(*t == 32) {newx+=5;t++;continue;}
213 else ac = *t - '!' + STARTALPHANUM;
214
215 if( ac < STARTALPHANUM || ac > ENDALPHANUM ) break;
216
217 if(*t >= '0' && *t <= '9')
218 newx += 8;
219 else newx += tiles[ac].dim.width;
220 t++;
221 }
222
223 t = oldt;
224 x = (320>>1)-(newx>>1);
225 }
226
227 while(*t)
228 {
229 if(*t == 32) {x+=5;t++;continue;}
230 else ac = *t - '!' + STARTALPHANUM;
231
232 if( ac < STARTALPHANUM || ac > ENDALPHANUM )
233 break;
234
235 rotatesprite(x<<16,y<<16,65536L,0,ac,s,p,2+8+16,0,0,xdim-1,ydim-1);
236 if(*t >= '0' && *t <= '9')
237 x += 8;
238 else x += tiles[ac].dim.width;
239
240 t++;
241 }
242
243 return (x);
244}
245
246int gametextpart(int x,int y,char *t,uint8_t s,short p)
247{
248 short ac,newx, cnt;
249 uint8_t centre;
250 char * oldt;
251
252 centre = ( x == (320>>1) );
253 newx = 0;
254 oldt = t;
255 cnt = 0;
256
257 if(centre)
258 {
259 while(*t)
260 {
261 if(cnt == p) break;
262
263 if(*t == 32) {newx+=5;t++;continue;}
264 else ac = *t - '!' + STARTALPHANUM;
265
266 if( ac < STARTALPHANUM || ac > ENDALPHANUM ) break;
267
268 newx += tiles[ac].dim.width;
269 t++;
270 cnt++;
271
272 }
273
274 t = oldt;
275 x = (320>>1)-(newx>>1);
276 }
277
278 cnt = 0;
279 while(*t)
280 {
281 if(*t == 32) {x+=5;t++;continue;}
282 else ac = *t - '!' + STARTALPHANUM;
283
284 if( ac < STARTALPHANUM || ac > ENDALPHANUM ) break;
285
286 if(cnt == p)
287 {
288 rotatesprite(x<<16,y<<16,65536L,0,ac,s,1,2+8+16,0,0,xdim-1,ydim-1);
289 break;
290 }
291 else
292 rotatesprite(x<<16,y<<16,65536L,0,ac,s,0,2+8+16,0,0,xdim-1,ydim-1);
293
294 x += tiles[ac].dim.width;
295
296 t++;
297 cnt++;
298 }
299
300 return (x);
301}
302
303int minitext(int x,int y,char *str,uint8_t p,uint8_t sb)
304{
305 short ac;
306 char buf[128];
307 char *t;
308
309 strncpy (buf, str, 128);
310 buf[127] = 0;
311 t = buf;
312
313 while(*t)
314 {
315 *t = toupper(*t);
316 if(*t == 32) {x+=5;t++;continue;}
317 else ac = *t - '!' + MINIFONT;
318
319 rotatesprite(x<<16,y<<16,65536L,0,ac,0,p,sb,0,0,xdim-1,ydim-1);
320 x += 4; // tilesizx[ac]+1;
321
322 t++;
323 }
324 return (x);
325}
326
327int minitextshade(int x,int y,char *str,uint8_t s,uint8_t p,uint8_t sb)
328{
329 short ac;
330 char buf[128];
331 char *t;
332
333 strncpy (buf, str, 128);
334 buf[127] = 0;
335 t = buf;
336
337 while(*t)
338 {
339 *t = toupper(*t);
340 if(*t == 32) {x+=5;t++;continue;}
341 else ac = *t - '!' + MINIFONT;
342
343 rotatesprite(x<<16,y<<16,65536L,0,ac,s,p,sb,0,0,xdim-1,ydim-1);
344 x += 4; // tilesizx[ac]+1;
345
346 t++;
347 }
348 return (x);
349}
350
351void gamenumber(int32_t x,int32_t y,int32_t n,uint8_t s)
352{
353 char b[10];
354
355
356 //
357 // uint8_t * ltoa(int32_t l, uint8_t * buffer, int radix);
358 // is NON-STANDARD and equivalent to STANDARD
359 // (void) sprintf(buffer, "%ld", l);
360 //ltoa(n,b,10);
361 sprintf(b,"%d",n);
362 gametext(x,y,b,s,2+8+16);
363}
364
365
366char recbuf[80];
367void allowtimetocorrecterrorswhenquitting(void)
368{
369 int32_t i, j, oldtotalclock;
370
371 ready2send = 0;
372
373 for(j=0;j<8;j++)
374 {
375 oldtotalclock = totalclock;
376
377 while (totalclock < oldtotalclock+TICSPERFRAME)
378 getpackets();
379
380 if(KB_KeyPressed(sc_Escape)) return;
381
382 packbuf[0] = 127;
383 for(i=connecthead;i>=0;i=connectpoint2[i])
384 if (i != myconnectindex)
385 sendpacket(i,packbuf,1);
386 }
387}
388
389#define MAXUSERQUOTES 4
390int32_t quotebot, quotebotgoal;
391short user_quote_time[MAXUSERQUOTES];
392char user_quote[MAXUSERQUOTES][128];
393// uint8_t typebuflen,typebuf[41];
394
395static void adduserquote(char *daquote)
396{
397 int32_t i;
398
399 for(i=MAXUSERQUOTES-1;i>0;i--)
400 {
401 strcpy(user_quote[i],user_quote[i-1]);
402 user_quote_time[i] = user_quote_time[i-1];
403 }
404 strcpy(user_quote[0],daquote);
405 user_quote_time[0] = 180;
406 pub = NUMPAGES;
407}
408
409char *grpVersion2char_from_crc(unsigned int crc32_grp_to_identify)
410{
411 char *id;
412 int i=0;
413
414 id = crc32lookup[MAX_KNOWN_GRP].name; // unknown version
415
416 for(i=0; i<MAX_KNOWN_GRP; i++)
417 {
418 if(crc32lookup[i].crc32==crc32_grp_to_identify)
419 id = crc32lookup[i].name;
420 }
421
422 return(id);
423}
424
425char *grpVersion2char(uint8_t grp_to_identify)
426{
427 char *id;
428
429 switch(grp_to_identify)
430 {
431 case DUKEITOUTINDC_GRP:
432 id = "v1.5 DC PACK";
433 break;
434 case SHAREWARE_GRP13:
435 id = "v1.3 SHAREW.";
436 break;
437 case ATOMIC_GRP14_15:
438 id = "v1.5 ATOMIC";
439 break;
440 case REGULAR_GRP13D:
441 id = "v1.3D FULL";
442 break;
443 case UNKNOWN_GRP:
444 id = "vX.X UNKNOWN";
445 break;
446 default:
447 Error(EXIT_FAILURE,"Failed the GRP Identification\n");
448 break;
449 }
450
451 return(id);
452}
453
454//This is a function from the Engine module, used in getpackets.
455void sampletimer(void);
456
457void getpackets(void)
458{
459 int32_t i, j, k, l;
460 short other, packbufleng;
461 input *osyn, *nsyn;
462
463 sampletimer();
464 if(qe == 0 && KB_KeyPressed(sc_LeftControl) && KB_KeyPressed(sc_LeftAlt) && KB_KeyPressed(sc_Delete))
465 {
466 qe = 1;
467 gameexit("Quick Exit.");
468 }
469
470 // not a net game
471 if (numplayers < 2)
472 {
473 //printf("getpackets() numplayers < 2");
474 return;
475 }
476
477 while ((packbufleng = getpacket(&other,packbuf)) > 0)
478 {
479#ifdef _DEBUG_NETWORKING_
480 printf("RECEIVED PACKET: type: %d : len %d\n", packbuf[0], packbufleng);
481#endif
482
483 switch(packbuf[0])
484 {
485 case 253:
486 // This should have already been handled by mmulti.cpp so ignore it
487 printf("Invalid Packet: %d", packbuf[0]);
488 break;
489
490 case 125:
491 cp = 0;
492 break;
493
494 case 126:
495 multiflag = 2;
496 multiwhat = 0;
497 multiwho = other;
498 multipos = packbuf[1];
499 loadplayer( multipos );
500 multiflag = 0;
501 break;
502 case 0: //[0] (receive master sync buffer)
503 j = 1;
504
505 if ((movefifoend[other]&(TIMERUPDATESIZ-1)) == 0)
506 for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i])
507 {
508 if (playerquitflag[i] == 0) continue;
509 if (i == myconnectindex)
510 otherminlag = (int32_t)((int8_t )packbuf[j]);
511 j++;
512 }
513
514 osyn = (input *)&inputfifo[(movefifoend[connecthead]-1)&(MOVEFIFOSIZ-1)][0];
515 nsyn = (input *)&inputfifo[(movefifoend[connecthead])&(MOVEFIFOSIZ-1)][0];
516
517 k = j;
518 for(i=connecthead;i>=0;i=connectpoint2[i])
519 j += playerquitflag[i];
520 for(i=connecthead;i>=0;i=connectpoint2[i])
521 {
522 if (playerquitflag[i] == 0) continue;
523
524 l = packbuf[k++];
525 if (i == myconnectindex)
526 { j += ((l&1)<<1)+(l&2)+((l&4)>>2)+((l&8)>>3)+((l&16)>>4)+((l&32)>>5)+((l&64)>>6)+((l&128)>>7); continue; }
527
528 copybufbyte(&osyn[i],&nsyn[i],sizeof(input));
529 if (l&1) nsyn[i].fvel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2;
530 if (l&2) nsyn[i].svel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2;
531 if (l&4) nsyn[i].avel = (int8_t )packbuf[j++];
532 if (l&8) nsyn[i].bits = ((nsyn[i].bits&0xffffff00)|((int32_t)packbuf[j++]));
533 if (l&16) nsyn[i].bits = ((nsyn[i].bits&0xffff00ff)|((int32_t)packbuf[j++])<<8);
534 if (l&32) nsyn[i].bits = ((nsyn[i].bits&0xff00ffff)|((int32_t)packbuf[j++])<<16);
535 if (l&64) nsyn[i].bits = ((nsyn[i].bits&0x00ffffff)|((int32_t)packbuf[j++])<<24);
536 if (l&128) nsyn[i].horz = (int8_t )packbuf[j++];
537
538 if (nsyn[i].bits&(1<<26)) playerquitflag[i] = 0;
539 movefifoend[i]++;
540 }
541
542 while (j != packbufleng)
543 {
544 for(i=connecthead;i>=0;i=connectpoint2[i])
545 if(i != myconnectindex)
546 {
547 syncval[i][syncvalhead[i]&(MOVEFIFOSIZ-1)] = packbuf[j];
548 syncvalhead[i]++;
549 }
550 j++;
551 }
552
553 for(i=connecthead;i>=0;i=connectpoint2[i])
554 if (i != myconnectindex)
555 for(j=1;j<movesperpacket;j++)
556 {
557 copybufbyte(&nsyn[i],&inputfifo[movefifoend[i]&(MOVEFIFOSIZ-1)][i],sizeof(input));
558 movefifoend[i]++;
559 }
560
561 movefifosendplc += movesperpacket;
562
563 break;
564 case 1: //[1] (receive slave sync buffer)
565 j = 2; k = packbuf[1];
566
567 osyn = (input *)&inputfifo[(movefifoend[other]-1)&(MOVEFIFOSIZ-1)][0];
568 nsyn = (input *)&inputfifo[(movefifoend[other])&(MOVEFIFOSIZ-1)][0];
569
570 copybufbyte(&osyn[other],&nsyn[other],sizeof(input));
571 if (k&1) nsyn[other].fvel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2;
572 if (k&2) nsyn[other].svel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2;
573 if (k&4) nsyn[other].avel = (int8_t )packbuf[j++];
574 if (k&8) nsyn[other].bits = ((nsyn[other].bits&0xffffff00)|((int32_t)packbuf[j++]));
575 if (k&16) nsyn[other].bits = ((nsyn[other].bits&0xffff00ff)|((int32_t)packbuf[j++])<<8);
576 if (k&32) nsyn[other].bits = ((nsyn[other].bits&0xff00ffff)|((int32_t)packbuf[j++])<<16);
577 if (k&64) nsyn[other].bits = ((nsyn[other].bits&0x00ffffff)|((int32_t)packbuf[j++])<<24);
578 if (k&128) nsyn[other].horz = (int8_t )packbuf[j++];
579 movefifoend[other]++;
580
581 while (j != packbufleng)
582 {
583 syncval[other][syncvalhead[other]&(MOVEFIFOSIZ-1)] = packbuf[j++];
584 syncvalhead[other]++;
585 }
586
587 for(i=1;i<movesperpacket;i++)
588 {
589 copybufbyte(&nsyn[other],&inputfifo[movefifoend[other]&(MOVEFIFOSIZ-1)][other],sizeof(input));
590 movefifoend[other]++;
591 }
592
593 break;
594
595 case 4: // message talk T
596 strcpy(recbuf,(char*)packbuf+1);
597 recbuf[packbufleng-1] = 0;
598
599 adduserquote(recbuf);
600 sound(EXITMENUSOUND);
601
602 pus = NUMPAGES;
603 pub = NUMPAGES;
604
605 break;
606
607 case 5:
608 ud.m_level_number = ud.level_number = packbuf[1];
609 ud.m_volume_number = ud.volume_number = packbuf[2];
610 ud.m_player_skill = ud.player_skill = packbuf[3];
611 ud.m_monsters_off = ud.monsters_off = packbuf[4];
612 ud.m_respawn_monsters = ud.respawn_monsters = packbuf[5];
613 ud.m_respawn_items = ud.respawn_items = packbuf[6];
614 ud.m_respawn_inventory = ud.respawn_inventory = packbuf[7];
615 ud.m_coop = packbuf[8];
616 ud.m_marker = ud.marker = packbuf[9];
617 ud.m_ffire = ud.ffire = packbuf[10];
618
619 for(i=connecthead;i>=0;i=connectpoint2[i])
620 {
621 resetweapons(i);
622 resetinventory(i);
623 }
624
625 newgame(ud.volume_number,ud.level_number,ud.player_skill);
626 ud.coop = ud.m_coop;
627
628 enterlevel(MODE_GAME);
629
630 break;
631
632 case 6: // get names
633 for (i=2;packbuf[i] && i<=11;i++) // limit size of name
634 ud.user_name[other][i-2] = packbuf[i];
635 ud.user_name[other][i-2] = 0;
636
637 // we allow the old rancidmeat 19.1 to connect, using the old grpVersion system w/ BYTEVERSION
638 if(packbuf[1] == BYTEVERSION_27 || packbuf[1] == BYTEVERSION_117)
639 {
640 // Old rancid was using either BYTEVERSION_27 or BYTEVERSION_117
641 Error(EXIT_SUCCESS, "STOP: Your opponent is using an obsolete version\n"
642 "Please ask him to update to xDuke v%d.%d!\n", CHOCOLATE_DUKE_REV_X, CHOCOLATE_DUKE_REV_DOT_Y);
643 }
644 break;
645
646 case 9:
647 for (i=1;i<packbufleng;i++)
648 ud.wchoice[other][i-1] = packbuf[i];
649 break;
650
651 case 7:
652
653 if(numlumps == 0) break;
654
655 if (SoundToggle == 0 || ud.lockout == 1 || FXDevice == NumSoundCards)
656 break;
657 rtsptr = RTS_GetSound(packbuf[1]-1);
658 if (*rtsptr == 'C')
659 FX_PlayVOC3D(rtsptr,0,0,0,255,-packbuf[1]);
660 else
661 FX_PlayWAV3D(rtsptr,0,0,0,255,-packbuf[1]);
662 rtsplaying = 7;
663 break;
664 case 8:
665 ud.m_level_number = ud.level_number = packbuf[1];
666 ud.m_volume_number = ud.volume_number = packbuf[2];
667 ud.m_player_skill = ud.player_skill = packbuf[3];
668 ud.m_monsters_off = ud.monsters_off = packbuf[4];
669 ud.m_respawn_monsters = ud.respawn_monsters = packbuf[5];
670 ud.m_respawn_items = ud.respawn_items = packbuf[6];
671 ud.m_respawn_inventory = ud.respawn_inventory = packbuf[7];
672 ud.m_coop = ud.coop = packbuf[8];
673 ud.m_marker = ud.marker = packbuf[9];
674 ud.m_ffire = ud.ffire = packbuf[10];
675
676 copybufbyte(packbuf+10,boardfilename,packbufleng-11);
677 boardfilename[packbufleng-11] = 0;
678
679 for(i=connecthead;i>=0;i=connectpoint2[i])
680 {
681 resetweapons(i);
682 resetinventory(i);
683 }
684
685 newgame(ud.volume_number,ud.level_number,ud.player_skill);
686 enterlevel(MODE_GAME);
687 break;
688
689 case 16:
690 movefifoend[other] = movefifoplc = movefifosendplc = fakemovefifoplc = 0;
691 syncvalhead[other] = syncvaltottail = 0L;
692
693 case 17:
694 j = 1;
695
696 if ((movefifoend[other]&(TIMERUPDATESIZ-1)) == 0)
697 if (other == connecthead)
698 for(i=connectpoint2[connecthead]; i>=0; i=connectpoint2[i])
699 {
700 if (i == myconnectindex)
701 {
702 otherminlag = (int32_t)((int8_t )packbuf[j]);
703 }
704
705 j++;
706 }
707
708 osyn = (input *)&inputfifo[(movefifoend[other]-1)&(MOVEFIFOSIZ-1)][0];
709 nsyn = (input *)&inputfifo[(movefifoend[other])&(MOVEFIFOSIZ-1)][0];
710
711 copybufbyte(&osyn[other],&nsyn[other],sizeof(input));
712 k = packbuf[j++];
713 if (k&1) nsyn[other].fvel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2;
714 if (k&2) nsyn[other].svel = packbuf[j]+((short)packbuf[j+1]<<8), j += 2;
715 if (k&4) nsyn[other].avel = (int8_t )packbuf[j++];
716 if (k&8) nsyn[other].bits = ((nsyn[other].bits&0xffffff00)|((int32_t)packbuf[j++]));
717 if (k&16) nsyn[other].bits = ((nsyn[other].bits&0xffff00ff)|((int32_t)packbuf[j++])<<8);
718 if (k&32) nsyn[other].bits = ((nsyn[other].bits&0xff00ffff)|((int32_t)packbuf[j++])<<16);
719 if (k&64) nsyn[other].bits = ((nsyn[other].bits&0x00ffffff)|((int32_t)packbuf[j++])<<24);
720 if (k&128) nsyn[other].horz = (int8_t )packbuf[j++];
721 movefifoend[other]++;
722
723 for(i=1;i<movesperpacket;i++)
724 {
725 copybufbyte(&nsyn[other],&inputfifo[movefifoend[other]&(MOVEFIFOSIZ-1)][other],sizeof(input));
726 movefifoend[other]++;
727 }
728
729 if (j > packbufleng)
730 {
731 printf("INVALID GAME PACKET!!! (%d too many bytes) (j= %d, packbuflen= %d, type: %d)\n",j-packbufleng, j, packbufleng, packbuf[0]);
732 }
733
734 while (j != packbufleng)
735 {
736 syncval[other][syncvalhead[other]&(MOVEFIFOSIZ-1)] = packbuf[j++];
737 syncvalhead[other]++;
738 }
739
740 break;
741 case 127:
742 break;
743
744#ifdef CHECK_XDUKE_REV
745 case 131: // xDuke Rev ID
746 memcpy(ud.rev[other], packbuf, 10);
747 break;
748#endif
749
750 case 132: // get map CRC of opponents (to debug out of synch)
751 ud.mapCRC[other] = (uint16_t)packbuf[1] + (uint16_t)(packbuf[2]<<8);
752 break;
753
754 case 133: // client refused to disable the autoaim by host
755
756 Error(EXIT_SUCCESS, "One or more players refused to play with AutoAim OFF because this breaks\n"
757 "the official Duke's gameplay. Please restart without this option...\n");
758
759 break;
760
761 case 134: // Get GRP CRC32 + Con size + exeCRC + conCRC
762 memcpy(ud.groupefil_crc32[other], packbuf+1, sizeof(groupefil_crc32));
763 memcpy(ud.conSize+other, packbuf+1+sizeof(groupefil_crc32), sizeof(ud.conSize[0]));
764 memcpy(ud.conCRC+other, packbuf+1+sizeof(groupefil_crc32)+sizeof(ud.conSize[0]), sizeof(ud.conCRC[0]));
765 memcpy(ud.exeCRC+other, packbuf+1+sizeof(groupefil_crc32)+sizeof(ud.conSize[0])+sizeof(ud.conCRC[0]), sizeof(ud.exeCRC[0]));
766 break;
767
768 case 250:
769 {
770 playerreadyflag[other]++;
771 printf("Player %d '%s' is ready...\n", other, ud.user_name[other]);
772 }
773 break;
774 case 255:
775 gameexitanycase();
776 break;
777 }
778 }
779 rb->yield();
780}
781
782//From player.c
783void computergetinput(int32_t snum, input *syn);
784void faketimerhandler()
785{
786 int32_t i, j, k;
787 input *osyn, *nsyn;
788
789 //Check if we should quit the game.
790 if ((qe == 0 && KB_KeyPressed(sc_LeftControl) && KB_KeyPressed(sc_LeftAlt) && KB_KeyPressed(sc_Delete)) ||
791 (qe == 0 && KB_KeyPressed(sc_LeftAlt) && KB_KeyPressed(sc_F4)))
792 {
793 qe = 1;
794 gameexit("Quick Exit.");
795 }
796
797 //Has it been 120ticks ?
798 if ((totalclock < ototalclock+TICSPERFRAME) || (ready2send == 0))
799 return; // Returns here when playing a demo.
800
801 //YES : Add 120tick
802 ototalclock += TICSPERFRAME;
803
804 //Check network stuff.
805 getpackets();
806 if (getoutputcirclesize() >= 16)
807 return;
808
809
810 for(i=connecthead;i>=0;i=connectpoint2[i])
811 if (i != myconnectindex)
812 if (movefifoend[i] < movefifoend[myconnectindex]-200)
813 return;
814
815 if( !CONSOLE_IsActive())
816 {
817 getinput(myconnectindex);
818 }
819
820 avgfvel += loc.fvel; // x
821 avgsvel += loc.svel; // y
822 avgavel += loc.avel;
823 avghorz += loc.horz;
824 avgbits |= loc.bits;
825 if (movefifoend[myconnectindex]&(movesperpacket-1))
826 {
827 copybufbyte(&inputfifo[(movefifoend[myconnectindex]-1)&(MOVEFIFOSIZ-1)][myconnectindex],
828 &inputfifo[movefifoend[myconnectindex]&(MOVEFIFOSIZ-1)][myconnectindex],sizeof(input));
829 movefifoend[myconnectindex]++;
830 return;
831 }
832
833 nsyn = &inputfifo[movefifoend[myconnectindex]&(MOVEFIFOSIZ-1)][myconnectindex];
834 nsyn[0].fvel = avgfvel/movesperpacket;
835 nsyn[0].svel = avgsvel/movesperpacket;
836 nsyn[0].avel = avgavel/movesperpacket;
837 nsyn[0].horz = avghorz/movesperpacket;
838 nsyn[0].bits = avgbits;
839 avgfvel = avgsvel = avgavel = avghorz = avgbits = 0;
840 movefifoend[myconnectindex]++;
841
842 if (numplayers < 2)
843 {
844 if (ud.multimode > 1) for(i=connecthead;i>=0;i=connectpoint2[i])
845 if(i != myconnectindex)
846 {
847 //clearbufbyte(&inputfifo[movefifoend[i]&(MOVEFIFOSIZ-1)][i],sizeof(input),0L);
848 if(ud.playerai)
849 computergetinput(i,&inputfifo[movefifoend[i]&(MOVEFIFOSIZ-1)][i]);
850 movefifoend[i]++;
851 }
852 return;
853 }
854
855 for(i=connecthead;i>=0;i=connectpoint2[i])
856 if (i != myconnectindex)
857 {
858 k = (movefifoend[myconnectindex]-1)-movefifoend[i];
859 myminlag[i] = min(myminlag[i],k);
860 mymaxlag = max(mymaxlag,k);
861 }
862
863 if (((movefifoend[myconnectindex]-1)&(TIMERUPDATESIZ-1)) == 0)
864 {
865 i = mymaxlag-bufferjitter; mymaxlag = 0;
866 if (i > 0) bufferjitter += ((3+i)>>2);
867 else if (i < 0) bufferjitter -= ((1-i)>>2);
868 }
869
870 if (networkmode == 1)
871 {
872 packbuf[0] = 17;
873
874 if ((movefifoend[myconnectindex]-1) == 0)
875 {
876 packbuf[0] = 16;
877 }
878
879 j = 1;
880
881 //Fix timers and buffer/jitter value
882 if (((movefifoend[myconnectindex]-1)&(TIMERUPDATESIZ-1)) == 0)
883 {
884 if (myconnectindex != connecthead)
885 {
886 i = myminlag[connecthead]-otherminlag;
887 if (klabs(i) > 8)
888 {
889 i >>= 1;
890 }
891 else
892 if (klabs(i) > 2)
893 {
894 i = ksgn(i);
895 }
896 else
897 {
898 i = 0;
899 }
900
901 totalclock -= TICSPERFRAME*i;
902 myminlag[connecthead] -= i; otherminlag += i;
903 }
904
905 if (myconnectindex == connecthead)
906 for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i])
907 packbuf[j++] = min(max(myminlag[i],-128),127);
908
909 for(i=connecthead;i>=0;i=connectpoint2[i])
910 myminlag[i] = 0x7fffffff;
911 }
912
913 osyn = (input *)&inputfifo[(movefifoend[myconnectindex]-2)&(MOVEFIFOSIZ-1)][myconnectindex];
914 nsyn = (input *)&inputfifo[(movefifoend[myconnectindex]-1)&(MOVEFIFOSIZ-1)][myconnectindex];
915
916 k = j;
917 packbuf[j++] = 0;
918
919 if (nsyn[0].fvel != osyn[0].fvel)
920 {
921 packbuf[j++] = (uint8_t )nsyn[0].fvel;
922 packbuf[j++] = (uint8_t )(nsyn[0].fvel>>8);
923 packbuf[k] |= 1;
924 }
925 if (nsyn[0].svel != osyn[0].svel)
926 {
927 packbuf[j++] = (uint8_t )nsyn[0].svel;
928 packbuf[j++] = (uint8_t )(nsyn[0].svel>>8);
929 packbuf[k] |= 2;
930 }
931 if (nsyn[0].avel != osyn[0].avel)
932 {
933 packbuf[j++] = (int8_t )nsyn[0].avel;
934 packbuf[k] |= 4;
935 }
936 if ((nsyn[0].bits^osyn[0].bits)&0x000000ff) packbuf[j++] = (nsyn[0].bits&255), packbuf[k] |= 8;
937 if ((nsyn[0].bits^osyn[0].bits)&0x0000ff00) packbuf[j++] = ((nsyn[0].bits>>8)&255), packbuf[k] |= 16;
938 if ((nsyn[0].bits^osyn[0].bits)&0x00ff0000) packbuf[j++] = ((nsyn[0].bits>>16)&255), packbuf[k] |= 32;
939 if ((nsyn[0].bits^osyn[0].bits)&0xff000000) packbuf[j++] = ((nsyn[0].bits>>24)&255), packbuf[k] |= 64;
940 if (nsyn[0].horz != osyn[0].horz)
941 {
942 packbuf[j++] = (uint8_t )nsyn[0].horz;
943 packbuf[k] |= 128;
944 }
945
946 while (syncvalhead[myconnectindex] != syncvaltail)
947 {
948 packbuf[j++] = syncval[myconnectindex][syncvaltail&(MOVEFIFOSIZ-1)];
949 syncvaltail++;
950 }
951
952 for(i=connecthead;i>=0;i=connectpoint2[i])
953 if (i != myconnectindex)
954 sendpacket(i,packbuf,j);
955
956 return;
957 }
958 if (myconnectindex != connecthead) //Slave
959 {
960 //Fix timers and buffer/jitter value
961 if (((movefifoend[myconnectindex]-1)&(TIMERUPDATESIZ-1)) == 0)
962 {
963 i = myminlag[connecthead]-otherminlag;
964 if (klabs(i) > 8) i >>= 1;
965 else if (klabs(i) > 2) i = ksgn(i);
966 else i = 0;
967
968 totalclock -= TICSPERFRAME*i;
969 myminlag[connecthead] -= i; otherminlag += i;
970
971 for(i=connecthead;i>=0;i=connectpoint2[i])
972 myminlag[i] = 0x7fffffff;
973 }
974
975 packbuf[0] = 1; packbuf[1] = 0; j = 2;
976
977 osyn = (input *)&inputfifo[(movefifoend[myconnectindex]-2)&(MOVEFIFOSIZ-1)][myconnectindex];
978 nsyn = (input *)&inputfifo[(movefifoend[myconnectindex]-1)&(MOVEFIFOSIZ-1)][myconnectindex];
979
980 if (nsyn[0].fvel != osyn[0].fvel)
981 {
982 packbuf[j++] = (uint8_t )nsyn[0].fvel;
983 packbuf[j++] = (uint8_t )(nsyn[0].fvel>>8);
984 packbuf[1] |= 1;
985 }
986 if (nsyn[0].svel != osyn[0].svel)
987 {
988 packbuf[j++] = (uint8_t )nsyn[0].svel;
989 packbuf[j++] = (uint8_t )(nsyn[0].svel>>8);
990 packbuf[1] |= 2;
991 }
992 if (nsyn[0].avel != osyn[0].avel)
993 {
994 packbuf[j++] = (int8_t )nsyn[0].avel;
995 packbuf[1] |= 4;
996 }
997 if ((nsyn[0].bits^osyn[0].bits)&0x000000ff) packbuf[j++] = (nsyn[0].bits&255), packbuf[1] |= 8;
998 if ((nsyn[0].bits^osyn[0].bits)&0x0000ff00) packbuf[j++] = ((nsyn[0].bits>>8)&255), packbuf[1] |= 16;
999 if ((nsyn[0].bits^osyn[0].bits)&0x00ff0000) packbuf[j++] = ((nsyn[0].bits>>16)&255), packbuf[1] |= 32;
1000 if ((nsyn[0].bits^osyn[0].bits)&0xff000000) packbuf[j++] = ((nsyn[0].bits>>24)&255), packbuf[1] |= 64;
1001 if (nsyn[0].horz != osyn[0].horz)
1002 {
1003 packbuf[j++] = (uint8_t )nsyn[0].horz;
1004 packbuf[1] |= 128;
1005 }
1006
1007 while (syncvalhead[myconnectindex] != syncvaltail)
1008 {
1009 packbuf[j++] = syncval[myconnectindex][syncvaltail&(MOVEFIFOSIZ-1)];
1010 syncvaltail++;
1011 }
1012
1013 sendpacket(connecthead,packbuf,j);
1014 return;
1015 }
1016
1017 //This allows allow packet-resends
1018 for(i=connecthead;i>=0;i=connectpoint2[i])
1019 if (movefifoend[i] <= movefifosendplc)
1020 {
1021 packbuf[0] = 127;
1022 for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i])
1023 sendpacket(i,packbuf,1);
1024 return;
1025 }
1026
1027 while (1) //Master
1028 {
1029 for(i=connecthead;i>=0;i=connectpoint2[i])
1030 if (playerquitflag[i] && (movefifoend[i] <= movefifosendplc)) return;
1031
1032 osyn = (input *)&inputfifo[(movefifosendplc-1)&(MOVEFIFOSIZ-1)][0];
1033 nsyn = (input *)&inputfifo[(movefifosendplc )&(MOVEFIFOSIZ-1)][0];
1034
1035 //MASTER -> SLAVE packet
1036 packbuf[0] = 0; j = 1;
1037
1038 //Fix timers and buffer/jitter value
1039 if ((movefifosendplc&(TIMERUPDATESIZ-1)) == 0)
1040 {
1041 for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i])
1042 if (playerquitflag[i])
1043 packbuf[j++] = min(max(myminlag[i],-128),127);
1044
1045 for(i=connecthead;i>=0;i=connectpoint2[i])
1046 myminlag[i] = 0x7fffffff;
1047 }
1048
1049 k = j;
1050 for(i=connecthead;i>=0;i=connectpoint2[i])
1051 j += playerquitflag[i];
1052 for(i=connecthead;i>=0;i=connectpoint2[i])
1053 {
1054 if (playerquitflag[i] == 0) continue;
1055
1056 packbuf[k] = 0;
1057 if (nsyn[i].fvel != osyn[i].fvel)
1058 {
1059 packbuf[j++] = (uint8_t )nsyn[i].fvel;
1060 packbuf[j++] = (uint8_t )(nsyn[i].fvel>>8);
1061 packbuf[k] |= 1;
1062 }
1063 if (nsyn[i].svel != osyn[i].svel)
1064 {
1065 packbuf[j++] = (uint8_t )nsyn[i].svel;
1066 packbuf[j++] = (uint8_t )(nsyn[i].svel>>8);
1067 packbuf[k] |= 2;
1068 }
1069 if (nsyn[i].avel != osyn[i].avel)
1070 {
1071 packbuf[j++] = (int8_t )nsyn[i].avel;
1072 packbuf[k] |= 4;
1073 }
1074 if ((nsyn[i].bits^osyn[i].bits)&0x000000ff) packbuf[j++] = (nsyn[i].bits&255), packbuf[k] |= 8;
1075 if ((nsyn[i].bits^osyn[i].bits)&0x0000ff00) packbuf[j++] = ((nsyn[i].bits>>8)&255), packbuf[k] |= 16;
1076 if ((nsyn[i].bits^osyn[i].bits)&0x00ff0000) packbuf[j++] = ((nsyn[i].bits>>16)&255), packbuf[k] |= 32;
1077 if ((nsyn[i].bits^osyn[i].bits)&0xff000000) packbuf[j++] = ((nsyn[i].bits>>24)&255), packbuf[k] |= 64;
1078 if (nsyn[i].horz != osyn[i].horz)
1079 {
1080 packbuf[j++] = (uint8_t )nsyn[i].horz;
1081 packbuf[k] |= 128;
1082 }
1083 k++;
1084 }
1085
1086 while (syncvalhead[myconnectindex] != syncvaltail)
1087 {
1088 packbuf[j++] = syncval[myconnectindex][syncvaltail&(MOVEFIFOSIZ-1)];
1089 syncvaltail++;
1090 }
1091
1092 for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i])
1093 if (playerquitflag[i])
1094 {
1095 sendpacket(i,packbuf,j);
1096 if (nsyn[i].bits&(1<<26))
1097 playerquitflag[i] = 0;
1098 }
1099
1100 movefifosendplc += movesperpacket;
1101 }
1102}
1103
1104extern int32_t cacnum;
1105
1106typedef struct {
1107 uint8_t *hand;
1108 int32_t leng;
1109 uint8_t *lock; }
1110 cactype;
1111extern cactype cac[];
1112
1113void caches(void)
1114{
1115 short i,k;
1116 char text[512];
1117
1118 k = 0;
1119 for(i=0;i<cacnum;i++)
1120 if ((*cac[i].lock) >= 200)
1121 {
1122 sprintf(text,"Locked- %d: Leng:%d, Lock:%d",i,cac[i].leng,*cac[i].lock);
1123 printext256(0L,k,31,-1,text,1); k += 6;
1124 }
1125
1126 k += 6;
1127
1128 for(i=1;i<11;i++)
1129 if (lumplockbyte[i] >= 200)
1130 {
1131 sprintf(text,"RTS Locked %hd:",i);
1132 printext256(0L,k,31,-1,text,1); k += 6;
1133 }
1134
1135
1136}
1137
1138// FIX_00024: A key can be assigned to the new SHOW_INFO function. Display map CRC when
1139// in deathmatch. Usefull to identify who loaded a wrong map in multiplayer.
1140void dispVersion(void)
1141{
1142 int i;
1143 int offx, offy, stepx, stepy;
1144 char text[512];
1145
1146 offx = 21; offy = 30;
1147 stepx = 73; stepy = 20;
1148
1149 // black translucent background underneath lists
1150 rotatesprite(0<<16, 0<<16, 65536l<<5, 0, BLANK, 8, 0, 1+2+8+16+64,
1151 scale(0,xdim,320),scale(26,ydim,200),
1152 scale(320-0,xdim,320)-1,scale(200-((ud.multimode>4)?(161-1*7)-stepy:(161-1*7)),ydim,200)-1);
1153
1154 // FIX_00009: Show map CRC and GRP file version of each player in case of Out Of Synch
1155 for(i=connecthead;i>=0;i=connectpoint2[i])
1156 {
1157 // Disp name
1158 sprintf(text,"%s", ud.user_name[i]);
1159 minitext(offx+(stepx*(i&3)),offy+0+((i&4)>>2)*stepy, text, sprite[ps[i].i].pal, 2+8+16);
1160
1161 // Disp MAP CRC
1162 if(ps[i].fakeplayer)
1163 sprintf(text,"MAP CRC: (bot)");
1164 else
1165 sprintf(text,"MAP CRC: %X", ud.mapCRC[i]);
1166 minitext(offx+(stepx*(i&3)),offy+7+((i&4)>>2)*stepy, text, COLOR_ON,2+8+16);
1167
1168 }
1169}
1170
1171void checksync(void)
1172{
1173 int32_t i;
1174
1175 for(i=connecthead;i>=0;i=connectpoint2[i])
1176 if (syncvalhead[i] == syncvaltottail) break;
1177 if (i < 0)
1178 {
1179 syncstat = 0;
1180 do
1181 {
1182 for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i])
1183 {
1184 if (syncval[i][syncvaltottail&(MOVEFIFOSIZ-1)] != syncval[connecthead][syncvaltottail&(MOVEFIFOSIZ-1)])
1185 {
1186 syncstat = 1;
1187 }
1188 }
1189
1190 syncvaltottail++;
1191 for(i=connecthead;i>=0;i=connectpoint2[i])
1192 {
1193 if (syncvalhead[i] == syncvaltottail)
1194 {
1195 break;
1196 }
1197 }
1198 } while (i < 0);
1199 }
1200
1201 if (connectpoint2[connecthead] < 0)
1202 {
1203 syncstat = 0;
1204 }
1205
1206 if (syncstat)
1207 {
1208 minitext(21,30+35+30, "Out Of Sync - Please restart game", COLOR_ON,2+8+16);
1209 // FIX_00090: Removed info key. FPS were shown after CRC msg. CRC not always removed. (Turrican)
1210 for(i=connecthead;i>=0;i=connectpoint2[i])
1211 {
1212 if (ud.mapCRC[connecthead]!=ud.mapCRC[i])
1213 {
1214 minitext(21,30+42+30, "Map CRC mismatching. Please use exactly the same map.", COLOR_ON,2+8+16);
1215 dispVersion();
1216 }
1217 else
1218 minitext(21,30+42+30, "Verify the con files. Close your P2P if any", COLOR_ON,2+8+16);
1219
1220 }
1221 }
1222
1223 if (syncstate)
1224 {
1225 //printext256(4L,160L,31,0,"Missed Network packet!",0);
1226 //printext256(4L,138L,31,0,"RUN DN3DHELP.EXE for information.",0);
1227 minitext(21,30+35+30, "Missed Network packet!", COLOR_ON,2+8+16);
1228 }
1229
1230}
1231
1232
1233void check_fta_sounds(short i)
1234{
1235 if(sprite[i].extra > 0) switch(PN)
1236 {
1237 case LIZTROOPONTOILET:
1238 case LIZTROOPJUSTSIT:
1239 case LIZTROOPSHOOT:
1240 case LIZTROOPJETPACK:
1241 case LIZTROOPDUCKING:
1242 case LIZTROOPRUNNING:
1243 case LIZTROOP:
1244 spritesound(PRED_RECOG,i);
1245 break;
1246 case LIZMAN:
1247 case LIZMANSPITTING:
1248 case LIZMANFEEDING:
1249 case LIZMANJUMP:
1250 spritesound(CAPT_RECOG,i);
1251 break;
1252 case PIGCOP:
1253 case PIGCOPDIVE:
1254 spritesound(PIG_RECOG,i);
1255 break;
1256 case RECON:
1257 spritesound(RECO_RECOG,i);
1258 break;
1259 case DRONE:
1260 spritesound(DRON_RECOG,i);
1261 break;
1262 case COMMANDER:
1263 case COMMANDERSTAYPUT:
1264 spritesound(COMM_RECOG,i);
1265 break;
1266 case ORGANTIC:
1267 spritesound(TURR_RECOG,i);
1268 break;
1269 case OCTABRAIN:
1270 case OCTABRAINSTAYPUT:
1271 spritesound(OCTA_RECOG,i);
1272 break;
1273 case BOSS1:
1274 sound(BOS1_RECOG);
1275 break;
1276 case BOSS2:
1277 if(sprite[i].pal == 1)
1278 sound(BOS2_RECOG);
1279 else sound(WHIPYOURASS);
1280 break;
1281 case BOSS3:
1282 if(sprite[i].pal == 1)
1283 sound(BOS3_RECOG);
1284 else sound(RIPHEADNECK);
1285 break;
1286 case BOSS4:
1287 case BOSS4STAYPUT:
1288 if(sprite[i].pal == 1)
1289 sound(BOS4_RECOG);
1290 sound(BOSS4_FIRSTSEE);
1291 break;
1292 case GREENSLIME:
1293 spritesound(SLIM_RECOG,i);
1294 break;
1295 }
1296}
1297
1298short inventory(spritetype *s)
1299{
1300 switch(s->picnum)
1301 {
1302 case FIRSTAID:
1303 case STEROIDS:
1304 case HEATSENSOR:
1305 case BOOTS:
1306 case JETPACK:
1307 case HOLODUKE:
1308 case AIRTANK:
1309 return 1;
1310 }
1311 return 0;
1312}
1313
1314
1315short badguy(spritetype *s)
1316{
1317
1318 switch(s->picnum)
1319 {
1320 case SHARK:
1321 case RECON:
1322 case DRONE:
1323 case LIZTROOPONTOILET:
1324 case LIZTROOPJUSTSIT:
1325 case LIZTROOPSTAYPUT:
1326 case LIZTROOPSHOOT:
1327 case LIZTROOPJETPACK:
1328 case LIZTROOPDUCKING:
1329 case LIZTROOPRUNNING:
1330 case LIZTROOP:
1331 case OCTABRAIN:
1332 case COMMANDER:
1333 case COMMANDERSTAYPUT:
1334 case PIGCOP:
1335 case EGG:
1336 case PIGCOPSTAYPUT:
1337 case PIGCOPDIVE:
1338 case LIZMAN:
1339 case LIZMANSPITTING:
1340 case LIZMANFEEDING:
1341 case LIZMANJUMP:
1342 case ORGANTIC:
1343 case BOSS1:
1344 case BOSS2:
1345 case BOSS3:
1346 case BOSS4:
1347 case GREENSLIME:
1348 case GREENSLIME+1:
1349 case GREENSLIME+2:
1350 case GREENSLIME+3:
1351 case GREENSLIME+4:
1352 case GREENSLIME+5:
1353 case GREENSLIME+6:
1354 case GREENSLIME+7:
1355 case RAT:
1356 case ROTATEGUN:
1357 return 1;
1358 }
1359 if( actortype[s->picnum] ) return 1;
1360
1361 return 0;
1362}
1363
1364
1365short badguypic(short pn)
1366{
1367
1368 switch(pn)
1369 {
1370 case SHARK:
1371 case RECON:
1372 case DRONE:
1373 case LIZTROOPONTOILET:
1374 case LIZTROOPJUSTSIT:
1375 case LIZTROOPSTAYPUT:
1376 case LIZTROOPSHOOT:
1377 case LIZTROOPJETPACK:
1378 case LIZTROOPDUCKING:
1379 case LIZTROOPRUNNING:
1380 case LIZTROOP:
1381 case OCTABRAIN:
1382 case COMMANDER:
1383 case COMMANDERSTAYPUT:
1384 case PIGCOP:
1385 case EGG:
1386 case PIGCOPSTAYPUT:
1387 case PIGCOPDIVE:
1388 case LIZMAN:
1389 case LIZMANSPITTING:
1390 case LIZMANFEEDING:
1391 case LIZMANJUMP:
1392 case ORGANTIC:
1393 case BOSS1:
1394 case BOSS2:
1395 case BOSS3:
1396 case BOSS4:
1397 case GREENSLIME:
1398 case GREENSLIME+1:
1399 case GREENSLIME+2:
1400 case GREENSLIME+3:
1401 case GREENSLIME+4:
1402 case GREENSLIME+5:
1403 case GREENSLIME+6:
1404 case GREENSLIME+7:
1405 case RAT:
1406 case ROTATEGUN:
1407 return 1;
1408 }
1409
1410 if( actortype[pn] ) return 1;
1411
1412 return 0;
1413}
1414
1415
1416
1417void myos(int32_t x, int32_t y, short tilenum, int8_t shade, uint8_t orientation)
1418{
1419 uint8_t p;
1420 short a;
1421
1422 if(orientation&4)
1423 a = 1024;
1424 else a = 0;
1425
1426 p = sector[ps[screenpeek].cursectnum].floorpal;
1427 rotatesprite(x<<16,y<<16,65536L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2);
1428}
1429
1430void myospal(int32_t x, int32_t y, short tilenum, int8_t shade, uint8_t orientation, uint8_t p)
1431{
1432// uint8_t fp;
1433 short a;
1434
1435 if(orientation&4)
1436 a = 1024;
1437 else a = 0;
1438
1439// fp = sector[ps[screenpeek].cursectnum].floorpal;
1440
1441 rotatesprite(x<<16,y<<16,65536L,a,tilenum,shade,p,2|orientation,windowx1,windowy1,windowx2,windowy2);
1442
1443}
1444
1445void invennum(int32_t x,int32_t y,uint8_t num1,uint8_t ha,uint8_t sbits)
1446{
1447 char dabuf[80] = {0};
1448 sprintf(dabuf,"%d",num1);
1449 if(num1 > 99)
1450 {
1451 rotatesprite((x-4)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[0]-'0',ha,0,sbits,0,0,xdim-1,ydim-1);
1452 rotatesprite((x)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[1]-'0',ha,0,sbits,0,0,xdim-1,ydim-1);
1453 rotatesprite((x+4)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[2]-'0',ha,0,sbits,0,0,xdim-1,ydim-1);
1454 }
1455 else if(num1 > 9)
1456 {
1457 rotatesprite((x)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[0]-'0',ha,0,sbits,0,0,xdim-1,ydim-1);
1458 rotatesprite((x+4)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[1]-'0',ha,0,sbits,0,0,xdim-1,ydim-1);
1459 }
1460 else
1461 rotatesprite((x+4)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[0]-'0',ha,0,sbits,0,0,xdim-1,ydim-1);
1462}
1463
1464void orderweaponnum(short ind,int32_t x,int32_t y,int32_t num1, int32_t num2,uint8_t ha)
1465{
1466 rotatesprite((x-7)<<16,y<<16,65536L,0,THREEBYFIVE+ind+1,ha-10,7,10+128,0,0,xdim-1,ydim-1);
1467 rotatesprite((x-3)<<16,y<<16,65536L,0,THREEBYFIVE+10,ha,0,10+128,0,0,xdim-1,ydim-1);
1468
1469 minitextshade(x+1,y-4,"ORDER",26,6,2+8+16+128);
1470}
1471
1472void weaponnum(short ind,int32_t x,int32_t y,int32_t num1, int32_t num2,uint8_t ha)
1473{
1474 char dabuf[80] = {0};
1475
1476 rotatesprite((x-7)<<16,y<<16,65536L,0,THREEBYFIVE+ind+1,ha-10,7,10+128,0,0,xdim-1,ydim-1);
1477 rotatesprite((x-3)<<16,y<<16,65536L,0,THREEBYFIVE+10,ha,0,10+128,0,0,xdim-1,ydim-1);
1478 rotatesprite((x+9)<<16,y<<16,65536L,0,THREEBYFIVE+11,ha,0,10+128,0,0,xdim-1,ydim-1);
1479
1480 if(num1 > 99) num1 = 99;
1481 if(num2 > 99) num2 = 99;
1482
1483 sprintf(dabuf,"%d",num1);
1484 if(num1 > 9)
1485 {
1486 rotatesprite((x)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1487 rotatesprite((x+4)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1488 }
1489 else rotatesprite((x+4)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1490
1491 sprintf(dabuf,"%d",num2);
1492 if(num2 > 9)
1493 {
1494 rotatesprite((x+13)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1495 rotatesprite((x+17)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1496 }
1497 else rotatesprite((x+13)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1498}
1499
1500void weaponnum999(uint8_t ind,int32_t x,int32_t y,int32_t num1, int32_t num2,uint8_t ha)
1501{
1502 char dabuf[80] = {0};
1503
1504 rotatesprite((x-7)<<16,y<<16,65536L,0,THREEBYFIVE+ind+1,ha-10,7,10+128,0,0,xdim-1,ydim-1);
1505 rotatesprite((x-4)<<16,y<<16,65536L,0,THREEBYFIVE+10,ha,0,10+128,0,0,xdim-1,ydim-1);
1506 rotatesprite((x+13)<<16,y<<16,65536L,0,THREEBYFIVE+11,ha,0,10+128,0,0,xdim-1,ydim-1);
1507
1508 sprintf(dabuf,"%d",num1);
1509 if(num1 > 99)
1510 {
1511 rotatesprite((x)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1512 rotatesprite((x+4)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1513 rotatesprite((x+8)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[2]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1514 }
1515 else if(num1 > 9)
1516 {
1517 rotatesprite((x+4)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1518 rotatesprite((x+8)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1519 }
1520 else rotatesprite((x+8)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1521
1522 sprintf(dabuf,"%d",num2);
1523 if(num2 > 99)
1524 {
1525 rotatesprite((x+17)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1526 rotatesprite((x+21)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1527 rotatesprite((x+25)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[2]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1528 }
1529 else if(num2 > 9)
1530 {
1531 rotatesprite((x+17)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1532 rotatesprite((x+21)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[1]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1533 }
1534 else rotatesprite((x+25)<<16,y<<16,65536L,0,THREEBYFIVE+dabuf[0]-'0',ha,0,10+128,0,0,xdim-1,ydim-1);
1535}
1536
1537
1538//REPLACE FULLY
1539void weapon_amounts(struct player_struct *p,int32_t x,int32_t y,int32_t u)
1540{
1541 int cw;
1542
1543 cw = p->curr_weapon;
1544
1545 if (u&4)
1546 {
1547 if (u != 0xffffffff) patchstatusbar(96,178,96+12,178+6);
1548 weaponnum999(PISTOL_WEAPON,x,y,
1549 p->ammo_amount[PISTOL_WEAPON],max_ammo_amount[PISTOL_WEAPON],
1550 12-20*(cw == PISTOL_WEAPON) );
1551 }
1552 if (u&8)
1553 {
1554 if (u != 0xffffffff) patchstatusbar(96,184,96+12,184+6);
1555 weaponnum999(SHOTGUN_WEAPON,x,y+6,
1556 p->ammo_amount[SHOTGUN_WEAPON],max_ammo_amount[SHOTGUN_WEAPON],
1557 (!p->gotweapon[SHOTGUN_WEAPON]*9)+12-18*
1558 (cw == SHOTGUN_WEAPON) );
1559 }
1560 if (u&16)
1561 {
1562 if (u != 0xffffffff) patchstatusbar(96,190,96+12,190+6);
1563 weaponnum999(CHAINGUN_WEAPON,x,y+12,
1564 p->ammo_amount[CHAINGUN_WEAPON],max_ammo_amount[CHAINGUN_WEAPON],
1565 (!p->gotweapon[CHAINGUN_WEAPON]*9)+12-18*
1566 (cw == CHAINGUN_WEAPON) );
1567 }
1568 if (u&32)
1569 {
1570 if (u != 0xffffffff) patchstatusbar(135,178,135+8,178+6);
1571 weaponnum(RPG_WEAPON,x+39,y,
1572 p->ammo_amount[RPG_WEAPON],max_ammo_amount[RPG_WEAPON],
1573 (!p->gotweapon[RPG_WEAPON]*9)+12-19*
1574 (cw == RPG_WEAPON) );
1575 }
1576 if (u&64)
1577 {
1578 if (u != 0xffffffff) patchstatusbar(135,184,135+8,184+6);
1579 weaponnum(HANDBOMB_WEAPON,x+39,y+6,
1580 p->ammo_amount[HANDBOMB_WEAPON],max_ammo_amount[HANDBOMB_WEAPON],
1581 (((!p->ammo_amount[HANDBOMB_WEAPON])|(!p->gotweapon[HANDBOMB_WEAPON]))*9)+12-19*
1582 ((cw == HANDBOMB_WEAPON) || (cw == HANDREMOTE_WEAPON)));
1583 }
1584 if (u&128)
1585 {
1586 if (u != 0xffffffff) patchstatusbar(135,190,135+8,190+6);
1587
1588 if(VOLUMEONE)
1589 {
1590 orderweaponnum(SHRINKER_WEAPON,x+39,y+12,
1591 p->ammo_amount[SHRINKER_WEAPON],max_ammo_amount[SHRINKER_WEAPON],
1592 (!p->gotweapon[SHRINKER_WEAPON]*9)+12-18*
1593 (cw == SHRINKER_WEAPON) );
1594 }
1595 else
1596 {
1597 if(p->subweapon&(1<<GROW_WEAPON))
1598 weaponnum(SHRINKER_WEAPON,x+39,y+12,
1599 p->ammo_amount[GROW_WEAPON],max_ammo_amount[GROW_WEAPON],
1600 (!p->gotweapon[GROW_WEAPON]*9)+12-18*
1601 (cw == GROW_WEAPON) );
1602 else
1603 weaponnum(SHRINKER_WEAPON,x+39,y+12,
1604 p->ammo_amount[SHRINKER_WEAPON],max_ammo_amount[SHRINKER_WEAPON],
1605 (!p->gotweapon[SHRINKER_WEAPON]*9)+12-18*
1606 (cw == SHRINKER_WEAPON) );
1607 }
1608 }
1609 if (u&256)
1610 {
1611 if (u != 0xffffffff) patchstatusbar(166,178,166+8,178+6);
1612
1613 if(VOLUMEONE)
1614 {
1615 orderweaponnum(DEVISTATOR_WEAPON,x+70,y,
1616 p->ammo_amount[DEVISTATOR_WEAPON],max_ammo_amount[DEVISTATOR_WEAPON],
1617 (!p->gotweapon[DEVISTATOR_WEAPON]*9)+12-18*
1618 (cw == DEVISTATOR_WEAPON) );
1619 }
1620 else
1621 {
1622 weaponnum(DEVISTATOR_WEAPON,x+70,y,
1623 p->ammo_amount[DEVISTATOR_WEAPON],max_ammo_amount[DEVISTATOR_WEAPON],
1624 (!p->gotweapon[DEVISTATOR_WEAPON]*9)+12-18*
1625 (cw == DEVISTATOR_WEAPON) );
1626 }
1627 }
1628 if (u&512)
1629 {
1630 if (u != 0xffffffff) patchstatusbar(166,184,166+8,184+6);
1631 if(VOLUMEONE)
1632 {
1633 orderweaponnum(TRIPBOMB_WEAPON,x+70,y+6,
1634 p->ammo_amount[TRIPBOMB_WEAPON],max_ammo_amount[TRIPBOMB_WEAPON],
1635 (!p->gotweapon[TRIPBOMB_WEAPON]*9)+12-18*
1636 (cw == TRIPBOMB_WEAPON) );
1637 }
1638 else
1639 {
1640 weaponnum(TRIPBOMB_WEAPON,x+70,y+6,
1641 p->ammo_amount[TRIPBOMB_WEAPON],max_ammo_amount[TRIPBOMB_WEAPON],
1642 (!p->gotweapon[TRIPBOMB_WEAPON]*9)+12-18*
1643 (cw == TRIPBOMB_WEAPON) );
1644 }
1645 }
1646
1647 if (u&65536L)
1648 {
1649 if (u != 0xffffffff) patchstatusbar(166,190,166+8,190+6);
1650 if(VOLUMEONE)
1651 {
1652 orderweaponnum(-1,x+70,y+12,
1653 p->ammo_amount[FREEZE_WEAPON],max_ammo_amount[FREEZE_WEAPON],
1654 (!p->gotweapon[FREEZE_WEAPON]*9)+12-18*
1655 (cw == FREEZE_WEAPON) );
1656 }
1657 else
1658 {
1659 weaponnum(-1,x+70,y+12,
1660 p->ammo_amount[FREEZE_WEAPON],max_ammo_amount[FREEZE_WEAPON],
1661 (!p->gotweapon[FREEZE_WEAPON]*9)+12-18*
1662 (cw == FREEZE_WEAPON) );
1663 }
1664 }
1665}
1666
1667void digitalnumber(int32_t x,int32_t y,int32_t n,uint8_t s,uint8_t cs)
1668{
1669 short i, j, k, p, c;
1670 char b[10];
1671
1672 //
1673 // uint8_t * ltoa(int32_t l, uint8_t * buffer, int radix);
1674 // is NON-STANDARD and equivalent to STANDARD
1675 // (void) sprintf(buffer, "%ld", l);
1676 //ltoa(n,b,10);
1677 sprintf(b,"%d",n);
1678
1679 i = strlen(b);
1680 j = 0;
1681
1682 for(k=0;k<i;k++)
1683 {
1684 p = DIGITALNUM+*(b+k)-'0';
1685 j += tiles[p].dim.width+1;
1686 }
1687 c = x-(j>>1);
1688
1689 j = 0;
1690 for(k=0;k<i;k++)
1691 {
1692 p = DIGITALNUM+*(b+k)-'0';
1693 rotatesprite((c+j)<<16,y<<16,65536L,0,p,s,0,cs,0,0,xdim-1,ydim-1);
1694 j += tiles[p].dim.width+1;
1695 }
1696}
1697
1698/*
1699
1700 void scratchmarks(int32_t x,int32_t y,int32_t n,uint8_t s,uint8_t p)
1701 {
1702 int32_t i, ni;
1703
1704 ni = n/5;
1705 for(i=ni;i >= 0;i--)
1706 {
1707 overwritesprite(x-2,y,SCRATCH+4,s,0,0);
1708 x += tilesizx[SCRATCH+4]-1;
1709 }
1710
1711 ni = n%5;
1712 if(ni) overwritesprite(x,y,SCRATCH+ni-1,s,p,0);
1713 }
1714*/
1715void displayinventory(struct player_struct *p)
1716{
1717 short n, j, xoff, y;
1718
1719 j = xoff = 0;
1720
1721 n = (p->jetpack_amount > 0)<<3; if(n&8) j++;
1722 n |= ( p->scuba_amount > 0 )<<5; if(n&32) j++;
1723 n |= (p->steroids_amount > 0)<<1; if(n&2) j++;
1724 n |= ( p->holoduke_amount > 0)<<2; if(n&4) j++;
1725 n |= (p->firstaid_amount > 0); if(n&1) j++;
1726 n |= (p->heat_amount > 0)<<4; if(n&16) j++;
1727 n |= (p->boot_amount > 0)<<6; if(n&64) j++;
1728
1729 xoff = 160-(j*11);
1730
1731 j = 0;
1732
1733 if(ud.screen_size > 4)
1734 y = 154;
1735 else y = 172;
1736
1737 if(ud.screen_size == 4)
1738 {
1739 if(ud.multimode > 1)
1740 xoff += 56;
1741 else xoff += 65;
1742 }
1743
1744 while( j <= 9 )
1745 {
1746 if( n&(1<<j) )
1747 {
1748 switch( n&(1<<j) )
1749 {
1750 case 1:
1751 rotatesprite(xoff<<16,y<<16,65536L,0,FIRSTAID_ICON,0,0,2+16,windowx1,windowy1,windowx2,windowy2);break;
1752 case 2:
1753 rotatesprite((xoff+1)<<16,y<<16,65536L,0,STEROIDS_ICON,0,0,2+16,windowx1,windowy1,windowx2,windowy2);break;
1754 case 4:
1755 rotatesprite((xoff+2)<<16,y<<16,65536L,0,HOLODUKE_ICON,0,0,2+16,windowx1,windowy1,windowx2,windowy2);break;
1756 case 8:
1757 rotatesprite(xoff<<16,y<<16,65536L,0,JETPACK_ICON,0,0,2+16,windowx1,windowy1,windowx2,windowy2);break;
1758 case 16:
1759 rotatesprite(xoff<<16,y<<16,65536L,0,HEAT_ICON,0,0,2+16,windowx1,windowy1,windowx2,windowy2);break;
1760 case 32:
1761 rotatesprite(xoff<<16,y<<16,65536L,0,AIRTANK_ICON,0,0,2+16,windowx1,windowy1,windowx2,windowy2);break;
1762 case 64:
1763 rotatesprite(xoff<<16,(y-1)<<16,65536L,0,BOOT_ICON,0,0,2+16,windowx1,windowy1,windowx2,windowy2);break;
1764 }
1765
1766 xoff += 22;
1767
1768 if(p->inven_icon == j+1)
1769 rotatesprite((xoff-2)<<16,(y+19)<<16,65536L,1024,ARROW,-32,0,2+16,windowx1,windowy1,windowx2,windowy2);
1770 }
1771
1772 j++;
1773 }
1774}
1775
1776
1777
1778void displayfragbar(void)
1779{
1780 short i, j;
1781 char text[512];
1782
1783 j = 0;
1784
1785 for(i=connecthead;i>=0;i=connectpoint2[i])
1786 if(i > j) j = i;
1787
1788 rotatesprite(0,0,65600L,0,FRAGBAR,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1);
1789 if(j >= 4) rotatesprite(319,(8)<<16,65600L,0,FRAGBAR,0,0,10+16+64+128,0,0,xdim-1,ydim-1);
1790 if(j >= 8) rotatesprite(319,(16)<<16,65600L,0,FRAGBAR,0,0,10+16+64+128,0,0,xdim-1,ydim-1);
1791 if(j >= 12) rotatesprite(319,(24)<<16,65600L,0,FRAGBAR,0,0,10+16+64+128,0,0,xdim-1,ydim-1);
1792
1793 for(i=connecthead;i>=0;i=connectpoint2[i])
1794 {
1795 minitext(21+(73*(i&3)),2+((i&28)<<1),&ud.user_name[i][0],sprite[ps[i].i].pal,2+8+16+128);
1796 sprintf(text,"%d",ps[i].frag-ps[i].fraggedself);
1797 minitext(17+50+(73*(i&3)),2+((i&28)<<1),text,sprite[ps[i].i].pal,2+8+16+128);
1798 }
1799}
1800
1801void display_boardfilename_FPS_weapon(short *offx, short *offy, short *stepx, short *stepy)
1802{
1803
1804 short i;
1805
1806 // FIX_00025: Can toggle FPS and map name during a game (use dnrate OR toggle
1807 // from menu when in deathmatch).
1808
1809 // Display boardfilename and FPS
1810 if(ud.tickrate&1)
1811 {
1812 duke_tics(*offx, *offy, COLOR_ON);
1813 *offy += *stepy;
1814 }
1815 if(ud.tickrate&2)
1816 dispVersion();
1817
1818 // We display the weapons here instead of changing the function
1819 // displayweapon() because the display will be much faster
1820 for(i=connecthead;i>=0;i=connectpoint2[i])
1821 {
1822 if (ud.hideweapon && i==screenpeek)
1823 drawsmallweapon(ps[i].curr_weapon, 1, 130, (ud.screen_size<=4)?170:140);
1824 }
1825}
1826
1827
1828// FIX_00026: Weapon can now be hidden (on your screen only).
1829void drawsmallweapon(short weapon, float scale, short x, short y)
1830{
1831 float t = 60000;
1832 int s;
1833 float offsetx, offsety;
1834
1835
1836 switch(weapon)
1837 {
1838 case KNEE_WEAPON : s=0; break;
1839 case PISTOL_WEAPON : s=FIRSTGUNSPRITE;
1840 offsetx = 8;
1841 offsety = 7;
1842 break;
1843 case SHOTGUN_WEAPON : s=SHOTGUNSPRITE;
1844 t = 45000;
1845 offsetx = -1;
1846 offsety = 9;
1847 break;
1848 case CHAINGUN_WEAPON : s=CHAINGUNSPRITE;
1849 t = 45000;
1850 offsetx = -1;
1851 offsety = 9;
1852 break;
1853 case RPG_WEAPON : s=RPGSPRITE;
1854 t = 45000;
1855 offsetx = 4;
1856 offsety = 9;
1857 break;
1858 case HANDBOMB_WEAPON : s=HEAVYHBOMB;
1859 t=20000;
1860 offsetx = 16;
1861 offsety = 13;
1862 break;
1863 case SHRINKER_WEAPON : s=SHRINKERSPRITE;
1864 t = 30000;
1865 offsetx = 6;
1866 offsety = 14;
1867 break;
1868 case DEVISTATOR_WEAPON : s=DEVISTATORSPRITE;
1869 t = 45000;
1870 offsetx = 3;
1871 offsety = 9;
1872 break;
1873 case TRIPBOMB_WEAPON : s=TRIPBOMBSPRITE;
1874 t = 75000;
1875 offsetx = 10;
1876 offsety = 12;
1877 break;
1878 case FREEZE_WEAPON : s=FREEZESPRITE;
1879 t = 45000;
1880 offsetx = 1;
1881 offsety = 6;
1882 break;
1883 case HANDREMOTE_WEAPON : s=0;
1884 break;
1885 case GROW_WEAPON : s=GROWSPRITEICON;
1886 t = 30000;
1887 offsetx = 6;
1888 offsety = 4;
1889 break;
1890 default : s=0;
1891 }
1892
1893 if(s)
1894 rotatesprite((x+(short)(offsetx*scale))<<16,(y+(short)(offsety*scale))<<16,(int)(t*scale),0,s,0,0,2+8+16,0,0,xdim-1,ydim-1);
1895
1896 return;
1897}
1898
1899void coolgaugetext(short snum)
1900{
1901 struct player_struct *p;
1902 int32_t i, j, o, ss, u;
1903 uint8_t permbit;
1904 short offx = 3, offy = 3, stepx=60, stepy=6;
1905 char text[512];
1906
1907 p = &ps[snum];
1908
1909 if (p->invdisptime > 0)
1910 {
1911 displayinventory(p);
1912 }
1913
1914
1915 if(ps[snum].gm&MODE_MENU)
1916 if( (current_menu >= 400 && current_menu <= 405) )
1917 return;
1918
1919 offy += countfragbars(); //add fragbars
1920 display_boardfilename_FPS_weapon(&offx, &offy, &stepx, &stepy);
1921
1922
1923 ss = ud.screen_size; if (ss < 4) return;
1924
1925 // Draw the multi player frag status bar
1926 if ( ud.multimode > 1 && ud.coop != 1 )
1927 {
1928 if (pus)
1929 {
1930 displayfragbar();
1931 }
1932 else
1933 {
1934 for(i=connecthead;i>=0;i=connectpoint2[i])
1935 {
1936 if (ps[i].frag != sbar.frag[i])
1937 {
1938 displayfragbar();
1939 break;
1940 }
1941 }
1942 }
1943 for(i=connecthead;i>=0;i=connectpoint2[i])
1944 if (i != myconnectindex)
1945 sbar.frag[i] = ps[i].frag;
1946 }
1947
1948 if (ss == 4) //DRAW MINI STATUS BAR:
1949 {
1950 // FIX_00027: Added an extra small statusbar (HUD)
1951 if(ud.extended_screen_size>0)
1952 {
1953 offx = 5; offy = 160;
1954
1955 sprintf(text,"%d", ps[screenpeek].ammo_amount[ps[screenpeek].curr_weapon]);
1956 minitext(offx+26,offy+21,text,COLOR_ON,2+8+16); //minitext: 2 red light, 23 yellow
1957 sprintf(text,"%d", ps[screenpeek].last_extra);
1958 gametext(offx,offy+20,text,ps[screenpeek].last_extra<=50?15:0,2+8+16); //minitext: 2 red light, 23 yellow
1959 rotatesprite((offx+0*10)<<16,(offy+28)<<16,20000,0,SHIELD,ps[screenpeek].shield_amount?25:100,0,2+8+16,0,0,xdim-1,ydim-1);
1960 rotatesprite((offx+0*10)<<16,(offy+28)<<16,ksqrt(ps[screenpeek].shield_amount)*20000/10,0,SHIELD,0,0,2+8+16,0,0,xdim-1,ydim-1);
1961 rotatesprite((offx+1*10)<<16,(offy+28)<<16,35000,0,JETPACK_ICON,ps[screenpeek].jetpack_amount?25:100,0,2+8+16,0,0,xdim-1,ydim-1);
1962 rotatesprite((offx+1*10)<<16,(offy+28)<<16,ksqrt(ps[screenpeek].jetpack_amount)*35000/40,0,JETPACK_ICON,0,0,2+8+16,0,0,xdim-1,ydim-1);
1963 rotatesprite((offx+2*10-1)<<16,(offy+28)<<16,35000,0,STEROIDS_ICON,ps[screenpeek].steroids_amount?25:100,0,2+8+16,0,0,xdim-1,ydim-1);
1964 rotatesprite((offx+2*10-1)<<16,(offy+28)<<16,ksqrt(ps[screenpeek].steroids_amount)*35000/20,0,STEROIDS_ICON,5,0,2+8+16,0,0,xdim-1,ydim-1);
1965 rotatesprite((offx+3*10-3)<<16,(offy+28)<<16,40000,0,FIRSTAID_ICON,ps[screenpeek].firstaid_amount?25:100,0,2+8+16,0,0,xdim-1,ydim-1);
1966 rotatesprite((offx+3*10-3)<<16,(offy+28)<<16,ksqrt(ps[screenpeek].firstaid_amount)*40000/10,0,FIRSTAID_ICON,0,0,2+8+16,0,0,xdim-1,ydim-1);
1967 }
1968 else
1969 {
1970 if (p->inven_icon)
1971 rotatesprite(69<<16,(200-30)<<16,65536L,0,INVENTORYBOX,0,21,10+16,0,0,xdim-1,ydim-1);
1972 rotatesprite(5<<16,(200-28)<<16,65536L,0,HEALTHBOX,0,21,10+16,0,0,xdim-1,ydim-1);
1973
1974 if(sprite[p->i].pal == 1 && p->last_extra < 2)
1975 digitalnumber(20,200-17,1,-16,10+16);
1976 else digitalnumber(20,200-17,p->last_extra,-16,10+16);
1977
1978 rotatesprite(37<<16,(200-28)<<16,65536L,0,AMMOBOX,0,21,10+16,0,0,xdim-1,ydim-1);
1979
1980 if (p->curr_weapon == HANDREMOTE_WEAPON) i = HANDBOMB_WEAPON; else i = p->curr_weapon;
1981 digitalnumber(53,200-17,p->ammo_amount[i],-16,10+16);
1982
1983 o = 158; permbit = 0;
1984 if (p->inven_icon)
1985 {
1986 switch(p->inven_icon)
1987 {
1988 case 1: i = FIRSTAID_ICON; break;
1989 case 2: i = STEROIDS_ICON; break;
1990 case 3: i = HOLODUKE_ICON; break;
1991 case 4: i = JETPACK_ICON; break;
1992 case 5: i = HEAT_ICON; break;
1993 case 6: i = AIRTANK_ICON; break;
1994 case 7: i = BOOT_ICON; break;
1995 default: i = -1;
1996 }
1997 if (i >= 0) rotatesprite((231-o)<<16,(200-21)<<16,65536L,0,i,0,0,10+16+permbit,0,0,xdim-1,ydim-1);
1998
1999 minitext(292-30-o,190,"%",6,10+16+permbit);
2000
2001 j = 0x80000000;
2002 switch(p->inven_icon)
2003 {
2004 case 1: i = p->firstaid_amount; break;
2005 case 2: i = ((p->steroids_amount+3)>>2); break;
2006 case 3: i = ((p->holoduke_amount+15)/24); j = p->holoduke_on; break;
2007 case 4: i = ((p->jetpack_amount+15)>>4); j = p->jetpack_on; break;
2008 case 5: i = p->heat_amount/12; j = p->heat_on; break;
2009 case 6: i = ((p->scuba_amount+63)>>6); break;
2010 case 7: i = (p->boot_amount>>1); break;
2011 }
2012 invennum(284-30-o,200-6,(uint8_t )i,0,10+permbit);
2013 if (j > 0) minitext(288-30-o,180,"ON",0,10+16+permbit);
2014 else if (j != 0x80000000) minitext(284-30-o,180,"OFF",2,10+16+permbit);
2015 if (p->inven_icon >= 6) minitext(284-35-o,180,"AUTO",2,10+16+permbit);
2016 }
2017 }
2018 return;
2019 }
2020
2021 //DRAW/UPDATE FULL STATUS BAR:
2022
2023 if (pus) { pus = 0; u = 0xffffffff; } else u = 0;
2024
2025 if (sbar.frag[myconnectindex] != p->frag) { sbar.frag[myconnectindex] = p->frag; u |= 32768; }
2026 if (sbar.got_access != p->got_access) { sbar.got_access = p->got_access; u |= 16384; }
2027 if (sbar.last_extra != p->last_extra) { sbar.last_extra = p->last_extra; u |= 1; }
2028 if (sbar.shield_amount != p->shield_amount) { sbar.shield_amount = p->shield_amount; u |= 2; }
2029 if (sbar.curr_weapon != p->curr_weapon) { sbar.curr_weapon = p->curr_weapon; u |= (4+8+16+32+64+128+256+512+1024+65536L); }
2030 for(i=1;i < 10;i++)
2031 {
2032 if (sbar.ammo_amount[i] != p->ammo_amount[i]) {
2033 sbar.ammo_amount[i] = p->ammo_amount[i]; if(i < 9) u |= ((2<<i)+1024); else u |= 65536L+1024; }
2034 if (sbar.gotweapon[i] != p->gotweapon[i]) { sbar.gotweapon[i] =
2035 p->gotweapon[i]; if(i < 9 ) u |= ((2<<i)+1024); else u |= 65536L+1024; }
2036 }
2037 if (sbar.inven_icon != p->inven_icon) { sbar.inven_icon = p->inven_icon; u |= (2048+4096+8192); }
2038 if (sbar.holoduke_on != p->holoduke_on) { sbar.holoduke_on = p->holoduke_on; u |= (4096+8192); }
2039 if (sbar.jetpack_on != p->jetpack_on) { sbar.jetpack_on = p->jetpack_on; u |= (4096+8192); }
2040 if (sbar.heat_on != p->heat_on) { sbar.heat_on = p->heat_on; u |= (4096+8192); }
2041 if (sbar.firstaid_amount != p->firstaid_amount) { sbar.firstaid_amount = p->firstaid_amount; u |= 8192; }
2042 if (sbar.steroids_amount != p->steroids_amount) { sbar.steroids_amount = p->steroids_amount; u |= 8192; }
2043 if (sbar.holoduke_amount != p->holoduke_amount) { sbar.holoduke_amount = p->holoduke_amount; u |= 8192; }
2044 if (sbar.jetpack_amount != p->jetpack_amount) { sbar.jetpack_amount = p->jetpack_amount; u |= 8192; }
2045 if (sbar.heat_amount != p->heat_amount) { sbar.heat_amount = p->heat_amount; u |= 8192; }
2046 if (sbar.scuba_amount != p->scuba_amount) { sbar.scuba_amount = p->scuba_amount; u |= 8192; }
2047 if (sbar.boot_amount != p->boot_amount) { sbar.boot_amount = p->boot_amount; u |= 8192; }
2048 if (u == 0) return;
2049
2050 //0 - update health
2051 //1 - update armor
2052 //2 - update PISTOL_WEAPON ammo
2053 //3 - update SHOTGUN_WEAPON ammo
2054 //4 - update CHAINGUN_WEAPON ammo
2055 //5 - update RPG_WEAPON ammo
2056 //6 - update HANDBOMB_WEAPON ammo
2057 //7 - update SHRINKER_WEAPON ammo
2058 //8 - update DEVISTATOR_WEAPON ammo
2059 //9 - update TRIPBOMB_WEAPON ammo
2060 //10 - update ammo display
2061 //11 - update inventory icon
2062 //12 - update inventory on/off
2063 //13 - update inventory %
2064 //14 - update keys
2065 //15 - update kills
2066 //16 - update FREEZE_WEAPON ammo
2067
2068 if (u == 0xffffffff)
2069 {
2070 patchstatusbar(0,0,320,200);
2071 if (ud.multimode > 1 && ud.coop != 1)
2072 rotatesprite(277<<16,(200-27)<<16,65536L,0,KILLSICON,0,0,10+16+128,0,0,xdim-1,ydim-1);
2073 }
2074 if (ud.multimode > 1 && ud.coop != 1)
2075 {
2076 if (u&32768)
2077 {
2078 if (u != 0xffffffff) patchstatusbar(276,183,299,193);
2079 digitalnumber(287,200-17,max(p->frag-p->fraggedself,0),-16,10+16+128);
2080 }
2081 }
2082 else
2083 {
2084 if (u&16384)
2085 {
2086 if (u != 0xffffffff) patchstatusbar(275,182,299,194);
2087 if (p->got_access&4) rotatesprite(275<<16,182<<16,65536L,0,ACCESS_ICON,0,23,10+16+128,0,0,xdim-1,ydim-1);
2088 if (p->got_access&2) rotatesprite(288<<16,182<<16,65536L,0,ACCESS_ICON,0,21,10+16+128,0,0,xdim-1,ydim-1);
2089 if (p->got_access&1) rotatesprite(281<<16,189<<16,65536L,0,ACCESS_ICON,0,0,10+16+128,0,0,xdim-1,ydim-1);
2090 }
2091 }
2092 if (u&(4+8+16+32+64+128+256+512+65536L)) weapon_amounts(p,96,182,u);
2093
2094 if (u&1)
2095 {
2096 if (u != 0xffffffff) patchstatusbar(20,183,43,193);
2097 if(sprite[p->i].pal == 1 && p->last_extra < 2)
2098 digitalnumber(32,200-17,1,-16,10+16+128);
2099 else digitalnumber(32,200-17,p->last_extra,-16,10+16+128);
2100 }
2101 if (u&2)
2102 {
2103 if (u != 0xffffffff) patchstatusbar(52,183,75,193);
2104 digitalnumber(64,200-17,p->shield_amount,-16,10+16+128);
2105 }
2106
2107 if (u&1024)
2108 {
2109 if (u != 0xffffffff) patchstatusbar(196,183,219,193);
2110 if (p->curr_weapon != KNEE_WEAPON)
2111 {
2112 if (p->curr_weapon == HANDREMOTE_WEAPON) i = HANDBOMB_WEAPON; else i = p->curr_weapon;
2113 digitalnumber(230-22,200-17,p->ammo_amount[i],-16,10+16+128);
2114 }
2115 }
2116
2117 if (u&(2048+4096+8192))
2118 {
2119 if (u != 0xffffffff)
2120 {
2121 if (u&(2048+4096)) { patchstatusbar(231,179,265,197); }
2122 else { patchstatusbar(250,190,261,195); }
2123 }
2124 if (p->inven_icon)
2125 {
2126 o = 0; permbit = 128;
2127
2128 if (u&(2048+4096))
2129 {
2130 switch(p->inven_icon)
2131 {
2132 case 1: i = FIRSTAID_ICON; break;
2133 case 2: i = STEROIDS_ICON; break;
2134 case 3: i = HOLODUKE_ICON; break;
2135 case 4: i = JETPACK_ICON; break;
2136 case 5: i = HEAT_ICON; break;
2137 case 6: i = AIRTANK_ICON; break;
2138 case 7: i = BOOT_ICON; break;
2139 }
2140 rotatesprite((231-o)<<16,(200-21)<<16,65536L,0,i,0,0,10+16+permbit,0,0,xdim-1,ydim-1);
2141 minitext(292-30-o,190,"%",6,10+16+permbit);
2142 if (p->inven_icon >= 6) minitext(284-35-o,180,"AUTO",2,10+16+permbit);
2143 }
2144 if (u&(2048+4096))
2145 {
2146 switch(p->inven_icon)
2147 {
2148 case 3: j = p->holoduke_on; break;
2149 case 4: j = p->jetpack_on; break;
2150 case 5: j = p->heat_on; break;
2151 default: j = 0x80000000;
2152 }
2153 if (j > 0) minitext(288-30-o,180,"ON",0,10+16+permbit);
2154 else if (j != 0x80000000) minitext(284-30-o,180,"OFF",2,10+16+permbit);
2155 }
2156 if (u&8192)
2157 {
2158 switch(p->inven_icon)
2159 {
2160 case 1: i = p->firstaid_amount; break;
2161 case 2: i = ((p->steroids_amount+3)>>2); break;
2162 case 3: i = ((p->holoduke_amount+15)/24); break;
2163 case 4: i = ((p->jetpack_amount+15)>>4); break;
2164 case 5: i = p->heat_amount/12; break;
2165 case 6: i = ((p->scuba_amount+63)>>6); break;
2166 case 7: i = (p->boot_amount>>1); break;
2167 }
2168 invennum(284-30-o,200-6,(uint8_t )i,0,10+permbit);
2169 }
2170 }
2171 }
2172}
2173
2174
2175#define AVERAGEFRAMES 16
2176static int32_t frameval[AVERAGEFRAMES], framecnt = 0;
2177
2178void duke_tics(short offx, short offy, short color)
2179{
2180 int32_t i;
2181 char fps[512], mapname[512];
2182 int32_t currentFps;
2183 static int32_t fpsAvg = 0, savedFps = 0;
2184 static boolean toggle = true;
2185 char text[512];
2186
2187 strcpy(mapname,boardfilename);
2188 for(i=0;i<512;i++)
2189 if(mapname[i]=='.')
2190 mapname[i]=0;
2191
2192 if( mapname[0] != 0 && ud.m_level_number == 7 && ud.m_volume_number == 0 )
2193 sprintf(text, "%s", mapname);
2194 else
2195 //sprintf(tempbuf, "%s", level_names[ud.volume_number*11 + ud.level_number]);
2196 sprintf(text, "e%dl%d", ud.volume_number+1, ud.level_number+1);
2197
2198
2199 i = totalclock;
2200
2201 if (i != frameval[framecnt])
2202 {
2203 currentFps = (TICRATE*AVERAGEFRAMES)/(i-frameval[framecnt]);
2204 fpsAvg = ((fpsAvg<<3)+(fpsAvg<<2) + (currentFps<<2))>>4;
2205
2206 frameval[framecnt] = i;
2207 }
2208
2209 framecnt = ((framecnt+1)&(AVERAGEFRAMES-1));
2210
2211 // refresh screen and update visible FPS. This is to allow a refresh
2212 // of the screen when the screensize > 4 w/o compromising the FPS.
2213 if(ud.screen_size>8)
2214 if ((totalclock%64) < 32)
2215 {
2216 if(toggle)
2217 {
2218 vscrn();
2219 savedFps = fpsAvg;
2220 }
2221 toggle = false;
2222 }
2223 else
2224 {
2225 toggle = true;
2226 }
2227 else
2228 savedFps = fpsAvg;
2229
2230 extern int rbaud_underruns;
2231 sprintf(fps," %d %d", savedFps, rbaud_underruns);
2232 strcat(text, fps);
2233
2234 minitext(offx,offy,text,color,2+8+16+128);
2235}
2236
2237void coords(short snum)
2238{
2239 short x = 200, y = 0;
2240 char text[512];
2241 // x = 250 is too much on the right and
2242 // will make the text going out of the screen
2243 // if screen <= (320x200)
2244 // This will also *write beyond the video
2245 // buffer limit* and will crash the game.
2246
2247 if(ud.coop != 1)
2248 {
2249 if(ud.multimode > 1 && ud.multimode < 5)
2250 y = 8;
2251 else if(ud.multimode > 4)
2252 y = 16;
2253 }
2254
2255 sprintf(text,"X= %d",ps[snum].posx);
2256 printext256(x,y,31,-1,text,1);
2257 sprintf(text,"Y= %d",ps[snum].posy);
2258 printext256(x,y+7L,31,-1,text,1);
2259 sprintf(text,"Z= %d",ps[snum].posz);
2260 printext256(x,y+14L,31,-1,text,1);
2261 sprintf(text,"A= %d",ps[snum].ang);
2262 printext256(x,y+21L,31,-1,text,1);
2263 sprintf(text,"ZV= %d",ps[snum].poszv);
2264 printext256(x,y+28L,31,-1,text,1);
2265 sprintf(text,"OG= %d",ps[snum].on_ground);
2266 printext256(x,y+35L,31,-1,text,1);
2267 sprintf(text,"AM= %d",ps[snum].ammo_amount[GROW_WEAPON]);
2268 printext256(x,y+43L,31,-1,text,1);
2269 sprintf(text,"LFW= %d",ps[snum].last_full_weapon);
2270 printext256(x,y+50L,31,-1,text,1);
2271 sprintf(text,"SECTL= %d",sector[ps[snum].cursectnum].lotag);
2272 printext256(x,y+57L,31,-1,text,1);
2273 sprintf(text,"SEED= %d",randomseed);
2274 printext256(x,y+64L,31,-1,text,1);
2275 sprintf(text,"THOLD= %d",ps[snum].transporter_hold);
2276 printext256(x,y+64L+7,31,-1,text,1);
2277}
2278
2279void operatefta(void)
2280{
2281 int32_t i, j, k;
2282
2283 if(ud.screen_size > 0) j = 200-45; else j = 200-8;
2284 quotebot = min(quotebot,j);
2285 quotebotgoal = min(quotebotgoal,j);
2286 if(ps[myconnectindex].gm&MODE_TYPE) j -= 8;
2287 quotebotgoal = j; j = quotebot;
2288 for(i=0;i<MAXUSERQUOTES;i++)
2289 {
2290 k = user_quote_time[i]; if (k <= 0) break;
2291
2292 if (k > 4)
2293 gametext(320>>1,j,user_quote[i],0,2+8+16);
2294 else if (k > 2) gametext(320>>1,j,user_quote[i],0,2+8+16+1);
2295 else gametext(320>>1,j,user_quote[i],0,2+8+16+1+32);
2296 j -= 8;
2297 }
2298
2299 if (ps[screenpeek].fta <= 1) return;
2300
2301 if (ud.coop != 1 && ud.screen_size > 0 && ud.multimode > 1)
2302 {
2303 j = 0; k = 8;
2304 for(i=connecthead;i>=0;i=connectpoint2[i])
2305 if (i > j) j = i;
2306
2307 if (j >= 4 && j <= 8) k += 8;
2308 else if (j > 8 && j <= 12) k += 16;
2309 else if (j > 12) k += 24;
2310 }
2311 else k = 0;
2312
2313 if (ps[screenpeek].ftq == 115 || ps[screenpeek].ftq == 116)
2314 {
2315 k = quotebot;
2316 for(i=0;i<MAXUSERQUOTES;i++)
2317 {
2318 if (user_quote_time[i] <= 0) break;
2319 k -= 8;
2320 }
2321 k -= 4;
2322 }
2323
2324 j = ps[screenpeek].fta;
2325 if (j > 4)
2326 gametext(320>>1,k,fta_quotes[ps[screenpeek].ftq],0,2+8+16);
2327 else
2328 if (j > 2) gametext(320>>1,k,fta_quotes[ps[screenpeek].ftq],0,2+8+16+1);
2329 else
2330 gametext(320>>1,k,fta_quotes[ps[screenpeek].ftq],0,2+8+16+1+32);
2331}
2332
2333void FTA(short q,struct player_struct *p, int mode)
2334{
2335 if( ud.fta_on == 1 || mode)
2336 {
2337 if( p->fta > 0 && q != 115 && q != 116 )
2338 if( p->ftq == 115 || p->ftq == 116 ) return;
2339
2340 p->fta = 100;
2341
2342 if( p->ftq != q || q == 26 )
2343 // || q == 26 || q == 115 || q ==116 || q == 117 || q == 122 )
2344 {
2345 p->ftq = q;
2346 pub = NUMPAGES;
2347 pus = NUMPAGES;
2348 }
2349 }
2350}
2351
2352void showtwoscreens(void)
2353{
2354 short i;
2355
2356 if(VOLUMEONE)
2357 {
2358 setview(0,0,xdim-1,ydim-1);
2359 flushperms();
2360 ps[myconnectindex].palette = palette;
2361 for(i=0;i<64;i+=7) palto(0,0,0,i);
2362 KB_FlushKeyboardQueue();
2363
2364 rotatesprite(0,0,65536L,0,3291,0,0,2+8+16+64, 0,0,xdim-1,ydim-1);
2365
2366 nextpage();
2367 for(i=63;i>0;i-=7) palto(0,0,0,i);
2368
2369 while( !KB_KeyWaiting() ); // getpackets(); // Net already off. Trying to get packets here makes sporadic crash..
2370
2371 for(i=0;i<64;i+=7)
2372 palto(0,0,0,i);
2373
2374 KB_FlushKeyboardQueue();
2375
2376 rotatesprite(0,0,65536L,0,3290,0,0,2+8+16+64, 0,0,xdim-1,ydim-1);
2377 nextpage();
2378
2379 for(i=63;i>0;i-=7)
2380 palto(0,0,0,i);
2381
2382 while( !KB_KeyWaiting() ); // getpackets();
2383 }
2384 else if(PLUTOPAK)
2385 {
2386 setview(0,0,xdim-1,ydim-1);
2387 flushperms();
2388 ps[myconnectindex].palette = palette;
2389
2390 for(i=0;i<64;i+=7)
2391 palto(0,0,0,i);
2392
2393 KB_FlushKeyboardQueue();
2394
2395 clearview(0L);
2396 rotatesprite(0,0,65536L,0,TENSCREEN,0,0,2+8+16+64, 0,0,xdim-1,ydim-1);
2397 nextpage();
2398
2399 for(i=63;i>0;i-=7)
2400 palto(0,0,0,i);
2401
2402 totalclock = 0;
2403
2404 while( !KB_KeyWaiting() );
2405
2406 }
2407}
2408
2409
2410void gameexit(char *msg)
2411{
2412 char t[256];
2413
2414 strncpy(t,msg,256); t[255] = 0;
2415
2416 if(*t != 0) ps[myconnectindex].palette = (uint8_t *) &palette[0];
2417
2418 if(numplayers > 1)
2419 allowtimetocorrecterrorswhenquitting();
2420
2421 if(ud.recstat == 1)
2422 closedemowrite();
2423
2424 if(frecfilep != NULL)
2425 {
2426 fclose(frecfilep);
2427 frecfilep = NULL;
2428 }
2429
2430 if(qe || cp)
2431 goto GOTOHERE;
2432
2433 // FIX_00089: scoreboard not shown for last player who quits a DM. Only 19.7 affected. (Sarah)
2434 if( ud.m_recstat != 2 && ud.last_level >= 0 && playerswhenstarted > 1 && ud.coop != 1 && *t == ' ')
2435 {
2436 dobonus(1);
2437// CTW - MODIFICATION
2438// setgamemode();
2439// FIX_00028: No need to call the videodriver on gameexit()
2440// setgamemode(ScreenMode,ScreenWidth,ScreenHeight);
2441// CTW END - MODIFICATION
2442 }
2443
2444 if(playerswhenstarted > 1)
2445 uninitmultiplayers(); /* deinits network transport. */
2446
2447// CTW - MODIFICATION
2448/* if( *t != 0 && *(t+1) != 'V' && *(t+1) != 'Y' && playonten == 0 )
2449 showtwoscreens();*/
2450 if( *t != 0 && *(t+1) != 'V' && *(t+1) != 'Y' && true)
2451 if(ud.showcinematics) // FIX_00029: toggle cinematics on / off
2452 showtwoscreens();
2453// CTW END - MODIFICATION
2454
2455GOTOHERE:
2456
2457 Shutdown();
2458
2459 if(*t != 0)
2460 {
2461 setvmode(0x3);
2462
2463// CTW - MODIFICATION
2464/* if(playonten == 0)
2465 {
2466 if(*t == ' ' && *(t+1) == 0) *t = 0;
2467 printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
2468 printf("%s%s","\n",t);
2469 }*/
2470 if(true)
2471 {
2472 if(*t == ' ' && *(t+1) == 0) *t = 0;
2473#if PLATFORM_DOS // Is there a good reason for this? --ryan.
2474 printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
2475#else
2476 printf("\n%s\n",t);
2477#endif
2478 }
2479// CTW END - MODIFICATION
2480 }
2481
2482 uninitgroupfile();
2483
2484 unlink("duke3d.tmp");
2485
2486 Error(EXIT_SUCCESS, "");
2487
2488}
2489
2490
2491
2492
2493short inputloc = 0;
2494short strget(short x,short y,char *t,short dalen,short c)
2495{
2496 short ch,sc;
2497
2498 while(KB_KeyWaiting())
2499 {
2500 sc = 0;
2501 ch = KB_Getch();
2502
2503 if (ch == 0)
2504 {
2505
2506 sc = KB_Getch();
2507 if( sc == 104) return(1);
2508
2509 continue;
2510 }
2511 else
2512 {
2513 if(ch == 8) // asc_BackSpace
2514 {
2515 if( inputloc > 0 )
2516 {
2517 inputloc--;
2518 *(t+inputloc) = 0;
2519 }
2520 }
2521 else
2522 {
2523 if(ch == asc_Enter || sc == 104)
2524 {
2525 KB_ClearKeyDown(sc_Enter);
2526 KB_ClearKeyDown(sc_kpad_Enter);
2527 return (1);
2528 }
2529 else if(ch == asc_Escape)
2530 {
2531 KB_ClearKeyDown(sc_Escape);
2532 return (-1);
2533 }
2534 else if ( ch >= 32 && inputloc < dalen && ch < 127)
2535 {
2536 ch = toupper(ch);
2537 *(t+inputloc) = ch;
2538 *(t+inputloc+1) = 0;
2539 inputloc++;
2540 }
2541 }
2542 }
2543 }
2544
2545 if( c == 999 ) return(0);
2546 if( c == 998 )
2547 {
2548 char b[41],ii;
2549 for(ii=0;ii<inputloc;ii++)
2550 b[ii] = '*';
2551 b[ii] = 0;
2552 x = gametext(x,y,b,c,2+8+16);
2553 }
2554 else x = gametext(x,y,t,c,2+8+16);
2555 c = 4-(sintable[(totalclock<<4)&2047]>>11);
2556 rotatesprite((x+8)<<16,(y+4)<<16,32768L,0,SPINNINGNUKEICON+((totalclock>>3)%7),c,0,2+8,0,0,xdim-1,ydim-1);
2557
2558 return (0);
2559}
2560
2561void typemode(void)
2562{
2563 short ch, hitstate, i, j;
2564 char text[512];
2565
2566 if( ps[myconnectindex].gm&MODE_SENDTOWHOM )
2567 {
2568 if(sendmessagecommand != -1 || ud.multimode < 3 || movesperpacket == 4)
2569 {
2570 text[0] = 4; // message command
2571 text[1] = 0;
2572 recbuf[0] = 0;
2573
2574 if(ud.multimode < 3)
2575 sendmessagecommand = 2;
2576
2577 strcat(recbuf,ud.user_name[myconnectindex]);
2578 strcat(recbuf,": ");
2579 strcat(recbuf,typebuf);
2580 j = strlen(recbuf);
2581 recbuf[j] = 0;
2582 strcat(text+1,recbuf);
2583
2584 if(sendmessagecommand >= ud.multimode || movesperpacket == 4)
2585 {
2586 for(ch=connecthead;ch >= 0;ch=connectpoint2[ch])
2587 if (ch != myconnectindex)
2588 sendpacket(ch,(uint8_t*)tempbuf,j+1);
2589
2590 adduserquote(recbuf);
2591 quotebot += 8;
2592 quotebotgoal = quotebot;
2593 }
2594 else if(sendmessagecommand >= 0)
2595 sendpacket(sendmessagecommand,(uint8_t*)tempbuf,j+1);
2596
2597 sendmessagecommand = -1;
2598 ps[myconnectindex].gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
2599 }
2600 else if(sendmessagecommand == -1)
2601 {
2602 j = 50;
2603 gametext(320>>1,j,"SEND MESSAGE TO...",0,2+8+16); j += 8;
2604 for(i=connecthead;i>=0;i=connectpoint2[i])
2605// for(i=0;i<ud.multimode;i++)
2606 {
2607 if (i == myconnectindex)
2608 {
2609 minitextshade((320>>1)-40+1,j+1,"A/ENTER - ALL",26,0,2+8+16);
2610 minitext((320>>1)-40,j,"A/ENTER - ALL",0,2+8+16); j += 7;
2611 }
2612 else
2613 {
2614 sprintf(buf," %d - %s",i+1,ud.user_name[i]);
2615 minitextshade((320>>1)-40-6+1,j+1,buf,26,0,2+8+16);
2616 minitext((320>>1)-40-6,j,buf,0,2+8+16); j += 7;
2617 }
2618 }
2619 minitextshade((320>>1)-40-4+1,j+1," ESC - Abort",26,0,2+8+16);
2620 minitext((320>>1)-40-4,j," ESC - Abort",0,2+8+16); j += 7;
2621
2622 //sprintf(buf,"PRESS 1-%ld FOR INDIVIDUAL PLAYER.",ud.multimode);
2623 //gametext(320>>1,j,buf,0,2+8+16); j += 8;
2624 //gametext(320>>1,j,"'A' OR 'ENTER' FOR ALL PLAYERS",0,2+8+16); j += 8;
2625 //gametext(320>>1,j,"ESC ABORTS",0,2+8+16); j += 8;
2626
2627 if (ud.screen_size > 0) j = 200-45; else j = 200-8;
2628 gametext(320>>1,j,typebuf,0,2+8+16);
2629
2630 if( KB_KeyWaiting() )
2631 {
2632 i = KB_Getch();
2633
2634 if(i == 'A' || i == 'a' || i == 13)
2635 sendmessagecommand = ud.multimode;
2636 else if(i >= '1' || i <= (ud.multimode + '1') )
2637 sendmessagecommand = i - '1';
2638 else
2639 {
2640 sendmessagecommand = ud.multimode;
2641 if(i == 27)
2642 {
2643 ps[myconnectindex].gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
2644 sendmessagecommand = -1;
2645 }
2646 else
2647 typebuf[0] = 0;
2648 }
2649
2650 KB_ClearKeyDown(sc_1);
2651 KB_ClearKeyDown(sc_2);
2652 KB_ClearKeyDown(sc_3);
2653 KB_ClearKeyDown(sc_4);
2654 KB_ClearKeyDown(sc_5);
2655 KB_ClearKeyDown(sc_6);
2656 KB_ClearKeyDown(sc_7);
2657 KB_ClearKeyDown(sc_8);
2658 KB_ClearKeyDown(sc_A);
2659 KB_ClearKeyDown(sc_Escape);
2660 KB_ClearKeyDown(sc_Enter);
2661 }
2662 }
2663 }
2664 else
2665 {
2666 if(ud.screen_size > 0) j = 200-45; else j = 200-8;
2667 hitstate = strget(320>>1,j,typebuf,30,1);
2668
2669 if(hitstate == 1)
2670 {
2671 KB_ClearKeyDown(sc_Enter);
2672 ps[myconnectindex].gm |= MODE_SENDTOWHOM;
2673 }
2674 else if(hitstate == -1)
2675 ps[myconnectindex].gm &= ~(MODE_TYPE|MODE_SENDTOWHOM);
2676 else pub = NUMPAGES;
2677 }
2678}
2679
2680void moveclouds(void)
2681{
2682 if( totalclock > cloudtotalclock || totalclock < (cloudtotalclock-7))
2683 {
2684 short i;
2685
2686 cloudtotalclock = totalclock+6;
2687
2688 for(i=0;i<numclouds;i++)
2689 {
2690 cloudx[i] += (sintable[(ps[screenpeek].ang+512)&2047]>>9);
2691 cloudy[i] += (sintable[ps[screenpeek].ang&2047]>>9);
2692
2693 sector[clouds[i]].ceilingxpanning = cloudx[i]>>6;
2694 sector[clouds[i]].ceilingypanning = cloudy[i]>>6;
2695 }
2696 }
2697}
2698
2699
2700void displayrest(int32_t smoothratio)
2701{
2702 int32_t a, i, j;
2703
2704 struct player_struct *pp;
2705 walltype *wal;
2706 int32_t cposx,cposy,cang;
2707
2708 pp = &ps[screenpeek];
2709
2710
2711 if(ud.show_help)
2712 {
2713 switch(ud.show_help)
2714 {
2715 case 1:
2716 rotatesprite(0,0,65536L,0,TEXTSTORY,0,0,10+16+64, 0,0,xdim-1,ydim-1);
2717 break;
2718 case 2:
2719 rotatesprite(0,0,65536L,0,F1HELP,0,0,10+16+64, 0,0,xdim-1,ydim-1);
2720 break;
2721 }
2722
2723 if ( KB_KeyPressed(sc_Escape ) )
2724 {
2725 KB_ClearKeyDown(sc_Escape);
2726 ud.show_help = 0;
2727 if(ud.multimode < 2 && ud.recstat != 2)
2728 {
2729 ready2send = 1;
2730 totalclock = ototalclock;
2731 }
2732 vscrn();
2733 }
2734 return;
2735 }
2736
2737 i = pp->cursectnum;
2738
2739 show2dsector[i>>3] |= (1<<(i&7));
2740 wal = &wall[sector[i].wallptr];
2741 for(j=sector[i].wallnum;j>0;j--,wal++)
2742 {
2743 i = wal->nextsector;
2744 if (i < 0) continue;
2745 if (wal->cstat&0x0071) continue;
2746 if (wall[wal->nextwall].cstat&0x0071) continue;
2747 if (sector[i].lotag == 32767) continue;
2748 if (sector[i].ceilingz >= sector[i].floorz) continue;
2749 show2dsector[i>>3] |= (1<<(i&7));
2750 }
2751
2752 if(ud.camerasprite == -1)
2753 {
2754 if( ud.overhead_on != 2 )
2755 {
2756 if(pp->newowner >= 0)
2757 cameratext(pp->newowner);
2758 else
2759 {
2760 displayweapon(screenpeek);
2761 if(pp->over_shoulder_on == 0 )
2762 displaymasks(screenpeek);
2763 }
2764 moveclouds();
2765 }
2766
2767 if( ud.overhead_on > 0 )
2768 {
2769 smoothratio = min(max(smoothratio,0),65536);
2770 dointerpolations(smoothratio);
2771 if( ud.scrollmode == 0 )
2772 {
2773 if(pp->newowner == -1)
2774 {
2775 if (screenpeek == myconnectindex && numplayers > 1)
2776 {
2777 cposx = omyx+mulscale16((int32_t)(myx-omyx),smoothratio);
2778 cposy = omyy+mulscale16((int32_t)(myy-omyy),smoothratio);
2779 cang = omyang+mulscale16((int32_t)(((myang+1024-omyang)&2047)-1024),smoothratio);
2780 }
2781 else
2782 {
2783 cposx = pp->oposx+mulscale16((int32_t)(pp->posx-pp->oposx),smoothratio);
2784 cposy = pp->oposy+mulscale16((int32_t)(pp->posy-pp->oposy),smoothratio);
2785 cang = pp->oang+mulscale16((int32_t)(((pp->ang+1024-pp->oang)&2047)-1024),smoothratio);
2786 }
2787 }
2788 else
2789 {
2790 cposx = pp->oposx;
2791 cposy = pp->oposy;
2792 cang = pp->oang;
2793 }
2794 }
2795 else
2796 {
2797
2798 ud.fola += ud.folavel>>3;
2799 ud.folx += (ud.folfvel*sintable[(512+2048-ud.fola)&2047])>>14;
2800 ud.foly += (ud.folfvel*sintable[(512+1024-512-ud.fola)&2047])>>14;
2801
2802 cposx = ud.folx;
2803 cposy = ud.foly;
2804 cang = ud.fola;
2805 }
2806
2807 if(ud.overhead_on == 2)
2808 {
2809 clearview(0L);
2810 drawmapview(cposx,cposy,pp->zoom,cang);
2811 }
2812 drawoverheadmap( cposx,cposy,pp->zoom,cang);
2813
2814 restoreinterpolations();
2815
2816 if(ud.overhead_on == 2)
2817 {
2818 if(ud.screen_size > 0) a = 147;
2819 else a = 182;
2820
2821 minitext(1,a+6,volume_names[ud.volume_number],0,2+8+16);
2822 minitext(1,a+12,level_names[ud.volume_number*11 + ud.level_number],0,2+8+16);
2823 }
2824 }
2825 }
2826
2827 coolgaugetext(screenpeek);
2828 operatefta();
2829
2830 if( KB_KeyPressed(sc_Escape) && ud.overhead_on == 0
2831 && ud.show_help == 0
2832 && ps[myconnectindex].newowner == -1)
2833 {
2834 if( (ps[myconnectindex].gm&MODE_MENU) != MODE_MENU &&
2835 ps[myconnectindex].newowner == -1 &&
2836 (ps[myconnectindex].gm&MODE_TYPE) != MODE_TYPE)
2837 {
2838 KB_ClearKeyDown(sc_Escape);
2839 FX_StopAllSounds();
2840 clearsoundlocks();
2841
2842 intomenusounds();
2843
2844 ps[myconnectindex].gm |= MODE_MENU;
2845
2846 if(ud.multimode < 2 && ud.recstat != 2) ready2send = 0;
2847
2848 if(ps[myconnectindex].gm&MODE_GAME) cmenu(50);
2849 else cmenu(0);
2850 screenpeek = myconnectindex;
2851 }
2852 }
2853
2854 if(ps[myconnectindex].newowner == -1 && ud.overhead_on == 0 && ud.crosshair && ud.camerasprite == -1)
2855 rotatesprite((160L-(ps[myconnectindex].look_ang>>1))<<16,100L<<16,65536L,0,CROSSHAIR,0,0,2+1,windowx1,windowy1,windowx2,windowy2);
2856
2857 if(ps[myconnectindex].gm&MODE_TYPE)
2858 typemode();
2859 else
2860 {
2861 CONSOLE_HandleInput();
2862 if( !CONSOLE_IsActive())
2863 {
2864 menus();
2865 }
2866 CONSOLE_Render();
2867 }
2868
2869 if( ud.pause_on==1 && (ps[myconnectindex].gm&MODE_MENU) == 0 )
2870 {
2871 if (!CONSOLE_IsActive()) //Addfaz Console Pause Game line addition
2872 {
2873 menutext(160,100,0,0,"GAME PAUSED");
2874 }
2875 else
2876 {
2877 menutext(160,120,0,0,"GAME PAUSED");
2878 }
2879 }
2880
2881 if(ud.coords)
2882 coords(screenpeek);
2883
2884 // FIX_00085: Optimized Video driver. FPS increases by +20%.
2885 if( pp->pals_time > 0 && pp->loogcnt == 0)
2886 {
2887 palto( pp->pals[0],
2888 pp->pals[1],
2889 pp->pals[2],
2890 pp->pals_time|128);
2891
2892 restorepalette = 1;
2893 }
2894 else if( restorepalette )
2895 {
2896 setbrightness(ud.brightness>>2,&pp->palette[0]);
2897 restorepalette = 0;
2898 }
2899 else if(pp->loogcnt > 0) palto(0,64,0,(pp->loogcnt>>1)+128);
2900
2901}
2902
2903
2904void updatesectorz(int32_t x, int32_t y, int32_t z, short *sectnum)
2905{
2906 walltype *wal;
2907 int32_t i, j, cz, fz;
2908
2909 getzsofslope(*sectnum,x,y,&cz,&fz);
2910 if ((z >= cz) && (z <= fz))
2911 if (inside(x,y,*sectnum) != 0) return;
2912
2913 if ((*sectnum >= 0) && (*sectnum < numsectors))
2914 {
2915 wal = &wall[sector[*sectnum].wallptr];
2916 j = sector[*sectnum].wallnum;
2917 do
2918 {
2919 i = wal->nextsector;
2920 if (i >= 0)
2921 {
2922 getzsofslope(i,x,y,&cz,&fz);
2923 if ((z >= cz) && (z <= fz))
2924 if (inside(x,y,(short)i) == 1)
2925 { *sectnum = i; return; }
2926 }
2927 wal++; j--;
2928 } while (j != 0);
2929 }
2930
2931 for(i=numsectors-1;i>=0;i--)
2932 {
2933 getzsofslope(i,x,y,&cz,&fz);
2934 if ((z >= cz) && (z <= fz))
2935 if (inside(x,y,(short)i) == 1)
2936 { *sectnum = i; return; }
2937 }
2938
2939 *sectnum = -1;
2940}
2941
2942void view(struct player_struct *pp, int32_t *vx, int32_t *vy,int32_t *vz,short *vsectnum, short ang, short horiz)
2943{
2944 spritetype *sp;
2945 int32_t i, nx, ny, nz, hx, hy, hitx, hity, hitz;
2946 short bakcstat, hitsect, hitwall, hitsprite, daang;
2947
2948 nx = (sintable[(ang+1536)&2047]>>4);
2949 ny = (sintable[(ang+1024)&2047]>>4);
2950 nz = (horiz-100)*128;
2951
2952 sp = &sprite[pp->i];
2953
2954 bakcstat = sp->cstat;
2955 sp->cstat &= (short)~0x101;
2956
2957 updatesectorz(*vx,*vy,*vz,vsectnum);
2958 hitscan(*vx,*vy,*vz,*vsectnum,nx,ny,nz,&hitsect,&hitwall,&hitsprite,&hitx,&hity,&hitz,CLIPMASK1);
2959
2960 if(*vsectnum < 0)
2961 {
2962 sp->cstat = bakcstat;
2963 return;
2964 }
2965
2966 hx = hitx-(*vx); hy = hity-(*vy);
2967 if (klabs(nx)+klabs(ny) > klabs(hx)+klabs(hy))
2968 {
2969 *vsectnum = hitsect;
2970 if (hitwall >= 0)
2971 {
2972 daang = getangle(wall[wall[hitwall].point2].x-wall[hitwall].x,
2973 wall[wall[hitwall].point2].y-wall[hitwall].y);
2974
2975 i = nx*sintable[daang]+ny*sintable[(daang+1536)&2047];
2976 if (klabs(nx) > klabs(ny)) hx -= mulscale28(nx,i);
2977 else hy -= mulscale28(ny,i);
2978 }
2979 else if (hitsprite < 0)
2980 {
2981 if (klabs(nx) > klabs(ny)) hx -= (nx>>5);
2982 else hy -= (ny>>5);
2983 }
2984 if (klabs(nx) > klabs(ny)) i = divscale16(hx,nx);
2985 else i = divscale16(hy,ny);
2986 if (i < cameradist) cameradist = i;
2987 }
2988 *vx = (*vx)+mulscale16(nx,cameradist);
2989 *vy = (*vy)+mulscale16(ny,cameradist);
2990 *vz = (*vz)+mulscale16(nz,cameradist);
2991
2992 cameradist = min(cameradist+((totalclock-cameraclock)<<10),65536);
2993 cameraclock = totalclock;
2994
2995 updatesectorz(*vx,*vy,*vz,vsectnum);
2996
2997 sp->cstat = bakcstat;
2998}
2999
3000//REPLACE FULLY
3001void drawbackground(void)
3002{
3003 short dapicnum;
3004 int32_t x,y,x1,y1,x2,y2;
3005
3006 flushperms();
3007
3008 switch(ud.m_volume_number)
3009 {
3010 default:dapicnum = BIGHOLE;break;
3011 case 1:dapicnum = BIGHOLE;break;
3012 case 2:dapicnum = BIGHOLE;break;
3013 }
3014
3015 y1 = 0; y2 = ydim;
3016 if( ready2send || ud.recstat == 2 )
3017 {
3018 if(ud.coop != 1)
3019 {
3020 if (ud.multimode > 1) y1 += scale(ydim,8,200);
3021 if (ud.multimode > 4) y1 += scale(ydim,8,200);
3022 }
3023 if (ud.screen_size >= 8) y2 = scale(ydim,200-34,200);
3024 }
3025
3026 for(y=y1;y<y2;y+=128)
3027 for(x=0;x<xdim;x+=128)
3028 rotatesprite(x<<16,y<<16,65536L,0,dapicnum,8,0,8+16+64+128,0,y1,xdim-1,y2-1);
3029
3030 // FIX_00081: Screen border in menu
3031 if(ud.screen_size > 8 && (ps[myconnectindex].gm & MODE_GAME || ud.recstat == 2 )) // ud.recstat == 2 => playing demo
3032 {
3033 y = 0;
3034 if(ud.coop != 1)
3035 {
3036 if (ud.multimode > 1) y += 8;
3037 if (ud.multimode > 4) y += 8;
3038 }
3039
3040 x1 = max(windowx1-4,0);
3041 y1 = max(windowy1-4,y);
3042 x2 = min(windowx2+4,xdim-1);
3043 y2 = min(windowy2+4,scale(ydim,200-34,200)-1);
3044
3045 for(y=y1+4;y<y2-4;y+=64)
3046 {
3047 rotatesprite(x1<<16,y<<16,65536L,0,VIEWBORDER,0,0,8+16+64+128,x1,y1,x2,y2);
3048 rotatesprite((x2+1)<<16,(y+64)<<16,65536L,1024,VIEWBORDER,0,0,8+16+64+128,x1,y1,x2,y2);
3049 }
3050
3051 for(x=x1+4;x<x2-4;x+=64)
3052 {
3053 rotatesprite((x+64)<<16,y1<<16,65536L,512,VIEWBORDER,0,0,8+16+64+128,x1,y1,x2,y2);
3054 rotatesprite(x<<16,(y2+1)<<16,65536L,1536,VIEWBORDER,0,0,8+16+64+128,x1,y1,x2,y2);
3055 }
3056
3057 rotatesprite(x1<<16,y1<<16,65536L,0,VIEWBORDER+1,0,0,8+16+64+128,x1,y1,x2,y2);
3058 rotatesprite((x2+1)<<16,y1<<16,65536L,512,VIEWBORDER+1,0,0,8+16+64+128,x1,y1,x2,y2);
3059 rotatesprite((x2+1)<<16,(y2+1)<<16,65536L,1024,VIEWBORDER+1,0,0,8+16+64+128,x1,y1,x2,y2);
3060 rotatesprite(x1<<16,(y2+1)<<16,65536L,1536,VIEWBORDER+1,0,0,8+16+64+128,x1,y1,x2,y2);
3061 }
3062}
3063
3064
3065// Floor Over Floor
3066
3067// If standing in sector with SE42
3068// then draw viewing to SE41 and raise all =hi SE43 cielings.
3069
3070// If standing in sector with SE43
3071// then draw viewing to SE40 and lower all =hi SE42 floors.
3072
3073// If standing in sector with SE44
3074// then draw viewing to SE40.
3075
3076// If standing in sector with SE45
3077// then draw viewing to SE41.
3078
3079#define FOFTILE 13
3080#define FOFTILEX 32
3081#define FOFTILEY 32
3082int32_t tempsectorz[MAXSECTORS];
3083int32_t tempsectorpicnum[MAXSECTORS];
3084//short tempcursectnum;
3085
3086static void SE40_Draw(int spnum,int32_t x,int32_t y,int32_t z,short a,short h,int32_t smoothratio)
3087{
3088 int i=0,j=0,k=0;
3089 int floor1=0,floor2=0,ok=0,fofmode=0;
3090 int32_t offx,offy;
3091
3092 if(sprite[spnum].ang!=512) return;
3093
3094 i = FOFTILE; //Effect TILE
3095 if (!(gotpic[i>>3]&(1<<(i&7)))) return;
3096 gotpic[i>>3] &= ~(1<<(i&7));
3097
3098 floor1=spnum;
3099
3100 if(sprite[spnum].lotag==42) fofmode=40;
3101 if(sprite[spnum].lotag==43) fofmode=41;
3102 if(sprite[spnum].lotag==44) fofmode=40;
3103 if(sprite[spnum].lotag==45) fofmode=41;
3104
3105// fofmode=sprite[spnum].lotag-2;
3106
3107// sectnum=sprite[j].sectnum;
3108// sectnum=cursectnum;
3109 ok++;
3110
3111/* recursive?
3112 for(j=0;j<MAXSPRITES;j++)
3113 {
3114 if(
3115 sprite[j].sectnum==sectnum &&
3116 sprite[j].picnum==1 &&
3117 sprite[j].lotag==110
3118 ) { DrawFloorOverFloor(j); break;}
3119 }
3120*/
3121
3122// if(ok==0) { Message("no fof",RED); return; }
3123
3124 for(j=0;j<MAXSPRITES;j++)
3125 {
3126 if(
3127 sprite[j].picnum==1 &&
3128 sprite[j].lotag==fofmode &&
3129 sprite[j].hitag==sprite[floor1].hitag
3130 ) { floor1=j; fofmode=sprite[j].lotag; ok++; break;}
3131 }
3132// if(ok==1) { Message("no floor1",RED); return; }
3133
3134 if(fofmode==40) k=41; else k=40;
3135
3136 for(j=0;j<MAXSPRITES;j++)
3137 {
3138 if(
3139 sprite[j].picnum==1 &&
3140 sprite[j].lotag==k &&
3141 sprite[j].hitag==sprite[floor1].hitag
3142 )
3143 {
3144 floor2=j;
3145 ok++;
3146 break;
3147 }
3148 }
3149
3150// if(ok==2) { Message("no floor2",RED); return; }
3151
3152 for(j=0;j<MAXSPRITES;j++) // raise ceiling or floor
3153 {
3154 if(sprite[j].picnum==1 &&
3155 sprite[j].lotag==k+2 &&
3156 sprite[j].hitag==sprite[floor1].hitag
3157 )
3158 {
3159 if(k==40)
3160 {tempsectorz[sprite[j].sectnum]=sector[sprite[j].sectnum].floorz;
3161 sector[sprite[j].sectnum].floorz+=(((z-sector[sprite[j].sectnum].floorz)/32768)+1)*32768;
3162 tempsectorpicnum[sprite[j].sectnum]=sector[sprite[j].sectnum].floorpicnum;
3163 sector[sprite[j].sectnum].floorpicnum=13;
3164 }
3165 if(k==41)
3166 {tempsectorz[sprite[j].sectnum]=sector[sprite[j].sectnum].ceilingz;
3167 sector[sprite[j].sectnum].ceilingz+=(((z-sector[sprite[j].sectnum].ceilingz)/32768)-1)*32768;
3168 tempsectorpicnum[sprite[j].sectnum]=sector[sprite[j].sectnum].ceilingpicnum;
3169 sector[sprite[j].sectnum].ceilingpicnum=13;
3170 }
3171 }
3172 }
3173
3174 i=floor1;
3175 offx=x-sprite[i].x;
3176 offy=y-sprite[i].y;
3177 i=floor2;
3178 drawrooms(offx+sprite[i].x,offy+sprite[i].y,z,a,h,sprite[i].sectnum);
3179 animatesprites(x,y,a,smoothratio);
3180 drawmasks();
3181
3182 for(j=0;j<MAXSPRITES;j++) // restore ceiling or floor
3183 {
3184 if(sprite[j].picnum==1 &&
3185 sprite[j].lotag==k+2 &&
3186 sprite[j].hitag==sprite[floor1].hitag
3187 )
3188 {
3189 if(k==40)
3190 {sector[sprite[j].sectnum].floorz=tempsectorz[sprite[j].sectnum];
3191 sector[sprite[j].sectnum].floorpicnum=tempsectorpicnum[sprite[j].sectnum];
3192 }
3193 if(k==41)
3194 {sector[sprite[j].sectnum].ceilingz=tempsectorz[sprite[j].sectnum];
3195 sector[sprite[j].sectnum].ceilingpicnum=tempsectorpicnum[sprite[j].sectnum];
3196 }
3197 }// end if
3198 }// end for
3199
3200} // end SE40
3201
3202
3203
3204
3205static void se40code(int32_t x,int32_t y,int32_t z,int32_t a,int32_t h, int32_t smoothratio)
3206{
3207 int i;
3208
3209 i = headspritestat[15];
3210 while(i >= 0)
3211 {
3212 switch(sprite[i].lotag)
3213 {
3214// case 40:
3215// case 41:
3216// SE40_Draw(i,x,y,a,smoothratio);
3217// break;
3218 case 42:
3219 case 43:
3220 case 44:
3221 case 45:
3222 if(ps[screenpeek].cursectnum == sprite[i].sectnum)
3223 SE40_Draw(i,x,y,z,a,h,smoothratio);
3224 break;
3225 }
3226 i = nextspritestat[i];
3227 }
3228}
3229
3230static int32_t oyrepeat=-1;
3231
3232void displayrooms(short snum,int32_t smoothratio)
3233{
3234 int32_t cposx,cposy,cposz,dst,j,fz,cz;
3235 short sect, cang, k, choriz;
3236 struct player_struct *p;
3237 int32_t tposx,tposy,i;
3238 short tang;
3239
3240 p = &ps[snum];
3241
3242 if(pub > 0)
3243 {
3244 if(ud.screen_size > 8) drawbackground();
3245 pub = 0;
3246 }
3247
3248 if( ud.overhead_on == 2 || ud.show_help || p->cursectnum == -1)
3249 return;
3250
3251 smoothratio = min(max(smoothratio,0),65536);
3252
3253 visibility = p->visibility;
3254
3255 if(ud.pause_on || ps[snum].on_crane > -1) smoothratio = 65536;
3256
3257 sect = p->cursectnum;
3258 if(sect < 0 || sect >= MAXSECTORS) return;
3259
3260 dointerpolations(smoothratio);
3261
3262 animatecamsprite();
3263
3264 if(ud.camerasprite >= 0)
3265 {
3266 spritetype *s;
3267
3268 s = &sprite[ud.camerasprite];
3269
3270 if(s->yvel < 0) s->yvel = -100;
3271 else if(s->yvel > 199) s->yvel = 300;
3272
3273 cang = hittype[ud.camerasprite].tempang+mulscale16((int32_t)(((s->ang+1024-hittype[ud.camerasprite].tempang)&2047)-1024),smoothratio);
3274
3275 se40code(s->x,s->y,s->z,cang,s->yvel,smoothratio);
3276
3277 drawrooms(s->x,s->y,s->z-(4<<8),cang,s->yvel,s->sectnum);
3278 animatesprites(s->x,s->y,cang,smoothratio);
3279 drawmasks();
3280 }
3281 else
3282 {
3283 i = divscale22(1,sprite[p->i].yrepeat+28);
3284 if (i != oyrepeat)
3285 {
3286 oyrepeat = i;
3287 //printf("1: %d %d\n", oyrepeat,yxaspect);
3288 setaspect(oyrepeat,yxaspect);
3289 //printf("2: %d %d\n", oyrepeat,yxaspect);
3290 }
3291
3292 if(screencapt)
3293 {
3294 tiles[MAXTILES-1].lock = 254;
3295 if (tiles[MAXTILES-1].data == NULL)
3296 allocache(&tiles[MAXTILES-1].data,100*160,&tiles[MAXTILES-1].lock);
3297
3298 setviewtotile(MAXTILES-1,100L,160L);
3299 }
3300 else if( ( ud.screen_tilting && p->rotscrnang ) || ud.detail==0 )
3301 {
3302 if (ud.screen_tilting) tang = p->rotscrnang; else tang = 0;
3303
3304 tiles[MAXTILES-2].lock = 255;
3305 if (tiles[MAXTILES-2].data == NULL)
3306 allocache(&tiles[MAXTILES-2].data,320L*320L,&tiles[MAXTILES-2].lock);
3307 if ((tang&1023) == 0)
3308 setviewtotile(MAXTILES-2,200L>>(1-ud.detail),320L>>(1-ud.detail));
3309 else
3310 setviewtotile(MAXTILES-2,320L>>(1-ud.detail),320L>>(1-ud.detail));
3311 if ((tang&1023) == 512)
3312 { //Block off unscreen section of 90ø tilted screen
3313 j = ((320-60)>>(1-ud.detail));
3314 for(i=(60>>(1-ud.detail))-1;i>=0;i--)
3315 {
3316 startumost[i] = 1; startumost[i+j] = 1;
3317 startdmost[i] = 0; startdmost[i+j] = 0;
3318 }
3319 }
3320
3321 i = (tang&511); if (i > 256) i = 512-i;
3322 i = sintable[i+512]*8 + sintable[i]*5L;
3323 setaspect(i>>1,yxaspect);
3324 }
3325
3326 if ( (snum == myconnectindex) && (numplayers > 1) )
3327 {
3328 cposx = omyx+mulscale16((int32_t)(myx-omyx),smoothratio);
3329 cposy = omyy+mulscale16((int32_t)(myy-omyy),smoothratio);
3330 cposz = omyz+mulscale16((int32_t)(myz-omyz),smoothratio);
3331 cang = omyang+mulscale16((int32_t)(((myang+1024-omyang)&2047)-1024),smoothratio);
3332 choriz = omyhoriz+omyhorizoff+mulscale16((int32_t)(myhoriz+myhorizoff-omyhoriz-omyhorizoff),smoothratio);
3333 sect = mycursectnum;
3334 }
3335 else
3336 {
3337 cposx = p->oposx+mulscale16((int32_t)(p->posx-p->oposx),smoothratio);
3338 cposy = p->oposy+mulscale16((int32_t)(p->posy-p->oposy),smoothratio);
3339 cposz = p->oposz+mulscale16((int32_t)(p->posz-p->oposz),smoothratio);
3340 cang = p->oang+mulscale16((int32_t)(((p->ang+1024-p->oang)&2047)-1024),smoothratio);
3341 choriz = p->ohoriz+p->ohorizoff+mulscale16((int32_t)(p->horiz+p->horizoff-p->ohoriz-p->ohorizoff),smoothratio);
3342 }
3343 cang += p->look_ang;
3344
3345 if (p->newowner >= 0)
3346 {
3347 cang = p->ang+p->look_ang;
3348 choriz = p->horiz+p->horizoff;
3349 cposx = p->posx;
3350 cposy = p->posy;
3351 cposz = p->posz;
3352 sect = sprite[p->newowner].sectnum;
3353 smoothratio = 65536L;
3354 }
3355
3356 else if( p->over_shoulder_on == 0 )
3357 cposz += p->opyoff+mulscale16((int32_t)(p->pyoff-p->opyoff),smoothratio);
3358 else view(p,&cposx,&cposy,&cposz,&sect,cang,choriz);
3359
3360 cz = hittype[p->i].ceilingz;
3361 fz = hittype[p->i].floorz;
3362
3363 if(earthquaketime > 0 && p->on_ground == 1)
3364 {
3365 cposz += 256-(((earthquaketime)&1)<<9);
3366 cang += (2-((earthquaketime)&2))<<2;
3367 }
3368
3369 if(sprite[p->i].pal == 1) cposz -= (18<<8);
3370
3371 if(p->newowner >= 0)
3372 choriz = 100+sprite[p->newowner].shade;
3373 else if(p->spritebridge == 0)
3374 {
3375 if( cposz < ( p->truecz + (4<<8) ) ) cposz = cz + (4<<8);
3376 else if( cposz > ( p->truefz - (4<<8) ) ) cposz = fz - (4<<8);
3377 }
3378
3379 if (sect >= 0)
3380 {
3381 getzsofslope(sect,cposx,cposy,&cz,&fz);
3382 if (cposz < cz+(4<<8)) cposz = cz+(4<<8);
3383 if (cposz > fz-(4<<8)) cposz = fz-(4<<8);
3384 }
3385
3386 if(choriz > 299) choriz = 299;
3387 else if(choriz < -99) choriz = -99;
3388
3389 se40code(cposx,cposy,cposz,cang,choriz,smoothratio);
3390
3391 if ((gotpic[MIRROR>>3]&(1<<(MIRROR&7))) > 0)
3392 {
3393 dst = 0x7fffffff; i = 0;
3394 for(k=0;k<mirrorcnt;k++)
3395 {
3396 j = klabs(wall[mirrorwall[k]].x-cposx);
3397 j += klabs(wall[mirrorwall[k]].y-cposy);
3398 if (j < dst) dst = j, i = k;
3399 }
3400
3401 if( wall[mirrorwall[i]].overpicnum == MIRROR )
3402 {
3403 preparemirror(cposx,cposy,cposz,cang,choriz,mirrorwall[i],mirrorsector[i],&tposx,&tposy,&tang);
3404
3405 j = visibility;
3406 visibility = (j>>1) + (j>>2);
3407
3408 drawrooms(tposx,tposy,cposz,tang,choriz,mirrorsector[i]+MAXSECTORS);
3409
3410 display_mirror = 1;
3411 animatesprites(tposx,tposy,tang,smoothratio);
3412 display_mirror = 0;
3413
3414 drawmasks();
3415 completemirror(); //Reverse screen x-wise in this function
3416 visibility = j;
3417 }
3418 gotpic[MIRROR>>3] &= ~(1<<(MIRROR&7));
3419 }
3420
3421 drawrooms(cposx,cposy,cposz,cang,choriz,sect);
3422 animatesprites(cposx,cposy,cang,smoothratio);
3423 drawmasks();
3424
3425 if(screencapt == 1)
3426 {
3427 setviewback();
3428 tiles[MAXTILES-1].lock = 1;
3429 screencapt = 0;
3430 }
3431 else if( ( ud.screen_tilting && p->rotscrnang) || ud.detail==0 )
3432 {
3433 if (ud.screen_tilting) tang = p->rotscrnang; else tang = 0;
3434 setviewback();
3435 tiles[MAXTILES-2].animFlags &= 0xff0000ff;
3436 i = (tang&511); if (i > 256) i = 512-i;
3437 i = sintable[i+512]*8 + sintable[i]*5L;
3438 if ((1-ud.detail) == 0) i >>= 1;
3439 rotatesprite(160<<16,100<<16,i,tang+512,MAXTILES-2,0,0,4+2+64,windowx1,windowy1,windowx2,windowy2);
3440 tiles[MAXTILES-2].lock = 199;
3441 }
3442 }
3443
3444 restoreinterpolations();
3445
3446 if (totalclock < lastvisinc)
3447 {
3448 if (klabs(p->visibility-ud.const_visibility) > 8)
3449 p->visibility += (ud.const_visibility-p->visibility)>>2;
3450 }
3451 else p->visibility = ud.const_visibility;
3452}
3453
3454
3455
3456
3457
3458short LocateTheLocator(short n,short sn)
3459{
3460 short i;
3461
3462 i = headspritestat[7];
3463 while(i >= 0)
3464 {
3465 if( (sn == -1 || sn == SECT) && n == SLT )
3466 return i;
3467 i = nextspritestat[i];
3468 }
3469 return -1;
3470}
3471
3472short EGS(short whatsect,int32_t s_x,int32_t s_y,int32_t s_z,short s_pn,int8_t s_s,int8_t s_xr,int8_t s_yr,short s_a,short s_ve,int32_t s_zv,short s_ow,int8_t s_ss)
3473{
3474 short i;
3475 spritetype *s;
3476
3477 i = insertsprite(whatsect,s_ss);
3478
3479 if( i < 0 )
3480 gameexit(" Too many sprites spawned. This may happen (for any duke port) if you have hacked the steroids trail in the *.con files. If so, delete your *.con files to use the internal ones and try again.");
3481
3482 hittype[i].bposx = s_x;
3483 hittype[i].bposy = s_y;
3484 hittype[i].bposz = s_z;
3485
3486 s = &sprite[i];
3487
3488 s->x = s_x;
3489 s->y = s_y;
3490 s->z = s_z;
3491 s->cstat = 0;
3492 s->picnum = s_pn;
3493 s->shade = s_s;
3494 s->xrepeat = s_xr;
3495 s->yrepeat = s_yr;
3496 s->pal = 0;
3497
3498 s->ang = s_a;
3499 s->xvel = s_ve;
3500 s->zvel = s_zv;
3501 s->owner = s_ow;
3502 s->xoffset = 0;
3503 s->yoffset = 0;
3504 s->yvel = 0;
3505 s->clipdist = 0;
3506 s->pal = 0;
3507 s->lotag = 0;
3508
3509 hittype[i].picnum = sprite[s_ow].picnum;
3510
3511 hittype[i].lastvx = 0;
3512 hittype[i].lastvy = 0;
3513
3514 hittype[i].timetosleep = 0;
3515 hittype[i].actorstayput = -1;
3516 hittype[i].extra = -1;
3517 hittype[i].owner = s_ow;
3518 hittype[i].cgg = 0;
3519 hittype[i].movflag = 0;
3520 hittype[i].tempang = 0;
3521 hittype[i].dispicnum = 0;
3522 hittype[i].floorz = hittype[s_ow].floorz;
3523 hittype[i].ceilingz = hittype[s_ow].ceilingz;
3524
3525 T1=T3=T4=T6=0;
3526 if( actorscrptr[s_pn] )
3527 {
3528 s->extra = *actorscrptr[s_pn];
3529 T5 = *(actorscrptr[s_pn]+1);
3530 T2 = *(actorscrptr[s_pn]+2);
3531 s->hitag = *(actorscrptr[s_pn]+3);
3532 }
3533 else
3534 {
3535 T2=T5=0;
3536 s->extra = 0;
3537 s->hitag = 0;
3538 }
3539
3540 if (show2dsector[SECT>>3]&(1<<(SECT&7))) show2dsprite[i>>3] |= (1<<(i&7));
3541 else show2dsprite[i>>3] &= ~(1<<(i&7));
3542/*
3543 if(s->sectnum < 0)
3544 {
3545 s->xrepeat = s->yrepeat = 0;
3546 changespritestat(i,5);
3547 }
3548*/
3549 return(i);
3550}
3551
3552uint8_t wallswitchcheck(short i)
3553{
3554 switch(PN)
3555 {
3556 case HANDPRINTSWITCH:
3557 case HANDPRINTSWITCH+1:
3558 case ALIENSWITCH:
3559 case ALIENSWITCH+1:
3560 case MULTISWITCH:
3561 case MULTISWITCH+1:
3562 case MULTISWITCH+2:
3563 case MULTISWITCH+3:
3564 case ACCESSSWITCH:
3565 case ACCESSSWITCH2:
3566 case PULLSWITCH:
3567 case PULLSWITCH+1:
3568 case HANDSWITCH:
3569 case HANDSWITCH+1:
3570 case SLOTDOOR:
3571 case SLOTDOOR+1:
3572 case LIGHTSWITCH:
3573 case LIGHTSWITCH+1:
3574 case SPACELIGHTSWITCH:
3575 case SPACELIGHTSWITCH+1:
3576 case SPACEDOORSWITCH:
3577 case SPACEDOORSWITCH+1:
3578 case FRANKENSTINESWITCH:
3579 case FRANKENSTINESWITCH+1:
3580 case LIGHTSWITCH2:
3581 case LIGHTSWITCH2+1:
3582 case POWERSWITCH1:
3583 case POWERSWITCH1+1:
3584 case LOCKSWITCH1:
3585 case LOCKSWITCH1+1:
3586 case POWERSWITCH2:
3587 case POWERSWITCH2+1:
3588 case DIPSWITCH:
3589 case DIPSWITCH+1:
3590 case DIPSWITCH2:
3591 case DIPSWITCH2+1:
3592 case TECHSWITCH:
3593 case TECHSWITCH+1:
3594 case DIPSWITCH3:
3595 case DIPSWITCH3+1:
3596 return 1;
3597 }
3598 return 0;
3599}
3600
3601
3602int32_t tempwallptr;
3603short spawn( short j, short pn )
3604{
3605 short i, s, startwall, endwall, sect, clostest;
3606 int32_t x, y, d;
3607 spritetype *sp;
3608 char text[512];
3609
3610 if(j >= 0)
3611 {
3612 i = EGS(sprite[j].sectnum,sprite[j].x,sprite[j].y,sprite[j].z
3613 ,pn,0,0,0,0,0,0,j,0);
3614 hittype[i].picnum = sprite[j].picnum;
3615 }
3616 else
3617 {
3618 i = pn;
3619
3620 hittype[i].picnum = PN;
3621 hittype[i].timetosleep = 0;
3622 hittype[i].extra = -1;
3623
3624 hittype[i].bposx = SX;
3625 hittype[i].bposy = SY;
3626 hittype[i].bposz = SZ;
3627
3628 OW = hittype[i].owner = i;
3629 hittype[i].cgg = 0;
3630 hittype[i].movflag = 0;
3631 hittype[i].tempang = 0;
3632 hittype[i].dispicnum = 0;
3633 hittype[i].floorz = sector[SECT].floorz;
3634 hittype[i].ceilingz = sector[SECT].ceilingz;
3635
3636 hittype[i].lastvx = 0;
3637 hittype[i].lastvy = 0;
3638 hittype[i].actorstayput = -1;
3639
3640 T1 = T2 = T3 = T4 = T5 = T6 = 0;
3641
3642 if( PN != SPEAKER && PN != LETTER && PN != DUCK && PN != TARGET && PN != TRIPBOMB && PN != VIEWSCREEN && PN != VIEWSCREEN2 && (CS&48) )
3643 if( !(PN >= CRACK1 && PN <= CRACK4) )
3644 {
3645 if(SS == 127) return i;
3646 if( wallswitchcheck(i) == 1 && (CS&16) )
3647 {
3648 if( PN != ACCESSSWITCH && PN != ACCESSSWITCH2 && sprite[i].pal)
3649 {
3650 if( (ud.multimode < 2) || (ud.multimode > 1 && ud.coop==1) )
3651 {
3652 sprite[i].xrepeat = sprite[i].yrepeat = 0;
3653 sprite[i].cstat = SLT = SHT = 0;
3654 return i;
3655 }
3656 }
3657 CS |= 257;
3658 if( sprite[i].pal && PN != ACCESSSWITCH && PN != ACCESSSWITCH2)
3659 sprite[i].pal = 0;
3660 return i;
3661 }
3662
3663 if( SHT )
3664 {
3665 changespritestat(i,12);
3666 CS |= 257;
3667 SH = impact_damage;
3668 return i;
3669 }
3670 }
3671
3672 s = PN;
3673
3674 if( CS&1 ) CS |= 256;
3675
3676 if( actorscrptr[s] )
3677 {
3678 SH = *(actorscrptr[s]);
3679 T5 = *(actorscrptr[s]+1);
3680 T2 = *(actorscrptr[s]+2);
3681 if( *(actorscrptr[s]+3) && SHT == 0 )
3682 SHT = *(actorscrptr[s]+3);
3683 }
3684 else T2 = T5 = 0;
3685 }
3686
3687 sp = &sprite[i];
3688 sect = sp->sectnum;
3689
3690 switch(sp->picnum)
3691 {
3692 default:
3693
3694 if( actorscrptr[sp->picnum] )
3695 {
3696 if( j == -1 && sp->lotag > ud.player_skill )
3697 {
3698 sp->xrepeat=sp->yrepeat=0;
3699 changespritestat(i,5);
3700 break;
3701 }
3702
3703 // Init the size
3704 if(sp->xrepeat == 0 || sp->yrepeat == 0)
3705 sp->xrepeat = sp->yrepeat = 1;
3706
3707 if( actortype[sp->picnum] & 3)
3708 {
3709 if( ud.monsters_off == 1 )
3710 {
3711 sp->xrepeat=sp->yrepeat=0;
3712 changespritestat(i,5);
3713 break;
3714 }
3715
3716 makeitfall(i);
3717
3718 if( actortype[sp->picnum] & 2)
3719 hittype[i].actorstayput = sp->sectnum;
3720
3721 ps[myconnectindex].max_actors_killed++;
3722 sp->clipdist = 80;
3723 if(j >= 0)
3724 {
3725 if(sprite[j].picnum == RESPAWN)
3726 hittype[i].tempang = sprite[i].pal = sprite[j].pal;
3727 changespritestat(i,1);
3728 }
3729 else changespritestat(i,2);
3730 }
3731 else
3732 {
3733 sp->clipdist = 40;
3734 sp->owner = i;
3735 changespritestat(i,1);
3736 }
3737
3738 hittype[i].timetosleep = 0;
3739
3740 if(j >= 0)
3741 sp->ang = sprite[j].ang;
3742 }
3743 break;
3744 case FOF:
3745 sp->xrepeat = sp->yrepeat = 0;
3746 changespritestat(i,5);
3747 break;
3748 case WATERSPLASH2:
3749 if(j >= 0)
3750 {
3751 setsprite(i,sprite[j].x,sprite[j].y,sprite[j].z);
3752 sp->xrepeat = sp->yrepeat = 8+(TRAND&7);
3753 }
3754 else sp->xrepeat = sp->yrepeat = 16+(TRAND&15);
3755
3756 sp->shade = -16;
3757 sp->cstat |= 128;
3758 if(j >= 0)
3759 {
3760 if(sector[sprite[j].sectnum].lotag == 2)
3761 {
3762 sp->z = getceilzofslope(SECT,SX,SY)+(16<<8);
3763 sp->cstat |= 8;
3764 }
3765 else if( sector[sprite[j].sectnum].lotag == 1)
3766 sp->z = getflorzofslope(SECT,SX,SY);
3767 }
3768
3769 if(sector[sect].floorpicnum == FLOORSLIME ||
3770 sector[sect].ceilingpicnum == FLOORSLIME)
3771 sp->pal = 7;
3772 case NEON1:
3773 case NEON2:
3774 case NEON3:
3775 case NEON4:
3776 case NEON5:
3777 case NEON6:
3778 case DOMELITE:
3779 if(sp->picnum != WATERSPLASH2)
3780 sp->cstat |= 257;
3781 case NUKEBUTTON:
3782 if(sp->picnum == DOMELITE)
3783 sp->cstat |= 257;
3784 case JIBS1:
3785 case JIBS2:
3786 case JIBS3:
3787 case JIBS4:
3788 case JIBS5:
3789 case JIBS6:
3790 case HEADJIB1:
3791 case ARMJIB1:
3792 case LEGJIB1:
3793 case LIZMANHEAD1:
3794 case LIZMANARM1:
3795 case LIZMANLEG1:
3796 case DUKETORSO:
3797 case DUKEGUN:
3798 case DUKELEG:
3799 changespritestat(i,5);
3800 break;
3801 case TONGUE:
3802 if(j >= 0)
3803 sp->ang = sprite[j].ang;
3804 sp->z -= 38<<8;
3805 sp->zvel = 256-(TRAND&511);
3806 sp->xvel = 64-(TRAND&127);
3807 changespritestat(i,4);
3808 break;
3809 case NATURALLIGHTNING:
3810 sp->cstat &= ~257;
3811 sp->cstat |= 32768;
3812 break;
3813 case TRANSPORTERSTAR:
3814 case TRANSPORTERBEAM:
3815 if(j == -1) break;
3816 if(sp->picnum == TRANSPORTERBEAM)
3817 {
3818 sp->xrepeat = 31;
3819 sp->yrepeat = 1;
3820 sp->z = sector[sprite[j].sectnum].floorz-(40<<8);
3821 }
3822 else
3823 {
3824 if(sprite[j].statnum == 4)
3825 {
3826 sp->xrepeat = 8;
3827 sp->yrepeat = 8;
3828 }
3829 else
3830 {
3831 sp->xrepeat = 48;
3832 sp->yrepeat = 64;
3833 if(sprite[j].statnum == 10 || badguy(&sprite[j]) )
3834 sp->z -= (32<<8);
3835 }
3836 }
3837
3838 sp->shade = -127;
3839 sp->cstat = 128|2;
3840 sp->ang = sprite[j].ang;
3841
3842 sp->xvel = 128;
3843 changespritestat(i,5);
3844 ssp(i,CLIPMASK0);
3845 setsprite(i,sp->x,sp->y,sp->z);
3846 break;
3847
3848 case FRAMEEFFECT1:
3849 case FRAMEEFFECT1_13CON:
3850 if(j >= 0)
3851 {
3852 sp->xrepeat = sprite[j].xrepeat;
3853 sp->yrepeat = sprite[j].yrepeat;
3854 T2 = sprite[j].picnum;
3855 }
3856 else sp->xrepeat = sp->yrepeat = 0;
3857
3858 changespritestat(i,5);
3859
3860 break;
3861
3862 case LASERLINE:
3863 sp->yrepeat = 6;
3864 sp->xrepeat = 32;
3865
3866 if(lasermode == 1)
3867 sp->cstat = 16 + 2;
3868 else if(lasermode == 0 || lasermode == 2)
3869 sp->cstat = 16;
3870 else
3871 {
3872 sp->xrepeat = 0;
3873 sp->yrepeat = 0;
3874 }
3875
3876 if(j >= 0) sp->ang = hittype[j].temp_data[5]+512;
3877 changespritestat(i,5);
3878 break;
3879
3880 case FORCESPHERE:
3881 if(j == -1 )
3882 {
3883 sp->cstat = (short) 32768;
3884 changespritestat(i,2);
3885 }
3886 else
3887 {
3888 sp->xrepeat = sp->yrepeat = 1;
3889 changespritestat(i,5);
3890 }
3891 break;
3892
3893 case BLOOD:
3894 sp->xrepeat = sp->yrepeat = 16;
3895 sp->z -= (26<<8);
3896 if( j >= 0 && sprite[j].pal == 6 )
3897 sp->pal = 6;
3898 changespritestat(i,5);
3899 break;
3900 case BLOODPOOL:
3901 case PUKE:
3902 {
3903 short s1;
3904 s1 = sp->sectnum;
3905
3906 updatesector(sp->x+108,sp->y+108,&s1);
3907 if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz)
3908 {
3909 updatesector(sp->x-108,sp->y-108,&s1);
3910 if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz)
3911 {
3912 updatesector(sp->x+108,sp->y-108,&s1);
3913 if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz)
3914 {
3915 updatesector(sp->x-108,sp->y+108,&s1);
3916 if(s1 >= 0 && sector[s1].floorz != sector[sp->sectnum].floorz)
3917 { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;}
3918 }
3919 else { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;}
3920 }
3921 else { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;}
3922 }
3923 else { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;}
3924 }
3925
3926 if( sector[SECT].lotag == 1 )
3927 {
3928 changespritestat(i,5);
3929 break;
3930 }
3931
3932 if(j >= 0 && sp->picnum != PUKE)
3933 {
3934 if( sprite[j].pal == 1)
3935 sp->pal = 1;
3936 else if( sprite[j].pal != 6 && sprite[j].picnum != NUKEBARREL && sprite[j].picnum != TIRE )
3937 {
3938 if(sprite[j].picnum == FECES)
3939 sp->pal = 7; // Brown
3940 else sp->pal = 2; // Red
3941 }
3942 else sp->pal = 0; // green
3943
3944 if(sprite[j].picnum == TIRE)
3945 sp->shade = 127;
3946 }
3947 sp->cstat |= 32;
3948 case FECES:
3949 if( j >= 0)
3950 sp->xrepeat = sp->yrepeat = 1;
3951 changespritestat(i,5);
3952 break;
3953
3954 case BLOODSPLAT1:
3955 case BLOODSPLAT2:
3956 case BLOODSPLAT3:
3957 case BLOODSPLAT4:
3958 sp->cstat |= 16;
3959 sp->xrepeat = 7+(TRAND&7);
3960 sp->yrepeat = 7+(TRAND&7);
3961 sp->z -= (16<<8);
3962 if(j >= 0 && sprite[j].pal == 6)
3963 sp->pal = 6;
3964 insertspriteq(i);
3965 changespritestat(i,5);
3966 break;
3967
3968 case TRIPBOMB:
3969 if( sp->lotag > ud.player_skill )
3970 {
3971 sp->xrepeat=sp->yrepeat=0;
3972 changespritestat(i,5);
3973 break;
3974 }
3975
3976 sp->xrepeat=4;
3977 sp->yrepeat=5;
3978
3979 sp->owner = i;
3980 sp->hitag = i;
3981
3982 sp->xvel = 16;
3983 ssp(i,CLIPMASK0);
3984 hittype[i].temp_data[0] = 17;
3985 hittype[i].temp_data[2] = 0;
3986 hittype[i].temp_data[5] = sp->ang;
3987
3988 case SPACEMARINE:
3989 if(sp->picnum == SPACEMARINE)
3990 {
3991 sp->extra = 20;
3992 sp->cstat |= 257;
3993 }
3994 changespritestat(i,2);
3995 break;
3996
3997 case HYDRENT:
3998 case PANNEL1:
3999 case PANNEL2:
4000 case SATELITE:
4001 case FUELPOD:
4002 case SOLARPANNEL:
4003 case ANTENNA:
4004 case GRATE1:
4005 case CHAIR1:
4006 case CHAIR2:
4007 case CHAIR3:
4008 case BOTTLE1:
4009 case BOTTLE2:
4010 case BOTTLE3:
4011 case BOTTLE4:
4012 case BOTTLE5:
4013 case BOTTLE6:
4014 case BOTTLE7:
4015 case BOTTLE8:
4016 case BOTTLE10:
4017 case BOTTLE11:
4018 case BOTTLE12:
4019 case BOTTLE13:
4020 case BOTTLE14:
4021 case BOTTLE15:
4022 case BOTTLE16:
4023 case BOTTLE17:
4024 case BOTTLE18:
4025 case BOTTLE19:
4026 case OCEANSPRITE1:
4027 case OCEANSPRITE2:
4028 case OCEANSPRITE3:
4029 case OCEANSPRITE5:
4030 case MONK:
4031 case INDY:
4032 case LUKE:
4033 case JURYGUY:
4034 case SCALE:
4035 case VACUUM:
4036 case FANSPRITE:
4037 case CACTUS:
4038 case CACTUSBROKE:
4039 case HANGLIGHT:
4040 case FETUS:
4041 case FETUSBROKE:
4042 case CAMERALIGHT:
4043 case MOVIECAMERA:
4044 case IVUNIT:
4045 case POT1:
4046 case POT2:
4047 case POT3:
4048 case TRIPODCAMERA:
4049 case SUSHIPLATE1:
4050 case SUSHIPLATE2:
4051 case SUSHIPLATE3:
4052 case SUSHIPLATE4:
4053 case SUSHIPLATE5:
4054 case WAITTOBESEATED:
4055 case VASE:
4056 case PIPE1:
4057 case PIPE2:
4058 case PIPE3:
4059 case PIPE4:
4060 case PIPE5:
4061 case PIPE6:
4062 sp->clipdist = 32;
4063 sp->cstat |= 257;
4064 case OCEANSPRITE4:
4065 changespritestat(i,0);
4066 break;
4067 case FEMMAG1:
4068 case FEMMAG2:
4069 sp->cstat &= ~257;
4070 changespritestat(i,0);
4071 break;
4072 case DUKETAG:
4073 case SIGN1:
4074 case SIGN2:
4075 if(ud.multimode < 2 && sp->pal)
4076 {
4077 sp->xrepeat = sp->yrepeat = 0;
4078 changespritestat(i,5);
4079 }
4080 else sp->pal = 0;
4081 break;
4082 case MASKWALL1:
4083 case MASKWALL2:
4084 case MASKWALL3:
4085 case MASKWALL4:
4086 case MASKWALL5:
4087 case MASKWALL6:
4088 case MASKWALL7:
4089 case MASKWALL8:
4090 case MASKWALL9:
4091 case MASKWALL10:
4092 case MASKWALL11:
4093 case MASKWALL12:
4094 case MASKWALL13:
4095 case MASKWALL14:
4096 case MASKWALL15:
4097 j = sp->cstat&60;
4098 sp->cstat = j|1;
4099 changespritestat(i,0);
4100 break;
4101 case FOOTPRINTS:
4102 case FOOTPRINTS2:
4103 case FOOTPRINTS3:
4104 case FOOTPRINTS4:
4105 if(j >= 0)
4106 {
4107 short s1;
4108 s1 = sp->sectnum;
4109
4110 updatesector(sp->x+84,sp->y+84,&s1);
4111 if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz)
4112 {
4113 updatesector(sp->x-84,sp->y-84,&s1);
4114 if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz)
4115 {
4116 updatesector(sp->x+84,sp->y-84,&s1);
4117 if(s1 >= 0 && sector[s1].floorz == sector[sp->sectnum].floorz)
4118 {
4119 updatesector(sp->x-84,sp->y+84,&s1);
4120 if(s1 >= 0 && sector[s1].floorz != sector[sp->sectnum].floorz)
4121 { sp->xrepeat = sp->yrepeat = 0;changespritestat(i,5);break;}
4122 }
4123 else { sp->xrepeat = sp->yrepeat = 0;break;}
4124 }
4125 else { sp->xrepeat = sp->yrepeat = 0;break;}
4126 }
4127 else { sp->xrepeat = sp->yrepeat = 0;break;}
4128
4129 sp->cstat = 32+((ps[sprite[j].yvel].footprintcount&1)<<2);
4130 sp->ang = sprite[j].ang;
4131 }
4132
4133 sp->z = sector[sect].floorz;
4134 if(sector[sect].lotag != 1 && sector[sect].lotag != 2)
4135 sp->xrepeat = sp->yrepeat = 32;
4136
4137 insertspriteq(i);
4138 changespritestat(i,5);
4139 break;
4140
4141 case FEM1:
4142 case FEM2:
4143 case FEM3:
4144 case FEM4:
4145 case FEM5:
4146 case FEM6:
4147 case FEM7:
4148 case FEM8:
4149 case FEM9:
4150 case FEM10:
4151 case PODFEM1:
4152 case NAKED1:
4153 case STATUE:
4154 case TOUGHGAL:
4155 sp->yvel = sp->hitag;
4156 sp->hitag = -1;
4157 if(sp->picnum == PODFEM1) sp->extra <<= 1;
4158 case BLOODYPOLE:
4159
4160 case QUEBALL:
4161 case STRIPEBALL:
4162
4163 if(sp->picnum == QUEBALL || sp->picnum == STRIPEBALL)
4164 {
4165 sp->cstat = 256;
4166 sp->clipdist = 8;
4167 }
4168 else
4169 {
4170 sp->cstat |= 257;
4171 sp->clipdist = 32;
4172 }
4173
4174 changespritestat(i,2);
4175 break;
4176
4177 case DUKELYINGDEAD:
4178 if(j >= 0 && sprite[j].picnum == APLAYER)
4179 {
4180 sp->xrepeat = sprite[j].xrepeat;
4181 sp->yrepeat = sprite[j].yrepeat;
4182 sp->shade = sprite[j].shade;
4183 sp->pal = ps[sprite[j].yvel].palookup;
4184 }
4185 case DUKECAR:
4186 case HELECOPT:
4187// if(sp->picnum == HELECOPT || sp->picnum == DUKECAR) sp->xvel = 1024;
4188 sp->cstat = 0;
4189 sp->extra = 1;
4190 sp->xvel = 292;
4191 sp->zvel = 360;
4192 case RESPAWNMARKERRED:
4193 case BLIMP:
4194
4195 if(sp->picnum == RESPAWNMARKERRED)
4196 {
4197 sp->xrepeat = sp->yrepeat = 24;
4198 if(j >= 0) sp->z = hittype[j].floorz; // -(1<<4);
4199 }
4200 else
4201 {
4202 sp->cstat |= 257;
4203 sp->clipdist = 128;
4204 }
4205 case MIKE:
4206 if(sp->picnum == MIKE)
4207 sp->yvel = sp->hitag;
4208 case WEATHERWARN:
4209 changespritestat(i,1);
4210 break;
4211
4212 case SPOTLITE:
4213 T1 = sp->x;
4214 T2 = sp->y;
4215 break;
4216 case BULLETHOLE:
4217 sp->xrepeat = sp->yrepeat = 3;
4218 sp->cstat = 16+(TRAND&12);
4219 insertspriteq(i);
4220 case MONEY:
4221 case MAIL:
4222 case PAPER:
4223 if( sp->picnum == MONEY || sp->picnum == MAIL || sp->picnum == PAPER )
4224 {
4225 hittype[i].temp_data[0] = TRAND&2047;
4226 sp->cstat = TRAND&12;
4227 sp->xrepeat = sp->yrepeat = 8;
4228 sp->ang = TRAND&2047;
4229 }
4230 changespritestat(i,5);
4231 break;
4232
4233 case VIEWSCREEN:
4234 case VIEWSCREEN2:
4235 sp->owner = i;
4236 sp->lotag = 1;
4237 sp->extra = 1;
4238 changespritestat(i,6);
4239 break;
4240
4241 case SHELL: //From the player
4242 case SHOTGUNSHELL:
4243 if( j >= 0 )
4244 {
4245 short snum,a;
4246
4247 if(sprite[j].picnum == APLAYER)
4248 {
4249 snum = sprite[j].yvel;
4250 a = ps[snum].ang-(TRAND&63)+8; //Fine tune
4251
4252 T1 = TRAND&1;
4253 if(sp->picnum == SHOTGUNSHELL)
4254 sp->z = (6<<8)+ps[snum].pyoff+ps[snum].posz-((ps[snum].horizoff+ps[snum].horiz-100)<<4);
4255 else sp->z = (3<<8)+ps[snum].pyoff+ps[snum].posz-((ps[snum].horizoff+ps[snum].horiz-100)<<4);
4256 sp->zvel = -(TRAND&255);
4257 }
4258 else
4259 {
4260 a = sp->ang;
4261 sp->z = sprite[j].z-PHEIGHT+(3<<8);
4262 }
4263
4264 sp->x = sprite[j].x+(sintable[(a+512)&2047]>>7);
4265 sp->y = sprite[j].y+(sintable[a&2047]>>7);
4266
4267 sp->shade = -8;
4268
4269 sp->ang = a-512;
4270 sp->xvel = 20;
4271
4272 // do not try to make it 0 when ud.hideweapon Will make OOS when shooting in water
4273 sp->xrepeat=sp->yrepeat=4;
4274
4275 changespritestat(i,5);
4276 }
4277 break;
4278
4279 case RESPAWN:
4280 sp->extra = 66-13;
4281 case MUSICANDSFX:
4282 if( ud.multimode < 2 && sp->pal == 1)
4283 {
4284 sp->xrepeat = sp->yrepeat = 0;
4285 changespritestat(i,5);
4286 break;
4287 }
4288 sp->cstat = (short)32768;
4289 changespritestat(i,11);
4290 break;
4291
4292 case EXPLOSION2:
4293 case EXPLOSION2BOT:
4294 case BURNING:
4295 case BURNING2:
4296 case SMALLSMOKE:
4297 case SHRINKEREXPLOSION:
4298 case COOLEXPLOSION1:
4299
4300 if(j >= 0)
4301 {
4302 sp->ang = sprite[j].ang;
4303 sp->shade = -64;
4304 sp->cstat = 128|(TRAND&4);
4305 }
4306
4307 if(sp->picnum == EXPLOSION2 || sp->picnum == EXPLOSION2BOT)
4308 {
4309 sp->xrepeat = 48;
4310 sp->yrepeat = 48;
4311 sp->shade = -127;
4312 sp->cstat |= 128;
4313 }
4314 else if(sp->picnum == SHRINKEREXPLOSION )
4315 {
4316 sp->xrepeat = 32;
4317 sp->yrepeat = 32;
4318 }
4319 else if( sp->picnum == SMALLSMOKE )
4320 {
4321 // 64 "money"
4322 sp->xrepeat = 24;
4323 sp->yrepeat = 24;
4324 }
4325 else if(sp->picnum == BURNING || sp->picnum == BURNING2)
4326 {
4327 sp->xrepeat = 4;
4328 sp->yrepeat = 4;
4329 }
4330
4331 if(j >= 0)
4332 {
4333 x = getflorzofslope(sp->sectnum,sp->x,sp->y);
4334 if(sp->z > x-(12<<8) )
4335 sp->z = x-(12<<8);
4336 }
4337
4338 changespritestat(i,5);
4339
4340 break;
4341
4342 case PLAYERONWATER:
4343 if(j >= 0)
4344 {
4345 sp->xrepeat = sprite[j].xrepeat;
4346 sp->yrepeat = sprite[j].yrepeat;
4347 sp->zvel = 128;
4348 if(sector[sp->sectnum].lotag != 2)
4349 sp->cstat |= 32768;
4350 }
4351 changespritestat(i,13);
4352 break;
4353
4354 case APLAYER:
4355 sp->xrepeat = sp->yrepeat = 0;
4356 j = ud.coop;
4357 if(j == 2) j = 0;
4358
4359 if( ud.multimode < 2 || (ud.multimode > 1 && j != sp->lotag) )
4360 changespritestat(i,5);
4361 else
4362 changespritestat(i,10);
4363 break;
4364 case WATERBUBBLE:
4365 if(j >= 0 && sprite[j].picnum == APLAYER)
4366 sp->z -= (16<<8);
4367 if( sp->picnum == WATERBUBBLE)
4368 {
4369 if( j >= 0 )
4370 sp->ang = sprite[j].ang;
4371 sp->xrepeat = sp->yrepeat = 4;
4372 }
4373 else sp->xrepeat = sp->yrepeat = 32;
4374
4375 changespritestat(i,5);
4376 break;
4377
4378 case CRANE:
4379
4380 sp->cstat |= 64|257;
4381
4382 sp->picnum += 2;
4383 sp->z = sector[sect].ceilingz+(48<<8);
4384 T5 = tempwallptr;
4385
4386 msx[tempwallptr] = sp->x;
4387 msy[tempwallptr] = sp->y;
4388 msx[tempwallptr+2] = sp->z;
4389
4390 s = headspritestat[0];
4391 while(s >= 0)
4392 {
4393 if( sprite[s].picnum == CRANEPOLE && SHT == (sprite[s].hitag) )
4394 {
4395 msy[tempwallptr+2] = s;
4396
4397 T2 = sprite[s].sectnum;
4398
4399 sprite[s].xrepeat = 48;
4400 sprite[s].yrepeat = 128;
4401
4402 msx[tempwallptr+1] = sprite[s].x;
4403 msy[tempwallptr+1] = sprite[s].y;
4404
4405 sprite[s].x = sp->x;
4406 sprite[s].y = sp->y;
4407 sprite[s].z = sp->z;
4408 sprite[s].shade = sp->shade;
4409
4410 setsprite(s,sprite[s].x,sprite[s].y,sprite[s].z);
4411 break;
4412 }
4413 s = nextspritestat[s];
4414 }
4415
4416 tempwallptr += 3;
4417 sp->owner = -1;
4418 sp->extra = 8;
4419 changespritestat(i,6);
4420 break;
4421
4422 case WATERDRIP:
4423 if((j >= 0 && sprite[j].statnum == 10) || sprite[j].statnum == 1)
4424 {
4425 sp->shade = 32;
4426 if(sprite[j].pal != 1)
4427 {
4428 sp->pal = 2;
4429 sp->z -= (18<<8);
4430 }
4431 else sp->z -= (13<<8);
4432 sp->ang = getangle(ps[connecthead].posx-sp->x,ps[connecthead].posy-sp->y);
4433 sp->xvel = 48-(TRAND&31);
4434 ssp(i,CLIPMASK0);
4435 }
4436 else if(j == -1)
4437 {
4438 sp->z += (4<<8);
4439 T1 = sp->z;
4440 T2 = TRAND&127;
4441 }
4442 case TRASH:
4443
4444 if(sp->picnum != WATERDRIP)
4445 sp->ang = TRAND&2047;
4446
4447 case WATERDRIPSPLASH:
4448
4449 sp->xrepeat = 24;
4450 sp->yrepeat = 24;
4451
4452
4453 changespritestat(i,6);
4454 break;
4455
4456 case PLUG:
4457 sp->lotag = 9999;
4458 changespritestat(i,6);
4459 break;
4460 case TOUCHPLATE:
4461 T3 = sector[sect].floorz;
4462 if(sector[sect].lotag != 1 && sector[sect].lotag != 2)
4463 sector[sect].floorz = sp->z;
4464 if(sp->pal && ud.multimode > 1)
4465 {
4466 sp->xrepeat=sp->yrepeat=0;
4467 changespritestat(i,5);
4468 break;
4469 }
4470 case WATERBUBBLEMAKER:
4471 sp->cstat |= 32768;
4472 changespritestat(i,6);
4473 break;
4474 case BOLT1:
4475 case BOLT1+1:
4476 case BOLT1+2:
4477 case BOLT1+3:
4478 case SIDEBOLT1:
4479 case SIDEBOLT1+1:
4480 case SIDEBOLT1+2:
4481 case SIDEBOLT1+3:
4482 T1 = sp->xrepeat;
4483 T2 = sp->yrepeat;
4484 case MASTERSWITCH:
4485 if(sp->picnum == MASTERSWITCH)
4486 sp->cstat |= 32768;
4487 sp->yvel = 0;
4488 changespritestat(i,6);
4489 break;
4490 case TARGET:
4491 case DUCK:
4492 case LETTER:
4493 sp->extra = 1;
4494 sp->cstat |= 257;
4495 changespritestat(i,1);
4496 break;
4497 case OCTABRAINSTAYPUT:
4498 case LIZTROOPSTAYPUT:
4499 case PIGCOPSTAYPUT:
4500 case LIZMANSTAYPUT:
4501 case BOSS1STAYPUT:
4502 case PIGCOPDIVE:
4503 case COMMANDERSTAYPUT:
4504 case BOSS4STAYPUT:
4505 hittype[i].actorstayput = sp->sectnum;
4506 case BOSS1:
4507 case BOSS2:
4508 case BOSS3:
4509 case BOSS4:
4510 case ROTATEGUN:
4511 case GREENSLIME:
4512 if(sp->picnum == GREENSLIME)
4513 sp->extra = 1;
4514 case DRONE:
4515 case LIZTROOPONTOILET:
4516 case LIZTROOPJUSTSIT:
4517 case LIZTROOPSHOOT:
4518 case LIZTROOPJETPACK:
4519 case LIZTROOPDUCKING:
4520 case LIZTROOPRUNNING:
4521 case LIZTROOP:
4522 case OCTABRAIN:
4523 case COMMANDER:
4524 case PIGCOP:
4525 case LIZMAN:
4526 case LIZMANSPITTING:
4527 case LIZMANFEEDING:
4528 case LIZMANJUMP:
4529 case ORGANTIC:
4530 case RAT:
4531 case SHARK:
4532
4533 if(sp->pal == 0)
4534 {
4535 switch(sp->picnum)
4536 {
4537 case LIZTROOPONTOILET:
4538 case LIZTROOPSHOOT:
4539 case LIZTROOPJETPACK:
4540 case LIZTROOPDUCKING:
4541 case LIZTROOPRUNNING:
4542 case LIZTROOPSTAYPUT:
4543 case LIZTROOPJUSTSIT:
4544 case LIZTROOP:
4545 sp->pal = 22;
4546 break;
4547 }
4548 }
4549
4550 if( sp->picnum == BOSS4STAYPUT || sp->picnum == BOSS1 || sp->picnum == BOSS2 || sp->picnum == BOSS1STAYPUT || sp->picnum == BOSS3 || sp->picnum == BOSS4 )
4551 {
4552 if(j >= 0 && sprite[j].picnum == RESPAWN)
4553 sp->pal = sprite[j].pal;
4554 if(sp->pal)
4555 {
4556 sp->clipdist = 80;
4557 sp->xrepeat = 40;
4558 sp->yrepeat = 40;
4559 }
4560 else
4561 {
4562 sp->xrepeat = 80;
4563 sp->yrepeat = 80;
4564 sp->clipdist = 164;
4565 }
4566 }
4567 else
4568 {
4569 if(sp->picnum != SHARK)
4570 {
4571 sp->xrepeat = 40;
4572 sp->yrepeat = 40;
4573 sp->clipdist = 80;
4574 }
4575 else
4576 {
4577 sp->xrepeat = 60;
4578 sp->yrepeat = 60;
4579 sp->clipdist = 40;
4580 }
4581 }
4582
4583 if(j >= 0) sp->lotag = 0;
4584
4585 if( ( sp->lotag > ud.player_skill ) || ud.monsters_off == 1 )
4586 {
4587 sp->xrepeat=sp->yrepeat=0;
4588 changespritestat(i,5);
4589 break;
4590 }
4591 else
4592 {
4593 makeitfall(i);
4594
4595 if(sp->picnum == RAT)
4596 {
4597 sp->ang = TRAND&2047;
4598 sp->xrepeat = sp->yrepeat = 48;
4599 sp->cstat = 0;
4600 }
4601 else
4602 {
4603 sp->cstat |= 257;
4604
4605 if(sp->picnum != SHARK)
4606 ps[myconnectindex].max_actors_killed++;
4607 }
4608
4609 if(sp->picnum == ORGANTIC) sp->cstat |= 128;
4610
4611 if(j >= 0)
4612 {
4613 hittype[i].timetosleep = 0;
4614 check_fta_sounds(i);
4615 changespritestat(i,1);
4616 }
4617 else changespritestat(i,2);
4618 }
4619
4620 if(sp->picnum == ROTATEGUN)
4621 sp->zvel = 0;
4622
4623 break;
4624
4625 case LOCATORS:
4626 sp->cstat |= 32768;
4627 changespritestat(i,7);
4628 break;
4629
4630 case ACTIVATORLOCKED:
4631 case ACTIVATOR:
4632 sp->cstat = (short) 32768;
4633 if(sp->picnum == ACTIVATORLOCKED)
4634 sector[sp->sectnum].lotag |= 16384;
4635 changespritestat(i,8);
4636 break;
4637
4638 case DOORSHOCK:
4639 sp->cstat |= 1+256;
4640 sp->shade = -12;
4641 changespritestat(i,6);
4642 break;
4643
4644 case OOZ:
4645 case OOZ2:
4646 sp->shade = -12;
4647
4648 if(j >= 0)
4649 {
4650 if( sprite[j].picnum == NUKEBARREL )
4651 sp->pal = 8;
4652 insertspriteq(i);
4653 }
4654
4655 changespritestat(i,1);
4656
4657 getglobalz(i);
4658
4659 j = (hittype[i].floorz-hittype[i].ceilingz)>>9;
4660
4661 sp->yrepeat = j;
4662 sp->xrepeat = 25-(j>>1);
4663 sp->cstat |= (TRAND&4);
4664
4665 break;
4666
4667 case HEAVYHBOMB:
4668 if(j >= 0)
4669 sp->owner = j;
4670 else sp->owner = i;
4671 sp->xrepeat = sp->yrepeat = 9;
4672 sp->yvel = 4;
4673 case REACTOR2:
4674 case REACTOR:
4675 case RECON:
4676
4677 if(sp->picnum == RECON)
4678 {
4679 if( sp->lotag > ud.player_skill )
4680 {
4681 sp->xrepeat = sp->yrepeat = 0;
4682 changespritestat(i,5);
4683 return i;
4684 }
4685 ps[myconnectindex].max_actors_killed++;
4686 hittype[i].temp_data[5] = 0;
4687 if(ud.monsters_off == 1)
4688 {
4689 sp->xrepeat = sp->yrepeat = 0;
4690 changespritestat(i,5);
4691 break;
4692 }
4693 sp->extra = 130;
4694 }
4695
4696 if(sp->picnum == REACTOR || sp->picnum == REACTOR2)
4697 sp->extra = impact_damage;
4698
4699 CS |= 257; // Make it hitable
4700
4701 if( ud.multimode < 2 && sp->pal != 0)
4702 {
4703 sp->xrepeat = sp->yrepeat = 0;
4704 changespritestat(i,5);
4705 break;
4706 }
4707 sp->pal = 0;
4708 SS = -17;
4709
4710 changespritestat(i,2);
4711 break;
4712
4713 case ATOMICHEALTH:
4714 case STEROIDS:
4715 case HEATSENSOR:
4716 case SHIELD:
4717 case AIRTANK:
4718 case TRIPBOMBSPRITE:
4719 case JETPACK:
4720 case HOLODUKE:
4721
4722 case FIRSTGUNSPRITE:
4723 case CHAINGUNSPRITE:
4724 case SHOTGUNSPRITE:
4725 case RPGSPRITE:
4726 case SHRINKERSPRITE:
4727 case FREEZESPRITE:
4728 case DEVISTATORSPRITE:
4729
4730 case SHOTGUNAMMO:
4731 case FREEZEAMMO:
4732 case HBOMBAMMO:
4733 case CRYSTALAMMO:
4734 case GROWAMMO:
4735 case BATTERYAMMO:
4736 case DEVISTATORAMMO:
4737 case RPGAMMO:
4738 case BOOTS:
4739 case AMMO:
4740 case AMMOLOTS:
4741 case COLA:
4742 case FIRSTAID:
4743 case SIXPAK:
4744 if(j >= 0)
4745 {
4746 sp->lotag = 0;
4747 sp->z -= (32<<8);
4748 sp->zvel = -1024;
4749 ssp(i,CLIPMASK0);
4750 sp->cstat = TRAND&4;
4751 }
4752 else
4753 {
4754 sp->owner = i;
4755 sp->cstat = 0;
4756 }
4757
4758 if( ( ud.multimode < 2 && sp->pal != 0) || (sp->lotag > ud.player_skill) )
4759 {
4760 sp->xrepeat = sp->yrepeat = 0;
4761 changespritestat(i,5);
4762 break;
4763 }
4764
4765 sp->pal = 0;
4766
4767 case ACCESSCARD:
4768
4769 if(sp->picnum == ATOMICHEALTH)
4770 sp->cstat |= 128;
4771
4772 if(ud.multimode > 1 && ud.coop != 1 && sp->picnum == ACCESSCARD)
4773 {
4774 sp->xrepeat = sp->yrepeat = 0;
4775 changespritestat(i,5);
4776 break;
4777 }
4778 else
4779 {
4780 if(sp->picnum == AMMO)
4781 sp->xrepeat = sp->yrepeat = 16;
4782 else sp->xrepeat = sp->yrepeat = 32;
4783 }
4784
4785 sp->shade = -17;
4786
4787 if(j >= 0) changespritestat(i,1);
4788 else
4789 {
4790 changespritestat(i,2);
4791 makeitfall(i);
4792 }
4793 break;
4794
4795 case WATERFOUNTAIN:
4796 SLT = 1;
4797
4798 case TREE1:
4799 case TREE2:
4800 case TIRE:
4801 case CONE:
4802 case BOX:
4803 CS = 257; // Make it hitable
4804 sprite[i].extra = 1;
4805 changespritestat(i,6);
4806 break;
4807
4808 case FLOORFLAME:
4809 sp->shade = -127;
4810 changespritestat(i,6);
4811 break;
4812
4813 case BOUNCEMINE:
4814 sp->owner = i;
4815 sp->cstat |= 1+256; //Make it hitable
4816 sp->xrepeat = sp->yrepeat = 24;
4817 sp->shade = -127;
4818 sp->extra = impact_damage<<2;
4819 changespritestat(i,2);
4820 break;
4821
4822 case CAMERA1:
4823 case CAMERA1+1:
4824 case CAMERA1+2:
4825 case CAMERA1+3:
4826 case CAMERA1+4:
4827 case CAMERAPOLE:
4828 sp->extra = 1;
4829
4830 if(camerashitable) sp->cstat = 257;
4831 else sp->cstat = 0;
4832
4833 case GENERICPOLE:
4834
4835 if( ud.multimode < 2 && sp->pal != 0 )
4836 {
4837 sp->xrepeat = sp->yrepeat = 0;
4838 changespritestat(i,5);
4839 break;
4840 }
4841 else sp->pal = 0;
4842 if(sp->picnum == CAMERAPOLE || sp->picnum == GENERICPOLE) break;
4843 sp->picnum = CAMERA1;
4844 changespritestat(i,1);
4845 break;
4846 case STEAM:
4847 if(j >= 0)
4848 {
4849 sp->ang = sprite[j].ang;
4850 sp->cstat = 16+128+2;
4851 sp->xrepeat=sp->yrepeat=1;
4852 sp->xvel = -8;
4853 ssp(i,CLIPMASK0);
4854 }
4855 case CEILINGSTEAM:
4856 changespritestat(i,6);
4857 break;
4858
4859 case SECTOREFFECTOR:
4860 sp->yvel = sector[sect].extra;
4861 sp->cstat |= 32768;
4862 sp->xrepeat = sp->yrepeat = 0;
4863
4864 switch(sp->lotag)
4865 {
4866 case 28:
4867 T6 = 65;// Delay for lightning
4868 break;
4869 case 7: // Transporters!!!!
4870 case 23:// XPTR END
4871 if(sp->lotag != 23)
4872 {
4873 for(j=0;j<MAXSPRITES;j++)
4874 if(sprite[j].statnum < MAXSTATUS && sprite[j].picnum == SECTOREFFECTOR && ( sprite[j].lotag == 7 || sprite[j].lotag == 23 ) && i != j && sprite[j].hitag == SHT)
4875 {
4876 OW = j;
4877 break;
4878 }
4879 }
4880 else OW = i;
4881
4882 T5 = sector[sect].floorz == SZ;
4883 sp->cstat = 0;
4884 changespritestat(i,9);
4885 return i;
4886 case 1:
4887 sp->owner = -1;
4888 T1 = 1;
4889 break;
4890 case 18:
4891
4892 if(sp->ang == 512)
4893 {
4894 T2 = sector[sect].ceilingz;
4895 if(sp->pal)
4896 sector[sect].ceilingz = sp->z;
4897 }
4898 else
4899 {
4900 T2 = sector[sect].floorz;
4901 if(sp->pal)
4902 sector[sect].floorz = sp->z;
4903 }
4904
4905 sp->hitag <<= 2;
4906 break;
4907
4908 case 19:
4909 sp->owner = -1;
4910 break;
4911 case 25: // Pistons
4912 T4 = sector[sect].ceilingz;
4913 T5 = 1;
4914 sector[sect].ceilingz = sp->z;
4915 setinterpolation(&sector[sect].ceilingz);
4916 break;
4917 case 35:
4918 sector[sect].ceilingz = sp->z;
4919 break;
4920 case 27:
4921 if(ud.recstat == 1)
4922 {
4923 sp->xrepeat=sp->yrepeat=64;
4924 sp->cstat &= 32767;
4925 }
4926 break;
4927 case 12:
4928
4929 T2 = sector[sect].floorshade;
4930 T3 = sector[sect].ceilingshade;
4931 break;
4932
4933 case 13:
4934
4935 T1 = sector[sect].ceilingz;
4936 T2 = sector[sect].floorz;
4937
4938 if( klabs(T1-sp->z) < klabs(T2-sp->z) )
4939 sp->owner = 1;
4940 else sp->owner = 0;
4941
4942 if(sp->ang == 512)
4943 {
4944 if(sp->owner)
4945 sector[sect].ceilingz = sp->z;
4946 else
4947 sector[sect].floorz = sp->z;
4948 }
4949 else
4950 sector[sect].ceilingz = sector[sect].floorz = sp->z;
4951
4952 if( sector[sect].ceilingstat&1 )
4953 {
4954 sector[sect].ceilingstat ^= 1;
4955 T4 = 1;
4956
4957 if(!sp->owner && sp->ang==512)
4958 {
4959 sector[sect].ceilingstat ^= 1;
4960 T4 = 0;
4961 }
4962
4963 sector[sect].ceilingshade =
4964 sector[sect].floorshade;
4965
4966 if(sp->ang==512)
4967 {
4968 startwall = sector[sect].wallptr;
4969 endwall = startwall+sector[sect].wallnum;
4970 for(j=startwall;j<endwall;j++)
4971 {
4972 x = wall[j].nextsector;
4973 if(x >= 0)
4974 if( !(sector[x].ceilingstat&1) )
4975 {
4976 sector[sect].ceilingpicnum =
4977 sector[x].ceilingpicnum;
4978 sector[sect].ceilingshade =
4979 sector[x].ceilingshade;
4980 break; //Leave earily
4981 }
4982 }
4983 }
4984 }
4985
4986 break;
4987
4988 case 17:
4989
4990 T3 = sector[sect].floorz; //Stopping loc
4991
4992 j = nextsectorneighborz(sect,sector[sect].floorz,-1,-1);
4993 T4 = sector[j].ceilingz;
4994
4995 j = nextsectorneighborz(sect,sector[sect].ceilingz,1,1);
4996 T5 = sector[j].floorz;
4997
4998 if(numplayers < 2)
4999 {
5000 setinterpolation(&sector[sect].floorz);
5001 setinterpolation(&sector[sect].ceilingz);
5002 }
5003
5004 break;
5005
5006 case 24:
5007 sp->yvel <<= 1;
5008 case 36:
5009 break;
5010
5011 case 20:
5012 {
5013 int32_t q;
5014
5015 startwall = sector[sect].wallptr;
5016 endwall = startwall+sector[sect].wallnum;
5017
5018 //find the two most clostest wall x's and y's
5019 q = 0x7fffffff;
5020
5021 for(s=startwall;s<endwall;s++)
5022 {
5023 x = wall[s].x;
5024 y = wall[s].y;
5025
5026 d = FindDistance2D(sp->x-x,sp->y-y);
5027 if( d < q )
5028 {
5029 q = d;
5030 clostest = s;
5031 }
5032 }
5033
5034 T2 = clostest;
5035
5036 q = 0x7fffffff;
5037
5038 for(s=startwall;s<endwall;s++)
5039 {
5040 x = wall[s].x;
5041 y = wall[s].y;
5042
5043 d = FindDistance2D(sp->x-x,sp->y-y);
5044 if(d < q && s != T2)
5045 {
5046 q = d;
5047 clostest = s;
5048 }
5049 }
5050
5051 T3 = clostest;
5052 }
5053
5054 break;
5055
5056 case 3:
5057
5058 T4=sector[sect].floorshade;
5059
5060 sector[sect].floorshade = sp->shade;
5061 sector[sect].ceilingshade = sp->shade;
5062
5063 sp->owner = sector[sect].ceilingpal<<8;
5064 sp->owner |= sector[sect].floorpal;
5065
5066 //fix all the walls;
5067
5068 startwall = sector[sect].wallptr;
5069 endwall = startwall+sector[sect].wallnum;
5070
5071 for(s=startwall;s<endwall;s++)
5072 {
5073 if(!(wall[s].hitag&1))
5074 wall[s].shade=sp->shade;
5075 if( (wall[s].cstat&2) && wall[s].nextwall >= 0)
5076 wall[wall[s].nextwall].shade = sp->shade;
5077 }
5078 break;
5079
5080 case 31:
5081 T2 = sector[sect].floorz;
5082 // T3 = sp->hitag;
5083 if(sp->ang != 1536) sector[sect].floorz = sp->z;
5084
5085 startwall = sector[sect].wallptr;
5086 endwall = startwall+sector[sect].wallnum;
5087
5088 for(s=startwall;s<endwall;s++)
5089 if(wall[s].hitag == 0) wall[s].hitag = 9999;
5090
5091 setinterpolation(&sector[sect].floorz);
5092
5093 break;
5094 case 32:
5095 T2 = sector[sect].ceilingz;
5096 T3 = sp->hitag;
5097 if(sp->ang != 1536) sector[sect].ceilingz = sp->z;
5098
5099 startwall = sector[sect].wallptr;
5100 endwall = startwall+sector[sect].wallnum;
5101
5102 for(s=startwall;s<endwall;s++)
5103 if(wall[s].hitag == 0) wall[s].hitag = 9999;
5104
5105 setinterpolation(&sector[sect].ceilingz);
5106
5107 break;
5108
5109 case 4: //Flashing lights
5110
5111 T3 = sector[sect].floorshade;
5112
5113 startwall = sector[sect].wallptr;
5114 endwall = startwall+sector[sect].wallnum;
5115
5116 sp->owner = sector[sect].ceilingpal<<8;
5117 sp->owner |= sector[sect].floorpal;
5118
5119 for(s=startwall;s<endwall;s++)
5120 if(wall[s].shade > T4)
5121 T4 = wall[s].shade;
5122
5123 break;
5124
5125 case 9:
5126 if( sector[sect].lotag &&
5127 labs(sector[sect].ceilingz-sp->z) > 1024)
5128 sector[sect].lotag |= 32768; //If its open
5129 case 8:
5130 //First, get the ceiling-floor shade
5131
5132 T1 = sector[sect].floorshade;
5133 T2 = sector[sect].ceilingshade;
5134
5135 startwall = sector[sect].wallptr;
5136 endwall = startwall+sector[sect].wallnum;
5137
5138 for(s=startwall;s<endwall;s++)
5139 if(wall[s].shade > T3)
5140 T3 = wall[s].shade;
5141
5142 T4 = 1; //Take Out;
5143
5144 break;
5145
5146 case 11://Pivitor rotater
5147 if(sp->ang>1024) T4 = 2;
5148 else T4 = -2;
5149 case 0:
5150 case 2://Earthquakemakers
5151 case 5://Boss Creature
5152 case 6://Subway
5153 case 14://Caboos
5154 case 15://Subwaytype sliding door
5155 case 16://That rotating blocker reactor thing
5156 case 26://ESCELATOR
5157 case 30://No rotational subways
5158
5159 if(sp->lotag == 0)
5160 {
5161 if( sector[sect].lotag == 30 )
5162 {
5163 if(sp->pal) sprite[i].clipdist = 1;
5164 else sprite[i].clipdist = 0;
5165 T4 = sector[sect].floorz;
5166 sector[sect].hitag = i;
5167 }
5168
5169 for(j = 0;j < MAXSPRITES;j++)
5170 {
5171 if( sprite[j].statnum < MAXSTATUS )
5172 if( sprite[j].picnum == SECTOREFFECTOR &&
5173 sprite[j].lotag == 1 &&
5174 sprite[j].hitag == sp->hitag)
5175 {
5176 if( sp->ang == 512 )
5177 {
5178 sp->x = sprite[j].x;
5179 sp->y = sprite[j].y;
5180 }
5181 break;
5182 }
5183 }
5184 if(j == MAXSPRITES)
5185 {
5186 sprintf(text,"Found lonely Sector Effector (lotag 0) at (%d,%d)\n",sp->x,sp->y);
5187 gameexit(text);
5188 }
5189 sp->owner = j;
5190 }
5191
5192 startwall = sector[sect].wallptr;
5193 endwall = startwall+sector[sect].wallnum;
5194
5195 T2 = tempwallptr;
5196 for(s=startwall;s<endwall;s++)
5197 {
5198 msx[tempwallptr] = wall[s].x-sp->x;
5199 msy[tempwallptr] = wall[s].y-sp->y;
5200 tempwallptr++;
5201 if(tempwallptr > 2047)
5202 {
5203 sprintf(text,"Too many moving sectors at (%d,%d).\n",wall[s].x,wall[s].y);
5204 gameexit(text);
5205 }
5206 }
5207 if( sp->lotag == 30 || sp->lotag == 6 || sp->lotag == 14 || sp->lotag == 5 )
5208 {
5209
5210 startwall = sector[sect].wallptr;
5211 endwall = startwall+sector[sect].wallnum;
5212
5213 if(sector[sect].hitag == -1)
5214 sp->extra = 0;
5215 else sp->extra = 1;
5216
5217 sector[sect].hitag = i;
5218
5219 j = 0;
5220
5221 for(s=startwall;s<endwall;s++)
5222 {
5223 if( wall[ s ].nextsector >= 0 &&
5224 sector[ wall[ s ].nextsector].hitag == 0 &&
5225 sector[ wall[ s ].nextsector].lotag < 3 )
5226 {
5227 s = wall[s].nextsector;
5228 j = 1;
5229 break;
5230 }
5231 }
5232
5233 if(j == 0)
5234 {
5235 sprintf(text,"Subway found no zero'd sectors with locators\nat (%d,%d).\n",sp->x,sp->y);
5236 gameexit(text);
5237 }
5238
5239 sp->owner = -1;
5240 T1 = s;
5241
5242 if(sp->lotag != 30)
5243 T4 = sp->hitag;
5244 }
5245
5246 else if(sp->lotag == 16)
5247 T4 = sector[sect].ceilingz;
5248
5249 else if( sp->lotag == 26 )
5250 {
5251 T4 = sp->x;
5252 T5 = sp->y;
5253 if(sp->shade==sector[sect].floorshade) //UP
5254 sp->zvel = -256;
5255 else
5256 sp->zvel = 256;
5257
5258 sp->shade = 0;
5259 }
5260 else if( sp->lotag == 2)
5261 {
5262 T6 = sector[sp->sectnum].floorheinum;
5263 sector[sp->sectnum].floorheinum = 0;
5264 }
5265 }
5266
5267 switch(sp->lotag)
5268 {
5269 case 6:
5270 case 14:
5271 j = callsound(sect,i);
5272 if(j == -1) j = SUBWAY;
5273 hittype[i].lastvx = j;
5274 case 30:
5275 if(numplayers > 1) break;
5276 case 0:
5277 case 1:
5278 case 5:
5279 case 11:
5280 case 15:
5281 case 16:
5282 case 26:
5283 setsectinterpolate(i);
5284 break;
5285 }
5286
5287 switch(sprite[i].lotag)
5288 {
5289 case 40:
5290 case 41:
5291 case 43:
5292 case 44:
5293 case 45:
5294 changespritestat(i,15);
5295 break;
5296 default:
5297 changespritestat(i,3);
5298 break;
5299 }
5300
5301 break;
5302
5303
5304 case SEENINE:
5305 case OOZFILTER:
5306
5307 sp->shade = -16;
5308 if(sp->xrepeat <= 8)
5309 {
5310 sp->cstat = (short)32768;
5311 sp->xrepeat=sp->yrepeat=0;
5312 }
5313 else sp->cstat = 1+256;
5314 sp->extra = impact_damage<<2;
5315 sp->owner = i;
5316
5317 changespritestat(i,6);
5318 break;
5319
5320 case CRACK1:
5321 case CRACK2:
5322 case CRACK3:
5323 case CRACK4:
5324 case FIREEXT:
5325 if(sp->picnum == FIREEXT)
5326 {
5327 sp->cstat = 257;
5328 sp->extra = impact_damage<<2;
5329 }
5330 else
5331 {
5332 sp->cstat |= 17;
5333 sp->extra = 1;
5334 }
5335
5336 if( ud.multimode < 2 && sp->pal != 0)
5337 {
5338 sp->xrepeat = sp->yrepeat = 0;
5339 changespritestat(i,5);
5340 break;
5341 }
5342
5343 sp->pal = 0;
5344 sp->owner = i;
5345 changespritestat(i,6);
5346 sp->xvel = 8;
5347 ssp(i,CLIPMASK0);
5348 break;
5349
5350 case TOILET:
5351 case STALL:
5352 sp->lotag = 1;
5353 sp->cstat |= 257;
5354 sp->clipdist = 8;
5355 sp->owner = i;
5356 break;
5357 case CANWITHSOMETHING:
5358 case CANWITHSOMETHING2:
5359 case CANWITHSOMETHING3:
5360 case CANWITHSOMETHING4:
5361 case RUBBERCAN:
5362 sp->extra = 0;
5363 case EXPLODINGBARREL:
5364 case HORSEONSIDE:
5365 case FIREBARREL:
5366 case NUKEBARREL:
5367 case FIREVASE:
5368 case NUKEBARRELDENTED:
5369 case NUKEBARRELLEAKED:
5370 case WOODENHORSE:
5371
5372 if(j >= 0)
5373 sp->xrepeat = sp->yrepeat = 32;
5374 sp->clipdist = 72;
5375 makeitfall(i);
5376 if(j >= 0)
5377 sp->owner = j;
5378 else sp->owner = i;
5379 case EGG:
5380 if( ud.monsters_off == 1 && sp->picnum == EGG )
5381 {
5382 sp->xrepeat = sp->yrepeat = 0;
5383 changespritestat(i,5);
5384 }
5385 else
5386 {
5387 if(sp->picnum == EGG)
5388 sp->clipdist = 24;
5389 sp->cstat = 257|(TRAND&4);
5390 changespritestat(i,2);
5391 }
5392 break;
5393 case TOILETWATER:
5394 sp->shade = -16;
5395 changespritestat(i,6);
5396 break;
5397 }
5398 return i;
5399}
5400
5401
5402void animatesprites(int32_t x,int32_t y,short a,int32_t smoothratio)
5403{
5404 short i, j, k, p, sect;
5405 int32_t l, t1,t3,t4;
5406 spritetype *s,*t;
5407
5408 for(j=0;j < spritesortcnt; j++)
5409 {
5410 t = &tsprite[j];
5411 i = t->owner;
5412 s = &sprite[t->owner];
5413
5414 switch(t->picnum)
5415 {
5416 case BLOODPOOL:
5417 case PUKE:
5418 case FOOTPRINTS:
5419 case FOOTPRINTS2:
5420 case FOOTPRINTS3:
5421 case FOOTPRINTS4:
5422 if(t->shade == 127) continue;
5423 break;
5424 case RESPAWNMARKERRED:
5425 case RESPAWNMARKERYELLOW:
5426 case RESPAWNMARKERGREEN:
5427 if(ud.marker == 0)
5428 t->xrepeat = t->yrepeat = 0;
5429 continue;
5430 case CHAIR3:
5431
5432 k = (((t->ang+3072+128-a)&2047)>>8)&7;
5433 if(k>4)
5434 {
5435 k = 8-k;
5436 t->cstat |= 4;
5437 }
5438 else t->cstat &= ~4;
5439 t->picnum = s->picnum+k;
5440 break;
5441 case BLOODSPLAT1:
5442 case BLOODSPLAT2:
5443 case BLOODSPLAT3:
5444 case BLOODSPLAT4:
5445 if(ud.lockout) t->xrepeat = t->yrepeat = 0;
5446 else if(t->pal == 6)
5447 {
5448 t->shade = -127;
5449 continue;
5450 }
5451 case BULLETHOLE:
5452 case CRACK1:
5453 case CRACK2:
5454 case CRACK3:
5455 case CRACK4:
5456 t->shade = 16;
5457 continue;
5458 case NEON1:
5459 case NEON2:
5460 case NEON3:
5461 case NEON4:
5462 case NEON5:
5463 case NEON6:
5464 continue;
5465 case GREENSLIME:
5466 case GREENSLIME+1:
5467 case GREENSLIME+2:
5468 case GREENSLIME+3:
5469 case GREENSLIME+4:
5470 case GREENSLIME+5:
5471 case GREENSLIME+6:
5472 case GREENSLIME+7:
5473 break;
5474 default:
5475 if( ( (t->cstat&16) ) || ( badguy(t) && t->extra > 0) || t->statnum == 10)
5476 continue;
5477 }
5478
5479 if (sector[t->sectnum].ceilingstat&1)
5480 l = sector[t->sectnum].ceilingshade;
5481 else
5482 l = sector[t->sectnum].floorshade;
5483
5484 if(l < -127) l = -127;
5485 if(l > 128) l = 127;
5486 t->shade = l;
5487 }
5488
5489
5490 for(j=0;j < spritesortcnt; j++ ) //Between drawrooms() and drawmasks()
5491 { //is the perfect time to animate sprites
5492 t = &tsprite[j];
5493 i = t->owner;
5494 s = &sprite[i];
5495
5496 switch(s->picnum)
5497 {
5498 case SECTOREFFECTOR:
5499 if(t->lotag == 27 && ud.recstat == 1)
5500 {
5501 t->picnum = 11+((totalclock>>3)&1);
5502 t->cstat |= 128;
5503 }
5504 else
5505 t->xrepeat = t->yrepeat = 0;
5506 break;
5507 case NATURALLIGHTNING:
5508 t->shade = -127;
5509 break;
5510 case FEM1:
5511 case FEM2:
5512 case FEM3:
5513 case FEM4:
5514 case FEM5:
5515 case FEM6:
5516 case FEM7:
5517 case FEM8:
5518 case FEM9:
5519 case FEM10:
5520 case MAN:
5521 case MAN2:
5522 case WOMAN:
5523 case NAKED1:
5524 case PODFEM1:
5525 case FEMMAG1:
5526 case FEMMAG2:
5527 case FEMPIC1:
5528 case FEMPIC2:
5529 case FEMPIC3:
5530 case FEMPIC4:
5531 case FEMPIC5:
5532 case FEMPIC6:
5533 case FEMPIC7:
5534 case BLOODYPOLE:
5535 case FEM6PAD:
5536 case STATUE:
5537 case STATUEFLASH:
5538 case OOZ:
5539 case OOZ2:
5540 case WALLBLOOD1:
5541 case WALLBLOOD2:
5542 case WALLBLOOD3:
5543 case WALLBLOOD4:
5544 case WALLBLOOD5:
5545 case WALLBLOOD7:
5546 case WALLBLOOD8:
5547 case SUSHIPLATE1:
5548 case SUSHIPLATE2:
5549 case SUSHIPLATE3:
5550 case SUSHIPLATE4:
5551 case FETUS:
5552 case FETUSJIB:
5553 case FETUSBROKE:
5554 case HOTMEAT:
5555 case FOODOBJECT16:
5556 case DOLPHIN1:
5557 case DOLPHIN2:
5558 case TOUGHGAL:
5559 case TAMPON:
5560 case XXXSTACY:
5561 case 4946:
5562 case 4947:
5563 case 693:
5564 case 2254:
5565 case 4560:
5566 case 4561:
5567 case 4562:
5568 case 4498:
5569 case 4957:
5570 if(ud.lockout)
5571 {
5572 t->xrepeat = t->yrepeat = 0;
5573 continue;
5574 }
5575 }
5576
5577 if( t->statnum == 99 ) continue;
5578 if( s->statnum != 1 && s->picnum == APLAYER && ps[s->yvel].newowner == -1 && s->owner >= 0 )
5579 {
5580 t->x -= mulscale16(65536-smoothratio,ps[s->yvel].posx-ps[s->yvel].oposx);
5581 t->y -= mulscale16(65536-smoothratio,ps[s->yvel].posy-ps[s->yvel].oposy);
5582 t->z = ps[s->yvel].oposz + mulscale16(smoothratio,ps[s->yvel].posz-ps[s->yvel].oposz);
5583 t->z += (40<<8);
5584 }
5585 else if( ( s->statnum == 0 && s->picnum != CRANEPOLE) || s->statnum == 10 || s->statnum == 6 || s->statnum == 4 || s->statnum == 5 || s->statnum == 1 )
5586 {
5587 t->x -= mulscale16(65536-smoothratio,s->x-hittype[i].bposx);
5588 t->y -= mulscale16(65536-smoothratio,s->y-hittype[i].bposy);
5589 t->z -= mulscale16(65536-smoothratio,s->z-hittype[i].bposz);
5590 }
5591
5592 sect = s->sectnum;
5593 t1 = T2;t3 = T4;t4 = T5;
5594
5595 switch(s->picnum)
5596 {
5597 case DUKELYINGDEAD:
5598 t->z += (24<<8);
5599 break;
5600 case BLOODPOOL:
5601 case FOOTPRINTS:
5602 case FOOTPRINTS2:
5603 case FOOTPRINTS3:
5604 case FOOTPRINTS4:
5605 if(t->pal == 6)
5606 t->shade = -127;
5607 case PUKE:
5608 case MONEY:
5609 case MONEY+1:
5610 case MAIL:
5611 case MAIL+1:
5612 case PAPER:
5613 case PAPER+1:
5614 if(ud.lockout && s->pal == 2)
5615 {
5616 t->xrepeat = t->yrepeat = 0;
5617 continue;
5618 }
5619 break;
5620 case TRIPBOMB:
5621 continue;
5622 case FORCESPHERE:
5623 if(t->statnum == 5)
5624 {
5625 short sqa,sqb;
5626
5627 sqa =
5628 getangle(
5629 sprite[s->owner].x-ps[screenpeek].posx,
5630 sprite[s->owner].y-ps[screenpeek].posy);
5631 sqb =
5632 getangle(
5633 sprite[s->owner].x-t->x,
5634 sprite[s->owner].y-t->y);
5635
5636 if( klabs(getincangle(sqa,sqb)) > 512 )
5637 if( ldist(&sprite[s->owner],t) < ldist(&sprite[ps[screenpeek].i],&sprite[s->owner]) )
5638 t->xrepeat = t->yrepeat = 0;
5639 }
5640 continue;
5641 case BURNING:
5642 case BURNING2:
5643 if( sprite[s->owner].statnum == 10 )
5644 {
5645 if( display_mirror == 0 && sprite[s->owner].yvel == screenpeek && ps[sprite[s->owner].yvel].over_shoulder_on == 0 )
5646 t->xrepeat = 0;
5647 else
5648 {
5649 t->ang = getangle(x-t->x,y-t->y);
5650 t->x = sprite[s->owner].x;
5651 t->y = sprite[s->owner].y;
5652 t->x += sintable[(t->ang+512)&2047]>>10;
5653 t->y += sintable[t->ang&2047]>>10;
5654 }
5655 }
5656 break;
5657
5658 case ATOMICHEALTH:
5659 t->z -= (4<<8);
5660 break;
5661 case CRYSTALAMMO:
5662 t->shade = (sintable[(totalclock<<4)&2047]>>10);
5663 continue;
5664 case VIEWSCREEN:
5665 case VIEWSCREEN2:
5666 if(camsprite >= 0 && hittype[OW].temp_data[0] == 1)
5667 {
5668 t->picnum = STATIC;
5669 t->cstat |= (rand()&12);
5670 t->xrepeat += 8;
5671 t->yrepeat += 8;
5672 }
5673 break;
5674
5675 case SHRINKSPARK:
5676 t->picnum = SHRINKSPARK+( (totalclock>>4)&3 );
5677 break;
5678 case GROWSPARK:
5679 t->picnum = GROWSPARK+( (totalclock>>4)&3 );
5680 break;
5681 case RPG:
5682 k = getangle(s->x-x,s->y-y);
5683 k = (((s->ang+3072+128-k)&2047)/170);
5684 if(k > 6)
5685 {
5686 k = 12-k;
5687 t->cstat |= 4;
5688 }
5689 else t->cstat &= ~4;
5690 t->picnum = RPG+k;
5691 break;
5692
5693 case RECON:
5694
5695 k = getangle(s->x-x,s->y-y);
5696 if( T1 < 4 )
5697 k = (((s->ang+3072+128-k)&2047)/170);
5698 else k = (((s->ang+3072+128-k)&2047)/170);
5699
5700 if(k>6)
5701 {
5702 k = 12-k;
5703 t->cstat |= 4;
5704 }
5705 else t->cstat &= ~4;
5706
5707 if( klabs(t3) > 64 ) k += 7;
5708 t->picnum = RECON+k;
5709
5710 break;
5711
5712 case APLAYER:
5713
5714 p = s->yvel;
5715
5716 if(t->pal == 1) t->z -= (18<<8);
5717
5718 if(ps[p].over_shoulder_on > 0 && ps[p].newowner < 0 )
5719 {
5720 t->cstat |= 2;
5721 if ( screenpeek == myconnectindex && numplayers >= 2 )
5722 {
5723 t->x = omyx+mulscale16((int32_t)(myx-omyx),smoothratio);
5724 t->y = omyy+mulscale16((int32_t)(myy-omyy),smoothratio);
5725 t->z = omyz+mulscale16((int32_t)(myz-omyz),smoothratio)+(40<<8);
5726 t->ang = omyang+mulscale16((int32_t)(((myang+1024-omyang)&2047)-1024),smoothratio);
5727 t->sectnum = mycursectnum;
5728 }
5729 }
5730
5731 if( ( display_mirror == 1 || screenpeek != p || s->owner == -1 ) && ud.multimode > 1 && ud.showweapons && sprite[ps[p].i].extra > 0 && ps[p].curr_weapon > 0 )
5732 {
5733 memcpy((spritetype *)&tsprite[spritesortcnt],(spritetype *)t,sizeof(spritetype));
5734
5735 tsprite[spritesortcnt].statnum = 99;
5736
5737 tsprite[spritesortcnt].yrepeat = ( t->yrepeat>>3 );
5738 if(t->yrepeat < 4) t->yrepeat = 4;
5739
5740 tsprite[spritesortcnt].shade = t->shade;
5741 tsprite[spritesortcnt].cstat = 0;
5742
5743 switch(ps[p].curr_weapon)
5744 {
5745 case PISTOL_WEAPON: tsprite[spritesortcnt].picnum = FIRSTGUNSPRITE; break;
5746 case SHOTGUN_WEAPON: tsprite[spritesortcnt].picnum = SHOTGUNSPRITE; break;
5747 case CHAINGUN_WEAPON: tsprite[spritesortcnt].picnum = CHAINGUNSPRITE; break;
5748 case RPG_WEAPON: tsprite[spritesortcnt].picnum = RPGSPRITE; break;
5749 case HANDREMOTE_WEAPON:
5750 case HANDBOMB_WEAPON: tsprite[spritesortcnt].picnum = HEAVYHBOMB; break;
5751 case TRIPBOMB_WEAPON: tsprite[spritesortcnt].picnum = TRIPBOMBSPRITE; break;
5752 case GROW_WEAPON: tsprite[spritesortcnt].picnum = GROWSPRITEICON; break;
5753 case SHRINKER_WEAPON: tsprite[spritesortcnt].picnum = SHRINKERSPRITE; break;
5754 case FREEZE_WEAPON: tsprite[spritesortcnt].picnum = FREEZESPRITE; break;
5755 case DEVISTATOR_WEAPON: tsprite[spritesortcnt].picnum = DEVISTATORSPRITE; break;
5756 }
5757
5758 if(s->owner >= 0)
5759 tsprite[spritesortcnt].z = ps[p].posz-(12<<8);
5760 else tsprite[spritesortcnt].z = s->z-(51<<8);
5761 if(ps[p].curr_weapon == HANDBOMB_WEAPON)
5762 {
5763 tsprite[spritesortcnt].xrepeat = 10;
5764 tsprite[spritesortcnt].yrepeat = 10;
5765 }
5766 else
5767 {
5768 tsprite[spritesortcnt].xrepeat = 16;
5769 tsprite[spritesortcnt].yrepeat = 16;
5770 }
5771 tsprite[spritesortcnt].pal = 0;
5772 spritesortcnt++;
5773 }
5774
5775 if(s->owner == -1)
5776 {
5777 k = (((s->ang+3072+128-a)&2047)>>8)&7;
5778 if(k>4)
5779 {
5780 k = 8-k;
5781 t->cstat |= 4;
5782 }
5783 else t->cstat &= ~4;
5784
5785 if(sector[t->sectnum].lotag == 2) k += 1795-1405;
5786 else if( (hittype[i].floorz-s->z) > (64<<8) ) k += 60;
5787
5788 t->picnum += k;
5789 t->pal = ps[p].palookup;
5790
5791 goto PALONLY;
5792 }
5793
5794 if( ps[p].on_crane == -1 && (sector[s->sectnum].lotag&0x7ff) != 1 )
5795 {
5796 l = s->z-hittype[ps[p].i].floorz+(3<<8);
5797 if( l > 1024 && s->yrepeat > 32 && s->extra > 0 )
5798 s->yoffset = (int8_t )(l/(s->yrepeat<<2));
5799 else s->yoffset=0;
5800 }
5801
5802 if(ps[p].newowner > -1)
5803 {
5804 t4 = *(actorscrptr[APLAYER]+1);
5805 t3 = 0;
5806 t1 = *(actorscrptr[APLAYER]+2);
5807 }
5808
5809 if(ud.camerasprite == -1 && ps[p].newowner == -1)
5810 if(s->owner >= 0 && display_mirror == 0 && ps[p].over_shoulder_on == 0 )
5811 if( ud.multimode < 2 || ( ud.multimode > 1 && p == screenpeek ) )
5812 {
5813 t->owner = -1;
5814 t->xrepeat = t->yrepeat = 0;
5815 continue;
5816 }
5817
5818 PALONLY:
5819
5820 if( sector[sect].floorpal )
5821 t->pal = sector[sect].floorpal;
5822
5823 if(s->owner == -1) continue;
5824
5825 if( t->z > hittype[i].floorz && t->xrepeat < 32 )
5826 t->z = hittype[i].floorz;
5827
5828 break;
5829
5830 case JIBS1:
5831 case JIBS2:
5832 case JIBS3:
5833 case JIBS4:
5834 case JIBS5:
5835 case JIBS6:
5836 case HEADJIB1:
5837 case LEGJIB1:
5838 case ARMJIB1:
5839 case LIZMANHEAD1:
5840 case LIZMANARM1:
5841 case LIZMANLEG1:
5842 case DUKELEG:
5843 case DUKEGUN:
5844 case DUKETORSO:
5845 if(ud.lockout)
5846 {
5847 t->xrepeat = t->yrepeat = 0;
5848 continue;
5849 }
5850 if(t->pal == 6) t->shade = -120;
5851
5852 case SCRAP1:
5853 case SCRAP2:
5854 case SCRAP3:
5855 case SCRAP4:
5856 case SCRAP5:
5857 case SCRAP6:
5858 case SCRAP6+1:
5859 case SCRAP6+2:
5860 case SCRAP6+3:
5861 case SCRAP6+4:
5862 case SCRAP6+5:
5863 case SCRAP6+6:
5864 case SCRAP6+7:
5865
5866 if(hittype[i].picnum == BLIMP && t->picnum == SCRAP1 && s->yvel >= 0)
5867 t->picnum = s->yvel;
5868 else t->picnum += T1;
5869 t->shade -= 6;
5870
5871 if( sector[sect].floorpal )
5872 t->pal = sector[sect].floorpal;
5873 break;
5874
5875 case WATERBUBBLE:
5876 if(sector[t->sectnum].floorpicnum == FLOORSLIME)
5877 {
5878 t->pal = 7;
5879 break;
5880 }
5881 default:
5882
5883 if( sector[sect].floorpal )
5884 t->pal = sector[sect].floorpal;
5885 break;
5886 }
5887
5888 if( actorscrptr[s->picnum] )
5889 {
5890 if(t4>10000)
5891 // FIX_00093: fixed crashbugs in multiplayer (mine/blimp)
5892 // This is the mine issue (confusion bug in hittype[i].temp_data[4] usage)
5893 // close to blimp bug (search for BLIMP)
5894 // -> t4 aka macro T5 is incremented at DETONATEB: in actor.c
5895 // for a time counter. Instead we want an address.
5896 // Issue happens in confessn.map (do a dnclip + dnkroz + dncoords,
5897 // start with duke3d_w32 /m /q2 -map confessn.map)
5898 // go through the Guilty logo till x = -2932, y = 42174, z = 18416.
5899 // blow up the bomb. Wait in the water. Look at the respawn sign
5900 // at the bottom of the chain. Crashes when it's about to respawn.
5901 // Lame fix. ok for w32. Doesn't work for other plateform.
5902 // How to make a differene between a timer and an address??
5903 {
5904 l = *(int32_t *)(t4+8);
5905
5906 switch( l )
5907 {
5908 case 2:
5909 k = (((s->ang+3072+128-a)&2047)>>8)&1;
5910 break;
5911
5912 case 3:
5913 case 4:
5914 k = (((s->ang+3072+128-a)&2047)>>7)&7;
5915 if(k > 3)
5916 {
5917 t->cstat |= 4;
5918 k = 7-k;
5919 }
5920 else t->cstat &= ~4;
5921 break;
5922
5923 case 5:
5924 k = getangle(s->x-x,s->y-y);
5925 k = (((s->ang+3072+128-k)&2047)>>8)&7;
5926 if(k>4)
5927 {
5928 k = 8-k;
5929 t->cstat |= 4;
5930 }
5931 else t->cstat &= ~4;
5932 break;
5933 case 7:
5934 k = getangle(s->x-x,s->y-y);
5935 k = (((s->ang+3072+128-k)&2047)/170);
5936 if(k>6)
5937 {
5938 k = 12-k;
5939 t->cstat |= 4;
5940 }
5941 else t->cstat &= ~4;
5942 break;
5943 case 8:
5944 k = (((s->ang+3072+128-a)&2047)>>8)&7;
5945 t->cstat &= ~4;
5946 break;
5947 default:
5948 k = 0;
5949 break;
5950 }
5951
5952 t->picnum += k + ( *(int32_t *)t4 ) + l * t3;
5953
5954 if(l > 0)
5955 while(tiles[t->picnum].dim.width == 0 && t->picnum > 0 )
5956 t->picnum -= l; //Hack, for actors
5957
5958 if( hittype[i].dispicnum >= 0)
5959 hittype[i].dispicnum = t->picnum;
5960 }
5961 else if(display_mirror == 1)
5962 t->cstat |= 4;
5963 }
5964
5965 if( s->statnum == 13 || badguy(s) || (s->picnum == APLAYER && s->owner >= 0) )
5966 if(t->statnum != 99 && s->picnum != EXPLOSION2 && s->picnum != HANGLIGHT && s->picnum != DOMELITE)
5967 if(s->picnum != HOTMEAT)
5968 {
5969 if( hittype[i].dispicnum < 0 )
5970 {
5971 hittype[i].dispicnum++;
5972 continue;
5973 }
5974 else if( ud.shadows && spritesortcnt < (MAXSPRITESONSCREEN-2))
5975 {
5976 int32_t daz,xrep,yrep;
5977
5978 if( (sector[sect].lotag&0xff) > 2 || s->statnum == 4 || s->statnum == 5 || s->picnum == DRONE || s->picnum == COMMANDER )
5979 daz = sector[sect].floorz;
5980 else
5981 daz = hittype[i].floorz;
5982
5983 if( (s->z-daz) < (8<<8) )
5984 if( ps[screenpeek].posz < daz )
5985 {
5986 memcpy((spritetype *)&tsprite[spritesortcnt],(spritetype *)t,sizeof(spritetype));
5987
5988 tsprite[spritesortcnt].statnum = 99;
5989
5990 tsprite[spritesortcnt].yrepeat = ( t->yrepeat>>3 );
5991 if(t->yrepeat < 4) t->yrepeat = 4;
5992
5993 tsprite[spritesortcnt].shade = 127;
5994 tsprite[spritesortcnt].cstat |= 2;
5995
5996 tsprite[spritesortcnt].z = daz;
5997 xrep = tsprite[spritesortcnt].xrepeat;// - (klabs(daz-t->z)>>11);
5998 tsprite[spritesortcnt].xrepeat = xrep;
5999 tsprite[spritesortcnt].pal = 4;
6000
6001 yrep = tsprite[spritesortcnt].yrepeat;// - (klabs(daz-t->z)>>11);
6002 tsprite[spritesortcnt].yrepeat = yrep;
6003 spritesortcnt++;
6004 }
6005 }
6006
6007 if( ps[screenpeek].heat_amount > 0 && ps[screenpeek].heat_on )
6008 {
6009 t->pal = 6;
6010 t->shade = 0;
6011 }
6012 }
6013
6014
6015 switch(s->picnum)
6016 {
6017 case LASERLINE:
6018 if(sector[t->sectnum].lotag == 2) t->pal = 8;
6019 t->z = sprite[s->owner].z-(3<<8);
6020 if(lasermode == 2 && ps[screenpeek].heat_on == 0 )
6021 t->yrepeat = 0;
6022 case EXPLOSION2:
6023 case EXPLOSION2BOT:
6024 case FREEZEBLAST:
6025 case ATOMICHEALTH:
6026 case FIRELASER:
6027 case SHRINKSPARK:
6028 case GROWSPARK:
6029 case CHAINGUN:
6030 case SHRINKEREXPLOSION:
6031 case RPG:
6032 case FLOORFLAME:
6033 if(t->picnum == EXPLOSION2)
6034 {
6035 ps[screenpeek].visibility = -127;
6036 lastvisinc = totalclock+32;
6037 restorepalette = 1;
6038 }
6039 t->shade = -127;
6040 break;
6041 case FIRE:
6042 case FIRE2:
6043 case BURNING:
6044 case BURNING2:
6045 if( sprite[s->owner].picnum != TREE1 && sprite[s->owner].picnum != TREE2 )
6046 t->z = sector[t->sectnum].floorz;
6047 t->shade = -127;
6048 break;
6049 case COOLEXPLOSION1:
6050 t->shade = -127;
6051 t->picnum += (s->shade>>1);
6052 break;
6053 case PLAYERONWATER:
6054
6055 k = (((t->ang+3072+128-a)&2047)>>8)&7;
6056 if(k>4)
6057 {
6058 k = 8-k;
6059 t->cstat |= 4;
6060 }
6061 else t->cstat &= ~4;
6062
6063 t->picnum = s->picnum+k+((T1<4)*5);
6064 t->shade = sprite[s->owner].shade;
6065
6066 break;
6067
6068 case WATERSPLASH2:
6069 t->picnum = WATERSPLASH2+t1;
6070 break;
6071 case REACTOR2:
6072 t->picnum = s->picnum + T3;
6073 break;
6074 case SHELL:
6075 t->picnum = s->picnum+(T1&1);
6076 case SHOTGUNSHELL:
6077 t->cstat |= 12;
6078 if(T1 > 1) t->cstat &= ~4;
6079 if(T1 > 2) t->cstat &= ~12;
6080 break;
6081 case FRAMEEFFECT1:
6082 case FRAMEEFFECT1_13CON:
6083 if(s->owner >= 0 && sprite[s->owner].statnum < MAXSTATUS)
6084 {
6085 if(sprite[s->owner].picnum == APLAYER)
6086 if(ud.camerasprite == -1)
6087 if(screenpeek == sprite[s->owner].yvel && display_mirror == 0)
6088 {
6089 t->owner = -1;
6090 break;
6091 }
6092 if( (sprite[s->owner].cstat&32768) == 0 )
6093 {
6094 t->picnum = hittype[s->owner].dispicnum;
6095 t->pal = sprite[s->owner].pal;
6096 t->shade = sprite[s->owner].shade;
6097 t->ang = sprite[s->owner].ang;
6098 t->cstat = 2|sprite[s->owner].cstat;
6099 }
6100 }
6101 break;
6102
6103 case CAMERA1:
6104 case RAT:
6105 k = (((t->ang+3072+128-a)&2047)>>8)&7;
6106 if(k>4)
6107 {
6108 k = 8-k;
6109 t->cstat |= 4;
6110 }
6111 else t->cstat &= ~4;
6112 t->picnum = s->picnum+k;
6113 break;
6114 }
6115
6116 hittype[i].dispicnum = t->picnum;
6117 if(sector[t->sectnum].floorpicnum == MIRROR)
6118 t->xrepeat = t->yrepeat = 0;
6119 }
6120}
6121
6122
6123
6124#define NUMCHEATCODES 26
6125uint8_t cheatquotes[NUMCHEATCODES][14] = {
6126 {"cornholio"}, // 0
6127 {"stuff"}, // 1
6128 {"scotty###"}, // 2
6129 {"coords"}, // 3
6130 {"view"}, // 4
6131 {"time"}, // 5
6132 {"unlock"}, // 6
6133 {"cashman"}, // 7
6134 {"items"}, // 8
6135 {"rate"}, // 9
6136 {"skill#"}, // 10
6137 {"beta"}, // 11
6138 {"hyper"}, // 12
6139 {"monsters"}, // 13
6140 {"<RESERVED>"}, // 14
6141 {"<RESERVED>"}, // 15
6142 {"todd"}, // 16
6143 {"showmap"}, // 17
6144 {"kroz"}, // 18
6145 {"allen"}, // 19
6146 {"clip"}, // 20
6147 {"weapons"}, // 21
6148 {"inventory"}, // 22
6149 {"keys"}, // 23
6150 {"debug"} // 24
6151// {"ending"}
6152
6153};
6154
6155
6156uint8_t cheatbuf[10],cheatbuflen;
6157void cheats(void)
6158{
6159 short ch, i, j, k, weapon;
6160
6161 if( (ps[myconnectindex].gm&MODE_TYPE) || (ps[myconnectindex].gm&MODE_MENU))
6162 return;
6163
6164 if ( ps[myconnectindex].cheat_phase == 1)
6165 {
6166 while (KB_KeyWaiting())
6167 {
6168 ch = KB_Getch();
6169 ch = tolower(ch);
6170
6171 if( !( (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') ) )
6172 {
6173 ps[myconnectindex].cheat_phase = 0;
6174// FTA(46,&ps[myconnectindex]);
6175 return;
6176 }
6177
6178 cheatbuf[cheatbuflen++] = ch;
6179 cheatbuf[cheatbuflen] = 0;
6180
6181 if(cheatbuflen > 11)
6182 {
6183 ps[myconnectindex].cheat_phase = 0;
6184 return;
6185 }
6186
6187 for(k = 0;k < NUMCHEATCODES;k++)
6188 {
6189 for(j = 0;j<cheatbuflen;j++)
6190 {
6191 if( cheatbuf[j] == cheatquotes[k][j] || (cheatquotes[k][j] == '#' && ch >= '0' && ch <= '9') )
6192 {
6193 if( cheatquotes[k][j+1] == 0 ) goto FOUNDCHEAT;
6194 if(j == cheatbuflen-1) return;
6195 }
6196 else break;
6197 }
6198 }
6199
6200 ps[myconnectindex].cheat_phase = 0;
6201 return;
6202
6203 FOUNDCHEAT:
6204 {
6205 switch(k)
6206 {
6207 case 0: // cornholio
6208 case 18: // kroz
6209
6210 ud.god = 1-ud.god;
6211
6212 if(ud.god)
6213 { // set on
6214 pus = 1;
6215 pub = 1;
6216 sprite[ps[myconnectindex].i].cstat = 257;
6217
6218 hittype[ps[myconnectindex].i].temp_data[0] = 0;
6219 hittype[ps[myconnectindex].i].temp_data[1] = 0;
6220 hittype[ps[myconnectindex].i].temp_data[2] = 0;
6221 hittype[ps[myconnectindex].i].temp_data[3] = 0;
6222 hittype[ps[myconnectindex].i].temp_data[4] = 0;
6223 hittype[ps[myconnectindex].i].temp_data[5] = 0;
6224
6225 sprite[ps[myconnectindex].i].hitag = 0;
6226 sprite[ps[myconnectindex].i].lotag = 0;
6227 sprite[ps[myconnectindex].i].pal =
6228 ps[myconnectindex].palookup;
6229
6230 FTA(17,&ps[myconnectindex],1);
6231 }
6232 else // set off
6233 {
6234 ud.god = 0;
6235 sprite[ps[myconnectindex].i].extra = max_player_health;
6236 hittype[ps[myconnectindex].i].extra = -1;
6237 ps[myconnectindex].last_extra = max_player_health;
6238 FTA(18,&ps[myconnectindex],1);
6239 }
6240
6241 sprite[ps[myconnectindex].i].extra = max_player_health;
6242 hittype[ps[myconnectindex].i].extra = 0;
6243 ps[myconnectindex].cheat_phase = 0;
6244 KB_FlushKeyboardQueue();
6245
6246 return;
6247
6248 case 1: // stuff
6249
6250 if(VOLUMEONE)
6251 j = 6;
6252 else
6253 j = 0;
6254
6255 for ( weapon = PISTOL_WEAPON;weapon < MAX_WEAPONS-j;weapon++ )
6256 ps[myconnectindex].gotweapon[weapon] = 1;
6257
6258 for ( weapon = PISTOL_WEAPON;
6259 weapon < (MAX_WEAPONS-j);
6260 weapon++ )
6261 addammo( weapon, &ps[myconnectindex], max_ammo_amount[weapon] );
6262
6263 ps[myconnectindex].ammo_amount[GROW_WEAPON] = 50;
6264
6265 ps[myconnectindex].steroids_amount = 400;
6266 ps[myconnectindex].heat_amount = 1200;
6267 ps[myconnectindex].boot_amount = 200;
6268 ps[myconnectindex].shield_amount = 100;
6269 ps[myconnectindex].scuba_amount = 6400;
6270 ps[myconnectindex].holoduke_amount = 2400;
6271 ps[myconnectindex].jetpack_amount = 1600;
6272 ps[myconnectindex].firstaid_amount = max_player_health;
6273
6274 ps[myconnectindex].got_access = 7;
6275 FTA(5,&ps[myconnectindex],1);
6276 ps[myconnectindex].cheat_phase = 0;
6277
6278 ps[myconnectindex].cheat_phase = 0;
6279 KB_FlushKeyboardQueue();
6280 ps[myconnectindex].inven_icon = 1;
6281 return;
6282
6283 case 2: // dnscotty###
6284 case 10: // skill#
6285
6286 if(k == 2)
6287 {
6288 short volnume,levnume;
6289 volnume = cheatbuf[6] - '0';
6290 levnume = (cheatbuf[7] - '0')*10+(cheatbuf[8]-'0');
6291
6292 volnume--;
6293 levnume--;
6294 if (VOLUMEONE)
6295 {
6296 if( volnume > 0 )
6297 {
6298 ps[myconnectindex].cheat_phase = 0;
6299 KB_FlushKeyboardQueue();
6300 return;
6301 }
6302 }
6303
6304 if((volnume > 4)&&PLUTOPAK)
6305 {
6306 ps[myconnectindex].cheat_phase = 0;
6307 KB_FlushKeyboardQueue();
6308 return;
6309 }
6310 else
6311 if((volnume > 3)&&!PLUTOPAK)
6312 {
6313 ps[myconnectindex].cheat_phase = 0;
6314 KB_FlushKeyboardQueue();
6315 return;
6316 }
6317 else
6318
6319 if(volnume == 0)
6320 {
6321 if(levnume > 5)
6322 {
6323 ps[myconnectindex].cheat_phase = 0;
6324 KB_FlushKeyboardQueue();
6325 return;
6326 }
6327 }
6328 else
6329 {
6330 if(levnume >= 11)
6331 {
6332 ps[myconnectindex].cheat_phase = 0;
6333 KB_FlushKeyboardQueue();
6334 return;
6335 }
6336 }
6337
6338 ud.m_volume_number = ud.volume_number = volnume;
6339 ud.m_level_number = ud.level_number = levnume;
6340
6341 }
6342 else ud.m_player_skill = ud.player_skill =
6343 cheatbuf[5] - '1';
6344
6345 if(numplayers > 1 && myconnectindex == connecthead)
6346 {
6347 tempbuf[0] = 5;
6348 tempbuf[1] = ud.m_level_number;
6349 tempbuf[2] = ud.m_volume_number;
6350 tempbuf[3] = ud.m_player_skill;
6351 tempbuf[4] = ud.m_monsters_off;
6352 tempbuf[5] = ud.m_respawn_monsters;
6353 tempbuf[6] = ud.m_respawn_items;
6354 tempbuf[7] = ud.m_respawn_inventory;
6355 tempbuf[8] = ud.m_coop;
6356 tempbuf[9] = ud.m_marker;
6357 tempbuf[10] = ud.m_ffire;
6358
6359 for(i=connecthead;i>=0;i=connectpoint2[i])
6360 sendpacket(i,(uint8_t*)tempbuf,11);
6361 }
6362 else ps[myconnectindex].gm |= MODE_RESTART;
6363
6364 ps[myconnectindex].cheat_phase = 0;
6365 KB_FlushKeyboardQueue();
6366 return;
6367
6368 case 3: // coords
6369 ps[myconnectindex].cheat_phase = 0;
6370 ud.coords = 1-ud.coords;
6371 KB_FlushKeyboardQueue();
6372 return;
6373
6374 case 4: // view
6375 if( ps[myconnectindex].over_shoulder_on )
6376 ps[myconnectindex].over_shoulder_on = 0;
6377 else
6378 {
6379 ps[myconnectindex].over_shoulder_on = 1;
6380 cameradist = 0;
6381 cameraclock = totalclock;
6382 }
6383 // FTA(22,&ps[myconnectindex],1);
6384 ps[myconnectindex].cheat_phase = 0;
6385 KB_FlushKeyboardQueue();
6386 return;
6387
6388 case 5: // time
6389 // FTA(21,&ps[myconnectindex]);
6390 ps[myconnectindex].cheat_phase = 0;
6391 KB_FlushKeyboardQueue();
6392 return;
6393
6394 case 6: // unlock
6395 for(i=numsectors-1;i>=0;i--) //Unlock
6396 {
6397 j = sector[i].lotag;
6398 if(j == -1 || j == 32767) continue;
6399 if( (j & 0x7fff) > 2 )
6400 {
6401 if( j&(0xffff-16384) )
6402 sector[i].lotag &= (0xffff-16384);
6403 operatesectors(i,ps[myconnectindex].i);
6404 }
6405 }
6406 operateforcefields(ps[myconnectindex].i,-1);
6407
6408 FTA(100,&ps[myconnectindex],1);
6409 ps[myconnectindex].cheat_phase = 0;
6410 KB_FlushKeyboardQueue();
6411 return;
6412
6413 case 7: // cashman
6414 ud.cashman = 1-ud.cashman;
6415 KB_ClearKeyDown(sc_N);
6416 ps[myconnectindex].cheat_phase = 0;
6417 return;
6418
6419 case 8: // items
6420 ps[myconnectindex].steroids_amount = 400;
6421 ps[myconnectindex].heat_amount = 1200;
6422 ps[myconnectindex].boot_amount = 200;
6423 ps[myconnectindex].shield_amount = 100;
6424 ps[myconnectindex].scuba_amount = 6400;
6425 ps[myconnectindex].holoduke_amount = 2400;
6426 ps[myconnectindex].jetpack_amount = 1600;
6427
6428 ps[myconnectindex].firstaid_amount = max_player_health;
6429 ps[myconnectindex].got_access = 7;
6430 FTA(5,&ps[myconnectindex],1);
6431 ps[myconnectindex].cheat_phase = 0;
6432 KB_FlushKeyboardQueue();
6433 return;
6434
6435 case 9: // rate
6436 ud.tickrate ^= 1;
6437 vscrn(); // FIX_00056: Refresh issue w/FPS, small Weapon and custom FTA, when screen resized down
6438 ps[myconnectindex].cheat_phase = 0;
6439 KB_FlushKeyboardQueue();
6440 return;
6441
6442 case 11: // beta
6443 FTA(105,&ps[myconnectindex],1);
6444 KB_ClearKeyDown(sc_H);
6445 ps[myconnectindex].cheat_phase = 0;
6446 KB_FlushKeyboardQueue();
6447 return;
6448
6449 case 12: // hyper
6450 ps[myconnectindex].steroids_amount = 399;
6451 ps[myconnectindex].heat_amount = 1200;
6452 ps[myconnectindex].cheat_phase = 0;
6453 FTA(37,&ps[myconnectindex],1);
6454 KB_FlushKeyboardQueue();
6455 return;
6456
6457 case 13: // monsters
6458 if(actor_tog == 3) actor_tog = 0;
6459 actor_tog++;
6460 ps[screenpeek].cheat_phase = 0;
6461 KB_FlushKeyboardQueue();
6462 return;
6463
6464 case 14: // <RESERVED>
6465 case 25: // ??
6466 ud.eog = 1;
6467 ps[myconnectindex].gm |= MODE_EOL;
6468 KB_FlushKeyboardQueue();
6469 return;
6470
6471 case 15: // <RESERVED>
6472 ps[myconnectindex].gm = MODE_EOL;
6473 ps[myconnectindex].cheat_phase = 0;
6474 KB_FlushKeyboardQueue();
6475 return;
6476
6477 case 16: // todd
6478 FTA(99,&ps[myconnectindex],1);
6479 ps[myconnectindex].cheat_phase = 0;
6480 KB_FlushKeyboardQueue();
6481 return;
6482
6483 case 17: // showmap
6484 ud.showallmap = 1-ud.showallmap;
6485 if(ud.showallmap)
6486 {
6487 for(i=0;i<(MAXSECTORS>>3);i++)
6488 show2dsector[i] = 255;
6489 for(i=0;i<(MAXWALLS>>3);i++)
6490 show2dwall[i] = 255;
6491 FTA(111,&ps[myconnectindex],1);
6492 }
6493 else
6494 {
6495 for(i=0;i<(MAXSECTORS>>3);i++)
6496 show2dsector[i] = 0;
6497 for(i=0;i<(MAXWALLS>>3);i++)
6498 show2dwall[i] = 0;
6499 FTA(1,&ps[myconnectindex],1);
6500 }
6501 ps[myconnectindex].cheat_phase = 0;
6502 KB_FlushKeyboardQueue();
6503 return;
6504
6505 case 19: // allen
6506 FTA(79,&ps[myconnectindex],1);
6507 ps[myconnectindex].cheat_phase = 0;
6508 KB_ClearKeyDown(sc_N);
6509 return;
6510
6511 case 20: // clip
6512 ud.clipping = 1-ud.clipping;
6513 KB_FlushKeyboardQueue();
6514 ps[myconnectindex].cheat_phase = 0;
6515 FTA(112+ud.clipping,&ps[myconnectindex],1);
6516 return;
6517
6518 case 21: // weapons
6519 if(VOLUMEONE)
6520 j = 6;
6521 else
6522 j = 0;
6523
6524 for ( weapon = PISTOL_WEAPON;weapon < MAX_WEAPONS-j;weapon++ )
6525 {
6526 addammo( weapon, &ps[myconnectindex], max_ammo_amount[weapon] );
6527 ps[myconnectindex].gotweapon[weapon] = 1;
6528 }
6529
6530 KB_FlushKeyboardQueue();
6531 ps[myconnectindex].cheat_phase = 0;
6532 FTA(119,&ps[myconnectindex],1);
6533 return;
6534
6535 case 22: // inventory
6536 KB_FlushKeyboardQueue();
6537 ps[myconnectindex].cheat_phase = 0;
6538 ps[myconnectindex].steroids_amount = 400;
6539 ps[myconnectindex].heat_amount = 1200;
6540 ps[myconnectindex].boot_amount = 200;
6541 ps[myconnectindex].shield_amount = 100;
6542 ps[myconnectindex].scuba_amount = 6400;
6543 ps[myconnectindex].holoduke_amount = 2400;
6544 ps[myconnectindex].jetpack_amount = 1600;
6545 ps[myconnectindex].firstaid_amount = max_player_health;
6546 FTA(120,&ps[myconnectindex],1);
6547 ps[myconnectindex].cheat_phase = 0;
6548 return;
6549
6550 case 23: // keys
6551 ps[myconnectindex].got_access = 7;
6552 KB_FlushKeyboardQueue();
6553 ps[myconnectindex].cheat_phase = 0;
6554 FTA(121,&ps[myconnectindex],1);
6555 return;
6556
6557 case 24: // debug
6558 debug_on = 1-debug_on;
6559 KB_FlushKeyboardQueue();
6560 ps[myconnectindex].cheat_phase = 0;
6561 break;
6562 }
6563 }
6564 }
6565 }
6566
6567 else
6568 {
6569 if( KB_KeyPressed(sc_D) )
6570 {
6571 if( ps[myconnectindex].cheat_phase >= 0 && numplayers < 2 && ud.recstat == 0)
6572 ps[myconnectindex].cheat_phase = -1;
6573 }
6574
6575 if( KB_KeyPressed(sc_N) )
6576 {
6577 if( ps[myconnectindex].cheat_phase == -1 )
6578 {
6579 if(ud.player_skill == 4)
6580 {
6581 FTA(22,&ps[myconnectindex],1);
6582 ps[myconnectindex].cheat_phase = 0;
6583 }
6584 else
6585 {
6586 ps[myconnectindex].cheat_phase = 1;
6587// FTA(25,&ps[myconnectindex]);
6588 cheatbuflen = 0;
6589 }
6590 KB_FlushKeyboardQueue();
6591 }
6592 else if(ps[myconnectindex].cheat_phase != 0)
6593 {
6594 ps[myconnectindex].cheat_phase = 0;
6595 KB_ClearKeyDown(sc_D);
6596 KB_ClearKeyDown(sc_N);
6597 }
6598 }
6599 }
6600}
6601
6602
6603int32_t nonsharedtimer;
6604void nonsharedkeys(void)
6605{
6606 short i,ch;
6607 int32_t j;
6608 char text[512];
6609
6610 if(ud.recstat == 2)
6611 {
6612 ControlInfo noshareinfo;
6613 CONTROL_GetInput( &noshareinfo );
6614 }
6615
6616 if( KB_KeyPressed( sc_F12 ) )
6617 {
6618 KB_ClearKeyDown( sc_F12 );
6619 takescreenshot();
6620 // FTA(103,&ps[myconnectindex]); done better in takescreenshot()
6621 }
6622
6623 if( !ALT_IS_PRESSED && ud.overhead_on == 0)
6624 {
6625 if( ACTION( gamefunc_Enlarge_Screen ) )
6626 {
6627 CONTROL_ClearAction( gamefunc_Enlarge_Screen );
6628 if(ud.screen_size > 0)
6629 sound(THUD);
6630
6631 // FIX_00027: Added an extra small statusbar (HUD)
6632 if (ud.screen_size==4)
6633 {
6634 ud.extended_screen_size++;
6635 if(ud.extended_screen_size==2)
6636 {
6637 ud.extended_screen_size = 1;
6638 ud.screen_size -= 4;
6639 }
6640 }
6641 else
6642 ud.screen_size -= 4;
6643 vscrn();
6644 }
6645 if( ACTION( gamefunc_Shrink_Screen ) )
6646 {
6647 CONTROL_ClearAction( gamefunc_Shrink_Screen );
6648 if(ud.screen_size < 64) sound(THUD);
6649
6650 // FIX_00027: Added an extra small statusbar (HUD)
6651 if (ud.screen_size==4)
6652 {
6653 ud.extended_screen_size--;
6654 if(ud.extended_screen_size<0)
6655 {
6656 ud.extended_screen_size=0;
6657 ud.screen_size += 4;
6658 }
6659 }
6660 else
6661 ud.screen_size += 4;
6662 vscrn();
6663 }
6664
6665 if(ud.screen_size < 4)
6666 ud.extended_screen_size = 1;
6667 else if(ud.screen_size > 4)
6668 ud.extended_screen_size = 0;
6669
6670 }
6671
6672 if( ps[myconnectindex].cheat_phase == 1 || ps[myconnectindex].gm&(MODE_MENU|MODE_TYPE)) return;
6673
6674 if( ACTION(gamefunc_See_Coop_View) && ( ud.coop == 1 || ud.recstat == 2) )
6675 {
6676 CONTROL_ClearAction( gamefunc_See_Coop_View );
6677 screenpeek = connectpoint2[screenpeek];
6678 if(screenpeek == -1) screenpeek = connecthead;
6679 restorepalette = 1;
6680 }
6681
6682 if( ud.multimode > 1 && ACTION(gamefunc_Show_Opponents_Weapon) )
6683 {
6684 CONTROL_ClearAction(gamefunc_Show_Opponents_Weapon);
6685 ud.showweapons = 1-ud.showweapons;
6686 FTA(82-ud.showweapons,&ps[screenpeek],1);
6687 }
6688
6689 if( ACTION(gamefunc_Toggle_Crosshair) )
6690 {
6691 CONTROL_ClearAction(gamefunc_Toggle_Crosshair);
6692 ud.crosshair = 1-ud.crosshair;
6693 FTA(21-ud.crosshair,&ps[screenpeek],1);
6694 }
6695
6696 if(ud.overhead_on && ACTION(gamefunc_Map_Follow_Mode) )
6697 {
6698 CONTROL_ClearAction(gamefunc_Map_Follow_Mode);
6699 ud.scrollmode = 1-ud.scrollmode;
6700 if(ud.scrollmode)
6701 {
6702 ud.folx = ps[screenpeek].oposx;
6703 ud.foly = ps[screenpeek].oposy;
6704 ud.fola = ps[screenpeek].oang;
6705 }
6706 FTA(83+ud.scrollmode,&ps[myconnectindex],1);
6707 }
6708
6709 if( SHIFTS_IS_PRESSED || ALT_IS_PRESSED )
6710 {
6711 i = 0;
6712 if( KB_KeyPressed( sc_F1) ) { KB_ClearKeyDown(sc_F1);i = 1; }
6713 if( KB_KeyPressed( sc_F2) ) { KB_ClearKeyDown(sc_F2);i = 2; }
6714 if( KB_KeyPressed( sc_F3) ) { KB_ClearKeyDown(sc_F3);i = 3; }
6715 if( KB_KeyPressed( sc_F4) ) { KB_ClearKeyDown(sc_F4);i = 4; }
6716 if( KB_KeyPressed( sc_F5) ) { KB_ClearKeyDown(sc_F5);i = 5; }
6717 if( KB_KeyPressed( sc_F6) ) { KB_ClearKeyDown(sc_F6);i = 6; }
6718 if( KB_KeyPressed( sc_F7) ) { KB_ClearKeyDown(sc_F7);i = 7; }
6719 if( KB_KeyPressed( sc_F8) ) { KB_ClearKeyDown(sc_F8);i = 8; }
6720 if( KB_KeyPressed( sc_F9) ) { KB_ClearKeyDown(sc_F9);i = 9; }
6721 if( KB_KeyPressed( sc_F10) ) {KB_ClearKeyDown(sc_F10);i = 10; }
6722
6723 if(i)
6724 {
6725 if(SHIFTS_IS_PRESSED)
6726 {
6727 if(i == 5 && ps[myconnectindex].fta > 0 && ps[myconnectindex].ftq == 26)
6728 {
6729 music_select++;
6730
6731 // FIX_00065: Music cycling with F5 and SHIFT-F5 messed up
6732 if(VOLUMEALL) // Then its 1.3d reg
6733 {
6734 if(music_select == 33) music_select = 0;
6735 }
6736 else if (VOLUMEONE)
6737 {
6738 if(music_select == 6) music_select = 0;
6739 }
6740 else // assume 1.5 or plutopak
6741 {
6742 if(music_select == 44) music_select = 0;
6743 }
6744
6745 strcpy(text,"PLAYING ");
6746 strcat(text,&music_fn[0][music_select][0]);
6747 MUSIC_StopSong(); // FIX_00074: Shift f5 doesn't change hi-res tunes, but only midi tunes.
6748 playmusic(&music_fn[0][music_select][0]);
6749 strcpy(&fta_quotes[26][0],text);
6750 FTA(26,&ps[myconnectindex],1);
6751 return;
6752 }
6753
6754 adduserquote(ud.ridecule[i-1]);
6755
6756 ch = 0;
6757
6758 tempbuf[ch] = 4;
6759 tempbuf[ch+1] = 0;
6760 strcat((char*)tempbuf+1,ud.ridecule[i-1]);
6761
6762 i = 1+strlen(ud.ridecule[i-1]);
6763
6764 if(ud.multimode > 1)
6765 for(ch=connecthead;ch>=0;ch=connectpoint2[ch])
6766 if (ch != myconnectindex)
6767 sendpacket(ch,tempbuf,i);
6768
6769 pus = NUMPAGES;
6770 pub = NUMPAGES;
6771
6772 return;
6773
6774 }
6775
6776 if(ud.lockout == 0)
6777 if(SoundToggle && ALT_IS_PRESSED && ( RTS_NumSounds() > 0 ) && rtsplaying == 0 && VoiceToggle )
6778 {
6779 rtsptr = RTS_GetSound (i-1);
6780 if(*rtsptr == 'C')
6781 FX_PlayVOC3D( rtsptr,0,0,0,255,-i);
6782 else FX_PlayWAV3D( rtsptr,0,0,0,255,-i);
6783
6784 rtsplaying = 7;
6785
6786 if(ud.multimode > 1)
6787 {
6788 tempbuf[0] = 7;
6789 tempbuf[1] = i;
6790
6791 for(ch=connecthead;ch>=0;ch=connectpoint2[ch])
6792 if(ch != myconnectindex)
6793 sendpacket(ch,(uint8_t*)tempbuf,2);
6794 }
6795
6796 pus = NUMPAGES;
6797 pub = NUMPAGES;
6798
6799 return;
6800 }
6801 }
6802 }
6803
6804 if(!ALT_IS_PRESSED && !SHIFTS_IS_PRESSED)
6805 {
6806
6807 if( ud.multimode > 1 && ACTION(gamefunc_SendMessage) )
6808 {
6809 KB_FlushKeyboardQueue();
6810 CONTROL_ClearAction( gamefunc_SendMessage );
6811 ps[myconnectindex].gm |= MODE_TYPE;
6812 typebuf[0] = 0;
6813 inputloc = 0;
6814 }
6815
6816 if( KB_KeyPressed(sc_F1) || ( ud.show_help && ( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) ) ) )
6817 {
6818 KB_ClearKeyDown(sc_F1);
6819 KB_ClearKeyDown(sc_Space);
6820 KB_ClearKeyDown(sc_kpad_Enter);
6821 KB_ClearKeyDown(sc_Enter);
6822 ud.show_help ++;
6823
6824 if( ud.show_help > 2 )
6825 {
6826 ud.show_help = 0;
6827 if(ud.multimode < 2 && ud.recstat != 2) ready2send = 1;
6828 vscrn();
6829 }
6830 else
6831 {
6832 setview(0,0,xdim-1,ydim-1);
6833 if(ud.multimode < 2 && ud.recstat != 2)
6834 {
6835 ready2send = 0;
6836 totalclock = ototalclock;
6837 }
6838 }
6839 }
6840
6841// if(ud.multimode < 2)
6842 {
6843 if(ud.recstat != 2 && KB_KeyPressed( sc_F2 ) )
6844 {
6845 KB_ClearKeyDown( sc_F2 );
6846
6847 if(movesperpacket == 4 && connecthead != myconnectindex)
6848 return;
6849
6850 FAKE_F2:
6851 if(sprite[ps[myconnectindex].i].extra <= 0)
6852 {
6853 FTA(118,&ps[myconnectindex],1);
6854 return;
6855 }
6856 cmenu(350);
6857 screencapt = 1;
6858 displayrooms(myconnectindex,65536);
6859 savetemp("duke3d.tmp",tiles[MAXTILES-1].data,160*100);
6860 screencapt = 0;
6861 FX_StopAllSounds();
6862 clearsoundlocks();
6863
6864// setview(0,0,xdim-1,ydim-1);
6865 ps[myconnectindex].gm |= MODE_MENU;
6866
6867 if(ud.multimode < 2)
6868 {
6869 ready2send = 0;
6870 totalclock = ototalclock;
6871 screenpeek = myconnectindex;
6872 }
6873 }
6874
6875 if(KB_KeyPressed( sc_F3 ))
6876 {
6877 KB_ClearKeyDown( sc_F3 );
6878
6879 if(movesperpacket == 4 && connecthead != myconnectindex)
6880 return;
6881
6882 cmenu(300);
6883 FX_StopAllSounds();
6884 clearsoundlocks();
6885
6886// setview(0,0,xdim-1,ydim-1);
6887 ps[myconnectindex].gm |= MODE_MENU;
6888 if(ud.multimode < 2 && ud.recstat != 2)
6889 {
6890 ready2send = 0;
6891 totalclock = ototalclock;
6892 }
6893 screenpeek = myconnectindex;
6894 }
6895 }
6896
6897 if(KB_KeyPressed( sc_F4 ) && FXDevice != NumSoundCards )
6898 {
6899 KB_ClearKeyDown( sc_F4 );
6900 FX_StopAllSounds();
6901 clearsoundlocks();
6902
6903 ps[myconnectindex].gm |= MODE_MENU;
6904 if(ud.multimode < 2 && ud.recstat != 2)
6905 {
6906 ready2send = 0;
6907 totalclock = ototalclock;
6908 }
6909 cmenu(700);
6910
6911 }
6912
6913 if( KB_KeyPressed( sc_F6 ) && (ps[myconnectindex].gm&MODE_GAME))
6914 {
6915 KB_ClearKeyDown( sc_F6 );
6916
6917 if(movesperpacket == 4 && connecthead != myconnectindex)
6918 return;
6919
6920 if(lastsavedpos == -1) goto FAKE_F2;
6921
6922 KB_FlushKeyboardQueue();
6923
6924 if(sprite[ps[myconnectindex].i].extra <= 0)
6925 {
6926 FTA(118,&ps[myconnectindex],1);
6927 return;
6928 }
6929 screencapt = 1;
6930 displayrooms(myconnectindex,65536);
6931 savetemp("duke3d.tmp",tiles[MAXTILES-1].data,160*100);
6932 screencapt = 0;
6933 if( lastsavedpos >= 0 )
6934 {
6935 inputloc = strlen(&ud.savegame[lastsavedpos][0]);
6936 current_menu = 360+lastsavedpos;
6937 probey = lastsavedpos;
6938 }
6939 FX_StopAllSounds();
6940 clearsoundlocks();
6941
6942 setview(0,0,xdim-1,ydim-1);
6943 ps[myconnectindex].gm |= MODE_MENU;
6944 if(ud.multimode < 2 && ud.recstat != 2)
6945 {
6946 ready2send = 0;
6947 totalclock = ototalclock;
6948 }
6949 }
6950
6951 if(KB_KeyPressed( sc_F7 ) )
6952 {
6953 KB_ClearKeyDown(sc_F7);
6954 if( ps[myconnectindex].over_shoulder_on )
6955 ps[myconnectindex].over_shoulder_on = 0;
6956 else
6957 {
6958 ps[myconnectindex].over_shoulder_on = 1;
6959 cameradist = 0;
6960 cameraclock = totalclock;
6961 }
6962 FTA(109+ps[myconnectindex].over_shoulder_on,&ps[myconnectindex],1);
6963 }
6964
6965 if( KB_KeyPressed( sc_F5 ) && MusicDevice != NumSoundCards )
6966 {
6967 KB_ClearKeyDown( sc_F5 );
6968 strcpy(text,&music_fn[0][music_select][0]);
6969 strcat(text,". USE SHIFT-F5 TO CHANGE.");
6970 strcpy(fta_quotes[26],text);
6971 FTA(26,&ps[myconnectindex],1);
6972
6973 }
6974
6975 if(KB_KeyPressed( sc_F8 ))
6976 {
6977 KB_ClearKeyDown( sc_F8 );
6978 ud.fta_on = !ud.fta_on;
6979 FTA(24-ud.fta_on,&ps[myconnectindex],1);
6980 }
6981
6982 if(KB_KeyPressed( sc_F9 ) && (ps[myconnectindex].gm&MODE_GAME) )
6983 {
6984 KB_ClearKeyDown( sc_F9 );
6985
6986 if(movesperpacket == 4 && myconnectindex != connecthead)
6987 return;
6988
6989 if( lastsavedpos >= 0 ) cmenu(15001);
6990 else cmenu(25000);
6991 FX_StopAllSounds();
6992 clearsoundlocks();
6993 ps[myconnectindex].gm |= MODE_MENU;
6994 if(ud.multimode < 2 && ud.recstat != 2)
6995 {
6996 ready2send = 0;
6997 totalclock = ototalclock;
6998 }
6999 }
7000
7001 if(KB_KeyPressed( sc_F10 ))
7002 {
7003 KB_ClearKeyDown( sc_F10 );
7004 cmenu(500);
7005 FX_StopAllSounds();
7006 clearsoundlocks();
7007 ps[myconnectindex].gm |= MODE_MENU;
7008 if(ud.multimode < 2 && ud.recstat != 2)
7009 {
7010 ready2send = 0;
7011 totalclock = ototalclock;
7012 }
7013 }
7014
7015
7016 if( ud.overhead_on != 0)
7017 {
7018
7019 j = totalclock-nonsharedtimer; nonsharedtimer += j;
7020 if ( ACTION( gamefunc_Enlarge_Screen ) )
7021 ps[myconnectindex].zoom += mulscale6(j,max(ps[myconnectindex].zoom,256));
7022 if ( ACTION( gamefunc_Shrink_Screen ) )
7023 ps[myconnectindex].zoom -= mulscale6(j,max(ps[myconnectindex].zoom,256));
7024
7025 if( (ps[myconnectindex].zoom > 2048) )
7026 ps[myconnectindex].zoom = 2048;
7027 if( (ps[myconnectindex].zoom < 48) )
7028 ps[myconnectindex].zoom = 48;
7029
7030 }
7031 }
7032
7033 if( KB_KeyPressed(sc_Escape) && ud.overhead_on && ps[myconnectindex].newowner == -1 )
7034 {
7035 KB_ClearKeyDown( sc_Escape );
7036 ud.last_overhead = ud.overhead_on;
7037 ud.overhead_on = 0;
7038 ud.scrollmode = 0;
7039 vscrn();
7040 }
7041
7042 if( ACTION(gamefunc_AutoRun) )
7043 {
7044 CONTROL_ClearAction(gamefunc_AutoRun);
7045 ud.auto_run = 1-ud.auto_run;
7046 FTA(85+ud.auto_run,&ps[myconnectindex],1);
7047 }
7048
7049 if( ACTION(gamefunc_Map) )
7050 {
7051 CONTROL_ClearAction( gamefunc_Map );
7052 if( ud.last_overhead != ud.overhead_on && ud.last_overhead)
7053 {
7054 ud.overhead_on = ud.last_overhead;
7055 ud.last_overhead = 0;
7056 }
7057 else
7058 {
7059 ud.overhead_on++;
7060 if(ud.overhead_on == 3 ) ud.overhead_on = 0;
7061 ud.last_overhead = ud.overhead_on;
7062 }
7063 restorepalette = 1;
7064 vscrn();
7065 }
7066
7067 if(KB_KeyPressed( sc_F11 ))
7068 {
7069 KB_ClearKeyDown( sc_F11 );
7070 // FIX_00030: Brightness step was not the same from the keys vs menu
7071 if(SHIFTS_IS_PRESSED) ud.brightness-=8; // Keyboard step must be 8, as the brightness cursor step.
7072 else ud.brightness+=8;
7073
7074 if (ud.brightness > 56 )
7075 ud.brightness = 0;
7076 else if(ud.brightness < 0)
7077 ud.brightness = 56;
7078
7079 setbrightness(ud.brightness>>2,&ps[myconnectindex].palette[0]);
7080 if(ud.brightness < 40) FTA( 29 + (ud.brightness>>3) ,&ps[myconnectindex],1);
7081 else if(ud.brightness < 80) FTA( 96 + (ud.brightness>>3) - 5,&ps[myconnectindex],1);
7082 }
7083}
7084
7085
7086
7087void comlinehelp(char **argv)
7088{
7089 printf("Command line help. %s [/flags...]\n",argv[0]);
7090 puts(" ?, /? This help message");
7091 puts(" /l## Level (1-11)");
7092 puts(" /v# Volume (1-4)");
7093 puts(" /s# Skill (1-4)");
7094 puts(" /r Record demo");
7095 puts(" /dFILE Start to play demo FILE");
7096 puts(" /m No monsters");
7097 puts(" /ns No sound");
7098 puts(" /nm No music");
7099 puts(" /t# Respawn, 1 = Monsters, 2 = Items, 3 = Inventory, x = All");
7100 puts(" /c# MP mode, 1 = DukeMatch(spawn), 2 = Coop, 3 = Dukematch(no spawn)");
7101 puts(" /q# Fake multiplayer (2-8 players)");
7102 puts(" /a Use player AI (fake multiplayer only)");
7103 puts(" /i# Network mode (1/0) (multiplayer only) (default == 1)");
7104 puts(" /f# Send fewer packets (1, 2, 4) (multiplayer only)");
7105 puts(" /gFILE, /g... Use multiple group files (must be last on command line)");
7106 puts(" /xFILE Compile FILE (default GAME.CON)");
7107 puts(" /u######### User's favorite weapon order (default: 3425689071)");
7108 puts(" /# Load and run a game (slot 0-9)");
7109 puts(" /z Skip memory check");
7110 puts(" -map FILE Use a map FILE");
7111 puts(" -name NAME Foward NAME");
7112 puts(" -net Net mode game");
7113 printf("\n");
7114}
7115
7116void checkcommandline(int argc,char **argv)
7117{
7118 short i, j;
7119 char *c;
7120 char kbdKey;
7121
7122 ud.fta_on = 1;
7123 ud.god = 0;
7124 ud.m_respawn_items = 0;
7125 ud.m_respawn_monsters = 0;
7126 ud.m_respawn_inventory = 0;
7127 ud.warp_on = 0;
7128 ud.cashman = 0;
7129 ud.m_player_skill = ud.player_skill = 2;
7130 ud.multimode_bot = 0;
7131
7132#ifdef BETA
7133 return;
7134#endif
7135
7136 printf("Commands: ");
7137 i=1;
7138 while(i < argc)
7139 {
7140 printf("%s ",argv[i]);
7141 i++;
7142 }
7143 printf("\n");
7144
7145 i = 1;
7146
7147 if(argc > 1)
7148 {
7149 while(i < argc)
7150 {
7151 c = argv[i];
7152
7153 if (stricmp(c, "-map") == 0)
7154 {
7155 i++;
7156 strcpy(boardfilename,argv[i]);
7157 if( strchr(boardfilename,'.') == 0)
7158 strcat(boardfilename,".map");
7159 printf("Using level: '%s'.\n",boardfilename);
7160 continue;
7161
7162 }
7163
7164 if (stricmp(c, "-net") == 0)
7165 {
7166 i += 2; // skip filename.
7167 // FIX_00044: Markers are now on by default in netgames (as real DOS duke3d)
7168 ud.m_marker = ud.marker = 1;
7169 continue;
7170 }
7171
7172 if (stricmp(c, "-game_dir") == 0)
7173 {
7174 // Get the file name
7175 i++;
7176 c = argv[i];
7177 setGameDir(c);
7178
7179 // skip over the file name now that we have it.
7180 i++;
7181
7182 continue;
7183 }
7184
7185 if (stricmp(c, "-stun") == 0)
7186 {
7187 g_bStun = 1;
7188
7189 i++;
7190 continue;
7191 }
7192
7193 if (stricmp(c, "/disableautoaim") == 0)
7194 {
7195
7196 printf( "\nThe Host used the /disableautoaim option to turn your Weapon AutoAim OFF\n"
7197 "Playing without AutoAim is usually extremely difficult and can make boring\n"
7198 "games ruining Duke's playability. Duke3D was not designed to play with\n"
7199 "AutoAim OFF like in modern FPS.\n\n"
7200 "Do you authorize the HOST to turn your AutoAim OFF (Y/N)? ");
7201
7202 do
7203 kbdKey = getch()|' ';
7204 while(kbdKey != 'n' && kbdKey != 'y');
7205
7206 printf("%c \n", kbdKey);
7207
7208 if(kbdKey == 'y')
7209 nHostForceDisableAutoaim = 1;
7210 else
7211 nHostForceDisableAutoaim = 2;
7212
7213 i++;
7214 continue;
7215 }
7216
7217 if(*c == '-')
7218 {
7219 if( *(c+1) == '8' ) eightytwofifty = 1;
7220 i++;
7221 continue;
7222 }
7223
7224 if(*c == '?')
7225 {
7226 comlinehelp(argv);
7227 Error(EXIT_SUCCESS, "");
7228 }
7229
7230 if(*c == '/')
7231 {
7232 c++;
7233 switch(*c)
7234 {
7235 case 'x':
7236 case 'X':
7237 c++;
7238 if(*c)
7239 {
7240 if(getGameDir()[0] != '\0'){
7241 sprintf(confilename, "%s\\%s", getGameDir(), c);
7242 }
7243 else{
7244 strcpy(confilename,c);
7245 }
7246
7247 if(SafeFileExists(confilename) == 0){
7248 Error(EXIT_SUCCESS, "Could not find con file '%s'.\n",confilename);
7249 }
7250 else printf("Using con file: '%s'\n",confilename);
7251 }
7252 break;
7253 case 'g':
7254 case 'G':
7255 c++;
7256 if(*c){
7257 char fullpathgrpfile[16]; // 16 not enough
7258 memset(fullpathgrpfile, 0, 16);
7259
7260 if( strchr(c,'.') == 0){
7261 strcat(c,".grp"); // crap!
7262 }
7263
7264 if(getGameDir()[0] != '\0'){
7265 sprintf(fullpathgrpfile, "%s\\%s", getGameDir(), c);
7266 }
7267 else{
7268 strcpy(fullpathgrpfile, c);
7269 }
7270
7271 j = initgroupfile(fullpathgrpfile);
7272 if( j == -1 )
7273 printf("Could not find group file %s.\n",fullpathgrpfile);
7274 }
7275
7276 break;
7277 case 'a':
7278 case 'A':
7279 ud.playerai = 1;
7280 puts("Other player AI.");
7281 break;
7282 case 'n':
7283 case 'N':
7284 c++;
7285 if(*c == 's' || *c == 'S'){
7286 CommandSoundToggleOff = 2;
7287 puts("Sound off.");
7288 }
7289 else
7290 if(*c == 'm' || *c == 'M'){
7291 CommandMusicToggleOff = 1;
7292 puts("Music off.");
7293 }
7294 else{
7295 comlinehelp(argv);
7296 Error(EXIT_SUCCESS, "");
7297 }
7298 break;
7299 case 'i':
7300 case 'I':
7301 c++;
7302 if(*c == '0')
7303 networkmode = 0;
7304 if(*c == '1')
7305 networkmode = 1;
7306 printf("Network Mode %d\n",networkmode);
7307 break;
7308 case 'c':
7309 case 'C':
7310 c++;
7311 if(*c == '1' || *c == '2' || *c == '3' ) // C1 = DM; C2 =COOP
7312 ud.m_coop = *c - '0' - 1; // 0 = DM 1 = COOP
7313 else ud.m_coop = 0;
7314
7315 switch(ud.m_coop)
7316 {
7317 case 0:
7318 puts("Dukematch (spawn).");
7319 break;
7320 case 1:
7321 puts("Cooperative play.");
7322 break;
7323 case 2:
7324 puts("Dukematch (no spawn).");
7325 break;
7326 }
7327
7328 break;
7329 case 'z':
7330 case 'Z':
7331 memorycheckoveride = 1;
7332 break;
7333 case 'f':
7334 case 'F':
7335 c++;
7336 if(*c == '1')
7337 movesperpacket = 1;
7338 if(*c == '2')
7339 movesperpacket = 2;
7340 if(*c == '4')
7341 {
7342 movesperpacket = 4;
7343 setpackettimeout(0x3fffffff,0x3fffffff);
7344 }
7345 break;
7346 case 't':
7347 case 'T':
7348 c++;
7349 if(*c == '1') ud.m_respawn_monsters = 1;
7350 else if(*c == '2') ud.m_respawn_items = 1;
7351 else if(*c == '3') ud.m_respawn_inventory = 1;
7352 else
7353 {
7354 ud.m_respawn_monsters = 1;
7355 ud.m_respawn_items = 1;
7356 ud.m_respawn_inventory = 1;
7357 }
7358 puts("Respawn on.");
7359 break;
7360 case 'm':
7361 case 'M':
7362 if( *(c+1) != 'a' && *(c+1) != 'A' )
7363 {
7364 ud.m_monsters_off = 1;
7365 ud.m_player_skill = ud.player_skill = 0;
7366 puts("Monsters off.");
7367 }
7368 break;
7369 case 'w':
7370 case 'W':
7371 ud.coords = 1;
7372 break;
7373 case 'q':
7374 case 'Q':
7375 puts("Fake multiplayer mode.");
7376 if( *(++c) == 0) ud.multimode_bot = 1;
7377 else ud.multimode_bot = atol(c)%17;
7378 ud.multimode = ud.multimode_bot;
7379 ud.m_coop = ud.coop = 0;
7380 ud.m_marker = ud.marker = 1;
7381 ud.m_respawn_monsters = ud.respawn_monsters = 1;
7382 ud.m_respawn_items = ud.respawn_items = 1;
7383 ud.m_respawn_inventory = ud.respawn_inventory = 1;
7384
7385 break;
7386 case 'r':
7387 case 'R':
7388 ud.m_recstat = 1;
7389 puts("Demo record mode on.");
7390 break;
7391 case 'd':
7392 case 'D':
7393 c++;
7394 if( strchr(c,'.') == 0)
7395 strcat(c,".dmo");
7396 printf("Play demo %s.\n",c);
7397 strcpy(firstdemofile,c);
7398 break;
7399 case 'l':
7400 case 'L':
7401 ud.warp_on = 1;
7402 c++;
7403 ud.m_level_number = ud.level_number = (atol(c)-1)%11;
7404 break;
7405 case 'j':
7406 case 'J':
7407 Error(EXIT_SUCCESS, "This port has a auto adaptive version system. All versions supported, simply change your duke3d.grp\n");
7408 break;
7409
7410 case 'v':
7411 case 'V':
7412 c++;
7413 ud.warp_on = 1;
7414 ud.m_volume_number = ud.volume_number = atol(c)-1;
7415 break;
7416 case 's':
7417 case 'S':
7418 c++;
7419 ud.m_player_skill = ud.player_skill = (atol(c)%5);
7420 if(ud.m_player_skill == 4)
7421 ud.m_respawn_monsters = ud.respawn_monsters = 1;
7422 break;
7423 case '0':
7424 case '1':
7425 case '2':
7426 case '3':
7427 case '4':
7428 case '5':
7429 case '6':
7430 case '7':
7431 case '8':
7432 case '9':
7433 ud.warp_on = 2 + (*c) - '0';
7434 break;
7435 case 'u':
7436 case 'U':
7437 c++;
7438 j = 0;
7439 if(*c)
7440 {
7441 puts("Using favorite weapon order(s).");
7442 while(*c)
7443 {
7444 ud.mywchoice[j] = *c-'0';
7445 c++;
7446 j++;
7447 }
7448 while(j < 10)
7449 {
7450 if(j == 9)
7451 ud.mywchoice[9] = 1;
7452 else
7453 ud.mywchoice[j] = 2;
7454
7455 j++;
7456 }
7457 }
7458 else
7459 {
7460 puts("Using default weapon orders.");
7461 }
7462
7463 break;
7464
7465 case '?': // Show help
7466 default:
7467
7468 comlinehelp(argv);
7469 Error(EXIT_SUCCESS, "");
7470 break;
7471 }
7472 }
7473 i++;
7474 }
7475 }
7476}
7477
7478
7479
7480void printstr(short x, short y, uint8_t string[81], uint8_t attribute)
7481{
7482 uint8_t character;
7483 short i, pos;
7484
7485 pos = (y*80+x)<<1;
7486 i = 0;
7487 while (string[i] != 0)
7488 {
7489 character = string[i];
7490 printchrasm(0xb8000+(int32_t)pos,1L,(((int32_t)attribute<<8)+(int32_t)character));
7491 i++;
7492 pos+=2;
7493 }
7494}
7495
7496void Logo(void)
7497{
7498 short i,soundanm;
7499
7500 soundanm = 0;
7501
7502 ready2send = 0;
7503
7504 KB_FlushKeyboardQueue();
7505
7506 setview(0,0,xdim-1,ydim-1);
7507 clearview(0L);
7508 palto(0,0,0,63);
7509
7510 flushperms();
7511 nextpage();
7512
7513 MUSIC_StopSong();
7514
7515 if(ud.showcinematics && numplayers < 2)
7516 {
7517 ////This plays the explosion from the nuclear sign at the beginning.
7518 if(!VOLUMEONE)
7519 {
7520 if(!KB_KeyWaiting() && nomorelogohack == 0)
7521 {
7522 getpackets();
7523
7524#if 1
7525 playanm("logo.anm",5);
7526 palto(0,0,0,63);
7527#endif
7528
7529#if 0
7530 playanm("cineov2.anm",1);
7531 clearview(0L);
7532 nextpage();
7533 playanm("vol4e1.anm",8);
7534 clearview(0L);
7535 nextpage();
7536 playanm("vol4e2.anm",10);
7537 clearview(0L);
7538 nextpage();
7539 playanm("vol4e3.anm",11);
7540 clearview(0L);
7541 nextpage();
7542 playanm("DUKETEAM.ANM",4);
7543 clearview(0L);
7544 nextpage();
7545 playanm("cineov3.anm",2);
7546 clearview(0L);
7547 nextpage();
7548 playanm("RADLOGO.ANM",3);
7549 clearview(0L);
7550 nextpage();
7551
7552 playanm("vol41a.anm",6);
7553 clearview(0L);
7554 nextpage();
7555 playanm("vol42a.anm",7);
7556 clearview(0L);
7557 nextpage();
7558 playanm("vol43a.anm",9);
7559 clearview(0L);
7560 nextpage();
7561#endif
7562
7563 KB_FlushKeyboardQueue();
7564 }
7565
7566 clearview(0L);
7567 nextpage();
7568 }
7569
7570 //MIDI start here
7571 playmusic(&env_music_fn[0][0]);
7572
7573 //"REALITY IS OUR GAME" Screen
7574 for(i=0;i<64;i+=7)
7575 palto(0,0,0,i);
7576 ps[myconnectindex].palette = drealms;
7577 palto(0,0,0,63);
7578 rotatesprite(0,0,65536L,0,DREALMS,0,0,2+8+16+64, 0,0,xdim-1,ydim-1);
7579 nextpage();
7580 for(i=63;i>0;i-=7)
7581 palto(0,0,0,i);
7582
7583
7584
7585 totalclock = 0;
7586 while( totalclock < (120*7) && !KB_KeyWaiting() )
7587 getpackets();
7588
7589
7590
7591
7592
7593 for(i=0;i<64;i+=7)
7594 palto(0,0,0,i);
7595 clearview(0L);
7596 nextpage();
7597 ps[myconnectindex].palette = titlepal;
7598 flushperms();
7599 rotatesprite(0,0,65536L,0,BETASCREEN,0,0,2+8+16+64,0,0,xdim-1,ydim-1);
7600 KB_FlushKeyboardQueue();
7601 nextpage();
7602 for(i=63;i>0;i-=7)
7603 palto(0,0,0,i);
7604
7605 totalclock = 0;
7606
7607 //Animate screen (Duke picture wiht "DUKE" "NUKEM 3D" coming from far away and hitting the screen"
7608 while(totalclock < (860+120) && !KB_KeyWaiting())
7609 {
7610 rotatesprite(0,0,65536L,0,BETASCREEN,0,0,2+8+16+64,0,0,xdim-1,ydim-1);
7611
7612 if( totalclock > 120 && totalclock < (120+60) )
7613 {
7614 if(soundanm == 0)
7615 {
7616 soundanm = 1;
7617 sound(PIPEBOMB_EXPLODE);
7618 }
7619 rotatesprite(160<<16,104<<16,(totalclock-120)<<10,0,DUKENUKEM,0,0,2+8,0,0,xdim-1,ydim-1);
7620 }
7621 else if( totalclock >= (120+60) )
7622 rotatesprite(160<<16,(104)<<16,60<<10,0,DUKENUKEM,0,0,2+8,0,0,xdim-1,ydim-1);
7623
7624 if( totalclock > 220 && totalclock < (220+30) )
7625 {
7626 if( soundanm == 1)
7627 {
7628 soundanm = 2;
7629 sound(PIPEBOMB_EXPLODE);
7630 }
7631
7632 rotatesprite(160<<16,(104)<<16,60<<10,0,DUKENUKEM,0,0,2+8,0,0,xdim-1,ydim-1);
7633 rotatesprite(160<<16,(129)<<16,(totalclock - 220 )<<11,0,THREEDEE,0,0,2+8,0,0,xdim-1,ydim-1);
7634 }
7635 else if( totalclock >= (220+30) )
7636 rotatesprite(160<<16,(129)<<16,30<<11,0,THREEDEE,0,0,2+8,0,0,xdim-1,ydim-1);
7637
7638 if(PLUTOPAK) // FIX_00064: Cinematics explosions were not right for 1.3/1.3d grp.
7639 {
7640
7641 if( totalclock >= 280 && totalclock < 395 )
7642 {
7643 rotatesprite(160<<16,(151)<<16,(410-totalclock)<<12,0,PLUTOPAKSPRITE+1,0,0,2+8,0,0,xdim-1,ydim-1);
7644 if(soundanm == 2)
7645 {
7646 soundanm = 3;
7647 sound(FLY_BY);
7648 }
7649 }
7650 else if( totalclock >= 395 )
7651 {
7652 if(soundanm == 3)
7653 {
7654 soundanm = 4;
7655 sound(PIPEBOMB_EXPLODE);
7656 }
7657 rotatesprite(160<<16,(151)<<16,30<<11,0,PLUTOPAKSPRITE+1,0,0,2+8,0,0,xdim-1,ydim-1);
7658 }
7659 }
7660
7661 getpackets();
7662 nextpage();
7663 }
7664 // FIX_00077: Menu goes directly to the "NEW GAME" sub-menu when starting new game (Turrican)
7665 KB_FlushKeyboardQueue();
7666 }
7667 else if(numplayers > 1)
7668 {
7669 // FIX_00079: "waiting player" screen not showing up (black screen)
7670 playmusic(&env_music_fn[0][0]);
7671
7672 ps[myconnectindex].palette = titlepal;
7673 for(i=63;i>0;i-=7) palto(0,0,0,i);
7674
7675 rotatesprite(0,0,65536L,0,BETASCREEN,0,0,2+8+16+64,0,0,xdim-1,ydim-1);
7676 rotatesprite(160<<16,(104)<<16,60<<10,0,DUKENUKEM,0,0,2+8,0,0,xdim-1,ydim-1);
7677 rotatesprite(160<<16,(129)<<16,30<<11,0,THREEDEE,0,0,2+8,0,0,xdim-1,ydim-1);
7678 rotatesprite(160<<16,(151)<<16,30<<11,0,PLUTOPAKSPRITE+1,0,0,2+8,0,0,xdim-1,ydim-1);
7679
7680 gametext(160,190,"WAITING FOR PLAYERS",14,2);
7681 nextpage();
7682 }
7683 else
7684 {
7685 // FIX_00091: Main theme starting too early (Bryzian/Turrican)
7686 playmusic(&env_music_fn[0][0]);
7687 }
7688
7689 waitforeverybody();
7690
7691 flushperms();
7692 clearview(0L);
7693 nextpage();
7694
7695 ps[myconnectindex].palette = palette;
7696 sound(NITEVISION_ONOFF);
7697
7698 palto(0,0,0,0);
7699 clearview(0L);
7700}
7701
7702void loadtmb(void)
7703{
7704 uint8_t tmb[8000];
7705 int32_t fil, l;
7706
7707 fil = kopen4load("d3dtimbr.tmb",0);
7708
7709 if(fil == -1)
7710 return;
7711
7712 l = kfilelength(fil);
7713
7714 kread(fil,(uint8_t *)tmb,l);
7715
7716 MUSIC_RegisterTimbreBank(tmb);
7717
7718 kclose(fil);
7719}
7720
7721/*
7722 ===================
7723 =
7724 = ShutDown
7725 =
7726 ===================
7727*/
7728
7729void ShutDown( void )
7730{
7731 SoundShutdown();
7732 MusicShutdown();
7733 uninittimer();
7734 uninitengine();
7735 CONTROL_Shutdown();
7736 CONFIG_WriteSetup();
7737 KB_Shutdown();
7738 CONSOLE_Term();
7739}
7740
7741
7742/*
7743 ===================
7744 =
7745 = Startup
7746 =
7747 ===================
7748*/
7749
7750void compilecons(void)
7751{
7752 char userconfilename[512];
7753
7754 mymembuf = (char *)hittype;
7755 labelcode = (int32_t *)&sector[0];
7756 label = (char *)sprite;
7757
7758 sprintf(userconfilename, "%s", confilename);
7759
7760 loadefs(userconfilename,mymembuf, 0);
7761
7762}
7763
7764
7765void Startup(void)
7766{
7767 int i;
7768
7769 // Init the Console
7770 CONSOLE_Init();
7771
7772 KB_Startup();
7773
7774 CONFIG_GetSetupFilename();
7775 CONFIG_ReadSetup();
7776
7777 compilecons();
7778
7779#ifdef AUSTRALIA
7780 ud.lockout = 1;
7781#endif
7782
7783 if(CommandSoundToggleOff) SoundToggle = 0;
7784 if(CommandMusicToggleOff) MusicToggle = 0;
7785
7786//if(VOLUMEONE)
7787//{
7788// printf("\n*** You have run Duke Nukem 3D %ld times. ***\n",ud.executions);
7789// if(ud.executions >= 50) puts("IT IS NOW TIME TO UPGRADE TO THE COMPLETE VERSION!!!\n");
7790//}
7791
7792 CONTROL_Startup( ControllerType, &GetTime, TICRATE );
7793
7794// CTW - MODIFICATION
7795// initengine(ScreenMode,ScreenWidth,ScreenHeight);
7796 initengine();
7797// CTW END - MODIFICATION
7798 inittimer(TICRATE);
7799
7800 puts("Loading art header.");
7801
7802 loadpics("tiles000.art", "\0");
7803
7804 readsavenames();
7805
7806 tiles[MIRROR].dim.width = tiles[MIRROR].dim.height = 0;
7807
7808 for(i=0;i<MAXPLAYERS;i++) playerreadyflag[i] = 0;
7809 initmultiplayers(0,0,0);
7810
7811 if(numplayers > 1)
7812 puts("Multiplayer initialized.");
7813
7814 ps[myconnectindex].palette = (uint8_t *) &palette[0];
7815 SetupGameButtons();
7816
7817 if(networkmode == 255)
7818 networkmode = 1;
7819
7820#ifdef PLATFORM_DOS
7821 puts("Checking music inits.");
7822 MusicStartup();
7823 puts("Checking sound inits.");
7824 SoundStartup();
7825#else
7826 /* SBF - wasn't sure if swapping them would harm anything. */
7827 puts("Checking sound inits.");
7828 SoundStartup();
7829 puts("Checking music inits.");
7830 MusicStartup();
7831#endif
7832
7833 // AutoAim
7834 if(nHostForceDisableAutoaim)
7835 ud.auto_aim = 0;
7836
7837 puts("loadtmb()");
7838 loadtmb();
7839}
7840
7841
7842void sendscore(char *s)
7843{
7844 if(numplayers > 1)
7845 genericmultifunction(-1,s,strlen(s)+1,5);
7846}
7847
7848
7849void getnames(void)
7850{
7851 short i,j,l;
7852
7853 // FIX_00031: Names now limited to 10 chars max that is the fragbar field limit.
7854 for(l=0; l<=9 && myname[l];l++)
7855 {
7856 ud.user_name[myconnectindex][l] = toupper(myname[l]);
7857 buf[l+2] = toupper(myname[l]);
7858 }
7859
7860#ifdef CHECK_XDUKE_REV // must not be under "if(numplayers > 1)" so it runs in any case
7861 ud.rev[myconnectindex][0] = true; // always true. Used to check who we validated
7862 ud.rev[myconnectindex][1] = DUKE_ID;
7863 ud.rev[myconnectindex][2] = CHOCOLATE_DUKE_REV_X;
7864 ud.rev[myconnectindex][3] = CHOCOLATE_DUKE_REV_DOT_Y;
7865#endif
7866
7867 memcpy(ud.groupefil_crc32[myconnectindex],groupefil_crc32, sizeof(groupefil_crc32));
7868 ud.conSize[myconnectindex] = ud.conSize[0]; // [0] still containing the original value
7869 ud.conCRC[myconnectindex] = ud.conCRC[0];
7870 ud.exeCRC[myconnectindex] = ud.exeCRC[0];
7871
7872 if(numplayers > 1)
7873 {
7874
7875 buf[0] = 6;
7876 buf[1] = grpVersion;
7877
7878 buf[l+2] = 0;
7879 l += 3;
7880
7881 for(i=connecthead;i>=0;i=connectpoint2[i])
7882 if( i != myconnectindex )
7883 sendpacket(i,(uint8_t*)buf,l);
7884
7885 if(nHostForceDisableAutoaim==2) // user doesn't want AA off.
7886 for(i=connecthead;i>=0;i=connectpoint2[i])
7887 {
7888 buf[0] = 133; // request to stop the game.
7889 sendpacket(i,(uint8_t*)buf,l);
7890 }
7891
7892
7893#ifdef CHECK_XDUKE_REV
7894 buf[0] = 131; // xDuke TAG ID
7895 buf[1] = ud.rev[myconnectindex][1];
7896 buf[2] = ud.rev[myconnectindex][2]; // version x
7897 buf[3] = ud.rev[myconnectindex][3]; // version .y
7898
7899 buf[4] = 0; // reserved
7900 buf[5] = 0; // reserved...
7901 buf[9] = 0; // reserved.
7902 // See below for single player mode.
7903
7904 for(i=connecthead;i>=0;i=connectpoint2[i])
7905 if( i != myconnectindex )
7906 sendpacket(i,&buf[0],10);
7907#endif
7908
7909 // getpackets();
7910
7911
7912 l = 1;
7913 buf[0] = 9; // send weapon order
7914
7915 for(i=0;i<10;i++)
7916 {
7917 ud.wchoice[myconnectindex][i] = ud.mywchoice[i];
7918 buf[l] = (uint8_t ) ud.mywchoice[i];
7919 l++;
7920 }
7921
7922 for(i=connecthead;i>=0;i=connectpoint2[i])
7923 if(i != myconnectindex)
7924 sendpacket(i,(uint8_t*)&buf[0],11);
7925
7926 buf[0] = 134; // GRP CRC + CON SIZE + conCRC + exeCRC
7927 memcpy(buf+1, groupefil_crc32, sizeof(groupefil_crc32));
7928 memcpy(buf+1+sizeof(groupefil_crc32), ud.conSize, sizeof(ud.conSize[0]));
7929 memcpy(buf+1+sizeof(groupefil_crc32)+sizeof(ud.conSize[0]), ud.conCRC, sizeof(ud.conCRC[0]));
7930 memcpy(buf+1+sizeof(groupefil_crc32)+sizeof(ud.conSize[0])+sizeof(ud.conCRC[0]), ud.exeCRC, sizeof(ud.exeCRC[0]));
7931
7932 for(i=connecthead;i>=0;i=connectpoint2[i])
7933 if( i != myconnectindex )
7934 sendpacket(i,(uint8_t*)buf,1+sizeof(groupefil_crc32)+sizeof(ud.conSize[0])+sizeof(ud.conCRC[0])+
7935 sizeof(ud.exeCRC[0]));
7936
7937// getpackets();
7938
7939 buf[0] = 10;
7940 buf[1] = ps[0].aim_mode;
7941 ps[myconnectindex].aim_mode = ps[0].aim_mode;
7942
7943 for(i=connecthead;i>=0;i=connectpoint2[i])
7944 if(i != myconnectindex)
7945 sendpacket(i,(uint8_t*)buf,2);
7946
7947// getpackets();
7948
7949 if(cp == 0)
7950 {
7951 buf[0] = 125;
7952
7953 for(i=connecthead;i>=0;i=connectpoint2[i])
7954 if(i != myconnectindex)
7955 sendpacket(i,(uint8_t*)buf,1);
7956 }
7957
7958// getpackets();
7959
7960 waitforeverybody();
7961
7962#ifdef CHECK_XDUKE_REV
7963 // from command "case 131:"
7964 for(l=0,i=connecthead;i>=0;i=connectpoint2[i])
7965 if(((ud.rev[i][2]<<8)+ud.rev[i][3]) != ((CHOCOLATE_DUKE_REV_X<<8)+CHOCOLATE_DUKE_REV_DOT_Y))
7966 l=1;
7967 else
7968 ud.rev[i][0] = true; // means we validated this guy
7969
7970 if(l)
7971 {
7972 printf("\n*** One or more players do not have the same xDuke version:\n\n");
7973 for(l=0,i=connecthead;i>=0;i=connectpoint2[i])
7974 printf("Player [%-10s] is using Chocolate DukeNukem3D v%d.%d\n", ud.user_name[i],
7975 ud.rev[i][2],ud.rev[i][3]);
7976 Error(EXIT_SUCCESS, "");
7977 }
7978#endif
7979
7980 // checking GRP/CON size from "case 134"
7981 for(l=0,i=connecthead;i>=0;i=connectpoint2[i])
7982 for(j=0; j<MAXGROUPFILES; j++)
7983 {
7984 if(ud.groupefil_crc32[i][j]!=ud.groupefil_crc32[myconnectindex][j] || ud.conSize[i] != ud.conSize[myconnectindex])
7985 l=1;
7986 }
7987
7988 if(l)
7989 {
7990 printf("\n*** One or more players do not have the same GRP/CON version:\n\n");
7991 for(i=connecthead;i>=0;i=connectpoint2[i])
7992 {
7993 for(j=0; j<MAXGROUPFILES && ud.groupefil_crc32[i][j]; j++)
7994 {
7995 if(j)
7996 printf(" GRP (Add-on) : %s CRC=%X\n",
7997 grpVersion2char_from_crc(ud.groupefil_crc32[i][j]),
7998 ud.groupefil_crc32[i][j]);
7999 else
8000 printf("Player [%-10s] GRP (base) : %s CRC=%X\n", ud.user_name[i],
8001 grpVersion2char_from_crc(ud.groupefil_crc32[i][j]),
8002 ud.groupefil_crc32[i][j]);
8003 }
8004 printf(" CON code size: %d\n\n",ud.conSize[i]);
8005 }
8006 Error(EXIT_SUCCESS, "");
8007 }
8008 }
8009 else if(nHostForceDisableAutoaim==2)
8010 {
8011 nHostForceDisableAutoaim=0;
8012 ud.auto_aim = 2;
8013 }
8014
8015 if(cp == 1)
8016 gameexit("Please put Duke Nukem 3D Atomic Edition CD in drive.");
8017}
8018
8019
8020const char* const baseDir="duke3d*.grp";
8021#ifdef _WIN32
8022
8023void findGRPToUse(uint8_t * groupfilefullpath)
8024{
8025 WIN32_FIND_DATA FindFileData;
8026 HANDLE hFind = INVALID_HANDLE_VALUE;
8027 int i=0,kbdKey ;
8028 char groupfile[9][512];
8029 int grpID ;
8030
8031 if(getGameDir()[0] != '\0')
8032 {
8033 sprintf(groupfilefullpath, "%s\\%s", getGameDir(), baseDir);
8034 hFind = FindFirstFile(groupfilefullpath, &FindFileData);
8035 if (hFind == INVALID_HANDLE_VALUE)
8036 {
8037 sprintf(groupfilefullpath, "%s", baseDir);
8038 }
8039 else
8040 FindClose(hFind);
8041 }
8042 else
8043 sprintf(groupfilefullpath, "%s", baseDir);
8044
8045 printf("Searching '%d':\n\n",groupfilefullpath);
8046 hFind = FindFirstFile(groupfilefullpath,&FindFileData);
8047
8048 if ( hFind==INVALID_HANDLE_VALUE )
8049 Error(EXIT_SUCCESS, "Can't find '%s'\n", groupfilefullpath);
8050
8051 do
8052 {
8053 i++;
8054 sprintf(groupfile[i-1], "%s", FindFileData.cFileName);
8055 printf("Found GRP #%d:\t%d Bytes\t %s \n", i, FindFileData.nFileSizeLow, groupfile[i-1]);
8056 } while ( FindNextFile(hFind, &FindFileData) && i < 9 );
8057
8058 if(i==1)
8059 grpID = 0;
8060 else
8061 {
8062 printf("\n-> Choose a base GRP file from 1 to %c: ",'0' + i);
8063 do
8064 kbdKey = getch();
8065 while(kbdKey < '1' || kbdKey > ('0' + i));
8066 printf("%c\n", kbdKey);
8067 grpID = groupfile[kbdKey-'1'];
8068
8069 }
8070
8071 FindClose(hFind);
8072 if (strlen(getGameDir()) == 0)
8073 sprintf(groupfilefullpath, "./%s", groupfile[grpID]);
8074 else
8075 sprintf(groupfilefullpath, "%s//%s", getGameDir(), groupfile[grpID]);
8076}
8077
8078#else
8079
8080int dukeGRP_Match(char* filename,int length)
8081{
8082 char* cursor = filename+length-4;
8083
8084 if (strncasecmp(cursor,".grp",4))
8085 return 0;
8086
8087 return !strncasecmp(filename,"duke3d",6);
8088}
8089
8090
8091void findGRPToUse(char * groupfilefullpath){
8092
8093 char directoryToScan[512];
8094 struct dirent* dirEntry ;
8095
8096 directoryToScan[0] = '\0';
8097
8098 if (getGameDir()[0] != '\0')
8099 {
8100 strcat(directoryToScan,getGameDir());
8101 if (directoryToScan[strlen(directoryToScan)-1] != '/')
8102 strcat(directoryToScan,"/");
8103 }
8104 else{
8105 strcat(directoryToScan, "/");
8106 }
8107
8108 printf("Scanning directory '%s' for a GRP file like '%s'.\n",directoryToScan,baseDir);
8109
8110 DIR* dir = opendir(directoryToScan);
8111
8112 while ((dirEntry = readdir(dir)) != NULL)
8113 {
8114
8115#ifdef __linux__
8116 if (dukeGRP_Match(dirEntry->d_name, _D_EXACT_NAMLEN(dirEntry)))
8117#else
8118 if (dukeGRP_Match(dirEntry->d_name,strlen(dirEntry->d_name)))
8119#endif
8120 {
8121 sprintf(groupfilefullpath,"%s%s",directoryToScan,dirEntry->d_name);
8122 return;
8123 }
8124
8125 }
8126}
8127
8128#endif
8129
8130static int load_duke3d_groupfile(void)
8131{
8132 // FIX_00032: Added multi base GRP manager. Use duke3d*.grp to handle multiple grp.
8133
8134 char groupfilefullpath[512];
8135 groupfilefullpath[0] = '\0';
8136
8137 findGRPToUse(groupfilefullpath);
8138
8139 if (groupfilefullpath[0] == '\0')
8140 return false;
8141
8142
8143 FixFilePath(groupfilefullpath);
8144
8145 return(initgroupfile(groupfilefullpath) != -1);
8146}
8147
8148#ifdef COMBINED_SDL
8149#define main duke3d_main
8150#else
8151#define main my_main
8152#endif
8153
8154int main(int argc,char **argv)
8155{
8156 int32_t i, j;
8157 int32_t filehandle;
8158
8159
8160 uint8_t kbdKey;
8161 uint8_t *exe;
8162
8163
8164 //printf( "This is a debug version 19.7.1 only Based on 19.7\n"
8165 // "Fully compliant with v19.7. Added the following:\n\n"
8166 // "FIX_00086: grp loaded by smaller sucessive chunks to avoid\n"
8167 // " overloading low ram computers (Spanator)\n"
8168 // "FIX_00087: intro in 1024x768 mode being slow. Undone FIX_00070\n"
8169 // " and fixed font issue again (Bryzian)\n"
8170 // "FIX_00088: crash on maps using a bad palette index like the end\n"
8171 // " of roch3.map (NY00123)\n"
8172 // "FIX_00089: scoreboard not shown for last player who quits a DM.\n"
8173 // " Only 19.7 affected. (Sarah)\n"
8174 // "FIX_00090: Removed showinfo key. FPS were shown after CRC msg. \n"
8175 // " CRC not always removed. (Turrican)\n"
8176 // "FIX_00091: Main theme starting too early (Bryzian/Turrican)\n"
8177 // "FIX_00092: corrupted saved files making the following saved\n"
8178 // " files invisible (Bryzian)\n\n"
8179 // "This version should not be distributed. It's not secret but it\n"
8180 // "would create a bad mess in the duke community if people start\n"
8181 // "using it as it may contain new unsuspected bugs. Only a select\n"
8182 // "group of known dukers who know what they are doing should be using\n"
8183 // "it. Please report new bugs at xd@m-klein.com or on DX forums. Thx!\n\n");
8184
8185 printf("*** Chocolate DukeNukem3D v%d.%d ***\n\n", CHOCOLATE_DUKE_REV_X, CHOCOLATE_DUKE_REV_DOT_Y);
8186
8187 // FIX_00033: Fake multi and AI are now fully working
8188 ud.multimode = 1; // xduke: must be done before checkcommandline or that will prevent Fakeplayer and AI
8189
8190 if (!load_duke3d_groupfile())
8191 {
8192 Error(EXIT_SUCCESS, "Could not initialize any original BASE duke3d*.grp file\n"
8193 "Even if you are playing a custom GRP you still need\n"
8194 "an original base GRP file as Shareware/Full 1.3D GRP or\n"
8195 "the v1.5 ATOMIC GRP file. Such a file seems to be missing\n"
8196 "or is corrupted\n");
8197 }
8198
8199 rb->splashf(0, "point 1");
8200 // FIX_00022: Automatically recognize the shareware grp (v1.3) + full version (1.3d) +
8201 // atomic (1.4/1.5 grp) and the con files version (either 1.3 or 1.4) (JonoF's idea)
8202
8203 // Detecting grp version
8204 // We keep the old GRP scheme detection for 19.6 compliance. Will be obsolete.
8205 filehandle = kopen4load("DUKEDC9.MAP",1);
8206 kclose(filehandle);
8207
8208 rb->splashf(0, "point 2");
8209 if (filehandle == -1) // not DC pack
8210 {
8211 rb->splashf(0, "point 3");
8212 filehandle = kopen4load("DUKESW.BIN",1);
8213 kclose(filehandle);
8214 rb->splashf(0, "point 4");
8215
8216 if (filehandle == -1) // not Shareware version 1.3
8217 {
8218 rb->splashf(0, "point 5");
8219 filehandle = kopen4load("E4L11.MAP",1);
8220 kclose(filehandle);
8221 rb->splashf(0, "point 6");
8222
8223 if (filehandle == -1) // not Atomic Edition 1.4/1.5
8224 {
8225 rb->splashf(0, "point 7");
8226 filehandle = kopen4load("E3L11.MAP",1);
8227 kclose(filehandle);
8228
8229 rb->splashf(0, "point 8");
8230
8231 if (filehandle == -1) // not Regular version 1.3d
8232 {
8233 grpVersion = UNKNOWN_GRP;
8234 }
8235 else
8236 {
8237 grpVersion = REGULAR_GRP13D;
8238 }
8239 }
8240 else
8241 {
8242 grpVersion = ATOMIC_GRP14_15;
8243 }
8244 }
8245 else
8246 {
8247 grpVersion = SHAREWARE_GRP13;
8248 }
8249 }
8250 else
8251 {
8252 grpVersion = DUKEITOUTINDC_GRP;
8253 }
8254
8255 rb->splashf(0, "point 9");
8256 // FIX_00062: Better support and identification for GRP and CON files for 1.3/1.3d/1.4/1.5
8257 if ( groupefil_crc32[0]==CRC_BASE_GRP_SHAREWARE_13 ||
8258 groupefil_crc32[0]==CRC_BASE_GRP_FULL_13 ||
8259 groupefil_crc32[0]==CRC_BASE_GRP_PLUTONIUM_14 ||
8260 groupefil_crc32[0]==CRC_BASE_GRP_ATOMIC_15 )
8261 {
8262 rb->splashf(0, "point 10");
8263 printf("GRP identified as: %s\n", grpVersion2char_from_crc(groupefil_crc32[0]));
8264 }
8265 else
8266 {
8267 rb->splashf(0, "point 11");
8268 printf( "The content of your original BASE *.GRP is corrupted. CRC=%X\n"
8269 "You may run in troubles. Official GRP are:\n\n", groupefil_crc32[0]);
8270
8271 for(i=0; i<MAX_KNOWN_GRP; i++)
8272 printf("%s -> CRC32=%X Size=%d bytes\n", crc32lookup[i].name, crc32lookup[i].crc32, crc32lookup[i].size);
8273
8274 printf( "\nYou should try to get one of these GRP only as a base GRP\n"
8275 "Do you want to continue anyway? (Y/N): ");
8276 do
8277 kbdKey = getch() | ' ';
8278 while(kbdKey != 'y' && kbdKey != 'n');
8279 printf("%c\n", kbdKey);
8280
8281 if(kbdKey == 'n')
8282 Error(EXIT_SUCCESS,"");
8283 }
8284
8285 // computing exe crc
8286 ud.exeCRC[0] = 0;
8287 exe = NULL;
8288 //filehandle = open(argv[0],O_BINARY|O_RDONLY);
8289 filehandle = -1;
8290 if(filehandle!=-1)
8291 {
8292 exe = malloc(filelength(filehandle));
8293 if(exe)
8294 {
8295 read(filehandle, exe, filelength(filehandle));
8296 ud.exeCRC[0] = crc32_update(exe, filelength(filehandle), ud.exeCRC[0]);
8297 free(exe);
8298 }
8299 close(filehandle);
8300 }
8301
8302 checkcommandline(argc,argv);
8303
8304 _platform_init(argc, argv, "Duke Nukem 3D", "Duke3D");
8305
8306 totalmemory = Z_AvailHeap();
8307
8308 if(memorycheckoveride == 0)
8309 {
8310 if(totalmemory < (3162000-350000))
8311 {
8312 puts("You don't have enough free memory to run Duke Nukem 3D.");
8313 puts("The DOS \"mem\" command should report 6,800K (or 6.8 megs)");
8314 puts("of \"total memory free\".\n");
8315 printf("Duke Nukem 3D requires %d more bytes to run.\n",3162000-350000-totalmemory);
8316 Error(EXIT_SUCCESS, "");
8317 }
8318 }
8319 else
8320 printf("Using %d bytes for heap.\n",totalmemory);
8321
8322 RegisterShutdownFunction( ShutDown );
8323
8324 Startup();
8325
8326 if( eightytwofifty && numplayers > 1 && (MusicDevice != NumSoundCards) )
8327 {
8328 puts("\n=========================================================================");
8329 puts("WARNING: 8250 UART detected.");
8330 puts("Music is being disabled and lower quality sound is being set. We apologize");
8331 puts("for this, but it is necessary to maintain high frame rates while trying to");
8332 puts("play the game on an 8250. We suggest upgrading to a 16550 or better UART");
8333 puts("for maximum performance. Press any key to continue.");
8334 puts("=========================================================================\n");
8335
8336 while( !KB_KeyWaiting() ) getpackets();
8337 }
8338
8339 if(g_bStun)
8340 {
8341 waitforeverybody();
8342 }
8343
8344 if(numplayers > 1) // if multimode > 1 and numplayer == 1 => fake player mode on
8345 {
8346 ud.multimode = numplayers;
8347 sendlogon();
8348 }
8349 else if(boardfilename[0] != 0)
8350 {
8351 ud.m_level_number = 7;
8352 ud.m_volume_number = 0;
8353 ud.warp_on = 1;
8354 }
8355
8356 /* crashes */
8357 //rb->sleep(HZ/5);
8358 ud.last_level = -1;
8359
8360 getnames();
8361
8362 //if(ud.multimode > 1)
8363 //{
8364 // playerswhenstarted = ud.multimode;
8365
8366 // AddFaz fix.
8367 // This would cause monsters not to spawn when loading a usermap
8368 /*
8369 if(ud.warp_on == 0)
8370 {
8371 ud.m_monsters_off = 1;
8372 ud.m_player_skill = 0;
8373 }
8374 */
8375//}
8376
8377
8378 RTS_Init(ud.rtsname);
8379 if(numlumps)
8380 printf("Using .RTS file:%s\n",ud.rtsname);
8381
8382 if (CONTROL_JoystickEnabled)
8383 CONTROL_CenterJoystick(CenterCenter,UpperLeft,LowerRight,CenterThrottle,CenterRudder);
8384
8385 puts("Loading palette/lookups.");
8386 if( setgamemode(ScreenMode,ScreenWidth,ScreenHeight) < 0 )
8387 {
8388 printf("\nVESA driver for ( %i * %i ) not found/supported!\n",xdim,ydim);
8389 ScreenMode = 2;
8390 ScreenWidth = 320;
8391 ScreenHeight = 200;
8392 setgamemode(ScreenMode,ScreenWidth,ScreenHeight);
8393 }
8394
8395 printf("genspriteremaps()\n");
8396 genspriteremaps();
8397
8398 extern bool printf_enabled;
8399 printf_enabled = false;
8400
8401 setbrightness(ud.brightness>>2,&ps[myconnectindex].palette[0]);
8402
8403 if(KB_KeyPressed( sc_Escape ) )
8404 gameexit(" ");
8405
8406 FX_StopAllSounds();
8407 clearsoundlocks();
8408
8409 if(ud.warp_on > 1 && ud.multimode < 2)
8410 {
8411 clearview(0L);
8412 ps[myconnectindex].palette = palette;
8413 palto(0,0,0,0);
8414 rotatesprite(320<<15,200<<15,65536L,0,LOADSCREEN,0,0,2+8+64,0,0,xdim-1,ydim-1);
8415 menutext(160,105,0,0,"LOADING SAVED GAME...");
8416 nextpage();
8417
8418 j = loadplayer(ud.warp_on-2);
8419 if(j)
8420 ud.warp_on = 0;
8421 }
8422
8423MAIN_LOOP_RESTART:
8424
8425 if(ud.warp_on == 0) //if game is loaded without /V or /L cmd arguments.
8426 {
8427
8428 if (numplayers > 1 && boardfilename[0] != 0) //check if a user map is loaded and in multiplayer.
8429 {
8430 int c;
8431
8432 ud.level_number = ud.m_level_number = 7; // 7 = usermap.
8433 ud.volume_number = ud.m_volume_number;
8434 ud.player_skill = ud.m_player_skill;
8435
8436 switch(ud.m_coop) //set item spawn options, as they would be if
8437 { //game was started via main menu.
8438 case 0:
8439 ud.respawn_inventory = ud.m_respawn_inventory = 1;
8440 ud.respawn_items = ud.m_respawn_items = 1;
8441 break;
8442 case 1:
8443 ud.respawn_inventory = ud.m_respawn_inventory = 1;
8444 ud.respawn_items = ud.m_respawn_items = 0;
8445 break;
8446 case 2:
8447 ud.respawn_inventory = ud.m_respawn_inventory = 0;
8448 ud.respawn_items = ud.m_respawn_items = 0;
8449 break;
8450 }
8451
8452 if( ud.m_player_skill == 4 )
8453 {
8454 ud.m_respawn_monsters = 1; //set skill
8455 }
8456 else
8457 {
8458 ud.m_respawn_monsters = 0;
8459 }
8460
8461 waitforeverybody();
8462
8463 for(c=connecthead;c>=0;c=connectpoint2[c])
8464 {
8465 resetweapons(c);
8466 resetinventory(c);
8467 }
8468
8469 newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill);
8470
8471 enterlevel(MODE_GAME); //start game.
8472
8473 }
8474 else
8475 {
8476 Logo(); //play logo, (game must be started via menus).
8477 }
8478 }
8479
8480
8481
8482 else if(ud.warp_on == 1) //if cmd arguments /V and /L are given.
8483 {
8484
8485 if (numplayers > 1) //if in multiplayer reset everyones weapon status.
8486 {
8487 int c;
8488
8489 switch(ud.m_coop) //set item spawn options, as they would be if
8490 { //game was started via main menu.
8491 case 0:
8492 ud.respawn_inventory = ud.m_respawn_inventory = 1;
8493 ud.respawn_items = ud.m_respawn_items = 1;
8494 break;
8495 case 1:
8496 ud.respawn_inventory = ud.m_respawn_inventory = 1;
8497 ud.respawn_items = ud.m_respawn_items = 0;
8498 break;
8499 case 2:
8500 ud.respawn_inventory = ud.m_respawn_inventory = 0;
8501 ud.respawn_items = ud.m_respawn_items = 0;
8502 break;
8503 }
8504
8505 if( ud.m_player_skill == 4 )
8506 {
8507 ud.m_respawn_monsters = 1; //set skill
8508 }
8509 else
8510 {
8511 ud.m_respawn_monsters = 0;
8512 }
8513
8514 waitforeverybody();
8515
8516 for(c=connecthead;c>=0;c=connectpoint2[c])
8517 {
8518 resetweapons(c); //without this players would spawn with no weapon.
8519 resetinventory(c);
8520 }
8521
8522 }
8523
8524 newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill);
8525 enterlevel(MODE_GAME); //start game.
8526
8527 }
8528 else
8529 {
8530 vscrn();
8531 }
8532
8533 if( ud.warp_on == 0 && playback() )
8534 {
8535 FX_StopAllSounds();
8536 clearsoundlocks();
8537 nomorelogohack = 1;
8538 goto MAIN_LOOP_RESTART;
8539 }
8540
8541 ud.warp_on = 0;
8542
8543 //The main game loop is here.
8544 while ( !(ps[myconnectindex].gm&MODE_END) )
8545 {
8546 sampletimer();
8547 if( ud.recstat == 2 || ud.multimode > 1 || ( ud.show_help == 0 && (ps[myconnectindex].gm&MODE_MENU) != MODE_MENU ) )
8548 if( ps[myconnectindex].gm&MODE_GAME )
8549 {
8550 // (" It's stuck here ")
8551 //printf("ps[myconnectindex].gm&MODE_GAME\n");
8552 if( moveloop() )
8553 {
8554 continue;
8555 }
8556 }
8557
8558 if( ps[myconnectindex].gm&MODE_EOL || ps[myconnectindex].gm&MODE_RESTART )
8559 {
8560
8561 if( ps[myconnectindex].gm&MODE_EOL )
8562 {
8563 closedemowrite();
8564
8565 ready2send = 0;
8566
8567 i = ud.screen_size;
8568 ud.screen_size = 0;
8569 vscrn();
8570 ud.screen_size = i;
8571 dobonus(0);
8572
8573 if(ud.eog)
8574 {
8575 ud.eog = 0;
8576 if(ud.multimode < 2)
8577 {
8578 if(VOLUMEONE)
8579 doorders();
8580
8581 ps[myconnectindex].gm = MODE_MENU;
8582 cmenu(0);
8583 probey = 0;
8584 goto MAIN_LOOP_RESTART;
8585 }
8586 else
8587 {
8588 ud.m_level_number = 0;
8589 ud.level_number = 0;
8590 }
8591 }
8592 }
8593
8594 ready2send = 0;
8595 if(numplayers > 1) ps[myconnectindex].gm = MODE_GAME;
8596
8597 enterlevel(ps[myconnectindex].gm);
8598 continue;
8599 }
8600
8601 cheats();
8602
8603 if( !CONSOLE_IsActive() )
8604 nonsharedkeys();
8605
8606
8607 if( (ud.show_help == 0 && ud.multimode < 2 && !(ps[myconnectindex].gm&MODE_MENU) ) || ud.multimode > 1 || ud.recstat == 2)
8608 i = min(max((totalclock-ototalclock)*(65536L/TICSPERFRAME),0),65536);
8609 else
8610 i = 65536;
8611
8612 displayrooms(screenpeek,i);
8613 displayrest(i);
8614
8615 if(ps[myconnectindex].gm&MODE_DEMO)
8616 goto MAIN_LOOP_RESTART;
8617
8618 if(debug_on)
8619 caches();
8620
8621 checksync();
8622
8623 if (VOLUMEONE)
8624 if(ud.show_help == 0 && show_shareware > 0 && (ps[myconnectindex].gm&MODE_MENU) == 0 )
8625 rotatesprite((320-50)<<16,9<<16,65536L,0,BETAVERSION,0,0,2+8+16+128,0,0,xdim-1,ydim-1);
8626
8627 nextpage();
8628 }
8629
8630 gameexit(" ");
8631 return(0);
8632}
8633
8634uint8_t opendemoread(uint8_t which_demo) // 0 = mine
8635{
8636 char d[] = "demo_.dmo";
8637 char *fname = d;
8638 uint8_t ver;
8639 short i,j;
8640
8641 int32 dummy;
8642 int32_t groupefil_crc32_from_demo[MAXGROUPFILES];
8643
8644 if(which_demo == 10)
8645 d[4] = 'x';
8646 else
8647 d[4] = '0' + which_demo;
8648
8649 ud.reccnt = 0;
8650
8651 if(which_demo == 1 && firstdemofile[0] != 0)
8652 {
8653 fname = firstdemofile;
8654 if ((recfilep = TCkopen4load(firstdemofile,0)) == -1)
8655 {
8656 return(0);
8657 }
8658 }
8659 else
8660 {
8661 if ((recfilep = TCkopen4load(d,0)) == -1)
8662 {
8663 return(0);
8664 }
8665 }
8666
8667 kread(recfilep,&ud.reccnt,sizeof(int32_t));
8668 kread(recfilep,&ver,sizeof(uint8_t ));
8669
8670 printf("%s has version = %d\n", fname, ver);
8671
8672 // FIX_00015: Backward compliance with older demos (down to demos v27, 28, 116, 117 and 118)
8673 if (PLUTOPAK)
8674 {
8675 if( (ver != BYTEVERSION && ver != BYTEVERSION_116 && ver != BYTEVERSION_117 && ver != BYTEVERSION_118) ) // || (ud.reccnt < 512) )
8676 {
8677 printf("%s is a demo version %d. We want v. %d, %d, %d, or %d (1.5 Atomic versions)\n",
8678 fname, (int) ver, BYTEVERSION_116, BYTEVERSION_117, BYTEVERSION_118, BYTEVERSION);
8679 kclose(recfilep);
8680 return 0;
8681 }
8682 }
8683 else // 1.3/1.3d style
8684 {
8685 if( (ver != BYTEVERSION && ver != BYTEVERSION_27 && ver != BYTEVERSION_28 && ver != BYTEVERSION_29) ) // || (ud.reccnt < 512) )
8686 {
8687 printf("%s is a demo version %d. We want v. %d, %d, %d or %d (1.3/1.3d versions)\n",
8688 fname, (int) ver, BYTEVERSION_27, BYTEVERSION_28, BYTEVERSION_29, BYTEVERSION);
8689 kclose(recfilep);
8690 return 0;
8691 }
8692 }
8693
8694 // FIX_00062: Better support and identification for GRP and CON files for 1.3/1.3d/1.4/1.5
8695 if(ver==BYTEVERSION)
8696 {
8697 kread(recfilep, (int32_t *)groupefil_crc32_from_demo, sizeof(groupefil_crc32_from_demo));
8698
8699 for(i=0; i<MAXGROUPFILES; i++)
8700 if(groupefil_crc32_from_demo[i]!=groupefil_crc32[i])
8701 {
8702 for(j=0; j<=i; j++)
8703 {
8704 printf("You have GRP #%d: %s (CRC32=%X)\n"
8705 "this demo expects %s (CRC32=%X)\n",
8706 j, grpVersion2char_from_crc(groupefil_crc32[j]),groupefil_crc32[j],
8707 grpVersion2char_from_crc(groupefil_crc32_from_demo[j]),groupefil_crc32_from_demo[j]);
8708
8709 }
8710 kclose(recfilep);
8711 return 0;
8712 }
8713
8714
8715 }
8716
8717 ud.playing_demo_rev = ver;
8718
8719 kread(recfilep,(uint8_t *)&ud.volume_number,sizeof(uint8_t ));
8720 kread(recfilep,(uint8_t *)&ud.level_number,sizeof(uint8_t ));
8721 kread(recfilep,(uint8_t *)&ud.player_skill,sizeof(uint8_t ));
8722 kread(recfilep,(uint8_t *)&ud.m_coop,sizeof(uint8_t ));
8723 kread(recfilep,(uint8_t *)&ud.m_ffire,sizeof(uint8_t ));
8724 kread(recfilep,(short *)&ud.multimode,sizeof(short));
8725 kread(recfilep,(short *)&ud.m_monsters_off,sizeof(short));
8726 kread(recfilep,(int32 *)&ud.m_respawn_monsters,sizeof(int32));
8727 kread(recfilep,(int32 *)&ud.m_respawn_items,sizeof(int32));
8728 kread(recfilep,(int32 *)&ud.m_respawn_inventory,sizeof(int32));
8729 kread(recfilep,(int32 *)&ud.playerai,sizeof(int32));
8730 kread(recfilep,(uint8_t *)&ud.user_name[0][0],sizeof(ud.user_name));
8731 // FIX_00034: Demos do not turn your run mode off anymore:
8732 kread(recfilep,(int32 *)&dummy /*ud.auto_run*/,sizeof(int32)); // not needed and would affect autorun status in duke3d.cfg when quitting duke from a demo
8733 kread(recfilep,(uint8_t *)boardfilename,sizeof(boardfilename));
8734 if( boardfilename[0] != 0 )
8735 {
8736 ud.m_level_number = 7;
8737 ud.m_volume_number = 0;
8738 }
8739
8740 for(i=0;i<ud.multimode;i++)
8741 {
8742 kread(recfilep,(int32 *)&ps[i].aim_mode,sizeof(uint8_t ));
8743
8744 // FIX_00080: Out Of Synch in demos. Tries recovering OOS in old demos v27/28/29/116/117/118. New: v30/v119.
8745 if(ver==BYTEVERSION)
8746 kread(recfilep,ud.wchoice[i],sizeof(ud.wchoice[0]));
8747 }
8748
8749 ud.god = ud.cashman = ud.eog = ud.showallmap = 0;
8750 ud.clipping = ud.scrollmode = ud.overhead_on = 0;
8751 // FIX_00034: Demos do not turn your run mode off anymore:
8752 /* ud.showweapons = */ ud.pause_on /*= ud.auto_run */ = 0; // makes no sense to reset those 2 value!
8753
8754 newgame(ud.volume_number,ud.level_number,ud.player_skill);
8755 return(1);
8756}
8757
8758
8759void opendemowrite(void)
8760{
8761 char d[] = "demo1.dmo";
8762 int32_t dummylong = 0;
8763 uint8_t ver;
8764 short i;
8765 char fullpathdemofilename[16];
8766
8767 if(ud.recstat == 2) kclose(recfilep);
8768
8769 ver = BYTEVERSION;
8770
8771 // Are we loading a TC?
8772 if(getGameDir()[0] != '\0'){
8773 // Yes
8774 sprintf(fullpathdemofilename, "%s\\%s", getGameDir(), d);
8775 }
8776 else{
8777 // No
8778 sprintf(fullpathdemofilename, "%s", d);
8779 }
8780
8781// CTW - MODIFICATION
8782// if ((frecfilep = fopen(d,"wb")) == -1) return;
8783 if ((frecfilep = fopen(fullpathdemofilename,"wb")) == NULL) return;
8784// CTW END - MODIFICATION
8785 fwrite(&dummylong,4,1,frecfilep);
8786 fwrite(&ver,sizeof(uint8_t ),1,frecfilep);
8787 // FIX_00062: Better support and identification for GRP and CON files for 1.3/1.3d/1.4/1.5
8788 fwrite((int32_t *)groupefil_crc32,sizeof(groupefil_crc32),1,frecfilep);
8789 fwrite((uint8_t *)&ud.volume_number,sizeof(uint8_t ),1,frecfilep);
8790 fwrite((uint8_t *)&ud.level_number,sizeof(uint8_t ),1,frecfilep);
8791 fwrite((uint8_t *)&ud.player_skill,sizeof(uint8_t ),1,frecfilep);
8792 fwrite((uint8_t *)&ud.m_coop,sizeof(uint8_t ),1,frecfilep);
8793 fwrite((uint8_t *)&ud.m_ffire,sizeof(uint8_t ),1,frecfilep);
8794 fwrite((short *)&ud.multimode,sizeof(short),1,frecfilep);
8795 fwrite((short *)&ud.m_monsters_off,sizeof(short),1,frecfilep);
8796 fwrite((int32 *)&ud.m_respawn_monsters,sizeof(int32),1,frecfilep);
8797 fwrite((int32 *)&ud.m_respawn_items,sizeof(int32),1,frecfilep);
8798 fwrite((int32 *)&ud.m_respawn_inventory,sizeof(int32),1,frecfilep);
8799 fwrite((int32 *)&ud.playerai,sizeof(int32),1,frecfilep);
8800 fwrite((uint8_t *)&ud.user_name[0][0],sizeof(ud.user_name),1,frecfilep);
8801 fwrite((int32 *)&ud.auto_run,sizeof(int32),1,frecfilep);
8802 fwrite((uint8_t *)boardfilename,sizeof(boardfilename),1,frecfilep);
8803
8804 for(i=0;i<ud.multimode;i++)
8805 {
8806 fwrite((int32 *)&ps[i].aim_mode,sizeof(uint8_t ),1,frecfilep); // seems wrong; prolly not needed anyway
8807 // FIX_00080: Out Of Synch in demos. Tries recovering OOS in old demos v27/28/29/116/117/118. New: v30/v119.
8808 fwrite(ud.wchoice[i],sizeof(ud.wchoice[0]),1,frecfilep);
8809 }
8810
8811 totalreccnt = 0;
8812 ud.reccnt = 0;
8813}
8814
8815void record(void)
8816{
8817 short i;
8818 for(i=connecthead;i>=0;i=connectpoint2[i])
8819 {
8820 copybufbyte(&sync[i],&recsync[ud.reccnt],sizeof(input));
8821 ud.reccnt++;
8822 totalreccnt++;
8823 if (ud.reccnt >= RECSYNCBUFSIZ)
8824 {
8825 dfwrite(recsync,sizeof(input)*ud.multimode,ud.reccnt/ud.multimode,frecfilep);
8826 ud.reccnt = 0;
8827 }
8828 }
8829}
8830
8831void closedemowrite(void)
8832{
8833 if (ud.recstat == 1)
8834 {
8835 if (ud.reccnt > 0)
8836 {
8837 dfwrite(recsync,sizeof(input)*ud.multimode,ud.reccnt/ud.multimode,frecfilep);
8838
8839 fseek(frecfilep,SEEK_SET,0L);
8840 fwrite(&totalreccnt,sizeof(int32_t),1,frecfilep);
8841 ud.recstat = ud.m_recstat = 0;
8842 }
8843 fclose(frecfilep);
8844 frecfilep = NULL;
8845 }
8846}
8847
8848// CTW - MODIFICATION
8849// On my XP machine, demo playback causes the game to crash shortly in.
8850// Only bug found so far, not sure if it's OS dependent or compiler or what.
8851// Seems to happen when player input starts being simulated, but just guessing.
8852// This change effectively disables it. The related code is still enabled.
8853// (This is working on Linux, so I flipped it back to '1'. --ryan.)
8854 uint8_t which_demo = 0;
8855// CTW END - MODIFICATION
8856
8857uint8_t in_menu = 0;
8858
8859// extern int32_t syncs[];
8860int32_t playback(void)
8861{
8862 int32_t i,j,k,l,t;
8863 uint8_t foundemo;
8864
8865 if( ready2send )
8866 {
8867 return 0;
8868 }
8869
8870 /*
8871 if(numplayers > 1)
8872 return 1;
8873 */
8874
8875 foundemo = 0;
8876
8877 RECHECK:
8878
8879 in_menu = ps[myconnectindex].gm&MODE_MENU;
8880
8881 pub = NUMPAGES;
8882 pus = NUMPAGES;
8883
8884 flushperms();
8885
8886 if(numplayers < 2 && ud.multimode_bot<2) foundemo = opendemoread(which_demo);
8887
8888 if(foundemo == 0)
8889 {
8890
8891 if(which_demo > 1)
8892 {
8893 which_demo = 1;
8894 goto RECHECK;
8895 }
8896 for(t=0;t<63;t+=7) palto(0,0,0,t);
8897 drawbackground();
8898
8899 CONSOLE_HandleInput();
8900 if( !CONSOLE_IsActive())
8901 {
8902 menus();
8903 }
8904 CONSOLE_Render();
8905 ps[myconnectindex].palette = palette;
8906 nextpage();
8907 for(t=63;t>0;t-=7)
8908 {
8909 palto(0,0,0,t);
8910 }
8911
8912 ud.reccnt = 0;
8913 }
8914 else
8915 {
8916 ud.recstat = 2;
8917 which_demo++;
8918 if(which_demo == 10)
8919 {
8920 which_demo = 1;
8921 }
8922
8923 enterlevel(MODE_DEMO);
8924 }
8925
8926 if(foundemo == 0 || in_menu || KB_KeyWaiting() || numplayers > 1)
8927 {
8928 FX_StopAllSounds();
8929 clearsoundlocks();
8930 ps[myconnectindex].gm |= MODE_MENU;
8931 }
8932
8933 ready2send = 0;
8934 i = 0;
8935
8936 KB_FlushKeyboardQueue();
8937
8938 k = 0;
8939
8940 while (ud.reccnt > 0 || foundemo == 0)
8941 {
8942
8943 if(foundemo) while ( totalclock >= (lockclock+TICSPERFRAME) )
8944 {
8945 if ((i == 0) || (i >= RECSYNCBUFSIZ))
8946 {
8947 i = 0;
8948 l = min(ud.reccnt,RECSYNCBUFSIZ);
8949 kdfread(recsync,sizeof(input)*ud.multimode,l/ud.multimode,recfilep);
8950 }
8951
8952 for(j=connecthead;j>=0;j=connectpoint2[j])
8953 {
8954 copybufbyte(&recsync[i],&inputfifo[movefifoend[j]&(MOVEFIFOSIZ-1)][j],sizeof(input));
8955
8956 movefifoend[j]++;
8957 i++;
8958 ud.reccnt--;
8959 }
8960 domovethings();
8961 }
8962
8963 if(foundemo == 0)
8964 drawbackground();
8965 else
8966 {
8967 if( !CONSOLE_IsActive() )
8968 {
8969 nonsharedkeys();
8970 }
8971
8972 j = min(max((totalclock-lockclock)*(65536/TICSPERFRAME),0),65536);
8973 displayrooms(screenpeek,j);
8974 displayrest(j);
8975
8976 if(ud.multimode > 1 && ps[myconnectindex].gm )
8977 getpackets();
8978 }
8979
8980 if( (ps[myconnectindex].gm&MODE_MENU) && (ps[myconnectindex].gm&MODE_EOL) )
8981 {
8982 printf("playback(1) :: goto RECHECK:\n");
8983 goto RECHECK;
8984 }
8985
8986 if(ps[myconnectindex].gm&MODE_TYPE)
8987 {
8988 typemode();
8989 if((ps[myconnectindex].gm&MODE_TYPE) != MODE_TYPE)
8990 ps[myconnectindex].gm = MODE_MENU;
8991 }
8992 else
8993 {
8994 CONSOLE_HandleInput();
8995 if( !CONSOLE_IsActive())
8996 {
8997 menus();
8998 }
8999 CONSOLE_Render();
9000 if( ud.multimode > 1 )
9001 {
9002 ControlInfo noshareinfo;
9003 if( !CONSOLE_IsActive() )
9004 {
9005 CONTROL_GetInput( &noshareinfo );
9006 if( ACTION(gamefunc_SendMessage) )
9007 {
9008 KB_FlushKeyboardQueue();
9009 CONTROL_ClearAction( gamefunc_SendMessage );
9010 ps[myconnectindex].gm = MODE_TYPE;
9011 typebuf[0] = 0;
9012 inputloc = 0;
9013 }
9014 }
9015
9016 }
9017 }
9018
9019 operatefta();
9020
9021 if(ud.last_camsprite != ud.camerasprite)
9022 {
9023 ud.last_camsprite = ud.camerasprite;
9024 ud.camera_time = totalclock+(TICRATE*2);
9025 }
9026
9027 if (VOLUMEONE)
9028 if( ud.show_help == 0 && (ps[myconnectindex].gm&MODE_MENU) == 0 )
9029 rotatesprite((320-50)<<16,9<<16,65536L,0,BETAVERSION,0,0,2+8+16+128,0,0,xdim-1,ydim-1);
9030
9031 getpackets();
9032 nextpage();
9033
9034 if( ps[myconnectindex].gm==MODE_END || ps[myconnectindex].gm==MODE_GAME )
9035 {
9036 if(foundemo)
9037 kclose(recfilep);
9038 ud.playing_demo_rev = 0;
9039 return 0;
9040 }
9041 }
9042 kclose(recfilep);
9043 ud.playing_demo_rev = 0;
9044 if(ps[myconnectindex].gm&MODE_MENU)
9045 {
9046 goto RECHECK;
9047 }
9048
9049 return 1;
9050}
9051
9052uint8_t moveloop()
9053{
9054 int32_t i;
9055
9056 if (numplayers > 1)
9057 {
9058 while (fakemovefifoplc < movefifoend[myconnectindex])
9059 {
9060 fakedomovethings();
9061 }
9062 }
9063
9064
9065 getpackets();
9066
9067 if (numplayers < 2) bufferjitter = 0;
9068 while (movefifoend[myconnectindex]-movefifoplc > bufferjitter)
9069 {
9070 for(i=connecthead;i>=0;i=connectpoint2[i])
9071 if (movefifoplc == movefifoend[i]) break;
9072 if (i >= 0) break;
9073 if( domovethings() ) return 1;
9074 }
9075 return 0;
9076}
9077
9078void fakedomovethingscorrect(void)
9079{
9080 int32_t i;
9081 struct player_struct *p;
9082
9083 if (numplayers < 2) return;
9084
9085 i = ((movefifoplc-1)&(MOVEFIFOSIZ-1));
9086 p = &ps[myconnectindex];
9087
9088 if (p->posx == myxbak[i] && p->posy == myybak[i] && p->posz == myzbak[i]
9089 && p->horiz == myhorizbak[i] && p->ang == myangbak[i]) return;
9090
9091 myx = p->posx; omyx = p->oposx; myxvel = p->posxv;
9092 myy = p->posy; omyy = p->oposy; myyvel = p->posyv;
9093 myz = p->posz; omyz = p->oposz; myzvel = p->poszv;
9094 myang = p->ang; omyang = p->oang;
9095 mycursectnum = p->cursectnum;
9096 myhoriz = p->horiz; omyhoriz = p->ohoriz;
9097 myhorizoff = p->horizoff; omyhorizoff = p->ohorizoff;
9098 myjumpingcounter = p->jumping_counter;
9099 myjumpingtoggle = p->jumping_toggle;
9100 myonground = p->on_ground;
9101 myhardlanding = p->hard_landing;
9102 myreturntocenter = p->return_to_center;
9103
9104 fakemovefifoplc = movefifoplc;
9105 while (fakemovefifoplc < movefifoend[myconnectindex])
9106 fakedomovethings();
9107
9108}
9109
9110void fakedomovethings(void)
9111{
9112 input *syn;
9113 struct player_struct *p;
9114 int32_t i, j, k, doubvel, fz, cz, hz, lz, x, y;
9115 uint32_t sb_snum;
9116 short psect, psectlotag, tempsect, backcstat;
9117 uint8_t shrunk, spritebridge;
9118
9119 syn = (input *)&inputfifo[fakemovefifoplc&(MOVEFIFOSIZ-1)][myconnectindex];
9120
9121 p = &ps[myconnectindex];
9122
9123 backcstat = sprite[p->i].cstat;
9124 sprite[p->i].cstat &= ~257;
9125
9126 sb_snum = syn->bits;
9127
9128 psect = mycursectnum;
9129 psectlotag = sector[psect].lotag;
9130 spritebridge = 0;
9131
9132 shrunk = (sprite[p->i].yrepeat < 32);
9133
9134 if( ud.clipping == 0 && ( sector[psect].floorpicnum == MIRROR || psect < 0 || psect >= MAXSECTORS) )
9135 {
9136 myx = omyx;
9137 myy = omyy;
9138 }
9139 else
9140 {
9141 omyx = myx;
9142 omyy = myy;
9143 }
9144
9145 omyhoriz = myhoriz;
9146 omyhorizoff = myhorizoff;
9147 omyz = myz;
9148 omyang = myang;
9149
9150 getzrange(myx,myy,myz,psect,&cz,&hz,&fz,&lz,163L,CLIPMASK0);
9151
9152 j = getflorzofslope(psect,myx,myy);
9153
9154 if( (lz&49152) == 16384 && psectlotag == 1 && klabs(myz-j) > PHEIGHT+(16<<8) )
9155 psectlotag = 0;
9156
9157 if( p->aim_mode == 0 && myonground && psectlotag != 2 && (sector[psect].floorstat&2) )
9158 {
9159 x = myx+(sintable[(myang+512)&2047]>>5);
9160 y = myy+(sintable[myang&2047]>>5);
9161 tempsect = psect;
9162 updatesector(x,y,&tempsect);
9163 if (tempsect >= 0)
9164 {
9165 k = getflorzofslope(psect,x,y);
9166 if (psect == tempsect)
9167 myhorizoff += mulscale16(j-k,160);
9168 else if (klabs(getflorzofslope(tempsect,x,y)-k) <= (4<<8))
9169 myhorizoff += mulscale16(j-k,160);
9170 }
9171 }
9172 if (myhorizoff > 0) myhorizoff -= ((myhorizoff>>3)+1);
9173 else if (myhorizoff < 0) myhorizoff += (((-myhorizoff)>>3)+1);
9174
9175 if(hz >= 0 && (hz&49152) == 49152)
9176 {
9177 hz &= (MAXSPRITES-1);
9178 if (sprite[hz].statnum == 1 && sprite[hz].extra >= 0)
9179 {
9180 hz = 0;
9181 cz = getceilzofslope(psect,myx,myy);
9182 }
9183 }
9184
9185 if(lz >= 0 && (lz&49152) == 49152)
9186 {
9187 j = lz&(MAXSPRITES-1);
9188 if ((sprite[j].cstat&33) == 33)
9189 {
9190 psectlotag = 0;
9191 spritebridge = 1;
9192 }
9193 if(badguy(&sprite[j]) && sprite[j].xrepeat > 24 && klabs(sprite[p->i].z-sprite[j].z) < (84<<8) )
9194 {
9195 j = getangle( sprite[j].x-myx,sprite[j].y-myy);
9196 myxvel -= sintable[(j+512)&2047]<<4;
9197 myyvel -= sintable[j&2047]<<4;
9198 }
9199 }
9200
9201 if( sprite[p->i].extra <= 0 )
9202 {
9203 if( psectlotag == 2 )
9204 {
9205 if(p->on_warping_sector == 0)
9206 {
9207 if( klabs(myz-fz) > (PHEIGHT>>1))
9208 myz += 348;
9209 }
9210 clipmove(&myx,&myy,&myz,&mycursectnum,0,0,164L,(4L<<8),(4L<<8),CLIPMASK0);
9211 }
9212
9213 updatesector(myx,myy,&mycursectnum);
9214 pushmove(&myx,&myy,&myz,&mycursectnum,128L,(4L<<8),(20L<<8),CLIPMASK0);
9215
9216 myhoriz = 100;
9217 myhorizoff = 0;
9218
9219 goto ENDFAKEPROCESSINPUT;
9220 }
9221
9222 doubvel = TICSPERFRAME;
9223
9224 if(p->on_crane >= 0) goto FAKEHORIZONLY;
9225
9226 if(p->one_eighty_count < 0) myang += 128;
9227
9228 i = 40;
9229
9230 if( psectlotag == 2)
9231 {
9232 myjumpingcounter = 0;
9233
9234 if ( sb_snum&1 )
9235 {
9236 if(myzvel > 0) myzvel = 0;
9237 myzvel -= 348;
9238 if(myzvel < -(256*6)) myzvel = -(256*6);
9239 }
9240 else if (sb_snum&(1<<1))
9241 {
9242 if(myzvel < 0) myzvel = 0;
9243 myzvel += 348;
9244 if(myzvel > (256*6)) myzvel = (256*6);
9245 }
9246 else
9247 {
9248 if(myzvel < 0)
9249 {
9250 myzvel += 256;
9251 if(myzvel > 0)
9252 myzvel = 0;
9253 }
9254 if(myzvel > 0)
9255 {
9256 myzvel -= 256;
9257 if(myzvel < 0)
9258 myzvel = 0;
9259 }
9260 }
9261
9262 if(myzvel > 2048) myzvel >>= 1;
9263
9264 myz += myzvel;
9265
9266 if(myz > (fz-(15<<8)) )
9267 myz += ((fz-(15<<8))-myz)>>1;
9268
9269 if(myz < (cz+(4<<8)) )
9270 {
9271 myz = cz+(4<<8);
9272 myzvel = 0;
9273 }
9274 }
9275
9276 else if(p->jetpack_on)
9277 {
9278 myonground = 0;
9279 myjumpingcounter = 0;
9280 myhardlanding = 0;
9281
9282 if(p->jetpack_on < 11)
9283 myz -= (p->jetpack_on<<7); //Goin up
9284
9285 if(shrunk) j = 512;
9286 else j = 2048;
9287
9288 if (sb_snum&1) //A
9289 myz -= j;
9290 if (sb_snum&(1<<1)) //Z
9291 myz += j;
9292
9293 if(shrunk == 0 && ( psectlotag == 0 || psectlotag == 2 ) ) k = 32;
9294 else k = 16;
9295
9296 if(myz > (fz-(k<<8)) )
9297 myz += ((fz-(k<<8))-myz)>>1;
9298 if(myz < (cz+(18<<8)) )
9299 myz = cz+(18<<8);
9300 }
9301 else if( psectlotag != 2 )
9302 {
9303 if (psectlotag == 1 && p->spritebridge == 0)
9304 {
9305 if(shrunk == 0) i = 34;
9306 else i = 12;
9307 }
9308 if(myz < (fz-(i<<8)) && (floorspace(psect)|ceilingspace(psect)) == 0 ) //falling
9309 {
9310 if( (sb_snum&3) == 0 && myonground && (sector[psect].floorstat&2) && myz >= (fz-(i<<8)-(16<<8) ) )
9311 myz = fz-(i<<8);
9312 else
9313 {
9314 myonground = 0;
9315
9316 myzvel += (gc+80);
9317
9318 if(myzvel >= (4096+2048)) myzvel = (4096+2048);
9319 }
9320 }
9321
9322 else
9323 {
9324 if(psectlotag != 1 && psectlotag != 2 && myonground == 0 && myzvel > (6144>>1))
9325 myhardlanding = myzvel>>10;
9326 myonground = 1;
9327
9328 if(i==40)
9329 {
9330 //Smooth on the ground
9331
9332 k = ((fz-(i<<8))-myz)>>1;
9333 if( klabs(k) < 256 ) k = 0;
9334 myz += k; // ((fz-(i<<8))-myz)>>1;
9335 myzvel -= 768; // 412;
9336 if(myzvel < 0) myzvel = 0;
9337 }
9338 else if(myjumpingcounter == 0)
9339 {
9340 myz += ((fz-(i<<7))-myz)>>1; //Smooth on the water
9341 if(p->on_warping_sector == 0 && myz > fz-(16<<8))
9342 {
9343 myz = fz-(16<<8);
9344 myzvel >>= 1;
9345 }
9346 }
9347
9348 if( sb_snum&2 )
9349 myz += (2048+768);
9350
9351 if( (sb_snum&1) == 0 && myjumpingtoggle == 1)
9352 myjumpingtoggle = 0;
9353
9354 else if( (sb_snum&1) && myjumpingtoggle == 0 )
9355 {
9356 if( myjumpingcounter == 0 )
9357 if( (fz-cz) > (56<<8) )
9358 {
9359 myjumpingcounter = 1;
9360 myjumpingtoggle = 1;
9361 }
9362 }
9363 if( myjumpingcounter && (sb_snum&1) == 0 )
9364 myjumpingcounter = 0;
9365 }
9366
9367 if(myjumpingcounter)
9368 {
9369 if( (sb_snum&1) == 0 && myjumpingtoggle == 1)
9370 myjumpingtoggle = 0;
9371
9372 if( myjumpingcounter < (1024+256) )
9373 {
9374 if(psectlotag == 1 && myjumpingcounter > 768)
9375 {
9376 myjumpingcounter = 0;
9377 myzvel = -512;
9378 }
9379 else
9380 {
9381 myzvel -= (sintable[(2048-128+myjumpingcounter)&2047])/12;
9382 myjumpingcounter += 180;
9383
9384 myonground = 0;
9385 }
9386 }
9387 else
9388 {
9389 myjumpingcounter = 0;
9390 myzvel = 0;
9391 }
9392 }
9393
9394 myz += myzvel;
9395
9396 if(myz < (cz+(4<<8)) )
9397 {
9398 myjumpingcounter = 0;
9399 if(myzvel < 0) myxvel = myyvel = 0;
9400 myzvel = 128;
9401 myz = cz+(4<<8);
9402 }
9403
9404 }
9405
9406 if ( p->fist_incs ||
9407 p->transporter_hold > 2 ||
9408 myhardlanding ||
9409 p->access_incs > 0 ||
9410 p->knee_incs > 0 ||
9411 (p->curr_weapon == TRIPBOMB_WEAPON &&
9412 p->kickback_pic > 1 &&
9413 p->kickback_pic < 4 ) )
9414 {
9415 doubvel = 0;
9416 myxvel = 0;
9417 myyvel = 0;
9418 }
9419 else if ( syn->avel ) //p->ang += syncangvel * constant
9420 { //ENGINE calculates angvel for you
9421 int32_t tempang;
9422
9423 tempang = syn->avel<<1;
9424
9425 if(psectlotag == 2)
9426 myang += (tempang-(tempang>>3))*sgn(doubvel);
9427 else myang += (tempang)*sgn(doubvel);
9428 myang &= 2047;
9429 }
9430
9431 if ( myxvel || myyvel || syn->fvel || syn->svel )
9432 {
9433 if(p->steroids_amount > 0 && p->steroids_amount < 400)
9434 doubvel <<= 1;
9435
9436 myxvel += ((syn->fvel*doubvel)<<6);
9437 myyvel += ((syn->svel*doubvel)<<6);
9438
9439 if( ( p->curr_weapon == KNEE_WEAPON && p->kickback_pic > 10 && myonground ) || ( myonground && (sb_snum&2) ) )
9440 {
9441 myxvel = mulscale16(myxvel,dukefriction-0x2000);
9442 myyvel = mulscale16(myyvel,dukefriction-0x2000);
9443 }
9444 else
9445 {
9446 if(psectlotag == 2)
9447 {
9448 myxvel = mulscale16(myxvel,dukefriction-0x1400);
9449 myyvel = mulscale16(myyvel,dukefriction-0x1400);
9450 }
9451 else
9452 {
9453 myxvel = mulscale16(myxvel,dukefriction);
9454 myyvel = mulscale16(myyvel,dukefriction);
9455 }
9456 }
9457
9458 if( abs(myxvel) < 2048 && abs(myyvel) < 2048 )
9459 myxvel = myyvel = 0;
9460
9461 if( shrunk )
9462 {
9463 myxvel =
9464 mulscale16(myxvel,(dukefriction)-(dukefriction>>1)+(dukefriction>>2));
9465 myyvel =
9466 mulscale16(myyvel,(dukefriction)-(dukefriction>>1)+(dukefriction>>2));
9467 }
9468 }
9469
9470FAKEHORIZONLY:
9471 if(psectlotag == 1 || spritebridge == 1) i = (4L<<8); else i = (20L<<8);
9472
9473 clipmove(&myx,&myy,&myz,&mycursectnum,myxvel,myyvel,164L,4L<<8,i,CLIPMASK0);
9474 pushmove(&myx,&myy,&myz,&mycursectnum,164L,4L<<8,4L<<8,CLIPMASK0);
9475
9476 if( p->jetpack_on == 0 && psectlotag != 1 && psectlotag != 2 && shrunk)
9477 myz += 30<<8;
9478
9479 if ((sb_snum&(1<<18)) || myhardlanding)
9480 myreturntocenter = 9;
9481
9482 if (sb_snum&(1<<13))
9483 {
9484 myreturntocenter = 9;
9485 if (sb_snum&(1<<5)) myhoriz += 6;
9486 myhoriz += 6;
9487 }
9488 else if (sb_snum&(1<<14))
9489 {
9490 myreturntocenter = 9;
9491 if (sb_snum&(1<<5)) myhoriz -= 6;
9492 myhoriz -= 6;
9493 }
9494 else if (sb_snum&(1<<3))
9495 {
9496 if (sb_snum&(1<<5)) myhoriz += 6;
9497 myhoriz += 6;
9498 }
9499 else if (sb_snum&(1<<4))
9500 {
9501 if (sb_snum&(1<<5)) myhoriz -= 6;
9502 myhoriz -= 6;
9503 }
9504
9505 if (myreturntocenter > 0)
9506 if ((sb_snum&(1<<13)) == 0 && (sb_snum&(1<<14)) == 0)
9507 {
9508 myreturntocenter--;
9509 myhoriz += 33-(myhoriz/3);
9510 }
9511
9512 if(p->aim_mode)
9513 myhoriz += syn->horz>>1;
9514 else
9515 {
9516 if( myhoriz > 95 && myhoriz < 105) myhoriz = 100;
9517 if( myhorizoff > -5 && myhorizoff < 5) myhorizoff = 0;
9518 }
9519
9520 if (myhardlanding > 0)
9521 {
9522 myhardlanding--;
9523 myhoriz -= (myhardlanding<<4);
9524 }
9525
9526 if (myhoriz > 299) myhoriz = 299;
9527 else if (myhoriz < -99) myhoriz = -99;
9528
9529 if(p->knee_incs > 0)
9530 {
9531 myhoriz -= 48;
9532 myreturntocenter = 9;
9533 }
9534
9535
9536ENDFAKEPROCESSINPUT:
9537
9538 myxbak[fakemovefifoplc&(MOVEFIFOSIZ-1)] = myx;
9539 myybak[fakemovefifoplc&(MOVEFIFOSIZ-1)] = myy;
9540 myzbak[fakemovefifoplc&(MOVEFIFOSIZ-1)] = myz;
9541 myangbak[fakemovefifoplc&(MOVEFIFOSIZ-1)] = myang;
9542 myhorizbak[fakemovefifoplc&(MOVEFIFOSIZ-1)] = myhoriz;
9543 fakemovefifoplc++;
9544
9545 sprite[p->i].cstat = backcstat;
9546}
9547
9548
9549uint8_t domovethings(void)
9550{
9551 short i, j;
9552 uint8_t ch;
9553
9554
9555 for(i=connecthead;i>=0;i=connectpoint2[i])
9556 if( sync[i].bits&(1<<17) )
9557 {
9558 multiflag = 2;
9559 multiwhat = (sync[i].bits>>18)&1;
9560 multipos = (uint32_t) (sync[i].bits>>19)&15;
9561 multiwho = i;
9562
9563 if( multiwhat )
9564 {
9565 // FIX_00058: Save/load game crash in both single and multiplayer
9566 screencapt = 1;
9567 displayrooms(myconnectindex,65536);
9568 savetemp("duke3d.tmp",tiles[MAXTILES-1].data,160*100);
9569 screencapt = 0;
9570
9571 saveplayer( multipos );
9572 multiflag = 0;
9573
9574 if(multiwho != myconnectindex)
9575 {
9576 strcpy(fta_quotes[122],&ud.user_name[multiwho][0]);
9577 strcat(fta_quotes[122]," SAVED A MULTIPLAYER GAME");
9578 FTA(122,&ps[myconnectindex],1);
9579 }
9580 else
9581 {
9582 strcpy(fta_quotes[122],"MULTIPLAYER GAME SAVED");
9583 FTA(122,&ps[myconnectindex],1);
9584 }
9585 break;
9586 }
9587 else
9588 {
9589// waitforeverybody();
9590
9591 j = loadplayer( multipos );
9592
9593 multiflag = 0;
9594
9595 if(j == 0)
9596 {
9597 if(multiwho != myconnectindex)
9598 {
9599 strcpy(fta_quotes[122],&ud.user_name[multiwho][0]);
9600 strcat(fta_quotes[122]," LOADED A MULTIPLAYER GAME");
9601 FTA(122,&ps[myconnectindex],1);
9602 }
9603 else
9604 {
9605 strcpy(fta_quotes[122],"MULTIPLAYER GAME LOADED");
9606 FTA(122,&ps[myconnectindex],1);
9607 }
9608 return 1;
9609 }
9610 }
9611 }
9612
9613 ud.camerasprite = -1;
9614 lockclock += TICSPERFRAME;
9615
9616 if(earthquaketime > 0) earthquaketime--;
9617 if(rtsplaying > 0) rtsplaying--;
9618
9619 for(i=0;i<MAXUSERQUOTES;i++)
9620 if (user_quote_time[i])
9621 {
9622 user_quote_time[i]--;
9623 if (!user_quote_time[i]) pub = NUMPAGES;
9624 }
9625 if ((klabs(quotebotgoal-quotebot) <= 16) && (ud.screen_size <= 8))
9626 quotebot += ksgn(quotebotgoal-quotebot);
9627 else
9628 quotebot = quotebotgoal;
9629
9630 if( show_shareware > 0 )
9631 {
9632 show_shareware--;
9633 if(show_shareware == 0)
9634 {
9635 pus = NUMPAGES;
9636 pub = NUMPAGES;
9637 }
9638 }
9639
9640 everyothertime++;
9641
9642 for(i=connecthead;i>=0;i=connectpoint2[i])
9643 copybufbyte(&inputfifo[movefifoplc&(MOVEFIFOSIZ-1)][i],&sync[i],sizeof(input));
9644 movefifoplc++;
9645
9646 updateinterpolations();
9647
9648 j = -1;
9649 for(i=connecthead;i>=0;i=connectpoint2[i])
9650 {
9651 if ((sync[i].bits&(1<<26)) == 0) { j = i; continue; }
9652
9653 closedemowrite();
9654
9655 if (i == myconnectindex) gameexit(" ");
9656 if (screenpeek == i)
9657 {
9658 screenpeek = connectpoint2[i];
9659 if (screenpeek < 0) screenpeek = connecthead;
9660 }
9661
9662 if (i == connecthead) connecthead = connectpoint2[connecthead];
9663 else connectpoint2[j] = connectpoint2[i];
9664
9665 numplayers--;
9666 ud.multimode--;
9667
9668 if (numplayers < 2)
9669 sound(GENERIC_AMBIENCE17);
9670
9671 pub = NUMPAGES;
9672 pus = NUMPAGES;
9673 vscrn();
9674
9675 sprintf(buf,"%s is history!",ud.user_name[i]);
9676
9677 quickkill(&ps[i]);
9678 deletesprite(ps[i].i);
9679
9680 adduserquote(buf);
9681
9682 if(j < 0 && networkmode == 0 )
9683 gameexit( " \nThe 'MASTER/First player' just quit the game. All\nplayers are returned from the game. This only happens in 5-8\nplayer mode as a different network scheme is used.");
9684 }
9685
9686 if ((numplayers >= 2) && ((movefifoplc&7) == 7))
9687 {
9688 ch = (uint8_t )(randomseed&255);
9689 for(i=connecthead;i>=0;i=connectpoint2[i])
9690 ch += ((ps[i].posx+ps[i].posy+ps[i].posz+ps[i].ang+ps[i].horiz)&255);
9691 syncval[myconnectindex][syncvalhead[myconnectindex]&(MOVEFIFOSIZ-1)] = ch;
9692 syncvalhead[myconnectindex]++;
9693
9694
9695 }
9696
9697 if(ud.recstat == 1) record();
9698
9699 if( ud.pause_on == 0 )
9700 {
9701 global_random = TRAND;
9702 movedummyplayers();//ST 13
9703 }
9704
9705 for(i=connecthead;i>=0;i=connectpoint2[i])
9706 {
9707 cheatkeys(i);
9708
9709 if( ud.pause_on == 0 )
9710 {
9711 processinput(i);
9712 checksectors(i);
9713 }
9714 }
9715
9716 if( ud.pause_on == 0 )
9717 {
9718 movefta();//ST 2
9719 moveweapons(); //ST 5 (must be last)
9720 movetransports(); //ST 9
9721
9722 moveplayers(); //ST 10
9723 movefallers(); //ST 12
9724 moveexplosions(); //ST 4
9725
9726 moveactors(); //ST 1
9727 moveeffectors(); //ST 3
9728
9729 movestandables(); //ST 6
9730 doanimations();
9731 movefx(); //ST 11
9732 }
9733
9734 fakedomovethingscorrect();
9735
9736 if( (everyothertime&1) == 0)
9737 {
9738 animatewalls();
9739 movecyclers();
9740 pan3dsound();
9741 }
9742
9743
9744 return 0;
9745}
9746
9747
9748void doorders(void)
9749{
9750 short i;
9751
9752 setview(0,0,xdim-1,ydim-1);
9753
9754 for(i=0;i<63;i+=7) palto(0,0,0,i);
9755 ps[myconnectindex].palette = palette;
9756 totalclock = 0;
9757 KB_FlushKeyboardQueue();
9758 rotatesprite(0,0,65536L,0,ORDERING,0,0,2+8+16+64, 0,0,xdim-1,ydim-1);
9759 nextpage(); for(i=63;i>0;i-=7) palto(0,0,0,i);
9760 totalclock = 0;while( !KB_KeyWaiting() ) getpackets();
9761
9762 for(i=0;i<63;i+=7) palto(0,0,0,i);
9763 totalclock = 0;
9764 KB_FlushKeyboardQueue();
9765 rotatesprite(0,0,65536L,0,ORDERING+1,0,0,2+8+16+64, 0,0,xdim-1,ydim-1);
9766 nextpage(); for(i=63;i>0;i-=7) palto(0,0,0,i);
9767 totalclock = 0;while( !KB_KeyWaiting() ) getpackets();
9768
9769 for(i=0;i<63;i+=7) palto(0,0,0,i);
9770 totalclock = 0;
9771 KB_FlushKeyboardQueue();
9772 rotatesprite(0,0,65536L,0,ORDERING+2,0,0,2+8+16+64, 0,0,xdim-1,ydim-1);
9773 nextpage(); for(i=63;i>0;i-=7) palto(0,0,0,i);
9774 totalclock = 0;while( !KB_KeyWaiting() ) getpackets();
9775
9776 for(i=0;i<63;i+=7) palto(0,0,0,i);
9777 totalclock = 0;
9778 KB_FlushKeyboardQueue();
9779 rotatesprite(0,0,65536L,0,ORDERING+3,0,0,2+8+16+64, 0,0,xdim-1,ydim-1);
9780 nextpage(); for(i=63;i>0;i-=7) palto(0,0,0,i);
9781 totalclock = 0;while( !KB_KeyWaiting() ) getpackets();
9782}
9783
9784void dobonus(uint8_t bonusonly)
9785{
9786 short t, gfx_offset;
9787// short tinc;
9788 int32_t i, y,xfragtotal,yfragtotal;
9789 short bonuscnt;
9790 char text[512];
9791
9792 int32_t breathe[] =
9793 {
9794 0, 30,VICTORY1+1,176,59,
9795 30, 60,VICTORY1+2,176,59,
9796 60, 90,VICTORY1+1,176,59,
9797 90, 120,0 ,176,59
9798 };
9799
9800 int32_t bossmove[] =
9801 {
9802 0, 120,VICTORY1+3,86,59,
9803 220, 260,VICTORY1+4,86,59,
9804 260, 290,VICTORY1+5,86,59,
9805 290, 320,VICTORY1+6,86,59,
9806 320, 350,VICTORY1+7,86,59,
9807 350, 380,VICTORY1+8,86,59
9808 };
9809
9810 bonuscnt = 0;
9811
9812 for(t=0;t<64;t+=7) palto(0,0,0,t);
9813 setview(0,0,xdim-1,ydim-1);
9814 clearview(0L);
9815 nextpage();
9816 flushperms();
9817
9818 FX_StopAllSounds();
9819 clearsoundlocks();
9820 FX_SetReverb(0L);
9821
9822 if(bonusonly) goto FRAGBONUS;
9823
9824 if(numplayers < 2 && ud.eog && ud.from_bonus == 0)
9825 switch(ud.volume_number)
9826 {
9827 case 0:
9828 if(ud.lockout == 0)
9829 {
9830 clearview(0L);
9831 rotatesprite(0,50<<16,65536L,0,VICTORY1,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1);
9832 nextpage();
9833 ps[myconnectindex].palette = endingpal;
9834 for(t=63;t>=0;t--) palto(0,0,0,t);
9835
9836 KB_FlushKeyboardQueue();
9837 totalclock = 0; //tinc = 0;
9838 while( 1 )
9839 {
9840 clearview(0L);
9841 rotatesprite(0,50<<16,65536L,0,VICTORY1,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1);
9842
9843 // boss
9844 if( totalclock > 390 && totalclock < 780 )
9845 for(t=0;t<35;t+=5) if( bossmove[t+2] && (totalclock%390) > bossmove[t] && (totalclock%390) <= bossmove[t+1] )
9846 {
9847 if(t==10 && bonuscnt == 1) { sound(SHOTGUN_FIRE);sound(SQUISHED); bonuscnt++; }
9848 rotatesprite(bossmove[t+3]<<16,bossmove[t+4]<<16,65536L,0,bossmove[t+2],0,0,2+8+16+64+128,0,0,xdim-1,ydim-1);
9849 }
9850
9851 // Breathe
9852 if( totalclock < 450 || totalclock >= 750 )
9853 {
9854 if(totalclock >= 750)
9855 {
9856 rotatesprite(86<<16,59<<16,65536L,0,VICTORY1+8,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1);
9857 if(totalclock >= 750 && bonuscnt == 2) { sound(DUKETALKTOBOSS); bonuscnt++; }
9858 }
9859 for(t=0;t<20;t+=5)
9860 if( breathe[t+2] && (totalclock%120) > breathe[t] && (totalclock%120) <= breathe[t+1] )
9861 {
9862 if(t==5 && bonuscnt == 0)
9863 {
9864 sound(BOSSTALKTODUKE);
9865 bonuscnt++;
9866 }
9867 rotatesprite(breathe[t+3]<<16,breathe[t+4]<<16,65536L,0,breathe[t+2],0,0,2+8+16+64+128,0,0,xdim-1,ydim-1);
9868 }
9869 }
9870
9871 getpackets();
9872 nextpage();
9873 if( KB_KeyWaiting() ) break;
9874 }
9875 }
9876
9877 for(t=0;t<64;t++) palto(0,0,0,t);
9878
9879 KB_FlushKeyboardQueue();
9880 ps[myconnectindex].palette = palette;
9881
9882 rotatesprite(0,0,65536L,0,3292,0,0,2+8+16+64, 0,0,xdim-1,ydim-1);
9883 nextpage(); for(t=63;t>0;t--) palto(0,0,0,t);
9884 while( !KB_KeyWaiting() ) getpackets();
9885 for(t=0;t<64;t++) palto(0,0,0,t);
9886 MUSIC_StopSong();
9887 FX_StopAllSounds();
9888 clearsoundlocks();
9889 break;
9890 case 1:
9891 MUSIC_StopSong();
9892 clearview(0L);
9893 nextpage();
9894
9895 if(ud.lockout == 0)
9896 {
9897 playanm("cineov2.anm",1);
9898 KB_FlushKeyboardQueue();
9899 clearview(0L);
9900 nextpage();
9901 }
9902
9903 sound(PIPEBOMB_EXPLODE);
9904
9905 for(t=0;t<64;t++) palto(0,0,0,t);
9906 setview(0,0,xdim-1,ydim-1);
9907 KB_FlushKeyboardQueue();
9908 ps[myconnectindex].palette = palette;
9909 rotatesprite(0,0,65536L,0,3293,0,0,2+8+16+64, 0,0,xdim-1,ydim-1);
9910 nextpage(); for(t=63;t>0;t--) palto(0,0,0,t);
9911 while( !KB_KeyWaiting() ) getpackets();
9912 for(t=0;t<64;t++) palto(0,0,0,t);
9913
9914 break;
9915
9916 case 3:
9917
9918 setview(0,0,xdim-1,ydim-1);
9919
9920 MUSIC_StopSong();
9921 clearview(0L);
9922 nextpage();
9923
9924 if(ud.lockout == 0)
9925 {
9926 KB_FlushKeyboardQueue();
9927 playanm("vol4e1.anm",8);
9928 clearview(0L);
9929 nextpage();
9930 playanm("vol4e2.anm",10);
9931 clearview(0L);
9932 nextpage();
9933 playanm("vol4e3.anm",11);
9934 clearview(0L);
9935 nextpage();
9936 }
9937
9938 FX_StopAllSounds();
9939 clearsoundlocks();
9940 sound(ENDSEQVOL3SND4);
9941 KB_FlushKeyboardQueue();
9942
9943 ps[myconnectindex].palette = palette;
9944 palto(0,0,0,63);
9945 clearview(0L);
9946 menutext(160,60,0,0,"THANKS TO ALL OUR");
9947 menutext(160,60+16,0,0,"FANS FOR GIVING");
9948 menutext(160,60+16+16,0,0,"US BIG HEADS.");
9949 menutext(160,70+16+16+16,0,0,"LOOK FOR A DUKE NUKEM 3D");
9950 menutext(160,70+16+16+16+16,0,0,"SEQUEL SOON.");
9951 nextpage();
9952
9953 for(t=63;t>0;t-=3) palto(0,0,0,t);
9954 KB_FlushKeyboardQueue();
9955 while(!KB_KeyWaiting()) getpackets();
9956 for(t=0;t<64;t+=3) palto(0,0,0,t);
9957
9958 clearview(0L);
9959 nextpage();
9960
9961 playanm("DUKETEAM.ANM",4);
9962
9963 KB_FlushKeyboardQueue();
9964 while(!KB_KeyWaiting()) getpackets();
9965
9966 clearview(0L);
9967 nextpage();
9968 palto(0,0,0,63);
9969
9970 FX_StopAllSounds();
9971 clearsoundlocks();
9972 KB_FlushKeyboardQueue();
9973
9974 break;
9975
9976 case 2:
9977
9978 MUSIC_StopSong();
9979 clearview(0L);
9980 nextpage();
9981 if(ud.lockout == 0)
9982 {
9983 for(t=63;t>=0;t--) palto(0,0,0,t);
9984 playanm("cineov3.anm",2);
9985 KB_FlushKeyboardQueue();
9986 ototalclock = totalclock+200;
9987 while(totalclock < ototalclock) getpackets();
9988 clearview(0L);
9989 nextpage();
9990
9991 FX_StopAllSounds();
9992 clearsoundlocks();
9993 }
9994
9995 playanm("RADLOGO.ANM",3);
9996
9997 if( ud.lockout == 0 && !KB_KeyWaiting() )
9998 {
9999 sound(ENDSEQVOL3SND5);
10000 while(Sound[ENDSEQVOL3SND5].lock>=200) getpackets();
10001 if(KB_KeyWaiting()) goto ENDANM;
10002 sound(ENDSEQVOL3SND6);
10003 while(Sound[ENDSEQVOL3SND6].lock>=200) getpackets();
10004 if(KB_KeyWaiting()) goto ENDANM;
10005 sound(ENDSEQVOL3SND7);
10006 while(Sound[ENDSEQVOL3SND7].lock>=200) getpackets();
10007 if(KB_KeyWaiting()) goto ENDANM;
10008 sound(ENDSEQVOL3SND8);
10009 while(Sound[ENDSEQVOL3SND8].lock>=200) getpackets();
10010 if(KB_KeyWaiting()) goto ENDANM;
10011 sound(ENDSEQVOL3SND9);
10012 while(Sound[ENDSEQVOL3SND9].lock>=200) getpackets();
10013 }
10014
10015 KB_FlushKeyboardQueue();
10016 totalclock = 0;
10017 while(!KB_KeyWaiting() && totalclock < 120) getpackets();
10018
10019 ENDANM:
10020
10021 FX_StopAllSounds();
10022 clearsoundlocks();
10023
10024 KB_FlushKeyboardQueue();
10025
10026 clearview(0L);
10027
10028 break;
10029 }
10030
10031 FRAGBONUS:
10032
10033 ps[myconnectindex].palette = palette;
10034 KB_FlushKeyboardQueue();
10035 totalclock = 0; //tinc = 0;
10036 bonuscnt = 0;
10037
10038 MUSIC_StopSong();
10039 FX_StopAllSounds();
10040 clearsoundlocks();
10041
10042 if(playerswhenstarted > 1 && ud.coop != 1 )
10043 {
10044 if(!(MusicToggle == 0 || MusicDevice == NumSoundCards))
10045 sound(BONUSMUSIC);
10046
10047 rotatesprite(0,0,65536L,0,MENUSCREEN,16,0,2+8+16+64,0,0,xdim-1,ydim-1);
10048 rotatesprite(160<<16,34<<16,65536L,0,INGAMEDUKETHREEDEE,0,0,10,0,0,xdim-1,ydim-1);
10049 rotatesprite((260)<<16,36<<16,65536L,0,PLUTOPAKSPRITE+2,0,0,2+8,0,0,xdim-1,ydim-1);
10050 gametext(160,58+2,"MULTIPLAYER TOTALS",0,2+8+16);
10051 gametext(160,58+10,level_names[(ud.volume_number*11)+ud.last_level-1],0,2+8+16);
10052
10053 gametext(160,165,"PRESS ANY KEY TO CONTINUE",0,2+8+16);
10054
10055
10056 t = 0;
10057 minitext(23,80," NAME KILLS",8,2+8+16+128);
10058 for(i=0;i<playerswhenstarted;i++)
10059 {
10060 sprintf(text,"%-4d",i+1);
10061 minitext(92+(i*23),80,text,3,2+8+16+128);
10062 }
10063
10064 for(i=0;i<playerswhenstarted;i++)
10065 {
10066 xfragtotal = 0;
10067 sprintf(text,"%d",i+1);
10068
10069 minitext(30,90+t,text,0,2+8+16+128);
10070 minitext(38,90+t,ud.user_name[i],ps[i].palookup,2+8+16+128);
10071
10072 for(y=0;y<playerswhenstarted;y++)
10073 {
10074 if(i == y)
10075 {
10076 sprintf(text,"%-4d",ps[y].fraggedself);
10077 minitext(92+(y*23),90+t,text,2,2+8+16+128);
10078 xfragtotal -= ps[y].fraggedself;
10079 }
10080 else
10081 {
10082 sprintf(text,"%-4d",frags[i][y]);
10083 minitext(92+(y*23),90+t,text,0,2+8+16+128);
10084 xfragtotal += frags[i][y];
10085 }
10086
10087 if(myconnectindex == connecthead)
10088 {
10089 sprintf(text,"stats %d killed %d %d\n",i+1,y+1,frags[i][y]);
10090 sendscore(text);
10091 }
10092 }
10093
10094 sprintf(text,"%-4d",xfragtotal);
10095 minitext(101+(8*23),90+t,text,2,2+8+16+128);
10096
10097 t += 7;
10098 }
10099
10100 for(y=0;y<playerswhenstarted;y++)
10101 {
10102 yfragtotal = 0;
10103 for(i=0;i<playerswhenstarted;i++)
10104 {
10105 if(i == y)
10106 yfragtotal += ps[i].fraggedself;
10107 yfragtotal += frags[i][y];
10108 }
10109 sprintf(text,"%-4d",yfragtotal);
10110 minitext(92+(y*23),96+(8*7),text,2,2+8+16+128);
10111 }
10112
10113 minitext(45,96+(8*7),"DEATHS",8,2+8+16+128);
10114 nextpage();
10115
10116 for(t=0;t<64;t+=7)
10117 palto(0,0,0,63-t);
10118
10119 KB_FlushKeyboardQueue();
10120 while(KB_KeyWaiting()==0) getpackets();
10121
10122 if( KB_KeyPressed( sc_F12 ) )
10123 {
10124 KB_ClearKeyDown( sc_F12 );
10125 takescreenshot();
10126 }
10127
10128 if(bonusonly || ud.multimode > 1) return;
10129
10130 for(t=0;t<64;t+=7) palto(0,0,0,t);
10131 }
10132
10133 if(bonusonly || ud.multimode > 1) return;
10134
10135 switch(ud.volume_number)
10136 {
10137 case 1:
10138 gfx_offset = 5;
10139 break;
10140 default:
10141 gfx_offset = 0;
10142 break;
10143 }
10144
10145 rotatesprite(0,0,65536L,0,BONUSSCREEN+gfx_offset,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1);
10146
10147 menutext(160,20-6,0,0,&level_names[(ud.volume_number*11)+ud.last_level-1][0]);
10148 menutext(160,36-6,0,0,"COMPLETED");
10149
10150 gametext(160,192,"PRESS ANY KEY TO CONTINUE",16,2+8+16);
10151
10152 if(!(MusicToggle == 0 || MusicDevice == NumSoundCards))
10153 sound(BONUSMUSIC);
10154
10155 nextpage();
10156 KB_FlushKeyboardQueue();
10157 for(t=0;t<64;t++) palto(0,0,0,63-t);
10158 bonuscnt = 0;
10159 totalclock = 0; //tinc = 0;
10160
10161 while( 1 )
10162 {
10163 sampletimer();
10164 if(ps[myconnectindex].gm&MODE_EOL)
10165 {
10166 rotatesprite(0,0,65536L,0,BONUSSCREEN+gfx_offset,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1);
10167
10168 if( totalclock > (1000000000L) && totalclock < (1000000320L) )
10169 {
10170 switch( (totalclock>>4)%15 )
10171 {
10172 case 0:
10173 if(bonuscnt == 6)
10174 {
10175 bonuscnt++;
10176 sound(SHOTGUN_COCK);
10177 switch(rand()&3)
10178 {
10179 case 0:
10180 sound(BONUS_SPEECH1);
10181 break;
10182 case 1:
10183 sound(BONUS_SPEECH2);
10184 break;
10185 case 2:
10186 sound(BONUS_SPEECH3);
10187 break;
10188 case 3:
10189 sound(BONUS_SPEECH4);
10190 break;
10191 }
10192 }
10193 case 1:
10194 case 4:
10195 case 5:
10196 rotatesprite(199<<16,31<<16,65536L,0,BONUSSCREEN+3+gfx_offset,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1);
10197 break;
10198 case 2:
10199 case 3:
10200 rotatesprite(199<<16,31<<16,65536L,0,BONUSSCREEN+4+gfx_offset,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1);
10201 break;
10202 }
10203 }
10204 else if( totalclock > (10240+120L) ) break;
10205 else
10206 {
10207 switch( (totalclock>>5)&3 )
10208 {
10209 case 1:
10210 case 3:
10211 rotatesprite(199<<16,31<<16,65536L,0,BONUSSCREEN+1+gfx_offset,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1);
10212 break;
10213 case 2:
10214 rotatesprite(199<<16,31<<16,65536L,0,BONUSSCREEN+2+gfx_offset,0,0,2+8+16+64+128,0,0,xdim-1,ydim-1);
10215 break;
10216 }
10217 }
10218
10219 menutext(160,20-6,0,0,&level_names[(ud.volume_number*11)+ud.last_level-1][0]);
10220 menutext(160,36-6,0,0,"COMPLETED");
10221
10222 gametext(160,192,"PRESS ANY KEY TO CONTINUE",16,2+8+16);
10223
10224 if( totalclock > (60*3) )
10225 {
10226 gametext(10,59+9,"Your Time:",0,2+8+16);
10227 gametext(10,69+9,"Par time:",0,2+8+16);
10228 gametext(10,78+9,"3D Realms' Time:",0,2+8+16);
10229 if(bonuscnt == 0)
10230 bonuscnt++;
10231
10232 if( totalclock > (60*4) )
10233 {
10234 if(bonuscnt == 1)
10235 {
10236 bonuscnt++;
10237 sound(PIPEBOMB_EXPLODE);
10238 }
10239 sprintf(text,"%02d:%02d",
10240 (ps[myconnectindex].player_par/(26*60))%60,
10241 (ps[myconnectindex].player_par/26)%60);
10242 gametext((320>>2)+71,60+9,text,0,2+8+16);
10243
10244 sprintf(text,"%02d:%02d",
10245 (partime[ud.volume_number*11+ud.last_level-1]/(26*60))%60,
10246 (partime[ud.volume_number*11+ud.last_level-1]/26)%60);
10247 gametext((320>>2)+71,69+9,text,0,2+8+16);
10248
10249 sprintf(text,"%02d:%02d",
10250 (designertime[ud.volume_number*11+ud.last_level-1]/(26*60))%60,
10251 (designertime[ud.volume_number*11+ud.last_level-1]/26)%60);
10252 gametext((320>>2)+71,78+9,text,0,2+8+16);
10253
10254 }
10255 }
10256 if( totalclock > (60*6) )
10257 {
10258 gametext(10,94+9,"Enemies Killed:",0,2+8+16);
10259 gametext(10,99+4+9,"Enemies Left:",0,2+8+16);
10260
10261 if(bonuscnt == 2)
10262 {
10263 bonuscnt++;
10264 sound(FLY_BY);
10265 }
10266
10267 if( totalclock > (60*7) )
10268 {
10269 if(bonuscnt == 3)
10270 {
10271 bonuscnt++;
10272 sound(PIPEBOMB_EXPLODE);
10273 }
10274 sprintf(text,"%-3hhd",ps[myconnectindex].actors_killed);
10275 gametext((320>>2)+70,93+9,text,0,2+8+16);
10276 if(ud.player_skill > 3 )
10277 {
10278 sprintf(text,"N/A");
10279 gametext((320>>2)+70,99+4+9,text,0,2+8+16);
10280 }
10281 else
10282 {
10283 if( (ps[myconnectindex].max_actors_killed-ps[myconnectindex].actors_killed) < 0 )
10284 sprintf(text,"%-3d",0);
10285 else sprintf(text,"%-3d",ps[myconnectindex].max_actors_killed-ps[myconnectindex].actors_killed);
10286 gametext((320>>2)+70,99+4+9,text,0,2+8+16);
10287 }
10288 }
10289 }
10290 if( totalclock > (60*9) )
10291 {
10292 gametext(10,120+9,"Secrets Found:",0,2+8+16);
10293 gametext(10,130+9,"Secrets Missed:",0,2+8+16);
10294 if(bonuscnt == 4) bonuscnt++;
10295
10296 if( totalclock > (60*10) )
10297 {
10298 if(bonuscnt == 5)
10299 {
10300 bonuscnt++;
10301 sound(PIPEBOMB_EXPLODE);
10302 }
10303 sprintf(text,"%-3d",ps[myconnectindex].secret_rooms);
10304 gametext((320>>2)+70,120+9,text,0,2+8+16);
10305 if( ps[myconnectindex].secret_rooms > 0 )
10306 sprintf(text,"%-3d",(100*ps[myconnectindex].secret_rooms/ps[myconnectindex].max_secret_rooms));
10307 sprintf(text,"%-3d",ps[myconnectindex].max_secret_rooms-ps[myconnectindex].secret_rooms);
10308 gametext((320>>2)+70,130+9,text,0,2+8+16);
10309 }
10310 }
10311
10312 if(totalclock > 10240 && totalclock < 10240+10240)
10313 totalclock = 1024;
10314
10315 if( KB_KeyWaiting() && totalclock > (60*2) )
10316 {
10317 if( KB_KeyPressed( sc_F12 ) )
10318 {
10319 KB_ClearKeyDown( sc_F12 );
10320 takescreenshot();
10321 }
10322
10323 if( totalclock < (60*13) )
10324 {
10325 KB_FlushKeyboardQueue();
10326 totalclock = (60*13);
10327 }
10328 else if( totalclock < (1000000000L))
10329 totalclock = (1000000000L);
10330 }
10331 }
10332 else break;
10333 nextpage();
10334 }
10335}
10336
10337
10338void cameratext(short i)
10339{
10340 uint8_t flipbits;
10341 int32_t x , y;
10342
10343 if(!T1)
10344 {
10345 rotatesprite(24<<16,33<<16,65536L,0,CAMCORNER,0,0,2,windowx1,windowy1,windowx2,windowy2);
10346 rotatesprite((320-26)<<16,34<<16,65536L,0,CAMCORNER+1,0,0,2,windowx1,windowy1,windowx2,windowy2);
10347 rotatesprite(22<<16,163<<16,65536L,512,CAMCORNER+1,0,0,2+4,windowx1,windowy1,windowx2,windowy2);
10348 rotatesprite((310-10)<<16,163<<16,65536L,512,CAMCORNER+1,0,0,2,windowx1,windowy1,windowx2,windowy2);
10349 if(totalclock&16)
10350 rotatesprite(46<<16,32<<16,65536L,0,CAMLIGHT,0,0,2,windowx1,windowy1,windowx2,windowy2);
10351 }
10352 else
10353 {
10354 flipbits = (totalclock<<1)&48;
10355 for(x=0;x<394;x+=64)
10356 for(y=0;y<200;y+=64)
10357 rotatesprite(x<<16,y<<16,65536L,0,STATIC,0,0,2+flipbits,windowx1,windowy1,windowx2,windowy2);
10358 }
10359}
10360
10361void vglass(int32_t x,int32_t y,short a,short wn,short n)
10362{
10363 int32_t z, zincs;
10364 short sect;
10365
10366 sect = wall[wn].nextsector;
10367 if(sect == -1) return;
10368 zincs = ( sector[sect].floorz-sector[sect].ceilingz ) / n;
10369
10370 for(z = sector[sect].ceilingz;z < sector[sect].floorz; z += zincs )
10371 EGS(sect,x,y,z-(TRAND&8191),GLASSPIECES+(z&(TRAND%3)),-32,36,36,a+128-(TRAND&255),16+(TRAND&31),0,-1,5);
10372}
10373
10374void lotsofglass(short i,short wallnum,short n)
10375{
10376 int32_t j, xv, yv, z, x1, y1;
10377 short sect, a;
10378
10379 sect = -1;
10380
10381 if(wallnum < 0)
10382 {
10383 for(j=n-1; j >= 0 ;j--)
10384 {
10385 a = SA-256+(TRAND&511)+1024;
10386 EGS(SECT,SX,SY,SZ,GLASSPIECES+(j%3),-32,36,36,a,32+(TRAND&63),1024-(TRAND&1023),i,5);
10387 }
10388 return;
10389 }
10390
10391 j = n+1;
10392
10393 x1 = wall[wallnum].x;
10394 y1 = wall[wallnum].y;
10395
10396 xv = wall[wall[wallnum].point2].x-x1;
10397 yv = wall[wall[wallnum].point2].y-y1;
10398
10399 x1 -= ksgn(yv);
10400 y1 += ksgn(xv);
10401
10402 xv /= j;
10403 yv /= j;
10404
10405 for(j=n;j>0;j--)
10406 {
10407 x1 += xv;
10408 y1 += yv;
10409
10410 updatesector(x1,y1,&sect);
10411 if(sect >= 0)
10412 {
10413 z = sector[sect].floorz-(TRAND&(klabs(sector[sect].ceilingz-sector[sect].floorz)));
10414 if( z < -(32<<8) || z > (32<<8) )
10415 z = SZ-(32<<8)+(TRAND&((64<<8)-1));
10416 a = SA-1024;
10417 EGS(SECT,x1,y1,z,GLASSPIECES+(j%3),-32,36,36,a,32+(TRAND&63),-(TRAND&1023),i,5);
10418 }
10419 }
10420}
10421
10422void spriteglass(short i,short n)
10423{
10424 int32_t j, k, a, z;
10425
10426 for(j=n;j>0;j--)
10427 {
10428 a = TRAND&2047;
10429 z = SZ-((TRAND&16)<<8);
10430 k = EGS(SECT,SX,SY,z,GLASSPIECES+(j%3),TRAND&15,36,36,a,32+(TRAND&63),-512-(TRAND&2047),i,5);
10431 sprite[k].pal = sprite[i].pal;
10432 }
10433}
10434
10435void ceilingglass(short i,short sectnum,short n)
10436{
10437 int32_t j, xv, yv, z, x1, y1;
10438 short a,s, startwall,endwall;
10439
10440 startwall = sector[sectnum].wallptr;
10441 endwall = startwall+sector[sectnum].wallnum;
10442
10443 for(s=startwall;s<(endwall-1);s++)
10444 {
10445 x1 = wall[s].x;
10446 y1 = wall[s].y;
10447
10448 xv = (wall[s+1].x-x1)/(n+1);
10449 yv = (wall[s+1].y-y1)/(n+1);
10450
10451 for(j=n;j>0;j--)
10452 {
10453 x1 += xv;
10454 y1 += yv;
10455 a = TRAND&2047;
10456 z = sector[sectnum].ceilingz+((TRAND&15)<<8);
10457 EGS(sectnum,x1,y1,z,GLASSPIECES+(j%3),-32,36,36,a,(TRAND&31),0,i,5);
10458 }
10459 }
10460}
10461
10462
10463
10464void lotsofcolourglass(short i,short wallnum,short n)
10465{
10466 int32_t j, xv, yv, z, x1, y1;
10467 short sect = -1, a, k;
10468
10469 if(wallnum < 0)
10470 {
10471 for(j=n-1; j >= 0 ;j--)
10472 {
10473 a = TRAND&2047;
10474 k = EGS(SECT,SX,SY,SZ-(TRAND&(63<<8)),GLASSPIECES+(j%3),-32,36,36,a,32+(TRAND&63),1024-(TRAND&2047),i,5);
10475 sprite[k].pal = TRAND&15;
10476 }
10477 return;
10478 }
10479
10480 j = n+1;
10481 x1 = wall[wallnum].x;
10482 y1 = wall[wallnum].y;
10483
10484 xv = (wall[wall[wallnum].point2].x-wall[wallnum].x)/j;
10485 yv = (wall[wall[wallnum].point2].y-wall[wallnum].y)/j;
10486
10487 for(j=n;j>0;j--)
10488 {
10489 x1 += xv;
10490 y1 += yv;
10491
10492 updatesector(x1,y1,&sect);
10493 z = sector[sect].floorz-(TRAND&(klabs(sector[sect].ceilingz-sector[sect].floorz)));
10494 if( z < -(32<<8) || z > (32<<8) )
10495 z = SZ-(32<<8)+(TRAND&((64<<8)-1));
10496 a = SA-1024;
10497 k = EGS(SECT,x1,y1,z,GLASSPIECES+(j%3),-32,36,36,a,32+(TRAND&63),-(TRAND&2047),i,5);
10498 sprite[k].pal = TRAND&7;
10499 }
10500}
10501
10502void SetupGameButtons( void )
10503{
10504 CONTROL_DefineFlag(gamefunc_Move_Forward,false);
10505 CONTROL_DefineFlag(gamefunc_Move_Backward,false);
10506 CONTROL_DefineFlag(gamefunc_Turn_Left,false);
10507 CONTROL_DefineFlag(gamefunc_Turn_Right,false);
10508 CONTROL_DefineFlag(gamefunc_Strafe,false);
10509 CONTROL_DefineFlag(gamefunc_Fire,false);
10510 CONTROL_DefineFlag(gamefunc_Open,false);
10511 CONTROL_DefineFlag(gamefunc_Run,false);
10512 CONTROL_DefineFlag(gamefunc_AutoRun,false);
10513 CONTROL_DefineFlag(gamefunc_Jump,false);
10514 CONTROL_DefineFlag(gamefunc_Crouch,false);
10515 CONTROL_DefineFlag(gamefunc_Look_Up,false);
10516 CONTROL_DefineFlag(gamefunc_Look_Down,false);
10517 CONTROL_DefineFlag(gamefunc_Look_Left,false);
10518 CONTROL_DefineFlag(gamefunc_Look_Right,false);
10519 CONTROL_DefineFlag(gamefunc_Strafe_Left,false);
10520 CONTROL_DefineFlag(gamefunc_Strafe_Right,false);
10521 CONTROL_DefineFlag(gamefunc_Aim_Up,false);
10522 CONTROL_DefineFlag(gamefunc_Aim_Down,false);
10523 CONTROL_DefineFlag(gamefunc_Weapon_1,false);
10524 CONTROL_DefineFlag(gamefunc_Weapon_2,false);
10525 CONTROL_DefineFlag(gamefunc_Weapon_3,false);
10526 CONTROL_DefineFlag(gamefunc_Weapon_4,false);
10527 CONTROL_DefineFlag(gamefunc_Weapon_5,false);
10528 CONTROL_DefineFlag(gamefunc_Weapon_6,false);
10529 CONTROL_DefineFlag(gamefunc_Weapon_7,false);
10530 CONTROL_DefineFlag(gamefunc_Weapon_8,false);
10531 CONTROL_DefineFlag(gamefunc_Weapon_9,false);
10532 CONTROL_DefineFlag(gamefunc_Weapon_10,false);
10533 CONTROL_DefineFlag(gamefunc_Inventory,false);
10534 CONTROL_DefineFlag(gamefunc_Inventory_Left,false);
10535 CONTROL_DefineFlag(gamefunc_Inventory_Right,false);
10536 CONTROL_DefineFlag(gamefunc_Holo_Duke,false);
10537 CONTROL_DefineFlag(gamefunc_Jetpack,false);
10538 CONTROL_DefineFlag(gamefunc_NightVision,false);
10539 CONTROL_DefineFlag(gamefunc_MedKit,false);
10540 CONTROL_DefineFlag(gamefunc_TurnAround,false);
10541 CONTROL_DefineFlag(gamefunc_SendMessage,false);
10542 CONTROL_DefineFlag(gamefunc_Map,false);
10543 CONTROL_DefineFlag(gamefunc_Shrink_Screen,false);
10544 CONTROL_DefineFlag(gamefunc_Enlarge_Screen,false);
10545 CONTROL_DefineFlag(gamefunc_Center_View,false);
10546 CONTROL_DefineFlag(gamefunc_Holster_Weapon,false);
10547 CONTROL_DefineFlag(gamefunc_Show_Opponents_Weapon,false);
10548 CONTROL_DefineFlag(gamefunc_Map_Follow_Mode,false);
10549 CONTROL_DefineFlag(gamefunc_See_Coop_View,false);
10550 CONTROL_DefineFlag(gamefunc_Mouse_Aiming,false);
10551 CONTROL_DefineFlag(gamefunc_Toggle_Crosshair,false);
10552 CONTROL_DefineFlag(gamefunc_Steroids,false);
10553 CONTROL_DefineFlag(gamefunc_Quick_Kick,false);
10554 CONTROL_DefineFlag(gamefunc_Next_Weapon,false);
10555 CONTROL_DefineFlag(gamefunc_Previous_Weapon,false);
10556 CONTROL_DefineFlag(gamefunc_Console,false);
10557}
10558
10559/*
10560===================
10561=
10562= GetTime
10563=
10564===================
10565*/
10566
10567int32_t GetTime(void)
10568 {
10569 return totalclock;
10570 }
10571
10572
10573/*
10574===================
10575=
10576= CenterCenter
10577=
10578===================
10579*/
10580
10581void CenterCenter(void)
10582 {
10583 printf("Center the joystick and press a button\n");
10584 }
10585
10586/*
10587===================
10588=
10589= UpperLeft
10590=
10591===================
10592*/
10593
10594void UpperLeft(void)
10595 {
10596 printf("Move joystick to upper-left corner and press a button\n");
10597 }
10598
10599/*
10600===================
10601=
10602= LowerRight
10603=
10604===================
10605*/
10606
10607void LowerRight(void)
10608 {
10609 printf("Move joystick to lower-right corner and press a button\n");
10610 }
10611
10612/*
10613===================
10614=
10615= CenterThrottle
10616=
10617===================
10618*/
10619
10620void CenterThrottle(void)
10621 {
10622 printf("Center the throttle control and press a button\n");
10623 }
10624
10625/*
10626===================
10627=
10628= CenterRudder
10629=
10630===================
10631*/
10632
10633void CenterRudder(void)
10634{
10635 printf("Center the rudder control and press a button\n");
10636}
10637
10638// FIX_00006: better naming system for screenshots + message when pic is taken.
10639// Use ./screenshots folder. Screenshot code rerwritten. Faster and
10640// makes smaller files. Doesn't freeze or lag the game anymore.
10641void takescreenshot(void)
10642{
10643 char szFilename[256];
10644 int i;
10645 char score[20];
10646 time_t time4file;
10647 char text[512];
10648
10649 // xduke: Build a nice name w/ date and players name if in multi mode.
10650 time(&time4file);
10651
10652 sprintf(text, "Chocolate DukeNukem3D(v%d.%d) %d",
10653 CHOCOLATE_DUKE_REV_X,
10654 CHOCOLATE_DUKE_REV_DOT_Y,
10655 time(NULL));
10656
10657 if(ud.multimode>1) // if more than 1 player, we add name. Then add score if DM
10658 {
10659 text[0] = '\0';
10660 strcat((char *)text, " [");
10661 for(i=connecthead;i>=0;i=connectpoint2[i])
10662 {
10663 if(!ud.user_name[i][0])
10664 strcat(text, "NoName");
10665 else
10666 strcat(text, &ud.user_name[i][0]);
10667
10668 if(ud.m_coop==0 || ud.m_coop==2) // if DM or DM No spawn. Add Score as well
10669 {
10670 strcat(text, "(");
10671 snprintf(score, sizeof(score), "%d",ps[i].frag-ps[i].fraggedself);
10672 strcat(text, score);
10673 strcat(text, ") vs ");
10674 }
10675 else
10676 strcat(text, " vs ");
10677 }
10678 tempbuf[strlen(text)-4]=0; // remove last vs
10679 strcat(text, "]");
10680 }
10681 strcat(text, ".bmp");
10682
10683
10684 // If this is a TC save it to the TC's directory
10685 if(getGameDir()[0] != '\0')
10686 {
10687 sprintf(szFilename, "%s\\%s", getGameDir(), SCREENSHOTPATH);
10688 mkdir(szFilename);
10689 sprintf(szFilename, "%s\\%s\\%s", getGameDir(), SCREENSHOTPATH, tempbuf);
10690 }
10691 // otherwise let's save it to the root.
10692 else
10693 {
10694 mkdir(SCREENSHOTPATH);
10695 sprintf(szFilename, "%s\\%s", SCREENSHOTPATH, tempbuf);
10696 }
10697
10698 if(SafeFileExists(szFilename) == 0)
10699 {
10700 screencapture(szFilename,0);
10701 sprintf(fta_quotes[103],"SCREEN SAVED");
10702 sound(EXITMENUSOUND);
10703 }
10704 else
10705 sprintf(fta_quotes[103],"CAN'T WRITE FILE!");
10706
10707 FTA(103,&ps[screenpeek],1);
10708
10709}
10710
10711
10712// Rare Multiplayer, when dead, total screen screwup back again!
10713// E3l1 (Coop /w monsters) sprite list corrupt 50%
10714// Univbe exit, instead, default to screen buffer.
10715// Check all caches bounds and memory usages
10716// Fix enlarger weapon selections to perfection
10717// Need sounds.c
10718// Spawning a couple of sounds at the same time
10719// Check Weapon Switching
10720// FIRE and FIRE2
10721// Where should I flash the screen white???
10722// Jittery on subs in mp?
10723// Check accurate memory amounts!
10724// Why squish sound at hit space when dead?
10725// Falling Counter Not reset in mp
10726// Wierd small freezer
10727// Double freeze on player?, still firing
10728// Do Mouse Flip option
10729// Save mouse aiming
10730// Laser bounce off mirrors
10731// GEORGE: Ten in text screen.
10732// Alien:
10733// Freeze: change
10734// Press space holding player
10735// Press space
10736// tank broke
10737// 2d mode fucked in fake mp mode
10738// 207
10739// Mail not rolling up on conveyers
10740// Fix all alien animations
10741// Do episode names in .CONS
10742// do syntak check for "{?????"
10743// Make commline parms set approiate multiplayer flags
10744
10745// Check all breakables to see if they are exploding properly
10746// Fix freezing palette on Alien
10747
10748// Do a demo make run overnite
10749// Fix Super Duck
10750// Slime Guies, use quickkick.
10751
10752// Make Lasers from trip bombs reflect off mirrors
10753// Remember for lockout of sound swears
10754// Pass sender in packed, NOT
10755// Fatal sync give no message for TEN
10756// Hitting TEN BUTTON(OPTION) no TEN SCreen
10757// Check multioperateswitches for se 31,32
10758// Fix pal for ceilings (SE#18)
10759// case 31: sprites up one high
10760// E1l1 No Kill All troops in room, sleep time
10761
10762// Fifo for message list
10763
10764// Bloodsplat on conveyers
10765
10766// Meclanical
10767// Increase sound
10768// Mouse Delay at death
10769// Wierd slowdown
10770
10771// Footprints on stuff floating
10772
10773// Ken, The inside function is called a lot in -1 sectors
10774// No loading Univbe message rewrite
10775// Expander must cycle with rest of weapons
10776// Duck SHOOT PIPEBOMB, red wall
10777
10778// Get commit source from mark
10779
10780/*
10781 1. fix pipebomb bug
10782 2. check george maps
10783 4. Save/Restore check (MP and SP)
10784 5. Check TEN
10785 6. Get Commit fixed
10786 8. Is mail slow?
10787 9. Cacheing
10788 10. Blue out "PLAY ON TEN" in MULTIPLAYER
10789 11. Eight Player test
10790 12. Postal.voc not found.
10791 13. All Monsters explode in arcade,
10792 check SEENINE STRENGTH,
10793 Change 28<<8 back to 16<<8 in hitradius
10794 Compare 1.3d to 1.4
10795 14. Check sounds/gfx for for parr lock
10796 15. Player # Loaded a game
10797 16. Replace Crane code 1.3d to 1.4
10798 17. Fix Greenslime
10799 18. Small Freeze sprite,below floor
10800 19. Vesa message auto abort in mp?
10801 20. Fucked Palette in my skip ahead in MP
10802 21. Load in main menu
10803 22. Rotated frag screen no game screen
10804 23. Jibs sounds when killed other dukes
10805 24. Ten code and /f4 mode
10806 25. Fix All MP Glitches!!
10807 26. Unrem Menues anim tenbn
10808 27. buy groc,clothes,scanner
10809 28. Why Double Defs in global and game, is so at work
10810 29. Check that all .objs are erased
10811 30. Check why 1.3ds gotweapon gamedef coop code no workie
10812 31. Heavy mods to net code
10813 32. Make sure all commline stuff works,
10814 33. killed all waitfor???
10815 34. 90k stack
10816 35. double door probs
10817 36: copy protection
10818 * when you start a game the duke saying that is played when you choose a skill the sound is cut off.
10819 * NEWBEASTJUMPING is not deleted at premap in multi-play
10820 if(*c == '4') no work need objs ask ken, commit
10821 {
10822 movesperpacket = 4;
10823 setpackettimeout(0x3fffffff,0x3fffffff);
10824 }
10825 remember, netcode load
10826*/
10827// Ai Problem in god mode.
10828// Checkplayerhurtwall for forcefields bigforce
10829// Nuddie, posters. IMF
10830// Release commit.c to public?
10831// Document Save bug with mp
10832// Check moves per packet /f4 waitforeverybody over net?
10833// Kill IDF OBJ
10834// No shotguns under water @ tanker
10835// Unrem copyprotect
10836// Look for printf and puts
10837// Check con rewrites
10838// erase mmulti.c, or get newest objs
10839// Why nomonsters screwy in load menu in mp
10840// load last > 'y' == NOT
10841// Check xptr oos when dead rising to surface.
10842// diaginal warping with shotguns
10843// Test white room. Lasertripbomb arming crash
10844// The Bog
10845// Run Duke Out of windows
10846// Put Version number in con files
10847// Test diff. version playing together
10848// Reorganize dukecd
10849// Put out patch w/ two weeks testing
10850// Print draw3d
10851// Double Klick
10852
10853/*
10854 Duke Nukem V
10855
10856 Layout:
10857
10858 Settings:
10859 Suburbs
10860 Duke inflitrating neighborhoods inf. by aliens
10861 Death Valley:
10862 Sorta like a western. Bull-skulls half buried in the sand
10863 Military compound: Aliens take over nuke-missle silo, duke
10864 must destroy.
10865 Abondend Aircraft field
10866 Vegas:
10867 Blast anything bright! Alien lights camoflauged.
10868 Alien Drug factory. The Blue Liquid
10869 Mountainal Cave:
10870 Interior cave battles.
10871 Jungle:
10872 Trees, canopee, animals, a mysterious hole in the earth with
10873 gas seaping thru.
10874 Penetencury:
10875 Good use of spotlights:
10876 Mental ward:
10877 People whom have claimed to be slowly changing into an
10878 alien species
10879
10880 Inventory:
10881 Wood,
10882 Metal,
10883 Torch,
10884 Rope,
10885 Plastique,
10886 Cloth,
10887 Wiring,
10888 Glue,
10889 Cigars,
10890 Food,
10891 Duck Tape,
10892 Nails,
10893 Piping,
10894 Petrol,
10895 Uranium,
10896 Gold,
10897 Prism,
10898 Power Cell,
10899
10900 Hand spikes (Limited usage, they become dull)
10901 Oxygent (Oxygen mixed with stimulant)
10902
10903
10904 Player Skills:
10905 R-Left,R-Right,Foward,Back
10906 Strafe, Jump, Double Flip Jump for distance
10907 Help, Escape
10908 Fire/Use
10909 Use Menu
10910
10911 After a brief resbit, Duke decides to get back to work.
10912
10913 Cmdr: "Duke, we've got a lot of scared people down there.
10914 Some reports even claim that people are already
10915 slowly changing into aliens."
10916 Duke: "No problem, my speciality is in croud control."
10917 Cmdr: "Croud control, my ass! Remember that incident
10918 during the war? You created nuthin' but death and
10919 destruction."
10920 Duke: "Not destruction, justice."
10921 Cmdr: "I'll take no responsibility for your actions. Your on
10922 your own! Behave your self, damnit! You got that,
10923 soldger?"
10924 Duke: "I've always been on my own... Face it, it's ass kickin' time,
10925 SIR!"
10926 Cmdr: "Get outta here...!"
10927 (Duke gives the Cmdr a hard stair, then cocks his weapon and
10928 walks out of the room)
10929 Cmdr: In a wisper: "Good luck, my friend."
10930
10931 (Cut to a scene where aliens are injecting genetic material
10932 into an unconcious subject)
10933
10934 Programming: ( the functions I need )
10935 Images: Polys
10936 Actors:
10937 Multi-Object sections for change (head,arms,legs,torsoe,all change)
10938 Facial expressions. Pal lookup per poly?
10939
10940 struct imagetype
10941 {
10942 int *itable; // AngX,AngY,AngZ,Xoff,Yoff,Zoff;
10943 int *idata;
10944 struct imagetype *prev, *next;
10945 }
10946
10947*/
10948
10949
10950// Test frag screen name fuckup
10951// Test all xptrs
10952// Make Jibs stick to ceiling
10953// Save Game menu crash
10954// Cache len sum err
10955// Loading in main (MP), reset totalclock?
10956// White Room
10957// Sound hitch with repeat bits
10958// Rewrite saved menues so no crash
10959// Put a getpackets after loadplayer in menus
10960// Put "loading..." before waitfor in loadpla
10961// No ready2send = 0 for loading
10962// Test Joystick
10963// Ten
10964// Bog
10965// Test Blimp respawn
10966// move 1 in player???
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/game.h b/apps/plugins/sdl/progs/duke3d/Game/src/game.h
new file mode 100644
index 0000000000..2dbe4c6b60
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/game.h
@@ -0,0 +1,8 @@
1#ifndef _GAME_H_
2#define _GAME_H_
3
4//extern uint8_t game_dir[512];
5char * getgamedir();
6int gametextpal(int x,int y,char *t,uint8_t s,uint8_t p);
7#endif // include-once header.
8
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/gamedef.c b/apps/plugins/sdl/progs/duke3d/Game/src/gamedef.c
new file mode 100644
index 0000000000..52e2abaed6
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/gamedef.c
@@ -0,0 +1,3316 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#include "duke3d.h"
28
29
30extern short otherp;
31
32static short total_lines,line_number;
33static uint8_t checking_ifelse,parsing_state;
34char *last_used_text;
35static short num_squigilly_brackets;
36static int32_t last_used_size;
37
38static short g_i,g_p;
39static int32_t g_x;
40static int32_t *g_t;
41static spritetype *g_sp;
42
43#define NUMKEYWORDS 112
44
45//From global.c
46void FixFilePath(char *filename);
47
48//From actors.c
49void lotsofmail(spritetype *s, short n);
50void lotsofpaper(spritetype *s, short n);
51
52char *keyw[NUMKEYWORDS] =
53{
54 "definelevelname", // 0
55 "actor", // 1 [#]
56 "addammo", // 2 [#]
57 "ifrnd", // 3 [C]
58 "enda", // 4 [:]
59 "ifcansee", // 5 [C]
60 "ifhitweapon", // 6 [#]
61 "action", // 7 [#]
62 "ifpdistl", // 8 [#]
63 "ifpdistg", // 9 [#]
64 "else", // 10 [#]
65 "strength", // 11 [#]
66 "break", // 12 [#]
67 "shoot", // 13 [#]
68 "palfrom", // 14 [#]
69 "sound", // 15 [filename.voc]
70 "fall", // 16 []
71 "state", // 17
72 "ends", // 18
73 "define", // 19
74 "//", // 20
75 "ifai", // 21
76 "killit", // 22
77 "addweapon", // 23
78 "ai", // 24
79 "addphealth", // 25
80 "ifdead", // 26
81 "ifsquished", // 27
82 "sizeto", // 28
83 "{", // 29
84 "}", // 30
85 "spawn", // 31
86 "move", // 32
87 "ifwasweapon", // 33
88 "ifaction", // 34
89 "ifactioncount", // 35
90 "resetactioncount", // 36
91 "debris", // 37
92 "pstomp", // 38
93 "/*", // 39
94 "cstat", // 40
95 "ifmove", // 41
96 "resetplayer", // 42
97 "ifonwater", // 43
98 "ifinwater", // 44
99 "ifcanshoottarget", // 45
100 "ifcount", // 46
101 "resetcount", // 47
102 "addinventory", // 48
103 "ifactornotstayput",// 49
104 "hitradius", // 50
105 "ifp", // 51
106 "count", // 52
107 "ifactor", // 53
108 "music", // 54
109 "include", // 55
110 "ifstrength", // 56
111 "definesound", // 57
112 "guts", // 58
113 "ifspawnedby", // 59
114 "gamestartup", // 60
115 "wackplayer", // 61
116 "ifgapzl", // 62
117 "ifhitspace", // 63
118 "ifoutside", // 64
119 "ifmultiplayer", // 65
120 "operate", // 66
121 "ifinspace", // 67
122 "debug", // 68
123 "endofgame", // 69
124 "ifbulletnear", // 70
125 "ifrespawn", // 71
126 "iffloordistl", // 72
127 "ifceilingdistl", // 73
128 "spritepal", // 74
129 "ifpinventory", // 75
130 "betaname", // 76
131 "cactor", // 77
132 "ifphealthl", // 78
133 "definequote", // 79
134 "quote", // 80
135 "ifinouterspace", // 81
136 "ifnotmoving", // 82
137 "respawnhitag", // 83
138 "tip", // 84
139 "ifspritepal", // 85
140 "money", // 86
141 "soundonce", // 87
142 "addkills", // 88
143 "stopsound", // 89
144 "ifawayfromwall", // 90
145 "ifcanseetarget", // 91
146 "globalsound", // 92
147 "lotsofglass", // 93
148 "ifgotweaponce", // 94
149 "getlastpal", // 95
150 "pkick", // 96
151 "mikesnd", // 97
152 "useractor", // 98
153 "sizeat", // 99
154 "addstrength", // 100 [#]
155 "cstator", // 101
156 "mail", // 102
157 "paper", // 103
158 "tossweapon", // 104
159 "sleeptime", // 105
160 "nullop", // 106
161 "definevolumename", // 107
162 "defineskillname", // 108
163 "ifnosounds", // 109
164 "clipdist", // 110
165 "ifangdiffl" // 111
166};
167
168
169short getincangle(short a,short na)
170{
171 a &= 2047;
172 na &= 2047;
173
174 if(klabs(a-na) < 1024)
175 return (na-a);
176 else
177 {
178 if(na > 1024) na -= 2048;
179 if(a > 1024) a -= 2048;
180
181 na -= 2048;
182 a -= 2048;
183 return (na-a);
184 }
185}
186
187uint8_t ispecial(uint8_t c)
188{
189 if(c == 0x0a)
190 {
191 line_number++;
192 return 1;
193 }
194
195 if(c == ' ' || c == 0x0d)
196 return 1;
197
198 return 0;
199}
200
201uint8_t isaltok(uint8_t c)
202{
203 return ( isalnum(c) || c == '{' || c == '}' || c == '/' || c == '*' || c == '-' || c == '_' || c == '.');
204}
205
206void getglobalz(short i)
207{
208 int32_t hz,lz,zr;
209
210 spritetype *s = &sprite[i];
211
212 if( s->statnum == 10 || s->statnum == 6 || s->statnum == 2 || s->statnum == 1 || s->statnum == 4)
213 {
214 if(s->statnum == 4)
215 zr = 4L;
216 else zr = 127L;
217
218 getzrange(s->x,s->y,s->z-(FOURSLEIGHT),s->sectnum,&hittype[i].ceilingz,&hz,&hittype[i].floorz,&lz,zr,CLIPMASK0);
219
220 if( (lz&49152) == 49152 && (sprite[lz&(MAXSPRITES-1)].cstat&48) == 0 )
221 {
222 lz &= (MAXSPRITES-1);
223 if( badguy(&sprite[lz]) && sprite[lz].pal != 1)
224 {
225 if( s->statnum != 4 )
226 {
227 hittype[i].dispicnum = -4; // No shadows on actors
228 s->xvel = -256;
229 ssp(i,CLIPMASK0);
230 }
231 }
232 else if(sprite[lz].picnum == APLAYER && badguy(s) )
233 {
234 hittype[i].dispicnum = -4; // No shadows on actors
235 s->xvel = -256;
236 ssp(i,CLIPMASK0);
237 }
238 else if(s->statnum == 4 && sprite[lz].picnum == APLAYER)
239 if(s->owner == lz)
240 {
241 hittype[i].ceilingz = sector[s->sectnum].ceilingz;
242 hittype[i].floorz = sector[s->sectnum].floorz;
243 }
244 }
245 }
246 else
247 {
248 hittype[i].ceilingz = sector[s->sectnum].ceilingz;
249 hittype[i].floorz = sector[s->sectnum].floorz;
250 }
251}
252
253
254void makeitfall(short i)
255{
256 spritetype *s = &sprite[i];
257 int32_t hz,lz,c;
258
259 if( floorspace(s->sectnum) )
260 c = 0;
261 else
262 {
263 if( ceilingspace(s->sectnum) || sector[s->sectnum].lotag == 2)
264 c = gc/6;
265 else c = gc;
266 }
267
268 if( ( s->statnum == 1 || s->statnum == 10 || s->statnum == 2 || s->statnum == 6 ) )
269 getzrange(s->x,s->y,s->z-(FOURSLEIGHT),s->sectnum,&hittype[i].ceilingz,&hz,&hittype[i].floorz,&lz,127L,CLIPMASK0);
270 else
271 {
272 hittype[i].ceilingz = sector[s->sectnum].ceilingz;
273 hittype[i].floorz = sector[s->sectnum].floorz;
274 }
275
276 if( s->z < hittype[i].floorz-(FOURSLEIGHT) )
277 {
278 if( sector[s->sectnum].lotag == 2 && s->zvel > 3122 )
279 s->zvel = 3144;
280 if(s->zvel < 6144)
281 s->zvel += c;
282 else s->zvel = 6144;
283 s->z += s->zvel;
284 }
285 if( s->z >= hittype[i].floorz-(FOURSLEIGHT) )
286 {
287 s->z = hittype[i].floorz - FOURSLEIGHT;
288 s->zvel = 0;
289 }
290}
291
292
293void getlabel(void)
294{
295 int32_t i;
296
297 while( isalnum(*textptr) == 0 )
298 {
299 if(*textptr == 0x0a) line_number++;
300 textptr++;
301 if( *textptr == 0)
302 return;
303 }
304
305 i = 0;
306 while( ispecial(*textptr) == 0 )
307 label[(labelcnt<<6)+i++] = *(textptr++);
308
309 label[(labelcnt<<6)+i] = 0;
310}
311
312int32_t keyword(void)
313{
314 int32_t i;
315 char *temptextptr;
316
317 temptextptr = textptr;
318
319 while( isaltok(*temptextptr) == 0 )
320 {
321 temptextptr++;
322 if( *temptextptr == 0 )
323 return 0;
324 }
325
326 i = 0;
327 while( isaltok(*temptextptr) )
328 {
329 tempbuf[i] = *(temptextptr++);
330 i++;
331 }
332 tempbuf[i] = 0;
333
334 for(i=0;i<NUMKEYWORDS;i++)
335 if( strcmp( (const char *)tempbuf,keyw[i]) == 0 )
336 return i;
337
338 return -1;
339}
340
341int32_t transword(void) //Returns its code #
342{
343 int32_t i, l;
344
345 while( isaltok(*textptr) == 0 )
346 {
347 if(*textptr == 0x0a) line_number++;
348 if( *textptr == 0 )
349 return -1;
350 textptr++;
351 }
352
353 l = 0;
354 while( isaltok(*(textptr+l)) )
355 {
356 tempbuf[l] = textptr[l];
357 l++;
358 }
359 tempbuf[l] = 0;
360
361 for(i=0;i<NUMKEYWORDS;i++)
362 {
363 if( strcmp( (const char *)tempbuf,keyw[i]) == 0 )
364 {
365 *scriptptr = i;
366 textptr += l;
367 scriptptr++;
368 return i;
369 }
370 }
371
372 textptr += l;
373
374 if( tempbuf[0] == '{' && tempbuf[1] != 0)
375 printf(" * ERROR!(L%hd) Expecting a SPACE or CR between '{' and '%s'.\n",line_number,tempbuf+1);
376 else if( tempbuf[0] == '}' && tempbuf[1] != 0)
377 printf(" * ERROR!(L%hd) Expecting a SPACE or CR between '}' and '%s'.\n",line_number,tempbuf+1);
378 else if( tempbuf[0] == '/' && tempbuf[1] == '/' && tempbuf[2] != 0 )
379 printf(" * ERROR!(L%hd) Expecting a SPACE between '//' and '%s'.\n",line_number,tempbuf+2);
380 else if( tempbuf[0] == '/' && tempbuf[1] == '*' && tempbuf[2] != 0 )
381 printf(" * ERROR!(L%hd) Expecting a SPACE between '/*' and '%s'.\n",line_number,tempbuf+2);
382 else if( tempbuf[0] == '*' && tempbuf[1] == '/' && tempbuf[2] != 0 )
383 printf(" * ERROR!(L%hd) Expecting a SPACE between '*/' and '%s'.\n",line_number,tempbuf+2);
384 else printf(" * ERROR!(L%hd) Expecting key word, but found '%s'.\n",line_number,tempbuf);
385
386 error++;
387 return -1;
388}
389
390void transnum(void)
391{
392 int32_t i, l;
393
394 while( isaltok(*textptr) == 0 )
395 {
396 if(*textptr == 0x0a) line_number++;
397 textptr++;
398 if( *textptr == 0 )
399 return;
400 }
401
402
403 l = 0;
404 while( isaltok(*(textptr+l)) )
405 {
406 tempbuf[l] = textptr[l];
407 l++;
408 }
409 tempbuf[l] = 0;
410
411 for(i=0;i<NUMKEYWORDS;i++)
412 if( strcmp( label+(labelcnt<<6),keyw[i]) == 0 )
413 {
414 error++;
415 printf(" * ERROR!(L%hd) Symbol '%s' is a key word.\n",line_number,label+(labelcnt<<6));
416 textptr+=l;
417 }
418
419
420 for(i=0;i<labelcnt;i++)
421 {
422 if( strcmp((const char *)tempbuf,label+(i<<6)) == 0 )
423 {
424 *scriptptr = labelcode[i];
425 scriptptr++;
426 textptr += l;
427 return;
428 }
429 }
430
431 if( isdigit(*textptr) == 0 && *textptr != '-')
432 {
433 printf(" * ERROR!(L%hd) Parameter '%s' is undefined.\n",line_number,tempbuf);
434 error++;
435 textptr+=l;
436 return;
437 }
438
439 *scriptptr = atol(textptr);
440 scriptptr++;
441
442 textptr += l;
443}
444
445
446uint8_t parsecommand(int readfromGRP)
447{
448 int32_t i, j, k, *tempscrptr;
449 uint8_t done, temp_ifelse_check;
450 int32_t tw;
451 char *origtptr;
452 short temp_line_number;
453 int fp;
454
455 if( error > 12 || ( *textptr == '\0' ) || ( *(textptr+1) == '\0' ) ) return 1;
456
457 tw = transword();
458
459 switch(tw)
460 {
461 default:
462 case -1:
463 return 0; //End
464 case 39: //Rem endrem
465 scriptptr--;
466 j = line_number;
467 do
468 {
469 textptr++;
470 if(*textptr == 0x0a) line_number++;
471 if( *textptr == 0 )
472 {
473 printf(" * ERROR!(L%d) Found '/*' with no '*/'.\n",j);
474 error++;
475 return 0;
476 }
477 }
478 while( *textptr != '*' || *(textptr+1) != '/' );
479 textptr+=2;
480 return 0;
481 case 17:
482 if( parsing_actor == 0 && parsing_state == 0 )
483 {
484 getlabel();
485 scriptptr--;
486 labelcode[labelcnt] = (int32_t) scriptptr;
487 labelcnt++;
488
489 parsing_state = 1;
490
491 return 0;
492 }
493
494 getlabel();
495
496 for(i=0;i<NUMKEYWORDS;i++)
497 if( strcmp( label+(labelcnt<<6),keyw[i]) == 0 )
498 {
499 error++;
500 printf(" * ERROR!(L%hd) Symbol '%s' is a key word.\n",line_number,label+(labelcnt<<6));
501 return 0;
502 }
503
504 for(j=0;j<labelcnt;j++)
505 {
506 if( strcmp(label+(j<<6),label+(labelcnt<<6)) == 0 )
507 {
508 *scriptptr = labelcode[j];
509 break;
510 }
511 }
512
513 if(j==labelcnt)
514 {
515 printf(" * ERROR!(L%hd) State '%s' not found.\n",line_number,label+(labelcnt<<6));
516 error++;
517 }
518 scriptptr++;
519 return 0;
520
521 case 15:
522 case 92:
523 case 87:
524 case 89:
525 case 93:
526 transnum();
527 return 0;
528
529 case 18:
530 if( parsing_state == 0 )
531 {
532 printf(" * ERROR!(L%hd) Found 'ends' with no 'state'.\n",line_number);
533 error++;
534 }
535// else
536 {
537 if( num_squigilly_brackets > 0 )
538 {
539 printf(" * ERROR!(L%hd) Found more '{' than '}' before 'ends'.\n",line_number);
540 error++;
541 }
542 if( num_squigilly_brackets < 0 )
543 {
544 printf(" * ERROR!(L%hd) Found more '}' than '{' before 'ends'.\n",line_number);
545 error++;
546 }
547 parsing_state = 0;
548 }
549 return 0;
550 case 19:
551 getlabel();
552 // Check to see it's already defined
553
554 for(i=0;i<NUMKEYWORDS;i++)
555 if( strcmp( label+(labelcnt<<6),keyw[i]) == 0 )
556 {
557 error++;
558 printf(" * ERROR!(L%hd) Symbol '%s' is a key word.\n",line_number,label+(labelcnt<<6));
559 return 0;
560 }
561
562 for(i=0;i<labelcnt;i++)
563 {
564 if( strcmp(label+(labelcnt<<6),label+(i<<6)) == 0 )
565 {
566 warning++;
567 printf(" * WARNING.(L%hd) Duplicate definition '%s' ignored.\n",line_number,label+(labelcnt<<6));
568 break;
569 }
570 }
571
572 transnum();
573 if(i == labelcnt)
574 labelcode[labelcnt++] = *(scriptptr-1);
575 scriptptr -= 2;
576 return 0;
577 case 14:
578
579 for(j = 0;j < 4;j++)
580 {
581 if( keyword() == -1 )
582 transnum();
583 else break;
584 }
585
586 while(j < 4)
587 {
588 *scriptptr = 0;
589 scriptptr++;
590 j++;
591 }
592 return 0;
593
594 case 32:
595 if( parsing_actor || parsing_state )
596 {
597 transnum();
598
599 j = 0;
600 while(keyword() == -1)
601 {
602 transnum();
603 scriptptr--;
604 j |= *scriptptr;
605 }
606 *scriptptr = j;
607 scriptptr++;
608 }
609 else
610 {
611 scriptptr--;
612 getlabel();
613 // Check to see it's already defined
614
615 for(i=0;i<NUMKEYWORDS;i++)
616 if( strcmp( label+(labelcnt<<6),keyw[i]) == 0 )
617 {
618 error++;
619 printf(" * ERROR!(L%hd) Symbol '%s' is a key word.\n",line_number,label+(labelcnt<<6));
620 return 0;
621 }
622
623 for(i=0;i<labelcnt;i++)
624 if( strcmp(label+(labelcnt<<6),label+(i<<6)) == 0 )
625 {
626 warning++;
627 printf(" * WARNING.(L%hd) Duplicate move '%s' ignored.\n",line_number,label+(labelcnt<<6));
628 break;
629 }
630 if(i == labelcnt)
631 labelcode[labelcnt++] = (int32_t) scriptptr;
632 for(j=0;j<2;j++)
633 {
634 if(keyword() >= 0) break;
635 transnum();
636 }
637 for(k=j;k<2;k++)
638 {
639 *scriptptr = 0;
640 scriptptr++;
641 }
642 }
643 return 0;
644
645 case 54:
646 {
647 scriptptr--;
648 transnum(); // Volume Number (0/4)
649 scriptptr--;
650
651 k = *scriptptr-1;
652
653 if(k >= 0) // if it's background music
654 {
655 i = 0;
656 while(keyword() == -1)
657 {
658 while( isaltok(*textptr) == 0 )
659 {
660 if(*textptr == 0x0a) line_number++;
661 textptr++;
662 if( *textptr == 0 ) break;
663 }
664 j = 0;
665 while( isaltok(*(textptr+j)) )
666 {
667 music_fn[k][i][j] = textptr[j];
668 j++;
669 }
670 music_fn[k][i][j] = '\0';
671 textptr += j;
672 if(i > 9) break;
673 i++;
674 }
675 }
676 else
677 {
678 i = 0;
679 while(keyword() == -1)
680 {
681 while( isaltok(*textptr) == 0 )
682 {
683 if(*textptr == 0x0a) line_number++;
684 textptr++;
685 if( *textptr == 0 ) break;
686 }
687 j = 0;
688 while( isaltok(*(textptr+j)) )
689 {
690 env_music_fn[i][j] = textptr[j];
691 j++;
692 }
693 env_music_fn[i][j] = '\0';
694
695 textptr += j;
696 if(i > 9) break;
697 i++;
698 }
699 }
700 }
701 return 0;
702 case 55: // include other con files.
703 {
704 char includedconfile[512];
705 scriptptr--;
706 while( isaltok(*textptr) == 0 )
707 {
708 if(*textptr == 0x0a) line_number++;
709 textptr++;
710 if( *textptr == 0 ) break;
711 }
712 j = 0;
713 while( isaltok(*textptr) )
714 {
715 tempbuf[j] = *(textptr++);
716 j++;
717 }
718 tempbuf[j] = '\0';
719
720 // fix path for unix. (doesn't really matter...)
721 FixFilePath((char *)tempbuf);
722
723 sprintf(includedconfile, "%s/%s", getGameDir(), tempbuf);
724
725 fp = TCkopen4load(includedconfile,readfromGRP);
726 if(fp <= 0)
727 {
728 error++;
729 printf(" * ERROR!(ln%hd) Could not find '%s'.\n",line_number,label+(labelcnt<<6));
730
731 printf("ERROR: could not open (%s)\n", includedconfile);
732 gameexit("");
733 return 0;
734 }
735
736 j = kfilelength(fp);
737
738 printf("Including: '%s'.\n", includedconfile);
739
740 temp_line_number = line_number;
741 line_number = 1;
742 temp_ifelse_check = checking_ifelse;
743 checking_ifelse = 0;
744 origtptr = textptr;
745 textptr = last_used_text+last_used_size;
746
747 *(textptr+j) = 0;
748
749 kread(fp,(uint8_t *)textptr,j);
750 kclose(fp);
751 ud.conCRC[0] = crc32_update((uint8_t *)textptr, j, ud.conCRC[0]);
752
753 do
754 done = parsecommand(readfromGRP);
755 while( done == 0 );
756
757 textptr = origtptr;
758 total_lines += line_number;
759 line_number = temp_line_number;
760 checking_ifelse = temp_ifelse_check;
761
762 return 0;
763 }
764 case 24:
765 if( parsing_actor || parsing_state )
766 transnum();
767 else
768 {
769 scriptptr--;
770 getlabel();
771
772 for(i=0;i<NUMKEYWORDS;i++)
773 if( strcmp( label+(labelcnt<<6),keyw[i]) == 0 )
774 {
775 error++;
776 printf(" * ERROR!(L%hd) Symbol '%s' is a key word.\n",line_number,label+(labelcnt<<6));
777 return 0;
778 }
779
780 for(i=0;i<labelcnt;i++)
781 if( strcmp(label+(labelcnt<<6),label+(i<<6)) == 0 )
782 {
783 warning++;
784 printf(" * WARNING.(L%hd) Duplicate ai '%s' ignored.\n",line_number,label+(labelcnt<<6));
785 break;
786 }
787
788 if(i == labelcnt)
789 labelcode[labelcnt++] = (int32_t) scriptptr;
790
791 for(j=0;j<3;j++)
792 {
793 if(keyword() >= 0) break;
794 if(j == 2)
795 {
796 k = 0;
797 while(keyword() == -1)
798 {
799 transnum();
800 scriptptr--;
801 k |= *scriptptr;
802 }
803 *scriptptr = k;
804 scriptptr++;
805 return 0;
806 }
807 else transnum();
808 }
809 for(k=j;k<3;k++)
810 {
811 *scriptptr = 0;
812 scriptptr++;
813 }
814 }
815 return 0;
816
817 case 7:
818 if( parsing_actor || parsing_state )
819 transnum();
820 else
821 {
822 scriptptr--;
823 getlabel();
824 // Check to see it's already defined
825
826 for(i=0;i<NUMKEYWORDS;i++)
827 if( strcmp( label+(labelcnt<<6),keyw[i]) == 0 )
828 {
829 error++;
830 printf(" * ERROR!(L%hd) Symbol '%s' is a key word.\n",line_number,label+(labelcnt<<6));
831 return 0;
832 }
833
834 for(i=0;i<labelcnt;i++)
835 if( strcmp(label+(labelcnt<<6),label+(i<<6)) == 0 )
836 {
837 warning++;
838 printf(" * WARNING.(L%hd) Duplicate action '%s' ignored.\n",line_number,label+(labelcnt<<6));
839 break;
840 }
841
842 if(i == labelcnt)
843 labelcode[labelcnt++] = (int32_t) scriptptr;
844
845 for(j=0;j<5;j++)
846 {
847 if(keyword() >= 0) break;
848 transnum();
849 }
850 for(k=j;k<5;k++)
851 {
852 *scriptptr = 0;
853 scriptptr++;
854 }
855 }
856 return 0;
857
858 case 1:
859 if( parsing_state )
860 {
861 printf(" * ERROR!(L%hd) Found 'actor' within 'state'.\n",line_number);
862 error++;
863 }
864
865 if( parsing_actor )
866 {
867 printf(" * ERROR!(L%hd) Found 'actor' within 'actor'.\n",line_number);
868 error++;
869 }
870
871 num_squigilly_brackets = 0;
872 scriptptr--;
873 parsing_actor = scriptptr;
874
875 transnum();
876 scriptptr--;
877 actorscrptr[*scriptptr] = parsing_actor;
878
879 for(j=0;j<4;j++)
880 {
881 *(parsing_actor+j) = 0;
882 if(j == 3)
883 {
884 j = 0;
885 while(keyword() == -1)
886 {
887 transnum();
888 scriptptr--;
889 j |= *scriptptr;
890 }
891 *scriptptr = j;
892 scriptptr++;
893 break;
894 }
895 else
896 {
897 if(keyword() >= 0)
898 {
899 scriptptr += (4-j);
900 break;
901 }
902 transnum();
903
904 *(parsing_actor+j) = *(scriptptr-1);
905 }
906 }
907
908 checking_ifelse = 0;
909
910 return 0;
911
912 case 98:
913
914 if( parsing_state )
915 {
916 printf(" * ERROR!(L%hd) Found 'useritem' within 'state'.\n",line_number);
917 error++;
918 }
919
920 if( parsing_actor )
921 {
922 printf(" * ERROR!(L%hd) Found 'useritem' within 'actor'.\n",line_number);
923 error++;
924 }
925
926 num_squigilly_brackets = 0;
927 scriptptr--;
928 parsing_actor = scriptptr;
929
930 transnum();
931 scriptptr--;
932 j = *scriptptr;
933
934 transnum();
935 scriptptr--;
936 actorscrptr[*scriptptr] = parsing_actor;
937 actortype[*scriptptr] = j;
938
939 for(j=0;j<4;j++)
940 {
941 *(parsing_actor+j) = 0;
942 if(j == 3)
943 {
944 j = 0;
945 while(keyword() == -1)
946 {
947 transnum();
948 scriptptr--;
949 j |= *scriptptr;
950 }
951 *scriptptr = j;
952 scriptptr++;
953 break;
954 }
955 else
956 {
957 if(keyword() >= 0)
958 {
959 scriptptr += (4-j);
960 break;
961 }
962 transnum();
963
964 *(parsing_actor+j) = *(scriptptr-1);
965 }
966 }
967
968 checking_ifelse = 0;
969
970 return 0;
971
972
973
974 case 11:
975 case 13:
976 case 25:
977 case 31:
978 case 40:
979 case 52:
980 case 69:
981 case 74:
982 case 77:
983 case 80:
984 case 86:
985 case 88:
986 case 68:
987 case 100:
988 case 101:
989 case 102:
990 case 103:
991 case 105:
992 case 110:
993 transnum();
994 return 0;
995
996 case 2:
997 case 23:
998 case 28:
999 case 99:
1000 case 37:
1001 case 48:
1002 case 58:
1003 transnum();
1004 transnum();
1005 break;
1006 case 50:
1007 transnum();
1008 transnum();
1009 transnum();
1010 transnum();
1011 transnum();
1012 break;
1013 case 10:
1014 if( checking_ifelse )
1015 {
1016 checking_ifelse--;
1017 tempscrptr = scriptptr;
1018 scriptptr++; //Leave a spot for the fail location
1019 parsecommand(readfromGRP);
1020 *tempscrptr = (int32_t) scriptptr;
1021 }
1022 else
1023 {
1024 scriptptr--;
1025 error++;
1026 printf(" * ERROR!(L%hd) Found 'else' with no 'if'.\n",line_number);
1027 }
1028
1029 return 0;
1030
1031 case 75:
1032 transnum();
1033 case 3:
1034 case 8:
1035 case 9:
1036 case 21:
1037 case 33:
1038 case 34:
1039 case 35:
1040 case 41:
1041 case 46:
1042 case 53:
1043 case 56:
1044 case 59:
1045 case 62:
1046 case 72:
1047 case 73:
1048// case 74:
1049 case 78:
1050 case 85:
1051 case 94:
1052 case 111:
1053 transnum();
1054 case 43:
1055 case 44:
1056 case 49:
1057 case 5:
1058 case 6:
1059 case 27:
1060 case 26:
1061 case 45:
1062 case 51:
1063 case 63:
1064 case 64:
1065 case 65:
1066 case 67:
1067 case 70:
1068 case 71:
1069 case 81:
1070 case 82:
1071 case 90:
1072 case 91:
1073 case 109:
1074
1075 if(tw == 51)
1076 {
1077 j = 0;
1078 do
1079 {
1080 transnum();
1081 scriptptr--;
1082 j |= *scriptptr;
1083 }
1084 while(keyword() == -1);
1085 *scriptptr = j;
1086 scriptptr++;
1087 }
1088
1089 tempscrptr = scriptptr;
1090 scriptptr++; //Leave a spot for the fail location
1091
1092 do
1093 {
1094 j = keyword();
1095 if(j == 20 || j == 39)
1096 parsecommand(readfromGRP);
1097 } while(j == 20 || j == 39);
1098
1099 parsecommand(readfromGRP);
1100
1101 *tempscrptr = (int32_t) scriptptr;
1102
1103 checking_ifelse++;
1104 return 0;
1105 case 29:
1106 num_squigilly_brackets++;
1107 do
1108 done = parsecommand(readfromGRP);
1109 while( done == 0 );
1110 return 0;
1111 case 30:
1112 num_squigilly_brackets--;
1113 if( num_squigilly_brackets < 0 )
1114 {
1115 printf(" * ERROR!(L%hd) Found more '}' than '{'.\n",line_number);
1116 error++;
1117 }
1118 return 1;
1119 case 76:
1120 scriptptr--;
1121 j = 0;
1122 while( *textptr != 0x0a )
1123 {
1124 betaname[j] = *textptr;
1125 j++; textptr++;
1126 }
1127 betaname[j] = 0;
1128 return 0;
1129 case 20:
1130 scriptptr--; //Negate the rem
1131 while( *textptr != 0x0a )
1132 textptr++;
1133
1134 // line_number++;
1135 return 0;
1136
1137 case 107:
1138 scriptptr--;
1139 transnum();
1140 scriptptr--;
1141 j = *scriptptr;
1142 while( *textptr == ' ' ) textptr++;
1143
1144 i = 0;
1145
1146 while( *textptr != 0x0a )
1147 {
1148 volume_names[j][i] = toupper(*textptr);
1149 textptr++,i++;
1150 if(i >= 32)
1151 {
1152 printf(" * ERROR!(L%hd) Volume name exceeds character size limit of 32.\n",line_number);
1153 error++;
1154 while( *textptr != 0x0a ) textptr++;
1155 break;
1156 }
1157 }
1158#ifdef PLATFORM_UNIX
1159 volume_names[j][i] = '\0';
1160#else
1161 volume_names[j][i-1] = '\0';
1162#endif
1163 return 0;
1164 case 108:
1165 scriptptr--;
1166 transnum();
1167 scriptptr--;
1168 j = *scriptptr;
1169 while( *textptr == ' ' ) textptr++;
1170
1171 i = 0;
1172
1173 while( *textptr != 0x0a )
1174 {
1175 skill_names[j][i] = toupper(*textptr);
1176 textptr++,i++;
1177 if(i >= 32)
1178 {
1179 printf(" * ERROR!(L%hd) Skill name exceeds character size limit of 32.\n",line_number);
1180 error++;
1181 while( *textptr != 0x0a ) textptr++;
1182 break;
1183 }
1184 }
1185#if defined(PLATFORM_UNIX) || defined(PLATFORM_ROCKBOX)
1186 skill_names[j][i] = '\0';
1187#else
1188 skill_names[j][i-1] = '\0';
1189#endif
1190 return 0;
1191
1192 case 0:
1193 scriptptr--;
1194 transnum();
1195 scriptptr--;
1196 j = *scriptptr;
1197 transnum();
1198 scriptptr--;
1199 k = *scriptptr;
1200 while( *textptr == ' ' ) textptr++;
1201
1202 i = 0;
1203 while( *textptr != ' ' && *textptr != 0x0a )
1204 {
1205 level_file_names[j*11+k][i] = *textptr;
1206 textptr++,i++;
1207 if(i > 127)
1208 {
1209 printf(" * ERROR!(L%hd) Level file name exceeds character size limit of 128.\n",line_number);
1210 error++;
1211 while( *textptr != ' ') textptr++;
1212 break;
1213 }
1214 }
1215#if defined(PLATFORM_UNIX) || defined(PLATFORM_ROCKBOX)
1216 level_names[j*11+k][i] = '\0';
1217#else
1218 level_names[j*11+k][i-1] = '\0';
1219#endif
1220 while( *textptr == ' ' ) textptr++;
1221
1222 partime[j*11+k] =
1223 (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*26*60)+
1224 (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*26);
1225
1226 textptr += 5;
1227 while( *textptr == ' ' ) textptr++;
1228
1229 designertime[j*11+k] =
1230 (((*(textptr+0)-'0')*10+(*(textptr+1)-'0'))*26*60)+
1231 (((*(textptr+3)-'0')*10+(*(textptr+4)-'0'))*26);
1232
1233 textptr += 5;
1234 while( *textptr == ' ' ) textptr++;
1235
1236 i = 0;
1237
1238 while( *textptr != 0x0a )
1239 {
1240 level_names[j*11+k][i] = toupper(*textptr);
1241 textptr++,i++;
1242 if(i >= 32)
1243 {
1244 printf(" * ERROR!(L%hd) Level name exceeds character size limit of 32.\n",line_number);
1245 error++;
1246 while( *textptr != 0x0a ) textptr++;
1247 break;
1248 }
1249 }
1250#ifdef PLATFORM_UNIX
1251 level_names[j*11+k][i] = '\0';
1252#else
1253 level_names[j*11+k][i-1] = '\0';
1254#endif
1255 return 0;
1256
1257 case 79:
1258 scriptptr--;
1259 transnum();
1260 k = *(scriptptr-1);
1261 if(k >= NUMOFFIRSTTIMEACTIVE)
1262 {
1263 printf(" * ERROR!(L%hd) Quote amount exceeds limit of %d characters.\n",line_number,NUMOFFIRSTTIMEACTIVE);
1264 error++;
1265 }
1266 scriptptr--;
1267 i = 0;
1268 while( *textptr == ' ' )
1269 textptr++;
1270
1271 while( *textptr != 0x0a )
1272 {
1273 fta_quotes[k][i] = *textptr;
1274 textptr++,i++;
1275 if(i >= 64)
1276 {
1277 printf(" * ERROR!(L%hd) Quote exceeds character size limit of 64.\n",line_number);
1278 error++;
1279 while( *textptr != 0x0a ) textptr++;
1280 break;
1281 }
1282 }
1283 fta_quotes[k][i] = '\0';
1284 return 0;
1285 case 57:
1286 scriptptr--;
1287 transnum();
1288 k = *(scriptptr-1);
1289 if(k >= NUM_SOUNDS)
1290 {
1291 printf(" * ERROR!(L%hd) Exceeded sound limit of %d.\n",line_number,NUM_SOUNDS);
1292 error++;
1293 }
1294 scriptptr--;
1295 i = 0;
1296 while( *textptr == ' ')
1297 textptr++;
1298
1299 while( *textptr != ' ' )
1300 {
1301 sounds[k][i] = *textptr;
1302 textptr++,i++;
1303 if(i >= 13)
1304 {
1305 puts(sounds[k]);
1306 printf(" * ERROR!(L%hd) Sound filename exceeded limit of 13 characters.\n",line_number);
1307 error++;
1308 while( *textptr != ' ' ) textptr++;
1309 break;
1310 }
1311 }
1312 sounds[k][i] = '\0';
1313
1314 transnum();
1315 soundps[k] = *(scriptptr-1);
1316 scriptptr--;
1317 transnum();
1318 soundpe[k] = *(scriptptr-1);
1319 scriptptr--;
1320 transnum();
1321 soundpr[k] = *(scriptptr-1);
1322 scriptptr--;
1323 transnum();
1324 soundm[k] = *(scriptptr-1);
1325 scriptptr--;
1326 transnum();
1327 soundvo[k] = *(scriptptr-1);
1328 scriptptr--;
1329 return 0;
1330
1331 case 4:
1332 if( parsing_actor == 0 )
1333 {
1334 printf(" * ERROR!(L%hd) Found 'enda' without defining 'actor'.\n",line_number);
1335 error++;
1336 }
1337// else
1338 {
1339 if( num_squigilly_brackets > 0 )
1340 {
1341 printf(" * ERROR!(L%hd) Found more '{' than '}' before 'enda'.\n",line_number);
1342 error++;
1343 }
1344 parsing_actor = 0;
1345 }
1346
1347 return 0;
1348 case 12:
1349 case 16:
1350 case 84:
1351// case 21:
1352 case 22: //KILLIT
1353 case 36:
1354 case 38:
1355 case 42:
1356 case 47:
1357 case 61:
1358 case 66:
1359 case 83:
1360 case 95:
1361 case 96:
1362 case 97:
1363 case 104:
1364 case 106:
1365 return 0;
1366 case 60:
1367 {
1368 int32_t params[30];
1369
1370 scriptptr--;
1371 for(j = 0; j < 30; j++)
1372 {
1373 transnum();
1374 scriptptr--;
1375 params[j] = *scriptptr;
1376
1377 if (j != 25) continue; // we try to guess if we are using 1.3/1.3d or 1.4/1.5 con files
1378
1379 if (keyword() != -1) // Is the 26th variable set? If so then it's probably a 1.4/1.5 con file
1380 {
1381 break;
1382 }
1383 else
1384 {
1385 conVersion = 15;
1386 }
1387 }
1388
1389 /* From Jonathon's code --mk
1390 v1.3d v1.5
1391
1392 DEFAULTVISIBILITY DEFAULTVISIBILITY
1393 GENERICIMPACTDAMAGE GENERICIMPACTDAMAGE
1394 MAXPLAYERHEALTH MAXPLAYERHEALTH
1395 STARTARMORHEALTH STARTARMORHEALTH
1396 RESPAWNACTORTIME RESPAWNACTORTIME
1397 RESPAWNITEMTIME RESPAWNITEMTIME
1398 RUNNINGSPEED RUNNINGSPEED
1399 GRAVITATIONALCONSTANT
1400 RPGBLASTRADIUS RPGBLASTRADIUS
1401 PIPEBOMBRADIUS PIPEBOMBRADIUS
1402 SHRINKERBLASTRADIUS SHRINKERBLASTRADIUS
1403 TRIPBOMBBLASTRADIUS TRIPBOMBBLASTRADIUS
1404 MORTERBLASTRADIUS MORTERBLASTRADIUS
1405 BOUNCEMINEBLASTRADIUS BOUNCEMINEBLASTRADIUS
1406 SEENINEBLASTRADIUS SEENINEBLASTRADIUS
1407 MAXPISTOLAMMO MAXPISTOLAMMO
1408 MAXSHOTGUNAMMO MAXSHOTGUNAMMO
1409 MAXCHAINGUNAMMO MAXCHAINGUNAMMO
1410 MAXRPGAMMO MAXRPGAMMO
1411 MAXHANDBOMBAMMO MAXHANDBOMBAMMO
1412 MAXSHRINKERAMMO MAXSHRINKERAMMO
1413 MAXDEVISTATORAMMO MAXDEVISTATORAMMO
1414 MAXTRIPBOMBAMMO MAXTRIPBOMBAMMO
1415 MAXFREEZEAMMO MAXFREEZEAMMO
1416 MAXGROWAMMO
1417 CAMERASDESTRUCTABLE CAMERASDESTRUCTABLE
1418 NUMFREEZEBOUNCES NUMFREEZEBOUNCES
1419 FREEZERHURTOWNER FREEZERHURTOWNER
1420 QSIZE
1421 TRIPBOMBLASERMODE
1422 */
1423
1424 // Used Jonathon Fowler's parser. Cool to make the code
1425 // robust to 1.3 con files --mk
1426
1427 j = 0;
1428
1429 ud.const_visibility = params[j++];
1430 impact_damage = params[j++];
1431 max_player_health = params[j++];
1432 max_armour_amount = params[j++];
1433 respawnactortime = params[j++];
1434 respawnitemtime = params[j++];
1435 dukefriction = params[j++];
1436 if (conVersion == 15)
1437 gc = params[j++];
1438 else
1439 gc = 176; // default (guess) when using 1.3d CONs
1440 rpgblastradius = params[j++];
1441 pipebombblastradius = params[j++];
1442 shrinkerblastradius = params[j++];
1443 tripbombblastradius = params[j++];
1444 morterblastradius = params[j++];
1445 bouncemineblastradius = params[j++];
1446 seenineblastradius = params[j++];
1447 max_ammo_amount[PISTOL_WEAPON] = params[j++];
1448 max_ammo_amount[SHOTGUN_WEAPON] = params[j++];
1449 max_ammo_amount[CHAINGUN_WEAPON] = params[j++];
1450 max_ammo_amount[RPG_WEAPON] = params[j++];
1451 max_ammo_amount[HANDBOMB_WEAPON] = params[j++];
1452 max_ammo_amount[SHRINKER_WEAPON] = params[j++];
1453 max_ammo_amount[DEVISTATOR_WEAPON] = params[j++];
1454 max_ammo_amount[TRIPBOMB_WEAPON] = params[j++];
1455 max_ammo_amount[FREEZE_WEAPON] = params[j++];
1456 if (conVersion == 15)
1457 max_ammo_amount[GROW_WEAPON] = params[j++];
1458 else
1459 max_ammo_amount[GROW_WEAPON] = 50; // default (guess) when using 1.3d CONs
1460 camerashitable = params[j++];
1461 numfreezebounces = params[j++];
1462 freezerhurtowner = params[j++];
1463 if (conVersion == 15)
1464 {
1465 spriteqamount = params[j++];
1466
1467 if(spriteqamount > 1024)
1468 spriteqamount = 1024;
1469 else if(spriteqamount < 0)
1470 spriteqamount = 0;
1471 lasermode = params[j++];
1472 }
1473 else
1474 {
1475 // spriteqamount = 64 is the default
1476 lasermode = 0; // default (guess) when using 1.3d CONs
1477 }
1478 }
1479 return 0;
1480
1481 } // end of switch(tw)
1482
1483 return 0;
1484}
1485
1486
1487void passone(int readfromGRP)
1488{
1489
1490 while( parsecommand(readfromGRP) == 0 );
1491
1492 if( (error+warning) > 12)
1493 puts( " * ERROR! Too many warnings or errors.");
1494
1495}
1496
1497char *defaultcons[3] =
1498{
1499 "GAME.CON",
1500 "USER.CON",
1501 "DEFS.CON"
1502};
1503
1504void copydefaultcons(void)
1505{
1506 int32_t i, fs, fpi;
1507 FILE *fpo;
1508
1509 for(i=0;i<3;i++)
1510 {
1511 fpi = TCkopen4load(defaultcons[i],1);
1512 fpo = fopen( defaultcons[i],"wb");
1513
1514 if(fpi == 0)
1515 {
1516// CTW - MODIFICATION
1517// if(fpo == -1) fclose(fpo);
1518 if(fpo == NULL) fclose(fpo);
1519// CTW END - MODIFICATION
1520 continue;
1521 }
1522// CTW - MODIFICATION
1523// if(fpo == -1)
1524 if(fpo == NULL)
1525// CTW END - MODIFICATION
1526 {
1527 if(fpi == 0) kclose(fpi);
1528 continue;
1529 }
1530
1531 fs = kfilelength(fpi);
1532
1533 kread(fpi,&hittype[0],fs);
1534 fwrite(&hittype[0],fs,1,fpo);
1535
1536 kclose(fpi);
1537 fclose(fpo);
1538 }
1539}
1540
1541void loadefs(char *filenam, char *mptr, int readfromGRP)
1542{
1543 LOGF("loadefs %s", filenam);
1544 int32_t fs,fp;
1545 uint8_t kbdKey;
1546
1547 memset(script, 0, sizeof(script));
1548
1549 // FIX_00071: do not ask for internal default con if
1550 // external con or internal con is buggy
1551 fp = TCkopen4load(filenam,readfromGRP);
1552 if( fp < 0 )
1553 {
1554 Error(EXIT_SUCCESS, "ERROR: CON(%s) not found.\n", filenam);
1555 }
1556 else
1557 {
1558 printf("Compiling: '%s'.\n",filenam);
1559
1560 fs = kfilelength(fp);
1561
1562 LOGF("file size: %d bytes", fs);
1563
1564 last_used_text = textptr = (char *) mptr;
1565 last_used_size = fs;
1566
1567 kread(fp,(uint8_t *)textptr,fs);
1568 kclose(fp);
1569 ud.conCRC[0]=0;
1570 //ud.conCRC[0] = crc32_update((uint8_t *)textptr, fs, ud.conCRC[0]);
1571 }
1572
1573#ifdef PLATFORM_UNIX
1574 textptr[fs - 1] = 0;
1575#else
1576 textptr[fs - 2] = 0;
1577#endif
1578
1579 clearbuf(actorscrptr,MAXSPRITES,0L);
1580 clearbufbyte(actortype,MAXSPRITES,0L);
1581
1582 labelcnt = 0;
1583 scriptptr = script+1;
1584 warning = 0;
1585 error = 0;
1586 line_number = 1;
1587 total_lines = 0;
1588
1589 passone(readfromGRP); //Tokenize
1590 *script = (int32_t) scriptptr;
1591
1592 if(warning|error)
1593 printf("Found %hhd warning(s), '%c' error(s).\n",warning,error);
1594
1595 if(error)
1596 {
1597 Error(EXIT_SUCCESS, "ERROR in CON(%s)\n", filenam);
1598 }
1599 else
1600 {
1601 total_lines += line_number;
1602 printf("Code Size:%d bytes(%d labels).\n",(int32_t)((scriptptr-script)<<2)-4,labelcnt);
1603 ud.conSize[0] = (int32_t)(scriptptr-script)-1;
1604
1605 // FIX_00062: Better support and identification for GRP and CON files for 1.3/1.3d/1.4/1.5
1606 if( ud.conSize[0] == 16208 && labelcnt == 1794 && conVersion == 15)
1607 conVersion = 14;
1608 printf("Con version: Looks like v%d\n", conVersion);
1609
1610 // FIX_00022: Automatically recognize the shareware grp (v1.3) + full version (1.3d) +
1611 // atomic (1.4/1.5 grp) and the con files version (either 1.3 or 1.4) (JonoF's idea)
1612
1613 if(conVersion != 13 && (getGRPcrc32(0)==CRC_BASE_GRP_SHAREWARE_13 ||
1614 getGRPcrc32(0)==CRC_BASE_GRP_FULL_13) && !getGRPcrc32(1))
1615 {
1616 printf( "\nYou are trying to use a v1.3 Shareware/Full *.GRP with v1.4 or v1.5\n"
1617 "external *.CON files. You may run in troubles by doing so and/or get\n"
1618 "Out Of Synch errors. You can safely delete those files so xDuke will\n"
1619 "always use the GRP internal CON files.\n"
1620 "\nReload normal GRP internal *.CON files? (Y/N) : ");
1621 do
1622 kbdKey = getch() | ' ';
1623 while(kbdKey != 'y' && kbdKey != 'n');
1624 printf("%c\n", kbdKey);
1625
1626 if(kbdKey == 'y')
1627 {
1628 conVersion = 13;
1629 loadefs(filenam, mptr, 1); // force GRP con files
1630 }
1631 }
1632 else if(conVersion != 15 && getGRPcrc32(0)==CRC_BASE_GRP_ATOMIC_15 && !getGRPcrc32(1))
1633 {
1634 printf( "\nYou are trying to use a v1.5 ATOMIC *.GRP with v1.4 or v1.3\n"
1635 "external *.CON files. You may run in troubles by doing so and/or get\n"
1636 "Out Of Synch errors. You can safely delete those files so xDuke will\n"
1637 "always use the GRP internal CON files.\n"
1638 "\nReload normal GRP internal *.CON files? (Y/N) : ");
1639 do
1640 kbdKey = getch() | ' ';
1641 while(kbdKey != 'y' && kbdKey != 'n');
1642 printf("%c\n", kbdKey);
1643
1644 if(kbdKey == 'y')
1645 {
1646 loadefs(filenam, mptr, 1); // force GRP con files
1647 }
1648 }else if(conVersion != 14 && getGRPcrc32(0)==CRC_BASE_GRP_PLUTONIUM_14 && !getGRPcrc32(1))
1649 {
1650 printf( "\nYou are trying to use a v1.4 PLUTONIUM *.GRP with v1.3 or v1.5\n"
1651 "external *.CON files. You may run in troubles by doing so and/or get\n"
1652 "Out Of Synch errors. You can safely delete those files so xDuke will\n"
1653 "always use the GRP internal CON files.\n"
1654 "\nReload normal GRP internal *.CON files? (Y/N) : ");
1655 do
1656 kbdKey = getch() | ' ';
1657 while(kbdKey != 'y' && kbdKey != 'n');
1658 printf("%c\n", kbdKey);
1659
1660 if(kbdKey == 'y')
1661 {
1662 loadefs(filenam, mptr, 1); // force GRP con files
1663 }
1664 }
1665 }
1666}
1667
1668uint8_t dodge(spritetype *s)
1669{
1670 short i;
1671 int32_t bx,by,mx,my,bxvect,byvect,mxvect,myvect,d;
1672
1673 mx = s->x;
1674 my = s->y;
1675 mxvect = sintable[(s->ang+512)&2047]; myvect = sintable[s->ang&2047];
1676
1677 for(i=headspritestat[4];i>=0;i=nextspritestat[i]) //weapons list
1678 {
1679 if( OW == i || SECT != s->sectnum)
1680 continue;
1681
1682 bx = SX-mx;
1683 by = SY-my;
1684 bxvect = sintable[(SA+512)&2047]; byvect = sintable[SA&2047];
1685
1686 if (mxvect*bx + myvect*by >= 0)
1687 if (bxvect*bx + byvect*by < 0)
1688 {
1689 d = bxvect*by - byvect*bx;
1690 if (klabs(d) < 65536*64)
1691 {
1692 s->ang -= 512+(TRAND&1024);
1693 return 1;
1694 }
1695 }
1696 }
1697 return 0;
1698}
1699
1700short furthestangle(short i,short angs)
1701{
1702 short j, hitsect,hitwall,hitspr,furthest_angle, angincs;
1703 int32_t hx, hy, hz, d, greatestd;
1704 spritetype *s = &sprite[i];
1705
1706 greatestd = -(1<<30);
1707 angincs = 2048/angs;
1708
1709 if(s->picnum != APLAYER)
1710 if( (g_t[0]&63) > 2 ) return( s->ang + 1024 );
1711
1712 for(j=s->ang;j<(2048+s->ang);j+=angincs)
1713 {
1714 hitscan(s->x, s->y, s->z-(8<<8), s->sectnum,
1715 sintable[(j+512)&2047],
1716 sintable[j&2047],0,
1717 &hitsect,&hitwall,&hitspr,&hx,&hy,&hz,CLIPMASK1);
1718
1719 d = klabs(hx-s->x) + klabs(hy-s->y);
1720
1721 if(d > greatestd)
1722 {
1723 greatestd = d;
1724 furthest_angle = j;
1725 }
1726 }
1727 return (furthest_angle&2047);
1728}
1729
1730short furthestcanseepoint(short i,spritetype *ts,int32_t *dax,int32_t *day)
1731{
1732 short j, hitsect,hitwall,hitspr, angincs;
1733 int32_t hx, hy, hz, d, da;//, d, cd, ca,tempx,tempy,cx,cy;
1734 spritetype *s = &sprite[i];
1735
1736 if( (g_t[0]&63) ) return -1;
1737
1738 if(ud.multimode < 2 && ud.player_skill < 3)
1739 angincs = 2048/2;
1740 else angincs = 2048/(1+(TRAND&1));
1741
1742 for(j=ts->ang;j<(2048+ts->ang);j+=(angincs-(TRAND&511)))
1743 {
1744 hitscan(ts->x, ts->y, ts->z-(16<<8), ts->sectnum,
1745 sintable[(j+512)&2047],
1746 sintable[j&2047],16384-(TRAND&32767),
1747 &hitsect,&hitwall,&hitspr,&hx,&hy,&hz,CLIPMASK1);
1748
1749 d = klabs(hx-ts->x)+klabs(hy-ts->y);
1750 da = klabs(hx-s->x)+klabs(hy-s->y);
1751
1752 if( d < da )
1753 if(cansee(hx,hy,hz,hitsect,s->x,s->y,s->z-(16<<8),s->sectnum))
1754 {
1755 *dax = hx;
1756 *day = hy;
1757 return hitsect;
1758 }
1759 }
1760 return -1;
1761}
1762
1763
1764
1765
1766void alterang(short a)
1767{
1768 short aang, angdif, goalang,j;
1769 int32_t ticselapsed, *moveptr;
1770
1771 moveptr = (int32_t *)g_t[1];
1772
1773 ticselapsed = (g_t[0])&31;
1774
1775 aang = g_sp->ang;
1776
1777 g_sp->xvel += (*moveptr-g_sp->xvel)/5;
1778 if(g_sp->zvel < 648) g_sp->zvel += ((*(moveptr+1)<<4)-g_sp->zvel)/5;
1779
1780 if(a&seekplayer)
1781 {
1782 j = ps[g_p].holoduke_on;
1783
1784 if(j >= 0 && cansee(sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].sectnum,g_sp->x,g_sp->y,g_sp->z,g_sp->sectnum) )
1785 g_sp->owner = j;
1786 else g_sp->owner = ps[g_p].i;
1787
1788 if(sprite[g_sp->owner].picnum == APLAYER)
1789 goalang = getangle(hittype[g_i].lastvx-g_sp->x,hittype[g_i].lastvy-g_sp->y);
1790 else
1791 goalang = getangle(sprite[g_sp->owner].x-g_sp->x,sprite[g_sp->owner].y-g_sp->y);
1792
1793 if(g_sp->xvel && g_sp->picnum != DRONE)
1794 {
1795 angdif = getincangle(aang,goalang);
1796
1797 if(ticselapsed < 2)
1798 {
1799 if( klabs(angdif) < 256)
1800 {
1801 j = 128-(TRAND&256);
1802 g_sp->ang += j;
1803 if( hits(g_i) < 844 )
1804 g_sp->ang -= j;
1805 }
1806 }
1807 else if(ticselapsed > 18 && ticselapsed < 26) // choose
1808 {
1809 if(klabs(angdif>>2) < 128) g_sp->ang = goalang;
1810 else g_sp->ang += angdif>>2;
1811 }
1812 }
1813 else g_sp->ang = goalang;
1814 }
1815
1816 if(ticselapsed < 1)
1817 {
1818 j = 2;
1819 if(a&furthestdir)
1820 {
1821 goalang = furthestangle(g_i,j);
1822 g_sp->ang = goalang;
1823 g_sp->owner = ps[g_p].i;
1824 }
1825
1826 if(a&fleeenemy)
1827 {
1828 goalang = furthestangle(g_i,j);
1829 g_sp->ang = goalang; // += angdif; // = getincangle(aang,goalang)>>1;
1830 }
1831 }
1832}
1833
1834void move()
1835{
1836 int32_t l, *moveptr;
1837 short a, goalang, angdif;
1838 int32_t daxvel;
1839
1840 a = g_sp->hitag;
1841
1842 if(a == -1) a = 0;
1843
1844 g_t[0]++;
1845
1846 if(a&face_player)
1847 {
1848 if(ps[g_p].newowner >= 0)
1849 goalang = getangle(ps[g_p].oposx-g_sp->x,ps[g_p].oposy-g_sp->y);
1850 else goalang = getangle(ps[g_p].posx-g_sp->x,ps[g_p].posy-g_sp->y);
1851 angdif = getincangle(g_sp->ang,goalang)>>2;
1852 if(angdif > -8 && angdif < 0) angdif = 0;
1853 g_sp->ang += angdif;
1854 }
1855
1856 if(a&spin)
1857 g_sp->ang += sintable[ ((g_t[0]<<3)&2047) ]>>6;
1858
1859 if(a&face_player_slow)
1860 {
1861 if(ps[g_p].newowner >= 0)
1862 goalang = getangle(ps[g_p].oposx-g_sp->x,ps[g_p].oposy-g_sp->y);
1863 else goalang = getangle(ps[g_p].posx-g_sp->x,ps[g_p].posy-g_sp->y);
1864 angdif = ksgn(getincangle(g_sp->ang,goalang))<<5;
1865 if(angdif > -32 && angdif < 0)
1866 {
1867 angdif = 0;
1868 g_sp->ang = goalang;
1869 }
1870 g_sp->ang += angdif;
1871 }
1872
1873
1874 if((a&jumptoplayer) == jumptoplayer)
1875 {
1876 if(g_t[0] < 16)
1877 g_sp->zvel -= (sintable[(512+(g_t[0]<<4))&2047]>>5);
1878 }
1879
1880 if(a&face_player_smart)
1881 {
1882 int32_t newx,newy;
1883
1884 newx = ps[g_p].posx+(ps[g_p].posxv/768);
1885 newy = ps[g_p].posy+(ps[g_p].posyv/768);
1886 goalang = getangle(newx-g_sp->x,newy-g_sp->y);
1887 angdif = getincangle(g_sp->ang,goalang)>>2;
1888 if(angdif > -8 && angdif < 0) angdif = 0;
1889 g_sp->ang += angdif;
1890 }
1891
1892 if( g_t[1] == 0 || a == 0 )
1893 {
1894 if( ( badguy(g_sp) && g_sp->extra <= 0 ) || (hittype[g_i].bposx != g_sp->x) || (hittype[g_i].bposy != g_sp->y) )
1895 {
1896 hittype[g_i].bposx = g_sp->x;
1897 hittype[g_i].bposy = g_sp->y;
1898 setsprite(g_i,g_sp->x,g_sp->y,g_sp->z);
1899 }
1900 return;
1901 }
1902
1903 moveptr = (int32_t *)g_t[1];
1904
1905 if(a&geth) g_sp->xvel += (*moveptr-g_sp->xvel)>>1;
1906 if(a&getv) g_sp->zvel += ((*(moveptr+1)<<4)-g_sp->zvel)>>1;
1907
1908 if(a&dodgebullet)
1909 dodge(g_sp);
1910
1911 if(g_sp->picnum != APLAYER)
1912 alterang(a);
1913
1914 if(g_sp->xvel > -6 && g_sp->xvel < 6 ) g_sp->xvel = 0;
1915
1916 a = badguy(g_sp);
1917
1918 if(g_sp->xvel || g_sp->zvel)
1919 {
1920 if(a && g_sp->picnum != ROTATEGUN)
1921 {
1922 if( (g_sp->picnum == DRONE || g_sp->picnum == COMMANDER) && g_sp->extra > 0)
1923 {
1924 if(g_sp->picnum == COMMANDER)
1925 {
1926 hittype[g_i].floorz = l = getflorzofslope(g_sp->sectnum,g_sp->x,g_sp->y);
1927 if( g_sp->z > (l-(8<<8)) )
1928 {
1929 if( g_sp->z > (l-(8<<8)) ) g_sp->z = l-(8<<8);
1930 g_sp->zvel = 0;
1931 }
1932
1933 hittype[g_i].ceilingz = l = getceilzofslope(g_sp->sectnum,g_sp->x,g_sp->y);
1934 if( (g_sp->z-l) < (80<<8) )
1935 {
1936 g_sp->z = l+(80<<8);
1937 g_sp->zvel = 0;
1938 }
1939 }
1940 else
1941 {
1942 if( g_sp->zvel > 0 )
1943 {
1944 hittype[g_i].floorz = l = getflorzofslope(g_sp->sectnum,g_sp->x,g_sp->y);
1945 if( g_sp->z > (l-(30<<8)) )
1946 g_sp->z = l-(30<<8);
1947 }
1948 else
1949 {
1950 hittype[g_i].ceilingz = l = getceilzofslope(g_sp->sectnum,g_sp->x,g_sp->y);
1951 if( (g_sp->z-l) < (50<<8) )
1952 {
1953 g_sp->z = l+(50<<8);
1954 g_sp->zvel = 0;
1955 }
1956 }
1957 }
1958 }
1959 else if(g_sp->picnum != ORGANTIC)
1960 {
1961 if(g_sp->zvel > 0 && hittype[g_i].floorz < g_sp->z)
1962 g_sp->z = hittype[g_i].floorz;
1963 if( g_sp->zvel < 0)
1964 {
1965 l = getceilzofslope(g_sp->sectnum,g_sp->x,g_sp->y);
1966 if( (g_sp->z-l) < (66<<8) )
1967 {
1968 g_sp->z = l+(66<<8);
1969 g_sp->zvel >>= 1;
1970 }
1971 }
1972 }
1973 }
1974 else if(g_sp->picnum == APLAYER)
1975 if( (g_sp->z-hittype[g_i].ceilingz) < (32<<8) )
1976 g_sp->z = hittype[g_i].ceilingz+(32<<8);
1977
1978 daxvel = g_sp->xvel;
1979 angdif = g_sp->ang;
1980
1981 if( a && g_sp->picnum != ROTATEGUN )
1982 {
1983 if( g_x < 960 && g_sp->xrepeat > 16 )
1984 {
1985
1986 daxvel = -(1024-g_x);
1987 angdif = getangle(ps[g_p].posx-g_sp->x,ps[g_p].posy-g_sp->y);
1988
1989 if(g_x < 512)
1990 {
1991 ps[g_p].posxv = 0;
1992 ps[g_p].posyv = 0;
1993 }
1994 else
1995 {
1996 ps[g_p].posxv = mulscale(ps[g_p].posxv,dukefriction-0x2000,16);
1997 ps[g_p].posyv = mulscale(ps[g_p].posyv,dukefriction-0x2000,16);
1998 }
1999 }
2000 else if(g_sp->picnum != DRONE && g_sp->picnum != SHARK && g_sp->picnum != COMMANDER)
2001 {
2002 if( hittype[g_i].bposz != g_sp->z || ( ud.multimode < 2 && ud.player_skill < 2 ) )
2003 {
2004 if( (g_t[0]&1) || ps[g_p].actorsqu == g_i ) return;
2005 else daxvel <<= 1;
2006 }
2007 else
2008 {
2009 if( (g_t[0]&3) || ps[g_p].actorsqu == g_i ) return;
2010 else daxvel <<= 2;
2011 }
2012 }
2013 }
2014
2015 hittype[g_i].movflag = movesprite(g_i,
2016 (daxvel*(sintable[(angdif+512)&2047]))>>14,
2017 (daxvel*(sintable[angdif&2047]))>>14,g_sp->zvel,CLIPMASK0);
2018 }
2019
2020 if( a )
2021 {
2022 if (sector[g_sp->sectnum].ceilingstat&1)
2023 g_sp->shade += (sector[g_sp->sectnum].ceilingshade-g_sp->shade)>>1;
2024 else g_sp->shade += (sector[g_sp->sectnum].floorshade-g_sp->shade)>>1;
2025
2026 if( sector[g_sp->sectnum].floorpicnum == MIRROR )
2027 deletesprite(g_i);
2028 }
2029}
2030
2031uint8_t parse(void);
2032
2033void parseifelse(int32_t condition)
2034{
2035 if( condition )
2036 {
2037 insptr+=2;
2038 parse();
2039 }
2040 else
2041 {
2042 insptr = (int32_t *) *(insptr+1);
2043 if(*insptr == 10)
2044 {
2045 insptr+=2;
2046 parse();
2047 }
2048 }
2049}
2050
2051// int32_t *it = 0x00589a04;
2052
2053uint8_t parse(void)
2054{
2055 int32_t j, l, s;
2056
2057 if(killit_flag) return 1;
2058
2059// if(*it == 1668249134L) gameexit("\nERR");
2060
2061 switch(*insptr)
2062 {
2063 case 3:
2064 insptr++;
2065 parseifelse( rnd(*insptr));
2066 break;
2067 case 45:
2068
2069 if(g_x > 1024)
2070 {
2071 short temphit, sclip, angdif;
2072
2073 if( badguy(g_sp) && g_sp->xrepeat > 56 )
2074 {
2075 sclip = 3084;
2076 angdif = 48;
2077 }
2078 else
2079 {
2080 sclip = 768;
2081 angdif = 16;
2082 }
2083
2084 j = hitasprite(g_i,&temphit);
2085 if(j == (1<<30))
2086 {
2087 parseifelse(1);
2088 break;
2089 }
2090 if(j > sclip)
2091 {
2092 if(temphit >= 0 && sprite[temphit].picnum == g_sp->picnum)
2093 j = 0;
2094 else
2095 {
2096 g_sp->ang += angdif;j = hitasprite(g_i,&temphit);g_sp->ang -= angdif;
2097 if(j > sclip)
2098 {
2099 if(temphit >= 0 && sprite[temphit].picnum == g_sp->picnum)
2100 j = 0;
2101 else
2102 {
2103 g_sp->ang -= angdif;j = hitasprite(g_i,&temphit);g_sp->ang += angdif;
2104 if( j > 768 )
2105 {
2106 if(temphit >= 0 && sprite[temphit].picnum == g_sp->picnum)
2107 j = 0;
2108 else j = 1;
2109 }
2110 else j = 0;
2111 }
2112 }
2113 else j = 0;
2114 }
2115 }
2116 else j = 0;
2117 }
2118 else j = 1;
2119
2120 parseifelse(j);
2121 break;
2122 case 91:
2123 j = cansee(g_sp->x,g_sp->y,g_sp->z-((TRAND&41)<<8),g_sp->sectnum,ps[g_p].posx,ps[g_p].posy,ps[g_p].posz/*-((TRAND&41)<<8)*/,sprite[ps[g_p].i].sectnum);
2124 parseifelse(j);
2125 if( j ) hittype[g_i].timetosleep = SLEEPTIME;
2126 break;
2127
2128 case 49:
2129 parseifelse(hittype[g_i].actorstayput == -1);
2130 break;
2131 case 5:
2132 {
2133 spritetype *s;
2134
2135 if(ps[g_p].holoduke_on >= 0)
2136 {
2137 s = &sprite[ps[g_p].holoduke_on];
2138 j = cansee(g_sp->x,g_sp->y,g_sp->z-(TRAND&((32<<8)-1)),g_sp->sectnum,
2139 s->x,s->y,s->z,s->sectnum);
2140 if(j == 0)
2141 s = &sprite[ps[g_p].i];
2142 }
2143 else s = &sprite[ps[g_p].i];
2144
2145 j = cansee(g_sp->x,g_sp->y,g_sp->z-(TRAND&((47<<8))),g_sp->sectnum,
2146 s->x,s->y,s->z-(24<<8),s->sectnum);
2147
2148 if(j == 0)
2149 {
2150 if( ( klabs(hittype[g_i].lastvx-g_sp->x)+klabs(hittype[g_i].lastvy-g_sp->y) ) <
2151 ( klabs(hittype[g_i].lastvx-s->x)+klabs(hittype[g_i].lastvy-s->y) ) )
2152 j = 0;
2153
2154 if( j == 0 )
2155 {
2156 j = furthestcanseepoint(g_i,s,&hittype[g_i].lastvx,&hittype[g_i].lastvy);
2157
2158 if(j == -1) j = 0;
2159 else j = 1;
2160 }
2161 }
2162 else
2163 {
2164 hittype[g_i].lastvx = s->x;
2165 hittype[g_i].lastvy = s->y;
2166 }
2167
2168 if( j == 1 && ( g_sp->statnum == 1 || g_sp->statnum == 6 ) )
2169 hittype[g_i].timetosleep = SLEEPTIME;
2170
2171 parseifelse(j == 1);
2172 break;
2173 }
2174
2175 case 6:
2176 parseifelse(ifhitbyweapon(g_i) >= 0);
2177 break;
2178 case 27:
2179 parseifelse( ifsquished(g_i, g_p) == 1);
2180 break;
2181 case 26:
2182 {
2183 j = g_sp->extra;
2184 if(g_sp->picnum == APLAYER)
2185 j--;
2186 parseifelse(j < 0);
2187 }
2188 break;
2189 case 24:
2190 insptr++;
2191 g_t[5] = *insptr;
2192 g_t[4] = *(int32_t *)(g_t[5]); // Action
2193 g_t[1] = *(int32_t *)(g_t[5]+4); // move
2194 g_sp->hitag = *(int32_t *)(g_t[5]+8); // Ai
2195 g_t[0] = g_t[2] = g_t[3] = 0;
2196 if(g_sp->hitag&random_angle)
2197 g_sp->ang = TRAND&2047;
2198 insptr++;
2199 break;
2200 case 7:
2201 insptr++;
2202 g_t[2] = 0;
2203 g_t[3] = 0;
2204 // FIX_00093: fixed crashbugs in multiplayer (mine/blimp)
2205 // This is the blimp bug.
2206 // *.con code 1.3 and 1.4 are buggy when you try to blow up the
2207 // blimp in multiplayer. duke3d_w32 /q2 /m /v3 /l9
2208 // This is because the con code gives a timeout value of 2048
2209 // as a action address instead of giving a real action address.
2210 // We simply counter this specific con code bug by resetting
2211 // the action address to 0 when we get an address "2048":
2212 g_t[4] = ((*insptr)==2048)?0:(*insptr);
2213 insptr++;
2214 break;
2215
2216 case 8:
2217 insptr++;
2218 parseifelse(g_x < *insptr);
2219 if(g_x > MAXSLEEPDIST && hittype[g_i].timetosleep == 0)
2220 hittype[g_i].timetosleep = SLEEPTIME;
2221 break;
2222 case 9:
2223 insptr++;
2224 parseifelse(g_x > *insptr);
2225 if(g_x > MAXSLEEPDIST && hittype[g_i].timetosleep == 0)
2226 hittype[g_i].timetosleep = SLEEPTIME;
2227 break;
2228 case 10:
2229 insptr = (int32_t *) *(insptr+1);
2230 break;
2231 case 100:
2232 insptr++;
2233 g_sp->extra += *insptr;
2234 insptr++;
2235 break;
2236 case 11:
2237 insptr++;
2238 g_sp->extra = *insptr;
2239 insptr++;
2240 break;
2241 case 94:
2242 insptr++;
2243
2244 if(ud.coop >= 1 && ud.multimode > 1)
2245 {
2246 if(*insptr == 0)
2247 {
2248 for(j=0;j < ps[g_p].weapreccnt;j++)
2249 if( ps[g_p].weaprecs[j] == g_sp->picnum )
2250 break;
2251
2252 parseifelse(j < ps[g_p].weapreccnt && g_sp->owner == g_i);
2253 }
2254 else if(ps[g_p].weapreccnt < 16)
2255 {
2256 ps[g_p].weaprecs[ps[g_p].weapreccnt++] = g_sp->picnum;
2257 parseifelse(g_sp->owner == g_i);
2258 }
2259 }
2260 else parseifelse(0);
2261 break;
2262 case 95:
2263 insptr++;
2264 if(g_sp->picnum == APLAYER)
2265 g_sp->pal = ps[g_sp->yvel].palookup;
2266 else g_sp->pal = hittype[g_i].tempang;
2267 hittype[g_i].tempang = 0;
2268 break;
2269 case 104:
2270 insptr++;
2271 checkweapons(&ps[g_sp->yvel]);
2272 break;
2273 case 106:
2274 insptr++;
2275 break;
2276 case 97:
2277 insptr++;
2278 if(Sound[g_sp->yvel].num == 0)
2279 spritesound(g_sp->yvel,g_i);
2280 break;
2281 case 96:
2282 insptr++;
2283
2284 if( ud.multimode > 1 && g_sp->picnum == APLAYER )
2285 {
2286 if(ps[otherp].quick_kick == 0)
2287 ps[otherp].quick_kick = 14;
2288 }
2289 else if(g_sp->picnum != APLAYER && ps[g_p].quick_kick == 0)
2290 ps[g_p].quick_kick = 14;
2291 break;
2292 case 28:
2293 insptr++;
2294
2295 j = ((*insptr)-g_sp->xrepeat)<<1;
2296 g_sp->xrepeat += ksgn(j);
2297
2298 insptr++;
2299
2300 if( ( g_sp->picnum == APLAYER && g_sp->yrepeat < 36 ) ||
2301 *insptr < g_sp->yrepeat ||
2302 ((g_sp->yrepeat*(tiles[g_sp->picnum].dim.height+8))<<2) < (hittype[g_i].floorz - hittype[g_i].ceilingz) )
2303 {
2304 j = ((*insptr)-g_sp->yrepeat)<<1;
2305 if( klabs(j) ) g_sp->yrepeat += ksgn(j);
2306 }
2307
2308 insptr++;
2309
2310 break;
2311 case 99:
2312 insptr++;
2313 g_sp->xrepeat = (uint8_t ) *insptr;
2314 insptr++;
2315 g_sp->yrepeat = (uint8_t ) *insptr;
2316 insptr++;
2317 break;
2318 case 13:
2319 insptr++;
2320 shoot(g_i,(short)*insptr);
2321 insptr++;
2322 break;
2323 case 87:
2324 insptr++;
2325 if( Sound[*insptr].num == 0 )
2326 spritesound((short) *insptr,g_i);
2327 insptr++;
2328 break;
2329 case 89:
2330 insptr++;
2331 if( Sound[*insptr].num > 0 )
2332 stopsound((short)*insptr);
2333 insptr++;
2334 break;
2335 case 92:
2336 insptr++;
2337 if(g_p == screenpeek || ud.coop==1)
2338 spritesound((short) *insptr,ps[screenpeek].i);
2339 insptr++;
2340 break;
2341 case 15:
2342 insptr++;
2343 spritesound((short) *insptr,g_i);
2344 insptr++;
2345 break;
2346 case 84:
2347 insptr++;
2348 ps[g_p].tipincs = 26;
2349 break;
2350 case 16:
2351 insptr++;
2352 g_sp->xoffset = 0;
2353 g_sp->yoffset = 0;
2354// if(!gotz)
2355 {
2356 int32_t c;
2357
2358 if( floorspace(g_sp->sectnum) )
2359 c = 0;
2360 else
2361 {
2362 if( ceilingspace(g_sp->sectnum) || sector[g_sp->sectnum].lotag == 2)
2363 c = gc/6;
2364 else c = gc;
2365 }
2366
2367 if( hittype[g_i].cgg <= 0 || (sector[g_sp->sectnum].floorstat&2) )
2368 {
2369 getglobalz(g_i);
2370 hittype[g_i].cgg = 6;
2371 }
2372 else hittype[g_i].cgg --;
2373
2374 if( g_sp->z < (hittype[g_i].floorz-FOURSLEIGHT) )
2375 {
2376 g_sp->zvel += c;
2377 g_sp->z+=g_sp->zvel;
2378
2379 if(g_sp->zvel > 6144) g_sp->zvel = 6144;
2380 }
2381 else
2382 {
2383 g_sp->z = hittype[g_i].floorz - FOURSLEIGHT;
2384
2385 if( badguy(g_sp) || ( g_sp->picnum == APLAYER && g_sp->owner >= 0) )
2386 {
2387
2388 if( g_sp->zvel > 3084 && g_sp->extra <= 1)
2389 {
2390 if(g_sp->pal != 1 && g_sp->picnum != DRONE)
2391 {
2392 if(g_sp->picnum == APLAYER && g_sp->extra > 0)
2393 goto SKIPJIBS;
2394 guts(g_sp,JIBS6,15,g_p);
2395 spritesound(SQUISHED,g_i);
2396 spawn(g_i,BLOODPOOL);
2397 }
2398
2399 SKIPJIBS:
2400
2401 hittype[g_i].picnum = SHOTSPARK1;
2402 hittype[g_i].extra = 1;
2403 g_sp->zvel = 0;
2404 }
2405 else if(g_sp->zvel > 2048 && sector[g_sp->sectnum].lotag != 1)
2406 {
2407
2408 j = g_sp->sectnum;
2409 pushmove(&g_sp->x,&g_sp->y,&g_sp->z,(short*)&j,128L,(4L<<8),(4L<<8),CLIPMASK0);
2410 if(j != g_sp->sectnum && j >= 0 && j < MAXSECTORS)
2411 changespritesect(g_i,j);
2412
2413 spritesound(THUD,g_i);
2414 }
2415 }
2416 if(sector[g_sp->sectnum].lotag == 1)
2417 switch (g_sp->picnum)
2418 {
2419 case OCTABRAIN:
2420 case COMMANDER:
2421 case DRONE:
2422 break;
2423 default:
2424 g_sp->z += (24<<8);
2425 break;
2426 }
2427 else g_sp->zvel = 0;
2428 }
2429 }
2430
2431 break;
2432 case 4:
2433 case 12:
2434 case 18:
2435 return 1;
2436 case 30:
2437 insptr++;
2438 return 1;
2439 case 2:
2440 insptr++;
2441 if( ps[g_p].ammo_amount[*insptr] >= max_ammo_amount[*insptr] )
2442 {
2443 killit_flag = 2;
2444 break;
2445 }
2446 addammo( *insptr, &ps[g_p], *(insptr+1) );
2447 if(ps[g_p].curr_weapon == KNEE_WEAPON)
2448 if( ps[g_p].gotweapon[*insptr] )
2449 addweapon( &ps[g_p], *insptr );
2450 insptr += 2;
2451 break;
2452 case 86:
2453 insptr++;
2454 lotsofmoney(g_sp,*insptr);
2455 insptr++;
2456 break;
2457 case 102:
2458 insptr++;
2459 lotsofmail(g_sp,*insptr);
2460 insptr++;
2461 break;
2462 case 105:
2463 insptr++;
2464 hittype[g_i].timetosleep = (short)*insptr;
2465 insptr++;
2466 break;
2467 case 103:
2468 insptr++;
2469 lotsofpaper(g_sp,*insptr);
2470 insptr++;
2471 break;
2472 case 88:
2473 insptr++;
2474 ps[g_p].actors_killed += *insptr;
2475 hittype[g_i].actorstayput = -1;
2476 insptr++;
2477 break;
2478 case 93:
2479 insptr++;
2480 spriteglass(g_i,*insptr);
2481 insptr++;
2482 break;
2483 case 22:
2484 insptr++;
2485 killit_flag = 1;
2486 break;
2487 case 23:
2488 insptr++;
2489 if( ps[g_p].gotweapon[*insptr] == 0 ) addweapon( &ps[g_p], *insptr );
2490 else if( ps[g_p].ammo_amount[*insptr] >= max_ammo_amount[*insptr] )
2491 {
2492 killit_flag = 2;
2493 break;
2494 }
2495 addammo( *insptr, &ps[g_p], *(insptr+1) );
2496 if(ps[g_p].curr_weapon == KNEE_WEAPON)
2497 if( ps[g_p].gotweapon[*insptr] )
2498 addweapon( &ps[g_p], *insptr );
2499 insptr+=2;
2500 break;
2501 case 68:
2502 insptr++;
2503 printf("%d\n",*insptr);
2504 insptr++;
2505 break;
2506 case 69:
2507 insptr++;
2508 ps[g_p].timebeforeexit = *insptr;
2509 ps[g_p].customexitsound = -1;
2510 ud.eog = 1;
2511 insptr++;
2512 break;
2513 case 25:
2514 insptr++;
2515
2516 if(ps[g_p].newowner >= 0)
2517 {
2518 ps[g_p].newowner = -1;
2519 ps[g_p].posx = ps[g_p].oposx;
2520 ps[g_p].posy = ps[g_p].oposy;
2521 ps[g_p].posz = ps[g_p].oposz;
2522 ps[g_p].ang = ps[g_p].oang;
2523 updatesector(ps[g_p].posx,ps[g_p].posy,&ps[g_p].cursectnum);
2524 setpal(&ps[g_p]);
2525
2526 j = headspritestat[1];
2527 while(j >= 0)
2528 {
2529 if(sprite[j].picnum==CAMERA1)
2530 sprite[j].yvel = 0;
2531 j = nextspritestat[j];
2532 }
2533 }
2534
2535 j = sprite[ps[g_p].i].extra;
2536
2537 if(g_sp->picnum != ATOMICHEALTH)
2538 {
2539 if( j > max_player_health && *insptr > 0 )
2540 {
2541 insptr++;
2542 break;
2543 }
2544 else
2545 {
2546 if(j > 0)
2547 j += *insptr;
2548 if ( j > max_player_health && *insptr > 0 )
2549 j = max_player_health;
2550 }
2551 }
2552 else
2553 {
2554 if( j > 0 )
2555 j += *insptr;
2556 if ( j > (max_player_health<<1) )
2557 j = (max_player_health<<1);
2558 }
2559
2560 if(j < 0) j = 0;
2561
2562 if(ud.god == 0)
2563 {
2564 if(*insptr > 0)
2565 {
2566 if( ( j - *insptr ) < (max_player_health>>2) &&
2567 j >= (max_player_health>>2) )
2568 spritesound(DUKE_GOTHEALTHATLOW,ps[g_p].i);
2569
2570 ps[g_p].last_extra = j;
2571 }
2572
2573 sprite[ps[g_p].i].extra = j;
2574 }
2575
2576 insptr++;
2577 break;
2578 case 17:
2579 {
2580 int32_t *tempscrptr;
2581
2582 tempscrptr = insptr+2;
2583
2584 insptr = (int32_t *) *(insptr+1);
2585 while(1) if(parse()) break;
2586 insptr = tempscrptr;
2587 }
2588 break;
2589 case 29:
2590 insptr++;
2591 while(1) if(parse()) break;
2592 break;
2593 case 32:
2594 g_t[0]=0;
2595 insptr++;
2596 g_t[1] = *insptr;
2597 insptr++;
2598 g_sp->hitag = *insptr;
2599 insptr++;
2600 if(g_sp->hitag&random_angle)
2601 g_sp->ang = TRAND&2047;
2602 break;
2603 case 31:
2604 insptr++;
2605 if(g_sp->sectnum >= 0 && g_sp->sectnum < MAXSECTORS)
2606 spawn(g_i,*insptr);
2607 insptr++;
2608 break;
2609 case 33:
2610 insptr++;
2611 parseifelse( hittype[g_i].picnum == *insptr);
2612 break;
2613 case 21:
2614 insptr++;
2615 parseifelse(g_t[5] == *insptr);
2616 break;
2617 case 34:
2618 insptr++;
2619 parseifelse(g_t[4] == *insptr);
2620 break;
2621 case 35:
2622 insptr++;
2623 parseifelse(g_t[2] >= *insptr);
2624 break;
2625 case 36:
2626 insptr++;
2627 g_t[2] = 0;
2628 break;
2629 case 37:
2630 {
2631 short dnum;
2632
2633 insptr++;
2634 dnum = *insptr;
2635 insptr++;
2636
2637 if(g_sp->sectnum >= 0 && g_sp->sectnum < MAXSECTORS)
2638 for(j=(*insptr)-1;j>=0;j--)
2639 {
2640 if(g_sp->picnum == BLIMP && dnum == SCRAP1)
2641 s = 0;
2642 else s = (TRAND%3);
2643
2644 l = EGS(g_sp->sectnum,
2645 g_sp->x+(TRAND&255)-128,g_sp->y+(TRAND&255)-128,g_sp->z-(8<<8)-(TRAND&8191),
2646 dnum+s,g_sp->shade,32+(TRAND&15),32+(TRAND&15),
2647 TRAND&2047,(TRAND&127)+32,
2648 -(TRAND&2047),g_i,5);
2649 if(g_sp->picnum == BLIMP && dnum == SCRAP1)
2650 sprite[l].yvel = weaponsandammosprites[j%14];
2651 else sprite[l].yvel = -1;
2652 sprite[l].pal = g_sp->pal;
2653 }
2654 insptr++;
2655 }
2656 break;
2657 case 52:
2658 insptr++;
2659 g_t[0] = (short) *insptr;
2660 insptr++;
2661 break;
2662 case 101:
2663 insptr++;
2664 g_sp->cstat |= (short)*insptr;
2665 insptr++;
2666 break;
2667 case 110:
2668 insptr++;
2669 g_sp->clipdist = (short) *insptr;
2670 insptr++;
2671 break;
2672 case 40:
2673 insptr++;
2674 g_sp->cstat = (short) *insptr;
2675 insptr++;
2676 break;
2677 case 41:
2678 insptr++;
2679 parseifelse(g_t[1] == *insptr);
2680 break;
2681 case 42:
2682 insptr++;
2683
2684 if(ud.multimode < 2)
2685 {
2686 if( lastsavedpos >= 0 && ud.recstat != 2 )
2687 {
2688 ps[g_p].gm = MODE_MENU;
2689 KB_ClearKeyDown(sc_Space);
2690 cmenu(15000);
2691 }
2692 else ps[g_p].gm = MODE_RESTART;
2693 killit_flag = 2;
2694 }
2695 else
2696 {
2697 pickrandomspot(g_p);
2698 g_sp->x = hittype[g_i].bposx = ps[g_p].bobposx = ps[g_p].oposx = ps[g_p].posx;
2699 g_sp->y = hittype[g_i].bposy = ps[g_p].bobposy = ps[g_p].oposy =ps[g_p].posy;
2700 g_sp->z = hittype[g_i].bposy = ps[g_p].oposz =ps[g_p].posz;
2701 updatesector(ps[g_p].posx,ps[g_p].posy,&ps[g_p].cursectnum);
2702 setsprite(ps[g_p].i,ps[g_p].posx,ps[g_p].posy,ps[g_p].posz+PHEIGHT);
2703 g_sp->cstat = 257;
2704
2705 g_sp->shade = -12;
2706 g_sp->clipdist = 64;
2707 g_sp->xrepeat = 42;
2708 g_sp->yrepeat = 36;
2709 g_sp->owner = g_i;
2710 g_sp->xoffset = 0;
2711 g_sp->pal = ps[g_p].palookup;
2712
2713 ps[g_p].last_extra = g_sp->extra = max_player_health;
2714 ps[g_p].wantweaponfire = -1;
2715 ps[g_p].horiz = 100;
2716 ps[g_p].on_crane = -1;
2717 ps[g_p].frag_ps = g_p;
2718 ps[g_p].horizoff = 0;
2719 ps[g_p].opyoff = 0;
2720 ps[g_p].wackedbyactor = -1;
2721 ps[g_p].shield_amount = max_armour_amount;
2722 ps[g_p].dead_flag = 0;
2723 ps[g_p].pals_time = 0;
2724 ps[g_p].footprintcount = 0;
2725 ps[g_p].weapreccnt = 0;
2726 ps[g_p].fta = 0;
2727 ps[g_p].ftq = 0;
2728 ps[g_p].posxv = ps[g_p].posyv = 0;
2729 ps[g_p].rotscrnang = 0;
2730
2731 ps[g_p].falling_counter = 0;
2732
2733 hittype[g_i].extra = -1;
2734 hittype[g_i].owner = g_i;
2735
2736 hittype[g_i].cgg = 0;
2737 hittype[g_i].movflag = 0;
2738 hittype[g_i].tempang = 0;
2739 hittype[g_i].actorstayput = -1;
2740 hittype[g_i].dispicnum = 0;
2741 hittype[g_i].owner = ps[g_p].i;
2742
2743 resetinventory(g_p);
2744 resetweapons(g_p);
2745
2746 cameradist = 0;
2747 cameraclock = totalclock;
2748 }
2749 setpal(&ps[g_p]);
2750
2751 break;
2752 case 43:
2753 parseifelse( klabs(g_sp->z-sector[g_sp->sectnum].floorz) < (32<<8) && sector[g_sp->sectnum].lotag == 1);
2754 break;
2755 case 44:
2756 parseifelse( sector[g_sp->sectnum].lotag == 2);
2757 break;
2758 case 46:
2759 insptr++;
2760 parseifelse(g_t[0] >= *insptr);
2761 break;
2762 case 53:
2763 insptr++;
2764 parseifelse(g_sp->picnum == *insptr);
2765 break;
2766 case 47:
2767 insptr++;
2768 g_t[0] = 0;
2769 break;
2770 case 48:
2771 insptr+=2;
2772 switch(*(insptr-1))
2773 {
2774 case 0:
2775 ps[g_p].steroids_amount = *insptr;
2776 ps[g_p].inven_icon = 2;
2777 break;
2778 case 1:
2779 ps[g_p].shield_amount += *insptr;// 100;
2780 if(ps[g_p].shield_amount > max_player_health)
2781 ps[g_p].shield_amount = max_player_health;
2782 break;
2783 case 2:
2784 ps[g_p].scuba_amount = *insptr;// 1600;
2785 ps[g_p].inven_icon = 6;
2786 break;
2787 case 3:
2788 ps[g_p].holoduke_amount = *insptr;// 1600;
2789 ps[g_p].inven_icon = 3;
2790 break;
2791 case 4:
2792 ps[g_p].jetpack_amount = *insptr;// 1600;
2793 ps[g_p].inven_icon = 4;
2794 break;
2795 case 6:
2796 switch(g_sp->pal)
2797 {
2798 case 0: ps[g_p].got_access |= 1;break;
2799 case 21: ps[g_p].got_access |= 2;break;
2800 case 23: ps[g_p].got_access |= 4;break;
2801 }
2802 break;
2803 case 7:
2804 ps[g_p].heat_amount = *insptr;
2805 ps[g_p].inven_icon = 5;
2806 break;
2807 case 9:
2808 ps[g_p].inven_icon = 1;
2809 ps[g_p].firstaid_amount = *insptr;
2810 break;
2811 case 10:
2812 ps[g_p].inven_icon = 7;
2813 ps[g_p].boot_amount = *insptr;
2814 break;
2815 }
2816 insptr++;
2817 break;
2818 case 50:
2819 hitradius(g_i,*(insptr+1),*(insptr+2),*(insptr+3),*(insptr+4),*(insptr+5));
2820 insptr+=6;
2821 break;
2822 case 51:
2823 {
2824 insptr++;
2825
2826 l = *insptr;
2827 j = 0;
2828
2829 s = g_sp->xvel;
2830
2831 if( (l&8) && ps[g_p].on_ground && (sync[g_p].bits&2) )
2832 j = 1;
2833 else if( (l&16) && ps[g_p].jumping_counter == 0 && !ps[g_p].on_ground &&
2834 ps[g_p].poszv > 2048 )
2835 j = 1;
2836 else if( (l&32) && ps[g_p].jumping_counter > 348 )
2837 j = 1;
2838 else if( (l&1) && s >= 0 && s < 8)
2839 j = 1;
2840 else if( (l&2) && s >= 8 && !(sync[g_p].bits&(1<<5)) )
2841 j = 1;
2842 else if( (l&4) && s >= 8 && sync[g_p].bits&(1<<5) )
2843 j = 1;
2844 else if( (l&64) && ps[g_p].posz < (g_sp->z-(48<<8)) )
2845 j = 1;
2846 else if( (l&128) && s <= -8 && !(sync[g_p].bits&(1<<5)) )
2847 j = 1;
2848 else if( (l&256) && s <= -8 && (sync[g_p].bits&(1<<5)) )
2849 j = 1;
2850 else if( (l&512) && ( ps[g_p].quick_kick > 0 || ( ps[g_p].curr_weapon == KNEE_WEAPON && ps[g_p].kickback_pic > 0 ) ) )
2851 j = 1;
2852 else if( (l&1024) && sprite[ps[g_p].i].xrepeat < 32 )
2853 j = 1;
2854 else if( (l&2048) && ps[g_p].jetpack_on )
2855 j = 1;
2856 else if( (l&4096) && ps[g_p].steroids_amount > 0 && ps[g_p].steroids_amount < 400 )
2857 j = 1;
2858 else if( (l&8192) && ps[g_p].on_ground)
2859 j = 1;
2860 else if( (l&16384) && sprite[ps[g_p].i].xrepeat > 32 && sprite[ps[g_p].i].extra > 0 && ps[g_p].timebeforeexit == 0 )
2861 j = 1;
2862 else if( (l&32768) && sprite[ps[g_p].i].extra <= 0)
2863 j = 1;
2864 else if( (l&65536L) )
2865 {
2866 if(g_sp->picnum == APLAYER && ud.multimode > 1)
2867 j = getincangle(ps[otherp].ang,getangle(ps[g_p].posx-ps[otherp].posx,ps[g_p].posy-ps[otherp].posy));
2868 else
2869 j = getincangle(ps[g_p].ang,getangle(g_sp->x-ps[g_p].posx,g_sp->y-ps[g_p].posy));
2870
2871 if( j > -128 && j < 128 )
2872 j = 1;
2873 else
2874 j = 0;
2875 }
2876
2877 parseifelse((int32_t) j);
2878
2879 }
2880 break;
2881 case 56:
2882 insptr++;
2883 parseifelse(g_sp->extra <= *insptr);
2884 break;
2885 case 58:
2886 insptr += 2;
2887 guts(g_sp,*(insptr-1),*insptr,g_p);
2888 insptr++;
2889 break;
2890 case 59:
2891 insptr++;
2892// if(g_sp->owner >= 0 && sprite[g_sp->owner].picnum == *insptr)
2893 // parseifelse(1);
2894// else
2895 parseifelse( hittype[g_i].picnum == *insptr);
2896 break;
2897 case 61:
2898 insptr++;
2899 forceplayerangle(&ps[g_p]);
2900 return 0;
2901 case 62:
2902 insptr++;
2903 parseifelse( (( hittype[g_i].floorz - hittype[g_i].ceilingz ) >> 8 ) < *insptr);
2904 break;
2905 case 63:
2906 parseifelse( sync[g_p].bits&(1<<29));
2907 break;
2908 case 64:
2909 parseifelse(sector[g_sp->sectnum].ceilingstat&1);
2910 break;
2911 case 65:
2912 parseifelse(ud.multimode > 1);
2913 break;
2914 case 66:
2915 insptr++;
2916 if( sector[g_sp->sectnum].lotag == 0 )
2917 {
2918 neartag(g_sp->x,g_sp->y,g_sp->z-(32<<8),g_sp->sectnum,g_sp->ang,&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,768L,1);
2919 if( neartagsector >= 0 && isanearoperator(sector[neartagsector].lotag) )
2920 if( (sector[neartagsector].lotag&0xff) == 23 || sector[neartagsector].floorz == sector[neartagsector].ceilingz )
2921 if( (sector[neartagsector].lotag&16384) == 0 )
2922 if( (sector[neartagsector].lotag&32768) == 0 )
2923 {
2924 j = headspritesect[neartagsector];
2925 while(j >= 0)
2926 {
2927 if(sprite[j].picnum == ACTIVATOR)
2928 break;
2929 j = nextspritesect[j];
2930 }
2931 if(j == -1)
2932 operatesectors(neartagsector,g_i);
2933 }
2934 }
2935 break;
2936 case 67:
2937 parseifelse(ceilingspace(g_sp->sectnum));
2938 break;
2939
2940 case 74:
2941 insptr++;
2942 if(g_sp->picnum != APLAYER)
2943 hittype[g_i].tempang = g_sp->pal;
2944 g_sp->pal = *insptr;
2945 insptr++;
2946 break;
2947
2948 case 77:
2949 insptr++;
2950 g_sp->picnum = *insptr;
2951 insptr++;
2952 break;
2953
2954 case 70:
2955 parseifelse( dodge(g_sp) == 1);
2956 break;
2957 case 71:
2958 if( badguy(g_sp) )
2959 parseifelse( ud.respawn_monsters );
2960 else if( inventory(g_sp) )
2961 parseifelse( ud.respawn_inventory );
2962 else
2963 parseifelse( ud.respawn_items );
2964 break;
2965 case 72:
2966 insptr++;
2967// getglobalz(g_i);
2968 parseifelse( (hittype[g_i].floorz - g_sp->z) <= ((*insptr)<<8));
2969 break;
2970 case 73:
2971 insptr++;
2972// getglobalz(g_i);
2973 parseifelse( ( g_sp->z - hittype[g_i].ceilingz ) <= ((*insptr)<<8));
2974 break;
2975 case 14:
2976
2977 insptr++;
2978 ps[g_p].pals_time = *insptr;
2979 insptr++;
2980 for(j=0;j<3;j++)
2981 {
2982 ps[g_p].pals[j] = *insptr;
2983 insptr++;
2984 }
2985 break;
2986
2987/* case 74:
2988 insptr++;
2989 getglobalz(g_i);
2990 parseifelse( (( hittype[g_i].floorz - hittype[g_i].ceilingz ) >> 8 ) >= *insptr);
2991 break;
2992*/
2993 case 78:
2994 insptr++;
2995 parseifelse( sprite[ps[g_p].i].extra < *insptr);
2996 break;
2997
2998 case 75:
2999 {
3000 insptr++;
3001 j = 0;
3002 switch(*(insptr++))
3003 {
3004 case 0:if( ps[g_p].steroids_amount != *insptr)
3005 j = 1;
3006 break;
3007 case 1:if(ps[g_p].shield_amount != max_player_health )
3008 j = 1;
3009 break;
3010 case 2:if(ps[g_p].scuba_amount != *insptr) j = 1;break;
3011 case 3:if(ps[g_p].holoduke_amount != *insptr) j = 1;break;
3012 case 4:if(ps[g_p].jetpack_amount != *insptr) j = 1;break;
3013 case 6:
3014 switch(g_sp->pal)
3015 {
3016 case 0: if(ps[g_p].got_access&1) j = 1;break;
3017 case 21: if(ps[g_p].got_access&2) j = 1;break;
3018 case 23: if(ps[g_p].got_access&4) j = 1;break;
3019 }
3020 break;
3021 case 7:if(ps[g_p].heat_amount != *insptr) j = 1;break;
3022 case 9:
3023 if(ps[g_p].firstaid_amount != *insptr) j = 1;break;
3024 case 10:
3025 if(ps[g_p].boot_amount != *insptr) j = 1;break;
3026 }
3027
3028 parseifelse(j);
3029 break;
3030 }
3031 case 38:
3032 insptr++;
3033 if( ps[g_p].knee_incs == 0 && sprite[ps[g_p].i].xrepeat >= 40 )
3034 if( cansee(g_sp->x,g_sp->y,g_sp->z-(4<<8),g_sp->sectnum,ps[g_p].posx,ps[g_p].posy,ps[g_p].posz+(16<<8),sprite[ps[g_p].i].sectnum) )
3035 {
3036 ps[g_p].knee_incs = 1;
3037 if(ps[g_p].weapon_pos == 0)
3038 ps[g_p].weapon_pos = -1;
3039 ps[g_p].actorsqu = g_i;
3040 }
3041 break;
3042 case 90:
3043 {
3044 short s1;
3045
3046 s1 = g_sp->sectnum;
3047
3048 j = 0;
3049
3050 updatesector(g_sp->x+108,g_sp->y+108,&s1);
3051 if( s1 == g_sp->sectnum )
3052 {
3053 updatesector(g_sp->x-108,g_sp->y-108,&s1);
3054 if( s1 == g_sp->sectnum )
3055 {
3056 updatesector(g_sp->x+108,g_sp->y-108,&s1);
3057 if( s1 == g_sp->sectnum )
3058 {
3059 updatesector(g_sp->x-108,g_sp->y+108,&s1);
3060 if( s1 == g_sp->sectnum )
3061 j = 1;
3062 }
3063 }
3064 }
3065 parseifelse( j );
3066 }
3067
3068 break;
3069 case 80:
3070 insptr++;
3071 FTA(*insptr,&ps[g_p],0);
3072 insptr++;
3073 break;
3074 case 81:
3075 parseifelse( floorspace(g_sp->sectnum));
3076 break;
3077 case 82:
3078 parseifelse( (hittype[g_i].movflag&49152) > 16384 );
3079 break;
3080 case 83:
3081 insptr++;
3082 switch(g_sp->picnum)
3083 {
3084 case FEM1:
3085 case FEM2:
3086 case FEM3:
3087 case FEM4:
3088 case FEM5:
3089 case FEM6:
3090 case FEM7:
3091 case FEM8:
3092 case FEM9:
3093 case FEM10:
3094 case PODFEM1:
3095 case NAKED1:
3096 case STATUE:
3097 if(g_sp->yvel) operaterespawns(g_sp->yvel);
3098 break;
3099 default:
3100 if(g_sp->hitag >= 0) operaterespawns(g_sp->hitag);
3101 break;
3102 }
3103 break;
3104 case 85:
3105 insptr++;
3106 parseifelse( g_sp->pal == *insptr);
3107 break;
3108
3109 case 111:
3110 insptr++;
3111 j = klabs(getincangle(ps[g_p].ang,g_sp->ang));
3112 parseifelse( j <= *insptr);
3113 break;
3114
3115 case 109:
3116
3117 for(j=1;j<NUM_SOUNDS;j++)
3118 if( SoundOwner[j][0].i == g_i )
3119 break;
3120
3121 parseifelse( j == NUM_SOUNDS );
3122 break;
3123 default:
3124 killit_flag = 1;
3125 break;
3126 }
3127 return 0;
3128}
3129
3130void execute(short i,short p,int32_t x)
3131{
3132 uint8_t done;
3133
3134 g_i = i;
3135 g_p = p;
3136 g_x = x;
3137 g_sp = &sprite[g_i];
3138 g_t = &hittype[g_i].temp_data[0];
3139
3140 if( actorscrptr[g_sp->picnum] == 0 ) return;
3141
3142 insptr = 4 + (actorscrptr[g_sp->picnum]);
3143
3144 killit_flag = 0;
3145
3146 if(g_sp->sectnum < 0 || g_sp->sectnum >= MAXSECTORS)
3147 {
3148 if(badguy(g_sp))
3149 ps[g_p].actors_killed++;
3150 deletesprite(g_i);
3151 return;
3152 }
3153
3154
3155 if(g_t[4])
3156 {
3157 g_sp->lotag += TICSPERFRAME;
3158 if(g_sp->lotag > *(int32_t *)(g_t[4]+16) )
3159 {
3160 g_t[2]++;
3161 g_sp->lotag = 0;
3162 g_t[3] += *(int32_t *)( g_t[4]+12 );
3163 }
3164 if( klabs(g_t[3]) >= klabs( *(int32_t *)(g_t[4]+4) * *(int32_t *)(g_t[4]+12) ) )
3165 g_t[3] = 0;
3166 }
3167
3168 do
3169 done = parse();
3170 while( done == 0 );
3171
3172 if(killit_flag == 1)
3173 {
3174 if(ps[g_p].actorsqu == g_i)
3175 ps[g_p].actorsqu = -1;
3176 deletesprite(g_i);
3177 }
3178 else
3179 {
3180 move();
3181
3182 if( g_sp->statnum == 1)
3183 {
3184 if( badguy(g_sp) )
3185 {
3186 if( g_sp->xrepeat > 60 ) return;
3187 if( ud.respawn_monsters == 1 && g_sp->extra <= 0 ) return;
3188 }
3189 else if( ud.respawn_items == 1 && (g_sp->cstat&32768) ) return;
3190
3191 if(hittype[g_i].timetosleep > 1)
3192 hittype[g_i].timetosleep--;
3193 else if(hittype[g_i].timetosleep == 1)
3194 changespritestat(g_i,2);
3195 }
3196
3197 else if(g_sp->statnum == 6)
3198 switch(g_sp->picnum)
3199 {
3200 case RUBBERCAN:
3201 case EXPLODINGBARREL:
3202 case WOODENHORSE:
3203 case HORSEONSIDE:
3204 case CANWITHSOMETHING:
3205 case FIREBARREL:
3206 case NUKEBARREL:
3207 case NUKEBARRELDENTED:
3208 case NUKEBARRELLEAKED:
3209 case TRIPBOMB:
3210 case EGG:
3211 if(hittype[g_i].timetosleep > 1)
3212 hittype[g_i].timetosleep--;
3213 else if(hittype[g_i].timetosleep == 1)
3214 changespritestat(g_i,2);
3215 break;
3216 }
3217 }
3218}
3219
3220
3221
3222
3223
3224// "Duke 2000"
3225// "Virchua Duke"
3226// "Son of Death
3227// "Cromium"
3228// "Potent"
3229// "Flotsom"
3230
3231// Volume One
3232// "Duke is brain dead",
3233// "BOOT TO THE HEAD"
3234// Damage too duke
3235// Weapons are computer cont. Only logical thinking
3236// is disappearing.
3237// " Flips! "
3238// Flash on screen, inst.
3239// "BUMS"
3240// "JAIL"/"MENTAL WARD (Cop code for looney? T. asks Cop.)"
3241// "GUTS OR GLORY"
3242
3243// ( Duke's Mission
3244
3245// Duke: "Looks like some kind of transporter...?"
3246// Byte: "...YES"
3247
3248// Duke: "Waa, here goes nuthin'. "
3249// (Duke puts r. arm in device)
3250
3251// Duke: AAAAHHHHHHHHHHHHHHHHHHHHHHHHH!!!
3252// (Duke's arm is seved.)
3253// Byte: NO.NO.NO.NO.NO.NO.NO...
3254// ( Byte directs duke to the nearest heat source)
3255// (Shut Up Mode)
3256// ( Duke Staggers, end of arm bleeding, usual oozing arm guts. )
3257// Byte: Left, Left, Left, Left, Right.
3258// ( Duke, loozing consc, trips on broken pipe, )
3259// ( hits temple on edge of step. )
3260// ( Rats everywhere, byte pushing them away with weapon,
3261// ( eventually covered, show usual groosums, Duke appears dead
3262// ( Duke wakes up, in hospital, vision less blurry
3263// ( Hospital doing brain scan, 1/3 cran. mass MISSING!
3264// Doc: Hummm? ( Grabbing upper lip to "appear" smart. )
3265
3266// Stand back boys
3267
3268// Schrapnel has busted my scull!
3269// Now I'm insane, Mental ward, got to escape.
3270// Search light everywhere.
3271
3272// (M)Mendor, The Tree Dweller.
3273// (M)BashMan, The Destructor.
3274// (M)Lash, The Scavenger.
3275// (F)Mag, The Slut.
3276// (F)
3277// NRA OR SOMETHIN'
3278
3279// Duke Nukem
3280// 5th Dimention
3281// Pentagon Man!
3282
3283
3284// I Hope your not stupid!
3285// The 70's meet the future.
3286// Dirty Harry style. 70's music with futuristic edge
3287// The Instant De-Welder(tm)
3288// I think I'm going to puke...
3289// Badge attitude.
3290// He's got a Badge(LA 3322), a Bulldog, a Bronco (beat up/bondoed).
3291// Gfx:
3292// Lite rail systems
3293// A church. Large cross
3294// Sniper Scope,
3295// Really use the phone
3296// The Boiler Room
3297// The IRS, nuking other government buildings?
3298// You wouldn't have a belt of booz, would ya?
3299// Slow turning signes
3300// More persise shooting/descructions
3301// Faces, use phoneoms and its lookup. Talking, getting in fights.
3302// Drug dealers, pimps, and all galore
3303// Weapons, Anything lying around.
3304// Trees to clime, burning trees.
3305// Sledge Hammer, Sledge hammer with Spike
3306// sancurary, get away from it all.
3307// Goodlife = ( War + Greed ) / Peace
3308// Monsterism (ACTION)
3309// Global Hunter (RPG)
3310// Slick a Wick (PUZZLE)
3311// Roach Condo (FUNNY)
3312// AntiProfit (RPG)
3313// Pen Patrol (TD SIM)
3314// 97.5 KPIG! - Wanker County
3315// "Fauna" - Native Indiginouns Animal Life
3316
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/gamedefs.h b/apps/plugins/sdl/progs/duke3d/Game/src/gamedefs.h
new file mode 100644
index 0000000000..f06789b49a
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/gamedefs.h
@@ -0,0 +1,131 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27//****************************************************************************
28//
29// gamedefs.h
30//
31// common defines between the game and the setup program
32//
33//****************************************************************************
34
35#ifndef _gamedefs_public_
36#define _gamedefs_public_
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41//****************************************************************************
42//
43// DEFINES
44//
45//****************************************************************************
46
47//
48// Setup program defines
49//
50#define SETUPFILENAME "duke3d.cfg"
51
52
53// Max number of players
54#define MAXPLAYERS 16
55
56// Number of Mouse buttons
57#define MAXMOUSEBUTTONS 7
58
59// Number of JOY buttons
60#define MAXJOYBUTTONS 32
61
62// Number of joystick "top hats"
63#define MAXJOYHATS 6
64
65// Number of EXTERNAL buttons
66
67//#define MAXEXTERNALBUTTONS 6
68
69//
70// modem string defines
71//
72
73#define MAXMODEMSTRING 50
74
75// MACRO defines
76
77#define MAXMACROS 10
78#define MAXMACROLENGTH 34
79
80// Phone list defines
81
82#define PHONENUMBERLENGTH 28
83#define PHONENAMELENGTH 16
84#define MAXPHONEENTRIES 10
85
86// length of program functions
87
88#define MAXFUNCTIONLENGTH 30
89
90// length of axis functions
91
92#define MAXAXISFUNCTIONLENGTH 30
93
94// Max Player Name length
95
96#define MAXPLAYERNAMELENGTH 11
97
98// Max RTS Name length
99
100#define MAXRTSNAMELENGTH 15
101
102// Number of Mouse Axes
103
104#define MAXMOUSEAXES 2
105
106// Number of JOY axes
107
108#define MAXJOYAXES 6
109 //4
110
111// Number of GAMEPAD axes
112
113#define MAXGAMEPADAXES 2
114
115// MIN/MAX scale value for controller scales
116
117#define MAXCONTROLSCALEVALUE (1<<19)
118
119// DEFAULT scale value for controller scales
120
121#define DEFAULTCONTROLSCALEVALUE (1<<16)
122
123// base value for controller scales
124
125#define BASECONTROLSCALEVALUE (1<<16)
126
127#ifdef __cplusplus
128};
129#endif
130#endif
131
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/global.c b/apps/plugins/sdl/progs/duke3d/Game/src/global.c
new file mode 100644
index 0000000000..861e1326e8
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/global.c
@@ -0,0 +1,931 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <stdarg.h>
31#include <errno.h>
32#include "global.h"
33#include "duke3d.h"
34
35uint16_t readLE16(void *addr)
36{
37 uint8_t *ptr = addr;
38 return (*(ptr+1) << 8) | *ptr;
39}
40
41uint32_t readLE32(void *addr)
42{
43 uint8_t *ptr = addr;
44 return (*(ptr+3) << 24) |(*(ptr+2) << 16) | (*(ptr+1) << 8) | *ptr;
45}
46
47char *mymembuf;
48uint8_t MusicPtr[72000];
49
50
51crc32_t crc32lookup[] = {
52 // good:
53 { CRC_BASE_GRP_SHAREWARE_13, "SHAREWARE 1.3D", 11035779 },
54 { CRC_BASE_GRP_FULL_13, "FULL 1.3D ", 26524524 },
55 { CRC_BASE_GRP_PLUTONIUM_14, "PLUTONIUM 1.4 ", 44348015 },
56 { CRC_BASE_GRP_ATOMIC_15, "ATOMIC 1.5 ", 44356548 },
57 // unknown:
58 { 0, "HACK/UNKNOWN ", 0}
59 };
60
61uint8_t conVersion = 13;
62uint8_t grpVersion = 0;
63
64// FIX_00015: Backward compliance with older demos (down to demos v27, 28, 116 and 117 only)
65
66// For BYTEVERSION diff, 27/116 vs 28/117 see extras\duke3d.h vs source\duke3d.h
67// from the official source code release.
68
69int BYTEVERSION_27 = 27; // 1.3 under 1.4 Plutonium. Not supported anymore
70int BYTEVERSION_116 = 116; // 1.4 Plutonium. Not supported anymore
71
72int BYTEVERSION_28 = 28; // 1.3 under 1.5 engine
73int BYTEVERSION_117 = 117; // 1.5 Atomic
74
75int BYTEVERSION_29 = 29; // 1.3 under xDuke v19.6.
76int BYTEVERSION_118 = 118; // 1.5 Atomic under xDuke v19.6.
77
78int BYTEVERSION_1_3 = 1; // for 1.3 demos (Not compatible)
79
80int BYTEVERSION = 119; // xDuke v19.7
81
82short global_random;
83short neartagsector, neartagwall, neartagsprite;
84
85int32_t gc,neartaghitdist,lockclock,max_player_health,max_armour_amount,max_ammo_amount[MAX_WEAPONS];
86
87// int32_t temp_data[MAXSPRITES][6];
88struct weaponhit hittype[MAXSPRITES];
89short spriteq[1024],spriteqloc,spriteqamount=64;
90
91// ported build engine has this, too. --ryan.
92#if PLATFORM_DOS
93short moustat = 0;
94#endif
95
96struct animwalltype animwall[MAXANIMWALLS];
97short numanimwalls;
98int32_t *animateptr[MAXANIMATES], animategoal[MAXANIMATES], animatevel[MAXANIMATES], animatecnt;
99// int32_t oanimateval[MAXANIMATES];
100short animatesect[MAXANIMATES];
101int32_t msx[2048],msy[2048];
102short cyclers[MAXCYCLERS][6],numcyclers;
103
104char fta_quotes[NUMOFFIRSTTIMEACTIVE][64];
105
106uint8_t tempbuf[2048];
107uint8_t packbuf[576];
108
109char buf[80];
110
111short camsprite;
112short mirrorwall[64], mirrorsector[64], mirrorcnt;
113
114int current_menu;
115
116uint8_t betaname[80];
117
118char level_names[44][33];
119char level_file_names[44][128];
120int32_t partime[44],designertime[44];
121char volume_names[4][33] = { "L.A. MELTDOWN", "LUNAR APOCALYPSE", "SHRAPNEL CITY", "" }; // Names are not in 1.3 con files. MUST be in code.
122char skill_names[5][33] = { "PIECE OF CAKE", "LET'S ROCK", "COME GET SOME", "DAMN I'M GOOD", "" };
123
124volatile int32_t checksume;
125int32_t soundsiz[NUM_SOUNDS];
126
127short soundps[NUM_SOUNDS],soundpe[NUM_SOUNDS],soundvo[NUM_SOUNDS];
128uint8_t soundm[NUM_SOUNDS],soundpr[NUM_SOUNDS];
129char sounds[NUM_SOUNDS][14];
130
131short title_zoom;
132
133fx_device device;
134
135SAMPLE Sound[ NUM_SOUNDS ];
136SOUNDOWNER SoundOwner[NUM_SOUNDS][4];
137
138uint8_t numplayersprites,earthquaketime;
139
140int32_t fricxv,fricyv;
141struct player_orig po[MAXPLAYERS];
142struct player_struct ps[MAXPLAYERS];
143struct user_defs ud;
144
145uint8_t pus, pub;
146uint8_t syncstat, syncval[MAXPLAYERS][MOVEFIFOSIZ];
147int32_t syncvalhead[MAXPLAYERS], syncvaltail, syncvaltottail;
148
149input sync[MAXPLAYERS], loc;
150input recsync[RECSYNCBUFSIZ];
151int32_t avgfvel, avgsvel, avgavel, avghorz, avgbits;
152
153
154input inputfifo[MOVEFIFOSIZ][MAXPLAYERS];
155input recsync[RECSYNCBUFSIZ];
156
157int32_t movefifosendplc;
158
159 //Multiplayer syncing variables
160short screenpeek;
161int32_t movefifoend[MAXPLAYERS];
162
163
164 //Game recording variables
165
166uint8_t playerreadyflag[MAXPLAYERS],ready2send;
167uint8_t playerquitflag[MAXPLAYERS];
168int32_t vel, svel, angvel, horiz, ototalclock, respawnactortime=768, respawnitemtime=768, groupfile;
169
170int32_t script[MAXSCRIPTSIZE],*scriptptr,*insptr,*labelcode,labelcnt;
171int32_t *actorscrptr[MAXTILES],*parsing_actor;
172char *label,*textptr,error,warning ;
173uint8_t killit_flag;
174uint8_t *music_pointer;
175uint8_t actortype[MAXTILES];
176
177
178uint8_t display_mirror,typebuflen;
179char typebuf[41];
180
181char music_fn[4][11][13];
182uint8_t music_select;
183char env_music_fn[4][13];
184uint8_t rtsplaying;
185
186
187short weaponsandammosprites[15] = {
188 RPGSPRITE,
189 CHAINGUNSPRITE,
190 DEVISTATORAMMO,
191 RPGAMMO,
192 RPGAMMO,
193 JETPACK,
194 SHIELD,
195 FIRSTAID,
196 STEROIDS,
197 RPGAMMO,
198 RPGAMMO,
199 RPGSPRITE,
200 RPGAMMO,
201 FREEZESPRITE,
202 FREEZEAMMO
203 };
204
205int32_t impact_damage;
206
207 //GLOBAL.C - replace the end "my's" with this
208int32_t myx, omyx, myxvel, myy, omyy, myyvel, myz, omyz, myzvel;
209short myhoriz, omyhoriz, myhorizoff, omyhorizoff;
210short myang, omyang, mycursectnum, myjumpingcounter,frags[MAXPLAYERS][MAXPLAYERS];
211
212uint8_t myjumpingtoggle, myonground, myhardlanding, myreturntocenter;
213int8_t multiwho, multipos, multiwhat, multiflag;
214
215int32_t fakemovefifoplc,movefifoplc;
216int32_t myxbak[MOVEFIFOSIZ], myybak[MOVEFIFOSIZ], myzbak[MOVEFIFOSIZ];
217int32_t myhorizbak[MOVEFIFOSIZ],dukefriction = 0xcc00, show_shareware;
218
219short myangbak[MOVEFIFOSIZ];
220char myname[2048] = "XDUKE";
221uint8_t camerashitable,freezerhurtowner=0,lasermode;
222// CTW - MODIFICATION
223// uint8_t networkmode = 255, movesperpacket = 1,gamequit = 0,playonten = 0,everyothertime;
224uint8_t networkmode = 255, movesperpacket = 1,gamequit = 0,everyothertime;
225// CTW END - MODIFICATION
226int32_t numfreezebounces=3,rpgblastradius,pipebombblastradius,tripbombblastradius,shrinkerblastradius,morterblastradius,bouncemineblastradius,seenineblastradius;
227STATUSBARTYPE sbar;
228
229int32_t myminlag[MAXPLAYERS], mymaxlag, otherminlag, bufferjitter = 1;
230short numclouds,clouds[128],cloudx[128],cloudy[128];
231int32_t cloudtotalclock = 0,totalmemory = 0;
232int32_t numinterpolations = 0, startofdynamicinterpolations = 0;
233int32_t oldipos[MAXINTERPOLATIONS];
234int32_t bakipos[MAXINTERPOLATIONS];
235int32_t *curipos[MAXINTERPOLATIONS];
236
237
238// portability stuff. --ryan.
239// A good portion of this was ripped from GPL'd Rise of the Triad. --ryan.
240
241#ifndef PATH_SEP_CHAR
242#define PATH_SEP_CHAR '/'
243#endif
244
245void FixFilePath(char *filename)
246{
247#if PLATFORM_UNIX || PLATFORM_ROCKBOX
248 uint8_t *ptr;
249 uint8_t *lastsep = filename;
250
251 if ((!filename) || (*filename == '\0'))
252 return;
253 if(filename[0] != '/')
254 LOGF("%s is not absolute", filename);
255
256 if (rb->file_exists(filename)) /* File exists; we're good to go. */
257 return;
258
259 for (ptr = filename; 1; ptr++)
260 {
261 if (*ptr == '\\')
262 *ptr = PATH_SEP_CHAR;
263
264 if ((*ptr == PATH_SEP_CHAR) || (*ptr == '\0'))
265 {
266 uint8_t pch = *ptr;
267 struct dirent *dent = NULL;
268 DIR *dir;
269
270 if ((pch == PATH_SEP_CHAR) && (*(ptr + 1) == '\0'))
271 return; /* eos is pathsep; we're done. */
272
273 if (lastsep == ptr)
274 continue; /* absolute path; skip to next one. */
275
276 *ptr = '\0';
277 if (lastsep == filename) {
278 dir = opendir((*lastsep == PATH_SEP_CHAR) ? "/" : "/");
279
280 if (*lastsep == PATH_SEP_CHAR) {
281 lastsep++;
282 }
283 }
284 else
285 {
286 *lastsep = '\0';
287 dir = opendir(filename);
288 *lastsep = PATH_SEP_CHAR;
289 lastsep++;
290 }
291
292 if (dir == NULL)
293 {
294 *ptr = PATH_SEP_CHAR;
295 return; /* maybe dir doesn't exist? give up. */
296 }
297
298 while ((dent = readdir(dir)) != NULL)
299 {
300 if (strcasecmp(dent->d_name, lastsep) == 0)
301 {
302 /* found match; replace it. */
303 strcpy(lastsep, dent->d_name);
304 break;
305 }
306 }
307
308 closedir(dir);
309 *ptr = pch;
310 lastsep = ptr;
311
312 if (dent == NULL)
313 return; /* no match. oh well. */
314
315 if (pch == '\0') /* eos? */
316 return;
317 }
318 }
319#endif
320}
321
322
323#if PLATFORM_DOS
324 /* no-op. */
325
326#elif PLATFORM_WIN32
327int _dos_findfirst(uint8_t *filename, int x, struct find_t *f)
328{
329 int32_t rc = _findfirst(filename, &f->data);
330 f->handle = rc;
331 if (rc != -1)
332 {
333 strncpy(f->name, f->data.name, sizeof (f->name) - 1);
334 f->name[sizeof (f->name) - 1] = '\0';
335 return(0);
336 }
337 return(1);
338}
339
340int _dos_findnext(struct find_t *f)
341{
342 int rc = 0;
343 if (f->handle == -1)
344 return(1); /* invalid handle. */
345
346 rc = _findnext(f->handle, &f->data);
347 if (rc == -1)
348 {
349 _findclose(f->handle);
350 f->handle = -1;
351 return(1);
352 }
353
354 strncpy(f->name, f->data.name, sizeof (f->name) - 1);
355 f->name[sizeof (f->name) - 1] = '\0';
356 return(0);
357}
358
359#elif defined(PLATFORM_UNIX) || defined(PLATFORM_MACOSX) || defined(PLATFORM_ROCKBOX)
360int _dos_findfirst(char *filename, int x, struct find_t *f)
361{
362 char *ptr;
363
364 if (strlen(filename) >= sizeof (f->pattern))
365 return(1);
366
367 strcpy(f->pattern, filename);
368 FixFilePath(f->pattern);
369 ptr = strrchr(f->pattern, PATH_SEP_CHAR);
370
371 if (ptr == NULL)
372 {
373 ptr = filename;
374 f->dir = opendir(CURDIR);
375 }
376 else
377 {
378 *ptr = '\0';
379 f->dir = opendir(f->pattern);
380 memmove(f->pattern, ptr + 1, strlen(ptr + 1) + 1);
381 }
382
383 return(_dos_findnext(f));
384}
385
386
387static int check_pattern_nocase(const char *x, const char *y)
388{
389 if ((x == NULL) || (y == NULL))
390 return(0); /* not a match. */
391
392 while ((*x) && (*y))
393 {
394 if (*x == '*')
395 {
396 x++;
397 while (*y != '\0')
398 {
399 if (toupper((int) *x) == toupper((int) *y))
400 break;
401 y++;
402 }
403 }
404
405 else if (*x == '?')
406 {
407 if (*y == '\0')
408 return(0); /* anything but EOS is okay. */
409 }
410
411 else
412 {
413 if (toupper((int) *x) != toupper((int) *y))
414 return(0); /* not a match. */
415 }
416
417 x++;
418 y++;
419 }
420
421 return(*x == *y); /* it's a match (both should be EOS). */
422}
423
424int _dos_findnext(struct find_t *f)
425{
426 struct dirent *dent;
427
428 if (f->dir == NULL)
429 return(1); /* no such dir or we're just done searching. */
430
431 while ((dent = readdir(f->dir)) != NULL)
432 {
433 if (check_pattern_nocase(f->pattern, dent->d_name))
434 {
435 if (strlen(dent->d_name) < sizeof (f->name))
436 {
437 strcpy(f->name, dent->d_name);
438 return(0); /* match. */
439 }
440 }
441 }
442
443 closedir(f->dir);
444 f->dir = NULL;
445 return(1); /* no match in whole directory. */
446}
447#else
448#error please define for your platform.
449#endif
450
451
452#if !PLATFORM_DOS
453void _dos_getdate(struct dosdate_t *date)
454{
455 time_t curtime = time(NULL);
456 struct tm *tm;
457
458 if (date == NULL) {
459 return;
460 }
461
462 memset(date, 0, sizeof(struct dosdate_t));
463
464 rb->mktime(&tm);
465 date->day = tm->tm_mday;
466 date->month = tm->tm_mon + 1;
467 date->year = tm->tm_year + 1900;
468 date->dayofweek = tm->tm_wday + 1;
469}
470#endif
471
472
473int FindDistance2D(int ix, int iy)
474{
475 int t;
476
477 ix= abs(ix); /* absolute values */
478 iy= abs(iy);
479
480 if (ix<iy)
481 {
482 int tmp = ix;
483 ix = iy;
484 iy = tmp;
485 }
486
487 t = iy + (iy>>1);
488
489 return (ix - (ix>>5) - (ix>>7) + (t>>2) + (t>>6));
490}
491
492int FindDistance3D(int ix, int iy, int iz)
493{
494 int t;
495
496 ix= abs(ix); /* absolute values */
497 iy= abs(iy);
498 iz= abs(iz);
499
500 if (ix<iy)
501 {
502 int tmp = ix;
503 ix = iy;
504 iy = tmp;
505 }
506
507 if (ix<iz)
508 {
509 int tmp = ix;
510 ix = iz;
511 iz = tmp;
512 }
513
514 t = iy + iz;
515
516 return (ix - (ix>>4) + (t>>2) + (t>>3));
517}
518#include "SDL.h"
519void Error (int errorType, char *error, ...)
520{
521 va_list argptr;
522
523 SDL_Quit();
524
525 //FCS: http://duke3d.m-klein.com is obscolete :/ !
526 /*
527 if(errorType==EXIT_FAILURE)
528 printf("ERROR: Please copy that screen and visit http://duke3d.m-klein.com for report:\n");
529 else
530 printf("http://duke3d.m-klein.com\n");
531 */
532
533
534 va_start (argptr, error);
535 vprintf(error, argptr);
536 va_end (argptr);
537
538 //printf("Press any key to continue...\n");
539
540 // FIX_00043: Nicer exit on error. Ask the user to hit a key on exits and error exits.
541 //getch();
542
543 exit (errorType);
544}
545
546void write2disk(int line, char * cfilename, char *filename2write, char *message)
547{
548 // usage: write2disk(__LINE__, __FILE__, "c:\temp\my_dbug_file.txt", uint8_t * msg);
549
550 int i, k=0;
551 char filename[2048];
552 FILE *pFile;
553
554 for(i=0; cfilename[i]; i++)
555 {
556 if(cfilename[i]=='\\')
557 {
558 i++;
559 k = 0;
560 }
561 filename[k++]=(cfilename[i]=='.')?0:cfilename[i];
562 }
563 pFile = fopen(filename2write,"a");
564 fprintf(pFile,"%-4d %-5s %s", line, filename, message);
565 fclose(pFile);
566}
567
568int32 SafeOpenAppend (const char *_filename, int32 filetype)
569{
570 int handle;
571 char filename[MAX_PATH];
572
573 strncpy(filename, _filename, sizeof (filename));
574 filename[sizeof (filename) - 1] = '\0';
575 FixFilePath(filename);
576
577#if (defined PLATFORM_WIN32)
578 handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_APPEND );
579#else
580 handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_APPEND , 0666);
581#endif
582
583 if (handle == -1)
584 Error (EXIT_FAILURE, "Error opening for append %s: %s",filename,strerror(errno));
585
586 return handle;
587}
588
589boolean SafeFileExists ( const char * _filename )
590{
591 char filename[MAX_PATH];
592 strncpy(filename, _filename, sizeof (filename));
593 filename[sizeof (filename) - 1] = '\0';
594 FixFilePath(filename);
595
596#if( defined PLATFORM_WIN32)
597 return(access(filename, 6) == 0);
598#else
599 return(rb->file_exists(filename));
600#endif
601}
602
603
604int32 SafeOpenWrite (const char *_filename, int32 filetype)
605{
606 int handle;
607 char filename[MAX_PATH];
608 strncpy(filename, _filename, sizeof (filename));
609 filename[sizeof (filename) - 1] = '\0';
610 FixFilePath(filename);
611
612#if (defined PLATFORM_WIN32)
613 handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_TRUNC );
614#else
615 handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_TRUNC
616 , 0666);
617#endif
618
619 if (handle == -1)
620 Error (EXIT_FAILURE, "Error opening %s: %s",filename,strerror(errno));
621
622 return handle;
623}
624
625
626
627
628int32 SafeOpenRead (const char *_filename, int32 filetype)
629{
630 int handle;
631 char filename[MAX_PATH];
632 strncpy(filename, _filename, sizeof (filename));
633 filename[sizeof (filename) - 1] = '\0';
634 FixFilePath(filename);
635
636 handle = open(filename,O_RDONLY | O_BINARY);
637
638 if (handle == -1)
639 Error (EXIT_FAILURE, "Error opening %s: %s",filename,strerror(errno));
640
641 return handle;
642}
643
644
645void SafeRead (int32 handle, void *buffer, int32 count)
646{
647 unsigned iocount;
648
649 while (count)
650 {
651 iocount = count > 0x8000 ? 0x8000 : count;
652 if (read (handle,buffer,iocount) != (int)iocount)
653 Error (EXIT_FAILURE, "File read failure reading %ld bytes",count);
654 buffer = (void *)( (byte *)buffer + iocount );
655 count -= iocount;
656 }
657}
658
659
660void SafeWrite (int32 handle, void *buffer, int32 count)
661{
662 unsigned iocount;
663
664 while (count)
665 {
666 iocount = count > 0x8000 ? 0x8000 : count;
667 if (write (handle,buffer,iocount) != (int)iocount)
668 Error (EXIT_FAILURE, "File write failure writing %ld bytes",count);
669 buffer = (void *)( (byte *)buffer + iocount );
670 count -= iocount;
671 }
672}
673
674void SafeWriteString (int handle, char * buffer)
675{
676 unsigned iocount;
677
678 iocount=strlen(buffer);
679 if (write (handle,buffer,iocount) != (int)iocount)
680 Error (EXIT_FAILURE, "File write string failure writing %s\n",buffer);
681}
682
683void *SafeMalloc (int32_t size)
684{
685 void *ptr;
686
687 ptr = malloc(size);
688
689 if (!ptr)
690 Error (EXIT_FAILURE, "SafeMalloc failure for %lu bytes",size);
691
692 return ptr;
693}
694
695void SafeRealloc (void **x, int32 size)
696{
697 void *ptr;
698
699 ptr = realloc(*x, size);
700
701 if (!ptr)
702 Error (EXIT_FAILURE, "SafeRealloc failure for %lu bytes",size);
703
704 *x = ptr;
705}
706
707void *SafeLevelMalloc (int32_t size)
708{
709 void *ptr;
710
711 ptr = malloc(size);
712
713 if (!ptr)
714 Error (EXIT_FAILURE, "SafeLevelMalloc failure for %lu bytes",size);
715
716 return ptr;
717}
718
719void SafeFree (void * ptr)
720{
721 if ( ptr == NULL )
722 Error (EXIT_FAILURE, "SafeFree : Tried to free a freed pointer\n");
723
724 free(ptr);
725
726}
727
728short SwapShort (short l)
729{
730 byte b1,b2;
731
732 b1 = l&255;
733 b2 = (l>>8)&255;
734
735 return (b1<<8) + b2;
736}
737
738short KeepShort (short l)
739{
740 return l;
741}
742
743
744int32_t Swapint32_t (int32_t l)
745{
746 byte b1,b2,b3,b4;
747
748 b1 = l&255;
749 b2 = (l>>8)&255;
750 b3 = (l>>16)&255;
751 b4 = (l>>24)&255;
752
753 return ((int32_t)b1<<24) + ((int32_t)b2<<16) + ((int32_t)b3<<8) + b4;
754}
755
756int32_t Keepint32_t (int32_t l)
757{
758 return l;
759}
760
761
762#undef KeepShort
763#undef KeepLong
764#undef SwapShort
765#undef SwapLong
766
767void SwapIntelLong(int32_t *l)
768{
769 *l = IntelLong(*l);
770}
771
772void SwapIntelShort(short *s)
773{
774 *s = IntelShort(*s);
775}
776
777void SwapIntelLongArray(int32_t *l, int num)
778{
779 while (num--) {
780 SwapIntelLong(l);
781 l++;
782 }
783}
784
785void SwapIntelShortArray(short *s, int num)
786{
787 while (num--) {
788 SwapIntelShort(s);
789 s++;
790 }
791}
792
793
794/*
795 Copied over from Wolf3D Linux: http://www.icculus.org/wolf3d/
796 Modified for ROTT.
797 Stolen for Duke3D, too.
798 */
799
800#if PLATFORM_UNIX
801uint8_t *strlwr(uint8_t *s)
802{
803 uint8_t *p = s;
804
805 while (*p) {
806 *p = tolower(*p);
807 p++;
808 }
809
810 return s;
811}
812
813uint8_t *strupr(uint8_t *s)
814{
815 uint8_t *p = s;
816
817 while (*p) {
818 *p = toupper(*p);
819 p++;
820 }
821
822 return s;
823}
824
825uint8_t *itoa(int value, uint8_t *string, int radix)
826{
827 switch (radix) {
828 case 10:
829 sprintf(string, "%d", value);
830 break;
831 case 16:
832 sprintf(string, "%x", value);
833 break;
834 default:
835 STUBBED("unknown radix");
836 break;
837 }
838
839 return string;
840}
841
842uint8_t *ltoa(int32_t value, uint8_t *string, int radix)
843{
844 switch (radix) {
845 case 10:
846 sprintf(string, "%d", value);
847 break;
848 case 16:
849 sprintf(string, "%x", value);
850 break;
851 default:
852 STUBBED("unknown radix");
853 break;
854 }
855
856 return string;
857}
858
859uint8_t *ultoa(uint32_t value, uint8_t *string, int radix)
860{
861 switch (radix) {
862 case 10:
863 sprintf(string, "%u", value);
864 break;
865 case 16:
866 sprintf(string, "%ux", value);
867 break;
868 default:
869 STUBBED("unknown radix");
870 break;
871 }
872
873 return string;
874}
875#endif
876
877char ApogeePath[256];
878
879int setup_homedir (void)
880{
881#if PLATFORM_UNIX
882 int err;
883
884 snprintf (ApogeePath, sizeof (ApogeePath), "%s/.duke3d/", getenv ("HOME"));
885
886 //err = mkdir (ApogeePath, S_IRWXU);
887 err = mkdir (ApogeePath);
888 if (err == -1 && errno != EEXIST)
889 {
890 fprintf (stderr, "Couldn't create preferences directory: %s\n",
891 strerror (errno));
892 return -1;
893 }
894#else
895 sprintf(ApogeePath, ".%s", PATH_SEP_STR);
896#endif
897
898 return 0;
899}
900
901
902uint8_t CheckParm (char *check)
903{
904 int i;
905 for (i = 1; i < _argc; i++)
906 {
907 if ((*(_argv[i]) == '-') && (strcmpi(_argv[i] + 1, check) == 0))
908 return(i);
909 }
910
911 return(0);
912}
913
914
915static void (*shutdown_func)(void) = NULL;
916
917void RegisterShutdownFunction( void (* shutdown) (void) )
918{
919 shutdown_func = shutdown;
920}
921
922void Shutdown(void)
923{
924 if (shutdown_func != NULL)
925 {
926 shutdown_func();
927 shutdown_func = NULL;
928 }
929}
930
931
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/global.h b/apps/plugins/sdl/progs/duke3d/Game/src/global.h
new file mode 100644
index 0000000000..f34ef7ab9f
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/global.h
@@ -0,0 +1,80 @@
1//
2// global.h
3// Duke3D
4//
5// Created by fabien sanglard on 12-12-17.
6// Copyright (c) 2012 fabien sanglard. All rights reserved.
7//
8
9#ifndef Duke3D_global_h
10#define Duke3D_global_h
11
12#include "SDL.h"
13
14#define open rb->open
15uint16_t readLE16(void *addr);
16uint32_t readLE32(void *addr);
17
18void FixFilePath(char *filename);
19int FindDistance3D(int ix, int iy, int iz);
20void Shutdown(void);
21
22#ifndef LITTLE_ENDIAN
23 #ifdef __APPLE__
24 #else
25 #define LITTLE_ENDIAN 1234
26 #endif
27#endif
28
29#ifndef BIG_ENDIAN
30 #ifdef __APPLE__
31 #else
32 #define BIG_ENDIAN 4321
33 #endif
34#endif
35
36#if PLATFORM_WIN32
37#ifndef BYTE_ORDER
38#define BYTE_ORDER LITTLE_ENDIAN
39#endif
40#endif
41
42#ifdef ROCKBOX
43#ifdef ROCKBOX_LITTLE_ENDIAN
44#define BYTE_ORDER LITTLE_ENDIAN
45#else
46#define BYTE_ORDER BIG_ENDIAN
47#endif
48#endif
49
50#ifdef __APPLE__
51#if __powerpc__
52#define BYTE_ORDER BIG_ENDIAN
53#else
54// Defined in endian.h
55// #define BYTE_ORDER LITTLE_ENDIAN
56#endif
57#endif
58
59#ifndef BYTE_ORDER
60#error Please define your platform.
61#endif
62
63#if (BYTE_ORDER == LITTLE_ENDIAN)
64#define KeepShort IntelShort
65#define SwapShort MotoShort
66#define Keepint32_t IntelLong
67#define Swapint32_t MotoLong
68#else
69#define KeepShort MotoShort
70#define SwapShort IntelShort
71#define Keepint32_t MotoLong
72#define Swapint32_t IntelLong
73#endif
74
75int32_t MotoLong (int32_t l);
76int32_t IntelLong (int32_t l);
77
78void Error (int errorType, char *error, ...);
79
80#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/joystick.h b/apps/plugins/sdl/progs/duke3d/Game/src/joystick.h
new file mode 100644
index 0000000000..ef5daed64b
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/joystick.h
@@ -0,0 +1,19 @@
1#ifndef __joystick_h
2#define __joystick_h
3#ifdef __cplusplus
4extern "C" {
5#endif
6
7 void JOYSTICK_UpdateHats( void );
8 void _joystick_init(void);
9 void _joystick_deinit(void);
10 int _joystick_update(void);
11 int _joystick_axis(int axis);
12 int _joystick_hat(int hat);
13 int _joystick_button(int button);
14
15#ifdef __cplusplus
16};
17
18#endif
19#endif /* __joystick_h */ \ No newline at end of file
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/keyboard.c b/apps/plugins/sdl/progs/duke3d/Game/src/keyboard.c
new file mode 100644
index 0000000000..245169207d
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/keyboard.c
@@ -0,0 +1,441 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#include "duke3d.h"
28#include "keyboard.h"
29
30/*
31=============================================================================
32
33 GLOBAL VARIABLES
34
35=============================================================================
36*/
37
38byte KB_KeyDown[ MAXKEYBOARDSCAN ]; // Keyboard state array
39kb_scancode KB_LastScan;
40
41static volatile boolean keyIsWaiting = 0;
42
43static uint8_t scancodeToASCII[ MAXKEYBOARDSCAN ];
44static uint8_t shiftedScancodeToASCII[ MAXKEYBOARDSCAN ];
45static uint8_t extscanToSC[ MAXKEYBOARDSCAN ];
46
47/*
48=============================================================================
49FUNCTIONS
50=============================================================================
51*/
52
53void keyhandler(void)
54{
55 static boolean gotextended = false;
56
57 int rawkey = _readlastkeyhit();
58 int lastkey = rawkey & 0x7f;
59
60 // 128 bit means key was released.
61 int pressed = !(rawkey & 0x80);
62
63 if (rawkey == 0xe0 && !gotextended)
64 {
65 gotextended = true;
66 return;
67 }
68
69 if (rawkey == 0xe1)
70 {
71 /* SBF - build doesn't actually generate this for Pause/Break */
72 STUBBED("Another extended key!");
73 return;
74 }
75
76 if (gotextended)
77 {
78 gotextended = false;
79
80 /* remap extended key to Duke3D equivalent */
81 lastkey = extscanToSC[lastkey];
82 }
83
84 if (lastkey >= MAXKEYBOARDSCAN)
85 {
86 STUBBED("Scancode out of range!");
87 return;
88 }
89
90 if (pressed)
91 {
92 KB_LastScan = lastkey;
93 }
94
95 KB_KeyDown[lastkey] = pressed;
96
97 keyIsWaiting = ((keyIsWaiting) || (KB_KeyDown[lastkey]));
98
99 CONTROL_UpdateKeyboardState(lastkey, pressed);
100}
101
102void KB_KeyEvent( int scancode, int keypressed )
103{
104 STUBBED("KB_KeyEvent");
105}
106
107int KB_KeyWaiting( void )
108{
109 _handle_events();
110 return keyIsWaiting;
111}
112
113uint8_t KB_Getch( void )
114{
115
116 while (!keyIsWaiting) { _idle(); /* pull the pud. */ }
117 keyIsWaiting = false;
118 if (KB_LastScan >= MAXKEYBOARDSCAN)
119 return(0xFF);
120
121 if (KB_KeyDown[sc_LeftShift] || KB_KeyDown[sc_RightShift])
122 return shiftedScancodeToASCII[KB_LastScan];
123
124 return scancodeToASCII[KB_LastScan];
125}
126
127void KB_Addch( uint8_t ch )
128{
129 STUBBED("KB_Addch");
130}
131
132void KB_FlushKeyboardQueue( void )
133{
134 _handle_events();
135 keyIsWaiting = false;
136 memset(KB_KeyDown, 0, sizeof(KB_KeyDown));
137 // FIX_00077: Menu goes directly to the "NEW GAME" sub-menu when starting new game (Turrican)
138}
139
140void KB_ClearKeysDown( void )
141{
142 memset((void *) KB_KeyDown, '\0', sizeof (KB_KeyDown));
143 keyIsWaiting = false;
144}
145
146static struct {
147 char * name;
148 int code;
149} keyname2scancode[] = {
150 { ",", sc_Comma },
151 { ".", sc_Period },
152 { "Enter", sc_Return },
153 { "Escape", sc_Escape },
154 { "Space", sc_Space },
155 { "BakSpc", sc_BackSpace },
156 { "Tab", sc_Tab },
157 { "LAlt", sc_LeftAlt },
158 { "LCtrl", sc_LeftControl },
159 { "CapLck", sc_CapsLock },
160 { "LShift", sc_LeftShift },
161 { "RShift", sc_RightShift },
162 { "F1", sc_F1 },
163 { "F2", sc_F2 },
164 { "F3", sc_F3 },
165 { "F4", sc_F4 },
166 { "F5", sc_F5 },
167 { "F6", sc_F6 },
168 { "F7", sc_F7 },
169 { "F8", sc_F8 },
170 { "F9", sc_F9 },
171 { "F10", sc_F10 },
172 { "F11", sc_F11 },
173 { "F12", sc_F12 },
174 { "Kpad*", sc_Kpad_Star },
175 { "Pause", sc_Pause },
176 { "ScrLck", sc_ScrollLock },
177 { "NumLck", sc_NumLock }, // 6 chars Max please.
178 { "/", sc_Slash },
179 { ";", sc_SemiColon },
180 { "'", sc_Quote },
181 { "`", sc_Tilde },
182 { "\\", sc_BackSlash },
183 { "[", sc_OpenBracket },
184 { "]", sc_CloseBracket },
185 { "1", sc_1 },
186 { "2", sc_2 },
187 { "3", sc_3 },
188 { "4", sc_4 },
189 { "5", sc_5 },
190 { "6", sc_6 },
191 { "7", sc_7 },
192 { "8", sc_8 },
193 { "9", sc_9 },
194 { "0", sc_0 },
195 { "-", sc_Minus },
196 { "=", sc_Equals },
197 { "+", sc_Plus },
198 { "Kpad1", sc_kpad_1 },
199 { "Kpad2", sc_kpad_2 },
200 { "Kpad3", sc_kpad_3 },
201 { "Kpad4", sc_kpad_4 },
202 { "Kpad5", sc_kpad_5 },
203 { "Kpad6", sc_kpad_6 },
204 { "Kpad7", sc_kpad_7 },
205 { "Kpad8", sc_kpad_8 },
206 { "Kpad9", sc_kpad_9 },
207 { "Kpad0", sc_kpad_0 },
208 { "Kpad-", sc_kpad_Minus },
209 { "Kpad+", sc_kpad_Plus },
210 { "Kpad.", sc_kpad_Period },
211 { "A", sc_A },
212 { "B", sc_B },
213 { "C", sc_C },
214 { "D", sc_D },
215 { "E", sc_E },
216 { "F", sc_F },
217 { "G", sc_G },
218 { "H", sc_H },
219 { "I", sc_I },
220 { "J", sc_J },
221 { "K", sc_K },
222 { "L", sc_L },
223 { "M", sc_M },
224 { "N", sc_N },
225 { "O", sc_O },
226 { "P", sc_P },
227 { "Q", sc_Q },
228 { "R", sc_R },
229 { "S", sc_S },
230 { "T", sc_T },
231 { "U", sc_U },
232 { "V", sc_V },
233 { "W", sc_W },
234 { "X", sc_X },
235 { "Y", sc_Y },
236 { "Z", sc_Z },
237 { "Up", sc_UpArrow },
238 { "Down", sc_DownArrow },
239 { "Left", sc_LeftArrow },
240 { "Right", sc_RightArrow },
241 { "Insert", sc_Insert },
242 { "Delete", sc_Delete },
243 { "Home", sc_Home },
244 { "End", sc_End },
245 { "PgUp", sc_PgUp },
246 { "PgDn", sc_PgDn },
247 { "RAlt", sc_RightAlt },
248 { "RCtrl", sc_RightControl },
249 { "Kpad/", sc_kpad_Slash },
250 { "KpdEnt", sc_kpad_Enter },
251 { "PrtScn", sc_PrintScreen },
252 { NULL, 0 }
253};
254
255char *KB_ScanCodeToString( kb_scancode scancode )
256{
257 int i;
258 for(i = 0; keyname2scancode[i].name != NULL; i++)
259 {
260 if (keyname2scancode[i].code == scancode)
261 return keyname2scancode[i].name;
262 }
263
264 return NULL;
265}
266
267kb_scancode KB_StringToScanCode( char * string )
268{
269 char * name = NULL;
270 int32 i=0;
271 name = keyname2scancode[i].name;
272 for(;name;++i, name=keyname2scancode[i].name)
273 {
274 if(!stricmp(name,string))
275 break;
276 }
277
278 return keyname2scancode[i].code;
279}
280
281void KB_TurnKeypadOn( void )
282{
283 STUBBED("KB_TurnKeypadOn");
284}
285
286void KB_TurnKeypadOff( void )
287{
288 STUBBED("KB_TurnKeypadOff");
289}
290
291int KB_KeypadActive( void )
292{
293 STUBBED("KB_KeypadActive");
294 return false;
295}
296
297void KB_Startup( void )
298{
299 memset(scancodeToASCII, 0xFF, sizeof (scancodeToASCII));
300
301 // !!! FIXME: incomplete?
302 scancodeToASCII[sc_A] = 'a';
303 scancodeToASCII[sc_B] = 'b';
304 scancodeToASCII[sc_C] = 'c';
305 scancodeToASCII[sc_D] = 'd';
306 scancodeToASCII[sc_E] = 'e';
307 scancodeToASCII[sc_F] = 'f';
308 scancodeToASCII[sc_G] = 'g';
309 scancodeToASCII[sc_H] = 'h';
310 scancodeToASCII[sc_I] = 'i';
311 scancodeToASCII[sc_J] = 'j';
312 scancodeToASCII[sc_K] = 'k';
313 scancodeToASCII[sc_L] = 'l';
314 scancodeToASCII[sc_M] = 'm';
315 scancodeToASCII[sc_N] = 'n';
316 scancodeToASCII[sc_O] = 'o';
317 scancodeToASCII[sc_P] = 'p';
318 scancodeToASCII[sc_Q] = 'q';
319 scancodeToASCII[sc_R] = 'r';
320 scancodeToASCII[sc_S] = 's';
321 scancodeToASCII[sc_T] = 't';
322 scancodeToASCII[sc_U] = 'u';
323 scancodeToASCII[sc_V] = 'v';
324 scancodeToASCII[sc_W] = 'w';
325 scancodeToASCII[sc_X] = 'x';
326 scancodeToASCII[sc_Y] = 'y';
327 scancodeToASCII[sc_Z] = 'z';
328 scancodeToASCII[sc_0] = '0';
329 scancodeToASCII[sc_1] = '1';
330 scancodeToASCII[sc_2] = '2';
331 scancodeToASCII[sc_3] = '3';
332 scancodeToASCII[sc_4] = '4';
333 scancodeToASCII[sc_5] = '5';
334 scancodeToASCII[sc_6] = '6';
335 scancodeToASCII[sc_7] = '7';
336 scancodeToASCII[sc_8] = '8';
337 scancodeToASCII[sc_9] = '9';
338 scancodeToASCII[sc_Escape] = asc_Escape;
339 scancodeToASCII[sc_Tab] = asc_Tab;
340 scancodeToASCII[sc_Space] = asc_Space;
341 scancodeToASCII[sc_Enter] = asc_Enter;
342 scancodeToASCII[sc_BackSpace] = asc_BackSpace;
343 scancodeToASCII[sc_Comma] = ',';
344 scancodeToASCII[sc_Period] = '.';
345 scancodeToASCII[sc_Kpad_Star] = '*';
346 scancodeToASCII[sc_Slash] = '/';
347 scancodeToASCII[sc_SemiColon] = ';';
348 scancodeToASCII[sc_Quote] = '\'';
349 scancodeToASCII[sc_Tilde] = '`';
350 scancodeToASCII[sc_BackSlash] = '\\';
351 scancodeToASCII[sc_OpenBracket] = '[';
352 scancodeToASCII[sc_CloseBracket] = ']';
353 scancodeToASCII[sc_Minus] = '-';
354 scancodeToASCII[sc_Equals] = '=';
355 scancodeToASCII[sc_Plus] = '+';
356 scancodeToASCII[sc_kpad_Minus] = '-';
357 scancodeToASCII[sc_kpad_Period] = '.';
358 scancodeToASCII[sc_kpad_Plus] = '+';
359
360 // !!! FIXME: incomplete?
361 memset(shiftedScancodeToASCII, 0xFF, sizeof (shiftedScancodeToASCII));
362 shiftedScancodeToASCII[sc_A] = 'A';
363 shiftedScancodeToASCII[sc_B] = 'B';
364 shiftedScancodeToASCII[sc_C] = 'C';
365 shiftedScancodeToASCII[sc_D] = 'D';
366 shiftedScancodeToASCII[sc_E] = 'E';
367 shiftedScancodeToASCII[sc_F] = 'F';
368 shiftedScancodeToASCII[sc_G] = 'G';
369 shiftedScancodeToASCII[sc_H] = 'H';
370 shiftedScancodeToASCII[sc_I] = 'I';
371 shiftedScancodeToASCII[sc_J] = 'J';
372 shiftedScancodeToASCII[sc_K] = 'K';
373 shiftedScancodeToASCII[sc_L] = 'L';
374 shiftedScancodeToASCII[sc_M] = 'M';
375 shiftedScancodeToASCII[sc_N] = 'N';
376 shiftedScancodeToASCII[sc_O] = 'O';
377 shiftedScancodeToASCII[sc_P] = 'P';
378 shiftedScancodeToASCII[sc_Q] = 'Q';
379 shiftedScancodeToASCII[sc_R] = 'R';
380 shiftedScancodeToASCII[sc_S] = 'S';
381 shiftedScancodeToASCII[sc_T] = 'T';
382 shiftedScancodeToASCII[sc_U] = 'U';
383 shiftedScancodeToASCII[sc_V] = 'V';
384 shiftedScancodeToASCII[sc_W] = 'W';
385 shiftedScancodeToASCII[sc_X] = 'X';
386 shiftedScancodeToASCII[sc_Y] = 'Y';
387 shiftedScancodeToASCII[sc_Z] = 'Z';
388 shiftedScancodeToASCII[sc_0] = ')';
389 shiftedScancodeToASCII[sc_1] = '!';
390 shiftedScancodeToASCII[sc_2] = '@';
391 shiftedScancodeToASCII[sc_3] = '#';
392 shiftedScancodeToASCII[sc_4] = '$';
393 shiftedScancodeToASCII[sc_5] = '%';
394 shiftedScancodeToASCII[sc_6] = '^';
395 shiftedScancodeToASCII[sc_7] = '&';
396 shiftedScancodeToASCII[sc_8] = '*';
397 shiftedScancodeToASCII[sc_9] = '(';
398 shiftedScancodeToASCII[sc_Comma] = '<';
399 shiftedScancodeToASCII[sc_Period] = '>';
400 shiftedScancodeToASCII[sc_Kpad_Star] = '*';
401 shiftedScancodeToASCII[sc_Slash] = '?';
402 shiftedScancodeToASCII[sc_SemiColon] = ':';
403 shiftedScancodeToASCII[sc_Quote] = '\"';
404 shiftedScancodeToASCII[sc_Tilde] = '~';
405 shiftedScancodeToASCII[sc_BackSlash] = '|';
406 shiftedScancodeToASCII[sc_OpenBracket] = '{';
407 shiftedScancodeToASCII[sc_CloseBracket] = '}';
408 shiftedScancodeToASCII[sc_Minus] = '_';
409 shiftedScancodeToASCII[sc_Equals] = '+';
410 shiftedScancodeToASCII[sc_Plus] = '+';
411 shiftedScancodeToASCII[sc_kpad_Minus] = '-';
412 shiftedScancodeToASCII[sc_kpad_Period] = '.';
413 shiftedScancodeToASCII[sc_kpad_Plus] = '+';
414
415 memset(extscanToSC, '\0', sizeof (extscanToSC));
416
417 /* map extended keys to their Duke3D equivalents */
418 extscanToSC[0x1C] = sc_kpad_Enter;
419 extscanToSC[0x1D] = sc_RightControl;
420 extscanToSC[0x35] = sc_kpad_Slash;
421 extscanToSC[0x37] = sc_PrintScreen;
422 extscanToSC[0x38] = sc_RightAlt;
423 extscanToSC[0x47] = sc_Home;
424 extscanToSC[0x48] = sc_UpArrow;
425 extscanToSC[0x49] = sc_PgUp;
426 extscanToSC[0x4B] = sc_LeftArrow;
427 extscanToSC[0x4D] = sc_RightArrow;
428 extscanToSC[0x4F] = sc_End;
429 extscanToSC[0x50] = sc_DownArrow;
430 extscanToSC[0x51] = sc_PgDn;
431 extscanToSC[0x52] = sc_Insert;
432 extscanToSC[0x53] = sc_Delete;
433
434 KB_ClearKeysDown();
435}
436
437void KB_Shutdown( void )
438{
439 KB_ClearKeysDown();
440}
441
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/keyboard.h b/apps/plugins/sdl/progs/duke3d/Game/src/keyboard.h
new file mode 100644
index 0000000000..312ff2a54d
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/keyboard.h
@@ -0,0 +1,224 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#ifndef _keyboard_public
28#define _keyboard_public
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33/*
34=============================================================================
35
36 DEFINES
37
38=============================================================================
39*/
40
41typedef uint8_t kb_scancode;
42
43#define sc_None 0
44#define sc_Bad 0xff
45#define sc_Comma 0x33
46#define sc_Period 0x34
47#define sc_Return 0x1c
48#define sc_Enter sc_Return
49#define sc_Escape 0x01
50#define sc_Space 0x39
51#define sc_BackSpace 0x0e
52#define sc_Tab 0x0f
53#define sc_LeftAlt 0x38
54#define sc_LeftControl 0x1d
55#define sc_CapsLock 0x3a
56#define sc_LeftShift 0x2a
57#define sc_RightShift 0x36
58#define sc_F1 0x3b
59#define sc_F2 0x3c
60#define sc_F3 0x3d
61#define sc_F4 0x3e
62#define sc_F5 0x3f
63#define sc_F6 0x40
64#define sc_F7 0x41
65#define sc_F8 0x42
66#define sc_F9 0x43
67#define sc_F10 0x44
68#define sc_F11 0x57
69#define sc_F12 0x58
70#define sc_Kpad_Star 0x37
71#define sc_Pause 0x59
72#define sc_ScrollLock 0x46
73#define sc_NumLock 0x45
74#define sc_Slash 0x35
75#define sc_SemiColon 0x27
76#define sc_Quote 0x28
77#define sc_Tilde 0x29
78#define sc_BackSlash 0x2b
79
80#define sc_OpenBracket 0x1a
81#define sc_CloseBracket 0x1b
82
83#define sc_1 0x02
84#define sc_2 0x03
85#define sc_3 0x04
86#define sc_4 0x05
87#define sc_5 0x06
88#define sc_6 0x07
89#define sc_7 0x08
90#define sc_8 0x09
91#define sc_9 0x0a
92#define sc_0 0x0b
93#define sc_Minus 0x0c
94#define sc_Equals 0x0d
95#define sc_Plus 0x0d
96
97#define sc_kpad_1 0x4f
98#define sc_kpad_2 0x50
99#define sc_kpad_3 0x51
100#define sc_kpad_4 0x4b
101#define sc_kpad_5 0x4c
102#define sc_kpad_6 0x4d
103#define sc_kpad_7 0x47
104#define sc_kpad_8 0x48
105#define sc_kpad_9 0x49
106#define sc_kpad_0 0x52
107#define sc_kpad_Minus 0x4a
108#define sc_kpad_Plus 0x4e
109#define sc_kpad_Period 0x53
110
111#define sc_A 0x1e
112#define sc_B 0x30
113#define sc_C 0x2e
114#define sc_D 0x20
115#define sc_E 0x12
116#define sc_F 0x21
117#define sc_G 0x22
118#define sc_H 0x23
119#define sc_I 0x17
120#define sc_J 0x24
121#define sc_K 0x25
122#define sc_L 0x26
123#define sc_M 0x32
124#define sc_N 0x31
125#define sc_O 0x18
126#define sc_P 0x19
127#define sc_Q 0x10
128#define sc_R 0x13
129#define sc_S 0x1f
130#define sc_T 0x14
131#define sc_U 0x16
132#define sc_V 0x2f
133#define sc_W 0x11
134#define sc_X 0x2d
135#define sc_Y 0x15
136#define sc_Z 0x2c
137
138// Extended scan codes
139
140#define sc_UpArrow 0x5a
141#define sc_DownArrow 0x6a
142#define sc_LeftArrow 0x6b
143#define sc_RightArrow 0x6c
144#define sc_Insert 0x5e
145#define sc_Delete 0x5f
146#define sc_Home 0x61
147#define sc_End 0x62
148#define sc_PgUp 0x63
149#define sc_PgDn 0x64
150#define sc_RightAlt 0x65
151#define sc_RightControl 0x66
152#define sc_kpad_Slash 0x67
153#define sc_kpad_Enter 0x68
154#define sc_PrintScreen 0x69
155#define sc_LastScanCode 0x6e
156
157// Ascii scan codes
158
159#define asc_Enter 13
160#define asc_Escape 27
161#define asc_BackSpace 8
162#define asc_Tab 9
163#define asc_Space 32
164
165#define MAXKEYBOARDSCAN 128
166
167
168/*
169=============================================================================
170
171 GLOBAL VARIABLES
172
173=============================================================================
174*/
175
176extern uint8_t KB_KeyDown[ MAXKEYBOARDSCAN ]; // Keyboard state array
177extern kb_scancode KB_LastScan;
178
179
180/*
181=============================================================================
182
183 MACROS
184
185=============================================================================
186*/
187
188#define KB_GetLastScanCode() ( KB_LastScan )
189
190#define KB_SetLastScanCode( scancode ) { KB_LastScan = ( scancode ); }
191
192#define KB_ClearLastScanCode() { KB_SetLastScanCode( sc_None ); }
193
194#define KB_KeyPressed( scan ) ( KB_KeyDown[ ( scan ) ] != 0 )
195
196#define KB_ClearKeyDown( scan ) { KB_KeyDown[ ( scan ) ] = false; }
197
198#define KB_SetKeyDown( scan ) { KB_KeyDown[ ( scan ) ] = true; }
199/*
200=============================================================================
201
202 FUNCTION PROTOTYPES
203
204=============================================================================
205*/
206
207void KB_KeyEvent( int scancode, int keypressed ); // Interprets scancodes
208int KB_KeyWaiting( void ); // Checks if a character is waiting in the keyboard queue
209uint8_t KB_Getch( void ); // Gets the next keypress
210void KB_Addch( uint8_t ch ); // Adds key to end of queue
211void KB_FlushKeyboardQueue( void ); // Empties the keyboard queue of all waiting characters.
212void KB_ClearKeysDown( void ); // Clears all keys down flags.
213char * KB_ScanCodeToString( kb_scancode scancode ); // convert scancode into a string
214kb_scancode KB_StringToScanCode( char * string ); // convert a string into a scancode
215void KB_TurnKeypadOn( void ); // turn the keypad on
216void KB_TurnKeypadOff( void ); // turn the keypad off
217int KB_KeypadActive( void ); // check whether keypad is active
218void KB_Startup( void );
219void KB_Shutdown( void );
220
221#ifdef __cplusplus
222};
223#endif
224#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/menues.c b/apps/plugins/sdl/progs/duke3d/Game/src/menues.c
new file mode 100644
index 0000000000..3585600f43
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/menues.c
@@ -0,0 +1,4707 @@
1//-------------------------------------------------------------------------
2/*
3 Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5 This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7 Duke Nukem 3D is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 aint32_t with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 Original Source: 1996 - Todd Replogle
23 Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#include "duke3d.h"
28#include "mouse.h"
29#include "animlib.h"
30#include "control.h"
31
32#include "../../Engine/src/filesystem.h"
33#include "SDL.h"
34#include "premap.h"
35#include "../../Engine/src/display.h"
36
37extern SDL_Surface *surface;
38extern short inputloc;
39extern int recfilep;
40extern uint8_t vgacompatible;
41short probey=0,lastprobey=0,last_menu,globalskillsound=-1;
42short sh,onbar,buttonstat,deletespot;
43short last_zero,last_fifty,last_threehundred = 0;
44static uint8_t fileselect = 1, menunamecnt;
45static char menuname[256][17];
46
47// File tree info
48//
49uint8_t szCurrentDirectory[1024] = {'\0'};
50
51#define FILETYPE_DIRECTORY 0
52#define FILETYPE_FILE 1
53
54typedef struct fileentry
55{
56 uint8_t filename[16];
57 int type;
58}FILEENTRY;
59
60typedef struct filelist
61{
62 FILEENTRY *files;
63}FILELIST;
64
65FILELIST m_Files;// = NULL;
66
67//
68//
69
70#define MENU_SELECT_EPISODE 100
71#define MENU_USER_MAP 101
72
73
74// CTW - REMOVED
75/* Error codes */
76/*
77 #define eTenBnNotInWindows 3801
78 #define eTenBnBadGameIni 3802
79 #define eTenBnBadTenIni 3803
80 #define eTenBnBrowseCancel 3804
81 #define eTenBnBadTenInst 3805
82
83 int tenBnStart(void);
84 void tenBnSetBrowseRtn(uint8_t *(*rtn)(uint8_t *str, int len));
85 void tenBnSetExitRtn(void (*rtn)(void));
86 void tenBnSetEndRtn(void (*rtn)(void));*/
87// CTW END - REMOVED
88
89void dummyfunc(void)
90{
91}
92
93void dummymess(int i,uint8_t *c)
94{
95}
96
97// CTW - REMOVED
98/*
99 void TENtext(void)
100 {
101 int32_t dacount,dalastcount;
102
103 puts("\nDuke Nukem 3D has been licensed exclusively to TEN (Total");
104 puts("Entertainment Network) for wide-area networked (WAN) multiplayer");
105 puts("games.\n");
106
107 puts("The multiplayer code within Duke Nukem 3D has been highly");
108 puts("customized to run best on TEN, where you'll experience fast and");
109 puts("stable performance, plus other special benefits.\n");
110
111 puts("We do not authorize or recommend the use of Duke Nukem 3D with");
112 puts("gaming services other than TEN.\n");
113
114 puts("Duke Nukem 3D is protected by United States copyright law and");
115 puts("international treaty.\n");
116
117 puts("For the best online multiplayer gaming experience, please call TEN");
118 puts("at 800-8040-TEN, or visit TEN's Web Site at www.ten.net.\n");
119
120 puts("Press any key to continue.\n");
121
122 _bios_timeofday(0,&dacount);
123
124 while( _bios_keybrd(1) == 0 )
125 {
126 _bios_timeofday(0,&dalastcount);
127 if( (dacount+240) < dalastcount ) break;
128 }
129 }
130*/
131// CTW END - REMOVED
132
133void cmenu(short cm)
134{
135 current_menu = cm;
136
137 if( (cm >= 1000 && cm <= 1010) )
138 return;
139
140 if( cm == 0 )
141 probey = last_zero;
142 else if(cm == 50)
143 probey = last_fifty;
144 else if(cm >= 300 && cm < 400)
145 probey = last_threehundred;
146 else if(cm == 110)
147 probey = 1;
148 else probey = 0;
149 lastprobey = -1;
150}
151
152
153void savetemp(char *fn,uint8_t* daptr,int32_t dasiz)
154{
155 int fp;
156
157 char full[256];
158 snprintf(full, "%s/%s", game_dir, fn);
159 fp = rb->open(full,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666);
160
161 write(fp,(uint8_t *)daptr,dasiz);
162
163 close(fp);
164}
165
166void getangplayers(short snum)
167{
168 short i,a;
169
170 for(i=connecthead;i>=0;i=connectpoint2[i])
171 {
172 if(i != snum)
173 {
174 a = ps[snum].ang+getangle(ps[i].posx-ps[snum].posx,ps[i].posy-ps[snum].posy);
175 a = a-1024;
176 rotatesprite(
177 (320<<15) + (((sintable[(a+512)&2047])>>7)<<15),
178 (320<<15) - (((sintable[a&2047])>>8)<<15),
179 klabs(sintable[((a>>1)+768)&2047]<<2),0,APLAYER,0,ps[i].palookup,0,0,0,xdim-1,ydim-1);
180 }
181 }
182}
183
184int loadpheader(uint8_t spot,int32 *vn,int32 *ln,int32 *psk,int32 *nump)
185{
186
187 char fn[] = "game0.sav";
188 int32_t fil;
189 int32_t bv;
190
191 fn[4] = spot+'0';
192
193 char fullfn[256];
194 sprintf(fullfn, "%s/%s", game_dir, fn);
195
196 if ((fil = TCkopen4load(fullfn,0)) == -1) return(-1);
197
198 tiles[MAXTILES-3].lock = 255;
199
200 kdfread(&bv,4,1,fil);
201 if(bv != BYTEVERSION)
202 {
203 FTA(114,&ps[myconnectindex],1);
204 kclose(fil);
205 return 1;
206 }
207
208 kdfread(nump,sizeof(int32),1,fil);
209
210 kdfread(tempbuf,19,1,fil);
211 kdfread(vn,sizeof(int32),1,fil);
212 kdfread(ln,sizeof(int32),1,fil);
213 kdfread(psk,sizeof(int32),1,fil);
214
215 if (tiles[MAXTILES-3].data == NULL)
216 allocache(&tiles[MAXTILES-3].data,160*100,&tiles[MAXTILES-3].lock);
217 tiles[MAXTILES-3].dim.width = 100;
218 tiles[MAXTILES-3].dim.height = 160;
219 kdfread(tiles[MAXTILES-3].data,160,100,fil);
220 kclose(fil);
221 return(0);
222}
223
224
225int loadplayer(int8_t spot)
226{
227 short k,music_changed;
228 char fn[] = "game0.sav";
229 char mpfn[] = "gameA_00.sav";
230 char *fnptr, scriptptrs[MAXSCRIPTSIZE];
231 int32_t fil, bv, i, j, x;
232 int32 nump;
233
234 if(spot < 0)
235 {
236 multiflag = 1;
237 multiwhat = 0;
238 multipos = -spot-1;
239 return -1;
240 }
241
242 if( multiflag == 2 && multiwho != myconnectindex )
243 {
244 fnptr = mpfn;
245 mpfn[4] = spot + 'A';
246
247 if(ud.multimode > 9)
248 {
249 mpfn[6] = (multiwho/10) + '0';
250 mpfn[7] = (multiwho%10) + '0';
251 }
252 else mpfn[7] = multiwho + '0';
253 }
254 else
255 {
256 fnptr = fn;
257 fn[4] = spot + '0';
258 }
259
260 char fullfn[256];
261 sprintf(fullfn, "%s/%s", game_dir, fnptr);
262
263 if ((fil = TCkopen4load(fullfn,0)) == -1) return(-1);
264
265 if(ud.recstat != 2)
266 ready2send = 0;
267
268 kdfread(&bv,4,1,fil);
269 if(bv != BYTEVERSION)
270 {
271 rb->splashf(HZ, "wrong version (%d != %d)", bv, BYTEVERSION);
272 FTA(114,&ps[myconnectindex],1);
273 kclose(fil);
274 if(ud.recstat != 2)
275 {
276 // FIX_00084: Various bugs in the load game (single player) option if ESC is hit or if wrong version
277 ototalclock = totalclock;
278 ready2send = 1;
279 }
280 return 1;
281 }
282
283 kdfread(&nump,sizeof(nump),1,fil);
284 if(nump != numplayers)
285 {
286 rb->splash(HZ, "wrong num players");
287 kclose(fil);
288 if(ud.recstat != 2)
289 {
290 // FIX_00084: Various bugs in the load game (single player) option if ESC is hit or if wrong version
291 ototalclock = totalclock;
292 ready2send = 1;
293 }
294 FTA(124,&ps[myconnectindex],1);
295 return 1;
296 }
297
298 if(numplayers > 1)
299 {
300 pub = NUMPAGES;
301 pus = NUMPAGES;
302 vscrn();
303 drawbackground();
304 menutext(160,100,0,0,"LOADING...");
305 nextpage();
306 }
307
308 waitforeverybody();
309
310 FX_StopAllSounds();
311 clearsoundlocks();
312 MUSIC_StopSong();
313
314 if(numplayers > 1)
315 kdfread(&buf,19,1,fil);
316 else
317 kdfread(&ud.savegame[spot][0],19,1,fil);
318
319 music_changed = (music_select != (ud.volume_number*11) + ud.level_number);
320
321 kdfread(&ud.volume_number,sizeof(ud.volume_number),1,fil);
322 kdfread(&ud.level_number,sizeof(ud.level_number),1,fil);
323 kdfread(&ud.player_skill,sizeof(ud.player_skill),1,fil);
324
325 ud.m_level_number = ud.level_number;
326 ud.m_volume_number = ud.volume_number;
327 ud.m_player_skill = ud.player_skill;
328
329 //Fake read because lseek won't work with compression
330 tiles[MAXTILES-3].lock = 1;
331
332 if (tiles[MAXTILES-3].data == NULL)
333 allocache(&tiles[MAXTILES-3].data,160*100,&tiles[MAXTILES-3].lock);
334
335 tiles[MAXTILES-3].dim.width = 100;
336 tiles[MAXTILES-3].dim.height = 160;
337
338 kdfread(tiles[MAXTILES-3].data,160,100,fil);
339
340 kdfread(&numwalls,2,1,fil);
341 kdfread(&wall[0],sizeof(walltype),MAXWALLS,fil);
342 kdfread(&numsectors,2,1,fil);
343 kdfread(&sector[0],sizeof(sectortype),MAXSECTORS,fil);
344 kdfread(&sprite[0],sizeof(spritetype),MAXSPRITES,fil);
345 kdfread(&headspritesect[0],2,MAXSECTORS+1,fil);
346 kdfread(&prevspritesect[0],2,MAXSPRITES,fil);
347 kdfread(&nextspritesect[0],2,MAXSPRITES,fil);
348 kdfread(&headspritestat[0],2,MAXSTATUS+1,fil);
349 kdfread(&prevspritestat[0],2,MAXSPRITES,fil);
350 kdfread(&nextspritestat[0],2,MAXSPRITES,fil);
351 kdfread(&numcyclers,sizeof(numcyclers),1,fil);
352 kdfread(&cyclers[0][0],12,MAXCYCLERS,fil);
353 kdfread(ps,sizeof(ps),1,fil);
354 kdfread(po,sizeof(po),1,fil);
355 kdfread(&numanimwalls,sizeof(numanimwalls),1,fil);
356 kdfread(&animwall,sizeof(animwall),1,fil);
357 kdfread(&msx[0],sizeof(int32_t),sizeof(msx)/sizeof(int32_t),fil);
358 kdfread(&msy[0],sizeof(int32_t),sizeof(msy)/sizeof(int32_t),fil);
359 kdfread((short *)&spriteqloc,sizeof(short),1,fil);
360 kdfread((short *)&spriteqamount,sizeof(short),1,fil);
361 kdfread((short *)&spriteq[0],sizeof(short),spriteqamount,fil);
362 kdfread(&mirrorcnt,sizeof(short),1,fil);
363 kdfread(&mirrorwall[0],sizeof(short),64,fil);
364 kdfread(&mirrorsector[0],sizeof(short),64,fil);
365 kdfread(&show2dsector[0],sizeof(uint8_t ),MAXSECTORS>>3,fil);
366 kdfread(&actortype[0],sizeof(uint8_t ),MAXTILES,fil);
367 kdfread(&boardfilename[0],sizeof(boardfilename),1,fil);
368
369 kdfread(&numclouds,sizeof(numclouds),1,fil);
370 kdfread(&clouds[0],sizeof(short)<<7,1,fil);
371 kdfread(&cloudx[0],sizeof(short)<<7,1,fil);
372 kdfread(&cloudy[0],sizeof(short)<<7,1,fil);
373
374 kdfread(&scriptptrs[0],1,MAXSCRIPTSIZE,fil);
375 kdfread(&script[0],4,MAXSCRIPTSIZE,fil);
376 for(i=0;i<MAXSCRIPTSIZE;i++)
377 if( scriptptrs[i] )
378 {
379 j = (int32_t)script[i]+(int32_t)&script[0];
380 script[i] = j;
381 }
382
383 kdfread(&actorscrptr[0],4,MAXTILES,fil);
384 for(i=0;i<MAXTILES;i++)
385 if(actorscrptr[i])
386 {
387 j = (int32_t)actorscrptr[i]+(int32_t)&script[0];
388 actorscrptr[i] = (int32_t *)j;
389 }
390
391 kdfread(&scriptptrs[0],1,MAXSPRITES,fil);
392 kdfread(&hittype[0],sizeof(struct weaponhit),MAXSPRITES,fil);
393
394 for(i=0;i<MAXSPRITES;i++)
395 {
396 j = (int32_t)(&script[0]);
397 if( scriptptrs[i]&1 ) T2 += j;
398 if( scriptptrs[i]&2 ) T5 += j;
399 if( scriptptrs[i]&4 ) T6 += j;
400 }
401
402 kdfread(&lockclock,sizeof(lockclock),1,fil);
403 kdfread(&pskybits,sizeof(pskybits),1,fil);
404 kdfread(&pskyoff[0],sizeof(pskyoff[0]),MAXPSKYTILES,fil);
405
406 kdfread(&animatecnt,sizeof(animatecnt),1,fil);
407 kdfread(&animatesect[0],2,MAXANIMATES,fil);
408 kdfread(&animateptr[0],4,MAXANIMATES,fil);
409 for(i = animatecnt-1;i>=0;i--) animateptr[i] = (int32_t *)((int32_t)animateptr[i]+(int32_t)(&sector[0]));
410 kdfread(&animategoal[0],4,MAXANIMATES,fil);
411 kdfread(&animatevel[0],4,MAXANIMATES,fil);
412
413 kdfread(&earthquaketime,sizeof(earthquaketime),1,fil);
414 kdfread(&ud.from_bonus,sizeof(ud.from_bonus),1,fil);
415 kdfread(&ud.secretlevel,sizeof(ud.secretlevel),1,fil);
416 kdfread(&ud.respawn_monsters,sizeof(ud.respawn_monsters),1,fil);
417 ud.m_respawn_monsters = ud.respawn_monsters;
418 kdfread(&ud.respawn_items,sizeof(ud.respawn_items),1,fil);
419 ud.m_respawn_items = ud.respawn_items;
420 kdfread(&ud.respawn_inventory,sizeof(ud.respawn_inventory),1,fil);
421 ud.m_respawn_inventory = ud.respawn_inventory;
422
423 kdfread(&ud.god,sizeof(ud.god),1,fil);
424 kdfread(&ud.auto_run,sizeof(ud.auto_run),1,fil);
425 kdfread(&ud.crosshair,sizeof(ud.crosshair),1,fil);
426 kdfread(&ud.monsters_off,sizeof(ud.monsters_off),1,fil);
427 ud.m_monsters_off = ud.monsters_off;
428 kdfread(&ud.last_level,sizeof(ud.last_level),1,fil);
429 kdfread(&ud.eog,sizeof(ud.eog),1,fil);
430
431 kdfread(&ud.coop,sizeof(ud.coop),1,fil);
432 ud.m_coop = ud.coop;
433 kdfread(&ud.marker,sizeof(ud.marker),1,fil);
434 ud.m_marker = ud.marker;
435 kdfread(&ud.ffire,sizeof(ud.ffire),1,fil);
436 ud.m_ffire = ud.ffire;
437
438 kdfread(&camsprite,sizeof(camsprite),1,fil);
439 kdfread(&connecthead,sizeof(connecthead),1,fil);
440 kdfread(connectpoint2,sizeof(connectpoint2),1,fil);
441 kdfread(&numplayersprites,sizeof(numplayersprites),1,fil);
442 kdfread((short *)&frags[0][0],sizeof(frags),1,fil);
443
444 kdfread(&randomseed,sizeof(randomseed),1,fil);
445 kdfread(&global_random,sizeof(global_random),1,fil);
446 kdfread(&parallaxyscale,sizeof(parallaxyscale),1,fil);
447
448 kclose(fil);
449
450 if(ps[myconnectindex].over_shoulder_on != 0)
451 {
452 cameradist = 0;
453 cameraclock = 0;
454 ps[myconnectindex].over_shoulder_on = 1;
455 }
456
457 screenpeek = myconnectindex;
458
459 clearbufbyte(gotpic,sizeof(gotpic),0L);
460 clearsoundlocks();
461 cacheit();
462 docacheit();
463
464 if(music_changed == 0)
465 music_select = (ud.volume_number*11) + ud.level_number;
466 playmusic(&music_fn[0][music_select][0]);
467
468 ps[myconnectindex].gm = MODE_GAME;
469 ud.recstat = 0;
470
471 if(ps[myconnectindex].jetpack_on)
472 spritesound(DUKE_JETPACK_IDLE,ps[myconnectindex].i);
473
474 restorepalette = 1;
475 setpal(&ps[myconnectindex]);
476 vscrn();
477
478 FX_SetReverb(0);
479
480 if(ud.lockout == 0)
481 {
482 for(x=0;x<numanimwalls;x++)
483 if( wall[animwall[x].wallnum].extra >= 0 )
484 wall[animwall[x].wallnum].picnum = wall[animwall[x].wallnum].extra;
485 }
486 else
487 {
488 for(x=0;x<numanimwalls;x++)
489 switch(wall[animwall[x].wallnum].picnum)
490 {
491 case FEMPIC1:
492 wall[animwall[x].wallnum].picnum = BLANKSCREEN;
493 break;
494 case FEMPIC2:
495 case FEMPIC3:
496 wall[animwall[x].wallnum].picnum = SCREENBREAK6;
497 break;
498 }
499 }
500
501 numinterpolations = 0;
502 startofdynamicinterpolations = 0;
503
504 k = headspritestat[3];
505 while(k >= 0)
506 {
507 switch(sprite[k].lotag)
508 {
509 case 31:
510 setinterpolation(&sector[sprite[k].sectnum].floorz);
511 break;
512 case 32:
513 setinterpolation(&sector[sprite[k].sectnum].ceilingz);
514 break;
515 case 25:
516 setinterpolation(&sector[sprite[k].sectnum].floorz);
517 setinterpolation(&sector[sprite[k].sectnum].ceilingz);
518 break;
519 case 17:
520 setinterpolation(&sector[sprite[k].sectnum].floorz);
521 setinterpolation(&sector[sprite[k].sectnum].ceilingz);
522 break;
523 case 0:
524 case 5:
525 case 6:
526 case 11:
527 case 14:
528 case 15:
529 case 16:
530 case 26:
531 case 30:
532 setsectinterpolate(k);
533 break;
534 }
535
536 k = nextspritestat[k];
537 }
538
539 for(i=numinterpolations-1;i>=0;i--) bakipos[i] = *curipos[i];
540 for(i = animatecnt-1;i>=0;i--)
541 setinterpolation(animateptr[i]);
542
543 show_shareware = 0;
544 everyothertime = 0;
545
546 clearbufbyte(playerquitflag,MAXPLAYERS,0x01010101);
547
548 resetmys();
549
550 ready2send = 1;
551
552 flushpackets();
553 clearfifo();
554 waitforeverybody();
555
556 resettimevars();
557
558 return(0);
559}
560
561int saveplayer(int8_t spot)
562{
563 int32_t i, j;
564 char fn[] = "game0.sav";
565 char mpfn[] = "gameA_00.sav";
566 char *fnptr,scriptptrs[MAXSCRIPTSIZE];
567 FILE *fil;
568 int32_t bv = BYTEVERSION;
569 char fullpathsavefilename[256];
570
571 if(spot < 0)
572 {
573 multiflag = 1;
574 multiwhat = 1;
575 multipos = -spot-1;
576 return -1;
577 }
578
579 waitforeverybody();
580
581 if( multiflag == 2 && multiwho != myconnectindex )
582 {
583 fnptr = mpfn;
584 mpfn[4] = spot + 'A';
585
586 if(ud.multimode > 9)
587 {
588 mpfn[6] = (multiwho/10) + '0';
589 mpfn[7] = multiwho + '0';
590 }
591 else mpfn[7] = multiwho + '0';
592 }
593 else
594 {
595 fnptr = fn;
596 fn[4] = spot + '0';
597 }
598
599
600 // Are we loading a TC?
601 if(getGameDir()[0] != '\0')
602 {
603 // Yes
604 sprintf(fullpathsavefilename, "%s/%s", getGameDir(), fnptr);
605 }
606 else
607 {
608 // No
609 sprintf(fullpathsavefilename, "%s", fnptr);
610 }
611
612 if ((fil = fopen(fullpathsavefilename,"wb")) == 0) return(-1);
613
614 ready2send = 0;
615
616 dfwrite(&bv,4,1,fil);
617 dfwrite(&ud.multimode,sizeof(ud.multimode),1,fil);
618
619 dfwrite(&ud.savegame[spot][0],19,1,fil);
620 dfwrite(&ud.volume_number,sizeof(ud.volume_number),1,fil);
621 dfwrite(&ud.level_number,sizeof(ud.level_number),1,fil);
622 dfwrite(&ud.player_skill,sizeof(ud.player_skill),1,fil);
623 dfwrite(tiles[MAXTILES-1].data,160,100,fil);
624
625 dfwrite(&numwalls,2,1,fil);
626 dfwrite(&wall[0],sizeof(walltype),MAXWALLS,fil);
627 dfwrite(&numsectors,2,1,fil);
628 dfwrite(&sector[0],sizeof(sectortype),MAXSECTORS,fil);
629 dfwrite(&sprite[0],sizeof(spritetype),MAXSPRITES,fil);
630 dfwrite(&headspritesect[0],2,MAXSECTORS+1,fil);
631 dfwrite(&prevspritesect[0],2,MAXSPRITES,fil);
632 dfwrite(&nextspritesect[0],2,MAXSPRITES,fil);
633 dfwrite(&headspritestat[0],2,MAXSTATUS+1,fil);
634 dfwrite(&prevspritestat[0],2,MAXSPRITES,fil);
635 dfwrite(&nextspritestat[0],2,MAXSPRITES,fil);
636 dfwrite(&numcyclers,sizeof(numcyclers),1,fil);
637 dfwrite(&cyclers[0][0],12,MAXCYCLERS,fil);
638 dfwrite(ps,sizeof(ps),1,fil);
639 dfwrite(po,sizeof(po),1,fil);
640 dfwrite(&numanimwalls,sizeof(numanimwalls),1,fil);
641 dfwrite(&animwall,sizeof(animwall),1,fil);
642 dfwrite(&msx[0],sizeof(int32_t),sizeof(msx)/sizeof(int32_t),fil);
643 dfwrite(&msy[0],sizeof(int32_t),sizeof(msy)/sizeof(int32_t),fil);
644 dfwrite(&spriteqloc,sizeof(short),1,fil);
645 dfwrite(&spriteqamount,sizeof(short),1,fil);
646 dfwrite(&spriteq[0],sizeof(short),spriteqamount,fil);
647 dfwrite(&mirrorcnt,sizeof(short),1,fil);
648 dfwrite(&mirrorwall[0],sizeof(short),64,fil);
649 dfwrite(&mirrorsector[0],sizeof(short),64,fil);
650 dfwrite(&show2dsector[0],sizeof(uint8_t ),MAXSECTORS>>3,fil);
651 dfwrite(&actortype[0],sizeof(uint8_t ),MAXTILES,fil);
652 dfwrite(&boardfilename[0],sizeof(boardfilename),1,fil);
653
654 dfwrite(&numclouds,sizeof(numclouds),1,fil);
655 dfwrite(&clouds[0],sizeof(short)<<7,1,fil);
656 dfwrite(&cloudx[0],sizeof(short)<<7,1,fil);
657 dfwrite(&cloudy[0],sizeof(short)<<7,1,fil);
658
659 for(i=0;i<MAXSCRIPTSIZE;i++)
660 {
661 if( (int32_t)script[i] >= (int32_t)(&script[0]) && (int32_t)script[i] < (int32_t)(&script[MAXSCRIPTSIZE]) )
662 {
663 scriptptrs[i] = 1;
664 j = (int32_t)script[i] - (int32_t)&script[0];
665 script[i] = j;
666 }
667 else scriptptrs[i] = 0;
668 }
669
670 dfwrite(&scriptptrs[0],1,MAXSCRIPTSIZE,fil);
671 dfwrite(&script[0],4,MAXSCRIPTSIZE,fil);
672
673 for(i=0;i<MAXSCRIPTSIZE;i++)
674 if( scriptptrs[i] )
675 {
676 j = script[i]+(int32_t)&script[0];
677 script[i] = j;
678 }
679
680 for(i=0;i<MAXTILES;i++)
681 if(actorscrptr[i])
682 {
683 j = (int32_t)actorscrptr[i]-(int32_t)&script[0];
684 actorscrptr[i] = (int32_t *)j;
685 }
686 dfwrite(&actorscrptr[0],4,MAXTILES,fil);
687 for(i=0;i<MAXTILES;i++)
688 if(actorscrptr[i])
689 {
690 j = (int32_t)actorscrptr[i]+(int32_t)&script[0];
691 actorscrptr[i] = (int32_t *)j;
692 }
693
694 for(i=0;i<MAXSPRITES;i++)
695 {
696 scriptptrs[i] = 0;
697
698 if(actorscrptr[PN] == 0) continue;
699
700 j = (int32_t)&script[0];
701
702 if(T2 >= j && T2 < (int32_t)(&script[MAXSCRIPTSIZE]) )
703 {
704 scriptptrs[i] |= 1;
705 T2 -= j;
706 }
707 if(T5 >= j && T5 < (int32_t)(&script[MAXSCRIPTSIZE]) )
708 {
709 scriptptrs[i] |= 2;
710 T5 -= j;
711 }
712 if(T6 >= j && T6 < (int32_t)(&script[MAXSCRIPTSIZE]) )
713 {
714 scriptptrs[i] |= 4;
715 T6 -= j;
716 }
717 }
718
719 dfwrite(&scriptptrs[0],1,MAXSPRITES,fil);
720 dfwrite(&hittype[0],sizeof(struct weaponhit),MAXSPRITES,fil);
721
722 for(i=0;i<MAXSPRITES;i++)
723 {
724 if(actorscrptr[PN] == 0) continue;
725 j = (int32_t)&script[0];
726
727 if(scriptptrs[i]&1)
728 T2 += j;
729 if(scriptptrs[i]&2)
730 T5 += j;
731 if(scriptptrs[i]&4)
732 T6 += j;
733 }
734
735 dfwrite(&lockclock,sizeof(lockclock),1,fil);
736 dfwrite(&pskybits,sizeof(pskybits),1,fil);
737 dfwrite(&pskyoff[0],sizeof(pskyoff[0]),MAXPSKYTILES,fil);
738 dfwrite(&animatecnt,sizeof(animatecnt),1,fil);
739 dfwrite(&animatesect[0],2,MAXANIMATES,fil);
740 for(i = animatecnt-1;i>=0;i--) animateptr[i] = (int32_t *)((int32_t)animateptr[i]-(int32_t)(&sector[0]));
741 dfwrite(&animateptr[0],4,MAXANIMATES,fil);
742 for(i = animatecnt-1;i>=0;i--) animateptr[i] = (int32_t *)((int32_t)animateptr[i]+(int32_t)(&sector[0]));
743 dfwrite(&animategoal[0],4,MAXANIMATES,fil);
744 dfwrite(&animatevel[0],4,MAXANIMATES,fil);
745
746 dfwrite(&earthquaketime,sizeof(earthquaketime),1,fil);
747 dfwrite(&ud.from_bonus,sizeof(ud.from_bonus),1,fil);
748 dfwrite(&ud.secretlevel,sizeof(ud.secretlevel),1,fil);
749 dfwrite(&ud.respawn_monsters,sizeof(ud.respawn_monsters),1,fil);
750 dfwrite(&ud.respawn_items,sizeof(ud.respawn_items),1,fil);
751 dfwrite(&ud.respawn_inventory,sizeof(ud.respawn_inventory),1,fil);
752 dfwrite(&ud.god,sizeof(ud.god),1,fil);
753 dfwrite(&ud.auto_run,sizeof(ud.auto_run),1,fil);
754 dfwrite(&ud.crosshair,sizeof(ud.crosshair),1,fil);
755 dfwrite(&ud.monsters_off,sizeof(ud.monsters_off),1,fil);
756 dfwrite(&ud.last_level,sizeof(ud.last_level),1,fil);
757 dfwrite(&ud.eog,sizeof(ud.eog),1,fil);
758 dfwrite(&ud.coop,sizeof(ud.coop),1,fil);
759 dfwrite(&ud.marker,sizeof(ud.marker),1,fil);
760 dfwrite(&ud.ffire,sizeof(ud.ffire),1,fil);
761 dfwrite(&camsprite,sizeof(camsprite),1,fil);
762 dfwrite(&connecthead,sizeof(connecthead),1,fil);
763 dfwrite(connectpoint2,sizeof(connectpoint2),1,fil);
764 dfwrite(&numplayersprites,sizeof(numplayersprites),1,fil);
765 dfwrite((short *)&frags[0][0],sizeof(frags),1,fil);
766
767 dfwrite(&randomseed,sizeof(randomseed),1,fil);
768 dfwrite(&global_random,sizeof(global_random),1,fil);
769 dfwrite(&parallaxyscale,sizeof(parallaxyscale),1,fil);
770
771 fclose(fil);
772
773 if(ud.multimode < 2)
774 {
775 strcpy(fta_quotes[122],"GAME SAVED");
776 FTA(122,&ps[myconnectindex],1);
777 }
778
779 ready2send = 1;
780
781 waitforeverybody();
782
783 ototalclock = totalclock;
784
785 return(0);
786}
787
788#define LMB (buttonstat&1)
789#define RMB (buttonstat&2)
790
791// FIX_00036: Mouse wheel can now be used in menu
792#define WHEELUP (buttonstat&8)
793#define WHEELDOWN (buttonstat&16)
794
795ControlInfo minfo;
796
797int probe(int x,int y,int i,int n)
798{
799 return( probeXduke(x, y, i, n, 65536L) );
800}
801
802int probeXduke(int x,int y,int i,int n, int32_t spriteSize)
803{
804 short centre;
805 int32 mouseSens;
806
807 static int32_t delay_counter_up = 0, delay_counter_down = 0, delay_up = 50, delay_down = 50;
808 static int32_t mi = 0;
809
810 // FIX_00075: Bad Sensitivity aint32_t Y axis when using mouse in menu (Thanks to Turrican)
811 mouseSens = CONTROL_GetMouseSensitivity_Y();
812 mouseSens = mouseSens ? mouseSens : 1;
813
814 if( ((ControllerType == controltype_keyboardandmouse)||
815 (ControllerType == controltype_joystickandmouse)) )
816 //&& CONTROL_MousePresent )
817 {
818 memset(&minfo, 0, sizeof(ControlInfo));
819
820 CONTROL_GetInput( &minfo );
821 //mouseY = CONTROL_GetMouseY();
822 //mi = mouseY;
823 mi += minfo.dz / mouseSens;
824 mi += minfo.dpitch / mouseSens;
825 }
826
827 else minfo.dz = minfo.dyaw = 0;
828
829 if( x == (320>>1) )
830 centre = 320>>2;
831 else centre = 0;
832
833 if( KB_KeyPressed( sc_UpArrow ) || KB_KeyPressed( sc_PgUp ) || KB_KeyPressed( sc_kpad_8 ) ||
834 (mi < -1024) || WHEELUP)
835 {
836 // FIX_00060: Repeat key function was not working in the menu
837 if(delay_counter_up==0 || (totalclock-delay_counter_up)>delay_up || (mi < -1024) || WHEELUP)
838 {
839 mi = 0;
840 sound(KICK_HIT);
841
842 probey--;
843 if(probey < 0) probey = n-1;
844 minfo.dz = 0;
845 minfo.dpitch = 0;
846 if (delay_counter_up && (totalclock-delay_counter_up)>delay_up)
847 delay_up = 10;
848 delay_counter_up = totalclock;
849 }
850 }
851 else
852 {
853 KB_ClearKeyDown( sc_UpArrow );
854 KB_ClearKeyDown( sc_kpad_8 );
855 KB_ClearKeyDown( sc_PgUp );
856 delay_counter_up = 0;
857 delay_up = 50;
858 }
859
860 if( KB_KeyPressed( sc_DownArrow ) || KB_KeyPressed( sc_PgDn ) || KB_KeyPressed( sc_kpad_2 )
861 || (mi > 1024) || WHEELDOWN )
862 {
863 if(delay_counter_down==0 || (totalclock-delay_counter_down)>delay_down || (mi > 1024) || WHEELDOWN)
864 {
865 mi = 0;
866 sound(KICK_HIT);
867 probey++;
868 minfo.dz = 0;
869 minfo.dpitch = 0;
870 if (delay_counter_down && (totalclock-delay_counter_down)>delay_down)
871 delay_down = 10;
872 delay_counter_down = totalclock;
873 }
874 }
875 else
876 {
877 KB_ClearKeyDown( sc_DownArrow );
878 KB_ClearKeyDown( sc_kpad_2 );
879 KB_ClearKeyDown( sc_PgDn );
880 delay_counter_down = 0;
881 delay_down = 50;
882 }
883
884 if(probey >= n)
885 probey = 0;
886
887 if(centre)
888 {
889// rotatesprite(((320>>1)+(centre)+54)<<16,(y+(probey*i)-4)<<16,65536L,0,SPINNINGNUKEICON+6-((6+(totalclock>>3))%7),sh,0,10,0,0,xdim-1,ydim-1);
890// rotatesprite(((320>>1)-(centre)-54)<<16,(y+(probey*i)-4)<<16,65536L,0,SPINNINGNUKEICON+((totalclock>>3)%7),sh,0,10,0,0,xdim-1,ydim-1);
891
892 rotatesprite(((320>>1)+(centre>>1)+70)<<16,(y+(probey*i)-4)<<16,spriteSize,0,SPINNINGNUKEICON+6-((6+(totalclock>>3))%7),sh,0,10,0,0,xdim-1,ydim-1);
893 rotatesprite(((320>>1)-(centre>>1)-70)<<16,(y+(probey*i)-4)<<16,spriteSize,0,SPINNINGNUKEICON+((totalclock>>3)%7),sh,0,10,0,0,xdim-1,ydim-1);
894 }
895 else
896 rotatesprite((x-tiles[BIGFNTCURSOR].dim.width-4)<<16,(y+(probey*i)-4)<<16,spriteSize,0,SPINNINGNUKEICON+(((totalclock>>3))%7),sh,0,10,0,0,xdim-1,ydim-1);
897
898 if( KB_KeyPressed(sc_Space) || KB_KeyPressed( sc_kpad_Enter ) || KB_KeyPressed( sc_Enter ) || (LMB))// && !onbar) )
899 {
900 if(current_menu != 110)
901 sound(PISTOL_BODYHIT);
902 KB_ClearKeyDown( sc_Enter );
903 KB_ClearKeyDown( sc_Space );
904 KB_ClearKeyDown( sc_kpad_Enter );
905 return(probey);
906 }
907 else if( KB_KeyPressed( sc_Escape ) || (RMB) )
908 {
909 onbar = 0;
910 KB_ClearKeyDown( sc_Escape );
911 sound(EXITMENUSOUND);
912 return(-1);
913 }
914 else
915 {
916 if(onbar == 0) return(-probey-2);
917 if ( KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || ((buttonstat&1) && minfo.dyaw < -128 ) )
918 return(probey);
919 else if ( KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || ((buttonstat&1) && minfo.dyaw > 128 ) )
920 return(probey);
921 else return(-probey-2);
922 }
923}
924
925int menutext(int x,int y,short s,short p,char *t)
926{
927 short i, ac, centre;
928
929 y -= 12;
930
931 i = centre = 0;
932
933 if( x == (320>>1) )
934 {
935 while( *(t+i) )
936 {
937 if(*(t+i) == ' ')
938 {
939 centre += 5;
940 i++;
941 continue;
942 }
943 ac = 0;
944 if(*(t+i) >= '0' && *(t+i) <= '9')
945 ac = *(t+i) - '0' + BIGALPHANUM-10;
946 else if(*(t+i) >= 'a' && *(t+i) <= 'z')
947 ac = toupper(*(t+i)) - 'A' + BIGALPHANUM;
948 else if(*(t+i) >= 'A' && *(t+i) <= 'Z')
949 ac = *(t+i) - 'A' + BIGALPHANUM;
950 else switch(*(t+i))
951 {
952 case '-':
953 ac = BIGALPHANUM-11;
954 break;
955 case '.':
956 ac = BIGPERIOD;
957 break;
958 case '\'':
959 ac = BIGAPPOS;
960 break;
961 case ',':
962 ac = BIGCOMMA;
963 break;
964 case '!':
965 ac = BIGX;
966 break;
967 case '?':
968 ac = BIGQ;
969 break;
970 case ';':
971 ac = BIGSEMI;
972 break;
973 case ':':
974 ac = BIGSEMI;
975 break;
976 default:
977 centre += 5;
978 i++;
979 continue;
980 }
981
982 centre += tiles[ac].dim.width-1;
983 i++;
984 }
985 }
986
987 if(centre)
988 x = (320-centre-10)>>1;
989
990 while(*t)
991 {
992 if(*t == ' ') {x+=5;t++;continue;}
993 ac = 0;
994 if(*t >= '0' && *t <= '9')
995 ac = *t - '0' + BIGALPHANUM-10;
996 else if(*t >= 'a' && *t <= 'z')
997 ac = toupper(*t) - 'A' + BIGALPHANUM;
998 else if(*t >= 'A' && *t <= 'Z')
999 ac = *t - 'A' + BIGALPHANUM;
1000 else switch(*t)
1001 {
1002 case '-':
1003 ac = BIGALPHANUM-11;
1004 break;
1005 case '.':
1006 ac = BIGPERIOD;
1007 break;
1008 case ',':
1009 ac = BIGCOMMA;
1010 break;
1011 case '!':
1012 ac = BIGX;
1013 break;
1014 case '\'':
1015 ac = BIGAPPOS;
1016 break;
1017 case '?':
1018 ac = BIGQ;
1019 break;
1020 case ';':
1021 ac = BIGSEMI;
1022 break;
1023 case ':':
1024 ac = BIGCOLIN;
1025 break;
1026 default:
1027 x += 5;
1028 t++;
1029 continue;
1030 }
1031
1032 rotatesprite(x<<16,y<<16,65536L,0,ac,s,p,10+16,0,0,xdim-1,ydim-1);
1033
1034 x += tiles[ac].dim.width;
1035 t++;
1036 }
1037 return (x);
1038}
1039
1040int menutextc(int x,int y,short s,short p,char *t)
1041{
1042 short i, ac, centre;
1043
1044 s += 8;
1045 y -= 12;
1046
1047 i = centre = 0;
1048
1049// if( x == (320>>1) )
1050 {
1051 while( *(t+i) )
1052 {
1053 if(*(t+i) == ' ')
1054 {
1055 centre += 5;
1056 i++;
1057 continue;
1058 }
1059 ac = 0;
1060 if(*(t+i) >= '0' && *(t+i) <= '9')
1061 ac = *(t+i) - '0' + BIGALPHANUM+26+26;
1062 if(*(t+i) >= 'a' && *(t+i) <= 'z')
1063 ac = *(t+i) - 'a' + BIGALPHANUM+26;
1064 if(*(t+i) >= 'A' && *(t+i) <= 'Z')
1065 ac = *(t+i) - 'A' + BIGALPHANUM;
1066
1067 else switch(*t)
1068 {
1069 case '-':
1070 ac = BIGALPHANUM-11;
1071 break;
1072 case '.':
1073 ac = BIGPERIOD;
1074 break;
1075 case ',':
1076 ac = BIGCOMMA;
1077 break;
1078 case '!':
1079 ac = BIGX;
1080 break;
1081 case '?':
1082 ac = BIGQ;
1083 break;
1084 case ';':
1085 ac = BIGSEMI;
1086 break;
1087 case ':':
1088 ac = BIGCOLIN;
1089 break;
1090 }
1091
1092 centre += tiles[ac].dim.width-1;
1093 i++;
1094 }
1095 }
1096
1097 x -= centre>>1;
1098
1099 while(*t)
1100 {
1101 if(*t == ' ') {x+=5;t++;continue;}
1102 ac = 0;
1103 if(*t >= '0' && *t <= '9')
1104 ac = *t - '0' + BIGALPHANUM+26+26;
1105 if(*t >= 'a' && *t <= 'z')
1106 ac = *t - 'a' + BIGALPHANUM+26;
1107 if(*t >= 'A' && *t <= 'Z')
1108 ac = *t - 'A' + BIGALPHANUM;
1109 switch(*t)
1110 {
1111 case '-':
1112 ac = BIGALPHANUM-11;
1113 break;
1114 case '.':
1115 ac = BIGPERIOD;
1116 break;
1117 case ',':
1118 ac = BIGCOMMA;
1119 break;
1120 case '!':
1121 ac = BIGX;
1122 break;
1123 case '?':
1124 ac = BIGQ;
1125 break;
1126 case ';':
1127 ac = BIGSEMI;
1128 break;
1129 case ':':
1130 ac = BIGCOLIN;
1131 break;
1132 }
1133
1134 rotatesprite(x<<16,y<<16,65536L,0,ac,s,p,10+16,0,0,xdim-1,ydim-1);
1135
1136 x += tiles[ac].dim.width;
1137 t++;
1138 }
1139 return (x);
1140}
1141
1142
1143void bar(int x,int y,short *p,short dainc,uint8_t damodify,short s, short pa)
1144{
1145 short xloc;
1146 uint8_t rev;
1147
1148 if(dainc < 0) { dainc = -dainc; rev = 1; }
1149 else rev = 0;
1150 y-=2;
1151
1152 if(damodify)
1153 {
1154 if(rev == 0)
1155 {
1156 if( KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || ((buttonstat&1) && minfo.dyaw < -256 ) ) // && onbar) )
1157 {
1158 KB_ClearKeyDown( sc_LeftArrow );
1159 KB_ClearKeyDown( sc_kpad_4 );
1160
1161 *p -= dainc;
1162 if(*p < 0)
1163 *p = 0;
1164 sound(KICK_HIT);
1165 }
1166 if( KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || ((buttonstat&1) && minfo.dyaw > 256 ) )//&& onbar) )
1167 {
1168 KB_ClearKeyDown( sc_RightArrow );
1169 KB_ClearKeyDown( sc_kpad_6 );
1170
1171 *p += dainc;
1172 if(*p > 63)
1173 *p = 63;
1174 sound(KICK_HIT);
1175 }
1176 }
1177 else
1178 {
1179 if( KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || ((buttonstat&1) && minfo.dyaw > 256 ))//&& onbar ))
1180 {
1181 KB_ClearKeyDown( sc_RightArrow );
1182 KB_ClearKeyDown( sc_kpad_6 );
1183
1184 *p -= dainc;
1185 if(*p < 0)
1186 *p = 0;
1187 sound(KICK_HIT);
1188 }
1189 if( KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || ((buttonstat&1) && minfo.dyaw < -256 ))// && onbar) )
1190 {
1191 KB_ClearKeyDown( sc_LeftArrow );
1192 KB_ClearKeyDown( sc_kpad_4 );
1193
1194 *p += dainc;
1195 if(*p > 64)
1196 *p = 64;
1197 sound(KICK_HIT);
1198 }
1199 }
1200 }
1201
1202 xloc = *p;
1203
1204 rotatesprite( (x+22)<<16,(y-3)<<16,65536L,0,SLIDEBAR,s,pa,10,0,0,xdim-1,ydim-1);
1205 if(rev == 0)
1206 rotatesprite( (x+xloc+1)<<16,(y+1)<<16,65536L,0,SLIDEBAR+1,s,pa,10,0,0,xdim-1,ydim-1);
1207 else
1208 rotatesprite( (x+(65-xloc) )<<16,(y+1)<<16,65536L,0,SLIDEBAR+1,s,pa,10,0,0,xdim-1,ydim-1);
1209}
1210
1211#define SHX(X) 0
1212// ((x==X)*(-sh))
1213#define PHX(X) 0
1214// ((x==X)?1:2)
1215#define MWIN(X) rotatesprite( 320<<15,200<<15,X,0,MENUSCREEN,-16,0,10+64,0,0,xdim-1,ydim-1)
1216#define MWINXY(X,OX,OY) rotatesprite( ( 320+(OX) )<<15, ( 200+(OY) )<<15,X,0,MENUSCREEN,-16,0,10+64,0,0,xdim-1,ydim-1)
1217
1218
1219int32 volnum,levnum,plrskl,numplr;
1220short lastsavedpos = -1;
1221
1222void dispnames(void)
1223{
1224 short x, c = 160;
1225
1226 c += 64;
1227 for(x = 0;x <= 108;x += 12)
1228 rotatesprite((c+91-64)<<16,(x+56)<<16,65536L,0,TEXTBOX,24,0,10,0,0,xdim-1,ydim-1);
1229
1230 rotatesprite(22<<16,97<<16,65536L,0,WINDOWBORDER2,24,0,10,0,0,xdim-1,ydim-1);
1231 rotatesprite(180<<16,97<<16,65536L,1024,WINDOWBORDER2,24,0,10,0,0,xdim-1,ydim-1);
1232 rotatesprite(99<<16,50<<16,65536L,512,WINDOWBORDER1,24,0,10,0,0,xdim-1,ydim-1);
1233 rotatesprite(103<<16,144<<16,65536L,1024+512,WINDOWBORDER1,24,0,10,0,0,xdim-1,ydim-1);
1234
1235 minitext(c,48,ud.savegame[0],2,10+16);
1236 minitext(c,48+12,ud.savegame[1],2,10+16);
1237 minitext(c,48+12+12,ud.savegame[2],2,10+16);
1238 minitext(c,48+12+12+12,ud.savegame[3],2,10+16);
1239 minitext(c,48+12+12+12+12,ud.savegame[4],2,10+16);
1240 minitext(c,48+12+12+12+12+12,ud.savegame[5],2,10+16);
1241 minitext(c,48+12+12+12+12+12+12,ud.savegame[6],2,10+16);
1242 minitext(c,48+12+12+12+12+12+12+12,ud.savegame[7],2,10+16);
1243 minitext(c,48+12+12+12+12+12+12+12+12,ud.savegame[8],2,10+16);
1244 minitext(c,48+12+12+12+12+12+12+12+12+12,ud.savegame[9],2,10+16);
1245
1246}
1247
1248
1249// This is the same thing as was in build.c ...
1250// We DO have a _dos_findfirst implementation now...maybe use that instead?
1251// --ryan.
1252#if ORIGINAL_DUKE3D_GETFILENAMES
1253int getfilenames(uint8_t kind[6])
1254{
1255 short type;
1256 struct find_t fileinfo;
1257
1258 if (strcmp(kind,"SUBD") == 0)
1259 {
1260 strcpy(kind,"*.*");
1261 if (_dos_findfirst(kind,_A_SUBDIR,&fileinfo) != 0)
1262 return(-1);
1263 type = 1;
1264 }
1265 else
1266 {
1267 if (_dos_findfirst(kind,_A_NORMAL,&fileinfo) != 0)
1268 return(-1);
1269 type = 0;
1270 }
1271 do
1272 {
1273 if ((type == 0) || ((fileinfo.attrib&16) > 0))
1274 if ((fileinfo.name[0] != '.') || (fileinfo.name[1] != 0))
1275 {
1276 strcpy(menuname[menunamecnt],fileinfo.name);
1277 menuname[menunamecnt][16] = type;
1278 menunamecnt++;
1279 }
1280 }
1281 while (_dos_findnext(&fileinfo) == 0);
1282
1283 return(0);
1284}
1285
1286#else
1287
1288int getfilenames(char kind[6])
1289{
1290/* !!! FIXME: Visual C? */
1291#if (defined __WATCOMC__)
1292 short type;
1293 struct find_t fileinfo;
1294
1295 if (strcmp(kind,"SUBD") == 0)
1296 {
1297 strcpy(kind,"*.*");
1298 if (_dos_findfirst(kind,_A_SUBDIR,&fileinfo) != 0)
1299 return(-1);
1300 type = 1;
1301 }
1302 else
1303 {
1304 if (_dos_findfirst(kind,_A_NORMAL,&fileinfo) != 0)
1305 return(-1);
1306 type = 0;
1307 }
1308 do
1309 {
1310 if ((type == 0) || ((fileinfo.attrib&16) > 0))
1311 if ((fileinfo.name[0] != '.') || (fileinfo.name[1] != 0))
1312 {
1313 strcpy(menuname[menunamecnt],fileinfo.name);
1314 menuname[menunamecnt][16] = type;
1315 menunamecnt++;
1316 }
1317 }
1318 while (_dos_findnext(&fileinfo) == 0);
1319
1320#elif (defined PLATFORM_UNIX)
1321
1322 DIR *dir;
1323 struct dirent *dent;
1324 struct stat statbuf;
1325 int add_this;
1326 uint8_t *ptr = NULL;
1327 int len = 0;
1328 int subdirs = 0;
1329
1330 if (strcmp(kind,"SUBD") == 0)
1331 subdirs = 1;
1332
1333 dir = opendir(getGamedir());
1334 if (dir == NULL)
1335 return(-1);
1336
1337 do
1338 {
1339 add_this = 0;
1340 dent = readdir(dir);
1341 if (dent != NULL)
1342 {
1343 if (stat(dent->d_name, &statbuf) == 0)
1344 {
1345 if (subdirs)
1346 {
1347 if (S_ISDIR(statbuf.st_mode))
1348 add_this = 1;
1349 } /* if */
1350 else
1351 {
1352 /* need to expand support if this assertion ever fails. */
1353 assert(stricmp(kind, "*.MAP") == 0);
1354 len = strlen(dent->d_name);
1355 if (len >= 5)
1356 {
1357 ptr = ((uint8_t *) dent->d_name) + len;
1358 ptr += strlen(ptr) - 4;
1359 if (stricmp(ptr, ".MAP") == 0)
1360 add_this = 1;
1361 } /* if */
1362 } /* else */
1363
1364 if (add_this)
1365 {
1366 strcpy(menuname[menunamecnt],dent->d_name);
1367 menuname[menunamecnt][16] = subdirs;
1368 menunamecnt++;
1369 } /* if */
1370 } /* if */
1371 } /* if */
1372 } while (dent != NULL);
1373
1374 closedir(dir);
1375
1376#endif
1377 return(0);
1378}
1379
1380#endif
1381
1382
1383void sortfilenames()
1384{
1385 uint8_t sortbuffer[17];
1386 int32_t i, j, k;
1387
1388 for(i=1;i<menunamecnt;i++)
1389 for(j=0;j<i;j++)
1390 {
1391 k = 0;
1392 while ((menuname[i][k] == menuname[j][k]) && (menuname[i][k] != 0) && (menuname[j][k] != 0))
1393 k++;
1394 if (menuname[i][k] < menuname[j][k])
1395 {
1396 memcpy(&sortbuffer[0],&menuname[i][0],sizeof(menuname[0]));
1397 memcpy(&menuname[i][0],&menuname[j][0],sizeof(menuname[0]));
1398 memcpy(&menuname[j][0],&sortbuffer[0],sizeof(menuname[0]));
1399 }
1400 }
1401}
1402
1403int32_t quittimer = 0;
1404
1405void gameexitanycase(void)
1406{
1407 KB_FlushKeyboardQueue();
1408
1409 if( gamequit == 0 && ( numplayers > 1 ) )
1410 {
1411 if(ps[myconnectindex].gm&MODE_GAME)
1412 {
1413 gamequit = 1;
1414 quittimer = totalclock+120;
1415 sound(SHORT_CIRCUIT);
1416 }
1417 else
1418 {
1419 sendlogoff();
1420 gameexit(" ");
1421 sound(NITEVISION_ONOFF);
1422 }
1423 }
1424 else if( numplayers < 2 )
1425 gameexit(" ");
1426
1427 if( ( totalclock > quittimer ) && ( gamequit == 1) )
1428 {
1429 gameexit("Timed out.");
1430 }
1431}
1432
1433
1434void menus(void)
1435{
1436 short c,x;
1437 volatile int32_t l;
1438 int i,j;
1439
1440 static int lastkeysetup = 0;
1441 static int waiting4key = false;
1442 static int current_resolution = 0;
1443 char text[512];
1444
1445 getpackets();
1446
1447 if(((ControllerType == controltype_keyboardandmouse)||
1448 (ControllerType == controltype_joystickandmouse))
1449 //&& CONTROL_MousePresent
1450 )
1451 {
1452
1453 if(buttonstat != 0 && !onbar) // anti-repeat
1454 {
1455 x = MOUSE_GetButtons()<<3;
1456 if( x )
1457 {
1458 buttonstat = x<<3;
1459 }
1460 else
1461 {
1462 buttonstat = 0;
1463 }
1464 }
1465 else
1466
1467 buttonstat = MOUSE_GetButtons();
1468 }
1469 else buttonstat = 0;
1470
1471 if( (ps[myconnectindex].gm&MODE_MENU) == 0 )
1472 {
1473 tiles[MAXTILES-3].lock = 1;
1474 return;
1475 }
1476
1477 ps[myconnectindex].gm &= (0xff-MODE_TYPE);
1478 ps[myconnectindex].fta = 0;
1479
1480 x = 0;
1481
1482 sh = 4-(sintable[(totalclock<<4)&2047]>>11);
1483
1484 if(!(current_menu >= 1000 && current_menu <= 2999 && current_menu >= 300 && current_menu <= 369))
1485 vscrn();
1486
1487 // printf("Current menu=%d, game mode=%d, last menu =%d\n", current_menu, ps[myconnectindex].gm, last_menu);
1488
1489 switch(current_menu)
1490 {
1491 case 25000:
1492 gametext(160,90,"SELECT A SAVE SPOT BEFORE",0,2+8+16);
1493 gametext(160,90+9,"YOU QUICK RESTORE.",0,2+8+16);
1494
1495 x = probe(186,124,0,0);
1496 if(x >= -1)
1497 {
1498 if(ud.multimode < 2 && ud.recstat != 2)
1499 {
1500 ready2send = 1;
1501 totalclock = ototalclock;
1502 }
1503 ps[myconnectindex].gm &= ~MODE_MENU;
1504 }
1505 break;
1506
1507 case 20000:
1508 x = probe(326,190,0,0);
1509 gametext(160,50-8,"YOU ARE PLAYING THE SHAREWARE",0,2+8+16);
1510 gametext(160,59-8,"VERSION OF DUKE NUKEM 3D. WHILE",0,2+8+16);
1511 gametext(160,68-8,"THIS VERSION IS REALLY COOL, YOU",0,2+8+16);
1512 gametext(160,77-8,"ARE MISSING OVER 75% OF THE TOTAL",0,2+8+16);
1513 gametext(160,86-8,"GAME, ALONG WITH OTHER GREAT EXTRAS",0,2+8+16);
1514 gametext(160,95-8,"AND GAMES, WHICH YOU'LL GET WHEN",0,2+8+16);
1515 gametext(160,104-8,"YOU ORDER THE COMPLETE VERSION AND",0,2+8+16);
1516 gametext(160,113-8,"GET THE FINAL TWO EPISODES.",0,2+8+16);
1517
1518 gametext(160,113+8,"PLEASE READ THE 'HOW TO ORDER' ITEM",0,2+8+16);
1519 gametext(160,122+8,"ON THE MAIN MENU IF YOU WISH TO",0,2+8+16);
1520 gametext(160,131+8,"UPGRADE TO THE FULL REGISTERED",0,2+8+16);
1521 gametext(160,140+8,"VERSION OF DUKE NUKEM 3D.",0,2+8+16);
1522 gametext(160,149+16,"PRESS ANY KEY...",0,2+8+16);
1523
1524 if( x >= -1 ) cmenu(100);
1525 break;
1526
1527
1528 case 15001:
1529 case 15000:
1530
1531 gametext(160,90,"LOAD last game:",0,2+8+16);
1532
1533 sprintf(text,"\"%s\"",ud.savegame[lastsavedpos]);
1534 gametext(160,99,text,0,2+8+16);
1535
1536 gametext(160,99+9,"(Y/N)",0,2+8+16);
1537
1538 _handle_events();
1539 if( KB_KeyPressed(sc_Escape) || KB_KeyPressed(sc_N) || RMB)
1540 {
1541 if(sprite[ps[myconnectindex].i].extra <= 0)
1542 {
1543 enterlevel(MODE_GAME);
1544 return;
1545 }
1546
1547 KB_ClearKeyDown(sc_N);
1548 KB_ClearKeyDown(sc_Escape);
1549
1550 ps[myconnectindex].gm &= ~MODE_MENU;
1551 if(ud.multimode < 2 && ud.recstat != 2)
1552 {
1553 ready2send = 1;
1554 totalclock = ototalclock;
1555 }
1556 }
1557
1558 if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB )
1559 {
1560 KB_FlushKeyboardQueue();
1561 FX_StopAllSounds();
1562
1563 if(ud.multimode > 1)
1564 {
1565 loadplayer(-1-lastsavedpos);
1566 ps[myconnectindex].gm = MODE_GAME;
1567 }
1568 else
1569 {
1570 c = loadplayer(lastsavedpos);
1571 if(c == 0)
1572 ps[myconnectindex].gm = MODE_GAME;
1573 }
1574 }
1575
1576 probe(186,124+9,0,0);
1577
1578 break;
1579
1580 case 10000: // parental
1581 case 10001:
1582
1583 c = (320>>1)-120;
1584 rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
1585 menutext(320>>1,24,0,0,"ADULT MODE");
1586
1587 x = probe(c+6,43,16,2);
1588
1589 if(x == -1)
1590 {
1591 cmenu(702);
1592 probey = 6;
1593 break;
1594 }
1595
1596 menutext(c,43,SHX(-2),PHX(-2),"ADULT MODE");
1597 menutext(c+160+40,43,0,0,ud.lockout?"OFF":"ON");
1598
1599 menutext(c,43+16,SHX(-3),PHX(-3),"ENTER PASSWORD");
1600
1601 if(current_menu == 10001)
1602 {
1603 gametext(160,43+16+16+16-12,"ENTER PASSWORD",0,2+8+16);
1604 x = strget((320>>1),43+16+16+16,buf,19, 998);
1605
1606 if(x == 1) // user hit enter key
1607 {
1608 if(ud.pwlockout[0] == 0 || ud.lockout == 0 ) // if already unlocked then we set pwd or reset pwd is there is already one
1609 strcpy(&ud.pwlockout[0],buf);
1610 else if( strcmp(buf,&ud.pwlockout[0]) == 0 ) // if (pwd was up AND lockout is true (locked) AND pwd is good)
1611 {
1612 ud.lockout = 0;
1613 buf[0] = 0;
1614
1615 for(x=0;x<numanimwalls;x++)
1616 if( wall[animwall[x].wallnum].picnum != W_SCREENBREAK &&
1617 wall[animwall[x].wallnum].picnum != W_SCREENBREAK+1 &&
1618 wall[animwall[x].wallnum].picnum != W_SCREENBREAK+2 )
1619 if( wall[animwall[x].wallnum].extra >= 0 )
1620 wall[animwall[x].wallnum].picnum = wall[animwall[x].wallnum].extra;
1621
1622 }
1623 current_menu = 10000;
1624 KB_ClearKeyDown(sc_Enter);
1625 KB_ClearKeyDown(sc_kpad_Enter);
1626 KB_FlushKeyboardQueue();
1627 }
1628 else if(x==-1) // pressed esc while typing. We discard the text.
1629 {
1630 *buf = 0;
1631 current_menu = 10000;
1632 KB_ClearKeyDown(sc_Escape);
1633 }
1634 }
1635 else
1636 {
1637 if(x == 0)
1638 {
1639 if( ud.lockout == 1 )
1640 {
1641 if(ud.pwlockout[0] == 0)
1642 {
1643 ud.lockout = 0;
1644 for(x=0;x<numanimwalls;x++)
1645 if( wall[animwall[x].wallnum].picnum != W_SCREENBREAK &&
1646 wall[animwall[x].wallnum].picnum != W_SCREENBREAK+1 &&
1647 wall[animwall[x].wallnum].picnum != W_SCREENBREAK+2 )
1648 if( wall[animwall[x].wallnum].extra >= 0 )
1649 wall[animwall[x].wallnum].picnum = wall[animwall[x].wallnum].extra;
1650 }
1651 else
1652 {
1653 buf[0] = 0;
1654 current_menu = 10001;
1655 inputloc = 0;
1656 KB_FlushKeyboardQueue();
1657 }
1658 }
1659 else
1660 {
1661 ud.lockout = 1;
1662
1663 for(x=0;x<numanimwalls;x++)
1664 switch(wall[animwall[x].wallnum].picnum)
1665 {
1666 case FEMPIC1:
1667 wall[animwall[x].wallnum].picnum = BLANKSCREEN;
1668 break;
1669 case FEMPIC2:
1670 case FEMPIC3:
1671 wall[animwall[x].wallnum].picnum = SCREENBREAK6;
1672 break;
1673 }
1674 }
1675 }
1676
1677 else if(x == 1)
1678 {
1679 current_menu = 10001; // ask for password change
1680 inputloc = 0;
1681 *buf = 0;
1682 KB_FlushKeyboardQueue();
1683 }
1684 }
1685
1686 break;
1687
1688 case 1000:
1689 case 1001:
1690 case 1002:
1691 case 1003:
1692 case 1004:
1693 case 1005:
1694 case 1006:
1695 case 1007:
1696 case 1008:
1697 case 1009:
1698
1699 rotatesprite(160<<16,200<<15,65536L,0,MENUSCREEN,16,0,10+64,0,0,xdim-1,ydim-1);
1700 rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
1701 menutext(160,24,0,0,"LOAD GAME");
1702 rotatesprite(101<<16,97<<16,65536,512,MAXTILES-3,-32,0,4+10+64,0,0,xdim-1,ydim-1);
1703
1704 dispnames();
1705
1706 sprintf((char*)tempbuf,"PLAYERS: %-2d ",numplr);
1707 gametext(160,158,(char*)tempbuf,0,2+8+16);
1708
1709 sprintf((char*)tempbuf,"EPISODE: %-2d / LEVEL: %-2d / SKILL: %-2d",1+volnum,1+levnum,plrskl);
1710 gametext(160,170,(char*)tempbuf,0,2+8+16);
1711
1712 gametext(160,90,"LOAD game:",0,2+8+16);
1713 sprintf((char*)tempbuf,"\"%s\"",ud.savegame[current_menu-1000]);
1714 gametext(160,99,(char*)tempbuf,0,2+8+16);
1715 gametext(160,99+9,"(Y/N)",0,2+8+16);
1716
1717 _handle_events();
1718 if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB )
1719 {
1720 lastsavedpos = current_menu-1000;
1721
1722 KB_FlushKeyboardQueue();
1723 //if(ud.multimode < 2 && ud.recstat != 2)
1724 //{
1725 // ready2send = 1;
1726 // totalclock = ototalclock;
1727 //}
1728
1729 if(ud.multimode > 1)
1730 {
1731 if( ps[myconnectindex].gm&MODE_GAME )
1732 {
1733 loadplayer(-1-lastsavedpos);
1734 ps[myconnectindex].gm = MODE_GAME;
1735 }
1736 else
1737 {
1738 tempbuf[0] = 126;
1739 tempbuf[1] = lastsavedpos;
1740 for(x=connecthead;x>=0;x=connectpoint2[x])
1741 if(x != myconnectindex)
1742 sendpacket(x,(uint8_t*)tempbuf,2);
1743
1744 getpackets();
1745
1746 loadplayer(lastsavedpos);
1747
1748 multiflag = 0;
1749 }
1750 }
1751 else
1752 {
1753 // FIX_00084: Various bugs in the load game (single player) option if ESC is hit or if wrong version
1754
1755 c = loadplayer(lastsavedpos);
1756 if(c == 0)
1757 {
1758 ps[myconnectindex].gm = MODE_GAME;
1759 if (ud.recstat != 2) // if not playing a demo then ..
1760 totalclock = ototalclock;
1761 }
1762 else
1763 cmenu(1010); // failed loading game
1764 }
1765
1766 break;
1767 }
1768
1769 if( KB_KeyPressed(sc_N) || KB_KeyPressed(sc_Escape) || RMB)
1770 {
1771 KB_ClearKeyDown(sc_N);
1772 KB_ClearKeyDown(sc_Escape);
1773 sound(EXITMENUSOUND);
1774 cmenu(300);
1775 // FIX_00084: Various bugs in the load game (single player) option if ESC is hit or if wrong version
1776 // simply get back w/o changing anything.
1777
1778 }
1779
1780 break;
1781
1782 case 1010: //loading a saved game failed
1783
1784 gametext(160,99,"YOU CAN'T LOAD THIS GAME",0,2+8+16);
1785 gametext(160,99+9,"EITHER A WONG VERSION",0,2+8+16);
1786 gametext(160,99+9+9,"OR BAD # OF PLAYERS OR...",0,2+8+16);
1787
1788 _handle_events();
1789 if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Escape) || KB_KeyPressed(sc_Enter)
1790 || RMB) {
1791 KB_ClearKeyDown(sc_Space);
1792 KB_ClearKeyDown(sc_Escape);
1793 KB_ClearKeyDown(sc_Enter);
1794 sound(EXITMENUSOUND);
1795 cmenu(300);
1796 }
1797
1798 break;
1799
1800 case 1500:
1801 _handle_events();
1802 if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB )
1803 {
1804 KB_FlushKeyboardQueue();
1805 cmenu(100);
1806 }
1807 if( KB_KeyPressed(sc_N) || KB_KeyPressed(sc_Escape) || RMB)
1808 {
1809 KB_ClearKeyDown(sc_N);
1810 KB_ClearKeyDown(sc_Escape);
1811 if(ud.multimode < 2 && ud.recstat != 2)
1812 {
1813 ready2send = 1;
1814 totalclock = ototalclock;
1815 }
1816 ps[myconnectindex].gm &= ~MODE_MENU;
1817 sound(EXITMENUSOUND);
1818 break;
1819 }
1820 probe(186,124,0,0);
1821 gametext(160,90,"ABORT this game?",0,2+8+16);
1822 gametext(160,90+9,"(Y/N)",0,2+8+16);
1823
1824 break;
1825
1826 case 2000:
1827 case 2001:
1828 case 2002:
1829 case 2003:
1830 case 2004:
1831 case 2005:
1832 case 2006:
1833 case 2007:
1834 case 2008:
1835 case 2009:
1836
1837 rotatesprite(160<<16,200<<15,65536L,0,MENUSCREEN,16,0,10+64,0,0,xdim-1,ydim-1);
1838 rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
1839 menutext(160,24,0,0,"SAVE GAME");
1840
1841 rotatesprite(101<<16,97<<16,65536L,512,MAXTILES-3,-32,0,4+10+64,0,0,xdim-1,ydim-1);
1842 sprintf(text,"PLAYERS: %-2d ",ud.multimode);
1843 gametext(160,158,text,0,2+8+16);
1844
1845 sprintf(text,"EPISODE: %-2d / LEVEL: %-2d / SKILL: %-2d",1+ud.volume_number,1+ud.level_number,ud.player_skill);
1846 gametext(160,170,text,0,2+8+16);
1847
1848 dispnames();
1849
1850 gametext(160,90,"OVERWRITE previous SAVED game?",0,2+8+16);
1851 gametext(160,90+9,"(Y/N)",0,2+8+16);
1852
1853 _handle_events();
1854 if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB )
1855 {
1856 KB_FlushKeyboardQueue();
1857 inputloc = strlen(&ud.savegame[current_menu-2000][0]);
1858
1859 cmenu(current_menu-2000+360);
1860
1861 KB_FlushKeyboardQueue();
1862 break;
1863 }
1864 if( KB_KeyPressed(sc_N) || KB_KeyPressed(sc_Escape) || RMB)
1865 {
1866 KB_ClearKeyDown(sc_N);
1867 KB_ClearKeyDown(sc_Escape);
1868 cmenu(351);
1869 sound(EXITMENUSOUND);
1870 }
1871
1872 probe(186,124,0,0);
1873
1874 break;
1875
1876 case 990: // credits
1877 case 991:
1878 case 992:
1879 case 993:
1880 case 994:
1881 case 995:
1882 case 996:
1883 case 997:
1884 c = 160;
1885 if (!PLUTOPAK) {
1886 //rotatesprite(c<<16,200<<15,65536L,0,MENUSCREEN,16,0,10+64,0,0,xdim-1,ydim-1);
1887 rotatesprite(c<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
1888 menutext(c,24,0,0,"CREDITS");
1889
1890 l = 7;
1891 } else {
1892 l = 2;
1893 }
1894
1895 if(KB_KeyPressed(sc_Escape)) { cmenu(0); break; }
1896
1897 if( KB_KeyPressed( sc_LeftArrow ) ||
1898 KB_KeyPressed( sc_kpad_4 ) ||
1899 KB_KeyPressed( sc_UpArrow ) ||
1900 KB_KeyPressed( sc_PgUp ) ||
1901 KB_KeyPressed( sc_kpad_8 ) )
1902 {
1903 KB_ClearKeyDown(sc_LeftArrow);
1904 KB_ClearKeyDown(sc_kpad_4);
1905 KB_ClearKeyDown(sc_UpArrow);
1906 KB_ClearKeyDown(sc_PgUp);
1907 KB_ClearKeyDown(sc_kpad_8);
1908
1909 sound(KICK_HIT);
1910 current_menu--;
1911 if(current_menu < 990) current_menu = 990+l;
1912 }
1913 else if(
1914 KB_KeyPressed( sc_PgDn ) ||
1915 KB_KeyPressed( sc_Enter ) ||
1916 KB_KeyPressed( sc_Space ) ||
1917 KB_KeyPressed( sc_kpad_Enter ) ||
1918 KB_KeyPressed( sc_RightArrow ) ||
1919 KB_KeyPressed( sc_DownArrow ) ||
1920 KB_KeyPressed( sc_kpad_2 ) ||
1921 KB_KeyPressed( sc_kpad_9 ) ||
1922 KB_KeyPressed( sc_kpad_6 ) )
1923 {
1924 KB_ClearKeyDown(sc_PgDn);
1925 KB_ClearKeyDown(sc_Enter);
1926 KB_ClearKeyDown(sc_RightArrow);
1927 KB_ClearKeyDown(sc_kpad_Enter);
1928 KB_ClearKeyDown(sc_kpad_6);
1929 KB_ClearKeyDown(sc_kpad_9);
1930 KB_ClearKeyDown(sc_kpad_2);
1931 KB_ClearKeyDown(sc_DownArrow);
1932 KB_ClearKeyDown(sc_Space);
1933 sound(KICK_HIT);
1934 current_menu++;
1935 if(current_menu > 990+l) current_menu = 990;
1936 }
1937
1938 if (!PLUTOPAK) { // This is Jonathon Fowler code. Text respects the true 1.3/1.3d --mk
1939 switch (current_menu) {
1940 case 990:
1941 gametext(c,40, "ORIGINAL CONCEPT",0,2+8+16);
1942 gametext(c,40+9, "TODD REPLOGLE",0,2+8+16);
1943 gametext(c,40+9+9, "ALLEN H. BLUM III",0,2+8+16);
1944
1945 gametext(c,40+9+9+9+9, "PRODUCED & DIRECTED BY",0,2+8+16);
1946 gametext(c,40+9+9+9+9+9, "GREG MALONE",0,2+8+16);
1947
1948 gametext(c,40+9+9+9+9+9+9+9, "EXECUTIVE PRODUCER",0,2+8+16);
1949 gametext(c,40+9+9+9+9+9+9+9+9, "GEORGE BROUSSARD",0,2+8+16);
1950
1951 gametext(c,40+9+9+9+9+9+9+9+9+9+9, "BUILD ENGINE",0,2+8+16);
1952 gametext(c,40+9+9+9+9+9+9+9+9+9+9+9,"KEN SILVERMAN",0,2+8+16);
1953 break;
1954 case 991:
1955 gametext(c,40, "GAME PROGRAMMING",0,2+8+16);
1956 gametext(c,40+9, "TODD REPLOGLE",0,2+8+16);
1957
1958 gametext(c,40+9+9+9, "3D ENGINE/TOOLS/NET",0,2+8+16);
1959 gametext(c,40+9+9+9+9, "KEN SILVERMAN",0,2+8+16);
1960
1961 gametext(c,40+9+9+9+9+9+9, "NETWORK LAYER/SETUP PROGRAM",0,2+8+16);
1962 gametext(c,40+9+9+9+9+9+9+9, "MARK DOCHTERMANN",0,2+8+16);
1963 break;
1964 case 992:
1965 gametext(c,40, "MAP DESIGN",0,2+8+16);
1966 gametext(c,40+9, "ALLEN H BLUM III",0,2+8+16);
1967 gametext(c,40+9+9, "RICHARD GRAY",0,2+8+16);
1968
1969 gametext(c,40+9+9+9+9, "3D MODELING",0,2+8+16);
1970 gametext(c,40+9+9+9+9+9, "CHUCK JONES",0,2+8+16);
1971 gametext(c,40+9+9+9+9+9+9, "SAPPHIRE CORPORATION",0,2+8+16);
1972
1973 gametext(c,40+9+9+9+9+9+9+9+9, "ARTWORK",0,2+8+16);
1974 gametext(c,40+9+9+9+9+9+9+9+9+9, "DIRK JONES, STEPHEN HORNBACK",0,2+8+16);
1975 gametext(c,40+9+9+9+9+9+9+9+9+9+9, "JAMES STOREY, DAVID DEMARET",0,2+8+16);
1976 gametext(c,40+9+9+9+9+9+9+9+9+9+9+9,"DOUGLAS R WOOD",0,2+8+16);
1977 break;
1978 case 993:
1979 gametext(c,40, "SOUND ENGINE",0,2+8+16);
1980 gametext(c,40+9, "JIM DOSE",0,2+8+16);
1981
1982 gametext(c,40+9+9+9, "SOUND & MUSIC DEVELOPMENT",0,2+8+16);
1983 gametext(c,40+9+9+9+9, "ROBERT PRINCE",0,2+8+16);
1984 gametext(c,40+9+9+9+9+9, "LEE JACKSON",0,2+8+16);
1985
1986 gametext(c,40+9+9+9+9+9+9+9, "VOICE TALENT",0,2+8+16);
1987 gametext(c,40+9+9+9+9+9+9+9+9, "LANI MINELLA - VOICE PRODUCER",0,2+8+16);
1988 gametext(c,40+9+9+9+9+9+9+9+9+9, "JON ST. JOHN AS \"DUKE NUKEM\"",0,2+8+16);
1989 break;
1990 case 994:
1991 gametext(c,60, "GRAPHIC DESIGN",0,2+8+16);
1992 gametext(c,60+9, "PACKAGING, MANUAL, ADS",0,2+8+16);
1993 gametext(c,60+9+9, "ROBERT M. ATKINS",0,2+8+16);
1994 gametext(c,60+9+9+9, "MICHAEL HADWIN",0,2+8+16);
1995
1996 gametext(c,60+9+9+9+9+9, "SPECIAL THANKS TO",0,2+8+16);
1997 gametext(c,60+9+9+9+9+9+9, "STEVEN BLACKBURN, TOM HALL",0,2+8+16);
1998 gametext(c,60+9+9+9+9+9+9+9, "SCOTT MILLER, JOE SIEGLER",0,2+8+16);
1999 gametext(c,60+9+9+9+9+9+9+9+9, "TERRY NAGY, COLLEEN COMPTON",0,2+8+16);
2000 gametext(c,60+9+9+9+9+9+9+9+9+9, "HASH INC., FORMGEN, INC.",0,2+8+16);
2001 break;
2002 case 995:
2003 gametext(c,49, "THE 3D REALMS BETA TESTERS",0,2+8+16);
2004
2005 gametext(c,49+9+9, "NATHAN ANDERSON, WAYNE BENNER",0,2+8+16);
2006 gametext(c,49+9+9+9, "GLENN BRENSINGER, ROB BROWN",0,2+8+16);
2007 gametext(c,49+9+9+9+9, "ERIK HARRIS, KEN HECKBERT",0,2+8+16);
2008 gametext(c,49+9+9+9+9+9, "TERRY HERRIN, GREG HIVELY",0,2+8+16);
2009 gametext(c,49+9+9+9+9+9+9, "HANK LEUKART, ERIC BAKER",0,2+8+16);
2010 gametext(c,49+9+9+9+9+9+9+9, "JEFF RAUSCH, KELLY ROGERS",0,2+8+16);
2011 gametext(c,49+9+9+9+9+9+9+9+9, "MIKE DUNCAN, DOUG HOWELL",0,2+8+16);
2012 gametext(c,49+9+9+9+9+9+9+9+9+9, "BILL BLAIR",0,2+8+16);
2013 break;
2014 case 996:
2015 gametext(c,32, "COMPANY PRODUCT SUPPORT",0,2+8+16);
2016
2017 gametext(c,32+9+9, "THE FOLLOWING COMPANIES WERE COOL",0,2+8+16);
2018 gametext(c,32+9+9+9, "ENOUGH TO GIVE US LOTS OF STUFF",0,2+8+16);
2019 gametext(c,32+9+9+9+9, "DURING THE MAKING OF DUKE NUKEM 3D.",0,2+8+16);
2020
2021 gametext(c,32+9+9+9+9+9+9, "ALTEC LANSING MULTIMEDIA",0,2+8+16);
2022 gametext(c,32+9+9+9+9+9+9+9, "FOR TONS OF SPEAKERS AND THE",0,2+8+16);
2023 gametext(c,32+9+9+9+9+9+9+9+9, "THX-LICENSED SOUND SYSTEM",0,2+8+16);
2024 gametext(c,32+9+9+9+9+9+9+9+9+9, "FOR INFO CALL 1-800-548-0620",0,2+8+16);
2025
2026 gametext(c,32+9+9+9+9+9+9+9+9+9+9+9,"CREATIVE LABS, INC.",0,2+8+16);
2027
2028 gametext(c,32+9+9+9+9+9+9+9+9+9+9+9+9+9,"THANKS FOR THE HARDWARE, GUYS.",0,2+8+16);
2029 break;
2030 case 997:
2031 gametext(c,50, "DUKE NUKEM IS A TRADEMARK OF",0,2+8+16);
2032 gametext(c,50+9, "3D REALMS ENTERTAINMENT",0,2+8+16);
2033
2034 gametext(c,50+9+9+9, "DUKE NUKEM",0,2+8+16);
2035 gametext(c,50+9+9+9+9, "(C) 1996 3D REALMS ENTERTAINMENT",0,2+8+16);
2036
2037 if (VOLUMEONE) {
2038 gametext(c,106, "PLEASE READ LICENSE.DOC FOR SHAREWARE",0,2+8+16);
2039 gametext(c,106+9, "DISTRIBUTION GRANTS AND RESTRICTIONS",0,2+8+16);
2040 }
2041
2042 gametext(c,VOLUMEONE?134:115, "MADE IN DALLAS, TEXAS USA",0,2+8+16);
2043 break;
2044 }
2045 }
2046
2047 switch(current_menu)
2048 {
2049 case 990:
2050 case 991:
2051 case 992:
2052 rotatesprite(160<<16,200<<15,65536L,0,2504+current_menu-990,0,0,10+64,0,0,xdim-1,ydim-1);
2053
2054 break;
2055
2056 }
2057 break;
2058
2059 case 0: // main menu
2060 c = (320>>1);
2061 rotatesprite(c<<16,28<<16,65536L,0,INGAMEDUKETHREEDEE,0,0,10,0,0,xdim-1,ydim-1);
2062 rotatesprite((c+100)<<16,36<<16,65536L,0,PLUTOPAKSPRITE+2,(sintable[(totalclock<<4)&2047]>>11),0,2+8,0,0,xdim-1,ydim-1);
2063
2064 x = probe(c,67,16,6);
2065
2066 if(x >= 0)
2067 {
2068 if( ud.multimode > 1 && x == 0 && ud.recstat != 2)
2069 {
2070 if( movesperpacket == 4 && myconnectindex != connecthead )
2071 break;
2072
2073 last_zero = 0;
2074 cmenu( 600 );
2075 }
2076 else
2077 {
2078 last_zero = x;
2079 switch(x)
2080 {
2081 case 0:
2082 cmenu(100);
2083 break;
2084 case 1: cmenu(200);break;
2085 case 2:
2086 if(movesperpacket == 4 && connecthead != myconnectindex)
2087 break;
2088 cmenu(300);
2089 break;
2090 case 3: KB_FlushKeyboardQueue();cmenu(400);break; // help
2091 case 4: cmenu(990);break; // credit
2092 case 5: cmenu(501);break; // quit
2093
2094 }
2095 }
2096 }
2097
2098 if(KB_KeyPressed(sc_Q)) cmenu(501);
2099
2100 if(x == -1)
2101 {
2102 // FIX_00069: Hitting Esc at the menu screen shows an empty green screen
2103 if(ud.recstat == 2) // playing demo
2104 ps[myconnectindex].gm &= ~MODE_MENU;
2105 }
2106
2107 if(movesperpacket == 4)
2108 {
2109 if( myconnectindex == connecthead )
2110 menutext(c,67,SHX(-2),PHX(-2),"NEW GAME");
2111 else
2112 menutext(c,67,SHX(-2),1,"NEW GAME");
2113 }
2114 else
2115 menutext(c,67,SHX(-2),PHX(-2),"NEW GAME");
2116
2117 menutext(c,67+16,SHX(-3),PHX(-3),"OPTIONS");
2118
2119 if(movesperpacket == 4 && connecthead != myconnectindex)
2120 menutext(c,67+16+16,SHX(-4),1,"LOAD GAME");
2121 else menutext(c,67+16+16,SHX(-4),PHX(-4),"LOAD GAME");
2122
2123 if(VOLUMEONE)
2124 menutext(c,67+16+16+16,SHX(-5),PHX(-5),"HOW TO ORDER");
2125 else
2126 menutext(c,67+16+16+16,SHX(-5),PHX(-5),"HELP");
2127
2128 menutext(c,67+16+16+16+16,SHX(-6),PHX(-6),"CREDITS");
2129
2130 menutext(c,67+16+16+16+16+16,SHX(-7),PHX(-7),"QUIT");
2131
2132 break;
2133// CTW END - MODIFICATION
2134
2135 case 50: // general menu as cmenu(0) but for multiplayer games
2136 c = (320>>1);
2137 rotatesprite(c<<16,32<<16,65536L,0,INGAMEDUKETHREEDEE,0,0,10,0,0,xdim-1,ydim-1);
2138 rotatesprite((c+100)<<16,36<<16,65536L,0,PLUTOPAKSPRITE+2,(sintable[(totalclock<<4)&2047]>>11),0,2+8,0,0,xdim-1,ydim-1);
2139 x = probe(c,67,16,7);
2140 switch(x)
2141 {
2142 case 0:
2143 if(movesperpacket == 4 && myconnectindex != connecthead)
2144 break;
2145 if(ud.multimode < 2 || ud.recstat == 2)
2146 cmenu(1500);
2147 else
2148 {
2149 cmenu(600);
2150 last_fifty = 0;
2151 }
2152 break;
2153 case 1:
2154 if(movesperpacket == 4 && connecthead != myconnectindex)
2155 break;
2156 if(ud.recstat != 2)
2157 {
2158 last_fifty = 1;
2159 cmenu(350);
2160 setview(0,0,xdim-1,ydim-1);
2161 }
2162 break;
2163 case 2:
2164 if(movesperpacket == 4 && connecthead != myconnectindex)
2165 break;
2166 last_fifty = 2;
2167 cmenu(300);
2168 break;
2169 case 3:
2170 last_fifty = 3;
2171 cmenu(200);
2172 break;
2173 case 4:
2174 last_fifty = 4;
2175 KB_FlushKeyboardQueue();
2176 cmenu(400);
2177 break;
2178 case 5:
2179 if(numplayers < 2)
2180 {
2181 last_fifty = 5;
2182 cmenu(503);
2183 }
2184 break;
2185 case 6:
2186 last_fifty = 6;
2187 cmenu(502);
2188 break;
2189 case -1:
2190 ps[myconnectindex].gm &= ~MODE_MENU;
2191 if(ud.multimode < 2 && ud.recstat != 2)
2192 {
2193 ready2send = 1;
2194 totalclock = ototalclock;
2195 }
2196 break;
2197 }
2198
2199 if( KB_KeyPressed(sc_Q) )
2200 cmenu(502);
2201
2202 if(movesperpacket == 4 && connecthead != myconnectindex)
2203 {
2204 menutext(c,67+16*0 ,SHX(-2),1,"NEW GAME");
2205 menutext(c,67+16*1 ,SHX(-3),1,"SAVE GAME");
2206 menutext(c,67+16*2 ,SHX(-4),1,"LOAD GAME");
2207 }
2208 else
2209 {
2210 menutext(c,67+16*0 ,SHX(-2),PHX(-2),"NEW GAME");
2211 menutext(c,67+16*1 ,SHX(-3),PHX(-3),"SAVE GAME");
2212 menutext(c,67+16*2 ,SHX(-4),PHX(-4),"LOAD GAME");
2213 }
2214
2215 menutext(c,67+16*3 ,SHX(-5),PHX(-5),"OPTIONS");
2216 if(VOLUMEONE)
2217 menutext(c,67+16*4 ,SHX(-6),PHX(-6),"HOW TO ORDER");
2218 else
2219 menutext(c,67+16*4 ,SHX(-6),PHX(-6)," HELP");
2220
2221 if(numplayers > 1)
2222 menutext(c,67+16*5 ,SHX(-7),1,"QUIT TO TITLE");
2223 else menutext(c,67+16*5 ,SHX(-7),PHX(-7),"QUIT TO TITLE");
2224 menutext(c,67+16*6,SHX(-8),PHX(-8),"QUIT GAME");
2225
2226 break;
2227
2228 case 100: // Title menu
2229 rotatesprite(160<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
2230 menutext(160,24,0,0,"SELECT AN EPISODE");
2231 if(PLUTOPAK)
2232 { //////if(boardfilename[0])
2233 //
2234 // uncomment this for user map
2235 //x = probe(160,60,20,5);
2236 x = probe(160,60,20,4);
2237
2238 //////else x = probe(160,60,20,4);
2239 }
2240 else
2241 {
2242 if(boardfilename[0])
2243 x = probe(160,60,20,4);
2244 else x = probe(160,60,20,3);
2245 }
2246 if(x >= 0)
2247 {
2248
2249 if (VOLUMEONE)
2250 {
2251 if(x > 0)
2252 cmenu(20000);
2253 else
2254 {
2255 ud.m_volume_number = x;
2256 ud.m_level_number = 0;
2257 cmenu(110);
2258 }
2259 }
2260
2261 else
2262 {
2263
2264 if((x == 3 && boardfilename[0])&&!PLUTOPAK)
2265 {
2266 ud.m_volume_number = 0;
2267 ud.m_level_number = 7;
2268 }
2269 else
2270
2271 /*
2272 if(x == 4 && boardfilename[0])
2273 {
2274 ud.m_volume_number = 0;
2275 ud.m_level_number = 7;
2276 }
2277 */
2278
2279 // USER MAP
2280 if((x == 4)&&PLUTOPAK)
2281 {
2282 //CONSOLE_Printf("MENU_USER_MAP");
2283 //
2284 //[Todo: generate file list starting from .\\maps]")
2285
2286 cmenu(MENU_USER_MAP); // cmenu(101)
2287 break;
2288 }
2289 else
2290 {
2291 ud.m_volume_number = x;
2292 ud.m_level_number = 0;
2293 }
2294 cmenu(110);
2295 }
2296 }
2297 else if(x == -1)
2298 {
2299 if(ps[myconnectindex].gm&MODE_GAME) cmenu(50);
2300 else cmenu(0);
2301 }
2302
2303 menutext(160,60,SHX(-2),PHX(-2),volume_names[0]);
2304
2305 c = 80;
2306 if (VOLUMEONE)
2307 {
2308 menutext(160,60+20,SHX(-3),1,volume_names[1]);
2309 menutext(160,60+20+20,SHX(-4),1,volume_names[2]);
2310 if(PLUTOPAK)
2311 menutext(160,60+20+20,SHX(-5),1,volume_names[3]);
2312 }
2313 else
2314 {
2315 menutext(160,60+20,SHX(-3),PHX(-3),volume_names[1]);
2316 menutext(160,60+20+20,SHX(-4),PHX(-4),volume_names[2]);
2317 if(PLUTOPAK)
2318 {
2319 menutext(160,60+20+20+20,SHX(-5),PHX(-5),volume_names[3]);
2320 //if(boardfilename[0])
2321 //{
2322
2323 // uncomment this for usermap
2324 //menutext(160,60+20+20+20+20,SHX(-6),PHX(-6),"USER MAP");
2325
2326 //gametextpal(160,60+20+20+20+20+3,boardfilename,16+(sintable[(totalclock<<4)&2047]>>11),2);
2327 //}
2328 }
2329 else
2330 { /*
2331 if(boardfilename[0])
2332 {
2333 menutext(160,60+20+20+20,SHX(-6),PHX(-6),"USER MAP");
2334 gametext(160,60+20+20+20+6,boardfilename,2,2+8+16);
2335 }
2336 */
2337 }
2338 }
2339 break;
2340
2341 case 101: // MENU_USER_MAP
2342 c = (320>>1);
2343 rotatesprite(c<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
2344 menutext(c,24,0,0,"USER MAP");
2345
2346 // Draw USER MAP background
2347 {
2348 int y, x1;
2349 int32_t xPos, xPos2;
2350 int32_t yPos; //yPos2;
2351
2352 xPos = ( xdim *32) / 320;
2353 yPos = ( ydim *30) / 200;
2354
2355 xPos2 = ( xdim *282) / 320;
2356 //yPos2 = ( ydim *130) / 200;
2357
2358 for(y=yPos; y < (ydim - (yPos*2)); y+=128)
2359 {
2360 for(x1=xPos; x1 < xPos2; x1+=128)
2361 {
2362 rotatesprite(x1<<16,y<<16,65536L,0,BIGHOLE,8,0,1+8+16+64+128,0,0, xdim - xPos, ydim - (yPos*2));
2363 }
2364 }
2365 }
2366
2367 c = (320>>1)-120;
2368 x = probe(c,70,19,4);
2369
2370 if(x == -1)
2371 {
2372 cmenu(MENU_SELECT_EPISODE);
2373 }
2374 break;
2375
2376 case 110:
2377 c = (320>>1);
2378 rotatesprite(c<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
2379 menutext(c,24,0,0,"SELECT SKILL");
2380 x = probe(c,70,19,4);
2381 if(x >= 0)
2382 {
2383 switch(x)
2384 {
2385 case 0: globalskillsound = JIBBED_ACTOR6;break;
2386 case 1: globalskillsound = BONUS_SPEECH1;break;
2387 case 2: globalskillsound = DUKE_GETWEAPON2;break;
2388 case 3: globalskillsound = JIBBED_ACTOR5;break;
2389 }
2390
2391 sound(globalskillsound);
2392
2393 ud.m_player_skill = x+1;
2394 if(x == 3) ud.m_respawn_monsters = 1;
2395 else ud.m_respawn_monsters = 0;
2396
2397 ud.m_monsters_off = ud.monsters_off = 0;
2398
2399 ud.m_respawn_items = 0;
2400 ud.m_respawn_inventory = 0;
2401
2402 ud.multimode = 1;
2403
2404 // if (ud.showcinematics)
2405 //if(ud.m_volume_number == 3) // not needed to play cinematics. Black screen not nice
2406 //{
2407 // flushperms();
2408 // setview(0,0,xdim-1,ydim-1);
2409 // clearview(0L);
2410 // nextpage();
2411 //}
2412
2413 newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill);
2414 enterlevel(MODE_GAME);
2415 }
2416 else if(x == -1)
2417 {
2418 cmenu(100);
2419 KB_FlushKeyboardQueue();
2420 }
2421
2422 menutext(c,70,SHX(-2),PHX(-2),skill_names[0]);
2423 menutext(c,70+19,SHX(-3),PHX(-3),skill_names[1]);
2424 menutext(c,70+19+19,SHX(-4),PHX(-4),skill_names[2]);
2425 menutext(c,70+19+19+19,SHX(-5),PHX(-5),skill_names[3]);
2426 break;
2427
2428 case 200:
2429
2430 rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
2431 menutext(320>>1,24,0,0,"OPTIONS");
2432
2433 c = (320>>1)-120;
2434
2435 x = probe(c+6,43,16,6);
2436
2437 if(x == -1)
2438 { if(ps[myconnectindex].gm&MODE_GAME) cmenu(50);else cmenu(0); }
2439
2440 switch(x)
2441 {
2442 case 0:
2443 cmenu(702); // game options
2444 break;
2445
2446 case 1:
2447 cmenu(703); // keybaord setup
2448 probey = 7;
2449 break;
2450
2451 case 2:
2452 cmenu(701); // mouse setup
2453 break;
2454
2455 case 3:
2456 cmenu(700); // sound setup
2457 break;
2458
2459 case 4:
2460 cmenu(706); // Video setup
2461 lastkeysetup = 0;
2462 current_resolution = 0; // in case we don't find it
2463 for(i=0; i<validmodecnt; i++)
2464 {
2465 if(validmodexdim[i] == xdim && validmodeydim[i] == ydim)
2466 current_resolution = i;
2467 }
2468 break;
2469
2470 case 5: // record on/off
2471 if( (ps[myconnectindex].gm&MODE_GAME) )
2472 {
2473 closedemowrite();
2474 break;
2475 }
2476 ud.m_recstat = !ud.m_recstat;
2477 break;
2478
2479 //case -7:
2480 // gametext(320>>1,43+16*6,"*** DISABLED. WILL BE FIXED SOON***",0,2+8+16); // center-i
2481 // break;
2482
2483 }
2484
2485 menutext(c,43,SHX(-6),PHX(-6),"GAME OPTIONS");
2486
2487 menutext(c,43+16,SHX(-6),PHX(-6),"SETUP KEYBOARD");
2488
2489 menutext(c,43+16+16,SHX(-6),PHX(-6),"SETUP MOUSE");
2490
2491 menutext(c,43+16+16+16,SHX(-8),PHX(-8),"SETUP SOUND");
2492
2493 menutext(c,43+16+16+16+16,SHX(-8),PHX(-8),"SETUP VIDEO");
2494
2495 if( (ps[myconnectindex].gm&MODE_GAME) && ud.m_recstat != 1 )
2496 {
2497 menutext(c,43+16+16+16+16+16,SHX(-10),1,"RECORD");
2498 menutext(c+160+40,43+16+16+16+16+16,SHX(-10),1,"OFF");
2499 }
2500 else
2501 {
2502 menutext(c,43+16+16+16+16+16,SHX(-10),PHX(-10),"RECORD");
2503
2504 if(ud.m_recstat == 1)
2505 menutext(c+160+40,43+16+16+16+16+16,SHX(-10),PHX(-10),"ON");
2506 else menutext(c+160+40,43+16+16+16+16+16,SHX(-10),PHX(-10),"OFF");
2507 }
2508
2509 break;
2510
2511 case 700:
2512
2513 c = (320>>1)-120;
2514 rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
2515 menutext(320>>1,24,0,0,"SETUP SOUNDS");
2516 onbar = ((probey == 2)&&SoundToggle) || ((probey == 3)&&MusicToggle) ;
2517
2518 x = probe(c+6,43,16,8);
2519
2520 switch(x)
2521 {
2522 case -1:
2523 cmenu(200);
2524 probey = 3;
2525 break;
2526
2527 case 0:
2528 if (FXDevice != NumSoundCards)
2529 {
2530 SoundToggle = 1-SoundToggle;
2531 if( SoundToggle == 0 )
2532 {
2533 FX_StopAllSounds();
2534 clearsoundlocks();
2535 }
2536 }
2537 break;
2538
2539 case 1:
2540
2541 if(eightytwofifty == 0 || numplayers < 2)
2542 if(MusicDevice != NumSoundCards)
2543 {
2544 MusicToggle = 1-MusicToggle;
2545 if( MusicToggle == 0 )
2546 MUSIC_StopSong();
2547 else
2548 {
2549 if(ud.recstat != 2 && ps[myconnectindex].gm&MODE_GAME)
2550 playmusic(&music_fn[0][music_select][0]);
2551 else playmusic(&env_music_fn[0][0]);
2552
2553 MUSIC_Continue();
2554 }
2555 }
2556 break;
2557
2558 case 4:
2559 if(SoundToggle && (FXDevice != NumSoundCards)) VoiceToggle = 1-VoiceToggle;
2560 break;
2561
2562 case 5:
2563 if(SoundToggle && (FXDevice != NumSoundCards)) AmbienceToggle = 1-AmbienceToggle;
2564 break;
2565
2566 case 6:
2567 if(SoundToggle && (FXDevice != NumSoundCards))
2568 {
2569 ReverseStereo = 1-ReverseStereo;
2570 FX_SetReverseStereo(ReverseStereo);
2571 }
2572 break;
2573
2574 case 7: // xduke: 1.3d sound style - hear opponent
2575 if(SoundToggle && (FXDevice != NumSoundCards))
2576 {
2577 OpponentSoundToggle = 1-OpponentSoundToggle;
2578 }
2579 break;
2580
2581 default:
2582 break;
2583 }
2584
2585 if(SoundToggle && FXDevice != NumSoundCards) menutext(c+160+40,43,0,(FXDevice == NumSoundCards),"ON");
2586 else menutext(c+160+40,43,0,(FXDevice == NumSoundCards),"OFF");
2587
2588 if(MusicToggle && (MusicDevice != NumSoundCards) && (!eightytwofifty||numplayers<2))
2589 menutext(c+160+40,43+16,0,(MusicDevice == NumSoundCards),"ON");
2590 else menutext(c+160+40,43+16,0,(MusicDevice == NumSoundCards),"OFF");
2591
2592 menutext(c,43,SHX(-2),(FXDevice == NumSoundCards),"SOUND");
2593 menutext(c,43+16+16,SHX(-4),(FXDevice==NumSoundCards)||SoundToggle==0,"SOUND VOLUME");
2594 {
2595 l = FXVolume;
2596 FXVolume >>= 2;
2597 bar(c+167+40,43+16+16,(short *)&FXVolume,4,(FXDevice!=NumSoundCards)&&x==2,SHX(-4),SoundToggle==0||(FXDevice==NumSoundCards));
2598 if(l != FXVolume)
2599 FXVolume <<= 2;
2600 if(l != FXVolume)
2601 FX_SetVolume( (short) FXVolume );
2602 }
2603 menutext(c,43+16,SHX(-3),(MusicDevice==NumSoundCards),"MUSIC");
2604 menutext(c,43+16+16+16,SHX(-5),(MusicDevice==NumSoundCards)||(numplayers > 1 && eightytwofifty)||MusicToggle==0,"MUSIC VOLUME");
2605 {
2606 l = MusicVolume;
2607 MusicVolume >>= 2;
2608 bar(c+167+40,43+16+16+16,
2609 (short *)&MusicVolume,4,
2610 (eightytwofifty==0||numplayers < 2) && (MusicDevice!=NumSoundCards) && x==3,SHX(-5),
2611 (numplayers > 1 && eightytwofifty)||MusicToggle==0||(MusicDevice==NumSoundCards));
2612 MusicVolume <<= 2;
2613 if(l != MusicVolume)
2614 {
2615 STUBBED("Check this");
2616 // !!! FIXME: Used to be Music_ not MUSIC_. --ryan.
2617 MUSIC_SetVolume( (short) MusicVolume );
2618 }
2619 }
2620 menutext(c,43+16+16+16+16,SHX(-6),(FXDevice==NumSoundCards)||SoundToggle==0,"DUKE TALK");
2621 menutext(c,43+16+16+16+16+16,SHX(-7),(FXDevice==NumSoundCards)||SoundToggle==0,"AMBIENCE");
2622
2623 menutext(c,43+16+16+16+16+16+16,SHX(-8),(FXDevice==NumSoundCards)||SoundToggle==0,"FLIP STEREO");
2624
2625 if(VoiceToggle) menutext(c+160+40,43+16+16+16+16,0,(FXDevice==NumSoundCards)||SoundToggle==0,"ON");
2626 else menutext(c+160+40,43+16+16+16+16,0,(FXDevice==NumSoundCards)||SoundToggle==0,"OFF");
2627
2628 if(AmbienceToggle) menutext(c+160+40,43+16+16+16+16+16,0,(FXDevice==NumSoundCards)||SoundToggle==0,"ON");
2629 else menutext(c+160+40,43+16+16+16+16+16,0,(FXDevice==NumSoundCards)||SoundToggle==0,"OFF");
2630
2631 if(ReverseStereo) menutext(c+160+40,43+16+16+16+16+16+16,0,(FXDevice==NumSoundCards)||SoundToggle==0,"ON");
2632 else menutext(c+160+40,43+16+16+16+16+16+16,0,(FXDevice==NumSoundCards)||SoundToggle==0,"OFF");
2633
2634 menutext(c,43+16+16+16+16+16+16+16,SHX(-9),(FXDevice==NumSoundCards)||SoundToggle==0,"OPPONENT SOUND");
2635 if(OpponentSoundToggle) menutext(c+160+40,43+16+16+16+16+16+16+16,0,(FXDevice==NumSoundCards)||SoundToggle==0,"ON");
2636 else menutext(c+160+40,43+16+16+16+16+16+16+16,0,(FXDevice==NumSoundCards)||SoundToggle==0,"OFF");
2637
2638 break;
2639
2640 case 701:
2641 c = (320>>1)-120;
2642 rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
2643 menutext(320>>1,24,0,0,"SETUP MOUSE");
2644 onbar = ( probey == 0 || probey == 1);
2645
2646 x = probe(c+6,43,16,8);
2647 switch(x)
2648 {
2649 case -7:
2650 gametext(320>>1,43+16*7+3,"*** SHORTCUT: ALT-M ***",0,2+8+16); // center-i
2651 break;
2652
2653 case -1:
2654 cmenu(200);
2655 probey = 2;
2656 break;
2657
2658 case 0:
2659 case 1:
2660 break;
2661 case 2:
2662
2663 if ( ((ControllerType == controltype_keyboardandmouse)||
2664 (ControllerType == controltype_joystickandmouse)) )
2665 {
2666 MouseAiming = !MouseAiming;
2667 if(MouseAiming)
2668 myaimmode = 0;
2669
2670 }
2671 break;
2672
2673 case 3:
2674
2675 if ( ((ControllerType == controltype_keyboardandmouse)||
2676 (ControllerType == controltype_joystickandmouse)) )
2677 {
2678 if(!MouseAiming) // means we are in toggle mode
2679 myaimmode = !myaimmode;
2680 }
2681 break;
2682
2683 case 4:
2684
2685 if ( ((ControllerType == controltype_keyboardandmouse)||
2686 (ControllerType == controltype_joystickandmouse)) )
2687 {
2688 ud.mouseflip = 1-ud.mouseflip;
2689 }
2690 break;
2691
2692 case 5:
2693
2694 if (SDL_WM_GrabInput(SDL_GRAB_QUERY)==SDL_GRAB_ON)
2695 {
2696 SDL_WM_GrabInput(SDL_GRAB_OFF);
2697 SDL_ShowCursor(1);
2698 }
2699 else
2700 {
2701 SDL_WM_GrabInput(SDL_GRAB_ON);
2702 SDL_ShowCursor(0);
2703 }
2704 break;
2705
2706 case 6:
2707 cmenu(704); // Button setup
2708 break;
2709
2710 case 7:
2711 cmenu(705); // Digital axes setup
2712 break;
2713
2714 default:
2715 break;
2716 }
2717
2718 {
2719 short sense;
2720
2721 sense = CONTROL_GetMouseSensitivity_X();
2722 menutext(c,43+16*0,SHX(-7),PHX(-7),"X SENSITIVITY");
2723 bar(c+167+40,43+16*0,&sense,1,x==0,SHX(-7),PHX(-7));
2724 CONTROL_SetMouseSensitivity_X( sense );
2725
2726 sense = CONTROL_GetMouseSensitivity_Y();
2727 menutext(c,43+16*1,SHX(-7),PHX(-7),"Y SENSITIVITY");
2728 bar(c+167+40,43+16*1,&sense,1,x==1,SHX(-7),PHX(-7));
2729 CONTROL_SetMouseSensitivity_Y( sense );
2730
2731 menutext(c,43+16*2,SHX(-7),PHX(-7),"MOUSE AIM TYPE");
2732 if(MouseAiming) menutext(c+160+40,43+16*2,SHX(-7),PHX(-7),"HELD");
2733 else menutext(c+160+40,43+16*2,SHX(-7),PHX(-7),"TOGGLE");
2734
2735 menutext(c,43+16*3,SHX(-7),MouseAiming,"MOUSE AIMING");
2736 if(myaimmode) menutext(c+160+40,43+16*3,SHX(-7),MouseAiming,"ON");
2737 else menutext(c+160+40,43+16*3,SHX(-7),MouseAiming,"OFF");
2738
2739 menutext(c,43+16*4,SHX(-7),PHX(-7),"MOUSE AIMING FLIP");
2740 if(ud.mouseflip) menutext(c+160+40,43+16*4,SHX(-7),PHX(-7),"ON");
2741 else menutext(c+160+40,43+16*4,SHX(-7),PHX(-7),"OFF");
2742
2743
2744 menutext(c,43+16*5,SHX(-7),PHX(-7),"MOUSE CURSOR");
2745 if(SDL_WM_GrabInput(SDL_GRAB_QUERY)==SDL_GRAB_ON)
2746 menutext(c+160+40,43+16*5,SHX(-7),PHX(-7),"TAKEN");
2747 else
2748 menutext(c+160+40,43+16*5,SHX(-7),PHX(-7),"FREE'D");
2749
2750 menutext(c,43+16*6,SHX(-7),PHX(-7),"BUTTON SETUP...");
2751
2752 menutext(c,43+16*7,SHX(-7),PHX(-7),"DIGITAL AXES SETUP...");
2753 }
2754
2755 break;
2756
2757 case 702:
2758 c = (320>>1)-120;
2759 rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
2760 menutext(320>>1,24,0,0,"GAME OPTIONS");
2761
2762 onbar = 0;
2763
2764 x = probe(c+6,43,16,7);
2765
2766 switch(x)
2767 {
2768
2769 case -1:
2770 cmenu(200);
2771 break;
2772
2773 case 0:
2774 ud.shadows = 1-ud.shadows;
2775 break;
2776 case 1:
2777 ud.screen_tilting = 1-ud.screen_tilting;
2778 break;
2779 case 2:
2780 ud.showcinematics = !ud.showcinematics;
2781 break;
2782 case 3:
2783 ud.hideweapon = !ud.hideweapon;
2784 vscrn(); // FIX_00056: Refresh issue w/FPS, small Weapon and custom FTA, when screen resized down
2785 break;
2786 case 4:
2787 ud.weaponautoswitch = !ud.weaponautoswitch;
2788 break;
2789 case 5:
2790 // FIX_00045: Autoaim mode can now be toggled on/off from menu
2791 if( nHostForceDisableAutoaim == 0)
2792 {
2793 ud.auto_aim++;
2794 ud.auto_aim = ((ud.auto_aim-1)%2)+1; // 2 = normal = full; 1 = bullet only
2795 }
2796 break;
2797 case 6: // parental
2798#ifndef AUSTRALIA
2799 cmenu(10000);
2800#endif
2801 break;
2802
2803 }
2804
2805
2806 menutext(c,43+16*0,SHX(-3),PHX(-3),"SHADOWS");
2807 if(ud.shadows) menutext(c+160+40,43+16*0,0,0,"ON");
2808 else menutext(c+160+40,43+16*0,0,0,"OFF");
2809
2810 menutext(c,43+16*1,SHX(-4),PHX(-4),"SCREEN TILTING");
2811 switch(ud.screen_tilting)
2812 {
2813 case 0: menutext(c+160+40,43+16*1,0,0,"OFF");break;
2814 case 1: menutext(c+160+40,43+16*1,0,0,"ON");break;
2815 case 2: menutext(c+160+40,43+16*1,0,0,"FULL");break;
2816 }
2817
2818 menutext(c,43+16*2,SHX(-3),PHX(-3),"CINEMATICS");
2819 if(ud.showcinematics) menutext(c+160+40,43+16*2,0,0,"ON");
2820 else menutext(c+160+40,43+16*2,0,0,"OFF");
2821
2822 menutext(c,43+16*3,SHX(-3),PHX(-3),"WEAPON MODEL");
2823 if(ud.hideweapon) menutext(c+160+40,43+16*3,0,0,"OFF");
2824 else menutext(c+160+40,43+16*3,0,0,"ON");
2825
2826 menutext(c,43+16*4,SHX(-3),PHX(-3),"WEAPON SWITCH");
2827 if(ud.weaponautoswitch) menutext(c+160+40,43+16*4,0,0,"OFF");
2828 else menutext(c+160+40,43+16*4,0,0,"ON");
2829
2830 switch(ud.auto_aim)
2831 {
2832 case 0: menutext(c,43+16*5,0,nHostForceDisableAutoaim,"AUTOAIM DISABLED BY HOST");
2833 break;
2834 case 1: menutext(c,43+16*5,0,0,"AUTOAIM BULLET ONLY");
2835 break;
2836 case 2: menutext(c,43+16*5,0,0,"AUTOAIM REGULAR FULL");
2837 break;
2838 }
2839
2840#ifndef AUSTRALIA
2841 menutext(c,43+16*6,SHX(-9),PHX(-9),"PARENTAL LOCK");
2842#else
2843 menutext(c,43+16*6,SHX(-9),1,"PARENTAL LOCK");
2844#endif
2845
2846
2847 break;
2848
2849 case 703:
2850
2851 // black translucent background underneath lists
2852 rotatesprite(0<<16, 0<<16, 65536l<<5, 0, BLANK, 8, 0, 1+2+8+16+64,
2853 scale(0,xdim,320),scale(0,ydim,200),
2854 scale(320-0,xdim,320)-1,scale(200-34,ydim,200)-1);
2855
2856 c = (320>>1)-120-25;
2857 rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
2858 menutext(320>>1,24,0,0,"SETUP KEYBOARD");
2859
2860 onbar = 0;
2861 x = probeXduke(c+210+lastkeysetup*62,46+16+16+16,0,NUMGAMEFUNCTIONS,20000);
2862 if(waiting4key)
2863 {
2864 probey = waiting4key-1; // force it to stay at the same location
2865 x=-(waiting4key-1)-2;
2866 }
2867
2868 if (( KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_LeftArrow ) ||
2869 KB_KeyPressed( sc_kpad_4 ) || KB_KeyPressed( sc_kpad_6 )) &&
2870 !waiting4key) // set left or right column flag
2871 {
2872 lastkeysetup = !lastkeysetup;
2873 KB_ClearKeyDown( sc_RightArrow ); KB_ClearKeyDown( sc_LeftArrow );
2874 KB_ClearKeyDown( sc_kpad_4 ); KB_ClearKeyDown( sc_kpad_6 );
2875 sound(KICK_HIT);
2876 }
2877
2878 if (KB_KeyPressed(sc_Delete) && -2>=x && x>=(-NUMGAMEFUNCTIONS-1) && !waiting4key) // clear a key
2879 {
2880 if(lastkeysetup)
2881 CONTROL_MapKey(-x-2, KeyMapping[-x-2].key1, 0);
2882 else
2883 CONTROL_MapKey(-x-2, 0, KeyMapping[-x-2].key2);
2884
2885 KB_ClearKeyDown( sc_Delete ); // Avoid repeating delete
2886 sound(EXITMENUSOUND);
2887 }
2888
2889 if ( (0<=x && x<NUMGAMEFUNCTIONS) || waiting4key) // set a key
2890 {
2891 if(!waiting4key)
2892 {
2893 waiting4key = x+1; // so it's always true
2894 KB_ClearLastScanCode(); // clear the enter hit that was just hit
2895 }
2896
2897 if(KB_GetLastScanCode())
2898 {
2899 if(KB_GetLastScanCode() != sc_Escape) // ESC is reserved for menu. Using it for controls could discard it completely, eg: AutoRun = "Escape"
2900 {
2901 if(lastkeysetup)
2902 CONTROL_MapKey(waiting4key-1, KeyMapping[waiting4key-1].key1, KB_GetLastScanCode());
2903 else
2904 CONTROL_MapKey(waiting4key-1, KB_GetLastScanCode(), KeyMapping[waiting4key-1].key2);
2905
2906 sound(KICK_HIT);
2907 }
2908 else
2909 CONTROL_MapKey(waiting4key - 1, sc_None, sc_None); /* allow clearing */
2910
2911 KB_ClearLastScanCode();
2912 KB_FlushKeyboardQueue();
2913 KB_ClearKeysDown();
2914 waiting4key = false;
2915 }
2916 }
2917
2918 if(!waiting4key)
2919 switch(x)
2920 {
2921 case -1:
2922 cmenu(200);
2923 probey = 1; // back to setup keyboard
2924 break;
2925 }
2926
2927 // display and scroll the whole keyboard list
2928 j = 7; // -j .. 0 .. j lines => 2*j+1 lines
2929 if(-2>=x && x>=(-NUMGAMEFUNCTIONS-1)) // -2 to -54 (53 values -> 0->52)
2930 {
2931 for(i=-j; i<=+j; i++)
2932 if(NUMGAMEFUNCTIONS > (-x-2+i) && (-x-2+i) >= 0)
2933 {
2934 gametext(c-10,47-16+8*(i+j),gamefunctions[-x-2+i],i?0:0,2+8+16); // disp name
2935 if (i || lastkeysetup || !waiting4key || (totalclock%128 < 64)) // blink 1st key
2936 gametext(c+185,47-16+8*(i+j),KB_ScanCodeToString( KeyMapping[-x-2+i].key1 )?KB_ScanCodeToString( KeyMapping[-x-2+i].key1 ):"...",i?0:0,2+8+16); // center-i
2937 if (i || !lastkeysetup || !waiting4key || (totalclock%128 < 64)) // blink 2nd key
2938 gametext(c+247,47-16+8*(i+j),KB_ScanCodeToString( KeyMapping[-x-2+i].key2 )?KB_ScanCodeToString( KeyMapping[-x-2+i].key2 ):"...",i?0:0,2+8+16); // center-i
2939 }
2940 }
2941
2942 if(waiting4key)
2943 gametext(320>>1,47-16+8*(2*j+2)-4,"*** HIT A NEW KEY ***",0,2+8+16); // center-i
2944 else
2945 gametext(320>>1,47-16+8*(2*j+2)-4,"*** HIT ENTER OR DEL KEY ***",0,2+8+16); // center-i
2946
2947 break;
2948
2949 case 704: // mouse button setup, frm menu 701
2950 c = (320>>1)-120-25;
2951 rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
2952 menutext(320>>1,24,0,0,"SETUP MOUSE");
2953
2954 // black translucent background underneath lists
2955 rotatesprite(0<<16, 0<<16, 65536l<<5, 0, BLANK, 8, 0, 1+2+8+16+64,
2956 scale(0,xdim,320),scale(40,ydim,200),
2957 scale(320-0,xdim,320)-1,scale(200-75,ydim,200)-1);
2958
2959 onbar = 0;
2960 x = probeXduke(c+146,46+8,8,MAXMOUSEBUTTONS,20000);
2961 lastkeysetup = 0;
2962
2963 if ( KB_KeyPressed( sc_kpad_4 ) || KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed (sc_BackSpace) )
2964 {
2965 lastkeysetup = 1; // reversed;
2966 KB_ClearKeyDown( sc_kpad_4 );
2967 KB_ClearKeyDown( sc_LeftArrow );
2968 KB_ClearKeyDown(sc_BackSpace);
2969 sound(KICK_HIT);
2970 x = -x-2;
2971 }
2972 else if ( KB_KeyPressed( sc_kpad_6 ) || KB_KeyPressed( sc_RightArrow ) )
2973 {
2974 KB_ClearKeyDown( sc_kpad_6 );
2975 KB_ClearKeyDown( sc_RightArrow );
2976 sound(KICK_HIT);
2977 x = -x-2;
2978 }
2979
2980 if (KB_KeyPressed(sc_Delete) && -2>=x && x>=(-MAXMOUSEBUTTONS-1)) // clear a key
2981 {
2982 MouseMapping[-x-2] = -1;
2983 KB_ClearKeyDown( sc_Delete ); // Avoid repeating delete
2984 sound(EXITMENUSOUND);
2985 }
2986
2987 if (0<=x && x<MAXMOUSEBUTTONS) // set a function
2988 {
2989 if (lastkeysetup) // going up
2990 {
2991 MouseMapping[x]--;
2992 if(MouseMapping[x]==-2)
2993 MouseMapping[x] = NUMGAMEFUNCTIONS-1;
2994
2995 }
2996 else
2997 {
2998 MouseMapping[x]++;
2999 if(MouseMapping[x]==NUMGAMEFUNCTIONS)
3000 MouseMapping[x] = -1; // Discard
3001 }
3002 }
3003
3004 switch(x)
3005 {
3006 case -1:
3007 cmenu(701);
3008 probey = 6; // back to the general mouse setup menu
3009 break;
3010 }
3011
3012 // display the button list
3013 for(i=0; i<MAXMOUSEBUTTONS; i++)
3014 {
3015 sprintf(text, "#%d",i);
3016 switch(i)
3017 {
3018 case 0:
3019 strcat(text, " Left");
3020 break;
3021 case 1:
3022 strcat(text, " Right");
3023 break;
3024 case 2:
3025 strcat(text, " Middle");
3026 break;
3027 case 3:
3028 strcat(text, " Wheel up");
3029 break;
3030 case 4:
3031 strcat(text, " Wheel down");
3032 break;
3033 default:
3034 strcat(text, " (Extra)");
3035 break;
3036 }
3037
3038 gametext(c,47+i*8,text,0,2+8+16);
3039 gametext(c+121,47+i*8,(MouseMapping[i]!=-1)?CONFIG_FunctionNumToName(MouseMapping[i]):"...",0,2+8+16);
3040 }
3041
3042 gametext(320>>1,47+(MAXMOUSEBUTTONS+1)*8,"*** USE ARROWS OR DEL KEY ***",0,2+8+16);
3043
3044 break;
3045
3046 case 705: // digital axes setup, from menu 701
3047 c = (320>>1)-120-25;
3048 rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
3049 menutext(320>>1,24,0,0,"DIGITAL AXES");
3050
3051 // black translucent background underneath lists
3052 rotatesprite(0<<16, 0<<16, 65536l<<5, 0, BLANK, 8, 0, 1+2+8+16+64,
3053 scale(0,xdim,320),scale(40,ydim,200),
3054 scale(320-0,xdim,320)-1,scale(200-100,ydim,200)-1);
3055
3056 onbar = 0;
3057 x = probeXduke(c+146,46+8,8,MAXMOUSEAXES*2,20000);
3058 lastkeysetup = 0;
3059
3060 if ( KB_KeyPressed( sc_kpad_4 ) || KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed (sc_BackSpace) )
3061 {
3062 lastkeysetup = 1; // reversed;
3063 KB_ClearKeyDown( sc_kpad_4 );
3064 KB_ClearKeyDown( sc_LeftArrow );
3065 KB_ClearKeyDown(sc_BackSpace);
3066 sound(KICK_HIT);
3067 x = -x-2;
3068 }
3069 else if ( KB_KeyPressed( sc_kpad_6 ) || KB_KeyPressed( sc_RightArrow ) )
3070 {
3071 KB_ClearKeyDown( sc_kpad_6 );
3072 KB_ClearKeyDown( sc_RightArrow );
3073 sound(KICK_HIT);
3074 x = -x-2;
3075 }
3076
3077 if (KB_KeyPressed(sc_Delete) && -2>=x && x>=(-(MAXMOUSEAXES*2)-1)) // clear a key
3078 {
3079 MouseDigitalAxeMapping[(-x-2)>>1][(-x-2)&1] = -1;
3080 KB_ClearKeyDown( sc_Delete ); // Avoid repeating delete
3081 sound(EXITMENUSOUND);
3082 }
3083
3084 if (0<=x && x<(MAXMOUSEAXES*2)) // set a function
3085 {
3086 if (lastkeysetup) // going up
3087 {
3088 MouseDigitalAxeMapping[x>>1][x&1]--;
3089 if(MouseDigitalAxeMapping[x>>1][x&1]==-2)
3090 MouseDigitalAxeMapping[x>>1][x&1] = NUMGAMEFUNCTIONS-1;
3091 }
3092 else
3093 {
3094 MouseDigitalAxeMapping[x>>1][x&1]++;
3095 if(MouseDigitalAxeMapping[x>>1][x&1]==NUMGAMEFUNCTIONS)
3096 MouseDigitalAxeMapping[x>>1][x&1] = -1; // Discard
3097 }
3098 }
3099
3100 switch(x)
3101 {
3102 case -1:
3103 cmenu(701);
3104 probey = 7; // back to the general mouse setup menu
3105 break;
3106 }
3107
3108 // display the button list
3109 for(i=0; i<(MAXMOUSEAXES*2); i++)
3110 {
3111 *tempbuf = 0;
3112 switch(i)
3113 {
3114 case 0:
3115 strcat(text, "X left");
3116 break;
3117 case 1:
3118 strcat(text, "X right");
3119 break;
3120 case 2:
3121 strcat(text, "Y up");
3122 break;
3123 case 3:
3124 strcat(text, "Y down");
3125 break;
3126 default:
3127 break;
3128 }
3129
3130 gametext(c,47+i*8,text,0,2+8+16);
3131 gametext(c+121,47+i*8,(MouseDigitalAxeMapping[i>>1][i&1]!=-1)?CONFIG_FunctionNumToName(MouseDigitalAxeMapping[i>>1][i&1]):"...",0,2+8+16);
3132 }
3133
3134 gametext(320>>1,47+(4+1)*8,"*** USE ARROWS OR DEL KEY ***",0,2+8+16);
3135
3136 break;
3137
3138 case 706: // Video setup
3139 // FIX_00042: Build in Video setup.
3140 c = (320>>1)-120;
3141 rotatesprite(320<<15,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
3142 menutext(320>>1,24,0,0,"VIDEO SETUP");
3143
3144 onbar = (probey == 3 || probey == 4);
3145 x = probe(c+6,43,16,6);
3146
3147 switch(x)
3148 {
3149 case -7: // cursor idle on the FPS option (5)
3150 gametext(320>>1,43+16*7,"*** SHORTCUT: TYPE DNRATE ***",0,2+8+16); // center-i
3151
3152 break;
3153
3154 case -3: // cursor idle on the togglefullscreen option (1)
3155 gametext(320>>1,43+16*7,"*** SHORTCUT: ALT-ENTER ***",0,2+8+16); // center-i
3156
3157 break;
3158
3159 case -2: // cursor idle on the resolution option (0)
3160 if ( KB_KeyPressed( sc_kpad_4 ) || KB_KeyPressed( sc_LeftArrow ) )
3161 {
3162 current_resolution--;
3163 if(current_resolution == -1)
3164 current_resolution = 0;
3165 lastkeysetup = 1; // indicates we changed
3166 KB_ClearKeyDown( sc_kpad_4 );
3167 KB_ClearKeyDown( sc_LeftArrow );
3168 sound(PISTOL_BODYHIT);
3169 }
3170 else if ( KB_KeyPressed( sc_kpad_6 ) || KB_KeyPressed( sc_RightArrow ) )
3171 {
3172 current_resolution++; // reversed;
3173 if(current_resolution == validmodecnt)
3174 current_resolution = validmodecnt-1;
3175 lastkeysetup = 1; // indicates we changed
3176 KB_ClearKeyDown( sc_kpad_6 );
3177 KB_ClearKeyDown( sc_RightArrow );
3178 sound(PISTOL_BODYHIT);
3179 }
3180
3181 if(lastkeysetup)
3182 gametext(320>>1,43+16*7,"*** HIT ENTER TO VALIDATE ***",0,2+8+16); // center-i
3183 else
3184 gametext(320>>1,43+16*7,"*** LEFT/RIGHT ARROW TO SELECT ***",0,2+8+16); // center-i
3185
3186 break;
3187
3188 case -1:
3189 cmenu(200);
3190 probey = 4; // back to the general option menu
3191 break;
3192
3193 case 0:
3194 if(lastkeysetup)
3195 setgamemode(ScreenMode,validmodexdim[current_resolution],validmodeydim[current_resolution]);
3196 lastkeysetup = 0; // indicating changes are done
3197 break;
3198
3199 case 1:
3200 BFullScreen = !BFullScreen;
3201 SDL_QuitSubSystem(SDL_INIT_VIDEO);
3202 _platform_init(0, NULL, "Duke Nukem 3D", "Duke3D");
3203 _setgamemode(ScreenMode,validmodexdim[current_resolution],validmodeydim[current_resolution]);
3204 break;
3205
3206 case 2:
3207 ud.detail = 1-ud.detail;
3208 break;
3209
3210 case 5:
3211 ud.tickrate ^= 1;
3212 vscrn(); // FIX_00056: Refresh issue w/FPS, small Weapon and custom FTA, when screen resized down
3213 break;
3214 }
3215
3216 menutext(c,43,0,0,"RESOLUTION");
3217 sprintf(text, "%d x %d", validmodexdim[current_resolution],validmodeydim[current_resolution]);
3218 if (lastkeysetup == 0 || (totalclock%64 < 32)) // blink color after change
3219 menutext(c+150,43,0,0,text);
3220 else
3221 menutext(c+150,43,0,1,text);
3222
3223 menutext(c,43+16*1,SHX(-3),PHX(-3),"FULLSCREEN");
3224 menutext(c+160+40,43+16*1,0,0,BFullScreen?"ON":"OFF");
3225
3226 menutext(c,43+16*2,SHX(-2),PHX(-2),"DETAIL");
3227 menutext(c+160+40,43+16*2,0,0,ud.detail?"HIGH":"LOW");
3228 {
3229 int32 screen_size = ud.screen_size;
3230
3231 // FIX_00027: Added an extra small statusbar (HUD)
3232 menutext(c,43+16*3,SHX(-5),PHX(-5),"SCREEN SIZE");
3233 bar(c+167+40,43+16*3,(short *)&screen_size,-4,x==3,SHX(-5),PHX(-5));
3234 if(ud.screen_size==4)
3235 {
3236 if(screen_size==0)
3237 {
3238 ud.extended_screen_size++;
3239 if(ud.extended_screen_size==2)
3240 {
3241 ud.extended_screen_size = 1;
3242 ud.screen_size -= 4;
3243 }
3244 }
3245 else if(screen_size==8)
3246 {
3247 ud.extended_screen_size--;
3248 if(ud.extended_screen_size<0)
3249 {
3250 ud.extended_screen_size=0;
3251 ud.screen_size += 4;
3252 }
3253 }
3254 }
3255 else
3256 ud.screen_size = screen_size;
3257 }
3258
3259 menutext(c,43+16*4,SHX(-6),PHX(-6),"BRIGHTNESS");
3260 bar(c+167+40,43+16*4,(short *)&ud.brightness,8,x==4,SHX(-6),PHX(-6));
3261 if(x==4) setbrightness(ud.brightness>>2,&ps[myconnectindex].palette[0]);
3262
3263 menutext(c,43+16*5,SHX(-2),PHX(-2),"SHOW FPS");
3264 menutext(c+160+40,43+16*5,0,0,(ud.tickrate&1)?"ON":"OFF");
3265
3266 break;
3267
3268 case 350:
3269 cmenu(351);
3270 screencapt = 1;
3271 displayrooms(myconnectindex,65536);
3272 savetemp("duke3d.tmp",tiles[MAXTILES-1].data,160*100);
3273 screencapt = 0;
3274 break;
3275
3276 case 360:
3277 case 361:
3278 case 362:
3279 case 363:
3280 case 364:
3281 case 365:
3282 case 366:
3283 case 367:
3284 case 368:
3285 case 369:
3286 case 351:
3287 case 300:
3288
3289 c = 320>>1;
3290 rotatesprite(c<<16,200<<15,65536L,0,MENUSCREEN,16,0,10+64,0,0,xdim-1,ydim-1);
3291 rotatesprite(c<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
3292
3293 if(current_menu == 300) menutext(c,24,0,0,"LOAD GAME");
3294 else menutext(c,24,0,0,"SAVE GAME");
3295
3296 if(current_menu >= 360 && current_menu <= 369 )
3297 {
3298 sprintf(text,"PLAYERS: %-2d ",ud.multimode);
3299 gametext(160,158,text,0,2+8+16);
3300 sprintf(text,"EPISODE: %-2d / LEVEL: %-2d / SKILL: %-2d",1+ud.volume_number,1+ud.level_number,ud.player_skill);
3301 gametext(160,170,text,0,2+8+16);
3302
3303 x = strget((320>>1),184,&ud.savegame[current_menu-360][0],19, 999 );
3304
3305 if(x == -1)
3306 {
3307 // readsavenames();
3308 ps[myconnectindex].gm = MODE_GAME;
3309 if(ud.multimode < 2 && ud.recstat != 2)
3310 {
3311 ready2send = 1;
3312 totalclock = ototalclock;
3313 }
3314 goto DISPLAYNAMES;
3315 }
3316
3317 if( x == 1 )
3318 {
3319 if( ud.savegame[current_menu-360][0] == 0 )
3320 {
3321 KB_FlushKeyboardQueue();
3322 cmenu(351);
3323 }
3324 else
3325 {
3326 if(ud.multimode > 1)
3327 saveplayer(-1-(current_menu-360));
3328 else saveplayer(current_menu-360);
3329 lastsavedpos = current_menu-360;
3330 ps[myconnectindex].gm = MODE_GAME;
3331
3332 if(ud.multimode < 2 && ud.recstat != 2)
3333 {
3334 ready2send = 1;
3335 totalclock = ototalclock;
3336 }
3337 KB_ClearKeyDown(sc_Escape);
3338 sound(EXITMENUSOUND);
3339 }
3340 }
3341
3342 rotatesprite(101<<16,97<<16,65536,512,MAXTILES-1,-32,0,2+4+8+64,0,0,xdim-1,ydim-1);
3343 dispnames();
3344 rotatesprite((c+67+strlen(&ud.savegame[current_menu-360][0])*4)<<16,(50+12*probey)<<16,32768L-10240,0,SPINNINGNUKEICON+(((totalclock)>>3)%7),0,0,10,0,0,xdim-1,ydim-1);
3345 break;
3346 }
3347
3348 last_threehundred = probey;
3349
3350 x = probe(c+68,54,12,10);
3351
3352 if(current_menu == 300)
3353 {
3354 if( ud.savegame[probey][0] )
3355 {
3356 if( lastprobey != probey )
3357 {
3358 loadpheader(probey,&volnum,&levnum,&plrskl,&numplr);
3359 lastprobey = probey;
3360 }
3361
3362 rotatesprite(101<<16,97<<16,65536L,512,MAXTILES-3,-32,0,4+10+64,0,0,xdim-1,ydim-1);
3363 sprintf(text,"PLAYERS: %-2d ",numplr);
3364 gametext(160,158,text,0,2+8+16);
3365 sprintf(text,"EPISODE: %-2d / LEVEL: %-2d / SKILL: %-2d",1+volnum,1+levnum,plrskl);
3366 gametext(160,170,text,0,2+8+16);
3367 }
3368 else menutext(69,70,0,0,"EMPTY");
3369 }
3370 else
3371 {
3372 if( ud.savegame[probey][0] )
3373 {
3374 if(lastprobey != probey)
3375 loadpheader(probey,&volnum,&levnum,&plrskl,&numplr);
3376 lastprobey = probey;
3377 rotatesprite(101<<16,97<<16,65536L,512,MAXTILES-3,-32,0,4+10+64,0,0,xdim-1,ydim-1);
3378 }
3379 else menutext(69,70,0,0,"EMPTY");
3380 sprintf(text,"PLAYERS: %-2d ",ud.multimode);
3381 gametext(160,158,text,0,2+8+16);
3382 sprintf(text,"EPISODE: %-2d / LEVEL: %-2d / SKILL: %-2d",1+ud.volume_number,1+ud.level_number,ud.player_skill);
3383 gametext(160,170,text,0,2+8+16);
3384 }
3385
3386 switch( x )
3387 {
3388 case -1:
3389 if(current_menu == 300) //load game
3390 {
3391 if( (ps[myconnectindex].gm&MODE_GAME) != MODE_GAME)
3392 {
3393 cmenu(0);
3394 break;
3395 }
3396 else
3397 ps[myconnectindex].gm &= ~MODE_MENU;
3398 }
3399 else // save game
3400 ps[myconnectindex].gm = MODE_GAME;
3401
3402 if(ud.multimode < 2 && ud.recstat != 2)
3403 {
3404 ready2send = 1;
3405 totalclock = ototalclock;
3406 }
3407
3408 break;
3409 case 0:
3410 case 1:
3411 case 2:
3412 case 3:
3413 case 4:
3414 case 5:
3415 case 6:
3416 case 7:
3417 case 8:
3418 case 9:
3419 if( current_menu == 300)
3420 {
3421 if( ud.savegame[x][0] )
3422 current_menu = (1000+x);
3423 }
3424 else
3425 {
3426 if( ud.savegame[x][0] != 0)
3427 current_menu = 2000+x;
3428 else
3429 {
3430 KB_FlushKeyboardQueue();
3431 current_menu = (360+x);
3432 ud.savegame[x][0] = 0;
3433 inputloc = 0;
3434 }
3435 }
3436 break;
3437 }
3438
3439 DISPLAYNAMES:
3440 dispnames();
3441 break;
3442
3443 case 400: // help
3444 case 401:
3445 if(!VOLUMEONE)
3446 {
3447 c = 320>>1;
3448
3449 if( KB_KeyPressed( sc_LeftArrow ) ||
3450 KB_KeyPressed( sc_kpad_4 ) ||
3451 KB_KeyPressed( sc_UpArrow ) ||
3452 KB_KeyPressed( sc_PgUp ) ||
3453 KB_KeyPressed( sc_kpad_8 ) )
3454 {
3455 KB_ClearKeyDown(sc_LeftArrow);
3456 KB_ClearKeyDown(sc_kpad_4);
3457 KB_ClearKeyDown(sc_UpArrow);
3458 KB_ClearKeyDown(sc_PgUp);
3459 KB_ClearKeyDown(sc_kpad_8);
3460
3461 sound(KICK_HIT);
3462 current_menu--;
3463 if(current_menu < 400) current_menu = 401;
3464 }
3465 else if(
3466 KB_KeyPressed( sc_PgDn ) ||
3467 KB_KeyPressed( sc_Enter ) ||
3468 KB_KeyPressed( sc_kpad_Enter ) ||
3469 KB_KeyPressed( sc_RightArrow ) ||
3470 KB_KeyPressed( sc_DownArrow ) ||
3471 KB_KeyPressed( sc_kpad_2 ) ||
3472 KB_KeyPressed( sc_kpad_9 ) ||
3473 KB_KeyPressed( sc_Space ) ||
3474 KB_KeyPressed( sc_kpad_6 ) )
3475 {
3476 KB_ClearKeyDown(sc_PgDn);
3477 KB_ClearKeyDown(sc_Enter);
3478 KB_ClearKeyDown(sc_RightArrow);
3479 KB_ClearKeyDown(sc_kpad_Enter);
3480 KB_ClearKeyDown(sc_kpad_6);
3481 KB_ClearKeyDown(sc_kpad_9);
3482 KB_ClearKeyDown(sc_kpad_2);
3483 KB_ClearKeyDown(sc_DownArrow);
3484 KB_ClearKeyDown(sc_Space);
3485 sound(KICK_HIT);
3486 current_menu++;
3487 if(current_menu > 401) current_menu = 400;
3488 }
3489
3490 if( KB_KeyPressed(sc_Escape) )
3491 {
3492 KB_ClearKeyDown(sc_Escape); // or else ESC will be activated in cmenu(0)
3493 if(ps[myconnectindex].gm&MODE_GAME)
3494 cmenu(50);
3495 else cmenu(0);
3496 return;
3497 }
3498
3499 flushperms();
3500 switch(current_menu)
3501 {
3502 case 400:
3503 rotatesprite(0,0,65536L,0,TEXTSTORY,0,0,10+16+64, 0,0,xdim-1,ydim-1);
3504 break;
3505 case 401:
3506 rotatesprite(0,0,65536L,0,F1HELP,0,0,10+16+64, 0,0,xdim-1,ydim-1);
3507 break;
3508 }
3509 break;
3510 }
3511
3512 case 402:
3513 case 403:
3514 if(VOLUMEONE)
3515 {
3516 c = 320>>1;
3517
3518 if( KB_KeyPressed( sc_LeftArrow ) ||
3519 KB_KeyPressed( sc_kpad_4 ) ||
3520 KB_KeyPressed( sc_UpArrow ) ||
3521 KB_KeyPressed( sc_PgUp ) ||
3522 KB_KeyPressed( sc_kpad_8 ) )
3523 {
3524 KB_ClearKeyDown(sc_LeftArrow);
3525 KB_ClearKeyDown(sc_kpad_4);
3526 KB_ClearKeyDown(sc_UpArrow);
3527 KB_ClearKeyDown(sc_PgUp);
3528 KB_ClearKeyDown(sc_kpad_8);
3529
3530 sound(KICK_HIT);
3531 current_menu--;
3532 if(current_menu < 400) current_menu = 403;
3533 }
3534 else if(
3535 KB_KeyPressed( sc_PgDn ) ||
3536 KB_KeyPressed( sc_Enter ) ||
3537 KB_KeyPressed( sc_kpad_Enter ) ||
3538 KB_KeyPressed( sc_RightArrow ) ||
3539 KB_KeyPressed( sc_DownArrow ) ||
3540 KB_KeyPressed( sc_kpad_2 ) ||
3541 KB_KeyPressed( sc_kpad_9 ) ||
3542 KB_KeyPressed( sc_Space ) ||
3543 KB_KeyPressed( sc_kpad_6 ) )
3544 {
3545 KB_ClearKeyDown(sc_PgDn);
3546 KB_ClearKeyDown(sc_Enter);
3547 KB_ClearKeyDown(sc_RightArrow);
3548 KB_ClearKeyDown(sc_kpad_Enter);
3549 KB_ClearKeyDown(sc_kpad_6);
3550 KB_ClearKeyDown(sc_kpad_9);
3551 KB_ClearKeyDown(sc_kpad_2);
3552 KB_ClearKeyDown(sc_DownArrow);
3553 KB_ClearKeyDown(sc_Space);
3554 sound(KICK_HIT);
3555 current_menu++;
3556 if(current_menu > 403) current_menu = 400;
3557 }
3558
3559 if( KB_KeyPressed(sc_Escape) )
3560 {
3561 if(ps[myconnectindex].gm&MODE_GAME)
3562 cmenu(50);
3563 else cmenu(0);
3564 return;
3565 }
3566
3567 flushperms();
3568 rotatesprite(0,0,65536L,0,ORDERING+current_menu-400,0,0,10+16+64,0,0,xdim-1,ydim-1);
3569 }
3570 break;
3571
3572 case 500: // from f10
3573 case 501: // from menu 0
3574 case 502: // from menu 50
3575
3576 c = 320>>1;
3577
3578 gametext(c,90,"Are you sure you want to quit?",0,2+8+16);
3579 gametext(c,99,"(Y/N)",0,2+8+16);
3580
3581 _handle_events();
3582 if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB )
3583 {
3584 gameexitanycase();
3585 }
3586
3587 x = probe(186,124,0,0);
3588 if(x == -1 || KB_KeyPressed(sc_N) || RMB)
3589 {
3590 KB_ClearKeyDown(sc_N);
3591 quittimer = 0;
3592 // FIX_00073: menu off messed up. While in game hit Esc -> select quit -> press esc => stuck in menu
3593 if (current_menu==500)
3594 ps[myconnectindex].gm &= ~MODE_MENU;
3595 else if(current_menu==501)
3596 cmenu(0);
3597 else
3598 cmenu(50);
3599 }
3600 break;
3601
3602 case 503:
3603 c = 320>>1;
3604 gametext(c,90,"Quit to Title?",0,2+8+16);
3605 gametext(c,99,"(Y/N)",0,2+8+16);
3606
3607 _handle_events();
3608 if( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) || KB_KeyPressed(sc_Y) || LMB )
3609 {
3610 KB_FlushKeyboardQueue();
3611 ps[myconnectindex].gm = MODE_DEMO;
3612 if(ud.recstat == 1)
3613 closedemowrite();
3614 if( ud.m_recstat != 2 && ud.last_level >= 0 && ud.multimode > 1 && ud.coop != 1)
3615 dobonus(1);
3616 ud.last_level = -1;
3617 cmenu(0);
3618 }
3619
3620 x = probe(186,124,0,0);
3621
3622 if(x == -1 || KB_KeyPressed(sc_N) || RMB)
3623 {
3624 cmenu(50);
3625 if(ud.multimode < 2 && ud.recstat != 2)
3626 {
3627 ready2send = 1;
3628 totalclock = ototalclock;
3629 }
3630 }
3631
3632 break;
3633
3634 case 601:
3635 displayfragbar();
3636 rotatesprite(160<<16,29<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
3637 menutext(320>>1,34,0,0,&ud.user_name[myconnectindex][0]);
3638
3639 sprintf((char*)tempbuf,"Waiting for master");
3640 gametext(160,50,(char*)tempbuf,0,2+8+16);
3641 gametext(160,59,"to select level",0,2+8+16);
3642
3643 if( KB_KeyPressed(sc_Escape) )
3644 {
3645 KB_ClearKeyDown(sc_Escape);
3646 sound(EXITMENUSOUND);
3647 cmenu(0);
3648 }
3649 break;
3650
3651 case 602:
3652 if(menunamecnt == 0)
3653 {
3654 // getfilenames("SUBD");
3655 getfilenames("*.MAP");
3656 sortfilenames();
3657 if (menunamecnt == 0)
3658 cmenu(600);
3659 }
3660 case 603:
3661 c = (320>>1) - 120;
3662 displayfragbar();
3663 rotatesprite(320>>1<<16,19<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
3664 menutext(320>>1,24,0,0,"USER MAPS");
3665 for(x=0;x<menunamecnt;x++)
3666 {
3667 if(x == fileselect)
3668 minitext(15 + (x/15)*54,32 + (x%15)*8,menuname[x],0,26);
3669 else minitext(15 + (x/15)*54,32 + (x%15)*8,menuname[x],16,26);
3670 }
3671
3672 fileselect = probey;
3673 if( KB_KeyPressed( sc_LeftArrow ) || KB_KeyPressed( sc_kpad_4 ) || ((buttonstat&1) && minfo.dyaw < -256 ) )
3674 {
3675 KB_ClearKeyDown( sc_LeftArrow );
3676 KB_ClearKeyDown( sc_kpad_4 );
3677 probey -= 15;
3678 if(probey < 0) probey += 15;
3679 else sound(KICK_HIT);
3680 }
3681 if( KB_KeyPressed( sc_RightArrow ) || KB_KeyPressed( sc_kpad_6 ) || ((buttonstat&1) && minfo.dyaw > 256 ) )
3682 {
3683 KB_ClearKeyDown( sc_RightArrow );
3684 KB_ClearKeyDown( sc_kpad_6 );
3685 probey += 15;
3686 if(probey >= menunamecnt)
3687 probey -= 15;
3688 else sound(KICK_HIT);
3689 }
3690
3691 onbar = 0;
3692 x = probe(0,0,0,menunamecnt);
3693
3694 if(x == -1) cmenu(600);
3695 else if(x >= 0)
3696 {
3697 tempbuf[0] = 8;
3698 tempbuf[1] = ud.m_level_number = 6;
3699 tempbuf[2] = ud.m_volume_number = 0;
3700 tempbuf[3] = ud.m_player_skill+1;
3701
3702 if(ud.player_skill == 3)
3703 ud.m_respawn_monsters = 1;
3704 else ud.m_respawn_monsters = 0;
3705
3706 if(ud.m_coop == 0) ud.m_respawn_items = 1;
3707 else ud.m_respawn_items = 0;
3708
3709 ud.m_respawn_inventory = 1;
3710
3711 tempbuf[4] = ud.m_monsters_off;
3712 tempbuf[5] = ud.m_respawn_monsters;
3713 tempbuf[6] = ud.m_respawn_items;
3714 tempbuf[7] = ud.m_respawn_inventory;
3715 tempbuf[8] = ud.m_coop;
3716 tempbuf[9] = ud.m_marker;
3717
3718 x = strlen(menuname[probey]);
3719
3720 copybufbyte(menuname[probey],tempbuf+10,x);
3721 copybufbyte(menuname[probey],boardfilename,x+1);
3722
3723 for(c=connecthead;c>=0;c=connectpoint2[c])
3724 if(c != myconnectindex)
3725 sendpacket(c,(uint8_t*)tempbuf,x+10);
3726
3727 newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill+1);
3728 enterlevel(MODE_GAME);
3729 }
3730 break;
3731
3732 case 600: // multiplayer and bot menu
3733 c = (320>>1) - 120;
3734 if((ps[myconnectindex].gm&MODE_GAME) != MODE_GAME)
3735 displayfragbar();
3736 rotatesprite(160<<16,26<<16,65536L,0,MENUBAR,16,0,10,0,0,xdim-1,ydim-1);
3737 menutext(160,31,0,0,&ud.user_name[myconnectindex][0]);
3738
3739 x = probe(c,57-8,16,8);
3740
3741 switch(x)
3742 {
3743 // FIX_00068: menu "New Game" in multiplayer mode now allowing left/right arrow for selection
3744 case -7: // idle on case 5
3745 if ( KB_KeyPressed( sc_kpad_4 ) || KB_KeyPressed( sc_LeftArrow ) ||
3746 KB_KeyPressed( sc_kpad_6 ) || KB_KeyPressed( sc_RightArrow ))
3747 {
3748 if(ud.m_coop == 1)
3749 ud.m_ffire = !ud.m_ffire;
3750
3751 KB_ClearKeyDown( sc_kpad_4 );
3752 KB_ClearKeyDown( sc_LeftArrow );
3753 KB_ClearKeyDown( sc_kpad_6 );
3754 KB_ClearKeyDown( sc_RightArrow );
3755 sound(PISTOL_BODYHIT);
3756 }
3757 break;
3758
3759 case -6: // idle on case 4
3760 if ( KB_KeyPressed( sc_kpad_4 ) || KB_KeyPressed( sc_LeftArrow ) ||
3761 KB_KeyPressed( sc_kpad_6 ) || KB_KeyPressed( sc_RightArrow ))
3762 {
3763 if(ud.m_coop == 0)
3764 ud.m_marker = !ud.m_marker;
3765
3766 KB_ClearKeyDown( sc_kpad_4 );
3767 KB_ClearKeyDown( sc_LeftArrow );
3768 KB_ClearKeyDown( sc_kpad_6 );
3769 KB_ClearKeyDown( sc_RightArrow );
3770 sound(PISTOL_BODYHIT);
3771 }
3772 break;
3773
3774 case -5: // idle on case 3
3775 if ( KB_KeyPressed( sc_kpad_4 ) || KB_KeyPressed( sc_LeftArrow ) )
3776 {
3777 if(ud.m_monsters_off == 1 && ud.m_player_skill > 0)
3778 ud.m_monsters_off = 0;
3779
3780 if(ud.m_monsters_off == 1)
3781 {
3782 ud.m_monsters_off = 0;
3783 ud.m_player_skill = 3;
3784 }
3785 else
3786 {
3787 ud.m_player_skill--;
3788 if(ud.m_player_skill < 0)
3789 {
3790 ud.m_player_skill = 0;
3791 ud.m_monsters_off = 1;
3792 }
3793 }
3794
3795 KB_ClearKeyDown( sc_kpad_4 );
3796 KB_ClearKeyDown( sc_LeftArrow );
3797 sound(PISTOL_BODYHIT);
3798 }
3799 else if( KB_KeyPressed( sc_kpad_6 ) || KB_KeyPressed( sc_RightArrow ) )
3800 {
3801 if(ud.m_monsters_off == 1 && ud.m_player_skill > 0)
3802 ud.m_monsters_off = 0;
3803
3804 if(ud.m_monsters_off == 0)
3805 {
3806 ud.m_player_skill++;
3807 if(ud.m_player_skill > 3)
3808 {
3809 ud.m_player_skill = 0;
3810 ud.m_monsters_off = 1;
3811 }
3812 }
3813 else
3814 {
3815 ud.m_monsters_off = 0;
3816 ud.m_player_skill = 0;
3817 }
3818
3819 KB_ClearKeyDown( sc_kpad_6 );
3820 KB_ClearKeyDown( sc_RightArrow );
3821 sound(PISTOL_BODYHIT);
3822 }
3823 break;
3824
3825#ifndef ONELEVELDEMO
3826
3827 case -4: // idle on case 2
3828 if ( KB_KeyPressed( sc_kpad_4 ) || KB_KeyPressed( sc_LeftArrow ) )
3829 {
3830 ud.m_level_number--;
3831 if (!VOLUMEONE)
3832 {
3833 if(ud.m_volume_number == 0 && ud.m_level_number < 0)
3834 ud.m_level_number = 6;
3835 }
3836 else
3837 {
3838 if(ud.m_volume_number == 0 && ud.m_level_number < 0)
3839 ud.m_level_number = 5;
3840 }
3841 if(ud.m_level_number < 0) ud.m_level_number = 10;
3842
3843 KB_ClearKeyDown( sc_kpad_4 );
3844 KB_ClearKeyDown( sc_LeftArrow );
3845 sound(PISTOL_BODYHIT);
3846 }
3847 else if ( KB_KeyPressed( sc_kpad_6 ) || KB_KeyPressed( sc_RightArrow ) )
3848 {
3849 ud.m_level_number++;
3850 if (!VOLUMEONE)
3851 {
3852 if(ud.m_volume_number == 0 && ud.m_level_number > 6)
3853 ud.m_level_number = 0;
3854 }
3855 else
3856 {
3857 if(ud.m_volume_number == 0 && ud.m_level_number > 5)
3858 ud.m_level_number = 0;
3859 }
3860 if(ud.m_level_number > 10) ud.m_level_number = 0;
3861
3862 KB_ClearKeyDown( sc_kpad_6 );
3863 KB_ClearKeyDown( sc_RightArrow );
3864 sound(PISTOL_BODYHIT);
3865 }
3866 break;
3867#endif
3868
3869 case -3: // Idle on case 1
3870 if (!VOLUMEONE)
3871 {
3872 if ( KB_KeyPressed( sc_kpad_4 ) || KB_KeyPressed( sc_LeftArrow ) )
3873 {
3874 ud.m_volume_number--;
3875 if(PLUTOPAK)
3876 { if(ud.m_volume_number < 0 ) ud.m_volume_number = 3; }
3877 else
3878 { if(ud.m_volume_number < 0) ud.m_volume_number = 2; }
3879
3880 if(ud.m_volume_number == 0 && ud.m_level_number > 6)
3881 ud.m_level_number = 0;
3882 if(ud.m_level_number > 10) ud.m_level_number = 0;
3883
3884 KB_ClearKeyDown( sc_kpad_4 );
3885 KB_ClearKeyDown( sc_LeftArrow );
3886 sound(PISTOL_BODYHIT);
3887 }
3888 else if( KB_KeyPressed( sc_kpad_6 ) || KB_KeyPressed( sc_RightArrow ) )
3889 {
3890 ud.m_volume_number++;
3891 if(PLUTOPAK)
3892 { if(ud.m_volume_number > 3) ud.m_volume_number = 0; }
3893 else
3894 { if(ud.m_volume_number > 2) ud.m_volume_number = 0; }
3895
3896 if(ud.m_volume_number == 0 && ud.m_level_number > 6)
3897 ud.m_level_number = 0;
3898 if(ud.m_level_number > 10) ud.m_level_number = 0;
3899
3900 KB_ClearKeyDown( sc_kpad_6 );
3901 KB_ClearKeyDown( sc_RightArrow );
3902 sound(PISTOL_BODYHIT);
3903 }
3904 }
3905 break;
3906
3907 case -2: // Idle on case 0
3908 if ( KB_KeyPressed( sc_kpad_4 ) || KB_KeyPressed( sc_LeftArrow ) )
3909 {
3910 ud.m_coop--;
3911 if(ud.m_coop == -1) ud.m_coop = 2;
3912
3913 KB_ClearKeyDown( sc_kpad_4 );
3914 KB_ClearKeyDown( sc_LeftArrow );
3915 sound(PISTOL_BODYHIT);
3916 }
3917 else if( KB_KeyPressed( sc_kpad_6 ) || KB_KeyPressed( sc_RightArrow ) )
3918 {
3919 ud.m_coop++;
3920 if(ud.m_coop == 3) ud.m_coop = 0;
3921
3922 KB_ClearKeyDown( sc_kpad_6 );
3923 KB_ClearKeyDown( sc_RightArrow );
3924 sound(PISTOL_BODYHIT);
3925 }
3926 break;
3927
3928 case -1:
3929 ud.m_recstat = 0;
3930 if(ps[myconnectindex].gm&MODE_GAME) cmenu(50);
3931 else cmenu(0);
3932 break;
3933 case 0:
3934 ud.m_coop++;
3935 if(ud.m_coop == 3) ud.m_coop = 0;
3936 break;
3937 case 1:
3938 if (!VOLUMEONE)
3939 { ud.m_volume_number++;
3940 if(PLUTOPAK)
3941 { if(ud.m_volume_number > 3) ud.m_volume_number = 0; }
3942 else
3943 { if(ud.m_volume_number > 2) ud.m_volume_number = 0; }
3944
3945 if(ud.m_volume_number == 0 && ud.m_level_number > 6)
3946 ud.m_level_number = 0;
3947 if(ud.m_level_number > 10) ud.m_level_number = 0;
3948 }
3949 break;
3950 case 2:
3951#ifndef ONELEVELDEMO
3952 ud.m_level_number++;
3953 if (!VOLUMEONE)
3954 {
3955 if(ud.m_volume_number == 0 && ud.m_level_number > 6)
3956 ud.m_level_number = 0;
3957 }
3958 else
3959 {
3960 if(ud.m_volume_number == 0 && ud.m_level_number > 5)
3961 ud.m_level_number = 0;
3962 }
3963 if(ud.m_level_number > 10) ud.m_level_number = 0;
3964#endif
3965 break;
3966 case 3:
3967 if(ud.m_monsters_off == 1 && ud.m_player_skill > 0)
3968 ud.m_monsters_off = 0;
3969
3970 if(ud.m_monsters_off == 0)
3971 {
3972 ud.m_player_skill++;
3973 if(ud.m_player_skill > 3)
3974 {
3975 ud.m_player_skill = 0;
3976 ud.m_monsters_off = 1;
3977 }
3978 }
3979 else
3980 {
3981 ud.m_monsters_off = 0;
3982 ud.m_player_skill = 0;
3983 }
3984
3985 break;
3986
3987 case 4:
3988 if(ud.m_coop == 0)
3989 ud.m_marker = !ud.m_marker;
3990 break;
3991
3992 case 5:
3993 if(ud.m_coop == 1)
3994 ud.m_ffire = !ud.m_ffire;
3995 break;
3996
3997 case 6: // select user map
3998 if(!VOLUMEONE)
3999 { if(boardfilename[0] == 0) break;
4000
4001 tempbuf[0] = 5;
4002 tempbuf[1] = ud.m_level_number = 7;
4003 tempbuf[2] = ud.m_volume_number = 0;
4004 tempbuf[3] = ud.m_player_skill+1;
4005
4006 ud.level_number = ud.m_level_number;
4007 ud.volume_number = ud.m_volume_number;
4008
4009 if( ud.m_player_skill == 3 ) ud.m_respawn_monsters = 1;
4010 else ud.m_respawn_monsters = 0;
4011
4012 if(ud.m_coop == 0) ud.m_respawn_items = 1;
4013 else ud.m_respawn_items = 0;
4014
4015 ud.m_respawn_inventory = 1;
4016
4017 tempbuf[4] = ud.m_monsters_off;
4018 tempbuf[5] = ud.m_respawn_monsters;
4019 tempbuf[6] = ud.m_respawn_items;
4020 tempbuf[7] = ud.m_respawn_inventory;
4021 tempbuf[8] = ud.m_coop;
4022 tempbuf[9] = ud.m_marker;
4023 tempbuf[10] = ud.m_ffire;
4024
4025 for(c=connecthead;c>=0;c=connectpoint2[c])
4026 {
4027 resetweapons(c);
4028 resetinventory(c);
4029
4030 if(c != myconnectindex)
4031 sendpacket(c,(uint8_t*)tempbuf,11);
4032 }
4033
4034 newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill+1);
4035 enterlevel(MODE_GAME);
4036
4037 return;
4038 }
4039 case 7: // start game
4040
4041 tempbuf[0] = 5;
4042 tempbuf[1] = ud.m_level_number;
4043 tempbuf[2] = ud.m_volume_number;
4044 tempbuf[3] = ud.m_player_skill+1;
4045
4046 if( ud.m_player_skill == 3 ) ud.m_respawn_monsters = 1;
4047 else ud.m_respawn_monsters = 0;
4048
4049 if(ud.m_coop == 0) ud.m_respawn_items = 1;
4050 else ud.m_respawn_items = 0;
4051
4052 ud.m_respawn_inventory = 1;
4053
4054 tempbuf[4] = ud.m_monsters_off;
4055 tempbuf[5] = ud.m_respawn_monsters;
4056 tempbuf[6] = ud.m_respawn_items;
4057 tempbuf[7] = ud.m_respawn_inventory;
4058 tempbuf[8] = ud.m_coop;
4059 tempbuf[9] = ud.m_marker;
4060 tempbuf[10] = ud.m_ffire;
4061
4062 for(c=connecthead;c>=0;c=connectpoint2[c])
4063 {
4064 resetweapons(c);
4065 resetinventory(c);
4066
4067 if(c != myconnectindex)
4068 sendpacket(c,(uint8_t*)tempbuf,11);
4069 }
4070
4071 newgame(ud.m_volume_number,ud.m_level_number,ud.m_player_skill+1);
4072 enterlevel(MODE_GAME);
4073
4074 return;
4075
4076 }
4077
4078 c += 40;
4079
4080 if(ud.m_coop==1) gametext(c+70,57-7-9,"COOPERATIVE PLAY",0,2+8+16);
4081 else if(ud.m_coop==2) gametext(c+70,57-7-9,"DUKEMATCH (NO SPAWN)",0,2+8+16);
4082 else gametext(c+70,57-7-9,"DUKEMATCH (SPAWN)",0,2+8+16);
4083
4084 if(VOLUMEONE)
4085 gametext(c+70,57+16-7-9,volume_names[ud.m_volume_number],0,2+8+16);
4086 else
4087 gametext(c+70,57+16-7-9,volume_names[ud.m_volume_number],0,2+8+16);
4088
4089 gametext(c+70,57+16+16-7-9,&level_names[11*ud.m_volume_number+ud.m_level_number][0],0,2+8+16);
4090
4091 if(ud.m_monsters_off == 0 || ud.m_player_skill > 0)
4092 gametext(c+70,57+16+16+16-7-9,skill_names[ud.m_player_skill],0,2+8+16);
4093 else gametext(c+70,57+16+16+16-7-9,"NONE",0,2+8+16);
4094
4095 if(ud.m_coop == 0)
4096 {
4097 if(ud.m_marker)
4098 gametext(c+70,57+16+16+16+16-7-9,"ON",0,2+8+16);
4099 else gametext(c+70,57+16+16+16+16-7-9,"OFF",0,2+8+16);
4100 }
4101
4102 if(ud.m_coop == 1)
4103 {
4104 if(ud.m_ffire)
4105 gametext(c+70,57+16+16+16+16+16-7-9,"ON",0,2+8+16);
4106 else gametext(c+70,57+16+16+16+16+16-7-9,"OFF",0,2+8+16);
4107 }
4108
4109 c -= 44;
4110
4111 menutext(c,57-9,SHX(-2),PHX(-2),"GAME TYPE");
4112
4113 if (VOLUMEONE)
4114 { sprintf(text,"EPISODE %d",ud.m_volume_number+1);
4115 menutext(c,57+16-9,SHX(-3),1,text);
4116 }
4117 else
4118 {
4119 sprintf(text,"EPISODE %d",ud.m_volume_number+1);
4120 menutext(c,57+16-9,SHX(-3),PHX(-3),text);
4121 }
4122
4123#ifndef ONELEVELDEMO
4124 sprintf(text,"LEVEL %d",ud.m_level_number+1);
4125 menutext(c,57+16+16-9,SHX(-4),PHX(-4),text);
4126#else
4127 sprintf(text,"LEVEL %d",ud.m_level_number+1);
4128 menutext(c,57+16+16-9,SHX(-4),1,text);
4129#endif
4130 menutext(c,57+16+16+16-9,SHX(-5),PHX(-5),"MONSTERS");
4131
4132 if(ud.m_coop == 0)
4133 menutext(c,57+16+16+16+16-9,SHX(-6),PHX(-6),"MARKERS");
4134 else
4135 menutext(c,57+16+16+16+16-9,SHX(-6),1,"MARKERS");
4136
4137 if(ud.m_coop == 1)
4138 menutext(c,57+16+16+16+16+16-9,SHX(-6),PHX(-6),"FR. FIRE");
4139 else menutext(c,57+16+16+16+16+16-9,SHX(-6),1,"FR. FIRE");
4140
4141 if(!VOLUMEONE)
4142 { menutext(c,57+16+16+16+16+16+16-9,SHX(-7),boardfilename[0] == 0,"USER MAP");
4143 if( boardfilename[0] != 0 )
4144 gametext(c+70+44,57+16+16+16+16+16,boardfilename,0,2+8+16);
4145 }
4146 else
4147 {
4148 menutext(c,57+16+16+16+16+16+16-9,SHX(-7),1,"USER MAP");
4149 }
4150
4151 menutext(c,57+16+16+16+16+16+16+16-9,SHX(-8),PHX(-8),"START GAME");
4152
4153 break;
4154 }
4155
4156 if( (ps[myconnectindex].gm&MODE_MENU) != MODE_MENU)
4157 {
4158 vscrn();
4159 cameraclock = totalclock;
4160 cameradist = 65536L;
4161 }
4162}
4163
4164void palto(uint8_t r,uint8_t g,uint8_t b,int32_t e)
4165{
4166 int i;
4167 uint8_t temparray[768];
4168
4169 for(i=0;i<(256*3);i+=3)
4170 {
4171 temparray[i ] =ps[myconnectindex].palette[i+0]+((((int32_t)r-(int32_t)ps[myconnectindex].palette[i+0])*(int32_t)(e&127))>>6);
4172 temparray[i+1] =ps[myconnectindex].palette[i+1]+((((int32_t)g-(int32_t)ps[myconnectindex].palette[i+1])*(int32_t)(e&127))>>6);
4173 temparray[i+2] =ps[myconnectindex].palette[i+2]+((((int32_t)b-(int32_t)ps[myconnectindex].palette[i+2])*(int32_t)(e&127))>>6);
4174 }
4175
4176 setbrightness(ud.brightness>>2,temparray);
4177}
4178
4179
4180void drawoverheadmap(int32_t cposx, int32_t cposy, int32_t czoom, short cang)
4181{
4182 int32_t i, j, k, l, x1, y1, x2, y2, x3, y3, x4, y4, ox, oy, xoff, yoff;
4183 int32_t dax, day, cosang, sinang, xspan, yspan, sprx, spry;
4184 int32_t xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang;
4185 int32_t xvect, yvect, xvect2, yvect2;
4186 short p;
4187 uint8_t col;
4188 walltype *wal, *wal2;
4189 spritetype *spr;
4190
4191 xvect = sintable[(-cang)&2047] * czoom;
4192 yvect = sintable[(1536-cang)&2047] * czoom;
4193 xvect2 = mulscale16(xvect,yxaspect);
4194 yvect2 = mulscale16(yvect,yxaspect);
4195
4196 //Draw red lines
4197 for(i=0;i<numsectors;i++)
4198 {
4199 if (!(show2dsector[i>>3]&(1<<(i&7)))) continue;
4200
4201 startwall = sector[i].wallptr;
4202 endwall = sector[i].wallptr + sector[i].wallnum;
4203
4204 z1 = sector[i].ceilingz; z2 = sector[i].floorz;
4205
4206 for(j=startwall,wal=&wall[startwall];j<endwall;j++,wal++)
4207 {
4208 k = wal->nextwall; if (k < 0) continue;
4209
4210 //if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue;
4211 //if ((k > j) && ((show2dwall[k>>3]&(1<<(k&7))) > 0)) continue;
4212
4213 if (sector[wal->nextsector].ceilingz == z1)
4214 if (sector[wal->nextsector].floorz == z2)
4215 if (((wal->cstat|wall[wal->nextwall].cstat)&(16+32)) == 0) continue;
4216
4217 col = 139; //red
4218 if ((wal->cstat|wall[wal->nextwall].cstat)&1) col = 234; //magenta
4219
4220 if (!(show2dsector[wal->nextsector>>3]&(1<<(wal->nextsector&7))))
4221 col = 24;
4222 else continue;
4223
4224 ox = wal->x-cposx; oy = wal->y-cposy;
4225 x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11);
4226 y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11);
4227
4228 wal2 = &wall[wal->point2];
4229 ox = wal2->x-cposx; oy = wal2->y-cposy;
4230 x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11);
4231 y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11);
4232
4233 drawline256(x1,y1,x2,y2,col);
4234 }
4235 }
4236
4237 //Draw sprites
4238 k = ps[screenpeek].i;
4239 for(i=0;i<numsectors;i++)
4240 {
4241 if (!(show2dsector[i>>3]&(1<<(i&7)))) continue;
4242 for(j=headspritesect[i];j>=0;j=nextspritesect[j])
4243 //if ((show2dsprite[j>>3]&(1<<(j&7))) > 0)
4244 {
4245 spr = &sprite[j];
4246
4247 if (j == k || (spr->cstat&0x8000) || spr->cstat == 257 || spr->xrepeat == 0) continue;
4248
4249 col = 71; //cyan
4250 if (spr->cstat&1) col = 234; //magenta
4251
4252 sprx = spr->x;
4253 spry = spr->y;
4254
4255 if( (spr->cstat&257) != 0) switch (spr->cstat&48)
4256 {
4257 case 0: break;
4258 ox = sprx-cposx; oy = spry-cposy;
4259 x1 = dmulscale16(ox,xvect,-oy,yvect);
4260 y1 = dmulscale16(oy,xvect2,ox,yvect2);
4261
4262 ox = (sintable[(spr->ang+512)&2047]>>7);
4263 oy = (sintable[(spr->ang)&2047]>>7);
4264 x2 = dmulscale16(ox,xvect,-oy,yvect);
4265 y2 = dmulscale16(oy,xvect,ox,yvect);
4266
4267 x3 = mulscale16(x2,yxaspect);
4268 y3 = mulscale16(y2,yxaspect);
4269
4270 drawline256(x1-x2+(xdim<<11),y1-y3+(ydim<<11),
4271 x1+x2+(xdim<<11),y1+y3+(ydim<<11),col);
4272 drawline256(x1-y2+(xdim<<11),y1+x3+(ydim<<11),
4273 x1+x2+(xdim<<11),y1+y3+(ydim<<11),col);
4274 drawline256(x1+y2+(xdim<<11),y1-x3+(ydim<<11),
4275 x1+x2+(xdim<<11),y1+y3+(ydim<<11),col);
4276 break;
4277
4278 case 16:
4279 if( spr->picnum == LASERLINE )
4280 {
4281 x1 = sprx; y1 = spry;
4282 tilenum = spr->picnum;
4283 xoff = (int32_t)((int8_t )((tiles[tilenum].animFlags>>8)&255))+((int32_t)spr->xoffset);
4284 if ((spr->cstat&4) > 0)
4285 xoff = -xoff;
4286 k = spr->ang; l = spr->xrepeat;
4287 dax = sintable[k&2047]*l; day = sintable[(k+1536)&2047]*l;
4288 l = tiles[tilenum].dim.width;
4289 k = (l>>1)+xoff;
4290 x1 -= mulscale16(dax,k);
4291 x2 = x1+mulscale16(dax,l);
4292 y1 -= mulscale16(day,k);
4293 y2 = y1+mulscale16(day,l);
4294
4295 ox = x1-cposx; oy = y1-cposy;
4296 x1 = dmulscale16(ox,xvect,-oy,yvect);
4297 y1 = dmulscale16(oy,xvect2,ox,yvect2);
4298
4299 ox = x2-cposx; oy = y2-cposy;
4300 x2 = dmulscale16(ox,xvect,-oy,yvect);
4301 y2 = dmulscale16(oy,xvect2,ox,yvect2);
4302
4303 drawline256(x1+(xdim<<11),y1+(ydim<<11),
4304 x2+(xdim<<11),y2+(ydim<<11),col);
4305 }
4306
4307 break;
4308
4309 case 32:
4310
4311 tilenum = spr->picnum;
4312 xoff = (int32_t)((int8_t )((tiles[tilenum].animFlags>>8)&255))+((int32_t)spr->xoffset);
4313 yoff = (int32_t)((int8_t )((tiles[tilenum].animFlags>>16)&255))+((int32_t)spr->yoffset);
4314 if ((spr->cstat&4) > 0) xoff = -xoff;
4315 if ((spr->cstat&8) > 0) yoff = -yoff;
4316
4317 k = spr->ang;
4318 cosang = sintable[(k+512)&2047];
4319 sinang = sintable[k];
4320 xspan = tiles[tilenum].dim.width;
4321 xrepeat = spr->xrepeat;
4322 yspan = tiles[tilenum].dim.height;
4323 yrepeat = spr->yrepeat;
4324
4325 dax = ((xspan>>1)+xoff)*xrepeat; day = ((yspan>>1)+yoff)*yrepeat;
4326 x1 = sprx + dmulscale16(sinang,dax,cosang,day);
4327 y1 = spry + dmulscale16(sinang,day,-cosang,dax);
4328 l = xspan*xrepeat;
4329 x2 = x1 - mulscale16(sinang,l);
4330 y2 = y1 + mulscale16(cosang,l);
4331 l = yspan*yrepeat;
4332 k = -mulscale16(cosang,l); x3 = x2+k; x4 = x1+k;
4333 k = -mulscale16(sinang,l); y3 = y2+k; y4 = y1+k;
4334
4335 ox = x1-cposx; oy = y1-cposy;
4336 x1 = dmulscale16(ox,xvect,-oy,yvect);
4337 y1 = dmulscale16(oy,xvect2,ox,yvect2);
4338
4339 ox = x2-cposx; oy = y2-cposy;
4340 x2 = dmulscale16(ox,xvect,-oy,yvect);
4341 y2 = dmulscale16(oy,xvect2,ox,yvect2);
4342
4343 ox = x3-cposx; oy = y3-cposy;
4344 x3 = dmulscale16(ox,xvect,-oy,yvect);
4345 y3 = dmulscale16(oy,xvect2,ox,yvect2);
4346
4347 ox = x4-cposx; oy = y4-cposy;
4348 x4 = dmulscale16(ox,xvect,-oy,yvect);
4349 y4 = dmulscale16(oy,xvect2,ox,yvect2);
4350
4351 drawline256(x1+(xdim<<11),y1+(ydim<<11),
4352 x2+(xdim<<11),y2+(ydim<<11),col);
4353
4354 drawline256(x2+(xdim<<11),y2+(ydim<<11),
4355 x3+(xdim<<11),y3+(ydim<<11),col);
4356
4357 drawline256(x3+(xdim<<11),y3+(ydim<<11),
4358 x4+(xdim<<11),y4+(ydim<<11),col);
4359
4360 drawline256(x4+(xdim<<11),y4+(ydim<<11),
4361 x1+(xdim<<11),y1+(ydim<<11),col);
4362
4363 break;
4364 }
4365 }
4366 }
4367
4368 //Draw white lines
4369 for(i=0;i<numsectors;i++)
4370 {
4371 if (!(show2dsector[i>>3]&(1<<(i&7)))) continue;
4372
4373 startwall = sector[i].wallptr;
4374 endwall = sector[i].wallptr + sector[i].wallnum;
4375
4376 k = -1;
4377 for(j=startwall,wal=&wall[startwall];j<endwall;j++,wal++)
4378 {
4379 if (wal->nextwall >= 0) continue;
4380
4381 //if ((show2dwall[j>>3]&(1<<(j&7))) == 0) continue;
4382
4383 if (tiles[wal->picnum].dim.width == 0)
4384 continue;
4385 if (tiles[wal->picnum].dim.height== 0)
4386 continue;
4387
4388 if (j == k)
4389 { x1 = x2; y1 = y2; }
4390 else
4391 {
4392 ox = wal->x-cposx; oy = wal->y-cposy;
4393 x1 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11);
4394 y1 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11);
4395 }
4396
4397 k = wal->point2; wal2 = &wall[k];
4398 ox = wal2->x-cposx; oy = wal2->y-cposy;
4399 x2 = dmulscale16(ox,xvect,-oy,yvect)+(xdim<<11);
4400 y2 = dmulscale16(oy,xvect2,ox,yvect2)+(ydim<<11);
4401
4402 drawline256(x1,y1,x2,y2,24);
4403 }
4404 }
4405
4406 for(p=connecthead;p >= 0;p=connectpoint2[p])
4407 {
4408 if(ud.scrollmode && p == screenpeek) continue;
4409
4410 ox = sprite[ps[p].i].x-cposx; oy = sprite[ps[p].i].y-cposy;
4411 daang = (sprite[ps[p].i].ang-cang)&2047;
4412 if (p == screenpeek) { ox = 0; oy = 0; daang = 0; }
4413 x1 = mulscale(ox,xvect,16) - mulscale(oy,yvect,16);
4414 y1 = mulscale(oy,xvect2,16) + mulscale(ox,yvect2,16);
4415
4416 if(p == screenpeek || ud.coop == 1 )
4417 {
4418 if(sprite[ps[p].i].xvel > 16 && ps[p].on_ground)
4419 i = APLAYERTOP+((totalclock>>4)&3);
4420 else
4421 i = APLAYERTOP;
4422
4423 j = klabs(ps[p].truefz-ps[p].posz)>>8;
4424 j = mulscale(czoom*(sprite[ps[p].i].yrepeat+j),yxaspect,16);
4425
4426 if(j < 22000) j = 22000;
4427 else if(j > (65536<<1)) j = (65536<<1);
4428
4429 rotatesprite((x1<<4)+(xdim<<15),(y1<<4)+(ydim<<15),j,
4430 daang,i,sprite[ps[p].i].shade,sprite[ps[p].i].pal,
4431 (sprite[ps[p].i].cstat&2)>>1,windowx1,windowy1,windowx2,windowy2);
4432 }
4433 }
4434}
4435
4436
4437
4438void endanimsounds(int32_t fr)
4439{
4440 switch(ud.volume_number)
4441 {
4442 case 0:break;
4443 case 1:
4444 switch(fr)
4445 {
4446 case 1:
4447 sound(WIND_AMBIENCE);
4448 break;
4449 case 26:
4450 sound(ENDSEQVOL2SND1);
4451 break;
4452 case 36:
4453 sound(ENDSEQVOL2SND2);
4454 break;
4455 case 54:
4456 sound(THUD);
4457 break;
4458 case 62:
4459 sound(ENDSEQVOL2SND3);
4460 break;
4461 case 75:
4462 sound(ENDSEQVOL2SND4);
4463 break;
4464 case 81:
4465 sound(ENDSEQVOL2SND5);
4466 break;
4467 case 115:
4468 sound(ENDSEQVOL2SND6);
4469 break;
4470 case 124:
4471 sound(ENDSEQVOL2SND7);
4472 break;
4473 }
4474 break;
4475 case 2:
4476 switch(fr)
4477 {
4478 case 1:
4479 sound(WIND_REPEAT);
4480 break;
4481 case 98:
4482 sound(DUKE_GRUNT);
4483 break;
4484 case 82+20:
4485 sound(THUD);
4486 sound(SQUISHED);
4487 break;
4488 case 104+20:
4489 sound(ENDSEQVOL3SND3);
4490 break;
4491 case 114+20:
4492 sound(ENDSEQVOL3SND2);
4493 break;
4494 case 158:
4495 sound(PIPEBOMB_EXPLODE);
4496 break;
4497 }
4498 break;
4499 }
4500}
4501
4502void logoanimsounds(int32_t fr)
4503{
4504 switch(fr)
4505 {
4506 case 1:
4507 sound(FLY_BY);
4508 break;
4509 case 19:
4510 sound(PIPEBOMB_EXPLODE);
4511 break;
4512 }
4513}
4514
4515void intro4animsounds(int32_t fr)
4516{
4517 switch(fr)
4518 {
4519 case 1:
4520 sound(INTRO4_B);
4521 break;
4522 case 12:
4523 case 34:
4524 sound(SHORT_CIRCUIT);
4525 break;
4526 case 18:
4527 sound(INTRO4_5);
4528 break;
4529 }
4530}
4531
4532void first4animsounds(int32_t fr)
4533{
4534 switch(fr)
4535 {
4536 case 1:
4537 sound(INTRO4_1);
4538 break;
4539 case 12:
4540 sound(INTRO4_2);
4541 break;
4542 case 7:
4543 sound(INTRO4_3);
4544 break;
4545 case 26:
4546 sound(INTRO4_4);
4547 break;
4548 }
4549}
4550
4551void intro42animsounds(int32_t fr)
4552{
4553 switch(fr)
4554 {
4555 case 10:
4556 sound(INTRO4_6);
4557 break;
4558 }
4559}
4560
4561
4562
4563
4564void endanimvol41(int32_t fr)
4565{
4566 switch(fr)
4567 {
4568 case 3:
4569 sound(DUKE_UNDERWATER);
4570 break;
4571 case 35:
4572 sound(VOL4ENDSND1);
4573 break;
4574 }
4575}
4576
4577void endanimvol42(int32_t fr)
4578{
4579 switch(fr)
4580 {
4581 case 11:
4582 sound(DUKE_UNDERWATER);
4583 break;
4584 case 20:
4585 sound(VOL4ENDSND1);
4586 break;
4587 case 39:
4588 sound(VOL4ENDSND2);
4589 break;
4590 case 50:
4591 FX_StopAllSounds();
4592 break;
4593 }
4594}
4595
4596void endanimvol43(int32_t fr)
4597{
4598 switch(fr)
4599 {
4600 case 1:
4601 sound(BOSS4_DEADSPEECH);
4602 break;
4603 case 40:
4604 sound(VOL4ENDSND1);
4605 sound(DUKE_UNDERWATER);
4606 break;
4607 case 50:
4608 sound(BIGBANG);
4609 break;
4610 }
4611}
4612
4613
4614int32_t lastanimhack=0;
4615void playanm(char *fn,uint8_t t)
4616{
4617 uint8_t *animbuf, *palptr;
4618 int32_t i, j, k, length=0, numframes=0;
4619 int32 handle=-1;
4620
4621 if(t != 7 && t != 9 && t != 10 && t != 11)
4622 KB_FlushKeyboardQueue();
4623
4624 if( KB_KeyWaiting() )
4625 {
4626 FX_StopAllSounds();
4627 goto ENDOFANIMLOOP;
4628 }
4629
4630 handle = TCkopen4load(fn,0);
4631
4632 if(handle == -1)
4633 return;
4634
4635 length = kfilelength(handle);
4636
4637 tiles[MAXTILES-3-t].lock = 219+t;
4638
4639 if(anim == 0 || lastanimhack != (MAXTILES-3-t))
4640 allocache((uint8_t**)&anim,length+sizeof(anim_t),&tiles[MAXTILES-3-t].lock);
4641
4642 animbuf = (uint8_t *)(anim)+sizeof(anim_t);
4643
4644 lastanimhack = (MAXTILES-3-t);
4645
4646 tiles[MAXTILES-3-t].dim.width = 200;
4647 tiles[MAXTILES-3-t].dim.height = 320;
4648
4649 kread(handle,animbuf,length);
4650 kclose(handle);
4651
4652 ANIM_LoadAnim (animbuf);
4653 numframes = ANIM_NumFrames();
4654
4655 palptr = ANIM_GetPalette();
4656 for(i=0;i<256;i++)
4657 {
4658 j = (i<<2); k = j-i;
4659 tempbuf[j+0] = (palptr[k+2]>>2);
4660 tempbuf[j+1] = (palptr[k+1]>>2);
4661 tempbuf[j+2] = (palptr[k+0]>>2);
4662 tempbuf[j+3] = 0;
4663 }
4664
4665 VBE_setPalette(tempbuf);
4666
4667 ototalclock = totalclock + 10;
4668
4669 for(i=1;i<numframes;i++)
4670 {
4671 //rb->splashf(HZ, "%d/%d", i, numframes);
4672 while(totalclock < ototalclock)
4673 {
4674 if( KB_KeyWaiting() )
4675 goto ENDOFANIMLOOP;
4676 getpackets();
4677 }
4678
4679 if(t == 10) ototalclock += 14;
4680 else if(t == 9) ototalclock += 10;
4681 else if(t == 7) ototalclock += 18;
4682 else if(t == 6) ototalclock += 14;
4683 else if(t == 5) ototalclock += 9;
4684 else if(ud.volume_number == 3) ototalclock += 10;
4685 else if(ud.volume_number == 2) ototalclock += 10;
4686 else if(ud.volume_number == 1) ototalclock += 18;
4687 else ototalclock += 10;
4688
4689 tiles[MAXTILES-3-t].data = ANIM_DrawFrame(i);
4690 rotatesprite(0<<16,0<<16,65536L,512,MAXTILES-3-t,0,0,2+4+8+16+64, 0,0,xdim-1,ydim-1);
4691 nextpage();
4692
4693 if(t == 8) endanimvol41(i);
4694 else if(t == 10) endanimvol42(i);
4695 else if(t == 11) endanimvol43(i);
4696 else if(t == 9) intro42animsounds(i);
4697 else if(t == 7) intro4animsounds(i);
4698 else if(t == 6) first4animsounds(i);
4699 else if(t == 5) logoanimsounds(i);
4700 else if(t < 4) endanimsounds(i);
4701 }
4702
4703ENDOFANIMLOOP:
4704
4705 ANIM_FreeAnim ();
4706 tiles[MAXTILES-3-t].lock = 1;
4707}
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/midi/sdl_midi.c b/apps/plugins/sdl/progs/duke3d/Game/src/midi/sdl_midi.c
new file mode 100644
index 0000000000..36fd6f61fa
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/midi/sdl_midi.c
@@ -0,0 +1,191 @@
1//
2// sdl_midi.c
3// Duke3D
4//
5// Created by fabien sanglard on 12-12-15.
6// Copyright (c) 2012 fabien sanglard. All rights reserved.
7//
8
9#include <stdio.h>
10#include "../audiolib/music.h"
11#include "SDL.h"
12#include "SDL_mixer.h"
13#include "../../../Engine/src/build.h"
14
15/*
16 Because the music is stored in a GRP file that is never fully loaded in RAM
17 (the full version of Duke Nukem 3D is a 43MB GRP) we need to extract the music
18 from it and store it in RAM.
19*/
20#define KILOBYTE (1024)
21uint8_t musicDataBuffer[100 * KILOBYTE];
22
23char *MUSIC_ErrorString(int ErrorNumber)
24{
25 return "";
26}
27
28int MUSIC_Init(int SoundCard, int Address)
29{
30 if(Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024)==-1) {
31 printf("Mix_OpenAudio: %s\n", Mix_GetError());
32 }
33
34 return MUSIC_Ok;
35}
36
37int MUSIC_Shutdown(void)
38{
39 MUSIC_StopSong();
40 return(MUSIC_Ok);
41}
42
43void MUSIC_SetMaxFMMidiChannel(int channel)
44{
45}
46
47void MUSIC_SetVolume(int volume)
48{
49 Mix_VolumeMusic((int)(volume / 2));
50}
51
52void MUSIC_SetMidiChannelVolume(int channel, int volume)
53{
54}
55
56void MUSIC_ResetMidiChannelVolumes(void)
57{
58}
59
60int MUSIC_GetVolume(void)
61{
62 return 0;
63}
64
65void MUSIC_SetLoopFlag(int loopflag)
66{
67}
68
69int MUSIC_SongPlaying(void)
70{
71 return Mix_PlayingMusic();
72}
73
74void MUSIC_Continue(void)
75{
76 if (Mix_PausedMusic())
77 Mix_ResumeMusic();
78}
79
80void MUSIC_Pause(void)
81{
82 Mix_PauseMusic();
83}
84
85int MUSIC_StopSong(void)
86{
87 if ( (Mix_PlayingMusic()) || (Mix_PausedMusic()) )
88 Mix_HaltMusic();
89
90 return(MUSIC_Ok);
91}
92
93
94
95int MUSIC_PlaySong(char *songFilename, int loopflag)
96{
97 int32_t fd = 0;
98 int fileSize;
99 SDL_RWops *rw;
100 Mix_Music* sdlMusic;
101
102 fd = kopen4load(songFilename,0);
103
104 if(fd < 0){
105 printf("The music '%s' cannot be found in the GRP or the filesystem.\n",songFilename);
106 return 0;
107 }
108
109
110
111 fileSize = kfilelength( fd );
112 if(fileSize >= sizeof(musicDataBuffer))
113 {
114 printf("The music '%s' was found but is too big (%dKB)to fit in the buffer (%luKB).\n",songFilename,fileSize/1024,sizeof(musicDataBuffer)/1024);
115 kclose(fd);
116 return 0;
117 }
118
119 kread( fd, musicDataBuffer, fileSize);
120 kclose( fd );
121
122 //Ok, the file is in memory
123 rw = SDL_RWFromMem((void *) musicDataBuffer, fileSize);
124
125 sdlMusic = Mix_LoadMUS_RW(rw);
126 if(!sdlMusic)
127 printf("Mixer ERROR: %s", Mix_GetError());
128
129 Mix_PlayMusic(sdlMusic, (loopflag == MUSIC_PlayOnce) ? 0 : -1);
130
131 return 1;
132}
133
134
135void MUSIC_SetContext(int context)
136{
137}
138
139int MUSIC_GetContext(void)
140{
141 return 0;
142}
143
144void MUSIC_SetSongTick(uint32_t PositionInTicks)
145{
146}
147
148void MUSIC_SetSongTime(uint32_t milliseconds)
149{
150}
151
152void MUSIC_SetSongPosition(int measure, int beat, int tick)
153{
154}
155
156void MUSIC_GetSongPosition(songposition *pos)
157{
158}
159
160void MUSIC_GetSongLength(songposition *pos)
161{
162}
163
164int MUSIC_FadeVolume(int tovolume, int milliseconds)
165{
166 return(MUSIC_Ok);
167}
168
169int MUSIC_FadeActive(void)
170{
171 return 0;
172}
173
174void MUSIC_StopFade(void)
175
176{
177}
178
179void MUSIC_RerouteMidiChannel(int channel, int cdecl function( int event, int c1, int c2 ))
180{
181}
182
183void MUSIC_RegisterTimbreBank(uint8_t *timbres)
184{
185}
186
187// This is the method called from the Game Module.
188void PlayMusic(char *fileName){
189 LOGF("===== MUSIC ===== (%s)", fileName);
190 MUSIC_PlaySong(fileName,1);
191}
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/mouse.h b/apps/plugins/sdl/progs/duke3d/Game/src/mouse.h
new file mode 100644
index 0000000000..0adfa3c82a
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/mouse.h
@@ -0,0 +1,51 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#ifndef __mouse_h
28#define __mouse_h
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33#define LEFT_MOUSE 1
34#define RIGHT_MOUSE 2
35#define MIDDLE_MOUSE 4
36#define LEFT_MOUSE_PRESSED( button ) ( ( ( button ) & LEFT_MOUSE ) != 0 )
37#define RIGHT_MOUSE_PRESSED( button ) ( ( ( button ) & RIGHT_MOUSE ) != 0 )
38#define MIDDLE_MOUSE_PRESSED( button ) ( ( ( button ) & MIDDLE_MOUSE ) != 0 )
39
40boolean MOUSE_Init( void );
41void MOUSE_Shutdown( void );
42void MOUSE_ShowCursor( void );
43void MOUSE_HideCursor( void );
44int32 MOUSE_GetButtons( void );
45void MOUSE_GetPosition( int32*x, int32*y );
46void MOUSE_GetDelta( int32*x, int32*y );
47
48#ifdef __cplusplus
49};
50#endif
51#endif /* __mouse_h */
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/names.h b/apps/plugins/sdl/progs/duke3d/Game/src/names.h
new file mode 100644
index 0000000000..16d80c344c
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/names.h
@@ -0,0 +1,754 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#define SECTOREFFECTOR 1
28#define ACTIVATOR 2
29#define TOUCHPLATE 3
30#define ACTIVATORLOCKED 4
31#define MUSICANDSFX 5
32#define LOCATORS 6
33#define CYCLER 7
34#define MASTERSWITCH 8
35#define RESPAWN 9
36#define GPSPEED 10
37#define FOF 13
38#define ARROW 20
39#define FIRSTGUNSPRITE 21
40#define CHAINGUNSPRITE 22
41#define RPGSPRITE 23
42#define FREEZESPRITE 24
43#define SHRINKERSPRITE 25
44#define HEAVYHBOMB 26
45#define TRIPBOMBSPRITE 27
46#define SHOTGUNSPRITE 28
47#define DEVISTATORSPRITE 29
48#define HEALTHBOX 30
49#define AMMOBOX 31
50#define GROWSPRITEICON 32
51#define INVENTORYBOX 33
52#define FREEZEAMMO 37
53#define AMMO 40
54#define BATTERYAMMO 41
55#define DEVISTATORAMMO 42
56#define RPGAMMO 44
57#define GROWAMMO 45
58#define CRYSTALAMMO 46
59#define HBOMBAMMO 47
60#define AMMOLOTS 48
61#define SHOTGUNAMMO 49
62#define COLA 51
63#define SIXPAK 52
64#define FIRSTAID 53
65#define SHIELD 54
66#define STEROIDS 55
67#define AIRTANK 56
68#define JETPACK 57
69#define HEATSENSOR 59
70#define ACCESSCARD 60
71#define BOOTS 61
72#define MIRRORBROKE 70
73#define CLOUDYOCEAN 78
74#define CLOUDYSKIES 79
75#define MOONSKY1 80
76#define MOONSKY2 81
77#define MOONSKY3 82
78#define MOONSKY4 83
79#define BIGORBIT1 84
80#define BIGORBIT2 85
81#define BIGORBIT3 86
82#define BIGORBIT4 87
83#define BIGORBIT5 88
84#define LA 89
85#define REDSKY1 98
86#define REDSKY2 99
87#define ATOMICHEALTH 100
88#define TECHLIGHT2 120
89#define TECHLIGHTBUST2 121
90#define TECHLIGHT4 122
91#define TECHLIGHTBUST4 123
92#define WALLLIGHT4 124
93#define WALLLIGHTBUST4 125
94#define ACCESSSWITCH 130
95#define SLOTDOOR 132
96#define LIGHTSWITCH 134
97#define SPACEDOORSWITCH 136
98#define SPACELIGHTSWITCH 138
99#define FRANKENSTINESWITCH 140
100#define NUKEBUTTON 142
101#define MULTISWITCH 146
102#define DOORTILE5 150
103#define DOORTILE6 151
104#define DOORTILE1 152
105#define DOORTILE2 153
106#define DOORTILE3 154
107#define DOORTILE4 155
108#define DOORTILE7 156
109#define DOORTILE8 157
110#define DOORTILE9 158
111#define DOORTILE10 159
112#define DOORSHOCK 160
113#define DIPSWITCH 162
114#define DIPSWITCH2 164
115#define TECHSWITCH 166
116#define DIPSWITCH3 168
117#define ACCESSSWITCH2 170
118#define REFLECTWATERTILE 180
119#define FLOORSLIME 200
120#define BIGFORCE 230
121#define EPISODE 247
122#define MASKWALL9 255
123#define W_LIGHT 260
124#define SCREENBREAK1 263
125#define SCREENBREAK2 264
126#define SCREENBREAK3 265
127#define SCREENBREAK4 266
128#define SCREENBREAK5 267
129#define SCREENBREAK6 268
130#define SCREENBREAK7 269
131#define SCREENBREAK8 270
132#define SCREENBREAK9 271
133#define SCREENBREAK10 272
134#define SCREENBREAK11 273
135#define SCREENBREAK12 274
136#define SCREENBREAK13 275
137#define MASKWALL1 285
138#define W_TECHWALL1 293
139#define W_TECHWALL2 297
140#define W_TECHWALL15 299
141#define W_TECHWALL3 301
142#define W_TECHWALL4 305
143#define W_TECHWALL10 306
144#define W_TECHWALL16 307
145#define WATERTILE2 336
146#define BPANNEL1 341
147#define PANNEL1 342
148#define PANNEL2 343
149#define WATERTILE 344
150#define STATIC 351
151#define W_SCREENBREAK 357
152#define W_HITTECHWALL3 360
153#define W_HITTECHWALL4 361
154#define W_HITTECHWALL2 362
155#define W_HITTECHWALL1 363
156#define MASKWALL10 387
157#define MASKWALL11 391
158#define DOORTILE22 395
159#define FANSPRITE 407
160#define FANSPRITEBROKE 411
161#define FANSHADOW 412
162#define FANSHADOWBROKE 416
163#define DOORTILE18 447
164#define DOORTILE19 448
165#define DOORTILE20 449
166// #define SPACESHUTTLE 487
167#define SATELLITE 489
168#define VIEWSCREEN2 499
169#define VIEWSCREENBROKE 501
170#define VIEWSCREEN 502
171#define GLASS 503
172#define GLASS2 504
173#define STAINGLASS1 510
174#define MASKWALL5 514
175#define SATELITE 516
176#define FUELPOD 517
177#define SLIMEPIPE 538
178#define CRACK1 546
179#define CRACK2 547
180#define CRACK3 548
181#define CRACK4 549
182#define FOOTPRINTS 550
183#define DOMELITE 551
184#define CAMERAPOLE 554
185#define CHAIR1 556
186#define CHAIR2 557
187#define BROKENCHAIR 559
188#define MIRROR 560
189#define WATERFOUNTAIN 563
190#define WATERFOUNTAINBROKE 567
191#define FEMMAG1 568
192#define TOILET 569
193#define STALL 571
194#define STALLBROKE 573
195#define FEMMAG2 577
196#define REACTOR2 578
197#define REACTOR2BURNT 579
198#define REACTOR2SPARK 580
199#define GRATE1 595
200#define BGRATE1 596
201#define SOLARPANNEL 602
202#define NAKED1 603
203#define ANTENNA 607
204#define MASKWALL12 609
205#define TOILETBROKE 615
206#define PIPE2 616
207#define PIPE1B 617
208#define PIPE3 618
209#define PIPE1 619
210#define CAMERA1 621
211#define BRICK 626
212#define SPLINTERWOOD 630
213#define PIPE2B 633
214#define BOLT1 634
215#define W_NUMBERS 640
216#define WATERDRIP 660
217#define WATERBUBBLE 661
218#define WATERBUBBLEMAKER 662
219#define W_FORCEFIELD 663
220#define VACUUM 669
221#define FOOTPRINTS2 672
222#define FOOTPRINTS3 673
223#define FOOTPRINTS4 674
224#define EGG 675
225#define SCALE 678
226#define CHAIR3 680
227#define CAMERALIGHT 685
228#define MOVIECAMERA 686
229#define IVUNIT 689
230#define POT1 694
231#define POT2 695
232#define POT3 697
233#define PIPE3B 700
234#define WALLLIGHT3 701
235#define WALLLIGHTBUST3 702
236#define WALLLIGHT1 703
237#define WALLLIGHTBUST1 704
238#define WALLLIGHT2 705
239#define WALLLIGHTBUST2 706
240#define LIGHTSWITCH2 712
241#define WAITTOBESEATED 716
242#define DOORTILE14 717
243#define STATUE 753
244#define MIKE 762
245#define VASE 765
246#define SUSHIPLATE1 768
247#define SUSHIPLATE2 769
248#define SUSHIPLATE3 774
249#define SUSHIPLATE4 779
250#define DOORTILE16 781
251#define SUSHIPLATE5 792
252#define OJ 806
253#define MASKWALL13 830
254#define HURTRAIL 859
255#define POWERSWITCH1 860
256#define LOCKSWITCH1 862
257#define POWERSWITCH2 864
258#define ATM 867
259#define STATUEFLASH 869
260#define ATMBROKE 888
261#define BIGHOLE2 893
262#define STRIPEBALL 901
263#define QUEBALL 902
264#define POCKET 903
265#define WOODENHORSE 904
266#define TREE1 908
267#define TREE2 910
268#define CACTUS 911
269#define MASKWALL2 913
270#define MASKWALL3 914
271#define MASKWALL4 915
272#define FIREEXT 916
273#define TOILETWATER 921
274#define NEON1 925
275#define NEON2 926
276#define CACTUSBROKE 939
277#define BOUNCEMINE 940
278#define BROKEFIREHYDRENT 950
279#define BOX 951
280#define BULLETHOLE 952
281#define BOTTLE1 954
282#define BOTTLE2 955
283#define BOTTLE3 956
284#define BOTTLE4 957
285#define FEMPIC5 963
286#define FEMPIC6 964
287#define FEMPIC7 965
288#define HYDROPLANT 969
289#define OCEANSPRITE1 971
290#define OCEANSPRITE2 972
291#define OCEANSPRITE3 973
292#define OCEANSPRITE4 974
293#define OCEANSPRITE5 975
294#define GENERICPOLE 977
295#define CONE 978
296#define HANGLIGHT 979
297#define HYDRENT 981
298#define MASKWALL14 988
299#define TIRE 990
300#define PIPE5 994
301#define PIPE6 995
302#define PIPE4 996
303#define PIPE4B 997
304#define BROKEHYDROPLANT 1003
305#define PIPE5B 1005
306#define NEON3 1007
307#define NEON4 1008
308#define NEON5 1009
309#define BOTTLE5 1012
310#define BOTTLE6 1013
311#define BOTTLE8 1014
312#define SPOTLITE 1020
313#define HANGOOZ 1022
314#define MASKWALL15 1024
315#define BOTTLE7 1025
316#define HORSEONSIDE 1026
317#define GLASSPIECES 1031
318#define HORSELITE 1034
319#define DONUTS 1045
320#define NEON6 1046
321#define MASKWALL6 1059
322#define CLOCK 1060
323#define RUBBERCAN 1062
324#define BROKENCLOCK 1067
325#define PLUG 1069
326#define OOZFILTER 1079
327#define FLOORPLASMA 1082
328#define REACTOR 1088
329#define REACTORSPARK 1092
330#define REACTORBURNT 1096
331#define DOORTILE15 1102
332#define HANDSWITCH 1111
333#define CIRCLEPANNEL 1113
334#define CIRCLEPANNELBROKE 1114
335#define PULLSWITCH 1122
336#define MASKWALL8 1124
337#define BIGHOLE 1141
338#define ALIENSWITCH 1142
339#define DOORTILE21 1144
340#define HANDPRINTSWITCH 1155
341#define BOTTLE10 1157
342#define BOTTLE11 1158
343#define BOTTLE12 1159
344#define BOTTLE13 1160
345#define BOTTLE14 1161
346#define BOTTLE15 1162
347#define BOTTLE16 1163
348#define BOTTLE17 1164
349#define BOTTLE18 1165
350#define BOTTLE19 1166
351#define DOORTILE17 1169
352#define MASKWALL7 1174
353#define JAILBARBREAK 1175
354#define DOORTILE11 1178
355#define DOORTILE12 1179
356#define VENDMACHINE 1212
357#define VENDMACHINEBROKE 1214
358#define COLAMACHINE 1215
359#define COLAMACHINEBROKE 1217
360#define CRANEPOLE 1221
361#define CRANE 1222
362#define BARBROKE 1225
363#define BLOODPOOL 1226
364#define NUKEBARREL 1227
365#define NUKEBARRELDENTED 1228
366#define NUKEBARRELLEAKED 1229
367#define CANWITHSOMETHING 1232
368#define MONEY 1233
369#define BANNER 1236
370#define EXPLODINGBARREL 1238
371#define EXPLODINGBARREL2 1239
372#define FIREBARREL 1240
373#define SEENINE 1247
374#define SEENINEDEAD 1248
375#define STEAM 1250
376#define CEILINGSTEAM 1255
377#define PIPE6B 1260
378#define TRANSPORTERBEAM 1261
379#define RAT 1267
380#define TRASH 1272
381#define FEMPIC1 1280
382#define FEMPIC2 1289
383#define BLANKSCREEN 1293
384#define PODFEM1 1294
385#define FEMPIC3 1298
386#define FEMPIC4 1306
387#define FEM1 1312
388#define FEM2 1317
389#define FEM3 1321
390#define FEM5 1323
391#define BLOODYPOLE 1324
392#define FEM4 1325
393#define FEM6 1334
394#define FEM6PAD 1335
395#define FEM8 1336
396#define HELECOPT 1346
397#define FETUSJIB 1347
398#define HOLODUKE 1348
399#define SPACEMARINE 1353
400#define INDY 1355
401#define FETUS 1358
402#define FETUSBROKE 1359
403#define MONK 1352
404#define LUKE 1354
405#define COOLEXPLOSION1 1360
406#define WATERSPLASH2 1380
407#define FIREVASE 1390
408#define SCRATCH 1393
409#define FEM7 1395
410#define APLAYERTOP 1400
411#define APLAYER 1405
412#define PLAYERONWATER 1420
413#define DUKELYINGDEAD 1518
414#define DUKETORSO 1520
415#define DUKEGUN 1528
416#define DUKELEG 1536
417#define SHARK 1550
418#define BLOOD 1620
419#define FIRELASER 1625
420#define TRANSPORTERSTAR 1630
421#define SPIT 1636
422#define LOOGIE 1637
423#define FIST 1640
424#define FREEZEBLAST 1641
425#define DEVISTATORBLAST 1642
426#define SHRINKSPARK 1646
427#define TONGUE 1647
428#define MORTER 1650
429#define SHRINKEREXPLOSION 1656
430#define RADIUSEXPLOSION 1670
431#define FORCERIPPLE 1671
432#define LIZTROOP 1680
433#define LIZTROOPRUNNING 1681
434#define LIZTROOPSTAYPUT 1682
435#define LIZTOP 1705
436#define LIZTROOPSHOOT 1715
437#define LIZTROOPJETPACK 1725
438#define LIZTROOPDSPRITE 1734
439#define LIZTROOPONTOILET 1741
440#define LIZTROOPJUSTSIT 1742
441#define LIZTROOPDUCKING 1744
442#define HEADJIB1 1768
443#define ARMJIB1 1772
444#define LEGJIB1 1776
445#define CANNONBALL 1817
446#define OCTABRAIN 1820
447#define OCTABRAINSTAYPUT 1821
448#define OCTATOP 1845
449#define OCTADEADSPRITE 1855
450#define INNERJAW 1860
451#define DRONE 1880
452#define EXPLOSION2 1890
453#define COMMANDER 1920
454#define COMMANDERSTAYPUT 1921
455#define RECON 1960
456#define TANK 1975
457#define PIGCOP 2000
458#define PIGCOPSTAYPUT 2001
459#define PIGCOPDIVE 2045
460#define PIGCOPDEADSPRITE 2060
461#define PIGTOP 2061
462#define LIZMAN 2120
463#define LIZMANSTAYPUT 2121
464#define LIZMANSPITTING 2150
465#define LIZMANFEEDING 2160
466#define LIZMANJUMP 2165
467#define LIZMANDEADSPRITE 2185
468#define FECES 2200
469#define LIZMANHEAD1 2201
470#define LIZMANARM1 2205
471#define LIZMANLEG1 2209
472#define EXPLOSION2BOT 2219
473#define USERWEAPON 2235
474#define HEADERBAR 2242
475#define JIBS1 2245
476#define JIBS2 2250
477#define JIBS3 2255
478#define JIBS4 2260
479#define JIBS5 2265
480#define BURNING 2270
481#define FIRE 2271
482#define JIBS6 2286
483#define BLOODSPLAT1 2296
484#define BLOODSPLAT3 2297
485#define BLOODSPLAT2 2298
486#define BLOODSPLAT4 2299
487#define OOZ 2300
488#define OOZ2 2309
489#define WALLBLOOD1 2301
490#define WALLBLOOD2 2302
491#define WALLBLOOD3 2303
492#define WALLBLOOD4 2304
493#define WALLBLOOD5 2305
494#define WALLBLOOD6 2306
495#define WALLBLOOD7 2307
496#define WALLBLOOD8 2308
497#define BURNING2 2310
498#define FIRE2 2311
499#define CRACKKNUCKLES 2324
500#define SMALLSMOKE 2329
501#define SMALLSMOKEMAKER 2330
502#define FLOORFLAME 2333
503#define ROTATEGUN 2360
504#define GREENSLIME 2370
505#define WATERDRIPSPLASH 2380
506#define SCRAP6 2390
507#define SCRAP1 2400
508#define SCRAP2 2404
509#define SCRAP3 2408
510#define SCRAP4 2412
511#define SCRAP5 2416
512#define ORGANTIC 2420
513#define BETAVERSION 2440
514#define PLAYERISHERE 2442
515#define PLAYERWASHERE 2443
516#define SELECTDIR 2444
517#define F1HELP 2445
518#define NOTCHON 2446
519#define NOTCHOFF 2447
520#define GROWSPARK 2448
521#define DUKEICON 2452
522#define BADGUYICON 2453
523#define FOODICON 2454
524#define GETICON 2455
525#define MENUSCREEN 2456
526#define MENUBAR 2457
527#define KILLSICON 2458
528#define FIRSTAID_ICON 2460
529#define HEAT_ICON 2461
530#define BOTTOMSTATUSBAR 2462
531#define BOOT_ICON 2463
532#define FRAGBAR 2465
533#define JETPACK_ICON 2467
534#define AIRTANK_ICON 2468
535#define STEROIDS_ICON 2469
536#define HOLODUKE_ICON 2470
537#define ACCESS_ICON 2471
538#define DIGITALNUM 2472
539#define DUKECAR 2491
540#define CAMCORNER 2482
541#define CAMLIGHT 2484
542#define LOGO 2485
543#define TITLE 2486
544#define NUKEWARNINGICON 2487
545#define MOUSECURSOR 2488
546#define SLIDEBAR 2489
547#define DREALMS 2492
548#define BETASCREEN 2493
549#define WINDOWBORDER1 2494
550#define TEXTBOX 2495
551#define WINDOWBORDER2 2496
552#define DUKENUKEM 2497
553#define THREEDEE 2498
554#define INGAMEDUKETHREEDEE 2499
555#define TENSCREEN 2500
556#define PLUTOPAKSPRITE 2501
557#define DEVISTATOR 2510
558#define KNEE 2521
559#define CROSSHAIR 2523
560#define FIRSTGUN 2524
561#define FIRSTGUNRELOAD 2528
562#define FALLINGCLIP 2530
563#define CLIPINHAND 2531
564#define HAND 2532
565#define SHELL 2533
566#define SHOTGUNSHELL 2535
567#define CHAINGUN 2536
568#define RPGGUN 2544
569#define RPGMUZZLEFLASH 2545
570#define FREEZE 2548
571#define CATLITE 2552
572#define SHRINKER 2556
573#define HANDHOLDINGLASER 2563
574#define TRIPBOMB 2566
575#define LASERLINE 2567
576#define HANDHOLDINGACCESS 2568
577#define HANDREMOTE 2570
578#define HANDTHROW 2573
579#define TIP 2576
580#define GLAIR 2578
581#define SCUBAMASK 2581
582#define SPACEMASK 2584
583#define FORCESPHERE 2590
584#define SHOTSPARK1 2595
585#define RPG 2605
586#define LASERSITE 2612
587#define SHOTGUN 2613
588#define BOSS1 2630
589#define BOSS1STAYPUT 2631
590#define BOSS1SHOOT 2660
591#define BOSS1LOB 2670
592#define BOSSTOP 2696
593#define BOSS2 2710
594#define BOSS3 2760
595#define SPINNINGNUKEICON 2813
596#define BIGFNTCURSOR 2820
597#define SMALLFNTCURSOR 2821
598#define STARTALPHANUM 2822
599#define ENDALPHANUM 2915
600#define BIGALPHANUM 2940
601#define BIGPERIOD 3002
602#define BIGCOMMA 3003
603#define BIGX 3004
604#define BIGQ 3005
605#define BIGSEMI 3006
606#define BIGCOLIN 3007
607#define THREEBYFIVE 3010
608#define BIGAPPOS 3022
609#define BLANK 3026
610#define MINIFONT 3072
611#define BUTTON1 3164
612#define GLASS3 3187
613#define RESPAWNMARKERRED 3190
614#define RESPAWNMARKERYELLOW 3200
615#define RESPAWNMARKERGREEN 3210
616#define BONUSSCREEN 3240
617#define VIEWBORDER 3250
618#define VICTORY1 3260
619#define ORDERING 3270
620#define TEXTSTORY 3280
621#define LOADSCREEN 3281
622#define BORNTOBEWILDSCREEN 3370
623#define BLIMP 3400
624#define FEM9 3450
625#define FOOTPRINT 3701
626#define POOP 4094
627#define FRAMEEFFECT1 4095
628// FIX_00037: steroids trigger a too many sprite respawn in 1.3 and 1.3d.
629#define FRAMEEFFECT1_13CON 3999 // Needed to ensure 1.3/1.3d compliance --mk
630#define PANNEL3 4099
631#define SCREENBREAK14 4120
632#define SCREENBREAK15 4123
633#define SCREENBREAK19 4125
634#define SCREENBREAK16 4127
635#define SCREENBREAK17 4128
636#define SCREENBREAK18 4129
637#define W_TECHWALL11 4130
638#define W_TECHWALL12 4131
639#define W_TECHWALL13 4132
640#define W_TECHWALL14 4133
641#define W_TECHWALL5 4134
642#define W_TECHWALL6 4136
643#define W_TECHWALL7 4138
644#define W_TECHWALL8 4140
645#define W_TECHWALL9 4142
646#define BPANNEL3 4100
647#define W_HITTECHWALL16 4144
648#define W_HITTECHWALL10 4145
649#define W_HITTECHWALL15 4147
650#define W_MILKSHELF 4181
651#define W_MILKSHELFBROKE 4203
652#define PURPLELAVA 4240
653#define LAVABUBBLE 4340
654#define DUKECUTOUT 4352
655#define TARGET 4359
656#define GUNPOWDERBARREL 4360
657#define DUCK 4361
658#define HATRACK 4367
659#define DESKLAMP 4370
660#define COFFEEMACHINE 4372
661#define CUPS 4373
662#define GAVALS 4374
663#define GAVALS2 4375
664#define POLICELIGHTPOLE 4377
665#define FLOORBASKET 4388
666#define PUKE 4389
667#define DOORTILE23 4391
668#define TOPSECRET 4396
669#define SPEAKER 4397
670#define TEDDYBEAR 4400
671#define ROBOTDOG 4402
672#define ROBOTPIRATE 4404
673#define ROBOTMOUSE 4407
674#define MAIL 4410
675#define MAILBAG 4413
676#define HOTMEAT 4427
677#define COFFEEMUG 4438
678#define DONUTS2 4440
679#define TRIPODCAMERA 4444
680#define METER 4453
681#define DESKPHONE 4454
682#define GUMBALLMACHINE 4458
683#define GUMBALLMACHINEBROKE 4459
684#define PAPER 4460
685#define MACE 4464
686#define GENERICPOLE2 4465
687#define XXXSTACY 4470
688#define WETFLOOR 4495
689#define BROOM 4496
690#define MOP 4497
691#define LETTER 4502
692#define PIRATE1A 4510
693#define PIRATE4A 4511
694#define PIRATE2A 4512
695#define PIRATE5A 4513
696#define PIRATE3A 4514
697#define PIRATE6A 4515
698#define PIRATEHALF 4516
699#define CHESTOFGOLD 4520
700#define SIDEBOLT1 4525
701#define FOODOBJECT1 4530
702#define FOODOBJECT2 4531
703#define FOODOBJECT3 4532
704#define FOODOBJECT4 4533
705#define FOODOBJECT5 4534
706#define FOODOBJECT6 4535
707#define FOODOBJECT7 4536
708#define FOODOBJECT8 4537
709#define FOODOBJECT9 4538
710#define FOODOBJECT10 4539
711#define FOODOBJECT11 4540
712#define FOODOBJECT12 4541
713#define FOODOBJECT13 4542
714#define FOODOBJECT14 4543
715#define FOODOBJECT15 4544
716#define FOODOBJECT16 4545
717#define FOODOBJECT17 4546
718#define FOODOBJECT18 4547
719#define FOODOBJECT19 4548
720#define FOODOBJECT20 4549
721#define HEADLAMP 4550
722#define TAMPON 4557
723#define SKINNEDCHICKEN 4554
724#define FEATHEREDCHICKEN 4555
725#define ROBOTDOG2 4560
726#define JOLLYMEAL 4569
727#define DUKEBURGER 4570
728#define SHOPPINGCART 4576
729#define CANWITHSOMETHING2 4580
730#define CANWITHSOMETHING3 4581
731#define CANWITHSOMETHING4 4582
732#define SNAKEP 4590
733#define DOLPHIN1 4591
734#define DOLPHIN2 4592
735#define NEWBEAST 4610
736#define NEWBEASTSTAYPUT 4611
737#define NEWBEASTJUMP 4690
738#define NEWBEASTHANG 4670
739#define NEWBEASTHANGDEAD 4671
740#define BOSS4 4740
741#define BOSS4STAYPUT 4741
742#define FEM10 4864
743#define TOUGHGAL 4866
744#define MAN 4871
745#define MAN2 4872
746#define WOMAN 4874
747#define PLEASEWAIT 4887
748#define NATURALLIGHTNING 4890
749#define WEATHERWARN 4893
750#define DUKETAG 4900
751#define SIGN1 4909
752#define SIGN2 4912
753#define JURYGUY 4943
754
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/player.c b/apps/plugins/sdl/progs/duke3d/Game/src/player.c
new file mode 100644
index 0000000000..65387b9046
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/player.c
@@ -0,0 +1,4462 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27// Savage Baggage Masters
28
29#include "duke3d.h"
30
31int32 turnheldtime; //MED
32int32 lastcontroltime; //MED
33
34void setpal(struct player_struct *p)
35{
36 if(p->heat_on) p->palette = slimepal;
37 else switch(sector[p->cursectnum].ceilingpicnum)
38 {
39 case FLOORSLIME:
40 case FLOORSLIME+1:
41 case FLOORSLIME+2:
42 p->palette = slimepal;
43 break;
44 default:
45 if(sector[p->cursectnum].lotag == 2) p->palette = waterpal;
46 else p->palette = palette;
47 break;
48 }
49 restorepalette = 1;
50}
51
52void incur_damage( struct player_struct *p )
53{
54 int32_t damage = 0L, shield_damage = 0L;
55
56 sprite[p->i].extra -= p->extra_extra8>>8;
57
58 damage = sprite[p->i].extra - p->last_extra;
59
60 if ( damage < 0 )
61 {
62 p->extra_extra8 = 0;
63
64 if ( p->shield_amount > 0 )
65 {
66 shield_damage = damage * (20 + (TRAND%30)) / 100;
67 damage -= shield_damage;
68
69 p->shield_amount += shield_damage;
70
71 if ( p->shield_amount < 0 )
72 {
73 damage += p->shield_amount;
74 p->shield_amount = 0;
75 }
76 }
77
78 sprite[p->i].extra = p->last_extra + damage;
79 }
80}
81
82void quickkill(struct player_struct *p)
83{
84 p->pals[0] = 48;
85 p->pals[1] = 48;
86 p->pals[2] = 48;
87 p->pals_time = 48;
88
89 sprite[p->i].extra = 0;
90 sprite[p->i].cstat |= 32768;
91 if(ud.god == 0) guts(&sprite[p->i],JIBS6,8,myconnectindex);
92 return;
93}
94
95void forceplayerangle(struct player_struct *p)
96{
97 short n;
98
99 n = 128-(TRAND&255);
100
101 p->horiz += 64;
102 p->return_to_center = 9;
103 p->look_ang = n>>1;
104 p->rotscrnang = n>>1;
105}
106
107void tracers(int32_t x1,int32_t y1,int32_t z1,int32_t x2,int32_t y2,int32_t z2,int32_t n)
108{
109 int32_t i, xv, yv, zv;
110 short sect = -1;
111
112 i = n+1;
113 xv = (x2-x1)/i;
114 yv = (y2-y1)/i;
115 zv = (z2-z1)/i;
116
117 if( ( klabs(x1-x2)+klabs(y1-y2) ) < 3084 )
118 return;
119
120 for(i=n;i>0;i--)
121 {
122 x1 += xv;
123 y1 += yv;
124 z1 += zv;
125 updatesector(x1,y1,&sect);
126 if(sect >= 0)
127 {
128 if(sector[sect].lotag == 2)
129 EGS(sect,x1,y1,z1,WATERBUBBLE,-32,4+(TRAND&3),4+(TRAND&3),TRAND&2047,0,0,ps[0].i,5);
130 else
131 EGS(sect,x1,y1,z1,SMALLSMOKE,-32,14,14,0,0,0,ps[0].i,5);
132 }
133 }
134}
135
136int32_t hits(short i)
137{
138 int32_t sx,sy,sz;
139 short sect,hw,hs;
140 int32_t zoff;
141
142 if(PN == APLAYER) zoff = (40<<8);
143 else zoff = 0;
144
145 hitscan(SX,SY,SZ-zoff,SECT,
146 sintable[(SA+512)&2047],
147 sintable[SA&2047],
148 0,&sect,&hw,&hs,&sx,&sy,&sz,CLIPMASK1);
149
150 return ( FindDistance2D( sx-SX,sy-SY ) );
151}
152
153int32_t hitasprite(short i,short *hitsp)
154{
155 int32_t sx,sy,sz,zoff;
156 short sect,hw;
157
158 if(badguy(&sprite[i]) )
159 zoff = (42<<8);
160 else if(PN == APLAYER) zoff = (39<<8);
161 else zoff = 0;
162
163 hitscan(SX,SY,SZ-zoff,SECT,
164 sintable[(SA+512)&2047],
165 sintable[SA&2047],
166 0,&sect,&hw,hitsp,&sx,&sy,&sz,CLIPMASK1);
167
168 if(hw >= 0 && (wall[hw].cstat&16) && badguy(&sprite[i]) )
169 return((1<<30));
170
171 return ( FindDistance2D(sx-SX,sy-SY) );
172}
173
174/*
175int32_t hitaspriteandwall(short i,short *hitsp,short *hitw,short *x, short *y)
176{
177 int32_t sz;
178 short sect;
179
180 hitscan(SX,SY,SZ,SECT,
181 sintable[(SA+512)&2047],
182 sintable[SA&2047],
183 0,&sect,hitw,hitsp,x,y,&sz,CLIPMASK1);
184
185 return ( FindDistance2D(*x-SX,*y-SY) );
186}
187*/
188
189
190int32_t hitawall(struct player_struct *p,short *hitw)
191{
192 int32_t sx,sy,sz;
193 short sect,hs;
194
195 hitscan(p->posx,p->posy,p->posz,p->cursectnum,
196 sintable[(p->ang+512)&2047],
197 sintable[p->ang&2047],
198 0,&sect,hitw,&hs,&sx,&sy,&sz,CLIPMASK0);
199
200 return ( FindDistance2D(sx-p->posx,sy-p->posy) );
201}
202
203short aim(spritetype *s,short aang, short auto_aim)
204{
205 uint8_t gotshrinker,gotfreezer;
206 short i, j, a, k, cans;
207 short aimstats[] = {10,13,1,2};
208 int32_t dx1, dy1, dx2, dy2, dx3, dy3, smax, sdist;
209 int32_t xv, yv;
210
211 a = s->ang;
212
213 j = -1;
214// if(s->picnum == APLAYER && ps[s->yvel].aim_mode) return -1;
215
216 gotshrinker = s->picnum == APLAYER && ps[s->yvel].curr_weapon == SHRINKER_WEAPON;
217 gotfreezer = s->picnum == APLAYER && ps[s->yvel].curr_weapon == FREEZE_WEAPON;
218
219 smax = 0x7fffffff;
220
221 dx1 = sintable[(a+512-aang)&2047];
222 dy1 = sintable[(a-aang)&2047];
223 dx2 = sintable[(a+512+aang)&2047];
224 dy2 = sintable[(a+aang)&2047];
225
226 dx3 = sintable[(a+512)&2047];
227 dy3 = sintable[a&2047];
228
229 // FIX_00015: Backward compliance with older demos (down to demos v27, 28, 116 and 117 only)
230
231 //if player has AutoAim ON do the function.
232 if((auto_aim && nHostForceDisableAutoaim == 0)||
233 ud.playing_demo_rev == BYTEVERSION_27 ||
234 ud.playing_demo_rev == BYTEVERSION_28 ||
235 ud.playing_demo_rev == BYTEVERSION_116 ||
236 ud.playing_demo_rev == BYTEVERSION_117)
237 // don't disable any autoaim in case we are playing an old demo
238 {
239 for(k=0;k<4;k++)
240 {
241 if( j >= 0 )
242 break;
243 for(i=headspritestat[aimstats[k]];i >= 0;i=nextspritestat[i])
244 if( sprite[i].xrepeat > 0 && sprite[i].extra >= 0 && (sprite[i].cstat&(257+32768)) == 257)
245 if( badguy(&sprite[i]) || k < 2 )
246 {
247 if(badguy(&sprite[i]) || PN == APLAYER || PN == SHARK)
248 {
249 if( PN == APLAYER &&
250// ud.ffire == 0 &&
251 ud.coop == 1 &&
252 s->picnum == APLAYER &&
253 s != &sprite[i])
254 continue;
255
256 if(gotshrinker && sprite[i].xrepeat < 30 )
257 {
258 switch(PN)
259 {
260 case SHARK:
261 if(sprite[i].xrepeat < 20) continue;
262 continue;
263 case GREENSLIME:
264 case GREENSLIME+1:
265 case GREENSLIME+2:
266 case GREENSLIME+3:
267 case GREENSLIME+4:
268 case GREENSLIME+5:
269 case GREENSLIME+6:
270 case GREENSLIME+7:
271 break;
272 default:
273 continue;
274 }
275 }
276 if(gotfreezer && sprite[i].pal == 1) continue;
277 }
278
279 xv = (SX-s->x);
280 yv = (SY-s->y);
281
282 if( (dy1*xv) <= (dx1*yv) )
283 if( ( dy2*xv ) >= (dx2*yv) )
284 {
285 sdist = mulscale(dx3,xv,14) + mulscale(dy3,yv,14);
286 if( sdist > 512 && sdist < smax )
287 {
288 if(s->picnum == APLAYER)
289 a = (klabs(scale(SZ-s->z,10,sdist)-(ps[s->yvel].horiz+ps[s->yvel].horizoff-100)) < 100);
290 else a = 1;
291
292 if(PN == ORGANTIC || PN == ROTATEGUN )
293 cans = cansee(SX,SY,SZ,SECT,s->x,s->y,s->z-(32<<8),s->sectnum);
294 else cans = cansee(SX,SY,SZ-(32<<8),SECT,s->x,s->y,s->z-(32<<8),s->sectnum);
295
296 if( a && cans )
297 {
298 smax = sdist;
299 j = i;
300 }
301 }
302 }
303 }
304 }
305 }
306
307 return j;
308}
309
310
311
312
313void shoot(short i,short atwith)
314{
315 short sect, hitsect, hitspr, hitwall, l, sa, p, j, k, scount;
316 int32_t sx, sy, sz, vel, zvel, hitx, hity, hitz, x, oldzvel, dal;
317 uint8_t sizx,sizy;
318 spritetype *s;
319
320 s = &sprite[i];
321 sect = s->sectnum;
322 zvel = 0;
323
324 if( s->picnum == APLAYER )
325 {
326 p = s->yvel;
327
328 sx = ps[p].posx;
329 sy = ps[p].posy;
330 sz = ps[p].posz+ps[p].pyoff+(4<<8);
331 sa = ps[p].ang;
332
333 ps[p].crack_time = 777;
334
335 }
336 else
337 {
338 p = -1;
339 sa = s->ang;
340 sx = s->x;
341 sy = s->y;
342 sz = s->z-((s->yrepeat*tiles[s->picnum].dim.height)<<1)+(4<<8);
343 if(s->picnum != ROTATEGUN)
344 {
345 sz -= (7<<8);
346 if(badguy(s) && PN != COMMANDER)
347 {
348 sx += (sintable[(sa+1024+96)&2047]>>7);
349 sy += (sintable[(sa+512+96)&2047]>>7);
350 }
351 }
352 }
353
354 switch(atwith)
355 {
356 case BLOODSPLAT1:
357 case BLOODSPLAT2:
358 case BLOODSPLAT3:
359 case BLOODSPLAT4:
360
361 if(p >= 0)
362 sa += 64 - (TRAND&127);
363 else sa += 1024 + 64 - (TRAND&127);
364 zvel = 1024-(TRAND&2047);
365 case KNEE:
366 if(atwith == KNEE )
367 {
368 if(p >= 0)
369 {
370 zvel = (100-ps[p].horiz-ps[p].horizoff)<<5;
371 sz += (6<<8);
372 sa += 15;
373 }
374 else
375 {
376 j = ps[findplayer(s,&x)].i;
377 zvel = ( (sprite[j].z-sz)<<8 ) / (x+1);
378 sa = getangle(sprite[j].x-sx,sprite[j].y-sy);
379 }
380 }
381
382 hitscan(sx,sy,sz,sect,
383 sintable[(sa+512)&2047],
384 sintable[sa&2047],zvel<<6,
385 &hitsect,&hitwall,&hitspr,&hitx,&hity,&hitz,CLIPMASK1);
386
387 if( atwith == BLOODSPLAT1 ||
388 atwith == BLOODSPLAT2 ||
389 atwith == BLOODSPLAT3 ||
390 atwith == BLOODSPLAT4 )
391 {
392 if( FindDistance2D(sx-hitx,sy-hity) < 1024 )
393 if( hitwall >= 0 && wall[hitwall].overpicnum != BIGFORCE )
394 if( ( wall[hitwall].nextsector >= 0 && hitsect >= 0 &&
395 sector[wall[hitwall].nextsector].lotag == 0 &&
396 sector[hitsect].lotag == 0 &&
397 sector[wall[hitwall].nextsector].lotag == 0 &&
398 (sector[hitsect].floorz-sector[wall[hitwall].nextsector].floorz) > (16<<8) ) ||
399 ( wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0 ) )
400 if( (wall[hitwall].cstat&16) == 0)
401 {
402 if(wall[hitwall].nextsector >= 0)
403 {
404 k = headspritesect[wall[hitwall].nextsector];
405 while(k >= 0)
406 {
407 if(sprite[k].statnum == 3 && sprite[k].lotag == 13)
408 return;
409 k = nextspritesect[k];
410 }
411 }
412
413 if( wall[hitwall].nextwall >= 0 &&
414 wall[wall[hitwall].nextwall].hitag != 0 )
415 return;
416
417 if(wall[hitwall].hitag == 0)
418 {
419 k = spawn(i,atwith);
420 sprite[k].xvel = -12;
421 sprite[k].ang = getangle(wall[hitwall].x-wall[wall[hitwall].point2].x,
422 wall[hitwall].y-wall[wall[hitwall].point2].y)+512;
423 sprite[k].x = hitx;
424 sprite[k].y = hity;
425 sprite[k].z = hitz;
426 sprite[k].cstat |= (TRAND&4);
427 ssp(k,CLIPMASK0);
428 setsprite(k,sprite[k].x,sprite[k].y,sprite[k].z);
429 if( PN == OOZFILTER || PN == NEWBEAST )
430 sprite[k].pal = 6;
431 }
432 }
433 return;
434 }
435
436 if(hitsect < 0) break;
437
438 if( ( klabs(sx-hitx)+klabs(sy-hity) ) < 1024 )
439 {
440 if(hitwall >= 0 || hitspr >= 0)
441 {
442 j = EGS(hitsect,hitx,hity,hitz,KNEE,-15,0,0,sa,32,0,i,4);
443 sprite[j].extra += (TRAND&7);
444 if(p >= 0)
445 {
446 k = spawn(j,SMALLSMOKE);
447 sprite[k].z -= (8<<8);
448 spritesound(KICK_HIT,j);
449 }
450
451 if ( p >= 0 && ps[p].steroids_amount > 0 && ps[p].steroids_amount < 400 )
452 sprite[j].extra += (max_player_health>>2);
453
454 if( hitspr >= 0 && sprite[hitspr].picnum != ACCESSSWITCH && sprite[hitspr].picnum != ACCESSSWITCH2 )
455 {
456 checkhitsprite(hitspr,j);
457 if(p >= 0) checkhitswitch(p,hitspr,1);
458 }
459
460 else if( hitwall >= 0 )
461 {
462 if( wall[hitwall].cstat&2 )
463 if(wall[hitwall].nextsector >= 0)
464 if(hitz >= (sector[wall[hitwall].nextsector].floorz) )
465 hitwall = wall[hitwall].nextwall;
466
467 if( hitwall >= 0 && wall[hitwall].picnum != ACCESSSWITCH && wall[hitwall].picnum != ACCESSSWITCH2 )
468 {
469 checkhitwall(j,hitwall,hitx,hity,hitz,atwith);
470 if(p >= 0) checkhitswitch(p,hitwall,0);
471 }
472 }
473 }
474 else if(p >= 0 && zvel > 0 && sector[hitsect].lotag == 1)
475 {
476 j = spawn(ps[p].i,WATERSPLASH2);
477 sprite[j].x = hitx;
478 sprite[j].y = hity;
479 sprite[j].ang = ps[p].ang; // Total tweek
480 sprite[j].xvel = 32;
481 ssp(i,CLIPMASK0);
482 sprite[j].xvel = 0;
483
484 }
485 }
486
487 break;
488
489 case SHOTSPARK1:
490 case SHOTGUN:
491 case CHAINGUN:
492
493 if( s->extra >= 0 ) s->shade = -96;
494
495 if(p >= 0)
496 {
497 j = aim( s, AUTO_AIM_ANGLE, ps[p].auto_aim!= 0 );
498 if(j >= 0)
499 {
500 dal = ((sprite[j].xrepeat*tiles[sprite[j].picnum].dim.height)<<1)+(5<<8);
501 switch(sprite[j].picnum)
502 {
503 case GREENSLIME:
504 case GREENSLIME+1:
505 case GREENSLIME+2:
506 case GREENSLIME+3:
507 case GREENSLIME+4:
508 case GREENSLIME+5:
509 case GREENSLIME+6:
510 case GREENSLIME+7:
511 case ROTATEGUN:
512 dal -= (8<<8);
513 break;
514 }
515 zvel = ( ( sprite[j].z-sz-dal )<<8 ) / ldist(&sprite[ps[p].i], &sprite[j]) ;
516 sa = getangle(sprite[j].x-sx,sprite[j].y-sy);
517 }
518
519 if(atwith == SHOTSPARK1)
520 {
521 if(j == -1)
522 {
523 sa += 16-(TRAND&31);
524 zvel = (100-ps[p].horiz-ps[p].horizoff)<<5;
525 zvel += 128-(TRAND&255);
526 }
527 }
528 else
529 {
530 sa += 16-(TRAND&31);
531 if(j == -1) zvel = (100-ps[p].horiz-ps[p].horizoff)<<5;
532 zvel += 128-(TRAND&255);
533 }
534 sz -= (2<<8);
535 }
536 else
537 {
538 j = findplayer(s,&x);
539 sz -= (4<<8);
540 zvel = ( (ps[j].posz-sz) <<8 ) / (ldist(&sprite[ps[j].i], s ) );
541 if(s->picnum != BOSS1)
542 {
543 zvel += 128-(TRAND&255);
544 sa += 32-(TRAND&63);
545 }
546 else
547 {
548 zvel += 128-(TRAND&255);
549 sa = getangle(ps[j].posx-sx,ps[j].posy-sy)+64-(TRAND&127);
550 }
551 }
552
553 s->cstat &= ~257;
554 hitscan(sx,sy,sz,sect,
555 sintable[(sa+512)&2047],
556 sintable[sa&2047],
557 zvel<<6,&hitsect,&hitwall,&hitspr,&hitx,&hity,&hitz,CLIPMASK1);
558 s->cstat |= 257;
559
560 if(hitsect < 0) return;
561
562 if( (TRAND&15) == 0 && sector[hitsect].lotag == 2 )
563 tracers(hitx,hity,hitz,sx,sy,sz,8-(ud.multimode>>1));
564
565 if(p >= 0)
566 {
567 k = EGS(hitsect,hitx,hity,hitz,SHOTSPARK1,-15,10,10,sa,0,0,i,4);
568 sprite[k].extra = *actorscrptr[atwith];
569 sprite[k].extra += (TRAND%6);
570
571 if( hitwall == -1 && hitspr == -1)
572 {
573 if( zvel < 0 )
574 {
575 if( sector[hitsect].ceilingstat&1 )
576 {
577 sprite[k].xrepeat = 0;
578 sprite[k].yrepeat = 0;
579 return;
580 }
581 else
582 checkhitceiling(hitsect);
583 }
584 spawn(k,SMALLSMOKE);
585 }
586
587 if(hitspr >= 0)
588 {
589 checkhitsprite(hitspr,k);
590 if( sprite[hitspr].picnum == APLAYER && (ud.coop != 1 || ud.ffire == 1) )
591 {
592 l = spawn(k,JIBS6);
593 sprite[k].xrepeat = sprite[k].yrepeat = 0;
594 sprite[l].z += (4<<8);
595 sprite[l].xvel = 16;
596 sprite[l].xrepeat = sprite[l].yrepeat = 24;
597 sprite[l].ang += 64-(TRAND&127);
598 }
599 else spawn(k,SMALLSMOKE);
600
601 if(p >= 0 && (
602 sprite[hitspr].picnum == DIPSWITCH ||
603 sprite[hitspr].picnum == DIPSWITCH+1 ||
604 sprite[hitspr].picnum == DIPSWITCH2 ||
605 sprite[hitspr].picnum == DIPSWITCH2+1 ||
606 sprite[hitspr].picnum == DIPSWITCH3 ||
607 sprite[hitspr].picnum == DIPSWITCH3+1 ||
608 sprite[hitspr].picnum == HANDSWITCH ||
609 sprite[hitspr].picnum == HANDSWITCH+1) )
610 {
611 checkhitswitch(p,hitspr,1);
612 return;
613 }
614 }
615 else if( hitwall >= 0 )
616 {
617 spawn(k,SMALLSMOKE);
618
619 if( isadoorwall(wall[hitwall].picnum) == 1 )
620 goto SKIPBULLETHOLE;
621 if(p >= 0 && (
622 wall[hitwall].picnum == DIPSWITCH ||
623 wall[hitwall].picnum == DIPSWITCH+1 ||
624 wall[hitwall].picnum == DIPSWITCH2 ||
625 wall[hitwall].picnum == DIPSWITCH2+1 ||
626 wall[hitwall].picnum == DIPSWITCH3 ||
627 wall[hitwall].picnum == DIPSWITCH3+1 ||
628 wall[hitwall].picnum == HANDSWITCH ||
629 wall[hitwall].picnum == HANDSWITCH+1) )
630 {
631 checkhitswitch(p,hitwall,0);
632 return;
633 }
634
635 if(wall[hitwall].hitag != 0 || ( wall[hitwall].nextwall >= 0 && wall[wall[hitwall].nextwall].hitag != 0 ) )
636 goto SKIPBULLETHOLE;
637
638 if( hitsect >= 0 && sector[hitsect].lotag == 0 )
639 if( wall[hitwall].overpicnum != BIGFORCE )
640 if( (wall[hitwall].nextsector >= 0 && sector[wall[hitwall].nextsector].lotag == 0 ) ||
641 ( wall[hitwall].nextsector == -1 && sector[hitsect].lotag == 0 ) )
642 if( (wall[hitwall].cstat&16) == 0)
643 {
644 if(wall[hitwall].nextsector >= 0)
645 {
646 l = headspritesect[wall[hitwall].nextsector];
647 while(l >= 0)
648 {
649 if(sprite[l].statnum == 3 && sprite[l].lotag == 13)
650 goto SKIPBULLETHOLE;
651 l = nextspritesect[l];
652 }
653 }
654
655 l = headspritestat[5];
656 while(l >= 0)
657 {
658 if(sprite[l].picnum == BULLETHOLE)
659 if(dist(&sprite[l],&sprite[k]) < (12+(TRAND&7)) )
660 goto SKIPBULLETHOLE;
661 l = nextspritestat[l];
662 }
663 l = spawn(k,BULLETHOLE);
664 sprite[l].xvel = -1;
665 sprite[l].ang = getangle(wall[hitwall].x-wall[wall[hitwall].point2].x,
666 wall[hitwall].y-wall[wall[hitwall].point2].y)+512;
667 ssp(l,CLIPMASK0);
668 }
669
670 SKIPBULLETHOLE:
671
672 if( wall[hitwall].cstat&2 )
673 if(wall[hitwall].nextsector >= 0)
674 if(hitz >= (sector[wall[hitwall].nextsector].floorz) )
675 hitwall = wall[hitwall].nextwall;
676
677 checkhitwall(k,hitwall,hitx,hity,hitz,SHOTSPARK1);
678 }
679 }
680 else
681 {
682 k = EGS(hitsect,hitx,hity,hitz,SHOTSPARK1,-15,24,24,sa,0,0,i,4);
683 sprite[k].extra = *actorscrptr[atwith];
684
685 if( hitspr >= 0 )
686 {
687 checkhitsprite(hitspr,k);
688 if( sprite[hitspr].picnum != APLAYER )
689 spawn(k,SMALLSMOKE);
690 else sprite[k].xrepeat = sprite[k].yrepeat = 0;
691 }
692 else if( hitwall >= 0 )
693 checkhitwall(k,hitwall,hitx,hity,hitz,SHOTSPARK1);
694 }
695
696 if( (TRAND&255) < 4 )
697 xyzsound(PISTOL_RICOCHET,k,hitx,hity,hitz);
698
699 return;
700
701 case FIRELASER:
702 case SPIT:
703 case COOLEXPLOSION1:
704
705 if( s->extra >= 0 ) s->shade = -96;
706
707 scount = 1;
708 if(atwith == SPIT) vel = 292;
709 else
710 {
711 if(atwith == COOLEXPLOSION1)
712 {
713 if(s->picnum == BOSS2) vel = 644;
714 else vel = 348;
715 sz -= (4<<7);
716 }
717 else
718 {
719 vel = 840;
720 sz -= (4<<7);
721 }
722 }
723
724 if(p >= 0)
725 {
726 j = aim( s, AUTO_AIM_ANGLE, ps[p].auto_aim==2 );
727 if(j >= 0)
728 {
729 dal = ((sprite[j].xrepeat*tiles[sprite[j].picnum].dim.height)<<1)-(12<<8);
730 zvel = ((sprite[j].z-sz-dal)*vel ) / ldist(&sprite[ps[p].i], &sprite[j]) ;
731 sa = getangle(sprite[j].x-sx,sprite[j].y-sy);
732 }
733 else
734 zvel = (100-ps[p].horiz-ps[p].horizoff)*98;
735 }
736 else
737 {
738 j = findplayer(s,&x);
739// sa = getangle(ps[j].oposx-sx,ps[j].oposy-sy);
740 sa += 16-(TRAND&31);
741 zvel = ( ( (ps[j].oposz - sz + (3<<8) ) )*vel ) / ldist(&sprite[ps[j].i],s);
742 }
743
744 oldzvel = zvel;
745
746 if(atwith == SPIT) { sizx = 18;sizy = 18,sz -= (10<<8); }
747 else
748 {
749 if( atwith == FIRELASER )
750 {
751 if(p >= 0)
752 {
753
754 sizx = 34;
755 sizy = 34;
756 }
757 else
758 {
759 sizx = 18;
760 sizy = 18;
761 }
762 }
763 else
764 {
765 sizx = 18;
766 sizy = 18;
767 }
768 }
769
770 if(p >= 0) sizx = 7,sizy = 7;
771
772 while(scount > 0)
773 {
774 j = EGS(sect,sx,sy,sz,atwith,-127,sizx,sizy,sa,vel,zvel,i,4);
775 sprite[j].extra += (TRAND&7);
776
777 if(atwith == COOLEXPLOSION1)
778 {
779 sprite[j].shade = 0;
780 if(PN == BOSS2)
781 {
782 l = sprite[j].xvel;
783 sprite[j].xvel = 1024;
784 ssp(j,CLIPMASK0);
785 sprite[j].xvel = l;
786 sprite[j].ang += 128-(TRAND&255);
787 }
788 }
789
790 sprite[j].cstat = 128;
791 sprite[j].clipdist = 4;
792
793 sa = s->ang+32-(TRAND&63);
794 zvel = oldzvel+512-(TRAND&1023);
795
796 scount--;
797 }
798
799 return;
800
801 case FREEZEBLAST:
802 sz += (3<<8);
803 case RPG:
804
805 if( s->extra >= 0 ) s->shade = -96;
806
807 scount = 1;
808 vel = 644;
809
810 j = -1;
811
812 if(p >= 0)
813 {
814 j = aim( s, 48, ps[p].auto_aim==2);
815 if(j >= 0)
816 {
817 dal = ((sprite[j].xrepeat*tiles[sprite[j].picnum].dim.height)<<1)+(8<<8);
818 zvel = ( (sprite[j].z-sz-dal)*vel ) / ldist(&sprite[ps[p].i], &sprite[j]);
819 if( sprite[j].picnum != RECON )
820 sa = getangle(sprite[j].x-sx,sprite[j].y-sy);
821 }
822 else zvel = (100-ps[p].horiz-ps[p].horizoff)*81;
823 if(atwith == RPG)
824 spritesound(RPG_SHOOT,i);
825
826 }
827 else
828 {
829 j = findplayer(s,&x);
830 sa = getangle(ps[j].oposx-sx,ps[j].oposy-sy);
831 if(PN == BOSS3)
832 sz -= (32<<8);
833 else if(PN == BOSS2)
834 {
835 vel += 128;
836 sz += 24<<8;
837 }
838
839 l = ldist(&sprite[ps[j].i],s);
840 zvel = ( (ps[j].oposz-sz)*vel) / l;
841
842 if( badguy(s) && (s->hitag&face_player_smart) )
843 sa = s->ang+(TRAND&31)-16;
844 }
845
846 if( p >= 0 && j >= 0)
847 l = j;
848 else l = -1;
849
850 j = EGS(sect,
851 sx+(sintable[(348+sa+512)&2047]/448),
852 sy+(sintable[(sa+348)&2047]/448),
853 sz-(1<<8),atwith,0,14,14,sa,vel,zvel,i,4);
854
855 sprite[j].extra += (TRAND&7);
856 if(atwith != FREEZEBLAST)
857 sprite[j].yvel = l;
858 else
859 {
860 sprite[j].yvel = numfreezebounces;
861 sprite[j].xrepeat >>= 1;
862 sprite[j].yrepeat >>= 1;
863 sprite[j].zvel -= (2<<4);
864 }
865
866 if(p == -1)
867 {
868 if(PN == BOSS3)
869 {
870 if(TRAND&1)
871 {
872 sprite[j].x -= sintable[sa&2047]>>6;
873 sprite[j].y -= sintable[(sa+1024+512)&2047]>>6;
874 sprite[j].ang -= 8;
875 }
876 else
877 {
878 sprite[j].x += sintable[sa&2047]>>6;
879 sprite[j].y += sintable[(sa+1024+512)&2047]>>6;
880 sprite[j].ang += 4;
881 }
882 sprite[j].xrepeat = 42;
883 sprite[j].yrepeat = 42;
884 }
885 else if(PN == BOSS2)
886 {
887 sprite[j].x -= sintable[sa&2047]/56;
888 sprite[j].y -= sintable[(sa+1024+512)&2047]/56;
889 sprite[j].ang -= 8+(TRAND&255)-128;
890 sprite[j].xrepeat = 24;
891 sprite[j].yrepeat = 24;
892 }
893 else if(atwith != FREEZEBLAST)
894 {
895 sprite[j].xrepeat = 30;
896 sprite[j].yrepeat = 30;
897 sprite[j].extra >>= 2;
898 }
899 }
900 else if(ps[p].curr_weapon == DEVISTATOR_WEAPON)
901 {
902 sprite[j].extra >>= 2;
903 sprite[j].ang += 16-(TRAND&31);
904 sprite[j].zvel += 256-(TRAND&511);
905
906 if( ps[p].hbomb_hold_delay )
907 {
908 sprite[j].x -= sintable[sa&2047]/644;
909 sprite[j].y -= sintable[(sa+1024+512)&2047]/644;
910 }
911 else
912 {
913 sprite[j].x += sintable[sa&2047]>>8;
914 sprite[j].y += sintable[(sa+1024+512)&2047]>>8;
915 }
916 sprite[j].xrepeat >>= 1;
917 sprite[j].yrepeat >>= 1;
918 }
919
920 sprite[j].cstat = 128;
921 if(atwith == RPG)
922 sprite[j].clipdist = 4;
923 else
924 sprite[j].clipdist = 40;
925
926 break;
927
928 case HANDHOLDINGLASER:
929
930 if(p >= 0)
931 zvel = (100-ps[p].horiz-ps[p].horizoff)*32;
932 else zvel = 0;
933
934 hitscan(sx,sy,sz-ps[p].pyoff,sect,
935 sintable[(sa+512)&2047],
936 sintable[sa&2047],
937 zvel<<6,&hitsect,&hitwall,&hitspr,&hitx,&hity,&hitz,CLIPMASK1);
938
939 j = 0;
940 if(hitspr >= 0) break;
941
942 if(hitwall >= 0 && hitsect >= 0)
943 if( ((hitx-sx)*(hitx-sx)+(hity-sy)*(hity-sy)) < (290*290) )
944 {
945 if( wall[hitwall].nextsector >= 0)
946 {
947 if( sector[wall[hitwall].nextsector].lotag <= 2 && sector[hitsect].lotag <= 2 )
948 j = 1;
949 }
950 else if( sector[hitsect].lotag <= 2 )
951 j = 1;
952 }
953
954 if(j == 1)
955 {
956 k = EGS(hitsect,hitx,hity,hitz,TRIPBOMB,-16,4,5,sa,0,0,i,6);
957
958 sprite[k].hitag = k;
959 spritesound(LASERTRIP_ONWALL,k);
960 sprite[k].xvel = -20;
961 ssp(k,CLIPMASK0);
962 sprite[k].cstat = 16;
963 hittype[k].temp_data[5] = sprite[k].ang = getangle(wall[hitwall].x-wall[wall[hitwall].point2].x,wall[hitwall].y-wall[wall[hitwall].point2].y)-512;
964
965 if(p >= 0)
966 ps[p].ammo_amount[TRIPBOMB_WEAPON]--;
967
968 }
969 return;
970
971 case BOUNCEMINE:
972 case MORTER:
973
974 if( s->extra >= 0 ) s->shade = -96;
975
976 j = ps[findplayer(s,&x)].i;
977 x = ldist(&sprite[j],s);
978
979 zvel = -x>>1;
980
981 if(zvel < -4096)
982 zvel = -2048;
983 vel = x>>4;
984
985 EGS(sect,
986 sx+(sintable[(512+sa+512)&2047]>>8),
987 sy+(sintable[(sa+512)&2047]>>8),
988 sz+(6<<8),atwith,-64,32,32,sa,vel,zvel,i,1);
989 break;
990
991 case GROWSPARK:
992
993 if(p >= 0)
994 {
995 j = aim( s, AUTO_AIM_ANGLE, ps[p].auto_aim==2);
996 if(j >= 0)
997 {
998 dal = ((sprite[j].xrepeat*tiles[sprite[j].picnum].dim.height)<<1)+(5<<8);
999 switch(sprite[j].picnum)
1000 {
1001 case GREENSLIME:
1002 case GREENSLIME+1:
1003 case GREENSLIME+2:
1004 case GREENSLIME+3:
1005 case GREENSLIME+4:
1006 case GREENSLIME+5:
1007 case GREENSLIME+6:
1008 case GREENSLIME+7:
1009 case ROTATEGUN:
1010 dal -= (8<<8);
1011 break;
1012 }
1013 zvel = ( ( sprite[j].z-sz-dal )<<8 ) / (ldist(&sprite[ps[p].i], &sprite[j]) );
1014 sa = getangle(sprite[j].x-sx,sprite[j].y-sy);
1015 }
1016 else
1017 {
1018 sa += 16-(TRAND&31);
1019 zvel = (100-ps[p].horiz-ps[p].horizoff)<<5;
1020 zvel += 128-(TRAND&255);
1021 }
1022
1023 sz -= (2<<8);
1024 }
1025 else
1026 {
1027 j = findplayer(s,&x);
1028 sz -= (4<<8);
1029 zvel = ( (ps[j].posz-sz) <<8 ) / (ldist(&sprite[ps[j].i], s ) );
1030 zvel += 128-(TRAND&255);
1031 sa += 32-(TRAND&63);
1032 }
1033
1034 k = 0;
1035
1036// RESHOOTGROW:
1037
1038 s->cstat &= ~257;
1039 hitscan(sx,sy,sz,sect,
1040 sintable[(sa+512)&2047],
1041 sintable[sa&2047],
1042 zvel<<6,&hitsect,&hitwall,&hitspr,&hitx,&hity,&hitz,CLIPMASK1);
1043
1044 s->cstat |= 257;
1045
1046 j = EGS(sect,hitx,hity,hitz,GROWSPARK,-16,28,28,sa,0,0,i,1);
1047
1048 sprite[j].pal = 2;
1049 sprite[j].cstat |= 130;
1050 sprite[j].xrepeat = sprite[j].yrepeat = 1;
1051
1052 if( hitwall == -1 && hitspr == -1 && hitsect >= 0)
1053 {
1054 if( zvel < 0 && (sector[hitsect].ceilingstat&1) == 0)
1055 checkhitceiling(hitsect);
1056 }
1057 else if(hitspr >= 0) checkhitsprite(hitspr,j);
1058 else if(hitwall >= 0 && wall[hitwall].picnum != ACCESSSWITCH && wall[hitwall].picnum != ACCESSSWITCH2 )
1059 {
1060 /* if(wall[hitwall].overpicnum == MIRROR && k == 0)
1061 {
1062 l = getangle(
1063 wall[wall[hitwall].point2].x-wall[hitwall].x,
1064 wall[wall[hitwall].point2].y-wall[hitwall].y);
1065
1066 sx = hitx;
1067 sy = hity;
1068 sz = hitz;
1069 sect = hitsect;
1070 sa = ((l<<1) - sa)&2047;
1071 sx += sintable[(sa+512)&2047]>>12;
1072 sy += sintable[sa&2047]>>12;
1073
1074 k++;
1075 goto RESHOOTGROW;
1076 }
1077 else */
1078 checkhitwall(j,hitwall,hitx,hity,hitz,atwith);
1079 }
1080
1081 break;
1082 case SHRINKER:
1083 if( s->extra >= 0 ) s->shade = -96;
1084 if(p >= 0)
1085 {
1086 j = aim( s, AUTO_AIM_ANGLE, ps[p].auto_aim==2);
1087 if(j >= 0)
1088 {
1089 dal = ((sprite[j].xrepeat*tiles[sprite[j].picnum].dim.height)<<1);
1090 zvel = ( (sprite[j].z-sz-dal-(4<<8))*768) / (ldist( &sprite[ps[p].i], &sprite[j]));
1091 sa = getangle(sprite[j].x-sx,sprite[j].y-sy);
1092 }
1093 else zvel = (100-ps[p].horiz-ps[p].horizoff)*98;
1094 }
1095 else if(s->statnum != 3)
1096 {
1097 j = findplayer(s,&x);
1098 l = ldist(&sprite[ps[j].i],s);
1099 zvel = ( (ps[j].oposz-sz)*512) / l ;
1100 }
1101 else zvel = 0;
1102
1103 j = EGS(sect,
1104 sx+(sintable[(512+sa+512)&2047]>>12),
1105 sy+(sintable[(sa+512)&2047]>>12),
1106 sz+(2<<8),SHRINKSPARK,-16,28,28,sa,768,zvel,i,4);
1107
1108 sprite[j].cstat = 128;
1109 sprite[j].clipdist = 32;
1110
1111
1112 return;
1113 }
1114 return;
1115}
1116
1117void displayloogie(short snum)
1118{
1119 int32_t i, a, x, y, z;
1120
1121 if(ps[snum].loogcnt == 0) return;
1122
1123 y = (ps[snum].loogcnt<<2);
1124 for(i=0;i<ps[snum].numloogs;i++)
1125 {
1126 a = klabs(sintable[((ps[snum].loogcnt+i)<<5)&2047])>>5;
1127 z = 4096+((ps[snum].loogcnt+i)<<9);
1128 x = (-sync[snum].avel)+(sintable[((ps[snum].loogcnt+i)<<6)&2047]>>10);
1129
1130 rotatesprite(
1131 (ps[snum].loogiex[i]+x)<<16,(200+ps[snum].loogiey[i]-y)<<16,z-(i<<8),256-a,
1132 LOOGIE,0,0,2,0,0,xdim-1,ydim-1);
1133 }
1134}
1135
1136uint8_t animatefist(short gs,short snum)
1137{
1138 short looking_arc,fisti,fistpal;
1139 int32_t fistzoom, fistz;
1140
1141 fisti = ps[snum].fist_incs;
1142 if(fisti > 32) fisti = 32;
1143 if(fisti <= 0) return 0;
1144
1145 looking_arc = klabs(ps[snum].look_ang)/9;
1146
1147 fistzoom = 65536L - (sintable[(512+(fisti<<6))&2047]<<2);
1148 if(fistzoom > 90612L)
1149 fistzoom = 90612L;
1150 if(fistzoom < 40920)
1151 fistzoom = 40290;
1152 fistz = 194 + (sintable[((6+fisti)<<7)&2047]>>9);
1153
1154 if(sprite[ps[snum].i].pal == 1)
1155 fistpal = 1;
1156 else
1157 fistpal = sector[ps[snum].cursectnum].floorpal;
1158
1159 rotatesprite(
1160 (-fisti+222+(sync[snum].avel>>4))<<16,
1161 (looking_arc+fistz)<<16,
1162 fistzoom,0,FIST,gs,fistpal,2,0,0,xdim-1,ydim-1);
1163
1164 return 1;
1165}
1166
1167uint8_t animateknee(short gs,short snum)
1168{
1169 short knee_y[] = {0,-8,-16,-32,-64,-84,-108,-108,-108,-72,-32,-8};
1170 short looking_arc, pal;
1171
1172 if(ps[snum].knee_incs > 11 || ps[snum].knee_incs == 0 || sprite[ps[snum].i].extra <= 0) return 0;
1173
1174 looking_arc = knee_y[ps[snum].knee_incs] + klabs(ps[snum].look_ang)/9;
1175
1176 looking_arc -= (ps[snum].hard_landing<<3);
1177
1178 if(sprite[ps[snum].i].pal == 1)
1179 pal = 1;
1180 else
1181 {
1182 pal = sector[ps[snum].cursectnum].floorpal;
1183 if(pal == 0)
1184 pal = ps[snum].palookup;
1185 }
1186
1187 myospal(105+(sync[snum].avel>>4)-(ps[snum].look_ang>>1)+(knee_y[ps[snum].knee_incs]>>2),looking_arc+280-((ps[snum].horiz-ps[snum].horizoff)>>4),KNEE,gs,4,pal);
1188
1189 return 1;
1190}
1191
1192uint8_t animateknuckles(short gs,short snum)
1193{
1194 short knuckle_frames[] = {0,1,2,2,3,3,3,2,2,1,0};
1195 short looking_arc, pal;
1196
1197 if(ps[snum].knuckle_incs == 0 || sprite[ps[snum].i].extra <= 0) return 0;
1198
1199 looking_arc = klabs(ps[snum].look_ang)/9;
1200
1201 looking_arc -= (ps[snum].hard_landing<<3);
1202
1203 if(sprite[ps[snum].i].pal == 1)
1204 pal = 1;
1205 else
1206 pal = sector[ps[snum].cursectnum].floorpal;
1207
1208 myospal(160+(sync[snum].avel>>4)-(ps[snum].look_ang>>1),looking_arc+180-((ps[snum].horiz-ps[snum].horizoff)>>4),CRACKKNUCKLES+knuckle_frames[ps[snum].knuckle_incs>>1],gs,4,pal);
1209
1210 return 1;
1211}
1212
1213
1214
1215int32_t lastvisinc;
1216
1217void displaymasks(short snum)
1218{
1219 short p;
1220
1221 if(sprite[ps[snum].i].pal == 1)
1222 p = 1;
1223 else
1224 p = sector[ps[snum].cursectnum].floorpal;
1225
1226 if(ps[snum].scuba_on)
1227 {
1228 if(ud.screen_size > 4)
1229 {
1230 rotatesprite((43<<16),(200-8-((tiles[SCUBAMASK].dim.height)<<16)),65536,0,SCUBAMASK,0,p,2+16,windowx1,windowy1,windowx2,windowy2);
1231 rotatesprite(((320-43)<<16),(200-8-((tiles[SCUBAMASK].dim.height)<<16)),65536,1024,SCUBAMASK,0,p,2+4+16,windowx1,windowy1,windowx2,windowy2);
1232 }
1233 else
1234 {
1235 rotatesprite((43<<16),(200-((tiles[SCUBAMASK].dim.height)<<16)),65536,0,SCUBAMASK,0,p,2+16,windowx1,windowy1,windowx2,windowy2);
1236 rotatesprite(((320-43)<<16),(200-((tiles[SCUBAMASK].dim.height)<<16)),65536,1024,SCUBAMASK,0,p,2+4+16,windowx1,windowy1,windowx2,windowy2);
1237 }
1238 }
1239}
1240
1241uint8_t animatetip(short gs,short snum)
1242{
1243 short p,looking_arc;
1244 short tip_y[] = {0,-8,-16,-32,-64,-84,-108,-108,-108,-108,-108,-108,-108,-108,-108,-108,-96,-72,-64,-32,-16};
1245
1246 if(ps[snum].tipincs == 0) return 0;
1247
1248 looking_arc = klabs(ps[snum].look_ang)/9;
1249 looking_arc -= (ps[snum].hard_landing<<3);
1250
1251 if(sprite[ps[snum].i].pal == 1)
1252 p = 1;
1253 else
1254 p = sector[ps[snum].cursectnum].floorpal;
1255
1256/* if(ps[snum].access_spritenum >= 0)
1257 p = sprite[ps[snum].access_spritenum].pal;
1258 else
1259 p = wall[ps[snum].access_wallnum].pal;
1260 */
1261 myospal(170+(sync[snum].avel>>4)-(ps[snum].look_ang>>1),
1262 (tip_y[ps[snum].tipincs]>>1)+looking_arc+240-((ps[snum].horiz-ps[snum].horizoff)>>4),TIP+((26-ps[snum].tipincs)>>4),gs,0,p);
1263
1264 return 1;
1265}
1266
1267uint8_t animateaccess(short gs,short snum)
1268{
1269 short access_y[] = {0,-8,-16,-32,-64,-84,-108,-108,-108,-108,-108,-108,-108,-108,-108,-108,-96,-72,-64,-32,-16};
1270 short looking_arc;
1271 uint8_t p;
1272
1273 if(ps[snum].access_incs == 0 || sprite[ps[snum].i].extra <= 0) return 0;
1274
1275 looking_arc = access_y[ps[snum].access_incs] + klabs(ps[snum].look_ang)/9;
1276 looking_arc -= (ps[snum].hard_landing<<3);
1277
1278 if(ps[snum].access_spritenum >= 0)
1279 p = sprite[ps[snum].access_spritenum].pal;
1280 else p = 0;
1281// else
1282// p = wall[ps[snum].access_wallnum].pal;
1283
1284 if((ps[snum].access_incs-3) > 0 && (ps[snum].access_incs-3)>>3)
1285 myospal(170+(sync[snum].avel>>4)-(ps[snum].look_ang>>1)+(access_y[ps[snum].access_incs]>>2),looking_arc+266-((ps[snum].horiz-ps[snum].horizoff)>>4),HANDHOLDINGLASER+(ps[snum].access_incs>>3),gs,0,p);
1286 else
1287 myospal(170+(sync[snum].avel>>4)-(ps[snum].look_ang>>1)+(access_y[ps[snum].access_incs]>>2),looking_arc+266-((ps[snum].horiz-ps[snum].horizoff)>>4),HANDHOLDINGACCESS,gs,4,p);
1288
1289 return 1;
1290}
1291
1292short fistsign;
1293
1294void displayweapon(short snum)
1295{
1296 int32_t gun_pos, looking_arc, cw;
1297 int32_t weapon_xoffset, i, j;
1298 uint8_t o,pal;
1299 int8_t gs;
1300 struct player_struct *p;
1301 short *kb;
1302
1303
1304
1305 p = &ps[snum];
1306 kb = &p->kickback_pic;
1307
1308 o = 0;
1309
1310 looking_arc = klabs(p->look_ang)/9;
1311
1312 gs = sprite[p->i].shade;
1313 if(gs > 24) gs = 24;
1314
1315 if(p->newowner >= 0 || ud.camerasprite >= 0 || p->over_shoulder_on > 0 || (sprite[p->i].pal != 1 && sprite[p->i].extra <= 0) || animatefist(gs,snum) || animateknuckles(gs,snum) || animatetip(gs,snum) || animateaccess(gs,snum) )
1316 return;
1317
1318 animateknee(gs,snum);
1319
1320 gun_pos = 80-(p->weapon_pos*p->weapon_pos);
1321
1322 weapon_xoffset = (160)-90;
1323 weapon_xoffset -= (sintable[((p->weapon_sway>>1)+512)&2047]/(1024+512));
1324 weapon_xoffset -= 58 + p->weapon_ang;
1325 if( sprite[p->i].xrepeat < 32 )
1326 gun_pos -= klabs(sintable[(p->weapon_sway<<2)&2047]>>9);
1327 else gun_pos -= klabs(sintable[(p->weapon_sway>>1)&2047]>>10);
1328
1329 gun_pos -= (p->hard_landing<<3);
1330
1331 if(p->last_weapon >= 0)
1332 cw = p->last_weapon;
1333 else cw = p->curr_weapon;
1334
1335 j = 14-p->quick_kick;
1336 if(j != 14)
1337 {
1338 if(sprite[p->i].pal == 1)
1339 pal = 1;
1340 else
1341 {
1342 pal = sector[p->cursectnum].floorpal;
1343 if(pal == 0)
1344 pal = p->palookup;
1345 }
1346
1347
1348 if( j < 5 || j > 9 )
1349 myospal(weapon_xoffset+80-(p->look_ang>>1),
1350 looking_arc+250-gun_pos,KNEE,gs,o|4,pal);
1351 else myospal(weapon_xoffset+160-16-(p->look_ang>>1),
1352 looking_arc+214-gun_pos,KNEE+1,gs,o|4,pal);
1353 }
1354
1355 if( sprite[p->i].xrepeat < 40 )
1356 {
1357 if(p->jetpack_on == 0 )
1358 {
1359 i = sprite[p->i].xvel;
1360 looking_arc += 32-(i>>1);
1361 fistsign += i>>1;
1362 }
1363 cw = weapon_xoffset;
1364 weapon_xoffset += sintable[(fistsign)&2047]>>10;
1365 myos(weapon_xoffset+250-(p->look_ang>>1),
1366 looking_arc+258-(klabs(sintable[(fistsign)&2047]>>8)),
1367 FIST,gs,o);
1368 weapon_xoffset = cw;
1369 weapon_xoffset -= sintable[(fistsign)&2047]>>10;
1370 myos(weapon_xoffset+40-(p->look_ang>>1),
1371 looking_arc+200+(klabs(sintable[(fistsign)&2047]>>8)),
1372 FIST,gs,o|4);
1373 }
1374 else
1375 {
1376 // FIX_00026: Weapon can now be hidden (on your screen only).
1377 if(!ud.hideweapon || cw==KNEE_WEAPON || cw == HANDREMOTE_WEAPON)
1378 {
1379 switch(cw)
1380 {
1381 case KNEE_WEAPON:
1382 if( (*kb) > 0 )
1383 {
1384 if(sprite[p->i].pal == 1)
1385 pal = 1;
1386 else
1387 {
1388 pal = sector[p->cursectnum].floorpal;
1389 if(pal == 0)
1390 pal = p->palookup;
1391 }
1392
1393 if( (*kb) < 5 || (*kb) > 9 )
1394 myospal(weapon_xoffset+220-(p->look_ang>>1),
1395 looking_arc+250-gun_pos,KNEE,gs,o,pal);
1396 else
1397 myospal(weapon_xoffset+160-(p->look_ang>>1),
1398 looking_arc+214-gun_pos,KNEE+1,gs,o,pal);
1399 }
1400 break;
1401
1402 case TRIPBOMB_WEAPON:
1403 if(sprite[p->i].pal == 1)
1404 pal = 1;
1405 else
1406 pal = sector[p->cursectnum].floorpal;
1407
1408 weapon_xoffset += 8;
1409 gun_pos -= 10;
1410
1411 if((*kb) > 6)
1412 looking_arc += ((*kb)<<3);
1413 else if((*kb) < 4)
1414 myospal(weapon_xoffset+142-(p->look_ang>>1),
1415 looking_arc+234-gun_pos,HANDHOLDINGLASER+3,gs,o,pal);
1416
1417 myospal(weapon_xoffset+130-(p->look_ang>>1),
1418 looking_arc+249-gun_pos,
1419 HANDHOLDINGLASER+((*kb)>>2),gs,o,pal);
1420 myospal(weapon_xoffset+152-(p->look_ang>>1),
1421 looking_arc+249-gun_pos,
1422 HANDHOLDINGLASER+((*kb)>>2),gs,o|4,pal);
1423
1424 break;
1425
1426 case RPG_WEAPON:
1427 if(sprite[p->i].pal == 1)
1428 pal = 1;
1429 else pal = sector[p->cursectnum].floorpal;
1430
1431 weapon_xoffset -= sintable[(768+((*kb)<<7))&2047]>>11;
1432 gun_pos += sintable[(768+(((*kb)<<7)&2047))]>>11;
1433
1434 if(*kb > 0)
1435 {
1436 if(*kb < 8)
1437 {
1438 myospal(weapon_xoffset+164,(looking_arc<<1)+176-gun_pos,
1439 RPGGUN+((*kb)>>1),gs,o,pal);
1440 }
1441 }
1442
1443 myospal(weapon_xoffset+164,(looking_arc<<1)+176-gun_pos,
1444 RPGGUN,gs,o,pal);
1445
1446 break;
1447
1448 case SHOTGUN_WEAPON:
1449 if(sprite[p->i].pal == 1)
1450 pal = 1;
1451 else
1452 pal = sector[p->cursectnum].floorpal;
1453
1454 weapon_xoffset -= 8;
1455
1456 switch(*kb)
1457 {
1458 case 1:
1459 case 2:
1460 myospal(weapon_xoffset+168-(p->look_ang>>1),looking_arc+201-gun_pos,
1461 SHOTGUN+2,-128,o,pal);
1462 case 0:
1463 case 6:
1464 case 7:
1465 case 8:
1466 myospal(weapon_xoffset+146-(p->look_ang>>1),looking_arc+202-gun_pos,
1467 SHOTGUN,gs,o,pal);
1468 break;
1469 case 3:
1470 case 4:
1471 case 5:
1472 case 9:
1473 case 10:
1474 case 11:
1475 case 12:
1476 if( *kb > 1 && *kb < 5 )
1477 {
1478 gun_pos -= 40;
1479 weapon_xoffset += 20;
1480
1481 myospal(weapon_xoffset+178-(p->look_ang>>1),looking_arc+194-gun_pos,
1482 SHOTGUN+1+((*(kb)-1)>>1),-128,o,pal);
1483 }
1484
1485 myospal(weapon_xoffset+158-(p->look_ang>>1),looking_arc+220-gun_pos,
1486 SHOTGUN+3,gs,o,pal);
1487
1488 break;
1489 case 13:
1490 case 14:
1491 case 15:
1492 myospal(32+weapon_xoffset+166-(p->look_ang>>1),looking_arc+210-gun_pos,
1493 SHOTGUN+4,gs,o,pal);
1494 break;
1495 case 16:
1496 case 17:
1497 case 18:
1498 case 19:
1499 myospal(64+weapon_xoffset+170-(p->look_ang>>1),looking_arc+196-gun_pos,
1500 SHOTGUN+5,gs,o,pal);
1501 break;
1502 case 20:
1503 case 21:
1504 case 22:
1505 case 23:
1506 myospal(64+weapon_xoffset+176-(p->look_ang>>1),looking_arc+196-gun_pos,
1507 SHOTGUN+6,gs,o,pal);
1508 break;
1509 case 24:
1510 case 25:
1511 case 26:
1512 case 27:
1513 myospal(64+weapon_xoffset+170-(p->look_ang>>1),looking_arc+196-gun_pos,
1514 SHOTGUN+5,gs,o,pal);
1515 break;
1516 case 28:
1517 case 29:
1518 case 30:
1519 myospal(32+weapon_xoffset+156-(p->look_ang>>1),looking_arc+206-gun_pos,
1520 SHOTGUN+4,gs,o,pal);
1521 break;
1522 }
1523 break;
1524
1525
1526
1527 case CHAINGUN_WEAPON:
1528 if(sprite[p->i].pal == 1)
1529 pal = 1;
1530 else
1531 pal = sector[p->cursectnum].floorpal;
1532
1533 if(*kb > 0)
1534 gun_pos -= sintable[(*kb)<<7]>>12;
1535
1536 if(*kb > 0 && sprite[p->i].pal != 1) weapon_xoffset += 1-(rand()&3);
1537
1538 myospal(weapon_xoffset+168-(p->look_ang>>1),looking_arc+260-gun_pos,
1539 CHAINGUN,gs,o,pal);
1540 switch(*kb)
1541 {
1542 case 0:
1543 myospal(weapon_xoffset+178-(p->look_ang>>1),looking_arc+233-gun_pos,
1544 CHAINGUN+1,gs,o,pal);
1545 break;
1546 default:
1547 if(*kb > 4 && *kb < 12)
1548 {
1549 i = 0;
1550 if(sprite[p->i].pal != 1) i = rand()&7;
1551 myospal(i+weapon_xoffset-4+140-(p->look_ang>>1),i+looking_arc-((*kb)>>1)+208-gun_pos,
1552 CHAINGUN+5+((*kb-4)/5),gs,o,pal);
1553 if(sprite[p->i].pal != 1) i = rand()&7;
1554 myospal(i+weapon_xoffset-4+184-(p->look_ang>>1),i+looking_arc-((*kb)>>1)+208-gun_pos,
1555 CHAINGUN+5+((*kb-4)/5),gs,o,pal);
1556 }
1557 if(*kb < 8)
1558 {
1559 i = rand()&7;
1560 myospal(i+weapon_xoffset-4+162-(p->look_ang>>1),i+looking_arc-((*kb)>>1)+208-gun_pos,
1561 CHAINGUN+5+((*kb-2)/5),gs,o,pal);
1562 myospal(weapon_xoffset+178-(p->look_ang>>1),looking_arc+233-gun_pos,
1563 CHAINGUN+1+((*kb)>>1),gs,o,pal);
1564 }
1565 else myospal(weapon_xoffset+178-(p->look_ang>>1),looking_arc+233-gun_pos,
1566 CHAINGUN+1,gs,o,pal);
1567 break;
1568 }
1569 break;
1570 case PISTOL_WEAPON:
1571 if(sprite[p->i].pal == 1)
1572 pal = 1;
1573 else
1574 pal = sector[p->cursectnum].floorpal;
1575
1576 if( (*kb) < 5)
1577 {
1578 short kb_frames[] = {0,1,2,0,0},l;
1579
1580 l = 195-12+weapon_xoffset;
1581
1582 if((*kb) == 2)
1583 l -= 3;
1584 myospal(
1585 (l-(p->look_ang>>1)),
1586 (looking_arc+244-gun_pos),
1587 FIRSTGUN+kb_frames[*kb],
1588 gs,2,pal);
1589 }
1590 else
1591 {
1592 if((*kb) < 10)
1593 myospal(194-(p->look_ang>>1),looking_arc+230-gun_pos,FIRSTGUN+4,gs,o,pal);
1594 else if((*kb) < 15)
1595 {
1596 myospal(244-((*kb)<<3)-(p->look_ang>>1),looking_arc+130-gun_pos+((*kb)<<4),FIRSTGUN+6,gs,o,pal);
1597 myospal(224-(p->look_ang>>1),looking_arc+220-gun_pos,FIRSTGUN+5,gs,o,pal);
1598 }
1599 else if((*kb) < 20)
1600 {
1601 myospal(124+((*kb)<<1)-(p->look_ang>>1),looking_arc+430-gun_pos-((*kb)<<3),FIRSTGUN+6,gs,o,pal);
1602 myospal(224-(p->look_ang>>1),looking_arc+220-gun_pos,FIRSTGUN+5,gs,o,pal);
1603 }
1604 else if((*kb) < 23)
1605 {
1606 myospal(184-(p->look_ang>>1),looking_arc+235-gun_pos,FIRSTGUN+8,gs,o,pal);
1607 myospal(224-(p->look_ang>>1),looking_arc+210-gun_pos,FIRSTGUN+5,gs,o,pal);
1608 }
1609 else if((*kb) < 25)
1610 {
1611 myospal(164-(p->look_ang>>1),looking_arc+245-gun_pos,FIRSTGUN+8,gs,o,pal);
1612 myospal(224-(p->look_ang>>1),looking_arc+220-gun_pos,FIRSTGUN+5,gs,o,pal);
1613 }
1614 else if((*kb) < 27)
1615 myospal(194-(p->look_ang>>1),looking_arc+235-gun_pos,FIRSTGUN+5,gs,o,pal);
1616 }
1617
1618 break;
1619 case HANDBOMB_WEAPON:
1620 {
1621 if(sprite[p->i].pal == 1)
1622 pal = 1;
1623 else
1624 pal = sector[p->cursectnum].floorpal;
1625
1626 if((*kb))
1627 {
1628 uint8_t throw_frames[]
1629 = {0,0,0,0,0,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2};
1630
1631 if((*kb) < 7)
1632 gun_pos -= 10*(*kb); //D
1633 else if((*kb) < 12)
1634 gun_pos += 20*((*kb)-10); //U
1635 else if((*kb) < 20)
1636 gun_pos -= 9*((*kb)-14); //D
1637
1638 myospal(weapon_xoffset+190-(p->look_ang>>1),looking_arc+250-gun_pos,HANDTHROW+throw_frames[(*kb)],gs,o,pal);
1639 }
1640 else
1641 myospal(weapon_xoffset+190-(p->look_ang>>1),looking_arc+260-gun_pos,HANDTHROW,gs,o,pal);
1642 }
1643 break;
1644
1645 case HANDREMOTE_WEAPON:
1646 {
1647 int8_t remote_frames[] = {0,1,1,2,1,1,0,0,0,0,0};
1648 if(sprite[p->i].pal == 1)
1649 pal = 1;
1650 else
1651 pal = sector[p->cursectnum].floorpal;
1652
1653 weapon_xoffset = -48;
1654
1655 if((*kb))
1656 myospal(weapon_xoffset+150-(p->look_ang>>1),looking_arc+258-gun_pos,HANDREMOTE+remote_frames[(*kb)],gs,o,pal);
1657 else
1658 myospal(weapon_xoffset+150-(p->look_ang>>1),looking_arc+258-gun_pos,HANDREMOTE,gs,o,pal);
1659 }
1660 break;
1661 case DEVISTATOR_WEAPON:
1662 if(sprite[p->i].pal == 1)
1663 pal = 1;
1664 else
1665 pal = sector[p->cursectnum].floorpal;
1666
1667 if((*kb))
1668 {
1669 uint8_t cycloidy[] = {0,4,12,24,12,4,0};
1670
1671 i = sgn((*kb)>>2);
1672
1673 if(p->hbomb_hold_delay)
1674 {
1675 myospal( (cycloidy[*kb]>>1)+weapon_xoffset+268-(p->look_ang>>1),cycloidy[*kb]+looking_arc+238-gun_pos,DEVISTATOR+i,-32,o,pal);
1676 myospal(weapon_xoffset+30-(p->look_ang>>1),looking_arc+240-gun_pos,DEVISTATOR,gs,o|4,pal);
1677 }
1678 else
1679 {
1680 myospal( -(cycloidy[*kb]>>1)+weapon_xoffset+30-(p->look_ang>>1),cycloidy[*kb]+looking_arc+240-gun_pos,DEVISTATOR+i,-32,o|4,pal);
1681 myospal(weapon_xoffset+268-(p->look_ang>>1),looking_arc+238-gun_pos,DEVISTATOR,gs,o,pal);
1682 }
1683 }
1684 else
1685 {
1686 myospal(weapon_xoffset+268-(p->look_ang>>1),looking_arc+238-gun_pos,DEVISTATOR,gs,o,pal);
1687 myospal(weapon_xoffset+30-(p->look_ang>>1),looking_arc+240-gun_pos,DEVISTATOR,gs,o|4,pal);
1688 }
1689 break;
1690
1691 case FREEZE_WEAPON:
1692 if(sprite[p->i].pal == 1)
1693 pal = 1;
1694 else
1695 pal = sector[p->cursectnum].floorpal;
1696
1697 if((*kb))
1698 {
1699 uint8_t cat_frames[] = { 0,0,1,1,2,2 };
1700
1701 if(sprite[p->i].pal != 1)
1702 {
1703 weapon_xoffset += rand()&3;
1704 looking_arc += rand()&3;
1705 }
1706 gun_pos -= 16;
1707 myospal(weapon_xoffset+210-(p->look_ang>>1),looking_arc+261-gun_pos,FREEZE+2,-32,o,pal);
1708 myospal(weapon_xoffset+210-(p->look_ang>>1),looking_arc+235-gun_pos,FREEZE+3+cat_frames[*kb%6],-32,o,pal);
1709 }
1710 else myospal(weapon_xoffset+210-(p->look_ang>>1),looking_arc+261-gun_pos,FREEZE,gs,o,pal);
1711
1712 break;
1713
1714 case SHRINKER_WEAPON:
1715 case GROW_WEAPON:
1716 weapon_xoffset += 28;
1717 looking_arc += 18;
1718 if(sprite[p->i].pal == 1)
1719 pal = 1;
1720 else
1721 pal = sector[p->cursectnum].floorpal;
1722 if((*kb) == 0)
1723 {
1724 if(cw == GROW_WEAPON)
1725 {
1726 myospal(weapon_xoffset+184-(p->look_ang>>1),
1727 looking_arc+240-gun_pos,SHRINKER+2,
1728 16-(sintable[p->random_club_frame&2047]>>10),
1729 o,2);
1730
1731 myospal(weapon_xoffset+188-(p->look_ang>>1),
1732 looking_arc+240-gun_pos,SHRINKER-2,gs,o,pal);
1733 }
1734 else
1735 {
1736 myospal(weapon_xoffset+184-(p->look_ang>>1),
1737 looking_arc+240-gun_pos,SHRINKER+2,
1738 16-(sintable[p->random_club_frame&2047]>>10),
1739 o,0);
1740
1741 myospal(weapon_xoffset+188-(p->look_ang>>1),
1742 looking_arc+240-gun_pos,SHRINKER,gs,o,pal);
1743 }
1744 }
1745 else
1746 {
1747 if(sprite[p->i].pal != 1)
1748 {
1749 weapon_xoffset += rand()&3;
1750 gun_pos += (rand()&3);
1751 }
1752
1753 if(cw == GROW_WEAPON)
1754 {
1755 myospal(weapon_xoffset+184-(p->look_ang>>1),
1756 looking_arc+240-gun_pos,SHRINKER+3+((*kb)&3),-32,
1757 o,2);
1758
1759 myospal(weapon_xoffset+188-(p->look_ang>>1),
1760 looking_arc+240-gun_pos,SHRINKER-1,gs,o,pal);
1761
1762 }
1763 else
1764 {
1765 myospal(weapon_xoffset+184-(p->look_ang>>1),
1766 looking_arc+240-gun_pos,SHRINKER+3+((*kb)&3),-32,
1767 o,0);
1768
1769 myospal(weapon_xoffset+188-(p->look_ang>>1),
1770 looking_arc+240-gun_pos,SHRINKER+1,gs,o,pal);
1771 }
1772 }
1773 break;
1774 }
1775 }
1776 }
1777
1778 displayloogie(snum);
1779
1780}
1781
1782#define TURBOTURNTIME (TICRATE/3) // 7
1783#define NORMALTURN 15
1784#define PREAMBLETURN 5
1785#define NORMALKEYMOVE 40
1786#define MAXVEL ((NORMALKEYMOVE*2)+10)
1787#define MAXSVEL ((NORMALKEYMOVE*2)+10)
1788#define MAXANGVEL 127
1789#define MAXHORIZ 127
1790
1791int32_t myaimmode = 0, myaimstat = 0, omyaimstat = 0;
1792
1793void getinput(short snum)
1794{
1795
1796 short j, daang;
1797// MED
1798 ControlInfo info;
1799 int32 tics;
1800 boolean running;
1801 int32 turnamount;
1802 int32 keymove;
1803 int32 momx,momy;
1804 struct player_struct *p;
1805
1806 // FIX_00038: Improved Mouse accuracy (losses of integer computation)
1807 static fixed previousInfoDyaw = 0;
1808 static fixed previousInfoDpitch = 0;
1809 static fixed previousInfoDyawSvel = 0;
1810
1811 momx = momy = 0;
1812 p = &ps[snum];
1813
1814 CONTROL_GetInput( &info );
1815
1816 // FIX_00021: Duke was moving when moving the mouse up/down. Y axis move is disabled.
1817 info.dz = 0; // remove y axis
1818
1819 if( (p->gm&MODE_MENU) || (p->gm&MODE_TYPE) || (ud.pause_on && !KB_KeyPressed(sc_Pause)) )
1820 {
1821 loc.fvel = vel = 0;
1822 loc.svel = svel = 0;
1823 loc.avel = angvel = 0;
1824 loc.horz = horiz = 0;
1825 loc.bits = (((int32_t)gamequit)<<26);
1826 info.dz = info.dyaw = 0;
1827 return;
1828 }
1829
1830 tics = totalclock-lastcontroltime;
1831 lastcontroltime = totalclock;
1832
1833
1834 if (MouseAiming)
1835 myaimmode = ACTION(gamefunc_Mouse_Aiming); // mouse aiming button is temporary
1836 else
1837 { // mouse aiming button is a toggle
1838 omyaimstat = myaimstat; myaimstat = ACTION(gamefunc_Mouse_Aiming);
1839 if (myaimstat > omyaimstat)
1840 {
1841 myaimmode ^= 1;
1842 FTA(44+myaimmode,p,1);
1843 }
1844 }
1845
1846 // FIX_00039: Toggle autoaim between Normal (full) and partial (on bullet weapons only)
1847 if( ACTION(gamefunc_Auto_Aim) && nHostForceDisableAutoaim == 0)
1848 {
1849 ud.auto_aim++;
1850 ud.auto_aim = ((ud.auto_aim-1)%2)+1;
1851 sprintf(fta_quotes[103],"AUTOAIM %s", ud.auto_aim?(ud.auto_aim==1)?"BULLET ONLY":"NORMAL (FULL)":"OFF");
1852 vscrn(); // FIX_00056: Refresh issue w/FPS, small Weapon and custom FTA, when screen resized down
1853 // This is because we use the same FTA for BULLET and NORMAL text: duke doesn't see we
1854 // changed the text and doesnt issue a refresh
1855 FTA(103,&ps[screenpeek],1); // Originally reserved for "screen saved". Now used dynamically.
1856 CONTROL_ClearAction(gamefunc_Auto_Aim);
1857 }
1858
1859 if(multiflag == 1)
1860 {
1861 loc.bits = 1<<17;
1862 loc.bits |= multiwhat<<18;
1863 loc.bits |= multipos<<19;
1864 multiflag = 0;
1865 return;
1866 }
1867
1868 loc.bits = ACTION(gamefunc_Jump);
1869 loc.bits |= ACTION(gamefunc_Crouch)<<1;
1870 loc.bits |= ACTION(gamefunc_Fire)<<2;
1871 loc.bits |= ACTION(gamefunc_Aim_Up)<<3;
1872 loc.bits |= ACTION(gamefunc_Aim_Down)<<4;
1873 loc.bits |= ACTION(gamefunc_Run)<<5;
1874 loc.bits |= (ud.auto_aim==2)<<6; // 2 = normal, 1 = bullet only, 0 = disabled (not implemented)
1875 loc.bits |= ud.weaponautoswitch<<7;
1876
1877 j=0;
1878 if (ACTION(gamefunc_Weapon_1))
1879 j = 1;
1880 if (ACTION(gamefunc_Weapon_2))
1881 j = 2;
1882 if (ACTION(gamefunc_Weapon_3))
1883 j = 3;
1884 if (ACTION(gamefunc_Weapon_4))
1885 j = 4;
1886 if (ACTION(gamefunc_Weapon_5))
1887 j = 5;
1888 if (ACTION(gamefunc_Weapon_6))
1889 j = 6;
1890
1891 if (ACTION(gamefunc_Previous_Weapon))
1892 j = 11;
1893 if (ACTION(gamefunc_Next_Weapon))
1894 j = 12;
1895
1896 if (!VOLUMEONE)
1897 {
1898 if (ACTION(gamefunc_Weapon_7))
1899 j = 7;
1900 if (ACTION(gamefunc_Weapon_8))
1901 j = 8;
1902 if (ACTION(gamefunc_Weapon_9))
1903 j = 9;
1904 if (ACTION(gamefunc_Weapon_10))
1905 j = 10;
1906 }
1907
1908 loc.bits |= j<<8;
1909 loc.bits |= ACTION(gamefunc_Steroids)<<12;
1910 loc.bits |= ACTION(gamefunc_Look_Up)<<13;
1911 loc.bits |= ACTION(gamefunc_Look_Down)<<14;
1912 loc.bits |= ACTION(gamefunc_NightVision)<<15;
1913 if(ud.gitdat_mdk)
1914 {
1915 if(sprite[ps[myconnectindex].i].extra < max_player_health && ps[myconnectindex].firstaid_amount) // avoid medkit overloading controls
1916 loc.bits |= ACTION(gamefunc_MedKit)<<16;
1917 }
1918 else
1919 {
1920 loc.bits |= ACTION(gamefunc_MedKit)<<16;
1921 }
1922 loc.bits |= ACTION(gamefunc_Center_View)<<18;
1923 loc.bits |= ACTION(gamefunc_Holster_Weapon)<<19;
1924 if(ACTION(gamefunc_Hide_Weapon))
1925 {
1926 ud.hideweapon = !ud.hideweapon;
1927 vscrn(); // FIX_00056: Refresh issue w/FPS, small Weapon and custom FTA, when screen resized down
1928 CONTROL_ClearAction(gamefunc_Hide_Weapon);
1929 }
1930 loc.bits |= ACTION(gamefunc_Inventory_Left)<<20;
1931 loc.bits |= KB_KeyPressed(sc_Pause)<<21;
1932 loc.bits |= ACTION(gamefunc_Quick_Kick)<<22;
1933 loc.bits |= myaimmode<<23;
1934 loc.bits |= ACTION(gamefunc_Holo_Duke)<<24;
1935 loc.bits |= ACTION(gamefunc_Jetpack)<<25;
1936 loc.bits |= (((int32_t)gamequit)<<26);
1937 loc.bits |= ACTION(gamefunc_Inventory_Right)<<27;
1938 loc.bits |= ACTION(gamefunc_TurnAround)<<28;
1939 loc.bits |= ACTION(gamefunc_Open)<<29;
1940 loc.bits |= ACTION(gamefunc_Inventory)<<30;
1941 loc.bits |= KB_KeyPressed(sc_Escape)<<31;
1942
1943 running = ACTION(gamefunc_Run)|ud.auto_run;
1944 svel = vel = angvel = horiz = 0;
1945
1946 if( CONTROL_JoystickEnabled )
1947 {
1948 if ( running )
1949 {
1950 info.dz *= 2;
1951 }
1952 }
1953
1954 if( ACTION(gamefunc_Strafe) )
1955 {
1956 svel = -(info.dyaw+previousInfoDyawSvel)/8;
1957 }
1958 else
1959 {
1960 angvel = (info.dyaw+previousInfoDyaw)/64;
1961 }
1962
1963 previousInfoDyaw = (previousInfoDyaw+info.dyaw)%64; // % xduke: dont waste mouse tics
1964 previousInfoDyawSvel = (previousInfoDyawSvel+info.dyaw)%8;
1965
1966 // svel -= info.dx;
1967 svel = -info.dx>>6; // This helps the analog feel a bit.
1968
1969 vel = -info.dz>>6;
1970
1971 // Account for which mode we're in. (1, 2 or 7)
1972 switch(ControllerType)
1973 {
1974 case controltype_keyboardandjoystick:
1975
1976 case controltype_joystickandmouse:
1977
1978 if(CONTROL_JoystickEnabled)
1979 {
1980 if(ud.mouseflip)
1981 {
1982 horiz = -(info.dpitch+previousInfoDpitch)/(314-128);
1983 }
1984 else
1985 {
1986 horiz = (info.dpitch+previousInfoDpitch)/(314-128);
1987 }
1988 horiz = (horiz>=0)?horiz+1:horiz; // xduke: fix assymetry (speed of 2 is like -1)
1989 previousInfoDpitch = (previousInfoDpitch+info.dpitch)%(314-128);
1990 info.dpitch = 0;
1991 }
1992 break;
1993
1994 default:
1995 // If Mouse aim active
1996 if( myaimmode )
1997 {
1998 //
1999 //
2000 if(ud.mouseflip)
2001 {
2002 horiz = -(info.dpitch+previousInfoDpitch)/(314-128);
2003 }
2004 else
2005 {
2006 horiz = (info.dpitch+previousInfoDpitch)/(314-128);
2007 }
2008 horiz = (horiz>=0)?horiz+1:horiz; // xduke: fix assymetry (speed of 2 is like -1)
2009 previousInfoDpitch = (previousInfoDpitch+info.dpitch)%(314-128);
2010 info.dpitch = 0;
2011 }
2012 break;
2013 }
2014
2015
2016
2017 if (running)
2018 {
2019 turnamount = NORMALTURN<<1;
2020 keymove = NORMALKEYMOVE<<1;
2021 }
2022 else
2023 {
2024 turnamount = NORMALTURN;
2025 keymove = NORMALKEYMOVE;
2026 }
2027
2028 if (ACTION(gamefunc_Strafe))
2029 {
2030 if ( ACTION(gamefunc_Turn_Left))
2031 {
2032 svel -= -keymove;
2033 }
2034 if ( ACTION(gamefunc_Turn_Right))
2035 {
2036 svel -= keymove;
2037 }
2038 }
2039 else
2040 {
2041 if ( ACTION(gamefunc_Turn_Left))
2042 {
2043 turnheldtime += tics;
2044 if (turnheldtime>=TURBOTURNTIME)
2045 {
2046 angvel -= turnamount;
2047 }
2048 else
2049 {
2050 angvel -= PREAMBLETURN;
2051 }
2052 }
2053 else if ( ACTION(gamefunc_Turn_Right))
2054 {
2055 turnheldtime += tics;
2056 if (turnheldtime>=TURBOTURNTIME)
2057 {
2058 angvel += turnamount;
2059 }
2060 else
2061 {
2062 angvel += PREAMBLETURN;
2063 }
2064 }
2065 else
2066 {
2067 turnheldtime=0;
2068 }
2069 }
2070
2071 if ( ACTION( gamefunc_Strafe_Left ) )
2072 {
2073 svel += keymove;
2074 angvel = (info.dyaw+previousInfoDyaw)/64;
2075 }
2076
2077 if ( ACTION( gamefunc_Strafe_Right ) )
2078 {
2079 svel += -keymove;
2080 angvel = (info.dyaw+previousInfoDyaw)/64;
2081 }
2082
2083 if ( ACTION(gamefunc_Move_Forward) )
2084 vel += keymove;
2085
2086 if ( ACTION(gamefunc_Move_Backward) )
2087 vel += -keymove;
2088
2089 if(vel < -MAXVEL) vel = -MAXVEL;
2090 if(vel > MAXVEL) vel = MAXVEL;
2091 if(svel < -MAXSVEL) svel = -MAXSVEL;
2092 if(svel > MAXSVEL) svel = MAXSVEL;
2093 if(angvel < -MAXANGVEL) angvel = -MAXANGVEL;
2094 if(angvel > MAXANGVEL) angvel = MAXANGVEL;
2095 if(horiz < -MAXHORIZ) horiz = -MAXHORIZ;
2096 if(horiz > MAXHORIZ) horiz = MAXHORIZ;
2097
2098 if(ud.scrollmode && ud.overhead_on)
2099 {
2100 ud.folfvel = vel;
2101 ud.folavel = angvel;
2102 loc.fvel = 0;
2103 loc.svel = 0;
2104 loc.avel = 0;
2105 loc.horz = 0;
2106 return;
2107 }
2108
2109 if( numplayers > 1 )
2110 daang = myang;
2111 else daang = p->ang;
2112
2113 momx = mulscale9(vel,sintable[(daang+2560)&2047]);
2114 momy = mulscale9(vel,sintable[(daang+2048)&2047]);
2115
2116 momx += mulscale9(svel,sintable[(daang+2048)&2047]);
2117 momy += mulscale9(svel,sintable[(daang+1536)&2047]);
2118
2119 momx += fricxv;
2120 momy += fricyv;
2121
2122 loc.fvel = momx;
2123 loc.svel = momy;
2124 loc.avel = angvel;
2125// if(loc.avel)
2126// printf("getinput loc.avel=%d\n", loc.avel);
2127 loc.horz = horiz;
2128}
2129
2130
2131uint8_t doincrements(struct player_struct *p)
2132{
2133 int32_t snum;
2134
2135 snum = sprite[p->i].yvel;
2136// j = sync[snum].avel;
2137// p->weapon_ang = -(j/5);
2138
2139 p->player_par++;
2140
2141 if(p->invdisptime > 0)
2142 p->invdisptime--;
2143
2144 if(p->tipincs > 0) p->tipincs--;
2145
2146 if(p->last_pissed_time > 0 )
2147 {
2148 p->last_pissed_time--;
2149
2150 if( p->last_pissed_time == (26*219) )
2151 {
2152 spritesound(FLUSH_TOILET,p->i);
2153 if(snum == screenpeek || ud.coop == 1)
2154 spritesound(DUKE_PISSRELIEF,p->i);
2155 }
2156
2157 if( p->last_pissed_time == (26*218) )
2158 {
2159 p->holster_weapon = 0;
2160 p->weapon_pos = 10;
2161 }
2162 }
2163
2164 if(p->crack_time > 0)
2165 {
2166 p->crack_time--;
2167 if(p->crack_time == 0)
2168 {
2169 p->knuckle_incs = 1;
2170 p->crack_time = 777;
2171 }
2172 }
2173
2174 if( p->steroids_amount > 0 && p->steroids_amount < 400)
2175 {
2176 p->steroids_amount--;
2177 if(p->steroids_amount == 0)
2178 checkavailinven(p);
2179 if( !(p->steroids_amount&7) )
2180 if(snum == screenpeek || ud.coop == 1)
2181 spritesound(DUKE_HARTBEAT,p->i);
2182 }
2183
2184 if(p->heat_on && p->heat_amount > 0)
2185 {
2186 p->heat_amount--;
2187 if( p->heat_amount == 0 )
2188 {
2189 p->heat_on = 0;
2190 checkavailinven(p);
2191 spritesound(NITEVISION_ONOFF,p->i);
2192 setpal(p);
2193 }
2194 }
2195
2196 if( p->holoduke_on >= 0 )
2197 {
2198 p->holoduke_amount--;
2199 if(p->holoduke_amount <= 0)
2200 {
2201 spritesound(TELEPORTER,p->i);
2202 p->holoduke_on = -1;
2203 checkavailinven(p);
2204 }
2205 }
2206
2207 if( p->jetpack_on && p->jetpack_amount > 0 )
2208 {
2209 p->jetpack_amount--;
2210 if(p->jetpack_amount <= 0)
2211 {
2212 p->jetpack_on = 0;
2213 checkavailinven(p);
2214 spritesound(DUKE_JETPACK_OFF,p->i);
2215 stopsound(DUKE_JETPACK_IDLE);
2216 stopsound(DUKE_JETPACK_ON);
2217 }
2218 }
2219
2220 if(p->quick_kick > 0 && sprite[p->i].pal != 1)
2221 {
2222 p->quick_kick--;
2223 if( p->quick_kick == 8 )
2224 shoot(p->i,KNEE);
2225 }
2226
2227 if(p->access_incs && sprite[p->i].pal != 1)
2228 {
2229 p->access_incs++;
2230 if(sprite[p->i].extra <= 0)
2231 p->access_incs = 12;
2232 if(p->access_incs == 12)
2233 {
2234 if(p->access_spritenum >= 0)
2235 {
2236 checkhitswitch(snum,p->access_spritenum,1);
2237 switch(sprite[p->access_spritenum].pal)
2238 {
2239 case 0:p->got_access &= (0xffff-0x1);break;
2240 case 21:p->got_access &= (0xffff-0x2);break;
2241 case 23:p->got_access &= (0xffff-0x4);break;
2242 }
2243 p->access_spritenum = -1;
2244 }
2245 else
2246 {
2247 checkhitswitch(snum,p->access_wallnum,0);
2248 switch(wall[p->access_wallnum].pal)
2249 {
2250 case 0:p->got_access &= (0xffff-0x1);break;
2251 case 21:p->got_access &= (0xffff-0x2);break;
2252 case 23:p->got_access &= (0xffff-0x4);break;
2253 }
2254 }
2255 }
2256
2257 if(p->access_incs > 20)
2258 {
2259 p->access_incs = 0;
2260 p->weapon_pos = 10;
2261 p->kickback_pic = 0;
2262 }
2263 }
2264
2265 if(p->scuba_on == 0 && sector[p->cursectnum].lotag == 2)
2266 {
2267 if(p->scuba_amount > 0)
2268 {
2269 p->scuba_on = 1;
2270 p->inven_icon = 6;
2271 FTA(76,p,0);
2272 }
2273 else
2274 {
2275 if(p->airleft > 0)
2276 p->airleft--;
2277 else
2278 {
2279 p->extra_extra8 += 32;
2280 if(p->last_extra < (max_player_health>>1) && (p->last_extra&3) == 0)
2281 spritesound(DUKE_LONGTERM_PAIN,p->i);
2282 }
2283 }
2284 }
2285 else if(p->scuba_amount > 0 && p->scuba_on)
2286 {
2287 p->scuba_amount--;
2288 if(p->scuba_amount == 0)
2289 {
2290 p->scuba_on = 0;
2291 checkavailinven(p);
2292 }
2293 }
2294
2295 if(p->knuckle_incs)
2296 {
2297 p->knuckle_incs ++;
2298 if(p->knuckle_incs==10)
2299 {
2300 if(totalclock > 1024)
2301 if(snum == screenpeek || ud.coop == 1)
2302 {
2303 if(rand()&1)
2304 spritesound(DUKE_CRACK,p->i);
2305 else spritesound(DUKE_CRACK2,p->i);
2306 }
2307 spritesound(DUKE_CRACK_FIRST,p->i);
2308 }
2309 else if( p->knuckle_incs == 22 || (sync[snum].bits&(1<<2)))
2310 p->knuckle_incs=0;
2311
2312 return 1;
2313 }
2314 return 0;
2315}
2316
2317short weapon_sprites[MAX_WEAPONS] = { KNEE, FIRSTGUNSPRITE, SHOTGUNSPRITE,
2318 CHAINGUNSPRITE, RPGSPRITE, HEAVYHBOMB, SHRINKERSPRITE, DEVISTATORSPRITE,
2319 TRIPBOMBSPRITE, FREEZESPRITE, HEAVYHBOMB, SHRINKERSPRITE};
2320
2321void checkweapons(struct player_struct *p)
2322{
2323 short cw;
2324
2325 cw = p->curr_weapon;
2326
2327 if(cw < 1 || cw >= MAX_WEAPONS) return;
2328
2329 if(cw)
2330 {
2331 if(TRAND&1)
2332 spawn(p->i,weapon_sprites[cw]);
2333 else switch(cw)
2334 {
2335 case RPG_WEAPON:
2336 case HANDBOMB_WEAPON:
2337 spawn(p->i,EXPLOSION2);
2338 break;
2339 }
2340 }
2341}
2342
2343void processinput(short snum)
2344{
2345 int32_t j, i, k, doubvel, fz, cz, hz, lz, truefdist, x, y;
2346 uint8_t shrunk;
2347 uint32_t sb_snum;
2348 short psect, psectlotag,*kb, tempsect, pi;
2349 struct player_struct *p;
2350 spritetype *s;
2351 char text[512];
2352
2353 p = &ps[snum];
2354 pi = p->i;
2355 s = &sprite[pi];
2356
2357 kb = &p->kickback_pic;
2358
2359 if(p->cheat_phase <= 0) sb_snum = sync[snum].bits;
2360 else sb_snum = 0;
2361
2362 psect = p->cursectnum;
2363 if(psect == -1)
2364 {
2365 if(s->extra > 0 && ud.clipping == 0)
2366 {
2367 quickkill(p);
2368 spritesound(SQUISHED,pi);
2369 }
2370 psect = 0;
2371 }
2372
2373 psectlotag = sector[psect].lotag;
2374 p->spritebridge = 0;
2375
2376 shrunk = (s->yrepeat < 32);
2377 getzrange(p->posx,p->posy,p->posz,psect,&cz,&hz,&fz,&lz,163L,CLIPMASK0);
2378
2379 j = getflorzofslope(psect,p->posx,p->posy);
2380
2381 p->truefz = j;
2382 p->truecz = getceilzofslope(psect,p->posx,p->posy);
2383
2384 truefdist = klabs(p->posz-j);
2385 if( (lz&49152) == 16384 && psectlotag == 1 && truefdist > PHEIGHT+(16<<8) )
2386 psectlotag = 0;
2387
2388 hittype[pi].floorz = fz;
2389 hittype[pi].ceilingz = cz;
2390
2391 p->ohoriz = p->horiz;
2392 p->ohorizoff = p->horizoff;
2393
2394 if( p->aim_mode == 0 && p->on_ground && psectlotag != 2 && (sector[psect].floorstat&2) )
2395 {
2396 x = p->posx+(sintable[(p->ang+512)&2047]>>5);
2397 y = p->posy+(sintable[p->ang&2047]>>5);
2398 tempsect = psect;
2399 updatesector(x,y,&tempsect);
2400 if (tempsect >= 0)
2401 {
2402 k = getflorzofslope(psect,x,y);
2403 if (psect == tempsect)
2404 p->horizoff += mulscale16(j-k,160);
2405 else if (klabs(getflorzofslope(tempsect,x,y)-k) <= (4<<8))
2406 p->horizoff += mulscale16(j-k,160);
2407 }
2408 }
2409 if (p->horizoff > 0) p->horizoff -= ((p->horizoff>>3)+1);
2410 else if (p->horizoff < 0) p->horizoff += (((-p->horizoff)>>3)+1);
2411
2412 if( hz >= 0 && (hz&49152) == 49152)
2413 {
2414 hz &= (MAXSPRITES-1);
2415
2416 if(sprite[hz].statnum == 1 && sprite[hz].extra >= 0)
2417 {
2418 hz = 0;
2419 cz = p->truecz;
2420 }
2421 }
2422
2423 if(lz >= 0 && (lz&49152) == 49152)
2424 {
2425 j = lz&(MAXSPRITES-1);
2426
2427 if( (sprite[j].cstat&33) == 33 )
2428 {
2429 psectlotag = 0;
2430 p->footprintcount = 0;
2431 p->spritebridge = 1;
2432 }
2433 else if(badguy(&sprite[j]) && sprite[j].xrepeat > 24 && klabs(s->z-sprite[j].z) < (84<<8) )
2434 {
2435 j = getangle(sprite[j].x-p->posx,sprite[j].y-p->posy);
2436 p->posxv -= sintable[(j+512)&2047]<<4;
2437 p->posyv -= sintable[j&2047]<<4;
2438 }
2439 }
2440
2441
2442 if ( s->extra > 0 ) incur_damage( p );
2443 else
2444 {
2445 s->extra = 0;
2446 p->shield_amount = 0;
2447 }
2448
2449 p->last_extra = s->extra;
2450
2451 if(p->loogcnt > 0) p->loogcnt--;
2452 else p->loogcnt = 0;
2453
2454 if(p->fist_incs)
2455 {
2456 p->fist_incs++;
2457 if(p->fist_incs == 28)
2458 {
2459 if(ud.recstat == 1) closedemowrite();
2460 sound(PIPEBOMB_EXPLODE);
2461 p->pals[0] = 64;
2462 p->pals[1] = 64;
2463 p->pals[2] = 64;
2464 p->pals_time = 48;
2465 }
2466 if(p->fist_incs > 42)
2467 {
2468 if(p->buttonpalette && ud.from_bonus == 0)
2469 {
2470 ud.from_bonus = ud.level_number+1;
2471 if(ud.secretlevel > 0 && ud.secretlevel < 12) ud.level_number = ud.secretlevel-1;
2472 ud.m_level_number = ud.level_number;
2473 }
2474 else
2475 {
2476 if(ud.from_bonus)
2477 {
2478 ud.level_number = ud.from_bonus;
2479 ud.m_level_number = ud.level_number;
2480 ud.from_bonus = 0;
2481 }
2482 else
2483 {
2484 if(ud.level_number == ud.secretlevel && ud.from_bonus > 0 )
2485 ud.level_number = ud.from_bonus;
2486 else ud.level_number++;
2487
2488 if(ud.level_number > 10) ud.level_number = 0;
2489 ud.m_level_number = ud.level_number;
2490
2491 }
2492 }
2493 for(i=connecthead;i>=0;i=connectpoint2[i])
2494 ps[i].gm = MODE_EOL;
2495 p->fist_incs = 0;
2496
2497 return;
2498 }
2499 }
2500
2501 if(p->timebeforeexit > 1 && p->last_extra > 0)
2502 {
2503 p->timebeforeexit--;
2504 if(p->timebeforeexit == 26*5)
2505 {
2506 FX_StopAllSounds();
2507 clearsoundlocks();
2508 if(p->customexitsound >= 0)
2509 {
2510 sound(p->customexitsound);
2511 FTA(102,p,0);
2512 }
2513 }
2514 else if(p->timebeforeexit == 1)
2515 {
2516 for(i=connecthead;i>=0;i=connectpoint2[i])
2517 ps[i].gm = MODE_EOL;
2518 if(ud.from_bonus)
2519 {
2520 ud.level_number = ud.from_bonus;
2521 ud.m_level_number = ud.level_number;
2522 ud.from_bonus = 0;
2523 }
2524 else
2525 {
2526 ud.level_number++;
2527 ud.m_level_number = ud.level_number;
2528 }
2529 return;
2530 }
2531 }
2532
2533 if(p->pals_time > 0)
2534 p->pals_time--;
2535
2536 if(p->fta > 0)
2537 {
2538 p->fta--;
2539 if(p->fta == 0)
2540 {
2541 pub = NUMPAGES;
2542 pus = NUMPAGES;
2543 p->ftq = 0;
2544 }
2545 }
2546
2547 if( s->extra <= 0 )
2548 {
2549 if(p->dead_flag == 0)
2550 {
2551 if(s->pal != 1)
2552 {
2553 p->pals[0] = 63;
2554 p->pals[1] = 0;
2555 p->pals[2] = 0;
2556 p->pals_time = 63;
2557 p->posz -= (16<<8);
2558 s->z -= (16<<8);
2559 }
2560
2561 if(ud.recstat == 1 && ud.multimode < 2)
2562 closedemowrite();
2563
2564 if(s->pal != 1)
2565 p->dead_flag = (512-((TRAND&1)<<10)+(TRAND&255)-512)&2047;
2566
2567 p->jetpack_on = 0;
2568 p->holoduke_on = -1;
2569
2570 stopsound(DUKE_JETPACK_IDLE);
2571 if(p->scream_voice > FX_Ok)
2572 {
2573 FX_StopSound(p->scream_voice);
2574 testcallback(DUKE_SCREAM);
2575 p->scream_voice = FX_Ok;
2576 }
2577
2578 if( s->pal != 1 && (s->cstat&32768) == 0) s->cstat = 0;
2579
2580 if( ud.multimode > 1 && ( s->pal != 1 || (s->cstat&32768) ) )
2581 {
2582 if(p->frag_ps != snum)
2583 {
2584 ps[p->frag_ps].frag++;
2585 frags[p->frag_ps][snum]++;
2586
2587 if( ud.user_name[p->frag_ps][0] != 0)
2588 {
2589 if(snum == screenpeek)
2590 {
2591 sprintf(&fta_quotes[115][0],"KILLED BY %s",&ud.user_name[p->frag_ps][0]);
2592 FTA(115,p,1);
2593 }
2594 else if(screenpeek == p->frag_ps)
2595 // FIX_00076: Added default names for bots + fixed a "killed <name>" bug in Fakeplayers with AI
2596 {
2597 sprintf(&fta_quotes[116][0],"KILLED %s",&ud.user_name[snum][0]);
2598 FTA(116,&ps[p->frag_ps],1);
2599 }
2600 }
2601 else
2602 {
2603 if(snum == screenpeek)
2604 {
2605 sprintf(&fta_quotes[115][0],"KILLED BY PLAYER %d",1+p->frag_ps);
2606 FTA(115,p,1);
2607 }
2608 else if(screenpeek == p->frag_ps)
2609 {
2610 sprintf(&fta_quotes[116][0],"KILLED PLAYER %d",1+snum);
2611 FTA(116,&ps[p->frag_ps],1);
2612 }
2613 }
2614 }
2615 else p->fraggedself++;
2616
2617 if(myconnectindex == connecthead)
2618 {
2619 sprintf(text,"frag %d killed %d\n",p->frag_ps+1,snum+1);
2620 sendscore(text);
2621// printf(tempbuf);
2622 }
2623
2624 p->frag_ps = snum;
2625 pus = NUMPAGES;
2626 }
2627 }
2628
2629 if( psectlotag == 2 )
2630 {
2631 if(p->on_warping_sector == 0)
2632 {
2633 if( klabs(p->posz-fz) > (PHEIGHT>>1))
2634 p->posz += 348;
2635 }
2636 else
2637 {
2638 s->z -= 512;
2639 s->zvel = -348;
2640 }
2641
2642 clipmove(&p->posx,&p->posy,
2643 &p->posz,&p->cursectnum,
2644 0,0,164L,(4L<<8),(4L<<8),CLIPMASK0);
2645// p->bobcounter += 32;
2646 }
2647
2648 p->oposx = p->posx;
2649 p->oposy = p->posy;
2650 p->oposz = p->posz;
2651 p->oang = p->ang;
2652 p->opyoff = p->pyoff;
2653
2654 p->horiz = 100;
2655 p->horizoff = 0;
2656
2657 updatesector(p->posx,p->posy,&p->cursectnum);
2658
2659 pushmove(&p->posx,&p->posy,&p->posz,&p->cursectnum,128L,(4L<<8),(20L<<8),CLIPMASK0);
2660
2661 if( fz > cz+(16<<8) && s->pal != 1)
2662 p->rotscrnang = (p->dead_flag + ( (fz+p->posz)>>7))&2047;
2663
2664 p->on_warping_sector = 0;
2665
2666 return;
2667 }
2668
2669 if(p->transporter_hold > 0)
2670 {
2671 p->transporter_hold--;
2672 if(p->transporter_hold == 0 && p->on_warping_sector)
2673 p->transporter_hold = 2;
2674 }
2675 if(p->transporter_hold < 0)
2676 p->transporter_hold++;
2677
2678 if(p->newowner >= 0)
2679 {
2680 i = p->newowner;
2681 p->posx = SX;
2682 p->posy = SY;
2683 p->posz = SZ;
2684 p->ang = SA;
2685 p->posxv = p->posyv = s->xvel = 0;
2686 p->look_ang = 0;
2687 p->rotscrnang = 0;
2688 doincrements(p);
2689
2690 if(p->curr_weapon == HANDREMOTE_WEAPON) goto SHOOTINCODE;
2691
2692 return;
2693 }
2694
2695 p->weaponautoswitch = (sb_snum&(1<<7))?1:0;
2696 p->auto_aim = (sb_snum&(1<<6))?2:1; // 2 == normal == full; 1 == partial; 0 = none (not implemented)
2697
2698 doubvel = TICSPERFRAME;
2699
2700 if (p->rotscrnang > 0) p->rotscrnang -= ((p->rotscrnang>>1)+1);
2701 else if (p->rotscrnang < 0) p->rotscrnang += (((-p->rotscrnang)>>1)+1);
2702
2703 p->look_ang -= (p->look_ang>>2);
2704
2705 // 1<<6: toggle ud.auto_aim
2706 if( ((ud.playing_demo_rev == BYTEVERSION_27 ||
2707 ud.playing_demo_rev == BYTEVERSION_28 ||
2708 ud.playing_demo_rev == BYTEVERSION_116 ||
2709 ud.playing_demo_rev == BYTEVERSION_117) &&
2710 sb_snum&(1<<6)) ||
2711 (ACTION(gamefunc_Look_Left) && (p->gm&MODE_GAME) &&
2712 !(p->gm&MODE_MENU) && !(p->gm&MODE_TYPE) && !(ud.pause_on) && (ud.recstat != 2)))
2713 {
2714 p->look_ang -= 152;
2715 p->rotscrnang += 24;
2716 }
2717
2718 // 1<<7 : ANTIWEAPONSWITCH
2719 if( ((ud.playing_demo_rev == BYTEVERSION_27 ||
2720 ud.playing_demo_rev == BYTEVERSION_28 ||
2721 ud.playing_demo_rev == BYTEVERSION_116 ||
2722 ud.playing_demo_rev == BYTEVERSION_117) &&
2723 sb_snum&(1<<7)) ||
2724 (
2725 ACTION(gamefunc_Look_Right) && (p->gm&MODE_GAME) &&
2726 !(p->gm&MODE_MENU) && !(p->gm&MODE_TYPE) && !(ud.pause_on) && (ud.recstat != 2)
2727 )
2728 )
2729 {
2730 p->look_ang += 152;
2731 p->rotscrnang -= 24;
2732 }
2733
2734 if(p->on_crane >= 0)
2735 goto HORIZONLY;
2736
2737 j = ksgn(sync[snum].avel);
2738 /*
2739 if( j && ud.screen_tilting == 2)
2740 {
2741 k = 4;
2742 if(sb_snum&(1<<5)) k <<= 2;
2743 p->rotscrnang -= k*j;
2744 p->look_ang += k*j;
2745 }
2746 */
2747
2748 if( s->xvel < 32 || p->on_ground == 0 || p->bobcounter == 1024 )
2749 {
2750 if( (p->weapon_sway&2047) > (1024+96) )
2751 p->weapon_sway -= 96;
2752 else if( (p->weapon_sway&2047) < (1024-96) )
2753 p->weapon_sway += 96;
2754 else p->weapon_sway = 1024;
2755 }
2756 else p->weapon_sway = p->bobcounter;
2757
2758 s->xvel =
2759 ksqrt( (p->posx-p->bobposx)*(p->posx-p->bobposx)+(p->posy-p->bobposy)*(p->posy-p->bobposy));
2760 if(p->on_ground) p->bobcounter += sprite[p->i].xvel>>1;
2761
2762 if( ud.clipping == 0 && ( sector[p->cursectnum].floorpicnum == MIRROR || p->cursectnum < 0 || p->cursectnum >= MAXSECTORS) )
2763 {
2764 p->posx = p->oposx;
2765 p->posy = p->oposy;
2766 }
2767 else
2768 {
2769 p->oposx = p->posx;
2770 p->oposy = p->posy;
2771 }
2772
2773 p->bobposx = p->posx;
2774 p->bobposy = p->posy;
2775
2776 p->oposz = p->posz;
2777 p->opyoff = p->pyoff;
2778 p->oang = p->ang;
2779
2780 if(p->one_eighty_count < 0)
2781 {
2782 p->one_eighty_count += 128;
2783 p->ang += 128;
2784 }
2785
2786 // Shrinking code
2787
2788 i = 40;
2789
2790 if( psectlotag == 2)
2791 {
2792 p->jumping_counter = 0;
2793
2794 p->pycount += 32;
2795 p->pycount &= 2047;
2796 p->pyoff = sintable[p->pycount]>>7;
2797
2798 if( Sound[DUKE_UNDERWATER].num == 0 )
2799 spritesound(DUKE_UNDERWATER,pi);
2800
2801 if ( sb_snum&1 )
2802 {
2803 if(p->poszv > 0) p->poszv = 0;
2804 p->poszv -= 348;
2805 if(p->poszv < -(256*6)) p->poszv = -(256*6);
2806 }
2807 else if (sb_snum&(1<<1))
2808 {
2809 if(p->poszv < 0) p->poszv = 0;
2810 p->poszv += 348;
2811 if(p->poszv > (256*6)) p->poszv = (256*6);
2812 }
2813 else
2814 {
2815 if(p->poszv < 0)
2816 {
2817 p->poszv += 256;
2818 if(p->poszv > 0)
2819 p->poszv = 0;
2820 }
2821 if(p->poszv > 0)
2822 {
2823 p->poszv -= 256;
2824 if(p->poszv < 0)
2825 p->poszv = 0;
2826 }
2827 }
2828
2829 if(p->poszv > 2048)
2830 p->poszv >>= 1;
2831
2832 p->posz += p->poszv;
2833
2834 if(p->posz > (fz-(15<<8)) )
2835 p->posz += ((fz-(15<<8))-p->posz)>>1;
2836
2837 if(p->posz < (cz+(4<<8)) )
2838 {
2839 p->posz = cz+(4<<8);
2840 p->poszv = 0;
2841 }
2842
2843 if( p->scuba_on && (TRAND&255) < 8 )
2844 {
2845 j = spawn(pi,WATERBUBBLE);
2846 sprite[j].x +=
2847 sintable[(p->ang+512+64-(global_random&128))&2047]>>6;
2848 sprite[j].y +=
2849 sintable[(p->ang+64-(global_random&128))&2047]>>6;
2850 sprite[j].xrepeat = 3;
2851 sprite[j].yrepeat = 2;
2852 sprite[j].z = p->posz+(8<<8);
2853 }
2854 }
2855
2856 else if(p->jetpack_on)
2857 {
2858 p->on_ground = 0;
2859 p->jumping_counter = 0;
2860 p->hard_landing = 0;
2861 p->falling_counter = 0;
2862
2863 p->pycount += 32;
2864 p->pycount &= 2047;
2865 p->pyoff = sintable[p->pycount]>>7;
2866
2867 if(p->jetpack_on < 11)
2868 {
2869 p->jetpack_on++;
2870 p->posz -= (p->jetpack_on<<7); //Goin up
2871 }
2872 else if(p->jetpack_on == 11 && Sound[DUKE_JETPACK_IDLE].num < 1)
2873 spritesound(DUKE_JETPACK_IDLE,pi);
2874
2875 if(shrunk) j = 512;
2876 else j = 2048;
2877
2878 if ( sb_snum&1 ) //A (soar high)
2879 {
2880 p->posz -= j;
2881 p->crack_time = 777;
2882 }
2883
2884 if (sb_snum&(1<<1)) //Z (soar low)
2885 {
2886 p->posz += j;
2887 p->crack_time = 777;
2888 }
2889
2890 if( shrunk == 0 && (psectlotag == 0 || psectlotag == 2)) k = 32;
2891 else k = 16;
2892
2893 if( psectlotag != 2 && p->scuba_on == 1 )
2894 p->scuba_on = 0;
2895
2896 if(p->posz > (fz-(k<<8)) )
2897 p->posz += ((fz-(k<<8))-p->posz)>>1;
2898 if(p->posz < (hittype[pi].ceilingz+(18<<8)) )
2899 p->posz = hittype[pi].ceilingz+(18<<8);
2900
2901 }
2902 else if( psectlotag != 2 )
2903 {
2904 if(p->airleft != 15*26)
2905 p->airleft = 15*26; //Aprox twenty seconds.
2906
2907 if(p->scuba_on == 1)
2908 p->scuba_on = 0;
2909
2910 if( psectlotag == 1 && p->spritebridge == 0)
2911 {
2912 if(shrunk == 0)
2913 {
2914 i = 34;
2915 p->pycount += 32;
2916 p->pycount &= 2047;
2917 p->pyoff = sintable[p->pycount]>>6;
2918 }
2919 else i = 12;
2920
2921 if(shrunk == 0 && truefdist <= PHEIGHT)
2922 {
2923 if(p->on_ground == 1)
2924 {
2925 if( p->dummyplayersprite == -1 )
2926 p->dummyplayersprite =
2927 spawn(pi,PLAYERONWATER);
2928
2929 p->footprintcount = 6;
2930 if(sector[p->cursectnum].floorpicnum == FLOORSLIME)
2931 p->footprintpal = 8;
2932 else p->footprintpal = 0;
2933 p->footprintshade = 0;
2934 }
2935 }
2936 }
2937 else
2938 {
2939 if(p->footprintcount > 0 && p->on_ground)
2940 if( (sector[p->cursectnum].floorstat&2) != 2 )
2941 {
2942 for(j=headspritesect[psect];j>=0;j=nextspritesect[j])
2943 if( sprite[j].picnum == FOOTPRINTS || sprite[j].picnum == FOOTPRINTS2 || sprite[j].picnum == FOOTPRINTS3 || sprite[j].picnum == FOOTPRINTS4 )
2944 if (klabs(sprite[j].x-p->posx) < 384)
2945 if (klabs(sprite[j].y-p->posy) < 384)
2946 break;
2947 if(j < 0)
2948 {
2949 p->footprintcount--;
2950 if( sector[p->cursectnum].lotag == 0 && sector[p->cursectnum].hitag == 0 )
2951 {
2952 switch(TRAND&3)
2953 {
2954 case 0: j = spawn(pi,FOOTPRINTS); break;
2955 case 1: j = spawn(pi,FOOTPRINTS2); break;
2956 case 2: j = spawn(pi,FOOTPRINTS3); break;
2957 default: j = spawn(pi,FOOTPRINTS4); break;
2958 }
2959 sprite[j].pal = p->footprintpal;
2960 sprite[j].shade = p->footprintshade;
2961 }
2962 }
2963 }
2964 }
2965
2966 if(p->posz < (fz-(i<<8)) ) //falling
2967 {
2968 if( (sb_snum&3) == 0 && p->on_ground && (sector[psect].floorstat&2) && p->posz >= (fz-(i<<8)-(16<<8) ) )
2969 p->posz = fz-(i<<8);
2970 else
2971 {
2972 p->on_ground = 0;
2973 p->poszv += (gc+80); // (TICSPERFRAME<<6);
2974 if(p->poszv >= (4096+2048)) p->poszv = (4096+2048);
2975 if(p->poszv > 2400 && p->falling_counter < 255)
2976 {
2977 p->falling_counter++;
2978 if( p->falling_counter == 38 )
2979 p->scream_voice = spritesound(DUKE_SCREAM,pi);
2980 }
2981
2982 if( (p->posz+p->poszv) >= (fz-(i<<8)) ) // hit the ground
2983 if(sector[p->cursectnum].lotag != 1)
2984 {
2985 if( p->falling_counter > 62 ) quickkill(p);
2986
2987 else if( p->falling_counter > 9 )
2988 {
2989 j = p->falling_counter;
2990 s->extra -= j-(TRAND&3);
2991 if(s->extra <= 0)
2992 {
2993 spritesound(SQUISHED,pi);
2994 p->pals[0] = 63;
2995 p->pals[1] = 0;
2996 p->pals[2] = 0;
2997 p->pals_time = 63;
2998 }
2999 else
3000 {
3001 spritesound(DUKE_LAND,pi);
3002 spritesound(DUKE_LAND_HURT,pi);
3003 }
3004
3005 p->pals[0] = 16;
3006 p->pals[1] = 0;
3007 p->pals[2] = 0;
3008 p->pals_time = 32;
3009 }
3010 else if(p->poszv > 2048) spritesound(DUKE_LAND,pi);
3011 }
3012 }
3013 }
3014
3015 else
3016 {
3017 p->falling_counter = 0;
3018 if(p->scream_voice > FX_Ok)
3019 {
3020 FX_StopSound(p->scream_voice);
3021 p->scream_voice = FX_Ok;
3022 }
3023
3024 if(psectlotag != 1 && psectlotag != 2 && p->on_ground == 0 && p->poszv > (6144>>1))
3025 p->hard_landing = p->poszv>>10;
3026
3027 p->on_ground = 1;
3028
3029 if( i==40 )
3030 {
3031 //Smooth on the ground
3032
3033 k = ((fz-(i<<8))-p->posz)>>1;
3034 if( klabs(k) < 256 ) k = 0;
3035 p->posz += k;
3036 p->poszv -= 768;
3037 if(p->poszv < 0) p->poszv = 0;
3038 }
3039 else if(p->jumping_counter == 0)
3040 {
3041 p->posz += ((fz-(i<<7))-p->posz)>>1; //Smooth on the water
3042 if(p->on_warping_sector == 0 && p->posz > fz-(16<<8))
3043 {
3044 p->posz = fz-(16<<8);
3045 p->poszv >>= 1;
3046 }
3047 }
3048
3049 p->on_warping_sector = 0;
3050
3051 if( (sb_snum&2) )
3052 {
3053 p->posz += (2048+768);
3054 p->crack_time = 777;
3055 }
3056
3057 if( (sb_snum&1) == 0 && p->jumping_toggle == 1)
3058 p->jumping_toggle = 0;
3059
3060 else if( (sb_snum&1) && p->jumping_toggle == 0 )
3061 {
3062 if( p->jumping_counter == 0 )
3063 if( (fz-cz) > (56<<8) )
3064 {
3065 p->jumping_counter = 1;
3066 p->jumping_toggle = 1;
3067 }
3068 }
3069
3070 if( p->jumping_counter && (sb_snum&1) == 0 )
3071 p->jumping_toggle = 0;
3072 }
3073
3074 if(p->jumping_counter)
3075 {
3076 if( (sb_snum&1) == 0 && p->jumping_toggle == 1)
3077 p->jumping_toggle = 0;
3078
3079 if( p->jumping_counter < (1024+256) )
3080 {
3081 if(psectlotag == 1 && p->jumping_counter > 768)
3082 {
3083 p->jumping_counter = 0;
3084 p->poszv = -512;
3085 }
3086 else
3087 {
3088 p->poszv -= (sintable[(2048-128+p->jumping_counter)&2047])/12;
3089 p->jumping_counter += 180;
3090 p->on_ground = 0;
3091 }
3092 }
3093 else
3094 {
3095 p->jumping_counter = 0;
3096 p->poszv = 0;
3097 }
3098 }
3099
3100 p->posz += p->poszv;
3101
3102 if(p->posz < (cz+(4<<8)))
3103 {
3104 p->jumping_counter = 0;
3105 if(p->poszv < 0)
3106 p->posxv = p->posyv = 0;
3107 p->poszv = 128;
3108 p->posz = cz+(4<<8);
3109 }
3110 }
3111
3112 //Do the quick lefts and rights
3113
3114 if ( p->fist_incs ||
3115 p->transporter_hold > 2 ||
3116 p->hard_landing ||
3117 p->access_incs > 0 ||
3118 p->knee_incs > 0 ||
3119 (p->curr_weapon == TRIPBOMB_WEAPON &&
3120 *kb > 1 &&
3121 *kb < 4 ) )
3122 {
3123 doubvel = 0;
3124 p->posxv = 0;
3125 p->posyv = 0;
3126 }
3127 else if ( sync[snum].avel ) //p->ang += syncangvel * constant
3128 { //ENGINE calculates angvel for you
3129 int32_t tempang;
3130
3131 tempang = sync[snum].avel<<1;
3132
3133 if( psectlotag == 2 ) p->angvel =(tempang-(tempang>>3))*ksgn(doubvel);
3134 else p->angvel = tempang*ksgn(doubvel);
3135
3136 p->ang += p->angvel;
3137 p->ang &= 2047;
3138 p->crack_time = 777;
3139 }
3140
3141 if(p->spritebridge == 0)
3142 {
3143 j = sector[s->sectnum].floorpicnum;
3144
3145 if( j == PURPLELAVA || sector[s->sectnum].ceilingpicnum == PURPLELAVA )
3146 {
3147 if(p->boot_amount > 0)
3148 {
3149 p->boot_amount--;
3150 p->inven_icon = 7;
3151 if(p->boot_amount <= 0)
3152 checkavailinven(p);
3153 }
3154 else
3155 {
3156 if(Sound[DUKE_LONGTERM_PAIN].num < 1)
3157 spritesound(DUKE_LONGTERM_PAIN,pi);
3158 p->pals[0] = 0; p->pals[1] = 8; p->pals[2] = 0;
3159 p->pals_time = 32;
3160 s->extra--;
3161 }
3162 }
3163
3164 k = 0;
3165
3166 if(p->on_ground && truefdist <= PHEIGHT+(16<<8))
3167 {
3168 switch(j)
3169 {
3170 case HURTRAIL:
3171 if( rnd(32) )
3172 {
3173 if(p->boot_amount > 0)
3174 k = 1;
3175 else
3176 {
3177 if(Sound[DUKE_LONGTERM_PAIN].num < 1)
3178 spritesound(DUKE_LONGTERM_PAIN,pi);
3179 p->pals[0] = 64; p->pals[1] = 64; p->pals[2] = 64;
3180 p->pals_time = 32;
3181 s->extra -= 1+(TRAND&3);
3182 if(Sound[SHORT_CIRCUIT].num < 1)
3183 spritesound(SHORT_CIRCUIT,pi);
3184 }
3185 }
3186 break;
3187 case FLOORSLIME:
3188 if( rnd(16) )
3189 {
3190 if(p->boot_amount > 0)
3191 k = 1;
3192 else
3193 {
3194 if(Sound[DUKE_LONGTERM_PAIN].num < 1)
3195 spritesound(DUKE_LONGTERM_PAIN,pi);
3196 p->pals[0] = 0; p->pals[1] = 8; p->pals[2] = 0;
3197 p->pals_time = 32;
3198 s->extra -= 1+(TRAND&3);
3199 }
3200 }
3201 break;
3202 case FLOORPLASMA:
3203 if( rnd(32) )
3204 {
3205 if( p->boot_amount > 0 )
3206 k = 1;
3207 else
3208 {
3209 if(Sound[DUKE_LONGTERM_PAIN].num < 1)
3210 spritesound(DUKE_LONGTERM_PAIN,pi);
3211 p->pals[0] = 8; p->pals[1] = 0; p->pals[2] = 0;
3212 p->pals_time = 32;
3213 s->extra -= 1+(TRAND&3);
3214 }
3215 }
3216 break;
3217 }
3218 }
3219
3220 if( k )
3221 {
3222 FTA(75,p,0);
3223 p->boot_amount -= 2;
3224 if(p->boot_amount <= 0)
3225 checkavailinven(p);
3226 }
3227 }
3228
3229 if ( p->posxv || p->posyv || sync[snum].fvel || sync[snum].svel )
3230 {
3231 p->crack_time = 777;
3232
3233 k = sintable[p->bobcounter&2047]>>12;
3234
3235 if(truefdist < PHEIGHT+(8<<8) )
3236 {
3237 if( k == 1 || k == 3 )
3238 {
3239 if(p->spritebridge == 0 && p->walking_snd_toggle == 0 && p->on_ground)
3240 {
3241 switch( psectlotag )
3242 {
3243 case 0:
3244
3245 if(lz >= 0 && (lz&(MAXSPRITES-1))==49152 )
3246 j = sprite[lz&(MAXSPRITES-1)].picnum;
3247 else j = sector[psect].floorpicnum;
3248
3249 switch(j)
3250 {
3251 case PANNEL1:
3252 case PANNEL2:
3253 spritesound(DUKE_WALKINDUCTS,pi);
3254 p->walking_snd_toggle = 1;
3255 break;
3256 }
3257 break;
3258 case 1:
3259 if((TRAND&1) == 0)
3260 spritesound(DUKE_ONWATER,pi);
3261 p->walking_snd_toggle = 1;
3262 break;
3263 }
3264 }
3265 }
3266 else{
3267 if(p->walking_snd_toggle > 0)
3268 {
3269 p->walking_snd_toggle --;
3270 }
3271 }
3272 }
3273
3274 if(p->jetpack_on == 0 && p->steroids_amount > 0 && p->steroids_amount < 400)
3275 doubvel <<= 1;
3276
3277 p->posxv += ((sync[snum].fvel*doubvel)<<6);
3278 p->posyv += ((sync[snum].svel*doubvel)<<6);
3279
3280 if( ( p->curr_weapon == KNEE_WEAPON && *kb > 10 && p->on_ground ) || ( p->on_ground && (sb_snum&2) ) )
3281 {
3282 p->posxv = mulscale(p->posxv,dukefriction-0x2000,16);
3283 p->posyv = mulscale(p->posyv,dukefriction-0x2000,16);
3284 }
3285 else
3286 {
3287 if(psectlotag == 2)
3288 {
3289 p->posxv = mulscale(p->posxv,dukefriction-0x1400,16);
3290 p->posyv = mulscale(p->posyv,dukefriction-0x1400,16);
3291 }
3292 else
3293 {
3294 p->posxv = mulscale(p->posxv,dukefriction,16);
3295 p->posyv = mulscale(p->posyv,dukefriction,16);
3296 }
3297 }
3298
3299 if( abs(p->posxv) < 2048 && abs(p->posyv) < 2048 )
3300 p->posxv = p->posyv = 0;
3301
3302 if( shrunk )
3303 {
3304 p->posxv =
3305 mulscale16(p->posxv,dukefriction-(dukefriction>>1)+(dukefriction>>2));
3306 p->posyv =
3307 mulscale16(p->posyv,dukefriction-(dukefriction>>1)+(dukefriction>>2));
3308 }
3309 }
3310
3311 HORIZONLY:
3312
3313 if(psectlotag == 1 || p->spritebridge == 1) i = (4L<<8);
3314 else i = (20L<<8);
3315
3316 if(sector[p->cursectnum].lotag == 2) k = 0;
3317 else k = 1;
3318
3319 if(ud.clipping)
3320 {
3321 j = 0;
3322 p->posx += p->posxv>>14;
3323 p->posy += p->posyv>>14;
3324 updatesector(p->posx,p->posy,&p->cursectnum);
3325 changespritesect(pi,p->cursectnum);
3326 }
3327 else
3328 j = clipmove(&p->posx,&p->posy,
3329 &p->posz,&p->cursectnum,
3330 p->posxv,p->posyv,164L,(4L<<8),i,CLIPMASK0);
3331
3332 if(p->jetpack_on == 0 && psectlotag != 2 && psectlotag != 1 && shrunk)
3333 p->posz += 32<<8;
3334
3335 if(j)
3336 checkplayerhurt(p,j);
3337
3338 if(p->jetpack_on == 0)
3339 {
3340 if( s->xvel > 16 )
3341 {
3342 if( psectlotag != 1 && psectlotag != 2 && p->on_ground )
3343 {
3344 p->pycount += 52;
3345 p->pycount &= 2047;
3346 p->pyoff =
3347 klabs(s->xvel*sintable[p->pycount])/1596;
3348 }
3349 }
3350 else if( psectlotag != 2 && psectlotag != 1 )
3351 p->pyoff = 0;
3352 }
3353
3354 // RBG***
3355 setsprite(pi,p->posx,p->posy,p->posz+PHEIGHT);
3356
3357 if( psectlotag < 3 )
3358 {
3359 psect = s->sectnum;
3360 if( ud.clipping == 0 && sector[psect].lotag == 31)
3361 {
3362 if( sprite[sector[psect].hitag].xvel && hittype[sector[psect].hitag].temp_data[0] == 0)
3363 {
3364 quickkill(p);
3365 return;
3366 }
3367 }
3368 }
3369
3370 if(truefdist < PHEIGHT && p->on_ground && psectlotag != 1 && shrunk == 0 && sector[p->cursectnum].lotag == 1)
3371 if( Sound[DUKE_ONWATER].num == 0 )
3372 spritesound(DUKE_ONWATER,pi);
3373
3374 if (p->cursectnum != s->sectnum)
3375 changespritesect(pi,p->cursectnum);
3376
3377 if(ud.clipping == 0)
3378 j = ( pushmove(&p->posx,&p->posy,&p->posz,&p->cursectnum,164L,(4L<<8),(4L<<8),CLIPMASK0) < 0 && furthestangle(pi,8) < 512 );
3379 else j = 0;
3380
3381 if(ud.clipping == 0)
3382 {
3383 if( klabs(hittype[pi].floorz-hittype[pi].ceilingz) < (48<<8) || j )
3384 {
3385 if ( !(sector[s->sectnum].lotag&0x8000) && ( isanunderoperator(sector[s->sectnum].lotag) ||
3386 isanearoperator(sector[s->sectnum].lotag) ) )
3387 activatebysector(s->sectnum,pi);
3388 if(j)
3389 {
3390 quickkill(p);
3391 return;
3392 }
3393 }
3394 else if( klabs(fz-cz) < (32<<8) && isanunderoperator(sector[psect].lotag) )
3395 activatebysector(psect,pi);
3396 }
3397
3398 if( sb_snum&(1<<18) || p->hard_landing)
3399 p->return_to_center = 9;
3400
3401 if( sb_snum&(1<<13) )
3402 {
3403 p->return_to_center = 9;
3404 if( sb_snum&(1<<5) ) p->horiz += 12;
3405 p->horiz += 12;
3406 }
3407
3408 else if( sb_snum&(1<<14) )
3409 {
3410 p->return_to_center = 9;
3411 if( sb_snum&(1<<5) ) p->horiz -= 12;
3412 p->horiz -= 12;
3413 }
3414
3415 else if( sb_snum&(1<<3) )
3416 {
3417 if( sb_snum&(1<<5) ) p->horiz += 6;
3418 p->horiz += 6;
3419 }
3420
3421 else if( sb_snum&(1<<4) )
3422 {
3423 if( sb_snum&(1<<5) ) p->horiz -= 6;
3424 p->horiz -= 6;
3425 }
3426 if(p->return_to_center > 0)
3427 if( (sb_snum&(1<<13)) == 0 && (sb_snum&(1<<14)) == 0 )
3428 {
3429 p->return_to_center--;
3430 p->horiz += 33-(p->horiz/3);
3431 }
3432
3433 if(p->hard_landing > 0)
3434 {
3435 p->hard_landing--;
3436 p->horiz -= (p->hard_landing<<4);
3437 }
3438
3439 if(p->aim_mode)
3440 p->horiz += sync[snum].horz>>1;
3441 else
3442 {
3443 if( p->horiz > 95 && p->horiz < 105) p->horiz = 100;
3444 if( p->horizoff > -5 && p->horizoff < 5) p->horizoff = 0;
3445 }
3446
3447 if(p->horiz > 299) p->horiz = 299;
3448 else if(p->horiz < -99) p->horiz = -99;
3449
3450 //Shooting code/changes
3451
3452 if( p->show_empty_weapon > 0)
3453 {
3454 p->show_empty_weapon--;
3455 if(p->show_empty_weapon == 0)
3456 {
3457 if(p->last_full_weapon == GROW_WEAPON)
3458 p->subweapon |= (1<<GROW_WEAPON);
3459 else if(p->last_full_weapon == SHRINKER_WEAPON)
3460 p->subweapon &= ~(1<<GROW_WEAPON);
3461 addweapon( p, p->last_full_weapon );
3462 return;
3463 }
3464 }
3465
3466 if(p->knee_incs > 0)
3467 {
3468 p->knee_incs++;
3469 p->horiz -= 48;
3470 p->return_to_center = 9;
3471 if(p->knee_incs > 15)
3472 {
3473 p->knee_incs = 0;
3474 p->holster_weapon = 0;
3475 if(p->weapon_pos < 0)
3476 p->weapon_pos = -p->weapon_pos;
3477 if(p->actorsqu >= 0 && dist(&sprite[pi],&sprite[p->actorsqu]) < 1400 )
3478 {
3479 guts(&sprite[p->actorsqu],JIBS6,7,myconnectindex);
3480 spawn(p->actorsqu,BLOODPOOL);
3481 spritesound(SQUISHED,p->actorsqu);
3482 switch(sprite[p->actorsqu].picnum)
3483 {
3484 case FEM1:
3485 case FEM2:
3486 case FEM3:
3487 case FEM4:
3488 case FEM5:
3489 case FEM6:
3490 case FEM7:
3491 case FEM8:
3492 case FEM9:
3493 case FEM10:
3494 case PODFEM1:
3495 case NAKED1:
3496 case STATUE:
3497 if(sprite[p->actorsqu].yvel)
3498 operaterespawns(sprite[p->actorsqu].yvel);
3499 break;
3500 }
3501
3502 if(sprite[p->actorsqu].picnum == APLAYER)
3503 {
3504 quickkill(&ps[sprite[p->actorsqu].yvel]);
3505 ps[sprite[p->actorsqu].yvel].frag_ps = snum;
3506 }
3507 else if(badguy(&sprite[p->actorsqu]))
3508 {
3509 deletesprite(p->actorsqu);
3510 p->actors_killed++;
3511 }
3512 else deletesprite(p->actorsqu);
3513 }
3514 p->actorsqu = -1;
3515 }
3516 else if(p->actorsqu >= 0)
3517 p->ang += getincangle(p->ang,getangle(sprite[p->actorsqu].x-p->posx,sprite[p->actorsqu].y-p->posy))>>2;
3518 }
3519
3520 if( doincrements(p) ) return;
3521
3522 if(p->weapon_pos != 0)
3523 {
3524 if(p->weapon_pos == -9)
3525 {
3526 if(p->last_weapon >= 0)
3527 {
3528 p->weapon_pos = 10;
3529// if(p->curr_weapon == KNEE_WEAPON) *kb = 1;
3530 p->last_weapon = -1;
3531 }
3532 else if(p->holster_weapon == 0)
3533 p->weapon_pos = 10;
3534 }
3535 else p->weapon_pos--;
3536 }
3537
3538 // HACKS
3539
3540 SHOOTINCODE:
3541
3542 if( p->curr_weapon == SHRINKER_WEAPON || p->curr_weapon == GROW_WEAPON )
3543 p->random_club_frame += 64; // Glowing
3544
3545 if(p->rapid_fire_hold == 1)
3546 {
3547 if( sb_snum&(1<<2) ) return;
3548 p->rapid_fire_hold = 0;
3549 }
3550
3551 if(shrunk || p->tipincs || p->access_incs)
3552 sb_snum &= ~(1<<2);
3553 else if ( shrunk == 0 && (sb_snum&(1<<2)) && (*kb) == 0 && p->fist_incs == 0 &&
3554 p->last_weapon == -1 && ( p->weapon_pos == 0 || p->holster_weapon == 1 ) )
3555 {
3556
3557 p->crack_time = 777;
3558
3559 if(p->holster_weapon == 1)
3560 {
3561 if( p->last_pissed_time <= (26*218) && p->weapon_pos == -9)
3562 {
3563 p->holster_weapon = 0;
3564 p->weapon_pos = 10;
3565 FTA(74,p,1);
3566 }
3567 }
3568 else switch(p->curr_weapon)
3569 {
3570 case HANDBOMB_WEAPON:
3571 p->hbomb_hold_delay = 0;
3572 if( p->ammo_amount[HANDBOMB_WEAPON] > 0 )
3573 (*kb)=1;
3574 break;
3575 case HANDREMOTE_WEAPON:
3576 p->hbomb_hold_delay = 0;
3577 (*kb) = 1;
3578 break;
3579
3580 case PISTOL_WEAPON:
3581 if( p->ammo_amount[PISTOL_WEAPON] > 0 )
3582 {
3583 p->ammo_amount[PISTOL_WEAPON]--;
3584 (*kb) = 1;
3585 }
3586 break;
3587
3588
3589 case CHAINGUN_WEAPON:
3590 if( p->ammo_amount[CHAINGUN_WEAPON] > 0 ) // && p->random_club_frame == 0)
3591 (*kb)=1;
3592 break;
3593
3594 case SHOTGUN_WEAPON:
3595 if( p->ammo_amount[SHOTGUN_WEAPON] > 0 && p->random_club_frame == 0 )
3596 (*kb)=1;
3597 break;
3598
3599 case TRIPBOMB_WEAPON:
3600 if (VOLUMEONE) break;
3601 if ( p->ammo_amount[TRIPBOMB_WEAPON] > 0 )
3602 {
3603 int32_t sx,sy,sz;
3604 short sect,hw,hitsp;
3605
3606 hitscan( p->posx, p->posy, p->posz,
3607 p->cursectnum, sintable[(p->ang+512)&2047],
3608 sintable[p->ang&2047], (100-p->horiz-p->horizoff)*32,
3609 &sect, &hw, &hitsp, &sx, &sy, &sz,CLIPMASK1);
3610
3611 if(sect < 0 || hitsp >= 0)
3612 break;
3613
3614 if( hw >= 0 && sector[sect].lotag > 2 )
3615 break;
3616
3617 if(hw >= 0 && wall[hw].overpicnum >= 0)
3618 if(wall[hw].overpicnum == BIGFORCE)
3619 break;
3620
3621 j = headspritesect[sect];
3622 while(j >= 0)
3623 {
3624 if( sprite[j].picnum == TRIPBOMB &&
3625 klabs(sprite[j].z-sz) < (12<<8) && ((sprite[j].x-sx)*(sprite[j].x-sx)+(sprite[j].y-sy)*(sprite[j].y-sy)) < (290*290) )
3626 break;
3627 j = nextspritesect[j];
3628 }
3629
3630 if(j == -1 && hw >= 0 && (wall[hw].cstat&16) == 0 )
3631 if( ( wall[hw].nextsector >= 0 && sector[wall[hw].nextsector].lotag <= 2 ) || ( wall[hw].nextsector == -1 && sector[sect].lotag <= 2 ) )
3632 if( ( (sx-p->posx)*(sx-p->posx) + (sy-p->posy)*(sy-p->posy) ) < (290*290) )
3633 {
3634 p->posz = p->oposz;
3635 p->poszv = 0;
3636 (*kb) = 1;
3637 }
3638 }
3639 break;
3640
3641 case SHRINKER_WEAPON:
3642 case GROW_WEAPON:
3643 if (VOLUMEONE) break;
3644 if( p->curr_weapon == GROW_WEAPON )
3645 {
3646 if( p->ammo_amount[GROW_WEAPON] > 0 )
3647 {
3648 (*kb) = 1;
3649 spritesound(EXPANDERSHOOT,pi);
3650 }
3651 }
3652 else if( p->ammo_amount[SHRINKER_WEAPON] > 0)
3653 {
3654 (*kb) = 1;
3655 spritesound(SHRINKER_FIRE,pi);
3656 }
3657 break;
3658
3659 case FREEZE_WEAPON:
3660 if (VOLUMEONE) break;
3661 if( p->ammo_amount[FREEZE_WEAPON] > 0 )
3662 {
3663 (*kb) = 1;
3664 spritesound(CAT_FIRE,pi);
3665 }
3666 break;
3667 case DEVISTATOR_WEAPON:
3668 if (VOLUMEONE) break;
3669 if( p->ammo_amount[DEVISTATOR_WEAPON] > 0 )
3670 {
3671 (*kb) = 1;
3672 p->hbomb_hold_delay = !p->hbomb_hold_delay;
3673 spritesound(CAT_FIRE,pi);
3674 }
3675 break;
3676
3677 case RPG_WEAPON:
3678 if ( p->ammo_amount[RPG_WEAPON] > 0)
3679 (*kb) = 1;
3680 break;
3681
3682 case KNEE_WEAPON:
3683 if(p->quick_kick == 0) (*kb) = 1;
3684 break;
3685 }
3686 }
3687 else if((*kb))
3688 {
3689 switch( p->curr_weapon )
3690 {
3691 case HANDBOMB_WEAPON:
3692
3693 if( (*kb) == 6 && (sb_snum&(1<<2)) )
3694 {
3695 p->rapid_fire_hold = 1;
3696 break;
3697 }
3698 (*kb)++;
3699 if((*kb)==12)
3700 {
3701 p->ammo_amount[HANDBOMB_WEAPON]--;
3702
3703 if(p->on_ground && (sb_snum&2) )
3704 {
3705 k = 15;
3706 i = ((p->horiz+p->horizoff-100)*20);
3707 }
3708 else
3709 {
3710 k = 140;
3711 i = -512-((p->horiz+p->horizoff-100)*20);
3712 }
3713
3714 j = EGS(p->cursectnum,
3715 p->posx+(sintable[(p->ang+512)&2047]>>6),
3716 p->posy+(sintable[p->ang&2047]>>6),
3717 p->posz,HEAVYHBOMB,-16,9,9,
3718 p->ang,(k+(p->hbomb_hold_delay<<5)),i,pi,1);
3719
3720 if(k == 15)
3721 {
3722 sprite[j].yvel = 3;
3723 sprite[j].z += (8<<8);
3724 }
3725
3726 k = hits(pi);
3727 if( k < 512 )
3728 {
3729 sprite[j].ang += 1024;
3730 sprite[j].zvel /= 3;
3731 sprite[j].xvel /= 3;
3732 }
3733
3734 p->hbomb_on = 1;
3735
3736 }
3737 else if( (*kb) < 12 && (sb_snum&(1<<2)) )
3738 p->hbomb_hold_delay++;
3739 else if( (*kb) > 19 )
3740 {
3741 (*kb) = 0;
3742 p->curr_weapon = HANDREMOTE_WEAPON;
3743 p->last_weapon = -1;
3744 p->weapon_pos = 10;
3745 }
3746
3747 break;
3748
3749
3750 case HANDREMOTE_WEAPON:
3751
3752 (*kb)++;
3753
3754 if((*kb) == 2)
3755 {
3756 p->hbomb_on = 0;
3757 }
3758
3759 if((*kb) == 10)
3760 {
3761 (*kb) = 0;
3762 if(p->ammo_amount[HANDBOMB_WEAPON] > 0)
3763 addweapon(p,HANDBOMB_WEAPON);
3764 else checkavailweapon(p);
3765 }
3766 break;
3767
3768 case PISTOL_WEAPON:
3769 if( (*kb)==1)
3770 {
3771 shoot(pi,SHOTSPARK1);
3772 spritesound(PISTOL_FIRE,pi);
3773
3774 lastvisinc = totalclock+32;
3775 p->visibility = 0;
3776 }
3777 else if((*kb) == 2)
3778 spawn(pi,SHELL);
3779
3780 (*kb)++;
3781
3782 if((*kb) >= 5)
3783 {
3784 if( p->ammo_amount[PISTOL_WEAPON] <= 0 || (p->ammo_amount[PISTOL_WEAPON]%12) )
3785 {
3786 (*kb)=0;
3787 checkavailweapon(p);
3788 }
3789 else
3790 {
3791 switch((*kb))
3792 {
3793 case 5:
3794 spritesound(EJECT_CLIP,pi);
3795 break;
3796 case 8:
3797 spritesound(INSERT_CLIP,pi);
3798 break;
3799 }
3800 }
3801 }
3802
3803 if((*kb) == 27)
3804 {
3805 (*kb) = 0;
3806 checkavailweapon(p);
3807 }
3808
3809 break;
3810
3811 case SHOTGUN_WEAPON:
3812
3813 (*kb)++;
3814
3815 if(*kb == 4)
3816 {
3817 shoot(pi,SHOTGUN);
3818 shoot(pi,SHOTGUN);
3819 shoot(pi,SHOTGUN);
3820 shoot(pi,SHOTGUN);
3821 shoot(pi,SHOTGUN);
3822 shoot(pi,SHOTGUN);
3823 shoot(pi,SHOTGUN);
3824
3825 p->ammo_amount[SHOTGUN_WEAPON]--;
3826
3827 spritesound(SHOTGUN_FIRE,pi);
3828
3829 lastvisinc = totalclock+32;
3830 p->visibility = 0;
3831 }
3832
3833 switch(*kb)
3834 {
3835 case 13:
3836 checkavailweapon(p);
3837 break;
3838 case 15:
3839 spritesound(SHOTGUN_COCK,pi);
3840 break;
3841 case 17:
3842 case 20:
3843 p->kickback_pic++;
3844 break;
3845 case 24:
3846 j = spawn(pi,SHOTGUNSHELL);
3847 sprite[j].ang += 1024;
3848 ssp(j,CLIPMASK0);
3849 sprite[j].ang += 1024;
3850 p->kickback_pic++;
3851 break;
3852 case 31:
3853 *kb = 0;
3854 return;
3855 }
3856 break;
3857
3858 case CHAINGUN_WEAPON:
3859
3860 (*kb)++;
3861
3862 if( *(kb) <= 12 )
3863 {
3864 if( ((*(kb))%3) == 0 )
3865 {
3866 p->ammo_amount[CHAINGUN_WEAPON]--;
3867
3868 if( (*(kb)%3) == 0 )
3869 {
3870 j = spawn(pi,SHELL);
3871
3872 sprite[j].ang += 1024;
3873 sprite[j].ang &= 2047;
3874 sprite[j].xvel += 32;
3875 sprite[j].z += (3<<8);
3876 ssp(j,CLIPMASK0);
3877 }
3878
3879 spritesound(CHAINGUN_FIRE,pi);
3880 shoot(pi,CHAINGUN);
3881 lastvisinc = totalclock+32;
3882 p->visibility = 0;
3883 checkavailweapon(p);
3884
3885 if( ( sb_snum&(1<<2) ) == 0 )
3886 {
3887 *kb = 0;
3888 break;
3889 }
3890 }
3891 }
3892 else if((*kb) > 10)
3893 {
3894 if( sb_snum&(1<<2) ) *kb = 1;
3895 else *kb = 0;
3896 }
3897
3898 break;
3899
3900 case SHRINKER_WEAPON:
3901 case GROW_WEAPON:
3902
3903 if(p->curr_weapon == GROW_WEAPON)
3904 {
3905 if((*kb) > 3)
3906 {
3907 *kb = 0;
3908 if( screenpeek == snum ) pus = 1;
3909 p->ammo_amount[GROW_WEAPON]--;
3910 shoot(pi,GROWSPARK);
3911
3912 p->visibility = 0;
3913 lastvisinc = totalclock+32;
3914 checkavailweapon(p);
3915 }
3916 else (*kb)++;
3917 }
3918 else
3919 {
3920 if( (*kb) > 10)
3921 {
3922 (*kb) = 0;
3923
3924 p->ammo_amount[SHRINKER_WEAPON]--;
3925 shoot(pi,SHRINKER);
3926
3927 p->visibility = 0;
3928 lastvisinc = totalclock+32;
3929 checkavailweapon(p);
3930 }
3931 else (*kb)++;
3932 }
3933 break;
3934
3935 case DEVISTATOR_WEAPON:
3936 if(*kb)
3937 {
3938 (*kb)++;
3939
3940 if( (*kb) & 1 )
3941 {
3942 p->visibility = 0;
3943 lastvisinc = totalclock+32;
3944 shoot(pi,RPG);
3945 p->ammo_amount[DEVISTATOR_WEAPON]--;
3946 checkavailweapon(p);
3947 }
3948 if((*kb) > 5) (*kb) = 0;
3949 }
3950 break;
3951 case FREEZE_WEAPON:
3952
3953 if( (*kb) < 4 )
3954 {
3955 (*kb)++;
3956 if( (*kb) == 3 )
3957 {
3958 p->ammo_amount[FREEZE_WEAPON]--;
3959 p->visibility = 0;
3960 lastvisinc = totalclock+32;
3961 shoot(pi,FREEZEBLAST);
3962 checkavailweapon(p);
3963 }
3964 if(s->xrepeat < 32)
3965 { *kb = 0; break; }
3966 }
3967 else
3968 {
3969 if( sb_snum&(1<<2))
3970 {
3971 *kb = 1;
3972 spritesound(CAT_FIRE,pi);
3973 }
3974 else *kb = 0;
3975 }
3976 break;
3977
3978 case TRIPBOMB_WEAPON:
3979 if(*kb < 4)
3980 {
3981 p->posz = p->oposz;
3982 p->poszv = 0;
3983 if( (*kb) == 3 )
3984 shoot(pi,HANDHOLDINGLASER);
3985 }
3986 if((*kb) == 16)
3987 {
3988 (*kb) = 0;
3989 checkavailweapon(p);
3990 p->weapon_pos = -9;
3991 }
3992 else (*kb)++;
3993 break;
3994 case KNEE_WEAPON:
3995 (*kb)++;
3996
3997 if( (*kb) == 7) shoot(pi,KNEE);
3998 else if( (*kb) == 14)
3999 {
4000 if( sb_snum&(1<<2) )
4001 *kb = 1+(TRAND&3);
4002 else *kb = 0;
4003 }
4004
4005 if(p->wantweaponfire >= 0)
4006 checkavailweapon(p);
4007 break;
4008
4009 case RPG_WEAPON:
4010 (*kb)++;
4011 if( (*kb) == 4 )
4012 {
4013 p->ammo_amount[RPG_WEAPON]--;
4014 lastvisinc = totalclock+32;
4015 p->visibility = 0;
4016 shoot(pi,RPG);
4017 checkavailweapon(p);
4018 }
4019 else if( *kb == 20 )
4020 *kb = 0;
4021 break;
4022 }
4023 }
4024}
4025
4026
4027
4028//UPDATE THIS FILE OVER THE OLD GETSPRITESCORE/COMPUTERGETINPUT FUNCTIONS
4029static int getspritescore(int32_t snum, int32_t dapicnum)
4030{
4031 switch(dapicnum)
4032 {
4033 case FIRSTGUNSPRITE: return(5);
4034 case CHAINGUNSPRITE: return(50);
4035 case RPGSPRITE: return(200);
4036 case FREEZESPRITE: return(25);
4037 case SHRINKERSPRITE: return(80);
4038 case HEAVYHBOMB: return(60);
4039 case TRIPBOMBSPRITE: return(50);
4040 case SHOTGUNSPRITE: return(120);
4041 case DEVISTATORSPRITE: return(120);
4042
4043 case FREEZEAMMO: if (ps[snum].ammo_amount[FREEZE_WEAPON] < max_ammo_amount[FREEZE_WEAPON]) return(10); else return(0);
4044 case AMMO: if (ps[snum].ammo_amount[SHOTGUN_WEAPON] < max_ammo_amount[SHOTGUN_WEAPON]) return(10); else return(0);
4045 case BATTERYAMMO: if (ps[snum].ammo_amount[CHAINGUN_WEAPON] < max_ammo_amount[CHAINGUN_WEAPON]) return(20); else return(0);
4046 case DEVISTATORAMMO: if (ps[snum].ammo_amount[DEVISTATOR_WEAPON] < max_ammo_amount[DEVISTATOR_WEAPON]) return(25); else return(0);
4047 case RPGAMMO: if (ps[snum].ammo_amount[RPG_WEAPON] < max_ammo_amount[RPG_WEAPON]) return(50); else return(0);
4048 case CRYSTALAMMO: if (ps[snum].ammo_amount[SHRINKER_WEAPON] < max_ammo_amount[SHRINKER_WEAPON]) return(10); else return(0);
4049 case HBOMBAMMO: if (ps[snum].ammo_amount[HANDBOMB_WEAPON] < max_ammo_amount[HANDBOMB_WEAPON]) return(30); else return(0);
4050 case SHOTGUNAMMO: if (ps[snum].ammo_amount[SHOTGUN_WEAPON] < max_ammo_amount[SHOTGUN_WEAPON]) return(25); else return(0);
4051
4052 case COLA: if (sprite[ps[snum].i].extra < 100) return(10); else return(0);
4053 case SIXPAK: if (sprite[ps[snum].i].extra < 100) return(30); else return(0);
4054 case FIRSTAID: if (ps[snum].firstaid_amount < 100) return(100); else return(0);
4055 case SHIELD: if (ps[snum].shield_amount < 100) return(50); else return(0);
4056 case STEROIDS: if (ps[snum].steroids_amount < 400) return(30); else return(0);
4057 case AIRTANK: if (ps[snum].scuba_amount < 6400) return(30); else return(0);
4058 case JETPACK: if (ps[snum].jetpack_amount < 1600) return(100); else return(0);
4059 case HEATSENSOR: if (ps[snum].heat_amount < 1200) return(10); else return(0);
4060 case ACCESSCARD: return(1);
4061 case BOOTS: if (ps[snum].boot_amount < 200) return(50); else return(0);
4062 case ATOMICHEALTH: if (sprite[ps[snum].i].extra < max_player_health) return(50); else return(0);
4063 case HOLODUKE: if (ps[snum].holoduke_amount < 2400) return(30); else return(0);
4064 }
4065 return(0);
4066}
4067
4068static int32_t fdmatrix[12][12] =
4069{
4070 //KNEE PIST SHOT CHAIN RPG PIPE SHRI DEVI WALL FREE HAND EXPA
4071 { 128, -1, -1, -1, 128, -1, -1, -1, 128, -1, 128, -1 }, //KNEE
4072 { 1024,1024,1024,1024,2560, 128,2560,2560,1024,2560,2560,2560 }, //PIST
4073 { 512, 512, 512, 512,2560, 128,2560,2560,1024,2560,2560,2560 }, //SHOT
4074 { 512, 512, 512, 512,2560, 128,2560,2560,1024,2560,2560,2560 }, //CHAIN
4075 { 2560,2560,2560,2560,2560,2560,2560,2560,2560,2560,2560,2560 }, //RPG
4076 { 512, 512, 512, 512,2048, 512,2560,2560, 512,2560,2560,2560 }, //PIPE
4077 { 128, 128, 128, 128,2560, 128,2560,2560, 128, 128, 128, 128 }, //SHRI
4078 { 1536,1536,1536,1536,2560,1536,1536,1536,1536,1536,1536,1536 }, //DEVI
4079 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, //WALL
4080 { 128, 128, 128, 128,2560, 128,2560,2560, 128, 128, 128, 128 }, //FREE
4081 { 2560,2560,2560,2560,2560,2560,2560,2560,2560,2560,2560,2560 }, //HAND
4082 { 128, 128, 128, 128,2560, 128,2560,2560, 128, 128, 128, 128 } //EXPA
4083};
4084
4085static int32_t goalx[MAXPLAYERS], goaly[MAXPLAYERS], goalz[MAXPLAYERS];
4086static int32_t goalsect[MAXPLAYERS], goalwall[MAXPLAYERS], goalsprite[MAXPLAYERS];
4087static int32_t goalplayer[MAXPLAYERS], clipmovecount[MAXPLAYERS];
4088short searchsect[MAXSECTORS], searchparent[MAXSECTORS];
4089uint8_t dashow2dsector[(MAXSECTORS+7)>>3];
4090void computergetinput(int32_t snum, input *syn)
4091{
4092 int32_t i, j, k, l, x1, y1, z1, x2, y2, z2, x3, y3, z3, dx, dy;
4093 int32_t dist, daang, zang, fightdist, damyang, damysect;
4094 int32_t startsect, endsect, splc, send, startwall, endwall;
4095 short dasect, dawall, daspr;
4096 struct player_struct *p;
4097 walltype *wal;
4098
4099 p = &ps[snum];
4100 syn->fvel = 0;
4101 syn->svel = 0;
4102 syn->avel = 0;
4103 syn->horz = 0;
4104 syn->bits = 0;
4105
4106 z2 = y2 = x2 = 0;
4107 x1 = sprite[p->i].x;
4108 y1 = sprite[p->i].y;
4109 z1 = sprite[p->i].z;
4110 damyang = sprite[p->i].ang;
4111 damysect = sprite[p->i].sectnum;
4112 if ((numplayers >= 2) && (snum == myconnectindex))
4113 { x1 = myx; y1 = myy; z1 = myz+PHEIGHT; damyang = myang; damysect = mycursectnum; }
4114
4115 if (!(numframes&7))
4116 {
4117 x2 = sprite[ps[goalplayer[snum]].i].x;
4118 y2 = sprite[ps[goalplayer[snum]].i].y;
4119 z2 = sprite[ps[goalplayer[snum]].i].z;
4120
4121 if (!cansee(x1,y1,z1-(48<<8),damysect,x2,y2,z2-(48<<8),sprite[ps[goalplayer[snum]].i].sectnum))
4122 goalplayer[snum] = snum;
4123 }
4124
4125 if ((goalplayer[snum] == snum) || (ps[goalplayer[snum]].dead_flag != 0))
4126 {
4127 j = 0x7fffffff;
4128 for(i=connecthead;i>=0;i=connectpoint2[i])
4129 if (i != snum)
4130 {
4131 dist = ksqrt((sprite[ps[i].i].x-x1)*(sprite[ps[i].i].x-x1)+(sprite[ps[i].i].y-y1)*(sprite[ps[i].i].y-y1));
4132
4133 x2 = sprite[ps[i].i].x;
4134 y2 = sprite[ps[i].i].y;
4135 z2 = sprite[ps[i].i].z;
4136 if (!cansee(x1,y1,z1-(48<<8),damysect,x2,y2,z2-(48<<8),sprite[ps[i].i].sectnum))
4137 dist <<= 1;
4138
4139 if (dist < j) { j = dist; goalplayer[snum] = i; }
4140 }
4141 }
4142
4143 x2 = sprite[ps[goalplayer[snum]].i].x;
4144 y2 = sprite[ps[goalplayer[snum]].i].y;
4145 z2 = sprite[ps[goalplayer[snum]].i].z;
4146
4147 if (p->dead_flag) syn->bits |= (1<<29);
4148 if ((p->firstaid_amount > 0) && (p->last_extra < max_player_health))
4149 syn->bits |= (1<<16);
4150
4151 for(j=headspritestat[4];j>=0;j=nextspritestat[j])
4152 {
4153 switch (sprite[j].picnum)
4154 {
4155 case TONGUE: k = 4; break;
4156 case FREEZEBLAST: k = 4; break;
4157 case SHRINKSPARK: k = 16; break;
4158 case RPG: k = 16; break;
4159 default: k = 0; break;
4160 }
4161 if (k)
4162 {
4163 x3 = sprite[j].x;
4164 y3 = sprite[j].y;
4165 z3 = sprite[j].z;
4166 for(l=0;l<=8;l++)
4167 {
4168 if (tmulscale11(x3-x1,x3-x1,y3-y1,y3-y1,(z3-z1)>>4,(z3-z1)>>4) < 3072)
4169 {
4170 dx = sintable[(sprite[j].ang+512)&2047];
4171 dy = sintable[sprite[j].ang&2047];
4172 if ((x1-x3)*dy > (y1-y3)*dx) i = -k*512; else i = k*512;
4173 syn->fvel -= mulscale17(dy,i);
4174 syn->svel += mulscale17(dx,i);
4175 }
4176 if (l < 7)
4177 {
4178 x3 += (mulscale14(sprite[j].xvel,sintable[(sprite[j].ang+512)&2047])<<2);
4179 y3 += (mulscale14(sprite[j].xvel,sintable[sprite[j].ang&2047])<<2);
4180 z3 += (sprite[j].zvel<<2);
4181 }
4182 else
4183 {
4184 hitscan(sprite[j].x,sprite[j].y,sprite[j].z,sprite[j].sectnum,
4185 mulscale14(sprite[j].xvel,sintable[(sprite[j].ang+512)&2047]),
4186 mulscale14(sprite[j].xvel,sintable[sprite[j].ang&2047]),
4187 (int32_t)sprite[j].zvel,
4188 &dasect,&dawall,&daspr,&x3,&y3,&z3,CLIPMASK1);
4189 }
4190 }
4191 }
4192 }
4193
4194 if ((ps[goalplayer[snum]].dead_flag == 0) &&
4195 ((cansee(x1,y1,z1,damysect,x2,y2,z2,sprite[ps[goalplayer[snum]].i].sectnum)) ||
4196 (cansee(x1,y1,z1-(24<<8),damysect,x2,y2,z2-(24<<8),sprite[ps[goalplayer[snum]].i].sectnum)) ||
4197 (cansee(x1,y1,z1-(48<<8),damysect,x2,y2,z2-(48<<8),sprite[ps[goalplayer[snum]].i].sectnum))))
4198 {
4199 syn->bits |= (1<<2);
4200
4201 if ((p->curr_weapon == HANDBOMB_WEAPON) && (!(rand()&7)))
4202 syn->bits &= ~(1<<2);
4203
4204 if (p->curr_weapon == TRIPBOMB_WEAPON)
4205 syn->bits |= ((rand()%MAX_WEAPONS)<<8);
4206
4207 if (p->curr_weapon == RPG_WEAPON)
4208 {
4209 hitscan(x1,y1,z1-PHEIGHT,damysect,sintable[(damyang+512)&2047],sintable[damyang&2047],
4210 (100-p->horiz-p->horizoff)*32,&dasect,&dawall,&daspr,&x3,&y3,&z3,CLIPMASK1);
4211 if ((x3-x1)*(x3-x1)+(y3-y1)*(y3-y1) < 2560*2560) syn->bits &= ~(1<<2);
4212 }
4213
4214
4215 fightdist = fdmatrix[p->curr_weapon][ps[goalplayer[snum]].curr_weapon];
4216 if (fightdist < 128) fightdist = 128;
4217 dist = ksqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); if (dist == 0) dist = 1;
4218 daang = getangle(x2+(ps[goalplayer[snum]].posxv>>14)-x1,y2+(ps[goalplayer[snum]].posyv>>14)-y1);
4219 zang = 100-((z2-z1)*8)/dist;
4220 fightdist = max(fightdist,(klabs(z2-z1)>>4));
4221
4222 if (sprite[ps[goalplayer[snum]].i].yrepeat < 32)
4223 { fightdist = 0; syn->bits &= ~(1<<2); }
4224 if (sprite[ps[goalplayer[snum]].i].pal == 1)
4225 { fightdist = 0; syn->bits &= ~(1<<2); }
4226
4227 if (dist < 256) syn->bits |= (1<<22);
4228
4229 x3 = x2+((x1-x2)*fightdist/dist);
4230 y3 = y2+((y1-y2)*fightdist/dist);
4231 syn->fvel += (x3-x1)*2047/dist;
4232 syn->svel += (y3-y1)*2047/dist;
4233
4234 //Strafe attack
4235 if (fightdist)
4236 {
4237 j = totalclock+snum*13468;
4238 i = sintable[(j<<6)&2047];
4239 i += sintable[((j+4245)<<5)&2047];
4240 i += sintable[((j+6745)<<4)&2047];
4241 i += sintable[((j+15685)<<3)&2047];
4242 dx = sintable[(sprite[ps[goalplayer[snum]].i].ang+512)&2047];
4243 dy = sintable[sprite[ps[goalplayer[snum]].i].ang&2047];
4244 if ((x1-x2)*dy > (y1-y2)*dx) i += 8192; else i -= 8192;
4245 syn->fvel += ((sintable[(daang+1024)&2047]*i)>>17);
4246 syn->svel += ((sintable[(daang+512)&2047]*i)>>17);
4247 }
4248
4249 syn->avel = min(max((((daang+1024-damyang)&2047)-1024)>>1,-127),127);
4250 syn->horz = min(max((zang-p->horiz)>>1,-MAXHORIZ),MAXHORIZ);
4251 syn->bits |= (1<<23);
4252 return;
4253 }
4254
4255 goalsect[snum] = -1;
4256 if (goalsect[snum] < 0)
4257 {
4258 goalwall[snum] = -1;
4259 startsect = sprite[p->i].sectnum;
4260 endsect = sprite[ps[goalplayer[snum]].i].sectnum;
4261
4262 clearbufbyte(dashow2dsector,(MAXSECTORS+7)>>3,0L);
4263 searchsect[0] = startsect;
4264 searchparent[0] = -1;
4265 dashow2dsector[startsect>>3] |= (1<<(startsect&7));
4266 for(splc=0,send=1;splc<send;splc++)
4267 {
4268 startwall = sector[searchsect[splc]].wallptr;
4269 endwall = startwall + sector[searchsect[splc]].wallnum;
4270 for(i=startwall,wal=&wall[startwall];i<endwall;i++,wal++)
4271 {
4272 j = wal->nextsector; if (j < 0) continue;
4273
4274 dx = ((wall[wal->point2].x+wal->x)>>1);
4275 dy = ((wall[wal->point2].y+wal->y)>>1);
4276 if ((getceilzofslope(j,dx,dy) > getflorzofslope(j,dx,dy)-(28<<8)) && ((sector[j].lotag < 15) || (sector[j].lotag > 22)))
4277 continue;
4278 if (getflorzofslope(j,dx,dy) < getflorzofslope(searchsect[splc],dx,dy)-(72<<8))
4279 continue;
4280 if ((dashow2dsector[j>>3]&(1<<(j&7))) == 0)
4281 {
4282 dashow2dsector[j>>3] |= (1<<(j&7));
4283 searchsect[send] = (short)j;
4284 searchparent[send] = (short)splc;
4285 send++;
4286 if (j == endsect)
4287 {
4288 clearbufbyte(dashow2dsector,(MAXSECTORS+7)>>3,0L);
4289 for(k=send-1;k>=0;k=searchparent[k])
4290 dashow2dsector[searchsect[k]>>3] |= (1<<(searchsect[k]&7));
4291
4292 for(k=send-1;k>=0;k=searchparent[k])
4293 if (!searchparent[k]) break;
4294
4295 goalsect[snum] = searchsect[k];
4296 startwall = sector[goalsect[snum]].wallptr;
4297 endwall = startwall+sector[goalsect[snum]].wallnum;
4298 x3 = y3 = 0;
4299 for(i=startwall;i<endwall;i++)
4300 {
4301 x3 += wall[i].x;
4302 y3 += wall[i].y;
4303 }
4304 x3 /= (endwall-startwall);
4305 y3 /= (endwall-startwall);
4306
4307 startwall = sector[startsect].wallptr;
4308 endwall = startwall+sector[startsect].wallnum;
4309 l = 0; k = startwall;
4310 for(i=startwall;i<endwall;i++)
4311 {
4312 if (wall[i].nextsector != goalsect[snum]) continue;
4313 dx = wall[wall[i].point2].x-wall[i].x;
4314 dy = wall[wall[i].point2].y-wall[i].y;
4315
4316 //if (dx*(y1-wall[i].y) <= dy*(x1-wall[i].x))
4317 // if (dx*(y2-wall[i].y) >= dy*(x2-wall[i].x))
4318 if ((x3-x1)*(wall[i].y-y1) <= (y3-y1)*(wall[i].x-x1))
4319 if ((x3-x1)*(wall[wall[i].point2].y-y1) >= (y3-y1)*(wall[wall[i].point2].x-x1))
4320 { k = i; break; }
4321
4322 dist = ksqrt(dx*dx+dy*dy);
4323 if (dist > l) { l = dist; k = i; }
4324 }
4325 goalwall[snum] = k;
4326 daang = ((getangle(wall[wall[k].point2].x-wall[k].x,wall[wall[k].point2].y-wall[k].y)+1536)&2047);
4327 goalx[snum] = ((wall[k].x+wall[wall[k].point2].x)>>1)+(sintable[(daang+512)&2047]>>8);
4328 goaly[snum] = ((wall[k].y+wall[wall[k].point2].y)>>1)+(sintable[daang&2047]>>8);
4329 goalz[snum] = sector[goalsect[snum]].floorz-(32<<8);
4330 break;
4331 }
4332 }
4333 }
4334
4335 for(i=headspritesect[searchsect[splc]];i>=0;i=nextspritesect[i])
4336 if (sprite[i].lotag == 7)
4337 {
4338 j = sprite[sprite[i].owner].sectnum;
4339 if ((dashow2dsector[j>>3]&(1<<(j&7))) == 0)
4340 {
4341 dashow2dsector[j>>3] |= (1<<(j&7));
4342 searchsect[send] = (short)j;
4343 searchparent[send] = (short)splc;
4344 send++;
4345 if (j == endsect)
4346 {
4347 clearbufbyte(dashow2dsector,(MAXSECTORS+7)>>3,0L);
4348 for(k=send-1;k>=0;k=searchparent[k])
4349 dashow2dsector[searchsect[k]>>3] |= (1<<(searchsect[k]&7));
4350
4351 for(k=send-1;k>=0;k=searchparent[k])
4352 if (!searchparent[k]) break;
4353
4354 goalsect[snum] = searchsect[k];
4355 startwall = sector[startsect].wallptr;
4356 endwall = startwall+sector[startsect].wallnum;
4357 l = 0; k = startwall;
4358 for(i=startwall;i<endwall;i++)
4359 {
4360 dx = wall[wall[i].point2].x-wall[i].x;
4361 dy = wall[wall[i].point2].y-wall[i].y;
4362 dist = ksqrt(dx*dx+dy*dy);
4363 if ((wall[i].nextsector == goalsect[snum]) && (dist > l))
4364 { l = dist; k = i; }
4365 }
4366 goalwall[snum] = k;
4367 daang = ((getangle(wall[wall[k].point2].x-wall[k].x,wall[wall[k].point2].y-wall[k].y)+1536)&2047);
4368 goalx[snum] = ((wall[k].x+wall[wall[k].point2].x)>>1)+(sintable[(daang+512)&2047]>>8);
4369 goaly[snum] = ((wall[k].y+wall[wall[k].point2].y)>>1)+(sintable[daang&2047]>>8);
4370 goalz[snum] = sector[goalsect[snum]].floorz-(32<<8);
4371 break;
4372 }
4373 }
4374 }
4375 if (goalwall[snum] >= 0) break;
4376 }
4377 }
4378
4379 if ((goalsect[snum] < 0) || (goalwall[snum] < 0))
4380 {
4381 if (goalsprite[snum] < 0)
4382 {
4383 for(k=0;k<4;k++)
4384 {
4385 i = (rand()%numsectors);
4386 for(j=headspritesect[i];j>=0;j=nextspritesect[j])
4387 {
4388 if ((sprite[j].xrepeat <= 0) || (sprite[j].yrepeat <= 0)) continue;
4389 if (getspritescore(snum,sprite[j].picnum) <= 0) continue;
4390 if (cansee(x1,y1,z1-(32<<8),damysect,sprite[j].x,sprite[j].y,sprite[j].z-(4<<8),i))
4391 { goalx[snum] = sprite[j].x; goaly[snum] = sprite[j].y; goalz[snum] = sprite[j].z; goalsprite[snum] = j; break; }
4392 }
4393 }
4394 }
4395 x2 = goalx[snum];
4396 y2 = goaly[snum];
4397 dist = ksqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); if (!dist) return;
4398 daang = getangle(x2-x1,y2-y1);
4399 syn->fvel += (x2-x1)*2047/dist;
4400 syn->svel += (y2-y1)*2047/dist;
4401 syn->avel = min(max((((daang+1024-damyang)&2047)-1024)>>3,-127),127);
4402 }
4403 else
4404 goalsprite[snum] = -1;
4405
4406 x3 = p->posx; y3 = p->posy; z3 = p->posz; dasect = p->cursectnum;
4407 i = clipmove(&x3,&y3,&z3,&dasect,p->posxv,p->posyv,164L,4L<<8,4L<<8,CLIPMASK0);
4408 if (!i)
4409 {
4410 x3 = p->posx; y3 = p->posy; z3 = p->posz+(24<<8); dasect = p->cursectnum;
4411 i = clipmove(&x3,&y3,&z3,&dasect,p->posxv,p->posyv,164L,4L<<8,4L<<8,CLIPMASK0);
4412 }
4413 if (i)
4414 {
4415 clipmovecount[snum]++;
4416
4417 j = 0;
4418 if ((i&0xc000) == 32768) //Hit a wall (49152 for sprite)
4419 if (wall[i&(MAXWALLS-1)].nextsector >= 0)
4420 {
4421 if (getflorzofslope(wall[i&(MAXWALLS-1)].nextsector,p->posx,p->posy) <= p->posz+(24<<8)) j |= 1;
4422 if (getceilzofslope(wall[i&(MAXWALLS-1)].nextsector,p->posx,p->posy) >= p->posz-(24<<8)) j |= 2;
4423 }
4424 if ((i&0xc000) == 49152) j = 1;
4425 if (j&1) if (clipmovecount[snum] == 4) syn->bits |= (1<<0);
4426 if (j&2) syn->bits |= (1<<1);
4427
4428 //Strafe attack
4429 daang = getangle(x2-x1,y2-y1);
4430 if ((i&0xc000) == 32768)
4431 daang = getangle(wall[wall[i&(MAXWALLS-1)].point2].x-wall[i&(MAXWALLS-1)].x,wall[wall[i&(MAXWALLS-1)].point2].y-wall[i&(MAXWALLS-1)].y);
4432 j = totalclock+snum*13468;
4433 i = sintable[(j<<6)&2047];
4434 i += sintable[((j+4245)<<5)&2047];
4435 i += sintable[((j+6745)<<4)&2047];
4436 i += sintable[((j+15685)<<3)&2047];
4437 syn->fvel += ((sintable[(daang+1024)&2047]*i)>>17);
4438 syn->svel += ((sintable[(daang+512)&2047]*i)>>17);
4439
4440 if ((clipmovecount[snum]&31) == 2) syn->bits |= (1<<29);
4441 if ((clipmovecount[snum]&31) == 17) syn->bits |= (1<<22);
4442 if (clipmovecount[snum] > 32) { goalsect[snum] = -1; goalwall[snum] = -1; clipmovecount[snum] = 0; }
4443
4444 goalsprite[snum] = -1;
4445 }
4446 else
4447 clipmovecount[snum] = 0;
4448
4449 if ((goalsect[snum] >= 0) && (goalwall[snum] >= 0))
4450 {
4451 x2 = goalx[snum];
4452 y2 = goaly[snum];
4453 dist = ksqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); if (!dist) return;
4454 daang = getangle(x2-x1,y2-y1);
4455 if ((goalwall[snum] >= 0) && (dist < 4096))
4456 daang = ((getangle(wall[wall[goalwall[snum]].point2].x-wall[goalwall[snum]].x,wall[wall[goalwall[snum]].point2].y-wall[goalwall[snum]].y)+1536)&2047);
4457 syn->fvel += (x2-x1)*2047/dist;
4458 syn->svel += (y2-y1)*2047/dist;
4459 syn->avel = min(max((((daang+1024-damyang)&2047)-1024)>>3,-127),127);
4460 }
4461}
4462
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/premap.c b/apps/plugins/sdl/progs/duke3d/Game/src/premap.c
new file mode 100644
index 0000000000..70ce9b16da
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/premap.c
@@ -0,0 +1,1728 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#include "duke3d.h"
28#include "../../Engine/src/filesystem.h"
29#include "game.h"
30
31
32extern uint8_t everyothertime;
33short which_palookup = 9;
34
35
36static void tloadtile(short tilenume)
37{
38 gotpic[tilenume>>3] |= (1<<(tilenume&7));
39}
40
41void cachespritenum(short i)
42{
43 uint8_t maxc;
44 short j;
45
46 if(ud.monsters_off && badguy(&sprite[i])) return;
47
48 maxc = 1;
49
50 switch(PN)
51 {
52 case HYDRENT:
53 tloadtile(BROKEFIREHYDRENT);
54 for(j = TOILETWATER; j < (TOILETWATER+4); j++)
55 if(tiles[j].data == NULL) tloadtile(j);
56 break;
57 case TOILET:
58 tloadtile(TOILETBROKE);
59 for(j = TOILETWATER; j < (TOILETWATER+4); j++)
60 if(tiles[j].data == NULL) tloadtile(j);
61 break;
62 case STALL:
63 tloadtile(STALLBROKE);
64 for(j = TOILETWATER; j < (TOILETWATER+4); j++)
65 if(tiles[j].data == NULL) tloadtile(j);
66 break;
67 case RUBBERCAN:
68 maxc = 2;
69 break;
70 case TOILETWATER:
71 maxc = 4;
72 break;
73 case FEMPIC1:
74 maxc = 44;
75 break;
76 case LIZTROOP:
77 case LIZTROOPRUNNING:
78 case LIZTROOPSHOOT:
79 case LIZTROOPJETPACK:
80 case LIZTROOPONTOILET:
81 case LIZTROOPDUCKING:
82 for(j = LIZTROOP; j < (LIZTROOP+72); j++)
83 if(tiles[j].data == NULL)
84 tloadtile(j);
85 for(j=HEADJIB1;j<LEGJIB1+3;j++)
86 if(tiles[j].data == NULL)
87 tloadtile(j);
88 maxc = 0;
89 break;
90 case WOODENHORSE:
91 maxc = 5;
92 for(j = HORSEONSIDE; j < (HORSEONSIDE+4); j++)
93 if(tiles[j].data == NULL)
94 tloadtile(j);
95 break;
96 case NEWBEAST:
97 case NEWBEASTSTAYPUT:
98 maxc = 90;
99 break;
100 case BOSS1:
101 case BOSS2:
102 case BOSS3:
103 maxc = 30;
104 break;
105 case OCTABRAIN:
106 case OCTABRAINSTAYPUT:
107 case COMMANDER:
108 case COMMANDERSTAYPUT:
109 maxc = 38;
110 break;
111 case RECON:
112 maxc = 13;
113 break;
114 case PIGCOP:
115 case PIGCOPDIVE:
116 maxc = 61;
117 break;
118 case SHARK:
119 maxc = 30;
120 break;
121 case LIZMAN:
122 case LIZMANSPITTING:
123 case LIZMANFEEDING:
124 case LIZMANJUMP:
125 for(j=LIZMANHEAD1;j<LIZMANLEG1+3;j++)
126 if(tiles[j].data == NULL)
127 tloadtile(j);
128 maxc = 80;
129 break;
130 case APLAYER:
131 maxc = 0;
132 if(ud.multimode > 1)
133 {
134 maxc = 5;
135 for(j = 1420;j < 1420+106; j++)
136 if(tiles[j].data == NULL)
137 tloadtile(j);
138 }
139 break;
140 case ATOMICHEALTH:
141 maxc = 14;
142 break;
143 case DRONE:
144 maxc = 10;
145 break;
146 case EXPLODINGBARREL:
147 case SEENINE:
148 case OOZFILTER:
149 maxc = 3;
150 break;
151 case NUKEBARREL:
152 case CAMERA1:
153 maxc = 5;
154 break;
155 }
156
157 for(j = PN; j < (PN+maxc); j++)
158 if(tiles[j].data == NULL)
159 tloadtile(j);
160}
161
162void cachegoodsprites(void)
163{
164 short i;
165
166 if(ud.screen_size >= 8)
167 {
168 if(tiles[BOTTOMSTATUSBAR].data == NULL)
169 tloadtile(BOTTOMSTATUSBAR);
170 if( ud.multimode > 1)
171 {
172 if(tiles[FRAGBAR].data == NULL)
173 tloadtile(FRAGBAR);
174 for(i=MINIFONT;i<MINIFONT+63;i++)
175 if(tiles[i].data == NULL)
176 tloadtile(i);
177 }
178 }
179
180 tloadtile(VIEWSCREEN);
181
182 for(i=STARTALPHANUM;i<ENDALPHANUM+1;i++)
183 if (tiles[i].data == NULL)
184 tloadtile(i);
185
186 for(i=FOOTPRINTS;i<FOOTPRINTS+3;i++)
187 if (tiles[i].data == NULL)
188 tloadtile(i);
189
190 for( i = BIGALPHANUM; i < BIGALPHANUM+82; i++)
191 if(tiles[i].data == NULL)
192 tloadtile(i);
193
194 for( i = BURNING; i < BURNING+14; i++)
195 if(tiles[i].data == NULL)
196 tloadtile(i);
197
198 for( i = BURNING2; i < BURNING2+14; i++)
199 if(tiles[i].data == NULL)
200 tloadtile(i);
201
202 for( i = CRACKKNUCKLES; i < CRACKKNUCKLES+4; i++)
203 if(tiles[i].data == NULL)
204 tloadtile(i);
205
206 for( i = FIRSTGUN; i < FIRSTGUN+3 ; i++ )
207 if(tiles[i].data == NULL)
208 tloadtile(i);
209
210 for( i = EXPLOSION2; i < EXPLOSION2+21 ; i++ )
211 if(tiles[i].data == NULL)
212 tloadtile(i);
213
214 tloadtile(BULLETHOLE);
215
216 for( i = FIRSTGUNRELOAD; i < FIRSTGUNRELOAD+8 ; i++ )
217 if(tiles[i].data == NULL)
218 tloadtile(i);
219
220 tloadtile(FOOTPRINTS);
221
222 for( i = JIBS1; i < (JIBS5+5); i++)
223 if(tiles[i].data == NULL)
224 tloadtile(i);
225
226 for( i = SCRAP1; i < (SCRAP1+19); i++)
227 if(tiles[i].data == NULL)
228 tloadtile(i);
229
230 for( i = SMALLSMOKE; i < (SMALLSMOKE+4); i++)
231 if(tiles[i].data == NULL)
232 tloadtile(i);
233}
234
235uint8_t getsound(uint16_t num)
236{
237 short fp;
238 int32_t l;
239
240 if(num >= NUM_SOUNDS || SoundToggle == 0) return 0;
241 if (FXDevice == NumSoundCards) return 0;
242
243 fp = TCkopen4load(sounds[num],0);
244 if(fp == -1) return 0;
245
246 l = kfilelength( fp );
247 soundsiz[num] = l;
248
249 if( (ud.level_number == 0 && ud.volume_number == 0 && (num == 189 || num == 232 || num == 99 || num == 233 || num == 17 ) ) ||
250 ( l < 12288 ) )
251 {
252 Sound[num].lock = 2;
253 allocache(&Sound[num].ptr,l,&Sound[num].lock);
254 if(Sound[num].ptr != NULL)
255 kread( fp, Sound[num].ptr , l);
256 }
257 kclose( fp );
258 return 1;
259}
260
261void precachenecessarysounds(void)
262{
263 short i, j;
264
265 if (FXDevice == NumSoundCards) return;
266 j = 0;
267
268 for(i=0;i<NUM_SOUNDS;i++)
269 if(Sound[i].ptr == 0)
270 {
271 j++;
272 if( (j&7) == 0 )
273 getpackets();
274 getsound(i);
275 }
276}
277
278
279void cacheit(void)
280{
281 short i,j;
282
283 precachenecessarysounds();
284
285 cachegoodsprites();
286
287 for(i=0;i<numwalls;i++)
288 if( tiles[wall[i].picnum].data == NULL)
289 {
290 if(tiles[wall[i].picnum].data == NULL)
291 tloadtile(wall[i].picnum);
292 if(wall[i].overpicnum >= 0 && tiles[wall[i].overpicnum].data == NULL )
293 tloadtile(wall[i].overpicnum);
294 }
295
296 for(i=0;i<numsectors;i++)
297 {
298 if( tiles[sector[i].floorpicnum].data == NULL )
299 tloadtile( sector[i].floorpicnum );
300 if( tiles[sector[i].ceilingpicnum].data == NULL )
301 {
302 tloadtile( sector[i].ceilingpicnum );
303 if( tiles[sector[i].ceilingpicnum].data == (uint8_t*)LA)
304 {
305 tloadtile(LA+1);
306 tloadtile(LA+2);
307 }
308 }
309
310 j = headspritesect[i];
311 while(j >= 0)
312 {
313 if(sprite[j].xrepeat != 0 && sprite[j].yrepeat != 0 && (sprite[j].cstat&32768) == 0)
314 if(tiles[sprite[j].picnum].data == NULL)
315 cachespritenum(j);
316 j = nextspritesect[j];
317 }
318 }
319
320}
321
322void docacheit(void)
323{
324 int32_t i,j;
325
326 j = 0;
327
328 for(i=0;i<MAXTILES;i++)
329 if( (gotpic[i>>3]&(1<<(i&7))) && tiles[i].data == NULL)
330 {
331 loadtile((short)i);
332 j++;
333 if((j&7) == 0) getpackets();
334 }
335
336 clearbufbyte(gotpic,sizeof(gotpic),0L);
337
338}
339
340
341
342void xyzmirror(short i,short tileId)
343{
344 if (tiles[tileId].data == NULL)
345 loadtile(tileId);
346
347 setviewtotile(tileId,tiles[tileId].dim.height,tiles[tileId].dim.width);
348
349 drawrooms(SX,SY,SZ,SA,100+sprite[i].shade,SECT);
350 display_mirror = 1; animatesprites(SX,SY,SA,65536L); display_mirror = 0;
351 drawmasks();
352
353 setviewback();
354 squarerotatetile(tileId);
355}
356
357void vscrn(void)
358{
359 int32_t ss, x1, x2, y1, y2;
360
361 if(ud.screen_size < 0) ud.screen_size = 0;
362 else if(ud.screen_size > 63) ud.screen_size = 64;
363
364 if(ud.screen_size == 0)
365 flushperms();
366
367 ss = max(ud.screen_size-8,0);
368
369 x1 = scale(ss,xdim,160);
370 x2 = xdim-x1;
371
372 y1 = ss; y2 = 200;
373 y1 += countfragbars();
374
375 if (ud.screen_size >= 8)
376 y2 -= (ss+34);
377
378 y1 = scale(y1,ydim,200);
379 y2 = scale(y2,ydim,200);
380
381 setview(x1,y1,x2-1,y2-1);
382
383 pub = NUMPAGES;
384 pus = NUMPAGES;
385}
386
387int countfragbars(void)
388{
389 int32_t i, j, y = 0;
390
391 if ( ud.screen_size > 0 && ud.coop != 1 && ud.multimode > 1)
392 {
393 j = 0;
394 for(i=connecthead;i>=0;i=connectpoint2[i])
395 if(i > j) j = i;
396
397 if (j >= 1) y += 8;
398 if (j >= 4) y += 8;
399 if (j >= 8) y += 8;
400 if (j >= 12) y += 8;
401 }
402
403 return(y);
404}
405
406
407void pickrandomspot(short snum)
408{
409 struct player_struct *p;
410 short i;
411
412 p = &ps[snum];
413
414 if( ud.multimode > 1 && ud.coop != 1)
415 i = TRAND%numplayersprites;
416 else i = snum;
417
418 p->bobposx = p->oposx = p->posx = po[i].ox;
419 p->bobposy = p->oposy = p->posy = po[i].oy;
420 p->oposz = p->posz = po[i].oz;
421 p->ang = po[i].oa;
422 p->cursectnum = po[i].os;
423}
424
425void resetplayerstats(short snum)
426{
427 struct player_struct *p;
428
429 p = &ps[snum];
430
431 ud.show_help = 0;
432 ud.showallmap = 0;
433 p->dead_flag = 0;
434 p->wackedbyactor = -1;
435 p->falling_counter = 0;
436 p->quick_kick = 0;
437 p->subweapon = 0;
438 p->last_full_weapon = 0;
439 p->ftq = 0;
440 p->fta = 0;
441 p->tipincs = 0;
442 p->buttonpalette = 0;
443 p->actorsqu =-1;
444 p->invdisptime = 0;
445 p->refresh_inventory= 0;
446 p->last_pissed_time = 0;
447 p->holster_weapon = 0;
448 p->pycount = 0;
449 p->pyoff = 0;
450 p->opyoff = 0;
451 p->loogcnt = 0;
452 p->angvel = 0;
453 p->weapon_sway = 0;
454// p->select_dir = 0;
455 p->extra_extra8 = 0;
456 p->show_empty_weapon= 0;
457 p->dummyplayersprite=-1;
458 p->crack_time = 0;
459 p->hbomb_hold_delay = 0;
460 p->transporter_hold = 0;
461 p->wantweaponfire = -1;
462 p->hurt_delay = 0;
463 p->footprintcount = 0;
464 p->footprintpal = 0;
465 p->footprintshade = 0;
466 p->jumping_toggle = 0;
467 p->ohoriz = p->horiz= 140;
468 p->horizoff = 0;
469 p->bobcounter = 0;
470 p->on_ground = 0;
471 p->player_par = 0;
472 p->return_to_center = 9;
473 p->airleft = 15*26;
474 p->rapid_fire_hold = 0;
475 p->toggle_key_flag = 0;
476 p->access_spritenum = -1;
477 if(ud.multimode > 1 && ud.coop != 1 )
478 p->got_access = 7;
479 else p->got_access = 0;
480 p->random_club_frame= 0;
481 pus = 1;
482 p->on_warping_sector = 0;
483 p->spritebridge = 0;
484 p->palette = (uint8_t *) &palette[0];
485
486 if(p->steroids_amount < 400 )
487 {
488 p->steroids_amount = 0;
489 p->inven_icon = 0;
490 }
491 p->heat_on = 0;
492 p->jetpack_on = 0;
493 p->holoduke_on = -1;
494
495 p->look_ang = 512 - ((ud.level_number&1)<<10);
496
497 p->rotscrnang = 0;
498 p->newowner =-1;
499 p->jumping_counter = 0;
500 p->hard_landing = 0;
501 p->posxv = 0;
502 p->posyv = 0;
503 p->poszv = 0;
504 fricxv = 0;
505 fricyv = 0;
506 p->somethingonplayer =-1;
507 p->one_eighty_count = 0;
508 p->cheat_phase = 0;
509
510 p->on_crane = -1;
511
512 if(p->curr_weapon == PISTOL_WEAPON)
513 p->kickback_pic = 5;
514 else p->kickback_pic = 0;
515
516 p->weapon_pos = 6;
517 p->walking_snd_toggle= 0;
518 p->weapon_ang = 0;
519
520 p->knuckle_incs = 1;
521 p->fist_incs = 0;
522 p->knee_incs = 0;
523 p->jetpack_on = 0;
524 setpal(p);
525 p->weaponautoswitch = 0;
526 p->auto_aim = 2;
527 p->fakeplayer = 0;
528}
529
530
531
532void resetweapons(short snum)
533{
534 short weapon;
535 struct player_struct *p;
536
537 p = &ps[snum];
538
539 for ( weapon = PISTOL_WEAPON; weapon < MAX_WEAPONS; weapon++ )
540 p->gotweapon[weapon] = 0;
541 for ( weapon = PISTOL_WEAPON; weapon < MAX_WEAPONS; weapon++ )
542 p->ammo_amount[weapon] = 0;
543
544 p->weapon_pos = 6;
545 p->kickback_pic = 5;
546 p->curr_weapon = PISTOL_WEAPON;
547 p->gotweapon[PISTOL_WEAPON] = 1;
548 p->gotweapon[KNEE_WEAPON] = 1;
549 p->ammo_amount[PISTOL_WEAPON] = 48;
550 p->gotweapon[HANDREMOTE_WEAPON] = 1;
551 p->last_weapon = -1;
552
553 p->show_empty_weapon= 0;
554 p->last_pissed_time = 0;
555 p->holster_weapon = 0;
556}
557
558void resetinventory(short snum)
559{
560 struct player_struct *p;
561
562 p = &ps[snum];
563
564 p->inven_icon = 0;
565 p->boot_amount = 0;
566 p->scuba_on = 0;p->scuba_amount = 0;
567 p->heat_amount = 0;p->heat_on = 0;
568 p->jetpack_on = 0;p->jetpack_amount = 0;
569 p->shield_amount = max_armour_amount;
570 p->holoduke_on = -1;
571 p->holoduke_amount = 0;
572 p->firstaid_amount = 0;
573 p->steroids_amount = 0;
574 p->inven_icon = 0;
575}
576
577
578void resetprestat(short snum,uint8_t g)
579{
580 struct player_struct *p;
581 short i;
582
583 p = &ps[snum];
584
585 spriteqloc = 0;
586 for(i=0;i<spriteqamount;i++) spriteq[i] = -1;
587
588 p->hbomb_on = 0;
589 p->cheat_phase = 0;
590 p->pals_time = 0;
591 p->toggle_key_flag = 0;
592 p->secret_rooms = 0;
593 p->max_secret_rooms = 0;
594 p->actors_killed = 0;
595 p->max_actors_killed = 0;
596 p->lastrandomspot = 0;
597 p->weapon_pos = 6;
598 p->kickback_pic = 5;
599 p->last_weapon = -1;
600 p->weapreccnt = 0;
601 p->show_empty_weapon= 0;
602 p->holster_weapon = 0;
603 p->last_pissed_time = 0;
604
605 p->one_parallax_sectnum = -1;
606 p->visibility = ud.const_visibility;
607
608 screenpeek = myconnectindex;
609 numanimwalls = 0;
610 numcyclers = 0;
611 animatecnt = 0;
612 parallaxtype = 0;
613 randomseed = 17L;
614 ud.pause_on = 0;
615 ud.camerasprite =-1;
616 ud.eog = 0;
617 tempwallptr = 0;
618 camsprite =-1;
619 earthquaketime = 0;
620
621 numinterpolations = 0;
622 startofdynamicinterpolations = 0;
623
624 if( ( (g&MODE_EOL) != MODE_EOL && numplayers < 2) || (ud.coop != 1 && numplayers > 1) )
625 {
626 resetweapons(snum);
627 resetinventory(snum);
628 }
629 else if(p->curr_weapon == HANDREMOTE_WEAPON)
630 {
631 p->ammo_amount[HANDBOMB_WEAPON]++;
632 p->curr_weapon = HANDBOMB_WEAPON;
633 }
634
635 p->timebeforeexit = 0;
636 p->customexitsound = 0;
637
638}
639
640void setupbackdrop(short sky)
641{
642 short i;
643
644 for(i=0;i<MAXPSKYTILES;i++) pskyoff[i]=0;
645
646 if(parallaxyscale != 65536L)
647 parallaxyscale = 32768;
648
649 switch(sky)
650 {
651 case CLOUDYOCEAN:
652 parallaxyscale = 65536L;
653 break;
654 case MOONSKY1 :
655 pskyoff[6]=1; pskyoff[1]=2; pskyoff[4]=2; pskyoff[2]=3;
656 break;
657 case BIGORBIT1: // orbit
658 pskyoff[5]=1; pskyoff[6]=2; pskyoff[7]=3; pskyoff[2]=4;
659 break;
660 case LA:
661 parallaxyscale = 16384+1024;
662 pskyoff[0]=1; pskyoff[1]=2; pskyoff[2]=1; pskyoff[3]=3;
663 pskyoff[4]=4; pskyoff[5]=0; pskyoff[6]=2; pskyoff[7]=3;
664 break;
665 }
666
667 pskybits=3;
668}
669
670void prelevel(uint8_t g)
671{
672 short i, nexti, j, startwall, endwall, lotaglist;
673 short lotags[65];
674
675
676 clearbufbyte(show2dsector,sizeof(show2dsector),0L);
677 clearbufbyte(show2dwall,sizeof(show2dwall),0L);
678 clearbufbyte(show2dsprite,sizeof(show2dsprite),0L);
679
680 resetprestat(0,g);
681 numclouds = 0;
682
683 for(i=0;i<numsectors;i++)
684 {
685 sector[i].extra = 256;
686
687 switch(sector[i].lotag)
688 {
689 case 20:
690 case 22:
691 if( sector[i].floorz > sector[i].ceilingz)
692 sector[i].lotag |= 32768;
693 continue;
694 }
695
696 if(sector[i].ceilingstat&1)
697 {
698 if(tiles[sector[i].ceilingpicnum].data == NULL)
699 {
700 if(sector[i].ceilingpicnum == LA)
701 for(j=0;j<5;j++)
702 if(tiles[sector[i].ceilingpicnum+j].data == NULL)
703 tloadtile(sector[i].ceilingpicnum+j);
704 }
705 setupbackdrop(sector[i].ceilingpicnum);
706
707 if(sector[i].ceilingpicnum == CLOUDYSKIES && numclouds < 127)
708 clouds[numclouds++] = i;
709
710 if(ps[0].one_parallax_sectnum == -1)
711 ps[0].one_parallax_sectnum = i;
712 }
713
714 if(sector[i].lotag == 32767) //Found a secret room
715 {
716 ps[0].max_secret_rooms++;
717 continue;
718 }
719
720 if(sector[i].lotag == -1)
721 {
722 ps[0].exitx = wall[sector[i].wallptr].x;
723 ps[0].exity = wall[sector[i].wallptr].y;
724 continue;
725 }
726 }
727
728 i = headspritestat[0];
729 while(i >= 0)
730 {
731 nexti = nextspritestat[i];
732
733 if(sprite[i].lotag == -1 && (sprite[i].cstat&16) )
734 {
735 ps[0].exitx = SX;
736 ps[0].exity = SY;
737 }
738 else switch(PN)
739 {
740 case GPSPEED:
741 sector[SECT].extra = SLT;
742 deletesprite(i);
743 break;
744
745 case CYCLER:
746 if(numcyclers >= MAXCYCLERS)
747 gameexit("\nToo many cycling sectors.");
748 cyclers[numcyclers][0] = SECT;
749 cyclers[numcyclers][1] = SLT;
750 cyclers[numcyclers][2] = SS;
751 cyclers[numcyclers][3] = sector[SECT].floorshade;
752 cyclers[numcyclers][4] = SHT;
753 cyclers[numcyclers][5] = (SA == 1536);
754 numcyclers++;
755 deletesprite(i);
756 break;
757 }
758 i = nexti;
759 }
760
761 for(i=0;i < MAXSPRITES;i++)
762 {
763 if(sprite[i].statnum < MAXSTATUS)
764 {
765 if(PN == SECTOREFFECTOR && SLT == 14)
766 continue;
767 spawn(-1,i);
768 }
769 }
770
771 for(i=0;i < MAXSPRITES;i++)
772 if(sprite[i].statnum < MAXSTATUS)
773 {
774 if( PN == SECTOREFFECTOR && SLT == 14 )
775 spawn(-1,i);
776 }
777
778 lotaglist = 0;
779
780 i = headspritestat[0];
781 while(i >= 0)
782 {
783 switch(PN)
784 {
785 case DIPSWITCH:
786 case DIPSWITCH2:
787 case ACCESSSWITCH:
788 case PULLSWITCH:
789 case HANDSWITCH:
790 case SLOTDOOR:
791 case LIGHTSWITCH:
792 case SPACELIGHTSWITCH:
793 case SPACEDOORSWITCH:
794 case FRANKENSTINESWITCH:
795 case LIGHTSWITCH2:
796 case POWERSWITCH1:
797 case LOCKSWITCH1:
798 case POWERSWITCH2:
799 break;
800 case DIPSWITCH+1:
801 case DIPSWITCH2+1:
802 case PULLSWITCH+1:
803 case HANDSWITCH+1:
804 case SLOTDOOR+1:
805 case LIGHTSWITCH+1:
806 case SPACELIGHTSWITCH+1:
807 case SPACEDOORSWITCH+1:
808 case FRANKENSTINESWITCH+1:
809 case LIGHTSWITCH2+1:
810 case POWERSWITCH1+1:
811 case LOCKSWITCH1+1:
812 case POWERSWITCH2+1:
813 for(j=0;j<lotaglist;j++)
814 if( SLT == lotags[j] )
815 break;
816
817 if( j == lotaglist )
818 {
819 lotags[lotaglist] = SLT;
820 lotaglist++;
821 if(lotaglist > 64)
822 gameexit("\nToo many switches (64 max).");
823
824 j = headspritestat[3];
825 while(j >= 0)
826 {
827 if(sprite[j].lotag == 12 && sprite[j].hitag == SLT)
828 hittype[j].temp_data[0] = 1;
829 j = nextspritestat[j];
830 }
831 }
832 break;
833 }
834 i = nextspritestat[i];
835 }
836
837 mirrorcnt = 0;
838
839 for( i = 0; i < numwalls; i++ )
840 {
841 walltype *wal;
842 wal = &wall[i];
843
844 if(wal->overpicnum == MIRROR && (wal->cstat&32) != 0)
845 {
846 j = wal->nextsector;
847
848 if(mirrorcnt > 63)
849 gameexit("\nToo many mirrors (64 max.)");
850 if ( (j >= 0) && sector[j].ceilingpicnum != MIRROR )
851 {
852 sector[j].ceilingpicnum = MIRROR;
853 sector[j].floorpicnum = MIRROR;
854 mirrorwall[mirrorcnt] = i;
855 mirrorsector[mirrorcnt] = j;
856 mirrorcnt++;
857 continue;
858 }
859 }
860
861 if(numanimwalls >= MAXANIMWALLS)
862 gameexit("\nToo many 'anim' walls (max 512.)");
863
864 animwall[numanimwalls].tag = 0;
865 animwall[numanimwalls].wallnum = 0;
866
867 switch(wal->overpicnum)
868 {
869 case FANSHADOW:
870 case FANSPRITE:
871 wall->cstat |= 65;
872 animwall[numanimwalls].wallnum = i;
873 numanimwalls++;
874 break;
875
876 case W_FORCEFIELD:
877 if(tiles[W_FORCEFIELD].data == NULL)
878 for(j=0;j<3;j++)
879 tloadtile(W_FORCEFIELD+j);
880 case W_FORCEFIELD+1:
881 case W_FORCEFIELD+2:
882 if(wal->shade > 31)
883 wal->cstat = 0;
884 else wal->cstat |= 85+256;
885
886
887 if(wal->lotag && wal->nextwall >= 0)
888 wall[wal->nextwall].lotag =
889 wal->lotag;
890
891 case BIGFORCE:
892
893 animwall[numanimwalls].wallnum = i;
894 numanimwalls++;
895
896 continue;
897 }
898
899 wal->extra = -1;
900
901 switch(wal->picnum)
902 {
903 case WATERTILE2:
904 for(j=0;j<3;j++)
905 if(tiles[wal->picnum+j].data == NULL)
906 tloadtile(wal->picnum+j);
907 break;
908
909 case TECHLIGHT2:
910 case TECHLIGHT4:
911 if(tiles[wal->picnum].data == NULL)
912 tloadtile(wal->picnum);
913 break;
914 case W_TECHWALL1:
915 case W_TECHWALL2:
916 case W_TECHWALL3:
917 case W_TECHWALL4:
918 animwall[numanimwalls].wallnum = i;
919// animwall[numanimwalls].tag = -1;
920 numanimwalls++;
921 break;
922 case SCREENBREAK6:
923 case SCREENBREAK7:
924 case SCREENBREAK8:
925 if(tiles[SCREENBREAK6].data == NULL)
926 for(j=SCREENBREAK6;j<SCREENBREAK9;j++)
927 tloadtile(j);
928 animwall[numanimwalls].wallnum = i;
929 animwall[numanimwalls].tag = -1;
930 numanimwalls++;
931 break;
932
933 case FEMPIC1:
934 case FEMPIC2:
935 case FEMPIC3:
936
937 wal->extra = wal->picnum;
938 animwall[numanimwalls].tag = -1;
939 if(ud.lockout)
940 {
941 if(wal->picnum == FEMPIC1)
942 wal->picnum = BLANKSCREEN;
943 else wal->picnum = SCREENBREAK6;
944 }
945
946 animwall[numanimwalls].wallnum = i;
947 animwall[numanimwalls].tag = wal->picnum;
948 numanimwalls++;
949 break;
950
951 case SCREENBREAK1:
952 case SCREENBREAK2:
953 case SCREENBREAK3:
954 case SCREENBREAK4:
955 case SCREENBREAK5:
956
957 case SCREENBREAK9:
958 case SCREENBREAK10:
959 case SCREENBREAK11:
960 case SCREENBREAK12:
961 case SCREENBREAK13:
962 case SCREENBREAK14:
963 case SCREENBREAK15:
964 case SCREENBREAK16:
965 case SCREENBREAK17:
966 case SCREENBREAK18:
967 case SCREENBREAK19:
968
969 animwall[numanimwalls].wallnum = i;
970 animwall[numanimwalls].tag = wal->picnum;
971 numanimwalls++;
972 break;
973 }
974 }
975
976 //Invalidate textures in sector behind mirror
977 for(i=0;i<mirrorcnt;i++)
978 {
979 startwall = sector[mirrorsector[i]].wallptr;
980 endwall = startwall + sector[mirrorsector[i]].wallnum;
981 for(j=startwall;j<endwall;j++)
982 {
983 wall[j].picnum = MIRROR;
984 wall[j].overpicnum = MIRROR;
985 }
986 }
987}
988
989
990void newgame(uint8_t vn,uint8_t ln,uint8_t sk)
991{
992 struct player_struct *p = &ps[0];
993 short i;
994
995 if(globalskillsound >= 0)
996 while(Sound[globalskillsound].lock>=200) rb->yield();
997 globalskillsound = -1;
998
999 waitforeverybody();
1000 ready2send = 0;
1001
1002 if( ud.m_recstat != 2 && ud.last_level >= 0 && ud.multimode > 1 && ud.coop != 1)
1003 dobonus(1);
1004
1005 if (ud.showcinematics)
1006 if( ln == 0 && vn == 3 && ud.multimode < 2 && ud.lockout == 0)
1007 {
1008 playmusic(&env_music_fn[1][0]);
1009
1010 flushperms();
1011 setview(0,0,xdim-1,ydim-1);
1012 clearview(0L);
1013 nextpage();
1014
1015 playanm("vol41a.anm",6);
1016 clearview(0L);
1017 nextpage();
1018 playanm("vol42a.anm",7);
1019 // clearview(0L);
1020 // nextpage();
1021 playanm("vol43a.anm",9);
1022 clearview(0L);
1023 nextpage();
1024
1025 FX_StopAllSounds();
1026 }
1027
1028 show_shareware = 26*34;
1029
1030 ud.level_number = ln;
1031 ud.volume_number = vn;
1032 ud.player_skill = sk;
1033 ud.secretlevel = 0;
1034 ud.from_bonus = 0;
1035 parallaxyscale = 0;
1036
1037 ud.last_level = -1;
1038 lastsavedpos = -1;
1039 p->zoom = 768;
1040 p->gm = 0;
1041
1042 if(ud.m_coop != 1)
1043 {
1044 p->curr_weapon = PISTOL_WEAPON;
1045 p->gotweapon[PISTOL_WEAPON] = 1;
1046 p->gotweapon[KNEE_WEAPON] = 1;
1047 p->ammo_amount[PISTOL_WEAPON] = 48;
1048 p->gotweapon[HANDREMOTE_WEAPON] = 1;
1049 p->last_weapon = -1;
1050 }
1051
1052 display_mirror = 0;
1053
1054 if(ud.multimode > 1 )
1055 {
1056 if(numplayers < 2)
1057 {
1058 connecthead = 0;
1059 for(i=0;i<MAXPLAYERS;i++) connectpoint2[i] = i+1;
1060 connectpoint2[ud.multimode-1] = -1;
1061 }
1062 }
1063 else
1064 {
1065 connecthead = 0;
1066 connectpoint2[0] = -1;
1067 }
1068}
1069
1070
1071void resetpspritevars(uint8_t g)
1072{
1073 short i, j, nexti; //circ;
1074// int32_t firstx,firsty;
1075 spritetype *s;
1076 uint8_t aimmode[MAXPLAYERS];
1077 STATUSBARTYPE tsbar[MAXPLAYERS];
1078
1079 #define BOT_MAX_NAME 20
1080 int bot_used[BOT_MAX_NAME] = { false };
1081 char *bot_names[] = { "* ELASTI",
1082 "* ^ZookeM^",
1083 "* DOOM",
1084 "* DRO",
1085 "* NOX",
1086 "* EXP",
1087 "* SKIPPY",
1088 "* BRYZIAN",
1089 "* ALI-GUN",
1090 "* ADDFAZ",
1091 "* TURRICAN",
1092 "* PODA",
1093 "* EWOLF",
1094 "* SOULIANE",
1095 "* SPANATOR",
1096 "* OVERLORD",
1097 "* COWBOYUK",
1098 "* JAKS",
1099 "* BLUEDRAG",
1100 "* MOE{GER}"};
1101
1102
1103 EGS(ps[0].cursectnum,ps[0].posx,ps[0].posy,ps[0].posz,
1104 APLAYER,0,0,0,ps[0].ang,0,0,0,10);
1105
1106 if(ud.recstat != 2) for(i=0;i<MAXPLAYERS;i++)
1107 {
1108 aimmode[i] = ps[i].aim_mode;
1109 if(ud.multimode > 1 && ud.coop == 1 && ud.last_level >= 0)
1110 {
1111 for(j=0;j<MAX_WEAPONS;j++)
1112 {
1113 tsbar[i].ammo_amount[j] = ps[i].ammo_amount[j];
1114 tsbar[i].gotweapon[j] = ps[i].gotweapon[j];
1115 }
1116
1117 tsbar[i].shield_amount = ps[i].shield_amount;
1118 tsbar[i].curr_weapon = ps[i].curr_weapon;
1119 tsbar[i].inven_icon = ps[i].inven_icon;
1120
1121 tsbar[i].firstaid_amount = ps[i].firstaid_amount;
1122 tsbar[i].steroids_amount = ps[i].steroids_amount;
1123 tsbar[i].holoduke_amount = ps[i].holoduke_amount;
1124 tsbar[i].jetpack_amount = ps[i].jetpack_amount;
1125 tsbar[i].heat_amount = ps[i].heat_amount;
1126 tsbar[i].scuba_amount = ps[i].scuba_amount;
1127 tsbar[i].boot_amount = ps[i].boot_amount;
1128 }
1129 }
1130
1131 resetplayerstats(0); // reset a player
1132
1133 for(i=1;i<MAXPLAYERS;i++) // reset all the others
1134 memcpy(&ps[i],&ps[0],sizeof(ps[0]));
1135
1136 // FIX_00080: Out Of Synch in demos. Tries recovering OOS in old demos v27/28/29/116/117/118. New: v30/v119.
1137 if(numplayers<2 && !(g&MODE_DEMO))
1138 memcpy(ud.wchoice[0],ud.mywchoice,sizeof(ud.mywchoice));
1139
1140 if(g&MODE_DEMO && (ud.playing_demo_rev == BYTEVERSION_27 ||
1141 ud.playing_demo_rev == BYTEVERSION_28 ||
1142 ud.playing_demo_rev == BYTEVERSION_29 ||
1143 ud.playing_demo_rev == BYTEVERSION_116 ||
1144 ud.playing_demo_rev == BYTEVERSION_117 ||
1145 ud.playing_demo_rev == BYTEVERSION_118 ))
1146 for(i=0; i<ud.multimode; i++)
1147 memcpy(ud.wchoice[i],ud.mywchoice,sizeof(ud.mywchoice)); // assuming.... :-(
1148
1149 // FIX_00076: Added default names for bots + fixed a "killed <name>" bug in Fakeplayers with AI
1150 if(!(g&MODE_DEMO) && numplayers<2 && ud.multimode > 1)
1151 for(i=connecthead;i>=0;i=connectpoint2[i])
1152 if (i!=myconnectindex)
1153 {
1154 memcpy(ud.wchoice[0],ud.mywchoice,sizeof(ud.mywchoice));
1155
1156 // add bot's names
1157 do
1158 {
1159 j = rand()%BOT_MAX_NAME;
1160 }
1161 while(bot_used[j]);
1162
1163 strcpy(ud.user_name[i], bot_names[j]);
1164 bot_used[j] = true;
1165 ps[i].fakeplayer = 1 + ud.playerai; // = true if fakerplayer. (==2 if AI)
1166 }
1167
1168 if(ud.recstat != 2) for(i=0;i<MAXPLAYERS;i++)
1169 {
1170 ps[i].aim_mode = aimmode[i];
1171 if(ud.multimode > 1 && ud.coop == 1 && ud.last_level >= 0)
1172 {
1173 for(j=0;j<MAX_WEAPONS;j++)
1174 {
1175 ps[i].ammo_amount[j] = tsbar[i].ammo_amount[j];
1176 ps[i].gotweapon[j] = tsbar[i].gotweapon[j];
1177 }
1178 ps[i].shield_amount = tsbar[i].shield_amount;
1179 ps[i].curr_weapon = tsbar[i].curr_weapon;
1180 ps[i].inven_icon = tsbar[i].inven_icon;
1181
1182 ps[i].firstaid_amount = tsbar[i].firstaid_amount;
1183 ps[i].steroids_amount= tsbar[i].steroids_amount;
1184 ps[i].holoduke_amount = tsbar[i].holoduke_amount;
1185 ps[i].jetpack_amount = tsbar[i].jetpack_amount;
1186 ps[i].heat_amount = tsbar[i].heat_amount;
1187 ps[i].scuba_amount= tsbar[i].scuba_amount;
1188 ps[i].boot_amount = tsbar[i].boot_amount;
1189 }
1190 }
1191
1192 numplayersprites = 0;
1193// circ = 2048/ud.multimode;
1194
1195 which_palookup = 9;
1196 j = connecthead;
1197 i = headspritestat[10];
1198 while(i >= 0)
1199 {
1200 nexti = nextspritestat[i];
1201 s = &sprite[i];
1202
1203 if( numplayersprites == MAXPLAYERS)
1204 gameexit("\nToo many player sprites (max 16.)");
1205
1206// if(numplayersprites == 0)
1207// {
1208// firstx = ps[0].posx;
1209// firsty = ps[0].posy;
1210// }
1211
1212 po[numplayersprites].ox = s->x;
1213 po[numplayersprites].oy = s->y;
1214 po[numplayersprites].oz = s->z;
1215 po[numplayersprites].oa = s->ang;
1216 po[numplayersprites].os = s->sectnum;
1217
1218 numplayersprites++;
1219 if(j >= 0)
1220 {
1221 s->owner = i;
1222 s->shade = 0;
1223 s->xrepeat = 42;
1224 s->yrepeat = 36;
1225 s->cstat = 1+256;
1226 s->xoffset = 0;
1227 s->clipdist = 64;
1228
1229 if( (g&MODE_EOL) != MODE_EOL || ps[j].last_extra == 0)
1230 {
1231 ps[j].last_extra = max_player_health;
1232 s->extra = max_player_health;
1233 }
1234 else s->extra = ps[j].last_extra;
1235
1236 s->yvel = j;
1237
1238 if(s->pal == 0)
1239 {
1240 s->pal = ps[j].palookup = which_palookup;
1241 which_palookup++;
1242 if( which_palookup >= 17 ) which_palookup = 9;
1243 }
1244 else ps[j].palookup = s->pal;
1245
1246 ps[j].i = i;
1247 ps[j].frag_ps = j;
1248 hittype[i].owner = i;
1249
1250 hittype[i].bposx = ps[j].bobposx = ps[j].oposx = ps[j].posx = s->x;
1251 hittype[i].bposy = ps[j].bobposy = ps[j].oposy = ps[j].posy = s->y;
1252 hittype[i].bposz = ps[j].oposz = ps[j].posz = s->z;
1253 ps[j].oang = ps[j].ang = s->ang;
1254
1255 updatesector(s->x,s->y,&ps[j].cursectnum);
1256
1257 j = connectpoint2[j];
1258
1259 }
1260 else deletesprite(i);
1261 i = nexti;
1262 }
1263}
1264
1265void clearfrags(void)
1266{
1267 short i;
1268
1269 for(i = 0;i<MAXPLAYERS;i++)
1270 ps[i].frag = ps[i].fraggedself = 0;
1271 clearbufbyte(&frags[0][0],(MAXPLAYERS*MAXPLAYERS)<<1,0L);
1272}
1273
1274void resettimevars(void)
1275{
1276 vel = svel = angvel = horiz = 0;
1277
1278 totalclock = 0L;
1279 cloudtotalclock = 0L;
1280 ototalclock = 0L;
1281 lockclock = 0L;
1282 ready2send = 1;
1283}
1284
1285
1286void genspriteremaps(void)
1287{
1288 int32_t j,fp;
1289 int8_t look_pos;
1290 char *lookfn = "lookup.dat";
1291 uint8_t numl;
1292
1293 fp = TCkopen4load(lookfn,0);
1294 if(fp != -1)
1295 kread(fp,(uint8_t *)&numl,1);
1296 else
1297 {
1298 gameexit("\nERROR: File 'LOOKUP.DAT' not found.");
1299 return;
1300 }
1301
1302 for(j=0;j < numl;j++)
1303 {
1304 kread(fp,(int8_t *)&look_pos,1);
1305 kread(fp,tempbuf,256);
1306 makepalookup((int32_t)look_pos,(uint8_t*)tempbuf,0,0,0,1);
1307 }
1308
1309 kread(fp,&waterpal[0],768);
1310 kread(fp,&slimepal[0],768);
1311 kread(fp,&titlepal[0],768);
1312 kread(fp,&drealms[0],768);
1313 kread(fp,&endingpal[0],768);
1314
1315 palette[765] = palette[766] = palette[767] = 0;
1316 slimepal[765] = slimepal[766] = slimepal[767] = 0;
1317 waterpal[765] = waterpal[766] = waterpal[767] = 0;
1318
1319 kclose(fp);
1320}
1321
1322void waitforeverybody()
1323{
1324 int32_t i;
1325
1326 if (numplayers < 2)
1327 {
1328 //printf("numplayers < 2 (num: %d)\n", numplayers);
1329 return;
1330 }
1331#ifdef _DEBUG_NETWORKING_
1332 else
1333 {
1334 printf("numplayers == %d\n", numplayers);
1335 }
1336#endif
1337
1338 printf("waitforeverybody()\n");
1339
1340 packbuf[0] = 250;
1341 for(i=connecthead;i>=0;i=connectpoint2[i])
1342 {
1343
1344 if (i != myconnectindex)
1345 {
1346 sendpacket(i,packbuf,1);
1347 }
1348 }
1349
1350 playerreadyflag[myconnectindex]++;
1351 do
1352 {
1353 _idle(); /* let input queue run... */
1354 getpackets();
1355 for(i=connecthead;i>=0;i=connectpoint2[i])
1356 {
1357 if (playerreadyflag[i] < playerreadyflag[myconnectindex])
1358 {
1359 break;
1360 }
1361 }
1362 } while (i >= 0);
1363
1364}
1365
1366void dofrontscreens(void)
1367{
1368 int32_t i,j;
1369
1370 if(ud.recstat != 2)
1371 {
1372 ps[myconnectindex].palette = palette;
1373 for(j=0;j<63;j+=7) palto(0,0,0,j);
1374 i = ud.screen_size;
1375 ud.screen_size = 0;
1376 vscrn();
1377 clearview(0L);
1378
1379 rotatesprite(320<<15,200<<15,65536L,0,LOADSCREEN,0,0,2+8+64,0,0,xdim-1,ydim-1);
1380
1381 if( boardfilename[0] != 0 && ud.level_number == 7 && ud.volume_number == 0 )
1382 {
1383 menutext(160,90,0,0,"ENTERING USER MAP");
1384 gametextpal(160,90+10,boardfilename,14,2);
1385 }
1386 else
1387 {
1388 menutext(160,90,0,0,"ENTERING");
1389 menutext(160,90+16+8,0,0,level_names[(ud.volume_number*11) + ud.level_number]);
1390 }
1391
1392 nextpage();
1393
1394 for(j=63;j>0;j-=7) palto(0,0,0,j);
1395
1396 KB_FlushKeyboardQueue();
1397 ud.screen_size = i;
1398 }
1399 else
1400 {
1401 clearview(0L);
1402 ps[myconnectindex].palette = palette;
1403 palto(0,0,0,0);
1404 rotatesprite(320<<15,200<<15,65536L,0,LOADSCREEN,0,0,2+8+64,0,0,xdim-1,ydim-1);
1405 menutext(160,105,0,0,"LOADING...");
1406 nextpage();
1407 }
1408}
1409
1410void clearfifo(void)
1411{
1412 syncvaltail = 0L;
1413 syncvaltottail = 0L;
1414 syncstat = 0;
1415 bufferjitter = 1;
1416 mymaxlag = otherminlag = 0;
1417
1418 movefifoplc = movefifosendplc = fakemovefifoplc = 0;
1419 avgfvel = avgsvel = avgavel = avghorz = avgbits = 0;
1420 otherminlag = mymaxlag = 0;
1421
1422 clearbufbyte(myminlag,MAXPLAYERS<<2,0L);
1423 clearbufbyte(&loc,sizeof(input),0L);
1424 clearbufbyte(&sync[0],sizeof(sync),0L);
1425 clearbufbyte(inputfifo,sizeof(input)*MOVEFIFOSIZ*MAXPLAYERS,0L);
1426
1427 clearbuf(movefifoend,MAXPLAYERS,0L);
1428 clearbuf(syncvalhead,MAXPLAYERS,0L);
1429 clearbuf(myminlag,MAXPLAYERS,0L);
1430
1431// clearbufbyte(playerquitflag,MAXPLAYERS,0x01);
1432}
1433
1434void resetmys(void)
1435{
1436 myx = omyx = ps[myconnectindex].posx;
1437 myy = omyy = ps[myconnectindex].posy;
1438 myz = omyz = ps[myconnectindex].posz;
1439 myxvel = myyvel = myzvel = 0;
1440 myang = omyang = ps[myconnectindex].ang;
1441 myhoriz = omyhoriz = ps[myconnectindex].horiz;
1442 myhorizoff = omyhorizoff = ps[myconnectindex].horizoff;
1443 mycursectnum = ps[myconnectindex].cursectnum;
1444 myjumpingcounter = ps[myconnectindex].jumping_counter;
1445 myjumpingtoggle = ps[myconnectindex].jumping_toggle;
1446 myonground = ps[myconnectindex].on_ground;
1447 myhardlanding = ps[myconnectindex].hard_landing;
1448 myreturntocenter = ps[myconnectindex].return_to_center;
1449}
1450
1451void enterlevel(uint8_t g)
1452{
1453 short i;
1454 int32_t l;
1455 char levname[256];
1456 char fulllevelfilename[512];
1457 char text[512];
1458
1459 KB_ClearKeyDown(sc_Pause); // avoid entering in pause mode.
1460
1461 if( (g&MODE_DEMO) != MODE_DEMO ) ud.recstat = ud.m_recstat;
1462 ud.respawn_monsters = ud.m_respawn_monsters;
1463 ud.respawn_items = ud.m_respawn_items;
1464 ud.respawn_inventory = ud.m_respawn_inventory;
1465 ud.monsters_off = ud.m_monsters_off;
1466 ud.coop = ud.m_coop;
1467 ud.marker = ud.m_marker;
1468 ud.ffire = ud.m_ffire;
1469
1470 if( (g&MODE_DEMO) == 0 && ud.recstat == 2)
1471 ud.recstat = 0;
1472
1473 FX_StopAllSounds();
1474 clearsoundlocks();
1475 FX_SetReverb(0);
1476
1477 i = ud.screen_size;
1478 ud.screen_size = 0;
1479 dofrontscreens();
1480 vscrn();
1481 ud.screen_size = i;
1482
1483if (!VOLUMEONE)
1484{
1485
1486 if( boardfilename[0] != 0 && ud.m_level_number == 7 && ud.m_volume_number == 0 )
1487 {
1488 sprintf(fulllevelfilename, "%s\\%s", getGameDir(), boardfilename);
1489 if(!SafeFileExists(fulllevelfilename))
1490 {
1491 sprintf(fulllevelfilename, "%s", boardfilename);
1492 }
1493
1494 if ( loadboard( fulllevelfilename,&ps[0].posx, &ps[0].posy, &ps[0].posz, &ps[0].ang,&ps[0].cursectnum ) == -1 )
1495 {
1496 sprintf(text,"User Map %s not found!\n",fulllevelfilename);
1497 gameexit(text);
1498 }
1499 }
1500 else
1501 {
1502 sprintf(fulllevelfilename, "%s\\%s", getGameDir(), level_file_names[ (ud.volume_number*11)+ud.level_number]);
1503 if(!SafeFileExists(fulllevelfilename))
1504 {
1505 sprintf(fulllevelfilename, "%s", level_file_names[ (ud.volume_number*11)+ud.level_number]);
1506 }
1507 printf("filename=%s\n",fulllevelfilename );
1508 if ( loadboard(fulllevelfilename ,&ps[0].posx, &ps[0].posy, &ps[0].posz, &ps[0].ang,&ps[0].cursectnum ) == -1)
1509 {
1510 sprintf(text,"Internal Map %s not found! Not using the right grp file?\n",level_file_names[(ud.volume_number*11)+ud.level_number]);
1511 gameexit(text);
1512 }
1513 }
1514
1515} else {
1516
1517 l = strlen(level_file_names[ (ud.volume_number*11)+ud.level_number]);
1518 copybufbyte( level_file_names[ (ud.volume_number*11)+ud.level_number],&levname[0],l);
1519 levname[l] = 0;
1520
1521 printf("levname=%s\n",levname );
1522
1523 if ( (ud.volume_number > 1) || loadboard( levname,&ps[0].posx, &ps[0].posy, &ps[0].posz, &ps[0].ang,&ps[0].cursectnum ) == -1)
1524 {
1525 sprintf(text,"Internal Map %s not found in Shareware grp pack!\n",level_file_names[(ud.volume_number*11)+ud.level_number]);
1526 gameexit(text);
1527 }
1528}
1529
1530 clearbufbyte(gotpic,sizeof(gotpic),0L);
1531
1532 prelevel(g);
1533
1534 allignwarpelevators();
1535 resetpspritevars(g);
1536
1537#ifdef CHECK_XDUKE_REV
1538 if((g&MODE_DEMO) != MODE_DEMO ) // don't check for demo
1539 for(i=connecthead;i>=0;i=connectpoint2[i])
1540 {
1541 // all the players must have been validated to have the same rev as we do
1542 if(!ud.rev[i][0] && !ps[i].fakeplayer)
1543 Error(EXIT_SUCCESS, "Your opponent [%s] is using an unknown version of xDuke."
1544 "You are using v%d.%d\n",
1545 ud.user_name[i], CHOCOLATE_DUKE_REV_X, CHOCOLATE_DUKE_REV_DOT_Y);
1546 }
1547#endif
1548
1549
1550 automapping = 0;
1551
1552 if(ud.recstat != 2) MUSIC_StopSong();
1553
1554 cacheit();
1555 docacheit();
1556
1557 if(ud.recstat != 2)
1558 {
1559 music_select = (ud.volume_number*11) + ud.level_number;
1560 playmusic(&music_fn[0][music_select][0]);
1561 }
1562
1563 if( (g&MODE_GAME) || (g&MODE_EOL) )
1564 ps[myconnectindex].gm = MODE_GAME;
1565 else if(g&MODE_RESTART)
1566 {
1567 if(ud.recstat == 2)
1568 ps[myconnectindex].gm = MODE_DEMO;
1569 else ps[myconnectindex].gm = MODE_GAME;
1570 }
1571
1572 if( (ud.recstat == 1) && (g&MODE_RESTART) != MODE_RESTART )
1573 opendemowrite();
1574
1575//if (VOLUMEONE)
1576// if(ud.level_number == 0 && ud.recstat != 2) FTA(40,&ps[myconnectindex]);
1577
1578#ifdef CHECK_XDUKE_REV
1579 sprintf(fta_quotes[103],"Chocolate Duke3D v%d.%d", ud.rev[myconnectindex][2], ud.rev[myconnectindex][3]);
1580 FTA(103,&ps[myconnectindex],1);
1581#endif
1582
1583 if(ud.auto_aim==1 && ud.recstat != 2)
1584 {
1585 sprintf(fta_quotes[103],"Autoaim set to Bullet only");
1586 FTA(103,&ps[myconnectindex],1);
1587 }
1588
1589 if(nHostForceDisableAutoaim && ud.recstat != 2)
1590 {
1591 sprintf(fta_quotes[103],"Autoaim disabled by host");
1592 FTA(103,&ps[myconnectindex],1);
1593 }
1594
1595
1596 for(i=connecthead;i>=0;i=connectpoint2[i])
1597 switch(sector[sprite[ps[i].i].sectnum].floorpicnum)
1598 {
1599 case HURTRAIL:
1600 case FLOORSLIME:
1601 case FLOORPLASMA:
1602 resetweapons(i);
1603 resetinventory(i);
1604 ps[i].gotweapon[PISTOL_WEAPON] = 0;
1605 ps[i].ammo_amount[PISTOL_WEAPON] = 0;
1606 ps[i].curr_weapon = KNEE_WEAPON;
1607 ps[i].kickback_pic = 0;
1608 break;
1609 }
1610
1611 //PREMAP.C - replace near the my's at the end of the file
1612
1613 resetmys();
1614
1615 ps[myconnectindex].palette = palette;
1616 palto(0,0,0,0);
1617
1618 setpal(&ps[myconnectindex]);
1619 flushperms();
1620
1621 everyothertime = 0;
1622 global_random = 0;
1623
1624 ud.last_level = ud.level_number+1;
1625
1626 clearfifo();
1627
1628 for(i=numinterpolations-1;i>=0;i--) bakipos[i] = *curipos[i];
1629
1630 restorepalette = 1;
1631
1632 flushpackets();
1633 waitforeverybody();
1634
1635 palto(0,0,0,0);
1636 vscrn();
1637 clearview(0L);
1638 drawbackground();
1639
1640 clearbufbyte(playerquitflag,MAXPLAYERS,0x01010101);
1641 ps[myconnectindex].over_shoulder_on = 0;
1642
1643 clearfrags();
1644
1645 resettimevars(); // Here we go
1646
1647 if(numplayers > 1)
1648 {
1649 buf[0] = 132; // xDuke TAG ID
1650 buf[1] = mapCRC & 0xFF;
1651 buf[2] = (mapCRC>>8) & 0xFF;
1652
1653 for(i=connecthead;i>=0;i=connectpoint2[i])
1654 if( i != myconnectindex )
1655 sendpacket(i,(uint8_t*)buf,3);
1656 }
1657
1658 ud.mapCRC[myconnectindex] = mapCRC;
1659
1660}
1661
1662/*
1663Duke Nukem V
1664
1665Layout:
1666
1667 Settings:
1668 Suburbs
1669 Duke inflitrating neighborhoods inf. by aliens
1670 Death Valley:
1671 Sorta like a western. Bull-skulls halb buried in the sand
1672 Military compound: Aliens take over nuke-missle silo, duke
1673 must destroy.
1674 Abondend Aircraft field
1675 Vegas:
1676 Blast anything bright! Alien lights camoflauged.
1677 Alien Drug factory. The Blue Liquid
1678 Mountainal Cave:
1679 Interior cave battles.
1680 Jungle:
1681 Trees, canopee, animals, a mysterious hole in the earth
1682 Penetencury:
1683 Good use of spotlights:
1684 Inventory:
1685 Wood,
1686 Metal,
1687 Torch,
1688 Rope,
1689 Plastique,
1690 Cloth,
1691 Wiring,
1692 Glue,
1693 Cigars,
1694 Food,
1695 Duck Tape,
1696 Nails,
1697 Piping,
1698 Petrol,
1699 Uranium,
1700 Gold,
1701 Prism,
1702 Power Cell,
1703
1704 Hand spikes (Limited usage, they become dull)
1705 Oxygent (Oxygen mixed with stimulant)
1706
1707
1708 Player Skills:
1709 R-Left,R-Right,Foward,Back
1710 Strafe, Jump, Double Flip Jump for distance
1711 Help, Escape
1712 Fire/Use
1713 Use Menu
1714
1715Programming:
1716 Images: Polys
1717 Actors:
1718 Multi-Object sections for change (head,arms,legs,torsoe,all change)
1719 Facial expressions. Pal lookup per poly?
1720
1721 struct imagetype
1722 {
1723 int *itable; // AngX,AngY,AngZ,Xoff,Yoff,Zoff;
1724 int *idata;
1725 struct imagetype *prev, *next;
1726 }
1727
1728*/
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/premap.h b/apps/plugins/sdl/progs/duke3d/Game/src/premap.h
new file mode 100644
index 0000000000..89691e1f92
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/premap.h
@@ -0,0 +1,17 @@
1//
2// premap.h
3// Duke3D
4//
5// Created by fabien sanglard on 12-12-17.
6// Copyright (c) 2012 fabien sanglard. All rights reserved.
7//
8
9#ifndef Duke3D_premap_h
10#define Duke3D_premap_h
11
12
13void resetmys(void);
14void docacheit(void);
15void clearfifo(void);
16
17#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/rts.c b/apps/plugins/sdl/progs/duke3d/Game/src/rts.c
new file mode 100644
index 0000000000..3a696c4b58
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/rts.c
@@ -0,0 +1,240 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#include "duke3d.h"
28#include "global.h"
29
30//=============
31// STATICS
32//=============
33
34int32 numlumps;
35static uint8_t **lumpcache;
36static lumpinfo_t *lumpinfo; // location of each lump on disk
37static boolean RTS_Started = false;
38
39uint8_t lumplockbyte[11];
40
41/*
42============================================================================
43
44 LUMP BASED ROUTINES
45
46============================================================================
47*/
48
49/*
50====================
51=
52= RTS_AddFile
53=
54= All files are optional, but at least one file must be found
55= Files with a .rts extension are wadlink files with multiple lumps
56= Other files are single lumps with the base filename for the lump name
57=
58====================
59*/
60
61void RTS_AddFile (char *filename)
62 {
63 wadinfo_t header;
64 lumpinfo_t *lump_p;
65 int32 i;
66 int32 handle, length;
67 int32 startlump;
68 filelump_t *fileinfo;
69
70//
71// read the entire file in
72// FIXME: shared opens
73
74 handle = SafeOpenRead( filename, filetype_binary );
75
76 startlump = numlumps;
77
78 // WAD file
79 printf(" Adding %s.\n",filename);
80 SafeRead( handle, &header, sizeof( header ) );
81 if (strncmp(header.identification,"IWAD",4))
82 Error (EXIT_FAILURE, "RTS file %s doesn't have IWAD id\n",filename);
83 header.numlumps = IntelLong(header.numlumps);
84 header.infotableofs = IntelLong(header.infotableofs);
85 length = header.numlumps*sizeof(filelump_t);
86 fileinfo = alloca (length);
87 if (!fileinfo)
88 Error (EXIT_FAILURE, "RTS file could not allocate header info on stack");
89 lseek (handle, header.infotableofs, SEEK_SET);
90 SafeRead (handle, fileinfo, length);
91 numlumps += header.numlumps;
92
93//
94// Fill in lumpinfo
95//
96 SafeRealloc((void **)&lumpinfo,numlumps*sizeof(lumpinfo_t));
97 lump_p = &lumpinfo[startlump];
98
99 for (i=startlump ; i<numlumps ; i++,lump_p++, fileinfo++)
100 {
101 lump_p->handle = handle;
102 lump_p->position = IntelLong(fileinfo->filepos);
103 lump_p->size = IntelLong(fileinfo->size);
104 strncpy (lump_p->name, fileinfo->name, 8);
105 }
106 }
107
108/*
109====================
110=
111= RTS_Init
112=
113= Files with a .rts extension are idlink files with multiple lumps
114=
115====================
116*/
117
118void RTS_Init (char *filename)
119 {
120 int32 length;
121 //
122 // open all the files, load headers, and count lumps
123 //
124 numlumps = 0;
125 lumpinfo = SafeMalloc(5); // will be realloced as lumps are added
126
127 printf("RTS Manager Started.\n");
128 if (SafeFileExists(filename))
129 RTS_AddFile (filename);
130
131 if (!numlumps) return;
132
133 //
134 // set up caching
135 //
136 length = (numlumps) * sizeof( *lumpcache );
137 lumpcache = SafeMalloc(length);
138 memset(lumpcache,0,length);
139 RTS_Started = true;
140 }
141
142
143/*
144====================
145=
146= RTS_NumSounds
147=
148====================
149*/
150
151int32 RTS_NumSounds (void)
152 {
153 return numlumps-1;
154 }
155
156/*
157====================
158=
159= RTS_SoundLength
160=
161= Returns the buffer size needed to load the given lump
162=
163====================
164*/
165
166int32 RTS_SoundLength (int32 lump)
167 {
168 lump++;
169 if (lump >= numlumps)
170 Error (EXIT_FAILURE, "RTS_SoundLength: %i >= numlumps",lump);
171 return lumpinfo[lump].size;
172 }
173
174/*
175====================
176=
177= RTS_GetSoundName
178=
179====================
180*/
181
182char * RTS_GetSoundName (int32 i)
183 {
184 i++;
185 if (i>=numlumps)
186 Error (EXIT_FAILURE, "RTS_GetSoundName: %i >= numlumps",i);
187 return &(lumpinfo[i].name[0]);
188 }
189
190/*
191====================
192=
193= RTS_ReadLump
194=
195= Loads the lump into the given buffer, which must be >= RTS_SoundLength()
196=
197====================
198*/
199void RTS_ReadLump (int32 lump, void *dest)
200 {
201 lumpinfo_t *l;
202
203 if (lump >= numlumps)
204 Error (EXIT_FAILURE, "RTS_ReadLump: %i >= numlumps",lump);
205 if (lump < 0)
206 Error (EXIT_FAILURE, "RTS_ReadLump: %i < 0",lump);
207 l = lumpinfo+lump;
208 lseek (l->handle, l->position, SEEK_SET);
209 SafeRead(l->handle,dest,l->size);
210 }
211
212/*
213====================
214=
215= RTS_GetSound
216=
217====================
218*/
219void *RTS_GetSound (int32 lump)
220{
221 lump++;
222 if ((uint32)lump >= numlumps)
223 Error (EXIT_FAILURE, "RTS_GetSound: %i >= %i\n",lump,numlumps);
224
225 if (lumpcache[lump] == NULL)
226 {
227 lumplockbyte[lump] = 200;
228 allocache(&lumpcache[lump],(int32_t)RTS_SoundLength(lump-1),&lumplockbyte[lump]);
229 RTS_ReadLump(lump, lumpcache[lump]);
230 }
231 else
232 {
233 if (lumplockbyte[lump] < 200)
234 lumplockbyte[lump] = 200;
235 else
236 lumplockbyte[lump]++;
237 }
238 return lumpcache[lump];
239}
240
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/rts.h b/apps/plugins/sdl/progs/duke3d/Game/src/rts.h
new file mode 100644
index 0000000000..a420663743
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/rts.h
@@ -0,0 +1,84 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27//***************************************************************************
28//
29// RTS.H
30//
31//***************************************************************************
32
33#ifndef __rts_public__
34#define __rts_public__
35
36/*
37====================
38=
39= RTS_Init
40=
41= Files with a .rts extension are idlink files with multiple lumps
42=
43====================
44*/
45
46void RTS_Init (char *filename);
47/*
48====================
49=
50= RTS_NumSounds
51=
52====================
53*/
54
55int32 RTS_NumSounds (void);
56/*
57====================
58=
59= RTS_SoundLength
60=
61= Returns the buffer size needed to load the given lump
62=
63====================
64*/
65
66int32 RTS_SoundLength (int32 lump);
67/*
68====================
69=
70= RTS_GetSoundName
71=
72====================
73*/
74
75char * RTS_GetSoundName (int32 i);
76/*
77====================
78=
79= RTS_GetSound
80=
81====================
82*/
83void *RTS_GetSound (int32 lump);
84#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/scriplib.c b/apps/plugins/sdl/progs/duke3d/Game/src/scriplib.c
new file mode 100644
index 0000000000..2071f8b3cc
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/scriplib.c
@@ -0,0 +1,1065 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#include <assert.h>
28#include <ctype.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32
33#include "duke3d.h"
34#include "scriplib.h"
35
36/* #define DEBUG_SCRIPLIB */
37
38#define MAX_SCRIPTS 5
39
40typedef enum {
41 SCRIPTFLAG_UNKNOWN,
42 SCRIPTFLAG_CATEGORY,
43 SCRIPTFLAG_ONESTRING,
44 SCRIPTFLAG_TWOSTRING,
45 SCRIPTFLAG_HEX,
46 SCRIPTFLAG_DECIMAL,
47 SCRIPTFLAG_FLOAT
48} scriptflag_t;
49
50typedef struct scriptnode_s {
51 struct scriptnode_s *child;
52 struct scriptnode_s *sibling;
53 char *key;
54 scriptflag_t type;
55 union {
56 char *string[2];
57 int number;
58 float floatnumber;
59 } data;
60} scriptnode_t;
61
62static int script_nexthandle = 0;
63static int script_numscriptsopen = 0;
64
65static scriptnode_t *script_headnode[MAX_SCRIPTS];
66
67/* Utility functions */
68static scriptnode_t *SCRIPT_constructnode (void)
69{
70 scriptnode_t *s;
71
72 s = (scriptnode_t *) malloc (sizeof (scriptnode_t));
73 if (s != NULL)
74 {
75 s->child = NULL;
76 s->sibling = NULL;
77 s->key = NULL;
78 s->data.string[0] = NULL;
79 s->data.string[1] = NULL;
80 s->type = SCRIPTFLAG_UNKNOWN;
81 }
82 return s;
83}
84
85static void SCRIPT_freenode (scriptnode_t *node)
86{
87 assert (node != NULL);
88
89 if (node->type == SCRIPTFLAG_ONESTRING) {
90 free (node->data.string[0]);
91 } else if (node->type == SCRIPTFLAG_TWOSTRING) {
92 free (node->data.string[0]);
93 free (node->data.string[1]);
94 }
95
96 free (node->key);
97 free (node->sibling);
98 free (node->child);
99 free (node);
100}
101
102static void SCRIPT_writenode (scriptnode_t *node, FILE *fp)
103{
104 switch (node->type)
105 {
106 case SCRIPTFLAG_UNKNOWN:
107 return;
108 break;
109 case SCRIPTFLAG_CATEGORY:
110 fprintf (fp, "\n[%s]\n", node->key);
111 break;
112 case SCRIPTFLAG_ONESTRING:
113 fprintf (fp, "%s = \"%s\"\n", node->key, node->data.string[0]);
114 break;
115 case SCRIPTFLAG_TWOSTRING:
116 fprintf (fp, "%s = \"%s\" \"%s\"\n", node->key, node->data.string[0], node->data.string[1]);
117 break;
118 case SCRIPTFLAG_HEX:
119 fprintf (fp, "%s = 0x%X\n", node->key, node->data.number);
120 break;
121 case SCRIPTFLAG_DECIMAL:
122 fprintf (fp, "%s = %d\n", node->key, node->data.number);
123 break;
124 case SCRIPTFLAG_FLOAT:
125 fprintf (fp, "%s = %ff\n", node->key, node->data.floatnumber);
126 break;
127 }
128}
129
130static void SCRIPT_recursivewrite (scriptnode_t *node, FILE *fp)
131{
132 if (node == NULL) return;
133
134 SCRIPT_writenode (node, fp);
135
136 /* Free dependant nodes first */
137 if (node->child) {
138 SCRIPT_recursivewrite (node->child, fp);
139 }
140
141 if (node->sibling) {
142 SCRIPT_recursivewrite (node->sibling, fp);
143 }
144}
145
146static void SCRIPT_recursivefree (scriptnode_t *node)
147{
148 assert (node != NULL);
149
150 /* Free dependant nodes first */
151 if (node->child) {
152 SCRIPT_recursivefree (node->child);
153 node->child = NULL;
154 }
155
156 if (node->sibling) {
157 SCRIPT_recursivefree (node->sibling);
158 node->sibling = NULL;
159 }
160
161 SCRIPT_freenode (node);
162 node = NULL;
163}
164
165static void SCRIPT_addsibling (scriptnode_t *node, scriptnode_t *sibling)
166{
167 assert (node != NULL);
168 assert (sibling != NULL);
169
170 /* printf ("addsib: %p, %p, %p\n", node, node->sibling, sibling); */
171
172 if (node->sibling == NULL) {
173 node->sibling = sibling;
174 } else {
175 SCRIPT_addsibling (node->sibling, sibling);
176 }
177}
178
179static void SCRIPT_addchild (scriptnode_t *parent, scriptnode_t *child)
180{
181 assert (parent != NULL);
182 assert (child != NULL);
183
184 if (parent->child == NULL) {
185 parent->child = child;
186 } else {
187 SCRIPT_addsibling (parent->child, child);
188 }
189}
190
191static char *SCRIPT_copystring (char * s)
192{
193 char *ret;
194
195 ret = (char *) malloc (strlen (s)+1);
196 if (ret != NULL)
197 {
198 strcpy (ret, s);
199 }
200 return ret;
201}
202
203static int SCRIPT_getnexttoken (char *buffer, char * token, int start)
204{
205 int iterator = start;
206
207 if (buffer[start] == '\0') {
208 token[0] = '\0';
209 return start;
210 }
211
212 while (iterator < 128 && !isspace (buffer[iterator]))
213 {
214 token[iterator-start] = buffer[iterator];
215 iterator++;
216 }
217
218 token[iterator-start] = '\0';
219
220 /* Trim off any extra whitespace */
221 while (iterator < 127 && isspace(buffer[iterator+1]))
222 iterator++;
223
224 return ++iterator;
225}
226
227/* Fills in a scriptnode with the interpreted contents of a line */
228static void SCRIPT_parseline (char *curline, scriptnode_t *node)
229{
230 char token[128];
231 int i;
232
233 /* Needs to handle 5 cases: */
234 /* key = someint */
235 /* key = 0xsomehexnum */
236 /* key = ~ */
237 /* key = "onestring" */
238 /* key = "two" "strings" */
239
240 assert (node != NULL);
241 assert (curline != NULL);
242
243 i = SCRIPT_getnexttoken (curline, token, 0);
244 node->key = SCRIPT_copystring (token);
245
246 i = SCRIPT_getnexttoken (curline, token, i);
247 /* Sanity check... this token should be "=" */
248 if (strcmp (token, "=")) {
249 /* Error state, free the memory allocated */
250 SCRIPT_recursivefree (node);
251 return;
252 }
253
254 /* This is where the real fun begins... */
255 /* we can begin to determine which of the 6 */
256 /* possibilities the node is now */
257 i = SCRIPT_getnexttoken (curline, token, i);
258
259 if (!strncmp (token, "0x", 2)) {
260 /* Found a hex digit! */
261 node->type = SCRIPTFLAG_HEX;
262 node->data.number = strtol (token, NULL, 16);
263 }else if (token[strlen(token) - 1] == 'f') {
264 /* Found a float */
265 node->type = SCRIPTFLAG_FLOAT;
266 node->data.floatnumber = atof(token);
267 }else if (isdigit (token[0])) {
268 /* Found a number! */
269 node->type = SCRIPTFLAG_DECIMAL;
270 node->data.number = atoi (token);
271 }else if (token[0] == '-' && isdigit (token[1])) {
272 /* Found a negative number! */
273 node->type = SCRIPTFLAG_DECIMAL;
274 node->data.number = atoi (token);
275 //- FIX_00067: *.cfg parser fails to read negative values (as it could be for the Midi selection)
276 // was node->data.number = 0; Can't find a reason for this.
277 }else if (token[0] == '~') {
278 /* Found a ... who knows */
279 node->type = SCRIPTFLAG_DECIMAL;
280 node->data.number = -1;
281 }else if (token[0] == '"') {
282 char workbuf[128];
283 int r;
284
285 /* Found one of possibly two strings */
286 strcpy (workbuf, token);
287 while (token != NULL && workbuf[strlen(workbuf)-1] != '"')
288 {
289 i = SCRIPT_getnexttoken (curline, token, i);
290 strcat (workbuf, " ");
291 strcat (workbuf, token);
292 }
293 //r = sscanf(workbuf, "\"%[^\"]\"", workbuf);
294 //if (r == 0) workbuf[0] = '\0';
295
296 node->type = SCRIPTFLAG_ONESTRING;
297 node->data.string[0] = SCRIPT_copystring (workbuf + 1); /* discard " */
298 node->data.string[0][strlen(workbuf) - 2] = '\0'; /* other " */
299 /* Check for a second string */
300 i = SCRIPT_getnexttoken (curline, token, i);
301 if (token[0] == '"') {
302 strcpy (workbuf, token);
303 while (token != NULL && workbuf[strlen(workbuf)-1] != '"')
304 {
305 i = SCRIPT_getnexttoken (curline, token, i);
306 strcat (workbuf, " ");
307 strcat (workbuf, token);
308 }
309 //r = sscanf(workbuf, "\"%[^\"]\"", workbuf);
310 //if (r == 0) workbuf[0] = '\0';
311
312 node->type = SCRIPTFLAG_TWOSTRING;
313 node->data.string[1] = SCRIPT_copystring (workbuf + 1);
314 node->data.string[1][strlen(workbuf) - 2] = '\0'; /* other " */
315 }
316 } else {
317 /* Error state! */
318 SCRIPT_recursivefree (node);
319 }
320}
321
322static scriptnode_t *SCRIPT_findinchildren (scriptnode_t *parent, char *s)
323{
324 scriptnode_t *cur = parent;
325
326 if (cur == NULL) return NULL;
327 cur = cur->child;
328 if (cur == NULL) return NULL;
329 while (cur != NULL)
330 {
331 if (!strcmp(cur->key, s))
332 break;
333 cur = cur->sibling;
334 }
335
336 return cur;
337}
338
339/*
340==============
341=
342= SCRIPT_Init
343=
344==============
345*/
346int32 SCRIPT_Init( uint8_t * name )
347{
348 STUBBED("Init");
349
350 return -1;
351}
352
353
354/*
355==============
356=
357= SCRIPT_Free
358=
359==============
360*/
361void SCRIPT_Free( int32 scripthandle )
362{
363 /* STUBBED("Free"); */
364 if (scripthandle == -1) return;
365
366 SCRIPT_recursivefree (script_headnode[scripthandle]);
367 script_numscriptsopen--;
368}
369
370
371/*
372==============
373=
374= SCRIPT_Parse
375=
376==============
377*/
378
379int32 SCRIPT_Parse ( uint8_t *data, int32 length, char * name )
380{
381 STUBBED("Parse");
382
383 return -1;
384}
385
386
387/*
388==============
389=
390= SCRIPT_Load
391=
392==============
393*/
394
395int32 SCRIPT_Load ( char * filename )
396{
397 FILE *fp;
398 char curline[128];
399 scriptnode_t *headnode = NULL;
400 scriptnode_t *cur_subsection = NULL;
401
402 if (script_numscriptsopen == MAX_SCRIPTS) return -1;
403
404 /* The main program does not check for any sort of */
405 /* error in loading, so each SCRIPT_ function needs */
406 /* to check if the handle is -1 before doing anything */
407 fp = fopen (filename, "r");
408
409 if (fp == NULL) return -1;
410
411 /* Start loading the script */
412 /* Loads and parse the entire file into a tree */
413 script_numscriptsopen++;
414
415 /* script_nexthandle is the current handle until we increment it */
416 script_headnode[script_nexthandle] = SCRIPT_constructnode ();
417 headnode = script_headnode[script_nexthandle];
418
419 memset (curline, 0, 128);
420 while (fgets (curline, 128, fp))
421 {
422 /* Skip comments */
423 if (curline[0] == ';') continue;
424
425 /* Parse line */
426 /* We have two options... it starts with a [, making it */
427 /* a new subsection (child of headnode) or it starts with */
428 /* a letter, making it a child of a subsection. */
429 if (curline[0] == '[')
430 {
431 scriptnode_t *node;
432 int i;
433
434 /* Remove [] manually */
435 for (i = 0; i < 127; i++)
436 curline[i] = curline[i+1];
437 for (i = 127; i >= 0; i--)
438 {
439 if (curline[i] == ']') {
440 curline[i] = '\0';
441 break;
442 } else {
443 curline[i] = '\0';
444 }
445 }
446
447 /* Insert into head */
448 node = SCRIPT_constructnode ();
449 node->type = SCRIPTFLAG_CATEGORY;
450 node->key = SCRIPT_copystring (curline);
451 SCRIPT_addchild (headnode, node);
452 cur_subsection = node;
453 /* printf ("Working in section \"%s\"\n", node->key); */
454 } else if (isalpha (curline[0])) {
455 scriptnode_t *node;
456
457 /* Ignore if not under a subsection */
458 if (cur_subsection == NULL)
459 continue;
460
461 node = SCRIPT_constructnode ();
462
463 /* TODO: Parse line here */
464 SCRIPT_parseline (curline, node);
465 if (node != NULL)
466 {
467 /* printf ("Adding node with key \"%s\"\n", node->key); */
468 SCRIPT_addchild (cur_subsection, node);
469 }
470 }
471 memset (curline, 0, 128);
472 }
473
474 fclose (fp);
475
476 return script_nexthandle++; /* postincrement is important here */
477}
478
479/*
480==============
481=
482= SCRIPT_Save
483=
484==============
485*/
486void SCRIPT_Save (int32 scripthandle, char* filename)
487{
488 LOGF("Script_Save(%s)", filename);
489 FILE *fp;
490 scriptnode_t *head;
491
492 if(scripthandle >= MAX_SCRIPTS || scripthandle < 0)
493 return;
494
495 fp = fopen (filename, "w");
496 if (fp == NULL) { rb->splashf(HZ, "Failed to write %s", filename); return; }
497
498 head = script_headnode[scripthandle];
499 SCRIPT_recursivewrite (head, fp);
500
501 fclose (fp);
502
503}
504
505
506/*
507==============
508=
509= SCRIPT_NumberSections
510=
511==============
512*/
513
514int32 SCRIPT_NumberSections( int32 scripthandle )
515{
516 STUBBED("NumberSections");
517
518 return -1;
519}
520
521/*
522==============
523=
524= SCRIPT_Section
525=
526==============
527*/
528
529uint8_t * SCRIPT_Section( int32 scripthandle, int32 which )
530{
531 STUBBED("Section");
532
533 return NULL;
534}
535
536/*
537==============
538=
539= SCRIPT_NumberEntries
540=
541==============
542*/
543
544int32 SCRIPT_NumberEntries( int32 scripthandle, char * sectionname )
545{
546 scriptnode_t *node = NULL;
547 int32 entries = 0;
548
549 if(scripthandle >= MAX_SCRIPTS || scripthandle < 0)
550 return 0;
551
552 node = script_headnode[scripthandle];
553 node = SCRIPT_findinchildren(node, sectionname);
554 if(!node) return 0;
555
556 for(node=node->child; node ; node=node->sibling)
557 {
558 ++entries;
559 }
560
561 return entries;
562}
563
564
565/*
566==============
567=
568= SCRIPT_Entry
569=
570==============
571*/
572char * SCRIPT_Entry( int32 scripthandle, char * sectionname, int32 which )
573{
574 scriptnode_t *node = NULL;
575 int32 entrynum = 0;
576 char * val = NULL;
577
578 if(scripthandle >= MAX_SCRIPTS || scripthandle < 0)
579 return "";
580
581 node = script_headnode[scripthandle];
582 node = SCRIPT_findinchildren(node,sectionname);
583 if(!node) return "";
584
585 for(node=node->child; node ; node=node->sibling, ++entrynum)
586 {
587 if(entrynum == which)
588 {
589 val = node->key;
590 break;
591 }
592 }
593
594 return val;
595}
596
597
598/*
599==============
600=
601= SCRIPT_GetRaw
602=
603==============
604*/
605char * SCRIPT_GetRaw(int32 scripthandle, char * sectionname, char * entryname)
606{
607 STUBBED("GetRaw");
608
609 return NULL;
610}
611
612/*
613==============
614=
615= SCRIPT_GetString
616=
617==============
618*/
619void SCRIPT_GetString
620 (
621 int32 scripthandle,
622 char * sectionname,
623 char * entryname,
624 char * dest
625 )
626{
627 scriptnode_t *cur;
628
629 /* STUBBED("GetString"); */
630 if (scripthandle == -1) return;
631
632 cur = script_headnode[scripthandle];
633
634 cur = SCRIPT_findinchildren (cur, sectionname);
635 cur = SCRIPT_findinchildren (cur, entryname);
636
637 if (cur != NULL && cur->type == SCRIPTFLAG_ONESTRING)
638 {
639 strcpy (dest, cur->data.string[0]);
640#ifdef DEBUG_SCRIPLIB
641 printf ("GetString: value for %s:%s is %s\n", sectionname, entryname, dest);
642#endif
643 }
644}
645
646/*
647==============
648=
649= SCRIPT_GetDoubleString
650=
651==============
652*/
653void SCRIPT_GetDoubleString
654 (
655 int32 scripthandle,
656 char * sectionname,
657 char * entryname,
658 char * dest1,
659 char * dest2
660 )
661{
662 scriptnode_t *cur;
663
664 /* STUBBED("GetDoubleString"); */
665 if (scripthandle == -1) return;
666
667 cur = script_headnode[scripthandle];
668
669 cur = SCRIPT_findinchildren (cur, sectionname);
670 cur = SCRIPT_findinchildren (cur, entryname);
671
672 if (cur != NULL && cur->type == SCRIPTFLAG_TWOSTRING)
673 {
674 strcpy (dest1, cur->data.string[0]);
675 strcpy (dest2, cur->data.string[1]);
676#ifdef DEBUG_SCRIPLIB
677 printf ("GetDoubleString: value for %s:%s is %s %s\n", sectionname, entryname, dest1, dest2);
678#endif
679 }
680}
681
682/*
683==============
684=
685= SCRIPT_GetNumber
686=
687==============
688*/
689boolean SCRIPT_GetNumber
690 (
691 int32 scripthandle,
692 char * sectionname,
693 char * entryname,
694 int32 * number
695 )
696{
697 scriptnode_t *cur;
698
699 /* STUBBED("GetNumber"); */
700 if (scripthandle == -1) return false;
701
702 cur = script_headnode[scripthandle];
703
704 cur = SCRIPT_findinchildren (cur, sectionname);
705 cur = SCRIPT_findinchildren (cur, entryname);
706
707 if (cur != NULL && cur->type == SCRIPTFLAG_DECIMAL)
708 {
709 *number = cur->data.number;
710#ifdef DEBUG_SCRIPLIB
711 printf ("GetNumber: value for %s:%s is %ld\n", sectionname, entryname, *number);
712#endif
713 }
714
715 return (cur != NULL) ? true : false;
716}
717
718/*
719==============
720=
721= SCRIPT_GetBoolean
722=
723==============
724*/
725void SCRIPT_GetBoolean
726 (
727 int32 scripthandle,
728 uint8_t * sectionname,
729 uint8_t * entryname,
730 boolean * b
731 )
732{
733 STUBBED("GetBoolean");
734}
735
736
737/*
738==============
739=
740= SCRIPT_GetFloat
741=
742==============
743*/
744boolean SCRIPT_GetFloat
745 (
746 int32 scripthandle,
747 char * sectionname,
748 char * entryname,
749 float * floatnumber
750 )
751{
752 scriptnode_t *cur;
753
754 if (scripthandle == -1) return false;
755
756 cur = script_headnode[scripthandle];
757
758 cur = SCRIPT_findinchildren (cur, sectionname);
759 cur = SCRIPT_findinchildren (cur, entryname);
760
761 if (cur != NULL && cur->type == SCRIPTFLAG_FLOAT)
762 {
763 *floatnumber = cur->data.floatnumber;
764#ifdef DEBUG_SCRIPLIB
765 printf ("GetFloat: value for %s:%s is %f\n", sectionname, entryname, *number);
766#endif
767 }
768
769 return (cur != NULL) ? true : false;
770}
771
772
773/*
774==============
775=
776= SCRIPT_GetDouble
777=
778==============
779*/
780
781void SCRIPT_GetDouble
782 (
783 int32 scripthandle,
784 char * sectionname,
785 char * entryname,
786 double * number
787 )
788{
789 STUBBED("GetDouble");
790}
791
792
793
794/*
795==============
796=
797= SCRIPT_PutComment
798=
799==============
800*/
801void SCRIPT_PutComment( int32 scripthandle, uint8_t * sectionname, uint8_t * comment )
802{
803 STUBBED("PutComment");
804}
805
806/*
807==============
808=
809= SCRIPT_PutEOL
810=
811==============
812*/
813void SCRIPT_PutEOL( int32 scripthandle, uint8_t * sectionname )
814{
815 STUBBED("PutEOL");
816}
817
818/*
819==============
820=
821= SCRIPT_PutMultiComment
822=
823==============
824*/
825void SCRIPT_PutMultiComment
826 (
827 int32 scripthandle,
828 uint8_t * sectionname,
829 uint8_t * comment,
830 ...
831 )
832{
833 STUBBED("PutMultiComment");
834}
835
836/*
837==============
838=
839= SCRIPT_PutSection
840=
841==============
842*/
843void SCRIPT_PutSection( int32 scripthandle, uint8_t * sectionname )
844{
845 STUBBED("PutSection");
846}
847
848/*
849==============
850=
851= SCRIPT_PutRaw
852=
853==============
854*/
855void SCRIPT_PutRaw
856 (
857 int32 scripthandle,
858 uint8_t * sectionname,
859 uint8_t * entryname,
860 uint8_t * raw
861 )
862{
863 STUBBED("PutRaw");
864}
865
866/*
867==============
868=
869= SCRIPT_PutString
870=
871==============
872*/
873void SCRIPT_PutString
874 (
875 int32 scripthandle,
876 char * sectionname,
877 char * entryname,
878 char * string
879 )
880{
881 scriptnode_t *head;
882 scriptnode_t *section;
883 scriptnode_t *node;
884
885 if(scripthandle >= MAX_SCRIPTS || scripthandle < 0)
886 return;
887
888 head = script_headnode[scripthandle];
889
890 /* We're screwed if there's no head */
891 if (head == NULL) return;
892
893 section = SCRIPT_findinchildren (head, sectionname);
894 if (section == NULL)
895 {
896 /* Add the section if it does not exist */
897 section = SCRIPT_constructnode ();
898 section->type = SCRIPTFLAG_CATEGORY;
899 section->key = SCRIPT_copystring (sectionname);
900 SCRIPT_addchild (head, section);
901 }
902
903 node = SCRIPT_findinchildren (section, entryname);
904 if (node == NULL)
905 {
906 /* Add the section if it does not exist */
907 node = SCRIPT_constructnode ();
908 node->type = SCRIPTFLAG_ONESTRING;
909 node->key = SCRIPT_copystring (entryname);
910 SCRIPT_addchild (section, node);
911 } else {
912 free (node->data.string[0]);
913 }
914
915 node->data.string[0] = SCRIPT_copystring (string);
916}
917
918/*
919==============
920=
921= SCRIPT_PutDoubleString
922=
923==============
924*/
925void SCRIPT_PutDoubleString
926 (
927 int32 scripthandle,
928 char * sectionname,
929 char * entryname,
930 char * string1,
931 char * string2
932 )
933{
934 scriptnode_t *head;
935 scriptnode_t *section;
936 scriptnode_t *node;
937
938 if(scripthandle >= MAX_SCRIPTS || scripthandle < 0)
939 return;
940
941 head = script_headnode[scripthandle];
942
943 /* We're screwed if there's no head */
944 if (head == NULL) return;
945
946 section = SCRIPT_findinchildren (head, sectionname);
947 if (section == NULL)
948 {
949 /* Add the section if it does not exist */
950 section = SCRIPT_constructnode ();
951 section->type = SCRIPTFLAG_CATEGORY;
952 section->key = SCRIPT_copystring (sectionname);
953 SCRIPT_addchild (head, section);
954 }
955
956 node = SCRIPT_findinchildren (section, entryname);
957 if (node == NULL)
958 {
959 /* Add the section if it does not exist */
960 node = SCRIPT_constructnode ();
961 node->type = SCRIPTFLAG_TWOSTRING;
962 node->key = SCRIPT_copystring (entryname);
963 SCRIPT_addchild (section, node);
964 } else {
965 free (node->data.string[0]);
966 free (node->data.string[1]);
967 }
968
969 node->data.string[0] = SCRIPT_copystring (string1);
970 node->data.string[1] = SCRIPT_copystring (string2);
971}
972
973/*
974==============
975=
976= SCRIPT_PutNumber
977=
978==============
979*/
980void SCRIPT_PutNumber
981 (
982 int32 scripthandle,
983 char * sectionname,
984 char * entryname,
985 int32 number,
986 boolean hexadecimal,
987 boolean defaultvalue
988 )
989{
990 /* DDOI - I don't know what "defaultvalue" is for so it's ignored */
991 scriptnode_t *head;
992 scriptnode_t *section;
993 scriptnode_t *node;
994
995 if(scripthandle >= MAX_SCRIPTS || scripthandle < 0)
996 return;
997
998 head = script_headnode[scripthandle];
999
1000 /* We're screwed if there's no head */
1001 if (head == NULL) return;
1002
1003 section = SCRIPT_findinchildren (head, sectionname);
1004 if (section == NULL)
1005 {
1006 /* Add the section if it does not exist */
1007 section = SCRIPT_constructnode ();
1008 section->type = SCRIPTFLAG_CATEGORY;
1009 section->key = SCRIPT_copystring (sectionname);
1010 SCRIPT_addchild (head, section);
1011 }
1012
1013 node = SCRIPT_findinchildren (section, entryname);
1014 if (node == NULL)
1015 {
1016 /* Add the section if it does not exist */
1017 node = SCRIPT_constructnode ();
1018 node->key = SCRIPT_copystring (entryname);
1019 SCRIPT_addchild (section, node);
1020 }
1021
1022 if (hexadecimal)
1023 node->type = SCRIPTFLAG_HEX;
1024 else
1025 node->type = SCRIPTFLAG_DECIMAL;
1026 node->data.number = number;
1027}
1028
1029/*
1030==============
1031=
1032= SCRIPT_PutBoolean
1033=
1034==============
1035*/
1036void SCRIPT_PutBoolean
1037 (
1038 int32 scripthandle,
1039 uint8_t * sectionname,
1040 uint8_t * entryname,
1041 boolean b
1042 )
1043{
1044 STUBBED("PutBoolean");
1045}
1046
1047/*
1048==============
1049=
1050= SCRIPT_PutDouble
1051=
1052==============
1053*/
1054
1055void SCRIPT_PutDouble
1056 (
1057 int32 scripthandle,
1058 uint8_t * sectionname,
1059 uint8_t * entryname,
1060 double number,
1061 boolean defaultvalue
1062 )
1063{
1064 STUBBED("PutDouble");
1065}
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/scriplib.h b/apps/plugins/sdl/progs/duke3d/Game/src/scriplib.h
new file mode 100644
index 0000000000..53b6009a90
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/scriplib.h
@@ -0,0 +1,373 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27// scriplib.h
28
29#ifndef _scriplib_public
30#define _scriplib_public
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35#include "types.h"
36/*
37==============
38=
39= SCRIPT_Init
40=
41==============
42*/
43int32 SCRIPT_Init( uint8_t * name );
44
45
46/*
47==============
48=
49= SCRIPT_Free
50=
51==============
52*/
53void SCRIPT_Free( int32 scripthandle );
54
55/*
56==============
57=
58= SCRIPT_Parse
59=
60==============
61*/
62
63int32 SCRIPT_Parse ( uint8_t *data, int32 length, char * name );
64
65
66/*
67==============
68=
69= SCRIPT_Load
70=
71==============
72*/
73
74int32 SCRIPT_Load ( char * filename );
75
76/*
77==============
78=
79= SCRIPT_Save
80=
81==============
82*/
83void SCRIPT_Save (int32 scripthandle, char * filename);
84
85
86/*
87==============
88=
89= SCRIPT_NumberSections
90=
91==============
92*/
93
94int32 SCRIPT_NumberSections( int32 scripthandle );
95
96/*
97==============
98=
99= SCRIPT_Section
100=
101==============
102*/
103
104uint8_t * SCRIPT_Section( int32 scripthandle, int32 which );
105
106/*
107==============
108=
109= SCRIPT_NumberEntries
110=
111==============
112*/
113
114int32 SCRIPT_NumberEntries( int32 scripthandle, char * sectionname );
115
116/*
117==============
118=
119= SCRIPT_Entry
120=
121==============
122*/
123
124char * SCRIPT_Entry( int32 scripthandle, char * sectionname, int32 which );
125
126
127/*
128==============
129=
130= SCRIPT_GetRaw
131=
132==============
133*/
134char * SCRIPT_GetRaw(int32 scripthandle, char * sectionname, char * entryname);
135
136/*
137==============
138=
139= SCRIPT_GetString
140=
141==============
142*/
143void SCRIPT_GetString
144 (
145 int32 scripthandle,
146 char * sectionname,
147 char * entryname,
148 char * dest
149 );
150
151/*
152==============
153=
154= SCRIPT_GetDoubleString
155=
156==============
157*/
158void SCRIPT_GetDoubleString
159 (
160 int32 scripthandle,
161 char * sectionname,
162 char * entryname,
163 char * dest1,
164 char * dest2
165 );
166
167/*
168==============
169=
170= SCRIPT_GetNumber
171=
172==============
173*/
174boolean SCRIPT_GetNumber
175 (
176 int32 scripthandle,
177 char * sectionname,
178 char * entryname,
179 int32 * number
180 );
181
182/*
183==============
184=
185= SCRIPT_GetBoolean
186=
187==============
188*/
189void SCRIPT_GetBoolean
190 (
191 int32 scripthandle,
192 uint8_t * sectionname,
193 uint8_t * entryname,
194 boolean * b
195 );
196
197/*
198==============
199=
200= SCRIPT_GetFloat
201=
202==============
203*/
204
205boolean SCRIPT_GetFloat
206 (
207 int32 scripthandle,
208 char * sectionname,
209 char * entryname,
210 float * floatnumber
211 );
212
213
214/*
215==============
216=
217= SCRIPT_GetDouble
218=
219==============
220*/
221
222void SCRIPT_GetDouble
223 (
224 int32 scripthandle,
225 char * sectionname,
226 char * entryname,
227 double * number
228 );
229
230
231
232/*
233==============
234=
235= SCRIPT_PutComment
236=
237==============
238*/
239void SCRIPT_PutComment( int32 scripthandle, uint8_t * sectionname, uint8_t * comment );
240
241/*
242==============
243=
244= SCRIPT_PutEOL
245=
246==============
247*/
248void SCRIPT_PutEOL( int32 scripthandle, uint8_t * sectionname );
249
250/*
251==============
252=
253= SCRIPT_PutMultiComment
254=
255==============
256*/
257void SCRIPT_PutMultiComment
258 (
259 int32 scripthandle,
260 uint8_t * sectionname,
261 uint8_t * comment,
262 ...
263 );
264
265/*
266==============
267=
268= SCRIPT_PutSection
269=
270==============
271*/
272void SCRIPT_PutSection( int32 scripthandle, uint8_t * sectionname );
273
274/*
275==============
276=
277= SCRIPT_PutRaw
278=
279==============
280*/
281void SCRIPT_PutRaw
282 (
283 int32 scripthandle,
284 uint8_t * sectionname,
285 uint8_t * entryname,
286 uint8_t * raw
287 );
288
289/*
290==============
291=
292= SCRIPT_PutString
293=
294==============
295*/
296void SCRIPT_PutString
297 (
298 int32 scripthandle,
299 char * sectionname,
300 char * entryname,
301 char * string
302 );
303
304/*
305==============
306=
307= SCRIPT_PutDoubleString
308=
309==============
310*/
311void SCRIPT_PutDoubleString
312 (
313 int32 scripthandle,
314 char * sectionname,
315 char * entryname,
316 char * string1,
317 char * string2
318 );
319
320/*
321==============
322=
323= SCRIPT_PutNumber
324=
325==============
326*/
327void SCRIPT_PutNumber
328 (
329 int32 scripthandle,
330 char * sectionname,
331 char * entryname,
332 int32 number,
333 boolean hexadecimal,
334 boolean defaultvalue
335 );
336
337/*
338==============
339=
340= SCRIPT_PutBoolean
341=
342==============
343*/
344void SCRIPT_PutBoolean
345 (
346 int32 scripthandle,
347 uint8_t * sectionname,
348 uint8_t * entryname,
349 boolean b
350 );
351
352/*
353==============
354=
355= SCRIPT_PutDouble
356=
357==============
358*/
359
360void SCRIPT_PutDouble
361 (
362 int32 scripthandle,
363 uint8_t * sectionname,
364 uint8_t * entryname,
365 double number,
366 boolean defaultvalue
367 );
368
369
370#ifdef __cplusplus
371};
372#endif
373#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/sector.c b/apps/plugins/sdl/progs/duke3d/Game/src/sector.c
new file mode 100644
index 0000000000..b15f0eb46b
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/sector.c
@@ -0,0 +1,3249 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#include "duke3d.h"
28
29// PRIMITIVE
30
31
32uint8_t haltsoundhack;
33short callsound(short sn,short whatsprite)
34{
35 short i;
36
37 if(haltsoundhack)
38 {
39 haltsoundhack = 0;
40 return -1;
41 }
42
43 i = headspritesect[sn];
44 while(i >= 0)
45 {
46 if( PN == MUSICANDSFX && SLT < 1000 )
47 {
48 if(whatsprite == -1) whatsprite = i;
49
50 if(T1 == 0)
51 {
52 if( (soundm[SLT]&16) == 0)
53 {
54 if(SLT)
55 {
56 spritesound(SLT,whatsprite);
57 if(SHT && SLT != SHT && SHT < NUM_SOUNDS)
58 stopsound(SHT);
59 }
60
61 if( (sector[SECT].lotag&0xff) != 22)
62 T1 = 1;
63 }
64 }
65 else if(SHT < NUM_SOUNDS)
66 {
67 if(SHT) spritesound(SHT,whatsprite);
68 if( (soundm[SLT]&1) || ( SHT && SHT != SLT ) )
69 stopsound(SLT);
70 T1 = 0;
71 }
72 return SLT;
73 }
74 i = nextspritesect[i];
75 }
76 return -1;
77}
78
79
80short check_activator_motion( short lotag )
81{
82 short i, j;
83 spritetype *s;
84
85 i = headspritestat[8];
86 while ( i >= 0 )
87 {
88 if ( sprite[i].lotag == lotag )
89 {
90 s = &sprite[i];
91
92 for ( j = animatecnt-1; j >= 0; j-- )
93 if ( s->sectnum == animatesect[j] )
94 return( 1 );
95
96 j = headspritestat[3];
97 while ( j >= 0 )
98 {
99 if(s->sectnum == sprite[j].sectnum)
100 switch(sprite[j].lotag)
101 {
102 case 11:
103 case 30:
104 if ( hittype[j].temp_data[4] )
105 return( 1 );
106 break;
107 case 20:
108 case 31:
109 case 32:
110 case 18:
111 if ( hittype[j].temp_data[0] )
112 return( 1 );
113 break;
114 }
115
116 j = nextspritestat[j];
117 }
118 }
119 i = nextspritestat[i];
120 }
121 return( 0 );
122}
123
124uint8_t isadoorwall(short dapic)
125{
126 switch(dapic)
127 {
128 case DOORTILE1:
129 case DOORTILE2:
130 case DOORTILE3:
131 case DOORTILE4:
132 case DOORTILE5:
133 case DOORTILE6:
134 case DOORTILE7:
135 case DOORTILE8:
136 case DOORTILE9:
137 case DOORTILE10:
138 case DOORTILE11:
139 case DOORTILE12:
140 case DOORTILE14:
141 case DOORTILE15:
142 case DOORTILE16:
143 case DOORTILE17:
144 case DOORTILE18:
145 case DOORTILE19:
146 case DOORTILE20:
147 case DOORTILE21:
148 case DOORTILE22:
149 case DOORTILE23:
150 return 1;
151 }
152 return 0;
153}
154
155
156uint8_t isanunderoperator(short lotag)
157{
158 switch(lotag&0xff)
159 {
160 case 15:
161 case 16:
162 case 17:
163 case 18:
164 case 19:
165 case 22:
166 case 26:
167 return 1;
168 }
169 return 0;
170}
171
172uint8_t isanearoperator(short lotag)
173{
174 switch(lotag&0xff)
175 {
176 case 9:
177 case 15:
178 case 16:
179 case 17:
180 case 18:
181 case 19:
182 case 20:
183 case 21:
184 case 22:
185 case 23:
186 case 25:
187 case 26:
188 case 29://Toothed door
189 return 1;
190 }
191 return 0;
192}
193
194short checkcursectnums(short sect)
195{
196 short i;
197 for(i=connecthead;i>=0;i=connectpoint2[i])
198 if( sprite[ps[i].i].sectnum == sect ) return i;
199 return -1;
200}
201
202int32_t ldist(spritetype *s1,spritetype *s2)
203{
204 int32_t vx,vy;
205 vx = s1->x - s2->x;
206 vy = s1->y - s2->y;
207 return(FindDistance2D(vx,vy) + 1);
208}
209
210// Declaration here just to shut down compiler warning:
211// The linker was able to find it :/ regardless !
212int FindDistance3D(int ix, int iy, int iz);
213int32_t dist(spritetype *s1,spritetype *s2)
214{
215 int32_t vx,vy,vz;
216 vx = s1->x - s2->x;
217 vy = s1->y - s2->y;
218 vz = s1->z - s2->z;
219 return(FindDistance3D(vx,vy,vz>>4));
220}
221
222short findplayer(spritetype *s,int32_t *d)
223{
224 short j, closest_player;
225 int32_t x, closest;
226
227 if(ud.multimode < 2)
228 {
229 *d = klabs(ps[myconnectindex].oposx-s->x) + klabs(ps[myconnectindex].oposy-s->y) + ((klabs(ps[myconnectindex].oposz-s->z+(28<<8)))>>4);
230 return myconnectindex;
231 }
232
233 closest = 0x7fffffff;
234 closest_player = 0;
235
236 for(j=connecthead;j>=0;j=connectpoint2[j])
237 {
238 x = klabs(ps[j].oposx-s->x) + klabs(ps[j].oposy-s->y) + ((klabs(ps[j].oposz-s->z+(28<<8)))>>4);
239 if( x < closest && sprite[ps[j].i].extra > 0 )
240 {
241 closest_player = j;
242 closest = x;
243 }
244 }
245
246 *d = closest;
247 return closest_player;
248}
249
250short findotherplayer(short p,int32_t *d)
251{
252 short j, closest_player;
253 int32_t x, closest;
254
255 closest = 0x7fffffff;
256 closest_player = p;
257
258 for(j=connecthead;j>=0;j=connectpoint2[j])
259 if(p != j && sprite[ps[j].i].extra > 0)
260 {
261 x = klabs(ps[j].oposx-ps[p].posx) + klabs(ps[j].oposy-ps[p].posy) + (klabs(ps[j].oposz-ps[p].posz)>>4);
262
263 if( x < closest )
264 {
265 closest_player = j;
266 closest = x;
267 }
268 }
269
270 *d = closest;
271 return closest_player;
272}
273
274
275
276void doanimations(void)
277{
278 int32_t i, j, a, p, v, dasect;
279
280 for(i=animatecnt-1;i>=0;i--)
281 {
282 a = *animateptr[i];
283 v = animatevel[i]*TICSPERFRAME;
284 dasect = animatesect[i];
285
286 if (a == animategoal[i])
287 {
288 stopinterpolation(animateptr[i]);
289
290 animatecnt--;
291 animateptr[i] = animateptr[animatecnt];
292 animategoal[i] = animategoal[animatecnt];
293 animatevel[i] = animatevel[animatecnt];
294 animatesect[i] = animatesect[animatecnt];
295 if( sector[animatesect[i]].lotag == 18 || sector[animatesect[i]].lotag == 19 )
296 if(animateptr[i] == &sector[animatesect[i]].ceilingz)
297 continue;
298
299 if( (sector[dasect].lotag&0xff) != 22 )
300 callsound(dasect,-1);
301
302 continue;
303 }
304
305 if (v > 0) { a = min(a+v,animategoal[i]); }
306 else { a = max(a+v,animategoal[i]); }
307
308 if( animateptr[i] == &sector[animatesect[i]].floorz)
309 {
310 for(p=connecthead;p>=0;p=connectpoint2[p])
311 if (ps[p].cursectnum == dasect)
312 if ((sector[dasect].floorz-ps[p].posz) < (64<<8))
313 if (sprite[ps[p].i].owner >= 0)
314 {
315 ps[p].posz += v;
316 ps[p].poszv = 0;
317 if (p == myconnectindex)
318 {
319 myz += v;
320 myzvel = 0;
321 myzbak[((movefifoplc-1)&(MOVEFIFOSIZ-1))] = ps[p].posz;
322 }
323 }
324
325 for(j=headspritesect[dasect];j>=0;j=nextspritesect[j])
326 if (sprite[j].statnum != 3)
327 {
328 hittype[j].bposz = sprite[j].z;
329 sprite[j].z += v;
330 hittype[j].floorz = sector[dasect].floorz+v;
331 }
332 }
333
334 *animateptr[i] = a;
335 }
336}
337
338int32_t getanimationgoal(int32_t *animptr)
339{
340 int32_t i, j;
341
342 j = -1;
343 for(i=animatecnt-1;i>=0;i--)
344 if (animptr == (int32_t *)animateptr[i])
345 {
346 j = i;
347 break;
348 }
349 return(j);
350}
351
352int32_t setanimation(short animsect,int32_t *animptr, int32_t thegoal, int32_t thevel)
353{
354 int32_t i, j;
355
356 if (animatecnt >= MAXANIMATES-1)
357 return(-1);
358
359 j = animatecnt;
360 for(i=0;i<animatecnt;i++)
361 if (animptr == animateptr[i])
362 {
363 j = i;
364 break;
365 }
366
367 animatesect[j] = animsect;
368 animateptr[j] = animptr;
369 animategoal[j] = thegoal;
370 if (thegoal >= *animptr)
371 animatevel[j] = thevel;
372 else
373 animatevel[j] = -thevel;
374
375 if (j == animatecnt) animatecnt++;
376
377 setinterpolation(animptr);
378
379 return(j);
380}
381
382
383
384
385void animatecamsprite(void)
386{
387 short i;
388
389 if(camsprite <= 0) return;
390
391 i = camsprite;
392
393 if(T1 >= 11)
394 {
395 T1 = 0;
396
397 if(ps[screenpeek].newowner >= 0)
398 OW = ps[screenpeek].newowner;
399
400 else if(OW >= 0 && dist(&sprite[ps[screenpeek].i],&sprite[i]) < 2048)
401 xyzmirror(OW,PN);
402 }
403 else T1++;
404}
405
406void animatewalls(void)
407{
408 int32_t i, j, p, t;
409
410 for(p=0;p < numanimwalls ;p++)
411// for(p=numanimwalls-1;p>=0;p--)
412 {
413 i = animwall[p].wallnum;
414 j = wall[i].picnum;
415
416 switch(j)
417 {
418 case SCREENBREAK1:
419 case SCREENBREAK2:
420 case SCREENBREAK3:
421 case SCREENBREAK4:
422 case SCREENBREAK5:
423
424 case SCREENBREAK9:
425 case SCREENBREAK10:
426 case SCREENBREAK11:
427 case SCREENBREAK12:
428 case SCREENBREAK13:
429 case SCREENBREAK14:
430 case SCREENBREAK15:
431 case SCREENBREAK16:
432 case SCREENBREAK17:
433 case SCREENBREAK18:
434 case SCREENBREAK19:
435
436 if( (TRAND&255) < 16)
437 {
438 animwall[p].tag = wall[i].picnum;
439 wall[i].picnum = SCREENBREAK6;
440 }
441
442 continue;
443
444 case SCREENBREAK6:
445 case SCREENBREAK7:
446 case SCREENBREAK8:
447
448 if(animwall[p].tag >= 0 && wall[i].extra != FEMPIC2 && wall[i].extra != FEMPIC3 )
449 wall[i].picnum = animwall[p].tag;
450 else
451 {
452 wall[i].picnum++;
453 if(wall[i].picnum == (SCREENBREAK6+3) )
454 wall[i].picnum = SCREENBREAK6;
455 }
456 continue;
457
458 }
459
460 if(wall[i].cstat&16)
461 switch(wall[i].overpicnum)
462 {
463 case W_FORCEFIELD:
464 case W_FORCEFIELD+1:
465 case W_FORCEFIELD+2:
466
467 t = animwall[p].tag;
468
469 if(wall[i].cstat&254)
470 {
471 wall[i].xpanning -= t>>10; // sintable[(t+512)&2047]>>12;
472 wall[i].ypanning -= t>>10; // sintable[t&2047]>>12;
473
474 if(wall[i].extra == 1)
475 {
476 wall[i].extra = 0;
477 animwall[p].tag = 0;
478 }
479 else
480 animwall[p].tag+=128;
481
482 if( animwall[p].tag < (128<<4) )
483 {
484 if( animwall[p].tag&128 )
485 wall[i].overpicnum = W_FORCEFIELD;
486 else wall[i].overpicnum = W_FORCEFIELD+1;
487 }
488 else
489 {
490 if( (TRAND&255) < 32 )
491 animwall[p].tag = 128<<(TRAND&3);
492 else wall[i].overpicnum = W_FORCEFIELD+1;
493 }
494 }
495
496 break;
497 }
498 }
499}
500
501uint8_t activatewarpelevators(short s,short d) //Parm = sectoreffectornum
502{
503 short i, sn;
504
505 sn = sprite[s].sectnum;
506
507 // See if the sector exists
508
509 i = headspritestat[3];
510 while(i >= 0)
511 {
512 if( SLT == 17 )
513 if( SHT == sprite[s].hitag )
514 if( (klabs(sector[sn].floorz-hittype[s].temp_data[2]) > SP) ||
515 (sector[SECT].hitag == (sector[sn].hitag-d) ) )
516 break;
517 i = nextspritestat[i];
518 }
519
520 if(i==-1)
521 {
522 d = 0;
523 return 1; // No find
524 }
525 else
526 {
527 if(d == 0)
528 spritesound(ELEVATOR_OFF,s);
529 else spritesound(ELEVATOR_ON,s);
530 }
531
532
533 i = headspritestat[3];
534 while(i >= 0)
535 {
536 if( SLT == 17 )
537 if( SHT == sprite[s].hitag )
538 {
539 T1 = d;
540 T2 = d; //Make all check warp
541 }
542 i = nextspritestat[i];
543 }
544 return 0;
545}
546
547
548
549void operatesectors(short sn,short ii)
550{
551 int32_t j=0, l, q, startwall, endwall;
552 short i;
553// uint8_t sect_error;
554 sectortype *sptr;
555
556// sect_error = 0;
557 sptr = &sector[sn];
558
559 switch(sptr->lotag&(0xffff-49152))
560 {
561
562 case 30:
563 j = sector[sn].hitag;
564 if( hittype[j].tempang == 0 ||
565 hittype[j].tempang == 256)
566 callsound(sn,ii);
567 if(sprite[j].extra == 1)
568 sprite[j].extra = 3;
569 else sprite[j].extra = 1;
570 break;
571
572 case 31:
573
574 j = sector[sn].hitag;
575 if(hittype[j].temp_data[4] == 0)
576 hittype[j].temp_data[4] = 1;
577
578 callsound(sn,ii);
579 break;
580
581 case 26: //The split doors
582 i = getanimationgoal(&sptr->ceilingz);
583 if(i == -1) //if the door has stopped
584 {
585 haltsoundhack = 1;
586 sptr->lotag &= 0xff00;
587 sptr->lotag |= 22;
588 operatesectors(sn,ii);
589 sptr->lotag &= 0xff00;
590 sptr->lotag |= 9;
591 operatesectors(sn,ii);
592 sptr->lotag &= 0xff00;
593 sptr->lotag |= 26;
594 }
595 return;
596
597 case 9:
598 {
599 int32_t dax,day,dax2,day2,sp;
600 int32_t wallfind[2];
601
602 startwall = sptr->wallptr;
603 endwall = startwall+sptr->wallnum-1;
604
605 sp = sptr->extra>>4;
606
607 //first find center point by averaging all points
608 dax = 0L, day = 0L;
609 for(i=startwall;i<=endwall;i++)
610 {
611 dax += wall[i].x;
612 day += wall[i].y;
613 }
614 dax /= (endwall-startwall+1);
615 day /= (endwall-startwall+1);
616
617 //find any points with either same x or same y coordinate
618 // as center (dax, day) - should be 2 points found.
619 wallfind[0] = -1;
620 wallfind[1] = -1;
621 for(i=startwall;i<=endwall;i++)
622 if ((wall[i].x == dax) || (wall[i].y == day))
623 {
624 if (wallfind[0] == -1)
625 wallfind[0] = i;
626 else wallfind[1] = i;
627 }
628
629 for(j=0;j<2;j++)
630 {
631 if ((wall[wallfind[j]].x == dax) && (wall[wallfind[j]].y == day))
632 {
633 //find what direction door should open by averaging the
634 // 2 neighboring points of wallfind[0] & wallfind[1].
635 i = wallfind[j]-1; if (i < startwall) i = endwall;
636 dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x;
637 day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y;
638 if (dax2 != 0)
639 {
640 dax2 = wall[wall[wall[wallfind[j]].point2].point2].x;
641 dax2 -= wall[wall[wallfind[j]].point2].x;
642 setanimation(sn,&wall[wallfind[j]].x,wall[wallfind[j]].x+dax2,sp);
643 setanimation(sn,&wall[i].x,wall[i].x+dax2,sp);
644 setanimation(sn,&wall[wall[wallfind[j]].point2].x,wall[wall[wallfind[j]].point2].x+dax2,sp);
645 callsound(sn,ii);
646 }
647 else if (day2 != 0)
648 {
649 day2 = wall[wall[wall[wallfind[j]].point2].point2].y;
650 day2 -= wall[wall[wallfind[j]].point2].y;
651 setanimation(sn,&wall[wallfind[j]].y,wall[wallfind[j]].y+day2,sp);
652 setanimation(sn,&wall[i].y,wall[i].y+day2,sp);
653 setanimation(sn,&wall[wall[wallfind[j]].point2].y,wall[wall[wallfind[j]].point2].y+day2,sp);
654 callsound(sn,ii);
655 }
656 }
657 else
658 {
659 i = wallfind[j]-1; if (i < startwall) i = endwall;
660 dax2 = ((wall[i].x+wall[wall[wallfind[j]].point2].x)>>1)-wall[wallfind[j]].x;
661 day2 = ((wall[i].y+wall[wall[wallfind[j]].point2].y)>>1)-wall[wallfind[j]].y;
662 if (dax2 != 0)
663 {
664 setanimation(sn,&wall[wallfind[j]].x,dax,sp);
665 setanimation(sn,&wall[i].x,dax+dax2,sp);
666 setanimation(sn,&wall[wall[wallfind[j]].point2].x,dax+dax2,sp);
667 callsound(sn,ii);
668 }
669 else if (day2 != 0)
670 {
671 setanimation(sn,&wall[wallfind[j]].y,day,sp);
672 setanimation(sn,&wall[i].y,day+day2,sp);
673 setanimation(sn,&wall[wall[wallfind[j]].point2].y,day+day2,sp);
674 callsound(sn,ii);
675 }
676 }
677 }
678
679 }
680 return;
681
682 case 15://Warping elevators
683
684 if(sprite[ii].picnum != APLAYER) return;
685// if(ps[sprite[ii].yvel].select_dir == 1) return;
686
687 i = headspritesect[sn];
688 while(i >= 0)
689 {
690 if(PN==SECTOREFFECTOR && SLT == 17 ) break;
691 i = nextspritesect[i];
692 }
693
694 if(sprite[ii].sectnum == sn)
695 {
696 if( activatewarpelevators(i,-1) )
697 activatewarpelevators(i,1);
698 else if( activatewarpelevators(i,1) )
699 activatewarpelevators(i,-1);
700 return;
701 }
702 else
703 {
704 if(sptr->floorz > SZ)
705 activatewarpelevators(i,-1);
706 else
707 activatewarpelevators(i,1);
708 }
709
710 return;
711
712 case 16:
713 case 17:
714
715 i = getanimationgoal(&sptr->floorz);
716
717 if(i == -1)
718 {
719 i = nextsectorneighborz(sn,sptr->floorz,1,1);
720 if( i == -1 )
721 {
722 i = nextsectorneighborz(sn,sptr->floorz,1,-1);
723 if( i == -1 ) return;
724 j = sector[i].floorz;
725 setanimation(sn,&sptr->floorz,j,sptr->extra);
726 }
727 else
728 {
729 j = sector[i].floorz;
730 setanimation(sn,&sptr->floorz,j,sptr->extra);
731 }
732 callsound(sn,ii);
733 }
734
735 return;
736
737 case 18:
738 case 19:
739
740 i = getanimationgoal(&sptr->floorz);
741
742 if(i==-1)
743 {
744 i = nextsectorneighborz(sn,sptr->floorz,1,-1);
745 if(i==-1) i = nextsectorneighborz(sn,sptr->floorz,1,1);
746 if(i==-1) return;
747 j = sector[i].floorz;
748 q = sptr->extra;
749 l = sptr->ceilingz-sptr->floorz;
750 setanimation(sn,&sptr->floorz,j,q);
751 setanimation(sn,&sptr->ceilingz,j+l,q);
752 callsound(sn,ii);
753 }
754 return;
755
756 case 29:
757
758 if(sptr->lotag&0x8000)
759 j = sector[nextsectorneighborz(sn,sptr->ceilingz,1,1)].floorz;
760 else
761 j = sector[nextsectorneighborz(sn,sptr->ceilingz,-1,-1)].ceilingz;
762
763 i = headspritestat[3]; //Effectors
764 while(i >= 0)
765 {
766 if( (SLT == 22) &&
767 (SHT == sptr->hitag) )
768 {
769 sector[SECT].extra = -sector[SECT].extra;
770
771 T1 = sn;
772 T2 = 1;
773 }
774 i = nextspritestat[i];
775 }
776
777 sptr->lotag ^= 0x8000;
778
779 setanimation(sn,&sptr->ceilingz,j,sptr->extra);
780
781 callsound(sn,ii);
782
783 return;
784
785 case 20:
786
787 REDODOOR:
788
789 if(sptr->lotag&0x8000)
790 {
791 i = headspritesect[sn];
792 while(i >= 0)
793 {
794 if(sprite[i].statnum == 3 && SLT==9)
795 {
796 j = SZ;
797 break;
798 }
799 i = nextspritesect[i];
800 }
801 if(i==-1)
802 j = sptr->floorz;
803 }
804 else
805 {
806 j = nextsectorneighborz(sn,sptr->ceilingz,-1,-1);
807
808 if(j >= 0) j = sector[j].ceilingz;
809 else
810 {
811 sptr->lotag |= 32768;
812 goto REDODOOR;
813 }
814 }
815
816 sptr->lotag ^= 0x8000;
817
818 setanimation(sn,&sptr->ceilingz,j,sptr->extra);
819 callsound(sn,ii);
820
821 return;
822
823 case 21:
824 i = getanimationgoal(&sptr->floorz);
825 if (i >= 0)
826 {
827 if (animategoal[sn] == sptr->ceilingz)
828 animategoal[i] = sector[nextsectorneighborz(sn,sptr->ceilingz,1,1)].floorz;
829 else animategoal[i] = sptr->ceilingz;
830 j = animategoal[i];
831 }
832 else
833 {
834 if (sptr->ceilingz == sptr->floorz)
835 j = sector[nextsectorneighborz(sn,sptr->ceilingz,1,1)].floorz;
836 else j = sptr->ceilingz;
837
838 sptr->lotag ^= 0x8000;
839
840 if(setanimation(sn,&sptr->floorz,j,sptr->extra) >= 0)
841 callsound(sn,ii);
842 }
843 return;
844
845 case 22:
846
847 // REDODOOR22:
848
849 if ( (sptr->lotag&0x8000) )
850 {
851 q = (sptr->ceilingz+sptr->floorz)>>1;
852 j = setanimation(sn,&sptr->floorz,q,sptr->extra);
853 j = setanimation(sn,&sptr->ceilingz,q,sptr->extra);
854 }
855 else
856 {
857 q = sector[nextsectorneighborz(sn,sptr->floorz,1,1)].floorz;
858 j = setanimation(sn,&sptr->floorz,q,sptr->extra);
859 q = sector[nextsectorneighborz(sn,sptr->ceilingz,-1,-1)].ceilingz;
860 j = setanimation(sn,&sptr->ceilingz,q,sptr->extra);
861 }
862
863 sptr->lotag ^= 0x8000;
864
865 callsound(sn,ii);
866
867 return;
868
869 case 23: //Swingdoor
870
871 j = -1;
872 q = 0;
873
874 i = headspritestat[3];
875 while(i >= 0)
876 {
877 if( SLT == 11 && SECT == sn && !T5)
878 {
879 j = i;
880 break;
881 }
882 i = nextspritestat[i];
883 }
884
885 //Why would this ever be -1?
886 if(i < 0)
887 {
888 return;
889 }//FIXME: CRASH HERE (the "l = sector[SECT].lotag&0x8000; " code)
890
891 l = sector[SECT].lotag&0x8000;
892
893 if(j >= 0)
894 {
895 i = headspritestat[3];
896 while(i >= 0)
897 {
898 if( l == (sector[SECT].lotag&0x8000) && SLT == 11 && sprite[j].hitag == SHT && !T5 )
899 {
900 if(sector[SECT].lotag&0x8000) sector[SECT].lotag &= 0x7fff;
901 else sector[SECT].lotag |= 0x8000;
902 T5 = 1;
903 T4 = -T4;
904 if(q == 0)
905 {
906 callsound(sn,i);
907 q = 1;
908 }
909 }
910 i = nextspritestat[i];
911 }
912 }
913 return;
914
915 case 25: //Subway type sliding doors
916
917 j = headspritestat[3];
918 while(j >= 0)//Find the sprite
919 {
920 if( (sprite[j].lotag) == 15 && sprite[j].sectnum == sn )
921 break; //Found the sectoreffector.
922 j = nextspritestat[j];
923 }
924
925 if(j < 0)
926 return;
927
928 i = headspritestat[3];
929 while(i >= 0)
930 {
931 if( SHT==sprite[j].hitag )
932 {
933 if( SLT == 15 )
934 {
935 sector[SECT].lotag ^= 0x8000; // Toggle the open or close
936 SA += 1024;
937 if(T5) callsound(SECT,i);
938 callsound(SECT,i);
939 if(sector[SECT].lotag&0x8000) T5 = 1;
940 else T5 = 2;
941 }
942 }
943 i = nextspritestat[i];
944 }
945 return;
946
947 case 27: //Extended bridge
948
949 j = headspritestat[3];
950 while(j >= 0)
951 {
952 if( (sprite[j].lotag&0xff)==20 && sprite[j].sectnum == sn) //Bridge
953 {
954
955 sector[sn].lotag ^= 0x8000;
956 if(sector[sn].lotag&0x8000) //OPENING
957 hittype[j].temp_data[0] = 1;
958 else hittype[j].temp_data[0] = 2;
959 callsound(sn,ii);
960 break;
961 }
962 j = nextspritestat[j];
963 }
964 return;
965
966
967 case 28:
968 //activate the rest of them
969
970 j = headspritesect[sn];
971 while(j >= 0)
972 {
973 if(sprite[j].statnum==3 && (sprite[j].lotag&0xff)==21)
974 break; //Found it
975 j = nextspritesect[j];
976 }
977
978 j = sprite[j].hitag;
979
980 l = headspritestat[3];
981 while(l >= 0)
982 {
983 if( (sprite[l].lotag&0xff)==21 && !hittype[l].temp_data[0] &&
984 (sprite[l].hitag) == j )
985 hittype[l].temp_data[0] = 1;
986 l = nextspritestat[l];
987 }
988 callsound(sn,ii);
989
990 return;
991 }
992}
993
994
995
996void operaterespawns(short low)
997{
998 short i, j, nexti;
999
1000 i = headspritestat[11];
1001 while(i >= 0)
1002 {
1003 nexti = nextspritestat[i];
1004 if(SLT == low) switch(PN)
1005 {
1006 case RESPAWN:
1007 if( badguypic(SHT) && ud.monsters_off ) break;
1008
1009 j = spawn(i,TRANSPORTERSTAR);
1010 sprite[j].z -= (32<<8);
1011
1012 sprite[i].extra = 66-12; // Just a way to killit
1013 break;
1014 }
1015 i = nexti;
1016 }
1017}
1018
1019void operateactivators(short low,short snum)
1020{
1021 short i, j, k, *p;
1022 walltype *wal;
1023
1024 for(i=numcyclers-1;i>=0;i--)
1025 {
1026 p = &cyclers[i][0];
1027
1028 if(p[4] == low)
1029 {
1030 p[5] = !p[5];
1031
1032 sector[p[0]].floorshade = sector[p[0]].ceilingshade = p[3];
1033 wal = &wall[sector[p[0]].wallptr];
1034 for(j=sector[p[0]].wallnum;j > 0;j--,wal++)
1035 wal->shade = p[3];
1036 }
1037 }
1038
1039 i = headspritestat[8];
1040 k = -1;
1041 while(i >= 0)
1042 {
1043 if(sprite[i].lotag == low)
1044 {
1045 if( sprite[i].picnum == ACTIVATORLOCKED )
1046 {
1047 if(sector[SECT].lotag&16384)
1048 sector[SECT].lotag &= 65535-16384;
1049 else
1050 sector[SECT].lotag |= 16384;
1051
1052 if(snum >= 0)
1053 {
1054 if(sector[SECT].lotag&16384)
1055 FTA(4,&ps[snum],0);
1056 else FTA(8,&ps[snum],0);
1057 }
1058 }
1059 else
1060 {
1061 switch(SHT)
1062 {
1063 case 0:
1064 break;
1065 case 1:
1066 if(sector[SECT].floorz != sector[SECT].ceilingz)
1067 {
1068 i = nextspritestat[i];
1069 continue;
1070 }
1071 break;
1072 case 2:
1073 if(sector[SECT].floorz == sector[SECT].ceilingz)
1074 {
1075 i = nextspritestat[i];
1076 continue;
1077 }
1078 break;
1079 }
1080
1081 if( sector[sprite[i].sectnum].lotag < 3 )
1082 {
1083 j = headspritesect[sprite[i].sectnum];
1084 while(j >= 0)
1085 {
1086 if( sprite[j].statnum == 3 ) switch(sprite[j].lotag)
1087 {
1088 case 36:
1089 case 31:
1090 case 32:
1091 case 18:
1092 hittype[j].temp_data[0] = 1-hittype[j].temp_data[0];
1093 callsound(SECT,j);
1094 break;
1095 }
1096 j = nextspritesect[j];
1097 }
1098 }
1099
1100 if( k == -1 && (sector[SECT].lotag&0xff) == 22 )
1101 k = callsound(SECT,i);
1102
1103 operatesectors(SECT,i);
1104 }
1105 }
1106 i = nextspritestat[i];
1107 }
1108
1109 operaterespawns(low);
1110}
1111
1112void operatemasterswitches(short low)
1113{
1114 short i;
1115
1116 i = headspritestat[6];
1117 while(i >= 0)
1118 {
1119 if( PN == MASTERSWITCH && SLT == low && SP == 0 )
1120 SP = 1;
1121 i = nextspritestat[i];
1122 }
1123}
1124
1125
1126
1127void operateforcefields(short s, short low)
1128{
1129 short i, p;
1130
1131 for(p=numanimwalls;p>=0;p--)
1132 {
1133 i = animwall[p].wallnum;
1134
1135 if(low == wall[i].lotag || low == -1)
1136 switch(wall[i].overpicnum)
1137 {
1138 case W_FORCEFIELD :
1139 case W_FORCEFIELD+1:
1140 case W_FORCEFIELD+2:
1141 case BIGFORCE:
1142
1143 animwall[p].tag = 0;
1144
1145 if( wall[i].cstat )
1146 {
1147 wall[i].cstat = 0;
1148
1149 if( s >= 0 && sprite[s].picnum == SECTOREFFECTOR &&
1150 sprite[s].lotag == 30)
1151 wall[i].lotag = 0;
1152 }
1153 else
1154 wall[i].cstat = 85;
1155 break;
1156 }
1157 }
1158}
1159
1160
1161uint8_t checkhitswitch(short snum,int32_t w,uint8_t switchtype)
1162{
1163 uint8_t switchpal;
1164 short i, x, lotag,hitag,picnum,correctdips,numdips;
1165 int32_t sx,sy;
1166
1167 if(w < 0) return 0;
1168 correctdips = 1;
1169 numdips = 0;
1170
1171 if(switchtype == 1) // A wall sprite
1172 {
1173 lotag = sprite[w].lotag; if(lotag == 0) return 0;
1174 hitag = sprite[w].hitag;
1175 sx = sprite[w].x;
1176 sy = sprite[w].y;
1177 picnum = sprite[w].picnum;
1178 switchpal = sprite[w].pal;
1179 }
1180 else
1181 {
1182 lotag = wall[w].lotag; if(lotag == 0) return 0;
1183 hitag = wall[w].hitag;
1184 sx = wall[w].x;
1185 sy = wall[w].y;
1186 picnum = wall[w].picnum;
1187 switchpal = wall[w].pal;
1188 }
1189
1190 switch(picnum)
1191 {
1192 case DIPSWITCH:
1193 case DIPSWITCH+1:
1194 case TECHSWITCH:
1195 case TECHSWITCH+1:
1196 case ALIENSWITCH:
1197 case ALIENSWITCH+1:
1198 break;
1199 case ACCESSSWITCH:
1200 case ACCESSSWITCH2:
1201 if(ps[snum].access_incs == 0)
1202 {
1203 if( switchpal == 0 )
1204 {
1205 if( (ps[snum].got_access&1) )
1206 ps[snum].access_incs = 1;
1207 else FTA(70,&ps[snum],1);
1208 }
1209
1210 else if( switchpal == 21 )
1211 {
1212 if( ps[snum].got_access&2 )
1213 ps[snum].access_incs = 1;
1214 else FTA(71,&ps[snum],1);
1215 }
1216
1217 else if( switchpal == 23 )
1218 {
1219 if( ps[snum].got_access&4 )
1220 ps[snum].access_incs = 1;
1221 else FTA(72,&ps[snum],1);
1222 }
1223
1224 if( ps[snum].access_incs == 1 )
1225 {
1226 if(switchtype == 0)
1227 ps[snum].access_wallnum = w;
1228 else
1229 ps[snum].access_spritenum = w;
1230 }
1231
1232 return 0;
1233 }
1234 case DIPSWITCH2:
1235 case DIPSWITCH2+1:
1236 case DIPSWITCH3:
1237 case DIPSWITCH3+1:
1238 case MULTISWITCH:
1239 case MULTISWITCH+1:
1240 case MULTISWITCH+2:
1241 case MULTISWITCH+3:
1242 case PULLSWITCH:
1243 case PULLSWITCH+1:
1244 case HANDSWITCH:
1245 case HANDSWITCH+1:
1246 case SLOTDOOR:
1247 case SLOTDOOR+1:
1248 case LIGHTSWITCH:
1249 case LIGHTSWITCH+1:
1250 case SPACELIGHTSWITCH:
1251 case SPACELIGHTSWITCH+1:
1252 case SPACEDOORSWITCH:
1253 case SPACEDOORSWITCH+1:
1254 case FRANKENSTINESWITCH:
1255 case FRANKENSTINESWITCH+1:
1256 case LIGHTSWITCH2:
1257 case LIGHTSWITCH2+1:
1258 case POWERSWITCH1:
1259 case POWERSWITCH1+1:
1260 case LOCKSWITCH1:
1261 case LOCKSWITCH1+1:
1262 case POWERSWITCH2:
1263 case POWERSWITCH2+1:
1264 if( check_activator_motion( lotag ) ) return 0;
1265 break;
1266 default:
1267 if( isadoorwall(picnum) == 0 ) return 0;
1268 break;
1269 }
1270
1271 i = headspritestat[0];
1272 while(i >= 0)
1273 {
1274 if( lotag == SLT ) switch(PN)
1275 {
1276 case DIPSWITCH:
1277 case TECHSWITCH:
1278 case ALIENSWITCH:
1279 if( switchtype == 1 && w == i ) PN++;
1280 else if( SHT == 0 ) correctdips++;
1281 numdips++;
1282 break;
1283 case TECHSWITCH+1:
1284 case DIPSWITCH+1:
1285 case ALIENSWITCH+1:
1286 if( switchtype == 1 && w == i ) PN--;
1287 else if( SHT == 1 ) correctdips++;
1288 numdips++;
1289 break;
1290 case MULTISWITCH:
1291 case MULTISWITCH+1:
1292 case MULTISWITCH+2:
1293 case MULTISWITCH+3:
1294 sprite[i].picnum++;
1295 if( sprite[i].picnum > (MULTISWITCH+3) )
1296 sprite[i].picnum = MULTISWITCH;
1297 break;
1298 case ACCESSSWITCH:
1299 case ACCESSSWITCH2:
1300 case SLOTDOOR:
1301 case LIGHTSWITCH:
1302 case SPACELIGHTSWITCH:
1303 case SPACEDOORSWITCH:
1304 case FRANKENSTINESWITCH:
1305 case LIGHTSWITCH2:
1306 case POWERSWITCH1:
1307 case LOCKSWITCH1:
1308 case POWERSWITCH2:
1309 case HANDSWITCH:
1310 case PULLSWITCH:
1311 case DIPSWITCH2:
1312 case DIPSWITCH3:
1313 sprite[i].picnum++;
1314 break;
1315 case PULLSWITCH+1:
1316 case HANDSWITCH+1:
1317 case LIGHTSWITCH2+1:
1318 case POWERSWITCH1+1:
1319 case LOCKSWITCH1+1:
1320 case POWERSWITCH2+1:
1321 case SLOTDOOR+1:
1322 case LIGHTSWITCH+1:
1323 case SPACELIGHTSWITCH+1:
1324 case SPACEDOORSWITCH+1:
1325 case FRANKENSTINESWITCH+1:
1326 case DIPSWITCH2+1:
1327 case DIPSWITCH3+1:
1328 sprite[i].picnum--;
1329 break;
1330 }
1331 i = nextspritestat[i];
1332 }
1333
1334 for(i=0;i<numwalls;i++)
1335 {
1336 x = i;
1337 if(lotag == wall[x].lotag)
1338 switch(wall[x].picnum)
1339 {
1340 case DIPSWITCH:
1341 case TECHSWITCH:
1342 case ALIENSWITCH:
1343 if( switchtype == 0 && i == w ) wall[x].picnum++;
1344 else if( wall[x].hitag == 0 ) correctdips++;
1345 numdips++;
1346 break;
1347 case DIPSWITCH+1:
1348 case TECHSWITCH+1:
1349 case ALIENSWITCH+1:
1350 if( switchtype == 0 && i == w ) wall[x].picnum--;
1351 else if( wall[x].hitag == 1 ) correctdips++;
1352 numdips++;
1353 break;
1354 case MULTISWITCH:
1355 case MULTISWITCH+1:
1356 case MULTISWITCH+2:
1357 case MULTISWITCH+3:
1358 wall[x].picnum++;
1359 if(wall[x].picnum > (MULTISWITCH+3) )
1360 wall[x].picnum = MULTISWITCH;
1361 break;
1362 case ACCESSSWITCH:
1363 case ACCESSSWITCH2:
1364 case SLOTDOOR:
1365 case LIGHTSWITCH:
1366 case SPACELIGHTSWITCH:
1367 case SPACEDOORSWITCH:
1368 case LIGHTSWITCH2:
1369 case POWERSWITCH1:
1370 case LOCKSWITCH1:
1371 case POWERSWITCH2:
1372 case PULLSWITCH:
1373 case HANDSWITCH:
1374 case DIPSWITCH2:
1375 case DIPSWITCH3:
1376 wall[x].picnum++;
1377 break;
1378 case HANDSWITCH+1:
1379 case PULLSWITCH+1:
1380 case LIGHTSWITCH2+1:
1381 case POWERSWITCH1+1:
1382 case LOCKSWITCH1+1:
1383 case POWERSWITCH2+1:
1384 case SLOTDOOR+1:
1385 case LIGHTSWITCH+1:
1386 case SPACELIGHTSWITCH+1:
1387 case SPACEDOORSWITCH+1:
1388 case DIPSWITCH2+1:
1389 case DIPSWITCH3+1:
1390 wall[x].picnum--;
1391 break;
1392 }
1393 }
1394
1395 if(lotag == (short) 65535)
1396 {
1397 ps[myconnectindex].gm = MODE_EOL;
1398 if(ud.from_bonus)
1399 {
1400 ud.level_number = ud.from_bonus;
1401 ud.m_level_number = ud.level_number;
1402 ud.from_bonus = 0;
1403 }
1404 else
1405 {
1406 ud.level_number++;
1407 if( (ud.volume_number && ud.level_number > 10 ) || ( ud.volume_number == 0 && ud.level_number > 5 ) )
1408 ud.level_number = 0;
1409 ud.m_level_number = ud.level_number;
1410 }
1411 return 1;
1412 }
1413
1414 switch(picnum)
1415 {
1416 default:
1417 if(isadoorwall(picnum) == 0) break;
1418 case DIPSWITCH:
1419 case DIPSWITCH+1:
1420 case TECHSWITCH:
1421 case TECHSWITCH+1:
1422 case ALIENSWITCH:
1423 case ALIENSWITCH+1:
1424 if( picnum == DIPSWITCH || picnum == DIPSWITCH+1 ||
1425 picnum == ALIENSWITCH || picnum == ALIENSWITCH+1 ||
1426 picnum == TECHSWITCH || picnum == TECHSWITCH+1 )
1427 {
1428 if( picnum == ALIENSWITCH || picnum == ALIENSWITCH+1)
1429 {
1430 if(switchtype == 1)
1431 xyzsound(ALIEN_SWITCH1,w,sx,sy,ps[snum].posz);
1432 else xyzsound(ALIEN_SWITCH1,ps[snum].i,sx,sy,ps[snum].posz);
1433 }
1434 else
1435 {
1436 if(switchtype == 1)
1437 xyzsound(SWITCH_ON,w,sx,sy,ps[snum].posz);
1438 else xyzsound(SWITCH_ON,ps[snum].i,sx,sy,ps[snum].posz);
1439 }
1440 if(numdips != correctdips) break;
1441 xyzsound(END_OF_LEVEL_WARN,ps[snum].i,sx,sy,ps[snum].posz);
1442 }
1443 case DIPSWITCH2:
1444 case DIPSWITCH2+1:
1445 case DIPSWITCH3:
1446 case DIPSWITCH3+1:
1447 case MULTISWITCH:
1448 case MULTISWITCH+1:
1449 case MULTISWITCH+2:
1450 case MULTISWITCH+3:
1451 case ACCESSSWITCH:
1452 case ACCESSSWITCH2:
1453 case SLOTDOOR:
1454 case SLOTDOOR+1:
1455 case LIGHTSWITCH:
1456 case LIGHTSWITCH+1:
1457 case SPACELIGHTSWITCH:
1458 case SPACELIGHTSWITCH+1:
1459 case SPACEDOORSWITCH:
1460 case SPACEDOORSWITCH+1:
1461 case FRANKENSTINESWITCH:
1462 case FRANKENSTINESWITCH+1:
1463 case LIGHTSWITCH2:
1464 case LIGHTSWITCH2+1:
1465 case POWERSWITCH1:
1466 case POWERSWITCH1+1:
1467 case LOCKSWITCH1:
1468 case LOCKSWITCH1+1:
1469 case POWERSWITCH2:
1470 case POWERSWITCH2+1:
1471 case HANDSWITCH:
1472 case HANDSWITCH+1:
1473 case PULLSWITCH:
1474 case PULLSWITCH+1:
1475
1476 if( picnum == MULTISWITCH || picnum == (MULTISWITCH+1) ||
1477 picnum == (MULTISWITCH+2) || picnum == (MULTISWITCH+3) )
1478 lotag += picnum-MULTISWITCH;
1479
1480 x = headspritestat[3];
1481 while(x >= 0)
1482 {
1483 if( (sprite[x].hitag) == lotag )
1484 {
1485 switch(sprite[x].lotag)
1486 {
1487 case 12:
1488 sector[sprite[x].sectnum].floorpal = 0;
1489 hittype[x].temp_data[0]++;
1490 if(hittype[x].temp_data[0] == 2)
1491 hittype[x].temp_data[0]++;
1492
1493 break;
1494 case 24:
1495 case 34:
1496 case 25:
1497 hittype[x].temp_data[4] = !hittype[x].temp_data[4];
1498 if(hittype[x].temp_data[4])
1499 FTA(15,&ps[snum],1);
1500 else FTA(2,&ps[snum],1);
1501 break;
1502 case 21:
1503 FTA(2,&ps[screenpeek],1);
1504 break;
1505 }
1506 }
1507 x = nextspritestat[x];
1508 }
1509
1510 operateactivators(lotag,snum);
1511 operateforcefields(ps[snum].i,lotag);
1512 operatemasterswitches(lotag);
1513
1514 if( picnum == DIPSWITCH || picnum == DIPSWITCH+1 ||
1515 picnum == ALIENSWITCH || picnum == ALIENSWITCH+1 ||
1516 picnum == TECHSWITCH || picnum == TECHSWITCH+1 ) return 1;
1517
1518 if( hitag == 0 && isadoorwall(picnum) == 0 )
1519 {
1520 if(switchtype == 1)
1521 xyzsound(SWITCH_ON,w,sx,sy,ps[snum].posz);
1522 else xyzsound(SWITCH_ON,ps[snum].i,sx,sy,ps[snum].posz);
1523 }
1524 else if(hitag != 0)
1525 {
1526 if(switchtype == 1 && (soundm[hitag]&4) == 0)
1527 xyzsound(hitag,w,sx,sy,ps[snum].posz);
1528 else spritesound(hitag,ps[snum].i);
1529 }
1530
1531 return 1;
1532 }
1533 return 0;
1534}
1535
1536
1537void activatebysector(short sect,short j)
1538{
1539 short i,didit;
1540
1541 didit = 0;
1542
1543 i = headspritesect[sect];
1544 while(i >= 0)
1545 {
1546 if(PN == ACTIVATOR)
1547 {
1548 operateactivators(SLT,-1);
1549 didit = 1;
1550// return;
1551 }
1552 i = nextspritesect[i];
1553 }
1554
1555 if(didit == 0)
1556 operatesectors(sect,j);
1557}
1558
1559void breakwall(short newpn,short spr,short dawallnum)
1560{
1561 wall[dawallnum].picnum = newpn;
1562 spritesound(VENT_BUST,spr);
1563 spritesound(GLASS_HEAVYBREAK,spr);
1564 lotsofglass(spr,dawallnum,10);
1565}
1566
1567void checkhitwall(short spr,short dawallnum,int32_t x,int32_t y,int32_t z,short atwith)
1568{
1569 short j, i, sn = -1, darkestwall;
1570 walltype *wal;
1571
1572
1573 wal = &wall[dawallnum];
1574
1575 if(wal->overpicnum == MIRROR)
1576 {
1577 switch(atwith)
1578 {
1579 case HEAVYHBOMB:
1580 case RADIUSEXPLOSION:
1581 case RPG:
1582 case HYDRENT:
1583 case SEENINE:
1584 case OOZFILTER:
1585 case EXPLODINGBARREL:
1586 lotsofglass(spr,dawallnum,70);
1587 wal->cstat &= ~16;
1588 wal->overpicnum = MIRRORBROKE;
1589 spritesound(GLASS_HEAVYBREAK,spr);
1590 return;
1591 }
1592 }
1593
1594 if( ( (wal->cstat&16) || wal->overpicnum == BIGFORCE ) && wal->nextsector >= 0 )
1595 if( sector[wal->nextsector].floorz > z )
1596 if( sector[wal->nextsector].floorz-sector[wal->nextsector].ceilingz )
1597 switch(wal->overpicnum)
1598 {
1599 case W_FORCEFIELD:
1600 case W_FORCEFIELD+1:
1601 case W_FORCEFIELD+2:
1602 wal->extra = 1; // tell the forces to animate
1603 case BIGFORCE:
1604 updatesector(x,y,&sn);
1605 if( sn < 0 ) return;
1606
1607 if(atwith == -1)
1608 i = EGS(sn,x,y,z,FORCERIPPLE,-127,8,8,0,0,0,spr,5);
1609 else
1610 {
1611 if(atwith == CHAINGUN)
1612 i = EGS(sn,x,y,z,FORCERIPPLE,-127,16+sprite[spr].xrepeat,16+sprite[spr].yrepeat,0,0,0,spr,5);
1613 else i = EGS(sn,x,y,z,FORCERIPPLE,-127,32,32,0,0,0,spr,5);
1614 }
1615
1616 CS |= 18+128;
1617 SA = getangle(wal->x-wall[wal->point2].x,
1618 wal->y-wall[wal->point2].y)-512;
1619
1620 spritesound(SOMETHINGHITFORCE,i);
1621
1622 return;
1623
1624 case FANSPRITE:
1625 wal->overpicnum = FANSPRITEBROKE;
1626 wal->cstat &= 65535-65;
1627 if(wal->nextwall >= 0)
1628 {
1629 wall[wal->nextwall].overpicnum = FANSPRITEBROKE;
1630 wall[wal->nextwall].cstat &= 65535-65;
1631 }
1632 spritesound(VENT_BUST,spr);
1633 spritesound(GLASS_BREAKING,spr);
1634 return;
1635
1636 case GLASS:
1637 updatesector(x,y,&sn); if( sn < 0 ) return;
1638 wal->overpicnum=GLASS2;
1639 lotsofglass(spr,dawallnum,10);
1640 wal->cstat = 0;
1641
1642 if(wal->nextwall >= 0)
1643 wall[wal->nextwall].cstat = 0;
1644
1645 i = EGS(sn,x,y,z,SECTOREFFECTOR,0,0,0,ps[0].ang,0,0,spr,3);
1646 SLT = 128; T2 = 5; T3 = dawallnum;
1647 spritesound(GLASS_BREAKING,i);
1648 return;
1649 case STAINGLASS1:
1650 updatesector(x,y,&sn); if( sn < 0 ) return;
1651 lotsofcolourglass(spr,dawallnum,80);
1652 wal->cstat = 0;
1653 if(wal->nextwall >= 0)
1654 wall[wal->nextwall].cstat = 0;
1655 spritesound(VENT_BUST,spr);
1656 spritesound(GLASS_BREAKING,spr);
1657 return;
1658 }
1659
1660 switch(wal->picnum)
1661 {
1662 case COLAMACHINE:
1663 case VENDMACHINE:
1664 breakwall(wal->picnum+2,spr,dawallnum);
1665 spritesound(VENT_BUST,spr);
1666 return;
1667
1668 case OJ:
1669 case FEMPIC2:
1670 case FEMPIC3:
1671
1672 case SCREENBREAK6:
1673 case SCREENBREAK7:
1674 case SCREENBREAK8:
1675
1676 case SCREENBREAK1:
1677 case SCREENBREAK2:
1678 case SCREENBREAK3:
1679 case SCREENBREAK4:
1680 case SCREENBREAK5:
1681
1682 case SCREENBREAK9:
1683 case SCREENBREAK10:
1684 case SCREENBREAK11:
1685 case SCREENBREAK12:
1686 case SCREENBREAK13:
1687 case SCREENBREAK14:
1688 case SCREENBREAK15:
1689 case SCREENBREAK16:
1690 case SCREENBREAK17:
1691 case SCREENBREAK18:
1692 case SCREENBREAK19:
1693 case BORNTOBEWILDSCREEN:
1694
1695 lotsofglass(spr,dawallnum,30);
1696 wal->picnum=W_SCREENBREAK+(TRAND%3);
1697 spritesound(GLASS_HEAVYBREAK,spr);
1698 return;
1699
1700 case W_TECHWALL5:
1701 case W_TECHWALL6:
1702 case W_TECHWALL7:
1703 case W_TECHWALL8:
1704 case W_TECHWALL9:
1705 breakwall(wal->picnum+1,spr,dawallnum);
1706 return;
1707 case W_MILKSHELF:
1708 breakwall(W_MILKSHELFBROKE,spr,dawallnum);
1709 return;
1710
1711 case W_TECHWALL10:
1712 breakwall(W_HITTECHWALL10,spr,dawallnum);
1713 return;
1714
1715 case W_TECHWALL1:
1716 case W_TECHWALL11:
1717 case W_TECHWALL12:
1718 case W_TECHWALL13:
1719 case W_TECHWALL14:
1720 breakwall(W_HITTECHWALL1,spr,dawallnum);
1721 return;
1722
1723 case W_TECHWALL15:
1724 breakwall(W_HITTECHWALL15,spr,dawallnum);
1725 return;
1726
1727 case W_TECHWALL16:
1728 breakwall(W_HITTECHWALL16,spr,dawallnum);
1729 return;
1730
1731 case W_TECHWALL2:
1732 breakwall(W_HITTECHWALL2,spr,dawallnum);
1733 return;
1734
1735 case W_TECHWALL3:
1736 breakwall(W_HITTECHWALL3,spr,dawallnum);
1737 return;
1738
1739 case W_TECHWALL4:
1740 breakwall(W_HITTECHWALL4,spr,dawallnum);
1741 return;
1742
1743 case ATM:
1744 wal->picnum = ATMBROKE;
1745 lotsofmoney(&sprite[spr],1+(TRAND&7));
1746 spritesound(GLASS_HEAVYBREAK,spr);
1747 break;
1748
1749 case WALLLIGHT1:
1750 case WALLLIGHT2:
1751 case WALLLIGHT3:
1752 case WALLLIGHT4:
1753 case TECHLIGHT2:
1754 case TECHLIGHT4:
1755
1756 if( rnd(128) )
1757 spritesound(GLASS_HEAVYBREAK,spr);
1758 else spritesound(GLASS_BREAKING,spr);
1759 lotsofglass(spr,dawallnum,30);
1760
1761 if(wal->picnum == WALLLIGHT1)
1762 wal->picnum = WALLLIGHTBUST1;
1763
1764 if(wal->picnum == WALLLIGHT2)
1765 wal->picnum = WALLLIGHTBUST2;
1766
1767 if(wal->picnum == WALLLIGHT3)
1768 wal->picnum = WALLLIGHTBUST3;
1769
1770 if(wal->picnum == WALLLIGHT4)
1771 wal->picnum = WALLLIGHTBUST4;
1772
1773 if(wal->picnum == TECHLIGHT2)
1774 wal->picnum = TECHLIGHTBUST2;
1775
1776 if(wal->picnum == TECHLIGHT4)
1777 wal->picnum = TECHLIGHTBUST4;
1778
1779 if(!wal->lotag) return;
1780
1781 sn = wal->nextsector;
1782 if(sn < 0) return;
1783 darkestwall = 0;
1784
1785 wal = &wall[sector[sn].wallptr];
1786 for(i=sector[sn].wallnum;i > 0;i--,wal++)
1787 if(wal->shade > darkestwall)
1788 darkestwall=wal->shade;
1789
1790 j = TRAND&1;
1791 i= headspritestat[3];
1792 while(i >= 0)
1793 {
1794 if(SHT == wall[dawallnum].lotag && SLT == 3 )
1795 {
1796 T3 = j;
1797 T4 = darkestwall;
1798 T5 = 1;
1799 }
1800 i = nextspritestat[i];
1801 }
1802 break;
1803 }
1804}
1805
1806
1807void checkplayerhurt(struct player_struct *p,short j)
1808{
1809 if( (j&49152) == 49152 )
1810 {
1811 j &= (MAXSPRITES-1);
1812
1813 switch(sprite[j].picnum)
1814 {
1815 case CACTUS:
1816 if(p->hurt_delay < 8 )
1817 {
1818 sprite[p->i].extra -= 5;
1819
1820 p->hurt_delay = 16;
1821 p->pals_time = 32;
1822 p->pals[0] = 32;
1823 p->pals[1] = 0;
1824 p->pals[2] = 0;
1825 spritesound(DUKE_LONGTERM_PAIN,p->i);
1826 }
1827 break;
1828 }
1829 return;
1830 }
1831
1832 if( (j&49152) != 32768) return;
1833 j &= (MAXWALLS-1);
1834
1835 if( p->hurt_delay > 0 ) p->hurt_delay--;
1836 else if( wall[j].cstat&85 ) switch(wall[j].overpicnum)
1837 {
1838 case W_FORCEFIELD:
1839 case W_FORCEFIELD+1:
1840 case W_FORCEFIELD+2:
1841 sprite[p->i].extra -= 5;
1842
1843 p->hurt_delay = 16;
1844 p->pals_time = 32;
1845 p->pals[0] = 32;
1846 p->pals[1] = 0;
1847 p->pals[2] = 0;
1848
1849 p->posxv = -(sintable[(p->ang+512)&2047]<<8);
1850 p->posyv = -(sintable[(p->ang)&2047]<<8);
1851 spritesound(DUKE_LONGTERM_PAIN,p->i);
1852
1853 checkhitwall(p->i,j,
1854 p->posx+(sintable[(p->ang+512)&2047]>>9),
1855 p->posy+(sintable[p->ang&2047]>>9),
1856 p->posz,-1);
1857
1858 break;
1859
1860 case BIGFORCE:
1861 p->hurt_delay = 26;
1862 checkhitwall(p->i,j,
1863 p->posx+(sintable[(p->ang+512)&2047]>>9),
1864 p->posy+(sintable[p->ang&2047]>>9),
1865 p->posz,-1);
1866 break;
1867
1868 }
1869}
1870
1871
1872uint8_t checkhitceiling(short sn)
1873{
1874 short i, j;
1875
1876
1877
1878 switch(sector[sn].ceilingpicnum)
1879 {
1880 case WALLLIGHT1:
1881 case WALLLIGHT2:
1882 case WALLLIGHT3:
1883 case WALLLIGHT4:
1884 case TECHLIGHT2:
1885 case TECHLIGHT4:
1886
1887 ceilingglass(ps[myconnectindex].i,sn,10);
1888 spritesound(GLASS_BREAKING,ps[screenpeek].i);
1889
1890 if(sector[sn].ceilingpicnum == WALLLIGHT1)
1891 sector[sn].ceilingpicnum = WALLLIGHTBUST1;
1892
1893 if(sector[sn].ceilingpicnum == WALLLIGHT2)
1894 sector[sn].ceilingpicnum = WALLLIGHTBUST2;
1895
1896 if(sector[sn].ceilingpicnum == WALLLIGHT3)
1897 sector[sn].ceilingpicnum = WALLLIGHTBUST3;
1898
1899 if(sector[sn].ceilingpicnum == WALLLIGHT4)
1900 sector[sn].ceilingpicnum = WALLLIGHTBUST4;
1901
1902 if(sector[sn].ceilingpicnum == TECHLIGHT2)
1903 sector[sn].ceilingpicnum = TECHLIGHTBUST2;
1904
1905 if(sector[sn].ceilingpicnum == TECHLIGHT4)
1906 sector[sn].ceilingpicnum = TECHLIGHTBUST4;
1907
1908
1909 if(!sector[sn].hitag)
1910 {
1911 i = headspritesect[sn];
1912 while(i >= 0)
1913 {
1914 if( PN == SECTOREFFECTOR && SLT == 12 )
1915 {
1916 j = headspritestat[3];
1917 while(j >= 0)
1918 {
1919 if( sprite[j].hitag == SHT )
1920 hittype[j].temp_data[3] = 1;
1921 j = nextspritestat[j];
1922 }
1923 break;
1924 }
1925 i = nextspritesect[i];
1926 }
1927 }
1928
1929 i = headspritestat[3];
1930 j = TRAND&1;
1931 while(i >= 0)
1932 {
1933 if(SHT == (sector[sn].hitag) && SLT == 3 )
1934 {
1935 T3 = j;
1936 T5 = 1;
1937 }
1938 i = nextspritestat[i];
1939 }
1940
1941 return 1;
1942 }
1943
1944 return 0;
1945}
1946
1947void checkhitsprite(short i,short sn)
1948{
1949 short j, k, p;
1950 spritetype *s;
1951
1952 i &= (MAXSPRITES-1);
1953
1954 switch(PN)
1955 {
1956 case OCEANSPRITE1:
1957 case OCEANSPRITE2:
1958 case OCEANSPRITE3:
1959 case OCEANSPRITE4:
1960 case OCEANSPRITE5:
1961 spawn(i,SMALLSMOKE);
1962 deletesprite(i);
1963 break;
1964 case QUEBALL:
1965 case STRIPEBALL:
1966 if(sprite[sn].picnum == QUEBALL || sprite[sn].picnum == STRIPEBALL)
1967 {
1968 sprite[sn].xvel = (sprite[i].xvel>>1)+(sprite[i].xvel>>2);
1969 sprite[sn].ang -= (SA<<1)+1024;
1970 SA = getangle(SX-sprite[sn].x,SY-sprite[sn].y)-512;
1971 if(Sound[POOLBALLHIT].num < 2)
1972 spritesound(POOLBALLHIT,i);
1973 }
1974 else
1975 {
1976 if( TRAND&3 )
1977 {
1978 sprite[i].xvel = 164;
1979 sprite[i].ang = sprite[sn].ang;
1980 }
1981 else
1982 {
1983 lotsofglass(i,-1,3);
1984 deletesprite(i);
1985 }
1986 }
1987 break;
1988 case TREE1:
1989 case TREE2:
1990 case TIRE:
1991 case CONE:
1992 case BOX:
1993 switch(sprite[sn].picnum)
1994 {
1995 case RADIUSEXPLOSION:
1996 case RPG:
1997 case FIRELASER:
1998 case HYDRENT:
1999 case HEAVYHBOMB:
2000 if(T1 == 0)
2001 {
2002 CS &= ~257;
2003 T1 = 1;
2004 spawn(i,BURNING);
2005 }
2006 break;
2007 }
2008 break;
2009 case CACTUS:
2010// case CACTUSBROKE:
2011 switch(sprite[sn].picnum)
2012 {
2013 case RADIUSEXPLOSION:
2014 case RPG:
2015 case FIRELASER:
2016 case HYDRENT:
2017 case HEAVYHBOMB:
2018 for(k=0;k<64;k++)
2019 {
2020 j = EGS(SECT,SX,SY,SZ-(TRAND%(48<<8)),SCRAP3+(TRAND&3),-8,48,48,TRAND&2047,(TRAND&63)+64,-(TRAND&4095)-(sprite[i].zvel>>2),i,5);
2021 sprite[j].pal = 8;
2022 }
2023
2024 if(PN == CACTUS)
2025 PN = CACTUSBROKE;
2026 CS &= ~257;
2027 // else deletesprite(i);
2028 break;
2029 }
2030 break;
2031
2032 case HANGLIGHT:
2033 case GENERICPOLE2:
2034 for(k=0;k<6;k++)
2035 EGS(SECT,SX,SY,SZ-(8<<8),SCRAP1+(TRAND&15),-8,48,48,TRAND&2047,(TRAND&63)+64,-(TRAND&4095)-(sprite[i].zvel>>2),i,5);
2036 spritesound(GLASS_HEAVYBREAK,i);
2037 deletesprite(i);
2038 break;
2039
2040
2041 case FANSPRITE:
2042 PN = FANSPRITEBROKE;
2043 CS &= (65535-257);
2044 if( sector[SECT].floorpicnum == FANSHADOW )
2045 sector[SECT].floorpicnum = FANSHADOWBROKE;
2046
2047 spritesound(GLASS_HEAVYBREAK,i);
2048 s = &sprite[i];
2049 for(j=0;j<16;j++) RANDOMSCRAP;
2050
2051 break;
2052 case WATERFOUNTAIN:
2053 case WATERFOUNTAIN+1:
2054 case WATERFOUNTAIN+2:
2055 case WATERFOUNTAIN+3:
2056 PN = WATERFOUNTAINBROKE;
2057 spawn(i,TOILETWATER);
2058 break;
2059 case SATELITE:
2060 case FUELPOD:
2061 case SOLARPANNEL:
2062 case ANTENNA:
2063 if(sprite[sn].extra != *actorscrptr[SHOTSPARK1] )
2064 {
2065 for(j=0;j<15;j++)
2066 EGS(SECT,SX,SY,sector[SECT].floorz-(12<<8)-(j<<9),SCRAP1+(TRAND&15),-8,64,64,
2067 TRAND&2047,(TRAND&127)+64,-(TRAND&511)-256,i,5);
2068 spawn(i,EXPLOSION2);
2069 deletesprite(i);
2070 }
2071 break;
2072 case BOTTLE1:
2073 case BOTTLE2:
2074 case BOTTLE3:
2075 case BOTTLE4:
2076 case BOTTLE5:
2077 case BOTTLE6:
2078 case BOTTLE8:
2079 case BOTTLE10:
2080 case BOTTLE11:
2081 case BOTTLE12:
2082 case BOTTLE13:
2083 case BOTTLE14:
2084 case BOTTLE15:
2085 case BOTTLE16:
2086 case BOTTLE17:
2087 case BOTTLE18:
2088 case BOTTLE19:
2089 case WATERFOUNTAINBROKE:
2090 case DOMELITE:
2091 case SUSHIPLATE1:
2092 case SUSHIPLATE2:
2093 case SUSHIPLATE3:
2094 case SUSHIPLATE4:
2095 case SUSHIPLATE5:
2096 case WAITTOBESEATED:
2097 case VASE:
2098 case STATUEFLASH:
2099 case STATUE:
2100 if(PN == BOTTLE10)
2101 lotsofmoney(&sprite[i],4+(TRAND&3));
2102 else if(PN == STATUE || PN == STATUEFLASH)
2103 {
2104 lotsofcolourglass(i,-1,40);
2105 spritesound(GLASS_HEAVYBREAK,i);
2106 }
2107 else if(PN == VASE)
2108 lotsofglass(i,-1,40);
2109
2110 spritesound(GLASS_BREAKING,i);
2111 SA = TRAND&2047;
2112 lotsofglass(i,-1,8);
2113 deletesprite(i);
2114 break;
2115 case FETUS:
2116 PN = FETUSBROKE;
2117 spritesound(GLASS_BREAKING,i);
2118 lotsofglass(i,-1,10);
2119 break;
2120 case FETUSBROKE:
2121 for(j=0;j<48;j++)
2122 {
2123 shoot(i,BLOODSPLAT1);
2124 SA += 333;
2125 }
2126 spritesound(GLASS_HEAVYBREAK,i);
2127 spritesound(SQUISHED,i);
2128 case BOTTLE7:
2129 spritesound(GLASS_BREAKING,i);
2130 lotsofglass(i,-1,10);
2131 deletesprite(i);
2132 break;
2133 case HYDROPLANT:
2134 PN = BROKEHYDROPLANT;
2135 spritesound(GLASS_BREAKING,i);
2136 lotsofglass(i,-1,10);
2137 break;
2138
2139 case FORCESPHERE:
2140 sprite[i].xrepeat = 0;
2141 hittype[OW].temp_data[0] = 32;
2142 hittype[OW].temp_data[1] = !hittype[OW].temp_data[1];
2143 hittype[OW].temp_data[2] ++;
2144 spawn(i,EXPLOSION2);
2145 break;
2146
2147 case BROKEHYDROPLANT:
2148 if(CS&1)
2149 {
2150 spritesound(GLASS_BREAKING,i);
2151 SZ += 16<<8;
2152 CS = 0;
2153 lotsofglass(i,-1,5);
2154 }
2155 break;
2156
2157 case TOILET:
2158 PN = TOILETBROKE;
2159 CS |= (TRAND&1)<<2;
2160 CS &= ~257;
2161 spawn(i,TOILETWATER);
2162 spritesound(GLASS_BREAKING,i);
2163 break;
2164
2165 case STALL:
2166 PN = STALLBROKE;
2167 CS |= (TRAND&1)<<2;
2168 CS &= ~257;
2169 spawn(i,TOILETWATER);
2170 spritesound(GLASS_HEAVYBREAK,i);
2171 break;
2172
2173 case HYDRENT:
2174 PN = BROKEFIREHYDRENT;
2175 spawn(i,TOILETWATER);
2176
2177// for(k=0;k<5;k++)
2178 // {
2179 // j = EGS(SECT,SX,SY,SZ-(TRAND%(48<<8)),SCRAP3+(TRAND&3),-8,48,48,TRAND&2047,(TRAND&63)+64,-(TRAND&4095)-(sprite[i].zvel>>2),i,5);
2180 // sprite[j].pal = 2;
2181 // }
2182 spritesound(GLASS_HEAVYBREAK,i);
2183 break;
2184
2185 case GRATE1:
2186 PN = BGRATE1;
2187 CS &= (65535-256-1);
2188 spritesound(VENT_BUST,i);
2189 break;
2190
2191 case CIRCLEPANNEL:
2192 PN = CIRCLEPANNELBROKE;
2193 CS &= (65535-256-1);
2194 spritesound(VENT_BUST,i);
2195 break;
2196 case PANNEL1:
2197 case PANNEL2:
2198 PN = BPANNEL1;
2199 CS &= (65535-256-1);
2200 spritesound(VENT_BUST,i);
2201 break;
2202 case PANNEL3:
2203 PN = BPANNEL3;
2204 CS &= (65535-256-1);
2205 spritesound(VENT_BUST,i);
2206 break;
2207 case PIPE1:
2208 case PIPE2:
2209 case PIPE3:
2210 case PIPE4:
2211 case PIPE5:
2212 case PIPE6:
2213 switch(PN)
2214 {
2215 case PIPE1:PN=PIPE1B;break;
2216 case PIPE2:PN=PIPE2B;break;
2217 case PIPE3:PN=PIPE3B;break;
2218 case PIPE4:PN=PIPE4B;break;
2219 case PIPE5:PN=PIPE5B;break;
2220 case PIPE6:PN=PIPE6B;break;
2221 }
2222
2223 j = spawn(i,STEAM);
2224 sprite[j].z = sector[SECT].floorz-(32<<8);
2225 break;
2226
2227 case MONK:
2228 case LUKE:
2229 case INDY:
2230 case JURYGUY:
2231 spritesound(SLT,i);
2232 spawn(i,SHT);
2233 case SPACEMARINE:
2234 sprite[i].extra -= sprite[sn].extra;
2235 if(sprite[i].extra > 0) break;
2236 SA = TRAND&2047;
2237 shoot(i,BLOODSPLAT1);
2238 SA = TRAND&2047;
2239 shoot(i,BLOODSPLAT2);
2240 SA = TRAND&2047;
2241 shoot(i,BLOODSPLAT3);
2242 SA = TRAND&2047;
2243 shoot(i,BLOODSPLAT4);
2244 SA = TRAND&2047;
2245 shoot(i,BLOODSPLAT1);
2246 SA = TRAND&2047;
2247 shoot(i,BLOODSPLAT2);
2248 SA = TRAND&2047;
2249 shoot(i,BLOODSPLAT3);
2250 SA = TRAND&2047;
2251 shoot(i,BLOODSPLAT4);
2252 guts(&sprite[i],JIBS1,1,myconnectindex);
2253 guts(&sprite[i],JIBS2,2,myconnectindex);
2254 guts(&sprite[i],JIBS3,3,myconnectindex);
2255 guts(&sprite[i],JIBS4,4,myconnectindex);
2256 guts(&sprite[i],JIBS5,1,myconnectindex);
2257 guts(&sprite[i],JIBS3,6,myconnectindex);
2258 sound(SQUISHED);
2259 deletesprite(i);
2260 break;
2261 case CHAIR1:
2262 case CHAIR2:
2263 PN = BROKENCHAIR;
2264 CS = 0;
2265 break;
2266 case CHAIR3:
2267 case MOVIECAMERA:
2268 case SCALE:
2269 case VACUUM:
2270 case CAMERALIGHT:
2271 case IVUNIT:
2272 case POT1:
2273 case POT2:
2274 case POT3:
2275 case TRIPODCAMERA:
2276 spritesound(GLASS_HEAVYBREAK,i);
2277 s = &sprite[i];
2278 for(j=0;j<16;j++) RANDOMSCRAP;
2279 deletesprite(i);
2280 break;
2281 case PLAYERONWATER:
2282 i = OW;
2283 default:
2284 if( (sprite[i].cstat&16) && SHT == 0 && SLT == 0 && sprite[i].statnum == 0)
2285 break;
2286
2287 if( ( sprite[sn].picnum == FREEZEBLAST || sprite[sn].owner != i ) && sprite[i].statnum != 4)
2288 {
2289 if( badguy(&sprite[i]) == 1)
2290 {
2291 if(sprite[sn].picnum == RPG) sprite[sn].extra <<= 1;
2292
2293 if( (PN != DRONE) && (PN != ROTATEGUN) && (PN != COMMANDER) && (PN < GREENSLIME || PN > GREENSLIME+7) )
2294 if(sprite[sn].picnum != FREEZEBLAST )
2295 if( actortype[PN] == 0 )
2296 {
2297 j = spawn(sn,JIBS6);
2298 if(sprite[sn].pal == 6)
2299 sprite[j].pal = 6;
2300 sprite[j].z += (4<<8);
2301 sprite[j].xvel = 16;
2302 sprite[j].xrepeat = sprite[j].yrepeat = 24;
2303 sprite[j].ang += 32-(TRAND&63);
2304 }
2305
2306 j = sprite[sn].owner;
2307
2308 if( j >= 0 && sprite[j].picnum == APLAYER && PN != ROTATEGUN && PN != DRONE )
2309 if( ps[sprite[j].yvel].curr_weapon == SHOTGUN_WEAPON )
2310 {
2311 shoot(i,BLOODSPLAT3);
2312 shoot(i,BLOODSPLAT1);
2313 shoot(i,BLOODSPLAT2);
2314 shoot(i,BLOODSPLAT4);
2315 }
2316
2317 if( PN != TANK && PN != BOSS1 && PN != BOSS4 && PN != BOSS2 && PN != BOSS3 && PN != RECON && PN != ROTATEGUN )
2318 {
2319 if( (sprite[i].cstat&48) == 0 )
2320 SA = (sprite[sn].ang+1024)&2047;
2321 sprite[i].xvel = -(sprite[sn].extra<<2);
2322 j = SECT;
2323 pushmove(&SX,&SY,&SZ,&j,128L,(4L<<8),(4L<<8),CLIPMASK0);
2324 if(j != SECT && j >= 0 && j < MAXSECTORS)
2325 changespritesect(i,j);
2326 }
2327
2328 if(sprite[i].statnum == 2)
2329 {
2330 changespritestat(i,1);
2331 hittype[i].timetosleep = SLEEPTIME;
2332 }
2333 if( ( RX < 24 || PN == SHARK) && sprite[sn].picnum == SHRINKSPARK) return;
2334 }
2335
2336 if( sprite[i].statnum != 2 )
2337 {
2338 if( sprite[sn].picnum == FREEZEBLAST && ( (PN == APLAYER && sprite[i].pal == 1 ) || ( freezerhurtowner == 0 && sprite[sn].owner == i ) ) )
2339 return;
2340
2341 hittype[i].picnum = sprite[sn].picnum;
2342 hittype[i].extra += sprite[sn].extra;
2343 hittype[i].ang = sprite[sn].ang;
2344 hittype[i].owner = sprite[sn].owner;
2345 }
2346
2347 if(sprite[i].statnum == 10)
2348 {
2349 p = sprite[i].yvel;
2350 if(ps[p].newowner >= 0)
2351 {
2352 ps[p].newowner = -1;
2353 ps[p].posx = ps[p].oposx;
2354 ps[p].posy = ps[p].oposy;
2355 ps[p].posz = ps[p].oposz;
2356 ps[p].ang = ps[p].oang;
2357
2358 updatesector(ps[p].posx,ps[p].posy,&ps[p].cursectnum);
2359 setpal(&ps[p]);
2360
2361 j = headspritestat[1];
2362 while(j >= 0)
2363 {
2364 if(sprite[j].picnum==CAMERA1) sprite[j].yvel = 0;
2365 j = nextspritestat[j];
2366 }
2367 }
2368
2369 if( RX < 24 && sprite[sn].picnum == SHRINKSPARK)
2370 return;
2371
2372 if( sprite[hittype[i].owner].picnum != APLAYER)
2373 if(ud.player_skill >= 3)
2374 sprite[sn].extra += (sprite[sn].extra>>1);
2375 }
2376
2377 }
2378 break;
2379 }
2380}
2381
2382
2383void allignwarpelevators(void)
2384{
2385 short i, j;
2386
2387 i = headspritestat[3];
2388 while(i >= 0)
2389 {
2390 if( SLT == 17 && SS > 16)
2391 {
2392 j = headspritestat[3];
2393 while(j >= 0)
2394 {
2395 if( (sprite[j].lotag) == 17 && i != j &&
2396 (SHT) == (sprite[j].hitag) )
2397 {
2398 sector[sprite[j].sectnum].floorz =
2399 sector[SECT].floorz;
2400 sector[sprite[j].sectnum].ceilingz =
2401 sector[SECT].ceilingz;
2402 }
2403
2404 j = nextspritestat[j];
2405 }
2406 }
2407 i = nextspritestat[i];
2408 }
2409}
2410
2411
2412
2413
2414void cheatkeys(short snum)
2415{
2416 short i, k;
2417 uint8_t dainv;
2418 uint32_t sb_snum, j;
2419 struct player_struct *p;
2420 uint8_t playing_old_demo = 0;
2421
2422 sb_snum = sync[snum].bits;
2423 p = &ps[snum];
2424
2425 if(p->cheat_phase == 1) return;
2426
2427 i = p->aim_mode;
2428 p->aim_mode = (sb_snum>>23)&1;
2429 if(p->aim_mode < i)
2430 p->return_to_center = 9;
2431
2432 if( (sb_snum&(1<<22)) && p->quick_kick == 0)
2433 if( !PLUTOPAK || p->curr_weapon != KNEE_WEAPON || p->kickback_pic == 0 )
2434 // FIX_00066: Removed the QuickKick restrictions for 1.3/1.3d (like 1.3d dos version behavior)
2435 {
2436 p->quick_kick = 14;
2437 FTA(80,p,0);
2438 }
2439
2440 // FIX_00040: Preventing multi keypress locks
2441 playing_old_demo = ud.playing_demo_rev == BYTEVERSION_27 ||
2442 ud.playing_demo_rev == BYTEVERSION_28 ||
2443 ud.playing_demo_rev == BYTEVERSION_116 ||
2444 ud.playing_demo_rev == BYTEVERSION_117;
2445
2446 if(!playing_old_demo)
2447 {
2448 // A more efficient toggle (make old demos going oos):
2449 j = sb_snum & ((15<<8)|(1<<12)|(1<<15)|(1<<16)|(1<<22)|(1<<19)|(1<<20)|(1<<21)|(1<<24)| \
2450 (1<<25)|(1<<27)|(1<<28)|(1<<29)|(1<<30)|(1<<31));
2451 sb_snum = j & ~p->interface_toggle_flag;
2452 p->interface_toggle_flag = j;
2453 }
2454
2455 if( playing_old_demo && !(sb_snum&((15<<8)|(1<<12)|(1<<15)|(1<<16)|(1<<22)|(1<<19)|(1<<20)|(1<<21)|(1<<24)|(1<<25)|(1<<27)|(1<<28)|(1<<29)|(1<<30)|(1<<31))) )
2456 p->interface_toggle_flag = 0;
2457 else if(((p->interface_toggle_flag == 0 && ( sb_snum&(1<<17) ) == 0) && playing_old_demo) ||
2458 ((sb_snum && ( sync[snum].bits&(1<<17) ) == 0) && !playing_old_demo))
2459 {
2460 if(playing_old_demo)
2461 p->interface_toggle_flag = 1;
2462
2463 if( sb_snum&(1<<21) )
2464 {
2465 KB_ClearKeyDown( sc_Pause );
2466 ud.pause_on = !ud.pause_on;
2467 if( ud.pause_on == 1 && sb_snum&(1<<5) ) ud.pause_on = 2;
2468 if(ud.pause_on)
2469 {
2470 MUSIC_Pause();
2471 FX_StopAllSounds();
2472 clearsoundlocks();
2473 }
2474 else
2475 {
2476 if(MusicToggle) MUSIC_Continue();
2477 pub = NUMPAGES;
2478 pus = NUMPAGES;
2479 }
2480 }
2481
2482 if(ud.pause_on) return;
2483
2484 if(sprite[p->i].extra <= 0) return;
2485
2486 if( sb_snum&(1<<30) && p->newowner == -1 )
2487 {
2488 switch(p->inven_icon)
2489 {
2490 case 4: sb_snum |= (1<<25);break;
2491 case 3: sb_snum |= (1<<24);break;
2492 case 5: sb_snum |= (1<<15);break;
2493 case 1: sb_snum |= (1<<16);break;
2494 case 2: sb_snum |= (1<<12);break;
2495 }
2496 }
2497
2498 if( sb_snum&(1<<15) && p->heat_amount > 0 )
2499 {
2500 p->heat_on = !p->heat_on;
2501 setpal(p);
2502 p->inven_icon = 5;
2503 spritesound(NITEVISION_ONOFF,p->i);
2504 FTA(106+(!p->heat_on),p,0);
2505 }
2506
2507 if( (sb_snum&(1<<12)) )
2508 {
2509 if(p->steroids_amount == 400 )
2510 {
2511 p->steroids_amount--;
2512 spritesound(DUKE_TAKEPILLS,p->i);
2513 p->inven_icon = 2;
2514 FTA(12,p,0);
2515 }
2516 return;
2517 }
2518
2519 if(p->newowner == -1)
2520 if( sb_snum&(1<<20) || sb_snum&(1<<27) || p->refresh_inventory)
2521 {
2522 p->invdisptime = 26*2;
2523
2524 if( sb_snum&(1<<27) ) k = 1;
2525 else k = 0;
2526
2527 if(p->refresh_inventory) p->refresh_inventory = 0;
2528 dainv = p->inven_icon;
2529
2530 i = 0;
2531 CHECKINV1:
2532
2533 if(i < 9)
2534 {
2535 i++;
2536
2537 switch(dainv)
2538 {
2539 case 4:
2540 if(p->jetpack_amount > 0 && i > 1)
2541 break;
2542 if(k) dainv = 5;
2543 else dainv = 3;
2544 goto CHECKINV1;
2545 case 6:
2546 if(p->scuba_amount > 0 && i > 1)
2547 break;
2548 if(k) dainv = 7;
2549 else dainv = 5;
2550 goto CHECKINV1;
2551 case 2:
2552 if(p->steroids_amount > 0 && i > 1)
2553 break;
2554 if(k) dainv = 3;
2555 else dainv = 1;
2556 goto CHECKINV1;
2557 case 3:
2558 if(p->holoduke_amount > 0 && i > 1)
2559 break;
2560 if(k) dainv = 4;
2561 else dainv = 2;
2562 goto CHECKINV1;
2563 case 0:
2564 case 1:
2565 if(p->firstaid_amount > 0 && i > 1)
2566 break;
2567 if(k) dainv = 2;
2568 else dainv = 7;
2569 goto CHECKINV1;
2570 case 5:
2571 if(p->heat_amount > 0 && i > 1)
2572 break;
2573 if(k) dainv = 6;
2574 else dainv = 4;
2575 goto CHECKINV1;
2576 case 7:
2577 if(p->boot_amount > 0 && i > 1)
2578 break;
2579 if(k) dainv = 1;
2580 else dainv = 6;
2581 goto CHECKINV1;
2582 }
2583 }
2584 else dainv = 0;
2585 p->inven_icon = dainv;
2586
2587 switch(dainv)
2588 {
2589 case 1: FTA(3,p,0);break;
2590 case 2: FTA(90,p,0);break;
2591 case 3: FTA(91,p,0);break;
2592 case 4: FTA(88,p,0);break;
2593 case 5: FTA(101,p,0);break;
2594 case 6: FTA(89,p,0);break;
2595 case 7: FTA(6,p,0);break;
2596 }
2597 }
2598
2599 j = ( (sb_snum&(15<<8))>>8 ) - 1;
2600
2601 if( j > 0 && p->kickback_pic > 0)
2602 p->wantweaponfire = j;
2603
2604 if(p->last_pissed_time <= (26*218) && p->show_empty_weapon == 0 && p->kickback_pic == 0 && p->quick_kick == 0 && sprite[p->i].xrepeat > 32 && p->access_incs == 0 && p->knee_incs == 0 )
2605 {
2606 if( ( p->weapon_pos == 0 || ( p->holster_weapon && p->weapon_pos == -9 ) ) )
2607 {
2608 if(j == 10 || j == 11)
2609 {
2610 k = p->curr_weapon;
2611 j = ( j == 10 ? -1 : 1 );
2612 i = 0;
2613
2614 while( ( k >= 0 && k < 10 ) || ( k == GROW_WEAPON && (p->subweapon&(1<<GROW_WEAPON) ) ) )
2615 {
2616 if(k == GROW_WEAPON)
2617 {
2618 if(j == -1)
2619 k = 5;
2620 else k = 7;
2621
2622 }
2623 else
2624 {
2625 k += j;
2626 if( k == 6 && p->subweapon&(1<<GROW_WEAPON) )
2627 k = GROW_WEAPON;
2628 }
2629
2630 if(k == -1) k = 9;
2631 else if(k == 10) k = 0;
2632
2633 if( p->gotweapon[k] && p->ammo_amount[k] > 0 )
2634 {
2635 if( k == SHRINKER_WEAPON && p->subweapon&(1<<GROW_WEAPON) )
2636 k = GROW_WEAPON;
2637 j = k;
2638 break;
2639 }
2640 else
2641 if(k == GROW_WEAPON && p->ammo_amount[GROW_WEAPON] == 0 && p->gotweapon[SHRINKER_WEAPON] && p->ammo_amount[SHRINKER_WEAPON] > 0)
2642 {
2643 j = SHRINKER_WEAPON;
2644 p->subweapon &= ~(1<<GROW_WEAPON);
2645 break;
2646 }
2647 else
2648 if(k == SHRINKER_WEAPON && p->ammo_amount[SHRINKER_WEAPON] == 0 && p->gotweapon[SHRINKER_WEAPON] && p->ammo_amount[GROW_WEAPON] > 0)
2649 {
2650 j = GROW_WEAPON;
2651 p->subweapon |= (1<<GROW_WEAPON);
2652 break;
2653 }
2654
2655 i++;
2656 if(i == 10)
2657 {
2658 addweapon( p, KNEE_WEAPON );
2659 break;
2660 }
2661 }
2662 }
2663
2664 k = -1;
2665
2666
2667 if( j == HANDBOMB_WEAPON && p->ammo_amount[HANDBOMB_WEAPON] == 0 )
2668 {
2669 k = headspritestat[1];
2670 while(k >= 0)
2671 {
2672 if( sprite[k].picnum == HEAVYHBOMB && sprite[k].owner == p->i )
2673 {
2674 p->gotweapon[HANDBOMB_WEAPON] = 1;
2675 j = HANDREMOTE_WEAPON;
2676 break;
2677 }
2678 k = nextspritestat[k];
2679 }
2680 }
2681
2682 if(j == SHRINKER_WEAPON)
2683 {
2684 if(screenpeek == snum) pus = NUMPAGES;
2685
2686 if( p->curr_weapon != GROW_WEAPON && p->curr_weapon != SHRINKER_WEAPON )
2687 {
2688 if( p->ammo_amount[GROW_WEAPON] > 0 )
2689 {
2690 if( (p->subweapon&(1<<GROW_WEAPON)) == (1<<GROW_WEAPON) )
2691 j = GROW_WEAPON;
2692 else if(p->ammo_amount[SHRINKER_WEAPON] == 0)
2693 {
2694 j = GROW_WEAPON;
2695 p->subweapon |= (1<<GROW_WEAPON);
2696 }
2697 }
2698 else if( p->ammo_amount[SHRINKER_WEAPON] > 0 )
2699 p->subweapon &= ~(1<<GROW_WEAPON);
2700 }
2701 else if( p->curr_weapon == SHRINKER_WEAPON )
2702 {
2703 p->subweapon |= (1<<GROW_WEAPON);
2704 j = GROW_WEAPON;
2705 }
2706 else
2707 p->subweapon &= ~(1<<GROW_WEAPON);
2708 }
2709
2710 if(p->holster_weapon)
2711 {
2712 sb_snum |= 1<<19;
2713 p->weapon_pos = -9;
2714 }
2715 else if(j < MAX_WEAPONS && p->gotweapon[j] && p->curr_weapon != j ) switch(j)
2716 {
2717 case KNEE_WEAPON:
2718 addweapon( p, KNEE_WEAPON );
2719 break;
2720 case PISTOL_WEAPON:
2721 if ( p->ammo_amount[PISTOL_WEAPON] == 0 )
2722 if(p->show_empty_weapon == 0)
2723 {
2724 p->last_full_weapon = p->curr_weapon;
2725 p->show_empty_weapon = 32;
2726 }
2727 addweapon( p, PISTOL_WEAPON );
2728 break;
2729 case SHOTGUN_WEAPON:
2730 if( p->ammo_amount[SHOTGUN_WEAPON] == 0 && p->show_empty_weapon == 0)
2731 {
2732 p->last_full_weapon = p->curr_weapon;
2733 p->show_empty_weapon = 32;
2734 }
2735 addweapon( p, SHOTGUN_WEAPON);
2736 break;
2737 case CHAINGUN_WEAPON:
2738 if( p->ammo_amount[CHAINGUN_WEAPON] == 0 && p->show_empty_weapon == 0)
2739 {
2740 p->last_full_weapon = p->curr_weapon;
2741 p->show_empty_weapon = 32;
2742 }
2743 addweapon( p, CHAINGUN_WEAPON);
2744 break;
2745 case RPG_WEAPON:
2746 if( p->ammo_amount[RPG_WEAPON] == 0 )
2747 if(p->show_empty_weapon == 0)
2748 {
2749 p->last_full_weapon = p->curr_weapon;
2750 p->show_empty_weapon = 32;
2751 }
2752 addweapon( p, RPG_WEAPON );
2753 break;
2754 case DEVISTATOR_WEAPON:
2755 if( p->ammo_amount[DEVISTATOR_WEAPON] == 0 && p->show_empty_weapon == 0 )
2756 {
2757 p->last_full_weapon = p->curr_weapon;
2758 p->show_empty_weapon = 32;
2759 }
2760 addweapon( p, DEVISTATOR_WEAPON );
2761 break;
2762 case FREEZE_WEAPON:
2763 if( p->ammo_amount[FREEZE_WEAPON] == 0 && p->show_empty_weapon == 0)
2764 {
2765 p->last_full_weapon = p->curr_weapon;
2766 p->show_empty_weapon = 32;
2767 }
2768 addweapon( p, FREEZE_WEAPON );
2769 break;
2770 case GROW_WEAPON:
2771 case SHRINKER_WEAPON:
2772
2773 if( p->ammo_amount[j] == 0 && p->show_empty_weapon == 0)
2774 {
2775 p->show_empty_weapon = 32;
2776 p->last_full_weapon = p->curr_weapon;
2777 }
2778
2779 addweapon(p, j);
2780 break;
2781 case HANDREMOTE_WEAPON:
2782 if(k >= 0) // Found in list of [1]'s
2783 {
2784 p->curr_weapon = HANDREMOTE_WEAPON;
2785 p->last_weapon = -1;
2786 p->weapon_pos = 10;
2787 }
2788 break;
2789 case HANDBOMB_WEAPON:
2790 if( p->ammo_amount[HANDBOMB_WEAPON] > 0 && p->gotweapon[HANDBOMB_WEAPON] )
2791 addweapon( p, HANDBOMB_WEAPON );
2792 break;
2793 case TRIPBOMB_WEAPON:
2794 if( p->ammo_amount[TRIPBOMB_WEAPON] > 0 && p->gotweapon[TRIPBOMB_WEAPON] )
2795 addweapon( p, TRIPBOMB_WEAPON );
2796 break;
2797 }
2798 }
2799
2800 if( sb_snum&(1<<19) )
2801 {
2802 if( p->curr_weapon > KNEE_WEAPON )
2803 {
2804 if(p->holster_weapon == 0 && p->weapon_pos == 0)
2805 {
2806 p->holster_weapon = 1;
2807 p->weapon_pos = -1;
2808 FTA(73,p,1);
2809 }
2810 else if(p->holster_weapon == 1 && p->weapon_pos == -9)
2811 {
2812 p->holster_weapon = 0;
2813 p->weapon_pos = 10;
2814 FTA(74,p,1);
2815 }
2816 }
2817 }
2818 }
2819
2820 if( sb_snum&(1<<24) && p->newowner == -1 )
2821 {
2822 if( p->holoduke_on == -1 )
2823 {
2824
2825 if( p->holoduke_amount > 0 )
2826 {
2827 p->inven_icon = 3;
2828
2829 p->holoduke_on = i =
2830 EGS(p->cursectnum,
2831 p->posx,
2832 p->posy,
2833 p->posz+(30<<8),APLAYER,-64,0,0,p->ang,0,0,-1,10);
2834 T4 = T5 = 0;
2835 SP = snum;
2836 sprite[i].extra = 0;
2837 FTA(47,p,0);
2838 }
2839 else FTA(49,p,0);
2840 spritesound(TELEPORTER,p->holoduke_on);
2841
2842 }
2843 else
2844 {
2845 spritesound(TELEPORTER,p->holoduke_on);
2846 p->holoduke_on = -1;
2847 FTA(48,p,0);
2848 }
2849 }
2850
2851 if( sb_snum&(1<<16) )
2852 {
2853 if( p->firstaid_amount > 0 && sprite[p->i].extra < max_player_health )
2854 {
2855 j = max_player_health-sprite[p->i].extra;
2856
2857 if(p->firstaid_amount > j)
2858 {
2859 p->firstaid_amount -= j;
2860 sprite[p->i].extra = max_player_health;
2861 p->inven_icon = 1;
2862 }
2863 else
2864 {
2865 sprite[p->i].extra += p->firstaid_amount;
2866 p->firstaid_amount = 0;
2867 checkavailinven(p);
2868 }
2869 spritesound(DUKE_USEMEDKIT,p->i);
2870 }
2871 }
2872
2873 if( sb_snum&(1<<25) && p->newowner == -1)
2874 {
2875 if( p->jetpack_amount > 0 )
2876 {
2877 p->jetpack_on = !p->jetpack_on;
2878 if(p->jetpack_on)
2879 {
2880 p->inven_icon = 4;
2881 if(p->scream_voice > FX_Ok)
2882 {
2883 FX_StopSound(p->scream_voice);
2884 testcallback(DUKE_SCREAM);
2885 p->scream_voice = FX_Ok;
2886 }
2887
2888 spritesound(DUKE_JETPACK_ON,p->i);
2889
2890 FTA(52,p,0);
2891 }
2892 else
2893 {
2894 p->hard_landing = 0;
2895 p->poszv = 0;
2896 spritesound(DUKE_JETPACK_OFF,p->i);
2897 stopsound(DUKE_JETPACK_IDLE);
2898 stopsound(DUKE_JETPACK_ON);
2899 FTA(53,p,0);
2900 }
2901 }
2902 else FTA(50,p,0);
2903 }
2904
2905 if(sb_snum&(1<<28) && p->one_eighty_count == 0)
2906 p->one_eighty_count = -1024;
2907 }
2908}
2909
2910void checksectors(short snum)
2911{
2912 int32_t i = -1,oldz;
2913 struct player_struct *p;
2914 short j,hitscanwall;
2915
2916 p = &ps[snum];
2917
2918 switch(sector[p->cursectnum].lotag)
2919 {
2920
2921 case 32767:
2922 sector[p->cursectnum].lotag = 0;
2923 FTA(9,p,0); // secret place found
2924 p->secret_rooms++;
2925 return;
2926 case -1:
2927 for(i=connecthead;i>=0;i=connectpoint2[i])
2928 ps[i].gm = MODE_EOL;
2929 sector[p->cursectnum].lotag = 0;
2930 if(ud.from_bonus)
2931 {
2932 ud.level_number = ud.from_bonus;
2933 ud.m_level_number = ud.level_number;
2934 ud.from_bonus = 0;
2935 }
2936 else
2937 {
2938 ud.level_number++;
2939 if( (ud.volume_number && ud.level_number > 10 ) || ud.level_number > 5 )
2940 ud.level_number = 0;
2941 ud.m_level_number = ud.level_number;
2942 }
2943 return;
2944 case -2:
2945 sector[p->cursectnum].lotag = 0;
2946 p->timebeforeexit = 26*8;
2947 p->customexitsound = sector[p->cursectnum].hitag;
2948 return;
2949 default:
2950 if(sector[p->cursectnum].lotag >= 10000 && sector[p->cursectnum].lotag < 16383)
2951 {
2952 if(snum == screenpeek || ud.coop == 1 )
2953 spritesound(sector[p->cursectnum].lotag-10000,p->i);
2954 sector[p->cursectnum].lotag = 0;
2955 }
2956 break;
2957
2958 }
2959
2960 //After this point the the player effects the map with space
2961
2962 if(p->gm&MODE_TYPE || sprite[p->i].extra <= 0) return;
2963
2964 if( ud.cashman && sync[snum].bits&(1<<29) )
2965 lotsofmoney(&sprite[p->i],2);
2966
2967 if(p->newowner >= 0)
2968 {
2969 if( klabs(sync[snum].svel) > 768 || klabs(sync[snum].fvel) > 768 )
2970 {
2971 i = -1;
2972 goto CLEARCAMERAS;
2973 }
2974 }
2975
2976 if( !(sync[snum].bits&(1<<29)) && !(sync[snum].bits&(1<<31)))
2977 p->toggle_key_flag = 0;
2978
2979 else if(!p->toggle_key_flag)
2980 {
2981
2982 if( (sync[snum].bits&(1<<31)) )
2983 {
2984 if( p->newowner >= 0 )
2985 {
2986 i = -1;
2987 goto CLEARCAMERAS;
2988 }
2989 return;
2990 }
2991
2992 neartagsprite = -1;
2993 p->toggle_key_flag = 1;
2994 hitscanwall = -1;
2995
2996 i = hitawall(p,&hitscanwall);
2997
2998 if(i < 1280 && hitscanwall >= 0 && wall[hitscanwall].overpicnum == MIRROR)
2999 if( wall[hitscanwall].lotag > 0 && Sound[wall[hitscanwall].lotag].num == 0 && snum == screenpeek)
3000 {
3001 spritesound(wall[hitscanwall].lotag,p->i);
3002 return;
3003 }
3004
3005 if(hitscanwall >= 0 && (wall[hitscanwall].cstat&16) )
3006 switch(wall[hitscanwall].overpicnum)
3007 {
3008 default:
3009 if(wall[hitscanwall].lotag)
3010 return;
3011 }
3012
3013 if(p->newowner >= 0)
3014 neartag(p->oposx,p->oposy,p->oposz,sprite[p->i].sectnum,p->oang,&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1280L,1);
3015 else
3016 {
3017 neartag(p->posx,p->posy,p->posz,sprite[p->i].sectnum,p->oang,&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1280L,1);
3018 if(neartagsprite == -1 && neartagwall == -1 && neartagsector == -1)
3019 neartag(p->posx,p->posy,p->posz+(8<<8),sprite[p->i].sectnum,p->oang,&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1280L,1);
3020 if(neartagsprite == -1 && neartagwall == -1 && neartagsector == -1)
3021 neartag(p->posx,p->posy,p->posz+(16<<8),sprite[p->i].sectnum,p->oang,&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1280L,1);
3022 if(neartagsprite == -1 && neartagwall == -1 && neartagsector == -1)
3023 {
3024 neartag(p->posx,p->posy,p->posz+(16<<8),sprite[p->i].sectnum,p->oang,&neartagsector,&neartagwall,&neartagsprite,&neartaghitdist,1280L,3);
3025 if(neartagsprite >= 0)
3026 {
3027 switch(sprite[neartagsprite].picnum)
3028 {
3029 case FEM1:
3030 case FEM2:
3031 case FEM3:
3032 case FEM4:
3033 case FEM5:
3034 case FEM6:
3035 case FEM7:
3036 case FEM8:
3037 case FEM9:
3038 case FEM10:
3039 case PODFEM1:
3040 case NAKED1:
3041 case STATUE:
3042 case TOUGHGAL:
3043 return;
3044 }
3045 }
3046
3047 neartagsprite = -1;
3048 neartagwall = -1;
3049 neartagsector = -1;
3050 }
3051 }
3052
3053 if(p->newowner == -1 && neartagsprite == -1 && neartagsector == -1 && neartagwall == -1 )
3054 if( isanunderoperator(sector[sprite[p->i].sectnum].lotag) )
3055 neartagsector = sprite[p->i].sectnum;
3056
3057 if( neartagsector >= 0 && (sector[neartagsector].lotag&16384) )
3058 return;
3059
3060 if( neartagsprite == -1 && neartagwall == -1)
3061 if(sector[p->cursectnum].lotag == 2 )
3062 {
3063 oldz = hitasprite(p->i,&neartagsprite);
3064 if(oldz > 1280) neartagsprite = -1;
3065 }
3066
3067 if(neartagsprite >= 0)
3068 {
3069 if( checkhitswitch(snum,neartagsprite,1) ) return;
3070
3071 switch(sprite[neartagsprite].picnum)
3072 {
3073 case TOILET:
3074 case STALL:
3075 if(p->last_pissed_time == 0)
3076 {
3077 if(ud.lockout == 0) spritesound(DUKE_URINATE,p->i);
3078
3079 p->last_pissed_time = 26*220;
3080 p->transporter_hold = 29*2;
3081 if(p->holster_weapon == 0)
3082 {
3083 p->holster_weapon = 1;
3084 p->weapon_pos = -1;
3085 }
3086 if(sprite[p->i].extra <= (max_player_health-(max_player_health/10) ) )
3087 {
3088 sprite[p->i].extra += max_player_health/10;
3089 p->last_extra = sprite[p->i].extra;
3090 }
3091 else if(sprite[p->i].extra < max_player_health )
3092 sprite[p->i].extra = max_player_health;
3093 }
3094 else if(Sound[FLUSH_TOILET].num == 0)
3095 spritesound(FLUSH_TOILET,p->i);
3096 return;
3097
3098 case NUKEBUTTON:
3099
3100 hitawall(p,&j);
3101 if(j >= 0 && wall[j].overpicnum == 0)
3102 if(hittype[neartagsprite].temp_data[0] == 0)
3103 {
3104 hittype[neartagsprite].temp_data[0] = 1;
3105 sprite[neartagsprite].owner = p->i;
3106 p->buttonpalette = sprite[neartagsprite].pal;
3107 if(p->buttonpalette)
3108 ud.secretlevel = sprite[neartagsprite].lotag;
3109 else ud.secretlevel = 0;
3110 }
3111 return;
3112 case WATERFOUNTAIN:
3113 if(hittype[neartagsprite].temp_data[0] != 1)
3114 {
3115 hittype[neartagsprite].temp_data[0] = 1;
3116 sprite[neartagsprite].owner = p->i;
3117
3118 if(sprite[p->i].extra < max_player_health)
3119 {
3120 sprite[p->i].extra++;
3121 spritesound(DUKE_DRINKING,p->i);
3122 }
3123 }
3124 return;
3125 case PLUG:
3126 spritesound(SHORT_CIRCUIT,p->i);
3127 sprite[p->i].extra -= 2+(TRAND&3);
3128 p->pals[0] = 48;
3129 p->pals[1] = 48;
3130 p->pals[2] = 64;
3131 p->pals_time = 32;
3132 break;
3133 case VIEWSCREEN:
3134 case VIEWSCREEN2:
3135 {
3136 i = headspritestat[1];
3137
3138 while(i >= 0)
3139 {
3140 if( PN == CAMERA1 && SP == 0 && sprite[neartagsprite].hitag == SLT )
3141 {
3142 SP = 1; //Using this camera
3143 spritesound(MONITOR_ACTIVE,neartagsprite);
3144
3145 sprite[neartagsprite].owner = i;
3146 sprite[neartagsprite].yvel = 1;
3147
3148
3149 j = p->cursectnum;
3150 p->cursectnum = SECT;
3151 setpal(p);
3152 p->cursectnum = j;
3153
3154 // parallaxtype = 2;
3155 p->newowner = i;
3156 return;
3157 }
3158 i = nextspritestat[i];
3159 }
3160 }
3161
3162 CLEARCAMERAS:
3163
3164 if(i < 0)
3165 {
3166 p->posx = p->oposx;
3167 p->posy = p->oposy;
3168 p->posz = p->oposz;
3169 p->ang = p->oang;
3170 p->newowner = -1;
3171
3172 updatesector(p->posx,p->posy,&p->cursectnum);
3173 setpal(p);
3174
3175
3176 i = headspritestat[1];
3177 while(i >= 0)
3178 {
3179 if(PN==CAMERA1) SP = 0;
3180 i = nextspritestat[i];
3181 }
3182 }
3183 else if(p->newowner >= 0)
3184 p->newowner = -1;
3185
3186 if( KB_KeyPressed(sc_Escape) )
3187 KB_ClearKeyDown(sc_Escape);
3188
3189 return;
3190 }
3191 }
3192
3193 if( (sync[snum].bits&(1<<29)) == 0 ) return;
3194 else if(p->newowner >= 0) { i = -1; goto CLEARCAMERAS; }
3195
3196 if(neartagwall == -1 && neartagsector == -1 && neartagsprite == -1)
3197 if( klabs(hits(p->i)) < 512 )
3198 {
3199 if( (TRAND&255) < 16 )
3200 spritesound(DUKE_SEARCH2,p->i);
3201 else spritesound(DUKE_SEARCH,p->i);
3202 return;
3203 }
3204
3205 if( neartagwall >= 0 )
3206 {
3207 if( wall[neartagwall].lotag > 0 && isadoorwall(wall[neartagwall].picnum) )
3208 {
3209 if(hitscanwall == neartagwall || hitscanwall == -1)
3210 checkhitswitch(snum,neartagwall,0);
3211 return;
3212 }
3213 else if(p->newowner >= 0)
3214 {
3215 i = -1;
3216 goto CLEARCAMERAS;
3217 }
3218 }
3219
3220 if( neartagsector >= 0 && (sector[neartagsector].lotag&16384) == 0 && isanearoperator(sector[neartagsector].lotag) )
3221 {
3222 i = headspritesect[neartagsector];
3223 while(i >= 0)
3224 {
3225 if( PN == ACTIVATOR || PN == MASTERSWITCH )
3226 return;
3227 i = nextspritesect[i];
3228 }
3229 operatesectors(neartagsector,p->i);
3230 }
3231 else if( (sector[sprite[p->i].sectnum].lotag&16384) == 0 )
3232 {
3233 if( isanunderoperator(sector[sprite[p->i].sectnum].lotag) )
3234 {
3235 i = headspritesect[sprite[p->i].sectnum];
3236 while(i >= 0)
3237 {
3238 if(PN == ACTIVATOR || PN == MASTERSWITCH) return;
3239 i = nextspritesect[i];
3240 }
3241 operatesectors(sprite[p->i].sectnum,p->i);
3242 }
3243 else checkhitswitch(snum,neartagwall,0);
3244 }
3245 }
3246}
3247
3248
3249
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/sounddebugdefs.h b/apps/plugins/sdl/progs/duke3d/Game/src/sounddebugdefs.h
new file mode 100644
index 0000000000..f9c4979f95
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/sounddebugdefs.h
@@ -0,0 +1,8 @@
1#ifndef _SOUND_DEBUG_DEFS_H_
2#define _SOUND_DEBUG_DEFS_H_
3
4extern uint32_t sounddebugActiveSounds;
5extern uint32_t sounddebugAllocateSoundCalls;
6extern uint32_t sounddebugDeallocateSoundCalls;
7
8#endif \ No newline at end of file
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/soundefs.h b/apps/plugins/sdl/progs/duke3d/Game/src/soundefs.h
new file mode 100644
index 0000000000..e9fefdb2e5
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/soundefs.h
@@ -0,0 +1,1233 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#define SECTOREFFECTOR 1
28#define ACTIVATOR 2
29#define TOUCHPLATE 3
30#define ACTIVATORLOCKED 4
31#define MUSICANDSFX 5
32#define LOCATORS 6
33#define CYCLER 7
34#define MASTERSWITCH 8
35#define RESPAWN 9
36#define GPSPEED 10
37#define ARROW 20
38#define FIRSTGUNSPRITE 21
39#define CHAINGUNSPRITE 22
40#define RPGSPRITE 23
41#define FREEZESPRITE 24
42#define SHRINKERSPRITE 25
43#define HEAVYHBOMB 26
44#define TRIPBOMBSPRITE 27
45#define SHOTGUNSPRITE 28
46#define DEVISTATORSPRITE 29
47#define HEALTHBOX 30
48#define AMMOBOX 31
49#define INVENTORYBOX 33
50#define FREEZEAMMO 37
51#define AMMO 40
52#define BATTERYAMMO 41
53#define DEVISTATORAMMO 42
54#define RPGAMMO 44
55#define GROWAMMO 45
56#define CRYSTALAMMO 46
57#define HBOMBAMMO 47
58#define AMMOLOTS 48
59#define SHOTGUNAMMO 49
60#define COLA 51
61#define SIXPAK 52
62#define FIRSTAID 53
63#define SHIELD 54
64#define STEROIDS 55
65#define AIRTANK 56
66#define JETPACK 57
67#define HEATSENSOR 59
68#define ACCESSCARD 60
69#define BOOTS 61
70#define MIRRORBROKE 70
71#define CLOUDYOCEAN 78
72#define CLOUDYSKIES 79
73#define MOONSKY1 80
74#define MOONSKY2 81
75#define MOONSKY3 82
76#define MOONSKY4 83
77#define BIGORBIT1 84
78#define BIGORBIT2 85
79#define BIGORBIT3 86
80#define BIGORBIT4 87
81#define BIGORBIT5 88
82#define LA 89
83#define REDSKY1 98
84#define REDSKY2 99
85#define ATOMICHEALTH 100
86#define TECHLIGHT2 120
87#define TECHLIGHTBUST2 121
88#define TECHLIGHT4 122
89#define TECHLIGHTBUST4 123
90#define WALLLIGHT4 124
91#define WALLLIGHTBUST4 125
92#define ACCESSSWITCH 130
93#define SLOTDOOR 132
94#define LIGHTSWITCH 134
95#define SPACEDOORSWITCH 136
96#define SPACELIGHTSWITCH 138
97#define FRANKENSTINESWITCH 140
98#define NUKEBUTTON 142
99#define MULTISWITCH 146
100#define DOORTILE5 150
101#define DOORTILE6 151
102#define DOORTILE1 152
103#define DOORTILE2 153
104#define DOORTILE3 154
105#define DOORTILE4 155
106#define DOORTILE7 156
107#define DOORTILE8 157
108#define DOORTILE9 158
109#define DOORTILE10 159
110#define DOORSHOCK 160
111#define DIPSWITCH 162
112#define DIPSWITCH2 164
113#define TECHSWITCH 166
114#define DIPSWITCH3 168
115#define ACCESSSWITCH2 170
116#define REFLECTWATERTILE 180
117#define FLOORSLIME 200
118#define BIGFORCE 230
119#define EPISODE 247
120#define MASKWALL9 255
121#define W_LIGHT 260
122#define SCREENBREAK1 263
123#define SCREENBREAK2 264
124#define SCREENBREAK3 265
125#define SCREENBREAK4 266
126#define SCREENBREAK5 267
127#define SCREENBREAK6 268
128#define SCREENBREAK7 269
129#define SCREENBREAK8 270
130#define SCREENBREAK9 271
131#define SCREENBREAK10 272
132#define SCREENBREAK11 273
133#define SCREENBREAK12 274
134#define SCREENBREAK13 275
135#define MASKWALL1 285
136#define W_TECHWALL1 293
137#define W_TECHWALL2 297
138#define W_TECHWALL15 299
139#define W_TECHWALL3 301
140#define W_TECHWALL4 305
141#define W_TECHWALL10 306
142#define W_TECHWALL16 307
143#define WATERTILE2 336
144#define BPANNEL1 341
145#define PANNEL1 342
146#define PANNEL2 343
147#define WATERTILE 344
148#define STATIC 351
149#define W_SCREENBREAK 357
150#define W_HITTECHWALL3 360
151#define W_HITTECHWALL4 361
152#define W_HITTECHWALL2 362
153#define W_HITTECHWALL1 363
154#define MASKWALL10 387
155#define MASKWALL11 391
156#define DOORTILE22 395
157#define FANSPRITE 407
158#define FANSPRITEBROKE 411
159#define FANSHADOW 412
160#define FANSHADOWBROKE 416
161#define DOORTILE18 447
162#define DOORTILE19 448
163#define DOORTILE20 449
164// #define SPACESHUTTLE 487
165#define SATELLITE 489
166#define VIEWSCREEN2 499
167#define VIEWSCREENBROKE 501
168#define VIEWSCREEN 502
169#define GLASS 503
170#define GLASS2 504
171#define STAINGLASS1 510
172#define MASKWALL5 514
173#define SATELITE 516
174#define FUELPOD 517
175#define SLIMEPIPE 538
176#define CRACK1 546
177#define CRACK2 547
178#define CRACK3 548
179#define CRACK4 549
180#define FOOTPRINTS 550
181#define DOMELITE 551
182#define CAMERAPOLE 554
183#define CHAIR1 556
184#define CHAIR2 557
185#define BROKENCHAIR 559
186#define MIRROR 560
187#define WATERFOUNTAIN 563
188#define WATERFOUNTAINBROKE 567
189#define FEMMAG1 568
190#define TOILET 569
191#define STALL 571
192#define STALLBROKE 573
193#define FEMMAG2 577
194#define REACTOR2 578
195#define REACTOR2BURNT 579
196#define REACTOR2SPARK 580
197#define GRATE1 595
198#define BGRATE1 596
199#define SOLARPANNEL 602
200#define NAKED1 603
201#define ANTENNA 607
202#define MASKWALL12 609
203#define TOILETBROKE 615
204#define PIPE2 616
205#define PIPE1B 617
206#define PIPE3 618
207#define PIPE1 619
208#define CAMERA1 621
209#define BRICK 626
210#define SPLINTERWOOD 630
211#define PIPE2B 633
212#define BOLT1 634
213#define W_NUMBERS 640
214#define WATERDRIP 660
215#define WATERBUBBLE 661
216#define WATERBUBBLEMAKER 662
217#define W_FORCEFIELD 663
218#define VACUUM 669
219#define FOOTPRINTS2 672
220#define FOOTPRINTS3 673
221#define FOOTPRINTS4 674
222#define EGG 675
223#define SCALE 678
224#define CHAIR3 680
225#define CAMERALIGHT 685
226#define MOVIECAMERA 686
227#define IVUNIT 689
228#define POT1 694
229#define POT2 695
230#define POT3 697
231#define PIPE3B 700
232#define WALLLIGHT3 701
233#define WALLLIGHTBUST3 702
234#define WALLLIGHT1 703
235#define WALLLIGHTBUST1 704
236#define WALLLIGHT2 705
237#define WALLLIGHTBUST2 706
238#define LIGHTSWITCH2 712
239#define WAITTOBESEATED 716
240#define DOORTILE14 717
241#define STATUE 753
242#define MIKE 762
243#define VASE 765
244#define SUSHIPLATE1 768
245#define SUSHIPLATE2 769
246#define SUSHIPLATE3 774
247#define SUSHIPLATE4 779
248#define DOORTILE16 781
249#define SUSHIPLATE5 792
250#define OJ 806
251#define MASKWALL13 830
252#define HURTRAIL 859
253#define POWERSWITCH1 860
254#define LOCKSWITCH1 862
255#define POWERSWITCH2 864
256#define ATM 867
257#define STATUEFLASH 869
258#define ATMBROKE 888
259#define BIGHOLE2 893
260#define STRIPEBALL 901
261#define QUEBALL 902
262#define POCKET 903
263#define WOODENHORSE 904
264#define TREE1 908
265#define TREE2 910
266#define CACTUS 911
267#define MASKWALL2 913
268#define MASKWALL3 914
269#define MASKWALL4 915
270#define FIREEXT 916
271#define TOILETWATER 921
272#define NEON1 925
273#define NEON2 926
274#define CACTUSBROKE 939
275#define BOUNCEMINE 940
276#define BROKEFIREHYDRENT 950
277#define BOX 951
278#define BULLETHOLE 952
279#define BOTTLE1 954
280#define BOTTLE2 955
281#define BOTTLE3 956
282#define BOTTLE4 957
283#define FEMPIC5 963
284#define FEMPIC6 964
285#define FEMPIC7 965
286#define HYDROPLANT 969
287#define OCEANSPRITE1 971
288#define OCEANSPRITE2 972
289#define OCEANSPRITE3 973
290#define OCEANSPRITE4 974
291#define OCEANSPRITE5 975
292#define GENERICPOLE 977
293#define CONE 978
294#define HANGLIGHT 979
295#define HYDRENT 981
296#define MASKWALL14 988
297#define TIRE 990
298#define PIPE5 994
299#define PIPE6 995
300#define PIPE4 996
301#define PIPE4B 997
302#define BROKEHYDROPLANT 1003
303#define PIPE5B 1005
304#define NEON3 1007
305#define NEON4 1008
306#define NEON5 1009
307#define BOTTLE5 1012
308#define BOTTLE6 1013
309#define BOTTLE8 1014
310#define SPOTLITE 1020
311#define HANGOOZ 1022
312#define MASKWALL15 1024
313#define BOTTLE7 1025
314#define HORSEONSIDE 1026
315#define GLASSPIECES 1031
316#define HORSELITE 1034
317#define DONUTS 1045
318#define NEON6 1046
319#define MASKWALL6 1059
320#define CLOCK 1060
321#define RUBBERCAN 1062
322#define BROKENCLOCK 1067
323#define PLUG 1069
324#define OOZFILTER 1079
325#define FLOORPLASMA 1082
326#define REACTOR 1088
327#define REACTORSPARK 1092
328#define REACTORBURNT 1096
329#define DOORTILE15 1102
330#define HANDSWITCH 1111
331#define CIRCLEPANNEL 1113
332#define CIRCLEPANNELBROKE 1114
333#define PULLSWITCH 1122
334#define MASKWALL8 1124
335#define BIGHOLE 1141
336#define ALIENSWITCH 1142
337#define DOORTILE21 1144
338#define HANDPRINTSWITCH 1155
339#define BOTTLE10 1157
340#define BOTTLE11 1158
341#define BOTTLE12 1159
342#define BOTTLE13 1160
343#define BOTTLE14 1161
344#define BOTTLE15 1162
345#define BOTTLE16 1163
346#define BOTTLE17 1164
347#define BOTTLE18 1165
348#define BOTTLE19 1166
349#define DOORTILE17 1169
350#define MASKWALL7 1174
351#define JAILBARBREAK 1175
352#define DOORTILE11 1178
353#define DOORTILE12 1179
354#define VENDMACHINE 1212
355#define VENDMACHINEBROKE 1214
356#define COLAMACHINE 1215
357#define COLAMACHINEBROKE 1217
358#define CRANEPOLE 1221
359#define CRANE 1222
360#define BARBROKE 1225
361#define BLOODPOOL 1226
362#define NUKEBARREL 1227
363#define NUKEBARRELDENTED 1228
364#define NUKEBARRELLEAKED 1229
365#define CANWITHSOMETHING 1232
366#define MONEY 1233
367#define BANNER 1236
368#define EXPLODINGBARREL 1238
369#define EXPLODINGBARREL2 1239
370#define FIREBARREL 1240
371#define SEENINE 1247
372#define SEENINEDEAD 1248
373#define STEAM 1250
374#define CEILINGSTEAM 1255
375#define PIPE6B 1260
376#define TRANSPORTERBEAM 1261
377#define RAT 1267
378#define TRASH 1272
379#define FEMPIC1 1280
380#define FEMPIC2 1289
381#define BLANKSCREEN 1293
382#define PODFEM1 1294
383#define FEMPIC3 1298
384#define FEMPIC4 1306
385#define FEM1 1312
386#define FEM2 1317
387#define FEM3 1321
388#define FEM5 1323
389#define BLOODYPOLE 1324
390#define FEM4 1325
391#define FEM6 1334
392#define FEM6PAD 1335
393#define FEM8 1336
394#define HELECOPT 1346
395#define FETUSJIB 1347
396#define HOLODUKE 1348
397#define SPACEMARINE 1353
398#define INDY 1355
399#define FETUS 1358
400#define FETUSBROKE 1359
401#define MONK 1352
402#define LUKE 1354
403#define COOLEXPLOSION1 1360
404#define WATERSPLASH2 1380
405#define FIREVASE 1390
406#define SCRATCH 1393
407#define FEM7 1395
408#define APLAYERTOP 1400
409#define APLAYER 1405
410#define PLAYERONWATER 1420
411#define DUKELYINGDEAD 1518
412#define DUKETORSO 1520
413#define DUKEGUN 1528
414#define DUKELEG 1536
415#define SHARK 1550
416#define BLOOD 1620
417#define FIRELASER 1625
418#define TRANSPORTERSTAR 1630
419#define SPIT 1636
420#define LOOGIE 1637
421#define FIST 1640
422#define FREEZEBLAST 1641
423#define DEVISTATORBLAST 1642
424#define SHRINKSPARK 1646
425#define TONGUE 1647
426#define MORTER 1650
427#define SHRINKEREXPLOSION 1656
428#define RADIUSEXPLOSION 1670
429#define FORCERIPPLE 1671
430#define LIZTROOP 1680
431#define LIZTROOPRUNNING 1681
432#define LIZTROOPSTAYPUT 1682
433#define LIZTOP 1705
434#define LIZTROOPSHOOT 1715
435#define LIZTROOPJETPACK 1725
436#define LIZTROOPDSPRITE 1734
437#define LIZTROOPONTOILET 1741
438#define LIZTROOPJUSTSIT 1742
439#define LIZTROOPDUCKING 1744
440#define HEADJIB1 1768
441#define ARMJIB1 1772
442#define LEGJIB1 1776
443#define CANNONBALL 1817
444#define OCTABRAIN 1820
445#define OCTABRAINSTAYPUT 1821
446#define OCTATOP 1845
447#define OCTADEADSPRITE 1855
448#define INNERJAW 1860
449#define DRONE 1880
450#define EXPLOSION2 1890
451#define COMMANDER 1920
452#define COMMANDERSTAYPUT 1921
453#define RECON 1960
454#define TANK 1975
455#define PIGCOP 2000
456#define PIGCOPSTAYPUT 2001
457#define PIGCOPDIVE 2045
458#define PIGCOPDEADSPRITE 2060
459#define PIGTOP 2061
460#define LIZMAN 2120
461#define LIZMANSTAYPUT 2121
462#define LIZMANSPITTING 2150
463#define LIZMANFEEDING 2160
464#define LIZMANJUMP 2165
465#define LIZMANDEADSPRITE 2185
466#define FECES 2200
467#define LIZMANHEAD1 2201
468#define LIZMANARM1 2205
469#define LIZMANLEG1 2209
470#define EXPLOSION2BOT 2219
471#define USERWEAPON 2235
472#define HEADERBAR 2242
473#define JIBS1 2245
474#define JIBS2 2250
475#define JIBS3 2255
476#define JIBS4 2260
477#define JIBS5 2265
478#define BURNING 2270
479#define FIRE 2271
480#define JIBS6 2286
481#define BLOODSPLAT1 2296
482#define BLOODSPLAT3 2297
483#define BLOODSPLAT2 2298
484#define BLOODSPLAT4 2299
485#define OOZ 2300
486#define OOZ2 2309
487#define WALLBLOOD1 2301
488#define WALLBLOOD2 2302
489#define WALLBLOOD3 2303
490#define WALLBLOOD4 2304
491#define WALLBLOOD5 2305
492#define WALLBLOOD6 2306
493#define WALLBLOOD7 2307
494#define WALLBLOOD8 2308
495#define BURNING2 2310
496#define FIRE2 2311
497#define CRACKKNUCKLES 2324
498#define SMALLSMOKE 2329
499#define SMALLSMOKEMAKER 2330
500#define FLOORFLAME 2333
501#define ROTATEGUN 2360
502#define GREENSLIME 2370
503#define WATERDRIPSPLASH 2380
504#define SCRAP6 2390
505#define SCRAP1 2400
506#define SCRAP2 2404
507#define SCRAP3 2408
508#define SCRAP4 2412
509#define SCRAP5 2416
510#define ORGANTIC 2420
511#define BETAVERSION 2440
512#define PLAYERISHERE 2442
513#define PLAYERWASHERE 2443
514#define SELECTDIR 2444
515#define F1HELP 2445
516#define NOTCHON 2446
517#define NOTCHOFF 2447
518#define GROWSPARK 2448
519#define DUKEICON 2452
520#define BADGUYICON 2453
521#define FOODICON 2454
522#define GETICON 2455
523#define MENUSCREEN 2456
524#define MENUBAR 2457
525#define KILLSICON 2458
526#define FIRSTAID_ICON 2460
527#define HEAT_ICON 2461
528#define BOTTOMSTATUSBAR 2462
529#define BOOT_ICON 2463
530#define FRAGBAR 2465
531#define JETPACK_ICON 2467
532#define AIRTANK_ICON 2468
533#define STEROIDS_ICON 2469
534#define HOLODUKE_ICON 2470
535#define ACCESS_ICON 2471
536#define DIGITALNUM 2472
537#define DUKECAR 2491
538#define CAMCORNER 2482
539#define CAMLIGHT 2484
540#define LOGO 2485
541#define TITLE 2486
542#define NUKEWARNINGICON 2487
543#define MOUSECURSOR 2488
544#define SLIDEBAR 2489
545#define DREALMS 2492
546#define BETASCREEN 2493
547#define WINDOWBORDER1 2494
548#define TEXTBOX 2495
549#define WINDOWBORDER2 2496
550#define DUKENUKEM 2497
551#define THREEDEE 2498
552#define INGAMEDUKETHREEDEE 2499
553#define TENSCREEN 2500
554#define PLUTOPAKSPRITE 2501
555#define DEVISTATOR 2510
556#define KNEE 2521
557#define CROSSHAIR 2523
558#define FIRSTGUN 2524
559#define FIRSTGUNRELOAD 2528
560#define FALLINGCLIP 2530
561#define CLIPINHAND 2531
562#define HAND 2532
563#define SHELL 2533
564#define SHOTGUNSHELL 2535
565#define CHAINGUN 2536
566#define RPGGUN 2544
567#define RPGMUZZLEFLASH 2545
568#define FREEZE 2548
569#define CATLITE 2552
570#define SHRINKER 2556
571#define HANDHOLDINGLASER 2563
572#define TRIPBOMB 2566
573#define LASERLINE 2567
574#define HANDHOLDINGACCESS 2568
575#define HANDREMOTE 2570
576#define HANDTHROW 2573
577#define TIP 2576
578#define GLAIR 2578
579#define SCUBAMASK 2581
580#define SPACEMASK 2584
581#define FORCESPHERE 2590
582#define SHOTSPARK1 2595
583#define RPG 2605
584#define LASERSITE 2612
585#define SHOTGUN 2613
586#define BOSS1 2630
587#define BOSS1STAYPUT 2631
588#define BOSS1SHOOT 2660
589#define BOSS1LOB 2670
590#define BOSSTOP 2696
591#define BOSS2 2710
592#define BOSS3 2760
593#define SPINNINGNUKEICON 2813
594#define BIGFNTCURSOR 2820
595#define SMALLFNTCURSOR 2821
596#define STARTALPHANUM 2822
597#define ENDALPHANUM 2915
598#define BIGALPHANUM 2940
599#define BIGPERIOD 3002
600#define BIGCOMMA 3003
601#define BIGX 3004
602#define BIGQ 3005
603#define BIGSEMI 3006
604#define BIGCOLIN 3007
605#define THREEBYFIVE 3010
606#define BIGAPPOS 3022
607#define BLANK 3026
608#define MINIFONT 3072
609#define BUTTON1 3164
610#define GLASS3 3187
611#define RESPAWNMARKERRED 3190
612#define RESPAWNMARKERYELLOW 3200
613#define RESPAWNMARKERGREEN 3210
614#define BONUSSCREEN 3240
615#define VIEWBORDER 3250
616#define VICTORY1 3260
617#define ORDERING 3270
618#define TEXTSTORY 3280
619#define LOADSCREEN 3281
620#define BORNTOBEWILDSCREEN 3370
621#define BLIMP 3400
622#define FEM9 3450
623#define FOOTPRINT 3701
624#define POOP 4094
625#define FRAMEEFFECT1 4095
626// FIX_00037: steroids trigger a too many sprite respawn in 1.3 and 1.3d.
627#define FRAMEEFFECT1_13CON 3999 // Needed to ensure 1.3/1.3d compliance --mk
628#define PANNEL3 4099
629#define SCREENBREAK19 4125
630#define W_TECHWALL11 4130
631#define W_TECHWALL12 4131
632#define W_TECHWALL13 4132
633#define W_TECHWALL14 4133
634#define SCREENBREAK14 4120
635#define SCREENBREAK15 4123
636#define SCREENBREAK16 4127
637#define SCREENBREAK17 4128
638#define SCREENBREAK18 4129
639#define W_TECHWALL5 4134
640#define W_TECHWALL6 4136
641#define W_TECHWALL7 4138
642#define W_TECHWALL8 4140
643#define W_TECHWALL9 4142
644#define BPANNEL3 4100
645#define MIMON 4120
646#define W_HITTECHWALL16 4144
647#define W_HITTECHWALL10 4145
648#define W_HITTECHWALL15 4147
649#define W_MILKSHELF 4181
650#define W_MILKSHELFBROKE 4203
651#define PURPLELAVA 4240
652#define LAVABUBBLE 4340
653#define DUKECUTOUT 4352
654#define TARGET 4359
655#define GUNPOWDERBARREL 4360
656#define DUCK 4361
657#define HATRACK 4367
658#define DESKLAMP 4370
659#define COFFEEMACHINE 4372
660#define CUPS 4373
661#define GAVALS 4374
662#define GAVALS2 4375
663#define POLICELIGHTPOLE 4377
664#define FLOORBASKET 4388
665#define PUKE 4389
666#define DOORTILE23 4391
667#define TOPSECRET 4396
668#define SPEAKER 4397
669#define TEDDYBEAR 4400
670#define ROBOTDOG 4402
671#define ROBOTPIRATE 4404
672#define ROBOTMOUSE 4407
673#define MAIL 4410
674#define MAILBAG 4413
675#define HOTMEAT 4427
676#define COFFEEMUG 4438
677#define DONUTS2 4440
678#define TRIPODCAMERA 4444
679#define METER 4453
680#define DESKPHONE 4454
681#define GUMBALLMACHINE 4458
682#define GUMBALLMACHINEBROKE 4459
683#define PAPER 4460
684#define MACE 4464
685#define GENERICPOLE2 4465
686#define XXXSTACY 4470
687#define WETFLOOR 4495
688#define BROOM 4496
689#define MOP 4497
690#define PIRATE1A 4510
691#define PIRATE4A 4511
692#define PIRATE2A 4512
693#define PIRATE5A 4513
694#define PIRATE3A 4514
695#define PIRATE6A 4515
696#define PIRATEHALF 4516
697#define CHESTOFGOLD 4520
698#define SIDEBOLT1 4525
699#define FOODOBJECT1 4530
700#define FOODOBJECT2 4531
701#define FOODOBJECT3 4532
702#define FOODOBJECT4 4533
703#define FOODOBJECT5 4534
704#define FOODOBJECT6 4535
705#define FOODOBJECT7 4536
706#define FOODOBJECT8 4537
707#define FOODOBJECT9 4538
708#define FOODOBJECT10 4539
709#define FOODOBJECT11 4540
710#define FOODOBJECT12 4541
711#define FOODOBJECT13 4542
712#define FOODOBJECT14 4543
713#define FOODOBJECT15 4544
714#define FOODOBJECT16 4545
715#define FOODOBJECT17 4546
716#define FOODOBJECT18 4547
717#define FOODOBJECT19 4548
718#define FOODOBJECT20 4549
719#define HEADLAMP 4550
720#define TAMPON 4557
721#define SKINNEDCHICKEN 4554
722#define FEATHEREDCHICKEN 4555
723#define ROBOTDOG2 4560
724#define JOLLYMEAL 4569
725#define DUKEBURGER 4570
726#define SHOPPINGCART 4576
727#define CANWITHSOMETHING2 4580
728#define CANWITHSOMETHING3 4581
729#define CANWITHSOMETHING4 4582
730#define SNAKEP 4590
731#define DOLPHIN1 4591
732#define DOLPHIN2 4592
733#define NEWBEAST 4610
734#define NEWBEASTSTAYPUT 4611
735#define NEWBEASTJUMP 4690
736#define NEWBEASTHANG 4670
737#define NEWBEASTHANGDEAD 4671
738#define BOSS4 4740
739#define BOSS4STAYPUT 4741
740#define FEM10 4864
741#define TOUGHGAL 4866
742#define MAN 4871
743#define MAN2 4872
744#define WOMAN 4874
745#define PLEASEWAIT 4887
746#define NATURALLIGHTNING 4890
747#define WEATHERWARN 4893
748#define DUKETAG 4900
749#define SIGN1 4909
750#define SIGN2 4912
751#define JURYGUY 4943
752
753
754
755
756// These tile positions are reserved!
757#define RESERVEDSLOT1 6132
758#define RESERVEDSLOT2 6133
759#define RESERVEDSLOT3 6134
760#define RESERVEDSLOT4 6135
761#define RESERVEDSLOT5 6136
762#define RESERVEDSLOT6 6137
763#define RESERVEDSLOT7 6138
764#define RESERVEDSLOT8 6139
765#define RESERVEDSLOT9 6140
766#define RESERVEDSLOT10 6141
767#define RESERVEDSLOT11 6142
768#define RESERVEDSLOT12 6143
769
770// Defines weapon, not to be used with the 'shoot' keyword.
771
772#define KNEE_WEAPON 0
773#define PISTOL_WEAPON 1
774#define SHOTGUN_WEAPON 2
775#define CHAINGUN_WEAPON 3
776#define RPG_WEAPON 4
777#define HANDBOMB_WEAPON 5
778#define SHRINKER_WEAPON 6
779#define DEVISTATOR_WEAPON 7
780#define TRIPBOMB_WEAPON 8
781#define FREEZE_WEAPON 9
782#define HANDREMOTE_WEAPON 10
783#define GROW_WEAPON 11
784
785// Defines the motion characteristics of an actor
786#define faceplayer 1
787#define geth 2
788#define getv 4
789#define randomangle 8
790#define faceplayerslow 16
791#define spin 32
792#define faceplayersmart 64
793#define fleeenemy 128
794#define jumptoplayer 257
795#define seekplayer 512
796#define furthestdir 1024
797#define dodgebullet 4096
798
799// Some misc #defines
800#define NO 0
801#define YES 1
802
803// Defines for 'useractor' keyword
804#define notenemy 0
805#define enemy 1
806#define enemystayput 2
807
808// Player Actions.
809#define pstanding 1
810#define pwalking 2
811#define prunning 4
812#define pducking 8
813#define pfalling 16
814#define pjumping 32
815#define phigher 64
816#define pwalkingback 128
817#define prunningback 256
818#define pkicking 512
819#define pshrunk 1024
820#define pjetpack 2048
821#define ponsteroids 4096
822#define ponground 8192
823#define palive 16384
824#define pdead 32768
825#define pfacing 65536
826
827
828#define GET_STEROIDS 0
829#define GET_SHIELD 1
830#define GET_SCUBA 2
831#define GET_HOLODUKE 3
832#define GET_JETPACK 4
833#define GET_ACCESS 6
834#define GET_HEATS 7
835#define GET_FIRSTAID 9
836#define GET_BOOTS 10
837
838
839#define KICK_HIT 0
840#define PISTOL_RICOCHET 1
841#define PISTOL_BODYHIT 2
842#define PISTOL_FIRE 3
843#define EJECT_CLIP 4
844#define INSERT_CLIP 5
845#define CHAINGUN_FIRE 6
846#define RPG_SHOOT 7
847#define POOLBALLHIT 8
848#define RPG_EXPLODE 9
849#define CAT_FIRE 10
850#define SHRINKER_FIRE 11
851#define ACTOR_SHRINKING 12
852#define PIPEBOMB_BOUNCE 13
853#define PIPEBOMB_EXPLODE 14
854#define LASERTRIP_ONWALL 15
855#define LASERTRIP_ARMING 16
856#define LASERTRIP_EXPLODE 17
857#define VENT_BUST 18
858#define GLASS_BREAKING 19
859#define GLASS_HEAVYBREAK 20
860#define SHORT_CIRCUIT 21
861#define ITEM_SPLASH 22
862#define DUKE_BREATHING 23
863#define DUKE_EXHALING 24
864#define DUKE_GASP 25
865#define SLIM_RECOG 26
866// #define ENDSEQVOL3SND1 27
867#define DUKE_URINATE 28
868#define ENDSEQVOL3SND2 29
869#define ENDSEQVOL3SND3 30
870#define DUKE_PASSWIND 32
871#define DUKE_CRACK 33
872#define SLIM_ATTACK 34
873#define SOMETHINGHITFORCE 35
874#define DUKE_DRINKING 36
875#define DUKE_KILLED1 37
876#define DUKE_GRUNT 38
877#define DUKE_HARTBEAT 39
878#define DUKE_ONWATER 40
879#define DUKE_DEAD 41
880#define DUKE_LAND 42
881#define DUKE_WALKINDUCTS 43
882#define DUKE_GLAD 44
883#define DUKE_YES 45
884#define DUKE_HEHE 46
885#define DUKE_SHUCKS 47
886#define DUKE_UNDERWATER 48
887#define DUKE_JETPACK_ON 49
888#define DUKE_JETPACK_IDLE 50
889#define DUKE_JETPACK_OFF 51
890#define LIZTROOP_GROWL 52
891#define LIZTROOP_TALK1 53
892#define LIZTROOP_TALK2 54
893#define LIZTROOP_TALK3 55
894#define DUKETALKTOBOSS 56
895#define LIZCAPT_GROWL 57
896#define LIZCAPT_TALK1 58
897#define LIZCAPT_TALK2 59
898#define LIZCAPT_TALK3 60
899#define LIZARD_BEG 61
900#define LIZARD_PAIN 62
901#define LIZARD_DEATH 63
902#define LIZARD_SPIT 64
903#define DRONE1_HISSRATTLE 65
904#define DRONE1_HISSSCREECH 66
905#define DUKE_TIP2 67
906#define FLESH_BURNING 68
907#define SQUISHED 69
908#define TELEPORTER 70
909#define ELEVATOR_ON 71
910#define DUKE_KILLED3 72
911#define ELEVATOR_OFF 73
912#define DOOR_OPERATE1 74
913#define SUBWAY 75
914#define SWITCH_ON 76
915#define FAN 77
916#define DUKE_GETWEAPON3 78
917#define FLUSH_TOILET 79
918#define HOVER_CRAFT 80
919#define EARTHQUAKE 81
920#define INTRUDER_ALERT 82
921#define END_OF_LEVEL_WARN 83
922#define ENGINE_OPERATING 84
923#define REACTOR_ON 85
924#define COMPUTER_AMBIENCE 86
925#define GEARS_GRINDING 87
926#define BUBBLE_AMBIENCE 88
927#define MACHINE_AMBIENCE 89
928#define SEWER_AMBIENCE 90
929#define WIND_AMBIENCE 91
930#define SOMETHING_DRIPPING 92
931#define STEAM_HISSING 93
932#define THEATER_BREATH 94
933#define BAR_MUSIC 95
934#define BOS1_ROAM 96
935#define BOS1_RECOG 97
936#define BOS1_ATTACK1 98
937#define BOS1_PAIN 99
938#define BOS1_DYING 100
939#define BOS2_ROAM 101
940#define BOS2_RECOG 102
941#define BOS2_ATTACK 103
942#define BOS2_PAIN 104
943#define BOS2_DYING 105
944#define GETATOMICHEALTH 106
945#define DUKE_GETWEAPON2 107
946#define BOS3_DYING 108
947#define SHOTGUN_FIRE 109
948#define PRED_ROAM 110
949#define PRED_RECOG 111
950#define PRED_ATTACK 112
951#define PRED_PAIN 113
952#define PRED_DYING 114
953#define CAPT_ROAM 115
954#define CAPT_ATTACK 116
955#define CAPT_RECOG 117
956#define CAPT_PAIN 118
957#define CAPT_DYING 119
958#define PIG_ROAM 120
959#define PIG_RECOG 121
960#define PIG_ATTACK 122
961#define PIG_PAIN 123
962#define PIG_DYING 124
963#define RECO_ROAM 125
964#define RECO_RECOG 126
965#define RECO_ATTACK 127
966#define RECO_PAIN 128
967#define RECO_DYING 129
968#define DRON_ROAM 130
969#define DRON_RECOG 131
970#define DRON_ATTACK1 132
971#define DRON_PAIN 133
972#define DRON_DYING 134
973#define COMM_ROAM 135
974#define COMM_RECOG 136
975#define COMM_ATTACK 137
976#define COMM_PAIN 138
977#define COMM_DYING 139
978#define OCTA_ROAM 140
979#define OCTA_RECOG 141
980#define OCTA_ATTACK1 142
981#define OCTA_PAIN 143
982#define OCTA_DYING 144
983#define TURR_ROAM 145
984#define TURR_RECOG 146
985#define TURR_ATTACK 147
986#define DUMPSTER_MOVE 148
987#define SLIM_DYING 149
988#define BOS3_ROAM 150
989#define BOS3_RECOG 151
990#define BOS3_ATTACK1 152
991#define BOS3_PAIN 153
992#define BOS1_ATTACK2 154
993#define COMM_SPIN 155
994#define BOS1_WALK 156
995#define DRON_ATTACK2 157
996#define THUD 158
997#define OCTA_ATTACK2 159
998#define WIERDSHOT_FLY 160
999#define TURR_PAIN 161
1000#define TURR_DYING 162
1001#define SLIM_ROAM 163
1002#define LADY_SCREAM 164
1003#define DOOR_OPERATE2 165
1004#define DOOR_OPERATE3 166
1005#define DOOR_OPERATE4 167
1006#define BORNTOBEWILDSND 168
1007#define SHOTGUN_COCK 169
1008#define GENERIC_AMBIENCE1 170
1009#define GENERIC_AMBIENCE2 171
1010#define GENERIC_AMBIENCE3 172
1011#define GENERIC_AMBIENCE4 173
1012#define GENERIC_AMBIENCE5 174
1013#define GENERIC_AMBIENCE6 175
1014#define BOS3_ATTACK2 176
1015#define GENERIC_AMBIENCE17 177
1016#define GENERIC_AMBIENCE18 178
1017#define GENERIC_AMBIENCE19 179
1018#define GENERIC_AMBIENCE20 180
1019#define GENERIC_AMBIENCE21 181
1020#define GENERIC_AMBIENCE22 182
1021#define SECRETLEVELSND 183
1022#define GENERIC_AMBIENCE8 184
1023#define GENERIC_AMBIENCE9 185
1024#define GENERIC_AMBIENCE10 186
1025#define GENERIC_AMBIENCE11 187
1026#define GENERIC_AMBIENCE12 188
1027#define GENERIC_AMBIENCE13 189
1028#define GENERIC_AMBIENCE14 190
1029#define GENERIC_AMBIENCE15 192
1030#define GENERIC_AMBIENCE16 193
1031#define FIRE_CRACKLE 194
1032#define BONUS_SPEECH1 195
1033#define BONUS_SPEECH2 196
1034#define BONUS_SPEECH3 197
1035#define PIG_CAPTURE_DUKE 198
1036#define BONUS_SPEECH4 199
1037#define DUKE_LAND_HURT 200
1038#define DUKE_HIT_STRIPPER1 201
1039#define DUKE_TIP1 202
1040#define DUKE_KILLED2 203
1041#define PRED_ROAM2 204
1042#define PIG_ROAM2 205
1043#define DUKE_GETWEAPON1 206
1044#define DUKE_SEARCH2 207
1045#define DUKE_CRACK2 208
1046#define DUKE_SEARCH 209
1047#define DUKE_GET 210
1048#define DUKE_LONGTERM_PAIN 211
1049#define MONITOR_ACTIVE 212
1050#define NITEVISION_ONOFF 213
1051#define DUKE_HIT_STRIPPER2 214
1052#define DUKE_CRACK_FIRST 215
1053#define DUKE_USEMEDKIT 216
1054#define DUKE_TAKEPILLS 217
1055#define DUKE_PISSRELIEF 218
1056#define SELECT_WEAPON 219
1057#define WATER_GURGLE 220
1058#define DUKE_GETWEAPON4 221
1059#define JIBBED_ACTOR1 222
1060#define JIBBED_ACTOR2 223
1061#define JIBBED_ACTOR3 224
1062#define JIBBED_ACTOR4 225
1063#define JIBBED_ACTOR5 226
1064#define JIBBED_ACTOR6 227
1065#define JIBBED_ACTOR7 228
1066#define DUKE_GOTHEALTHATLOW 229
1067#define BOSSTALKTODUKE 230
1068#define WAR_AMBIENCE1 231
1069#define WAR_AMBIENCE2 232
1070#define WAR_AMBIENCE3 233
1071#define WAR_AMBIENCE4 234
1072#define WAR_AMBIENCE5 235
1073#define WAR_AMBIENCE6 236
1074#define WAR_AMBIENCE7 237
1075#define WAR_AMBIENCE8 238
1076#define WAR_AMBIENCE9 239
1077#define WAR_AMBIENCE10 240
1078#define ALIEN_TALK1 241
1079#define ALIEN_TALK2 242
1080#define EXITMENUSOUND 243
1081#define FLY_BY 244
1082#define DUKE_SCREAM 245
1083#define SHRINKER_HIT 246
1084#define RATTY 247
1085#define INTO_MENU 248
1086#define BONUSMUSIC 249
1087#define DUKE_BOOBY 250
1088#define DUKE_TALKTOBOSSFALL 251
1089#define DUKE_LOOKINTOMIRROR 252
1090#define PIG_ROAM3 253
1091#define KILLME 254
1092#define DRON_JETSND 255
1093#define SPACE_DOOR1 256
1094#define SPACE_DOOR2 257
1095#define SPACE_DOOR3 258
1096#define SPACE_DOOR4 259
1097#define SPACE_DOOR5 260
1098#define ALIEN_ELEVATOR1 261
1099#define VAULT_DOOR 262
1100#define JIBBED_ACTOR13 263
1101#define DUKE_GETWEAPON6 264
1102#define JIBBED_ACTOR8 265
1103#define JIBBED_ACTOR9 266
1104#define JIBBED_ACTOR10 267
1105#define JIBBED_ACTOR11 268
1106#define JIBBED_ACTOR12 269
1107#define DUKE_KILLED4 270
1108#define DUKE_KILLED5 271
1109#define ALIEN_SWITCH1 272
1110#define DUKE_STEPONFECES 273
1111#define DUKE_LONGTERM_PAIN2 274
1112#define DUKE_LONGTERM_PAIN3 275
1113#define DUKE_LONGTERM_PAIN4 276
1114#define COMPANB2 277
1115#define KTIT 278
1116#define HELICOP_IDLE 279
1117#define STEPNIT 280
1118#define SPACE_AMBIENCE1 281
1119#define SPACE_AMBIENCE2 282
1120#define SLIM_HATCH 283
1121#define RIPHEADNECK 284
1122#define FOUNDJONES 285
1123#define ALIEN_DOOR1 286
1124#define ALIEN_DOOR2 287
1125#define ENDSEQVOL3SND4 288
1126#define ENDSEQVOL3SND5 289
1127#define ENDSEQVOL3SND6 290
1128#define ENDSEQVOL3SND7 291
1129#define ENDSEQVOL3SND8 292
1130#define ENDSEQVOL3SND9 293
1131#define WHIPYOURASS 294
1132#define ENDSEQVOL2SND1 295
1133#define ENDSEQVOL2SND2 296
1134#define ENDSEQVOL2SND3 297
1135#define ENDSEQVOL2SND4 298
1136#define ENDSEQVOL2SND5 299
1137#define ENDSEQVOL2SND6 300
1138#define ENDSEQVOL2SND7 301
1139#define GENERIC_AMBIENCE23 302
1140#define SOMETHINGFROZE 303
1141#define DUKE_LONGTERM_PAIN5 304
1142#define DUKE_LONGTERM_PAIN6 305
1143#define DUKE_LONGTERM_PAIN7 306
1144#define DUKE_LONGTERM_PAIN8 307
1145#define WIND_REPEAT 308
1146#define MYENEMY_ROAM 309
1147#define MYENEMY_HURT 310
1148#define MYENEMY_DEAD 311
1149#define MYENEMY_SHOOT 312
1150#define STORE_MUSIC 313
1151#define STORE_MUSIC_BROKE 314
1152#define ACTOR_GROWING 315
1153#define NEWBEAST_ROAM 316
1154#define NEWBEAST_RECOG 317
1155#define NEWBEAST_ATTACK 318
1156#define NEWBEAST_PAIN 319
1157#define NEWBEAST_DYING 320
1158#define NEWBEAST_SPIT 321
1159#define VOL4_1 322
1160#define SUPERMARKET 323
1161#define MOUSEANNOY 324
1162#define BOOKEM 325
1163#define SUPERMARKETCRY 326
1164#define DESTRUCT 327
1165#define EATFOOD 328
1166#define MAKEMYDAY 329
1167#define WITNESSSTAND 330
1168#define VACATIONSPEECH 331
1169#define YIPPEE1 332
1170#define YOHOO1 333
1171#define YOHOO2 334
1172#define DOLPHINSND 335
1173#define TOUGHGALSND1 336
1174#define TOUGHGALSND2 337
1175#define TOUGHGALSND3 338
1176#define TOUGHGALSND4 339
1177#define TANK_ROAM 340
1178#define BOS4_ROAM 341
1179#define BOS4_RECOG 342
1180#define BOS4_ATTACK 343
1181#define BOS4_PAIN 344
1182#define BOS4_DYING 345
1183#define NEWBEAST_ATTACKMISS 346
1184#define VOL4_2 347
1185#define COOKINGDEEPFRIER 348
1186#define WHINING_DOG 349
1187#define DEAD_DOG 350
1188#define LIGHTNING_SLAP 351
1189#define THUNDER 352
1190#define HAPPYMOUSESND1 353
1191#define HAPPYMOUSESND2 354
1192#define HAPPYMOUSESND3 355
1193#define HAPPYMOUSESND4 356
1194#define ALARM 357
1195#define RAIN 358
1196#define DTAG_GREENRUN 359
1197#define DTAG_BROWNRUN 360
1198#define DTAG_GREENSCORE 361
1199#define DTAG_BROWNSCORE 362
1200#define INTRO4_1 363
1201#define INTRO4_2 364
1202#define INTRO4_3 365
1203#define INTRO4_4 366
1204#define INTRO4_5 367
1205#define INTRO4_6 368
1206#define SCREECH 369
1207#define BOSS4_DEADSPEECH 370
1208#define BOSS4_FIRSTSEE 371
1209#define PARTY_SPEECH 372
1210#define POSTAL_SPEECH 373
1211#define TGSPEECH 374
1212#define DOGROOMSPEECH 375
1213#define SMACKED 376
1214#define MDEVSPEECH 377
1215#define AREA51SPEECH 378
1216#define JEEPSOUND 379
1217#define BIGDOORSLAM 380
1218#define BOS4_LAY 381
1219#define WAVESOUND 382
1220#define ILLBEBACK 383
1221#define VOL4ENDSND1 384
1222#define VOL4ENDSND2 385
1223#define EXPANDERHIT 386
1224#define SNAKESPEECH 387
1225#define EXPANDERSHOOT 388
1226#define GETBACKTOWORK 389
1227#define JIBBED_ACTOR14 390
1228#define JIBBED_ACTOR15 391
1229#define INTRO4_B 392
1230#define BIGBANG 393
1231#define SMACKIT 394
1232#define BELLSND 395
1233// MAXIMUM NUMBER OF SOUNDS: 450 ( 0-449 )
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/sounds.c b/apps/plugins/sdl/progs/duke3d/Game/src/sounds.c
new file mode 100644
index 0000000000..4d40434011
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/sounds.c
@@ -0,0 +1,681 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#if PLATFORM_DOS
28#include <conio.h>
29#endif
30
31#include <stdio.h>
32#include <string.h>
33#include "../../Game/src/types.h"
34#include "util_lib.h"
35#include "duke3d.h"
36#include "global.h"
37#include "../../Engine/src/filesystem.h"
38
39
40#define LOUDESTVOLUME 150
41
42int32_t backflag,numenvsnds;
43
44/*
45===================
46=
47= SoundStartup
48=
49===================
50*/
51
52void SoundStartup( void )
53 {
54 int32 status;
55
56 // if they chose None lets return
57 if (FXDevice == NumSoundCards) return;
58
59 // Do special Sound Blaster, AWE32 stuff
60 if (
61 ( FXDevice == SoundBlaster ) ||
62 ( FXDevice == Awe32 )
63 )
64 {
65 int MaxVoices;
66 int MaxBits;
67 int MaxChannels;
68
69 status = FX_SetupSoundBlaster
70 (
71 BlasterConfig, (int *)&MaxVoices, (int *)&MaxBits, (int *)&MaxChannels
72 );
73 }
74 else
75 {
76 status = FX_Ok;
77 }
78
79 if ( status == FX_Ok )
80 {
81 if ( eightytwofifty && numplayers > 1)
82 {
83 status = FX_Init( FXDevice, min( NumVoices,4 ), 1, 8, 8000 );
84 }
85 else
86 {
87 status = FX_Init( FXDevice, NumVoices, NumChannels, NumBits, MixRate );
88 }
89 if ( status == FX_Ok )
90 {
91
92 FX_SetVolume( FXVolume );
93 if (ReverseStereo == 1)
94 {
95 FX_SetReverseStereo(!FX_GetReverseStereo());
96 }
97 }
98 }
99 if ( status != FX_Ok )
100 {
101 Error(EXIT_FAILURE, FX_ErrorString( FX_Error ));
102 }
103
104 status = FX_SetCallBack( TestCallBack );
105
106 if ( status != FX_Ok )
107 {
108 Error(EXIT_FAILURE, FX_ErrorString( FX_Error ));
109 }
110 }
111
112/*
113===================
114=
115= SoundShutdown
116=
117===================
118*/
119
120void SoundShutdown( void )
121 {
122 int32 status;
123
124 // if they chose None lets return
125 if (FXDevice == NumSoundCards)
126 return;
127
128 status = FX_Shutdown();
129 if ( status != FX_Ok )
130 {
131 Error(EXIT_FAILURE, FX_ErrorString( FX_Error ));
132 }
133 }
134
135/*
136===================
137=
138= MusicStartup
139=
140===================
141*/
142
143void MusicStartup( void )
144 {
145 int32 status;
146
147 // if they chose None lets return
148 if ((MusicDevice == NumSoundCards) || (eightytwofifty && numplayers > 1) )
149 return;
150
151 // satisfy AWE32 and WAVEBLASTER stuff
152 BlasterConfig.Midi = MidiPort;
153
154 // Do special Sound Blaster, AWE32 stuff
155 if (
156 ( FXDevice == SoundBlaster ) ||
157 ( FXDevice == Awe32 )
158 )
159 {
160 int MaxVoices;
161 int MaxBits;
162 int MaxChannels;
163
164 FX_SetupSoundBlaster
165 (
166 BlasterConfig, (int *)&MaxVoices, (int *)&MaxBits, (int *)&MaxChannels
167 );
168 }
169 status = MUSIC_Init( MusicDevice, MidiPort );
170
171 if ( status == MUSIC_Ok )
172 {
173 MUSIC_SetVolume( MusicVolume );
174 }
175 else
176 {
177 SoundShutdown();
178 uninittimer();
179 uninitengine();
180 CONTROL_Shutdown();
181 CONFIG_WriteSetup();
182 KB_Shutdown();
183 uninitgroupfile();
184 unlink("duke3d.tmp");
185 Error(EXIT_FAILURE, "Couldn't find selected sound card, or, error w/ sound card itself\n");
186 }
187}
188
189/*
190===================
191=
192= MusicShutdown
193=
194===================
195*/
196
197void MusicShutdown( void )
198 {
199 int32 status;
200
201 // if they chose None lets return
202 if ((MusicDevice == NumSoundCards) || (eightytwofifty && numplayers > 1) )
203 return;
204
205 status = MUSIC_Shutdown();
206 if ( status != MUSIC_Ok )
207 {
208 //Error( MUSIC_ErrorString( MUSIC_ErrorCode ));
209 }
210 }
211
212
213#if 0
214int USRHOOKS_GetMem(void **ptr, uint32_t size )
215{
216 *ptr = malloc(size);
217
218 if (*ptr == NULL)
219 return(USRHOOKS_Error);
220
221 return( USRHOOKS_Ok);
222
223}
224
225int USRHOOKS_FreeMem(void *ptr)
226{
227 free(ptr);
228 return( USRHOOKS_Ok);
229}
230#endif
231
232uint8_t menunum=0;
233
234void intomenusounds(void)
235{
236 static const short menusnds[] =
237 {
238 LASERTRIP_EXPLODE,
239 DUKE_GRUNT,
240 DUKE_LAND_HURT,
241 CHAINGUN_FIRE,
242 SQUISHED,
243 KICK_HIT,
244 PISTOL_RICOCHET,
245 PISTOL_BODYHIT,
246 PISTOL_FIRE,
247 SHOTGUN_FIRE,
248 BOS1_WALK,
249 RPG_EXPLODE,
250 PIPEBOMB_BOUNCE,
251 PIPEBOMB_EXPLODE,
252 NITEVISION_ONOFF,
253 RPG_SHOOT,
254 SELECT_WEAPON
255 };
256 sound(menusnds[(int)menunum++]);
257 menunum %= 17;
258}
259
260void playmusic(char *fn)
261{
262 if(MusicToggle == 0) return;
263 if(MusicDevice == NumSoundCards) return;
264
265 // the SDL_mixer version does more or less this same thing. --ryan.
266 PlayMusic(fn);
267}
268
269uint8_t loadsound(uint16_t num)
270{
271 int32_t fp, l;
272
273 if(num >= NUM_SOUNDS || SoundToggle == 0) return 0;
274 if (FXDevice == NumSoundCards) return 0;
275
276 fp = TCkopen4load(sounds[num],0);
277 if(fp == -1)
278 {
279 sprintf(&fta_quotes[113][0],"Sound %s(#%d) not found.",sounds[num],num);
280 FTA(113,&ps[myconnectindex],1);
281 return 0;
282 }
283
284 l = kfilelength( fp );
285 soundsiz[num] = l;
286
287 Sound[num].lock = 200;
288
289 allocache(&Sound[num].ptr,l,(uint8_t *)&Sound[num].lock);
290 kread( fp, Sound[num].ptr , l);
291 kclose( fp );
292 return 1;
293}
294
295int xyzsound(short num,short i,int32_t x,int32_t y,int32_t z)
296{
297 int32_t sndist, cx, cy, cz, j,k;
298 short pitche,pitchs,cs;
299 int voice, sndang, ca, pitch;
300
301 /*
302 rb->splashf(HZ * 3, "%d %d %d %d %d %d %d %d", num >= NUM_SOUNDS,
303 FXDevice == NumSoundCards,
304 ( (soundm[num]&8) && ud.lockout ),
305 SoundToggle == 0,
306 Sound[num].num > 3,
307 FX_VoiceAvailable(soundpr[num]) == 0,
308 (ps[myconnectindex].timebeforeexit > 0 && ps[myconnectindex].timebeforeexit <= 26*3),
309 ps[myconnectindex].gm&MODE_MENU);
310 */
311
312 if( num >= NUM_SOUNDS ||
313 FXDevice == NumSoundCards ||
314 ( (soundm[num]&8) && ud.lockout ) ||
315 SoundToggle == 0 ||
316 Sound[num].num > 3 ||
317 FX_VoiceAvailable(soundpr[num]) == 0 ||
318 (ps[myconnectindex].timebeforeexit > 0 && ps[myconnectindex].timebeforeexit <= 26*3) ||
319 ps[myconnectindex].gm&MODE_MENU) return -1;
320
321 if( soundm[num]&128 )
322 {
323 sound(num);
324 return 0;
325 }
326
327 if( soundm[num]&4 )
328 {
329 // FIX_00041: Toggle to hear the opponent sound in DM (like it used to be in v1.3d)
330 if(VoiceToggle==0 || (ud.multimode > 1 && PN == APLAYER && sprite[i].yvel != screenpeek && /*ud.coop!=1 &&*/ !OpponentSoundToggle) ) return -1; //xduke : 1.3d Style: makes opponent sound in DM as in COOP
331
332 for(j=0;j<NUM_SOUNDS;j++)
333 for(k=0;k<Sound[j].num;k++)
334 if( (Sound[j].num > 0) && (soundm[j]&4) )
335 return -1;
336 }
337
338 cx = ps[screenpeek].oposx;
339 cy = ps[screenpeek].oposy;
340 cz = ps[screenpeek].oposz;
341 cs = ps[screenpeek].cursectnum;
342 ca = ps[screenpeek].ang+ps[screenpeek].look_ang;
343
344 sndist = FindDistance3D((cx-x),(cy-y),(cz-z)>>4);
345
346 if( i >= 0 && (soundm[num]&16) == 0 && PN == MUSICANDSFX && SLT < 999 && (sector[SECT].lotag&0xff) < 9 )
347 sndist = divscale14(sndist,(SHT+1));
348
349 pitchs = soundps[num];
350 pitche = soundpe[num];
351 cx = klabs(pitche-pitchs);
352
353 if(cx)
354 {
355 if( pitchs < pitche )
356 pitch = pitchs + ( rand()%cx );
357 else pitch = pitche + ( rand()%cx );
358 }
359 else pitch = pitchs;
360
361 sndist += soundvo[num];
362 if(sndist < 0) sndist = 0;
363 if( sndist && PN != MUSICANDSFX && !cansee(cx,cy,cz-(24<<8),cs,SX,SY,SZ-(24<<8),SECT) )
364 sndist += sndist>>5;
365
366 switch(num)
367 {
368 case PIPEBOMB_EXPLODE:
369 case LASERTRIP_EXPLODE:
370 case RPG_EXPLODE:
371 if(sndist > (6144) )
372 sndist = 6144;
373 if(sector[ps[screenpeek].cursectnum].lotag == 2)
374 pitch -= 1024;
375 break;
376 default:
377 if(sector[ps[screenpeek].cursectnum].lotag == 2 && (soundm[num]&4) == 0)
378 pitch = -768;
379 if( sndist > 31444 && PN != MUSICANDSFX)
380 return -1;
381 break;
382 }
383
384
385 if( Sound[num].num > 0 && PN != MUSICANDSFX )
386 {
387 if( SoundOwner[num][0].i == i ) stopsound(num);
388 else if( Sound[num].num > 1 ) stopsound(num);
389 else if( badguy(&sprite[i]) && sprite[i].extra <= 0 ) stopsound(num);
390 }
391
392 if( PN == APLAYER && sprite[i].yvel == screenpeek )
393 {
394 sndang = 0;
395 sndist = 0;
396 }
397 else
398 {
399 sndang = 2048 + ca - getangle(cx-x,cy-y);
400 sndang &= 2047;
401 }
402
403 if(Sound[num].ptr == 0) { if( loadsound(num) == 0 ) return 0; }
404 else
405 {
406 if (Sound[num].lock < 200)
407 Sound[num].lock = 200;
408 else Sound[num].lock++;
409 }
410
411 if( soundm[num]&16 ) sndist = 0;
412
413 if(sndist < ((255-LOUDESTVOLUME)<<6) )
414 sndist = ((255-LOUDESTVOLUME)<<6);
415
416 if( soundm[num]&1 )
417 {
418 uint16_t start;
419
420 if(Sound[num].num > 0) return -1;
421
422 start = readLE16(Sound[num].ptr + 0x14);
423
424 if(*Sound[num].ptr == 'C')
425 voice = FX_PlayLoopedVOC( Sound[num].ptr, start, start + soundsiz[num],
426 pitch,sndist>>6,sndist>>6,0,soundpr[num],num);
427 else
428 voice = FX_PlayLoopedWAV( Sound[num].ptr, start, start + soundsiz[num],
429 pitch,sndist>>6,sndist>>6,0,soundpr[num],num);
430 }
431 else
432 {
433 if( *Sound[num].ptr == 'C')
434 voice = FX_PlayVOC3D( Sound[ num ].ptr,pitch,sndang>>6,sndist>>6, soundpr[num], num );
435 else voice = FX_PlayWAV3D( Sound[ num ].ptr,pitch,sndang>>6,sndist>>6, soundpr[num], num );
436 }
437
438 if ( voice > FX_Ok )
439 {
440 SoundOwner[num][Sound[num].num].i = i;
441 SoundOwner[num][Sound[num].num].voice = voice;
442 Sound[num].num++;
443 }
444 else Sound[num].lock--;
445 return (voice);
446}
447
448void sound(short num)
449{
450 short pitch,pitche,pitchs,cx;
451 int voice;
452 int32_t start;
453
454 if (FXDevice == NumSoundCards) return;
455 if(SoundToggle==0) return;
456 if(VoiceToggle==0 && (soundm[num]&4) ) return;
457 if( (soundm[num]&8) && ud.lockout ) return;
458 if(FX_VoiceAvailable(soundpr[num]) == 0) return;
459
460 printf("sound %s (%d)\n", sounds[num], num);
461
462 pitchs = soundps[num];
463 pitche = soundpe[num];
464 cx = klabs(pitche-pitchs);
465
466 if(cx)
467 {
468 if( pitchs < pitche )
469 pitch = pitchs + ( rand()%cx );
470 else pitch = pitche + ( rand()%cx );
471 }
472 else pitch = pitchs;
473
474 if(Sound[num].ptr == 0) { if( loadsound(num) == 0 ) return; }
475 else
476 {
477 if (Sound[num].lock < 200)
478 Sound[num].lock = 200;
479 else Sound[num].lock++;
480 }
481
482 if( soundm[num]&1 )
483 {
484 if(*Sound[num].ptr == 'C')
485 {
486 start = (int32_t)readLE16(Sound[num].ptr + 0x14);
487 voice = FX_PlayLoopedVOC( Sound[num].ptr, start, start + soundsiz[num],
488 pitch,LOUDESTVOLUME,LOUDESTVOLUME,LOUDESTVOLUME,soundpr[num],num);
489 }
490 else
491 {
492 start = (int32_t)readLE16(Sound[num].ptr + 0x14);
493 voice = FX_PlayLoopedWAV( Sound[num].ptr, start, start + soundsiz[num],
494 pitch,LOUDESTVOLUME,LOUDESTVOLUME,LOUDESTVOLUME,soundpr[num],num);
495 }
496 }
497 else
498 {
499 if(*Sound[num].ptr == 'C')
500 voice = FX_PlayVOC3D( Sound[ num ].ptr, pitch,0,255-LOUDESTVOLUME,soundpr[num], num );
501 else
502 voice = FX_PlayWAV3D( Sound[ num ].ptr, pitch,0,255-LOUDESTVOLUME,soundpr[num], num );
503 }
504
505 if(voice > FX_Ok) return;
506 Sound[num].lock--;
507}
508
509int spritesound(uint16_t num, short i)
510{
511 if(num >= NUM_SOUNDS) return -1;
512 return xyzsound(num,i,SX,SY,SZ);
513}
514
515void stopsound(short num)
516{
517 if(Sound[num].num > 0)
518 {
519 FX_StopSound(SoundOwner[num][Sound[num].num-1].voice);
520 testcallback(num);
521 }
522}
523
524void stopenvsound(short num,short i)
525{
526 short j, k;
527
528 if(Sound[num].num > 0)
529 {
530 k = Sound[num].num;
531 for(j=0;j<k;j++)
532 if(SoundOwner[num][j].i == i)
533 {
534 FX_StopSound(SoundOwner[num][j].voice);
535 break;
536 }
537 }
538}
539
540void pan3dsound(void)
541{
542 int32_t sndist, sx, sy, sz, cx, cy, cz;
543 short sndang,ca,j,k,i,cs;
544
545 numenvsnds = 0;
546
547 if(ud.camerasprite == -1)
548 {
549 cx = ps[screenpeek].oposx;
550 cy = ps[screenpeek].oposy;
551 cz = ps[screenpeek].oposz;
552 cs = ps[screenpeek].cursectnum;
553 ca = ps[screenpeek].ang+ps[screenpeek].look_ang;
554 }
555 else
556 {
557 cx = sprite[ud.camerasprite].x;
558 cy = sprite[ud.camerasprite].y;
559 cz = sprite[ud.camerasprite].z;
560 cs = sprite[ud.camerasprite].sectnum;
561 ca = sprite[ud.camerasprite].ang;
562 }
563
564 for(j=0;j<NUM_SOUNDS;j++) for(k=0;k<Sound[j].num;k++)
565 {
566 i = SoundOwner[j][k].i;
567
568 sx = sprite[i].x;
569 sy = sprite[i].y;
570 sz = sprite[i].z;
571
572 if( PN == APLAYER && sprite[i].yvel == screenpeek)
573 {
574 sndang = 0;
575 sndist = 0;
576 }
577 else
578 {
579 sndang = 2048 + ca - getangle(cx-sx,cy-sy);
580 sndang &= 2047;
581 sndist = FindDistance3D((cx-sx),(cy-sy),(cz-sz)>>4);
582 if( i >= 0 && (soundm[j]&16) == 0 && PN == MUSICANDSFX && SLT < 999 && (sector[SECT].lotag&0xff) < 9 )
583 sndist = divscale14(sndist,(SHT+1));
584 }
585
586 sndist += soundvo[j];
587 if(sndist < 0) sndist = 0;
588
589 if( sndist && PN != MUSICANDSFX && !cansee(cx,cy,cz-(24<<8),cs,sx,sy,sz-(24<<8),SECT) )
590 sndist += sndist>>5;
591
592 if(PN == MUSICANDSFX && SLT < 999)
593 numenvsnds++;
594
595 switch(j)
596 {
597 case PIPEBOMB_EXPLODE:
598 case LASERTRIP_EXPLODE:
599 case RPG_EXPLODE:
600 if(sndist > (6144)) sndist = (6144);
601 break;
602 default:
603 if( sndist > 31444 && PN != MUSICANDSFX)
604 {
605 stopsound(j);
606 continue;
607 }
608 }
609
610 if(Sound[j].ptr == 0 && loadsound(j) == 0 ) continue;
611 if( soundm[j]&16 ) sndist = 0;
612
613 if(sndist < ((255-LOUDESTVOLUME)<<6) )
614 sndist = ((255-LOUDESTVOLUME)<<6);
615
616 FX_Pan3D(SoundOwner[j][k].voice,sndang>>6,sndist>>6);
617 }
618}
619
620void TestCallBack(int32_t num)
621{
622 short tempi,tempj,tempk;
623
624 if(num < 0)
625 {
626 if(lumplockbyte[-num] >= 200)
627 lumplockbyte[-num]--;
628 return;
629 }
630
631 tempk = Sound[num].num;
632
633 if(tempk > 0)
634 {
635 if( (soundm[num]&16) == 0)
636 for(tempj=0;tempj<tempk;tempj++)
637 {
638 tempi = SoundOwner[num][tempj].i;
639 if(sprite[tempi].picnum == MUSICANDSFX && sector[sprite[tempi].sectnum].lotag < 3 && sprite[tempi].lotag < 999)
640 {
641 hittype[tempi].temp_data[0] = 0;
642 if( (tempj + 1) < tempk )
643 {
644 SoundOwner[num][tempj].voice = SoundOwner[num][tempk-1].voice;
645 SoundOwner[num][tempj].i = SoundOwner[num][tempk-1].i;
646 }
647 break;
648 }
649 }
650
651 Sound[num].num--;
652 SoundOwner[num][tempk-1].i = -1;
653 }
654
655 Sound[num].lock--;
656}
657
658
659// no idea if this is right. I added this function. --ryan.
660void testcallback(uint32_t num)
661{
662// STUBBED("wtf?");
663 TestCallBack(num);
664}
665
666
667void clearsoundlocks(void)
668{
669 int32_t i;
670
671
672
673 for(i=0;i<NUM_SOUNDS;i++)
674
675 Sound[i].lock = 199;
676
677 for(i=0;i<11;i++)
678
679 lumplockbyte[i] = 199;
680}
681
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/sounds.h b/apps/plugins/sdl/progs/duke3d/Game/src/sounds.h
new file mode 100644
index 0000000000..1a457687fa
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/sounds.h
@@ -0,0 +1,62 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27//****************************************************************************
28//
29// sounds.h
30//
31//****************************************************************************
32#include "audiolib/fx_man.h"
33
34#ifndef _sounds_public_
35#define _sounds_public_
36
37#define HIRESMUSICPATH "tunes"
38
39extern int32_t FXDevice;
40extern int32_t MusicDevice;
41extern int32_t FXVolume;
42extern int32_t MusicVolume;
43extern fx_blaster_config BlasterConfig;
44extern int32_t NumVoices;
45extern int32_t NumChannels;
46extern int32_t NumBits;
47extern int32_t MixRate;
48extern int32_t MidiPort;
49extern int32_t ReverseStereo;
50
51void SoundStartup( void );
52void SoundShutdown( void );
53void MusicStartup( void );
54void MusicShutdown( void );
55
56/* sounds.c */
57void clearsoundlocks(void);
58
59/* dunno where this came from; I added it. --ryan. */
60void testcallback(uint32_t num);
61
62#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/types.h b/apps/plugins/sdl/progs/duke3d/Game/src/types.h
new file mode 100644
index 0000000000..017c851a18
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/types.h
@@ -0,0 +1,101 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27#ifndef _types_public
28#define _types_public
29
30#ifdef _WIN32
31 #include "../../Engine/src/windows/inttypes.h"
32#else
33 #include <inttypes.h>
34#endif
35
36#ifdef __cplusplus
37extern "C" {
38#endif
39
40
41//***************************************************************************
42//
43// Global Data Types (For portability)
44//
45//***************************************************************************
46
47typedef uint8_t uint8;
48typedef uint8 byte;
49typedef int8_t int8;
50
51typedef uint16_t uint16;
52typedef uint16_t word;
53typedef int16_t int16;
54
55typedef uint32_t uint32;
56typedef int32_t int32;
57typedef uint32 dword;
58
59typedef int32 fixed;
60#define boolean uint8_t
61typedef float float32;
62typedef double float64;
63typedef int64_t float128;
64typedef float64 appfloat;
65
66
67
68//***************************************************************************
69//
70// boolean values
71//
72//***************************************************************************
73
74#define true ( 1 == 1 )
75#define false ( ! true )
76
77//***************************************************************************
78//
79// BYTE ACCESS MACROS
80//
81//***************************************************************************
82
83// WORD macros
84#define Int16_HighByte( x ) ( (uint8) ((x)>>8) )
85#define Int16_LowByte( x ) ( (uint8) ((x)&0xff) )
86
87// DWORD macros
88#define Int32_4Byte( x ) ( (uint8) ((x)>>24)&0xff )
89#define Int32_3Byte( x ) ( (uint8) (((x)>>16)&0xff) )
90#define Int32_2Byte( x ) ( (uint8) (((x)>>8)&0xff) )
91#define Int32_1Byte( x ) ( (uint8) ((x)&0xff) )
92
93#ifdef __NeXT__
94#define stricmp strcasecmp
95#define strcmpi strcasecmp
96#endif
97
98#ifdef __cplusplus
99};
100#endif
101#endif
diff --git a/apps/plugins/sdl/progs/duke3d/Game/src/util_lib.h b/apps/plugins/sdl/progs/duke3d/Game/src/util_lib.h
new file mode 100644
index 0000000000..8af441cfc7
--- /dev/null
+++ b/apps/plugins/sdl/progs/duke3d/Game/src/util_lib.h
@@ -0,0 +1,77 @@
1//-------------------------------------------------------------------------
2/*
3Copyright (C) 1996, 2003 - 3D Realms Entertainment
4
5This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
6
7Duke Nukem 3D is free software; you can redistribute it and/or
8modify it under the terms of the GNU General Public License
9as published by the Free Software Foundation; either version 2
10of the License, or (at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19aint32_t with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22Original Source: 1996 - Todd Replogle
23Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
24*/
25//-------------------------------------------------------------------------
26
27//***************************************************************************
28//
29// UTIL_LIB.C - various utils
30//
31//***************************************************************************
32
33#ifdef _WIN32
34 #include "../../Engine/src/windows/inttypes.h"
35#else
36 #include <inttypes.h>
37#endif
38
39#ifndef _util_lib_public
40#define _util_lib_public
41
42
43#ifdef __cplusplus
44 extern "C" {
45#endif
46
47
48extern int _argc;
49extern char ** _argv;
50
51void RegisterShutdownFunction( void (* shutdown) (void) );
52void Error (int errorType, char *error, ...);
53
54uint8_t CheckParm (char *check);
55
56void *SafeMalloc (int32 size);
57int32 SafeMallocSize (void * ptr);
58void SafeFree (void * ptr);
59void SafeRealloc (void ** ptr, int32 newsize);
60int32 ParseHex (uint8_t *hex);
61int32 ParseNum (uint8_t *str);
62int16 MotoShort (int16 l);
63int16 IntelShort (int16 l);
64int32_t Motoint32_t (int32_t l);
65int32_t Intelint32_t (int32_t l);
66
67void HeapSort(uint8_t * base, int32 nel, int32 width, int32 (*compare)(), void (*switcher)());
68
69uint16_t readLE16(void *addr);
70uint32_t readLE32(void *addr);
71
72#ifdef __cplusplus
73};
74#endif
75
76
77#endif