Compare commits

...

2073 commits

Author SHA1 Message Date
smallmodel
cce81cabff
Implement multi-master queries and heartbeats (#717)
Some checks are pending
Build branch / build-all (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
Implement multi-master server list query and multi-master heartbeats. The server list is fetched from multiple masters to improve redundancy, reliability and performance. This improves multiplayer availability by implementing support for using multiple masters.
- The server sends an heartbeat to all masters at once
- The client can query up to 4 masters in parallel depending on their rate
2025-04-27 22:14:08 +02:00
smallmodel
08a985d183
Format script grammar source files
Some checks failed
Build branch / build-all (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
2025-04-26 19:35:45 +02:00
smallmodel
816126b13a
Add ScriptVariable conditions from Ubertools into the script lexer
Those are Ubertools / F.A.K.K remnants that are valid in original mohaa script grammar
2025-04-26 19:10:08 +02:00
smallmodel
f2a6278daa
Fix stage being written past the limit (#716) 2025-04-26 16:39:25 +02:00
smallmodel
c1efc0e066
Set the minimum number to 30 for cl_maxpackets
Some checks failed
Build branch / build-all (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
20 is the bare minimum for players, any value below makes movements look jittery on a 20 fps server. 30 is the optimal value based on network variation and fps variations
2025-04-23 23:56:05 +02:00
smallmodel
236897cfcc
Set the server list socket as non-blocking
Some checks are pending
Build branch / build-all (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
This prevents the game from freezing when the connection is slow or if the master server is unreachable
2025-04-23 00:37:48 +02:00
smallmodel
73b4569c07
Add Com_InitGameSpy() for future use 2025-04-22 22:51:06 +02:00
smallmodel
25de66ed80
Fix wrong function name 2025-04-22 22:01:29 +02:00
smallmodel
a2bbf6cff8
Use functions that return master host information
This splits gamespy client-specific and server-specific code and add common gamespy code to provide more flexibility in the future
2025-04-22 21:40:34 +02:00
smallmodel
01367d0731
Use a more recent version of the gqueryreporting code
Some checks are pending
Build branch / build-all (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
2025-04-22 01:35:28 +02:00
smallmodel
fedc993e57
Initialize the player buffer list 2025-04-22 01:19:42 +02:00
smallmodel
b597240cfd
Link gcd_key to gcd_qr2
This is primarily used for clarity
2025-04-22 00:48:39 +02:00
smallmodel
127c9fe8f4
Uncomment WSACleanup()
The previous issue was because gqueryreporting was not calling SocketStartUp() as expected
2025-04-22 00:31:39 +02:00
smallmodel
ffc35fb5ab
Use the original gqueryreporting from GameSpy SDK
Potentially more stable and thoroughly tested
2025-04-22 00:27:00 +02:00
smallmodel
aa7639485e
Use __linux__ definition to check for linux 2025-04-22 00:25:29 +02:00
smallmodel
a4267d4f77
Initialize update list only for queries that are neither grouprooms or masterinfo 2025-04-21 22:31:41 +02:00
smallmodel
12880db557
Don't force HRTF if the speaker type is not "Headphones" 2025-04-21 21:26:33 +02:00
smallmodel
881d7f2f51
Don't refresh the server list if it's not ready
The server list UI refresh the server list for the first time when drawing. In mohaa (not Spearhead nor Breakthrough), refreshserverlist is also called by clicking "browse internet servers" which causes the list to be queried twice
2025-04-21 21:03:42 +02:00
smallmodel
93335978ea
Code formatting 2025-04-21 20:40:55 +02:00
smallmodel
64f62583ce
Set a more explicit version number
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 44s
Makes it easier to identify the currently running OPM version from the server list, useful for troubleshooting and checking if the server is up to date
2025-04-20 21:42:33 +02:00
smallmodel
5530d3051b
Fix missing spaces between product information in the logfile
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 1m16s
2025-04-19 21:36:58 +02:00
smallmodel
42326ec708
Fix timestamps printed twice on the same line (#714) 2025-04-19 21:35:53 +02:00
smallmodel
aa54e3c673
Use an epsilon value to check if float numbers are equal (#713) 2025-04-19 21:11:51 +02:00
smallmodel
5ce7f4faa5
Compile Windows ARM64 builds using Windows-11 ARM
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 44s
This allows to distribute the load across completely different hosts and also to make sure it compiles on ARM platforms
2025-04-19 14:16:54 +02:00
smallmodel
6d20a438db
Shorter paragraph
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 48s
2025-04-18 21:28:37 +02:00
smallmodel
7f662a93df
Update features.md 2025-04-18 21:20:02 +02:00
smallmodel
1758a0cd2e
Move whitelisted server commands to a dedicated source file 2025-04-18 18:49:12 +02:00
smallmodel
9b003b5428
Update OpenAL to version 1.24.3 2025-04-18 18:11:18 +02:00
smallmodel
db7fdd57e4
Add a section about other systems
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 1m18s
2025-04-17 23:34:49 +02:00
smallmodel
689da52ddf
Master server address update
This uplinks directly with 333networks instead of using a domain as an alias
2025-04-17 22:55:31 +02:00
smallmodel
2a1e2d7d6c
Check for valid scoreboard menu
Some checks failed
Build branch / build-all (push) Failing after 1m11s
CodeQL / Analyze (push) Has been cancelled
Under rare circumstances, the scoreboard menu can be NULL and would cause a crash. This was fixed in mohaab 2.30
2025-04-15 18:37:35 +02:00
smallmodel
cf8af91516
Remove macOS package cache due to permission errors
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 48s
2025-04-15 00:40:48 +02:00
smallmodel
c9ff941600
Implement Instant Action from Breakthrough (#712)
This adds a feature that makes it easy to join a populated low-ping server (matching criteria from configuration file). This feature has been available since MOHAA Breakthrough 2.30.
2025-04-15 00:31:34 +02:00
smallmodel
d389f89c49
Simplified the running documentation
Some checks failed
Build branch / build-all (push) Failing after 46s
CodeQL / Analyze (push) Has been cancelled
2025-04-12 22:49:15 +02:00
smallmodel
e05114806a
Add a simple install guide for Windows users 2025-04-12 22:35:05 +02:00
smallmodel
3074494131
Convert the game version to number once
Some checks failed
Build branch / build-all (push) Failing after 44s
CodeQL / Analyze (push) Has been cancelled
2025-04-04 22:53:06 +02:00
smallmodel
a9e161181c
Improve compiling documentation
Some checks failed
Build branch / build-all (push) Failing after 1m37s
CodeQL / Analyze (push) Has been cancelled
2025-04-01 22:43:58 +02:00
smallmodel
f9db0ab8f9
Fix an access violation that would occur when opening the logfile before com_version is created (#708) 2025-04-01 22:07:05 +02:00
smallmodel
94cc77b848
Set cmake version to 3.5 minimum for libmad 2025-04-01 21:33:16 +02:00
smallmodel
f16bec1e0a
Remove #pragma once from uimessage
Some checks failed
Build branch / build-all (push) Failing after 1m13s
CodeQL / Analyze (push) Has been cancelled
2025-03-24 22:16:53 +01:00
smallmodel
e2c24abf62
Move alext functions out of qal.h (#706)
qal.h should contain core/required functions. To get functions from extensions, alGetProcAddress should be used, so they can be optional
2025-03-24 22:16:43 +01:00
smallmodel
50e3aa1f61
Fix compilation errors with AL local headers (#705)
Some checks failed
Build branch / build-all (push) Failing after 48s
CodeQL / Analyze (push) Has been cancelled
* Remove alext inclusion as it's included by qal.h already

* Update local AL headers
2025-03-22 23:45:41 +01:00
Trung Lê
3c15588292
Update compiling.md (#704)
PowerPC64 LE run the game perfectly
2025-03-22 23:25:50 +01:00
Sébastien Noel
fdab158290
fix build on Debian mips64el (#700)
Some checks failed
Build branch / build-all (push) Failing after 59s
CodeQL / Analyze (push) Has been cancelled
Co-authored-by: smallmodel <15067410+smallmodel@users.noreply.github.com>
2025-03-19 15:26:26 +01:00
Sébastien Noel
921726e0b8
Fix a few typos (#699)
Co-authored-by: smallmodel <15067410+smallmodel@users.noreply.github.com>
2025-03-19 15:03:01 +01:00
Sébastien Noel
b5e49df180
fix build with shared jpeg library (#701) 2025-03-19 14:46:12 +01:00
smallmodel
49fd4acef8
Wrap WriteCallback around HAS_LIBCURL define
Some checks failed
Build branch / build-all (push) Failing after 48s
CodeQL / Analyze (push) Has been cancelled
2025-03-17 11:50:41 +01:00
smallmodel
73aa377264
Fix hit/kill notify being swapped (#698)
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 42s
2025-03-17 00:19:40 +01:00
smallmodel
74e909d17f
Add echo 2025-03-15 19:48:17 +01:00
smallmodel
4b3c150004
Add cg_cameraverticaldisplacement 2025-03-15 19:47:35 +01:00
smallmodel
5ee7948071
Add more sound-related commands 2025-03-15 19:43:23 +01:00
smallmodel
f653317e5b
Add the reason parameter to banaddr documentation
Some checks failed
Build branch / build-all (push) Failing after 57s
CodeQL / Analyze (push) Has been cancelled
2025-03-13 23:57:45 +01:00
smallmodel
de43299841
Add a note about updates 2025-03-13 23:57:08 +01:00
smallmodel
e6f5d76abe
Set the appropriate headers to use API versioning 2025-03-13 23:42:50 +01:00
smallmodel
fecd1eb505
Preallocate and set the maximum buffer size to receive the request 2025-03-13 23:37:20 +01:00
smallmodel
9536a8ec64
Specify a small timeout for each request 2025-03-13 22:41:01 +01:00
smallmodel
06a12246f5
Notify the request thread of shutdown only if it's waiting
This avoids a deadlock that would occur if notify_all() is called before the thread is waiting
2025-03-13 22:37:21 +01:00
smallmodel
456b660b2a
Improve the update checker so it can be opt-out (#696)
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 1m4s
* Add a cvar to enable/disable update checking

* Refactor update checker

This splits the thread part from the main part to clarify the code

* Move and update the configuration documentation, for a more general approach
2025-03-13 21:09:42 +01:00
smallmodel
5b81f6a977
Merge pull request #695 from smallmodel/update_fix
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 43s
Fix the update code
2025-03-13 00:13:38 +01:00
smallmodel
c854df8ffa
Don't start the update thread if it shouldn't be active or if the network doesn't work 2025-03-12 23:58:24 +01:00
smallmodel
22a34d8d68
Fix compile error when libcurl is not installed 2025-03-12 23:18:11 +01:00
smallmodel
0f8969e076
Merge pull request #693 from ysdragon/ban-kick-with-reason
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 44s
Kick/Ban with/no reason
2025-03-12 18:20:48 +01:00
ysdragon
f164e889cc
Add optional reason to kick/ban commands
And enhance `SV_IsBanned` to return ban reason and update `SV_DirectConnect` to display it
2025-03-12 07:30:40 +02:00
ysdragon
1e2a331518
Add reason field to serverBan structure with defined maximum length 2025-03-12 07:30:22 +02:00
smallmodel
158ff62aaa
Fix small typo
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 59s
2025-03-12 00:02:44 +01:00
smallmodel
79af8a46d1
Increase update thread sleep time
This prevents wasting time in scheduling the thread
2025-03-11 23:57:40 +01:00
smallmodel
200bf3229c
Merge pull request #692 from smallmodel/update_notification
Add a client-side update notification
2025-03-11 23:53:51 +01:00
smallmodel
e0b7d4cc60
Display a message box to the client when a new update is available 2025-03-11 23:37:51 +01:00
smallmodel
4fe11b5ea9
Always return false for CheckNewVersion() if libcurl is not used 2025-03-11 23:37:34 +01:00
smallmodel
0b590ab147
Add a way to create a message box 2025-03-11 23:32:22 +01:00
smallmodel
7a20bb4deb
Add a new method that return version numbers 2025-03-11 23:32:18 +01:00
smallmodel
c87c242098
Add a getter for m_font 2025-03-11 23:31:16 +01:00
smallmodel
eb92182230
Split OS builds between different workflow files
Some checks failed
Build branch / build-all (push) Failing after 43s
CodeQL / Analyze (push) Has been cancelled
2025-03-08 16:19:08 +01:00
smallmodel
5b9efaa2a0
Remove cpp-httplib
Some checks failed
Build branch / build-all (push) Failing after 23s
CodeQL / Analyze (push) Has been cancelled
2025-03-06 20:21:23 +01:00
smallmodel
58f7e6f1fe
Use cURL instead of cpp-httplib 2025-03-05 23:40:05 +01:00
smallmodel
9538dcb6e7
Print network name change
Some checks failed
Build branch / build-all (push) Failing after 26s
CodeQL / Analyze (push) Has been cancelled
2025-03-03 22:36:46 +01:00
smallmodel
0080f55ef8
Round to integer to avoid blurry text
Some checks failed
Build branch / build-all (push) Failing after 20s
CodeQL / Analyze (push) Has been cancelled
2025-03-02 14:12:54 +01:00
smallmodel
aac91e8763
Refactor and simplify Alias_ListSort 2025-03-02 13:55:44 +01:00
smallmodel
5c0adf9a28
Refactor Alias_FindRandomRange 2025-03-02 13:49:01 +01:00
smallmodel
9963a99868
Fix a stack overflow issue (#686)
The length check now include the null-terminated character
2025-03-02 13:40:36 +01:00
smallmodel
515a531abf
Use the length returned by Com_sprintf 2025-03-02 13:26:47 +01:00
smallmodel
d3d16ab7b6
Use the index of the entry in the player list, rather than the client number 2025-03-02 13:24:08 +01:00
smallmodel
d08027360f
Formatting 2025-03-01 23:34:24 +01:00
smallmodel
70f6ede7b8
Add GAMESPY_PORT environment variable
Some checks failed
Build branch / build-all (push) Failing after 17s
CodeQL / Analyze (push) Has been cancelled
2025-03-01 00:09:33 +01:00
smallmodel
c1c70a53be
Transition to idle after grouprooms or masterinfo requests are finished 2025-02-28 18:12:34 +01:00
smallmodel
f89bfba5dc
Replace tabs by spaces 2025-02-28 18:11:09 +01:00
smallmodel
c1a66bf9e7
Update README
Some checks failed
Build branch / build-all (push) Failing after 17s
CodeQL / Analyze (push) Has been cancelled
2025-02-24 23:08:13 +01:00
smallmodel
e98c725043
Fix player having no damage alpha in mohaas and mohaab (#678) 2025-02-24 22:11:41 +01:00
smallmodel
ad527a7033
Use ubuntu-22.04-arm OS for GitHub Actions to improve build time 2025-02-24 21:42:42 +01:00
smallmodel
59706d4698
Cache third-party packages to optimize the build time 2025-02-24 20:05:55 +01:00
smallmodel
7addef4f5f
Use Windows Server 2025 to compile Windows binaries
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 17s
2025-02-24 16:44:00 +01:00
smallmodel
08d0a378f8
Fix compilation fail when DEBUG_MEM is set (#677) 2025-02-24 13:38:33 +01:00
smallmodel
01381ed084
Add HTTP support and update checking
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s
2025-02-24 02:20:31 +01:00
smallmodel
2c72908f76
Use the correct allocator when archiving a con_set object
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 17s
The default c++ allocator was be used to allocate an array of pointers, but then when destroying the array, Z_Free was called which would throw an error
2025-02-22 23:31:20 +01:00
smallmodel
32ba71693c
Remove some unnecessary endian swap 2025-02-22 22:56:57 +01:00
smallmodel
7fff3192a6
Fix server object mistakenly casted to int 2025-02-22 22:34:19 +01:00
smallmodel
83aa818c00
Don't add the same server twice 2025-02-22 22:24:19 +01:00
smallmodel
56d61bdef3
Implement support for parsing group rooms and master info 2025-02-22 22:13:23 +01:00
smallmodel
ebd86b32bd
Improve code clarity 2025-02-22 22:12:34 +01:00
smallmodel
08c718d232
Add support for server list encryption and tell the master server to return the server list encrypted 2025-02-22 20:39:10 +01:00
smallmodel
512831dea9
Properly unregister events from the level object
Some checks failed
Build branch / build-all (push) Failing after 18s
CodeQL / Analyze (push) Has been cancelled
Unregister() was mistakenly being called on the DM_Manager object when it should have been called on the level object, to unregister events like axiswin, allieswin, draw
2025-02-20 20:36:19 +01:00
smallmodel
a36bbb0cda
Remove useless qr fields
Some checks failed
Build branch / build-all (push) Failing after 39s
CodeQL / Analyze (push) Has been cancelled
2025-02-19 20:39:56 +01:00
smallmodel
8a9e0f0b01
Update master server address
It's now using master.openmohaa.org, which provides more flexibility for configuring the domain
2025-02-19 20:39:44 +01:00
smallmodel
076fd69131
Use the engine allocator to allocate/delete memory from the table of pointers 2025-02-19 20:11:07 +01:00
smallmodel
587f7f544e
Add REF_DLL for mem_blockalloc 2025-02-19 20:03:23 +01:00
smallmodel
178c486b83
Use NewEntry/DeleteEntry like con_set 2025-02-19 18:16:53 +01:00
smallmodel
ad1748b8be
Fix memory leaks (#668)
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s
2025-02-18 23:27:43 +01:00
smallmodel
004f88dae9
Use a better method for storing class lists
This prevents allocating a ClassDef just to act as a root list. The classlist would never be freed (memory leak)
2025-02-18 22:39:52 +01:00
smallmodel
97fe824b80
Clear subtitles for all nodes when deleting the alias list 2025-02-18 22:35:48 +01:00
smallmodel
758176dd32
Delete the waitTillSet when destroying the class 2025-02-18 21:52:35 +01:00
smallmodel
854c1980cc
Make EventQueueNode part of LightClass 2025-02-18 21:46:34 +01:00
smallmodel
840002b63a
Save and restore bots when needed
When the map was changing, it allocated an array of saved bots which would never be used due to the game module being freed, it caused a memory leaka
2025-02-18 21:35:23 +01:00
smallmodel
47a447dbb0
Remove all state scripts that were created
This fixes a memory leak that also occurs in the original game
2025-02-18 21:08:44 +01:00
smallmodel
a1d47cf64a
Add placement new/placement delete 2025-02-18 20:54:24 +01:00
smallmodel
a5bb4c1874
Free up debug strings when deallocating game-data
This fixes a memory leak, which also occurs in the original game
2025-02-18 20:43:03 +01:00
smallmodel
22b593215f
Implement stop, threadmove and moveoffset
Some checks failed
Build branch / build-all (push) Failing after 24s
CodeQL / Analyze (push) Has been cancelled
2025-02-15 14:39:54 +01:00
smallmodel
68181acec7
Implement Stop() 2025-02-15 14:39:39 +01:00
smallmodel
3af35fa610
Correctly parse the function name in ScriptDeprecatedAlt
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s
2025-02-15 00:51:19 +01:00
smallmodel
2c12d4f2de
Add a newline to ScriptDeprecatedAlt functions 2025-02-15 00:46:24 +01:00
smallmodel
bbac9c559c
Escape variable name 2025-02-14 23:54:15 +01:00
smallmodel
03eaa62902
Merge pull request #666 from ysdragon/fix-openbsd-compilation
Some checks failed
Build branch / build-all (push) Failing after 14s
CodeQL / Analyze (push) Has been cancelled
Fix compilation under OpenBSD
2025-02-08 23:33:58 +01:00
smallmodel
dcca5ed469
Merge branch 'ladder_getters' 2025-02-08 22:23:00 +01:00
smallmodel
2aa46f5a52
Add getters to get facing dir and angles for FuncLadder 2025-02-08 22:22:53 +01:00
smallmodel
ff3c27ab20
Fix assertion when the height is identical between vert0 and vert1 2025-02-08 20:28:46 +01:00
ysdragon
833408c663
Don't link against rt for musl and *BSD platforms 2025-02-08 04:03:24 +02:00
ysdragon
38d9f98221
Update gsPlatformThread.h to include pthread for OpenBSD 2025-02-08 03:49:24 +02:00
smallmodel
ac4b4266b4
Merge pull request #663 from richardradics/resolve-127-gamespy-deprecated-dialog
Some checks failed
Build branch / build-all (push) Failing after 14s
CodeQL / Analyze (push) Has been cancelled
feat: add GameSpy service unavailable dialog
2025-02-06 23:05:59 +01:00
smallmodel
b90bbd9dcf
Format document 2025-02-06 22:56:49 +01:00
smallmodel
e8f69e197c
Initialize variables from the class 2025-02-06 22:56:24 +01:00
smallmodel
9922a7095b
Activate the control and connect dialog's W_Deactivated after its creation
As the control is activated before, the connection should be done after the activation because ActivateControl() sends W_Activated to the UIFloatingWindow, which will cause ActivateControl() to be called again to activate the dialog's title bar button (and would deactivate the gamespy dialog)
2025-02-06 22:50:21 +01:00
smallmodel
3c836144e2
Move widget object creation from the constructor to FrameInitialized() 2025-02-06 22:41:50 +01:00
smallmodel
8c4a593fb0
Merge branch 'resolve-127-gamespy-deprecated-dialog' of https://github.com/richardradics/openmohaa into richardradics-resolve-127-gamespy-deprecated-dialog 2025-02-06 22:27:23 +01:00
smallmodel
0e282833e6
Merge pull request #665 from bulldozerecske/main
Updated FAQ
2025-02-06 22:19:26 +01:00
Bulldozer
54753caf94
Updated FAQ
Added 1 new FAQ and refined format.
2025-02-06 21:24:44 +01:00
Richard Radics
fcba3bed95 feat: add GameSpy service unavailable dialog
resolves #127
2025-02-05 23:12:05 +01:00
smallmodel
d348ac66de
Merge pull request #662 from richardradics/fix-545-loadgame-elapsed-logged
Some checks failed
Build branch / build-all (push) Failing after 14s
CodeQL / Analyze (push) Has been cancelled
fix: fix elapsed time and logged date in loadgame ui
2025-02-04 23:45:15 +01:00
Richard Radics
fd4f5e7d51 fix: fix elapsed time and logged date in loadgame ui
fixes #545
2025-02-04 22:14:52 +01:00
smallmodel
c77fcd2cbc
Clear the edict model when freeing the edict
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 15s
This fixes an issue where configstrings or game state chars would overflow when many models (such as actors with random headmodels/headskins) are spawned
2025-02-04 21:28:37 +01:00
smallmodel
ee385abfef
Update links to third-party libraries 2025-02-04 18:52:46 +01:00
smallmodel
49335ba8a8
Fix improper check of dir->path empty string
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 14s
2025-02-04 00:08:37 +01:00
smallmodel
8ac186ce17
Mark Archive() as override 2025-02-04 00:08:16 +01:00
smallmodel
ca2322a4da
Add recursive check in Com_Printf
This prevents recursive call to Com_Printf during localization and also remove localization errors
2025-02-04 00:03:30 +01:00
smallmodel
a1e7afac76
Prevent using a trick to spoof another name in 1.11 and below 2025-02-03 23:51:40 +01:00
smallmodel
2f75092d8b
Reserve console name for DMMessage 2025-02-03 23:42:38 +01:00
smallmodel
6f9e710ec9
Update events documentation
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 15s
2025-02-03 22:12:35 +01:00
smallmodel
0b12d160bb
Properly construct all objects that has been allocated with AddObjectAt() 2025-02-03 21:28:13 +01:00
smallmodel
330b45a1ed
Fix container object list not constructed when loading 2025-02-03 21:27:44 +01:00
smallmodel
5f0a0d0363
Update events documentation 2025-02-03 20:57:07 +01:00
smallmodel
ad01c2d966
Fix wrong flags getting checked for allowed weapons 2025-02-03 20:43:03 +01:00
smallmodel
fb5ed82401
Add events documentation 2025-02-03 20:24:35 +01:00
smallmodel
eaa7f10b36
Remove useless print 2025-02-03 20:24:26 +01:00
smallmodel
f2c8dbe57a
Merge pull request #661 from bulldozerecske/main
Updated FAQ
2025-02-03 20:05:24 +01:00
Bulldozer
447b0459aa
Merge branch 'openmoh:main' into main 2025-02-03 19:56:11 +01:00
Bulldozer
e31c64e42e
Updated FAQ
Added 2 additional issues and changed the layout.
2025-02-03 19:55:20 +01:00
smallmodel
32411b2a90
Rename player_damage to player_damaged.
The name was ambiguous. The delegate is triggered when the player gets hit (getting damaged), and not when the player damages someone else. The name properly matches the action.
2025-02-03 19:35:04 +01:00
smallmodel
32f850556e
Set the self object when triggering the delegate 2025-02-03 19:33:41 +01:00
smallmodel
fd94f53e25
Add a delegate for player text messages
self = the player who sent the message
first parameter = the text
second parameter = is team message?
2025-02-03 19:32:14 +01:00
smallmodel
4aa7e06a56
Make ev optional for Trigger() 2025-02-03 19:23:54 +01:00
smallmodel
033b76af14
Allow the self object to be specified 2025-02-03 19:22:29 +01:00
smallmodel
e37a5f4d06
Add "isBot" to check whether or not the player is a bot
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 14s
2025-02-02 21:02:06 +01:00
smallmodel
58e12e0141
Reset delegates on restart 2025-02-02 19:35:01 +01:00
smallmodel
147678b0f0
Merge pull request #660 from smallmodel/scriptdelegate
Implement and use delegates
2025-02-02 19:28:14 +01:00
smallmodel
e6cbd00871
Add script delegates matching common scripted events 2025-02-02 19:18:55 +01:00
smallmodel
1eb7458af9
Add event_subscribe and event_unsubscribe scripting commands 2025-02-02 19:14:07 +01:00
smallmodel
38cf5b82b2
Copy the list of registered delegates to execute them 2025-02-02 17:07:03 +01:00
smallmodel
a5c59c4b77
Use maxDataSize when copying Event 2025-02-02 16:50:07 +01:00
smallmodel
d190cc6e40
Use SafeAddFirst 2025-02-02 16:35:27 +01:00
smallmodel
8234ce1e5f
Add pragma once 2025-02-02 16:20:14 +01:00
smallmodel
e962e4e1f5
Use an int instead of a size_t 2025-02-02 16:03:40 +01:00
smallmodel
ee970a3fce
Remove PlayerBot class and use delegates instead 2025-02-02 16:02:56 +01:00
smallmodel
9242faaa49
Add delegate for stufftext 2025-02-02 16:02:22 +01:00
smallmodel
b813f7ee56
Add delegates related for kill/damage 2025-02-02 16:02:11 +01:00
smallmodel
7f64ef05d5
Mark Event getter methods as const 2025-02-02 16:01:41 +01:00
smallmodel
9cb593c9e4
Add support for event subscription (delegates) 2025-02-02 15:58:04 +01:00
smallmodel
cfb343d262
Add str move constructor/assignment
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 13s
2025-02-01 15:52:58 +01:00
smallmodel
9c811c2318
Mark getter methods as const for ScriptThreadLabel 2025-02-01 15:46:08 +01:00
smallmodel
7b97ad6e2f
Add move constructor for ContainerClass and refactor it
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 23s
2025-01-31 22:53:31 +01:00
smallmodel
fdea2a2e92
Free the object list when moving the container 2025-01-31 22:46:35 +01:00
smallmodel
aa0085b57d
Improve the Container class by using move constructor on reallocation when possible
This greatly optimize memory and speed by moving objects instead of copying objects
2025-01-31 22:38:00 +01:00
smallmodel
3fa489c0f9
Add move constructor for SafePtr 2025-01-31 22:22:00 +01:00
smallmodel
fbee409f47
Swap code with event pointer 2025-01-31 20:49:44 +01:00
smallmodel
7a8aa4eb84
Add placement new/delete for LightClass 2025-01-31 20:45:18 +01:00
smallmodel
d4bbaa41c3
Format safeptr source file 2025-01-31 20:45:11 +01:00
smallmodel
bb23fe159f
Fix copy constructor not using a const object 2025-01-31 20:27:37 +01:00
smallmodel
b1a02389f6
Define REF_DLL 2025-01-31 20:22:03 +01:00
smallmodel
f10ddcaa17
Update bot documentation 2025-01-31 20:21:56 +01:00
smallmodel
77f0ce0673
Merge pull request #658 from bulldozerecske/patch-2
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 17s
Create Frequently Asked Questions (FAQ)
2025-01-30 21:18:39 +01:00
smallmodel
7fc486757d
Merge branch 'main' into bulldozerecske-patch-2 2025-01-30 21:06:50 +01:00
smallmodel
dfc3fdb88b
Link to the FAQ 2025-01-30 21:05:02 +01:00
smallmodel
3769bd2a68
Translate instant messages when printing to console
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s
2025-01-29 20:00:55 +01:00
Bulldozer
80d1b3b204
Create Frequently Asked Questions (FAQ)
This document will be suitable for answering issues that have user-related solutions.
2025-01-29 10:12:09 +01:00
smallmodel
e66fd28831
Fix incompatible functions in renderergl2
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 17s
2025-01-28 21:52:58 +01:00
smallmodel
1cabf5c31e
Merge pull request #657 from smallmodel/bulletholes_fix
Bulletholes fix
2025-01-28 20:26:43 +01:00
smallmodel
8341f8cb6a
Fix bullet hole sometimes not playing 2025-01-28 20:24:14 +01:00
smallmodel
1fc36fce9b
Fix multiple bullet hole effects unnecessarily spawning 2025-01-28 20:03:02 +01:00
smallmodel
33dbb07559
Export game name and shortversion as information clients/servers can see 2025-01-28 19:30:17 +01:00
smallmodel
e510c50a24
Set minimum and maximum for effect variables
Some checks failed
Build branch / build-all (push) Failing after 1m39s
CodeQL / Analyze (push) Has been cancelled
2025-01-27 00:44:17 +01:00
smallmodel
c345035e12
Add Cvar_CheckRange exports 2025-01-27 00:13:01 +01:00
smallmodel
9bb4789b32
Add terrain flags
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 18s
2025-01-25 16:40:41 +01:00
smallmodel
7e26814cfa
Use a signed integer to display the score
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 18s
2025-01-24 21:39:09 +01:00
smallmodel
33855cfbee
Implement add, subtract, scale, append and bitset
Some checks failed
Build branch / build-all (push) Failing after 17s
CodeQL / Analyze (push) Has been cancelled
2025-01-23 01:09:33 +01:00
smallmodel
98bb3e0366
Fix Com_SanitizeName infinite loop 2025-01-23 01:09:18 +01:00
smallmodel
52744fb784
Whitelist cg_3rd_person 2025-01-22 21:35:27 +01:00
smallmodel
08e5208835
Add "append" as allowed command 2025-01-22 21:35:09 +01:00
smallmodel
187079842f
Add cg_cheats to check if cheats are enabled 2025-01-22 21:26:29 +01:00
smallmodel
ef2c5d2df6
Check and verify that selected player models are valid
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s
If the player model or the player german model is not valid, they will be reset to the default value. If the server doesn't have one or more of these models, force model feature will not work
2025-01-22 20:52:05 +01:00
smallmodel
92a0a9c197
Cache all models inside the models/player directory
Some player models are missing from precache scripts. This caches all models inside the player directory to avoid a short hitch when a player spawns with a non-cached model
2025-01-22 20:29:27 +01:00
smallmodel
90e46f535c
Add a random number next to the default name
Some checks failed
Build branch / build-all (push) Failing after 17s
CodeQL / Analyze (push) Has been cancelled
2025-01-21 23:26:21 +01:00
smallmodel
02fc573e31
Apply client and server config tweaks when loading the original config 2025-01-21 22:56:05 +01:00
smallmodel
b8c7223da7
Allow "name" to be changed by server
Players often get their name changed due to them having an empty or duplicate name
2025-01-21 22:55:00 +01:00
smallmodel
7b53e25dd5
Set the default rate to 25000 (xDSL) 2025-01-21 22:08:54 +01:00
smallmodel
f8f9d2f65c
Use MAX_PATHNODES rather than a constant number 2025-01-21 20:56:26 +01:00
smallmodel
19e12701f3
Fix HUD scaling for spectator text, and vote text on 4K 2025-01-21 20:15:43 +01:00
smallmodel
24c7311162
Also save the valid ground trace when stepping
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 45s
2025-01-20 22:33:14 +01:00
smallmodel
599914934c
Update documentation 2025-01-20 12:17:48 +01:00
smallmodel
8fdc66d138
Allow axis players to select kar98 sniper on 2.0 and above by choosing german panzer skins
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 18s
2025-01-19 19:16:28 +01:00
smallmodel
83caae7586
Fix terrain tessellation when there is insufficient tris in renderergl2 2025-01-19 17:32:14 +01:00
smallmodel
1f599e62c6
Clear numLightmaps in renderergl2 2025-01-19 17:31:50 +01:00
smallmodel
4e174fd5bf
Fix cheats mistakenly being disabled when loading a saved game, when developer mode is enabled
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 21s
2025-01-19 16:08:28 +01:00
smallmodel
edf3560dd5
Don't load lightmaps on on Permedia 2 2025-01-19 15:21:11 +01:00
smallmodel
7452bf39fb
Always initialize numLightmaps when loading lightmaps
This fixes an issue where the number of lightmaps is kept from the previous map if the new map has no lightmaps
2025-01-19 15:19:27 +01:00
smallmodel
c2bac6d1ef
Prevent lightmapIndex from going below LIGHTMAP_2D 2025-01-19 15:16:35 +01:00
smallmodel
47cd8ccfc8
Force vertex light when using permedia 2 2025-01-19 15:07:50 +01:00
smallmodel
ec6cab28a5
Don't apply kick fireback on older versions of the game
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 15s
2025-01-19 14:45:20 +01:00
smallmodel
45de1067bd
Fix localtime_r parameter
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 14s
2025-01-19 01:41:26 +01:00
smallmodel
7ab04b0bcb
Fix IsEntity() and SimpleEntity() improperly returning true when the listener is NULL
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 15s
2025-01-18 15:43:20 +01:00
smallmodel
1a71d44b43
Safely check if other is NULL when triggering
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 17s
2025-01-18 13:23:30 +01:00
smallmodel
1ea273fba0
Clear the top stack result when self is NULL 2025-01-18 13:02:05 +01:00
smallmodel
591be6c2fd
Create a new node if the load index is outside the node count
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s
2025-01-17 21:49:17 +01:00
smallmodel
6b02457190
Properly correct the opcode in OP_LOAD_STORE_SELF_VAR when self is NULL 2025-01-17 16:49:38 +01:00
smallmodel
87e5b6d41e
Clear the top variable when the event is not valid too 2025-01-17 16:21:13 +01:00
smallmodel
7f0c506fea
Add a comment about the spawn behavior in OG
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 22s
2025-01-16 23:59:04 +01:00
smallmodel
539c2df378
Check for valid event on listener and print an error if the command cannot be executed 2025-01-16 23:25:26 +01:00
smallmodel
4399e2ab31
Merge pull request #634 from smallmodel/bot_player_association_rework
Bot player association rework
2025-01-16 22:29:05 +01:00
smallmodel
210eeff481
Remove controllers that don't have an associated entity
This prevents crashes when the entity was removed (potentially by a mod)
2025-01-16 22:28:37 +01:00
smallmodel
95e72dd339
Use the number of controllers to get the number of spawned bots 2025-01-16 22:27:51 +01:00
smallmodel
a6d9369204
Remove DM player in destructor rather than in a manual function call 2025-01-16 22:17:14 +01:00
smallmodel
ab80045329
Properly check if the number of tris is sufficient for tessellation
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 18s
2025-01-15 21:38:49 +01:00
smallmodel
94aaeac194
Check for the vehicle owner
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 19s
2025-01-15 20:16:58 +01:00
smallmodel
4bec5cef01
Reduce telefrag bounds 2025-01-15 18:42:34 +01:00
smallmodel
1500d213e7
Fix wrong pointer being deleted 2025-01-15 18:29:56 +01:00
smallmodel
2dbe61789d
Don't use the target list if the world is NULL 2025-01-15 18:29:35 +01:00
smallmodel
3f9bed938e
Fix NULL string checking 2025-01-15 18:03:37 +01:00
smallmodel
619d27da81
Add getentity 2025-01-15 18:00:04 +01:00
smallmodel
bfd0f6e744
Fix the platform dependant compile error
Some checks failed
Build branch / build-all (push) Failing after 18s
CodeQL / Analyze (push) Has been cancelled
2025-01-14 00:08:34 +01:00
smallmodel
6d71cabbda
Export FS_FOpenFile 2025-01-13 23:22:33 +01:00
smallmodel
317664f88c
Throw an error if the player is dead in EndLevel() 2025-01-13 20:51:28 +01:00
smallmodel
e7cddd47a5
Fix incorrect map name and spawnpoint when a spawnpoint ('$') is specified, causing crash 2025-01-13 20:45:53 +01:00
smallmodel
393dfae33e
Give starting ammo at the next frame 2025-01-13 20:27:07 +01:00
DraGoN
c69ea0e4d8
Fixed parameter order in localtime_rand gmtime_r for FreeBSD, OpenBSD, and NetBSD
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s
2025-01-13 19:21:56 +01:00
smallmodel
59fdcf0ae9
Add debian 11 and 12
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 18s
2025-01-12 20:29:53 +01:00
smallmodel
f22ea9eb21
Link against rt
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 21s
2025-01-11 23:50:33 +01:00
smallmodel
752588ffcd
Update OpenAL to version 1.24.2 2025-01-11 16:35:02 +01:00
smallmodel
a0f6d7d361
Initialize met_comment to false 2025-01-11 15:20:41 +01:00
smallmodel
1b5232c2d0
Fix compile errors
Some checks failed
Build branch / build-all (push) Failing after 18s
CodeQL / Analyze (push) Has been cancelled
2025-01-09 23:17:39 +01:00
smallmodel
089e68e85e
Add a cvar to opt out for logfile timestamps 2025-01-09 23:08:15 +01:00
smallmodel
a9ec7cff4f
Write the time before each message printed in the logfile 2025-01-09 22:23:02 +01:00
smallmodel
63c2b3642c
Print the version when opening the logfile 2025-01-09 21:42:12 +01:00
smallmodel
5e04124211
Fix accuracy being 0.0 in the stats screen 2025-01-09 21:30:40 +01:00
smallmodel
bbfd4ac280
Bump version number 2025-01-09 20:38:18 +01:00
smallmodel
28fd0ba201
Use spline as the default source resampler for OpenAL
This makes sounds feel stronger, the spline resampler has slightly louder high frequencies
2025-01-09 20:36:15 +01:00
smallmodel
305c026f4e
Import alGetStringiSOFT 2025-01-09 20:29:30 +01:00
smallmodel
b836042a02
Merge pull request #614 from smallmodel/localization_fix
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 1m39s
Localization fix
2025-01-08 22:53:44 +01:00
smallmodel
ec95b6bfbe
Fix localization not working properly 2025-01-08 22:52:47 +01:00
smallmodel
6049ecfc6e
Localize dmbox and gmbox 2025-01-08 21:26:47 +01:00
smallmodel
6a31381c8e
Format localization source files 2025-01-08 21:26:41 +01:00
smallmodel
7f8bcf8075
Don't read localization.txt file twice 2025-01-08 21:07:13 +01:00
smallmodel
b84a47ad3f
Localization files should be sorted case-insensitive 2025-01-08 21:04:09 +01:00
smallmodel
f91d0c1693
Add missing EV_CanSeeNoEnts
The `canseenoents` was accidentally missing from the Entity's response list, some scripts rely on it
2025-01-08 20:52:24 +01:00
smallmodel
cd65424b00
Fix an infinite loop when setting up path for Vehicle 2025-01-08 20:32:34 +01:00
smallmodel
944e0f24ae
Merge pull request #606 from ysdragon/freebsd-support
FreeBSD support
2025-01-08 19:07:32 +01:00
smallmodel
d396a45e64
Annoying MSVC focus mistake 2025-01-08 18:55:54 +01:00
smallmodel
c0d5ebaaf3
Merge branch 'main' into freebsd-support 2025-01-08 18:55:50 +01:00
smallmodel
c3b42cc297
Merge branch 'main' into freebsd-support 2025-01-08 18:50:34 +01:00
smallmodel
4f32d436bb
Disable OpenAL limiter 2025-01-08 18:45:05 +01:00
smallmodel
4268a875fa
Revert commit b95241dcfe 2025-01-08 17:56:44 +01:00
ysdragon
2ec2ef8bbf
Update sys CMake configuration to link execinfo for BSD variants 2025-01-08 11:27:09 +02:00
ysdragon
7ba29029e1
Add support for additional BSD platforms in platform detection 2025-01-08 11:26:54 +02:00
smallmodel
bbdbe62930
Let SetOwner() assign the edict's ownerNum
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 15s
2025-01-07 21:41:49 +01:00
smallmodel
b95241dcfe
Rotate audio listener by +90 degrees forward
This fixes wrong spatialization of 3D sources with HRTF
2025-01-07 20:49:25 +01:00
smallmodel
8cc1cd6f2c
Install audio libraries for CodeQL
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 17s
2025-01-07 01:19:20 +01:00
smallmodel
f7947b3fe3
Add playerbot_strategy source files 2025-01-07 01:03:35 +01:00
smallmodel
4c06dd7107
Make UColor constant 2025-01-07 00:40:11 +01:00
smallmodel
d6db83805d
Make chat message colors brighter 2025-01-07 00:39:45 +01:00
smallmodel
25f4d0199d
Use const UColor pointer 2025-01-07 00:32:03 +01:00
smallmodel
3bcd5cf308
Add UColor copy constructor 2025-01-07 00:26:40 +01:00
smallmodel
ce38cf9040
Add missing newline for the health pickup message 2025-01-07 00:09:44 +01:00
smallmodel
adc2704da0
Improve code clarity 2025-01-07 00:09:28 +01:00
smallmodel
f999d87f68
Set the subtitle regardless of g_subtitle if the alias indicate it's forced
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 1m12s
2025-01-06 13:37:19 +01:00
smallmodel
7f8446ab82
If random alias name is NULL, use one from global aliases 2025-01-06 13:32:50 +01:00
smallmodel
4d2b61a766
Server-side subtitles must only work on single-player mode 2025-01-06 13:29:12 +01:00
smallmodel
1f3661238a
Check for valid player 0 before setting subtitle 2025-01-06 13:26:29 +01:00
smallmodel
5f236d4d42
Fix projectiles having an unassigned weapon owner
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 1m43s
This fixes weapons that shoot projectiles not being taken into account for being the preferred weapon
2025-01-05 23:57:08 +01:00
smallmodel
8fb3856ea6
Add a centerprint message when joining a team that is full 2025-01-05 20:19:52 +01:00
smallmodel
418985f90b
Fix animation not looping in the same state 2025-01-05 20:02:50 +01:00
smallmodel
2c738fa28e
Fix occasional errors related to SV_FindIndex
Some maps (and mods) declare many sounds, sounds with the same name would be present more than once because the case was taken into account
2025-01-05 19:54:32 +01:00
smallmodel
8a8ac2e3d1
Fix newline in win message 2025-01-05 18:36:45 +01:00
smallmodel
cf65fd890d
Fix incorrect number of wins in the scoreboard 2025-01-05 18:20:00 +01:00
smallmodel
6a86fc8067
Fix num voters when calling vote 2025-01-05 17:50:06 +01:00
smallmodel
528039f80b
Don't sanitize semicolon 2025-01-05 17:49:27 +01:00
smallmodel
b5875ae890
Allow the same torso animation to play again
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 15s
This allows replaying the same torso animation, like when activating a new weapon of the same weapon class
2025-01-05 02:29:02 +01:00
smallmodel
8801834804
Don't restart the legs animation from the beginning in the same state
This prevent walking silently by switching weapons indefinitely
2025-01-05 02:20:59 +01:00
smallmodel
a14a2c9684
Fix inconsistent torso animation cross-blending 2025-01-05 02:10:01 +01:00
smallmodel
269e73168e
Fix an issue where animations (legs) would not loop 2025-01-05 02:00:49 +01:00
smallmodel
19eec6305b
Use "idle" anim when in noclip mode 2025-01-04 21:15:32 +01:00
smallmodel
9930d50f99
Fix inconsistent player animation debug print 2025-01-04 20:37:15 +01:00
smallmodel
9427137dbd
Properly increment the packet number before sending the gamespy reply
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 32s
Some programs parse the packet number and stop working properly if the packet number is an incorrect value
2025-01-04 19:43:47 +01:00
smallmodel
c10fd17d19
Bump patch number 2025-01-04 18:01:52 +01:00
smallmodel
3c26b98b65
Generate checksum with noncompat protocol 2025-01-04 17:55:33 +01:00
smallmodel
6e357459e6
Fix fragments being sent too fast
This prevented players with low connection speed unable to connect due to UDP packets being lost. The rate of connecting clients will be properly taken into account
2025-01-04 17:55:11 +01:00
smallmodel
fe42511c54
Changed the color of UIListBox elements
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s
2025-01-03 22:08:59 +01:00
smallmodel
32f507ce15
Fix pulldown menu container using the wrong foreground color 2025-01-03 22:08:26 +01:00
smallmodel
efeda23627
Fix player losing part torso animation during pain
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 39s
2025-01-02 18:04:32 +01:00
smallmodel
465d462756
Automatically adjust the FOV depending on the aspect ratio 2025-01-02 15:52:45 +01:00
smallmodel
df22895b94
Fix compile error 2025-01-02 15:30:34 +01:00
smallmodel
6b2160c876
Add putaway getter for Weapon
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s
2025-01-02 14:27:39 +01:00
smallmodel
088b44e2cc
Don't use the same weapon and add getters for the newActiveWeapon 2025-01-02 14:27:31 +01:00
smallmodel
3f299610fc
Also try to find weapon by name in useWeapon() 2025-01-02 13:33:04 +01:00
smallmodel
713e361d85
Fix DM box position with resolutions above 1920x1080
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 14s
2025-01-02 01:46:34 +01:00
smallmodel
869075f47b
Disable audio virtualization on special audio sources such as music and ambient sounds
This prevents the music from being muffled by HRTF virtualization
2025-01-01 23:58:48 +01:00
smallmodel
a067c58b3d
Add EV_ScriptThread_FileClose2 to call fclose() without getting the return value 2025-01-01 23:38:49 +01:00
smallmodel
b16aaa5adc
Use a scripted object to store the C file handle for file functions
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 15s
2025-01-01 12:40:59 +01:00
smallmodel
f4a412cc24
Fix reverb toggle at runtime even if reverb is unimplemented
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 17s
2024-12-31 13:04:33 +01:00
smallmodel
d83ad43b0b
Fix FPS model not being set correctly to match the world model
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 3m46s
2024-12-30 20:24:49 +01:00
smallmodel
aa9847cf90
Use clean Radix sort code from ioquake3 to sort draw surfaces 2024-12-30 19:18:54 +01:00
smallmodel
18a3658935
Ignore fast path if the drawsurf is a sprite 2024-12-30 19:18:20 +01:00
smallmodel
716a574abe
Clean up terrain when shutting the Ref down 2024-12-30 18:51:10 +01:00
smallmodel
e0dee12578
Clamp LOD terrain values 2024-12-30 16:16:17 +01:00
smallmodel
04b1e88077
Clamp r_subdivisions value 2024-12-30 16:13:50 +01:00
smallmodel
51a2f7d479
Use an enumeration for weapon commands and a function to get the weapon command
This improves clarity for using weapon commands. Also the mask was incorrect for protocol above version 8 (mohaas and mohaab)
2024-12-30 00:55:29 +01:00
smallmodel
2656000ce4
Print chat message from the game module instead of the server 2024-12-29 18:46:40 +01:00
smallmodel
4ec10af1fd
Fix private message not working 2024-12-29 15:43:41 +01:00
smallmodel
78cd0cf28b
Prevent firing weapon if there is a weapon command
This prevent tricks like firing and dropping weapon to shoot silently
2024-12-29 13:45:18 +01:00
smallmodel
3e9d2bf89a
Fix incompatible type being used for shadertext
Some checks failed
Build branch / build-all (push) Failing after 17s
CodeQL / Analyze (push) Has been cancelled
2024-12-27 17:33:29 +01:00
smallmodel
ebe9795bba
Select a random player skin when the bot dies
Some checks failed
Build branch / build-all (push) Failing after 17s
CodeQL / Analyze (push) Has been cancelled
2024-12-25 15:08:57 +01:00
smallmodel
3f2c2f7aa4
Spectate the next player in mohaa 1.0 (instead of random) when pressing use in spectator 2024-12-25 15:08:00 +01:00
smallmodel
583c2720e2
Fix Info_RemoveKey not correctly removing the key 2024-12-25 15:00:32 +01:00
smallmodel
47d6843b70
Fix player model list never initialized 2024-12-25 14:50:11 +01:00
smallmodel
25fd01c46b
Automatically switch to another weapon when the current weapon has no ammo
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 22s
2024-12-24 20:19:08 +01:00
smallmodel
963b2a2bbd
Add getters for Sentient inventory and ammo inventory 2024-12-24 20:04:59 +01:00
smallmodel
7274ceb0ff
Make the bot melee when it is near the player 2024-12-24 19:53:20 +01:00
smallmodel
cb1c3c0b1c
Remove call to SV_WriteDownloadToClient() when sending snapshots, as it's already called when sending download messages 2024-12-24 18:42:05 +01:00
smallmodel
da5c35ec2b
Prevent connecting clients from receiving snapshots and CG messages while connecting
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s
2024-12-24 18:30:08 +01:00
smallmodel
515beeafa7
Fix wrong fov clamping
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 19s
2024-12-23 22:57:26 +01:00
smallmodel
37f5f64ef3
Update features.md 2024-12-23 22:55:17 +01:00
smallmodel
85c401496a
Add a client-game variable for customizing the FOV client-side 2024-12-23 22:53:31 +01:00
smallmodel
07f7c557ce
Move TargetArch.cmake to misc/cmake 2024-12-23 22:34:50 +01:00
smallmodel
31278fba92
Make sure to bind to the renderer FBO when drawing
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s
2024-12-22 22:41:54 +01:00
smallmodel
a32a9e8ae8
Update documentation about bots 2024-12-22 22:07:24 +01:00
smallmodel
70dc1820db
Update README 2024-12-22 21:53:19 +01:00
smallmodel
a760cb75a3
Use RE_AddPolyToScene2 for poly like beams 2024-12-22 20:27:59 +01:00
smallmodel
1d0b912f75
Make sure to check if the sprite is valid 2024-12-22 19:57:14 +01:00
smallmodel
439e0718ce
Fix sprite rendering causing crashes 2024-12-22 19:16:27 +01:00
smallmodel
4c57ba6ef3
Fix currentStaticModel assignment 2024-12-22 19:03:11 +01:00
smallmodel
b4bae40da8
Fix BSP minimum and maximum version on GL2 2024-12-22 19:00:15 +01:00
smallmodel
e04cbd57ea
Fix most shader errors, light rendering
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 18s
2024-12-21 22:49:38 +01:00
smallmodel
66664b7b46
Add tr_vis 2024-12-21 21:43:29 +01:00
smallmodel
546b90d75f
Add basic 3D GL2 rendering with static models and terrain 2024-12-21 17:04:31 +01:00
smallmodel
14e83a52a4
Add terrain rendering 2024-12-21 14:01:11 +01:00
smallmodel
dc9fec9d03
Load JPEG file first before TGA
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 28s
2024-12-20 23:35:14 +01:00
smallmodel
6d21d52d3e
Define USE_INTERNAL_JPEG macro for renderer when using the internal JPEG 2024-12-20 23:31:03 +01:00
smallmodel
3afb87486b
Add basic support for mohaa shaders for GL2 2024-12-20 23:21:28 +01:00
smallmodel
d0c0a55e6d
Fix drawing elements with color 2024-12-20 23:20:30 +01:00
smallmodel
1919b0efcb
Fix Cvar_SetValue not set for ref imports 2024-12-20 23:11:37 +01:00
smallmodel
954d096261
Fix font rendering 2024-12-20 21:53:33 +01:00
smallmodel
7e150c7a8a
Implement used draw functions 2024-12-20 21:27:10 +01:00
smallmodel
77646bda78
Implement RB_Stream draw surfaces 2024-12-20 21:21:10 +01:00
smallmodel
e6848a3ab0
Fix the window sizer losing focus when rapidly dragging the mouse
This would lead to annoyances when trying to resize the window as the window sizer would lose focus
2024-12-20 20:13:05 +01:00
smallmodel
011f49616b
Fix the improper focus and activation of pulldown menus 2024-12-20 19:35:27 +01:00
smallmodel
e1be3c0fd1
Call G_SetClientConfigString() instead to properly set the team configstring 2024-12-20 19:13:17 +01:00
smallmodel
3d950764a2
Add minimal renderergl2 implementation
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 17s
This implementation should just let the game run without crashing, the renderer doesn't show anything yet
2024-12-20 01:23:00 +01:00
smallmodel
fe16f999d8
Use ri.Printf to print instead of the Com_* functions 2024-12-19 22:40:38 +01:00
smallmodel
390c1d3f3d
Move tiki_mesh inclusion to renderercommon CMakeLists 2024-12-19 21:18:54 +01:00
smallmodel
49b5c29c11
Format renderergl1 source files 2024-12-19 21:13:39 +01:00
smallmodel
f86b495cc6
Set all common renderer imports and add openmohaa imports after ioquake3 imports for more clarity 2024-12-19 20:09:52 +01:00
smallmodel
a4d0a96ce5
Clear the camera jitter when ending the remote control 2024-12-19 19:52:29 +01:00
smallmodel
9d4ea75a18
Increase the number of aliases that can be found
Previously, 64 aliases could be chosen for random search, it was incremented to 128 since 2.0, however it should have been increased in Breakthrough as well, because there are aliases with more than 128 elements
2024-12-19 19:19:12 +01:00
smallmodel
38427fa3c5
Add support for compiling both opengl1 and opengl2 when they're built as shared libraries
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 26s
renderercommon is now used, which will appropriately use opengl1 when building static libraries, or compile both opengl1/opengl2 modules when building shared libraries
2024-12-18 23:24:04 +01:00
smallmodel
7d369dec74
Don't render static mesh if there is no static xyz 2024-12-18 19:44:48 +01:00
smallmodel
58bef33bc7
Don't check if the TIKI model exists when initializing a static model
In later version like 2.0 and above, the TIKI model can be registered before static models which would prevent static xyz to be initialized
2024-12-18 19:41:28 +01:00
smallmodel
bd021b109c
Fix a terrible mistake in TIKI_FindTiki with uninitialized variable
This was using an uninitialized buffer to find the cached TIKI, in most configurations it always returned false, but when compiled with GCC it would return true
2024-12-18 19:31:21 +01:00
smallmodel
7e15c2ac1b
Update features.md
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 27s
2024-12-17 23:03:58 +01:00
smallmodel
3b1b994152
Fix temporary spawn spots being incorrectly ignored 2024-12-17 22:54:46 +01:00
smallmodel
4e69d7a78a
Remove redundant code 2024-12-17 22:50:25 +01:00
smallmodel
16166a36b5
Fix spawnpoint metric for objective-based matches 2024-12-17 22:48:10 +01:00
smallmodel
bcbe7cd870
Fix spawn point metric functions not counting the last player 2024-12-17 22:45:43 +01:00
smallmodel
8dba91fbcc
Reopen doors to the other side when blocked 2024-12-17 22:17:02 +01:00
smallmodel
29fe5780e9
Only post the EV_MoveDone event if it's not pending when done moving
There are some situations where EV_MoveDone is posted again through a call to G_PushMove(), this avoids the mover unexpectedly and immediately moving to the new location
2024-12-17 22:15:53 +01:00
smallmodel
12686c0ab1
Format mover source file 2024-12-17 22:02:35 +01:00
smallmodel
a21d712f54
Reopen the door to the other side if it's blocked 2024-12-17 21:30:48 +01:00
smallmodel
2c7d18b331
Initialize client persistent in G_InitClientPersistant 2024-12-17 21:16:45 +01:00
smallmodel
e353673005
Fix player deaths (or total kills) being added twice in round-based matches 2024-12-17 21:11:34 +01:00
smallmodel
6b36bec8e9
Allow custom game ports other than 12203 to be specified through GAME_PORT environment variable 2024-12-17 19:29:17 +01:00
smallmodel
1be50cdddf
Clear the attack time during reaction time 2024-12-17 14:01:13 +01:00
smallmodel
869b257bf8
Add a slight random response time before attacking
Some checks failed
Build branch / build-all (push) Failing after 56s
CodeQL / Analyze (push) Has been cancelled
It's a way to make the fight less difficult between bots and players
2024-12-16 23:05:35 +01:00
smallmodel
f165ebf9a3
Refactor G_ExitLevel 2024-12-16 23:03:15 +01:00
smallmodel
a6c168c289
Count from 0 instead of CS_OBJECTIVES for more clarity 2024-12-16 22:13:26 +01:00
smallmodel
0057a8273c
Initialize the total map time 2024-12-16 21:17:36 +01:00
smallmodel
876829a742
Properly aim the enemy
The bot wasn't aiming properly at the enemy because the bot was aiming from the centroid. It also caused issues when the enemy was crouching
2024-12-16 19:45:42 +01:00
smallmodel
f4519325ce
Speed up bot rotation 2024-12-16 19:41:01 +01:00
smallmodel
932367d061
Append "demo" to the keywords if fs_restrict is enabled
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s
2024-12-15 21:32:34 +01:00
smallmodel
79643d963e
Correctly parse the name of the players returned by the serverstatus command 2024-12-15 21:32:23 +01:00
smallmodel
872b3f5d70
Improve bot movement when stuck 2024-12-15 21:10:48 +01:00
smallmodel
ac4138a763
Declare PID functions
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 17s
2024-12-15 00:20:31 +01:00
smallmodel
0765537d29
Improve bot attack state
This should stop bot aiming forever behind walls and getting stuck to a wall
2024-12-14 23:32:17 +01:00
smallmodel
f2f9ba9f83
Fix emulated death message incorrectly having a '?' at the beginning of each message on base game 2024-12-14 22:14:55 +01:00
smallmodel
20c1fab815
Don't set the frame number if the renderer function doesn't exist 2024-12-14 22:13:11 +01:00
smallmodel
d3fb1331f8
Fix NDEBUG check 2024-12-14 20:09:33 +01:00
smallmodel
13eafb9bf1
Update server doc 2024-12-14 19:53:28 +01:00
smallmodel
1ef61a6e3d
Use the PID file in non-debug builds
The PID file is used to check if openmohaa cleanly exited, and in case it didn't, the user is prompted to start in safe mode
2024-12-14 19:40:49 +01:00
smallmodel
0fb80a4ab5
Use unnamedsoldier.cfg config file if the openmohaa config file doesn't exist 2024-12-14 19:38:52 +01:00
smallmodel
981b12b63d
Return a rounded number in G_GetAngle
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 18s
There are scripts that compare the returned angle with an exact value and sometimes G_GetAngle return a value with a tiny fraction difference
2024-12-13 23:55:34 +01:00
smallmodel
508ee871b9
Add a small offset for checking if the player can get off ladder
This compensates with the difference with floating-point precision between architectures
2024-12-13 23:30:01 +01:00
smallmodel
c293a52f7a
Fix MASK_LADDER mask 2024-12-13 22:54:00 +01:00
smallmodel
acf2dd0ad1
Use an integer when waiting
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 26s
Since the expected time is in milliseconds, it's best to use an integer instead. Floating-point numbers lose precision as they get larger, especially when the level's current time is long (e.g., over 24 hours). This loss of precision could cause scripts to wait unsuccessfully with small numbers, causing unexpected behaviors
2024-12-13 22:17:43 +01:00
smallmodel
32bee2602c
Rename mods to home 2024-12-13 20:37:13 +01:00
smallmodel
d5ec17ec26
Allow subtitles to be set from stufftext 2024-12-13 19:24:58 +01:00
Bulldozer
e53c6b55bf
Update getting_started_installation.md
Spearhead was mentioned instead of Breakthrough.
2024-12-13 18:55:17 +01:00
smallmodel
85da9fabdd
Fix incorrect event/return value for ScriptOrigin::GetAngleEvent
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 17s
2024-12-12 23:50:42 +01:00
smallmodel
e15440af5e
Clear the view velocity when PMF_NO_MOVE is set 2024-12-12 22:52:28 +01:00
smallmodel
26c2225a24
Remove rate assertion 2024-12-12 22:45:44 +01:00
smallmodel
cd06dc0535
Don't validate facet if there is an invalid border plane
The check was missing, which would cause a crash during collision test
2024-12-12 22:37:09 +01:00
smallmodel
1b8ef411ee
Increase the value of MAX_PATCH_PLANES
Some checks failed
Build branch / build-all (push) Failing after 17s
CodeQL / Analyze (push) Has been cancelled
2024-12-11 23:20:27 +01:00
smallmodel
95466b810f
Prevent an infinite loop in ProcessPendingEvents() when an entity is being deleted in thinks 2024-12-11 21:55:31 +01:00
smallmodel
0a41f3bb76
Indicate when processing events 2024-12-11 21:55:22 +01:00
smallmodel
9b247a746c
Add health check script to check for the state of the mohaa server 2024-12-11 20:19:34 +01:00
smallmodel
fcdde53774
Use home instead of mods
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 17s
2024-12-11 00:57:31 +01:00
smallmodel
279cfb364b
Change the homepath instead of the game directory
Otherwise, clients would look for cgamex86.dll module that is inside the fs_game directory
2024-12-11 00:42:54 +01:00
smallmodel
3dcb2cad64
Fix typo 2024-12-10 23:07:57 +01:00
smallmodel
a199188ede
Add more stuff to build dev/server containers 2024-12-10 22:54:32 +01:00
smallmodel
8a84436d1b
Fix Cmd_TokenizeString2 incorrectly ignoring extended ascii characters
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 17s
2024-12-09 22:33:36 +01:00
smallmodel
231553f574
Fix round not ending when the clock reached 0:00
The wrong variable was being checked to end the round
2024-12-09 22:14:57 +01:00
smallmodel
37466cdffb
Fix wrong condition for checking entity 2024-12-09 22:02:48 +01:00
smallmodel
3cc417151d
Fix newlines for G_PrintToAllClients 2024-12-09 21:42:45 +01:00
smallmodel
d26718a711
Fix teamkill kick warning not working 2024-12-09 21:32:38 +01:00
smallmodel
0644bc2967
Don't execute old commands from previous map when initializing cgame 2024-12-09 21:27:08 +01:00
smallmodel
a2e4f1dc25
Use the server frametime when parsing baseline entities from the game state 2024-12-09 19:34:19 +01:00
smallmodel
9c952ab49d
Set the map name from the server 2024-12-09 19:33:05 +01:00
smallmodel
aa52fe73a5
Restart the file system when connected and when the local server has no paks 2024-12-09 19:31:58 +01:00
smallmodel
fee6390281
Update README 2024-12-09 18:55:36 +01:00
smallmodel
835ddb1de3
Set the compass scale to 0.55 by default on the base game 2024-12-09 18:08:00 +01:00
smallmodel
b58f031bcc
Remove unused cg variables
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 17s
2024-12-08 20:09:23 +01:00
smallmodel
3897a44ce6
Bump the version number 2024-12-08 19:58:59 +01:00
smallmodel
1ec88142b9
Put the value of the working directory in quotes 2024-12-08 19:46:36 +01:00
smallmodel
70a5dde726
Correctly handle long strings in chat and game message box 2024-12-08 19:22:25 +01:00
smallmodel
f684349c18
Make sure to pop the loading screen on error
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 16s
This fixes the client getting stuck in the loading screen due to a drop error
2024-12-08 18:47:10 +01:00
smallmodel
a08a9a4f10
Remove TOKEN_NUMBER (unused)
Some maps use #xx to indicate an identifier, so remove this token to avoid errors
2024-12-08 18:24:33 +01:00
smallmodel
f719b87e69
Handle identifiers that are present after strings, by marking strings as identifier 2024-12-08 18:15:26 +01:00
smallmodel
af1cbea966
Also make players non-solid in a vehicle slot 2024-12-08 17:19:39 +01:00
smallmodel
f3f53947bc
Call the switch label only is the primary turret is valid 2024-12-08 16:43:58 +01:00
smallmodel
f0cc34cccf
Correctly parse identifiers starting with a number and containing non-numeric characters 2024-12-08 16:19:57 +01:00
smallmodel
c4a1175ad0
Clear the invulnerable override when loading 2024-12-08 15:53:37 +01:00
smallmodel
333c452f44
Sanitize the name with a maximum buffer size limit 2024-12-08 12:51:14 +01:00
smallmodel
5801af34bb
Don't execute newconfig.cfg
This prevents graphic settings from being overridden by the configuration file previously generated by the original game
2024-12-08 12:43:05 +01:00
smallmodel
da0c36cc88
Also show the port of clients in status 2024-12-08 12:40:21 +01:00
smallmodel
d8d98ade6a
Set the default sound quality to 44 Hz 2024-12-08 12:37:59 +01:00
smallmodel
c3157ad4d7
Use DebugPrintf for errors that are relevant to developers
Some checks failed
Build branch / build-all (push) Failing after 16s
CodeQL / Analyze (push) Has been cancelled
2024-12-06 20:36:12 +01:00
smallmodel
6f686cb7fa
Check if the renderer is loaded instead of checking if it's registered
Some checks failed
CodeQL / Analyze (push) Waiting to run
Build branch / build-all (push) Failing after 43s
2024-12-06 00:45:18 +01:00
smallmodel
39981643a8
Fix incorrect count when unloading sgl fonts 2024-12-06 00:45:12 +01:00
smallmodel
28bdd1b2b3
Made the renderer modular and loadable
This removes coupling between the renderer and UI/client functions. An option USE_RENDERER_DLOPEN was added to specify whether a renderer module should be compiled and loaded, instead of integrating the renderer into the executable directly. This opens the door for a new renderer
2024-12-06 00:15:19 +01:00
smallmodel
35f40e949b
Properly clear UI resources when shutting down the UI 2024-12-05 23:31:38 +01:00
smallmodel
115b7b82aa
Correctly handle the scenario where multiple architectures are specified
Each target will produce a single binary having multiple architectures, instead of having a binary per architecture. The suffix for each binary will be `multiarch`. This makes it easier for the end-user to install and use. This also helps the transition between Intel and Apple Silicon hardware
2024-12-05 21:12:19 +01:00
smallmodel
d7c0ee47fe
Check if the skel is valid before freeing it 2024-12-05 00:42:50 +01:00
smallmodel
0559d643b7
Use TIKI_DPrintf instead of Skel_DPrintf 2024-12-05 00:42:31 +01:00
smallmodel
8446a655bb
Print an error when the skel file extension is unknown 2024-12-04 22:33:42 +01:00
smallmodel
01d098dab5
Clear the number of uses of the skel cache when registering a new skeleton 2024-12-04 22:33:28 +01:00
smallmodel
b6dd3914be
Correctly free skels when freeing TIKIs
This fixes a potential memory leak that would occur when the first skelcache's skel is NULL
2024-12-04 22:30:26 +01:00
smallmodel
c2e45710ad
Improve code clarity 2024-12-04 22:15:01 +01:00
smallmodel
5da24a8ab5
Update mac runner OS to macos-15 2024-12-04 19:37:45 +01:00
smallmodel
ac6b274a4f
Use MAP_SIZE instead of MAX_MAP_BOUNDS
This fixes collision being incorrect on big maps
2024-12-04 19:22:56 +01:00
smallmodel
f703ee2f26
Add a section about installing official patches and improve clarity 2024-12-03 23:09:43 +01:00
smallmodel
70b8f9868e
Use GameFront for links to demos 2024-12-03 22:29:53 +01:00
smallmodel
c69bafeb3f
Add a section about cleaning up the game directory 2024-12-03 21:07:18 +01:00
smallmodel
f7c8c745c4
Don't return a slash at the end for directory name 2024-12-02 21:08:42 +01:00
smallmodel
861338b0fc
Add support for smaller lightmaps
Large lightmap can be disabled for very low-end hardware. A BSP file with a smaller lightmap (_sml.bsp) will be used instead of the standard one if the map supports it
2024-12-02 20:36:45 +01:00
smallmodel
499fe44bde
Call R_RegisterShaderNoMip for the crosshair
This prevents the crosshair texture from being altered by the texture quality settings
2024-12-02 19:00:43 +01:00
smallmodel
ba74943844
Fix picmip adjustment 2024-12-02 18:59:48 +01:00
smallmodel
21f631e733
Compile SDL input/client and SDL OpenGL independently
This decouple the renderer from the client part of SDL (input), and only uses SDL for OpenGL
2024-12-01 22:23:28 +01:00
smallmodel
b5c32a41de
Check for tabs alongside spaces in the lexer between expressions and variables
This fixes a compile error in some scripts that use tabs instead of spaces between expressions
2024-12-01 20:36:30 +01:00
smallmodel
c9373cbc97
Comment out ABI compatibility checks 2024-12-01 20:34:38 +01:00
smallmodel
b5a73384d3
Exclude the slash at the beginning of each file for FS_ListFilteredFiles 2024-12-01 20:33:51 +01:00
smallmodel
4f699f3b58
Add support to compile renderergl2 (currently unimplemented) 2024-12-01 19:21:07 +01:00
smallmodel
4ea598d76b
Reimplement SkipBracedSection 2024-12-01 17:53:51 +01:00
smallmodel
7e6b0a1c2b
Remove SMP and render thread code, as they're unused 2024-12-01 16:32:19 +01:00
smallmodel
d884512a76
Update renderergl2 from upstream ioq3 2024-12-01 15:41:48 +01:00
smallmodel
71450fb36e
Move renderer to renderergl1 2024-12-01 15:30:23 +01:00
smallmodel
4775f29194
Fix build warnings and errors 2024-11-30 23:36:37 +01:00
smallmodel
d5d5c7a55d
Use bits per sample rather than bytes as there are 4-bit sounds 2024-11-30 23:23:49 +01:00
smallmodel
aa74934ae0
Fix huddraw scaling with high resolutions 2024-11-30 23:21:20 +01:00
smallmodel
0534482c22
Fix a small mistake where it uses vidWidth rather than vidHeight 2024-11-30 23:08:23 +01:00
smallmodel
6fe1e86b31
Automatically scale UI elements for high resolutions
This fixes UI elements being tiny on high resolutions like 4K. Now most UI elements will scale automatically with resolutions above 1920x1080.
2024-11-30 22:40:00 +01:00
smallmodel
47983481c9
Use UI definitions instead of cls.glconfig for UI code to get the resolution 2024-11-30 13:54:50 +01:00
smallmodel
383bc60ddb
Update OpenAL to 1.24.1 2024-11-30 00:40:41 +01:00
smallmodel
d834f08cad
Update compiling.md with current version of tools to use 2024-11-30 00:40:35 +01:00
smallmodel
387ccd5cc3
Bump the minimum CMake version to 3.12 2024-11-30 00:36:33 +01:00
smallmodel
0fb775cd60
Only set the infoclient if it's a teammate player that can be sent to other clients 2024-11-29 23:45:52 +01:00
smallmodel
f31ea39331
Add about tweaking the build 2024-11-29 23:00:57 +01:00
smallmodel
56cc3fff53
Use a single variable to disable modern DMA 2024-11-29 22:53:04 +01:00
smallmodel
5f33a617ab
Allow linking directly against system OpenAL library 2024-11-29 22:03:39 +01:00
smallmodel
b3da62f77e
Don't use an offset for constArrayValue
This is risky and a bad practice to offset a pointer. This also fixes the compiler warning
2024-11-29 21:58:07 +01:00
smallmodel
f1e5d02169
Fix insecure printf format 2024-11-29 21:48:56 +01:00
smallmodel
7cad7a4bd0
Fix printf format specifiers 2024-11-29 21:34:41 +01:00
smallmodel
83a874e4fd
Add an option for CMake to specify when targeting the local system 2024-11-29 20:59:47 +01:00
Joey Riches
6eab2ddd57
CMake: Support lib extension on unix
Some distros install to lib64 instead of lib, respect the lib extension
otherwise some {f,c}game gets installed to lib64 and other libs get
installed to lib.
2024-11-28 00:49:00 +01:00
smallmodel
d944b4a21e
Fix wrong command name for ForceDropHealth 2024-11-27 22:40:40 +01:00
smallmodel
58f0245e83
Only add entries for servers that were queried successfully 2024-11-27 22:12:55 +01:00
smallmodel
2f8382f100
Initialize m_bMumble 2024-11-27 21:15:49 +01:00
smallmodel
167bd45a6a
Make the AI rarely play the standidentify animation (pointing finger to the player) 2024-11-27 21:14:51 +01:00
smallmodel
1e9decf193
Add support for IMA-ADPCM sounds (4-bit)
Sounds such as sea waves (mohaa m3l1a) and subpen (mohaas flughafen) will be played accordingly. This uses OpenAL extensions such as AL_EXT_IMA4 and SOFT features such as AL_SOFT_block_alignment
2024-11-27 20:37:56 +01:00
smallmodel
459e13dc76
Allow pusher to teleport
This fixes an issue where teamslaves (bind elements) would not be in sync with the pusher
2024-11-27 14:36:16 +01:00
smallmodel
94e3d95d6c
Update getting_started_installation.md 2024-11-27 14:35:07 +01:00
smallmodel
eeb9139024
Fix incorrect delta for FaceEnemyOrMotion
The AI would not consistently aim at the enemy while covering
2024-11-27 11:57:05 +01:00
smallmodel
486b6f40e5
Don't play sound if the parameter is not specified 2024-11-26 22:47:55 +01:00
smallmodel
d3fdaa060a
Fix bad parameters passed to CG_AnimationDebugMessage 2024-11-26 19:21:18 +01:00
smallmodel
766258e84b
Archive instances of SmokeGrenade
This was mistakenly missing and fixes smoke grenade explosions disappearing after loading from save
2024-11-26 18:38:34 +01:00
smallmodel
8213bf41a8
Fix player having no inventory or dying when respawning immediately after getting killed 2024-11-26 00:53:38 +01:00
smallmodel
8843a8ee15
Remove owner assert
The owner can be NULL so there is no reason to assert on this
2024-11-26 00:36:47 +01:00
smallmodel
6bb09256c5
Teleport the player back to (0,0,0) origin if out of map bounds 2024-11-25 22:32:08 +01:00
smallmodel
b2e6e1b56f
Comment out the Illegal XYZ coordinates message to avoid spamming the console 2024-11-25 22:30:44 +01:00
smallmodel
6b402e5215
Format g_phys source file 2024-11-25 22:21:51 +01:00
smallmodel
04baf673dc
Set MAX_MAP_BOUNDS to 8192 2024-11-25 22:12:47 +01:00
smallmodel
10b7651eff
Use getters for max fire movement and zoom movement 2024-11-25 22:12:29 +01:00
smallmodel
4f76d7291f
Fix typo 2024-11-25 21:02:52 +01:00
smallmodel
1c2be68253
Update getting started (installation) 2024-11-25 20:36:42 +01:00
smallmodel
6c9d6940cc
Disable sv_floodProtect by default 2024-11-25 19:35:37 +01:00
smallmodel
b719455b78
Add the missing newline for iprintln functions 2024-11-25 19:18:15 +01:00
smallmodel
db16c8bea4
Localize player IPrint string 2024-11-25 19:09:02 +01:00
smallmodel
abdaecb28d
Update README 2024-11-25 19:08:03 +01:00
smallmodel
586da44c30
Remove what's Working documentation as everything is implemented 2024-11-24 18:03:15 +01:00
smallmodel
3956e03557
Use Ubuntu 22.04 as the runner OS for linux, to use a lower GLIBC version 2024-11-24 16:31:38 +01:00
ysdragon
8d0b7b77c6 Check for libc and link against execinfo lib for musl libc 2024-11-24 16:04:30 +01:00
ysdragon
23ad991743 Use nullptr instead 2024-11-24 16:04:30 +01:00
smallmodel
4493b2c42e
Prevent integer overflow when interpolating verts 2024-11-24 15:58:18 +01:00
smallmodel
8b6b1597d7
Check for bHitPerson in MV0, MV1 and MV2
This checks if the sentient being hit is dead, and skip it when moving the vehicle so the vehicle doesn't get stuck for when a sentient is dying
2024-11-23 22:58:51 +01:00
smallmodel
dddedba721
Update getting_started_running.md 2024-11-23 21:14:42 +01:00
smallmodel
be34870a18
Copy the channel origin to the sound entity origin when loading
If the channel had a valid entity at the time of saving, make sure to restore the origin
2024-11-23 21:12:58 +01:00
smallmodel
4d4b9288c6
Don't update the streamed channel if the source status AL_INITIAL
This can occur when starting a new sound without playing it, which can happen when reloading the sound system while all sounds are paused (game paused)
2024-11-23 18:42:27 +01:00
smallmodel
fc9be91124
Update OpenAL to 1.24.0
PowerPC will remain on 1.23.1 until the compile issue is resolved
2024-11-23 17:24:05 +01:00
smallmodel
0d24c620fb
Update GCC to version 14 2024-11-23 16:08:25 +01:00
smallmodel
89140f775e
Archive entities at the order they were created
This fixes an issue where turrets would Think() before the base they are mounted on (like tanks), which means the turret would set its origin before the base (tank) does. This issue also occurs on the original game
2024-11-23 15:19:05 +01:00
smallmodel
de6718b511
Include a new section on how to obtain demos online 2024-11-22 21:03:54 +01:00
smallmodel
5c094f9c8a
More clarity 2024-11-22 20:57:26 +01:00
smallmodel
e2f4d8cd6b
Use explicit constants when checking g_gametype 2024-11-22 19:44:53 +01:00
smallmodel
04da76167c
Set the correct face mode for when the AI is facing a entity that allows AI to face
This fixes a mistake where AI would turn away from the player if the player approaches too much
2024-11-22 18:52:36 +01:00
smallmodel
90639cee36
Fix incorrect effect being spawned for MakeEffect CGM 2024-11-22 18:18:27 +01:00
smallmodel
ecfdcca4d5
Update README 2024-11-21 22:07:11 +01:00
smallmodel
3790f057e1
Fix an infinite loop in BulletAttack
This would be caused by an entity that is inside another entity, like 2 actors at the same location
2024-11-21 20:41:57 +01:00
smallmodel
44d8adcfb0
Set the eyePos when loading from save
Server uses the playerState's vEyePos as the position, to add entities to snapshots, so make sure it's initialized before the next snapshot is sent
2024-11-21 20:26:12 +01:00
smallmodel
64f877ae80
Use the correct convention for installing the project
On Win32:
- Binaries and libraries will be installed by default in <PREFIX>/bin
- The prefix is set to `Program Files/openmohaa` by default

On Unix:
- Binaries and libraries will be installed by default in <PREFIX>/lib/openmohaa
- Shared data will be installed in <PREFIX>/share/applications, <PREFIX>/share/metainfo and <PREFIX>/share/icons
- The prefix is set to `/usr/local` by default
2024-11-21 19:49:43 +01:00
smallmodel
2ce8450a7e
Use fprintf to stderr 2024-11-21 01:14:08 +01:00
smallmodel
7e7b3ab280
Fix PDB files mistakenly not included 2024-11-21 00:13:37 +01:00
smallmodel
48c2d026e6
Fix ActorPath not archiving path properly
It was mistakenly archiving the first path multiple times instead of the whole path array. This lead to AI strangely moving after loading from save
2024-11-20 23:32:37 +01:00
smallmodel
ad825f5114
Reimplement noise functions 2024-11-20 23:02:22 +01:00
smallmodel
120a486aea
Use CMake installation directory
This removes the use of the DESTINATION parameter from install() command and instead rely on default values.
The shared build action file was modified to package installed files in a single folder
2024-11-20 22:50:49 +01:00
Joey Riches
864cdf1fc6
CMake: Add uninstall target
https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake

Useful when for testing system-wide installation with linux
2024-11-20 18:01:30 +01:00
Joey Riches
f1c12e0649
misc: Add linux assets
Add a .desktop file, this is used by application launchers in order to
find and execute applications, this should be installed to
`/usr/share/applications/org.openmoh.openmohaa.desktop`.

Add appstream metainfo, this provides metainfo that is used by Software
Centers for discoverability, this should be installed to
`/usr/share/metainfo/org.openmoh.openmohaa.metainfo.xml`.

This will open the door to getting OpenMoHAA packaged up by various
linux distros.
2024-11-20 16:40:01 +01:00
smallmodel
58d8a73269
Don't abort() on interrupt or on program termination 2024-11-20 12:46:04 +01:00
smallmodel
c788d57c52
Use abort() rather than doing a segfault 2024-11-19 23:15:01 +01:00
smallmodel
50eda4156a
Don't remove the weapon if it has no start ammo
Instead, prevent sentients from picking up weapons if they get no ammo from it and they already have that weapon. Instead, just let the weapon be picked up as a new weapon
2024-11-19 22:44:04 +01:00
smallmodel
1e609a4b2f
Ignore bullet tracers in 1.11 and below
Before 2.0, the tracer frequency is set on almost all weapons. This has some artifacts on multiplayer, the tracer doesn't look adjusted in first-person view
2024-11-19 22:24:50 +01:00
smallmodel
a0e2162dd7
Fix 1.11 servers filtered out 2024-11-19 22:16:55 +01:00
smallmodel
01dfbcdbfe
Properly print the backtrace and generate a core dump on both Windows/Unix 2024-11-19 21:45:49 +01:00
smallmodel
862af012cb
Fix infinite loop while getting the number of lines in objectives 2024-11-19 20:26:23 +01:00
smallmodel
d83374d38c
Set the default compass scale to 0.5 for the base game 2024-11-19 19:44:55 +01:00
smallmodel
05e14f6364
Adjust the objectives menu accordingly depending on the game message box which depends on the compass scale 2024-11-19 19:41:46 +01:00
smallmodel
6bc621462c
Use CL_FontStringWidth instead of uie.FontStringWidth 2024-11-19 19:17:16 +01:00
smallmodel
acb08b89f7
Fix constant for screenOrg 2024-11-18 22:03:58 +01:00
smallmodel
2107523eda
Use MAX_CLIENTS - 1 instead of 63 2024-11-18 21:57:02 +01:00
smallmodel
2662174eba
Fix radar clients not blinking when talking 2024-11-18 21:22:50 +01:00
smallmodel
59d03ff6f0
Return a virtual scale with the correct ratio if scale variable is set
This prevents the widget from being stretched out on widescreen, currently only the compass uses scalecvar
2024-11-18 21:13:43 +01:00
smallmodel
05d304dfc3
Set ignoredFiles only if ignore_files was specified
This fixes a crash that would occur due to a NULL string
2024-11-18 20:38:03 +01:00
smallmodel
614ed6e632
Use the vartree for flags, rather than copying the flags to a signed int value 2024-11-18 19:47:54 +01:00
smallmodel
eb938c872d
Make varnode endian-independant
This fixes terrain rendering incorrectly on big-endian architectures by using bit operation. The `flags` field in the union always matched the first byte of the variance float value instead of the least significant byte
2024-11-18 19:44:00 +01:00
smallmodel
46e1aa979b
Use ARRAY_LEN instead of sizeof 2024-11-18 18:46:14 +01:00
smallmodel
ec5acb4d98
Fix bad glDepthRange 2024-11-17 22:59:49 +01:00
smallmodel
b237222761
Update features.md 2024-11-17 22:27:20 +01:00
smallmodel
652df1a5af
Prevent players with SVF_NOCLIENT to use objects 2024-11-17 22:10:03 +01:00
smallmodel
69621335db
Put the target extension version in the version string 2024-11-17 21:31:45 +01:00
smallmodel
7b58fbec8a
Fix comparison operator for char 2024-11-17 21:25:54 +01:00
smallmodel
aeb8aa8e55
Don't send a voice chat message if the entity is not sent to clients 2024-11-17 20:28:03 +01:00
smallmodel
e74e113199
Fix voice message always being sent to enemies in team message 2024-11-17 20:26:40 +01:00
smallmodel
953091cdc8
Move and rename macros to snd_local_new.h 2024-11-17 19:11:59 +01:00
smallmodel
5819145af8
Synchronize the entity time with the channel time when loading
This prevents the channel from stopping immediately during respatialization, the entity time may be updated quite some time after loading
2024-11-17 18:46:21 +01:00
smallmodel
154464cda1
Set the server huddraw elements on single-player mode
This fixes huddraw elements not being archived properly when the map starts
2024-11-17 18:26:00 +01:00
smallmodel
2342f08a79
Print the new damage when g_showbullettrace is turned on 2024-11-17 18:02:57 +01:00
smallmodel
16711a33ef
Fix bulletthroughwood and bulletthroughmetal not being archived correctly
This caused issues on some single-player maps where bullet would go through walls
2024-11-17 18:02:35 +01:00
smallmodel
cea0d95fee
Set the pitch to default when setting a new SFX
This fixes channels having an incorrect pitch when starting the sound under some circumstances
2024-11-17 17:12:36 +01:00
smallmodel
989ec9574c
Fix too high farVal for glDepthRange 2024-11-17 16:46:21 +01:00
smallmodel
b0b82f0252
Fix incorrect start trace for Actor::DontFaceWall()
This fixes AI not turning from wall
2024-11-17 16:36:45 +01:00
smallmodel
80ddba1013
Fix constant string for "officer" disguise type
This fixes the officer think not working at all
2024-11-17 16:36:19 +01:00
smallmodel
23f776d3c7
Fix typo 2024-11-17 14:32:44 +01:00
smallmodel
880acf9120
Make com_target_game and com_target_demo write-protected (can only be set at startup) 2024-11-17 14:28:00 +01:00
smallmodel
598110477e
Archive the m_bAlwaysAway variable 2024-11-16 22:35:55 +01:00
smallmodel
ffdfbc3c7d
Fix the bullet stopping after the first entity 2024-11-16 21:57:12 +01:00
smallmodel
a7dc8b3493
Don't archive r_fastsky variable
This prevents this setting to be altered by mods forever
2024-11-16 21:36:56 +01:00
smallmodel
67d8cad64d
Allow sound files from OS disk in pure mode 2024-11-16 21:34:19 +01:00
smallmodel
b007842fb4
Fix pure checksums not matching the server 2024-11-16 21:32:53 +01:00
smallmodel
2c4b5fc9ba
Rename the type variable to currentType so it doesn't take precedence over the type member
This fixes an issue where it was the type variable that was being set, rather than the type member
2024-11-16 20:07:26 +01:00
smallmodel
e96a3f4f59
Use c_str() instead of accessing m_data
c_str() will always return a valid string even if empty
2024-11-16 19:27:48 +01:00
smallmodel
8eded28efc
Fix the typename in the error message for incompatible types 2024-11-16 19:22:01 +01:00
smallmodel
b68bb4cee7
Fix integer overflow in wait command that would cause infinite loop in stock scripts
It was causing a rare infinite loop in anim/stand.scr where it waits for 9999999 if the actor is unarmed and medic
2024-11-16 19:10:26 +01:00
smallmodel
824cfd789c
Properly save and restore entity's children solidity 2024-11-16 18:19:45 +01:00
smallmodel
a0b80a9096
Fix string not usable for targetname 2024-11-16 18:17:19 +01:00
smallmodel
857d25825b
Remove tmvolume like other commands when shutting down OpenAL 2024-11-16 16:57:59 +01:00
smallmodel
735832829d
Don't drop the weapon if it has no ammo 2024-11-16 00:29:44 +01:00
smallmodel
5703161166
Fix grenade dropping no ammo
This makes the weapon drop at least 1 ammo clip
2024-11-16 00:29:13 +01:00
smallmodel
d85455e9ec
Don't export referenced paks if download is disabled on the server 2024-11-15 21:00:20 +01:00
smallmodel
f6c9de4286
Use com_basegame instead of BASEGAME macro 2024-11-15 20:58:46 +01:00
smallmodel
a598cbf0dc
Update running documentation 2024-11-14 20:25:26 +01:00
smallmodel
67b285924c
Prefix OpenAL with debug prints 2024-11-14 19:49:22 +01:00
smallmodel
0c206beb45
Expect a SimpleEntity rather than an Entity
The specified path in FollowPath can be a Waypoint which is a subclass of SimpleEntity
2024-11-14 19:46:16 +01:00
smallmodel
9a6472210c
Use a separate user-data location for the demo version 2024-11-13 23:15:31 +01:00
smallmodel
7576d1241d
Add hardware requirements for non-x86 architectures 2024-11-13 21:49:43 +01:00
smallmodel
fb2f3bddaa
Fix the intermission screen (mission failed/success) not hiding immediately on the base game 2024-11-13 20:01:05 +01:00
smallmodel
96ca9c20e4
Rework fade sequence and make it work 2024-11-13 19:40:31 +01:00
smallmodel
d01fa33e46
Use 0.31 for Breakthrough demo
This makes the Breakthrough demo client compatible with Breakthrough demo servers
2024-11-13 00:07:07 +01:00
smallmodel
ab84a6ea58
Add support for the demo version of the game
This allows the demo version of the game to be used, both for playing on demo servers, or for hosting a demo server
2024-11-12 23:09:37 +01:00
smallmodel
b0a683c188
Don't localize if the localization hasn't been initialized 2024-11-12 23:09:32 +01:00
smallmodel
e5ef61c5d2
Abort decal loading if a shader cannot be found while loading 2024-11-12 23:00:38 +01:00
smallmodel
02af9a763d
Better support for older BSP versions 2024-11-12 20:56:26 +01:00
smallmodel
132903a843
Use different fields for protocol version 6 and 8 2024-11-12 20:56:02 +01:00
smallmodel
fe862badf6
Add printdeathmsg from moh 2.0 and above 2024-11-12 18:37:17 +01:00
smallmodel
1ad5964c2f
Implement stoploopsound from moh 2.0 and above 2024-11-12 18:21:24 +01:00
smallmodel
851a16e18c
Fix the bullet tracer scale 2024-11-12 00:09:29 +01:00
smallmodel
763a79cb74
Fix angle when in turret 2024-11-11 23:48:39 +01:00
smallmodel
c9ccb0efaf
Check for Sentient instead of Player 2024-11-11 23:48:19 +01:00
smallmodel
9e060d11b6
Allow user-created variables 2024-11-11 20:58:37 +01:00
smallmodel
50fdbaf152
Use CVAR_RESETSTRING instead of CVAR_SERVER_CREATED 2024-11-11 20:36:03 +01:00
smallmodel
ccca958ec5
Get the grid1 on each iteration in case it has been reallocated
This fixes a very rare crash that would occur when loading a world map
2024-11-11 19:48:49 +01:00
smallmodel
dd37ba2741
Properly archive clients 2024-11-11 19:06:05 +01:00
smallmodel
81b49236a5
Use proper types for playerState_t structure 2024-11-11 19:00:36 +01:00
smallmodel
894e1d7d66
Properly cleanup the existing owner from targets 2024-11-11 18:37:29 +01:00
smallmodel
9d83d58756
Create path only if the target is a SplinePath 2024-11-11 18:28:56 +01:00
smallmodel
54b9a0c340
Fix incorrect SKB offsets 2024-11-11 18:28:42 +01:00
smallmodel
2cf380c15d
Add scale field for skel header 2024-11-11 18:12:50 +01:00
smallmodel
d400d8927d
Fix archive data between 64-bit and 32-bit architectures 2024-11-11 17:52:24 +01:00
smallmodel
fef30ff3d5
Clear the splinepath entity flag when destroying 2024-11-11 17:35:41 +01:00
smallmodel
4023c9d863
Fix isOpen event, must return true if it's not closed 2024-11-11 16:40:43 +01:00
smallmodel
7bcb91bbb5
Don't allocate the mark if the number of allocated polys is insufficient
There was a very rare occurrence where it would hang trying to find a free mark poly, when the number of specified polys was more than the number of allocated polys. This bug also occurs in the original game
2024-11-11 15:14:20 +01:00
smallmodel
5edee7d12e
Add tmvolume from Spearhead and Breakthrough 2024-11-11 14:24:57 +01:00
smallmodel
51c7e27bc1
Fix the switch label not being archived 2024-11-11 14:05:14 +01:00
smallmodel
f400190531
Fix the switch label called incorrectly for VehicleTurretGunTandem 2024-11-11 14:04:51 +01:00
smallmodel
8732e368b6
Clear the last command angles when loading 2024-11-11 13:49:33 +01:00
smallmodel
7e4da514f6
Update features.md 2024-11-10 22:14:03 +01:00
smallmodel
9a55939b42
Fix weapon selection 2024-11-10 22:10:34 +01:00
smallmodel
cd89d2c0b4
Don't execute reloadmap if the server is not running 2024-11-10 22:10:24 +01:00
smallmodel
661b08a7fa
Don't set g_shownpc to 1 when developer is set 2024-11-10 21:47:58 +01:00
smallmodel
d27f928e2d
Update features.md 2024-11-10 20:58:46 +01:00
smallmodel
079555e43a
Fix VehicleTurretGun sound 2024-11-10 19:29:33 +01:00
smallmodel
fcc4e94655
Continue traveling if the bullet trace goes backwards 2024-11-10 19:02:59 +01:00
smallmodel
c5721f8a2c
Fix variable name starting with multiple consecutive numbers 2024-11-10 17:55:54 +01:00
smallmodel
e5acee55ea
Restore old behavior of "angle" event of the ScriptOrigin class on previous versions (below 2.30) 2024-11-10 17:42:37 +01:00
smallmodel
d3f3b9b51c
Don't allow lean in single-player in the base game 2024-11-10 17:01:56 +01:00
smallmodel
48e9db8966
Don't reload the state table when archiving
This fixes multiple issues where the player could end on an incorrect move type after loading from save, like getting out of the ladder
2024-11-10 16:50:23 +01:00
smallmodel
67486f1e49
Clear the player velocity on intermission 2024-11-10 16:17:03 +01:00
smallmodel
923a6de394
Clear the velocity when both walking and frozen 2024-11-10 16:07:55 +01:00
smallmodel
de0e4954f8
Call G_MoveClientToIntermission() instead of setting the immobile flag 2024-11-10 15:53:06 +01:00
smallmodel
1ef1bad9ae
Add network profiling tool from Spearhead and Breakthrough
Profiling can be enabled with `cl_netprofile` and `sv_netprofile`, the overlay can be shown using `cl_netprofileoverlay` and `sv_netprofileoverlay` and the server can dump network profile using the `netprofiledump` command
2024-11-09 21:38:16 +01:00
smallmodel
23a035e2ca
Use a default value for maxlen and bVirtualScale for Print 2024-11-09 19:38:15 +01:00
smallmodel
ec73268f94
Reorder methods 2024-11-09 19:21:24 +01:00
smallmodel
2b06cc690e
Add reloadmap server command from Breakthrough 2024-11-09 16:03:08 +01:00
smallmodel
7afc2427ac
Finish DrawBoundingBox() entity implementation 2024-11-09 15:51:27 +01:00
smallmodel
f3bbcba4f0
Set blue horizontal lines for debug bbox 2024-11-09 15:16:46 +01:00
smallmodel
0dca08a66a
Fix actor position on a turret 2024-11-09 14:35:52 +01:00
smallmodel
f646151ce2
Set medium difficulty by default 2024-11-09 13:27:24 +01:00
smallmodel
2e0e5db260
Implement bindweap 2024-11-09 00:27:42 +01:00
smallmodel
f34aad03cd
Add script owner implementation 2024-11-09 00:18:59 +01:00
smallmodel
332d209f62
Check if the turret's vehicle entity is valid 2024-11-08 22:31:49 +01:00
smallmodel
888e35466b
Drop error if the Script cannot load the file 2024-11-08 22:28:33 +01:00
smallmodel
1f69fce10e
Don't check for CONTENTS_BBOX on the base game for large bullets passing through entities
Some mods have tanks with mounted turrets and this would cause issues as the bullet would hit the tank instead
2024-11-08 22:06:51 +01:00
smallmodel
ac3eb58671
Return 4 from getconnstate even if it's deprecated 2024-11-08 21:46:25 +01:00
smallmodel
14f3e2faf9
Add a comment about driver solidity 2024-11-08 21:26:23 +01:00
smallmodel
a528e916c2
Add the owner when starting a thread from trigger_multipleall if the activator is a projectile 2024-11-08 21:26:09 +01:00
smallmodel
e6f83bc1d6
Fix the exit position for the base game 2024-11-08 20:46:45 +01:00
smallmodel
841a8d2b4a
Remove clientState_t from g_local.h (shouldn't be defined here) 2024-11-08 20:37:22 +01:00
smallmodel
a51c250a31
Add ScriptDeprecated macros 2024-11-08 19:33:15 +01:00
smallmodel
c2291e92c4
Add Anim_AngularDelta 2024-11-08 19:32:53 +01:00
smallmodel
b8cc3313b1
Check for valid tiki in PF functions 2024-11-08 19:26:37 +01:00
smallmodel
d1fca3e499
Check for valid skeletor 2024-11-08 19:24:07 +01:00
smallmodel
66b882346f
Clear the animation delta when the animation is invalid 2024-11-08 19:13:56 +01:00
smallmodel
b38fedb18c
Make the vehicle path drive from TurretMove
This fixes the issue where the AB41 can't be controlled
2024-11-07 20:23:24 +01:00
smallmodel
e6559c6ae6
Fire the turret only when attackleft is pressed 2024-11-07 20:02:49 +01:00
smallmodel
772aad79d7
Disable cubemap-based lighting due to rendering artifacts/bugs occurring 2024-11-07 19:37:12 +01:00
smallmodel
3e84dbe6ac
Initialize skipFade 2024-11-06 18:53:43 +01:00
smallmodel
381f2b02f5
Add a paragraph about which release should be downloaded 2024-11-05 22:53:54 +01:00
smallmodel
f347102ecb
Add the skipFade parameter in bsptransition so the fade can be skipped
Useful for scripts that are using fadeout during cinematics and then transitioning to the nextmap, like in e2l2 where vehicles explode at the end of the mission
2024-11-05 22:37:33 +01:00
smallmodel
f5d2fdbcad
Return an empty string if the channel is neither playing nor paused
It was only checking if the channel was playing. This was an issue because, in the main menu the music is paused, which means saving from main menu would not save the music filename
2024-11-05 22:16:15 +01:00
smallmodel
ab037f1890
Properly center the window 2024-11-05 22:03:43 +01:00
smallmodel
a933c78d93
Explosions must not kill the window immediately 2024-11-05 22:02:30 +01:00
smallmodel
d08f539e6d
Correctly initialize the window object 2024-11-05 22:02:08 +01:00
smallmodel
caea6e6bba
Return a reference to a const str for the result of Target() 2024-11-05 21:58:19 +01:00
smallmodel
6970e2d00c
Properly check entity sight against passOwnerNum 2024-11-05 21:48:43 +01:00
smallmodel
af084542c4
Don't set the leadside 2024-11-05 21:48:14 +01:00
smallmodel
9f728580b6
Fix Y normal for the output color from cube being mistakenly used twice
This improves the overall lighting from cubemap
2024-11-05 20:31:56 +01:00
smallmodel
c25d0b668a
Only check if m_bVisible is non-zero 2024-11-05 20:30:30 +01:00
smallmodel
1e29fd7d2b
Refactor SetScript/SetThread 2024-11-05 19:52:13 +01:00
smallmodel
67f822d492
Process label of type 'none'
A none variable should be considered valid, it will just clear the label
2024-11-05 18:43:28 +01:00
smallmodel
effbbd6c62
Support long subtitles 2024-11-05 01:14:21 +01:00
smallmodel
db802d1a4c
Update the running documentation 2024-11-04 22:56:06 +01:00
smallmodel
fba40370af
Only create launchers for the standalone game 2024-11-04 22:52:49 +01:00
smallmodel
fc0ca18632
Add missing QUAKED comments 2024-11-04 21:32:16 +01:00
smallmodel
059b0ba34f
Override respondTo method for TriggerEntity
This makes TriggerEntity respond to any object that is a subclass of Entity. This is useful for scripts wanting script_model to touch triggers for cinematic purposes (for example, the bike crash gag at the end of e2l2)
2024-11-04 21:22:09 +01:00
smallmodel
e833b08a8e
Fix G_GetAngle returning the wrong angle (was flipped) 2024-11-04 20:37:28 +01:00
smallmodel
afc431c413
Add a basic launcher 2024-11-04 01:00:53 +01:00
smallmodel
81e407a924
Add EXE_EXT 2024-11-03 21:45:27 +01:00
smallmodel
1f232efdf3
Add the push velocity when jumping from a valid ground entity 2024-11-03 20:34:49 +01:00
smallmodel
94e1830895
Don't jump when on top of another sentient 2024-11-03 20:32:17 +01:00
smallmodel
406f804ef8
Don't jump when inside a vehicle or turret 2024-11-03 20:30:37 +01:00
smallmodel
437f20dfb9
Set the view angles when archiving 2024-11-03 20:21:01 +01:00
smallmodel
ff4438bce9
Properly load the statemap file and get the pain conditions when archiving 2024-11-03 20:12:14 +01:00
smallmodel
5cb343730b
Rename Conditions to m_conditions 2024-11-03 20:06:31 +01:00
smallmodel
dacaaa2cef
Add missing variables from archive 2024-11-03 20:02:55 +01:00
smallmodel
2e6e20cf09
Set the m_bHasJumped value when jumping 2024-11-03 20:01:21 +01:00
smallmodel
2da379bade
Fix typo for nodropweapons 2024-11-03 19:30:56 +01:00
smallmodel
cf8f755f6c
Make comment more clear 2024-11-03 19:23:11 +01:00
smallmodel
8114003c84
Add screenshot/levelshot allowed stuff commands 2024-11-03 18:54:34 +01:00
smallmodel
bb47ba468c
Fix game.skill and game.detail missing getters 2024-11-03 18:51:27 +01:00
smallmodel
b97c47ab32
Cast to clock_t before left-shift 2024-11-03 18:40:18 +01:00
smallmodel
9042ea320c
Refactor UI_RegisterLoadResource 2024-11-03 18:38:12 +01:00
smallmodel
98e725ef7b
Fix EV_StatsUpdater_UpdateStats missing parameter declaration 2024-11-03 18:28:00 +01:00
smallmodel
05b2d3529e
Implement UI_EndLoadResource 2024-11-03 18:27:41 +01:00
smallmodel
00dbc74269
Use MAX_WEAPON_ANIM_SLOTS instead of a constant 2024-11-03 15:36:55 +01:00
smallmodel
8addeedf5e
Fix event parameters being incorrectly archived 2024-11-03 15:33:14 +01:00
smallmodel
bc834b021c
Use and draw the marker material when specified
This is used by the fuse stopwatch hud
2024-11-03 15:09:47 +01:00
smallmodel
6bac4bd57a
Add assertions to check for valid squad mates 2024-11-03 15:09:27 +01:00
smallmodel
51324aa8e9
Archive the ProjectileTarget ID
The ID was missing during save, this caused issues with projectile generators when looking for a local target
2024-11-03 01:51:17 +01:00
smallmodel
7d1d92980a
Disable the charge life when set to 0 2024-11-03 01:40:34 +01:00
smallmodel
3d42197f50
Initialize the minlife field 2024-11-03 01:26:30 +01:00
smallmodel
8a774c02dc
Call G_BeginIntermission() instead of G_MissionFailed() when calling missionfailed 2024-11-03 00:41:26 +01:00
smallmodel
a644e8a09c
Check for GT_SINGLE_PLAYER instead of 0 2024-11-03 00:40:59 +01:00
smallmodel
6f51427c7c
Add a function to count the number of valid clients 2024-11-03 00:34:33 +01:00
smallmodel
62bcf58d83
Call G_RestartLevelWithDelay instead in G_MissionFailed 2024-11-03 00:33:33 +01:00
smallmodel
f40f206161
Don't add the owner velocity by default
This fixes an issue where AI would throw grenades incorrectly
2024-11-03 00:21:27 +01:00
smallmodel
1235f42143
Set the grenade mode when tossing a grenade with the specified speed 2024-11-03 00:20:47 +01:00
smallmodel
1016bfa1ad
Fix calcgrenadetoss2 not pointing to the correct method 2024-11-03 00:19:31 +01:00
smallmodel
f9ce111784
Set the targetname for projectiles 2024-11-02 22:38:45 +01:00
smallmodel
4c057faf73
Add a newline for warnings 2024-11-02 21:51:19 +01:00
smallmodel
4f16179c09
getmins/getmaxs are getters instead of returns 2024-11-02 21:46:55 +01:00
smallmodel
6991c9f9f7
Fix save comment not having the proper string 2024-11-02 21:22:24 +01:00
smallmodel
6e6dac0b74
Proper formatting 2024-11-02 20:56:32 +01:00
smallmodel
23f9c1a1e6
Only set the effect angles from the supplied angles if the spawnthing doesn't have angle set 2024-11-02 20:14:30 +01:00
smallmodel
e4b2c863d8
Fix angles not being set correctly from the base 2024-11-02 20:13:23 +01:00
smallmodel
ae16994289
Fix amplitude mistakenly being set instead of the base 2024-11-02 19:46:32 +01:00
smallmodel
b8b17bb0c9
Implement VSS wind 2024-11-02 19:12:09 +01:00
smallmodel
3098fc98d3
Don't change the velocity for VSS, this was a mistake 2024-11-02 19:01:05 +01:00
smallmodel
f3ecfd04da
Use macro flags rather than constant values 2024-11-02 18:41:56 +01:00
smallmodel
0796fab24b
Fix VSS sources not lerping at all 2024-11-02 18:06:56 +01:00
smallmodel
0fda31b430
Fix radial velocity/circle effects not properly applying 2024-11-02 17:52:33 +01:00
smallmodel
84a2b4be76
Use cg_effect_physicsrate instead of a constant value 2024-11-02 17:51:44 +01:00
smallmodel
5269fbb1fa
Don't set the accel flag for swarm FX 2024-11-02 17:26:08 +01:00
smallmodel
f23dfa091e
Fix wrong flag used for checking for PMF_NO_HUD 2024-11-02 13:48:03 +01:00
smallmodel
32c3964474
Fix the source line having the entire file 2024-11-01 00:11:09 +01:00
smallmodel
6ff92f0a7e
Process the ubersound folder differently depending on the target version
- On 1.11 and below, the ubersound folder is parsed either only in dedicated server mode or in client-only mode
- On 2.0 and above, alias are cleared and the ubersound folder is always parsed in multiplayer on both client and server
2024-10-31 23:57:18 +01:00
smallmodel
c795b2390e
Add a ScriptMaster constructor 2024-10-31 23:55:12 +01:00
smallmodel
ce7005103c
Handle the case where a vector is given for the face command 2024-10-31 23:51:36 +01:00
smallmodel
1a18878f26
Parse unary operators last when calling events 2024-10-31 22:16:20 +01:00
smallmodel
1e036a7689
Clear the torso and legs state when the movement type is set to portable turret 2024-10-31 19:49:05 +01:00
smallmodel
858b27b809
Handle the case where the legs or the torso state is NULL 2024-10-31 19:48:30 +01:00
smallmodel
b4841a878b
Only set the first found mark time and alpha fade 2024-10-31 19:37:42 +01:00
smallmodel
4565b6a9a8
Add cg_addhud and cg_removehud as whitelisted stuff commands 2024-10-31 01:45:37 +01:00
smallmodel
9ffb407d11
Fix incorrect/uninitialized token returned when there is a macro 2024-10-31 01:31:41 +01:00
smallmodel
0f3ffa267a
Parse const array elements properly 2024-10-31 01:22:38 +01:00
smallmodel
74c8aa95f5
Properly ignore single-digits 2024-10-30 23:21:14 +01:00
smallmodel
4853235d86
Don't parse the token as a variable if the identifier only contains number
This fixes an issue where floats would be parsed as a variable after brackets
2024-10-30 22:42:55 +01:00
smallmodel
0d01ea939d
Fix whole script file being printed sometimes on error 2024-10-30 21:25:15 +01:00
smallmodel
5ba6c006c2
Fix compile error 2024-10-30 00:23:42 +01:00
smallmodel
22e7d1e2e4
Only put animation definitions that exist, rather than setting a NULL animation definition
This fixes issues when searching animations by name
2024-10-29 22:27:22 +01:00
smallmodel
c650af7b55
Fix stack corruption due to an improper assignment to the alias 2024-10-29 21:37:31 +01:00
smallmodel
2ce5e498ab
Use CurrentScriptThread() when getting the current script class
So if the current thread is NULL, it will properly throw an exception
2024-10-29 21:11:44 +01:00
smallmodel
d3212c55a0
Properly parse and cache ubersounds, and don't cache resources that must be always loaded to avoid filling up sound indexes 2024-10-29 21:02:16 +01:00
smallmodel
becf9f5d8c
Cache the source position to improve the source search time
This greatly reduces the time to compile big scripts
2024-10-29 20:26:51 +01:00
smallmodel
9cd8133068
Fix the directory prefix when using filters for FS_ListFilteredFiles 2024-10-29 20:25:25 +01:00
smallmodel
48fa5c0ce6
Parse all scr files inside the ubersound folder 2024-10-28 23:29:04 +01:00
smallmodel
6fc7199719
Register server sounds in multiplayer 2024-10-28 23:28:05 +01:00
smallmodel
9e04f94625
Check if the entity is valid after processing pending events during spawn 2024-10-28 23:14:46 +01:00
smallmodel
c9b844b9ea
Count the number of loaded anims and don't return a valid animation definition if there are no loaded animations 2024-10-28 22:57:52 +01:00
smallmodel
497058d7f4
Make the driver nonsolid while moving 2024-10-28 22:30:52 +01:00
smallmodel
a509dd4692
Fix vehicle exit position when targeting the base game
The base game always uses, when specified, the exit position
2024-10-28 22:25:49 +01:00
smallmodel
8fdfffab36
Keep the mouse cursor position when the client disconnects 2024-10-28 21:13:47 +01:00
smallmodel
aa118bceb3
Set the door speed based on the door type 2024-10-28 20:59:58 +01:00
smallmodel
4da50a78d5
Merge pull request #483 from smallmodel/marks_fix
Fix mark fragments being randomly culled or missing, especially on moving brush models
2024-10-28 20:59:28 +01:00
smallmodel
4d27a6daa3
Fix incorrect vert dist 2024-10-28 20:55:03 +01:00
smallmodel
b6f8997a01
Make the mark object local to the entity 2024-10-28 20:47:01 +01:00
smallmodel
568efd4742
Fix the link to the build branch 2024-10-28 19:05:16 +01:00
smallmodel
bf68808eae
Set the skel index for each updated entity so poses only update when needed
This fixes poses being updated even if they don't need update (no frame changed), which resulted in some performance loss and some rare accuracy issues when AI fire weapons
2024-10-28 00:55:37 +01:00
smallmodel
5cbd2dd988
Use true/false rather than qtrue/qfalse 2024-10-28 00:45:21 +01:00
smallmodel
92b4ae2702
Use ANIM_WEIGHT_NONE instead of 0 2024-10-27 22:16:04 +01:00
smallmodel
a8cdf0b5ad
Don't update the upper animation if the think state is attack/grenade/killed/pain 2024-10-27 21:48:13 +01:00
smallmodel
e8dfa0206b
Use a macro constant for movement/action skan blend frames 2024-10-27 21:39:16 +01:00
smallmodel
afe1ba47cf
Decrease the time tolerance between frames to make animations smoother 2024-10-27 19:37:56 +01:00
smallmodel
2afa9adceb
Add a link to mp-navigation for bots 2024-10-27 18:19:58 +01:00
smallmodel
ef32200c8d
Target older macOS versions 2024-10-27 17:45:23 +01:00
smallmodel
dae7795478
Add NDEBUG compile definition on non-debug builds 2024-10-27 17:45:20 +01:00
smallmodel
7c96b68623
Specify the home directory location for macOS 2024-10-27 15:16:01 +01:00
smallmodel
558e69dba8
Archive the vehicle name
This was missing and this allows the torso state to the modheight to set the bounding box height. Before that, it did not recognize the turret so the modheight was still set to stand. It caused issues when trying to get out a vehicle turret, like the flak88 in e1l1 (the player wasn't able to get out of the turret)
2024-10-27 14:27:44 +01:00
smallmodel
da7cd03f09
Increase packed animation time precision
This tries to fix some client commands replaying
2024-10-27 13:42:42 +01:00
smallmodel
6934e5cff8
Check for valid target list in GetScriptTarget() 2024-10-27 12:16:19 +01:00
smallmodel
c7cdde7bc2
Check if the target list is valid before adding the entity 2024-10-26 22:42:21 +02:00
smallmodel
940ac789b9
Change the current fov only if the fov is currently the selected fov
This prevents the player from modifying the fov while zooming
2024-10-26 22:42:18 +02:00
smallmodel
3d46bae1d0
Stop the triggered music when the server is restarted 2024-10-26 15:07:47 +02:00
smallmodel
16bedf7e86
Warp the sample offset for small streams so it doesn't get past the stream size 2024-10-26 15:07:09 +02:00
KevDoy
2ee531511b
Add: Instructions for installing GOG binaries on *nix 2024-10-26 14:58:34 +02:00
smallmodel
0ad5222946
Use the correct stopwatch for explosives 2024-10-26 13:34:33 +02:00
smallmodel
2b4aef4ea6
Add a newline to Cmd_Stuff
Next commands weren't correctly appended
2024-10-26 13:28:49 +02:00
smallmodel
679cf4b7ec
Correctly remove "prespawn"/"spawn" waittill when loading from save 2024-10-26 13:27:32 +02:00
smallmodel
a993b8d352
Specify "Fixed" instead of "Added" as it's a bug that was fixed 2024-10-26 00:34:50 +02:00
smallmodel
b7403347bb
Ignore the first responder if it's disabled so the UI doesn't get blocked by it 2024-10-26 00:30:42 +02:00
smallmodel
bf978256e9
Add changes from upstream, like pipefile, random number seed 2024-10-25 22:33:02 +02:00
smallmodel
9bd25e9734
Combine mouse movement events in event queue 2024-10-25 22:08:24 +02:00
smallmodel
e7499cca04
Also halt the secondary server list if it exists, when canceling refresh 2024-10-25 22:07:23 +02:00
smallmodel
e2d6156b5a
Apply the hidden visibility for all functions only on macOS
The backtrace still prints the name of functions regardless of the visibility on macOS
2024-10-25 22:01:49 +02:00
smallmodel
31cb6216c9
Use a volatile variable to prevent the function from being entirely optimized 2024-10-25 21:06:30 +02:00
smallmodel
e75f5bbbfc
Version number typo 2024-10-25 21:01:01 +02:00
smallmodel
69cc87212a
Bumped the version number to 0.80.0 due to the number of changes and the completeness 2024-10-25 20:49:23 +02:00
smallmodel
3c1500002b
Implement the destructor for the World class to free up the target list 2024-10-25 20:44:00 +02:00
smallmodel
b2287f3d83
Avoid using nextSnap if the prediction is disabled in the next snap
This prevent blinking issues like flashing arms
2024-10-24 21:56:44 +02:00
smallmodel
005a278210
Use CF_CAMERA_ANGLES_TURRETMODE 2024-10-24 21:08:52 +02:00
smallmodel
976e2ae022
Remove useless GetSentientOwner() 2024-10-24 21:08:44 +02:00
smallmodel
8fe87e1067
Handle turret camera flags which has no interpolation 2024-10-24 21:08:26 +02:00
smallmodel
d142ded9ad
Add RF_FRAMELERP flag to ref entity 2024-10-24 21:08:04 +02:00
smallmodel
090f362bb6
Declare g_allowvote as a serverinfo variable 2024-10-23 23:10:22 +02:00
smallmodel
ff3c25cc07
Add cg_allowvote 2024-10-23 23:09:39 +02:00
smallmodel
ed22a51a72
Only allow breakthrough clients when targeting mohaab 2024-10-23 22:22:09 +02:00
smallmodel
9e0c11a970
Reset scoreboard values like the objective and the picture when initializing a new game 2024-10-23 21:04:23 +02:00
smallmodel
edb52a8448
Properly move items in the map rotation list 2024-10-23 20:52:22 +02:00
smallmodel
afb08e0ea9
Prevent adding duplicate maps in the rotation list 2024-10-23 20:49:00 +02:00
smallmodel
8758ba6cb1
Fix the map not starting after applying the rotation list 2024-10-23 20:42:03 +02:00
smallmodel
e6a9968d23
Remove useless assertion 2024-10-23 20:25:17 +02:00
smallmodel
fcd2d2e668
Use the correct weapon selection menu 2024-10-23 20:15:29 +02:00
smallmodel
991c8869d1
Properly draw circles 2024-10-23 20:10:34 +02:00
smallmodel
aef9dc1704
Add feature to show static models culling with r_showcull 2024-10-23 20:07:17 +02:00
smallmodel
848cf7ac01
Fix AddPointToBounds not properly setting the max bounds 2024-10-23 20:03:07 +02:00
smallmodel
de1d3b6ef4
Don't reset the client structure on single-player 2024-10-22 22:36:46 +02:00
smallmodel
29f8ff8d71
Set the new frame radius
This fixes an issue when culling static models as it uses the radius and the radius wasn't initialized
2024-10-22 22:26:55 +02:00
smallmodel
b641a1040c
Fix incorrect cull point height (should be squared) 2024-10-22 22:25:59 +02:00
smallmodel
83acdeb16e
Allow activation of the game menu so it can be focused 2024-10-22 22:06:19 +02:00
smallmodel
aa2d73a1c8
Correctly copy frame bounds 2024-10-22 21:56:35 +02:00
smallmodel
b7a643aa59
Fix AI wrongly aiming at the wrong direction 2024-10-22 21:51:03 +02:00
smallmodel
3d454c90cb
Rework the target list, use a container instead of an hash set so the target list gets archived correctly
This fixes an issue when loading from a save. A variable referencing target list container would have random entities in it, which would cause errors and crashes when trying to do an action on the array of entities
2024-10-22 20:05:53 +02:00
smallmodel
590b3f5cbb
Fix class ID for throbbing box classes 2024-10-22 00:48:11 +02:00
smallmodel
f87e6d5938
Fix barrel jitter
This fixes barrel objects improperly jittering back and forth, sometimes forever
2024-10-21 22:12:13 +02:00
smallmodel
901e81cdf5
Format barrels source file 2024-10-21 21:59:12 +02:00
smallmodel
d2ed2f5e95
Correct the gamma with the proper destination resolution when resampling 2024-10-21 21:37:08 +02:00
smallmodel
c580ccdee1
Only print a warning instead of dropping when the next snapshot is out of range 2024-10-21 21:26:07 +02:00
smallmodel
8ecbe1dd79
Set the script origin local angles and angles when setting the angle
This fixes the issue where a ScriptOrigin would rotate in the wrong direction
2024-10-21 20:27:52 +02:00
smallmodel
64696c7645
Return the angle using the forward vector 2024-10-21 20:24:47 +02:00
smallmodel
ff0dcbd786
Add G_GetAngle 2024-10-21 20:24:33 +02:00
smallmodel
a3e5d62c96
Increase the precision of the delta animation time 2024-10-21 19:54:25 +02:00
smallmodel
267e2f4b15
Add a workaround against inactivity timer for mods that handle spectating 2024-10-21 19:25:52 +02:00
smallmodel
d52bf52e6a
Add BUTTON_ANY flag when moving mouse 2024-10-21 19:22:54 +02:00
smallmodel
f5391bbfa0
Use BUTTON_ANY to check for input rather than BUTTON_MOUSE 2024-10-21 19:03:19 +02:00
smallmodel
a218106c8b
Reset the number of songs when freeing all songs
This fixes an issue where songs from previous maps get played on maps without a music file
2024-10-21 18:40:42 +02:00
smallmodel
8f54f4b806
When loading from save, set the edict model directly rather than loading and resetting animations 2024-10-20 23:25:42 +02:00
smallmodel
78b2637c66
Don't replay animation for new snapshot entities
This prevent cannons effects from replaying due to it being shown when the player exits the cannon
2024-10-20 23:18:00 +02:00
smallmodel
4b25e24a13
Fix issues when using turret while charging a grenade or using the mine detector 2024-10-20 22:42:44 +02:00
smallmodel
aa0c704655
Instead of resetting the state, prevent using the turret if the player is charging 2024-10-20 22:42:05 +02:00
smallmodel
4da099d15c
Add GetChargeFraction() 2024-10-20 22:41:21 +02:00
smallmodel
0bb11d76bd
Remove accidental print 2024-10-20 22:22:36 +02:00
smallmodel
c146452570
Attempt to fix animation time going back and forth 2024-10-20 22:21:27 +02:00
smallmodel
ed05983a57
Use ceiling for the packed anim time
This is an attempt to fix an issue where the animation time would deviate from 1 bit and would go back and forth
2024-10-20 22:19:57 +02:00
smallmodel
909dc96c2f
Use a separate CG_InterpolateAnimParms function for animation 2024-10-20 22:18:40 +02:00
smallmodel
863a6293e7
Don't draw the lensflare in UI 2024-10-20 19:12:42 +02:00
smallmodel
7a49f6fc8b
Fix the fuse stopwatch 2024-10-20 18:55:27 +02:00
smallmodel
c1433a6d9e
Use the correct stopwatch type for when the sticky bomb gets wet 2024-10-20 18:54:36 +02:00
smallmodel
374b8b9ae7
Add fuse stopwatch 2024-10-20 18:52:50 +02:00
smallmodel
e2f5c80afc
Stop charging the weapon when using turret 2024-10-20 18:46:23 +02:00
smallmodel
29911380d1
Use the weapon owner rather than the last successful hit entity 2024-10-20 01:00:55 +02:00
smallmodel
405a4bfe28
Fix debug line delay not working properly 2024-10-20 00:55:08 +02:00
smallmodel
87e41f0c21
Set the model before anything else 2024-10-19 22:44:07 +02:00
smallmodel
dce2bcca7c
Initialize bModelSet 2024-10-19 22:41:32 +02:00
smallmodel
00421a7666
Process client events with the correct order
Effects that are using commanddelay were not working at all, this fixes the processing of delayed events so they get processed sequentially and at the correct time
2024-10-19 22:38:46 +02:00
smallmodel
fd426926e9
Set all alpha color channel in the current static model to prevent vertices from hiding randomly 2024-10-19 21:54:08 +02:00
smallmodel
d83634f8a2
Allow to specify a model when spawning an entity 2024-10-19 21:40:23 +02:00
smallmodel
6efac1c0f7
Don't set animation 2024-10-19 21:27:03 +02:00
smallmodel
3a68ca7f4b
Handle static shader data and entity surface values for when deforming vertexes 2024-10-19 20:45:50 +02:00
smallmodel
8898919fd3
Correctly parse lightingSpecular parameters 2024-10-19 20:45:24 +02:00
smallmodel
40834380cf
Check if the snap is valid before getting the client number 2024-10-19 20:39:57 +02:00
smallmodel
18abf3854d
Use normals for deform vertexes
This fixes the issue where some ocean shaders would look inconsistent
2024-10-19 20:33:57 +02:00
smallmodel
6d0b4f8cb7
Fix PVS sound overflow 2024-10-18 23:50:52 +02:00
smallmodel
fc1f795e83
Use ULightGreen color on SH/BT for dm messages 2024-10-18 23:19:09 +02:00
smallmodel
ef09f136d4
Fix sound indexes not erased correctly 2024-10-18 23:15:59 +02:00
smallmodel
6136bbd019
Set g_netoptimize to 1 when spawning server 2024-10-18 23:05:53 +02:00
smallmodel
5136aa4886
Properly handle and delete unused non visible entity sounds to free up sound indexes 2024-10-18 23:01:27 +02:00
smallmodel
1a3122bef3
Fix pointer to integer warning 2024-10-18 22:14:45 +02:00
smallmodel
23d7db814c
Use an unsigned integer for the column size
This fixes compile warnings
2024-10-18 22:03:41 +02:00
smallmodel
3174ca5da9
Explicitly mark overridden methods 2024-10-18 22:02:27 +02:00
smallmodel
6a107419e3
Only change the maxclients when the map is different
It fixes an issue where on restart, only the number of snapshot entities was changed without the memory being reallocated for it
2024-10-18 20:26:27 +02:00
smallmodel
6d69a8033f
Initialize the radar 2024-10-18 20:12:47 +02:00
smallmodel
bb9ccdd3b9
Make the bot move slowly when aiming with a semi-auto to improve the spread of their weapon 2024-10-18 20:03:39 +02:00
smallmodel
5b3ce85695
Add a method to get the spread factor 2024-10-18 19:52:49 +02:00
KevDoy
84c5bfa777
Add Open MoHAA Text Logos
Add a logo and update the README file to use the new logo

---------

Co-authored-by: smallmodel <15067410+smallmodel@users.noreply.github.com>
2024-10-18 19:26:01 +02:00
smallmodel
d9166478e5
Set the weapon animation back to idle when finished animating
This fixes an issue that also occur in OG, where some weapons would constantly replay the same sounds (often reload/rechamber) when the weapon entity is removed then added to the client snapshot
2024-10-17 17:50:33 +02:00
smallmodel
373fe45b50
Add an example for using bots 2024-10-17 16:33:26 +02:00
smallmodel
cd83091101
Update the ubuntu version for publishing tags 2024-10-17 16:00:06 +02:00
smallmodel
631abd2b0f
Update section about bots 2024-10-17 15:59:03 +02:00
smallmodel
02df233205
Refactor UploadCompressed 2024-10-17 15:17:20 +02:00
Jesse Mitchell
11e9d0f9ba
[macOS / Compiler Fix] Alter offset for Mouse Buttons
Fix the mouse buttons code and alter how the mouseButton check works
2024-10-17 01:24:22 +02:00
smallmodel
35fea91268
Download and install ninja on Windows, from the official ninja-build GitHub repository
This greatly reduces the compile time on Windows
2024-10-16 22:33:08 +02:00
smallmodel
6f3d79ae1b
Use multi-config generators and specify the build type in the --config when using the cmake command instead of using CMAKE_BUILD_TYPE. Also build third-party libraries in Release mode 2024-10-16 22:04:33 +02:00
smallmodel
32da07ea80
Cache Linux apt packages
This avoid overloading servers by downloading the same set of packages multiple times
2024-10-16 20:35:19 +02:00
smallmodel
e9a76f933b
Cast to int32 rather than uint32 when writing the packed velocity
This fixes an issue where the integer could overflow, on some platforms like ARM the integer would be 0
2024-10-16 19:52:47 +02:00
smallmodel
6b6adf1147
Copy second and third triangles, this was forgotten 2024-10-16 18:28:41 +02:00
smallmodel
6413e770e1
Update compiling doc 2024-10-15 23:46:21 +02:00
smallmodel
7d1067108b
Swap the archive type on big endian architectures 2024-10-15 23:38:39 +02:00
smallmodel
e00ebda641
Disable compression for big endian systems 2024-10-15 23:33:00 +02:00
smallmodel
2b6fc0602a
Avoid misaligned memory access 2024-10-15 23:18:14 +02:00
smallmodel
53c09b5342
Correctly swap skeletons for CPUs that don't support misaligned memory access 2024-10-15 23:10:04 +02:00
smallmodel
d78d8abb9f
Correctly load SKB models on big endian architectures 2024-10-15 23:07:58 +02:00
smallmodel
f6b459b408
Correctly copy long/short taking into account memory overlaps 2024-10-15 22:49:23 +02:00
smallmodel
581585a47c
Prevent clearing the event command list if the event system is not initialized
This fixes the issue where the game could crash (especially in optimized release) due to a memory corruption, because the event command list was deconstructed earlier
2024-10-15 20:52:53 +02:00
smallmodel
ddbdcc91dd
Don't use an offset for the reverse table 2024-10-15 19:22:54 +02:00
smallmodel
8f8b75e0aa
Set symbols visibility to hidden by default
This fixes an issue where shared libraries would use functions from in the executable because they have the same name, which would cause memory corruption
2024-10-14 20:36:06 +02:00
smallmodel
2e673a6bc9
Delete posted events when canceling 2024-10-13 23:49:52 +02:00
smallmodel
8c2b92d151
Remove player from turret when deleted 2024-10-13 23:22:13 +02:00
smallmodel
032fb9b5ba
Make sure to delete all conditional objects
This fixes the issue where memory would be leaked by conditionals
2024-10-13 22:09:38 +02:00
smallmodel
b1c5d6c62a
Increase the backtrace size to 64 2024-10-13 11:32:20 +02:00
smallmodel
037af5d728
Don't access the removed node 2024-10-13 11:32:11 +02:00
Leszek Godlewski
61a2b6a837
Don't call into the OAL channel in S_OPENAL_GetMusicFilename if QAL init failed
Prevent a crash upon vid_restart
2024-10-13 00:25:17 +02:00
smallmodel
13698a9590
MINS and MAXS must be signed values 2024-10-12 01:16:31 +02:00
smallmodel
4f2907ef77
Remove LADDER_HAND_HEIGHT (useless) 2024-10-12 01:16:04 +02:00
smallmodel
8667d11c52
Prevent SV_DropClient() from being called recursively if the client is dropped by a kick or timeout and has too many reliable commands 2024-10-11 22:55:24 +02:00
smallmodel
24309095ff
Rework bot save/load:
- Only save and restore the userinfo
- Restore bots when the server spawns
- Read client session data like real players
2024-10-11 22:54:40 +02:00
smallmodel
d5a90ded17
Add a comment about primary weapon selection on map change 2024-10-11 21:51:52 +02:00
smallmodel
9d744367ac
Add firstTime parameter for bots 2024-10-11 21:46:49 +02:00
smallmodel
46a46a9536
Remove unnecessary code 2024-10-10 22:29:17 +02:00
smallmodel
224c1df553
Test against entities with BSP solidity when testing client visibility 2024-10-10 21:38:51 +02:00
smallmodel
bcea5af30f
Remove unused sound index that were used for non visible players 2024-10-10 21:22:59 +02:00
smallmodel
211ce09c0b
Don't create sound index for non visible players if net optimization is disabled 2024-10-10 21:22:35 +02:00
smallmodel
1e41a2595d
Leave 1 second minimum between each call to RefindPath() 2024-10-10 20:27:52 +02:00
smallmodel
36a080b3a9
Call InitModelList() once
This fixes an issue where the model list would get initialized each frame
2024-10-10 20:11:12 +02:00
smallmodel
a3050f6c64
Avoid using too much performance to update the loading screen, especially on low-end PCs 2024-10-10 19:48:23 +02:00
smallmodel
be5deddc1d
Make indexes and coordinates 16-bytes aligned 2024-10-10 19:10:12 +02:00
smallmodel
36f9bdb88c
Use intptr_t instead of size_t because intptr_t can hold a pointer which is not always the case for size_t 2024-10-10 19:07:20 +02:00
smallmodel
1a33e9a15b
Add BotRotation class to handle bot turning 2024-10-09 21:21:19 +02:00
smallmodel
4157a49c7e
Remove useless include 2024-10-09 21:21:13 +02:00
smallmodel
f27be7314e
Add a BotMovement class for managing bot movements 2024-10-09 20:46:39 +02:00
smallmodel
a425038fa6
Set macOS rpath to @executable_path 2024-10-09 19:38:32 +02:00
smallmodel
0b07858bfc
Refactor PlayerBot to use a separate controller class, alongside classes that manage bots 2024-10-08 22:17:22 +02:00
smallmodel
7dbf1d7bf5
Add a method to get the ladder 2024-10-08 21:52:49 +02:00
smallmodel
34c44ab2cf
Add a method to get the max fire movement 2024-10-08 21:52:43 +02:00
smallmodel
5ec106642d
Fix node cover mask 2024-10-08 21:00:01 +02:00
smallmodel
dcd9ce91a8
Use the raw integer value of the squared distance when comparing nodes 2024-10-08 20:42:22 +02:00
smallmodel
a05fbfe69b
Fix incorrect value of AI_CONCEALMENT_MASK 2024-10-08 20:38:34 +02:00
smallmodel
feb76f4fb4
Allow entities other than SimpleActor for finding covers and sniper nodes 2024-10-08 20:31:50 +02:00
smallmodel
d467b68187
Add node editing support, with a way to dynamically load, remove and modify nodes while editing 2024-10-08 20:25:33 +02:00
smallmodel
de18fa2860
Refactor Entity::FovCheck 2024-10-08 20:14:10 +02:00
smallmodel
58f6c719a9
Add code to select current node in view and draw it for editing later 2024-10-08 01:14:40 +02:00
smallmodel
b2fa21a111
Format navigation source file 2024-10-07 23:52:39 +02:00
smallmodel
f94099e350
Don't link nodes that can't be reached with an high fall height 2024-10-07 23:49:39 +02:00
smallmodel
e2f11879d5
MAXS_Z is 94 2024-10-07 23:05:37 +02:00
Sébastien Noel
aa15b3ea7f
Allow to build against system libs instead of bundled copy 2024-10-07 20:51:23 +02:00
smallmodel
1624d10a01
Don't check for bots for smoothclients 2024-10-07 00:51:01 +02:00
smallmodel
0d53adf9bd
Rework bot spawning
- Add a sv_sharedbots to specify if real client slots should be used
- Removed m_bSpawnBot from level, bots are spawned directly in G_BotBegin instead
- sv_numbots can be used to directly configure the number of bots to spawn
- Fix the way bots spawn/unspawn on-demand
- Documented g_bot functions
2024-10-06 22:57:39 +02:00
smallmodel
295c267c31
Automatically join a team if the bot was put in spectator, and automatically select a primary weapon if none was selected 2024-10-06 22:57:31 +02:00
smallmodel
d4b3f7378e
Don't update the new path check time when there is a new move 2024-10-06 22:29:55 +02:00
smallmodel
a503e18966
Make the bot move to the enemy only if it was seen 2024-10-06 22:29:29 +02:00
smallmodel
b1f7d641fc
Use game.maxclients for the maximum number of bots 2024-10-06 21:44:10 +02:00
smallmodel
5019d1e4f9
Spawn bots after the server has spawned 2024-10-06 21:43:42 +02:00
smallmodel
2aa0205872
Clear client persistent to avoid leaking data 2024-10-06 21:01:05 +02:00
smallmodel
a7befa8882
When a client disconnects, delete the entity on the next frame if the function is called while in thinks 2024-10-06 21:00:40 +02:00
smallmodel
a5058c7bab
Call Delete() instead of deleting the item as it could cause issues if the item is being deleted while iterating over edicts 2024-10-06 19:57:03 +02:00
smallmodel
f5558d106e
Don't set the last radar time if the entity number is above the max number of clients 2024-10-06 19:19:44 +02:00
smallmodel
d19328230c
Allow more bots to be spawned alongside the minimum number of players 2024-10-06 18:50:42 +02:00
smallmodel
b77464386c
Count actual clients that aren't spectating 2024-10-06 18:46:23 +02:00
smallmodel
9119319429
Avoid unbalancing teams when removing bots 2024-10-06 18:46:02 +02:00
smallmodel
d3d85fded0
Add TEAM_MAX 2024-10-06 18:37:31 +02:00
smallmodel
9b9642df8f
Add a very tiny offset off the facing dir as a workaround the 1 bit difference between 32-bit and 64-bit
In 64-bit, some windings are off by 1 bit (float values) compared to 32-bit, which causes issue on some maps like `dm/mp_stadt_dm` where the player would get stuck climbing up because of the blocking patch at the top
2024-10-06 17:33:48 +02:00
smallmodel
e564a97b05
Check if the delta is exactly 16 2024-10-06 17:31:02 +02:00
smallmodel
a150cb5c6e
Also check for liberation game type when the team is dead 2024-10-06 16:58:20 +02:00
smallmodel
afd7943b62
Fix incorrect teams and controllers for TOW objectives 2024-10-06 15:20:45 +02:00
smallmodel
09eb130b6d
Update curiosity and MoveDone() 2024-10-06 14:24:32 +02:00
smallmodel
5869ba06bc
Update the attack time when moving 2024-10-06 01:13:12 +02:00
smallmodel
b6c2638c1b
Make curiosity random 2024-10-06 01:01:03 +02:00
smallmodel
16b0f0d625
Use random() in CuriousSound() 2024-10-06 00:53:31 +02:00
smallmodel
9293930628
Make bots jump off ladder
They don't support ladders yet
2024-10-05 23:59:32 +02:00
smallmodel
46935b165c
Fix MoveDone() not checking for height, also return false when temporarily getting away 2024-10-05 23:57:02 +02:00
smallmodel
c0dd08f6e0
Set an higher firing sound in MP 2024-10-05 21:24:45 +02:00
smallmodel
1fde1647e8
Use the proper enum for BroadcastAIEvent 2024-10-05 21:24:29 +02:00
smallmodel
7ef006ccca
Fix nodes improperly connecting to other nodes that are below the ground 2024-10-05 21:15:37 +02:00
smallmodel
fd69d6b42c
Allow the bot to get out if stuck while falling 2024-10-05 20:46:16 +02:00
smallmodel
627f66fb5b
Add basic pathnode editing feature 2024-10-05 20:45:56 +02:00
smallmodel
8451c11916
Add a feature to dynamically create a master class for development 2024-10-05 20:17:11 +02:00
smallmodel
6bbbbcfb05
Allow spawning a simple entity 2024-10-05 20:15:50 +02:00
smallmodel
63465278a5
When there is no free player start spot, try to find a random player s tart one 2024-10-05 20:15:40 +02:00
smallmodel
2980771deb
Fix path node connection, use the target node num 2024-10-05 20:13:03 +02:00
smallmodel
1169b84c2f
Make sure the entity is valid before checking for the bad place team 2024-10-05 20:12:37 +02:00
smallmodel
355491a950
Reduce the bot attack time to avoid the bot getting stuck 2024-10-05 14:47:09 +02:00
smallmodel
7caa0adbab
Toggle use button and don't use if the door is open 2024-10-05 14:46:44 +02:00
smallmodel
8acc51c489
Correctly add/remove bots 2024-10-05 13:54:53 +02:00
smallmodel
732fd98593
Make the bot strafe when attacking 2024-10-05 13:43:09 +02:00
smallmodel
21a610d22c
Fix NoticeEvent ignoring other players on FFA 2024-10-05 11:56:08 +02:00
smallmodel
a379e6efbf
Don't use Ninja on Windows because of chocolatey servers causing troubles 2024-10-05 00:39:23 +02:00
smallmodel
b1e1b6cc68
Properly aim at the last enemy position with some randomness applied 2024-10-04 22:10:51 +02:00
smallmodel
da86e0ce34
Fix bot incorrectly jumping 2024-10-04 21:23:49 +02:00
smallmodel
6ca12eb0de
Fix bot sometimes being stuck respawning between team spawn intervals 2024-10-04 20:27:28 +02:00
smallmodel
a25442368b
Make the bot jump more to avoid getting stuck 2024-10-04 20:25:05 +02:00
smallmodel
e7e95d47a5
Prevent others from picking up the health item if their future health will be full 2024-10-04 19:59:09 +02:00
smallmodel
292fe8eab4
Stop moving if there is a maximum fire movement so the weapon can be fired 2024-10-04 19:48:09 +02:00
smallmodel
272a401189
Make the bot jump even if the path is not valid to get out of spawns with no path nodes 2024-10-04 19:03:33 +02:00
smallmodel
592e3f47e9
Handle curiosity sounds better by getting the owner of concerned entities and ignoring team mates 2024-10-03 22:54:25 +02:00
smallmodel
cabf1a9043
Make AI path more random 2024-10-03 22:23:46 +02:00
smallmodel
e623541861
Improve the way bots turn, make it smoother 2024-10-03 21:57:29 +02:00
smallmodel
b74b6f8c1d
Use the last attacker origin instead of the last death position 2024-10-03 21:33:12 +02:00
smallmodel
11abdd451f
Fix incorrect dir for PathSearch::FindPathAway 2024-10-03 21:27:30 +02:00
smallmodel
1c3596b1f9
Add more conditions to check for valid enemies when attacking 2024-10-03 20:45:23 +02:00
smallmodel
1e73333fbe
Make bot path more random when idle 2024-10-03 20:22:54 +02:00
smallmodel
6eb49f567a
Made tempaway path better 2024-10-03 20:10:33 +02:00
smallmodel
0120e7e4a5
Add liberation messages 2024-10-03 19:06:03 +02:00
smallmodel
10e4d3db11
Check if the activeItem is within the configstring range to avoid leaking data 2024-10-03 19:05:56 +02:00
smallmodel
0b34d2dbb8
Fix ammo bits being incorrect 2024-10-02 23:04:30 +02:00
smallmodel
be1ef1de0e
Try respawning when the player should respawn
This fixes an issue where bots wouldn't respawn with `sv_team_spawn_interval` set
2024-10-02 22:18:07 +02:00
smallmodel
ef45c988c6
Fix player spectating often not spectating the next alive player 2024-10-02 22:16:58 +02:00
smallmodel
3ecdee1b89
Make bots play a taunt when they get a kill 2024-10-02 21:54:56 +02:00
smallmodel
c7561b1f6d
Send the GotKill event to the attacker when killed 2024-10-02 21:50:59 +02:00
smallmodel
50a3df8dff
Fix the instant message maximum number on AA and SH/BT 2024-10-02 21:49:20 +02:00
smallmodel
dfde4a58de
Improve bot movements
- Do random movements if the path cannot be found
- Reset the movement if the bot is really blocked
- Set an higher fall height
2024-10-02 21:29:38 +02:00
smallmodel
090ba308d8
Clear bot buttons after spawning
This fixes a rare occurrence where the bot would fire and reload after spawning
2024-10-02 20:14:24 +02:00
smallmodel
e01e989c22
Check if the snap is valid when notifying for hit/kill
The game would crash otherwise, this is also an issue in the original game
2024-10-02 20:10:29 +02:00
smallmodel
a9b4af98fc
Make bots use random player models 2024-10-02 19:42:03 +02:00
smallmodel
30f5442728
Limit bot vision distance to the farplane 2024-10-02 19:41:25 +02:00
smallmodel
123ca2812a
Define and use DEFAULT_SFX_NUMBER_PLAYING 2024-10-02 19:02:20 +02:00
smallmodel
95435ea512
Improve bot movement
- The bot will immediately move upon spawning
- If blocked, the block will move randomly to get out
- There is now only 1/5 chance the bot will go to the location where they died
2024-10-02 18:34:45 +02:00
smallmodel
db625baadd
Set the healrate to 0 (instant) by default on protocol 8 and below (vanilla AA) 2024-10-02 18:12:10 +02:00
smallmodel
200a80aa02
Automatically choose a primary weapon for bots 2024-10-02 17:02:59 +02:00
smallmodel
0472a93c3f
Ignore kills when telefragging
This fixes an issue (that also occur on OG) where telefrags would also count towards teamkills
2024-10-02 17:02:48 +02:00
smallmodel
9b70e646dc
Add "auto" to automatically choose a primary weapon 2024-10-02 16:52:22 +02:00
smallmodel
388ab210a7
Fix incorrect obituary hit location 2024-10-02 16:42:10 +02:00
smallmodel
15e8a71249
Fix bot userinfo accumulating with previous bot userinfo 2024-10-02 15:59:41 +02:00
smallmodel
dfd04f0d41
Reset the player state when using a turret
This prevents the player from using the turret + hold their weapon to crouch and become impossible to hit
2024-10-02 14:50:11 +02:00
smallmodel
88ac49c0c9
Set the correct flag when the player is using a turret 2024-10-02 14:35:37 +02:00
smallmodel
7d6ff3e6a4
Format bg source files 2024-10-02 14:09:36 +02:00
smallmodel
c68fbfacb9
Set the EF_PLAYER_IN_MENU flag when the player is talking 2024-10-02 14:09:27 +02:00
smallmodel
8e51c7ca3b
Fix VEHICLE_TYPE state condition not returning the vehicle type
This fixes player lacking animation when using heavy weapons like the granatwerfer
2024-10-02 14:09:07 +02:00
smallmodel
33064f8392
Set a default minimum delay between text messages 2024-10-02 13:31:45 +02:00
smallmodel
40141465b5
Add a section about flood protection 2024-10-02 13:29:58 +02:00
smallmodel
13d855c2e7
Use Cmd_Argv() to check for dmmessage 2024-10-02 13:07:04 +02:00
smallmodel
2f8b6a2009
Satisfy stufftext tests 2024-10-02 12:27:57 +02:00
smallmodel
23e56e767f
Increase sphere light limit
Some servers have a lot of objects in maps, causing all spheres to be used
2024-10-02 12:18:58 +02:00
smallmodel
ce5b954c4d
Use the target game version when sending the version to the server, instead of the global project version
The non-dedicated server version of MOH: Breakthrough (standalone executable) rejects clients that have a version of 2.30 or below, or a version of 2.50 or above (0.1 difference), which prevents playing LAN sessions of Breakthrough. To solve this issue, the client now sends a version value that is within the allowed version range for the target game
2024-10-01 23:36:05 +02:00
smallmodel
a0c20663a0
Don't make the player not solid in a vehicle slot
This fixes player not taking hits from explosions
2024-10-01 23:25:01 +02:00
smallmodel
56f850b59d
Don't add the same world surface more than once
This fixes an issue where shaders like water, ocean would look strange or completely black, due to them blending against each other multiple times
2024-10-01 20:51:56 +02:00
smallmodel
253d4e2c4d
Fix jammed door message printed on the first client 2024-10-01 20:26:17 +02:00
smallmodel
6fef42d6e0
Localize the jammed door message 2024-10-01 20:25:51 +02:00
smallmodel
d6a00a5984
Fix IsOpen event not being used
Some multiplayer and single-player scripts rely on it
2024-10-01 20:24:12 +02:00
smallmodel
26a1e24e3a
Fix TIKI_ParseAnimations incorrectly swallowing the full animation file when the map doesn't match
This fixes missing animations
2024-10-01 19:53:33 +02:00
smallmodel
6103efa8cc
Don't set the entity angles immediately during glue
The game expects objects to glue and keep their initial angles/origin
2024-10-01 19:03:17 +02:00
smallmodel
9a7ba0786c
Set the correct number of bits for the large bullet flag in 2.0 and above
This fixes the issue where there the client (in spearhead protocol mode) would read 2 bits instead of the 1 bit the server sent, which would cause a parse error
2024-10-01 18:52:39 +02:00
smallmodel
935efaeb3a
Fix sound event being posted with incorrect arguments
The argument wouldn't contain "wait" when necessary, which would cause scripts to be stuck forever waiting for sound to be done
2024-10-01 18:09:56 +02:00
smallmodel
020a6d8b66
Fix stupid compile error mistake 2024-09-30 22:39:33 +02:00
smallmodel
9dea8fc41e
Fix wrong pointer type passed to strncmp 2024-09-30 21:59:14 +02:00
smallmodel
3a7e249edf
Refactored svflags and use the correct entity server flags 2024-09-30 19:58:41 +02:00
smallmodel
c406aaf74f
Add a feature that prevents teams from being uneven 2024-09-29 19:00:19 +02:00
smallmodel
83938471ca
Set the blue component of the temp model entity
This fixes particles having an incorrect color sometimes
2024-09-29 15:41:35 +02:00
smallmodel
db6ff8901b
Set the render effect of skyportal and skyentity when adding them to the snapshot
This fixes the issue where some entities like effects would be visible through the sky
2024-09-29 15:27:54 +02:00
smallmodel
737ee3af64
Specify the compiler to use globally for macOS 2024-09-29 14:46:42 +02:00
smallmodel
9ea40f31e4
Clear all entities on registration 2024-09-29 13:30:56 +02:00
smallmodel
27bd6f4b1c
Merge pull request #379 from smallmodel/me/throbbingbox
Fix the destroyed model of specific throbbing boxes
2024-09-29 13:09:09 +02:00
smallmodel
b9e9137f90
Fix the spelling for the default explosive sound 2024-09-29 13:03:10 +02:00
smallmodel
bee0bbbe90
Initialize the effect and destroyed model for the specific ThrobbingBox explosive classes 2024-09-29 13:02:56 +02:00
smallmodel
277ca0c951
Handle bigger offsets in sample_ms_offset()
This fixes an issue where when the offset was big enough, the value would overflow and start again from 0
2024-09-29 12:34:07 +02:00
smallmodel
8aa059dd21
When paused, keep in sync with the server time (#371)
This fixes an issue where a temporary lag would occur when starting a single-player map, or when pausing/unpausing the game
2024-09-29 00:10:52 +02:00
smallmodel
c39bdd246a
Correctly load DDS file on bigendian architectures 2024-09-28 20:56:55 +02:00
smallmodel
9823af9159
Fix light grid offsets endianness 2024-09-28 20:45:04 +02:00
smallmodel
9ee0e0a3c9
Correctly copy data on big-endian (#365) 2024-09-28 20:09:42 +02:00
smallmodel
bf184fb719
Use #pragma once instead of #ifndef 2024-09-27 20:19:11 +02:00
smallmodel
94f308c50f
Draw a black outline for game messages and death messages when targeting mohta or mohtt 2024-09-27 20:01:48 +02:00
smallmodel
bfa0ef64ec
Fix the letterbox not transitioning smoothly
This fixes the letterbox being shown immediately
2024-09-27 19:35:30 +02:00
smallmodel
98fc0a8cb9
Fix the letterbox not correctly rendering
When a letterbox was active, it was covering the entire screen
2024-09-27 19:33:39 +02:00
smallmodel
facabc09f5
Don't set the label shader if the specified material name is considered empty (#364)
For labels linking to a variable for the shader, this prevents the label from still being rendered, drawing the tiled square grid (notexture)
2024-09-27 18:30:03 +02:00
smallmodel
51afcd7b96 Fix loading screen being incorrectly displayed
This fixes an issue where some part of the loading screen would not be drawn correctly, due to the screen being updated recursively through UI_Update()
2024-09-27 17:59:03 +02:00
smallmodel
340f1bb287
Put chat first in game and add a statement for disabling text messages 2024-09-26 22:13:33 +02:00
smallmodel
40c8479448
Update server configuration documentation 2024-09-26 20:48:26 +02:00
smallmodel
27e2063bf9
Add server configuration documentation 2024-09-26 20:30:37 +02:00
smallmodel
e43f0a9285
Add a new feature to enable/disable instant messages and text chat with a variable to set the minimum delay between messages 2024-09-26 19:29:56 +02:00
smallmodel
a977cbdd26
Update README 2024-09-26 19:27:11 +02:00
smallmodel
dbc536c6c2
Fix voice chat time not working on FFA 2024-09-26 19:10:01 +02:00
smallmodel
97c9075503
Fix a small mistake in normal calculations for MM_ClipVelocity2D
Same error as commit c76dda1523. This fixes an issue where AI would run too slowly, like the crate guy in the intro of e1l1, the crate guy was too slow that it ran through the intro vehicle
2024-09-26 18:20:25 +02:00
smallmodel
290e45062d
Set the server time before calling ge->RunFrame() in SV_SpawnServer()
This fixes an issue where some scripts wouldn't be initialized in time, like those that set AI animations. For example this caused an issue with the plane passenger in e2l1, where the animation would get reset due to a very specific chain of events
2024-09-26 01:18:11 +02:00
smallmodel
fc6bffe683
Don't post event when loading save game 2024-09-26 01:01:27 +02:00
smallmodel
1fb8327ca9
Don't let the frame msec go below 0 2024-09-25 22:14:27 +02:00
smallmodel
36208de902
Fix spawn time delta 2024-09-25 22:12:29 +02:00
smallmodel
5403577642
Fix the return value of FS_Seek
It returns a negative value on failure, so handle that properly
2024-09-25 21:04:55 +02:00
smallmodel
c76dda1523
Fix a small mistake in normal calculations for MM_ClipVelocity
This leaded to some occasional errors in AI movement, like in e3l2 where the medic gets stuck while going down the stairs
2024-09-25 20:22:42 +02:00
smallmodel
b5034e5b12
Fix the m_iSaySlot being mistakenly used for the weight cross blend, the specified slot parameter must be used instead
This fixes #266 where some AIs would lack speech animation
2024-09-25 20:04:58 +02:00
smallmodel
b039333922
Call AnimName() to get the current animation name 2024-09-25 19:48:06 +02:00
smallmodel
b504e0d109
Call CurrentAnim() to retrieve the animation index 2024-09-25 19:47:43 +02:00
smallmodel
0692b9dcdb
Fix events sometimes not being posted to entities
Fixes #253
2024-09-25 19:41:21 +02:00
smallmodel
085b72154f
Use a more modern implementation of minizip from ioquake3 2024-09-24 22:25:33 +02:00
smallmodel
4f99c0fa98
Merge branch 'me_main' 2024-09-24 20:11:44 +02:00
smallmodel
b38b71eb44
Small mistake fix 2024-09-24 20:11:34 +02:00
smallmodel
639da1a4b8
Remove unused variables 2024-09-24 20:09:39 +02:00
smallmodel
f2d27aae3f
Update getting_started_running.md 2024-09-24 20:06:37 +02:00
smallmodel
931876ac77
Remove lidbad-0.15.1b 2024-09-24 20:03:30 +02:00
smallmodel
e5f62a9188
Update features.md 2024-09-24 20:02:41 +02:00
smallmodel
3fb699979c
Fix small equality mistake (expected assignment) 2024-09-23 22:44:11 +02:00
smallmodel
85f15a1f28
Delete spawnthings when their last temp model is freed
This fixes:
- Losing FPS in a match with a lot of players, due to a massive amount of emitters getting spawned every time a weapon fires
- Memory leaks due to emitters staying in memory forever after being spawned
2024-09-23 19:29:07 +02:00
smallmodel
758017b638
If the temp model being removed is the head one, use its sibling 2024-09-23 19:16:31 +02:00
smallmodel
724d1db9b8
Properly clear parents of orphaned entities 2024-09-22 21:38:35 +02:00
smallmodel
00421fbee6
Fix the link to the branch build workflow 2024-09-22 20:18:40 +02:00
smallmodel
2510bab41f
Change the order of the target os for more clarity 2024-09-22 20:16:51 +02:00
smallmodel
c6675f2013
Remove special features code to avoid any confusion 2024-09-22 20:06:31 +02:00
smallmodel
1fd6c2bd52
Merge pull request #360 from pryon/UINotepad-fixes
UINotepad fixes and improvements
2024-09-22 19:35:52 +02:00
smallmodel
8f355fe188
Add Voip code from ioq3 2024-09-22 16:50:44 +02:00
smallmodel
dbd10a281b
call CL_ShutdownInput() 2024-09-22 16:39:30 +02:00
smallmodel
d57ea3695b
Add VOIP code for cl_input 2024-09-22 16:38:00 +02:00
smallmodel
8dd74b7789
Get rid of the code that sends next fragments from clients 2024-09-22 16:35:12 +02:00
smallmodel
36c00f146d
Improve gamepad support 2024-09-22 16:19:55 +02:00
SmileTheory
aba9f25744
Fix frame_msec possibly being zero in cl_input.c.
This fixes a mouse freezing bug.
2024-09-22 16:14:01 +02:00
smallmodel
dacfa6ae55
Made common source file a C file as it should be 2024-09-22 16:03:02 +02:00
smallmodel
f53fba082a
Improve memory for debugging purposes 2024-09-22 15:45:29 +02:00
smallmodel
764b95f617
Set a better name for binaries to properly distinguish the name of the architecture 2024-09-22 14:56:02 +02:00
smallmodel
3237b3564e
Update getting started running 2024-09-22 14:23:51 +02:00
Zack Middleton
985731f543
Fix command line variables not being set correctly
+seta, +sets, and +setu were ignored because Com_AddStartupCommands
thought Com_StartupVariable handled it.

+set didn't allow value to be multiple tokens which due to Unix shell
unintuitively removing quotes causes the variable to only be set to
the first token. This could be worked around by escaping quotes

    ioq3ded +set g_motd \"hello world\"

but it doesn't match behavior of other start up commands (which now
includes seta, sets, and setu) that use all tokens.
2024-09-22 13:47:55 +02:00
Thilo Schulz
7c28efe9cd
Fix bug where Com_StartupVariable would set CVAR_USER_CREATED on already existing cvars 2024-09-22 13:36:23 +02:00
smallmodel
5b567f4cba
Fix music volume not restored when the map restarts after the intermission 2024-09-22 01:39:40 +02:00
smallmodel
78918eb59d
Correctly process statements with a semicolon 2024-09-22 01:23:23 +02:00
smallmodel
1848506f09
Properly pass the size of the path buffer into Q_strncpyz 2024-09-21 23:09:16 +02:00
smallmodel
ce0004a296
Use unsafe version of strcpy as the buffer length is unknown 2024-09-21 23:08:52 +02:00
smallmodel
e85d3f2a19
Pass the correct size to Q_strncpyz 2024-09-21 22:50:53 +02:00
smallmodel
4e5a0a30bf
Fix subtitle being incorrect due to the size of the pointer (and not the size of the string) being passed to Q_strncpyz 2024-09-21 21:09:12 +02:00
pryon
9ab37e54b4 Fix CodeQL printf argument type warning 2024-09-21 20:59:27 +02:00
smallmodel
0bd15172b1
Use Ninja generator for faster builds and set compiler/flags in environment variables directly to reduce copy-pasted parameters 2024-09-21 20:34:45 +02:00
pryon
fe0e5c1d9c Fix bug when multiple lines are joined together after copy-pasting text 2024-09-21 20:08:11 +02:00
pryon
5128d88722 Fix bug when deleting multiple lines doesn't actually remove everything selected 2024-09-21 20:04:57 +02:00
pryon
173ca3e58e Fix assertion failures on str operations 2024-09-21 20:02:58 +02:00
pryon
2a13fca737 Fix an off-by-one bug when selection points are determined 2024-09-21 20:01:03 +02:00
pryon
b3a9f4423b Fix crash when saving a file with no contents or with no name 2024-09-21 19:52:20 +02:00
pryon
62c24826e6 Silence some localization error console spam messages
This helps to reduce the number of `LOCALIZATION ERROR` messages in the console for strings that couldn't be translated anyway
2024-09-21 19:49:43 +02:00
pryon
a3d2c2c044 Properly free uipopup_describe instances 2024-09-21 19:46:32 +02:00
pryon
72409622ef Stop activating controls when their vertical scrollbar is hovered over
This fixes the annoyance of open windows (console, notepad) losing focus just by simply moving the mouse around
2024-09-21 19:43:18 +02:00
pryon
c8a2de8235 Implement FS_FileTime for proper retrieval of file date/size info in FilePicker 2024-09-21 19:37:50 +02:00
pryon
6b91846b0c Reimplement Sys_ListFiles and Sys_ListFilteredFiles
They had several bugs, like showing the current and parent directory entires twice, not seeing files but only directories, etc.
2024-09-21 19:36:13 +02:00
pryon
92190220aa Implement clipboard functionality 2024-09-21 19:32:23 +02:00
smallmodel
705d30d125
Add ninja/cmake/clang to the list of packages to install 2024-09-21 19:18:35 +02:00
pryon
c316dc7b00 Fix incorrect line width calculation when tabs are present 2024-09-21 19:17:25 +02:00
smallmodel
529dc29d08
Remove CMake parallel build setting 2024-09-21 19:15:26 +02:00
smallmodel
91e760bf5f
Use a more recent version of ubuntu image for linux 2024-09-21 18:50:10 +02:00
smallmodel
61e24499bf
Cross-compile macOS binaries with single hosted runner image 2024-09-21 18:44:23 +02:00
smallmodel
75621651e5
Add arm64 to valid OSX architectures 2024-09-21 18:30:37 +02:00
smallmodel
3973b95746
Build MacOS binaries from GitHub Action 2024-09-20 23:09:07 +02:00
smallmodel
f9d264058b
Use safe version of sprintf and strcpy 2024-09-20 23:08:53 +02:00
smallmodel
a69d9d4483
Fix compilation errors for MacOS, and add support for MacOS 2024-09-20 21:31:27 +02:00
smallmodel
8b19d00086
Remove the last OpenAL linking as it's already linked before 2024-09-20 21:29:15 +02:00
smallmodel
1156d4f881
Replaced (u)int64_t with long long to avoid constructor conflicts with some compilers 2024-09-20 21:28:36 +02:00
smallmodel
08c5186426
Use stdlib.h as malloc.h is deprecated 2024-09-20 21:27:53 +02:00
smallmodel
61b4a817f3
Move alloca include directive to q_platform.h due to difference between platforms 2024-09-20 20:52:41 +02:00
smallmodel
13710904ba
Update getting started installation 2024-09-20 18:45:15 +02:00
smallmodel
015ebb650e
Clean up ClassDef class 2024-09-19 22:50:33 +02:00
smallmodel
17d623bf85
Add more clarity + check the length of the const_str enumeration and the length of the const string array to make sure they both match 2024-09-19 21:23:19 +02:00
smallmodel
0049348de5
Update features documentation 2024-09-19 21:06:22 +02:00
smallmodel
20d11f5f97
Add max_amount parameter to the EV_Sentient_GiveAmmo documentation 2024-09-19 21:02:04 +02:00
smallmodel
047a7bb949
Deprecate r_forceClampToEdge in favor of automatic detection
This avoids setting the variable manually to fix sky seams and weird graphical artifacts. Now, it's detected automatically
2024-09-19 21:00:22 +02:00
smallmodel
52c79f7f77
Make crates correctly fall 2024-09-19 20:49:33 +02:00
smallmodel
c97bc2e977
Add more clarity in crateobject.cpp 2024-09-19 20:38:31 +02:00
smallmodel
78d564cc04
Fix CrateThink stopping when it shouldn't 2024-09-19 20:34:04 +02:00
smallmodel
e27c0716c4
Allow more stufftext commands when the local server is running
Those stufftext commands are primarily used by single-player maps and briefings
2024-09-19 20:14:15 +02:00
smallmodel
35d037daff
small detail change 2024-09-19 20:00:53 +02:00
smallmodel
f055162ac0
Adjust the quick message DM console rectangle to avoid seeing characters 2024-09-19 19:46:27 +02:00
smallmodel
f2e32c737b
Fix the gap in the console between the bottom line and the text 2024-09-19 19:46:07 +02:00
smallmodel
205709271b
Add fixes from upstream ioq3 2024-09-19 19:24:31 +02:00
smallmodel
3e70a9fab8
Fix mistakes that lead to compilation errors 2024-09-19 19:19:58 +02:00
smallmodel
733c6c96f0
Merge pull request #359 from twolife/spelling
Fix a few typos
2024-09-19 17:44:08 +02:00
Sébastien Noel
a010e648ee Fix a few typos 2024-09-19 10:52:47 +02:00
smallmodel
1c7b561aa9
Filter stufftext commands
This works by allowing the stufftext server command to be executed if the statement only contains whitelisted commands and variables
2024-09-18 23:51:39 +02:00
smallmodel
75a71d35ec
Avoid calling isspace with a character that has a value below 0 2024-09-18 23:04:01 +02:00
smallmodel
7c0f0672bd
Add r_vidmode1024 and r_vidmodemax so the display resolution can be changed in Spearhead and Breakthrough 2024-09-18 22:59:30 +02:00
smallmodel
8fc6b6e3c3
Correctly handle quick message and message mode for the chat window
This fixes the chat window not being put in quick message mode at all when intended, now it also correctly handle team/private message modes
2024-09-18 22:14:16 +02:00
smallmodel
6c2c8ca2b7
Don't archive s_openaldevice and s_openaldriver 2024-09-18 22:10:33 +02:00
smallmodel
1b6bdd07e7
Disable function keys for UI
This fixes the issue where menus like the message mode can't be toggled
2024-09-18 21:51:35 +02:00
smallmodel
539688dd3d
Reduced the delay to 33 ms (30 fps) to update the loading bar
This makes the loading bar smoother
2024-09-18 20:56:13 +02:00
smallmodel
08e09c3b4c
Avoid setting variables with the same value
This prevents the console from being spammed with constant variable change when `developer` is set to 2
2024-09-18 20:55:02 +02:00
smallmodel
4259053c7e
Expose methods for basic DMA (when OpenAL is unavailable) 2024-09-18 20:49:38 +02:00
smallmodel
c221cfd493
Reorganize workflows and use multiple environments for different release stages 2024-09-18 20:33:30 +02:00
smallmodel
41298b53d4
Add PRODUCT_VERSION_STAGE variable to define the stage of the software through builds 2024-09-18 18:13:57 +02:00
smallmodel
ddcd05adc6
Cancel other CodeQL actions on newer pushes 2024-09-18 17:10:25 +02:00
smallmodel
a28cd64c7a
Update implementation documentation again 2024-09-18 00:30:38 +02:00
smallmodel
38e62fef18
Update the implementation documentation with the current state 2024-09-18 00:26:51 +02:00
smallmodel
3f139f463b
Remove stub print 2024-09-18 00:19:05 +02:00
smallmodel
0597191319
Implement SkelVec3::IsUnit 2024-09-18 00:18:08 +02:00
smallmodel
f4c8b0c21f
Initialize the cube build info
This should fix lighting being too dark or incorrect in some places
2024-09-17 22:22:42 +02:00
smallmodel
bba7031f3d
Add more clarity to code 2024-09-17 22:20:20 +02:00
smallmodel
4785913e02
compare_light_intensities should compare intensity as integers directly 2024-09-17 21:31:50 +02:00
smallmodel
a6808d1f6a
Fix incorrect light color for point lights and spot lights, also handle negative point light intensity
This fixes lighting from sphere being computed incorrectly for entities, making entities often look black or having strange lighting color
2024-09-17 21:27:14 +02:00
smallmodel
7188e9832a
Fix leaf iteration 2024-09-17 20:51:00 +02:00
smallmodel
0cce0c81fb
Prevent world values from being overridden by entities 2024-09-17 20:32:39 +02:00
smallmodel
a60baa03e0
Add MAX_SPHERE_LIGHTS 2024-09-17 20:06:35 +02:00
smallmodel
b0c8dafb33
Correctly compute colors for static model in vertex lit texture 2024-09-17 20:02:37 +02:00
smallmodel
b672fc8b29
Add #if, #if_not and #else shader statements 2024-09-17 20:00:24 +02:00
smallmodel
eac69f659f
For dot/oneminusdot, shader needs normal 2024-09-17 20:00:00 +02:00
smallmodel
d9ab65154c
Fix incorrect lighting grid blend 2024-09-17 00:27:01 +02:00
smallmodel
c120aed8bb
Fix incorrect static model grid lighting 2024-09-16 22:11:58 +02:00
smallmodel
ecdbe3d959
Don't check lightmap for RB_StageIteratorVertexLitTextureUnfogged to be used 2024-09-16 22:01:04 +02:00
smallmodel
96d10fb8b0
Mark r_light_nolight as cheat 2024-09-16 20:50:02 +02:00
smallmodel
2ab826268d
Clear the legs state during the torso evaluation when the movecontrol is not legs
The legs state won't be stuck anymore waiting for an empty animation. This could happen under special circumstances, when the torso evaluation sets the movecontrol to non-legs (clears the legs anim) and then back to legs in subsequent iterations.
Fixes #105, the issue cannot be exploited anymore for land-sharking
2024-09-16 20:20:19 +02:00
smallmodel
c3e3f368e0
use cheats rather than sv_cheats to check if the client is connected to a cheat server 2024-09-16 18:59:36 +02:00
smallmodel
f35582489d
Fix support for british, russian and italian voices in Spearhead and Breakthrough 2024-09-16 18:09:56 +02:00
smallmodel
9acea3484d
Play zing sounds only if the location if the zing is valid
This fixes a potential crash where uninitialized position would be passed to the sound system
2024-09-16 17:39:15 +02:00
smallmodel
a72da9b73e
Fix incorrect terrain height for poly
This caused decals to float in the air when they were placed on the terrain
2024-09-15 23:49:42 +02:00
smallmodel
df53d35967
Fix real dynamic lighting algorithm for both terrain and patch
This fixes #356 where real dynamic lighting would look completely wrong, making it look like there are graphical artifacts on surfaces
2024-09-15 21:23:17 +02:00
smallmodel
e5e7421d3c
Fix terrain lightmap when there is a dynamic light map
This fixes terrain having a completely wrong lightmap texture coordinates for dynamic lighting
2024-09-15 21:21:38 +02:00
smallmodel
6ff25d00fc
Use lightmap offset for grid surface when a dlightmap is specified 2024-09-15 21:15:01 +02:00
smallmodel
4a5b0b3105
Fix y lightmap position when allocating a new lightmap block
See the issue with dynamic lights: #356
2024-09-15 19:39:22 +02:00
smallmodel
d05d964432
Fix NaN lmapStep for terrain patches 2024-09-15 19:34:25 +02:00
smallmodel
daa4a67b49
Reuse dlightmap in R_CheckDlightSurface and R_CheckDlightTerrain 2024-09-15 19:34:06 +02:00
smallmodel
9c0224911c
Reset the number of dynamic lights when calculating the real terrain lighting
This fixes a crash that can occur when there is only the terrain that can be lit with dlights
2024-09-15 12:02:05 +02:00
smallmodel
ef5759cff5
Don't execute commands during the intro 2024-09-15 01:21:20 +02:00
smallmodel
77292fb9ab
First person spectator fix (not working yet) 2024-09-15 01:21:17 +02:00
smallmodel
6fb9ab078e
Implement RE_DrawBackground_DrawPixels 2024-09-15 01:12:00 +02:00
smallmodel
844a72e0f3
Add DrawPixels and PixelZoom 2024-09-15 01:11:52 +02:00
smallmodel
46e9046629
Implement VehicleHalfTrack 2024-09-15 01:03:37 +02:00
smallmodel
e5af60787e
Partially implement GetZone/IsInZone 2024-09-15 00:42:35 +02:00
smallmodel
4b0696a187
Implement remaining methods of ClientGameCommandManager 2024-09-15 00:42:22 +02:00
smallmodel
a6377fedab
Remove useless code 2024-09-14 23:36:19 +02:00
smallmodel
2f884e6d55
Call Key_GetCatcher/Key_SetCatcher instead of modifying the variable directly 2024-09-14 23:32:24 +02:00
smallmodel
28f8c65771
Key_SetCatcher() must use cls.keyCatchers 2024-09-14 23:30:30 +02:00
smallmodel
b509ef5ab4
Deactivate the mouse only when loading 2024-09-14 23:29:30 +02:00
smallmodel
9f48dabaec
Play the game's intro when starting 2024-09-14 22:59:27 +02:00
smallmodel
5b0224ae3c
Implement support for playing movies
Videos like briefings and intro are now played correctly
2024-09-14 22:58:43 +02:00
smallmodel
c3ef267d6d
Implement movie audio in OpenAL code 2024-09-14 21:55:15 +02:00
smallmodel
fe9b298705
Export cl_movieaudio 2024-09-14 21:53:19 +02:00
smallmodel
0b106cf47e
Print errors only when developer mode is set 2024-09-14 13:21:08 +02:00
smallmodel
9b417c9b26
Add EV_Client_ForceFeedback (unused) 2024-09-14 13:20:55 +02:00
smallmodel
37d5458c4c
Partially implement cinematic support for reading RoQ files (no audio yet) 2024-09-13 23:00:31 +02:00
smallmodel
77d48cb104
Don't call UI_ClearBackground in cinematic mode 2024-09-13 22:58:37 +02:00
smallmodel
a25200741a
Finis the loading screen if it's the default 2024-09-13 22:23:53 +02:00
smallmodel
d04a32920a
Fix an incorrect parameter value passed to FS_Read when reading the DCL file 2024-09-13 21:49:45 +02:00
smallmodel
792b676c11
Set the number of brush models
The level marks system depends on the number of brush models and leafs, having a number that doesn't match what was saved would cause a crash
2024-09-13 21:47:57 +02:00
smallmodel
690a7a7557
Format cl_ui file 2024-09-13 21:36:23 +02:00
smallmodel
e128c93ad9
Declare CL_FinishedStartStage 2024-09-13 21:25:41 +02:00
smallmodel
39add5ccec
Fix incorrect parsing of music volumes 2024-09-13 20:01:01 +02:00
smallmodel
a1a89cba34
Allow dynamic adjustment for the size of status columns in SVC_Status 2024-09-13 19:50:29 +02:00
smallmodel
2d696cf500
Also use the port when connecting to a server 2024-09-13 19:07:06 +02:00
smallmodel
45fe0bc8b7
Add an IP column
See #353 where servers would appear twice
2024-09-13 19:06:38 +02:00
smallmodel
9fc4c67187
Fix a crash when insep is 0 2024-09-13 19:05:30 +02:00
smallmodel
34aeab5f77
Fix the game type string being empty
(see #353 for the game type)
2024-09-13 18:34:43 +02:00
smallmodel
b510452260
Remove useless comment 2024-09-12 23:48:46 +02:00
smallmodel
89b8d5a67b
Use source files in renderercommon 2024-09-12 23:46:13 +02:00
smallmodel
500e3a3b2c
Add support for JPEG screenshots 2024-09-12 23:33:39 +02:00
smallmodel
47e575ed9a
define USE_INTERNAL_JPEG for compatible JPEG struct size 2024-09-12 23:33:21 +02:00
smallmodel
10b30d74e7
Implement sample_volume() 2024-09-12 22:23:27 +02:00
smallmodel
1ba4c6b7ad
Remove useless comment 2024-09-12 22:18:09 +02:00
smallmodel
eb899be95e
Implement RE_GetGraphicsInfo 2024-09-12 21:40:07 +02:00
smallmodel
6d993af419
Fix compiler warning 2024-09-12 21:09:07 +02:00
smallmodel
a136cccbe1
Implement R_CraterTerrain 2024-09-12 21:02:04 +02:00
smallmodel
2b43ebfca4
Add ter_crater command 2024-09-12 20:43:24 +02:00
smallmodel
06f4980ee1
Implement ghost textures with particles 2024-09-12 20:09:05 +02:00
smallmodel
6cdf5b7b7e
Process .gst files 2024-09-12 19:44:36 +02:00
smallmodel
117b9a5579
Add declarations for GHOST functions 2024-09-12 19:42:41 +02:00
smallmodel
9475be8f6f
Remove entityNumIndexes/staticModelNumIndexes from declaration as it causes compilation issue on some compilers 2024-09-11 23:41:47 +02:00
smallmodel
41ca1797f9
Implement basic GHOST methods and functions 2024-09-11 23:21:50 +02:00
smallmodel
e56ae3d266
Update features.md 2024-09-11 21:07:55 +02:00
smallmodel
735ffaf80b
Implement swipe 2024-09-11 19:57:45 +02:00
smallmodel
ed52d1c648
Implement R_FastDlightTerrain 2024-09-11 19:19:38 +02:00
smallmodel
78fa90c59b
Move RB_StaticMesh to tr_model.cpp for info world tris 2024-09-11 19:03:41 +02:00
smallmodel
548a3efe5a
Implement R_InfoWorldTris_f and R_PrintInfoWorldtris 2024-09-11 18:57:50 +02:00
smallmodel
18a12eeba3
Fix loop breaking instead of continuing 2024-09-11 18:51:05 +02:00
smallmodel
83d486ceeb
Add missing declarations 2024-09-11 18:48:47 +02:00
smallmodel
d898c0f995
Implement R_PrintInfoStaticModels 2024-09-11 18:45:17 +02:00
smallmodel
02faf6f8c1
Implement R_Sky_ChangeFrustum 2024-09-11 18:27:19 +02:00
smallmodel
3478bbddf2
Implement RB_ComputeShadowVolume 2024-09-11 18:02:39 +02:00
smallmodel
fd1ee31e1e
Remove useless comment 2024-09-11 17:56:26 +02:00
smallmodel
4a565f0985
Declare R_GetLightingGridValueFast 2024-09-11 00:23:43 +02:00
smallmodel
c68f23cdaf
Fix compilation warnings 2024-09-11 00:21:31 +02:00
smallmodel
e386eb00ef
Implement all lighting functions 2024-09-11 00:12:13 +02:00
smallmodel
662d048bf4
Implement R_AddLightGridSurfacesToScene 2024-09-10 20:42:05 +02:00
smallmodel
d9e3cc2188
Add a way to draw the skeleton for debugging purposes 2024-09-10 20:16:56 +02:00
smallmodel
a586f13af8
Remove CL_GamespyServers_f as there is an existing implementation 2024-09-10 19:58:28 +02:00
smallmodel
37820c1673
Generate QKey 2024-09-10 19:57:25 +02:00
smallmodel
8a2e4ca470
Add Com_RandomBytes and Com_IsVoipTarget 2024-09-10 19:54:25 +02:00
smallmodel
3a5da64c6f
Make radar clients speak on mohaas/mohaab 2024-09-10 19:50:43 +02:00
smallmodel
9c018a2330
Implement CGM_FENCEPOST 2024-09-10 19:40:53 +02:00
smallmodel
0840cdd83a
Restore the old behavior where the bullet would hit all entities in sight. Only works when targeting mohaa version 1.x
Fixes #348. Since 2.0, bullet trace stops after the first hit entity even if it's a trigger, which can be an issue on some SP maps.
2024-09-10 19:01:34 +02:00
smallmodel
e972747969
Update documentation
This adds an example for using fs_homepath
2024-09-09 23:59:06 +02:00
smallmodel
e151c6eb15
Update documentation 2024-09-09 23:38:37 +02:00
smallmodel
603444a69f
Fix an issue where the remaining time would reach 0:00 and the match would never end
See #287, this occurred when the fraglimit was defined.
2024-09-09 22:25:54 +02:00
smallmodel
999e0fd721
Implement test emitter 2024-09-09 21:48:40 +02:00
smallmodel
47131dec44
Fix wrong special effects count 2024-09-09 21:43:20 +02:00
smallmodel
6adad053d9
Explicitly disable looping when setting the sample loop count to a value other than 0
This fixes a rare occurrence where some sounds would loop forever
2024-09-09 00:15:39 +02:00
smallmodel
725561b655
Fix the usage of memory, strings, constant and parameters 2024-09-08 23:54:47 +02:00
smallmodel
b84fbf452e
Pass a vec4_t to GL_SetFogColor() rather than a vec3_t 2024-09-08 23:49:48 +02:00
smallmodel
eb7af2bce9
Implement basic test emitter functions 2024-09-08 23:33:55 +02:00
smallmodel
7c57c4b131
Fix wrong secondary ammo type being picked up 2024-09-08 20:20:58 +02:00
smallmodel
4460466cb3
Implement RE_SetRenderTime 2024-09-08 19:43:37 +02:00
smallmodel
eea19d733d
Add R_UpdateGhostTextures (unimplemented) 2024-09-08 19:43:29 +02:00
smallmodel
abc97dcab3
Implement R_AddTerrainMarkSurfaces and RE_AddTerrainMarkToScene 2024-09-08 19:40:00 +02:00
smallmodel
065c791a10
Implement CG_ResetEffectCommandCvars 2024-09-08 19:29:40 +02:00
smallmodel
6b902e7f5d
Remove "unimplemented" comment 2024-09-08 18:49:45 +02:00
smallmodel
df0cb87b35
Implement CG_AddLightShow (cg_acidtrip) 2024-09-08 18:48:15 +02:00
smallmodel
0b9687fea4
Implement functions for printing content types, surface properties and surface types 2024-09-08 18:39:39 +02:00
smallmodel
99fbe092bc
Use correct names for surface flags 2024-09-08 18:34:02 +02:00
smallmodel
7a7849ae83
Remove comment 2024-09-08 18:25:10 +02:00
smallmodel
47830bb330
Update version number 2024-09-08 18:24:59 +02:00
smallmodel
0dfb1a3a2a
Use Com_DPrintf for TIKI/alias warnings/errors
This prevent the console from getting spammed with developer errors in production
2024-09-08 18:22:12 +02:00
smallmodel
e2e1ab0275
Fix status command column length breaking some programs 2024-09-08 18:09:54 +02:00
smallmodel
4249cacf2f
Support token dollar in variable name
This fixes mods like trapshooting not working because of a '$' in a variable name
2024-09-08 18:03:43 +02:00
smallmodel
4e3ec52673
Fix a crash due to NULL string being appended 2024-09-08 18:02:57 +02:00
smallmodel
98991a4a7a
Fix file ordering with uppercase/lowercase file names 2024-09-08 17:59:30 +02:00
smallmodel
bca6d656b6
Fix bad verts value passed to CG_AddFragmentToScene 2024-09-08 17:53:35 +02:00
smallmodel
ffc3580d43
Implement CG_CheckCaptureKey 2024-09-08 16:31:19 +02:00
smallmodel
c18cdc78ea
Fix Cgame key catching 2024-09-08 15:48:46 +02:00
smallmodel
77ecc73631
Implement lens flare / sun flares
Some maps like mohdm1 have a sun flares, now when you look up the sky towards the sun direction, you will see the flare of the sun
2024-09-08 15:31:18 +02:00
smallmodel
3834f51d74
Fix GetNamedWidget() always returning the last valid widget
This is problematic when doing different logic when a widget doesn't exist, for example when loading a map, if the continue button doesn't exist then the game should continue automatically
2024-09-08 15:06:43 +02:00
smallmodel
86ddec3f76
Clear the world to prevent crashes 2024-09-08 14:59:10 +02:00
smallmodel
4d12bcb184
Export s_sun 2024-09-08 00:52:03 +02:00
smallmodel
7d93723382
Update getting started doc 2024-09-07 23:58:56 +02:00
smallmodel
8e1a52bbb7
Implement VIS debugging 2024-09-07 23:58:50 +02:00
smallmodel
cd9b1a741f
Match CG_PermanentMark parameters
This fixes #355
2024-09-07 23:57:17 +02:00
smallmodel
cefe331e0c
Remove useless surface flags 2024-09-07 23:51:52 +02:00
smallmodel
14d1fae54a
Implement all treadmark functions 2024-09-06 22:10:22 +02:00
smallmodel
a1601be7a6
Implement code to make tread mark decals 2024-09-05 23:54:01 +02:00
smallmodel
a2ebeb11e3
Update features.md 2024-09-05 23:10:50 +02:00
smallmodel
b7f0f32878
Fix DCL signature on big-endian architectures 2024-09-05 01:14:42 +02:00
smallmodel
58e39add5b
Implemented treadmarks update functions 2024-09-05 01:04:53 +02:00
smallmodel
61725c95df
Add MASK_TREADMARKS 2024-09-05 00:43:36 +02:00
smallmodel
71a1df661a
Fix current mark's alpha component not updating properly 2024-09-04 21:54:49 +02:00
smallmodel
9eed0eab5f
Implement CG_PermanentMark 2024-09-04 21:51:42 +02:00
smallmodel
e42b6fe0a9
Fix current mark not updating if it has a rotation 2024-09-04 21:51:16 +02:00
smallmodel
b1e640ad1d
Implement CG_PermanentMark 2024-09-04 21:41:16 +02:00
smallmodel
2fc091fdf7
Skip loading if the file length is less than the dcl header length 2024-09-04 20:56:41 +02:00
smallmodel
47ba241e7d
Fix file being closed but still used afterwards 2024-09-04 20:50:22 +02:00
smallmodel
c0d37c504a
Fix infinite loop in R_TerrainHeightForPoly 2024-09-04 20:46:10 +02:00
smallmodel
1e0195f6e3
Add variables that will be used in unimplemented functions 2024-09-04 20:29:29 +02:00
smallmodel
e806c1ddf1
Move MAX_MARK values to tr_types_new.h 2024-09-04 20:23:20 +02:00
smallmodel
78f0072c59
Update the SFX datasize when downsampling
This fixes #349 where the size of the AL buffer didn't match the real downsampled size, which would cause AL to read way past of end of the data buffer
2024-09-04 20:12:46 +02:00
smallmodel
1022ce531a
Fix AL buffers having sound data past end of the sound buffer 2024-09-04 20:10:56 +02:00
smallmodel
7f08a7bca8
Remove register keyword as it's deprecated since C++17 2024-09-04 20:10:21 +02:00
smallmodel
4123bef60d
Implement R_ApplyLevelDecal 2024-09-04 20:05:48 +02:00
smallmodel
c6464efa07
Implement level mark loading and updating 2024-09-04 00:02:07 +02:00
smallmodel
0a9075748e
Fix OpenAL binary name on ARM64 2024-09-02 20:38:38 +02:00
smallmodel
3733761696
Fix the reloading sound in 2.0, the behavior is different in 2.0 and 2.30 2024-09-02 19:52:32 +02:00
smallmodel
cde7cbc3a3
Implement G_ClientDrawTags 2024-09-02 19:52:32 +02:00
smallmodel
e927da56cf
Fix GetTagPositionAndOrientation() returning wrong tag axis and position 2024-09-02 19:52:31 +02:00
smallmodel
3b8bffe39c
Fix variable misspelling 2024-09-02 19:52:31 +02:00
smallmodel
19da377064
Implement G_ObfuscationForSmokeSprites
This is used so the player can throw a smoke grenade and hide behind it for AI
2024-09-02 19:52:30 +02:00
smallmodel
4d1380b5c4
Implement G_ClientDoBlends and FindIntermissionPoint 2024-09-02 19:52:30 +02:00
smallmodel
25c2904d66
Implement RE_MapVersion and RE_PrintBSPFileSizes 2024-09-02 19:52:30 +02:00
smallmodel
53565663d9
Add old welcome code (commented out) for when a player becomes spectator 2024-09-02 01:01:55 +02:00
smallmodel
76f0e17987
Fix bullet trace end being out of bounds, causing clients to have a strange bullet trace 2024-09-02 00:42:29 +02:00
smallmodel
5052449e38
Fix invisible bullet tracers 2024-09-02 00:25:07 +02:00
smallmodel
a539da3200
Clear velocity and avelocity in MoveDone
This fixes objects rotating forever like the radio tower in m1l3a
2024-09-02 00:06:12 +02:00
smallmodel
fb875501f0
Fix UI library forcing latched variables
This caused issues when setting render variables
2024-09-01 23:34:57 +02:00
smallmodel
89d805ab92
Fix the FireDelay always returning for FIRE_PRIMARY 2024-09-01 20:42:19 +02:00
smallmodel
7852929da3
Fix the music replaying when loading from save after it ended 2024-09-01 20:38:11 +02:00
smallmodel
595e6fcb8b
Fix AI firing forever in mohaa 2024-09-01 20:36:54 +02:00
smallmodel
a9792bd4c3
Add comments above all actor.cpp methods 2024-09-01 20:21:44 +02:00
smallmodel
c19bc7e7a2
Add comments about new additions from 2.0 and above 2024-09-01 20:04:10 +02:00
smallmodel
3e980ed371
Unset the script goal once the AI reached the point 2024-09-01 19:38:05 +02:00
smallmodel
a9a7c7fdb8
Adjust area portal when closing before broadcasting ai events 2024-09-01 18:49:41 +02:00
smallmodel
5baf5bccf2
Notify scripts when door has closed/opened 2024-09-01 18:43:38 +02:00
smallmodel
981d72ac5a
Add assertions to check for invalid path distance 2024-09-01 18:28:01 +02:00
smallmodel
a9b8cdce64
Only print the long word error in debug mode 2024-09-01 18:10:16 +02:00
smallmodel
f3222fc36a
Set AI angles only if they don't have an enemy, otherwise let the AI set their angles
This prevented actors from attacking correctly because the AI cover target state expects the AI to 100% stare at the enemy and the vehicle would keep changing the AI angles
2024-09-01 17:16:09 +02:00
smallmodel
e5aee8d206
Fix the MG42 fire delay being too slow by default for AIs 2024-09-01 16:51:41 +02:00
smallmodel
96d16bcbc1
Correctly check the max yaw offset in AI_CanTarget()
This caused AI to exit turrets immediately
2024-09-01 16:46:24 +02:00
smallmodel
010a5ffc74
Mark entities as missing until they are received
This fixes a bug where the plane sound in t1l1 would stop immediately because the entity isn't received at this point
2024-09-01 16:21:56 +02:00
smallmodel
bed9bbbd05
Update classes documentation 2024-08-31 22:13:21 +02:00
smallmodel
5cc168111c
Fix class not dumping properly 2024-08-31 22:10:44 +02:00
smallmodel
bdec6aab07
Fix calls to class dumping functions 2024-08-31 22:09:50 +02:00
smallmodel
56cbab8661
Fix NumEventCommands() returning an incorrect result 2024-08-31 21:42:07 +02:00
smallmodel
29c3bece4e
Prevent players to use developer commands like lod or view 2024-08-31 21:32:55 +02:00
smallmodel
dc24a4a067
Stop spawning if there is no entity 0 (could only happen in multiplayer) 2024-08-31 21:32:42 +02:00
smallmodel
c4683e2417
Don't execute entity events from the console if the client isn't running
This prevent the server from executing console commands for the first player
2024-08-31 21:18:35 +02:00
smallmodel
11f5870a8b
Add ioq3 server fixes and improvement
- Add a rate limit to protect against DoS attacks
- Better IPv6 support
2024-08-31 21:04:10 +02:00
smallmodel
9de71e3529
Correctly check if the AI either can see or can shoot to find the enemy
The AI would get stuck trying to cover otherwise
2024-08-31 18:06:02 +02:00
smallmodel
81866d96e0
Make flesh impacts properly work 2024-08-31 18:02:07 +02:00
smallmodel
70fcc70348
Fix AI turret placement
The AI was too much off from the turret
2024-08-31 17:34:10 +02:00
smallmodel
1911f04079
Fix strange AI turret target angles
The turret sometimes turned extremely fast or ignored the max yaw offset
2024-08-31 17:22:28 +02:00
smallmodel
b7288ba3f4
Don't affect the frameMsec with timescale as it causes issues with physics (like vehicles) 2024-08-31 16:50:10 +02:00
smallmodel
be655e2b9c
Fix the height of huddraw elements not being archived properly
A wrong variable was specified
2024-08-31 16:38:58 +02:00
smallmodel
915269e017
Fix the actor stuck targeting an enemy with really low threat (behind walls, not visible)
This fixes the actor being stuck aiming even if the player is near them
2024-08-31 16:24:59 +02:00
smallmodel
6071b5303c
Remove useless NET_Sleep and make sure frameMsec doesn't go below 1 2024-08-31 16:18:28 +02:00
smallmodel
e59a24ded3
Fix actors enemy not being able to be set if enemy switch is disabled 2024-08-31 16:17:37 +02:00
smallmodel
2239efa439
Fix sample_offset() returning a wrong value with looping sounds
The returned offset will now be the correct when the stream has been re-read from the beginning due to the sound looping
2024-08-30 21:12:39 +02:00
smallmodel
99fcec9f26
Initialize bStartedGame 2024-08-30 18:56:01 +02:00
smallmodel
2fe4e85543
Fix path goal end anim script never reaching
The end anim script should be executed below a certain speed (1/4 below normal speed).
This fixes a bug in e3l4 where the game would never continue past the first bunker. The actor would get stuck after collecting supplies for the first bunker at the beginning because it stopped too far away from the target origin
2024-08-30 00:44:14 +02:00
smallmodel
68f2635c06
Should be DotProduct2D 2024-08-29 23:31:46 +02:00
smallmodel
0147677412
Calculate sr/cr only if right or up is specified 2024-08-29 21:37:10 +02:00
smallmodel
89133bf05d
Fix looping sounds not stopped when stopping all sounds
This fixes an issue where some random looping sound (like footsteps) would be heard after restarting or when loading a saved game
2024-08-29 19:29:16 +02:00
smallmodel
7a0a671f18
Use the correct value when comparing the sound awareness multiplied by the range factor 2024-08-28 00:41:53 +02:00
smallmodel
c7d1f42edb
Use centroid when broadcasting new AI event 2024-08-28 00:40:57 +02:00
smallmodel
2b9d31fe7f
Normalize angles to fix interpolation issues on client
See #342
2024-08-27 15:24:31 +02:00
smallmodel
1f71bb714d
Fix sounds unexpectedly getting marked as streamed when they are not
This fixes #345 where a crash occurred because of a NULL buffer, as streamed sounds don't have a memory buffer
2024-08-27 12:47:58 +02:00
smallmodel
6b21f7e92e
Fix the turret firedelay behavior on mohaa base 2024-08-27 01:34:51 +02:00
smallmodel
8b5074b6ac
Fix Dot/Texcoords calc
This caused some shaders such as headlights beam on the opeltruck being weirdly rendered
2024-08-27 01:07:51 +02:00
smallmodel
7f7d797fce
Fix vehicles getting blocked by sentients dying 2024-08-27 00:36:03 +02:00
smallmodel
0b3aad5ad2
Fix entnum comparison (must be greater than or equal to the squadmate's entnum) 2024-08-27 00:09:13 +02:00
smallmodel
ad88215b85
Cleaned up actor_runandshoot.cpp 2024-08-26 23:45:41 +02:00
smallmodel
ccb1465e17
Use a raw pointer instead of the str object
Original game checks for the NUL character using the line buffer (`c_str()`) directly instead of the str object's operator[], as this would cause an assertion failure because the str's length ignore the NUL character
2024-08-26 23:09:55 +02:00
smallmodel
fde4d8d54f
Update README and bug report 2024-08-26 22:11:14 +02:00
smallmodel
37db2e8acc
Update issue templates 2024-08-26 22:04:30 +02:00
smallmodel
9413eb0d58
Update issue templates 2024-08-26 21:58:10 +02:00
smallmodel
06d2eaf409
Fix doors opening and closing indefinitely by actors 2024-08-26 19:04:49 +02:00
smallmodel
444ce284ae
Spawn a trigger field even if the TOGGLE flag is set
This fixes Actors not being able to open doors
2024-08-26 18:55:10 +02:00
smallmodel
a150c1b18b
Fix animation delta repeating when getting delta of the same frame
This fixes actors moving too much and strangely
2024-08-26 18:18:20 +02:00
smallmodel
194e898d90
Ignore bad SFX for 3D loop sounds 2024-08-26 13:22:40 +02:00
smallmodel
0b1a20dcff
Properly save and restore sound position, also fix loopsounds not playing properly 2024-08-26 01:29:42 +02:00
smallmodel
93e7561cb3
Fix Actor::EventSoundDone() using the wrong parameter for the sfxName, causing the SoundDone event to be sent immediately 2024-08-26 01:05:58 +02:00
smallmodel
6ab654264b
Cleaned up Entity::ProcessSoundEvent() 2024-08-26 01:05:13 +02:00
smallmodel
7023184892
Fix subdivisions endianness
See #332
2024-08-26 00:45:21 +02:00
smallmodel
07f13d1ae9
Force the soundtrack to be sent again 2024-08-26 00:08:29 +02:00
smallmodel
ac22b1cfbf
Use an higher fragment size when sending a message to the loopback 2024-08-25 23:41:03 +02:00
smallmodel
e70cdfb898
Improve code readability 2024-08-25 22:01:03 +02:00
smallmodel
022181fcfd
Remove processed buffers after half of the queued buffers has been processed 2024-08-25 16:49:24 +02:00
smallmodel
e021289d36
Fix the turret setting incorrect angles 2024-08-24 19:23:11 +02:00
smallmodel
91b80a8e21
Fix the sound system not restarting when modifying the speaker type to 0 2024-08-24 19:19:55 +02:00
smallmodel
322ca2b42e
Fix the loop protection not working when multiple scripts are executed
This fix will apply the protection globally
2024-08-24 18:50:04 +02:00
smallmodel
d399ffd609
Set the correct sound velocity 2024-08-24 18:18:20 +02:00
smallmodel
bf2626f804
Set the pitch before playing the sound 2024-08-24 17:53:13 +02:00
smallmodel
00f27ac02d
Fix improper sound distance values 2024-08-24 17:35:35 +02:00
smallmodel
5134aed352
Mark the functions as inline to optimize function calls 2024-08-24 17:35:02 +02:00
smallmodel
b457a84ed9
Fix AL_DISTANCE_MODEL value type, it must be an integer 2024-08-24 16:39:43 +02:00
smallmodel
8188d46ee7
Fix SetLittleLong() writing past end of bytes buffer
(even though the union was still 4-bytes because of the integer)
2024-08-24 15:10:12 +02:00
smallmodel
d64e88451f
Fix compiler warnings
Note that in Dismiss(), checking for `this` is not necessary (original code was generated by the compiler)
2024-08-24 15:08:42 +02:00
smallmodel
c70c578194
Ignore ALC_OUTPUT_MODE_SOFT if unavailable 2024-08-24 14:51:58 +02:00
smallmodel
54ceff5107
Process the value of s_speaker_type 2024-08-24 14:25:25 +02:00
smallmodel
3b94904ea8
Update getting started 2024-08-24 12:01:37 +02:00
smallmodel
1c8b4a1922
Update the documentation to reflect the current state of the project 2024-08-24 01:03:36 +02:00
smallmodel
32b0b2dfac
Fix camera angles changing too much when switching between linked turrets 2024-08-24 00:40:23 +02:00
smallmodel
6506577787
Add shader flags with tcMod rotate
This fixes vehicle wheels rotating forever. Wheels now rotate consistently depending on the vehicle speed
2024-08-24 00:35:39 +02:00
smallmodel
56775399d3
Fix 3D sounds not being attached to an entity when specified 2024-08-23 23:38:52 +02:00
smallmodel
d6d40975e5
Add more file debug print 2024-08-23 23:32:46 +02:00
smallmodel
e3936f52a2
Move Com_SwapSaveStruct to a better place 2024-08-23 22:39:14 +02:00
smallmodel
53d5dd1e40
Differentiate saves from mohaa, mohta and mohtt
Fixes #339 where Spearhead and Breakthrough would also display saves from mohaa
2024-08-23 22:25:43 +02:00
smallmodel
b2ef0fd6e3
Swap the save game struct on big endian architectures 2024-08-23 21:09:12 +02:00
smallmodel
8832fbe55d
Fix entities loopsound incorrectly having the streamed value at the end of the name, causing some sounds unable to load 2024-08-23 21:03:02 +02:00
smallmodel
b5ffe756d6
Fix buffers unnecessarily being unqueued after source has stopped 2024-08-23 20:38:41 +02:00
smallmodel
01a0173a2f
Take all branches into account for GitHub actions 2024-08-23 19:52:30 +02:00
smallmodel
7bebb2adab
Statically link the CRT runtime in soft-oal 2024-08-23 19:51:47 +02:00
smallmodel
8c41576daa
Remove assertion as sounds can be streamed at any time 2024-08-23 12:13:17 +02:00
smallmodel
a529b37f25
Show some AL errors on developer mode only 2024-08-23 12:07:28 +02:00
smallmodel
f84ed6b794
Fix crash when loading from save, caused by incorrect client-game state size
Closes #343
2024-08-23 11:48:50 +02:00
smallmodel
9526a92fc1
Use same parameters as oal to build OpenAL 2024-08-22 17:13:43 +02:00
smallmodel
5e60b89a0d
Fix linux compile error 2024-08-22 16:13:03 +02:00
smallmodel
e46625a52c
Added more verbosity 2024-08-22 15:39:28 +02:00
smallmodel
037cb0f5cb
Fix OpenAL64.dll name on Win32 and Win64 2024-08-22 15:18:20 +02:00
smallmodel
f67a7c6621
List available devices and use Generic Software if Generic Hardware is the default 2024-08-22 13:30:04 +02:00
smallmodel
4839a2026b
Fix string casting 2024-08-22 12:43:18 +02:00
smallmodel
219dbbb5b7
Open the default device by passing in the default device name instead of NULL 2024-08-22 12:39:14 +02:00
smallmodel
d78de51bc2
Bump version number 2024-08-21 19:02:23 +02:00
smallmodel
faa50352e0
Remove explicit USE_SOUND_NEW as OpenAL is the default 2024-08-21 18:53:57 +02:00
smallmodel
f2b49f7ccb
Fix wrong parameters 2024-08-21 18:48:16 +02:00
smallmodel
13911b051a
Use OpenAL by default 2024-08-21 18:35:06 +02:00
smallmodel
694167d352
Merge pull request #341 from runlevel5/fix-compilation-errors
Fix compilation error [WIP]
2024-08-20 17:02:20 +02:00
Trung Lê
3b2e4ff9c1
Revert to original code 2024-08-21 00:18:38 +10:00
Trung Lê
16e0dc17a8
Add implicit conversion from const-qualified pointer types to non-const-qualified var 2024-08-21 00:13:04 +10:00
Trung Lê
1f4b7718e8
Refactoring gameExport_s::ReadLevel() and gameExport_s::WriteLevel() 2024-08-20 23:41:43 +10:00
smallmodel
8c59d6020e
Backported ioquake3 fixes for https://www.cvedetails.com/cve/CVE-2017-11721/ (Buffer overflow) 2024-08-18 13:35:59 +02:00
smallmodel
377b0896c2
Fix drivable vehicle not having the death waittill after loading from save
This caused some vehicles to be destroyed immediately after being handled from script (like the halftrack in t2l1)
2024-08-18 12:03:01 +02:00
smallmodel
a399fdf6cf
Removed useless comments 2024-08-17 21:07:25 +02:00
smallmodel
783c24d6f7
Fix sound never playing from entities that are not sent to clients 2024-08-17 17:24:17 +02:00
smallmodel
1254146223
Fix streamed sound stopping before end 2024-08-17 11:09:35 +02:00
smallmodel
f776d842d1
Don't load sound immediately if they must be streamed
This removes more hiccups
2024-08-14 19:08:20 +02:00
smallmodel
74acf35a89
Merge branch 'main' into features/oal-streaming 2024-08-13 21:07:27 +02:00
smallmodel
81b8fe3f61
Use a pointer to an array instead of accessing the tiki mesh field directly to avoid loop badly optimized due to the compiler thinking there can be only 1 element
This fixes #337
2024-08-13 20:55:12 +02:00
smallmodel
679bfb90ea
Fix accessing 8th leaves element before finishing the loop
This caused the 8th element to be taken into account when enabling optimizations with GCC (invalid pointer to the leaf)
2024-08-13 20:41:53 +02:00
smallmodel
deb18c53b7
Implement streaming support for OpenAL
See #333, and #324
2024-08-12 20:26:17 +02:00
smallmodel
bbb7aa3771
Updated CodeQL actions to use newer version of steps 2024-08-12 18:23:03 +02:00
smallmodel
eb04e26823
Use the new libmad version as it seems stable enough 2024-08-09 20:33:59 +02:00
smallmodel
3af24ee0ea
Exclude new sound CPP files directly when not using the new sound system instead of using #ifdef 2024-08-09 20:30:35 +02:00
smallmodel
513fe7773f
Don't append a '\' at the beginning during autocompletion 2024-08-08 20:44:00 +02:00
smallmodel
9150d1cc44
Fix lighting grid being incorrect
It fixes #321 where impacts like bullets would have an incorrect color (like red, green...)
2024-08-08 20:31:19 +02:00
smallmodel
e19b72647e
Use qglGenTextures to guarantee the uniqueness of the texture number 2024-08-08 19:07:09 +02:00
smallmodel
d809975882
Use Q_snprintf because itoa is non-standard 2024-08-07 22:27:02 +02:00
smallmodel
7b92d99afa
Fix compile error 2024-08-07 22:24:52 +02:00
smallmodel
b463c905cf
Free up unused images
This fixes #93 where the game would hit `MAX_DRAWIMAGES` after loading a few maps
2024-08-07 21:11:16 +02:00
smallmodel
7f8a0c9931
Fix the image texture number not properly matching the image
It caused issues with textures being messed up sometimes, after multiple maps were loaded
2024-08-07 21:10:04 +02:00
smallmodel
53d812666c
Remove FIXME section 2024-08-07 21:02:48 +02:00
smallmodel
7b59f07181
Allow precaching image manually with r_precacheimages 2024-08-07 20:01:38 +02:00
smallmodel
d22dea5e8e
Count renderer memory 2024-08-07 19:57:09 +02:00
smallmodel
8817467216
Implement trace obfuscation 2024-08-06 22:58:16 +02:00
smallmodel
236afa7c3f
Implement obfuscation mapping setup
The implementation reads all obfuscation csv and return a list of visual obfuscations
2024-08-06 20:21:00 +02:00
smallmodel
cd6ec5e3a7
Fix streamed sound, use 2D instead with properly implemented panning 2024-08-06 18:43:15 +02:00
smallmodel
434aaf3eaf
Initialize last animation time 2024-08-05 23:41:17 +02:00
smallmodel
5b80ea20c7
Fix filename case sensitivity on Linux
This fixes #334 where some sounds wouldn't play because some scripts reference sounds without respecting the case
2024-08-05 21:11:49 +02:00
smallmodel
1d60405eaa
Fix heap corruption when taking screenshots with non-standard resolutions like 1366x768 2024-08-05 19:48:23 +02:00
smallmodel
64f4f59165
Fix vid_restart and snd_restart resetting the sound system (experimental sound system only)
This fixes #335 where one of those commands would clear all active sounds as well as the triggered music, and the soundtrack
2024-08-05 19:21:38 +02:00
smallmodel
192f9ac514
Added S_CurrentSoundtrack() 2024-08-05 19:14:30 +02:00
smallmodel
279b1413ec
Clear the active music when stopping the triggered music 2024-08-05 19:09:29 +02:00
smallmodel
9c5297882c
Renamed CHANNEL_FLAG_PLAYABLE to CHANNEL_FLAG_PLAY_DEFERRED 2024-08-05 18:49:41 +02:00
smallmodel
a6d508d791
Fix sounds replaying when unpausing
This caused some sounds to play again when saving
2024-08-05 18:49:16 +02:00
smallmodel
6b3402c631
Fix actor accuracy being crazy, killing the player easily 2024-08-05 18:43:56 +02:00
smallmodel
d5da32b8a9
Fix AI damage 2024-08-05 18:43:40 +02:00
smallmodel
39b3ed3d44
Fix part blend mult being incorrectly archived
This may have been the cause of animations not properly playing and the player being unable to climb on ladders
2024-08-03 18:40:27 +02:00
smallmodel
f8b97405ff
Fix infinite loop in DownSampleWav when s_khz is less than 44 kHz
This fixes #330 where `s_khz` below 44 (the usual sample rate of mohaa wav files) would cause an infinite loop due to improper usage of the `ii` variable in the loop where another variable would be accidentally incremented instead
2024-07-30 20:59:48 +02:00
smallmodel
1d4fe357c8
Fix ShaderForShaderNum incorrectly swapping the shader num 2024-07-29 21:39:24 +02:00
smallmodel
c7900b6048
Fix static model index endianness 2024-07-29 21:13:18 +02:00
smallmodel
6e3f959684
Fix header version incorrectly parsed 2024-07-29 20:32:21 +02:00
smallmodel
eb9a3b1bbf
R_UnpackTerraPatch: no need to get little-endian values as values are already swapped by R_SwapTerraPatch
See #332
2024-07-29 19:04:29 +02:00
smallmodel
391450f090
Swap bsp header on big-endian architectures
See #332 where the lump's offset and length are incorrect on big-endian architectures
2024-07-29 19:03:26 +02:00
smallmodel
f804476fbc
Add soft-oal to the build 2024-07-28 19:55:20 +02:00
smallmodel
60e4fa7005
Handle shader picmip and fix shaders not rendered properly with force32bit (alpha channel was ignored) 2024-07-28 19:25:24 +02:00
smallmodel
c13f9dc9a8
Increase MAX_IMAGE_ANIMATIONS
This fixes emitters not playing correctly
2024-07-28 19:12:08 +02:00
smallmodel
f213943b2d
Fix RB_SetGL2D 2024-07-28 19:02:06 +02:00
smallmodel
5159a534bb
Fix animated images playing at the same time for all entities 2024-07-28 19:01:34 +02:00
smallmodel
c7a4e705cb
Fix libmad still producing shared libraries 2024-07-28 18:51:15 +02:00
smallmodel
864ea08393
Fix special characters not being handled properly
This fixes characters (signed character below 0) being replaced by '?' in UI text elements, like in the console
2024-07-27 23:41:12 +02:00
smallmodel
ebfb6d1846
Fix inwardsphere not being used
This fixes emitters looking incorrect, like `animate/adamspark.tik`, for the explosion of electric panels
2024-07-27 23:20:30 +02:00
smallmodel
6b89ec615a
Set damage angles only for mohaa 1.0-1.11 2024-07-27 19:45:18 +02:00
smallmodel
af432e6d3f
Allow pain if the current time is above the allowed next pain time 2024-07-27 19:37:05 +02:00
smallmodel
44c17409a7
Allow pain if the player dies 2024-07-27 19:33:39 +02:00
smallmodel
0f48c39bc1
Add more resilience against null entity in G_FixEntityPosition 2024-07-27 19:05:45 +02:00
smallmodel
572e6652cc
Fix followpath not working under special circumstances
This fixes an issue where some planes (like the final bomber plane in t3l2) would not fly and look stuck
2024-07-27 19:05:05 +02:00
smallmodel
fecb601fc4
Clear velocity only if it's not ignored 2024-07-27 18:17:10 +02:00
smallmodel
7b238e9d34
Set new orders appropriately 2024-07-27 18:13:31 +02:00
smallmodel
73c8ff11b3
Call CurrentScriptThread() to get the current script, so it can throw an exception if the current thread is NULL 2024-07-27 18:03:41 +02:00
smallmodel
682dc89067
Add ignorevelocity argument for followpath 2024-07-27 17:54:48 +02:00
smallmodel
ee514710c5
Add Emscripten implementation from ioquake3 upstream 2024-07-26 23:57:50 +02:00
James Darpinian
2d15696a5e
Add .vscode and baseq3 to gitignore 2024-07-26 23:03:40 +02:00
Alan Zhao
769d06b0f0
Use nanosleep(2) instead of usleep(3)
usleep(3) was declared obsolete in POSIX.1-2001 and removed in
POSIX.1-2008 and nanosleep(2) was recommended to be used instead.
2024-07-26 23:03:09 +02:00
smallmodel
dcb0369e10
Fix actions deprecation warnings 2024-07-26 22:08:46 +02:00
smallmodel
1b35d3ce05
Fix angular delta being wrong
This fixes animated characters being sometimes badly positioned, like actors in the plane in t1l1
2024-07-25 21:46:33 +02:00
smallmodel
31d254cb9f
Use ceil() and set the delta appropriately if time1 is after team2 2024-07-25 21:43:19 +02:00
smallmodel
bf4780bbdb
From now, load streamed sound into memory as deferred loading is currently unsupported 2024-07-25 19:49:34 +02:00
smallmodel
5af8e127f8
Added NULL sound flag 2024-07-25 19:04:08 +02:00
smallmodel
016e062fef
Fix UIReggedMaterial::ReregisterMaterial and UIReggedMaterial::GetMaterial
ReregisterMaterial() must register the material if it was registered before, and GetMaterial() must register the material if it hasn't been registered and return it
2024-07-24 21:10:46 +02:00
smallmodel
c093122764
Made code C++ compatible so UI_LoadResource() can be used 2024-07-24 20:07:22 +02:00
smallmodel
11ec6270da
Made OpenAL package required 2024-07-24 19:57:22 +02:00
smallmodel
81df55310b
Fix medals always being awarded
This fixes #316
2024-07-23 19:53:40 +02:00
smallmodel
e5fb85ad08
Fix material not refreshing when it already has a shader.
This fixes #329 where the material (matching quick.tga) would be loaded only once without being able to change
2024-07-23 19:06:48 +02:00
smallmodel
c5ef60040a
Fix sounds not being resumed properly after loading from save 2024-07-22 20:44:00 +02:00
smallmodel
757b4849f8
Add a fix to load the music from save
This commit implements code to get/set sample offset in an OpenAL channel and saves the music filename/offset into the file. This only works by using the experimental sound system, so it partially fixes #327
2024-07-22 20:13:03 +02:00
smallmodel
2198bdec21
Added stub variables and functions for loading 2024-07-22 19:15:52 +02:00
smallmodel
8bd377ce85
Fix the save system taking a screenshot of the whole UI menu instead of just the 3D view
This fixes #328 where the save would have a screenshot of the save menu
2024-07-22 19:00:50 +02:00
smallmodel
89eae68318
Fixed parameter mistake
(Why didn't you tell anything about that, MSVC?)
2024-07-20 22:09:03 +02:00
smallmodel
d1e94f3934
Fix saveshot not executed when saving
This fixes #273 where the loadsave menu wouldn't show the screenshot
2024-07-20 16:07:02 +02:00
smallmodel
fc0a995c66
Added code to save image with custom resolution to a file 2024-07-20 16:04:04 +02:00
smallmodel
eee0eaac4a
Process the "!" (not) syntax for enabledcvar
This fixes #265 where the mine detector icon wouldn't appear because it wants SP mode
2024-07-17 23:55:11 +02:00
smallmodel
535da856a4
When returning a cvar value, use the latched string if present 2024-07-17 23:43:00 +02:00
smallmodel
422bf647a7
Save the client-game state into the archive file (feature from moh spearhead 2.0)
This saves cgame data such as emitters and vss sources
2024-07-15 23:45:32 +02:00
smallmodel
93cd470659
Fix broken cgame state saving 2024-07-15 23:44:11 +02:00
smallmodel
81b86d61da
Fix read-only cvar being improperly archived
This caused cvars like `paused` being wrongly restored. If the `paused` value is 1 or above, like when saving from the menu, the game would get stuck loading the level because it's paused, no frame could be executed.
It also fixes cvars like `sv_fps`, `g_playermodel` not being archived when they should.
Fixes #326
2024-07-15 20:39:22 +02:00
smallmodel
eac8580f64
Add libmad 0.16.4
This new version introduces patches against crashes and exploits. CMake is also fully supported and platforms are properly detected so architecture specific optimizations are used.

To use it, USE_SOUND_NEW must be non-zero when configuring the project
2024-07-11 23:04:04 +02:00
smallmodel
d56498e622
Adds CHANNEL_NONE case statement even if there is nothing to do 2024-07-11 22:04:03 +02:00
smallmodel
551fccb761
Fixes wrong handle being compared for uniqueness
This should fix invisible models (fixes #322)
2024-07-02 22:47:41 +02:00
smallmodel
5317b8424f
Prevents the player from walking
This fixes #275
2024-07-02 22:16:13 +02:00
smallmodel
5816391e9b
Fixes loopsound not properly working (not playing, or not being 3D) 2024-07-02 20:25:08 +02:00
smallmodel
543c00037a
Implements sample playback rate 2024-07-02 20:10:54 +02:00
smallmodel
d5f435ee90
Makes loops work as they should 2024-07-02 20:01:01 +02:00
smallmodel
02e2e92d36
Uses linear sound distance model 2024-07-02 19:30:29 +02:00
smallmodel
040f8db0ef
Fixes wrong sound volume and pitch 2024-07-02 19:10:48 +02:00
smallmodel
14927df9fa
Moves MAX_SUBTITLES to `q_shared.h| 2024-07-02 19:03:27 +02:00
smallmodel
dca9709b12
Fixes MASK_PLAYERSOLID incorrectly using CONTENTS_WEAPONCLIP instead of CONTENTS_PLAYERCLIP for invisible player collision
This fixes #317, fixes #319 and fixes #320 where the player would bypass clip/playerclip
2024-07-02 18:51:53 +02:00
smallmodel
d6571820fe
Fixes g_pVert/g_pTris being freed even when they are NULL 2024-07-02 18:46:27 +02:00
smallmodel
a0d3333ebb
Fixes chan->bufferdata not being set to NULL when released 2024-07-02 18:45:51 +02:00
smallmodel
9615fafc1e
Fixes incorrect usage of DotProduct result in an integer 2024-07-01 19:03:21 +02:00
smallmodel
5fc2425f3a
Set the mindist/maxdist for 3D sounds 2024-07-01 18:52:04 +02:00
smallmodel
63445c4fc1
Added a note to use the experimental openal-based sound system 2024-07-01 18:20:22 +02:00
smallmodel
eefe8ee2d1
Allow 3D / pan with streamed or MP3 sounds 2024-07-01 18:17:04 +02:00
smallmodel
edb1cb0ebe
Renamed SFX_FLAG_NO_DATA to SFX_FLAG_STREAMED 2024-07-01 18:05:24 +02:00
smallmodel
140242a761
Fixes MP3 files like dialog improperly working 2024-07-01 18:00:20 +02:00
smallmodel
ae13be0c37
Fixes OpenAL errors 2024-07-01 17:39:47 +02:00
smallmodel
74ff3b920e
Fixes OpenAL 2D origin 2024-07-01 17:39:32 +02:00
smallmodel
2cd6b981f1
Puts the volume gain constant in a variable 2024-07-01 16:46:54 +02:00
smallmodel
f866dcbcfc
Adds triggered music support
This allows the main menu music to play, as well as single-player musics
2024-07-01 16:10:42 +02:00
smallmodel
0d394a7e67
Fixes strings printing on the same line 2024-07-01 14:15:58 +02:00
smallmodel
7059f32ecc
Don't timeout if the client hosts the game 2024-07-01 01:09:39 +02:00
smallmodel
87baa69d7c
Fixes incorrect lighting color normalization
This fixes #314 where mark colors would have their values warped back to 0, making holes blue
2024-07-01 00:20:33 +02:00
smallmodel
408c901342
Fixes skyboxSpeed using an integer rather than a float
This fixes #313 where the skybox would be misplaced
2024-07-01 00:19:50 +02:00
smallmodel
d709dda87a
Use shader's distance range instead of the portal range 2024-06-30 23:57:32 +02:00
smallmodel
cda6225659
Adds a workaround against a bit that was lost on x86 with FP87.
This fixes #312 where a rounding error caused facets to be removed due to windings points being outside of the epsilon
2024-06-23 17:26:07 +02:00
smallmodel
563182c14c
Added FloatRoundedBitError() (currently unused) 2024-06-23 17:25:23 +02:00
smallmodel
303ed30a38
Don't remove the facet is there is no border planeCM_PlaneEqual 2024-06-23 17:19:52 +02:00
smallmodel
0a6c745ffb
Use VectorNormalize() instead of VectorNormalize2() 2024-06-23 17:10:58 +02:00
smallmodel
9d654faa3d
As m_BlockedPaths is an array of pathway_ref, the proper delete call must be used 2024-06-23 00:24:20 +02:00
smallmodel
9407b64fe3
Q_strncpyz: don't copy if the src is the same as the dest 2024-06-23 00:18:22 +02:00
smallmodel
1f0f5764a8
Added PathInfo() constructor initialization 2024-06-22 21:41:28 +02:00
smallmodel
13197acb3a
Uses a signed char instead of a char for opcode stack offset. On some platforms like ARM, char is unsigned by default
This fixes #311 where a memory corruption that occurred in ARM was caused because of insufficient ScriptVM stack size. The stack size was incorrectly calculated because the stack offset was using unsigned values instead of signed in ARM.
2024-06-22 19:18:08 +02:00
smallmodel
2f48ca6adb
Adds assertion check to check if top stack is out of bounds 2024-06-22 19:03:27 +02:00
smallmodel
01d938b5ba
Fixes some variables being uninitialized 2024-06-22 19:03:04 +02:00
smallmodel
186d7a12e5
typo 2024-06-22 16:51:20 +02:00
smallmodel
5192d36f81
Fixes gametype incorrectly checked in G_InitWorldSession 2024-06-22 16:43:03 +02:00
smallmodel
dfb6c37c9e
Don't copy the server name if it's from the same string address 2024-06-22 16:42:39 +02:00
smallmodel
cb208b9ad2
Initialize the message buffer to avoid leaking private data 2024-06-22 16:39:26 +02:00
smallmodel
e4d20c3fa1
Initialize explosion flash 2024-06-22 16:39:08 +02:00
smallmodel
0b747bf1c5
Use memmove rather than strcpy for removing key values 2024-06-22 16:39:00 +02:00
smallmodel
e207715b5e
Initialize m_iLastTiresUpdate 2024-06-22 16:12:29 +02:00
smallmodel
bef1b456e1
Initialize all Ammo members 2024-06-22 16:11:03 +02:00
smallmodel
11349f9ad5
Fixes the source pos access for ENUM_if_statement (out of bounds index) 2024-06-22 16:08:33 +02:00
smallmodel
2a485a6b69
Fixes the endianness when loading LOD from file 2024-06-22 15:34:38 +02:00
smallmodel
f41e92de6e
Fixes possible memory corruption when generating a LOD curve 2024-06-22 15:34:00 +02:00
smallmodel
835c0b0d9a
Adds constants for LOD curve values 2024-06-22 15:30:59 +02:00
smallmodel
d9dc34f06d
Checks for AGEN_TIKI_DIST_FADE and AGEN_ONE_MINUS_TIKI_DIST_FADE for static models 2024-06-21 22:02:59 +02:00
smallmodel
907ff36018
Fixes r_showstaticbboxes freezing the game 2024-06-21 21:49:13 +02:00
smallmodel
64626a767c
Fixes entities not being rendered after number 1023
This fixes #310 where some static models would not be rendered, making it look like there are invisible walls.
2024-06-21 21:48:55 +02:00
smallmodel
a7df73073d
Adds a condition to check if static model poly can be rendered 2024-06-21 20:54:14 +02:00
smallmodel
40492daecd
Avoid creating a new sound index when there is no active client 2024-06-16 23:20:30 +02:00
smallmodel
a5691d7779
Allows clients to join a single-player game 2024-06-16 20:48:34 +02:00
smallmodel
d1ecd4a3c8
Don't initialize client persistant data during autosave 2024-06-16 18:19:11 +02:00
smallmodel
5482b31c66
Reads the sv_privatePassword value 2024-06-16 18:18:14 +02:00
smallmodel
15f2f6c798
Renamed g_session functions 2024-06-16 18:16:14 +02:00
smallmodel
46b3f4eb5e
Adds differentMap parameter for G_ClientConnect, it clears the selected DM weapon.
On each map change, the player gets asked for the primary weapon like in 2.0 and above
2024-06-16 18:14:26 +02:00
smallmodel
f5aadbb788
If the loopSound has no origin, make it local
This should fix #309
2024-06-15 16:38:02 +02:00
smallmodel
bbb54ea36d
Uses LoopSounds() parameters instead of just the alias 2024-06-15 16:33:02 +02:00
smallmodel
d7a5eb5d2f
Use LEVEL_WIDE_MIN_DIST instead of 10000 constant 2024-06-15 16:26:35 +02:00
smallmodel
cc716c3fa4
Don't process loopsound yet when spawning 2024-06-15 16:22:34 +02:00
smallmodel
141574a0d7
Ignore mouse events when paused 2024-06-15 16:22:21 +02:00
smallmodel
2df8ed10d0
Improves timeout checking, properly show the timeout menu and shutdown the server 2024-06-15 14:56:30 +02:00
smallmodel
40e3977664
Continue using entities even when attached to a turret, in 1.11 and below for backwards compatibility!
Fixes #140 where the MG42 objective in m1l1 would not trigger
2024-06-15 00:16:29 +02:00
smallmodel
7ddee0100e
Implements CG_BodyFallSound() 2024-06-14 22:24:55 +02:00
smallmodel
6b869c4c0d
Use an enumeration instead of raw values 2024-06-14 21:39:54 +02:00
smallmodel
91497d8fa7
Implements Player::EventTestAnim() 2024-06-14 21:20:15 +02:00
smallmodel
85bf56ae03
Call SetWeight() rather than setting it manually 2024-06-14 21:19:04 +02:00
smallmodel
84d702838d
Implemented Player::MeasureLandmineDistances()
This makes minedetector actually detect mines, especially on `e1l2`
2024-06-13 23:58:31 +02:00
smallmodel
fd3a36f162
Fixed melee sometimes not making the hit sound 2024-06-13 23:30:19 +02:00
smallmodel
10e3192f85
Fixed MASK_PLAYERSOLID being wrong 2024-06-13 23:24:11 +02:00
smallmodel
de874874e4
Use an enum for setup case rather than raw values 2024-06-13 23:11:28 +02:00
smallmodel
72e315bce1
Using an enum channelType_e rather than raw values for bone channel types 2024-06-13 23:04:33 +02:00
smallmodel
02ef85e390
Removed GetChannelTypeFromName(), was useless 2024-06-13 21:28:49 +02:00
smallmodel
aeba0e0f6f
Set the real limit of MAX_SKELETOR_CHANNELS 2024-06-13 21:26:59 +02:00
smallmodel
f8fa944054
Some refactoring, + implemented SetLocalFromGlobal() 2024-06-13 21:26:51 +02:00
smallmodel
1d50fa088a
Don't dealloc if there is no frame in the channel 2024-06-13 21:26:29 +02:00
smallmodel
546ded324e
Made ChannelNames() method public 2024-06-13 21:25:45 +02:00
smallmodel
332a635031
Use MAX_GLOBAL_FROM_LOCAL 2024-06-13 21:25:02 +02:00
smallmodel
de02c868a2
Fixed bullet tracers being incorrect
This should fix almost immobile bullet tracers on t1l1
2024-06-11 23:46:50 +02:00
smallmodel
a74b966b7c
Update fog when changing whether or not the terrain must be rendered 2024-06-11 23:44:02 +02:00
smallmodel
ca4b1ebdee
Don't render terrain when refdef.render_terrain is set to false 2024-06-11 23:37:45 +02:00
smallmodel
42c20ac008
Portal sky mustn't cause entity surface to be r-eadded
This fixes an issue where an entity would get re-added with a really lower LOD. Fixes #307
2024-06-11 23:35:18 +02:00
smallmodel
a26e5b74c2
Use armhf and armel suffix to distinguish between ARM variants 2024-06-11 22:09:31 +02:00
smallmodel
ee5faedaf9
Removed the value of LittleSwap/BigSwap on little-endian/big-endian 2024-06-11 21:25:38 +02:00
smallmodel
874b034698
Corrected some compilation warnings 2024-06-11 21:24:01 +02:00
smallmodel
dfb2cb6bbf
Fixed buffer overrun 2024-06-11 21:19:15 +02:00
smallmodel
fb15f0f2b3
Fixed a tiny mistake that prevented morphs from working correctly
Actors now have a working dynamic facial expression (moving eyes/mouth/brown...)
2024-06-11 00:12:59 +02:00
smallmodel
4d231fbc50
Call LocalChannel instead of GetLocalFromGlobal 2024-06-11 00:05:28 +02:00
smallmodel
dd85118a9c
Don't pack channels when reading encoded frames from mohsh and above (they're already packed in the animation file) 2024-06-11 00:01:55 +02:00
smallmodel
531340627d
Call LocalChannel() instead 2024-06-10 23:53:42 +02:00
smallmodel
6b6e5291dd
Fixed EYES_up length 2024-06-10 23:40:50 +02:00
smallmodel
79b0e6998d
Fixed implementations 2024-06-10 23:40:34 +02:00
smallmodel
445814b144
Fixed skeletor_c::ChannelNames return value 2024-06-10 22:15:10 +02:00
smallmodel
ebb3173322
Added skeletorMorphCache_t as an alias to int 2024-06-10 22:06:47 +02:00
smallmodel
c16f2029b1
Implemented skeletor_c::ChannelNames() 2024-06-10 22:06:35 +02:00
smallmodel
abefdd772c
DecodeFrameValue should only return a float value 2024-06-10 22:06:25 +02:00
smallmodel
e550d244df
Reimplemented skelChannelList_s::LocalChannel 2024-06-10 22:05:39 +02:00
smallmodel
84cc66ad48
Merge pull request #306 from pryon/UINotepad
Implement UINotepad
2024-06-10 18:31:34 +02:00
pryon
fa5a97031d Fix assignment of a temporary to a non-const reference error on GCC 2024-06-10 14:43:40 +02:00
pryon
6e454cdfb3 Fix subtle bugs and refactor in UIWindowManager 2024-06-10 14:26:38 +02:00
pryon
52f43a3aa6 Document OPM fix for center-justified UINotepad statusbar 2024-06-10 14:25:30 +02:00
pryon
907aa21ba8 Fix UIPopupMenu crashes caused by dereferencing already freed instance 2024-06-10 14:24:39 +02:00
pryon
ac01ad6751 Take over va() memory safety fix from ioquake3 2024-06-10 14:19:29 +02:00
pryon
c84702b490 Fix file picker crash on AA 2024-06-10 14:18:49 +02:00
pryon
edd2a9d8f6 UIMultiLineEdit::Draw documentation 2024-06-10 14:17:35 +02:00
pryon
a19c7afce0 Add placeholders for handling clipboard operations in UIMultiLineEdit
Actual clipboard functionality will be added later
2024-06-10 14:15:06 +02:00
pryon
849f1ee7d1 Fix several bugs in UIMultiLineEdit
These are necessary so that UINotepad can actually be used for editing text
2024-06-10 14:13:21 +02:00
pryon
c60c2c09e1 Fix incorrect TAB character width calculation and refactor logic 2024-06-10 14:06:30 +02:00
pryon
3254b3f044 Send SE_CHAR events (CharEvent) for ENTER, TAB and ESCAPE keys
So that UINotepad registers them as valid keypresses when typing
2024-06-10 14:04:55 +02:00
pryon
9a35d34fc3 Implement UINotepad
Also fix several original game bugs within, some cosmetical, some memory corrupting
2024-06-10 14:02:10 +02:00
pryon
4da5e26cdc Move CTRL macro to q_shared.h 2024-06-10 13:59:10 +02:00
smallmodel
8a28ad0c36
Fixed explosion effects on protocol below 2.0 2024-06-09 20:16:14 +02:00
smallmodel
e08b2fe382
Added cg_target_game 2024-06-09 20:10:30 +02:00
smallmodel
8b16e94829
Fixed grenade bounce sound overly playing 2024-06-09 19:56:41 +02:00
smallmodel
618223f01b
Ignore NumShaders in protocol version 8 and below 2024-06-09 19:32:15 +02:00
smallmodel
13c63d3e1f
Fixed wrong condition with msg broadcast visibility 2024-06-09 18:51:39 +02:00
smallmodel
8e0aa5185b
Fixed CGM endianness 2024-06-09 18:48:22 +02:00
smallmodel
2b01f092b3
Fixed german model always being set to german_wehrmacht_soldier 2024-06-09 18:23:06 +02:00
smallmodel
1fd238567e
Fixed animation loading endian 2024-06-09 17:55:57 +02:00
smallmodel
cb59edc963
Handle script exceptions in G_ServerSpawned 2024-06-09 16:56:42 +02:00
smallmodel
0ce70b9f8f
Improved/fixed archive support for big-endian platforms 2024-06-09 16:53:50 +02:00
smallmodel
57175cfa5c
Simplified the decompression algorithm and fixed it for big-endian 2024-06-09 16:45:10 +02:00
smallmodel
8aacdcefb8
Fixed lz77 endianness 2024-06-09 14:14:11 +02:00
smallmodel
69766ae87a
Added SwapValue 2024-06-09 13:19:31 +02:00
smallmodel
d3d2082e41
Removed useless print 2024-06-09 13:08:01 +02:00
smallmodel
de621f6acb
Made short3 implementation endianness independant
This fixes scripts not working properly as script variables key are using short3
2024-06-09 00:59:23 +02:00
smallmodel
a7c5067475
Fixed the execution of a method on the correct class 2024-06-09 00:07:11 +02:00
smallmodel
7282426736
Improved the networking code for big-endian architectures 2024-06-09 00:02:00 +02:00
smallmodel
0333fd86f8
MSG_DeltaNeeded_ver_15 was never called 2024-06-08 21:52:28 +02:00
smallmodel
ab91ade685
Explicitly use signed char for patch xy because some platforms use unsigned char by default 2024-06-08 19:56:24 +02:00
smallmodel
005afcd53d
Simplified CM_PickTerrainSquareMode 2024-06-08 19:20:27 +02:00
smallmodel
c1604c0c8c
Handle animation file endianness 2024-06-08 14:59:52 +02:00
smallmodel
5155c10136
Fixed scripts not working on big-endian architectures 2024-06-08 14:40:35 +02:00
smallmodel
28c6e3b398
Properly swap terrain patches for rendering on big-endian architectures 2024-06-08 12:48:36 +02:00
smallmodel
41244095b1
CMod_LoadTerrainIndexes: big-endian compatibility 2024-06-08 12:47:18 +02:00
smallmodel
a5535fa789
Make sure to initialize the widget's command handler to NULL.
This should fix #305
2024-06-08 01:40:36 +02:00
smallmodel
6796a8b3fe
Properly swap terrain patch values on big-endian systems 2024-06-08 01:08:58 +02:00
smallmodel
819dffcb86
Added MAX_TERRAIN_VARNODES 2024-06-08 01:05:47 +02:00
smallmodel
b54db17069
Added unsigned swaps 2024-06-08 01:03:08 +02:00
smallmodel
e27f2443e8
Fixed skel loading on big-endian systems 2024-06-08 00:53:39 +02:00
smallmodel
a1e0bc5d7c
Implemented TIKI_SwapSkel (used on Big-Endian systems) 2024-06-08 00:40:52 +02:00
smallmodel
28ea95b9ff
Added scale field 2024-06-08 00:08:54 +02:00
smallmodel
e3b9e48d8c
Added TIKI_SKEL_LOD_INDEXES 2024-06-07 22:38:45 +02:00
smallmodel
026b6b2562
Ignore endianness on skd/skb header signature, as it's a string 2024-06-07 22:08:46 +02:00
smallmodel
0fa380ecff
Correctly read the BSP checksum on big-endian systems 2024-06-07 22:01:24 +02:00
smallmodel
ebd885f053
Fixed Subclient not having the correct client name 2024-06-07 20:36:55 +02:00
smallmodel
74ccb03e54
Reduced compilation warnings 2024-06-07 20:34:13 +02:00
smallmodel
50264c4968
Make sure to cast the float number to int when using it in the format specifier 2024-06-07 20:25:47 +02:00
smallmodel
be222b64a1
Fixed one tiny instruction mistake that could cause issues with dynamic lights on terrains 2024-06-07 20:20:19 +02:00
smallmodel
db7ae4ffef
Properly clear the color values 2024-06-07 19:57:14 +02:00
smallmodel
884a76db4c
Drop error instead of throwing an exception to meet non-throwing exception specification 2024-06-07 19:55:33 +02:00
smallmodel
18e5c6e714
Use unsigned format specifier to match MAX_VOTEOPTIONS_BUFFER_LENGTH's type 2024-06-07 19:49:51 +02:00
smallmodel
468341b7d0
Explicitly mark as override 2024-06-07 19:49:29 +02:00
smallmodel
e03b976ffd
Added missing header on scriptclass.cpp source file 2024-06-07 19:42:10 +02:00
smallmodel
34ea099d87
Define _FILE_OFFSET_BITS to 64 due to a bug in readdir() affecting 32-bit architectures
readdir() would return NULL, setting errno to EOVERFLOW, unable to load pk3 files
2024-06-06 22:18:23 +02:00
smallmodel
5f2827e2ab
Added hardware requirements 2024-06-05 22:32:36 +02:00
smallmodel
1d887b4655
Fixed leaf light being incorrectly reassigned 2024-06-05 21:21:35 +02:00
smallmodel
6250380f61
Added PowerPC into the build system 2024-06-05 21:13:33 +02:00
smallmodel
6bb475abe7
Fixed PowerPC platform support with proper checks for endianness and ppc64 2024-06-05 21:13:06 +02:00
smallmodel
31ea951357
Fixed SkelMorphGetXyz implementation 2024-06-05 00:43:08 +02:00
smallmodel
091c8b4d12
Optimized channel data memory and performance (feature from moh 2.0 and above) 2024-06-05 00:40:43 +02:00
smallmodel
c4523db991
Added GetBoneChannelType 2024-06-04 23:48:29 +02:00
smallmodel
2b66672d2d
Added MAX_GLOBAL_FROM_LOCAL constant and implemented skelChannelList_s::GlobalChannel and skelChannelList_s::LocalChannel 2024-06-04 21:06:43 +02:00
smallmodel
77de0b78ba
First test if the entity has morphs before proceeding to loop through vertices 2024-06-04 20:20:40 +02:00
smallmodel
0181fbcfa0
Use the weight's bone index if there is no morph 2024-06-04 19:52:32 +02:00
smallmodel
e1f2433c36
Fixed sky portal rendering
This fixes #260
2024-06-03 21:36:58 +02:00
smallmodel
c753dcafd8
SurfIsOffscreen: use raw surface values rather than tess values 2024-06-03 21:36:35 +02:00
smallmodel
57ac7d8c19
Removed code that is already present in CG_SetupFog() and CG_SetupPortalSky() 2024-06-03 21:36:12 +02:00
smallmodel
d64ef13b79
Fixed script_skyorigin never being sent to clients 2024-06-03 21:34:48 +02:00
smallmodel
911e87c6ec
physics_off: Don't reset the physics in 1.0 in Single-player mode
This fixes #303 in m4l2 where the player doesn't have their gun holstered in the truck
2024-06-03 20:29:41 +02:00
smallmodel
b75c7b64f1
Still allow crouch when glued in 1.0 and in Single-player mode
This fixes #303 where the player is standing in the truck in m4l2
2024-06-03 20:28:39 +02:00
smallmodel
135b519dd8
Reduced actor's change of getting curious 2024-06-02 23:47:06 +02:00
smallmodel
b7a0607d52
Using parameters that take the entity rather than raw values 2024-06-02 19:55:42 +02:00
smallmodel
2ee1a2099d
Ignore map name case sensitivity when parsing map-specific animations 2024-06-02 19:46:14 +02:00
smallmodel
7fe7e74fe2
Replaced all stricmp calls with Q_stricmp 2024-06-02 19:44:06 +02:00
smallmodel
0a3a23af41
Using AI_EVENT_MAX to check for max ai events 2024-05-29 23:54:48 +02:00
smallmodel
e89262ed3b
Fixed TIKI_ParseAnimations improperly returning, even when a map was specified, causing parsing issues 2024-05-28 21:38:17 +02:00
smallmodel
21fda4cabd
Removed redundant code 2024-05-28 21:31:28 +02:00
smallmodel
a85694b548
Fixed incorrect method for EV_ScriptThread_Showmenu.
This fixes #302 where screen text with the mission date would never be shown.
2024-05-28 20:49:09 +02:00
smallmodel
16464c5a68
Removed zone events from entity
This fixes a conflict where some scripts would store stuff in a variable named `zone` in an entity
2024-05-27 23:28:12 +02:00
smallmodel
85c8769512
Fixed incorrect usage of the grid lighting
This fixes some entities being invisible when `r_fastentlight` is set to 1, due to the alpha color being 0 (cast from int to char for each color value). Fixes #299
2024-05-20 13:11:48 +02:00
smallmodel
c3abbd9014
Added assertion checks 2024-05-20 13:10:12 +02:00
smallmodel
98239050d8
Correctly archive the active weapon (safe pointer)
This fixes the player sometimes being holstered after loading from a save (closes #270)
2024-05-12 23:55:11 +02:00
smallmodel
dc7caf04a8
Fixed MoveTo not working on waypoints.
This fixes an issue where objects using waypoint (like elevators) would move at `(0 0 0)`. Closes #298
2024-05-12 23:40:11 +02:00
smallmodel
db01f72adc
Reimplemented ScriptVariable::entityValue
Some script events don't check if it's an actual entity, it would cause crashes.
E3L3 would crash after the player got out of the AB41: the AB41 was targetting a VehiclePoint and vehicles_thinkers.scr script set the `self.collisionent` to `self.target` which caused a crash as `VehiclePoint` doesn't inherit from `Entity`
2024-05-01 20:41:57 +02:00
smallmodel
170b4b0972
Fixed ScriptAimedStrafingGunfire aimTarget never set nor used
This fixes the gunfire incorrectly damaging things it shouldn't damage.

For example, the sniper3 balcony AI on e3l1:
The bomber caused this AI to fall before initialization (by damaging them when it shouldn't), the AI became nonsolid. After initialization, the AI had enemy enabled, however it remained nonsolid because of the balcony fall. It was constantly shooting at the player and it was unkillable because it was nonsolid.
The mission wasn't able to be completed because of this issue.
2024-05-01 20:18:52 +02:00
smallmodel
ff6e81d44f
Fixed CL_GetSnapshot sometimes wrongfully assigning parents multiple times and displaying errors
This should fix #170
2024-05-01 18:55:25 +02:00
smallmodel
88bc0e1e85
Reimplemented MSG_SetBroadcastVisible() and MSG_SetBroadcastAll() 2024-05-01 18:36:27 +02:00
smallmodel
c5b46529b0
Check the client if it has a valid entity for MSG_SetBroadcastVisible() 2024-05-01 18:24:44 +02:00
smallmodel
e5dbfba55e
Fixed an issue where scripts would get compiled every time they are executed, causing a performance issue 2024-05-01 17:54:45 +02:00
smallmodel
daa7aceecf
Fixed sighttrace not properly passing entities
This fixes the issue where some scripts (like e2l3's BattleHouse) expect sighttrace to ignore entities (fixes #202)
2024-05-01 17:43:04 +02:00
smallmodel
35681e7a1f
Added MASK_IGNORE_ENTS 2024-05-01 17:42:02 +02:00
smallmodel
d4dfde3340
Trigger must not be effective when being damaged if it does not take damage
This fixes issue with vehicles damaging triggers by touching them (like the ClickItemTrigger on m5l3 with tanks)
2024-04-30 20:26:08 +02:00
smallmodel
05a6b43e08
Check for __APPLE__ to detect MacOS 2024-04-30 19:25:02 +02:00
smallmodel
16f775c78c
Fixed ScriptSlave path with 2 equal points
This fixes the script slave moving infinitely and not sending movedone notifications as it would never advance to the next path. e3l4's outro is now fixed because of that (was stuck).
2024-04-29 23:42:05 +02:00
smallmodel
af919dadca
Simplified code for g_showflypath 2024-04-29 20:04:21 +02:00
smallmodel
41c322ec81
Refactored ScriptSlave::FollowingPath and ScriptSlave::SetupPath with bugfixes 2024-04-29 19:59:16 +02:00
smallmodel
ac8c18250d
If the actor is an american, always call ThinkHoldGun_TurretGun() without checking for enemy 2024-04-28 20:39:54 +02:00
smallmodel
4b05c400b2
Round to integer for vectoyaw()
This fixes Actor never finishing TurnTo as the DesiredYaw was set to a very precise value
2024-04-28 19:29:54 +02:00
smallmodel
cc85d0c100
Bumped version number 2024-04-22 23:40:00 +02:00
smallmodel
56dce21538
Fixed an invalid access to lighting sphere leaves
It was causing crashes on some occasions
2024-04-22 23:39:07 +02:00
smallmodel
3cd5acf3aa
Fixed issue with case-sensitive variables.
normal/return commands are case-insensitive
getter/setter commands are case-sensitive
2024-04-22 20:10:01 +02:00
smallmodel
48fc5a72b8
Fixed some setters and getters being inverted 2024-04-22 19:59:20 +02:00
smallmodel
26c3375112
When there is no enter_boneindex for turret slot, use the boneindex instead
This fixes #208
2024-04-22 18:28:56 +02:00
smallmodel
e89543710c
Check for max use angle when using the vehicle 2024-04-22 18:04:14 +02:00
smallmodel
ee48193f15
Added notagaxis
Fixes #222
2024-04-22 17:21:26 +02:00
smallmodel
6d10ed27c5
Fixed preferred weapon not showing on stats screen
Fixes #271
2024-04-22 16:48:24 +02:00
smallmodel
19c68aa25d
Ignore player collision if the actor is already nonsolid
This fixes #277 where the vehicle could get stuck due to the actor being solid afterwards
2024-04-21 20:33:31 +02:00
smallmodel
5ee7cb16bb
for ANIM_MODE_SCRIPTED and ANIM_MODE_NOCLIP, set the yaw based on the angular delta 2024-04-21 20:28:54 +02:00
smallmodel
4630a1f386
Fixed wrong return values for Vehicle::EventCanUse
It fixes Modello being hardly usable on maps like e3l2
2024-04-21 19:40:33 +02:00
smallmodel
06dab5d8b0
Refactored ScriptThread::EventPointsWithinDist for more clarity 2024-04-21 19:39:39 +02:00
smallmodel
054201bea9
Fixed character assertion fail when the character was a value below 0 2024-04-21 19:07:08 +02:00
smallmodel
f39a4c0bc7
Fixed projectile explosion origin.
This fixes exploder triggers sometimes never being triggered (fixes #294)
2024-04-21 17:47:39 +02:00
smallmodel
0e20d7e880
Fixed arm/arm64 binary loading on Windows
(fixes #295)
2024-04-14 23:03:46 +02:00
smallmodel
927f4bb4bd
Marked overridden virtual methods 2024-04-11 00:30:00 +02:00
smallmodel
f9901787b5
Removed "touch" unregistration 2024-04-11 00:26:45 +02:00
smallmodel
6731f56aea
Fixed m_PrevCodePos usage 2024-04-10 23:42:09 +02:00
smallmodel
d6870ecbee
Added trigger_sideduse from 2.30 2024-04-10 21:44:03 +02:00
smallmodel
eea8c42268
Added GetOwner event 2024-04-10 21:37:49 +02:00
smallmodel
99647e677a
Do projectile vulnerability for vehicles 2024-04-10 00:22:35 +02:00
smallmodel
a5d637dbb3
Added GetOwner() 2024-04-10 00:21:23 +02:00
smallmodel
048a973290
Added GetProjectileHitsRemaining 2024-04-10 00:20:32 +02:00
smallmodel
fa80e0bd75
Implemented FencePost 2024-04-10 00:05:00 +02:00
smallmodel
a23de7b361
Made Killed() a virtual method 2024-04-09 23:54:08 +02:00
smallmodel
dc60cb45b2
Fixed scripts using syntax like $self 2024-04-09 23:22:54 +02:00
smallmodel
2bf1144a14
Removed unused source files 2024-04-09 22:41:41 +02:00
smallmodel
ab5efa5a64
Fixed sentient being improperly attached/detached from/to the turret
This fixes #255
2024-04-09 00:12:02 +02:00
smallmodel
ccc98e4c62
Implemented missing ThrobbingBox_Stickybomb() 2024-04-08 23:38:51 +02:00
smallmodel
52424f63f0
Make ThrowObject::Throw throws an exception when the owner and targetent is NULL, also use centroid if the target entity is not a sentient 2024-04-08 21:52:48 +02:00
smallmodel
881df7193b
Fixed ThrowObject not usable when spawned from script.
This fixes #218
2024-04-08 21:47:24 +02:00
smallmodel
e859bba61d
Added a forgotten call to SetupNextCycle when turning on the projectile generator and fixed the uninitialized delay before beginning the cycle.
This fixes artillery system not working on t2l3, t2l4, e1l1... (fixes #224)
2024-04-08 21:33:59 +02:00
smallmodel
e3beec985e
When parsing and compiling a script, return the length in an output parameter instead so the method can return a boolean to indicate success.
This fixes #221 where a script with no code would fail.
2024-04-08 21:04:26 +02:00
smallmodel
9eec50d69f
Fixed script model animation issues, especially when they're looping
This fixes #220.
2024-04-08 20:52:58 +02:00
smallmodel
5a8cc83e6e
Fixed MM stepping
This fixes actors being slow and it also fixes actors going under the map
2024-03-31 22:52:30 +02:00
smallmodel
724aeb22ed
Fixed MM_SlideMove() velocity clip and interaction 2024-03-31 22:15:19 +02:00
smallmodel
6fdc756b59
Set terrain rendering settings to max detail by default 2024-03-17 22:38:44 +01:00
smallmodel
25418b7857
Ammo name must be case-insensitive
This fixes some maps like t1l3 where the player would have a pistol with 6 bullets and no ammo
2024-03-06 23:49:37 +01:00
smallmodel
b4de0b53e4
Special items must not be archived in persistent data 2024-03-06 19:43:37 +01:00
smallmodel
cacf1ca1b7
Set the unarmed flag when archiving persistent data 2024-03-06 19:35:15 +01:00
smallmodel
98c61529b9
Archive the weapon clip amount in persistent data 2024-03-06 19:33:48 +01:00
smallmodel
6675a491be
Fixed the model name when archiving persistant data
This fixes a crash when the next mission map is loaded and then saving/loading afterwards (fixes #237)
2024-03-06 19:29:07 +01:00
smallmodel
b6485ad7db
Configstring optimization so that there is only one occurence of a configstring index in pending server commands
This fixes configstring overflow in big maps like t1l2 (fixes #289)
2024-03-06 18:54:32 +01:00
smallmodel
9f5df368d1
Fixed infinite player team spectate 2024-03-05 23:30:25 +01:00
smallmodel
e970e29953
Use a constant expression for clarity 2024-03-05 22:59:12 +01:00
smallmodel
9fb559bdb1
Added an assertion check for lastRadarTime 2024-03-05 22:52:19 +01:00
smallmodel
61e9146385
Moved con_set entry to the header file
This fixes compilation issue with GCC (fixes #288)
2024-03-05 18:30:31 +01:00
smallmodel
897c2322b9
Archive the target list
This fixes crashes related to scripts using entities by target name
2024-03-04 23:35:22 +01:00
smallmodel
7b8be9fed1
Added ArchiveObject() that accepts a SafePtr 2024-03-04 23:34:31 +01:00
smallmodel
cebb351505
Added and implemented TargetList 2024-03-04 23:08:22 +01:00
smallmodel
b4bce3431b
Archive LightClass object pointer instead of a Class object pointer 2024-03-04 22:51:29 +01:00
smallmodel
c6e3dfdbe6
Fixed velocity clip (sliding along plane)
This fixes the issue where vehicles would not be moving precisely where it should be moving (incorrect clipping of the velocity). For example, the minesweeper tank in e1l2 kept getting stuck because it didn't move appropriately (fixes #261)
2024-03-04 22:40:49 +01:00
smallmodel
22d2790735
Fixed vehicle stepping 2024-03-04 22:27:00 +01:00
smallmodel
5d3b76b249
Cleaned up SetMoveInfo() / SetCEMoveInfo() 2024-03-04 22:26:56 +01:00
smallmodel
7b07be1502
use double instead of float 2024-03-04 22:25:31 +01:00
smallmodel
3acb796b59
Call VectorNormalize() directly in Vector::normalize() 2024-03-04 20:07:06 +01:00
smallmodel
25bbc1793d
Fixed AngleNormalize360 2024-03-04 20:06:35 +01:00
smallmodel
63456beeb0
Code clarity 2024-03-03 22:47:31 +01:00
smallmodel
2e32395cf2
VectorNormalize optimization 2024-03-03 19:51:56 +01:00
smallmodel
d04ed0aace
Made M_PI double 2024-03-03 19:46:32 +01:00
smallmodel
302f06f8d2
Clear the variable if the field cannot be found 2024-03-03 18:54:22 +01:00
smallmodel
4cf4ca2943
Fixed crash on pSoundAlias 2024-03-03 18:53:22 +01:00
smallmodel
fe35e02ed4
Fixed weapon pickup logic, like player picking up the weapon indefinitely when reaching max ammo 2024-03-03 18:09:19 +01:00
smallmodel
5fa1b98d34
Fixed vert Z coord not matching average height
This caused issue where verts would never be merged. This should fix #232
2024-03-03 17:52:29 +01:00
smallmodel
bebe117487
Formatted document 2024-03-03 17:34:01 +01:00
smallmodel
26495fe0f8
Refactored R_TerraTriNeighbor 2024-03-03 17:33:35 +01:00
smallmodel
4c4ac9f90e
Added more assertions for consistency 2024-03-03 16:24:09 +01:00
smallmodel
bf5fdb8f06
Fixed improper fence masks
This fixes #284, fixes #280
2024-03-02 15:29:25 +01:00
smallmodel
01e68fd5ee
Fixed turret gun never being killed
This fixes #231
2024-03-02 15:29:08 +01:00
smallmodel
e930b5481a
Mark the trigger as dead after kill 2024-03-02 15:27:35 +01:00
smallmodel
9bd4d40f09
Formatted document 2024-03-02 15:00:56 +01:00
smallmodel
40035f4df3
Fixed multi-shaders snow 2024-03-02 14:23:32 +01:00
smallmodel
a7b3fdd70b
Added getConfigStringIdNormalized client game import to normalize config strings 2024-03-02 14:06:32 +01:00
smallmodel
b77af7fced
Implemented R_GetLightingForDecal 2024-03-01 22:59:06 +01:00
smallmodel
52c89f1de3
Fixed comparison operator 2024-03-01 22:31:33 +01:00
smallmodel
e7cd70b8ee
Enable cg_rain by default 2024-03-01 22:19:18 +01:00
smallmodel
e06ee0f26a
Bounce backwards check 2024-02-28 23:40:41 +01:00
smallmodel
76c9e4e048
Fixed pickup message appearing twice 2024-02-28 23:33:10 +01:00
smallmodel
06d8ddbfc7
Fixed AI firing multiple bullets when it should fire one
This fixes AI killing the player almost instantly
2024-02-28 22:56:05 +01:00
smallmodel
8b9840d37f
Implemented Game::Archive() 2024-02-28 22:52:44 +01:00
smallmodel
960469be77
Implemented MakePrimitive() 2024-02-28 22:52:25 +01:00
smallmodel
77ef0f3579
Implemented game.detail and game.skill 2024-02-28 22:21:53 +01:00
smallmodel
07c840a4a9
Don't assert for NULL owner 2024-02-28 22:10:18 +01:00
smallmodel
35a8c4edfa
g_droppeditemlife: make sure the value is non-null 2024-02-28 22:10:07 +01:00
smallmodel
36af9e6589
Fixed a very boring mistake ignored by MSVC 2024-02-27 00:02:20 +01:00
smallmodel
ea14ab5664
Implemented special func 2024-02-26 23:25:39 +01:00
smallmodel
1ed8538745
Bounds check clarity 2024-02-26 20:23:31 +01:00
smallmodel
12e36b987a
Use G_DebugRotatedBBox when drawing the entity's bounding box 2024-02-26 19:56:35 +01:00
smallmodel
8324c599de
Implemented G_DebugRotatedBBox 2024-02-26 19:56:23 +01:00
smallmodel
d972c85fba
Formatted debuglines source file 2024-02-26 19:33:52 +01:00
smallmodel
d8b9abe7f5
Fixed call to GunTarget()
It was specifying the position in the boolean parameter which lead to wrong results
2024-02-26 19:21:12 +01:00
smallmodel
4f868d9585
Fixed a collision bug with fence masks 2024-02-26 19:19:38 +01:00
smallmodel
e27ac45f44
Don't load TGA without alpha for collision 2024-02-26 19:08:21 +01:00
smallmodel
58d0e43f78
Use MASK_USE instead of MASK_SOLID 2024-02-26 17:37:38 +01:00
smallmodel
a6c1cbfd50
Added MASK_USE 2024-02-26 16:34:31 +01:00
smallmodel
e32222884d
Fixed DisguiseSalute never finishing animation 2024-02-26 15:53:38 +01:00
smallmodel
49a7a1f8ff
minimum visibility is 0.999 and not 1.0 2024-02-26 15:53:17 +01:00
smallmodel
e5275c0f05
Fixed MASK_TRANSITION being wrong 2024-02-25 21:26:08 +01:00
smallmodel
c391605f61
Fixed AI attacking the disguised player
This fixes #203
2024-02-25 20:10:02 +01:00
smallmodel
73c9e6f1d8
Ignore disabled ennemies 2024-02-25 19:16:07 +01:00
smallmodel
2d6ac6f0be
Fixed weapon melee AI broadcast 2024-02-25 19:15:41 +01:00
smallmodel
57870103a6
Fixed TriggerVehicle not responding to VehicleCollisionEntity 2024-02-25 18:54:42 +01:00
smallmodel
64604b5c44
Disable non-pvs sound in single-player
This fixes #267 where configstrings are full
2024-02-25 18:43:42 +01:00
smallmodel
9960884e3c
Initialize watchFadeTime 2024-02-23 23:53:27 +01:00
smallmodel
593982d586
Added assertion test 2024-02-23 23:53:18 +01:00
smallmodel
f229c1c5a8
Fixed player health in SP 2024-02-23 23:21:44 +01:00
smallmodel
35e9f9982c
Preallocate arguments for sp/dm commands 2024-02-23 23:19:59 +01:00
smallmodel
a0cb46d4a1
Formatting 2024-02-23 23:09:57 +01:00
smallmodel
e8a48184b9
Set the ground entity number to the glue master 2024-02-23 23:09:29 +01:00
smallmodel
d2aa26248f
Don't allow ducking when physics are off
This fixes #251
2024-02-23 23:02:29 +01:00
smallmodel
0f1de72ae6
Initialize the ground entity number 2024-02-23 22:51:08 +01:00
smallmodel
efaea69c09
Don't evaluate state when immobile 2024-02-23 21:12:38 +01:00
smallmodel
a67dbff603
Reset state to STAND when the player has no physics 2024-02-23 21:12:23 +01:00
smallmodel
35e6435382
Reimplemented DropInventoryItems from 2.30 2024-02-22 23:12:04 +01:00
smallmodel
7a2735885f
Send information about sentient's team
This fixes #259
2024-02-22 22:50:36 +01:00
smallmodel
cc721a3db6
Lexer fixes for integer
This fixes map loading issues (fixes #258)
2024-02-22 21:36:31 +01:00
smallmodel
1a5cac2c6a
Implemented all parm methods
This fixes, #249 and fixes #217
2024-02-22 20:44:15 +01:00
smallmodel
ef08f1c8f3
Fixed turret fire issues 2024-02-22 20:21:53 +01:00
smallmodel
8919890dbe
Fixed entity collision for vehicles
This fixes vehicle not properly handling damage triggers (fixes #223, fixes #240)
2024-02-22 19:59:28 +01:00
smallmodel
cf6335d180
Fixed VehicleTouched not handling damage properly if there is no driver 2024-02-22 18:29:31 +01:00
smallmodel
a86a707e4a
Added more variables to initialize 2024-02-22 18:29:16 +01:00
smallmodel
9d61993878
Archive name_index 2024-02-21 20:59:41 +01:00
smallmodel
6eb20a3524
Added PostSpawn for ammo
This fixed ammo being spawned in the air without falling (fixes #244)
2024-02-21 20:59:28 +01:00
smallmodel
7314543c88
Fixed snow bullet hit effect
This fixes #246
2024-02-21 20:17:01 +01:00
smallmodel
bb4b10d752
Use result from Cvar_InfoString_Big for CS_SYSTEMINFO 2024-02-21 20:13:24 +01:00
smallmodel
416c568c51
Make CVAR_ROM variables appear first in info strings 2024-02-21 20:13:08 +01:00
smallmodel
65d3a51a17
Use '\n' instead of 10 2024-02-21 20:12:14 +01:00
smallmodel
e55f5902d5
Avoid using constant values 2024-02-21 20:12:05 +01:00
smallmodel
b0180383df
Fixed FFA scores
This fixes #242
2024-02-21 19:37:49 +01:00
smallmodel
61f0fc665f
Fixed MG42 reload anim name 2024-02-20 23:29:47 +01:00
smallmodel
b0c1d79132
Fixed AI mg42 fire delay 2024-02-20 23:29:38 +01:00
smallmodel
7945c2ca66
Fixed target's m_Team accidentally being overwritten
This causes NPC to look invulnerable (fixes #238)
2024-02-20 22:57:02 +01:00
smallmodel
8b2b1a9a47
S_AddLoopingSound: ignore null sfx handle 2024-02-20 22:42:54 +01:00
smallmodel
b76f9a9a6c
Fixed skel_entity_cache initialization 2024-02-20 22:42:34 +01:00
smallmodel
8af5da5fca
tiki assert check 2024-02-20 20:45:05 +01:00
smallmodel
cbe6d85bcd
Added multiple cache per entity 2024-02-20 20:44:55 +01:00
smallmodel
6b6e2c947c
Fixed vNorm not being initializing causing crashes on rare occasions
This should fix #169
2024-02-20 19:53:08 +01:00
smallmodel
66fcc2cd14
Cleaned up VSS_AddRepulsion 2024-02-20 19:52:11 +01:00
smallmodel
af829772f9
Cleaned up VSS_CalcRepulsionForces and fixed vss index 2024-02-20 18:54:59 +01:00
smallmodel
7b6a558fe5
Check for valid turret gun in P_UserAim
When the player dies, it gets detached from turret can would cause crash (#216)
2024-02-19 23:41:57 +01:00
smallmodel
4122ee4168
Fixed RunAndShoot state crash due to NULL moving patrol node
(#214)
2024-02-19 23:25:39 +01:00
smallmodel
b77f62ab58
Load/Save SimpleArchivedEntity
This fixes #213 where elevator wouldn't go up because of missing waypoint
2024-02-19 23:23:15 +01:00
smallmodel
783bf1b63c
Archive ignorevelocity member 2024-02-19 23:22:53 +01:00
smallmodel
a0728b4a8a
Using MASK_CLICKITEM mask for ClickItemAttack 2024-02-19 23:10:14 +01:00
smallmodel
ea6e865cc8
Added MASK_CLICKITEM 2024-02-19 19:59:14 +01:00
smallmodel
1da4113110
Added FuncLadder archive method
This fixes bug where ladder would get unusable after loading from save game (see #211)
2024-02-19 19:36:46 +01:00
smallmodel
7956746b65
Fixed inward sphere argument: the argument should be optional
See #209
2024-02-19 19:34:11 +01:00
smallmodel
10a8d13ade
Added missing variables to archive 2024-02-18 23:27:15 +01:00
smallmodel
65b47a2b3a
Fixed AnimDone never being called
This fixes maps like e1l2 never starting because it waits for an anim to finish
2024-02-18 21:54:18 +01:00
smallmodel
46cc00d669
Set m_fMaxSpeed 2024-02-18 21:53:33 +01:00
smallmodel
5521cf9ab3
Fixed m_fMaxSpeed being always set to 250 2024-02-18 20:10:18 +01:00
smallmodel
a770df1e0b
Fixed path not found spam 2024-02-18 15:47:07 +01:00
smallmodel
03943a23ac
Fixed badplace and run and shoot think never working 2024-02-17 20:10:00 +01:00
smallmodel
685dc0336a
Corrected loop ordering 2024-02-17 00:05:39 +01:00
smallmodel
776012fedf
Health must have a targetname by default in 2.0 and above 2024-02-16 23:52:25 +01:00
smallmodel
6ba9f2655c
Call PostSpawn after constructing the health instance 2024-02-16 23:51:34 +01:00
smallmodel
8a3b62e93f
Fixed targetname error 2024-02-16 23:50:57 +01:00
smallmodel
bd999a6d9c
Fixed Trace's pass_entities parameter (didn't properly ignore entities) 2024-02-15 23:48:23 +01:00
smallmodel
f46078965d
info_null must inherits from Listener instead of Entity
This fixes Level::AllocEdict issues on some maps that use it a lot (like t2l4) #206
2024-02-15 21:15:37 +01:00
smallmodel
60f6bb17e3
Fixed AI parameters not fixing AI parameters 2024-02-15 20:40:55 +01:00
smallmodel
fdf1dac618
Wrong condition for SetDesiredYawDest (should set only if values are non-zero) 2024-02-15 20:23:50 +01:00
smallmodel
373a35acf0
Fixed target trigger being triggered by itself 2024-02-15 20:23:17 +01:00
smallmodel
abfdac59ba
Make aiMaxDeviation only supported on 2.0 and above 2024-02-15 00:21:01 +01:00
smallmodel
efc1354dcb
Fixed entity monitoring always used 2024-02-14 20:58:19 +01:00
smallmodel
c9f2603692
Don't suppress below 2.0 2024-02-14 20:48:11 +01:00
smallmodel
aab24260e2
FriendlyInLineOfFire should return false below 2.0 2024-02-14 20:47:54 +01:00
smallmodel
e450156bf7
Fixed path goal movement 2024-02-14 20:46:43 +01:00
smallmodel
1533c02a41
Fixed cover hide 2024-02-14 20:32:57 +01:00
smallmodel
c4855029a9
Fixed motion facing 2024-02-14 20:32:40 +01:00
smallmodel
4fa457118f
Fixed CanMovePathWithLeash() not returning the correct result 2024-02-14 20:06:35 +01:00
smallmodel
33b403d6eb
Fixed MASK_CANSEE 2024-02-14 19:58:29 +01:00
smallmodel
a5c6654dcb
Fixed m_fMaxDistanceSquared initialization value 2024-02-14 19:22:19 +01:00
smallmodel
07ec6adecb
Fixed ViewJitter never being removed 2024-02-14 18:40:34 +01:00
smallmodel
ceb901e9ca
Fixed disconnected menu not being pushed properly 2024-02-14 18:32:06 +01:00
smallmodel
651b86b066
Added comment for more clarity 2024-02-13 18:23:23 +01:00
smallmodel
a4003dd61c
Only execute anim/suppress.scr if targeting 2.0 and above 2024-02-13 18:16:52 +01:00
smallmodel
5e461786f9
Added a comment about FriendlyInLineOfFire 2024-02-13 18:15:54 +01:00
smallmodel
45108c6f4b
Fixed curious' finished animation global function
This fixes AI being permanently stuck in a curious animation
2024-02-13 17:38:11 +01:00
smallmodel
bc0d373dcd
Fixed AI getting blocked because of an obstacle 2024-02-13 17:37:28 +01:00
smallmodel
0f37a8f6ea
Fixed m_fLeashSquared initialization 2024-02-13 16:42:54 +01:00
smallmodel
03ceaf82ce
Fixed AngleMod() being inaccurate
This caused issues with Actor never finishing turning (because it expected the desired yaw to be at the exact same angle rounded by 0.001)
2024-02-13 16:23:47 +01:00
smallmodel
1e5e5e24f6
Fixed entity monitoring never printing 2024-02-13 16:23:06 +01:00
smallmodel
eb993dbd43
Fixed grenade toss location and wall facing 2024-02-13 16:22:56 +01:00
smallmodel
4f5abb3412
Fixed int conversion when printing the awareness 2024-02-13 16:22:39 +01:00
smallmodel
6418d79d76
Call PostThink() in Think_Alarm() 2024-02-13 16:22:18 +01:00
smallmodel
796a3a711f
Fixed animation delta over time 2024-02-13 01:01:51 +01:00
smallmodel
0ef743d945
Forgot newline 2024-02-13 01:01:39 +01:00
smallmodel
7c33f98ae9
Use m_fFollowRelativeYaw 2024-02-13 00:57:37 +01:00
smallmodel
51ba1e2951
Properly use identity / identitylighting when cgen isn't explicitly specified 2024-02-12 23:47:07 +01:00
smallmodel
0b16d599d5
Added UseCount for image_t 2024-02-12 22:11:15 +01:00
smallmodel
3b2223ad22
image validity check 2024-02-12 22:11:00 +01:00
smallmodel
186583148a
Use proper values for GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T 2024-02-12 22:10:00 +01:00
smallmodel
5475624b7f
Added DDS support + handle compressed textures correctly 2024-02-12 20:19:33 +01:00
smallmodel
d5be69239a
Added GL 1.3 functions 2024-02-12 20:18:52 +01:00
smallmodel
304645d720
Ignore CGEN_BAD stages 2024-02-12 19:50:32 +01:00
smallmodel
0591152f99
Added ifCvar / ifCvarnot support 2024-02-12 17:18:51 +01:00
smallmodel
74e8a38c00
When idle, limit the turret's pitch to the max idle pitch 2024-02-12 16:59:20 +01:00
smallmodel
5cadab46ab
Fixed fence mask being incorrectly specified as transparent rather than opaque 2024-02-12 16:49:27 +01:00
smallmodel
1577927d99
Ignore collision if the brush has a trace content and the trace content wasn't specified in the trace flags 2024-02-12 16:48:58 +01:00
smallmodel
5a0aeb2f88
Fixed last fire time being incorrectly set in the future 2024-02-12 15:12:55 +01:00
smallmodel
7a1f7773bf
Use sin/cos instead of sinf/cosf (accuracy) 2024-02-12 15:05:33 +01:00
smallmodel
b0e597cf55
Fixed vehicle collision orientation 2024-02-12 15:02:55 +01:00
smallmodel
c40d073d7a
Refactored CM_CheckTerrainTriSphere 2024-02-12 14:17:04 +01:00
smallmodel
dd8b3f607a
Fixed terrain tri sphere collision not returning correct results with small objects 2024-02-12 13:36:56 +01:00
smallmodel
5cc599984d
Fixed bullet hit effect for glass 2024-02-12 00:29:52 +01:00
smallmodel
b95b8c4c20
Fixed water bullet effect 2024-02-12 00:17:30 +01:00
smallmodel
3e190ca4b3
Added MASK_SHOT_FLUID (there are so many masks) 2024-02-12 00:02:28 +01:00
smallmodel
3853d1ef39
Properly map the CGM message depending on the protocol version 2024-02-11 23:38:24 +01:00
smallmodel
bf700186d0
Fixed bounce velocity reduction 2024-02-11 23:31:26 +01:00
smallmodel
ca7cacfdcc
Add a debug line when bouncing if enabled (for AI) 2024-02-11 23:27:21 +01:00
smallmodel
b893f4f89f
Properly stop if on ground 2024-02-11 23:20:52 +01:00
smallmodel
109686aca2
Reduce the velocity when bouncing 2024-02-11 23:14:08 +01:00
smallmodel
6840df4eca
backoff value should be 1.4 for bounce and 1.6 for Gib 2024-02-11 23:11:11 +01:00
smallmodel
ed3f212bd8
Also check for slide with bounce movetype 2024-02-11 23:10:21 +01:00
smallmodel
e1f2a51f2b
Only move angles if there is an angular velocity 2024-02-11 23:07:32 +01:00
smallmodel
d3870309fb
Fixed MASK_MONSTERSOLID 2024-02-11 22:56:44 +01:00
smallmodel
1fa2031f11
When a player is inside a vehicle, use the vehicle's health for the health stat 2024-02-08 20:41:33 +01:00
smallmodel
1d765125c7
Fixed facets and planes being badly initialized 2024-02-08 20:35:11 +01:00
smallmodel
5aa70d91f3
Fixed patch subdivisions 2024-02-07 23:44:59 +01:00
smallmodel
f018c2c15a
Ignore shaders for surface starting with the name "material" 2024-02-07 23:36:04 +01:00
smallmodel
1b8ad12b25
Call RefreshMaterial() instead of ReregisterMaterial() 2024-02-07 23:33:12 +01:00
smallmodel
078aa01895
Reimplemented RefreshMaterial() 2024-02-07 23:33:02 +01:00
smallmodel
f0aad4bb21
Don't mark the driver slot as unused by default 2024-02-07 22:51:50 +01:00
smallmodel
8fe054b063
Fixed door open direction 2024-02-06 23:32:33 +01:00
smallmodel
ac63e6c627
Rotate the client when blocked, and make sure the checked's velocity doesn't reach the push move speed 2024-02-06 23:31:48 +01:00
smallmodel
434a48af7d
Initialize m_iNumShotsFired 2024-02-06 22:57:37 +01:00
smallmodel
c5dcf96717
Implemented all RB_Calc functions 2024-02-06 22:54:48 +01:00
smallmodel
84791c42bc
Implemented RB_CalcSunReflectionTexCoords 2024-02-06 22:23:26 +01:00
smallmodel
e032a1a627
Implemented all tcMod values 2024-02-06 22:16:20 +01:00
smallmodel
1f2b5dcc86
Added and fixed all missing tcMod parameters 2024-02-06 20:07:39 +01:00
smallmodel
8bd30ffb22
Added rate tmod variable 2024-02-06 19:59:14 +01:00
smallmodel
fbf67fccc3
Added TMOD enum values from AA 1.11 2024-02-06 19:55:21 +01:00
smallmodel
b848ee0fac
Added rotateStart and rotateCoef for rotate tcMod 2024-02-06 19:48:55 +01:00
smallmodel
4a39e5411f
Fixed patch collision in position test 2024-02-05 23:46:43 +01:00
smallmodel
336ba6181e
Don't allocate planes / facets if there are none 2024-02-05 23:25:41 +01:00
smallmodel
c9aedf242d
Fixed scoreboard sending incorrect data for spectators 2024-02-05 21:03:10 +01:00
smallmodel
500c70016f
Don't crossblend with new weapons 2024-02-05 20:13:23 +01:00
smallmodel
cf1dbf07c7
Corrected MASK_CLICK tracemask (especially for patches surface) 2024-02-04 20:46:05 +01:00
smallmodel
13ec3435b4
Fixed rain num shaders 2024-02-04 19:36:56 +01:00
smallmodel
fce0f7b357
Better rain handlijng 2024-02-04 19:36:34 +01:00
smallmodel
0fabdc8c44
Added current objective index 2024-02-04 19:25:03 +01:00
smallmodel
2174f2ff85
For "delete" and "remove", use Listener::ScriptRemove 2024-02-04 19:09:08 +01:00
smallmodel
ac40373c09
Use RemoveVehicleSoundEntities() to remove sound entities 2024-02-04 19:08:37 +01:00
smallmodel
d5908bd75c
Fixed frag grenade spelling in SP 2024-02-04 16:30:31 +01:00
smallmodel
8cf3be3526
If in thinks, don't delete the object immediately 2024-02-04 16:30:22 +01:00
smallmodel
0290fa3351
Set default animation on the attached model if the tag was not found 2024-02-04 16:30:02 +01:00
smallmodel
937f3993ec
Removed unusable FX in 1.11 and below 2024-02-04 16:10:49 +01:00
smallmodel
d501285057
Play pain animation only in 2.0 and above 2024-02-04 15:47:48 +01:00
smallmodel
0ed92943de
Fixed commands not being executed properly on a specific type of array of listeners 2024-02-03 23:22:06 +01:00
smallmodel
56044dd8f8
HideMouse doesn't take parameters 2024-02-03 23:19:55 +01:00
smallmodel
e8109076f4
Assign shaders to surfaces that don't have a shader assigned 2024-02-03 23:03:41 +01:00
smallmodel
0a31ab7558
Use the correct view model animation for the kar98 mortar 2024-02-03 21:23:59 +01:00
smallmodel
e73be7ef5c
Smoke grenades don't exist in vanilla Allied Assault 2024-02-03 21:19:04 +01:00
smallmodel
aa209e0aaf
Fixed plane distance not being copied correctly with terrain square mode 5 or 6 2024-02-03 21:09:26 +01:00
smallmodel
570dddddd8
Formatted cm_terrain source files 2024-02-03 21:07:49 +01:00
smallmodel
534176423e
Fixed trace error with Vehicle Hit(MV2) 2024-02-02 23:05:55 +01:00
smallmodel
ca2c2fb8fe
Use floating-point operation in CalculateBoxPoints() 2024-02-02 23:05:18 +01:00
smallmodel
4388b7b187
AI_ThinkActive() must be used if the owner is an Actor 2024-02-02 19:26:11 +01:00
smallmodel
368f94ce3b
Fixed spline improperly returning the number of points when appending 2024-02-02 19:23:09 +01:00
smallmodel
e7fd0f7419
Merge pull request #138 from ysdragon/dev
Fixed compilation using Clang 16+
2024-01-31 20:43:30 +01:00
DraGoN
92f7c3633f
Fixed compilation using Clang 16+ 2024-01-30 22:54:13 +00:00
smallmodel
bf27caa61e
Fixed vehicle lacking gravity 2024-01-29 22:55:48 +01:00
smallmodel
808916029e
Formatted scriptthread source file 2024-01-29 00:03:51 +01:00
smallmodel
5f3ee10bc0
Fixed Linux compilation error because of stupid CL accepting anything 2024-01-29 00:01:39 +01:00
smallmodel
45f50cfe25
Fixed array variable being case-sensitive 2024-01-28 23:53:02 +01:00
smallmodel
42c0605abf
Fixed game message printing possible random characters if the string is empty 2024-01-28 23:33:59 +01:00
smallmodel
f83839e01b
Fixed crash with WhatIs command if the entity doesn't have a model 2024-01-28 23:32:43 +01:00
smallmodel
24dbc1ce4e
Use C vectors 2024-01-28 23:29:56 +01:00
smallmodel
d8505eff2b
Fixed label parameters being incorrectly case-sensitive 2024-01-28 23:17:00 +01:00
smallmodel
bca71ade85
Added automatic addition of idle animation when there is none (from 2.30 code) 2024-01-28 23:16:47 +01:00
smallmodel
7518d7b418
Reworked FS_CanonicalFilename 2024-01-28 20:41:17 +01:00
smallmodel
3f8aeac7e6
Exported WriteSkelmodel 2024-01-28 20:27:58 +01:00
smallmodel
c4a9a87929
Added TIKI_AddDefaultIdleAnim 2024-01-28 20:24:17 +01:00
smallmodel
7eca455795
Set the idle skelmodel and increase the number of skels 2024-01-28 20:24:04 +01:00
smallmodel
cb9ac23b23
Added TIKI_AllocAnim 2024-01-28 20:23:05 +01:00
smallmodel
4a66a41f91
Added idle skel and number of skeletons 2024-01-28 20:19:14 +01:00
smallmodel
665c35d089
Added TIKI array max values 2024-01-28 20:18:09 +01:00
smallmodel
0a634c633b
Fixed crash when loading MP3 in OpenAL 2024-01-28 19:41:31 +01:00
smallmodel
eb70b30e7a
Fixed an issue with the lexer (space before thhe dot) 2024-01-28 19:40:32 +01:00
smallmodel
8d188073b4
When pushing a menu, the max motion time must be taken from the head menu 2024-01-27 21:26:37 +01:00
smallmodel
ceea855c6f
Also play Widget motion if there is a fade sequence 2024-01-27 21:26:11 +01:00
smallmodel
9b7f192dce
Corrected marks not working on entities like doors 2024-01-27 21:14:13 +01:00
smallmodel
23a866f6f8
Implemented R_GetInlineModelBounds 2024-01-27 20:53:17 +01:00
smallmodel
946a7a406c
Fixed client not quitting when dedicated is set to 1 2024-01-27 20:45:56 +01:00
smallmodel
e209290073
Fixed cSpline using wrong positions 2024-01-25 21:55:21 +01:00
smallmodel
2c441ee541
Fixed vehicle sound entity using bad sound prefix 2024-01-25 21:55:03 +01:00
smallmodel
dd768ec9ef
Formatted VehicleSoundEntity source files 2024-01-25 21:54:44 +01:00
smallmodel
adaeaea596
Fixed other code that makes the game crash when length is 0 2024-01-25 19:48:34 +01:00
smallmodel
5a44740592
Fixed invalid event name causing crashes 2024-01-24 21:52:22 +01:00
smallmodel
97a0bd90ec
Set default values for sv_invulnerabletime and sv_team_spawn_interval depending on the target protocol 2024-01-24 20:37:43 +01:00
smallmodel
92ee1d9caf
Reset location print after sending it 2024-01-24 20:19:22 +01:00
smallmodel
9ab28dc7da
Fixed objective maps appearing twice 2024-01-23 22:42:27 +01:00
smallmodel
840501c8dd
Fixed waffenss skin name 2024-01-23 00:04:41 +01:00
smallmodel
ef4b79b1f5
Fixed pm_flags being wrong on Allied Assault 2024-01-22 23:53:25 +01:00
smallmodel
b6b35079ef
Fixed crouch height bounding box 2024-01-22 23:53:13 +01:00
smallmodel
b8e8aead93
Fixed issues with multiple consecutive dollars
This fixes the issue with scripts, like `m6l1c` that accidentally use double dollars for targetnames, like `$$player`
2024-01-22 22:20:25 +01:00
smallmodel
dd378db4d0
Avoid the use of fabs() for dot product 2024-01-22 00:08:27 +01:00
smallmodel
cc048f5099
Fixed some sounds being improperly replaced 2024-01-21 23:50:15 +01:00
smallmodel
ac02afaae6
Don't spam the console with OpenAL errors 2024-01-21 23:48:49 +01:00
smallmodel
bff58ae615
Removed trace.startsolid check 2024-01-21 23:30:48 +01:00
smallmodel
748934edcd
Fixed incorrect box in brush testing 2024-01-21 23:30:38 +01:00
smallmodel
d9fb375812
Fixed collision issues due to steps 2024-01-21 20:46:15 +01:00
smallmodel
55582a85ab
Fixed entityNum callback 2024-01-18 20:39:04 +01:00
smallmodel
9255c5259d
Fixed spawnpoint issues 2024-01-18 20:23:41 +01:00
smallmodel
f1e2a45520
Don't crash if the length is 0 2024-01-18 20:05:57 +01:00
smallmodel
cb9e69238c
Initialize buffer to 0 (integer) 2024-01-17 23:15:38 +01:00
smallmodel
56b2971dee
Fixed AL positioning and volume 2024-01-17 20:44:32 +01:00
smallmodel
ad917d96c8
Use roundf() for more clarity 2024-01-17 19:33:07 +01:00
smallmodel
1fd7bd3fa5
Fixed MP3 loading and improperly configured channels 2024-01-16 20:54:41 +01:00
smallmodel
1234bd89c7
Fixed wrong configstring for the soundtrack 2024-01-16 20:54:10 +01:00
smallmodel
187ee87f10
Make sure to initialize new sound system 2024-01-16 20:28:13 +01:00
smallmodel
5ae88b816d
Initialize pSoundAlias to NULL 2024-01-16 20:27:56 +01:00
smallmodel
3418691f88
Added S_NeedFullRestart and S_ReLoad 2024-01-16 20:27:43 +01:00
smallmodel
4e8a51db81
Fixed Wav not loading properly 2024-01-16 20:27:32 +01:00
smallmodel
2629ef17c3
Made snd_codec c++ aware 2024-01-16 20:27:20 +01:00
smallmodel
9b63625c2b
Add snd_codec 2024-01-16 20:27:10 +01:00
smallmodel
970d72cf07
Implemented snd_openal_new.cpp 2024-01-15 23:04:25 +01:00
smallmodel
d88870bc04
Added more exports 2024-01-15 23:04:13 +01:00
smallmodel
9b35e13923
Added qalGetSourceiv / qalGetBufferfv 2024-01-15 23:04:01 +01:00
smallmodel
032eb11cfb
Implemented various methods 2024-01-12 00:04:36 +01:00
smallmodel
9ea7b77231
Added channel flags and loopsound flags 2024-01-12 00:04:20 +01:00
smallmodel
318dc18891
Added MAX_OPENAL_POSITION_CHANNELS 2024-01-10 23:03:03 +01:00
smallmodel
8d327cd0a0
Added more SFX flags and exports 2024-01-10 23:02:30 +01:00
smallmodel
d3de937ee0
Added FS_CorrectCase 2024-01-10 19:45:53 +01:00
smallmodel
3be1673eb9
Added boolean sound DMA variables 2024-01-10 19:32:44 +01:00
smallmodel
13f23ace76
Added macros for more clarity 2024-01-09 23:30:29 +01:00
smallmodel
26c50f15dc
Added s_volume and sfx exports + added load_sfx_info() declaration 2024-01-09 23:28:28 +01:00
smallmodel
46aa58d0cd
Made qal.h C++ aware 2024-01-09 23:28:01 +01:00
smallmodel
aac9dd40de
Add USE_OPENAL=1 definition when USE_SOUND_NEW is defined 2024-01-09 23:27:51 +01:00
smallmodel
71dba1b7dc
Added snd_info.cpp 2024-01-08 23:25:48 +01:00
smallmodel
8b85e4e075
Export number_of_sfx_infos and sfx_infos 2024-01-08 23:25:41 +01:00
smallmodel
028489d673
Implemented snd_mem_new.c 2024-01-08 23:15:12 +01:00
smallmodel
5c4c14a17d
Added SFX flags 2024-01-08 23:15:09 +01:00
smallmodel
2e10a96d11
Crosshair must always be shown in 1.11 and below regardless of the property 2024-01-08 23:05:21 +01:00
smallmodel
09ad42ba47
Fixed players not being able to use while firing, below 2.0 2024-01-08 22:56:26 +01:00
smallmodel
88ccaee5cc
Implemented C++ sound DMA 2024-01-08 20:07:26 +01:00
smallmodel
e936a0b995
Added more declarations 2024-01-08 20:03:25 +01:00
smallmodel
ff5b0b7607
Added snd_mem_new.c 2024-01-08 19:43:47 +01:00
smallmodel
edd2fd5e63
Renamed aarch64 to arm64 2024-01-08 18:37:33 +01:00
804 changed files with 137186 additions and 125027 deletions

39
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,39 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots (OPTIONAL)**
If applicable, add screenshots to help explain your problem.
**Logs**
- Paste the output of the console window in a text file, and attach the text file.
- If applicable (`logfile` set to 2), attach the `qconsole.log` file. On Windows, it can be found in **%APPDATA%\...\qconsole.log** and on Linux, it can be found on the home directory **~/.openmohaa/.../qconsole.log**.
**Version information (please complete the following information):**
- OS: [e.g. `Debian`]
- OS Version [e.g `12`]
- OpenMoHAA Version: [e.g `0.70.0-alpha+0.0b1a20dcf win_msvc64-x86_64-debug`, can be found below **Common Initialization** in the console, or by typing `version`]
**Dump (OPTIONAL)**
You can include a core dump generated by the OS (`.dmp` file). If you compiled OpenMoHAA yourself, also add all output openmohaa binaries (except libopenal and libSDL).
**Additional context (OPTIONAL)**
Add any other context about the problem here.

17
.github/workflows/branches-build.yml vendored Normal file
View file

@ -0,0 +1,17 @@
name: Build branch
on:
push:
branches:
- '**'
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-all:
uses: ./.github/workflows/shared-build.yml
with:
environment: "testing"

View file

@ -1,194 +0,0 @@
name: Build
on:
push:
branches:
- '*'
pull_request:
workflow_call:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: RelWithDebInfo
jobs:
build-platform-linux:
strategy:
matrix:
architecture: [
{name: 'amd64', triple: 'x86_64-linux-gnu'},
{name: 'i686', triple: 'i686-linux-gnu'},
{name: 'aarch64', triple: 'aarch64-linux-gnu'},
{name: 'armhf', triple: 'arm-linux-gnueabihf'}
]
name: "Building for platform linux-${{matrix.architecture.name}}"
runs-on: ubuntu-22.04
steps:
- name: Settings
working-directory: ${{github.workspace}}
run: |
echo "CMAKE_BUILD_PARALLEL_LEVEL=$(($(nproc) * 16))" >> $GITHUB_ENV
# echo "CMAKE_GENERATOR=Ninja" >> $GITHUB_ENV
- name: Install required packages
run: |
sudo apt update && sudo apt install -y flex bison
- name: Install required cross-platform packages (${{ matrix.architecture.triple }})
if: matrix.architecture.name != 'amd64'
run: sudo apt install -y gcc-12-${{ matrix.architecture.triple }} g++-12-${{ matrix.architecture.triple }}
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: sdl2-latest
build-type: Release
cmake-arguments: "-DCMAKE_C_COMPILER=clang
-DCMAKE_CXX_COMPILER=clang++
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }}
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }}"
- uses: actions/checkout@v3
with:
path: 'source'
- name: CMake Settings
run: |
echo "CMAKE_PARAM=--log-level=VERBOSE \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }} \
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }} \
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
- name: Configure CMake
working-directory: ${{github.workspace}}
run: |
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
- name: Build
working-directory: ${{github.workspace}}
run: |
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Test
working-directory: ${{github.workspace}}
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: |
cd "${{github.workspace}}/build"
ctest -C ${{env.BUILD_TYPE}}
- name: Install
working-directory: ${{github.workspace}}
# Install to the directory defined in CMAKE_INSTALL_PREFIX
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
cp '${{steps.sdl.outputs.prefix}}/lib/libSDL2.so' '${{github.workspace}}/install'
- uses: actions/upload-artifact@v3
with:
name: out-linux-${{matrix.architecture.name}}
if-no-files-found: error
path:
${{github.workspace}}/install
build-platform-windows:
strategy:
matrix:
architecture: [
{name: 'x64', config: 'x64' },
{name: 'x86', config: 'Win32' },
{name: 'arm64', config: 'ARM64' }
]
name: "Building for platform windows-${{matrix.architecture.name}}"
runs-on: windows-2022
steps:
- name: Settings
working-directory: ${{github.workspace}}
run: |
echo "CMAKE_BUILD_PARALLEL_LEVEL=$((Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors * 16)" >> $GITHUB_ENV
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: sdl2-latest
build-type: Release
cmake-arguments: "-A ${{ matrix.architecture.config }}"
- name: Install Flex/Bison
working-directory: ${{github.workspace}}
run: |
mkdir thirdparties && cd thirdparties
git clone --depth 1 --single-branch --branch v2.5.25 https://github.com/lexxmark/winflexbison.git
cmake -B winflexbison-build -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/winflexbison-install' ./winflexbison
cmake --build winflexbison-build --config Release --parallel
cmake --install winflexbison-build
- uses: actions/checkout@v3
with:
path: 'source'
- name: CMake Settings
run: |
echo "CMAKE_PARAM=-A ${{ matrix.architecture.config }} `
--log-level=VERBOSE `
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' `
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} `
-DBISON_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_bison.exe' `
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
- name: Configure CMake
working-directory: ${{github.workspace}}
run: |
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
- name: Build
working-directory: ${{github.workspace}}
run: |
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Test
working-directory: ${{github.workspace}}
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: |
cd "${{github.workspace}}/build"
ctest -C ${{env.BUILD_TYPE}}
- name: Install
working-directory: ${{github.workspace}}
# Install to the directory defined in CMAKE_INSTALL_PREFIX
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/install'
- uses: actions/upload-artifact@v3
with:
name: out-windows-${{matrix.architecture.name}}
if-no-files-found: error
path: |
${{github.workspace}}/install
!${{github.workspace}}/install/**/*.pdb
- uses: actions/upload-artifact@v3
with:
name: out-windows-${{matrix.architecture.name}}-pdb
if-no-files-found: error
path: |
${{github.workspace}}/install

View file

@ -20,6 +20,10 @@ on:
schedule: schedule:
- cron: '42 8 * * 1' - cron: '42 8 * * 1'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
analyze: analyze:
name: Analyze name: Analyze
@ -41,7 +45,13 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3 uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@latest
name: Install required packages
with:
packages: libopenal-dev libpulse-dev portaudio19-dev libasound2-dev libjack-dev libpipewire-0.3-dev qtbase5-dev libdbus-1-dev
version: "0.1"
# Setup SDL # Setup SDL
- name: Set up SDL - name: Set up SDL
@ -52,7 +62,7 @@ jobs:
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v3
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@ -66,7 +76,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift). # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
# If this step fails, then you should remove it and run the build manually (see below) # If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v2 uses: github/codeql-action/autobuild@v3
# Command-line programs to run using the OS shell. # Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@ -79,6 +89,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh # ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@v3
with: with:
category: "/language:${{matrix.language}}" category: "/language:${{matrix.language}}"

246
.github/workflows/shared-build-linux.yml vendored Normal file
View file

@ -0,0 +1,246 @@
##########################
#
# Linux
# Ubuntu 22.04
#
# Using this version instead of 24.04 to use a lower GLIBC version (2.34).
# ARM is used for more efficiency, and x64 is used for legacy architectures like PowerPC.
##########################
name: Linux build workflow
on:
workflow_call:
inputs:
environment:
required: true
type: string
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: RelWithDebInfo
RELEASE_STAGE: ${{ vars.RELEASE_STAGE || 'unstable' }}
jobs:
build:
strategy:
matrix:
architecture: [
{name: 'amd64', os: "ubuntu-22.04-arm", package: 'x86-64-linux-gnu', triple: 'x86_64-linux-gnu', arch_option: 'linux-x86_64'},
{name: 'i686', os: "ubuntu-22.04-arm", package: 'i686-linux-gnu', triple: 'i686-linux-gnu', arch_option: 'linux-x86'},
{name: 'arm64', os: "ubuntu-22.04-arm", package: 'aarch64-linux-gnu', triple: 'aarch64-linux-gnu', arch_option: 'linux-aarch64'},
{name: 'armhf', os: "ubuntu-22.04-arm", package: 'arm-linux-gnueabihf', triple: 'arm-linux-gnueabihf', arch_option: 'linux-armv4'},
{name: 'powerpc', os: "ubuntu-22.04", package: 'powerpc-linux-gnu', triple: 'powerpc-linux-gnu', arch_option: 'linux-ppc'},
{name: 'ppc64', os: "ubuntu-22.04", package: 'powerpc64-linux-gnu', triple: 'powerpc64-linux-gnu', arch_option: 'linux-ppc64'},
{name: 'ppc64el', os: "ubuntu-22.04-arm", package: 'powerpc64le-linux-gnu', triple: 'powerpc64le-linux-gnu', arch_option: 'linux-ppc64le'}
]
name: "Building for platform linux-${{matrix.architecture.name}}"
runs-on: ${{ matrix.architecture.os }}
environment: ${{ inputs.environment }}
env:
wolfssl-version: 'v5.7.6-stable'
curl-version: '8_12_1'
openal-soft-branch: '1.24.3'
steps:
###
# Packages
###
- uses: awalsh128/cache-apt-pkgs-action@latest
name: Install required packages
with:
packages: flex bison ninja-build cmake clang libpulse-dev portaudio19-dev libasound2-dev libjack-dev libpipewire-0.3-dev qtbase5-dev libdbus-1-dev
version: "${{ runner.os }}-${{ runner.arch }}-v1"
- name: Settings
working-directory: ${{github.workspace}}
run: |
echo "HOST_TRIPLE=$(gcc -dumpmachine)" >> $GITHUB_ENV
- uses: awalsh128/cache-apt-pkgs-action@latest
name: Install required cross-platform packages (${{ matrix.architecture.package }})
if: env.HOST_TRIPLE != matrix.architecture.triple
with:
packages: gcc-12-${{ matrix.architecture.package }} g++-12-${{ matrix.architecture.package }}
version: "${{ runner.os }}-${{ runner.arch }}-v1"
- name: Settings
working-directory: ${{github.workspace}}
run: |
echo "CMAKE_GENERATOR=Ninja Multi-Config" >> $GITHUB_ENV
echo "CC=clang" >> $GITHUB_ENV
echo "CXX=clang++" >> $GITHUB_ENV
echo "CFLAGS='--target=${{ matrix.architecture.triple }}'" >> $GITHUB_ENV
echo "CXXFLAGS='--target=${{ matrix.architecture.triple }}'" >> $GITHUB_ENV
###
# SDL
###
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: 2-latest
build-type: Release
# Workaround for when changing the runner OS version
cmake-arguments: "-DCACHE_OS_VERSION=Ubuntu_22.04"
###
# OpenAL
###
- name: Cache OpenAL
id: cache-openal-soft
uses: actions/cache@v4
with:
path: 'thirdparties/soft-oal/install'
key: ${{ runner.os }}-${{ matrix.architecture.name }}-openal-soft-${{ env.openal-soft-branch }}-v1
# soft-oal setup
- name: Checkout soft-oal
if: steps.cache-openal-soft.outputs.cache-hit != 'true'
uses: actions/checkout@v4
with:
repository: 'kcat/openal-soft'
path: 'thirdparties/soft-oal'
ref: '${{ env.openal-soft-branch }}'
- name: Configure and install soft-oal
if: steps.cache-openal-soft.outputs.cache-hit != 'true'
working-directory: ${{github.workspace}}/thirdparties/soft-oal
run: |
cmake -B ./build \
-DALSOFT_UTILS=OFF \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install'
cmake --build ./build --config Release --parallel
cmake --install ./build --config Release
###
# WolfSSL
###
- name: Cache WolfSSL
id: cache-wolfssl
uses: actions/cache@v4
with:
path: 'thirdparties/wolfssl/install'
key: ${{ runner.os }}-${{ matrix.architecture.name }}-wolfssl-${{ env.wolfssl-version }}-v1
# WolfSSL setup
- name: Checkout WolfSSL
if: steps.cache-wolfssl.outputs.cache-hit != 'true'
uses: actions/checkout@v4
with:
repository: 'wolfssl/wolfssl'
path: 'thirdparties/wolfssl'
ref: '${{ env.wolfssl-version }}'
# WolfSSL build
- name: Configure and install wolfssl
if: steps.cache-wolfssl.outputs.cache-hit != 'true'
working-directory: ${{github.workspace}}/thirdparties/wolfssl
run: |
cmake -B ./build \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/wolfssl/install' \
-DCMAKE_C_FLAGS="$CFLAGS -fPIC" \
-DCMAKE_CXX_FLAGS="$CFLAGS -fPIC" \
-DBUILD_SHARED_LIBS=OFF -DWOLFSSL_OPENSSLEXTRA=ON -DWOLFSSL_ASM=OFF -DWOLFSSL_EXAMPLES=OFF -DWOLFSSL_CURL=ON
cmake --build ./build --config Release --parallel
cmake --install ./build --config Release
###
# cURL
###
- name: Cache cURL
id: cache-curl
uses: actions/cache@v4
with:
path: 'thirdparties/curl/install'
key: ${{ runner.os }}-${{ matrix.architecture.name }}-curl-${{ env.curl-version }}-v1
# cURL setup
- name: Checkout cURL
if: steps.cache-curl.outputs.cache-hit != 'true'
uses: actions/checkout@v4
with:
repository: 'curl/curl'
path: 'thirdparties/curl'
ref: 'curl-${{ env.curl-version }}'
# cURL build
- name: Configure and install curl
if: steps.cache-curl.outputs.cache-hit != 'true'
working-directory: ${{github.workspace}}/thirdparties/curl
run: |
cmake -B ./build \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/curl/install' \
-DCURL_USE_LIBPSL=OFF \
-DCURL_USE_WOLFSSL=ON \
-DCURL_ZLIB="" \
-DCURL_BROTLI="" \
-DCURL_ZSTD="" \
-DCMAKE_SHARED_LINKER_FLAGS="-lm" \
-DWolfSSL_ROOT='${{github.workspace}}/thirdparties/wolfssl/install'
cmake --build ./build --config Release --parallel
cmake --install ./build --config Release
###
# Project
###
- uses: actions/checkout@v4
with:
path: 'source'
- name: CMake Settings
run: |
echo "CMAKE_PARAM=--log-level=VERBOSE \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' \
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal' \
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/install/include' \
-DCURL_ROOT='${{github.workspace}}/thirdparties/curl/install' \
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} \
-DPRODUCT_VERSION_STAGE='${{ env.RELEASE_STAGE }}'" >> $GITHUB_ENV
- name: Configure CMake
working-directory: ${{github.workspace}}
run: |
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
- name: Build
working-directory: ${{github.workspace}}
run: |
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
- name: Test
working-directory: ${{github.workspace}}
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: |
cd "${{github.workspace}}/build"
ctest -C ${{env.BUILD_TYPE}}
- name: Install
working-directory: ${{github.workspace}}
# Install to the directory defined in CMAKE_INSTALL_PREFIX
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
# Copy libraries
mkdir ${{github.workspace}}/package
cp -l ${{steps.sdl.outputs.prefix}}/lib/libSDL2-2.0.so.0 '${{github.workspace}}/package/'
cp -l ${{github.workspace}}/thirdparties/soft-oal/install/lib/libopenal.so.1 '${{github.workspace}}/package/'
cp -l ${{github.workspace}}/thirdparties/curl/install/lib*/libcurl.so.4 '${{github.workspace}}/package/'
if [ -d ${{github.workspace}}/install/bin ]; then cp -r ${{github.workspace}}/install/bin/openmohaa/. '${{github.workspace}}/package'; fi
if [ -d ${{github.workspace}}/install/lib ]; then cp -r ${{github.workspace}}/install/lib/openmohaa/. '${{github.workspace}}/package'; fi
###
# Artifacts
###
- uses: actions/upload-artifact@v4
with:
name: out-linux-${{matrix.architecture.name}}
if-no-files-found: error
path:
${{github.workspace}}/package

239
.github/workflows/shared-build-macos.yml vendored Normal file
View file

@ -0,0 +1,239 @@
##########################
#
# Apple macOS
# macOS 15
#
# This version is used as the OS, as it's faster than other versions.
##########################
name: MacOS build workflow
on:
workflow_call:
inputs:
environment:
required: true
type: string
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: RelWithDebInfo
RELEASE_STAGE: ${{ vars.RELEASE_STAGE || 'unstable' }}
jobs:
build:
strategy:
matrix:
architecture: [
#{name: 'x86_64', triple: 'x86_64-apple-macos10.8'},
#{name: 'arm64', triple: 'arm64-apple-macos11'}
#{name: 'x86_64', build_name: 'x86_64'},
#{name: 'arm64', build_name: 'arm64'},
# Compile into an universal binary
{name: 'multiarch(arm64-x86_64)', build_name: 'arm64;x86_64' }
]
name: "Building for platform macos-${{matrix.architecture.name}}"
runs-on: "macos-15"
env:
openal-soft-branch: '1.24.3'
wolfssl-version: 'v5.7.6-stable'
curl-version: '8_12_1'
steps:
###
# Packages
###
- name: Install required packages
run: |
brew install git flex bison ninja cmake llvm perl
- name: Settings
working-directory: ${{github.workspace}}
run: |
echo "CMAKE_GENERATOR=Ninja Multi-Config" >> $GITHUB_ENV
echo "CC=clang" >> $GITHUB_ENV
echo "CXX=clang++" >> $GITHUB_ENV
echo "MACOSX_DEPLOYMENT_TARGET=10.15" >> $GITHUB_ENV
###
# SDL
###
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: 2-latest
build-type: Release
cmake-arguments: "-DCMAKE_OSX_ARCHITECTURES='${{ matrix.architecture.build_name }}'
-DCMAKE_VERBOSE_MAKEFILE=on"
###
# OpenAL
###
- name: Cache OpenAL
id: cache-openal-soft
uses: actions/cache@v4
with:
path: 'thirdparties/soft-oal/install'
key: ${{ runner.os }}-${{ matrix.architecture.name }}-openal-soft-${{ env.openal-soft-branch }}-v1
# soft-oal setup
# Use GCC instead of Clang because of missing SSE intrinsics
# It also doesn't enable altivec support on PowerPC by default
- name: Checkout soft-oal
if: steps.cache-openal-soft.outputs.cache-hit != 'true'
uses: actions/checkout@v4
with:
repository: 'kcat/openal-soft'
path: 'thirdparties/soft-oal'
ref: '${{ env.openal-soft-branch }}'
# soft-oal build
- name: Configure and install soft-oal
if: steps.cache-openal-soft.outputs.cache-hit != 'true'
working-directory: ${{github.workspace}}/thirdparties/soft-oal
run: |
cmake -B ./build \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' \
-DCMAKE_OSX_ARCHITECTURES='${{ matrix.architecture.build_name }}' \
-DCMAKE_VERBOSE_MAKEFILE=on
cmake --build ./build --config Release --parallel
cmake --install ./build --config Release
###
# WolfSSL
###
# FIXME: Figure out how to compile WolfSSL cross-architecture
#
# - name: Cache WolfSSL
# id: cache-wolfssl
# uses: actions/cache@v4
# with:
# path: 'thirdparties/wolfssl_install'
# key: ${{ runner.os }}-${{ matrix.architecture.name }}-wolfssl-${{ env.wolfssl-version }}-v1
#
# # WolfSSL setup
# - name: Checkout WolfSSL
# if: steps.cache-wolfssl.outputs.cache-hit != 'true'
# uses: actions/checkout@v4
# with:
# repository: 'wolfssl/wolfssl'
# path: 'thirdparties/wolfssl'
# ref: '${{ env.wolfssl-version }}'
#
# # WolfSSL build
# - name: Configure and install wolfssl
# if: steps.cache-wolfssl.outputs.cache-hit != 'true'
# working-directory: ${{github.workspace}}/thirdparties/wolfssl
# run: |
# cmake -B ./build \
# -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/wolfssl_install' \
# -DCMAKE_OSX_ARCHITECTURES='${{ matrix.architecture.build_name }}' \
# -DBUILD_SHARED_LIBS=OFF -DWOLFSSL_OPENSSLEXTRA=ON -DWOLFSSL_ASM=OFF -DWOLFSSL_EXAMPLES=OFF -DWOLFSSL_CURL=ON
# cmake --build ./build --config Release --parallel
# cmake --install ./build --config Release
###
# cURL
###
- name: Cache cURL
id: cache-curl
uses: actions/cache@v4
with:
path: 'thirdparties/curl/install'
key: ${{ runner.os }}-${{ matrix.architecture.name }}-curl-${{ env.curl-version }}-v1
# cURL setup
- name: Checkout cURL
if: steps.cache-curl.outputs.cache-hit != 'true'
uses: actions/checkout@v4
with:
repository: 'curl/curl'
path: 'thirdparties/curl'
ref: 'curl-${{ env.curl-version }}'
# cURL build
- name: Configure and install curl
if: steps.cache-curl.outputs.cache-hit != 'true'
working-directory: ${{github.workspace}}/thirdparties/curl
run: |
cmake -B ./build \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/curl/install' \
-DCMAKE_OSX_ARCHITECTURES='${{ matrix.architecture.build_name }}' \
-DCURL_USE_LIBPSL=OFF \
-DCURL_USE_WOLFSSL=OFF \
-DCURL_USE_LIBSSH2=OFF \
-DUSE_LIBIDN2=OFF \
-DUSE_NGHTTP2=OFF \
-DCURL_ENABLE_SSL=OFF \
-DCURL_ZLIB="" \
-DCURL_BROTLI="" \
-DCURL_ZSTD="" \
-DWolfSSL_ROOT='${{github.workspace}}/thirdparties/wolfssl_install'
cmake --build ./build --config Release --parallel
cmake --install ./build --config Release
###
# Project
###
- uses: actions/checkout@v4
with:
path: 'source'
- name: CMake Settings
run: |
echo "CMAKE_PARAM=--log-level=VERBOSE \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' \
-DCMAKE_VERBOSE_MAKEFILE=on \
-DCMAKE_OSX_ARCHITECTURES='${{ matrix.architecture.build_name }}' \
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal/install' \
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/install/include/AL' \
-DCURL_ROOT='${{github.workspace}}/thirdparties/curl/install' \
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} \
-DPRODUCT_VERSION_STAGE='${{ env.RELEASE_STAGE }}'" >> $GITHUB_ENV
- name: Configure CMake
working-directory: ${{github.workspace}}
run: |
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
- name: Build
working-directory: ${{github.workspace}}
run: |
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
- name: Test
working-directory: ${{github.workspace}}
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: |
cd "${{github.workspace}}/build"
ctest -C ${{env.BUILD_TYPE}}
- name: Install
working-directory: ${{github.workspace}}
# Install to the directory defined in CMAKE_INSTALL_PREFIX
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
# Create hard-link and copy symbolic links
mkdir ${{github.workspace}}/package
cp -l ${{steps.sdl.outputs.prefix}}/lib/libSDL2-2.0.0.dylib '${{github.workspace}}/package/'
cp -l ${{github.workspace}}/thirdparties/soft-oal/install/lib/libopenal.1.dylib '${{github.workspace}}/package/'
cp -l ${{github.workspace}}/thirdparties/curl/install/lib*/libcurl.4.dylib '${{github.workspace}}/package/'
if [ -d ${{github.workspace}}/install/bin ]; then cp -r ${{github.workspace}}/install/bin/openmohaa/. '${{github.workspace}}/package'; fi
if [ -d ${{github.workspace}}/install/lib ]; then cp -r ${{github.workspace}}/install/lib/openmohaa/. '${{github.workspace}}/package'; fi
###
# Artifacts
###
- uses: actions/upload-artifact@v4
with:
name: out-macos-${{matrix.architecture.name}}
if-no-files-found: error
path:
${{github.workspace}}/package

View file

@ -0,0 +1,259 @@
##########################
#
# Microsoft Windows
# Windows Server 2025
#
##########################
name: Windows build workflow
on:
workflow_call:
inputs:
environment:
required: true
type: string
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: RelWithDebInfo
RELEASE_STAGE: ${{ vars.RELEASE_STAGE || 'unstable' }}
jobs:
build:
strategy:
matrix:
architecture: [
{name: 'x64', os: 'windows-2025', config: 'x64', toolset: 'x64', arch_option: 'VC-WIN64A' },
{name: 'x86', os: 'windows-2025', config: 'Win32', toolset: 'x64_x86', arch_option: 'VC-WIN32' },
{name: 'arm64', os: 'windows-11-arm', config: 'ARM64', toolset: 'x64_arm64', arch_option: 'VC-WIN64-ARM' }
]
name: "Building for platform windows-${{matrix.architecture.name}}"
runs-on: ${{ matrix.architecture.os }}
environment: ${{ inputs.environment }}
env:
flexbison-branch: 'v2.5.25'
wolfssl-version: 'v5.7.6-stable'
curl-version: '8_12_1'
openal-soft-branch: '1.24.3'
steps:
###
# Packages
###
- name: Cache Flex/Bison
id: cache-flexbison
uses: actions/cache@v4
with:
path: 'thirdparties/winflexbison-install'
key: ${{ runner.os }}-${{ matrix.architecture.name }}-flexbison-${{ env.flexbison-branch }}-v1
- name: Install Flex/Bison
if: steps.cache-flexbison.outputs.cache-hit != 'true'
working-directory: ${{github.workspace}}
run: |
mkdir thirdparties && cd thirdparties
git clone --depth 1 --single-branch --branch ${{ env.flexbison-branch }} https://github.com/lexxmark/winflexbison.git
cmake -B winflexbison-build -DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/winflexbison-install' ./winflexbison
cmake --build winflexbison-build --config Release --parallel
cmake --install winflexbison-build --config Release
- name: Settings
working-directory: ${{github.workspace}}
run: |
echo "CMAKE_GENERATOR=Ninja Multi-Config" >> $env:GITHUB_ENV
echo "CC=cl.exe" >> $env:GITHUB_ENV
echo "CXX=cl.exe" >> $env:GITHUB_ENV
pushd "$($env:PROGRAMFILES)\Microsoft Visual Studio\*\*\VC\Auxiliary\Build"
cmd /c "vcvarsall.bat ${{ matrix.architecture.toolset }} & set" | ForEach-Object {
if ($_ -match "=") {
# Split into key=value
$var = $_.split("=", 2);
echo "$($var[0])=$($var[1])" >> $env:GITHUB_ENV
}
}
popd
- name: Cache Required Packages
id: cache-required-packages
uses: actions/cache@v4
with:
path: 'C:\Packages'
key: ${{ runner.os }}-${{ matrix.architecture.name }}-required-packages-v1
- name: Install required packages
if: steps.cache-required-packages.outputs.cache-hit != 'true'
run: |
$DownloadPath="$($env:USERPROFILE)\Downloads"
if ("${{ matrix.architecture.config }}" -ieq "ARM64") {
Invoke-WebRequest "https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-winarm64.zip" -OutFile "$DownloadPath\ninja-win.zip"
} else {
Invoke-WebRequest "https://github.com/ninja-build/ninja/releases/download/v1.12.1/ninja-win.zip" -OutFile "$DownloadPath\ninja-win.zip"
}
Expand-Archive -Path "$DownloadPath\ninja-win.zip" -DestinationPath "C:\Packages\ninja"
Invoke-WebRequest "https://download.qt.io/official_releases/jom/jom.zip" -OutFile "$DownloadPath\jom.zip"
Expand-Archive -Path "$DownloadPath\jom.zip" -DestinationPath "C:\Packages\jom"
- name: Setup required packages path
run: |
$env:PATH += ";C:\Packages\ninja;C:\Packages\jom;"
echo "PATH=$($env:PATH)" >> $env:GITHUB_ENV
###
# SDL
###
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
with:
version: 2-latest
build-type: Release
cmake-arguments: ""
###
# OpenAL
###
- name: Cache OpenAL
id: cache-openal-soft
uses: actions/cache@v4
with:
path: 'thirdparties/soft-oal/install'
key: ${{ runner.os }}-${{ matrix.architecture.name }}-openal-soft-${{ env.openal-soft-branch }}-v1
# soft-oal setup
- name: Checkout soft-oal
if: steps.cache-openal-soft.outputs.cache-hit != 'true'
uses: actions/checkout@v4
with:
repository: 'kcat/openal-soft'
path: 'thirdparties/soft-oal'
ref: '${{ env.openal-soft-branch }}'
# soft-oal build
# Statically link the CRT runtime into OAL as a workaround to prevent crashes
- name: Configure and install soft-oal
if: steps.cache-openal-soft.outputs.cache-hit != 'true'
working-directory: ${{github.workspace}}/thirdparties/soft-oal
run: |
cmake -B ./build `
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' `
-DALSOFT_BUILD_ROUTER=OFF `
-DALSOFT_REQUIRE_WINMM=ON `
-DALSOFT_REQUIRE_DSOUND=ON `
-DALSOFT_REQUIRE_WASAPI=ON `
-DCMAKE_C_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG" `
-DCMAKE_CXX_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG" `
-DCMAKE_C_FLAGS_MINSIZEREL="/MT /O2 /Ob2 /DNDEBUG" `
-DCMAKE_CXX_FLAGS_MINSIZEREL="/MT /O1 /Ob1 /DNDEBUG" `
-DCMAKE_C_FLAGS_RELWITHDEBINFO="/MT /Zi /O2 /Ob1 /DNDEBUG" `
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="/MT /Zi /O2 /Ob1 /DNDEBUG"
cmake --build ./build --config Release --parallel
cmake --install ./build --config Release
# Unfortunately soft-oal produces a binary called OpenAL32 even in 64-bit
if (("x64", "ARM64") -icontains "${{ matrix.architecture.config }}") { Rename-Item -Path '.\install\bin\OpenAL32.dll' -NewName 'OpenAL64.dll' }
###
# cURL
#
# Uses Schannel as SSL backend, native CAs are used
###
- name: Cache cURL
id: cache-curl
uses: actions/cache@v4
with:
path: 'thirdparties/curl/install'
key: ${{ runner.os }}-${{ matrix.architecture.name }}-curl-${{ env.curl-version }}-v1
# cURL setup
- name: Checkout cURL
if: steps.cache-curl.outputs.cache-hit != 'true'
uses: actions/checkout@v4
with:
repository: 'curl/curl'
path: 'thirdparties/curl'
ref: 'curl-${{ env.curl-version }}'
# cURL build
- name: Configure and install curl
if: steps.cache-curl.outputs.cache-hit != 'true'
working-directory: ${{github.workspace}}/thirdparties/curl
run: |
cmake -B ./build `
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/curl/install' `
-DCURL_USE_LIBPSL=OFF `
-DCURL_USE_SCHANNEL=ON
cmake --build ./build --config Release --parallel
cmake --install ./build --config Release
###
# Project
###
- uses: actions/checkout@v4
with:
path: 'source'
- name: CMake Settings
run: |
echo "CMAKE_PARAM= `
--log-level=VERBOSE `
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/install' `
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }} `
-DBISON_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_bison.exe' `
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal' `
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/install/include' `
-DCURL_ROOT='${{github.workspace}}/thirdparties/curl/install' `
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe' `
-DPRODUCT_VERSION_STAGE='${{ env.RELEASE_STAGE }}'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
- name: Configure CMake
working-directory: ${{github.workspace}}
run: |
cmake -B ./build ${{ env.CMAKE_PARAM }} ./source
- name: Build
working-directory: ${{github.workspace}}
run: |
cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
- name: Test
working-directory: ${{github.workspace}}
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: |
cd "${{github.workspace}}/build"
ctest -C ${{env.BUILD_TYPE}}
- name: Install
working-directory: ${{github.workspace}}
# Install to the directory defined in CMAKE_INSTALL_PREFIX
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
New-Item -ItemType Directory '${{github.workspace}}/package'
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/package'
Copy-Item '${{github.workspace}}/thirdparties/soft-oal/install/bin/*.dll' -Destination '${{github.workspace}}/package'
Copy-Item '${{github.workspace}}/thirdparties/curl/install/bin/*.dll' -Destination '${{github.workspace}}/package'
if (Test-Path ${{github.workspace}}/install/bin) { Copy-Item '${{github.workspace}}/install/bin/*' -Include '*.dll','*.exe','*.pdb' -Destination '${{github.workspace}}/package' }
if (Test-Path ${{github.workspace}}/install/lib) { Copy-Item '${{github.workspace}}/install/lib/*' -Include '*.dll','*.exe','*.pdb' -Destination '${{github.workspace}}/package' }
###
# Artifact
###
- uses: actions/upload-artifact@v4
with:
name: out-windows-${{matrix.architecture.name}}
if-no-files-found: error
path: |
${{github.workspace}}/package
!${{github.workspace}}/package/**/*.pdb
- uses: actions/upload-artifact@v4
with:
name: out-windows-${{matrix.architecture.name}}-pdb
if-no-files-found: error
path: |
${{github.workspace}}/package

24
.github/workflows/shared-build.yml vendored Normal file
View file

@ -0,0 +1,24 @@
name: Shared build workflow
on:
workflow_call:
inputs:
environment:
required: true
type: string
jobs:
build-platform-linux:
uses: ./.github/workflows/shared-build-linux.yml
with:
environment: ${{inputs.environment}}
build-platform-windows:
uses: ./.github/workflows/shared-build-windows.yml
with:
environment: ${{inputs.environment}}
build-platform-macos:
uses: ./.github/workflows/shared-build-macos.yml
with:
environment: ${{inputs.environment}}

View file

@ -6,7 +6,7 @@ on:
- "v*.*.*" - "v*.*.*"
env: env:
RELEASE_TYPE: ${{ vars.RELEASE_TYPE || 'test' }} RELEASE_STAGE: ${{ vars.RELEASE_STAGE || 'unstable' }}
RELEASE_IS_PRERELEASE: ${{ vars.RELEASE_IS_PRELEASE }} RELEASE_IS_PRERELEASE: ${{ vars.RELEASE_IS_PRELEASE }}
permissions: permissions:
@ -14,7 +14,9 @@ permissions:
jobs: jobs:
build-all: build-all:
uses: ./.github/workflows/build-cmake.yml uses: ./.github/workflows/shared-build.yml
with:
environment: "release"
deploy_all: deploy_all:
strategy: strategy:
@ -25,36 +27,42 @@ jobs:
target_os: [ target_os: [
'linux-amd64', 'linux-amd64',
'linux-i686', 'linux-i686',
'linux-aarch64', 'linux-arm64',
'linux-armhf', 'linux-armhf',
'linux-powerpc',
'linux-ppc64',
'linux-ppc64el',
'windows-x64', 'windows-x64',
'windows-x86',
'windows-x64-pdb', 'windows-x64-pdb',
'windows-x86',
'windows-x86-pdb', 'windows-x86-pdb',
'windows-arm64', 'windows-arm64',
'windows-arm64-pdb' 'windows-arm64-pdb',
#'macos-x86_64',
#'macos-arm64',
'macos-multiarch(arm64-x86_64)',
] ]
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
environment: release environment: "release"
needs: [build-all] needs: [build-all]
env: env:
RELEASE_NAME: ${{ github.event.repository.name }}-${{github.ref_name}}-${{matrix.target_os}} RELEASE_NAME: ${{ github.event.repository.name }}-${{github.ref_name}}-${{matrix.target_os}}
steps: steps:
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
with: with:
name: 'out-${{matrix.target_os}}' name: 'out-${{matrix.target_os}}'
path: ${{github.workspace}}/${{matrix.target_os}} path: ${{github.workspace}}/${{matrix.target_os}}
- name: Zip - name: Zip
working-directory: ${{github.workspace}}/${{matrix.target_os}} working-directory: '${{github.workspace}}/${{matrix.target_os}}'
run: zip -r ../${{ env.RELEASE_NAME }}.zip ./ run: zip -r "../${{ env.RELEASE_NAME }}.zip" ./
- name: Release - name: Release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v2
with: with:
name: '${{github.ref_name}}-${{env.RELEASE_TYPE}}' name: '${{github.ref_name}}-${{env.RELEASE_STAGE}}'
prerelease: ${{env.RELEASE_IS_PRERELEASE}} prerelease: ${{env.RELEASE_IS_PRERELEASE}}
files: ${{github.workspace}}/${{ env.RELEASE_NAME }}.zip files: ${{github.workspace}}/${{ env.RELEASE_NAME }}.zip

2
.gitignore vendored
View file

@ -5,6 +5,8 @@ Makefile.local
*.swp *.swp
*tags *tags
*~ *~
/.vscode/
/baseq3
# OS X # OS X
#################### ####################

View file

@ -1,36 +1,58 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.12)
project(openmohaa) project(openmohaa)
include(TargetArch.cmake) include(misc/cmake/TargetArch.cmake)
target_architecture(TARGET_ARCH) target_architecture(TARGET_ARCH)
list(LENGTH TARGET_ARCH TARGET_ARCH_COUNT)
set(USE_INTERNAL_LIBS ON)
if(USE_SYSTEM_LIBS)
set(USE_INTERNAL_LIBS OFF)
endif()
option(USE_INTERNAL_JPEG "If set, use bundled libjpeg." ${USE_INTERNAL_LIBS})
option(USE_INTERNAL_MAD "If set, use bundled libmad." ${USE_INTERNAL_LIBS})
option(USE_INTERNAL_ZLIB "If set, use bundled zlib." ${USE_INTERNAL_LIBS})
option(USE_RENDERER_DLOPEN "Whether to compile the renderer as separate pluggable modules" OFF)
option(TARGET_LOCAL_SYSTEM "Indicate that the project will be compiled and installed for the local system" OFF)
if(TARGET_GAME_TYPE) if(TARGET_GAME_TYPE)
message(SEND_ERROR "TARGET_GAME_TYPE is now unsupported, it is now done at runtime.") message(SEND_ERROR "TARGET_GAME_TYPE is now unsupported, it is now done at runtime.")
endif() endif()
set(TARGET_BASE_GAME "./") set(TARGET_BASE_GAME "./")
set(CMAKE_DEBUG_POSTFIX "-dbg") set(CMAKE_DEBUG_POSTFIX "-dbg")
#
# Microsoft compiler specific parameters
#
if(MSVC) if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE) add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
# Treat no return type as error # Treat no return type as error
add_compile_options(/we4715) add_compile_options(/we4715)
endif() endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU") #
# Clang and GCC specific parameters
#
if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Wno-comment) add_compile_options(-Wno-comment)
# Treat no return type as error # Treat no return type as error
add_compile_options(-Werror=return-type) add_compile_options(-Werror=return-type)
endif() endif()
#
# Clang specific parameters
#
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Ignore warnings for code like 'assert("Assert string")' # Ignore warnings for code like 'assert("Assert string")'
add_compile_options(-Wno-pointer-bool-conversion) add_compile_options(-Wno-pointer-bool-conversion)
endif() endif()
#
# GCC specific parameters
#
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# Add this option on gcc to prevent functions from having the STB_GNU_UNIQUE binding # Add this option on gcc to prevent functions from having the STB_GNU_UNIQUE binding
# Otherwise, it would prevent libraries from being unloaded # Otherwise, it would prevent libraries from being unloaded
@ -42,26 +64,40 @@ if(DEBUG_MEMORY)
add_definitions(-D_DEBUG_MEM) add_definitions(-D_DEBUG_MEM)
endif() endif()
IF("${TARGET_ARCH}" STREQUAL "i386") if("${TARGET_ARCH}" STREQUAL "i386")
set(TARGET_ARCH_SUFFIX "x86") set(TARGET_ARCH_SUFFIX "x86")
ELSE() else()
set(TARGET_ARCH_SUFFIX ${TARGET_ARCH}) set(TARGET_ARCH_SUFFIX ${TARGET_ARCH})
ENDIF() endif()
message(STATUS "Architecture detected: ${TARGET_ARCH}, suffix set to ${TARGET_ARCH_SUFFIX}.") message(STATUS "Architecture detected: ${TARGET_ARCH}")
IF(WIN32) if(TARGET_LOCAL_SYSTEM)
add_definitions(-DTARGET_LOCAL_SYSTEM)
# As it targets the local system, no need to know about the architecture used
set(TARGET_BIN_SUFFIX "")
message(STATUS "Binary suffix will not be used as the local system is the target")
elseif(${TARGET_ARCH_COUNT} GREATER 1)
add_definitions(-DTARGET_MULTIPLE_ARCHITECTURES)
set(TARGET_BIN_SUFFIX ".multiarch")
message(STATUS "Multiple architectures were specified, suffix set to 'multiarch'.")
else()
set(TARGET_BIN_SUFFIX ".${TARGET_ARCH}")
message(STATUS "Binary suffix set to '${TARGET_ARCH_SUFFIX}'.")
endif()
if(WIN32)
set(TARGET_PLATFORM_PREFIX "") set(TARGET_PLATFORM_PREFIX "")
message(STATUS "Using Win32 naming convention") message(STATUS "Using Win32 naming convention")
ELSEIF(UNIX) elseif(UNIX)
set(TARGET_PLATFORM_PREFIX "") set(TARGET_PLATFORM_PREFIX "")
message(STATUS "Using Unix naming convention") message(STATUS "Using Unix naming convention")
ELSE() else()
set(TARGET_PLATFORM_PREFIX "") set(TARGET_PLATFORM_PREFIX "")
ENDIF() endif()
IF(CMAKE_BUILD_TYPE MATCHES Debug) if(CMAKE_BUILD_TYPE MATCHES Debug)
add_definitions(-D_DEBUG) add_compile_definitions(_DEBUG)
# NOTE: The following may mess up function importation # NOTE: The following may mess up function importation
#if(UNIX) #if(UNIX)
@ -69,18 +105,60 @@ IF(CMAKE_BUILD_TYPE MATCHES Debug)
# set(CMAKE_ENABLE_EXPORTS ON) # set(CMAKE_ENABLE_EXPORTS ON)
# message(STATUS "Enabling exports on Unix for backtrace") # message(STATUS "Enabling exports on Unix for backtrace")
#endif() #endif()
ENDIF() else()
# Non-debug builds
add_compile_definitions(NDEBUG)
endif()
if(APPLE)
# macOS doesn't search the executable path by default
# so, locate libraries like SDL in the executable path
set(CMAKE_INSTALL_RPATH "@executable_path")
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
if(CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "GNU")
# Set the visibility to hidden on macOS to prevent shared libraries from
# using functions in the executable
# it's ok to hide them because the backtrace on macOS will still print the name of the functions
add_compile_options(-fvisibility=hidden)
endif()
endif()
#
# Setup the installation directory
#
if(WIN32)
# By default, both DLLs and EXEs are in the same directory
set(CMAKE_DEFAULT_INSTALL_RUNTIME_DIR bin)
set(BIN_INSTALL_SUBDIR ".")
set(LIB_INSTALL_SUBDIR ".")
else()
# Unix
set(CMAKE_DEFAULT_INSTALL_RUNTIME_DIR lib${CMAKE_LIB_SUFFIX})
set(BIN_INSTALL_SUBDIR ${CMAKE_PROJECT_NAME})
set(LIB_INSTALL_SUBDIR ${CMAKE_PROJECT_NAME})
endif()
# By default, put both binaries and shared libraries in the same directory
# the game uses internal shared libraries that must be in the same folder as the binaries
set(CMAKE_INSTALL_BINDIR ${CMAKE_DEFAULT_INSTALL_RUNTIME_DIR} CACHE PATH "Binary dir")
set(CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Library dir")
include(GNUInstallDirs)
#
# Common stuff # Common stuff
#
add_subdirectory("code/qcommon") add_subdirectory("code/qcommon")
add_subdirectory("code/gamespy") add_subdirectory("code/gamespy")
#
# Application # Application
#
add_subdirectory("code/sys") add_subdirectory("code/sys")
##
## Server app ## Server app
##
add_subdirectory("code/server") add_subdirectory("code/server")
add_executable(omohaaded "code/null/null_client.c" "code/null/null_input.c" "code/null/null_snddma.c") add_executable(omohaaded "code/null/null_client.c" "code/null/null_input.c" "code/null/null_snddma.c")
@ -91,48 +169,104 @@ target_link_libraries(omohaaded PRIVATE omohserver)
target_link_libraries(omohaaded PRIVATE syslib) target_link_libraries(omohaaded PRIVATE syslib)
target_link_libraries(omohaaded PRIVATE qcommon qcommon_standalone) target_link_libraries(omohaaded PRIVATE qcommon qcommon_standalone)
# Gamespy dependency # Add the gamespy dependency
target_include_directories(omohaaded PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server") target_include_directories(omohaaded PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server")
set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}") set_target_properties(omohaaded PROPERTIES OUTPUT_NAME "omohaaded${TARGET_BIN_SUFFIX}")
set_target_properties(omohaaded PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) set_target_properties(omohaaded PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
INSTALL(TARGETS omohaaded DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR})
if (MSVC) if (MSVC)
target_link_options(omohaaded PRIVATE "/MANIFEST:NO") target_link_options(omohaaded PRIVATE "/MANIFEST:NO")
INSTALL(FILES $<TARGET_PDB_FILE:omohaaded> DESTINATION "./" OPTIONAL) INSTALL(FILES $<TARGET_PDB_FILE:omohaaded> DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR} OPTIONAL)
endif() endif()
INSTALL(TARGETS omohaaded DESTINATION "./")
if (NOT BUILD_NO_CLIENT) if (NOT BUILD_NO_CLIENT)
##
## Client app ## Client app
##
option(NO_MODERN_DMA "Use older sound-system" FALSE)
add_subdirectory("code/renderer")
add_subdirectory("code/sdl")
add_subdirectory("code/client") add_subdirectory("code/client")
add_subdirectory("code/renderercommon")
#include("code/renderergl2/glsl/shaders.cmake") add_subdirectory("code/sdl")
#file(GLOB_RECURSE SOURCES_RENDERER "code/sdl/*.c" "code/renderercommon/*.c" "code/renderergl2/*.c" "code/renderergl2/*.cpp")
#list(FILTER SOURCES_RENDERER EXCLUDE REGEX "code/renderergl2/tr_subs.c")
#list(FILTER SOURCES_RENDERER EXCLUDE REGEX "code/renderergl2/tr_model.c")
add_executable(openmohaa "misc/dummy.c") add_executable(openmohaa "misc/dummy.c")
target_link_libraries(openmohaa PRIVATE syslib) target_link_libraries(openmohaa PRIVATE syslib)
target_link_libraries(openmohaa PRIVATE omohserver) target_link_libraries(openmohaa PRIVATE omohserver)
target_link_libraries(openmohaa PRIVATE omohclient) target_link_libraries(openmohaa PRIVATE omohclient)
target_link_libraries(openmohaa PRIVATE omohrenderer omohsdl) target_link_libraries(openmohaa PRIVATE omohrenderer)
target_link_libraries(openmohaa PRIVATE qcommon qcommon_standalone) target_link_libraries(openmohaa PRIVATE qcommon qcommon_standalone)
### Gamespy dependency # Add the gamespy dependency
target_include_directories(openmohaa PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server" "code/client" "code/uilib" "code/jpeg-8c") target_include_directories(openmohaa PUBLIC "code/qcommon" "code/script" "code/gamespy" "code/server" "code/client" "code/uilib")
set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BASE_SUFFIX}${TARGET_ARCH_SUFFIX}") set_target_properties(openmohaa PROPERTIES OUTPUT_NAME "openmohaa${TARGET_BIN_SUFFIX}")
set_target_properties(openmohaa PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) set_target_properties(openmohaa PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
target_link_libraries(openmohaa PRIVATE jpeg8) if(USE_INTERNAL_JPEG)
target_include_directories(openmohaa PUBLIC "code/jpeg-8c")
target_link_libraries(openmohaa PRIVATE jpeg8)
else()
find_package(JPEG REQUIRED)
target_include_directories(openmohaa PUBLIC ${JPEG_INCLUDE_DIRS})
target_link_libraries(openmohaa PRIVATE ${JPEG_LIBRARIES})
endif()
INSTALL(TARGETS openmohaa DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR})
if (MSVC) if (MSVC)
target_link_options(openmohaa PRIVATE "/MANIFEST:NO") target_link_options(openmohaa PRIVATE "/MANIFEST:NO")
INSTALL(FILES $<TARGET_PDB_FILE:openmohaa> DESTINATION "./" OPTIONAL) INSTALL(FILES $<TARGET_PDB_FILE:openmohaa> DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR} OPTIONAL)
endif() endif()
INSTALL(TARGETS openmohaa DESTINATION "./") if(UNIX AND NOT APPLE)
#
# Desktop entries installation on Unix
#
set(TARGET_ARCH ${TARGET_BIN_SUFFIX})
# Configure the .desktop entries with the arch suffix
configure_file(
misc/linux/org.openmoh.openmohaa.desktop.in
${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaa.desktop
@ONLY
)
configure_file(
misc/linux/org.openmoh.openmohaab.desktop.in
${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaab.desktop
@ONLY
)
configure_file(
misc/linux/org.openmoh.openmohaas.desktop.in
${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaas.desktop
@ONLY
)
# Install .desktop entries
install(FILES ${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaa.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
install(FILES ${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaab.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
install(FILES ${CMAKE_BINARY_DIR}/misc/linux/org.openmoh.openmohaas.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
install(FILES misc/linux/org.openmoh.openmohaa.metainfo.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo)
install(FILES misc/openmohaa.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/symbolic/apps/ RENAME org.openmoh.openmohaa.svg)
endif()
endif()
#
# Launcher
#
add_subdirectory(code/Launcher)
#
# uninstall target
#
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif() endif()

View file

@ -1,48 +1,49 @@
# OpenMoHAA # OpenMoHAA
![Build](https://github.com/openmoh/openmohaa/actions/workflows/build-cmake.yml/badge.svg?branch=main) [![Release](https://img.shields.io/github/v/release/openmoh/openmohaa)](https://github.com/openmoh/openmohaa/releases) [![Downloads](https://img.shields.io/github/downloads/openmoh/openmohaa/total)](https://github.com/openmoh/openmohaa/releases) [![Build](https://github.com/openmoh/openmohaa/actions/workflows/branches-build.yml/badge.svg?branch=main)](https://github.com/openmoh/openmohaa/actions/workflows/branches-build.yml) [![Release](https://img.shields.io/github/v/release/openmoh/openmohaa)](https://github.com/openmoh/openmohaa/releases) [![Downloads](https://img.shields.io/github/downloads/openmoh/openmohaa/total)](https://github.com/openmoh/openmohaa/releases)
![License](https://img.shields.io/github/license/openmoh/openmohaa) ![Commits](https://img.shields.io/github/commit-activity/t/openmoh/openmohaa) ![License](https://img.shields.io/github/license/openmoh/openmohaa) ![Commits](https://img.shields.io/github/commit-activity/t/openmoh/openmohaa)
![Discord](https://img.shields.io/discord/596049712579215361?logo=discord&logoColor=white&color=5865F2) ![Discord](https://img.shields.io/discord/596049712579215361?logo=discord&logoColor=white&color=5865F2)
![logo](misc/openmohaa-text-sm.png)
```
/ _ \ _ __ ___ _ __ | \/ |/ _ \| | | | / \ / \
| | | | '_ \ / _ \ '_ \| |\/| | | | | |_| | / _ \ / _ \
| |_| | |_) | __/ | | | | | | |_| | _ |/ ___ \ / ___ \
\___/| .__/ \___|_| |_|_| |_|\___/|_| |_/_/ \_\/_/ \_\
|_|
```
## Intro ## Intro
The main goal of OpenMoHAA is to ensure the future and continuity of **Medal of Honor: Allied Assault**. It has always been a dream in the community to provide patches and security fixes for the game. Thanks to the ioquake3 project, F.A.K.K SDK and other quality tools, OpenMoHAA has already reached more than half of its goal: to create an open-source version of MoH:AA (based on version 2.40) that is fully compatible with the original game (in terms of protocol, assets, and scripts). The main goal of OpenMoHAA is to ensure the future and continuity of **Medal of Honor: Allied Assault** (including Spearhead and Breakthrough expansions) on all platforms/architectures by providing new patches/features. Thanks to the ioquake3 project and the F.A.K.K SDK, OpenMoHAA has already reached more than half of its goal: an open-source version of MoH:AA (based on version 2.40) that is fully compatible with both the original game and expansions, in terms of network protocol, assets, and scripts. OpenMoHAA is compatible with both MOH:AA servers and clients (Spearhead and Breakthrough included).
## Getting started ## Getting started
- [Installing OpenMoHAA](docs/getting_started_installation.md) - [Downloading and installing OpenMoHAA](docs/getting_started_installation.md)
- [Running OpenMoHAA and using expansion assets](docs/getting_started_running.md) - [Running OpenMoHAA and using expansion assets](docs/getting_started_running.md)
- [Game configuration](docs/configuration.md)
If you encounter any issues, please refer to the [FAQ](docs/faq.md) for possible solutions.
## Current state ## Current state
### Multiplayer
The Multiplayer part is almost fully stable.
Server admins can use OpenMoHAA to [host](docs/getting_started_installation.md#server) a mohaa/mohaas/mohaab server. Bugs must be reported by creating a new [issue](https://github.com/openmoh/openmohaa/issues) on the OpenMoHAA GitHub project. Players can use OpenMoHAA to [play](docs/getting_started_installation.md#client) on a mohaa/mohaas/mohaab server.
All game modes including `Tug-of-War` from Medal of Honor: Spearhead, and `Liberation` from Medal of Honor: Breakthrough are implemented and are working as intended. Mods like `Freeze-Tag` are working as well.
### Single-player ### Single-player
The `training` map can be played from start to end. The single-player campaign is not fully functional, but at least AI can breathe, talk, run, and shoot. The entire single-player campaign should work (Allied Assault, Spearhead and Breakthrough). If you encounter any bug, please create a new [GitHub issue](https://github.com/openmoh/openmohaa/issues) describing them.
### Multiplayer
The Multiplayer part is almost fully stable, all game modes including `Tug-of-War` from Medal of Honor: Spearhead, and `Liberation` from Medal of Honor: Breakthrough are implemented and are working as intended. Mods like `Freeze-Tag` are working as well.
OpenMoHAA can be used to [host](docs/getting_started_installation.md#server) a mohaa/mohaas/mohaab server and players can use OpenMoHAA to [play](docs/getting_started_installation.md#client) on any server. If some bugs/strange behavior occurs, the best way to report them is by [creating a new issue](https://github.com/openmoh/openmohaa/issues) on the [OpenMoHAA GitHub](https://github.com/openmoh/openmohaa) project with the steps to reproduce (with eventually the problematic mods).
One of the big multiplayer features are bots. They were introduced for testing and for entertainment purposes so players can have fun alone. See [Configuring bots](docs/configuration/server.md#bots) in the dedicated server configuration documentation to set them up.
## Features ## Features
- [What's working and what's not](docs/features_implementation.md) - [List of new features](docs/features.md)
- [New features](docs/features.md) - [Scripting](docs/scripting.md)
- [Scripting commands](https://htmlpreview.github.io/?https://github.com/openmoh/openmohaa/blob/main/docs/features_g_allclasses.html)
## Reporting issues
If you encounter a bug, report it by creating a new [issue](https://github.com/openmoh/openmohaa/issues). Make sure to select the `Bug report` template and fill in the appropriate fields.
If you need help or have a problem, you can head over to the [discussions](https://github.com/openmoh/openmohaa/discussions) or join the OpenMoHAA Discord server (the link is at the bottom of this README).
## Compiling ## Compiling

21
cmake_uninstall.cmake.in Normal file
View file

@ -0,0 +1,21 @@
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif()
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
execute_process(
COMMAND "@CMAKE_COMMAND@" -E remove "$ENV{DESTDIR}${file}"
OUTPUT_VARIABLE rm_out
RESULT_VARIABLE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif()
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif()
endforeach()

View file

@ -1,8 +1,40 @@
#ifndef AL_AL_H #ifndef AL_AL_H
#define AL_AL_H #define AL_AL_H
#if defined(__cplusplus) /* NOLINTBEGIN */
#ifdef __cplusplus
extern "C" { extern "C" {
#ifdef _MSVC_LANG
#define AL_CPLUSPLUS _MSVC_LANG
#else
#define AL_CPLUSPLUS __cplusplus
#endif
#ifndef AL_DISABLE_NOEXCEPT
#if AL_CPLUSPLUS >= 201103L
#define AL_API_NOEXCEPT noexcept
#else
#define AL_API_NOEXCEPT
#endif
#if AL_CPLUSPLUS >= 201703L
#define AL_API_NOEXCEPT17 noexcept
#else
#define AL_API_NOEXCEPT17
#endif
#else /* AL_DISABLE_NOEXCEPT */
#define AL_API_NOEXCEPT
#define AL_API_NOEXCEPT17
#endif
#undef AL_CPLUSPLUS
#else /* __cplusplus */
#define AL_API_NOEXCEPT
#define AL_API_NOEXCEPT17
#endif #endif
#ifndef AL_API #ifndef AL_API
@ -15,14 +47,14 @@ extern "C" {
#endif #endif
#endif #endif
#if defined(_WIN32) #ifdef _WIN32
#define AL_APIENTRY __cdecl #define AL_APIENTRY __cdecl
#else #else
#define AL_APIENTRY #define AL_APIENTRY
#endif #endif
/** Deprecated macro. */ /* Deprecated macros. */
#define OPENAL #define OPENAL
#define ALAPI AL_API #define ALAPI AL_API
#define ALAPIENTRY AL_APIENTRY #define ALAPIENTRY AL_APIENTRY
@ -30,7 +62,7 @@ extern "C" {
#define AL_ILLEGAL_ENUM AL_INVALID_ENUM #define AL_ILLEGAL_ENUM AL_INVALID_ENUM
#define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION #define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION
/** Supported AL version. */ /* Supported AL versions. */
#define AL_VERSION_1_0 #define AL_VERSION_1_0
#define AL_VERSION_1_1 #define AL_VERSION_1_1
@ -40,43 +72,43 @@ typedef char ALboolean;
/** character */ /** character */
typedef char ALchar; typedef char ALchar;
/** signed 8-bit 2's complement integer */ /** signed 8-bit integer */
typedef signed char ALbyte; typedef signed char ALbyte;
/** unsigned 8-bit integer */ /** unsigned 8-bit integer */
typedef unsigned char ALubyte; typedef unsigned char ALubyte;
/** signed 16-bit 2's complement integer */ /** signed 16-bit integer */
typedef short ALshort; typedef short ALshort;
/** unsigned 16-bit integer */ /** unsigned 16-bit integer */
typedef unsigned short ALushort; typedef unsigned short ALushort;
/** signed 32-bit 2's complement integer */ /** signed 32-bit integer */
typedef int ALint; typedef int ALint;
/** unsigned 32-bit integer */ /** unsigned 32-bit integer */
typedef unsigned int ALuint; typedef unsigned int ALuint;
/** non-negative 32-bit binary integer size */ /** non-negative 32-bit integer size */
typedef int ALsizei; typedef int ALsizei;
/** enumerated 32-bit value */ /** 32-bit enumeration value */
typedef int ALenum; typedef int ALenum;
/** 32-bit IEEE754 floating-point */ /** 32-bit IEEE-754 floating-point */
typedef float ALfloat; typedef float ALfloat;
/** 64-bit IEEE754 floating-point */ /** 64-bit IEEE-754 floating-point */
typedef double ALdouble; typedef double ALdouble;
/** void type (for opaque pointers only) */ /** void type (opaque pointers only) */
typedef void ALvoid; typedef void ALvoid;
/* Enumerant values begin at column 50. No tabs. */ /* Enumeration values begin at column 50. Do not use tabs. */
/** "no distance model" or "no buffer" */ /** No distance model or no buffer */
#define AL_NONE 0 #define AL_NONE 0
/** Boolean False. */ /** Boolean False. */
@ -89,10 +121,10 @@ typedef void ALvoid;
/** /**
* Relative source. * Relative source.
* Type: ALboolean * Type: ALboolean
* Range: [AL_TRUE, AL_FALSE] * Range: [AL_FALSE, AL_TRUE]
* Default: AL_FALSE * Default: AL_FALSE
* *
* Specifies if the Source has relative coordinates. * Specifies if the source uses relative coordinates.
*/ */
#define AL_SOURCE_RELATIVE 0x202 #define AL_SOURCE_RELATIVE 0x202
@ -103,7 +135,8 @@ typedef void ALvoid;
* Range: [0 - 360] * Range: [0 - 360]
* Default: 360 * Default: 360
* *
* The angle covered by the inner cone, where the source will not attenuate. * The angle covered by the inner cone, the area within which the source will
* not be attenuated by direction.
*/ */
#define AL_CONE_INNER_ANGLE 0x1001 #define AL_CONE_INNER_ANGLE 0x1001
@ -112,8 +145,8 @@ typedef void ALvoid;
* Range: [0 - 360] * Range: [0 - 360]
* Default: 360 * Default: 360
* *
* The angle covered by the outer cone, where the source will be fully * The angle covered by the outer cone, the area outside of which the source
* attenuated. * will be fully attenuated by direction.
*/ */
#define AL_CONE_OUTER_ANGLE 0x1002 #define AL_CONE_OUTER_ANGLE 0x1002
@ -123,7 +156,7 @@ typedef void ALvoid;
* Range: [0.5 - 2.0] * Range: [0.5 - 2.0]
* Default: 1.0 * Default: 1.0
* *
* A multiplier for the frequency (sample rate) of the source's buffer. * A multiplier for the sample rate of the source's buffer.
*/ */
#define AL_PITCH 0x1003 #define AL_PITCH 0x1003
@ -134,12 +167,12 @@ typedef void ALvoid;
* *
* The source or listener location in three dimensional space. * The source or listener location in three dimensional space.
* *
* OpenAL, like OpenGL, uses a right handed coordinate system, where in a * OpenAL uses a right handed coordinate system, like OpenGL, where with a
* frontal default view X (thumb) points right, Y points up (index finger), and * default view, X points right (thumb), Y points up (index finger), and Z
* Z points towards the viewer/camera (middle finger). * points towards the viewer/camera (middle finger).
* *
* To switch from a left handed coordinate system, flip the sign on the Z * To change from or to a left handed coordinate system, negate the Z
* coordinate. * component.
*/ */
#define AL_POSITION 0x1004 #define AL_POSITION 0x1004
@ -148,8 +181,11 @@ typedef void ALvoid;
* Type: ALfloat[3], ALint[3] * Type: ALfloat[3], ALint[3]
* Default: {0, 0, 0} * Default: {0, 0, 0}
* *
* Specifies the current direction in local space. * Specifies the current direction in local space. A zero-length vector
* A zero-length vector specifies an omni-directional source (cone is ignored). * specifies an omni-directional source (cone is ignored).
*
* To change from or to a left handed coordinate system, negate the Z
* component.
*/ */
#define AL_DIRECTION 0x1005 #define AL_DIRECTION 0x1005
@ -158,26 +194,30 @@ typedef void ALvoid;
* Type: ALfloat[3], ALint[3] * Type: ALfloat[3], ALint[3]
* Default: {0, 0, 0} * Default: {0, 0, 0}
* *
* Specifies the current velocity in local space. * Specifies the current velocity, relative to the position.
*
* To change from or to a left handed coordinate system, negate the Z
* component.
*/ */
#define AL_VELOCITY 0x1006 #define AL_VELOCITY 0x1006
/** /**
* Source looping. * Source looping.
* Type: ALboolean * Type: ALboolean
* Range: [AL_TRUE, AL_FALSE] * Range: [AL_FALSE, AL_TRUE]
* Default: AL_FALSE * Default: AL_FALSE
* *
* Specifies whether source is looping. * Specifies whether source playback loops.
*/ */
#define AL_LOOPING 0x1007 #define AL_LOOPING 0x1007
/** /**
* Source buffer. * Source buffer.
* Type: ALuint * Type: ALuint
* Range: any valid Buffer. * Range: any valid Buffer ID
* Default: AL_NONE
* *
* Specifies the buffer to provide sound samples. * Specifies the buffer to provide sound samples for a source.
*/ */
#define AL_BUFFER 0x1009 #define AL_BUFFER 0x1009
@ -186,12 +226,12 @@ typedef void ALvoid;
* Type: ALfloat * Type: ALfloat
* Range: [0.0 - ] * Range: [0.0 - ]
* *
* A value of 1.0 means unattenuated. Each division by 2 equals an attenuation * For sources, an initial linear gain value (before attenuation is applied).
* of about -6dB. Each multiplicaton by 2 equals an amplification of about * For the listener, an output linear gain adjustment.
* +6dB.
* *
* A value of 0.0 is meaningless with respect to a logarithmic scale; it is * A value of 1.0 means unattenuated. Each division by 2 equals an attenuation
* silent. * of about -6dB. Each multiplication by 2 equals an amplification of about
* +6dB.
*/ */
#define AL_GAIN 0x100A #define AL_GAIN 0x100A
@ -200,8 +240,8 @@ typedef void ALvoid;
* Type: ALfloat * Type: ALfloat
* Range: [0.0 - 1.0] * Range: [0.0 - 1.0]
* *
* The minimum gain allowed for a source, after distance and cone attenation is * The minimum gain allowed for a source, after distance and cone attenuation
* applied (if applicable). * are applied (if applicable).
*/ */
#define AL_MIN_GAIN 0x100D #define AL_MIN_GAIN 0x100D
@ -210,31 +250,33 @@ typedef void ALvoid;
* Type: ALfloat * Type: ALfloat
* Range: [0.0 - 1.0] * Range: [0.0 - 1.0]
* *
* The maximum gain allowed for a source, after distance and cone attenation is * The maximum gain allowed for a source, after distance and cone attenuation
* applied (if applicable). * are applied (if applicable).
*/ */
#define AL_MAX_GAIN 0x100E #define AL_MAX_GAIN 0x100E
/** /**
* Listener orientation. * Listener orientation.
* Type: ALfloat[6] * Type: ALfloat[6]
* Default: {0.0, 0.0, -1.0, 0.0, 1.0, 0.0} * Default: {0.0, 0.0, -1.0, 0.0, 1.0, 0.0}
* *
* Effectively two three dimensional vectors. The first vector is the front (or * Effectively two three dimensional vectors. The first vector is the front (or
* "at") and the second is the top (or "up"). * "at") and the second is the top (or "up"). Both vectors are relative to the
* listener position.
* *
* Both vectors are in local space. * To change from or to a left handed coordinate system, negate the Z
* component of both vectors.
*/ */
#define AL_ORIENTATION 0x100F #define AL_ORIENTATION 0x100F
/** /**
* Source state (query only). * Source state (query only).
* Type: ALint * Type: ALenum
* Range: [AL_INITIAL, AL_PLAYING, AL_PAUSED, AL_STOPPED] * Range: [AL_INITIAL, AL_PLAYING, AL_PAUSED, AL_STOPPED]
*/ */
#define AL_SOURCE_STATE 0x1010 #define AL_SOURCE_STATE 0x1010
/** Source state value. */ /* Source state values. */
#define AL_INITIAL 0x1011 #define AL_INITIAL 0x1011
#define AL_PLAYING 0x1012 #define AL_PLAYING 0x1012
#define AL_PAUSED 0x1013 #define AL_PAUSED 0x1013
@ -267,9 +309,9 @@ typedef void ALvoid;
* Range: [0.0 - ] * Range: [0.0 - ]
* Default: 1.0 * Default: 1.0
* *
* The distance in units that no attenuation occurs. * The distance in units that no distance attenuation occurs.
* *
* At 0.0, no distance attenuation ever occurs on non-linear attenuation models. * At 0.0, no distance attenuation occurs with non-linear attenuation models.
*/ */
#define AL_REFERENCE_DISTANCE 0x1020 #define AL_REFERENCE_DISTANCE 0x1020
@ -292,7 +334,7 @@ typedef void ALvoid;
* Default: 0.0 * Default: 0.0
* *
* The gain attenuation applied when the listener is outside of the source's * The gain attenuation applied when the listener is outside of the source's
* outer cone. * outer cone angle.
*/ */
#define AL_CONE_OUTER_GAIN 0x1022 #define AL_CONE_OUTER_GAIN 0x1022
@ -300,7 +342,7 @@ typedef void ALvoid;
* Source maximum distance. * Source maximum distance.
* Type: ALfloat * Type: ALfloat
* Range: [0.0 - ] * Range: [0.0 - ]
* Default: +inf * Default: FLT_MAX
* *
* The distance above which the source is not attenuated any further with a * The distance above which the source is not attenuated any further with a
* clamped distance model, or where attenuation reaches 0.0 gain for linear * clamped distance model, or where attenuation reaches 0.0 gain for linear
@ -308,16 +350,16 @@ typedef void ALvoid;
*/ */
#define AL_MAX_DISTANCE 0x1023 #define AL_MAX_DISTANCE 0x1023
/** Source buffer position, in seconds */ /** Source buffer offset, in seconds */
#define AL_SEC_OFFSET 0x1024 #define AL_SEC_OFFSET 0x1024
/** Source buffer position, in sample frames */ /** Source buffer offset, in sample frames */
#define AL_SAMPLE_OFFSET 0x1025 #define AL_SAMPLE_OFFSET 0x1025
/** Source buffer position, in bytes */ /** Source buffer offset, in bytes */
#define AL_BYTE_OFFSET 0x1026 #define AL_BYTE_OFFSET 0x1026
/** /**
* Source type (query only). * Source type (query only).
* Type: ALint * Type: ALenum
* Range: [AL_STATIC, AL_STREAMING, AL_UNDETERMINED] * Range: [AL_STATIC, AL_STREAMING, AL_UNDETERMINED]
* *
* A Source is Static if a Buffer has been attached using AL_BUFFER. * A Source is Static if a Buffer has been attached using AL_BUFFER.
@ -330,31 +372,30 @@ typedef void ALvoid;
*/ */
#define AL_SOURCE_TYPE 0x1027 #define AL_SOURCE_TYPE 0x1027
/** Source type value. */ /* Source type values. */
#define AL_STATIC 0x1028 #define AL_STATIC 0x1028
#define AL_STREAMING 0x1029 #define AL_STREAMING 0x1029
#define AL_UNDETERMINED 0x1030 #define AL_UNDETERMINED 0x1030
/** Buffer format specifier. */ /** Unsigned 8-bit mono buffer format. */
#define AL_FORMAT_MONO8 0x1100 #define AL_FORMAT_MONO8 0x1100
/** Signed 16-bit mono buffer format. */
#define AL_FORMAT_MONO16 0x1101 #define AL_FORMAT_MONO16 0x1101
/** Unsigned 8-bit stereo buffer format. */
#define AL_FORMAT_STEREO8 0x1102 #define AL_FORMAT_STEREO8 0x1102
/** Signed 16-bit stereo buffer format. */
#define AL_FORMAT_STEREO16 0x1103 #define AL_FORMAT_STEREO16 0x1103
/** Buffer frequency (query only). */ /** Buffer frequency/sample rate (query only). */
#define AL_FREQUENCY 0x2001 #define AL_FREQUENCY 0x2001
/** Buffer bits per sample (query only). */ /** Buffer bits per sample (query only). */
#define AL_BITS 0x2002 #define AL_BITS 0x2002
/** Buffer channel count (query only). */ /** Buffer channel count (query only). */
#define AL_CHANNELS 0x2003 #define AL_CHANNELS 0x2003
/** Buffer data size (query only). */ /** Buffer data size in bytes (query only). */
#define AL_SIZE 0x2004 #define AL_SIZE 0x2004
/** /* Buffer state. Not for public use. */
* Buffer state.
*
* Not for public use.
*/
#define AL_UNUSED 0x2010 #define AL_UNUSED 0x2010
#define AL_PENDING 0x2011 #define AL_PENDING 0x2011
#define AL_PROCESSED 0x2012 #define AL_PROCESSED 0x2012
@ -363,32 +404,31 @@ typedef void ALvoid;
/** No error. */ /** No error. */
#define AL_NO_ERROR 0 #define AL_NO_ERROR 0
/** Invalid name paramater passed to AL call. */ /** Invalid name (ID) passed to an AL call. */
#define AL_INVALID_NAME 0xA001 #define AL_INVALID_NAME 0xA001
/** Invalid enum parameter passed to AL call. */ /** Invalid enumeration passed to AL call. */
#define AL_INVALID_ENUM 0xA002 #define AL_INVALID_ENUM 0xA002
/** Invalid value parameter passed to AL call. */ /** Invalid value passed to AL call. */
#define AL_INVALID_VALUE 0xA003 #define AL_INVALID_VALUE 0xA003
/** Illegal AL call. */ /** Illegal AL call. */
#define AL_INVALID_OPERATION 0xA004 #define AL_INVALID_OPERATION 0xA004
/** Not enough memory. */ /** Not enough memory to execute the AL call. */
#define AL_OUT_OF_MEMORY 0xA005 #define AL_OUT_OF_MEMORY 0xA005
/** Context string: Vendor ID. */ /** Context string: Vendor name. */
#define AL_VENDOR 0xB001 #define AL_VENDOR 0xB001
/** Context string: Version. */ /** Context string: Version. */
#define AL_VERSION 0xB002 #define AL_VERSION 0xB002
/** Context string: Renderer ID. */ /** Context string: Renderer name. */
#define AL_RENDERER 0xB003 #define AL_RENDERER 0xB003
/** Context string: Space-separated extension list. */ /** Context string: Space-separated extension list. */
#define AL_EXTENSIONS 0xB004 #define AL_EXTENSIONS 0xB004
/** /**
* Doppler scale. * Doppler scale.
* Type: ALfloat * Type: ALfloat
@ -398,7 +438,6 @@ typedef void ALvoid;
* Scale for source and listener velocities. * Scale for source and listener velocities.
*/ */
#define AL_DOPPLER_FACTOR 0xC000 #define AL_DOPPLER_FACTOR 0xC000
AL_API void AL_APIENTRY alDopplerFactor(ALfloat value);
/** /**
* Doppler velocity (deprecated). * Doppler velocity (deprecated).
@ -406,7 +445,6 @@ AL_API void AL_APIENTRY alDopplerFactor(ALfloat value);
* A multiplier applied to the Speed of Sound. * A multiplier applied to the Speed of Sound.
*/ */
#define AL_DOPPLER_VELOCITY 0xC001 #define AL_DOPPLER_VELOCITY 0xC001
AL_API void AL_APIENTRY alDopplerVelocity(ALfloat value);
/** /**
* Speed of Sound, in units per second. * Speed of Sound, in units per second.
@ -415,14 +453,13 @@ AL_API void AL_APIENTRY alDopplerVelocity(ALfloat value);
* Default: 343.3 * Default: 343.3
* *
* The speed at which sound waves are assumed to travel, when calculating the * The speed at which sound waves are assumed to travel, when calculating the
* doppler effect. * doppler effect from source and listener velocities.
*/ */
#define AL_SPEED_OF_SOUND 0xC003 #define AL_SPEED_OF_SOUND 0xC003
AL_API void AL_APIENTRY alSpeedOfSound(ALfloat value);
/** /**
* Distance attenuation model. * Distance attenuation model.
* Type: ALint * Type: ALenum
* Range: [AL_NONE, AL_INVERSE_DISTANCE, AL_INVERSE_DISTANCE_CLAMPED, * Range: [AL_NONE, AL_INVERSE_DISTANCE, AL_INVERSE_DISTANCE_CLAMPED,
* AL_LINEAR_DISTANCE, AL_LINEAR_DISTANCE_CLAMPED, * AL_LINEAR_DISTANCE, AL_LINEAR_DISTANCE_CLAMPED,
* AL_EXPONENT_DISTANCE, AL_EXPONENT_DISTANCE_CLAMPED] * AL_EXPONENT_DISTANCE, AL_EXPONENT_DISTANCE_CLAMPED]
@ -439,9 +476,8 @@ AL_API void AL_APIENTRY alSpeedOfSound(ALfloat value);
* distance calculated is clamped between the reference and max distances. * distance calculated is clamped between the reference and max distances.
*/ */
#define AL_DISTANCE_MODEL 0xD000 #define AL_DISTANCE_MODEL 0xD000
AL_API void AL_APIENTRY alDistanceModel(ALenum distanceModel);
/** Distance model value. */ /* Distance model values. */
#define AL_INVERSE_DISTANCE 0xD001 #define AL_INVERSE_DISTANCE 0xD001
#define AL_INVERSE_DISTANCE_CLAMPED 0xD002 #define AL_INVERSE_DISTANCE_CLAMPED 0xD002
#define AL_LINEAR_DISTANCE 0xD003 #define AL_LINEAR_DISTANCE 0xD003
@ -449,208 +485,223 @@ AL_API void AL_APIENTRY alDistanceModel(ALenum distanceModel);
#define AL_EXPONENT_DISTANCE 0xD005 #define AL_EXPONENT_DISTANCE 0xD005
#define AL_EXPONENT_DISTANCE_CLAMPED 0xD006 #define AL_EXPONENT_DISTANCE_CLAMPED 0xD006
/** Renderer State management. */ #ifndef AL_NO_PROTOTYPES
AL_API void AL_APIENTRY alEnable(ALenum capability); /* Renderer State management. */
AL_API void AL_APIENTRY alDisable(ALenum capability); AL_API void AL_APIENTRY alEnable(ALenum capability) AL_API_NOEXCEPT;
AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability); AL_API void AL_APIENTRY alDisable(ALenum capability) AL_API_NOEXCEPT;
AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability) AL_API_NOEXCEPT;
/** State retrieval. */ /* Context state setting. */
AL_API const ALchar* AL_APIENTRY alGetString(ALenum param); AL_API void AL_APIENTRY alDopplerFactor(ALfloat value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetBooleanv(ALenum param, ALboolean *values); AL_API void AL_APIENTRY alDopplerVelocity(ALfloat value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetIntegerv(ALenum param, ALint *values); AL_API void AL_APIENTRY alSpeedOfSound(ALfloat value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetFloatv(ALenum param, ALfloat *values); AL_API void AL_APIENTRY alDistanceModel(ALenum distanceModel) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetDoublev(ALenum param, ALdouble *values);
AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum param); /* Context state retrieval. */
AL_API ALint AL_APIENTRY alGetInteger(ALenum param); AL_API const ALchar* AL_APIENTRY alGetString(ALenum param) AL_API_NOEXCEPT;
AL_API ALfloat AL_APIENTRY alGetFloat(ALenum param); AL_API void AL_APIENTRY alGetBooleanv(ALenum param, ALboolean *values) AL_API_NOEXCEPT;
AL_API ALdouble AL_APIENTRY alGetDouble(ALenum param); AL_API void AL_APIENTRY alGetIntegerv(ALenum param, ALint *values) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetFloatv(ALenum param, ALfloat *values) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetDoublev(ALenum param, ALdouble *values) AL_API_NOEXCEPT;
AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum param) AL_API_NOEXCEPT;
AL_API ALint AL_APIENTRY alGetInteger(ALenum param) AL_API_NOEXCEPT;
AL_API ALfloat AL_APIENTRY alGetFloat(ALenum param) AL_API_NOEXCEPT;
AL_API ALdouble AL_APIENTRY alGetDouble(ALenum param) AL_API_NOEXCEPT;
/** /**
* Error retrieval. * Obtain the first error generated in the AL context since the last call to
* * this function.
* Obtain the first error generated in the AL context since the last check.
*/ */
AL_API ALenum AL_APIENTRY alGetError(void); AL_API ALenum AL_APIENTRY alGetError(void) AL_API_NOEXCEPT;
/** Query for the presence of an extension on the AL context. */
AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extname) AL_API_NOEXCEPT;
/** /**
* Extension support. * Retrieve the address of a function. The returned function may be context-
* * specific.
* Query for the presence of an extension, and obtain any appropriate function
* pointers and enum values.
*/ */
AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extname); AL_API void* AL_APIENTRY alGetProcAddress(const ALchar *fname) AL_API_NOEXCEPT;
AL_API void* AL_APIENTRY alGetProcAddress(const ALchar *fname); /**
AL_API ALenum AL_APIENTRY alGetEnumValue(const ALchar *ename); * Retrieve the value of an enum. The returned value may be context-specific.
*/
AL_API ALenum AL_APIENTRY alGetEnumValue(const ALchar *ename) AL_API_NOEXCEPT;
/** Set Listener parameters */ /* Set listener parameters. */
AL_API void AL_APIENTRY alListenerf(ALenum param, ALfloat value); AL_API void AL_APIENTRY alListenerf(ALenum param, ALfloat value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); AL_API void AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values); AL_API void AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alListeneri(ALenum param, ALint value); AL_API void AL_APIENTRY alListeneri(ALenum param, ALint value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3); AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values); AL_API void AL_APIENTRY alListeneriv(ALenum param, const ALint *values) AL_API_NOEXCEPT;
/** Get Listener parameters */ /* Get listener parameters. */
AL_API void AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value); AL_API void AL_APIENTRY alGetListenerf(ALenum param, ALfloat *value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); AL_API void AL_APIENTRY alGetListener3f(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values); AL_API void AL_APIENTRY alGetListenerfv(ALenum param, ALfloat *values) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetListeneri(ALenum param, ALint *value); AL_API void AL_APIENTRY alGetListeneri(ALenum param, ALint *value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3); AL_API void AL_APIENTRY alGetListener3i(ALenum param, ALint *value1, ALint *value2, ALint *value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint *values); AL_API void AL_APIENTRY alGetListeneriv(ALenum param, ALint *values) AL_API_NOEXCEPT;
/** Create Source objects. */ /** Create source objects. */
AL_API void AL_APIENTRY alGenSources(ALsizei n, ALuint *sources); AL_API void AL_APIENTRY alGenSources(ALsizei n, ALuint *sources) AL_API_NOEXCEPT;
/** Delete Source objects. */ /** Delete source objects. */
AL_API void AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources); AL_API void AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources) AL_API_NOEXCEPT;
/** Verify a handle is a valid Source. */ /** Verify an ID is for a valid source. */
AL_API ALboolean AL_APIENTRY alIsSource(ALuint source); AL_API ALboolean AL_APIENTRY alIsSource(ALuint source) AL_API_NOEXCEPT;
/** Set Source parameters. */ /* Set source parameters. */
AL_API void AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value); AL_API void AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); AL_API void AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat *values); AL_API void AL_APIENTRY alSourcefv(ALuint source, ALenum param, const ALfloat *values) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value); AL_API void AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3); AL_API void AL_APIENTRY alSource3i(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *values); AL_API void AL_APIENTRY alSourceiv(ALuint source, ALenum param, const ALint *values) AL_API_NOEXCEPT;
/** Get Source parameters. */ /* Get source parameters. */
AL_API void AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *value); AL_API void AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); AL_API void AL_APIENTRY alGetSource3f(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *values); AL_API void AL_APIENTRY alGetSourcefv(ALuint source, ALenum param, ALfloat *values) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value); AL_API void AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3); AL_API void AL_APIENTRY alGetSource3i(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values); AL_API void AL_APIENTRY alGetSourceiv(ALuint source, ALenum param, ALint *values) AL_API_NOEXCEPT;
/** Play, replay, or resume (if paused) a list of Sources */ /** Play, restart, or resume a source, setting its state to AL_PLAYING. */
AL_API void AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources); AL_API void AL_APIENTRY alSourcePlay(ALuint source) AL_API_NOEXCEPT;
/** Stop a list of Sources */ /** Stop a source, setting its state to AL_STOPPED if playing or paused. */
AL_API void AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources); AL_API void AL_APIENTRY alSourceStop(ALuint source) AL_API_NOEXCEPT;
/** Rewind a list of Sources */ /** Rewind a source, setting its state to AL_INITIAL. */
AL_API void AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources); AL_API void AL_APIENTRY alSourceRewind(ALuint source) AL_API_NOEXCEPT;
/** Pause a list of Sources */ /** Pause a source, setting its state to AL_PAUSED if playing. */
AL_API void AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources); AL_API void AL_APIENTRY alSourcePause(ALuint source) AL_API_NOEXCEPT;
/** Play, replay, or resume a Source */ /** Play, restart, or resume a list of sources atomically. */
AL_API void AL_APIENTRY alSourcePlay(ALuint source); AL_API void AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) AL_API_NOEXCEPT;
/** Stop a Source */ /** Stop a list of sources atomically. */
AL_API void AL_APIENTRY alSourceStop(ALuint source); AL_API void AL_APIENTRY alSourceStopv(ALsizei n, const ALuint *sources) AL_API_NOEXCEPT;
/** Rewind a Source (set playback postiton to beginning) */ /** Rewind a list of sources atomically. */
AL_API void AL_APIENTRY alSourceRewind(ALuint source); AL_API void AL_APIENTRY alSourceRewindv(ALsizei n, const ALuint *sources) AL_API_NOEXCEPT;
/** Pause a Source */ /** Pause a list of sources atomically. */
AL_API void AL_APIENTRY alSourcePause(ALuint source); AL_API void AL_APIENTRY alSourcePausev(ALsizei n, const ALuint *sources) AL_API_NOEXCEPT;
/** Queue buffers onto a source */ /** Queue buffers onto a source */
AL_API void AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei nb, const ALuint *buffers); AL_API void AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei nb, const ALuint *buffers) AL_API_NOEXCEPT;
/** Unqueue processed buffers from a source */ /** Unqueue processed buffers from a source */
AL_API void AL_APIENTRY alSourceUnqueueBuffers(ALuint source, ALsizei nb, ALuint *buffers); AL_API void AL_APIENTRY alSourceUnqueueBuffers(ALuint source, ALsizei nb, ALuint *buffers) AL_API_NOEXCEPT;
/** Create Buffer objects */ /** Create buffer objects */
AL_API void AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers); AL_API void AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers) AL_API_NOEXCEPT;
/** Delete Buffer objects */ /** Delete buffer objects */
AL_API void AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers); AL_API void AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers) AL_API_NOEXCEPT;
/** Verify a handle is a valid Buffer */ /** Verify an ID is a valid buffer (including the NULL buffer) */
AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer); AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer) AL_API_NOEXCEPT;
/** Specifies the data to be copied into a buffer */ /**
AL_API void AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq); * Copies data into the buffer, interpreting it using the specified format and
* samplerate.
*/
AL_API void AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei samplerate) AL_API_NOEXCEPT;
/** Set Buffer parameters, */ /* Set buffer parameters. */
AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat value); AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *values); AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *values) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value); AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3); AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values); AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values) AL_API_NOEXCEPT;
/** Get Buffer parameters. */ /* Get buffer parameters. */
AL_API void AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *value); AL_API void AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *values); AL_API void AL_APIENTRY alGetBufferfv(ALuint buffer, ALenum param, ALfloat *values) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value); AL_API void AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3); AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values); AL_API void AL_APIENTRY alGetBufferiv(ALuint buffer, ALenum param, ALint *values) AL_API_NOEXCEPT;
#endif /* AL_NO_PROTOTYPES */
/** Pointer-to-function type, useful for dynamically getting AL entry points. */ /* Pointer-to-function types, useful for storing dynamically loaded AL entry
typedef void (AL_APIENTRY *LPALENABLE)(ALenum capability); * points.
typedef void (AL_APIENTRY *LPALDISABLE)(ALenum capability); */
typedef ALboolean (AL_APIENTRY *LPALISENABLED)(ALenum capability); typedef void (AL_APIENTRY *LPALENABLE)(ALenum capability) AL_API_NOEXCEPT17;
typedef const ALchar* (AL_APIENTRY *LPALGETSTRING)(ALenum param); typedef void (AL_APIENTRY *LPALDISABLE)(ALenum capability) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBOOLEANV)(ALenum param, ALboolean *values); typedef ALboolean (AL_APIENTRY *LPALISENABLED)(ALenum capability) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETINTEGERV)(ALenum param, ALint *values); typedef const ALchar* (AL_APIENTRY *LPALGETSTRING)(ALenum param) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETFLOATV)(ALenum param, ALfloat *values); typedef void (AL_APIENTRY *LPALGETBOOLEANV)(ALenum param, ALboolean *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETDOUBLEV)(ALenum param, ALdouble *values); typedef void (AL_APIENTRY *LPALGETINTEGERV)(ALenum param, ALint *values) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALGETBOOLEAN)(ALenum param); typedef void (AL_APIENTRY *LPALGETFLOATV)(ALenum param, ALfloat *values) AL_API_NOEXCEPT17;
typedef ALint (AL_APIENTRY *LPALGETINTEGER)(ALenum param); typedef void (AL_APIENTRY *LPALGETDOUBLEV)(ALenum param, ALdouble *values) AL_API_NOEXCEPT17;
typedef ALfloat (AL_APIENTRY *LPALGETFLOAT)(ALenum param); typedef ALboolean (AL_APIENTRY *LPALGETBOOLEAN)(ALenum param) AL_API_NOEXCEPT17;
typedef ALdouble (AL_APIENTRY *LPALGETDOUBLE)(ALenum param); typedef ALint (AL_APIENTRY *LPALGETINTEGER)(ALenum param) AL_API_NOEXCEPT17;
typedef ALenum (AL_APIENTRY *LPALGETERROR)(void); typedef ALfloat (AL_APIENTRY *LPALGETFLOAT)(ALenum param) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALISEXTENSIONPRESENT)(const ALchar *extname); typedef ALdouble (AL_APIENTRY *LPALGETDOUBLE)(ALenum param) AL_API_NOEXCEPT17;
typedef void* (AL_APIENTRY *LPALGETPROCADDRESS)(const ALchar *fname); typedef ALenum (AL_APIENTRY *LPALGETERROR)(void) AL_API_NOEXCEPT17;
typedef ALenum (AL_APIENTRY *LPALGETENUMVALUE)(const ALchar *ename); typedef ALboolean (AL_APIENTRY *LPALISEXTENSIONPRESENT)(const ALchar *extname) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALLISTENERF)(ALenum param, ALfloat value); typedef void* (AL_APIENTRY *LPALGETPROCADDRESS)(const ALchar *fname) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALLISTENER3F)(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); typedef ALenum (AL_APIENTRY *LPALGETENUMVALUE)(const ALchar *ename) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALLISTENERFV)(ALenum param, const ALfloat *values); typedef void (AL_APIENTRY *LPALLISTENERF)(ALenum param, ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALLISTENERI)(ALenum param, ALint value); typedef void (AL_APIENTRY *LPALLISTENER3F)(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALLISTENER3I)(ALenum param, ALint value1, ALint value2, ALint value3); typedef void (AL_APIENTRY *LPALLISTENERFV)(ALenum param, const ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALLISTENERIV)(ALenum param, const ALint *values); typedef void (AL_APIENTRY *LPALLISTENERI)(ALenum param, ALint value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETLISTENERF)(ALenum param, ALfloat *value); typedef void (AL_APIENTRY *LPALLISTENER3I)(ALenum param, ALint value1, ALint value2, ALint value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETLISTENER3F)(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); typedef void (AL_APIENTRY *LPALLISTENERIV)(ALenum param, const ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETLISTENERFV)(ALenum param, ALfloat *values); typedef void (AL_APIENTRY *LPALGETLISTENERF)(ALenum param, ALfloat *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETLISTENERI)(ALenum param, ALint *value); typedef void (AL_APIENTRY *LPALGETLISTENER3F)(ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETLISTENER3I)(ALenum param, ALint *value1, ALint *value2, ALint *value3); typedef void (AL_APIENTRY *LPALGETLISTENERFV)(ALenum param, ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETLISTENERIV)(ALenum param, ALint *values); typedef void (AL_APIENTRY *LPALGETLISTENERI)(ALenum param, ALint *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGENSOURCES)(ALsizei n, ALuint *sources); typedef void (AL_APIENTRY *LPALGETLISTENER3I)(ALenum param, ALint *value1, ALint *value2, ALint *value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDELETESOURCES)(ALsizei n, const ALuint *sources); typedef void (AL_APIENTRY *LPALGETLISTENERIV)(ALenum param, ALint *values) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALISSOURCE)(ALuint source); typedef void (AL_APIENTRY *LPALGENSOURCES)(ALsizei n, ALuint *sources) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEF)(ALuint source, ALenum param, ALfloat value); typedef void (AL_APIENTRY *LPALDELETESOURCES)(ALsizei n, const ALuint *sources) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCE3F)(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); typedef ALboolean (AL_APIENTRY *LPALISSOURCE)(ALuint source) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEFV)(ALuint source, ALenum param, const ALfloat *values); typedef void (AL_APIENTRY *LPALSOURCEF)(ALuint source, ALenum param, ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEI)(ALuint source, ALenum param, ALint value); typedef void (AL_APIENTRY *LPALSOURCE3F)(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCE3I)(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3); typedef void (AL_APIENTRY *LPALSOURCEFV)(ALuint source, ALenum param, const ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEIV)(ALuint source, ALenum param, const ALint *values); typedef void (AL_APIENTRY *LPALSOURCEI)(ALuint source, ALenum param, ALint value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCEF)(ALuint source, ALenum param, ALfloat *value); typedef void (AL_APIENTRY *LPALSOURCE3I)(ALuint source, ALenum param, ALint value1, ALint value2, ALint value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCE3F)(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); typedef void (AL_APIENTRY *LPALSOURCEIV)(ALuint source, ALenum param, const ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCEFV)(ALuint source, ALenum param, ALfloat *values); typedef void (AL_APIENTRY *LPALGETSOURCEF)(ALuint source, ALenum param, ALfloat *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCEI)(ALuint source, ALenum param, ALint *value); typedef void (AL_APIENTRY *LPALGETSOURCE3F)(ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCE3I)(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3); typedef void (AL_APIENTRY *LPALGETSOURCEFV)(ALuint source, ALenum param, ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCEIV)(ALuint source, ALenum param, ALint *values); typedef void (AL_APIENTRY *LPALGETSOURCEI)(ALuint source, ALenum param, ALint *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEPLAYV)(ALsizei n, const ALuint *sources); typedef void (AL_APIENTRY *LPALGETSOURCE3I)(ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCESTOPV)(ALsizei n, const ALuint *sources); typedef void (AL_APIENTRY *LPALGETSOURCEIV)(ALuint source, ALenum param, ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEREWINDV)(ALsizei n, const ALuint *sources); typedef void (AL_APIENTRY *LPALSOURCEPLAYV)(ALsizei n, const ALuint *sources) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEPAUSEV)(ALsizei n, const ALuint *sources); typedef void (AL_APIENTRY *LPALSOURCESTOPV)(ALsizei n, const ALuint *sources) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEPLAY)(ALuint source); typedef void (AL_APIENTRY *LPALSOURCEREWINDV)(ALsizei n, const ALuint *sources) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCESTOP)(ALuint source); typedef void (AL_APIENTRY *LPALSOURCEPAUSEV)(ALsizei n, const ALuint *sources) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEREWIND)(ALuint source); typedef void (AL_APIENTRY *LPALSOURCEPLAY)(ALuint source) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEPAUSE)(ALuint source); typedef void (AL_APIENTRY *LPALSOURCESTOP)(ALuint source) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint source, ALsizei nb, const ALuint *buffers); typedef void (AL_APIENTRY *LPALSOURCEREWIND)(ALuint source) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint source, ALsizei nb, ALuint *buffers); typedef void (AL_APIENTRY *LPALSOURCEPAUSE)(ALuint source) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGENBUFFERS)(ALsizei n, ALuint *buffers); typedef void (AL_APIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint source, ALsizei nb, const ALuint *buffers) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDELETEBUFFERS)(ALsizei n, const ALuint *buffers); typedef void (AL_APIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint source, ALsizei nb, ALuint *buffers) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALISBUFFER)(ALuint buffer); typedef void (AL_APIENTRY *LPALGENBUFFERS)(ALsizei n, ALuint *buffers) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFERDATA)(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq); typedef void (AL_APIENTRY *LPALDELETEBUFFERS)(ALsizei n, const ALuint *buffers) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFERF)(ALuint buffer, ALenum param, ALfloat value); typedef ALboolean (AL_APIENTRY *LPALISBUFFER)(ALuint buffer) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFER3F)(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3); typedef void (AL_APIENTRY *LPALBUFFERDATA)(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei samplerate) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFERFV)(ALuint buffer, ALenum param, const ALfloat *values); typedef void (AL_APIENTRY *LPALBUFFERF)(ALuint buffer, ALenum param, ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFERI)(ALuint buffer, ALenum param, ALint value); typedef void (AL_APIENTRY *LPALBUFFER3F)(ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFER3I)(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3); typedef void (AL_APIENTRY *LPALBUFFERFV)(ALuint buffer, ALenum param, const ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFERIV)(ALuint buffer, ALenum param, const ALint *values); typedef void (AL_APIENTRY *LPALBUFFERI)(ALuint buffer, ALenum param, ALint value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFERF)(ALuint buffer, ALenum param, ALfloat *value); typedef void (AL_APIENTRY *LPALBUFFER3I)(ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFER3F)(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3); typedef void (AL_APIENTRY *LPALBUFFERIV)(ALuint buffer, ALenum param, const ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFERFV)(ALuint buffer, ALenum param, ALfloat *values); typedef void (AL_APIENTRY *LPALGETBUFFERF)(ALuint buffer, ALenum param, ALfloat *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFERI)(ALuint buffer, ALenum param, ALint *value); typedef void (AL_APIENTRY *LPALGETBUFFER3F)(ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFER3I)(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3); typedef void (AL_APIENTRY *LPALGETBUFFERFV)(ALuint buffer, ALenum param, ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFERIV)(ALuint buffer, ALenum param, ALint *values); typedef void (AL_APIENTRY *LPALGETBUFFERI)(ALuint buffer, ALenum param, ALint *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDOPPLERFACTOR)(ALfloat value); typedef void (AL_APIENTRY *LPALGETBUFFER3I)(ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDOPPLERVELOCITY)(ALfloat value); typedef void (AL_APIENTRY *LPALGETBUFFERIV)(ALuint buffer, ALenum param, ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSPEEDOFSOUND)(ALfloat value); typedef void (AL_APIENTRY *LPALDOPPLERFACTOR)(ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDISTANCEMODEL)(ALenum distanceModel); typedef void (AL_APIENTRY *LPALDOPPLERVELOCITY)(ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSPEEDOFSOUND)(ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDISTANCEMODEL)(ALenum distanceModel) AL_API_NOEXCEPT17;
#if defined(__cplusplus) #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif
/* NOLINTEND */
#endif /* AL_AL_H */ #endif /* AL_AL_H */

View file

@ -1,8 +1,40 @@
#ifndef AL_ALC_H #ifndef AL_ALC_H
#define AL_ALC_H #define AL_ALC_H
#if defined(__cplusplus) /* NOLINTBEGIN */
#ifdef __cplusplus
extern "C" { extern "C" {
#ifdef _MSVC_LANG
#define ALC_CPLUSPLUS _MSVC_LANG
#else
#define ALC_CPLUSPLUS __cplusplus
#endif
#ifndef AL_DISABLE_NOEXCEPT
#if ALC_CPLUSPLUS >= 201103L
#define ALC_API_NOEXCEPT noexcept
#else
#define ALC_API_NOEXCEPT
#endif
#if ALC_CPLUSPLUS >= 201703L
#define ALC_API_NOEXCEPT17 noexcept
#else
#define ALC_API_NOEXCEPT17
#endif
#else /* AL_DISABLE_NOEXCEPT */
#define ALC_API_NOEXCEPT
#define ALC_API_NOEXCEPT17
#endif
#undef ALC_CPLUSPLUS
#else /* __cplusplus */
#define ALC_API_NOEXCEPT
#define ALC_API_NOEXCEPT17
#endif #endif
#ifndef ALC_API #ifndef ALC_API
@ -15,14 +47,14 @@ extern "C" {
#endif #endif
#endif #endif
#if defined(_WIN32) #ifdef _WIN32
#define ALC_APIENTRY __cdecl #define ALC_APIENTRY __cdecl
#else #else
#define ALC_APIENTRY #define ALC_APIENTRY
#endif #endif
/** Deprecated macro. */ /* Deprecated macros. */
#define ALCAPI ALC_API #define ALCAPI ALC_API
#define ALCAPIENTRY ALC_APIENTRY #define ALCAPIENTRY ALC_APIENTRY
#define ALC_INVALID 0 #define ALC_INVALID 0
@ -31,9 +63,9 @@ extern "C" {
#define ALC_VERSION_0_1 1 #define ALC_VERSION_0_1 1
/** Opaque device handle */ /** Opaque device handle */
typedef struct ALCdevice_struct ALCdevice; typedef struct ALCdevice ALCdevice;
/** Opaque context handle */ /** Opaque context handle */
typedef struct ALCcontext_struct ALCcontext; typedef struct ALCcontext ALCcontext;
/** 8-bit boolean */ /** 8-bit boolean */
typedef char ALCboolean; typedef char ALCboolean;
@ -41,41 +73,41 @@ typedef char ALCboolean;
/** character */ /** character */
typedef char ALCchar; typedef char ALCchar;
/** signed 8-bit 2's complement integer */ /** signed 8-bit integer */
typedef signed char ALCbyte; typedef signed char ALCbyte;
/** unsigned 8-bit integer */ /** unsigned 8-bit integer */
typedef unsigned char ALCubyte; typedef unsigned char ALCubyte;
/** signed 16-bit 2's complement integer */ /** signed 16-bit integer */
typedef short ALCshort; typedef short ALCshort;
/** unsigned 16-bit integer */ /** unsigned 16-bit integer */
typedef unsigned short ALCushort; typedef unsigned short ALCushort;
/** signed 32-bit 2's complement integer */ /** signed 32-bit integer */
typedef int ALCint; typedef int ALCint;
/** unsigned 32-bit integer */ /** unsigned 32-bit integer */
typedef unsigned int ALCuint; typedef unsigned int ALCuint;
/** non-negative 32-bit binary integer size */ /** non-negative 32-bit integer size */
typedef int ALCsizei; typedef int ALCsizei;
/** enumerated 32-bit value */ /** 32-bit enumeration value */
typedef int ALCenum; typedef int ALCenum;
/** 32-bit IEEE754 floating-point */ /** 32-bit IEEE-754 floating-point */
typedef float ALCfloat; typedef float ALCfloat;
/** 64-bit IEEE754 floating-point */ /** 64-bit IEEE-754 floating-point */
typedef double ALCdouble; typedef double ALCdouble;
/** void type (for opaque pointers only) */ /** void type (for opaque pointers only) */
typedef void ALCvoid; typedef void ALCvoid;
/* Enumerant values begin at column 50. No tabs. */ /* Enumeration values begin at column 50. Do not use tabs. */
/** Boolean False. */ /** Boolean False. */
#define ALC_FALSE 0 #define ALC_FALSE 0
@ -89,7 +121,7 @@ typedef void ALCvoid;
/** Context attribute: <int> Hz. */ /** Context attribute: <int> Hz. */
#define ALC_REFRESH 0x1008 #define ALC_REFRESH 0x1008
/** Context attribute: AL_TRUE or AL_FALSE. */ /** Context attribute: AL_TRUE or AL_FALSE synchronous context? */
#define ALC_SYNC 0x1009 #define ALC_SYNC 0x1009
/** Context attribute: <int> requested Mono (3D) Sources. */ /** Context attribute: <int> requested Mono (3D) Sources. */
@ -107,30 +139,32 @@ typedef void ALCvoid;
/** Invalid context handle. */ /** Invalid context handle. */
#define ALC_INVALID_CONTEXT 0xA002 #define ALC_INVALID_CONTEXT 0xA002
/** Invalid enum parameter passed to an ALC call. */ /** Invalid enumeration passed to an ALC call. */
#define ALC_INVALID_ENUM 0xA003 #define ALC_INVALID_ENUM 0xA003
/** Invalid value parameter passed to an ALC call. */ /** Invalid value passed to an ALC call. */
#define ALC_INVALID_VALUE 0xA004 #define ALC_INVALID_VALUE 0xA004
/** Out of memory. */ /** Out of memory. */
#define ALC_OUT_OF_MEMORY 0xA005 #define ALC_OUT_OF_MEMORY 0xA005
/** Runtime ALC version. */ /** Runtime ALC major version. */
#define ALC_MAJOR_VERSION 0x1000 #define ALC_MAJOR_VERSION 0x1000
/** Runtime ALC minor version. */
#define ALC_MINOR_VERSION 0x1001 #define ALC_MINOR_VERSION 0x1001
/** Context attribute list properties. */ /** Context attribute list size. */
#define ALC_ATTRIBUTES_SIZE 0x1002 #define ALC_ATTRIBUTES_SIZE 0x1002
/** Context attribute list properties. */
#define ALC_ALL_ATTRIBUTES 0x1003 #define ALC_ALL_ATTRIBUTES 0x1003
/** String for the default device specifier. */ /** String for the default device specifier. */
#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004 #define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
/** /**
* String for the given device's specifier. * Device specifier string.
* *
* If device handle is NULL, it is instead a null-char separated list of * If device handle is NULL, it is instead a null-character separated list of
* strings of known device specifiers (list ends with an empty string). * strings of known device specifiers (list ends with an empty string).
*/ */
#define ALC_DEVICE_SPECIFIER 0x1005 #define ALC_DEVICE_SPECIFIER 0x1005
@ -141,9 +175,9 @@ typedef void ALCvoid;
/** Capture extension */ /** Capture extension */
#define ALC_EXT_CAPTURE 1 #define ALC_EXT_CAPTURE 1
/** /**
* String for the given capture device's specifier. * Capture device specifier string.
* *
* If device handle is NULL, it is instead a null-char separated list of * If device handle is NULL, it is instead a null-character separated list of
* strings of known capture device specifiers (list ends with an empty string). * strings of known capture device specifiers (list ends with an empty string).
*/ */
#define ALC_CAPTURE_DEVICE_SPECIFIER 0x310 #define ALC_CAPTURE_DEVICE_SPECIFIER 0x310
@ -158,80 +192,116 @@ typedef void ALCvoid;
/** String for the default extended device specifier. */ /** String for the default extended device specifier. */
#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012 #define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
/** /**
* String for the given extended device's specifier. * Device's extended specifier string.
* *
* If device handle is NULL, it is instead a null-char separated list of * If device handle is NULL, it is instead a null-character separated list of
* strings of known extended device specifiers (list ends with an empty string). * strings of known extended device specifiers (list ends with an empty string).
*/ */
#define ALC_ALL_DEVICES_SPECIFIER 0x1013 #define ALC_ALL_DEVICES_SPECIFIER 0x1013
/** Context management. */ #ifndef ALC_NO_PROTOTYPES
ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint* attrlist); /* Context management. */
ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context);
ALC_API void ALC_APIENTRY alcProcessContext(ALCcontext *context);
ALC_API void ALC_APIENTRY alcSuspendContext(ALCcontext *context);
ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context);
ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void);
ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *context);
/** Device management. */ /** Create and attach a context to the given device. */
ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename); ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrlist) ALC_API_NOEXCEPT;
ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device); /**
* Makes the given context the active process-wide context. Passing NULL clears
* the active context.
*/
ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context) ALC_API_NOEXCEPT;
/** Resumes processing updates for the given context. */
ALC_API void ALC_APIENTRY alcProcessContext(ALCcontext *context) ALC_API_NOEXCEPT;
/** Suspends updates for the given context. */
ALC_API void ALC_APIENTRY alcSuspendContext(ALCcontext *context) ALC_API_NOEXCEPT;
/** Remove a context from its device and destroys it. */
ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context) ALC_API_NOEXCEPT;
/** Returns the currently active context. */
ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void) ALC_API_NOEXCEPT;
/** Returns the device that a particular context is attached to. */
ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *context) ALC_API_NOEXCEPT;
/* Device management. */
/** Opens the named playback device. */
ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename) ALC_API_NOEXCEPT;
/** Closes the given playback device. */
ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device) ALC_API_NOEXCEPT;
/* Error support. */
/** Obtain the most recent Device error. */
ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device) ALC_API_NOEXCEPT;
/* Extension support. */
/** /**
* Error support. * Query for the presence of an extension on the device. Pass a NULL device to
* * query a device-inspecific extension.
* Obtain the most recent Device error.
*/ */
ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device); ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extname) ALC_API_NOEXCEPT;
/**
* Retrieve the address of a function. Given a non-NULL device, the returned
* function may be device-specific.
*/
ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcname) ALC_API_NOEXCEPT;
/**
* Retrieve the value of an enum. Given a non-NULL device, the returned value
* may be device-specific.
*/
ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumname) ALC_API_NOEXCEPT;
/* Query functions. */
/** Returns information about the device, and error strings. */
ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum param) ALC_API_NOEXCEPT;
/** Returns information about the device and the version of OpenAL. */
ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values) ALC_API_NOEXCEPT;
/* Capture functions. */
/** /**
* Extension support. * Opens the named capture device with the given frequency, format, and buffer
* * size.
* Query for the presence of an extension, and obtain any appropriate
* function pointers and enum values.
*/ */
ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extname); ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize) ALC_API_NOEXCEPT;
ALC_API void* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcname); /** Closes the given capture device. */
ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumname); ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device) ALC_API_NOEXCEPT;
/** Starts capturing samples into the device buffer. */
ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device) ALC_API_NOEXCEPT;
/** Stops capturing samples. Samples in the device buffer remain available. */
ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device) ALC_API_NOEXCEPT;
/** Reads samples from the device buffer. */
ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples) ALC_API_NOEXCEPT;
#endif /* ALC_NO_PROTOTYPES */
/** Query function. */ /* Pointer-to-function types, useful for storing dynamically loaded ALC entry
ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum param); * points.
ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values); */
typedef ALCcontext* (ALC_APIENTRY *LPALCCREATECONTEXT)(ALCdevice *device, const ALCint *attrlist) ALC_API_NOEXCEPT17;
typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)(ALCcontext *context) ALC_API_NOEXCEPT17;
typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)(ALCcontext *context) ALC_API_NOEXCEPT17;
typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)(ALCcontext *context) ALC_API_NOEXCEPT17;
typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)(ALCcontext *context) ALC_API_NOEXCEPT17;
typedef ALCcontext* (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)(void) ALC_API_NOEXCEPT17;
typedef ALCdevice* (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)(ALCcontext *context) ALC_API_NOEXCEPT17;
typedef ALCdevice* (ALC_APIENTRY *LPALCOPENDEVICE)(const ALCchar *devicename) ALC_API_NOEXCEPT17;
typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)(ALCdevice *device) ALC_API_NOEXCEPT17;
typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)(ALCdevice *device) ALC_API_NOEXCEPT17;
typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)(ALCdevice *device, const ALCchar *extname) ALC_API_NOEXCEPT17;
typedef ALCvoid* (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname) ALC_API_NOEXCEPT17;
typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname) ALC_API_NOEXCEPT17;
typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)(ALCdevice *device, ALCenum param) ALC_API_NOEXCEPT17;
typedef void (ALC_APIENTRY *LPALCGETINTEGERV)(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values) ALC_API_NOEXCEPT17;
typedef ALCdevice* (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize) ALC_API_NOEXCEPT17;
typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)(ALCdevice *device) ALC_API_NOEXCEPT17;
typedef void (ALC_APIENTRY *LPALCCAPTURESTART)(ALCdevice *device) ALC_API_NOEXCEPT17;
typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)(ALCdevice *device) ALC_API_NOEXCEPT17;
typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)(ALCdevice *device, ALCvoid *buffer, ALCsizei samples) ALC_API_NOEXCEPT17;
/** Capture function. */ #ifdef __cplusplus
ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize); } /* extern "C" */
ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device);
ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device);
ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device);
ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
/** Pointer-to-function type, useful for dynamically getting ALC entry points. */
typedef ALCcontext* (ALC_APIENTRY *LPALCCREATECONTEXT)(ALCdevice *device, const ALCint *attrlist);
typedef ALCboolean (ALC_APIENTRY *LPALCMAKECONTEXTCURRENT)(ALCcontext *context);
typedef void (ALC_APIENTRY *LPALCPROCESSCONTEXT)(ALCcontext *context);
typedef void (ALC_APIENTRY *LPALCSUSPENDCONTEXT)(ALCcontext *context);
typedef void (ALC_APIENTRY *LPALCDESTROYCONTEXT)(ALCcontext *context);
typedef ALCcontext* (ALC_APIENTRY *LPALCGETCURRENTCONTEXT)(void);
typedef ALCdevice* (ALC_APIENTRY *LPALCGETCONTEXTSDEVICE)(ALCcontext *context);
typedef ALCdevice* (ALC_APIENTRY *LPALCOPENDEVICE)(const ALCchar *devicename);
typedef ALCboolean (ALC_APIENTRY *LPALCCLOSEDEVICE)(ALCdevice *device);
typedef ALCenum (ALC_APIENTRY *LPALCGETERROR)(ALCdevice *device);
typedef ALCboolean (ALC_APIENTRY *LPALCISEXTENSIONPRESENT)(ALCdevice *device, const ALCchar *extname);
typedef void* (ALC_APIENTRY *LPALCGETPROCADDRESS)(ALCdevice *device, const ALCchar *funcname);
typedef ALCenum (ALC_APIENTRY *LPALCGETENUMVALUE)(ALCdevice *device, const ALCchar *enumname);
typedef const ALCchar* (ALC_APIENTRY *LPALCGETSTRING)(ALCdevice *device, ALCenum param);
typedef void (ALC_APIENTRY *LPALCGETINTEGERV)(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values);
typedef ALCdevice* (ALC_APIENTRY *LPALCCAPTUREOPENDEVICE)(const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize);
typedef ALCboolean (ALC_APIENTRY *LPALCCAPTURECLOSEDEVICE)(ALCdevice *device);
typedef void (ALC_APIENTRY *LPALCCAPTURESTART)(ALCdevice *device);
typedef void (ALC_APIENTRY *LPALCCAPTURESTOP)(ALCdevice *device);
typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)(ALCdevice *device, ALCvoid *buffer, ALCsizei samples);
#if defined(__cplusplus)
}
#endif #endif
/* NOLINTEND */
#endif /* AL_ALC_H */ #endif /* AL_ALC_H */

View file

@ -1,38 +1,22 @@
/**
* OpenAL cross platform audio library
* Copyright (C) 2008 by authors.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Or go to http://www.gnu.org/copyleft/lgpl.html
*/
#ifndef AL_ALEXT_H #ifndef AL_ALEXT_H
#define AL_ALEXT_H #define AL_ALEXT_H
/* NOLINTBEGIN */
#include <stddef.h> #include <stddef.h>
/* Define int64_t and uint64_t types */ /* Define int64 and uint64 types */
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
#include <inttypes.h> (defined(__cplusplus) && __cplusplus >= 201103L)
#elif defined(_WIN32) && defined(__GNUC__)
#include <stdint.h> #include <stdint.h>
typedef int64_t _alsoft_int64_t;
typedef uint64_t _alsoft_uint64_t;
#elif defined(_WIN32) #elif defined(_WIN32)
typedef __int64 int64_t; typedef __int64 _alsoft_int64_t;
typedef unsigned __int64 uint64_t; typedef unsigned __int64 _alsoft_uint64_t;
#else #else
/* Fallback if nothing above works */ /* Fallback if nothing above works */
#include <inttypes.h> #include <stdint.h>
typedef int64_t _alsoft_int64_t;
typedef uint64_t _alsoft_uint64_t;
#endif #endif
#include "alc.h" #include "alc.h"
@ -42,6 +26,8 @@ typedef unsigned __int64 uint64_t;
extern "C" { extern "C" {
#endif #endif
struct _GUID;
#ifndef AL_LOKI_IMA_ADPCM_format #ifndef AL_LOKI_IMA_ADPCM_format
#define AL_LOKI_IMA_ADPCM_format 1 #define AL_LOKI_IMA_ADPCM_format 1
#define AL_FORMAT_IMA_ADPCM_MONO16_EXT 0x10000 #define AL_FORMAT_IMA_ADPCM_MONO16_EXT 0x10000
@ -97,6 +83,31 @@ extern "C" {
#ifndef AL_EXT_MCFORMATS #ifndef AL_EXT_MCFORMATS
#define AL_EXT_MCFORMATS 1 #define AL_EXT_MCFORMATS 1
/* Provides support for surround sound buffer formats with 8, 16, and 32-bit
* samples.
*
* QUAD8: Unsigned 8-bit, Quadraphonic (Front Left, Front Right, Rear Left,
* Rear Right).
* QUAD16: Signed 16-bit, Quadraphonic.
* QUAD32: 32-bit float, Quadraphonic.
* REAR8: Unsigned 8-bit, Rear Stereo (Rear Left, Rear Right).
* REAR16: Signed 16-bit, Rear Stereo.
* REAR32: 32-bit float, Rear Stereo.
* 51CHN8: Unsigned 8-bit, 5.1 Surround (Front Left, Front Right, Front Center,
* LFE, Side Left, Side Right). Note that some audio systems may label
* 5.1's Side channels as Rear or Surround; they are equivalent for the
* purposes of this extension.
* 51CHN16: Signed 16-bit, 5.1 Surround.
* 51CHN32: 32-bit float, 5.1 Surround.
* 61CHN8: Unsigned 8-bit, 6.1 Surround (Front Left, Front Right, Front Center,
* LFE, Rear Center, Side Left, Side Right).
* 61CHN16: Signed 16-bit, 6.1 Surround.
* 61CHN32: 32-bit float, 6.1 Surround.
* 71CHN8: Unsigned 8-bit, 7.1 Surround (Front Left, Front Right, Front Center,
* LFE, Rear Left, Rear Right, Side Left, Side Right).
* 71CHN16: Signed 16-bit, 7.1 Surround.
* 71CHN32: 32-bit float, 7.1 Surround.
*/
#define AL_FORMAT_QUAD8 0x1204 #define AL_FORMAT_QUAD8 0x1204
#define AL_FORMAT_QUAD16 0x1205 #define AL_FORMAT_QUAD16 0x1205
#define AL_FORMAT_QUAD32 0x1206 #define AL_FORMAT_QUAD32 0x1206
@ -133,9 +144,9 @@ extern "C" {
#ifndef AL_EXT_STATIC_BUFFER #ifndef AL_EXT_STATIC_BUFFER
#define AL_EXT_STATIC_BUFFER 1 #define AL_EXT_STATIC_BUFFER 1
typedef ALvoid (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei); typedef void (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALuint,ALenum,ALvoid*,ALsizei,ALsizei) AL_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES #ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format, ALvoid *data, ALsizei len, ALsizei freq); void AL_APIENTRY alBufferDataStatic(const ALuint buffer, ALenum format, ALvoid *data, ALsizei size, ALsizei freq) AL_API_NOEXCEPT;
#endif #endif
#endif #endif
@ -151,11 +162,11 @@ AL_API ALvoid AL_APIENTRY alBufferDataStatic(const ALint buffer, ALenum format,
#ifndef ALC_EXT_thread_local_context #ifndef ALC_EXT_thread_local_context
#define ALC_EXT_thread_local_context 1 #define ALC_EXT_thread_local_context 1
typedef ALCboolean (ALC_APIENTRY*PFNALCSETTHREADCONTEXTPROC)(ALCcontext *context); typedef ALCboolean (ALC_APIENTRY*PFNALCSETTHREADCONTEXTPROC)(ALCcontext *context) ALC_API_NOEXCEPT17;
typedef ALCcontext* (ALC_APIENTRY*PFNALCGETTHREADCONTEXTPROC)(void); typedef ALCcontext* (ALC_APIENTRY*PFNALCGETTHREADCONTEXTPROC)(void) ALC_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES #ifdef AL_ALEXT_PROTOTYPES
ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context); ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context) ALC_API_NOEXCEPT;
ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void); ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void) ALC_API_NOEXCEPT;
#endif #endif
#endif #endif
@ -168,9 +179,9 @@ ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void);
#define AL_SOFT_buffer_sub_data 1 #define AL_SOFT_buffer_sub_data 1
#define AL_BYTE_RW_OFFSETS_SOFT 0x1031 #define AL_BYTE_RW_OFFSETS_SOFT 0x1031
#define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032 #define AL_SAMPLE_RW_OFFSETS_SOFT 0x1032
typedef ALvoid (AL_APIENTRY*PFNALBUFFERSUBDATASOFTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei); typedef void (AL_APIENTRY*PFNALBUFFERSUBDATASOFTPROC)(ALuint,ALenum,const ALvoid*,ALsizei,ALsizei) AL_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES #ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length); AL_API void AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const ALvoid *data,ALsizei offset,ALsizei length) AL_API_NOEXCEPT;
#endif #endif
#endif #endif
@ -187,12 +198,12 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const
#define AL_FOLDBACK_EVENT_STOP 0x4113 #define AL_FOLDBACK_EVENT_STOP 0x4113
#define AL_FOLDBACK_MODE_MONO 0x4101 #define AL_FOLDBACK_MODE_MONO 0x4101
#define AL_FOLDBACK_MODE_STEREO 0x4102 #define AL_FOLDBACK_MODE_STEREO 0x4102
typedef void (AL_APIENTRY*LPALFOLDBACKCALLBACK)(ALenum,ALsizei); typedef void (AL_APIENTRY*LPALFOLDBACKCALLBACK)(ALenum,ALsizei) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTART)(ALenum,ALsizei,ALsizei,ALfloat*,LPALFOLDBACKCALLBACK); typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTART)(ALenum,ALsizei,ALsizei,ALfloat*,LPALFOLDBACKCALLBACK) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTOP)(void); typedef void (AL_APIENTRY*LPALREQUESTFOLDBACKSTOP)(void) AL_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES #ifdef AL_ALEXT_PROTOTYPES
AL_API void AL_APIENTRY alRequestFoldbackStart(ALenum mode,ALsizei count,ALsizei length,ALfloat *mem,LPALFOLDBACKCALLBACK callback); AL_API void AL_APIENTRY alRequestFoldbackStart(ALenum mode,ALsizei count,ALsizei length,ALfloat *mem,LPALFOLDBACKCALLBACK callback) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alRequestFoldbackStop(void); AL_API void AL_APIENTRY alRequestFoldbackStop(void) AL_API_NOEXCEPT;
#endif #endif
#endif #endif
@ -255,15 +266,15 @@ AL_API void AL_APIENTRY alRequestFoldbackStop(void);
#define AL_SAMPLE_LENGTH_SOFT 0x200A #define AL_SAMPLE_LENGTH_SOFT 0x200A
#define AL_SEC_LENGTH_SOFT 0x200B #define AL_SEC_LENGTH_SOFT 0x200B
typedef void (AL_APIENTRY*LPALBUFFERSAMPLESSOFT)(ALuint,ALuint,ALenum,ALsizei,ALenum,ALenum,const ALvoid*); typedef void (AL_APIENTRY*LPALBUFFERSAMPLESSOFT)(ALuint,ALuint,ALenum,ALsizei,ALenum,ALenum,const ALvoid*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALBUFFERSUBSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,const ALvoid*); typedef void (AL_APIENTRY*LPALBUFFERSUBSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,const ALvoid*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETBUFFERSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,ALvoid*); typedef void (AL_APIENTRY*LPALGETBUFFERSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,ALvoid*) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY*LPALISBUFFERFORMATSUPPORTEDSOFT)(ALenum); typedef ALboolean (AL_APIENTRY*LPALISBUFFERFORMATSUPPORTEDSOFT)(ALenum) AL_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES #ifdef AL_ALEXT_PROTOTYPES
AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data); AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data); AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, const ALvoid *data) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, ALvoid *data); AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, ALsizei offset, ALsizei samples, ALenum channels, ALenum type, ALvoid *data) AL_API_NOEXCEPT;
AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format); AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format) AL_API_NOEXCEPT;
#endif #endif
#endif #endif
@ -294,13 +305,13 @@ AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format);
#define ALC_6POINT1_SOFT 0x1505 #define ALC_6POINT1_SOFT 0x1505
#define ALC_7POINT1_SOFT 0x1506 #define ALC_7POINT1_SOFT 0x1506
typedef ALCdevice* (ALC_APIENTRY*LPALCLOOPBACKOPENDEVICESOFT)(const ALCchar*); typedef ALCdevice* (ALC_APIENTRY*LPALCLOOPBACKOPENDEVICESOFT)(const ALCchar*) ALC_API_NOEXCEPT17;
typedef ALCboolean (ALC_APIENTRY*LPALCISRENDERFORMATSUPPORTEDSOFT)(ALCdevice*,ALCsizei,ALCenum,ALCenum); typedef ALCboolean (ALC_APIENTRY*LPALCISRENDERFORMATSUPPORTEDSOFT)(ALCdevice*,ALCsizei,ALCenum,ALCenum) ALC_API_NOEXCEPT17;
typedef void (ALC_APIENTRY*LPALCRENDERSAMPLESSOFT)(ALCdevice*,ALCvoid*,ALCsizei); typedef void (ALC_APIENTRY*LPALCRENDERSAMPLESSOFT)(ALCdevice*,ALCvoid*,ALCsizei) ALC_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES #ifdef AL_ALEXT_PROTOTYPES
ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName); ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName) AL_API_NOEXCEPT;
ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type); ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type) AL_API_NOEXCEPT;
ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples); ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples) AL_API_NOEXCEPT;
#endif #endif
#endif #endif
@ -318,38 +329,764 @@ ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffe
#define AL_SOFT_source_latency 1 #define AL_SOFT_source_latency 1
#define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200 #define AL_SAMPLE_OFFSET_LATENCY_SOFT 0x1200
#define AL_SEC_OFFSET_LATENCY_SOFT 0x1201 #define AL_SEC_OFFSET_LATENCY_SOFT 0x1201
typedef int64_t ALint64SOFT; typedef _alsoft_int64_t ALint64SOFT;
typedef uint64_t ALuint64SOFT; typedef _alsoft_uint64_t ALuint64SOFT;
typedef void (AL_APIENTRY*LPALSOURCEDSOFT)(ALuint,ALenum,ALdouble); typedef void (AL_APIENTRY*LPALSOURCEDSOFT)(ALuint,ALenum,ALdouble) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALSOURCE3DSOFT)(ALuint,ALenum,ALdouble,ALdouble,ALdouble); typedef void (AL_APIENTRY*LPALSOURCE3DSOFT)(ALuint,ALenum,ALdouble,ALdouble,ALdouble) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALSOURCEDVSOFT)(ALuint,ALenum,const ALdouble*); typedef void (AL_APIENTRY*LPALSOURCEDVSOFT)(ALuint,ALenum,const ALdouble*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETSOURCEDSOFT)(ALuint,ALenum,ALdouble*); typedef void (AL_APIENTRY*LPALGETSOURCEDSOFT)(ALuint,ALenum,ALdouble*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETSOURCE3DSOFT)(ALuint,ALenum,ALdouble*,ALdouble*,ALdouble*); typedef void (AL_APIENTRY*LPALGETSOURCE3DSOFT)(ALuint,ALenum,ALdouble*,ALdouble*,ALdouble*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETSOURCEDVSOFT)(ALuint,ALenum,ALdouble*); typedef void (AL_APIENTRY*LPALGETSOURCEDVSOFT)(ALuint,ALenum,ALdouble*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT); typedef void (AL_APIENTRY*LPALSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT,ALint64SOFT,ALint64SOFT); typedef void (AL_APIENTRY*LPALSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT,ALint64SOFT,ALint64SOFT) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALSOURCEI64VSOFT)(ALuint,ALenum,const ALint64SOFT*); typedef void (AL_APIENTRY*LPALSOURCEI64VSOFT)(ALuint,ALenum,const ALint64SOFT*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT*); typedef void (AL_APIENTRY*LPALGETSOURCEI64SOFT)(ALuint,ALenum,ALint64SOFT*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT*,ALint64SOFT*,ALint64SOFT*); typedef void (AL_APIENTRY*LPALGETSOURCE3I64SOFT)(ALuint,ALenum,ALint64SOFT*,ALint64SOFT*,ALint64SOFT*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETSOURCEI64VSOFT)(ALuint,ALenum,ALint64SOFT*); typedef void (AL_APIENTRY*LPALGETSOURCEI64VSOFT)(ALuint,ALenum,ALint64SOFT*) AL_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES #ifdef AL_ALEXT_PROTOTYPES
AL_API void AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble value); AL_API void AL_APIENTRY alSourcedSOFT(ALuint source, ALenum param, ALdouble value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3); AL_API void AL_APIENTRY alSource3dSOFT(ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdouble *values); AL_API void AL_APIENTRY alSourcedvSOFT(ALuint source, ALenum param, const ALdouble *values) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *value); AL_API void AL_APIENTRY alGetSourcedSOFT(ALuint source, ALenum param, ALdouble *value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3); AL_API void AL_APIENTRY alGetSource3dSOFT(ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble *values); AL_API void AL_APIENTRY alGetSourcedvSOFT(ALuint source, ALenum param, ALdouble *values) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT value); AL_API void AL_APIENTRY alSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3); AL_API void AL_APIENTRY alSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALint64SOFT *values); AL_API void AL_APIENTRY alSourcei64vSOFT(ALuint source, ALenum param, const ALint64SOFT *values) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT *value); AL_API void AL_APIENTRY alGetSourcei64SOFT(ALuint source, ALenum param, ALint64SOFT *value) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT *value1, ALint64SOFT *value2, ALint64SOFT *value3); AL_API void AL_APIENTRY alGetSource3i64SOFT(ALuint source, ALenum param, ALint64SOFT *value1, ALint64SOFT *value2, ALint64SOFT *value3) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT *values); AL_API void AL_APIENTRY alGetSourcei64vSOFT(ALuint source, ALenum param, ALint64SOFT *values) AL_API_NOEXCEPT;
#endif #endif
#endif #endif
#ifndef ALC_EXT_DEFAULT_FILTER_ORDER
#define ALC_EXT_DEFAULT_FILTER_ORDER 1
#define ALC_DEFAULT_FILTER_ORDER 0x1100
#endif
#ifndef AL_SOFT_deferred_updates
#define AL_SOFT_deferred_updates 1
#define AL_DEFERRED_UPDATES_SOFT 0xC002
typedef void (AL_APIENTRY*LPALDEFERUPDATESSOFT)(void) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALPROCESSUPDATESSOFT)(void) AL_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES
AL_API void AL_APIENTRY alDeferUpdatesSOFT(void) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alProcessUpdatesSOFT(void) AL_API_NOEXCEPT;
#endif
#endif
#ifndef AL_SOFT_block_alignment
#define AL_SOFT_block_alignment 1
#define AL_UNPACK_BLOCK_ALIGNMENT_SOFT 0x200C
#define AL_PACK_BLOCK_ALIGNMENT_SOFT 0x200D
#endif
#ifndef AL_SOFT_MSADPCM
#define AL_SOFT_MSADPCM 1
#define AL_FORMAT_MONO_MSADPCM_SOFT 0x1302
#define AL_FORMAT_STEREO_MSADPCM_SOFT 0x1303
#endif
#ifndef AL_SOFT_source_length
#define AL_SOFT_source_length 1
/*#define AL_BYTE_LENGTH_SOFT 0x2009*/
/*#define AL_SAMPLE_LENGTH_SOFT 0x200A*/
/*#define AL_SEC_LENGTH_SOFT 0x200B*/
#endif
#ifndef AL_SOFT_buffer_length_query
#define AL_SOFT_buffer_length_query 1
/*#define AL_BYTE_LENGTH_SOFT 0x2009*/
/*#define AL_SAMPLE_LENGTH_SOFT 0x200A*/
/*#define AL_SEC_LENGTH_SOFT 0x200B*/
#endif
#ifndef ALC_SOFT_pause_device
#define ALC_SOFT_pause_device 1
typedef void (ALC_APIENTRY*LPALCDEVICEPAUSESOFT)(ALCdevice *device) ALC_API_NOEXCEPT17;
typedef void (ALC_APIENTRY*LPALCDEVICERESUMESOFT)(ALCdevice *device) ALC_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES
ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device) ALC_API_NOEXCEPT;
ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device) ALC_API_NOEXCEPT;
#endif
#endif
#ifndef AL_EXT_BFORMAT
#define AL_EXT_BFORMAT 1
/* Provides support for B-Format ambisonic buffers (first-order, FuMa scaling
* and layout).
*
* BFORMAT2D_8: Unsigned 8-bit, 3-channel non-periphonic (WXY).
* BFORMAT2D_16: Signed 16-bit, 3-channel non-periphonic (WXY).
* BFORMAT2D_FLOAT32: 32-bit float, 3-channel non-periphonic (WXY).
* BFORMAT3D_8: Unsigned 8-bit, 4-channel periphonic (WXYZ).
* BFORMAT3D_16: Signed 16-bit, 4-channel periphonic (WXYZ).
* BFORMAT3D_FLOAT32: 32-bit float, 4-channel periphonic (WXYZ).
*/
#define AL_FORMAT_BFORMAT2D_8 0x20021
#define AL_FORMAT_BFORMAT2D_16 0x20022
#define AL_FORMAT_BFORMAT2D_FLOAT32 0x20023
#define AL_FORMAT_BFORMAT3D_8 0x20031
#define AL_FORMAT_BFORMAT3D_16 0x20032
#define AL_FORMAT_BFORMAT3D_FLOAT32 0x20033
#endif
#ifndef AL_EXT_MULAW_BFORMAT
#define AL_EXT_MULAW_BFORMAT 1
#define AL_FORMAT_BFORMAT2D_MULAW 0x10031
#define AL_FORMAT_BFORMAT3D_MULAW 0x10032
#endif
#ifndef ALC_SOFT_HRTF
#define ALC_SOFT_HRTF 1
#define ALC_HRTF_SOFT 0x1992
#define ALC_DONT_CARE_SOFT 0x0002
#define ALC_HRTF_STATUS_SOFT 0x1993
#define ALC_HRTF_DISABLED_SOFT 0x0000
#define ALC_HRTF_ENABLED_SOFT 0x0001
#define ALC_HRTF_DENIED_SOFT 0x0002
#define ALC_HRTF_REQUIRED_SOFT 0x0003
#define ALC_HRTF_HEADPHONES_DETECTED_SOFT 0x0004
#define ALC_HRTF_UNSUPPORTED_FORMAT_SOFT 0x0005
#define ALC_NUM_HRTF_SPECIFIERS_SOFT 0x1994
#define ALC_HRTF_SPECIFIER_SOFT 0x1995
#define ALC_HRTF_ID_SOFT 0x1996
typedef const ALCchar* (ALC_APIENTRY*LPALCGETSTRINGISOFT)(ALCdevice *device, ALCenum paramName, ALCsizei index) ALC_API_NOEXCEPT17;
typedef ALCboolean (ALC_APIENTRY*LPALCRESETDEVICESOFT)(ALCdevice *device, const ALCint *attribs) ALC_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES
ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index) ALC_API_NOEXCEPT;
ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs) ALC_API_NOEXCEPT;
#endif
#endif
#ifndef AL_SOFT_gain_clamp_ex
#define AL_SOFT_gain_clamp_ex 1
#define AL_GAIN_LIMIT_SOFT 0x200E
#endif
#ifndef AL_SOFT_source_resampler
#define AL_SOFT_source_resampler
#define AL_NUM_RESAMPLERS_SOFT 0x1210
#define AL_DEFAULT_RESAMPLER_SOFT 0x1211
#define AL_SOURCE_RESAMPLER_SOFT 0x1212
#define AL_RESAMPLER_NAME_SOFT 0x1213
typedef const ALchar* (AL_APIENTRY*LPALGETSTRINGISOFT)(ALenum pname, ALsizei index) AL_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES
AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index) AL_API_NOEXCEPT;
#endif
#endif
#ifndef AL_SOFT_source_spatialize
#define AL_SOFT_source_spatialize
#define AL_SOURCE_SPATIALIZE_SOFT 0x1214
#define AL_AUTO_SOFT 0x0002
#endif
#ifndef ALC_SOFT_output_limiter
#define ALC_SOFT_output_limiter
#define ALC_OUTPUT_LIMITER_SOFT 0x199A
#endif
#ifndef ALC_SOFT_device_clock
#define ALC_SOFT_device_clock 1
typedef _alsoft_int64_t ALCint64SOFT;
typedef _alsoft_uint64_t ALCuint64SOFT;
#define ALC_DEVICE_CLOCK_SOFT 0x1600
#define ALC_DEVICE_LATENCY_SOFT 0x1601
#define ALC_DEVICE_CLOCK_LATENCY_SOFT 0x1602
#define AL_SAMPLE_OFFSET_CLOCK_SOFT 0x1202
#define AL_SEC_OFFSET_CLOCK_SOFT 0x1203
typedef void (ALC_APIENTRY*LPALCGETINTEGER64VSOFT)(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values) ALC_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES
ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values) ALC_API_NOEXCEPT;
#endif
#endif
#ifndef AL_SOFT_direct_channels_remix
#define AL_SOFT_direct_channels_remix 1
#define AL_DROP_UNMATCHED_SOFT 0x0001
#define AL_REMIX_UNMATCHED_SOFT 0x0002
#endif
#ifndef AL_SOFT_bformat_ex
#define AL_SOFT_bformat_ex 1
#define AL_AMBISONIC_LAYOUT_SOFT 0x1997
#define AL_AMBISONIC_SCALING_SOFT 0x1998
/* Ambisonic layouts */
#define AL_FUMA_SOFT 0x0000
#define AL_ACN_SOFT 0x0001
/* Ambisonic scalings (normalization) */
/*#define AL_FUMA_SOFT*/
#define AL_SN3D_SOFT 0x0001
#define AL_N3D_SOFT 0x0002
#endif
#ifndef ALC_SOFT_loopback_bformat
#define ALC_SOFT_loopback_bformat 1
#define ALC_AMBISONIC_LAYOUT_SOFT 0x1997
#define ALC_AMBISONIC_SCALING_SOFT 0x1998
#define ALC_AMBISONIC_ORDER_SOFT 0x1999
#define ALC_MAX_AMBISONIC_ORDER_SOFT 0x199B
#define ALC_BFORMAT3D_SOFT 0x1507
/* Ambisonic layouts */
#define ALC_FUMA_SOFT 0x0000
#define ALC_ACN_SOFT 0x0001
/* Ambisonic scalings (normalization) */
/*#define ALC_FUMA_SOFT*/
#define ALC_SN3D_SOFT 0x0001
#define ALC_N3D_SOFT 0x0002
#endif
#ifndef AL_SOFT_effect_target
#define AL_SOFT_effect_target
#define AL_EFFECTSLOT_TARGET_SOFT 0x199C
#endif
#ifndef AL_SOFT_events
#define AL_SOFT_events 1
#define AL_EVENT_CALLBACK_FUNCTION_SOFT 0x19A2
#define AL_EVENT_CALLBACK_USER_PARAM_SOFT 0x19A3
#define AL_EVENT_TYPE_BUFFER_COMPLETED_SOFT 0x19A4
#define AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT 0x19A5
#define AL_EVENT_TYPE_DISCONNECTED_SOFT 0x19A6
typedef void (AL_APIENTRY*ALEVENTPROCSOFT)(ALenum eventType, ALuint object, ALuint param,
ALsizei length, const ALchar *message, void *userParam) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALEVENTCONTROLSOFT)(ALsizei count, const ALenum *types, ALboolean enable) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALEVENTCALLBACKSOFT)(ALEVENTPROCSOFT callback, void *userParam) AL_API_NOEXCEPT17;
typedef void* (AL_APIENTRY*LPALGETPOINTERSOFT)(ALenum pname) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETPOINTERVSOFT)(ALenum pname, void **values) AL_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES
AL_API void AL_APIENTRY alEventControlSOFT(ALsizei count, const ALenum *types, ALboolean enable) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alEventCallbackSOFT(ALEVENTPROCSOFT callback, void *userParam) AL_API_NOEXCEPT;
AL_API void* AL_APIENTRY alGetPointerSOFT(ALenum pname) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetPointervSOFT(ALenum pname, void **values) AL_API_NOEXCEPT;
#endif
#endif
#ifndef ALC_SOFT_reopen_device
#define ALC_SOFT_reopen_device
typedef ALCboolean (ALC_APIENTRY*LPALCREOPENDEVICESOFT)(ALCdevice *device,
const ALCchar *deviceName, const ALCint *attribs) ALC_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES
ALCboolean ALC_APIENTRY alcReopenDeviceSOFT(ALCdevice *device, const ALCchar *deviceName,
const ALCint *attribs) ALC_API_NOEXCEPT;
#endif
#endif
#ifndef AL_SOFT_callback_buffer
#define AL_SOFT_callback_buffer
#define AL_BUFFER_CALLBACK_FUNCTION_SOFT 0x19A0
#define AL_BUFFER_CALLBACK_USER_PARAM_SOFT 0x19A1
typedef ALsizei (AL_APIENTRY*ALBUFFERCALLBACKTYPESOFT)(ALvoid *userptr, ALvoid *sampledata, ALsizei numbytes) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALBUFFERCALLBACKSOFT)(ALuint buffer, ALenum format, ALsizei freq, ALBUFFERCALLBACKTYPESOFT callback, ALvoid *userptr) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETBUFFERPTRSOFT)(ALuint buffer, ALenum param, ALvoid **value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETBUFFER3PTRSOFT)(ALuint buffer, ALenum param, ALvoid **value1, ALvoid **value2, ALvoid **value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETBUFFERPTRVSOFT)(ALuint buffer, ALenum param, ALvoid **values) AL_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES
AL_API void AL_APIENTRY alBufferCallbackSOFT(ALuint buffer, ALenum format, ALsizei freq, ALBUFFERCALLBACKTYPESOFT callback, ALvoid *userptr) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetBufferPtrSOFT(ALuint buffer, ALenum param, ALvoid **ptr) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetBuffer3PtrSOFT(ALuint buffer, ALenum param, ALvoid **ptr0, ALvoid **ptr1, ALvoid **ptr2) AL_API_NOEXCEPT;
AL_API void AL_APIENTRY alGetBufferPtrvSOFT(ALuint buffer, ALenum param, ALvoid **ptr) AL_API_NOEXCEPT;
#endif
#endif
#ifndef AL_SOFT_UHJ
#define AL_SOFT_UHJ
#define AL_FORMAT_UHJ2CHN8_SOFT 0x19A2
#define AL_FORMAT_UHJ2CHN16_SOFT 0x19A3
#define AL_FORMAT_UHJ2CHN_FLOAT32_SOFT 0x19A4
#define AL_FORMAT_UHJ3CHN8_SOFT 0x19A5
#define AL_FORMAT_UHJ3CHN16_SOFT 0x19A6
#define AL_FORMAT_UHJ3CHN_FLOAT32_SOFT 0x19A7
#define AL_FORMAT_UHJ4CHN8_SOFT 0x19A8
#define AL_FORMAT_UHJ4CHN16_SOFT 0x19A9
#define AL_FORMAT_UHJ4CHN_FLOAT32_SOFT 0x19AA
#define AL_STEREO_MODE_SOFT 0x19B0
#define AL_NORMAL_SOFT 0x0000
#define AL_SUPER_STEREO_SOFT 0x0001
#define AL_SUPER_STEREO_WIDTH_SOFT 0x19B1
#endif
#ifndef AL_SOFT_UHJ_ex
#define AL_SOFT_UHJ_ex
#define AL_FORMAT_UHJ2CHN_MULAW_SOFT 0x19B3
#define AL_FORMAT_UHJ2CHN_ALAW_SOFT 0x19B4
#define AL_FORMAT_UHJ2CHN_IMA4_SOFT 0x19B5
#define AL_FORMAT_UHJ2CHN_MSADPCM_SOFT 0x19B6
#define AL_FORMAT_UHJ3CHN_MULAW_SOFT 0x19B7
#define AL_FORMAT_UHJ3CHN_ALAW_SOFT 0x19B8
#define AL_FORMAT_UHJ4CHN_MULAW_SOFT 0x19B9
#define AL_FORMAT_UHJ4CHN_ALAW_SOFT 0x19BA
#endif
#ifndef ALC_SOFT_output_mode
#define ALC_SOFT_output_mode
#define ALC_OUTPUT_MODE_SOFT 0x19AC
#define ALC_ANY_SOFT 0x19AD
/*#define ALC_MONO_SOFT 0x1500*/
/*#define ALC_STEREO_SOFT 0x1501*/
#define ALC_STEREO_BASIC_SOFT 0x19AE
#define ALC_STEREO_UHJ_SOFT 0x19AF
#define ALC_STEREO_HRTF_SOFT 0x19B2
/*#define ALC_QUAD_SOFT 0x1503*/
#define ALC_SURROUND_5_1_SOFT 0x1504
#define ALC_SURROUND_6_1_SOFT 0x1505
#define ALC_SURROUND_7_1_SOFT 0x1506
#endif
#ifndef AL_SOFT_source_start_delay
#define AL_SOFT_source_start_delay
typedef void (AL_APIENTRY*LPALSOURCEPLAYATTIMESOFT)(ALuint source, ALint64SOFT start_time) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALSOURCEPLAYATTIMEVSOFT)(ALsizei n, const ALuint *sources, ALint64SOFT start_time) AL_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES
void AL_APIENTRY alSourcePlayAtTimeSOFT(ALuint source, ALint64SOFT start_time) AL_API_NOEXCEPT;
void AL_APIENTRY alSourcePlayAtTimevSOFT(ALsizei n, const ALuint *sources, ALint64SOFT start_time) AL_API_NOEXCEPT;
#endif
#endif
#ifndef ALC_EXT_debug
#define ALC_EXT_debug
#define ALC_CONTEXT_FLAGS_EXT 0x19CF
#define ALC_CONTEXT_DEBUG_BIT_EXT 0x0001
#endif
#ifndef AL_EXT_debug
#define AL_EXT_debug
#define AL_DONT_CARE_EXT 0x0002
#define AL_DEBUG_OUTPUT_EXT 0x19B2
#define AL_DEBUG_CALLBACK_FUNCTION_EXT 0x19B3
#define AL_DEBUG_CALLBACK_USER_PARAM_EXT 0x19B4
#define AL_DEBUG_SOURCE_API_EXT 0x19B5
#define AL_DEBUG_SOURCE_AUDIO_SYSTEM_EXT 0x19B6
#define AL_DEBUG_SOURCE_THIRD_PARTY_EXT 0x19B7
#define AL_DEBUG_SOURCE_APPLICATION_EXT 0x19B8
#define AL_DEBUG_SOURCE_OTHER_EXT 0x19B9
#define AL_DEBUG_TYPE_ERROR_EXT 0x19BA
#define AL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_EXT 0x19BB
#define AL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_EXT 0x19BC
#define AL_DEBUG_TYPE_PORTABILITY_EXT 0x19BD
#define AL_DEBUG_TYPE_PERFORMANCE_EXT 0x19BE
#define AL_DEBUG_TYPE_MARKER_EXT 0x19BF
#define AL_DEBUG_TYPE_PUSH_GROUP_EXT 0x19C0
#define AL_DEBUG_TYPE_POP_GROUP_EXT 0x19C1
#define AL_DEBUG_TYPE_OTHER_EXT 0x19C2
#define AL_DEBUG_SEVERITY_HIGH_EXT 0x19C3
#define AL_DEBUG_SEVERITY_MEDIUM_EXT 0x19C4
#define AL_DEBUG_SEVERITY_LOW_EXT 0x19C5
#define AL_DEBUG_SEVERITY_NOTIFICATION_EXT 0x19C6
#define AL_DEBUG_LOGGED_MESSAGES_EXT 0x19C7
#define AL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_EXT 0x19C8
#define AL_MAX_DEBUG_MESSAGE_LENGTH_EXT 0x19C9
#define AL_MAX_DEBUG_LOGGED_MESSAGES_EXT 0x19CA
#define AL_MAX_DEBUG_GROUP_STACK_DEPTH_EXT 0x19CB
#define AL_MAX_LABEL_LENGTH_EXT 0x19CC
#define AL_STACK_OVERFLOW_EXT 0x19CD
#define AL_STACK_UNDERFLOW_EXT 0x19CE
#define AL_CONTEXT_FLAGS_EXT 0x19CF
#define AL_BUFFER_EXT 0x1009 /* Same as AL_BUFFER */
#define AL_SOURCE_EXT 0x19D0
#define AL_FILTER_EXT 0x19D1
#define AL_EFFECT_EXT 0x19D2
#define AL_AUXILIARY_EFFECT_SLOT_EXT 0x19D3
typedef void (AL_APIENTRY*ALDEBUGPROCEXT)(ALenum source, ALenum type, ALuint id, ALenum severity, ALsizei length, const ALchar *message, void *userParam) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALDEBUGMESSAGECALLBACKEXT)(ALDEBUGPROCEXT callback, void *userParam) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALDEBUGMESSAGEINSERTEXT)(ALenum source, ALenum type, ALuint id, ALenum severity, ALsizei length, const ALchar *message) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALDEBUGMESSAGECONTROLEXT)(ALenum source, ALenum type, ALenum severity, ALsizei count, const ALuint *ids, ALboolean enable) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALPUSHDEBUGGROUPEXT)(ALenum source, ALuint id, ALsizei length, const ALchar *message) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALPOPDEBUGGROUPEXT)(void) AL_API_NOEXCEPT17;
typedef ALuint (AL_APIENTRY*LPALGETDEBUGMESSAGELOGEXT)(ALuint count, ALsizei logBufSize, ALenum *sources, ALenum *types, ALuint *ids, ALenum *severities, ALsizei *lengths, ALchar *logBuf) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALOBJECTLABELEXT)(ALenum identifier, ALuint name, ALsizei length, const ALchar *label) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETOBJECTLABELEXT)(ALenum identifier, ALuint name, ALsizei bufSize, ALsizei *length, ALchar *label) AL_API_NOEXCEPT17;
typedef void* (AL_APIENTRY*LPALGETPOINTEREXT)(ALenum pname) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETPOINTERVEXT)(ALenum pname, void **values) AL_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES
void AL_APIENTRY alDebugMessageCallbackEXT(ALDEBUGPROCEXT callback, void *userParam) AL_API_NOEXCEPT;
void AL_APIENTRY alDebugMessageInsertEXT(ALenum source, ALenum type, ALuint id, ALenum severity, ALsizei length, const ALchar *message) AL_API_NOEXCEPT;
void AL_APIENTRY alDebugMessageControlEXT(ALenum source, ALenum type, ALenum severity, ALsizei count, const ALuint *ids, ALboolean enable) AL_API_NOEXCEPT;
void AL_APIENTRY alPushDebugGroupEXT(ALenum source, ALuint id, ALsizei length, const ALchar *message) AL_API_NOEXCEPT;
void AL_APIENTRY alPopDebugGroupEXT(void) AL_API_NOEXCEPT;
ALuint AL_APIENTRY alGetDebugMessageLogEXT(ALuint count, ALsizei logBufSize, ALenum *sources, ALenum *types, ALuint *ids, ALenum *severities, ALsizei *lengths, ALchar *logBuf) AL_API_NOEXCEPT;
void AL_APIENTRY alObjectLabelEXT(ALenum identifier, ALuint name, ALsizei length, const ALchar *label) AL_API_NOEXCEPT;
void AL_APIENTRY alGetObjectLabelEXT(ALenum identifier, ALuint name, ALsizei bufSize, ALsizei *length, ALchar *label) AL_API_NOEXCEPT;
void* AL_APIENTRY alGetPointerEXT(ALenum pname) AL_API_NOEXCEPT;
void AL_APIENTRY alGetPointervEXT(ALenum pname, void **values) AL_API_NOEXCEPT;
#endif
#endif
#ifndef ALC_SOFT_system_events
#define ALC_SOFT_system_events
#define ALC_PLAYBACK_DEVICE_SOFT 0x19D4
#define ALC_CAPTURE_DEVICE_SOFT 0x19D5
#define ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT 0x19D6
#define ALC_EVENT_TYPE_DEVICE_ADDED_SOFT 0x19D7
#define ALC_EVENT_TYPE_DEVICE_REMOVED_SOFT 0x19D8
#define ALC_EVENT_SUPPORTED_SOFT 0x19D9
#define ALC_EVENT_NOT_SUPPORTED_SOFT 0x19DA
typedef void (ALC_APIENTRY*ALCEVENTPROCTYPESOFT)(ALCenum eventType, ALCenum deviceType,
ALCdevice *device, ALCsizei length, const ALCchar *message, void *userParam) ALC_API_NOEXCEPT17;
typedef ALCenum (ALC_APIENTRY*LPALCEVENTISSUPPORTEDSOFT)(ALCenum eventType, ALCenum deviceType) ALC_API_NOEXCEPT17;
typedef ALCboolean (ALC_APIENTRY*LPALCEVENTCONTROLSOFT)(ALCsizei count, const ALCenum *events, ALCboolean enable) ALC_API_NOEXCEPT17;
typedef void (ALC_APIENTRY*LPALCEVENTCALLBACKSOFT)(ALCEVENTPROCTYPESOFT callback, void *userParam) ALC_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES
ALCenum ALC_APIENTRY alcEventIsSupportedSOFT(ALCenum eventType, ALCenum deviceType) ALC_API_NOEXCEPT;
ALCboolean ALC_APIENTRY alcEventControlSOFT(ALCsizei count, const ALCenum *events, ALCboolean enable) ALC_API_NOEXCEPT;
void ALC_APIENTRY alcEventCallbackSOFT(ALCEVENTPROCTYPESOFT callback, void *userParam) ALC_API_NOEXCEPT;
#endif
#endif
#ifndef AL_EXT_direct_context
#define AL_EXT_direct_context
typedef ALCvoid* (ALC_APIENTRY *LPALCGETPROCADDRESS2)(ALCdevice *device, const ALCchar *funcname) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALENABLEDIRECT)(ALCcontext *context, ALenum capability) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDISABLEDIRECT)(ALCcontext *context, ALenum capability) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALISENABLEDDIRECT)(ALCcontext *context, ALenum capability) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDOPPLERFACTORDIRECT)(ALCcontext *context, ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSPEEDOFSOUNDDIRECT)(ALCcontext *context, ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDISTANCEMODELDIRECT)(ALCcontext *context, ALenum distanceModel) AL_API_NOEXCEPT17;
typedef const ALchar* (AL_APIENTRY *LPALGETSTRINGDIRECT)(ALCcontext *context, ALenum param) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBOOLEANVDIRECT)(ALCcontext *context, ALenum param, ALboolean *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETINTEGERVDIRECT)(ALCcontext *context, ALenum param, ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETFLOATVDIRECT)(ALCcontext *context, ALenum param, ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETDOUBLEVDIRECT)(ALCcontext *context, ALenum param, ALdouble *values) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALGETBOOLEANDIRECT)(ALCcontext *context, ALenum param) AL_API_NOEXCEPT17;
typedef ALint (AL_APIENTRY *LPALGETINTEGERDIRECT)(ALCcontext *context, ALenum param) AL_API_NOEXCEPT17;
typedef ALfloat (AL_APIENTRY *LPALGETFLOATDIRECT)(ALCcontext *context, ALenum param) AL_API_NOEXCEPT17;
typedef ALdouble (AL_APIENTRY *LPALGETDOUBLEDIRECT)(ALCcontext *context, ALenum param) AL_API_NOEXCEPT17;
typedef ALenum (AL_APIENTRY *LPALGETERRORDIRECT)(ALCcontext *context) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALISEXTENSIONPRESENTDIRECT)(ALCcontext *context, const ALchar *extname) AL_API_NOEXCEPT17;
typedef void* (AL_APIENTRY *LPALGETPROCADDRESSDIRECT)(ALCcontext *context, const ALchar *fname) AL_API_NOEXCEPT17;
typedef ALenum (AL_APIENTRY *LPALGETENUMVALUEDIRECT)(ALCcontext *context, const ALchar *ename) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALLISTENERFDIRECT)(ALCcontext *context, ALenum param, ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALLISTENER3FDIRECT)(ALCcontext *context, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALLISTENERFVDIRECT)(ALCcontext *context, ALenum param, const ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALLISTENERIDIRECT)(ALCcontext *context, ALenum param, ALint value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALLISTENER3IDIRECT)(ALCcontext *context, ALenum param, ALint value1, ALint value2, ALint value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALLISTENERIVDIRECT)(ALCcontext *context, ALenum param, const ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETLISTENERFDIRECT)(ALCcontext *context, ALenum param, ALfloat *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETLISTENER3FDIRECT)(ALCcontext *context, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETLISTENERFVDIRECT)(ALCcontext *context, ALenum param, ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETLISTENERIDIRECT)(ALCcontext *context, ALenum param, ALint *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETLISTENER3IDIRECT)(ALCcontext *context, ALenum param, ALint *value1, ALint *value2, ALint *value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETLISTENERIVDIRECT)(ALCcontext *context, ALenum param, ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGENSOURCESDIRECT)(ALCcontext *context, ALsizei n, ALuint *sources) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDELETESOURCESDIRECT)(ALCcontext *context, ALsizei n, const ALuint *sources) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALISSOURCEDIRECT)(ALCcontext *context, ALuint source) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEFDIRECT)(ALCcontext *context, ALuint source, ALenum param, ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCE3FDIRECT)(ALCcontext *context, ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEFVDIRECT)(ALCcontext *context, ALuint source, ALenum param, const ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEIDIRECT)(ALCcontext *context, ALuint source, ALenum param, ALint value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCE3IDIRECT)(ALCcontext *context, ALuint source, ALenum param, ALint value1, ALint value2, ALint value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEIVDIRECT)(ALCcontext *context, ALuint source, ALenum param, const ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCEFDIRECT)(ALCcontext *context, ALuint source, ALenum param, ALfloat *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCE3FDIRECT)(ALCcontext *context, ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCEFVDIRECT)(ALCcontext *context, ALuint source, ALenum param, ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCEIDIRECT)(ALCcontext *context, ALuint source, ALenum param, ALint *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCE3IDIRECT)(ALCcontext *context, ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCEIVDIRECT)(ALCcontext *context, ALuint source, ALenum param, ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEPLAYDIRECT)(ALCcontext *context, ALuint source) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCESTOPDIRECT)(ALCcontext *context, ALuint source) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEREWINDDIRECT)(ALCcontext *context, ALuint source) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEPAUSEDIRECT)(ALCcontext *context, ALuint source) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEPLAYVDIRECT)(ALCcontext *context, ALsizei n, const ALuint *sources) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCESTOPVDIRECT)(ALCcontext *context, ALsizei n, const ALuint *sources) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEREWINDVDIRECT)(ALCcontext *context, ALsizei n, const ALuint *sources) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEPAUSEVDIRECT)(ALCcontext *context, ALsizei n, const ALuint *sources) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEQUEUEBUFFERSDIRECT)(ALCcontext *context, ALuint source, ALsizei nb, const ALuint *buffers) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEUNQUEUEBUFFERSDIRECT)(ALCcontext *context, ALuint source, ALsizei nb, ALuint *buffers) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGENBUFFERSDIRECT)(ALCcontext *context, ALsizei n, ALuint *buffers) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDELETEBUFFERSDIRECT)(ALCcontext *context, ALsizei n, const ALuint *buffers) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALISBUFFERDIRECT)(ALCcontext *context, ALuint buffer) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFERDATADIRECT)(ALCcontext *context, ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei samplerate) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFERFDIRECT)(ALCcontext *context, ALuint buffer, ALenum param, ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFER3FDIRECT)(ALCcontext *context, ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFERFVDIRECT)(ALCcontext *context, ALuint buffer, ALenum param, const ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFERIDIRECT)(ALCcontext *context, ALuint buffer, ALenum param, ALint value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFER3IDIRECT)(ALCcontext *context, ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALBUFFERIVDIRECT)(ALCcontext *context, ALuint buffer, ALenum param, const ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFERFDIRECT)(ALCcontext *context, ALuint buffer, ALenum param, ALfloat *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFER3FDIRECT)(ALCcontext *context, ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFERFVDIRECT)(ALCcontext *context, ALuint buffer, ALenum param, ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFERIDIRECT)(ALCcontext *context, ALuint buffer, ALenum param, ALint *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFER3IDIRECT)(ALCcontext *context, ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFERIVDIRECT)(ALCcontext *context, ALuint buffer, ALenum param, ALint *values) AL_API_NOEXCEPT17;
/* ALC_EXT_EFX */
typedef void (AL_APIENTRY *LPALGENEFFECTSDIRECT)(ALCcontext *context, ALsizei n, ALuint *effects) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDELETEEFFECTSDIRECT)(ALCcontext *context, ALsizei n, const ALuint *effects) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALISEFFECTDIRECT)(ALCcontext *context, ALuint effect) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALEFFECTIDIRECT)(ALCcontext *context, ALuint effect, ALenum param, ALint value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALEFFECTIVDIRECT)(ALCcontext *context, ALuint effect, ALenum param, const ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALEFFECTFDIRECT)(ALCcontext *context, ALuint effect, ALenum param, ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALEFFECTFVDIRECT)(ALCcontext *context, ALuint effect, ALenum param, const ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETEFFECTIDIRECT)(ALCcontext *context, ALuint effect, ALenum param, ALint *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETEFFECTIVDIRECT)(ALCcontext *context, ALuint effect, ALenum param, ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETEFFECTFDIRECT)(ALCcontext *context, ALuint effect, ALenum param, ALfloat *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETEFFECTFVDIRECT)(ALCcontext *context, ALuint effect, ALenum param, ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGENFILTERSDIRECT)(ALCcontext *context, ALsizei n, ALuint *filters) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDELETEFILTERSDIRECT)(ALCcontext *context, ALsizei n, const ALuint *filters) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALISFILTERDIRECT)(ALCcontext *context, ALuint filter) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALFILTERIDIRECT)(ALCcontext *context, ALuint filter, ALenum param, ALint value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALFILTERIVDIRECT)(ALCcontext *context, ALuint filter, ALenum param, const ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALFILTERFDIRECT)(ALCcontext *context, ALuint filter, ALenum param, ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALFILTERFVDIRECT)(ALCcontext *context, ALuint filter, ALenum param, const ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETFILTERIDIRECT)(ALCcontext *context, ALuint filter, ALenum param, ALint *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETFILTERIVDIRECT)(ALCcontext *context, ALuint filter, ALenum param, ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETFILTERFDIRECT)(ALCcontext *context, ALuint filter, ALenum param, ALfloat *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETFILTERFVDIRECT)(ALCcontext *context, ALuint filter, ALenum param, ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGENAUXILIARYEFFECTSLOTSDIRECT)(ALCcontext *context, ALsizei n, ALuint *effectslots) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDELETEAUXILIARYEFFECTSLOTSDIRECT)(ALCcontext *context, ALsizei n, const ALuint *effectslots) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALISAUXILIARYEFFECTSLOTDIRECT)(ALCcontext *context, ALuint effectslot) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTIDIRECT)(ALCcontext *context, ALuint effectslot, ALenum param, ALint value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTIVDIRECT)(ALCcontext *context, ALuint effectslot, ALenum param, const ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTFDIRECT)(ALCcontext *context, ALuint effectslot, ALenum param, ALfloat value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTFVDIRECT)(ALCcontext *context, ALuint effectslot, ALenum param, const ALfloat *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTIDIRECT)(ALCcontext *context, ALuint effectslot, ALenum param, ALint *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTIVDIRECT)(ALCcontext *context, ALuint effectslot, ALenum param, ALint *values) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTFDIRECT)(ALCcontext *context, ALuint effectslot, ALenum param, ALfloat *value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTFVDIRECT)(ALCcontext *context, ALuint effectslot, ALenum param, ALfloat *values) AL_API_NOEXCEPT17;
/* AL_EXT_BUFFER_DATA_STATIC */
typedef void (AL_APIENTRY *LPALBUFFERDATASTATICDIRECT)(ALCcontext *context, ALuint buffer, ALenum format, ALvoid *data, ALsizei size, ALsizei freq) AL_API_NOEXCEPT17;
/* AL_EXT_debug */
typedef void (AL_APIENTRY*LPALDEBUGMESSAGECALLBACKDIRECTEXT)(ALCcontext *context, ALDEBUGPROCEXT callback, void *userParam) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALDEBUGMESSAGEINSERTDIRECTEXT)(ALCcontext *context, ALenum source, ALenum type, ALuint id, ALenum severity, ALsizei length, const ALchar *message) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALDEBUGMESSAGECONTROLDIRECTEXT)(ALCcontext *context, ALenum source, ALenum type, ALenum severity, ALsizei count, const ALuint *ids, ALboolean enable) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALPUSHDEBUGGROUPDIRECTEXT)(ALCcontext *context, ALenum source, ALuint id, ALsizei length, const ALchar *message) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALPOPDEBUGGROUPDIRECTEXT)(ALCcontext *context) AL_API_NOEXCEPT17;
typedef ALuint (AL_APIENTRY*LPALGETDEBUGMESSAGELOGDIRECTEXT)(ALCcontext *context, ALuint count, ALsizei logBufSize, ALenum *sources, ALenum *types, ALuint *ids, ALenum *severities, ALsizei *lengths, ALchar *logBuf) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALOBJECTLABELDIRECTEXT)(ALCcontext *context, ALenum identifier, ALuint name, ALsizei length, const ALchar *label) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETOBJECTLABELDIRECTEXT)(ALCcontext *context, ALenum identifier, ALuint name, ALsizei bufSize, ALsizei *length, ALchar *label) AL_API_NOEXCEPT17;
typedef void* (AL_APIENTRY*LPALGETPOINTERDIRECTEXT)(ALCcontext *context, ALenum pname) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY*LPALGETPOINTERVDIRECTEXT)(ALCcontext *context, ALenum pname, void **values) AL_API_NOEXCEPT17;
/* AL_EXT_FOLDBACK */
typedef void (AL_APIENTRY *LPALREQUESTFOLDBACKSTARTDIRECT)(ALCcontext *context, ALenum mode, ALsizei count, ALsizei length, ALfloat *mem, LPALFOLDBACKCALLBACK callback) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALREQUESTFOLDBACKSTOPDIRECT)(ALCcontext *context) AL_API_NOEXCEPT17;
/* AL_SOFT_buffer_sub_data */
typedef void (AL_APIENTRY *LPALBUFFERSUBDATADIRECTSOFT)(ALCcontext *context, ALuint buffer, ALenum format, const ALvoid *data, ALsizei offset, ALsizei length) AL_API_NOEXCEPT17;
/* AL_SOFT_source_latency */
typedef void (AL_APIENTRY *LPALSOURCEDDIRECTSOFT)(ALCcontext*,ALuint,ALenum,ALdouble) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCE3DDIRECTSOFT)(ALCcontext*,ALuint,ALenum,ALdouble,ALdouble,ALdouble) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEDVDIRECTSOFT)(ALCcontext*,ALuint,ALenum,const ALdouble*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCEDDIRECTSOFT)(ALCcontext*,ALuint,ALenum,ALdouble*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCE3DDIRECTSOFT)(ALCcontext*,ALuint,ALenum,ALdouble*,ALdouble*,ALdouble*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCEDVDIRECTSOFT)(ALCcontext*,ALuint,ALenum,ALdouble*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEI64DIRECTSOFT)(ALCcontext*,ALuint,ALenum,ALint64SOFT) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCE3I64DIRECTSOFT)(ALCcontext*,ALuint,ALenum,ALint64SOFT,ALint64SOFT,ALint64SOFT) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEI64VDIRECTSOFT)(ALCcontext*,ALuint,ALenum,const ALint64SOFT*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCEI64DIRECTSOFT)(ALCcontext*,ALuint,ALenum,ALint64SOFT*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCE3I64DIRECTSOFT)(ALCcontext*,ALuint,ALenum,ALint64SOFT*,ALint64SOFT*,ALint64SOFT*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETSOURCEI64VDIRECTSOFT)(ALCcontext*,ALuint,ALenum,ALint64SOFT*) AL_API_NOEXCEPT17;
/* AL_SOFT_deferred_updates */
typedef void (AL_APIENTRY *LPALDEFERUPDATESDIRECTSOFT)(ALCcontext *context) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALPROCESSUPDATESDIRECTSOFT)(ALCcontext *context) AL_API_NOEXCEPT17;
/* AL_SOFT_source_resampler */
typedef const ALchar* (AL_APIENTRY *LPALGETSTRINGIDIRECTSOFT)(ALCcontext *context, ALenum pname, ALsizei index) AL_API_NOEXCEPT17;
/* AL_SOFT_events */
typedef void (AL_APIENTRY *LPALEVENTCONTROLDIRECTSOFT)(ALCcontext *context, ALsizei count, const ALenum *types, ALboolean enable) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALEVENTCALLBACKDIRECTSOFT)(ALCcontext *context, ALEVENTPROCSOFT callback, void *userParam) AL_API_NOEXCEPT17;
typedef void* (AL_APIENTRY *LPALGETPOINTERDIRECTSOFT)(ALCcontext *context, ALenum pname) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETPOINTERVDIRECTSOFT)(ALCcontext *context, ALenum pname, void **values) AL_API_NOEXCEPT17;
/* AL_SOFT_callback_buffer */
typedef void (AL_APIENTRY *LPALBUFFERCALLBACKDIRECTSOFT)(ALCcontext *context, ALuint buffer, ALenum format, ALsizei freq, ALBUFFERCALLBACKTYPESOFT callback, ALvoid *userptr) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFERPTRDIRECTSOFT)(ALCcontext *context, ALuint buffer, ALenum param, ALvoid **value) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFER3PTRDIRECTSOFT)(ALCcontext *context, ALuint buffer, ALenum param, ALvoid **value1, ALvoid **value2, ALvoid **value3) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETBUFFERPTRVDIRECTSOFT)(ALCcontext *context, ALuint buffer, ALenum param, ALvoid **values) AL_API_NOEXCEPT17;
/* AL_SOFT_source_start_delay */
typedef void (AL_APIENTRY *LPALSOURCEPLAYATTIMEDIRECTSOFT)(ALCcontext *context, ALuint source, ALint64SOFT start_time) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALSOURCEPLAYATTIMEVDIRECTSOFT)(ALCcontext *context, ALsizei n, const ALuint *sources, ALint64SOFT start_time) AL_API_NOEXCEPT17;
/* EAX */
typedef ALenum (AL_APIENTRY *LPEAXSETDIRECT)(ALCcontext *context, const struct _GUID *property_set_id, ALuint property_id, ALuint source_id, ALvoid *value, ALuint value_size) AL_API_NOEXCEPT17;
typedef ALenum (AL_APIENTRY *LPEAXGETDIRECT)(ALCcontext *context, const struct _GUID *property_set_id, ALuint property_id, ALuint source_id, ALvoid *value, ALuint value_size) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPEAXSETBUFFERMODEDIRECT)(ALCcontext *context, ALsizei n, const ALuint *buffers, ALint value) AL_API_NOEXCEPT17;
typedef ALenum (AL_APIENTRY *LPEAXGETBUFFERMODEDIRECT)(ALCcontext *context, ALuint buffer, ALint *pReserved) AL_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES
ALCvoid* ALC_APIENTRY alcGetProcAddress2(ALCdevice *device, const ALCchar *funcName) AL_API_NOEXCEPT;
void AL_APIENTRY alEnableDirect(ALCcontext *context, ALenum capability) AL_API_NOEXCEPT;
void AL_APIENTRY alDisableDirect(ALCcontext *context, ALenum capability) AL_API_NOEXCEPT;
ALboolean AL_APIENTRY alIsEnabledDirect(ALCcontext *context, ALenum capability) AL_API_NOEXCEPT;
void AL_APIENTRY alDopplerFactorDirect(ALCcontext *context, ALfloat value) AL_API_NOEXCEPT;
void AL_APIENTRY alSpeedOfSoundDirect(ALCcontext *context, ALfloat value) AL_API_NOEXCEPT;
void AL_APIENTRY alDistanceModelDirect(ALCcontext *context, ALenum distanceModel) AL_API_NOEXCEPT;
const ALchar* AL_APIENTRY alGetStringDirect(ALCcontext *context, ALenum param) AL_API_NOEXCEPT;
void AL_APIENTRY alGetBooleanvDirect(ALCcontext *context, ALenum param, ALboolean *values) AL_API_NOEXCEPT;
void AL_APIENTRY alGetIntegervDirect(ALCcontext *context, ALenum param, ALint *values) AL_API_NOEXCEPT;
void AL_APIENTRY alGetFloatvDirect(ALCcontext *context, ALenum param, ALfloat *values) AL_API_NOEXCEPT;
void AL_APIENTRY alGetDoublevDirect(ALCcontext *context, ALenum param, ALdouble *values) AL_API_NOEXCEPT;
ALboolean AL_APIENTRY alGetBooleanDirect(ALCcontext *context, ALenum param) AL_API_NOEXCEPT;
ALint AL_APIENTRY alGetIntegerDirect(ALCcontext *context, ALenum param) AL_API_NOEXCEPT;
ALfloat AL_APIENTRY alGetFloatDirect(ALCcontext *context, ALenum param) AL_API_NOEXCEPT;
ALdouble AL_APIENTRY alGetDoubleDirect(ALCcontext *context, ALenum param) AL_API_NOEXCEPT;
ALenum AL_APIENTRY alGetErrorDirect(ALCcontext *context) AL_API_NOEXCEPT;
ALboolean AL_APIENTRY alIsExtensionPresentDirect(ALCcontext *context, const ALchar *extname) AL_API_NOEXCEPT;
void* AL_APIENTRY alGetProcAddressDirect(ALCcontext *context, const ALchar *fname) AL_API_NOEXCEPT;
ALenum AL_APIENTRY alGetEnumValueDirect(ALCcontext *context, const ALchar *ename) AL_API_NOEXCEPT;
void AL_APIENTRY alListenerfDirect(ALCcontext *context, ALenum param, ALfloat value) AL_API_NOEXCEPT;
void AL_APIENTRY alListener3fDirect(ALCcontext *context, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) AL_API_NOEXCEPT;
void AL_APIENTRY alListenerfvDirect(ALCcontext *context, ALenum param, const ALfloat *values) AL_API_NOEXCEPT;
void AL_APIENTRY alListeneriDirect(ALCcontext *context, ALenum param, ALint value) AL_API_NOEXCEPT;
void AL_APIENTRY alListener3iDirect(ALCcontext *context, ALenum param, ALint value1, ALint value2, ALint value3) AL_API_NOEXCEPT;
void AL_APIENTRY alListenerivDirect(ALCcontext *context, ALenum param, const ALint *values) AL_API_NOEXCEPT;
void AL_APIENTRY alGetListenerfDirect(ALCcontext *context, ALenum param, ALfloat *value) AL_API_NOEXCEPT;
void AL_APIENTRY alGetListener3fDirect(ALCcontext *context, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) AL_API_NOEXCEPT;
void AL_APIENTRY alGetListenerfvDirect(ALCcontext *context, ALenum param, ALfloat *values) AL_API_NOEXCEPT;
void AL_APIENTRY alGetListeneriDirect(ALCcontext *context, ALenum param, ALint *value) AL_API_NOEXCEPT;
void AL_APIENTRY alGetListener3iDirect(ALCcontext *context, ALenum param, ALint *value1, ALint *value2, ALint *value3) AL_API_NOEXCEPT;
void AL_APIENTRY alGetListenerivDirect(ALCcontext *context, ALenum param, ALint *values) AL_API_NOEXCEPT;
void AL_APIENTRY alGenSourcesDirect(ALCcontext *context, ALsizei n, ALuint *sources) AL_API_NOEXCEPT;
void AL_APIENTRY alDeleteSourcesDirect(ALCcontext *context, ALsizei n, const ALuint *sources) AL_API_NOEXCEPT;
ALboolean AL_APIENTRY alIsSourceDirect(ALCcontext *context, ALuint source) AL_API_NOEXCEPT;
void AL_APIENTRY alSourcefDirect(ALCcontext *context, ALuint source, ALenum param, ALfloat value) AL_API_NOEXCEPT;
void AL_APIENTRY alSource3fDirect(ALCcontext *context, ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) AL_API_NOEXCEPT;
void AL_APIENTRY alSourcefvDirect(ALCcontext *context, ALuint source, ALenum param, const ALfloat *values) AL_API_NOEXCEPT;
void AL_APIENTRY alSourceiDirect(ALCcontext *context, ALuint source, ALenum param, ALint value) AL_API_NOEXCEPT;
void AL_APIENTRY alSource3iDirect(ALCcontext *context, ALuint source, ALenum param, ALint value1, ALint value2, ALint value3) AL_API_NOEXCEPT;
void AL_APIENTRY alSourceivDirect(ALCcontext *context, ALuint source, ALenum param, const ALint *values) AL_API_NOEXCEPT;
void AL_APIENTRY alGetSourcefDirect(ALCcontext *context, ALuint source, ALenum param, ALfloat *value) AL_API_NOEXCEPT;
void AL_APIENTRY alGetSource3fDirect(ALCcontext *context, ALuint source, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) AL_API_NOEXCEPT;
void AL_APIENTRY alGetSourcefvDirect(ALCcontext *context, ALuint source, ALenum param, ALfloat *values) AL_API_NOEXCEPT;
void AL_APIENTRY alGetSourceiDirect(ALCcontext *context, ALuint source, ALenum param, ALint *value) AL_API_NOEXCEPT;
void AL_APIENTRY alGetSource3iDirect(ALCcontext *context, ALuint source, ALenum param, ALint *value1, ALint *value2, ALint *value3) AL_API_NOEXCEPT;
void AL_APIENTRY alGetSourceivDirect(ALCcontext *context, ALuint source, ALenum param, ALint *values) AL_API_NOEXCEPT;
void AL_APIENTRY alSourcePlayDirect(ALCcontext *context, ALuint source) AL_API_NOEXCEPT;
void AL_APIENTRY alSourceStopDirect(ALCcontext *context, ALuint source) AL_API_NOEXCEPT;
void AL_APIENTRY alSourceRewindDirect(ALCcontext *context, ALuint source) AL_API_NOEXCEPT;
void AL_APIENTRY alSourcePauseDirect(ALCcontext *context, ALuint source) AL_API_NOEXCEPT;
void AL_APIENTRY alSourcePlayvDirect(ALCcontext *context, ALsizei n, const ALuint *sources) AL_API_NOEXCEPT;
void AL_APIENTRY alSourceStopvDirect(ALCcontext *context, ALsizei n, const ALuint *sources) AL_API_NOEXCEPT;
void AL_APIENTRY alSourceRewindvDirect(ALCcontext *context, ALsizei n, const ALuint *sources) AL_API_NOEXCEPT;
void AL_APIENTRY alSourcePausevDirect(ALCcontext *context, ALsizei n, const ALuint *sources) AL_API_NOEXCEPT;
void AL_APIENTRY alSourceQueueBuffersDirect(ALCcontext *context, ALuint source, ALsizei nb, const ALuint *buffers) AL_API_NOEXCEPT;
void AL_APIENTRY alSourceUnqueueBuffersDirect(ALCcontext *context, ALuint source, ALsizei nb, ALuint *buffers) AL_API_NOEXCEPT;
void AL_APIENTRY alGenBuffersDirect(ALCcontext *context, ALsizei n, ALuint *buffers) AL_API_NOEXCEPT;
void AL_APIENTRY alDeleteBuffersDirect(ALCcontext *context, ALsizei n, const ALuint *buffers) AL_API_NOEXCEPT;
ALboolean AL_APIENTRY alIsBufferDirect(ALCcontext *context, ALuint buffer) AL_API_NOEXCEPT;
void AL_APIENTRY alBufferDataDirect(ALCcontext *context, ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei samplerate) AL_API_NOEXCEPT;
void AL_APIENTRY alBufferfDirect(ALCcontext *context, ALuint buffer, ALenum param, ALfloat value) AL_API_NOEXCEPT;
void AL_APIENTRY alBuffer3fDirect(ALCcontext *context, ALuint buffer, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3) AL_API_NOEXCEPT;
void AL_APIENTRY alBufferfvDirect(ALCcontext *context, ALuint buffer, ALenum param, const ALfloat *values) AL_API_NOEXCEPT;
void AL_APIENTRY alBufferiDirect(ALCcontext *context, ALuint buffer, ALenum param, ALint value) AL_API_NOEXCEPT;
void AL_APIENTRY alBuffer3iDirect(ALCcontext *context, ALuint buffer, ALenum param, ALint value1, ALint value2, ALint value3) AL_API_NOEXCEPT;
void AL_APIENTRY alBufferivDirect(ALCcontext *context, ALuint buffer, ALenum param, const ALint *values) AL_API_NOEXCEPT;
void AL_APIENTRY alGetBufferfDirect(ALCcontext *context, ALuint buffer, ALenum param, ALfloat *value) AL_API_NOEXCEPT;
void AL_APIENTRY alGetBuffer3fDirect(ALCcontext *context, ALuint buffer, ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3) AL_API_NOEXCEPT;
void AL_APIENTRY alGetBufferfvDirect(ALCcontext *context, ALuint buffer, ALenum param, ALfloat *values) AL_API_NOEXCEPT;
void AL_APIENTRY alGetBufferiDirect(ALCcontext *context, ALuint buffer, ALenum param, ALint *value) AL_API_NOEXCEPT;
void AL_APIENTRY alGetBuffer3iDirect(ALCcontext *context, ALuint buffer, ALenum param, ALint *value1, ALint *value2, ALint *value3) AL_API_NOEXCEPT;
void AL_APIENTRY alGetBufferivDirect(ALCcontext *context, ALuint buffer, ALenum param, ALint *values) AL_API_NOEXCEPT;
void AL_APIENTRY alGenEffectsDirect(ALCcontext *context, ALsizei n, ALuint *effects) AL_API_NOEXCEPT;
void AL_APIENTRY alDeleteEffectsDirect(ALCcontext *context, ALsizei n, const ALuint *effects) AL_API_NOEXCEPT;
ALboolean AL_APIENTRY alIsEffectDirect(ALCcontext *context, ALuint effect) AL_API_NOEXCEPT;
void AL_APIENTRY alEffectiDirect(ALCcontext *context, ALuint effect, ALenum param, ALint iValue) AL_API_NOEXCEPT;
void AL_APIENTRY alEffectivDirect(ALCcontext *context, ALuint effect, ALenum param, const ALint *piValues) AL_API_NOEXCEPT;
void AL_APIENTRY alEffectfDirect(ALCcontext *context, ALuint effect, ALenum param, ALfloat flValue) AL_API_NOEXCEPT;
void AL_APIENTRY alEffectfvDirect(ALCcontext *context, ALuint effect, ALenum param, const ALfloat *pflValues) AL_API_NOEXCEPT;
void AL_APIENTRY alGetEffectiDirect(ALCcontext *context, ALuint effect, ALenum param, ALint *piValue) AL_API_NOEXCEPT;
void AL_APIENTRY alGetEffectivDirect(ALCcontext *context, ALuint effect, ALenum param, ALint *piValues) AL_API_NOEXCEPT;
void AL_APIENTRY alGetEffectfDirect(ALCcontext *context, ALuint effect, ALenum param, ALfloat *pflValue) AL_API_NOEXCEPT;
void AL_APIENTRY alGetEffectfvDirect(ALCcontext *context, ALuint effect, ALenum param, ALfloat *pflValues) AL_API_NOEXCEPT;
void AL_APIENTRY alGenFiltersDirect(ALCcontext *context, ALsizei n, ALuint *filters) AL_API_NOEXCEPT;
void AL_APIENTRY alDeleteFiltersDirect(ALCcontext *context, ALsizei n, const ALuint *filters) AL_API_NOEXCEPT;
ALboolean AL_APIENTRY alIsFilterDirect(ALCcontext *context, ALuint filter) AL_API_NOEXCEPT;
void AL_APIENTRY alFilteriDirect(ALCcontext *context, ALuint filter, ALenum param, ALint iValue) AL_API_NOEXCEPT;
void AL_APIENTRY alFilterivDirect(ALCcontext *context, ALuint filter, ALenum param, const ALint *piValues) AL_API_NOEXCEPT;
void AL_APIENTRY alFilterfDirect(ALCcontext *context, ALuint filter, ALenum param, ALfloat flValue) AL_API_NOEXCEPT;
void AL_APIENTRY alFilterfvDirect(ALCcontext *context, ALuint filter, ALenum param, const ALfloat *pflValues) AL_API_NOEXCEPT;
void AL_APIENTRY alGetFilteriDirect(ALCcontext *context, ALuint filter, ALenum param, ALint *piValue) AL_API_NOEXCEPT;
void AL_APIENTRY alGetFilterivDirect(ALCcontext *context, ALuint filter, ALenum param, ALint *piValues) AL_API_NOEXCEPT;
void AL_APIENTRY alGetFilterfDirect(ALCcontext *context, ALuint filter, ALenum param, ALfloat *pflValue) AL_API_NOEXCEPT;
void AL_APIENTRY alGetFilterfvDirect(ALCcontext *context, ALuint filter, ALenum param, ALfloat *pflValues) AL_API_NOEXCEPT;
void AL_APIENTRY alGenAuxiliaryEffectSlotsDirect(ALCcontext *context, ALsizei n, ALuint *effectslots) AL_API_NOEXCEPT;
void AL_APIENTRY alDeleteAuxiliaryEffectSlotsDirect(ALCcontext *context, ALsizei n, const ALuint *effectslots) AL_API_NOEXCEPT;
ALboolean AL_APIENTRY alIsAuxiliaryEffectSlotDirect(ALCcontext *context, ALuint effectslot) AL_API_NOEXCEPT;
void AL_APIENTRY alAuxiliaryEffectSlotiDirect(ALCcontext *context, ALuint effectslot, ALenum param, ALint iValue) AL_API_NOEXCEPT;
void AL_APIENTRY alAuxiliaryEffectSlotivDirect(ALCcontext *context, ALuint effectslot, ALenum param, const ALint *piValues) AL_API_NOEXCEPT;
void AL_APIENTRY alAuxiliaryEffectSlotfDirect(ALCcontext *context, ALuint effectslot, ALenum param, ALfloat flValue) AL_API_NOEXCEPT;
void AL_APIENTRY alAuxiliaryEffectSlotfvDirect(ALCcontext *context, ALuint effectslot, ALenum param, const ALfloat *pflValues) AL_API_NOEXCEPT;
void AL_APIENTRY alGetAuxiliaryEffectSlotiDirect(ALCcontext *context, ALuint effectslot, ALenum param, ALint *piValue) AL_API_NOEXCEPT;
void AL_APIENTRY alGetAuxiliaryEffectSlotivDirect(ALCcontext *context, ALuint effectslot, ALenum param, ALint *piValues) AL_API_NOEXCEPT;
void AL_APIENTRY alGetAuxiliaryEffectSlotfDirect(ALCcontext *context, ALuint effectslot, ALenum param, ALfloat *pflValue) AL_API_NOEXCEPT;
void AL_APIENTRY alGetAuxiliaryEffectSlotfvDirect(ALCcontext *context, ALuint effectslot, ALenum param, ALfloat *pflValues) AL_API_NOEXCEPT;
void AL_APIENTRY alBufferDataStaticDirect(ALCcontext *context, ALuint buffer, ALenum format, ALvoid *data, ALsizei size, ALsizei freq) AL_API_NOEXCEPT;
void AL_APIENTRY alDebugMessageCallbackDirectEXT(ALCcontext *context, ALDEBUGPROCEXT callback, void *userParam) AL_API_NOEXCEPT;
void AL_APIENTRY alDebugMessageInsertDirectEXT(ALCcontext *context, ALenum source, ALenum type, ALuint id, ALenum severity, ALsizei length, const ALchar *message) AL_API_NOEXCEPT;
void AL_APIENTRY alDebugMessageControlDirectEXT(ALCcontext *context, ALenum source, ALenum type, ALenum severity, ALsizei count, const ALuint *ids, ALboolean enable) AL_API_NOEXCEPT;
void AL_APIENTRY alPushDebugGroupDirectEXT(ALCcontext *context, ALenum source, ALuint id, ALsizei length, const ALchar *message) AL_API_NOEXCEPT;
void AL_APIENTRY alPopDebugGroupDirectEXT(ALCcontext *context) AL_API_NOEXCEPT;
ALuint AL_APIENTRY alGetDebugMessageLogDirectEXT(ALCcontext *context, ALuint count, ALsizei logBufSize, ALenum *sources, ALenum *types, ALuint *ids, ALenum *severities, ALsizei *lengths, ALchar *logBuf) AL_API_NOEXCEPT;
void AL_APIENTRY alObjectLabelDirectEXT(ALCcontext *context, ALenum identifier, ALuint name, ALsizei length, const ALchar *label) AL_API_NOEXCEPT;
void AL_APIENTRY alGetObjectLabelDirectEXT(ALCcontext *context, ALenum identifier, ALuint name, ALsizei bufSize, ALsizei *length, ALchar *label) AL_API_NOEXCEPT;
void* AL_APIENTRY alGetPointerDirectEXT(ALCcontext *context, ALenum pname) AL_API_NOEXCEPT;
void AL_APIENTRY alGetPointervDirectEXT(ALCcontext *context, ALenum pname, void **values) AL_API_NOEXCEPT;
void AL_APIENTRY alRequestFoldbackStartDirect(ALCcontext *context, ALenum mode, ALsizei count, ALsizei length, ALfloat *mem, LPALFOLDBACKCALLBACK callback) AL_API_NOEXCEPT;
void AL_APIENTRY alRequestFoldbackStopDirect(ALCcontext *context) AL_API_NOEXCEPT;
void AL_APIENTRY alBufferSubDataDirectSOFT(ALCcontext *context, ALuint buffer, ALenum format, const ALvoid *data, ALsizei offset, ALsizei length) AL_API_NOEXCEPT;
void AL_APIENTRY alSourcedDirectSOFT(ALCcontext *context, ALuint source, ALenum param, ALdouble value) AL_API_NOEXCEPT;
void AL_APIENTRY alSource3dDirectSOFT(ALCcontext *context, ALuint source, ALenum param, ALdouble value1, ALdouble value2, ALdouble value3) AL_API_NOEXCEPT;
void AL_APIENTRY alSourcedvDirectSOFT(ALCcontext *context, ALuint source, ALenum param, const ALdouble *values) AL_API_NOEXCEPT;
void AL_APIENTRY alGetSourcedDirectSOFT(ALCcontext *context, ALuint source, ALenum param, ALdouble *value) AL_API_NOEXCEPT;
void AL_APIENTRY alGetSource3dDirectSOFT(ALCcontext *context, ALuint source, ALenum param, ALdouble *value1, ALdouble *value2, ALdouble *value3) AL_API_NOEXCEPT;
void AL_APIENTRY alGetSourcedvDirectSOFT(ALCcontext *context, ALuint source, ALenum param, ALdouble *values) AL_API_NOEXCEPT;
void AL_APIENTRY alSourcei64DirectSOFT(ALCcontext *context, ALuint source, ALenum param, ALint64SOFT value) AL_API_NOEXCEPT;
void AL_APIENTRY alSource3i64DirectSOFT(ALCcontext *context, ALuint source, ALenum param, ALint64SOFT value1, ALint64SOFT value2, ALint64SOFT value3) AL_API_NOEXCEPT;
void AL_APIENTRY alSourcei64vDirectSOFT(ALCcontext *context, ALuint source, ALenum param, const ALint64SOFT *values) AL_API_NOEXCEPT;
void AL_APIENTRY alGetSourcei64DirectSOFT(ALCcontext *context, ALuint source, ALenum param, ALint64SOFT *value) AL_API_NOEXCEPT;
void AL_APIENTRY alGetSource3i64DirectSOFT(ALCcontext *context, ALuint source, ALenum param, ALint64SOFT *value1, ALint64SOFT *value2, ALint64SOFT *value3) AL_API_NOEXCEPT;
void AL_APIENTRY alGetSourcei64vDirectSOFT(ALCcontext *context, ALuint source, ALenum param, ALint64SOFT *values) AL_API_NOEXCEPT;
void AL_APIENTRY alDeferUpdatesDirectSOFT(ALCcontext *context) AL_API_NOEXCEPT;
void AL_APIENTRY alProcessUpdatesDirectSOFT(ALCcontext *context) AL_API_NOEXCEPT;
const ALchar* AL_APIENTRY alGetStringiDirectSOFT(ALCcontext *context, ALenum pname, ALsizei index) AL_API_NOEXCEPT;
void AL_APIENTRY alEventControlDirectSOFT(ALCcontext *context, ALsizei count, const ALenum *types, ALboolean enable) AL_API_NOEXCEPT;
void AL_APIENTRY alEventCallbackDirectSOFT(ALCcontext *context, ALEVENTPROCSOFT callback, void *userParam) AL_API_NOEXCEPT;
void* AL_APIENTRY alGetPointerDirectSOFT(ALCcontext *context, ALenum pname) AL_API_NOEXCEPT;
void AL_APIENTRY alGetPointervDirectSOFT(ALCcontext *context, ALenum pname, void **values) AL_API_NOEXCEPT;
void AL_APIENTRY alBufferCallbackDirectSOFT(ALCcontext *context, ALuint buffer, ALenum format, ALsizei freq, ALBUFFERCALLBACKTYPESOFT callback, ALvoid *userptr) AL_API_NOEXCEPT;
void AL_APIENTRY alGetBufferPtrDirectSOFT(ALCcontext *context, ALuint buffer, ALenum param, ALvoid **ptr) AL_API_NOEXCEPT;
void AL_APIENTRY alGetBuffer3PtrDirectSOFT(ALCcontext *context, ALuint buffer, ALenum param, ALvoid **ptr0, ALvoid **ptr1, ALvoid **ptr2) AL_API_NOEXCEPT;
void AL_APIENTRY alGetBufferPtrvDirectSOFT(ALCcontext *context, ALuint buffer, ALenum param, ALvoid **ptr) AL_API_NOEXCEPT;
void AL_APIENTRY alSourcePlayAtTimeDirectSOFT(ALCcontext *context, ALuint source, ALint64SOFT start_time) AL_API_NOEXCEPT;
void AL_APIENTRY alSourcePlayAtTimevDirectSOFT(ALCcontext *context, ALsizei n, const ALuint *sources, ALint64SOFT start_time) AL_API_NOEXCEPT;
ALenum AL_APIENTRY EAXSetDirect(ALCcontext *context, const struct _GUID *property_set_id, ALuint property_id, ALuint source_id, ALvoid *value, ALuint value_size) AL_API_NOEXCEPT;
ALenum AL_APIENTRY EAXGetDirect(ALCcontext *context, const struct _GUID *property_set_id, ALuint property_id, ALuint source_id, ALvoid *value, ALuint value_size) AL_API_NOEXCEPT;
ALboolean AL_APIENTRY EAXSetBufferModeDirect(ALCcontext *context, ALsizei n, const ALuint *buffers, ALint value) AL_API_NOEXCEPT;
ALenum AL_APIENTRY EAXGetBufferModeDirect(ALCcontext *context, ALuint buffer, ALint *pReserved) AL_API_NOEXCEPT;
#endif
#endif
#ifndef AL_SOFT_bformat_hoa
#define AL_SOFT_bformat_hoa
#define AL_UNPACK_AMBISONIC_ORDER_SOFT 0x199D
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/* NOLINTEND */
#endif #endif

View file

@ -2,6 +2,7 @@
#ifndef EFX_PRESETS_H #ifndef EFX_PRESETS_H
#define EFX_PRESETS_H #define EFX_PRESETS_H
/* NOLINTBEGIN */
#ifndef EFXEAXREVERBPROPERTIES_DEFINED #ifndef EFXEAXREVERBPROPERTIES_DEFINED
#define EFXEAXREVERBPROPERTIES_DEFINED #define EFXEAXREVERBPROPERTIES_DEFINED
@ -345,7 +346,7 @@ typedef struct {
/* Driving Presets */ /* Driving Presets */
#define EFX_REVERB_PRESET_DRIVING_COMMENTATOR \ #define EFX_REVERB_PRESET_DRIVING_COMMENTATOR \
{ 1.0000f, 0.0000f, 3.1623f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 } { 1.0000f, 0.0000f, 0.3162f, 0.5623f, 0.5012f, 2.4200f, 0.8800f, 0.6800f, 0.1995f, 0.0930f, { 0.0000f, 0.0000f, 0.0000f }, 0.2512f, 0.0170f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 1.0000f, 0.2500f, 0.0000f, 0.9886f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
#define EFX_REVERB_PRESET_DRIVING_PITGARAGE \ #define EFX_REVERB_PRESET_DRIVING_PITGARAGE \
{ 0.4287f, 0.5900f, 0.3162f, 0.7079f, 0.5623f, 1.7200f, 0.9300f, 0.8700f, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } { 0.4287f, 0.5900f, 0.3162f, 0.7079f, 0.5623f, 1.7200f, 0.9300f, 0.8700f, 0.5623f, 0.0000f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0160f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.1100f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
@ -399,4 +400,5 @@ typedef struct {
#define EFX_REVERB_PRESET_SMALLWATERROOM \ #define EFX_REVERB_PRESET_SMALLWATERROOM \
{ 1.0000f, 0.7000f, 0.3162f, 0.4477f, 1.0000f, 1.5100f, 1.2500f, 1.1400f, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 } { 1.0000f, 0.7000f, 0.3162f, 0.4477f, 1.0000f, 1.5100f, 1.2500f, 1.1400f, 0.8913f, 0.0200f, { 0.0000f, 0.0000f, 0.0000f }, 1.4125f, 0.0300f, { 0.0000f, 0.0000f, 0.0000f }, 0.1790f, 0.1500f, 0.8950f, 0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 }
/* NOLINTEND */
#endif /* EFX_PRESETS_H */ #endif /* EFX_PRESETS_H */

View file

@ -1,6 +1,8 @@
#ifndef AL_EFX_H #ifndef AL_EFX_H
#define AL_EFX_H #define AL_EFX_H
/* NOLINTBEGIN */
#include <float.h>
#include "alc.h" #include "alc.h"
#include "al.h" #include "al.h"
@ -203,80 +205,80 @@ extern "C" {
/* Effect object function types. */ /* Effect object function types. */
typedef void (AL_APIENTRY *LPALGENEFFECTS)(ALsizei, ALuint*); typedef void (AL_APIENTRY *LPALGENEFFECTS)(ALsizei, ALuint*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDELETEEFFECTS)(ALsizei, const ALuint*); typedef void (AL_APIENTRY *LPALDELETEEFFECTS)(ALsizei, const ALuint*) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALISEFFECT)(ALuint); typedef ALboolean (AL_APIENTRY *LPALISEFFECT)(ALuint) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALEFFECTI)(ALuint, ALenum, ALint); typedef void (AL_APIENTRY *LPALEFFECTI)(ALuint, ALenum, ALint) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALEFFECTIV)(ALuint, ALenum, const ALint*); typedef void (AL_APIENTRY *LPALEFFECTIV)(ALuint, ALenum, const ALint*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALEFFECTF)(ALuint, ALenum, ALfloat); typedef void (AL_APIENTRY *LPALEFFECTF)(ALuint, ALenum, ALfloat) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALEFFECTFV)(ALuint, ALenum, const ALfloat*); typedef void (AL_APIENTRY *LPALEFFECTFV)(ALuint, ALenum, const ALfloat*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETEFFECTI)(ALuint, ALenum, ALint*); typedef void (AL_APIENTRY *LPALGETEFFECTI)(ALuint, ALenum, ALint*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETEFFECTIV)(ALuint, ALenum, ALint*); typedef void (AL_APIENTRY *LPALGETEFFECTIV)(ALuint, ALenum, ALint*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETEFFECTF)(ALuint, ALenum, ALfloat*); typedef void (AL_APIENTRY *LPALGETEFFECTF)(ALuint, ALenum, ALfloat*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETEFFECTFV)(ALuint, ALenum, ALfloat*); typedef void (AL_APIENTRY *LPALGETEFFECTFV)(ALuint, ALenum, ALfloat*) AL_API_NOEXCEPT17;
/* Filter object function types. */ /* Filter object function types. */
typedef void (AL_APIENTRY *LPALGENFILTERS)(ALsizei, ALuint*); typedef void (AL_APIENTRY *LPALGENFILTERS)(ALsizei, ALuint*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDELETEFILTERS)(ALsizei, const ALuint*); typedef void (AL_APIENTRY *LPALDELETEFILTERS)(ALsizei, const ALuint*) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALISFILTER)(ALuint); typedef ALboolean (AL_APIENTRY *LPALISFILTER)(ALuint) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALFILTERI)(ALuint, ALenum, ALint); typedef void (AL_APIENTRY *LPALFILTERI)(ALuint, ALenum, ALint) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALFILTERIV)(ALuint, ALenum, const ALint*); typedef void (AL_APIENTRY *LPALFILTERIV)(ALuint, ALenum, const ALint*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALFILTERF)(ALuint, ALenum, ALfloat); typedef void (AL_APIENTRY *LPALFILTERF)(ALuint, ALenum, ALfloat) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALFILTERFV)(ALuint, ALenum, const ALfloat*); typedef void (AL_APIENTRY *LPALFILTERFV)(ALuint, ALenum, const ALfloat*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETFILTERI)(ALuint, ALenum, ALint*); typedef void (AL_APIENTRY *LPALGETFILTERI)(ALuint, ALenum, ALint*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETFILTERIV)(ALuint, ALenum, ALint*); typedef void (AL_APIENTRY *LPALGETFILTERIV)(ALuint, ALenum, ALint*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETFILTERF)(ALuint, ALenum, ALfloat*); typedef void (AL_APIENTRY *LPALGETFILTERF)(ALuint, ALenum, ALfloat*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETFILTERFV)(ALuint, ALenum, ALfloat*); typedef void (AL_APIENTRY *LPALGETFILTERFV)(ALuint, ALenum, ALfloat*) AL_API_NOEXCEPT17;
/* Auxiliary Effect Slot object function types. */ /* Auxiliary Effect Slot object function types. */
typedef void (AL_APIENTRY *LPALGENAUXILIARYEFFECTSLOTS)(ALsizei, ALuint*); typedef void (AL_APIENTRY *LPALGENAUXILIARYEFFECTSLOTS)(ALsizei, ALuint*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei, const ALuint*); typedef void (AL_APIENTRY *LPALDELETEAUXILIARYEFFECTSLOTS)(ALsizei, const ALuint*) AL_API_NOEXCEPT17;
typedef ALboolean (AL_APIENTRY *LPALISAUXILIARYEFFECTSLOT)(ALuint); typedef ALboolean (AL_APIENTRY *LPALISAUXILIARYEFFECTSLOT)(ALuint) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint); typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, const ALint*); typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, const ALint*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat); typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, const ALfloat*); typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, const ALfloat*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint*); typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, ALint*); typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, ALint*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat*); typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat*) AL_API_NOEXCEPT17;
typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, ALfloat*); typedef void (AL_APIENTRY *LPALGETAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, ALfloat*) AL_API_NOEXCEPT17;
#ifdef AL_ALEXT_PROTOTYPES #ifdef AL_ALEXT_PROTOTYPES
AL_API ALvoid AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects); AL_API void AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects); AL_API void AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects) AL_API_NOEXCEPT;
AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect); AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue); AL_API void AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint iValue) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *piValues); AL_API void AL_APIENTRY alEffectiv(ALuint effect, ALenum param, const ALint *piValues) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue); AL_API void AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *pflValues); AL_API void AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *pflValues) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue); AL_API void AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *piValue) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues); AL_API void AL_APIENTRY alGetEffectiv(ALuint effect, ALenum param, ALint *piValues) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue); AL_API void AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *pflValue) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues); AL_API void AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *pflValues) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters); AL_API void AL_APIENTRY alGenFilters(ALsizei n, ALuint *filters) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters); AL_API void AL_APIENTRY alDeleteFilters(ALsizei n, const ALuint *filters) AL_API_NOEXCEPT;
AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter); AL_API ALboolean AL_APIENTRY alIsFilter(ALuint filter) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue); AL_API void AL_APIENTRY alFilteri(ALuint filter, ALenum param, ALint iValue) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *piValues); AL_API void AL_APIENTRY alFilteriv(ALuint filter, ALenum param, const ALint *piValues) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue); AL_API void AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *pflValues); AL_API void AL_APIENTRY alFilterfv(ALuint filter, ALenum param, const ALfloat *pflValues) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue); AL_API void AL_APIENTRY alGetFilteri(ALuint filter, ALenum param, ALint *piValue) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues); AL_API void AL_APIENTRY alGetFilteriv(ALuint filter, ALenum param, ALint *piValues) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue); AL_API void AL_APIENTRY alGetFilterf(ALuint filter, ALenum param, ALfloat *pflValue) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues); AL_API void AL_APIENTRY alGetFilterfv(ALuint filter, ALenum param, ALfloat *pflValues) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots); AL_API void AL_APIENTRY alGenAuxiliaryEffectSlots(ALsizei n, ALuint *effectslots) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots); AL_API void AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots) AL_API_NOEXCEPT;
AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot); AL_API ALboolean AL_APIENTRY alIsAuxiliaryEffectSlot(ALuint effectslot) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue); AL_API void AL_APIENTRY alAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint iValue) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *piValues); AL_API void AL_APIENTRY alAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, const ALint *piValues) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue); AL_API void AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *pflValues); AL_API void AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, const ALfloat *pflValues) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue); AL_API void AL_APIENTRY alGetAuxiliaryEffectSloti(ALuint effectslot, ALenum param, ALint *piValue) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues); AL_API void AL_APIENTRY alGetAuxiliaryEffectSlotiv(ALuint effectslot, ALenum param, ALint *piValues) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue); AL_API void AL_APIENTRY alGetAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat *pflValue) AL_API_NOEXCEPT;
AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues); AL_API void AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, ALfloat *pflValues) AL_API_NOEXCEPT;
#endif #endif
/* Filter ranges and defaults. */ /* Filter ranges and defaults. */
@ -757,5 +759,6 @@ AL_API ALvoid AL_APIENTRY alGetAuxiliaryEffectSlotfv(ALuint effectslot, ALenum p
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif
/* NOLINTEND */
#endif /* AL_EFX_H */ #endif /* AL_EFX_H */

View file

@ -0,0 +1,38 @@
cmake_minimum_required(VERSION 3.12)
project(Launcher)
set(LAUNCHER_SOURCES "${CMAKE_SOURCE_DIR}/code/Launcher/launch_main.cpp")
if (WIN32)
set(LAUNCHER_SOURCES ${LAUNCHER_SOURCES}
"${CMAKE_SOURCE_DIR}/code/Launcher/launch_win32.cpp"
"${CMAKE_SOURCE_DIR}/code/sys/win_resource.rc")
else()
set(LAUNCHER_SOURCES ${LAUNCHER_SOURCES}
"${CMAKE_SOURCE_DIR}/code/Launcher/launch_linux.cpp")
endif()
function (create_launcher name type)
if (NOT BUILD_NO_CLIENT)
add_executable(openmohaa_launcher_${name} ${LAUNCHER_SOURCES})
target_include_directories(openmohaa_launcher_${name} PUBLIC "../qcommon")
target_compile_definitions(openmohaa_launcher_${name} PRIVATE NO_RC_MANIFEST=1 TARGET_GAME=${type})
target_compile_features(openmohaa_launcher_${name} PRIVATE cxx_std_17)
set_target_properties(openmohaa_launcher_${name} PROPERTIES OUTPUT_NAME "launch_openmohaa_${name}${TARGET_BIN_SUFFIX}")
INSTALL(TARGETS openmohaa_launcher_${name} DESTINATION ${CMAKE_INSTALL_BINDIR}/${BIN_INSTALL_SUBDIR})
endif()
#add_executable(omohaaded_launcher_${name} ${LAUNCHER_SOURCES})
#target_include_directories(omohaaded_launcher_${name} PUBLIC "../qcommon")
#target_compile_definitions(omohaaded_launcher_${name} PRIVATE NO_RC_MANIFEST=1 TARGET_GAME=${type} DEDICATED=1)
#target_compile_features(omohaaded_launcher_${name} PRIVATE cxx_std_17)
#set_target_properties(omohaaded_launcher_${name} PROPERTIES OUTPUT_NAME "launch_omohaaded_${name}${TARGET_BIN_SUFFIX}")
#
#INSTALL(TARGETS omohaaded_launcher_${name} DESTINATION ${CMAKE_INSTALL_BINDIR}/${PROJECT_INSTALL_SUBDIR})
endfunction()
create_launcher(base 0)
create_launcher(spearhead 1)
create_launcher(breakthrough 2)

View file

@ -1,6 +1,6 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2023 the OpenMoHAA team Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -20,15 +20,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=========================================================================== ===========================================================================
*/ */
// tr_vis.cpp: visibility culling // launch.h: Base interface for starting programs
#include "tr_local.h" #include "q_platform.h"
#include "tr_vis.h"
void R_VisDebug() { #include <filesystem>
// FIXME: unimplemented #include <string>
} #include <vector>
void R_VisDebugLoad(const char* szBSPName) { std::filesystem::path GetProgramLocation();
// FIXME: unimplemented void LaunchProgram(const std::filesystem::path& path, const std::vector<std::string>& argumentList);
}

View file

@ -0,0 +1,80 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// main.cpp: Windows implementation of the launcher
#include "launch.h"
#include <unistd.h>
#include <spawn.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string>
#include <iostream>
extern "C" char** environ;
std::filesystem::path GetProgramLocation()
{
char path[FILENAME_MAX];
ssize_t count = readlink("/proc/self/exe", path, FILENAME_MAX);
return std::filesystem::path(std::string(path, (count > 0) ? count : 0)).parent_path();
}
void LaunchProgram(const std::filesystem::path& path, const std::vector<std::string>& argumentList)
{
pid_t pid;
std::string pathString = path.string();
size_t argCount = argumentList.size();
char** argv;
int status;
argv = new char*[argCount + 2];
argv[0] = (char*)pathString.c_str();
for (size_t i = 0; i < argCount; i++) {
argv[i + 1] = (char*)argumentList[i].c_str();
}
argv[argCount + 1] = NULL;
//status = posix_spawn(&pid, pathString.c_str(), NULL, NULL, argv, environ);
//delete[] argv;
//if (status != 0) {
// std::cout << "posix_spawn returned error: " << status << std::endl;
// return;
//}
//
// Using execve rather than posix_spawn
// This replaces the current process that is not needed anyway
//
status = execve(pathString.c_str(), argv, environ);
delete[] argv;
if (status == -1) {
std::cout << "posix_spawn returned error: " << errno << std::endl;
return;
}
waitpid(pid, NULL, 0);
}

View file

@ -0,0 +1,67 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// main.cpp: The launcher
#include "launch.h"
#include <iostream>
#include <string>
#include <vector>
const char* targetGameList[] =
{
"Base",
"Spearhead",
"Breakthrough"
};
int main(int argc, const char* argv[]) {
std::vector<std::string> argumentList;
#if !defined(DEDICATED) || !DEDICATED
const char* programName = "openmohaa" ARCH_SUFFIX DLL_SUFFIX EXE_EXT;
#else
const char* programName = "omohaaded" ARCH_SUFFIX DLL_SUFFIX EXE_EXT;
#endif
argumentList.push_back("+set");
argumentList.push_back("com_target_game");
argumentList.push_back(std::to_string(TARGET_GAME));
for (size_t i = 1; i < argc; i++) {
argumentList.push_back(argv[i]);
}
std::cout << "Using the target game: " << targetGameList[TARGET_GAME] << std::endl;
std::cout << std::endl;
std::cout << "Expected program name: " << programName << std::endl;
const std::filesystem::path programLocation = GetProgramLocation();
const std::filesystem::path programPath = programLocation / programName;
std::cout << "Program location: " << programLocation << std::endl;
std::cout << "Expected path: " << programPath << std::endl;
LaunchProgram(programPath, argumentList);
return 0;
}

View file

@ -0,0 +1,87 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// main.cpp: Windows implementation of the launcher
#include "launch.h"
#include <Windows.h>
#include <string>
#include <iostream>
std::filesystem::path GetProgramLocation()
{
wchar_t path[FILENAME_MAX] = { 0 };
GetModuleFileNameW(nullptr, path, FILENAME_MAX);
return std::filesystem::path(path).parent_path();
}
void LaunchProgram(const std::filesystem::path& path, const std::vector<std::string>& argumentList)
{
PROCESS_INFORMATION processInfo;
STARTUPINFOW startupInfo;
BOOL returnValue;
std::wstring osCommandLine;
std::wstring commandLine;
size_t argCount = argumentList.size();
memset(&processInfo, 0, sizeof(processInfo));
memset(&startupInfo, 0, sizeof(startupInfo));
startupInfo.cb = sizeof(startupInfo);
for (size_t i = 0; i < argCount; i++) {
commandLine += L"\"";
commandLine += std::wstring(argumentList[i].begin(), argumentList[i].end());
commandLine += L"\"";
if (i != argCount - 1) {
commandLine += L" ";
}
}
osCommandLine = path.wstring();
osCommandLine += L" ";
osCommandLine += commandLine;
returnValue = CreateProcessW(
path.wstring().c_str(),
(LPWSTR)osCommandLine.c_str(),
NULL,
NULL,
FALSE,
0,
NULL,
std::filesystem::current_path().wstring().c_str(),
&startupInfo,
&processInfo
);
if (!returnValue) {
std::cout << "Error in CreateProcess: " << GetLastError() << std::endl;
return;
}
WaitForSingleObject(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}

View file

@ -933,10 +933,13 @@ static void waitToApplyUpdates(void)
OS forcibly closes the pipe), we will unblock. Then we can loop on OS forcibly closes the pipe), we will unblock. Then we can loop on
kill() until the process is truly gone. */ kill() until the process is truly gone. */
int x = 0; int x = 0;
struct timespec req;
req.tv_sec = 0;
req.tv_nsec = 100000000;
read(3, &x, sizeof (x)); read(3, &x, sizeof (x));
info("Pipe has closed, waiting for process to fully go away now."); info("Pipe has closed, waiting for process to fully go away now.");
while (kill(options.waitforprocess, 0) == 0) { while (kill(options.waitforprocess, 0) == 0) {
usleep(100000); nanosleep(&req, NULL);
} }
#endif #endif
} }

View file

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.12)
project(cgame) project(cgame)
# Shared source files for modules # Shared source files for modules
@ -27,16 +27,11 @@ target_compile_features(cgame PUBLIC cxx_nullptr)
target_compile_features(cgame PUBLIC c_variadic_macros) target_compile_features(cgame PUBLIC c_variadic_macros)
target_link_libraries(cgame PUBLIC qcommon) target_link_libraries(cgame PUBLIC qcommon)
set_target_properties(cgame PROPERTIES PREFIX "${TARGET_PLATFORM_PREFIX}") set_target_properties(cgame PROPERTIES PREFIX "")
set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_ARCH_SUFFIX}") set_target_properties(cgame PROPERTIES OUTPUT_NAME "cgame${TARGET_BIN_SUFFIX}")
set_target_properties(cgame PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_BASE_GAME}")
INSTALL( INSTALL(TARGETS cgame DESTINATION ${CMAKE_INSTALL_LIBDIR}/${LIB_INSTALL_SUBDIR})
TARGETS cgame
LIBRARY DESTINATION "${TARGET_BASE_GAME}"
RUNTIME DESTINATION "${TARGET_BASE_GAME}"
)
if(MSVC) if(MSVC)
INSTALL(FILES $<TARGET_PDB_FILE:cgame> DESTINATION "${TARGET_BASE_GAME}" OPTIONAL) INSTALL(FILES $<TARGET_PDB_FILE:cgame> DESTINATION ${CMAKE_INSTALL_LIBDIR}/${LIB_INSTALL_SUBDIR} OPTIONAL)
endif() endif()

View file

@ -113,7 +113,7 @@ void CG_ArchiveModelHandle(MemArchiver& archiver, qhandle_t* handle)
if (tmp.length()) { if (tmp.length()) {
*handle = cgi.R_RegisterModel(tmp.c_str()); *handle = cgi.R_RegisterModel(tmp.c_str());
} else { } else {
*handle = NULL; *handle = (qhandle_t)0;
} }
} else { } else {
if (*handle) { if (*handle) {
@ -135,7 +135,7 @@ void CG_ArchiveShaderHandle(MemArchiver& archiver, qhandle_t* handle)
if (tmp.length()) { if (tmp.length()) {
*handle = cgi.R_RegisterShader(tmp.c_str()); *handle = cgi.R_RegisterShader(tmp.c_str());
} else { } else {
*handle = NULL; *handle = (qhandle_t)0;
} }
} else { } else {
if (*handle) { if (*handle) {
@ -163,7 +163,7 @@ void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref)
archiver.ArchiveVec3(ref->axis[2]); archiver.ArchiveVec3(ref->axis[2]);
archiver.ArchiveBoolean(&ref->nonNormalizedAxes); archiver.ArchiveBoolean(&ref->nonNormalizedAxes);
archiver.ArchiveVec3(ref->origin); archiver.ArchiveVec3(ref->origin);
archiver.ArchiveRaw(ref->frameInfo, 192); archiver.ArchiveRaw(ref->frameInfo, sizeof(ref->frameInfo));
archiver.ArchiveFloat(&ref->actionWeight); archiver.ArchiveFloat(&ref->actionWeight);
archiver.ArchiveShort(&ref->wasframe); archiver.ArchiveShort(&ref->wasframe);
archiver.ArchiveFloat(&ref->scale); archiver.ArchiveFloat(&ref->scale);
@ -171,7 +171,7 @@ void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref)
archiver.ArchiveInteger(&ref->skinNum); archiver.ArchiveInteger(&ref->skinNum);
CG_ArchiveShaderHandle(archiver, &ref->customShader); CG_ArchiveShaderHandle(archiver, &ref->customShader);
archiver.ArchiveRaw(ref->shaderRGBA, 4); archiver.ArchiveRaw(ref->shaderRGBA, sizeof(ref->shaderRGBA));
archiver.ArchiveFloat(ref->shaderTexCoord); archiver.ArchiveFloat(ref->shaderTexCoord);
archiver.ArchiveFloat(&ref->shaderTexCoord[1]); archiver.ArchiveFloat(&ref->shaderTexCoord[1]);
archiver.ArchiveFloat(&ref->shaderTime); archiver.ArchiveFloat(&ref->shaderTime);

View file

@ -196,7 +196,8 @@ Event EV_Client_SetColorVelocity
"rVel gVel bVel", "rVel gVel bVel",
"Set the color velocity of the spawned dlight tempmodel" "Set the color velocity of the spawned dlight tempmodel"
); );
Event EV_Client_SetRandomVelocity( Event EV_Client_SetRandomVelocity
(
"randvel", "randvel",
EV_DEFAULT, EV_DEFAULT,
"SfFSfFSfF", "SfFSfFSfF",
@ -210,7 +211,8 @@ Event EV_Client_SetRandomVelocity(
"without randomness.\n" "without randomness.\n"
"This velocity is applied using the world axis" "This velocity is applied using the world axis"
); );
Event EV_Client_SetRandomVelocityAlongAxis( Event EV_Client_SetRandomVelocityAlongAxis
(
"randvelaxis", "randvelaxis",
EV_DEFAULT, EV_DEFAULT,
"SfFSfFSfF", "SfFSfFSfF",
@ -225,6 +227,14 @@ Event EV_Client_SetRandomVelocityAlongAxis(
"without randomness.\n" "without randomness.\n"
"This velocity is applied using the parent axis" "This velocity is applied using the parent axis"
); );
Event EV_Client_NoTagAxis
(
"notagaxis",
EV_DEFAULT,
NULL,
NULL,
"Forces the effect to use the model's orientation for randvelaxis and offsetalongaxis"
);
Event EV_Client_SetAccel Event EV_Client_SetAccel
( (
"accel", "accel",
@ -554,7 +564,16 @@ Event EV_Client_LoopSound
EV_DEFAULT, EV_DEFAULT,
"sFFf", "sFFf",
"soundName volume min_distance pitch", "soundName volume min_distance pitch",
"Play the specifed sound as a looping sound" "Play the specified sound as a looping sound"
);
// Added in 2.0
Event EV_Client_StopLoopSound
(
"stoploopsound",
EV_DEFAULT,
NULL,
NULL,
"Stop the looping sound"
); );
Event EV_Client_Cache Event EV_Client_Cache
( (
@ -975,7 +994,7 @@ Event EV_Client_BounceDecal(
"maxamount temporary", "maxamount temporary",
"Put a mark when the tempmodel bounces and hits a surface\n" "Put a mark when the tempmodel bounces and hits a surface\n"
"maxamount = Max amount of decals to make when bouncing\n" "maxamount = Max amount of decals to make when bouncing\n"
"temporary = specify 1 for a temporary mark that only appears for a short time, 0 for a decal that stays aroung " "temporary = specify 1 for a temporary mark that only appears for a short time, 0 for a decal that stays around "
"longer (default is 0)\n" "longer (default is 0)\n"
); );
Event EV_Client_SetDecalRadius Event EV_Client_SetDecalRadius
@ -1075,6 +1094,15 @@ Event EV_Client_Print
"string", "string",
"Prints a string." "Prints a string."
); );
// Added in 2.0
Event EV_Client_PrintDeathMsg
(
"printdeathmsg",
EV_DEFAULT,
"sssss",
"msg1, msg2, killer, victim, deathType",
"Prints a death message string. Used to allow death messages to appear in their correct language on client machines.."
);
Event EV_Client_SetVolumetric Event EV_Client_SetVolumetric
( (
"volumetric", "volumetric",
@ -1112,7 +1140,7 @@ Event EV_Client_SetAlignStretch(
EV_DEFAULT, EV_DEFAULT,
"F", "F",
"scaleMultiplier", "scaleMultiplier",
"Aligns the temp model to the direction of travel, and stretches it betwen the last and current positions.\n" "Aligns the temp model to the direction of travel, and stretches it between the last and current positions.\n"
); );
Event EV_Client_SetClampVelocity Event EV_Client_SetClampVelocity
( (
@ -1185,6 +1213,14 @@ Event EV_Client_SFXStartDelayed
"fDelay sCommand arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8", "fDelay sCommand arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8",
"Used for adding commands to a special effect with a time delay" "Used for adding commands to a special effect with a time delay"
); );
Event EV_Client_PlayForceFeedback
(
"playforcefeedback",
EV_DEFAULT,
"s",
"effectname",
"Starts a force feedback effect."
);
EffectsEventQueueNode EffectsEventQueue; EffectsEventQueueNode EffectsEventQueue;
@ -1221,6 +1257,7 @@ CLASS_DECLARATION(Listener, ClientGameCommandManager, NULL) {
{&EV_Client_SetColorVelocity, &ClientGameCommandManager::SetAngularVelocity }, {&EV_Client_SetColorVelocity, &ClientGameCommandManager::SetAngularVelocity },
{&EV_Client_SetRandomVelocity, &ClientGameCommandManager::SetRandomVelocity }, {&EV_Client_SetRandomVelocity, &ClientGameCommandManager::SetRandomVelocity },
{&EV_Client_SetRandomVelocityAlongAxis, &ClientGameCommandManager::SetRandomVelocityAlongAxis}, {&EV_Client_SetRandomVelocityAlongAxis, &ClientGameCommandManager::SetRandomVelocityAlongAxis},
{&EV_Client_NoTagAxis, &ClientGameCommandManager::SetNoTagAxis },
{&EV_Client_SetAccel, &ClientGameCommandManager::SetAccel }, {&EV_Client_SetAccel, &ClientGameCommandManager::SetAccel },
{&EV_Client_SetFriction, &ClientGameCommandManager::SetFriction }, {&EV_Client_SetFriction, &ClientGameCommandManager::SetFriction },
{&EV_Client_SetSpin, &ClientGameCommandManager::SetSpin }, {&EV_Client_SetSpin, &ClientGameCommandManager::SetSpin },
@ -1250,6 +1287,7 @@ CLASS_DECLARATION(Listener, ClientGameCommandManager, NULL) {
{&EV_Client_StopSound, &ClientGameCommandManager::StopSound }, {&EV_Client_StopSound, &ClientGameCommandManager::StopSound },
{&EV_Client_StopAliasChannel, &ClientGameCommandManager::StopAliasChannel }, {&EV_Client_StopAliasChannel, &ClientGameCommandManager::StopAliasChannel },
{&EV_Client_LoopSound, &ClientGameCommandManager::LoopSound }, {&EV_Client_LoopSound, &ClientGameCommandManager::LoopSound },
{&EV_Client_StopLoopSound, &ClientGameCommandManager::StopLoopSound },
{&EV_Client_Cache, &ClientGameCommandManager::Cache }, {&EV_Client_Cache, &ClientGameCommandManager::Cache },
{&EV_Client_CacheImage, &ClientGameCommandManager::CacheImage }, {&EV_Client_CacheImage, &ClientGameCommandManager::CacheImage },
{&EV_Client_CacheFont, &ClientGameCommandManager::CacheFont }, {&EV_Client_CacheFont, &ClientGameCommandManager::CacheFont },
@ -1312,6 +1350,7 @@ CLASS_DECLARATION(Listener, ClientGameCommandManager, NULL) {
{&EV_Client_SetClampVelocity, &ClientGameCommandManager::SetClampVel }, {&EV_Client_SetClampVelocity, &ClientGameCommandManager::SetClampVel },
{&EV_Client_SetClampVelocityAxis, &ClientGameCommandManager::SetClampVelAxis }, {&EV_Client_SetClampVelocityAxis, &ClientGameCommandManager::SetClampVelAxis },
{&EV_Client_Print, &ClientGameCommandManager::Print }, {&EV_Client_Print, &ClientGameCommandManager::Print },
{&EV_Client_PrintDeathMsg, &ClientGameCommandManager::PrintDeathMsg },
{&EV_Client_EyeLimits, &ClientGameCommandManager::SetEyeLimits }, {&EV_Client_EyeLimits, &ClientGameCommandManager::SetEyeLimits },
{&EV_Client_EyeMovement, &ClientGameCommandManager::SetEyeMovement }, {&EV_Client_EyeMovement, &ClientGameCommandManager::SetEyeMovement },
{&EV_Client_SFXStart, &ClientGameCommandManager::StartSFX }, {&EV_Client_SFXStart, &ClientGameCommandManager::StartSFX },
@ -1383,9 +1422,11 @@ qboolean ClientGameCommandManager::PostEventForEntity(Event *ev, float fWait)
EffectsEventQueueNode *node; EffectsEventQueueNode *node;
int inttime; int inttime;
if (!m_fEventWait || current_entity_number < 0) { if (m_fEventWait < 0 || current_entity_number < 0) {
if (!str::icmp(ev->getName(), ")")) { if (m_fEventWait != 0.0) {
m_fEventWait = 0.0; if (!str::icmp(ev->getName(), ")")) {
m_fEventWait = 0.0;
}
} }
delete ev; delete ev;
@ -1402,7 +1443,7 @@ qboolean ClientGameCommandManager::PostEventForEntity(Event *ev, float fWait)
event = EffectsEventQueue.next; event = EffectsEventQueue.next;
inttime = EVENT_msec + (fWait * 1000.0f + 0.5f); inttime = EVENT_msec + (fWait * 1000.0f + 0.5f);
while (event != &EffectsEventQueue && inttime > event->inttime) { while (event != &EffectsEventQueue && inttime >= event->inttime) {
event = event->next; event = event->next;
} }
@ -1438,8 +1479,8 @@ void ClientGameCommandManager::SetBaseAndAmplitude(Event *ev, Vector& base, Vect
base[j] = ev->GetFloat(i++); base[j] = ev->GetFloat(i++);
amplitude[j] = ev->GetFloat(i++); amplitude[j] = ev->GetFloat(i++);
} else { } else {
base[j] = 0.0; base[j] = atof(org.c_str());
amplitude[j] = atof(org.c_str()); amplitude[j] = 0.0;
} }
} }
} }
@ -1462,6 +1503,13 @@ void ClientGameCommandManager::Print(Event *ev)
} }
} }
void ClientGameCommandManager::PrintDeathMsg(Event* ev)
{
if (current_entity) {
cgi.DPrintf("%d:%s\n", current_entity->entityNumber, ev->GetString(1).c_str());
}
}
qboolean ClientGameCommandManager::IsBlockCommand(const str& name) qboolean ClientGameCommandManager::IsBlockCommand(const str& name)
{ {
if (!str::icmp(name, "originspawn")) { if (!str::icmp(name, "originspawn")) {
@ -1541,7 +1589,6 @@ void ClientGameCommandManager::CommandDelay(Event *ev)
ev1->AddValue(ev->GetValue(i)); ev1->AddValue(ev->GetValue(i));
} }
delay = ev->GetFloat(1) * 1000;
if (current_entity_number != -1) { if (current_entity_number != -1) {
PostEventForEntity(ev1, fWait); PostEventForEntity(ev1, fWait);
} else { } else {
@ -1551,6 +1598,16 @@ void ClientGameCommandManager::CommandDelay(Event *ev)
current_tiki->name current_tiki->name
); );
} }
if (IsBlockCommand(eventName)) {
m_fEventWait = fWait;
} else {
m_fEventWait = 0;
}
if (current_entity_number == -1 && m_fEventWait > 0) {
m_fEventWait = -1;
}
} }
void ClientGameCommandManager::StartSFX(Event *ev) void ClientGameCommandManager::StartSFX(Event *ev)
@ -2157,7 +2214,9 @@ void ClientGameCommandManager::SetInwardSphere(Event *ev)
} }
m_spawnthing->cgd.flags |= T_INWARDSPHERE; m_spawnthing->cgd.flags |= T_INWARDSPHERE;
m_spawnthing->sphereRadius = ev->GetFloat(1); if (ev->NumArgs() > 0) {
m_spawnthing->sphereRadius = ev->GetFloat(1);
}
} }
//============= //=============
@ -2586,7 +2645,9 @@ void ClientGameCommandManager::SetColorRange(Event *ev)
return; return;
} }
// FIXME: unused stub?? //
// Unused
//
} }
//============= //=============
@ -2666,6 +2727,15 @@ void ClientGameCommandManager::SetRandomVelocityAlongAxis(Event *ev)
SetRandomVelocity(ev); SetRandomVelocity(ev);
} }
void ClientGameCommandManager::SetNoTagAxis(Event* ev)
{
if (!m_spawnthing) {
return;
}
m_spawnthing->cgd.flags2 |= T2_NOTAGAXIS;
}
void ClientGameCommandManager::SetRadialVelocity(Event *ev) void ClientGameCommandManager::SetRadialVelocity(Event *ev)
{ {
if (!m_spawnthing) { if (!m_spawnthing) {
@ -2803,7 +2873,9 @@ void ClientGameCommandManager::SetAccel(Event *ev)
m_spawnthing->cgd.accel[1] = ev->GetFloat(2); m_spawnthing->cgd.accel[1] = ev->GetFloat(2);
m_spawnthing->cgd.accel[2] = ev->GetFloat(3); m_spawnthing->cgd.accel[2] = ev->GetFloat(3);
m_spawnthing->cgd.flags2 |= T2_ACCEL; if (!(m_spawnthing->cgd.flags & T_SWARM)) {
m_spawnthing->cgd.flags2 |= T2_ACCEL;
}
} }
void ClientGameCommandManager::SetFriction(Event *ev) void ClientGameCommandManager::SetFriction(Event *ev)
@ -3032,7 +3104,7 @@ spawnthing_t *ClientGameCommandManager::InitializeSpawnthing(spawnthing_t *sp)
sp->cgd.parent = -1; sp->cgd.parent = -1;
sp->cgd.tiki = nullptr; sp->cgd.tiki = nullptr;
sp->cgd.lightstyle = -1; sp->cgd.lightstyle = -1;
sp->cgd.physicsRate = 10; sp->cgd.physicsRate = cg_effect_physicsrate->integer;
sp->cgd.shadername = "beamshader"; sp->cgd.shadername = "beamshader";
sp->cgd.decal_orientation = 0; sp->cgd.decal_orientation = 0;
sp->cgd.decal_radius = 10; sp->cgd.decal_radius = 10;
@ -3794,7 +3866,7 @@ void ClientGameCommandManager::PlaySound(
} }
if (!name || !soundAlias) { if (!name || !soundAlias) {
Com_Printf( cgi.DPrintf(
"\nERROR PlaySound: %s needs an alias in ubersound.scr or uberdialog.scr - Please fix.\n", "\nERROR PlaySound: %s needs an alias in ubersound.scr or uberdialog.scr - Please fix.\n",
sound_name.c_str() sound_name.c_str()
); );
@ -3851,7 +3923,7 @@ void ClientGameCommandManager::PlaySound(
} else { } else {
if (debugSound->integer) { if (debugSound->integer) {
Com_Printf( Com_Printf(
"\nWARNING: OVERRIDE OVERRIDE OVERRIDESound %s had all its parm overriden by code.\n\n", "\nWARNING: OVERRIDE OVERRIDE OVERRIDESound %s had all its parm overridden by code.\n\n",
sound_name.c_str() sound_name.c_str()
); );
} }
@ -3965,6 +4037,9 @@ void ClientGameCommandManager::StopSound(Event *ev)
cgi.S_StopSound(current_entity_number, channel); cgi.S_StopSound(current_entity_number, channel);
} }
//===============
// StopAliasChannel
//===============
void ClientGameCommandManager::StopAliasChannel(Event *ev) void ClientGameCommandManager::StopAliasChannel(Event *ev)
{ {
str sound_name; str sound_name;
@ -3991,7 +4066,7 @@ void ClientGameCommandManager::StopAliasChannel(Event *ev)
} }
if (!name || !soundAlias) { if (!name || !soundAlias) {
Com_Printf("\nERROR stopaliaschannel: couldn't find alias %s\n", sound_name.c_str()); cgi.DPrintf("\nERROR stopaliaschannel: couldn't find alias %s\n", sound_name.c_str());
return; return;
} }
@ -4060,6 +4135,54 @@ void ClientGameCommandManager::LoopSound(Event *ev)
current_centity->tikiLoopSoundFlags = 0; current_centity->tikiLoopSoundFlags = 0;
} }
//===============
// StopLoopSound
//===============
void ClientGameCommandManager::StopLoopSound(Event* ev)
{
if (!current_centity) {
cgi.DPrintf("CCM::StopLoopSound : StopLoopSound in %s without current_centity\n", cgi.TIKI_Name(current_tiki));
return;
}
cgi.DPrintf("\n\nClientGameCommandManager::StopLoopSound\n\n");
current_centity->tikiLoopSound = (sfxHandle_t)0;
}
//===============
// CacheImageResource
//===============
void CacheImageResource(const char* stuff) {
str real_stuff;
char filename[1024];
if (cgi.fsDebug->integer == 2) {
Com_Printf("client cacheimage: %s\n", stuff);
}
Q_strncpyz(filename, stuff, sizeof(filename));
cgi.FS_CanonicalFilename(filename);
cgi.R_RegisterShaderNoMip(filename);
}
//===============
// CacheFontResource
//===============
void CacheFontResource(const char* stuff) {
str real_stuff;
char filename[1024];
if (cgi.fsDebug->integer == 2) {
Com_Printf("client cacheimage: %s\n", stuff);
}
Q_strncpyz(filename, stuff, sizeof(filename));
cgi.FS_CanonicalFilename(filename);
cgi.R_LoadFont(filename);
}
//=============== //===============
// CacheResource // CacheResource
//=============== //===============
@ -4099,12 +4222,12 @@ void ClientGameCommandManager::Cache(Event *ev)
void ClientGameCommandManager::CacheImage(Event *ev) void ClientGameCommandManager::CacheImage(Event *ev)
{ {
// FIXME: stub CacheImageResource(ev->GetString(1).c_str());
} }
void ClientGameCommandManager::CacheFont(Event *ev) void ClientGameCommandManager::CacheFont(Event *ev)
{ {
// FIXME: stub CacheFontResource(ev->GetString(1).c_str());
} }
//=============== //===============
@ -4112,15 +4235,16 @@ void ClientGameCommandManager::CacheFont(Event *ev)
//=============== //===============
void AliasResource(dtiki_t *pmdl, const char *alias, const char *realname, const char *parameters) void AliasResource(dtiki_t *pmdl, const char *alias, const char *realname, const char *parameters)
{ {
if (pmdl) { if (!pmdl) {
if (!pmdl->a->alias_list) {
pmdl->a->alias_list = cgi.AliasList_New(pmdl->a->name);
}
cgi.Alias_ListAdd((AliasList_t *)pmdl->a->alias_list, alias, realname, parameters);
} else {
cgi.Alias_Add(alias, realname, parameters); cgi.Alias_Add(alias, realname, parameters);
return;
} }
if (!pmdl->a->alias_list) {
pmdl->a->alias_list = cgi.AliasList_New(pmdl->a->name);
}
cgi.Alias_ListAdd((AliasList_t*)pmdl->a->alias_list, alias, realname, parameters);
} }
qboolean bLoadForMap(const char *psMapsBuffer, const char *name) qboolean bLoadForMap(const char *psMapsBuffer, const char *name)
@ -4141,7 +4265,7 @@ qboolean bLoadForMap(const char *psMapsBuffer, const char *name)
} }
if (!token || !token[0]) { if (!token || !token[0]) {
Com_Printf("ERROR bLoadForMap: %s alias with empty maps specification.\n", name); cgi.DPrintf("ERROR bLoadForMap: %s alias with empty maps specification.\n", name);
return false; return false;
} }
@ -4181,19 +4305,32 @@ void ClientGameCommandManager::AliasCache(Event *ev)
psMapsBuffer = NULL; psMapsBuffer = NULL;
for (i = 3; i <= ev->NumArgs(); i++) { for (i = 3; i <= ev->NumArgs(); i++) {
if (!strcmp(ev->GetToken(i).c_str(), "maps")) { str s = ev->GetString(i);
if (!s.icmp("maps")) {
i++; i++;
psMapsBuffer = ev->GetToken(i); psMapsBuffer = (char *)ev->GetToken(i).c_str();
} else if (!strcmp(ev->GetToken(i).c_str(), "always")) { continue;
bAlwaysLoaded = true;
} else {
strcat(parmbuffer, ev->GetToken(i));
strcat(parmbuffer, " ");
} }
if (!s.icmp("always")) {
bAlwaysLoaded = true;
continue;
}
strcat(parmbuffer, s);
strcat(parmbuffer, " ");
} }
if (bAlwaysLoaded || bLoadForMap(psMapsBuffer, ev->GetString(1))) { if (bAlwaysLoaded) {
AliasResource(current_tiki, ev->GetString(1), ev->GetString(2), parmbuffer); AliasResource(current_tiki, ev->GetString(1), ev->GetString(2), parmbuffer);
}
if (bLoadForMap(psMapsBuffer, ev->GetString(1))) {
if (!bAlwaysLoaded) {
AliasResource(current_tiki, ev->GetString(1), ev->GetString(2), parmbuffer);
}
CacheResource(ev->GetString(2)); CacheResource(ev->GetString(2));
} }
} }
@ -4223,28 +4360,33 @@ void ClientGameCommandManager::Alias(Event *ev)
psMapsBuffer = NULL; psMapsBuffer = NULL;
for (i = 3; i <= ev->NumArgs(); i++) { for (i = 3; i <= ev->NumArgs(); i++) {
if (!strcmp(ev->GetToken(i).c_str(), "maps")) { str s = ev->GetString(i);
if (!s.icmp("maps")) {
i++; i++;
psMapsBuffer = ev->GetToken(i); psMapsBuffer = (char *)ev->GetToken(i).c_str();
} else if (!strcmp(ev->GetToken(i).c_str(), "always")) { continue;
}
if (!s.icmp("always")) {
bAlwaysLoaded = true; bAlwaysLoaded = true;
} else if (subtitle) {
strcat(parmbuffer, "\"");
strcat(parmbuffer, s);
strcat(parmbuffer, "\" ");
subtitle = 0;
} else { } else {
subtitle = s.icmp("subtitle") == 0;
if (!subtitle) { if (!subtitle) {
if (!Q_stricmp(ev->GetToken(i), "subtitle") || !Q_stricmp(ev->GetToken(i), "forcesubtitle")) { subtitle = s.icmp("forcesubtitle") == 0;
subtitle = qtrue;
strcat(parmbuffer, ev->GetToken(i));
} else {
strcat(parmbuffer, ev->GetToken(i));
}
} else {
strcat(parmbuffer, "\"");
strcat(parmbuffer, ev->GetToken(i));
strcat(parmbuffer, "\"");
subtitle = qfalse;
} }
strcat(parmbuffer, " "); strcat(parmbuffer, s);
} }
strcat(parmbuffer, " ");
} }
if (bAlwaysLoaded || bLoadForMap(psMapsBuffer, ev->GetString(1))) { if (bAlwaysLoaded || bLoadForMap(psMapsBuffer, ev->GetString(1))) {
@ -4976,7 +5118,15 @@ bool ClientGameCommandManager::GetTagPositionAndOrientation(str tagname, orienta
//=============== //===============
void ClientGameCommandManager::RestartAllEmitters(void) void ClientGameCommandManager::RestartAllEmitters(void)
{ {
// FIXME: stub?? ctempmodel_t *p;
//
// FIXME: not sure if it's the right thing
//
for (p = m_active_tempmodels.prev; p != &m_active_tempmodels; p = p->next) {
p->cgd.createTime = cg.time;
}
} }
//=============== //===============
@ -5029,7 +5179,7 @@ void CG_ProcessInitCommands(dtiki_t *tiki, refEntity_t *ent)
} }
if (!commandManager.SelectProcessEvent(ev)) { if (!commandManager.SelectProcessEvent(ev)) {
Com_Printf( cgi.DPrintf(
"^~^~^ CG_ProcessInitCommands: Bad init client command '%s' in '%s'\n", pcmd->args[0], tiki->name "^~^~^ CG_ProcessInitCommands: Bad init client command '%s' in '%s'\n", pcmd->args[0], tiki->name
); );
} }
@ -5075,7 +5225,7 @@ void CG_ProcessCacheInitCommands(dtiki_t *tiki)
} }
if (!commandManager.SelectProcessEvent(ev)) { if (!commandManager.SelectProcessEvent(ev)) {
Com_Printf( cgi.DPrintf(
"^~^~^ CG_ProcessInitCommands: Bad init client command '%s' in '%s'\n", pcmd->args[0], tiki->name "^~^~^ CG_ProcessInitCommands: Bad init client command '%s' in '%s'\n", pcmd->args[0], tiki->name
); );
} }
@ -5148,7 +5298,7 @@ qboolean CG_ProcessEntityCommands(int frame, int anim, int entnum, refEntity_t *
current_centity = cent; current_centity = cent;
current_entity_number = entnum; current_entity_number = entnum;
current_tiki = ent->tiki; current_tiki = ent->tiki;
CG_AnimationDebugMessage(entnum, "Processing Ent Commands: Entity: %3d Anim:#(%i) Frame:#(%i)\n", anim, frame); CG_AnimationDebugMessage(entnum, "Processing Ent Commands: Entity: %3d Anim:#(%i) Frame:#(%i)\n", entnum, anim, frame);
for (i = 0; i < tikicmds.num_cmds; i++) { for (i = 0; i < tikicmds.num_cmds; i++) {
Event *ev; Event *ev;
@ -5187,7 +5337,7 @@ void CG_ClientCommandDebugMessage(centity_t *cent, const char *fmt, ...)
char msg[1024]; char msg[1024];
va_start(argptr, fmt); va_start(argptr, fmt);
vsprintf(msg, fmt, argptr); Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
va_end(argptr); va_end(argptr);
if ((!cg_debugAnimWatch->integer) || ((cg_debugAnimWatch->integer - 1) == cent->currentState.number)) { if ((!cg_debugAnimWatch->integer) || ((cg_debugAnimWatch->integer - 1) == cent->currentState.number)) {
@ -5342,7 +5492,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
current_tiki = NULL; current_tiki = NULL;
// Update the loading screen // Update the loading screen
sprintf(tempName, "m%s", filename); Com_sprintf(tempName, sizeof(tempName), "m%s", filename);
cgi.LoadResource(tempName); cgi.LoadResource(tempName);
bufstart = buffer; bufstart = buffer;
@ -5351,7 +5501,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
Event *ev; Event *ev;
// grab each line as we go // grab each line as we go
strcpy(com_token, COM_ParseExt(&buffer, qtrue)); Q_strncpyz(com_token, COM_ParseExt(&buffer, qtrue), sizeof(com_token));
if (!com_token[0]) { if (!com_token[0]) {
break; break;
} }
@ -5359,7 +5509,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
if (!Q_stricmp(com_token, "end") || !Q_stricmp(com_token, "server")) { if (!Q_stricmp(com_token, "end") || !Q_stricmp(com_token, "server")) {
// skip the line // skip the line
while (1) { while (1) {
strcpy(com_token, COM_ParseExt(&buffer, qfalse)); Q_strncpyz(com_token, COM_ParseExt(&buffer, qfalse), sizeof(com_token));
if (!com_token[0]) { if (!com_token[0]) {
break; break;
} }
@ -5372,7 +5522,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
// get the rest of the line // get the rest of the line
while (1) { while (1) {
strcpy(com_token, COM_ParseExt(&buffer, qfalse)); Q_strncpyz(com_token, COM_ParseExt(&buffer, qfalse), sizeof(com_token));
if (!com_token[0]) { if (!com_token[0]) {
break; break;
} }
@ -5384,7 +5534,7 @@ qboolean CG_Command_ProcessFile(const char *filename, qboolean quiet, dtiki_t *c
cgi.FS_FreeFile((void *)bufstart); cgi.FS_FreeFile((void *)bufstart);
// Update the loading screen // Update the loading screen
sprintf(tempName, "o%s", filename); Com_sprintf(tempName, sizeof(tempName), "o%s", filename);
cgi.LoadResource(tempName); cgi.LoadResource(tempName);
return qtrue; return qtrue;
@ -5690,7 +5840,7 @@ void ClientGameCommandManager::SetCurrentTiki(Event *ev)
str tikiName; str tikiName;
if (ev->NumArgs() != 1) { if (ev->NumArgs() != 1) {
Com_Printf("ERROR: settiki command takes 1 parameter.\n"); cgi.DPrintf("ERROR: settiki command takes 1 parameter.\n");
return; return;
} }

View file

@ -113,6 +113,7 @@ TIKI file, similar to ScriptMaster in the server game dll.
#define T2_VARYCOLOR (1 << 20) #define T2_VARYCOLOR (1 << 20)
#define T2_SPIN (1 << 21) #define T2_SPIN (1 << 21)
#define T2_RELATIVEANGLES (1 << 22) #define T2_RELATIVEANGLES (1 << 22)
#define T2_NOTAGAXIS (1 << 23)
class spawnthing_t; class spawnthing_t;
class specialeffect_t; class specialeffect_t;
@ -763,6 +764,7 @@ private:
void SpawnVSSSource(int count, int timealive); void SpawnVSSSource(int count, int timealive);
void EventViewKick(Event *ev); void EventViewKick(Event *ev);
void Print(Event *ev); void Print(Event *ev);
void PrintDeathMsg(Event *ev); // Added in 2.0
void StartBlock(Event *ev); void StartBlock(Event *ev);
void EndBlock(Event *ev); void EndBlock(Event *ev);
void UpdateSpawnThing(spawnthing_t *ep); void UpdateSpawnThing(spawnthing_t *ep);
@ -788,6 +790,7 @@ private:
void SetScaleRate(Event *ev); void SetScaleRate(Event *ev);
void SetRandomVelocity(Event *ev); void SetRandomVelocity(Event *ev);
void SetRandomVelocityAlongAxis(Event *ev); void SetRandomVelocityAlongAxis(Event *ev);
void SetNoTagAxis(Event *ev); // Added in 2.0
void SetAccel(Event *ev); void SetAccel(Event *ev);
void SetFriction(Event *ev); void SetFriction(Event *ev);
void SetSpin(Event *ev); void SetSpin(Event *ev);
@ -849,6 +852,7 @@ private:
void StopSound(Event *ev); void StopSound(Event *ev);
void StopAliasChannel(Event *ev); void StopAliasChannel(Event *ev);
void LoopSound(Event *ev); void LoopSound(Event *ev);
void StopLoopSound(Event *ev); // Added in 2.0
void Cache(Event *ev); void Cache(Event *ev);
void CacheImage(Event *ev); void CacheImage(Event *ev);
void CacheFont(Event *ev); void CacheFont(Event *ev);

View file

@ -1,6 +1,6 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2023 the OpenMoHAA team Copyright (C) 2008-2024 the OpenMoHAA team
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -160,17 +160,157 @@ baseshader_t *CG_GetShaderUnderCrosshair(qboolean bVerbose, trace_t *pRetTrace)
static void CG_PrintContentTypes(int iContentFlags) static void CG_PrintContentTypes(int iContentFlags)
{ {
// FIXME: unimplemented if (iContentFlags & CONTENTS_SOLID) {
cgi.Printf(" solid");
}
if (iContentFlags & CONTENTS_LAVA) {
cgi.Printf(" lava");
}
if (iContentFlags & CONTENTS_SLIME) {
cgi.Printf(" slime");
}
if (iContentFlags & CONTENTS_WATER) {
cgi.Printf(" water");
}
if (iContentFlags & CONTENTS_FOG) {
cgi.Printf(" fog");
}
if (iContentFlags & CONTENTS_FENCE) {
cgi.Printf(" fence");
}
if (iContentFlags & CONTENTS_AREAPORTAL) {
cgi.Printf(" areaportal");
}
if (iContentFlags & CONTENTS_PLAYERCLIP) {
cgi.Printf(" playerclip");
}
if (iContentFlags & CONTENTS_VEHICLECLIP) {
cgi.Printf(" vehicleclip");
}
if (iContentFlags & CONTENTS_MONSTERCLIP) {
cgi.Printf(" monsterclip");
}
if (iContentFlags & CONTENTS_WEAPONCLIP) {
cgi.Printf(" weaponclip");
}
if (iContentFlags & CONTENTS_SHOOTONLY) {
cgi.Printf(" shootableonly");
}
if (iContentFlags & CONTENTS_ORIGIN) {
cgi.Printf(" origin");
}
if (iContentFlags & CONTENTS_TRANSLUCENT) {
cgi.Printf(" trans");
}
} }
static void CG_PrintSurfaceProperties(int iSurfaceFlags) static void CG_PrintSurfaceProperties(int iSurfaceFlags)
{ {
// FIXME: unimplemented if (iSurfaceFlags & SURF_NODAMAGE) {
cgi.Printf(" nodamage");
}
if (iSurfaceFlags & SURF_SLICK) {
cgi.Printf(" slick");
}
if (iSurfaceFlags & SURF_SKY) {
cgi.Printf(" sky");
}
if (iSurfaceFlags & SURF_LADDER) {
cgi.Printf(" ladder");
}
if (iSurfaceFlags & SURF_NOIMPACT) {
cgi.Printf(" noimpact");
}
if (iSurfaceFlags & SURF_NOMARKS) {
cgi.Printf(" nomarks");
}
if (iSurfaceFlags & SURF_CASTSHADOW) {
cgi.Printf(" castshadow");
}
if (iSurfaceFlags & SURF_NODRAW) {
cgi.Printf(" nodraw");
}
if (iSurfaceFlags & SURF_NOLIGHTMAP) {
cgi.Printf(" nolightmap");
}
if (iSurfaceFlags & SURF_ALPHASHADOW) {
cgi.Printf(" alphashadow");
}
if (iSurfaceFlags & SURF_NOSTEPS) {
cgi.Printf(" nofootsteps");
}
if (iSurfaceFlags & SURF_NONSOLID) {
cgi.Printf(" nonsolid");
}
if (iSurfaceFlags & SURF_OVERBRIGHT) {
cgi.Printf(" overbright");
}
if (iSurfaceFlags & SURF_BACKSIDE) {
cgi.Printf(" backside");
}
if (iSurfaceFlags & SURF_NODLIGHT) {
cgi.Printf(" nodlight");
}
if (iSurfaceFlags & SURF_HINT) {
cgi.Printf(" hint");
}
if (iSurfaceFlags & SURF_PATCH) {
cgi.Printf(" patch");
}
} }
static void CG_PrintSurfaceType(int iSurfType) static void CG_PrintSurfaceType(int iSurfType)
{ {
// FIXME: unimplemented switch (iSurfType & MASK_SURF_TYPE) {
case SURF_FOLIAGE:
cgi.Printf("foliage");
break;
case SURF_SNOW:
cgi.Printf("snow");
break;
case SURF_CARPET:
cgi.Printf("carpet");
break;
case SURF_SAND:
cgi.Printf("sand");
break;
case SURF_PUDDLE:
cgi.Printf("puddle");
break;
case SURF_GLASS:
cgi.Printf("glass");
break;
case SURF_GRAVEL:
cgi.Printf("gravel");
break;
case SURF_MUD:
cgi.Printf("mud");
break;
case SURF_DIRT:
cgi.Printf("dirt");
break;
case SURF_GRILL:
cgi.Printf("metal grill");
break;
case SURF_GRASS:
cgi.Printf("grass");
break;
case SURF_ROCK:
cgi.Printf("rock");
break;
case SURF_PAPER:
cgi.Printf("paper");
break;
case SURF_WOOD:
cgi.Printf("wood");
break;
case SURF_METAL:
cgi.Printf("metal");
break;
default:
cgi.Printf("!!*none specified*!!");
break;
}
} }
void CG_GetCHShader(void) void CG_GetCHShader(void)
@ -216,9 +356,9 @@ void CG_EditCHShader(void)
pShader = CG_GetShaderUnderCrosshair(qfalse, NULL); pShader = CG_GetShaderUnderCrosshair(qfalse, NULL);
if (pShader) { if (pShader) {
strcpy(name, "editspecificshader "); Q_strncpyz(name, "editspecificshader ", sizeof(name));
strcat(name, pShader->shader); Q_strcat(name, sizeof(name), pShader->shader);
strcat(name, "\n"); Q_strcat(name, sizeof(name), "\n");
cgi.AddCommand(name); cgi.AddCommand(name);
} else { } else {
cgi.Printf("No surface selected\n"); cgi.Printf("No surface selected\n");
@ -340,65 +480,65 @@ typedef struct {
} consoleCommand_t; } consoleCommand_t;
static consoleCommand_t commands[] = { static consoleCommand_t commands[] = {
{"useweaponclass", &CG_UseWeaponClass_f }, {"useweaponclass", &CG_UseWeaponClass_f },
{"weapnext", &CG_NextWeapon_f }, {"weapnext", &CG_NextWeapon_f },
{"weapprev", &CG_PrevWeapon_f }, {"weapprev", &CG_PrevWeapon_f },
{"uselast", &CG_UseLastWeapon_f }, {"uselast", &CG_UseLastWeapon_f },
{"holster", &CG_HolsterWeapon_f }, {"holster", &CG_HolsterWeapon_f },
{"weapdrop", &CG_DropWeapon_f }, {"weapdrop", &CG_DropWeapon_f },
{"toggleitem", &CG_ToggleItem_f }, {"toggleitem", &CG_ToggleItem_f },
{"+scores", &CG_ScoresDown_f }, {"+scores", &CG_ScoresDown_f },
{"-scores", &CG_ScoresUp_f }, {"-scores", &CG_ScoresUp_f },
{"viewpos", &CG_Viewpos_f }, {"viewpos", &CG_Viewpos_f },
{"sizeup", &CG_SizeUp_f }, {"sizeup", &CG_SizeUp_f },
{"sizedown", &CG_SizeDown_f }, {"sizedown", &CG_SizeDown_f },
{"cg_eventlist", &CG_EventList_f }, {"cg_eventlist", &CG_EventList_f },
{"cg_eventhelp", &CG_EventHelp_f }, {"cg_eventhelp", &CG_EventHelp_f },
{"cg_dumpevents", &CG_DumpEventHelp_f }, {"cg_dumpevents", &CG_DumpEventHelp_f },
{"cg_pendingevents", &CG_PendingEvents_f }, {"cg_pendingevents", &CG_PendingEvents_f },
{"cg_classlist", &CG_ClassList_f }, {"cg_classlist", &CG_ClassList_f },
{"cg_classtree", &CG_ClassTree_f }, {"cg_classtree", &CG_ClassTree_f },
{"cg_classevents", &CG_ClassEvents_f }, {"cg_classevents", &CG_ClassEvents_f },
{"cg_dumpclassevents", &CG_DumpClassEvents_f }, {"cg_dumpclassevents", &CG_DumpClassEvents_f },
{"cg_dumpallclasses", &CG_DumpAllClasses_f }, {"cg_dumpallclasses", &CG_DumpAllClasses_f },
{"testemitter", &CG_TestEmitter_f }, {"testemitter", &CG_TestEmitter_f },
{"triggertestemitter", &CG_TriggerTestEmitter_f }, {"triggertestemitter", &CG_TriggerTestEmitter_f },
{"prevemittercommand", &CG_PrevEmitterCommand_f }, {"prevemittercommand", &CG_PrevEmitterCommand_f },
{"nextemittercommand", &CG_NextEmitterCommand_f }, {"nextemittercommand", &CG_NextEmitterCommand_f },
{"newemittercommand", &CG_NewEmitterCommand_f }, {"newemittercommand", &CG_NewEmitterCommand_f },
{"deleteemittercommand", &CG_DeleteEmitterCommand_f }, {"deleteemittercommand", &CG_DeleteEmitterCommand_f },
{"dumpemitter", &CG_DumpEmitter_f }, {"dumpemitter", &CG_DumpEmitter_f },
{"loademitter", &CG_LoadEmitter_f }, {"loademitter", &CG_LoadEmitter_f },
{"resetvss", &CG_ResetVSSSources }, {"resetvss", &CG_ResetVSSSources },
{"getchshader", &CG_GetCHShader }, {"getchshader", &CG_GetCHShader },
{"editchshader", &CG_EditCHShader }, {"editchshader", &CG_EditCHShader },
{"messagemode", &CG_MessageMode_f }, {"messagemode", &CG_MessageMode_f },
{"messagemode_all", &CG_MessageMode_All_f }, {"messagemode_all", &CG_MessageMode_All_f },
{"messagemode_team", &CG_MessageMode_Team_f }, {"messagemode_team", &CG_MessageMode_Team_f },
{"messagemode_private", &CG_MessageMode_Private_f }, {"messagemode_private", &CG_MessageMode_Private_f },
{"say", &CG_MessageSingleAll_f }, {"say", &CG_MessageSingleAll_f },
{"sayteam", &CG_MessageSingleTeam_f }, {"sayteam", &CG_MessageSingleTeam_f },
{"teamsay", &CG_MessageSingleTeam_f }, {"teamsay", &CG_MessageSingleTeam_f },
{"sayprivate", &CG_MessageSingleClient_f }, {"sayprivate", &CG_MessageSingleClient_f },
{"sayone", &CG_MessageSingleClient_f }, {"sayone", &CG_MessageSingleClient_f },
{"wisper", &CG_MessageSingleClient_f }, {"wisper", &CG_MessageSingleClient_f },
{"instamsg_main", &CG_InstaMessageMain_f }, {"instamsg_main", &CG_InstaMessageMain_f },
{"instamsg_group_a", &CG_InstaMessageGroupA_f }, {"instamsg_group_a", &CG_InstaMessageGroupA_f },
{"instamsg_group_b", &CG_InstaMessageGroupB_f }, {"instamsg_group_b", &CG_InstaMessageGroupB_f },
{"instamsg_group_c", &CG_InstaMessageGroupC_f }, {"instamsg_group_c", &CG_InstaMessageGroupC_f },
{"instamsg_group_d", &CG_InstaMessageGroupD_f }, {"instamsg_group_d", &CG_InstaMessageGroupD_f },
{"instamsg_group_e", &CG_InstaMessageGroupE_f }, {"instamsg_group_e", &CG_InstaMessageGroupE_f },
{"pushmenu_teamselect", &CG_PushMenuTeamSelect_f }, {"pushmenu_teamselect", &CG_PushMenuTeamSelect_f },
{"pushmenu_weaponselect", &CG_PushMenuWeaponSelect_f }, {"pushmenu_weaponselect", &CG_PushMenuWeaponSelect_f },
// Added in 2.0 // Added in 2.0
{"pushcallvote", &CG_PushCallVote_f }, {"pushcallvote", &CG_PushCallVote_f },
{"pushcallvotesublist", &CG_PushCallVoteSubList_f }, {"pushcallvotesublist", &CG_PushCallVoteSubList_f },
{"pushcallvotesubtext", &CG_PushCallVoteSubText_f }, {"pushcallvotesubtext", &CG_PushCallVoteSubText_f },
{"pushcallvotesubinteger",&CG_PushCallVoteSubInteger_f }, {"pushcallvotesubinteger", &CG_PushCallVoteSubInteger_f},
{"pushcallvotesubfloat", &CG_PushCallVoteSubFloat_f }, {"pushcallvotesubfloat", &CG_PushCallVoteSubFloat_f },
{"pushcallvotesubclient", &CG_PushCallVoteSubClient_f }, {"pushcallvotesubclient", &CG_PushCallVoteSubClient_f },
{"pushvote", &CG_PushVote_f }, {"pushvote", &CG_PushVote_f },
{"callentryvote", &CG_CallEntryVote_f }, {"callentryvote", &CG_CallEntryVote_f },
}; };
/* /*
@ -565,5 +705,5 @@ int CG_WeaponCommandButtonBits(void)
cg.iWeaponCommand = 0; cg.iWeaponCommand = 0;
} }
return iShiftedWeaponCommand & WEAPON_COMMAND_MASK; return iShiftedWeaponCommand & GetWeaponCommandMask(cg_protocol >= PROTOCOL_MOHTA_MIN ? WEAPON_COMMAND_MAX_VER17 : WEAPON_COMMAND_MAX_VER6);
} }

View file

@ -1,6 +1,6 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2023 the OpenMoHAA team Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -191,8 +191,8 @@ void CG_DrawDisconnect(void)
} }
handle = cgi.R_RegisterShader("gfx/2d/net.tga"); handle = cgi.R_RegisterShader("gfx/2d/net.tga");
w = cgi.R_GetShaderWidth(handle); w = cgi.R_GetShaderWidth(handle) * cgs.uiHiResScale[0];
h = cgi.R_GetShaderHeight(handle); h = cgi.R_GetShaderHeight(handle) * cgs.uiHiResScale[1];
x = ((float)cgs.glconfig.vidWidth - w) * 0.5; x = ((float)cgs.glconfig.vidWidth - w) * 0.5;
y = (float)cgs.glconfig.vidHeight - h; y = (float)cgs.glconfig.vidHeight - h;
@ -331,7 +331,7 @@ static void CG_DrawPauseIcon()
x = (cgs.glconfig.vidWidth - w) / 2.f; x = (cgs.glconfig.vidWidth - w) / 2.f;
cgi.R_SetColor(colorWhite); cgi.R_SetColor(colorWhite);
cgi.R_DrawStretchPic(x, y, w, h, 0, 0, 1, 1, handle); cgi.R_DrawStretchPic(x, y, w * cgs.uiHiResScale[0], h * cgs.uiHiResScale[1], 0, 0, 1, 1, handle);
} }
static void CG_DrawServerLag() static void CG_DrawServerLag()
@ -362,8 +362,8 @@ static void CG_DrawServerLag()
} }
handle = cgi.R_RegisterShader("gfx/2d/slowserver"); handle = cgi.R_RegisterShader("gfx/2d/slowserver");
w = (float)cgi.R_GetShaderWidth(handle) / 4; w = (float)cgi.R_GetShaderWidth(handle) * cgs.uiHiResScale[0] / 4;
h = (float)cgi.R_GetShaderHeight(handle) / 4; h = (float)cgi.R_GetShaderHeight(handle) * cgs.uiHiResScale[1] / 4;
x = ((float)cgs.glconfig.vidWidth - w) / 2; x = ((float)cgs.glconfig.vidWidth - w) / 2;
y = (float)cgs.glconfig.vidHeight - h; y = (float)cgs.glconfig.vidHeight - h;
cgi.R_DrawStretchPic(x, y, w, h, 0.0, 0.0, 1.0, 1.0, handle); cgi.R_DrawStretchPic(x, y, w, h, 0.0, 0.0, 1.0, 1.0, handle);
@ -577,14 +577,18 @@ void CG_RefreshHudDrawElements()
void CG_HudDrawElements() void CG_HudDrawElements()
{ {
int i; int i;
float fX, fY; float fX, fY;
float fWidth, fHeight; float fWidth, fHeight;
vec2_t virtualScale;
if (!cg_huddraw_force->integer && !cg_hud->integer) { if (!cg_huddraw_force->integer && !cg_hud->integer) {
return; return;
} }
virtualScale[0] = cgs.glconfig.vidWidth / 640.0;
virtualScale[1] = cgs.glconfig.vidHeight / 480.0;
for (i = 0; i < MAX_HUDDRAW_ELEMENTS; i++) { for (i = 0; i < MAX_HUDDRAW_ELEMENTS; i++) {
if ((!cgi.HudDrawElements[i].hShader && !cgi.HudDrawElements[i].string[0]) if ((!cgi.HudDrawElements[i].hShader && !cgi.HudDrawElements[i].string[0])
|| !cgi.HudDrawElements[i].vColor[3]) { || !cgi.HudDrawElements[i].vColor[3]) {
@ -597,6 +601,13 @@ void CG_HudDrawElements()
fWidth = cgi.HudDrawElements[i].iWidth; fWidth = cgi.HudDrawElements[i].iWidth;
fHeight = cgi.HudDrawElements[i].iHeight; fHeight = cgi.HudDrawElements[i].iHeight;
if (!cgi.HudDrawElements[i].bVirtualScreen) {
fWidth *= cgs.uiHiResScale[0];
fHeight *= cgs.uiHiResScale[1];
fX *= cgs.uiHiResScale[0];
fY *= cgs.uiHiResScale[1];
}
if (cgi.HudDrawElements[i].iHorizontalAlign == HUD_ALIGN_X_CENTER) { if (cgi.HudDrawElements[i].iHorizontalAlign == HUD_ALIGN_X_CENTER) {
if (cgi.HudDrawElements[i].bVirtualScreen) { if (cgi.HudDrawElements[i].bVirtualScreen) {
fX += 320.0 - fWidth * 0.5; fX += 320.0 - fWidth * 0.5;
@ -627,23 +638,21 @@ void CG_HudDrawElements()
cgi.R_SetColor(cgi.HudDrawElements[i].vColor); cgi.R_SetColor(cgi.HudDrawElements[i].vColor);
if (cgi.HudDrawElements[i].string[0]) { if (cgi.HudDrawElements[i].string[0]) {
if (cgi.HudDrawElements[i].pFont) { fontheader_t *pFont = cgi.HudDrawElements[i].pFont;
cgi.R_DrawString( if (!pFont) {
cgi.HudDrawElements[i].pFont, pFont = cgs.media.hudDrawFont;
cgi.LV_ConvertString(cgi.HudDrawElements[i].string), }
fX,
fY, if (cgi.HudDrawElements[i].bVirtualScreen) {
-1, cgi.R_DrawString(pFont, cgi.LV_ConvertString(cgi.HudDrawElements[i].string), fX, fY, -1, virtualScale);
cgi.HudDrawElements[i].bVirtualScreen
);
} else { } else {
cgi.R_DrawString( cgi.R_DrawString(
cgs.media.hudDrawFont, pFont,
cgi.LV_ConvertString(cgi.HudDrawElements[i].string), cgi.LV_ConvertString(cgi.HudDrawElements[i].string),
fX, fX / cgs.uiHiResScale[0],
fY, fY / cgs.uiHiResScale[1],
-1, -1,
cgi.HudDrawElements[i].bVirtualScreen cgs.uiHiResScale
); );
} }
} else { } else {
@ -675,14 +684,17 @@ void CG_DrawObjectives()
{ {
float vColor[4]; float vColor[4];
float fX, fY; float fX, fY;
int iNumObjectives;
float fObjectivesTop;
static float fWidth; static float fWidth;
float fHeight; float fHeight;
int iNumLines[20]; int iNumLines[20];
int iTotalNumLines; int iTotalNumLines;
int i; int i;
int ii;
int iCurrentObjective; int iCurrentObjective;
float fTimeDelta; float fTimeDelta;
const char *pszLocalizedText;
const char *pszLine;
iTotalNumLines = 0; iTotalNumLines = 0;
for (i = CS_OBJECTIVES; i < CS_OBJECTIVES + MAX_OBJECTIVES; ++i) { for (i = CS_OBJECTIVES; i < CS_OBJECTIVES + MAX_OBJECTIVES; ++i) {
@ -702,50 +714,78 @@ void CG_DrawObjectives()
return; return;
} }
for (i = 0; i < MAX_OBJECTIVES; i++) { // Added in 2.0
if ((cg.Objectives[i].flags & 0xFFFFFFFE)) { // Get the minimum Y value, it should be below the compass
iNumLines[i] = 0; fObjectivesTop = cgi.UI_GetObjectivesTop();
iNumObjectives = 0;
for (ii = 0; ii < MAX_STRING_CHARS; ii++) { for (i = 0; i < MAX_OBJECTIVES; i++) {
if (cg.Objectives[i].text[ii] == '\n') { if ((cg.Objectives[i].flags == OBJ_FLAG_NONE) || (cg.Objectives[i].flags & OBJ_FLAG_HIDDEN)) {
iTotalNumLines++; continue;
iNumLines[i]++;
} else if (!cg.Objectives[i].text[ii]) {
iTotalNumLines++;
iNumLines[i]++;
break;
}
}
} }
iNumObjectives++;
iNumLines[i] = 0;
pszLocalizedText = cgi.LV_ConvertString(cg.Objectives[i].text);
for (pszLine = strchr(pszLocalizedText, '\n'); pszLine; pszLine = strchr(pszLine + 1, '\n')) {
iNumLines[i]++;
}
iTotalNumLines += iNumLines[i];
} }
fX = 25.0; fX = 25.0;
fY = 125.0; fY = fObjectivesTop + 5;
fWidth = (float)(25 * iTotalNumLines + 155) + 5.0 - 130.0; fWidth = (float)(iTotalNumLines * 12 + fObjectivesTop + iNumObjectives * 25 + 32) - fY;
vColor[2] = 0.2f; vColor[2] = 0.2f;
vColor[1] = 0.2f; vColor[1] = 0.2f;
vColor[0] = 0.2f; vColor[0] = 0.2f;
vColor[3] = cg.ObjectivesCurrentAlpha * 0.75; vColor[3] = cg.ObjectivesCurrentAlpha * 0.75;
cgi.R_SetColor(vColor); cgi.R_SetColor(vColor);
cgi.R_DrawStretchPic(fX, fY, 450.0, fWidth, 0.0, 0.0, 1.0, 1.0, cgs.media.objectivesBackShader); cgi.R_DrawStretchPic(
fX,
fY,
450.0 * cgs.uiHiResScale[0],
fWidth * cgs.uiHiResScale[1],
0.0,
0.0,
1.0,
1.0,
cgs.media.objectivesBackShader
);
fX = 30.0; fX = 30.0;
fY = 130.0; fY = fObjectivesTop + 10;
vColor[0] = 1.0; vColor[0] = 1.0;
vColor[1] = 1.0; vColor[1] = 1.0;
vColor[2] = 1.0; vColor[2] = 1.0;
vColor[3] = cg.ObjectivesCurrentAlpha; vColor[3] = cg.ObjectivesCurrentAlpha;
cgi.R_SetColor(vColor); cgi.R_SetColor(vColor);
cgi.R_DrawString(cgs.media.objectiveFont, cgi.LV_ConvertString("Mission Objectives:"), fX, fY, -1, 0); cgi.R_DrawString(
cgs.media.objectiveFont,
cgi.LV_ConvertString("Mission Objectives:"),
fX,
fY / cgs.uiHiResScale[1],
-1,
cgs.uiHiResScale
);
fY = fY + 5.0; fY = fY + 5.0;
cgi.R_DrawString(cgs.media.objectiveFont, "_______________________________________________________", fX, fY, -1, 0); cgi.R_DrawString(
fHeight = 155.0; cgs.media.objectiveFont,
"_______________________________________________________",
fX,
fY / cgs.uiHiResScale[1],
-1,
cgs.uiHiResScale
);
fHeight = fObjectivesTop + 35 * cgs.uiHiResScale[1];
for (i = 0; i < MAX_OBJECTIVES; ++i) { for (i = 0; i < MAX_OBJECTIVES; ++i) {
qhandle_t hBoxShader; qhandle_t hBoxShader;
if ((cg.Objectives[i].flags & OBJ_FLAG_HIDDEN) || !cg.Objectives[i].flags) { if ((cg.Objectives[i].flags == OBJ_FLAG_NONE) || (cg.Objectives[i].flags & OBJ_FLAG_HIDDEN)) {
continue; continue;
} }
@ -778,7 +818,14 @@ void CG_DrawObjectives()
cgi.R_SetColor(vColor); cgi.R_SetColor(vColor);
fX = 55.0; fX = 55.0;
fY = fHeight; fY = fHeight;
cgi.R_DrawString(cgs.media.objectiveFont, cgi.LV_ConvertString(cg.Objectives[i].text), 55.0, fHeight, -1, 0); cgi.R_DrawString(
cgs.media.objectiveFont,
cgi.LV_ConvertString(cg.Objectives[i].text),
55.0,
fY / cgs.uiHiResScale[1],
-1,
cgs.uiHiResScale
);
fX = 30.0; fX = 30.0;
fY = fHeight; fY = fHeight;
@ -787,9 +834,19 @@ void CG_DrawObjectives()
vColor[2] = 1.0; vColor[2] = 1.0;
vColor[3] = cg.ObjectivesCurrentAlpha; vColor[3] = cg.ObjectivesCurrentAlpha;
cgi.R_SetColor(vColor); cgi.R_SetColor(vColor);
cgi.R_DrawStretchPic(fX, fY, 16.0, 16.0, 0.0, 0.0, 1.0, 1.0, hBoxShader); cgi.R_DrawStretchPic(
fX * cgs.uiHiResScale[0],
fY,
16.0 * cgs.uiHiResScale[0],
16.0 * cgs.uiHiResScale[1],
0.0,
0.0,
1.0,
1.0,
hBoxShader
);
fHeight += 25 * iNumLines[i]; fHeight += iNumLines[i] * 12 + 25 * cgs.uiHiResScale[1];
} }
} }
@ -813,7 +870,17 @@ void CG_DrawPlayerTeam()
if (handle) { if (handle) {
cgi.R_SetColor(NULL); cgi.R_SetColor(NULL);
cgi.R_DrawStretchPic(96.0, cgs.glconfig.vidHeight - 46, 24.0, 24.0, 0.0, 0.0, 1.0, 1.0, handle); cgi.R_DrawStretchPic(
96.0 * cgs.uiHiResScale[0],
cgs.glconfig.vidHeight - 46 * cgs.uiHiResScale[1],
24.0 * cgs.uiHiResScale[0],
24.0 * cgs.uiHiResScale[1],
0.0,
0.0,
1.0,
1.0,
handle
);
} }
} }
@ -855,13 +922,28 @@ void CG_DrawPlayerEntInfo()
if (handle) { if (handle) {
cgi.R_SetColor(0); cgi.R_SetColor(0);
cgi.R_DrawStretchPic(56.0, fY, 16.0, 16.0, 0.0, 0.0, 1.0, 1.0, handle); cgi.R_DrawStretchPic(
fX = 56.0 + 24.0; fX, fY, 16.0 * cgs.uiHiResScale[0], 16.0 * cgs.uiHiResScale[1], 0.0, 0.0, 1.0, 1.0, handle
);
} }
cgi.R_SetColor(color); cgi.R_SetColor(color);
cgi.R_DrawString(cgs.media.hudDrawFont, (char *)pszName, fX, fY, -1, 0); cgi.R_DrawString(
cgi.R_DrawString(cgs.media.hudDrawFont, va("%i", cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]), fX, fY + 20.0, -1, 0); cgs.media.hudDrawFont,
(char *)pszName,
fX / cgs.uiHiResScale[0] + 24.0,
fY / cgs.uiHiResScale[1],
-1,
cgs.uiHiResScale
);
cgi.R_DrawString(
cgs.media.hudDrawFont,
va("%i", cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]),
fX / cgs.uiHiResScale[0] + 24.0,
fY / cgs.uiHiResScale[1] + 20.0,
-1,
cgs.uiHiResScale
);
} }
void CG_UpdateAttackerDisplay() void CG_UpdateAttackerDisplay()
@ -900,7 +982,17 @@ void CG_UpdateAttackerDisplay()
if (handle) { if (handle) {
cgi.R_SetColor(0); cgi.R_SetColor(0);
cgi.R_DrawStretchPic(56.0, fY, 24.0, 24.0, 0.0, 0.0, 1.0, 1.0, handle); cgi.R_DrawStretchPic(
56.0 * cgs.uiHiResScale[0],
fY,
24.0 * cgs.uiHiResScale[0],
24.0 * cgs.uiHiResScale[1],
0.0,
0.0,
1.0,
1.0,
handle
);
} }
if ((cg.snap->ps.stats[STAT_TEAM] == TEAM_ALLIES || cg.snap->ps.stats[STAT_TEAM] == TEAM_AXIS) if ((cg.snap->ps.stats[STAT_TEAM] == TEAM_ALLIES || cg.snap->ps.stats[STAT_TEAM] == TEAM_AXIS)
@ -914,7 +1006,7 @@ void CG_UpdateAttackerDisplay()
color[2] = 0.5; color[2] = 0.5;
} }
fX = 56.0 + 32.0; fX = 56.0;
} else { } else {
color[0] = 1.0; color[0] = 1.0;
color[1] = 0.5; color[1] = 0.5;
@ -922,11 +1014,15 @@ void CG_UpdateAttackerDisplay()
} }
cgi.R_SetColor(color); cgi.R_SetColor(color);
cgi.R_DrawString(cgs.media.attackerFont, pszName, fX, fY, -1, 0); cgi.R_DrawString(
cgs.media.attackerFont, pszName, fX / cgs.uiHiResScale[0] + 32.0, fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale
);
} }
void CG_UpdateCountdown() void CG_UpdateCountdown()
{ {
const char *message = "";
if (!cg.snap) { if (!cg.snap) {
return; return;
} }
@ -937,16 +1033,25 @@ void CG_UpdateCountdown()
iSecondsLeft = (cgs.matchEndTime - cg.time) / 1000; iSecondsLeft = (cgs.matchEndTime - cg.time) / 1000;
if (iSecondsLeft >= 0) { if (iSecondsLeft >= 0) {
iMinutesLeft = iSecondsLeft / 60; iMinutesLeft = iSecondsLeft / 60;
cgi.Cvar_Set( message = va("%s %2i:%02i", cgi.LV_ConvertString("Time Left:"), iMinutesLeft, iSecondsLeft % 60);
"ui_timemessage", va("%s %2i:%02i", cgi.LV_ConvertString("Time Left:"), iMinutesLeft, iSecondsLeft % 60)
);
} else if (!cgs.matchEndTime) { } else if (!cgs.matchEndTime) {
cgi.Cvar_Set("ui_timemessage", ""); message = "";
} }
} else { } else {
// The match has not started yet // The match has not started yet
cgi.Cvar_Set("ui_timemessage", "Waiting For Players"); message = "Waiting For Players";
} }
if (strcmp(ui_timemessage->string, message)) {
cgi.Cvar_Set("ui_timemessage", message);
}
}
static void CG_RemoveStopwatch()
{
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n");
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_fuse\n");
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_fuse_wet\n");
} }
void CG_DrawStopwatch() void CG_DrawStopwatch()
@ -954,38 +1059,55 @@ void CG_DrawStopwatch()
int iFraction; int iFraction;
if (!cg_hud->integer) { if (!cg_hud->integer) {
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n"); CG_RemoveStopwatch();
return; return;
} }
if (!cgi.stopWatch->iStartTime) { if (!cgi.stopWatch->iStartTime) {
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n"); CG_RemoveStopwatch();
return; return;
} }
if (cgi.stopWatch->iStartTime >= cgi.stopWatch->iEndTime) { if (cgi.stopWatch->iStartTime >= cgi.stopWatch->iEndTime) {
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n"); CG_RemoveStopwatch();
return; return;
} }
if (cgi.stopWatch->iEndTime <= cg.time) { if (cgi.stopWatch->iEndTime <= cg.time) {
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n"); CG_RemoveStopwatch();
return; return;
} }
if (cg.ObjectivesCurrentAlpha >= 0.02) { if (cg.ObjectivesCurrentAlpha >= 0.02) {
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n"); CG_RemoveStopwatch();
return; return;
} }
if (cg.snap && cg.snap->ps.stats[STAT_HEALTH] <= 0) { if (cg.snap && cg.snap->ps.stats[STAT_HEALTH] <= 0) {
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_stopwatch\n"); CG_RemoveStopwatch();
return; return;
} }
if (cgi.stopWatch->eType >= SWT_FUSE_WET) {
iFraction = cgi.stopWatch->iEndTime - cgi.stopWatch->iStartTime;
} else {
iFraction = cgi.stopWatch->iEndTime - cg.time;
}
iFraction = cgi.stopWatch->iEndTime - cg.time;
cgi.Cvar_Set("ui_stopwatch", va("%i", iFraction)); cgi.Cvar_Set("ui_stopwatch", va("%i", iFraction));
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_stopwatch\n");
switch (cgi.stopWatch->eType) {
case SWT_NORMAL:
default:
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_stopwatch\n");
break;
case SWT_FUSE:
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_fuse\n");
break;
case SWT_FUSE_WET:
cgi.Cmd_Execute(EXEC_NOW, "ui_removehud hud_fuse\n");
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_fuse_wet\n");
break;
}
} }
void CG_DrawInstantMessageMenu() void CG_DrawInstantMessageMenu()
@ -1009,7 +1131,9 @@ void CG_DrawInstantMessageMenu()
x = 8.0; x = 8.0;
y = ((float)cgs.glconfig.vidHeight - h) * 0.5; y = ((float)cgs.glconfig.vidHeight - h) * 0.5;
cgi.R_SetColor(0); cgi.R_SetColor(0);
cgi.R_DrawStretchPic(x, y, w, h, 0.0, 0.0, 1.0, 1.0, handle); cgi.R_DrawStretchPic(
x * cgs.uiHiResScale[0], y, w * cgs.uiHiResScale[0], h * cgs.uiHiResScale[1], 0.0, 0.0, 1.0, 1.0, handle
);
} }
void CG_DrawSpectatorView_ver_15() void CG_DrawSpectatorView_ver_15()
@ -1032,10 +1156,14 @@ void CG_DrawSpectatorView_ver_15()
if (!bOnTeam) { if (!bOnTeam) {
cgi.Key_GetKeysForCommand("+attackprimary", &iKey1, &iKey2); cgi.Key_GetKeysForCommand("+attackprimary", &iKey1, &iKey2);
pszString = cgi.LV_ConvertString(va("Press Fire(%s) to join the battle!", cgi.Key_KeynumToBindString(iKey1))); pszString = cgi.LV_ConvertString(va("Press Fire(%s) to join the battle!", cgi.Key_KeynumToBindString(iKey1)));
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1)) * 0.5; fX = (float)(cgs.glconfig.vidWidth
fY = cgs.glconfig.vidHeight - 64.0; - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1) * cgs.uiHiResScale[0])
* 0.5;
fY = cgs.glconfig.vidHeight - 64.0 * cgs.uiHiResScale[1];
cgi.R_SetColor(NULL); cgi.R_SetColor(NULL);
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX, fY, -1, qfalse); cgi.R_DrawString(
cgs.media.attackerFont, pszString, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale
);
} }
if (cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW) { if (cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW) {
@ -1048,10 +1176,14 @@ void CG_DrawSpectatorView_ver_15()
cgi.Key_KeynumToBindString(iKey1b)) cgi.Key_KeynumToBindString(iKey1b))
); );
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1)) * 0.5; fX = (float)(cgs.glconfig.vidWidth
fY = (float)cgs.glconfig.vidHeight - 40.0; - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1) * cgs.uiHiResScale[0])
* 0.5;
fY = (float)cgs.glconfig.vidHeight - 40.0 * cgs.uiHiResScale[1];
cgi.R_SetColor(0); cgi.R_SetColor(0);
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX, fY, -1, 0); cgi.R_DrawString(
cgs.media.attackerFont, pszString, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale
);
} }
if (!bOnTeam && (cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW)) { if (!bOnTeam && (cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW)) {
@ -1059,10 +1191,14 @@ void CG_DrawSpectatorView_ver_15()
pszString = pszString =
cgi.LV_ConvertString(va("Press Use(%s) to enter free spectate mode.", cgi.Key_KeynumToBindString(iKey1))); cgi.LV_ConvertString(va("Press Use(%s) to enter free spectate mode.", cgi.Key_KeynumToBindString(iKey1)));
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1)) * 0.5; fX = (float)(cgs.glconfig.vidWidth
fY = (float)cgs.glconfig.vidHeight - 24.0; - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1) * cgs.uiHiResScale[0])
* 0.5;
fY = (float)cgs.glconfig.vidHeight - 24.0 * cgs.uiHiResScale[1];
cgi.R_SetColor(0); cgi.R_SetColor(0);
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX, fY, -1, 0); cgi.R_DrawString(
cgs.media.attackerFont, pszString, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale
);
} }
if (!(cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW)) { if (!(cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW)) {
@ -1072,20 +1208,27 @@ void CG_DrawSpectatorView_ver_15()
va("Press Use(%s) to enter player following spectate mode.", cgi.Key_KeynumToBindString(iKey1)) va("Press Use(%s) to enter player following spectate mode.", cgi.Key_KeynumToBindString(iKey1))
); );
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1)) * 0.5; fX = (float)(cgs.glconfig.vidWidth
fY = (float)cgs.glconfig.vidHeight - 24.0; - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1) * cgs.uiHiResScale[0])
* 0.5;
fY = (float)cgs.glconfig.vidHeight - 24.0 * cgs.uiHiResScale[1];
cgi.R_SetColor(0); cgi.R_SetColor(0);
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX, fY, -1, 0); cgi.R_DrawString(
cgs.media.attackerFont, pszString, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale
);
} }
if ((cg.predicted_player_state.pm_flags & 0x80) != 0 && cg.snap && cg.snap->ps.stats[STAT_INFOCLIENT] != -1) { if ((cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW) != 0 && cg.snap
&& cg.snap->ps.stats[STAT_INFOCLIENT] != -1) {
int iClientNum; int iClientNum;
qhandle_t hShader; qhandle_t hShader;
vec4_t color; vec4_t color;
char buf[128]; char buf[128];
iClientNum = cg.snap->ps.stats[STAT_INFOCLIENT]; iClientNum = cg.snap->ps.stats[STAT_INFOCLIENT];
sprintf(buf, "%s : %i", cg.clientinfo[iClientNum].name, cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]); Com_sprintf(
buf, sizeof(buf), "%s : %i", cg.clientinfo[iClientNum].name, cg.snap->ps.stats[STAT_INFOCLIENT_HEALTH]
);
hShader = 0; hShader = 0;
color[0] = 0.5; color[0] = 0.5;
@ -1093,10 +1236,14 @@ void CG_DrawSpectatorView_ver_15()
color[2] = 0.5; color[2] = 0.5;
color[3] = 1.0; color[3] = 1.0;
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1) - 16) * 0.5; fX = (float)(cgs.glconfig.vidWidth
fY = (float)cgs.glconfig.vidHeight - 80.0; - (cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1) - 16) * cgs.uiHiResScale[0])
* 0.5;
fY = (float)cgs.glconfig.vidHeight - 80.0 * cgs.uiHiResScale[1];
cgi.R_SetColor(color); cgi.R_SetColor(color);
cgi.R_DrawString(cgs.media.attackerFont, buf, fX, fY, -1, 0); cgi.R_DrawString(
cgs.media.attackerFont, buf, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale
);
if (cg.clientinfo[iClientNum].team == TEAM_ALLIES) { if (cg.clientinfo[iClientNum].team == TEAM_ALLIES) {
hShader = cgi.R_RegisterShader("textures/hud/allies"); hShader = cgi.R_RegisterShader("textures/hud/allies");
@ -1105,9 +1252,18 @@ void CG_DrawSpectatorView_ver_15()
} }
if (hShader) { if (hShader) {
fX -= 20.0;
cgi.R_SetColor(NULL); cgi.R_SetColor(NULL);
cgi.R_DrawStretchPic(fX, fY, 16.0, 16.0, 0.0, 0.0, 1.0, 1.0, hShader); cgi.R_DrawStretchPic(
fX - 20.0 * cgs.uiHiResScale[0],
fY,
16.0 * cgs.uiHiResScale[0],
16.0 * cgs.uiHiResScale[1],
0.0,
0.0,
1.0,
1.0,
hShader
);
} }
} }
} }
@ -1139,10 +1295,14 @@ void CG_DrawSpectatorView_ver_6()
pszString = cgi.LV_ConvertString(va("Press Use(%s) to follow a player.", cgi.Key_KeynumToBindString(iKey1))); pszString = cgi.LV_ConvertString(va("Press Use(%s) to follow a player.", cgi.Key_KeynumToBindString(iKey1)));
} }
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1)) * 0.5; fX = (float)(cgs.glconfig.vidWidth
fY = (float)cgs.glconfig.vidHeight - 40.0; - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1) * cgs.uiHiResScale[0])
* 0.5;
fY = (float)cgs.glconfig.vidHeight - 40.0 * cgs.uiHiResScale[1];
cgi.R_SetColor(0); cgi.R_SetColor(0);
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX, fY, -1, 0); cgi.R_DrawString(
cgs.media.attackerFont, pszString, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale
);
if (!bOnTeam && (cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW)) { if (!bOnTeam && (cg.predicted_player_state.pm_flags & PMF_CAMERA_VIEW)) {
cgi.Key_GetKeysForCommand("+moveup", &iKey1, &iKey2); cgi.Key_GetKeysForCommand("+moveup", &iKey1, &iKey2);
@ -1153,10 +1313,14 @@ void CG_DrawSpectatorView_ver_6()
cgi.Key_KeynumToBindString(iKey1b)) cgi.Key_KeynumToBindString(iKey1b))
); );
fX = (float)(cgs.glconfig.vidWidth - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1)) * 0.5; fX = (float)(cgs.glconfig.vidWidth
fY = (float)cgs.glconfig.vidHeight - 24.0; - cgi.UI_FontStringWidth(cgs.media.attackerFont, pszString, -1) * cgs.uiHiResScale[0])
* 0.5;
fY = (float)cgs.glconfig.vidHeight - 24.0 * cgs.uiHiResScale[1];
cgi.R_SetColor(0); cgi.R_SetColor(0);
cgi.R_DrawString(cgs.media.attackerFont, pszString, fX, fY, -1, 0); cgi.R_DrawString(
cgs.media.attackerFont, pszString, fX / cgs.uiHiResScale[0], fY / cgs.uiHiResScale[1], -1, cgs.uiHiResScale
);
} }
} }
@ -1180,7 +1344,7 @@ void CG_DrawCrosshair()
float x, y; float x, y;
float width, height; float width, height;
shader = NULL; shader = (qhandle_t)0;
if (!cg_hud->integer || !ui_crosshair->integer) { if (!cg_hud->integer || !ui_crosshair->integer) {
return; return;
@ -1190,7 +1354,7 @@ void CG_DrawCrosshair()
return; return;
} }
if ((cg.snap->ps.pm_flags & PMF_NO_LEAN) || (cg.snap->ps.pm_flags & PMF_INTERMISSION)) { if ((cg.snap->ps.pm_flags & PMF_NO_HUD) || (cg.snap->ps.pm_flags & PMF_INTERMISSION)) {
return; return;
} }
@ -1199,6 +1363,9 @@ void CG_DrawCrosshair()
return; return;
} }
// Fixed in OPM: R_RegisterShaderNoMip
// Use R_RegisterShaderNoMip, as it's UI stuff
if (cgs.gametype != GT_FFA) { if (cgs.gametype != GT_FFA) {
AngleVectorsLeft(cg.refdefViewAngles, forward, NULL, NULL); AngleVectorsLeft(cg.refdefViewAngles, forward, NULL, NULL);
@ -1226,23 +1393,23 @@ void CG_DrawCrosshair()
|| ((myFlags & EF_AXIS) && (friendEnt->currentState.eFlags & EF_AXIS))) { || ((myFlags & EF_AXIS) && (friendEnt->currentState.eFlags & EF_AXIS))) {
// friend // friend
if (cg.snap->ps.stats[STAT_CROSSHAIR]) { if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
shader = cgi.R_RegisterShader(cg_crosshair_friend->string); shader = cgi.R_RegisterShaderNoMip(cg_crosshair_friend->string);
} }
} else { } else {
// enemy // enemy
if (cg.snap->ps.stats[STAT_CROSSHAIR]) { if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
shader = cgi.R_RegisterShader(cg_crosshair->string); shader = cgi.R_RegisterShaderNoMip(cg_crosshair->string);
} }
} }
} else { } else {
if (cg.snap->ps.stats[STAT_CROSSHAIR]) { if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
shader = cgi.R_RegisterShader(cg_crosshair->string); shader = cgi.R_RegisterShaderNoMip(cg_crosshair->string);
} }
} }
} else { } else {
// FFA // FFA
if (cg.snap->ps.stats[STAT_CROSSHAIR]) { if (cg.snap->ps.stats[STAT_CROSSHAIR]) {
shader = cgi.R_RegisterShader(cg_crosshair->string); shader = cgi.R_RegisterShaderNoMip(cg_crosshair->string);
} }
} }
@ -1253,7 +1420,7 @@ void CG_DrawCrosshair()
y = (cgs.glconfig.vidHeight - height) * 0.5f; y = (cgs.glconfig.vidHeight - height) * 0.5f;
cgi.R_SetColor(NULL); cgi.R_SetColor(NULL);
cgi.R_DrawStretchPic(x, y, width, height, 0, 0, 1, 1, shader); cgi.R_DrawStretchPic(x, y, width * cgs.uiHiResScale[0], height * cgs.uiHiResScale[1], 0, 0, 1, 1, shader);
} }
} }
@ -1284,15 +1451,17 @@ void CG_DrawVote()
percentNo = cgs.numVotesNo * 100 / (cgs.numUndecidedVotes + cgs.numVotesNo + cgs.numVotesYes); percentNo = cgs.numVotesNo * 100 / (cgs.numUndecidedVotes + cgs.numVotesNo + cgs.numVotesYes);
percentUndecided = cgs.numUndecidedVotes * 100 / (cgs.numUndecidedVotes + cgs.numVotesNo + cgs.numVotesYes); percentUndecided = cgs.numUndecidedVotes * 100 / (cgs.numUndecidedVotes + cgs.numVotesNo + cgs.numVotesYes);
x = 8; x = 8 * cgs.uiHiResScale[0];
y = (cgs.glconfig.vidHeight > 480) ? (cgs.glconfig.vidHeight * 0.725f) : (cgs.glconfig.vidHeight * 0.75f); y = ((cgs.glconfig.vidHeight > 480) ? (cgs.glconfig.vidHeight * 0.725f) : (cgs.glconfig.vidHeight * 0.75f));
cgi.R_SetColor(NULL); cgi.R_SetColor(NULL);
text = va("%s: %s", cgi.LV_ConvertString("Vote Running"), cgs.voteString); text = va("%s: %s", cgi.LV_ConvertString("Vote Running"), cgs.voteString);
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse); cgi.R_DrawString(
cgs.media.attackerFont, text, x / cgs.uiHiResScale[0], y / cgs.uiHiResScale[1], -1, cgs.uiHiResScale
);
y += 12; y += 12 * cgs.uiHiResScale[1];
text = text =
va("%s: %isec %s: %i%% %s: %i%% %s: %i%%", va("%s: %isec %s: %i%% %s: %i%% %s: %i%%",
@ -1304,7 +1473,9 @@ void CG_DrawVote()
percentNo, percentNo,
cgi.LV_ConvertString("Undecided"), cgi.LV_ConvertString("Undecided"),
percentUndecided); percentUndecided);
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse); cgi.R_DrawString(
cgs.media.attackerFont, text, x / cgs.uiHiResScale[0], y / cgs.uiHiResScale[1], -1, cgs.uiHiResScale
);
if (cg.snap && !cg.snap->ps.voted) { if (cg.snap && !cg.snap->ps.voted) {
col[0] = 0.5; col[0] = 0.5;
@ -1313,15 +1484,19 @@ void CG_DrawVote()
col[3] = 1.0; col[3] = 1.0;
cgi.R_SetColor(col); cgi.R_SetColor(col);
y += 12; y += 12 * cgs.uiHiResScale[1];
text = cgi.LV_ConvertString("Vote now, it's your patriotic duty!"); text = cgi.LV_ConvertString("Vote now, it's your patriotic duty!");
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse); cgi.R_DrawString(
cgs.media.attackerFont, text, x / cgs.uiHiResScale[0], y / cgs.uiHiResScale[1], -1, cgs.uiHiResScale
);
y += 12; y += 12 * cgs.uiHiResScale[1];
text = cgi.LV_ConvertString("To vote Yes, press F1. To vote No, press F2."); text = cgi.LV_ConvertString("To vote Yes, press F1. To vote No, press F2.");
cgi.R_DrawString(cgs.media.attackerFont, text, x, y, -1, qfalse); cgi.R_DrawString(
cgs.media.attackerFont, text, x / cgs.uiHiResScale[0], y / cgs.uiHiResScale[1], -1, cgs.uiHiResScale
);
cgi.R_SetColor(NULL); cgi.R_SetColor(NULL);
} }
} }

View file

@ -59,7 +59,7 @@ qboolean CG_LightStyleColor(int style, int realtime, vec4_t color, qboolean clam
time = realtime / 50; time = realtime / 50;
frac = (realtime - (time * 50.0f)) / 50.0f; frac = (realtime - (time * 50.0f)) / 50.0f;
memset(color, 0, sizeof(color)); VectorClear4(color);
if ((style < 0) || (style >= (MAX_LIGHTSTYLES * 2))) { if ((style < 0) || (style >= (MAX_LIGHTSTYLES * 2))) {
cgi.DPrintf("CG_LightStyleColor: style out of range.\n"); cgi.DPrintf("CG_LightStyleColor: style out of range.\n");
return qtrue; return qtrue;

View file

@ -187,6 +187,7 @@ extern "C" {
float min_dist; float min_dist;
float width; float width;
char shader[MAX_RAIN_SHADERS][MAX_STRING_CHARS]; char shader[MAX_RAIN_SHADERS][MAX_STRING_CHARS];
char currentShader[MAX_STRING_CHARS];
int numshaders; int numshaders;
} crain_t; } crain_t;
@ -269,6 +270,8 @@ extern "C" {
qhandle_t hAlliedPlayerModelHandle; qhandle_t hAlliedPlayerModelHandle;
dtiki_t *pAxisPlayerModel; dtiki_t *pAxisPlayerModel;
qhandle_t hAxisPlayerModelHandle; qhandle_t hAxisPlayerModelHandle;
qboolean serverAlliedModelValid;
qboolean serverAxisModelValid;
// view eyes // view eyes
vec3_t vOffsetViewAngles; vec3_t vOffsetViewAngles;
@ -340,6 +343,7 @@ extern "C" {
float ObjectivesBaseAlpha; float ObjectivesBaseAlpha;
float ObjectivesDesiredAlpha; float ObjectivesDesiredAlpha;
float ObjectivesCurrentAlpha; float ObjectivesCurrentAlpha;
int ObjectivesCurrentIndex;
// misc // misc
crain_t rain; crain_t rain;
@ -378,6 +382,7 @@ extern "C" {
float screenXScale; // derived from glconfig float screenXScale; // derived from glconfig
float screenYScale; float screenYScale;
float screenXBias; float screenXBias;
vec2_t uiHiResScale;
int serverCommandSequence; // reliable command stream counter int serverCommandSequence; // reliable command stream counter
int processedSnapshotNum; // the number of snapshots cgame has requested int processedSnapshotNum; // the number of snapshots cgame has requested
@ -429,6 +434,7 @@ extern "C" {
extern cgs_t cgs; extern cgs_t cgs;
extern cg_t cg; extern cg_t cg;
extern clientGameImport_t cgi; extern clientGameImport_t cgi;
extern target_game_e cg_target_game;
extern int cg_protocol; extern int cg_protocol;
extern centity_t cg_entities[MAX_GENTITIES]; extern centity_t cg_entities[MAX_GENTITIES];
extern markPoly_t *cg_markPolys; extern markPoly_t *cg_markPolys;
@ -500,10 +506,18 @@ extern "C" {
extern cvar_t *voiceChat; extern cvar_t *voiceChat;
extern cvar_t *cg_shadowscount; extern cvar_t *cg_shadowscount;
extern cvar_t *cg_shadowdebug; extern cvar_t *cg_shadowdebug;
extern cvar_t *ui_timemessage;
//
// Added in OPM
//
extern cvar_t *cg_fov;
extern cvar_t *cg_cheats;
// //
// cg_main.c // cg_main.c
// //
qboolean CG_UseLargeLightmaps(const char* mapName);
void CG_ProcessConfigString(int num, qboolean modelOnly); void CG_ProcessConfigString(int num, qboolean modelOnly);
const char *CG_ConfigString(int index); const char *CG_ConfigString(int index);
void CG_AddToTeamChat(const char *str); void CG_AddToTeamChat(const char *str);
@ -519,6 +533,9 @@ extern "C" {
// //
// cg_modelanim.cpp // cg_modelanim.cpp
// //
void CG_ProcessPlayerModel();
void CG_ServerModelLoaded(const char* name, qhandle_t handle);
void CG_ServerModelUnloaded(qhandle_t handle);
void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime); void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime);
void CG_AttachEntity( void CG_AttachEntity(
refEntity_t *entity, refEntity_t *parent, dtiki_t *tiki, int tagnum, qboolean use_angles, vec3_t attach_offset refEntity_t *entity, refEntity_t *parent, dtiki_t *tiki, int tagnum, qboolean use_angles, vec3_t attach_offset
@ -726,8 +743,8 @@ extern "C" {
void CG_InitTestTreadMark(); void CG_InitTestTreadMark();
void CG_AddTreadMarks(); void CG_AddTreadMarks();
int CG_PermanentMark( int CG_PermanentMark(
const vec3_t origin, vec3_t origin,
const vec3_t dir, vec3_t dir,
float orientation, float orientation,
float fSScale, float fSScale,
float fTScale, float fTScale,
@ -920,7 +937,8 @@ qboolean CG_LightStyleColor(int style, int realtime, vec4_t color, qboolean clam
void CG_InstaMessageGroupD_f(void); void CG_InstaMessageGroupD_f(void);
void CG_InstaMessageGroupE_f(void); void CG_InstaMessageGroupE_f(void);
void CG_HudPrint_f(void); void CG_HudPrint_f(void);
int CG_CheckCaptureKey(int key, qboolean down, unsigned int time);
qboolean CG_CheckCaptureKey(int key, qboolean down, unsigned int time);
// //
// cg_vehicle.cpp // cg_vehicle.cpp

View file

@ -35,12 +35,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
clientGameImport_t cgi; clientGameImport_t cgi;
static clientGameExport_t cge; static clientGameExport_t cge;
cvar_t *paused; cvar_t *paused;
cvar_t *developer; cvar_t *developer;
cg_t cg; cg_t cg;
cgs_t cgs; cgs_t cgs;
int cg_protocol; target_game_e cg_target_game = TG_INVALID;
centity_t cg_entities[MAX_GENTITIES]; int cg_protocol;
centity_t cg_entities[MAX_GENTITIES];
cvar_t *cg_animSpeed; cvar_t *cg_animSpeed;
cvar_t *cg_debugAnim; cvar_t *cg_debugAnim;
@ -109,6 +110,13 @@ cvar_t *vm_lean_lower;
cvar_t *voiceChat; cvar_t *voiceChat;
cvar_t *cg_shadowscount; cvar_t *cg_shadowscount;
cvar_t *cg_shadowdebug; cvar_t *cg_shadowdebug;
cvar_t *ui_timemessage;
//
// Added in OPM
//
cvar_t *cg_fov;
cvar_t *cg_cheats;
/* /*
================= =================
@ -154,9 +162,9 @@ void CG_RegisterCvars(void)
cg_shadowdebug = cgi.Cvar_Get("cg_shadowdebug", "0", 0); cg_shadowdebug = cgi.Cvar_Get("cg_shadowdebug", "0", 0);
developer = cgi.Cvar_Get("developer", "0", 0); developer = cgi.Cvar_Get("developer", "0", 0);
dm_playermodel = cgi.Cvar_Get("dm_playermodel", "american_army", 3); dm_playermodel = cgi.Cvar_Get("dm_playermodel", "american_army", 3);
dm_playergermanmodel = cgi.Cvar_Get("dm_playergermanmodel", "german_wehrmacht_soldier", 3); dm_playergermanmodel = cgi.Cvar_Get("dm_playergermanmodel", "german_wehrmacht_soldier", CVAR_ARCHIVE | CVAR_USERINFO);
cg_forceModel = cgi.Cvar_Get("cg_forceModel", "0", CVAR_ARCHIVE); cg_forceModel = cgi.Cvar_Get("cg_forceModel", "0", CVAR_ARCHIVE);
cg_animationviewmodel = cgi.Cvar_Get("cg_animationviewmodel", "0", 8); cg_animationviewmodel = cgi.Cvar_Get("cg_animationviewmodel", "0", CVAR_SYSTEMINFO);
cg_hitmessages = cgi.Cvar_Get("cg_hitmessages", "1", CVAR_ARCHIVE); cg_hitmessages = cgi.Cvar_Get("cg_hitmessages", "1", CVAR_ARCHIVE);
cg_acidtrip = cgi.Cvar_Get("cg_acidtrip", "0", CVAR_CHEAT); cg_acidtrip = cgi.Cvar_Get("cg_acidtrip", "0", CVAR_CHEAT);
cg_hud = cgi.Cvar_Get("cg_hud", "0", 0); cg_hud = cgi.Cvar_Get("cg_hud", "0", 0);
@ -196,53 +204,113 @@ void CG_RegisterCvars(void)
vm_lean_lower = cgi.Cvar_Get("vm_lean_lower", "0.1", 0); vm_lean_lower = cgi.Cvar_Get("vm_lean_lower", "0.1", 0);
voiceChat = cgi.Cvar_Get("cg_voicechat", "1", 0); voiceChat = cgi.Cvar_Get("cg_voicechat", "1", 0);
ui_timemessage = cgi.Cvar_Get("ui_timemessage", "", 0);
// see if we are also running the server on this machine // see if we are also running the server on this machine
temp = cgi.Cvar_Get("sv_running", "0", 0); temp = cgi.Cvar_Get("sv_running", "0", 0);
cgs.localServer = temp->integer; cgs.localServer = temp->integer;
//
// Added in OPM
//
cg_fov = cgi.Cvar_Get("cg_fov", "80", CVAR_ARCHIVE);
cg_cheats = cgi.Cvar_Get("cheats", "0", CVAR_USERINFO | CVAR_SERVERINFO | CVAR_LATCH);
}
/*
===============
CG_UseLargeLightmaps
Added in 2.0
Returns true if the standard BSP file should be used, false if the smaller lightmap BSP file should be used
===============
*/
qboolean CG_UseLargeLightmaps(const char* mapName) {
char buffer[MAX_QPATH];
Com_sprintf(buffer, sizeof(buffer), "maps/%s_sml.bsp", mapName);
if (cgi.FS_ReadFile(buffer, NULL, qtrue) == -1) {
return qtrue;
}
return cgi.Cvar_Get("r_largemap", "0", 0)->integer;
}
/*
================
CG_RegisterSoundsForFile
Register the specified ubersound source file
================
*/
void CG_RegisterSoundsForFile(const char *name)
{
int startTime;
int endTime;
Com_Printf("\n\n-----------PARSING '%s'------------\n", name);
Com_Printf(
"Any SetCurrentTiki errors means that tiki wasn't prefetched and tiki-specific sounds for it won't work. To "
"fix prefetch the tiki. Ignore if you don't use that tiki on this level.\n"
);
startTime = cgi.Milliseconds();
CG_Command_ProcessFile(name, qfalse, NULL);
endTime = cgi.Milliseconds();
Com_Printf("Parse/Load time: %f seconds.\n", (float)(endTime - startTime) / 1000.0);
Com_Printf("-------------PARSING '%s' DONE---------------\n\n", name);
}
/*
=================
qsort_compare_strings
perform case-insensitive sorting
=================
*/
int qsort_compare_strings(const void *s1, const void *s2)
{
return Q_stricmp(*(const char **)s1, *(const char **)s2);
} }
/* /*
================= =================
CG_RegisterSounds CG_RegisterSounds
called during a precache command Called during a precache command
================= =================
*/ */
void CG_RegisterSounds(void) void CG_RegisterSounds(void)
{ {
int startTime; char **fileList;
int endTime; int numFiles;
char filename[MAX_QPATH]; int i;
Com_Printf("\n\n-----------PARSING UBERSOUND------------\n"); fileList = cgi.FS_ListFilteredFiles("ubersound/", "scr", "*.scr", qfalse, &numFiles, qtrue);
Com_Printf( if (cg_target_game >= TG_MOHTA) {
"Any SetCurrentTiki errors means that tiki wasn't prefetched and " // Fixed in 2.0
"tiki-specific sounds for it won't work. To fix prefe" // The behavior has changed, all aliases get cleared
"tch the tiki. Ignore if you don't use that tiki on this level.\n" if (cgs.gametype != GT_SINGLE_PLAYER) {
); cgi.Alias_Clear();
Com_sprintf(filename, sizeof(filename), "ubersound/ubersound.scr"); }
} else {
if (!cgs.localServer) {
cgi.Alias_Clear();
}
}
qsort(fileList, numFiles, sizeof(char *), &qsort_compare_strings);
startTime = cgi.Milliseconds(); for (i = 0; i < numFiles; i++) {
CG_Command_ProcessFile(filename, 0, 0); // Added in 2.0
endTime = cgi.Milliseconds(); // Since 2.0, all files in the ubersound folder
// are parsed
CG_RegisterSoundsForFile(va("ubersound/%s", fileList[i]));
}
Com_Printf("Parse/Load time: %f seconds.\n", (endTime - startTime) / 1000.0f); cgi.FS_FreeFileList(fileList);
Com_Printf("-------------UBERSOUND DONE---------------\n\n");
Com_Printf("\n\n-----------PARSING UBERDIALOG------------\n");
Com_Printf(
"Any SetCurrentTiki errors means that tiki wasn't prefetched and "
"tiki-specific sounds for it won't work. To fix prefe"
"tch the tiki. Ignore if you don't use that tiki on this level.\n"
);
Com_sprintf(filename, sizeof(filename), "ubersound/uberdialog.scr");
startTime = cgi.Milliseconds();
CG_Command_ProcessFile(filename, 0, 0);
endTime = cgi.Milliseconds() - startTime;
Com_Printf("Parse/Load time: %f seconds.\n", endTime / 1000.0f);
Com_Printf("-------------UBERDIALOG DONE---------------\n\n");
} }
/* /*
@ -252,13 +320,11 @@ CG_IsHandleUnique
Check if the model handle is unique Check if the model handle is unique
================ ================
*/ */
static qboolean CG_IsHandleUnique(int num) { static qboolean CG_IsHandleUnique(qhandle_t handle) {
qhandle_t handle;
int i; int i;
int numRef; int numRef;
numRef = 0; numRef = 0;
handle = cgs.model_draw[num];
for (i = 0; i < MAX_MODELS; i++) { for (i = 0; i < MAX_MODELS; i++) {
if (cgs.model_draw[i] == handle) { if (cgs.model_draw[i] == handle) {
numRef++; numRef++;
@ -301,6 +367,8 @@ void CG_ProcessConfigString(int num, qboolean modelOnly)
if (tiki) { if (tiki) {
CG_ProcessCacheInitCommands(tiki); CG_ProcessCacheInitCommands(tiki);
} }
CG_ServerModelLoaded(str, hModel);
} else { } else {
// clear out the model // clear out the model
if (hOldModel && CG_IsHandleUnique(hOldModel)) { if (hOldModel && CG_IsHandleUnique(hOldModel)) {
@ -308,6 +376,10 @@ void CG_ProcessConfigString(int num, qboolean modelOnly)
cgi.R_UnregisterServerModel(hOldModel); cgi.R_UnregisterServerModel(hOldModel);
} }
cgs.model_draw[num - CS_MODELS] = 0; cgs.model_draw[num - CS_MODELS] = 0;
if (!str || !str[0]) {
CG_ServerModelUnloaded(hOldModel);
}
} }
} }
@ -335,28 +407,39 @@ void CG_ProcessConfigString(int num, qboolean modelOnly)
cg.rain.width = atof(str); cg.rain.width = atof(str);
return; return;
case CS_RAIN_SHADER: case CS_RAIN_SHADER:
Q_strncpyz(cg.rain.currentShader, str, sizeof(cg.rain.currentShader));
if (cg.rain.numshaders) { if (cg.rain.numshaders) {
for (i = 0; i < cg.rain.numshaders; i++) { // Fixed in OPM
sprintf(cg.rain.shader[i], "%s%i", str, i); // not sure why some maps set a digit at the end...
size_t len = strlen(cg.rain.currentShader);
if (isdigit(cg.rain.currentShader[len - 1])) {
cg.rain.currentShader[len - 1] = 0;
} }
} else { }
strcpy(cg.rain.shader[0], str); for (i = 0; i < cg.rain.numshaders; ++i) {
Com_sprintf(cg.rain.shader[i], sizeof(cg.rain.shader[i]), "%s%i", cg.rain.currentShader, i);
}
if (!cg.rain.numshaders) {
Q_strncpyz(cg.rain.shader[0], cg.rain.currentShader, sizeof(cg.rain.shader[0]));
} }
return; return;
case CS_RAIN_NUMSHADERS: case CS_RAIN_NUMSHADERS:
cg.rain.numshaders = atoi(str); cg.rain.numshaders = atoi(str);
if (cg.rain.numshaders) { if (cg.rain.numshaders) {
for (i = 0; i < cg.rain.numshaders; i++) { for (i = 0; i < cg.rain.numshaders; i++) {
sprintf(cg.rain.shader[i], "%s%i", str, i); Com_sprintf(cg.rain.shader[i], sizeof(cg.rain.shader[i]), "%s%i", cg.rain.currentShader, i);
} }
} }
return; return;
case CS_CURRENT_OBJECTIVE:
cg.ObjectivesCurrentIndex = atoi(str);
return;
} }
if (num >= CS_OBJECTIVES && num < CS_OBJECTIVES + MAX_OBJECTIVES) { if (num >= CS_OBJECTIVES && num < CS_OBJECTIVES + MAX_OBJECTIVES) {
cobjective_t *objective = &cg.Objectives[num - CS_OBJECTIVES]; cobjective_t *objective = &cg.Objectives[num - CS_OBJECTIVES];
objective->flags = atoi(Info_ValueForKey(str, "flags")); objective->flags = atoi(Info_ValueForKey(str, "flags"));
strcpy(objective->text, Info_ValueForKey(str, "text")); Q_strncpyz(objective->text, Info_ValueForKey(str, "text"), sizeof(objective->text));
} }
switch (num) { switch (num) {
@ -411,7 +494,7 @@ void CG_ProcessConfigString(int num, qboolean modelOnly)
if (len) { if (len) {
qboolean streamed; qboolean streamed;
char buf[1024]; char buf[1024];
strcpy(buf, str); Q_strncpyz(buf, str, sizeof(buf));
streamed = buf[len - 1] != '0'; streamed = buf[len - 1] != '0';
buf[len - 1] = 0; buf[len - 1] = 0;
@ -525,6 +608,7 @@ void CG_GetRendererConfig(void)
cgi.GetGlconfig(&cgs.glconfig); cgi.GetGlconfig(&cgs.glconfig);
cgs.screenXScale = cgs.glconfig.vidWidth / 640.0; cgs.screenXScale = cgs.glconfig.vidWidth / 640.0;
cgs.screenYScale = cgs.glconfig.vidHeight / 480.0; cgs.screenYScale = cgs.glconfig.vidHeight / 480.0;
cgi.UI_GetHighResolutionScale(cgs.uiHiResScale);
} }
/* /*
@ -623,6 +707,8 @@ void CG_Init(clientGameImport_t *imported, int serverMessageNum, int serverComma
cgi = *imported; cgi = *imported;
cg_protocol = cgi.Cvar_Get("com_protocol", "", 0)->integer; cg_protocol = cgi.Cvar_Get("com_protocol", "", 0)->integer;
cg_target_game = (target_game_e)cgi.Cvar_Get("com_target_game", "0", 0)->integer;
CG_InitCGMessageAPI(&cge); CG_InitCGMessageAPI(&cge);
CG_InitScoresAPI(&cge); CG_InitScoresAPI(&cge);
@ -811,7 +897,7 @@ void Com_Error(int level, const char *error, ...)
char text[1024]; char text[1024];
va_start(argptr, error); va_start(argptr, error);
vsprintf(text, error, argptr); Q_vsnprintf(text, sizeof(text), error, argptr);
va_end(argptr); va_end(argptr);
cgi.Error(level, "%s", text); cgi.Error(level, "%s", text);
@ -823,7 +909,7 @@ void Com_Printf(const char *msg, ...)
char text[1024]; char text[1024];
va_start(argptr, msg); va_start(argptr, msg);
vsprintf(text, msg, argptr); Q_vsnprintf(text, sizeof(text), msg, argptr);
va_end(argptr); va_end(argptr);
cgi.Printf("%s", text); cgi.Printf("%s", text);

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2023 the OpenMoHAA team Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -26,6 +26,33 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cg_local.h" #include "cg_local.h"
#include "tiki.h" #include "tiki.h"
static qboolean cg_forceModelAllowed = qfalse;
/*
===============
CG_GetPlayerModelTiki
===============
*/
const char *CG_GetPlayerModelTiki(const char *modelName)
{
return va("models/player/%s.tik", modelName);
}
/*
===============
CG_GetPlayerLocalModelTiki
===============
*/
const char *CG_GetPlayerLocalModelTiki(const char *modelName)
{
return va("models/player/%s.tik", modelName);
}
/*
===============
CG_PlayerTeamIcon
===============
*/
void CG_PlayerTeamIcon(refEntity_t *pModel, entityState_t *pPlayerState) void CG_PlayerTeamIcon(refEntity_t *pModel, entityState_t *pPlayerState)
{ {
qboolean bInArtillery, bInTeam, bSpecialIcon; qboolean bInArtillery, bInTeam, bSpecialIcon;
@ -180,6 +207,118 @@ void CG_PlayerTeamIcon(refEntity_t *pModel, entityState_t *pPlayerState)
} }
} }
/*
===============
CG_InterpolateAnimParms
Interpolate between current and next entity
===============
*/
void CG_InterpolateAnimParms(entityState_t *state, entityState_t *sNext, refEntity_t *model)
{
static cvar_t *vmEntity = NULL;
int i;
float t;
float animLength;
float t1, t2;
if (!vmEntity) {
vmEntity = cgi.Cvar_Get("viewmodelanim", "1", 0);
}
if (sNext && sNext->usageIndex == state->usageIndex) {
t1 = cg.time - cg.snap->serverTime;
t2 = cg.nextSnap->serverTime - cg.snap->serverTime;
t = t1 / t2;
model->actionWeight = (sNext->actionWeight - state->actionWeight) * t + state->actionWeight;
for (i = 0; i < MAX_FRAMEINFOS; i++) {
if (sNext->frameInfo[i].weight) {
model->frameInfo[i].index = sNext->frameInfo[i].index;
if (sNext->frameInfo[i].index == state->frameInfo[i].index && state->frameInfo[i].weight) {
model->frameInfo[i].weight =
(sNext->frameInfo[i].weight - state->frameInfo[i].weight) * t + state->frameInfo[i].weight;
if (sNext->frameInfo[i].time >= state->frameInfo[i].time) {
model->frameInfo[i].time =
(sNext->frameInfo[i].time - state->frameInfo[i].time) * t + state->frameInfo[i].time;
} else {
animLength = cgi.Anim_Time(model->tiki, sNext->frameInfo[i].index);
if (!animLength) {
t1 = 0.0;
} else {
t1 = (animLength + sNext->frameInfo[i].time - state->frameInfo[i].time) * t
+ state->frameInfo[i].time;
}
t2 = t1;
while (t2 > animLength) {
t2 -= animLength;
if (t2 == t1) {
t2 = 1.0;
break;
}
t1 = t2;
}
model->frameInfo[i].time = t2;
}
} else {
animLength = cgi.Anim_Time(model->tiki, sNext->frameInfo[i].index);
if (!animLength) {
t1 = 0.0;
} else {
t1 = sNext->frameInfo[i].time - (cg.nextSnap->serverTime - cg.time) / 1000.0;
}
model->frameInfo[i].time = Q_max(0, t1);
model->frameInfo[i].weight = sNext->frameInfo[i].weight;
}
} else if (sNext->frameInfo[i].index == state->frameInfo[i].index) {
animLength = cgi.Anim_Time(model->tiki, sNext->frameInfo[i].index);
if (!animLength) {
t1 = 0.0;
} else {
t1 = (cg.time - cg.snap->serverTime) / 1000.0 + state->frameInfo[i].time;
}
model->frameInfo[i].index = Q_clamp_int(state->frameInfo[i].index, 0, model->tiki->a->num_anims - 1);
model->frameInfo[i].time = Q_min(animLength, t1);
model->frameInfo[i].weight = (1.0 - t) * state->frameInfo[i].weight;
} else {
model->frameInfo[i].index = -1;
model->frameInfo[i].weight = 0.0;
}
}
} else {
// no next state, don't blend anims
model->actionWeight = state->actionWeight;
for (i = 0; i < MAX_FRAMEINFOS; i++) {
if (state->frameInfo[i].weight) {
model->frameInfo[i].index = Q_clamp_int(state->frameInfo[i].index, 0, model->tiki->a->num_anims - 1);
model->frameInfo[i].time = state->frameInfo[i].time;
model->frameInfo[i].weight = state->frameInfo[i].weight;
} else {
model->frameInfo[i].index = -1;
model->frameInfo[i].weight = 0.0;
}
}
}
if (vmEntity->integer == state->number) {
static cvar_t *curanim;
if (!curanim) {
curanim = cgi.Cvar_Get("viewmodelanimslot", "1", 0);
}
cgi.Cvar_Set("viewmodelanimclienttime", va("%0.2f", model->frameInfo[curanim->integer].time));
}
}
/* /*
=============== ===============
CG_CastFootShadow CG_CastFootShadow
@ -187,20 +326,20 @@ CG_CastFootShadow
Cast complex foot shadow using lights Cast complex foot shadow using lights
=============== ===============
*/ */
void CG_CastFootShadow(const vec_t* vLightPos, vec_t* vLightIntensity, int iTag, refEntity_t* model) void CG_CastFootShadow(const vec_t *vLightPos, vec_t *vLightIntensity, int iTag, refEntity_t *model)
{ {
int i; int i;
float fAlpha; float fAlpha;
float fLength; float fLength;
float fWidth; float fWidth;
float fAlphaOfs; float fAlphaOfs;
float fOfs; float fOfs;
float fPitchCos; float fPitchCos;
vec3_t vPos; vec3_t vPos;
vec3_t vEnd; vec3_t vEnd;
vec3_t vDelta; vec3_t vDelta;
vec3_t vLightAngles; vec3_t vLightAngles;
trace_t trace; trace_t trace;
orientation_t oFoot; orientation_t oFoot;
VectorCopy(model->origin, vPos); VectorCopy(model->origin, vPos);
@ -210,8 +349,7 @@ void CG_CastFootShadow(const vec_t* vLightPos, vec_t* vLightIntensity, int iTag,
VectorMA(vPos, vEnd[i], model->axis[i], vPos); VectorMA(vPos, vEnd[i], model->axis[i], vPos);
} }
if (cg_shadowdebug->integer) if (cg_shadowdebug->integer) {
{
vec3_t vDir; vec3_t vDir;
// //
@ -262,12 +400,11 @@ void CG_CastFootShadow(const vec_t* vLightPos, vec_t* vLightIntensity, int iTag,
} }
fLength = fPitchCos * fPitchCos * 32.0 + fPitchCos * 8.0 + 10.0; fLength = fPitchCos * fPitchCos * 32.0 + fPitchCos * 8.0 + 10.0;
fOfs = 0.5 - (-4.1 / tan(DEG2RAD(vLightAngles[0])) + 4.0 - fLength) / fLength * 0.5; fOfs = 0.5 - (-4.1 / tan(DEG2RAD(vLightAngles[0])) + 4.0 - fLength) / fLength * 0.5;
VectorMA(vPos, -96.0, vDelta, vEnd); VectorMA(vPos, -96.0, vDelta, vEnd);
CG_Trace(&trace, vPos, vec3_origin, vec3_origin, vEnd, 0, MASK_FOOTSHADOW, qfalse, qtrue, "CG_CastFootShadow"); CG_Trace(&trace, vPos, vec3_origin, vec3_origin, vEnd, 0, MASK_FOOTSHADOW, qfalse, qtrue, "CG_CastFootShadow");
if (cg_shadowdebug->integer) if (cg_shadowdebug->integer) {
{
cgi.R_DebugLine(vPos, vLightPos, 0.75, 0.75, 0.5, 1.0); cgi.R_DebugLine(vPos, vLightPos, 0.75, 0.75, 0.5, 1.0);
cgi.R_DebugLine(vPos, vEnd, 1.0, 1.0, 1.0, 1.0); cgi.R_DebugLine(vPos, vEnd, 1.0, 1.0, 1.0, 1.0);
} }
@ -281,7 +418,7 @@ void CG_CastFootShadow(const vec_t* vLightPos, vec_t* vLightIntensity, int iTag,
trace.fraction = 0; trace.fraction = 0;
} }
fWidth = 10.f - (1.f - trace.fraction) * 6.f; fWidth = 10.f - (1.f - trace.fraction) * 6.f;
fAlphaOfs = (1.f - trace.fraction) * fAlpha; fAlphaOfs = (1.f - trace.fraction) * fAlpha;
fAlpha = Q_max(vLightIntensity[0], Q_max(vLightIntensity[1], vLightIntensity[2])); fAlpha = Q_max(vLightIntensity[0], Q_max(vLightIntensity[1], vLightIntensity[2]));
@ -334,13 +471,21 @@ CG_CastSimpleFeetShadow
Cast basic feet shadow Cast basic feet shadow
=============== ===============
*/ */
void CG_CastSimpleFeetShadow(const trace_t* pTrace, float fWidth, float fAlpha, int iRightTag, int iLeftTag, const dtiki_t* tiki, refEntity_t* model) void CG_CastSimpleFeetShadow(
const trace_t *pTrace,
float fWidth,
float fAlpha,
int iRightTag,
int iLeftTag,
const dtiki_t *tiki,
refEntity_t *model
)
{ {
int i; int i;
float fShadowYaw; float fShadowYaw;
float fLength; float fLength;
vec3_t vPos, vRightPos, vLeftPos; vec3_t vPos, vRightPos, vLeftPos;
vec3_t vDelta; vec3_t vDelta;
orientation_t oFoot; orientation_t oFoot;
// //
@ -374,7 +519,7 @@ void CG_CastSimpleFeetShadow(const trace_t* pTrace, float fWidth, float fAlpha,
// get the facing yaw // get the facing yaw
fShadowYaw = vectoyaw(vDelta); fShadowYaw = vectoyaw(vDelta);
fLength = VectorNormalize(vDelta) * 0.5 + 12; fLength = VectorNormalize(vDelta) * 0.5 + 12;
if (fLength < fWidth * 0.7) { if (fLength < fWidth * 0.7) {
fLength = fWidth * 0.7; fLength = fWidth * 0.7;
} }
@ -439,15 +584,13 @@ qboolean CG_EntityShadow(centity_t *cent, refEntity_t *model)
} }
if (iTagR != -1) { if (iTagR != -1) {
int iNumLights, iCurrLight; int iNumLights, iCurrLight;
vec3_t avLightPos[16], avLightIntensity[16]; vec3_t avLightPos[16], avLightIntensity[16];
iNumLights = Q_clamp(cg_shadowscount->integer, 1, 8); iNumLights = Q_clamp(cg_shadowscount->integer, 1, 8);
iNumLights = cgi.R_GatherLightSources(model->origin, avLightPos, avLightIntensity, iNumLights); iNumLights = cgi.R_GatherLightSources(model->origin, avLightPos, avLightIntensity, iNumLights);
if (iNumLights) if (iNumLights) {
{ for (iCurrLight = 0; iCurrLight < iNumLights; iCurrLight++) {
for (iCurrLight = 0; iCurrLight < iNumLights; iCurrLight++)
{
CG_CastFootShadow(avLightPos[iCurrLight], avLightIntensity[iCurrLight], iTagL, model); CG_CastFootShadow(avLightPos[iCurrLight], avLightIntensity[iCurrLight], iTagL, model);
CG_CastFootShadow(avLightPos[iCurrLight], avLightIntensity[iCurrLight], iTagR, model); CG_CastFootShadow(avLightPos[iCurrLight], avLightIntensity[iCurrLight], iTagR, model);
} }
@ -550,7 +693,7 @@ void CG_AnimationDebugMessage(int number, const char *fmt, ...)
char msg[1024]; char msg[1024];
va_start(argptr, fmt); va_start(argptr, fmt);
vsprintf(msg, fmt, argptr); Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
va_end(argptr); va_end(argptr);
if ((!cg_debugAnimWatch->integer) || ((cg_debugAnimWatch->integer - 1) == number)) { if ((!cg_debugAnimWatch->integer) || ((cg_debugAnimWatch->integer - 1) == number)) {
@ -614,6 +757,11 @@ void CG_AttachEntity(
VectorAdd(entity->origin, vOrigin, entity->lightingOrigin); VectorAdd(entity->origin, vOrigin, entity->lightingOrigin);
} }
/*
===============
CG_AttachEyeEntity
===============
*/
void CG_AttachEyeEntity( void CG_AttachEyeEntity(
refEntity_t *entity, refEntity_t *parent, dtiki_t *tiki, int tagnum, qboolean use_angles, vec_t *attach_offset refEntity_t *entity, refEntity_t *parent, dtiki_t *tiki, int tagnum, qboolean use_angles, vec_t *attach_offset
) )
@ -626,8 +774,7 @@ void CG_AttachEyeEntity(
AnglesToAxis(cg.refdefViewAngles, entity->axis); AnglesToAxis(cg.refdefViewAngles, entity->axis);
} }
if (attach_offset[0] || attach_offset[1] || attach_offset[2]) if (attach_offset[0] || attach_offset[1] || attach_offset[2]) {
{
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
VectorMA(entity->origin, attach_offset[i], entity->axis[i], entity->origin); VectorMA(entity->origin, attach_offset[i], entity->axis[i], entity->origin);
} }
@ -639,56 +786,219 @@ void CG_AttachEyeEntity(
VectorCopy(parent->lightingOrigin, entity->lightingOrigin); VectorCopy(parent->lightingOrigin, entity->lightingOrigin);
} }
/*
===============
CG_IsValidServerModel
===============
*/
qboolean CG_IsValidServerModel(const char *modelpath)
{
const char *str;
int i;
for (i = 1; i < MAX_MODELS; i++) {
str = CG_ConfigString(CS_MODELS + i);
if (!Q_stricmp(str, modelpath)) {
return qtrue;
}
}
return qfalse;
}
/*
===============
CG_CheckValidModels
This verifies the allied player model and the german player model:
- If they don't exist on the client, reset to the default allied player model
- If they don't exist on the server, don't allow forceModel so the client explicitly know the skin isn't supported
===============
*/
void CG_CheckValidModels()
{
const char *modelpath;
qboolean isDirty = qfalse;
if (dm_playermodel->modified) {
// Check for allied model
modelpath = va("models/player/%s.tik", dm_playermodel->string);
if (!cgi.R_RegisterModel(modelpath)) {
cgi.Printf(
"Allied model '%s' is invalid, resetting to '%s'\n", dm_playermodel->string, dm_playermodel->resetString
);
cgi.Cvar_Set("dm_playermodel", dm_playermodel->resetString);
modelpath = va("models/player/%s.tik", dm_playermodel->string);
}
cg.serverAlliedModelValid = CG_IsValidServerModel(modelpath);
}
if (dm_playergermanmodel->modified) {
// Check for axis model
modelpath = va("models/player/%s.tik", dm_playergermanmodel->string);
if (!cgi.R_RegisterModel(modelpath)) {
cgi.Printf(
"Allied model '%s' is invalid, resetting to '%s'\n",
dm_playergermanmodel->string,
dm_playergermanmodel->resetString
);
cgi.Cvar_Set("dm_playergermanmodel", dm_playergermanmodel->resetString);
modelpath = va("models/player/%s.tik", dm_playergermanmodel->string);
}
cg.serverAxisModelValid = CG_IsValidServerModel(modelpath);
}
if (dm_playermodel->modified || dm_playergermanmodel->modified) {
cg_forceModelAllowed = cg.serverAlliedModelValid && cg.serverAxisModelValid;
}
}
/*
===============
CG_ServerModelLoaded
===============
*/
void CG_ServerModelLoaded(const char *name, qhandle_t handle)
{
if (!Q_stricmpn(name, "models/player/", 14) && (!cg.serverAlliedModelValid || !cg.serverAxisModelValid)) {
char modelName[MAX_QPATH];
COM_StripExtension(name + 14, modelName, sizeof(modelName));
//
// The player model has been loaded on the server
// so try again parsing
//
if (!Q_stricmp(modelName, dm_playermodel->string)) {
dm_playermodel->modified = qtrue;
}
if (!Q_stricmp(modelName, dm_playergermanmodel->string)) {
dm_playergermanmodel->modified = qtrue;
}
}
}
/*
===============
CG_ServerModelUnloaded
===============
*/
void CG_ServerModelUnloaded(qhandle_t handle)
{
#if 0
if (cg.serverAlliedModelValid && handle == cg.hAlliedPlayerModelHandle) {
dm_playermodel->modified = qtrue;
}
if (cg.serverAxisModelValid && handle == cg.hAxisPlayerModelHandle) {
dm_playergermanmodel->modified = qtrue;
}
#endif
}
/*
===============
CG_UpdateForceModels
===============
*/
void CG_UpdateForceModels() void CG_UpdateForceModels()
{ {
qhandle_t hModel; qhandle_t hModel;
char* pszAlliesPartial; char *pszAlliesPartial;
char* pszAxisPartial; char *pszAxisPartial;
char szAlliesModel[256]; char szAlliesModel[256];
char szAxisModel[256]; char szAxisModel[256];
qboolean isDirty;
if (cg.pAlliedPlayerModel && cg.pAxisPlayerModel && !dm_playermodel->modified && !dm_playergermanmodel->modified) { isDirty = dm_playermodel->modified || dm_playergermanmodel->modified || cg_forceModel->modified;
if (!cg_forceModelAllowed) {
if (isDirty) {
cgi.Printf(
"One or more of the selected players model don't exist on the server or are not loaded, using the "
"default skin\n"
);
}
return;
}
if (cg.pAlliedPlayerModel && cg.pAxisPlayerModel && !isDirty) {
return; return;
} }
pszAlliesPartial = dm_playermodel->string; pszAlliesPartial = dm_playermodel->string;
pszAxisPartial = dm_playergermanmodel->string; pszAxisPartial = dm_playergermanmodel->string;
sprintf(szAlliesModel, "models/player/%s.tik", pszAlliesPartial); Com_sprintf(szAlliesModel, sizeof(szAlliesModel), "models/player/%s.tik", pszAlliesPartial);
sprintf(szAxisModel, "models/player/%s.tik", pszAxisPartial); Com_sprintf(szAxisModel, sizeof(szAxisModel), "models/player/%s.tik", pszAxisPartial);
hModel = cgi.R_RegisterModel(szAlliesModel);
if (!hModel) hModel = cgi.R_RegisterModel("models/player/american_army.tik"); hModel = cg.serverAlliedModelValid ? cgi.R_RegisterModel(szAlliesModel) : 0;
if (!hModel) {
Com_sprintf(szAlliesModel, sizeof(szAlliesModel), "models/player/%s.tik", dm_playermodel->resetString);
hModel = cgi.R_RegisterModel(szAlliesModel);
}
if (hModel) { if (hModel) {
cg.hAlliedPlayerModelHandle = hModel; cg.hAlliedPlayerModelHandle = hModel;
cg.pAlliedPlayerModel = cgi.R_Model_GetHandle(hModel); cg.pAlliedPlayerModel = cgi.R_Model_GetHandle(hModel);
if (!cg.pAlliedPlayerModel) { if (!cg.pAlliedPlayerModel) {
cg.hAlliedPlayerModelHandle = 0; cg.hAlliedPlayerModelHandle = 0;
} }
} else { } else {
cg.hAlliedPlayerModelHandle = 0; cg.hAlliedPlayerModelHandle = 0;
cg.pAlliedPlayerModel = 0; cg.pAlliedPlayerModel = NULL;
} }
hModel = cgi.R_RegisterModel(szAxisModel); hModel = cg.serverAxisModelValid ? cgi.R_RegisterModel(szAxisModel) : 0;
if (!hModel) hModel = cgi.R_RegisterModel("models/player/german_wehrmacht_soldier.tik"); if (!hModel) {
Com_sprintf(szAxisModel, sizeof(szAxisModel), "models/player/%s.tik", dm_playergermanmodel->resetString);
hModel = cgi.R_RegisterModel(szAxisModel);
}
if (hModel) { if (hModel) {
cg.hAxisPlayerModelHandle = hModel; cg.hAxisPlayerModelHandle = hModel;
cg.pAxisPlayerModel = cgi.R_Model_GetHandle(hModel); cg.pAxisPlayerModel = cgi.R_Model_GetHandle(hModel);
if (!cg.pAxisPlayerModel) { if (!cg.pAxisPlayerModel) {
cg.hAxisPlayerModelHandle = 0; cg.hAxisPlayerModelHandle = 0;
} }
} else { } else {
cg.hAxisPlayerModelHandle = 0; cg.hAxisPlayerModelHandle = 0;
cg.pAxisPlayerModel = 0; cg.pAxisPlayerModel = 0;
} }
// Clear modified flag // Clear modified flag
dm_playermodel->modified = qfalse; //dm_playermodel->modified = qfalse;
dm_playergermanmodel->modified = qfalse; //dm_playergermanmodel->modified = qfalse;
} }
/*
===============
CG_ProcessPlayerModel
Checks player models, and update force models
===============
*/
void CG_ProcessPlayerModel()
{
CG_CheckValidModels();
if (cg_forceModel->integer) {
CG_UpdateForceModels();
}
// Clear modified flag
dm_playermodel->modified = qfalse;
dm_playergermanmodel->modified = qfalse;
cg_forceModel->modified = qfalse;
}
/*
===============
CG_ModelAnim
===============
*/
void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime) void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
{ {
entityState_t *s1; entityState_t *s1;
@ -697,7 +1007,6 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
int i; int i;
vec3_t vMins, vMaxs, vTmp; vec3_t vMins, vMaxs, vTmp;
const char *szTagName; const char *szTagName;
static cvar_t *vmEntity = NULL;
int iAnimFlags; int iAnimFlags;
s1 = &cent->currentState; s1 = &cent->currentState;
@ -709,10 +1018,6 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
memset(&model, 0, sizeof(model)); memset(&model, 0, sizeof(model));
if (!vmEntity) {
vmEntity = cgi.Cvar_Get("viewmodelanim", "1", 0);
}
if (cent->interpolate) { if (cent->interpolate) {
sNext = &cent->nextState; sNext = &cent->nextState;
} }
@ -834,8 +1139,8 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
model.tiki = cgi.R_Model_GetHandle(cgs.model_draw[s1->modelindex]); model.tiki = cgi.R_Model_GetHandle(cgs.model_draw[s1->modelindex]);
if (s1->number != cg.snap->ps.clientNum && (s1->eType == ET_PLAYER || (s1->eFlags & EF_DEAD))) { if (s1->number != cg.snap->ps.clientNum && (s1->eType == ET_PLAYER || (s1->eFlags & EF_DEAD))) {
if (cg_forceModel->integer) { if (cg_forceModel->integer && cg_forceModelAllowed) {
CG_UpdateForceModels(); //CG_UpdateForceModels();
if (s1->eFlags & EF_AXIS) { if (s1->eFlags & EF_AXIS) {
model.hModel = cg.hAxisPlayerModelHandle; model.hModel = cg.hAxisPlayerModelHandle;
@ -859,9 +1164,9 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
if (!model.hModel || !model.tiki) { if (!model.hModel || !model.tiki) {
// Use a model in case it still doesn't exist // Use a model in case it still doesn't exist
if (s1->eFlags & EF_AXIS) { if (s1->eFlags & EF_AXIS) {
model.hModel = cgi.R_RegisterModel("models/player/german_wehrmacht_soldier.tik"); model.hModel = cgi.R_RegisterModel(CG_GetPlayerModelTiki(dm_playergermanmodel->resetString));
} else { } else {
model.hModel = cgi.R_RegisterModel("models/player/american_army.tik"); model.hModel = cgi.R_RegisterModel(CG_GetPlayerModelTiki(dm_playermodel->resetString));
} }
model.tiki = cgi.R_Model_GetHandle(model.hModel); model.tiki = cgi.R_Model_GetHandle(model.hModel);
model.hOldModel = cgs.model_draw[s1->modelindex]; model.hOldModel = cgs.model_draw[s1->modelindex];
@ -880,103 +1185,7 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
model.renderfx |= s1->renderfx; model.renderfx |= s1->renderfx;
cgi.TIKI_SetEyeTargetPos(model.tiki, model.entityNumber, s1->eyeVector); cgi.TIKI_SetEyeTargetPos(model.tiki, model.entityNumber, s1->eyeVector);
if (sNext && sNext->usageIndex == s1->usageIndex) { CG_InterpolateAnimParms(s1, sNext, &model);
float t;
float animLength;
float t1, t2;
t1 = cg.time - cg.snap->serverTime;
t2 = cg.nextSnap->serverTime - cg.snap->serverTime;
t = t1 / t2;
model.actionWeight = (sNext->actionWeight - s1->actionWeight) * t + s1->actionWeight;
for (i = 0; i < MAX_FRAMEINFOS; i++) {
if (sNext->frameInfo[i].weight) {
model.frameInfo[i].index = sNext->frameInfo[i].index;
if (sNext->frameInfo[i].index == s1->frameInfo[i].index && s1->frameInfo[i].weight) {
model.frameInfo[i].weight =
(sNext->frameInfo[i].weight - s1->frameInfo[i].weight) * t + s1->frameInfo[i].weight;
if (sNext->frameInfo[i].time >= s1->frameInfo[i].time) {
model.frameInfo[i].time =
(sNext->frameInfo[i].time - s1->frameInfo[i].time) * t + s1->frameInfo[i].time;
} else {
animLength = cgi.Anim_Time(model.tiki, sNext->frameInfo[i].index);
if (!animLength) {
t1 = 0.0;
} else {
t1 = (animLength + sNext->frameInfo[i].time - s1->frameInfo[i].time) * t
+ s1->frameInfo[i].time;
}
t2 = t1;
while (t2 > animLength) {
t2 -= animLength;
}
model.frameInfo[i].time = t2;
}
} else {
animLength = cgi.Anim_Time(model.tiki, sNext->frameInfo[i].index);
if (!animLength) {
t1 = 0.0;
} else {
t1 = sNext->frameInfo[i].time - (cg.nextSnap->serverTime - cg.time) / 1000.0;
}
t2 = t1;
if (t2 < 0.0) {
t2 = 0.0;
}
model.frameInfo[i].time = t2;
model.frameInfo[i].weight = sNext->frameInfo[i].weight;
}
} else if (sNext->frameInfo[i].index == s1->frameInfo[i].index) {
animLength = cgi.Anim_Time(model.tiki, sNext->frameInfo[i].index);
if (!animLength) {
t1 = 0.0;
} else {
t1 = (cg.time - cg.snap->serverTime) / 1000.0 + s1->frameInfo[i].time;
}
t2 = t1;
if (t2 < animLength) {
t2 = animLength;
}
model.frameInfo[i].index = s1->frameInfo[i].index;
model.frameInfo[i].time = t2;
model.frameInfo[i].weight = (1.0 - t) * s1->frameInfo[i].weight;
} else {
model.frameInfo[i].index = -1;
model.frameInfo[i].weight = 0.0;
}
}
} else {
// no next state, don't blend anims
model.actionWeight = s1->actionWeight;
for (i = 0; i < MAX_FRAMEINFOS; i++) {
if (s1->frameInfo[i].weight) {
model.frameInfo[i].index = s1->frameInfo[i].index;
model.frameInfo[i].time = s1->frameInfo[i].time;
model.frameInfo[i].weight = s1->frameInfo[i].weight;
} else {
model.frameInfo[i].index = -1;
model.frameInfo[i].weight = 0.0;
}
}
}
if (vmEntity->integer == s1->number) {
static cvar_t *curanim;
if (!curanim) {
curanim = cgi.Cvar_Get("viewmodelanimslot", "1", 0);
}
cgi.Cvar_Set("viewmodelanimclienttime", va("%0.2f", model.frameInfo[curanim->integer].time));
}
if (cent->currentState.parent != ENTITYNUM_NONE) { if (cent->currentState.parent != ENTITYNUM_NONE) {
int iTagNum; int iTagNum;
@ -1190,7 +1399,9 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
if (!cg.pLastPlayerWorldModel || cg.pLastPlayerWorldModel != model.tiki) { if (!cg.pLastPlayerWorldModel || cg.pLastPlayerWorldModel != model.tiki) {
qhandle_t hModel; qhandle_t hModel;
char fpsname[128]; char fpsname[128];
COM_StripExtension(model.tiki->a->name, fpsname, sizeof(fpsname)); COM_StripExtension(model.tiki->a->name, fpsname, sizeof(fpsname));
Q_strcat(fpsname, sizeof(fpsname), "_fps.tik");
hModel = cgi.R_RegisterModel(fpsname); hModel = cgi.R_RegisterModel(fpsname);
if (hModel) { if (hModel) {
@ -1201,9 +1412,9 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
} }
} else { } else {
if (cg.snap->ps.stats[STAT_TEAM] == TEAM_AXIS) { if (cg.snap->ps.stats[STAT_TEAM] == TEAM_AXIS) {
hModel = cgi.R_RegisterModel("models/player/german_wehrmacht_soldier_fps.tik"); hModel = cgi.R_RegisterModel(CG_GetPlayerLocalModelTiki(dm_playergermanmodel->resetString));
} else { } else {
hModel = cgi.R_RegisterModel("models/player/american_army_fps.tik"); hModel = cgi.R_RegisterModel(CG_GetPlayerLocalModelTiki(dm_playermodel->resetString));
} }
if (hModel) { if (hModel) {
@ -1227,6 +1438,7 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
memset(model.surfaces, 0, sizeof(model.surfaces)); memset(model.surfaces, 0, sizeof(model.surfaces));
CG_ViewModelAnimation(&model); CG_ViewModelAnimation(&model);
model.renderfx |= RF_FRAMELERP;
cgi.ForceUpdatePose(&model); cgi.ForceUpdatePose(&model);
if ((cent->currentState.eFlags & EF_UNARMED) || cg_drawviewmodel->integer <= 1 if ((cent->currentState.eFlags & EF_UNARMED) || cg_drawviewmodel->integer <= 1
@ -1323,7 +1535,12 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
if (model.frameInfo[i].weight) { if (model.frameInfo[i].weight) {
if (!((cent->animLastWeight >> i) & 1) || model.frameInfo[i].index != cent->animLast[i]) { if (!((cent->animLastWeight >> i) & 1) || model.frameInfo[i].index != cent->animLast[i]) {
CG_ProcessEntityCommands(TIKI_FRAME_ENTRY, model.frameInfo[i].index, s1->number, &model, cent); CG_ProcessEntityCommands(TIKI_FRAME_ENTRY, model.frameInfo[i].index, s1->number, &model, cent);
cent->animLastTimes[i] = 0.0; if (cent->animLastTimes[i] == -1) {
cent->animLast[i] = model.frameInfo[i].index;
cent->animLastTimes[i] = model.frameInfo[i].time;
} else {
cent->animLastTimes[i] = 0;
}
} }
CG_ClientCommands(&model, cent, i); CG_ClientCommands(&model, cent, i);

View file

@ -51,16 +51,16 @@ void RainTouch(ctempmodel_t *ct, trace_t *trace)
void ClientGameCommandManager::RainTouch(Event *ev) void ClientGameCommandManager::RainTouch(Event *ev)
{ {
// FIXME: unimplemented // Nothing to do
} }
void ClientGameCommandManager::InitializeRainCvars() void ClientGameCommandManager::InitializeRainCvars()
{ {
int i; int i;
cg_rain = cgi.Cvar_Get("cg_rain", "0", CVAR_ARCHIVE); cg_rain = cgi.Cvar_Get("cg_rain", "1", CVAR_ARCHIVE);
cg_rain_drawcoverage = cg_rain_drawcoverage =
cgi.Cvar_Get("cg_rain_drawcoverage", "0", CVAR_SAVEGAME | CVAR_SERVER_CREATED | CVAR_SYSTEMINFO); cgi.Cvar_Get("cg_rain_drawcoverage", "0", CVAR_SAVEGAME | CVAR_RESETSTRING | CVAR_SYSTEMINFO);
cg.rain.density = 0.0; cg.rain.density = 0.0;
cg.rain.speed = 2048.0f; cg.rain.speed = 2048.0f;

File diff suppressed because it is too large Load diff

View file

@ -190,8 +190,9 @@ void CG_ShowTrace(trace_t *trace, int passent, const char *reason)
assert(reason); assert(reason);
assert(trace); assert(trace);
sprintf( Com_sprintf(
text, text,
sizeof(text),
"%0.2f : Pass (%d) Frac %f Hit (%d): '%s'\n", "%0.2f : Pass (%d) Frac %f Hit (%d): '%s'\n",
(float)cg.time / 1000.0f, (float)cg.time / 1000.0f,
passent, passent,
@ -329,8 +330,18 @@ static void CG_InterpolatePlayerStateCamera(void)
// //
VectorCopy(cg.predicted_player_state.camera_angles, cg.camera_angles); VectorCopy(cg.predicted_player_state.camera_angles, cg.camera_angles);
VectorCopy(cg.predicted_player_state.camera_origin, cg.camera_origin); VectorCopy(cg.predicted_player_state.camera_origin, cg.camera_origin);
cg.camera_fov = cg.predicted_player_state.fov;
//
// Added in OPM
// Use the specified fov specified by the server
// when zooming
//
if (cg.predicted_player_state.stats[STAT_INZOOM]) {
cg.camera_fov = cg.predicted_player_state.fov;
} else {
cg.camera_fov = cg_fov->value;
}
// if the next frame is a teleport, we can't lerp to it // if the next frame is a teleport, we can't lerp to it
if (cg.nextFrameCameraCut) { if (cg.nextFrameCameraCut) {
return; return;
@ -342,13 +353,24 @@ static void CG_InterpolatePlayerStateCamera(void)
f = (float)(cg.time - prev->serverTime) / (next->serverTime - prev->serverTime); f = (float)(cg.time - prev->serverTime) / (next->serverTime - prev->serverTime);
// interpolate fov if (cg.predicted_player_state.stats[STAT_INZOOM]) {
cg.camera_fov = prev->ps.fov + f * (next->ps.fov - prev->ps.fov); // interpolate fov
cg.camera_fov = prev->ps.fov + f * (next->ps.fov - prev->ps.fov);
} else {
cg.camera_fov = cg_fov->value;
}
if (!(cg.snap->ps.pm_flags & PMF_CAMERA_VIEW)) { if (!(cg.snap->ps.pm_flags & PMF_CAMERA_VIEW)) {
return; return;
} }
// Added in 2.0
if (cg.predicted_player_state.camera_flags & CF_CAMERA_ANGLES_TURRETMODE) {
VectorCopy(cg.nextSnap->ps.camera_origin, cg.camera_origin);
VectorCopy(cg.nextSnap->ps.camera_angles, cg.camera_angles);
return;
}
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
cg.camera_origin[i] = prev->ps.camera_origin[i] + f * (next->ps.camera_origin[i] - prev->ps.camera_origin[i]); cg.camera_origin[i] = prev->ps.camera_origin[i] + f * (next->ps.camera_origin[i] - prev->ps.camera_origin[i]);
cg.camera_angles[i] = LerpAngle(prev->ps.camera_angles[i], next->ps.camera_angles[i], f); cg.camera_angles[i] = LerpAngle(prev->ps.camera_angles[i], next->ps.camera_angles[i], f);
@ -493,8 +515,13 @@ void CG_PredictPlayerState(void)
cg_pmove.leanSpeed = 2.f; cg_pmove.leanSpeed = 2.f;
} else { } else {
cg_pmove.alwaysAllowLean = qtrue; cg_pmove.alwaysAllowLean = qtrue;
if (cgs.gametype != GT_SINGLE_PLAYER) {
cg_pmove.leanMax = 40.f;
} else {
// Don't allow lean in single-player, like in the original game
cg_pmove.leanMax = 0;
}
cg_pmove.leanMax = 40.f;
cg_pmove.leanAdd = 10.f; cg_pmove.leanAdd = 10.f;
cg_pmove.leanRecoverSpeed = 15.f; cg_pmove.leanRecoverSpeed = 15.f;
cg_pmove.leanSpeed = 4.f; cg_pmove.leanSpeed = 4.f;
@ -515,7 +542,11 @@ void CG_PredictPlayerState(void)
// the server time is beyond our current cg.time, // the server time is beyond our current cg.time,
// because predicted player positions are going to // because predicted player positions are going to
// be ahead of everything else anyway // be ahead of everything else anyway
if (cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport) { // Added in OPM: prediction check
// Don't use the next snapshot if the prediction is about to be disabled
// this prevent "blinking" issues like when entering a vehicle turret gun
// where arms would be seen shortly
if (cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport && !(cg.nextSnap->ps.pm_flags & PMF_NO_PREDICTION)) {
cg.predicted_player_state = cg.nextSnap->ps; cg.predicted_player_state = cg.nextSnap->ps;
cg.physicsTime = cg.nextSnap->serverTime; cg.physicsTime = cg.nextSnap->serverTime;
} else { } else {

View file

@ -120,7 +120,9 @@ functions exported to the main executable
// console variable interaction // console variable interaction
cvar_t *(*Cvar_Get)(const char *var_name, const char *value, int flags); cvar_t *(*Cvar_Get)(const char *var_name, const char *value, int flags);
cvar_t *(*Cvar_Find)(const char *var_name);
void (*Cvar_Set)(const char *var_name, const char *value); void (*Cvar_Set)(const char *var_name, const char *value);
void (*Cvar_CheckRange)(cvar_t* var, float min, float max, qboolean integral);
// ClientCommand and ConsoleCommand parameter access // ClientCommand and ConsoleCommand parameter access
int (*Argc)(void); int (*Argc)(void);
@ -311,12 +313,12 @@ functions exported to the main executable
); // 0 = white ); // 0 = white
fontheader_t *(*R_LoadFont)(const char *name); fontheader_t *(*R_LoadFont)(const char *name);
void (*R_DrawString)( void (*R_DrawString)(
fontheader_t *font, const char *text, float x, float y, int maxLen, qboolean virtualScreen fontheader_t *font, const char *text, float x, float y, int maxLen, const float *pvVirtualScreen
); );
refEntity_t *(*R_GetRenderEntity)(int entityNumber); refEntity_t *(*R_GetRenderEntity)(int entityNumber);
void (*R_ModelBounds)(clipHandle_t model, vec3_t mins, vec3_t maxs); void (*R_ModelBounds)(clipHandle_t model, vec3_t mins, vec3_t maxs);
float (*R_ModelRadius)(clipHandle_t model); float (*R_ModelRadius)(clipHandle_t model);
float (*R_Noise)(float x, float y, float z, float t); float (*R_Noise)(float x, float y, float z, double t);
void (*R_DebugLine)(const vec3_t start, const vec3_t end, float r, float g, float b, float alpha); void (*R_DebugLine)(const vec3_t start, const vec3_t end, float r, float g, float b, float alpha);
baseshader_t *(*GetShader)(int shaderNum); baseshader_t *(*GetShader)(int shaderNum);
// =========== Swipes ============= // =========== Swipes =============
@ -360,6 +362,9 @@ functions exported to the main executable
void (*UI_ShowMenu)(const char *name, qboolean bForce); void (*UI_ShowMenu)(const char *name, qboolean bForce);
void (*UI_HideMenu)(const char *name, qboolean bForce); void (*UI_HideMenu)(const char *name, qboolean bForce);
int (*UI_FontStringWidth)(fontheader_t *font, const char *string, int maxLen); int (*UI_FontStringWidth)(fontheader_t *font, const char *string, int maxLen);
// Added in 2.0
float (*UI_GetObjectivesTop)(void);
void (*UI_GetHighResolutionScale)(vec2_t scale);
int (*Key_StringToKeynum)(const char *str); int (*Key_StringToKeynum)(const char *str);
const char *(*Key_KeynumToBindString)(int keyNum); const char *(*Key_KeynumToBindString)(int keyNum);
@ -430,6 +435,8 @@ functions exported to the main executable
void (*CL_RestoreSavedCgameState)(); void (*CL_RestoreSavedCgameState)();
void (*CL_ClearSavedCgameState)(); void (*CL_ClearSavedCgameState)();
size_t (*getConfigStringIdNormalized)(size_t num);
cvar_t *fsDebug; cvar_t *fsDebug;
hdelement_t *HudDrawElements; hdelement_t *HudDrawElements;
clientAnim_t *anim; clientAnim_t *anim;
@ -463,8 +470,8 @@ functions exported to the main executable
int (*CG_GetParent)(int entNum); int (*CG_GetParent)(int entNum);
float (*CG_GetObjectiveAlpha)(); float (*CG_GetObjectiveAlpha)();
int (*CG_PermanentMark)( int (*CG_PermanentMark)(
const vec3_t origin, vec3_t origin,
const vec3_t dir, vec3_t dir,
float orientation, float orientation,
float sScale, float sScale,
float tScale, float tScale,

View file

@ -58,19 +58,19 @@ void CG_PrepScoreBoardInfo()
{ {
switch (cgs.gametype) { switch (cgs.gametype) {
case GT_TEAM_ROUNDS: case GT_TEAM_ROUNDS:
strcpy(cg.scoresMenuName, "DM_Round_Scoreboard"); Q_strncpyz(cg.scoresMenuName, "DM_Round_Scoreboard", sizeof(cg.scoresMenuName));
break; break;
case GT_OBJECTIVE: case GT_OBJECTIVE:
strcpy(cg.scoresMenuName, "Obj_Scoreboard"); Q_strncpyz(cg.scoresMenuName, "Obj_Scoreboard", sizeof(cg.scoresMenuName));
break; break;
case GT_TOW: case GT_TOW:
strcpy(cg.scoresMenuName, "Tow_Scoreboard"); Q_strncpyz(cg.scoresMenuName, "Tow_Scoreboard", sizeof(cg.scoresMenuName));
break; break;
case GT_LIBERATION: case GT_LIBERATION:
strcpy(cg.scoresMenuName, "Lib_Scoreboard"); Q_strncpyz(cg.scoresMenuName, "Lib_Scoreboard", sizeof(cg.scoresMenuName));
break; break;
default: default:
strcpy(cg.scoresMenuName, "DM_Scoreboard"); Q_strncpyz(cg.scoresMenuName, "DM_Scoreboard", sizeof(cg.scoresMenuName));
break; break;
} }
} }
@ -296,14 +296,15 @@ void CG_ParseScores_ver_15()
switch (iClientTeam) { switch (iClientTeam) {
case 1: case 1:
strcpy(szString3, cgi.LV_ConvertString("Spectators")); Q_strncpyz(szString3, cgi.LV_ConvertString("Spectators"), sizeof(szString3));
break; break;
case 2: case 2:
strcpy(szString3, cgi.LV_ConvertString("Free-For-Allers")); Q_strncpyz(szString3, cgi.LV_ConvertString("Free-For-Allers"), sizeof(szString3));
break; break;
case 3: case 3:
sprintf( Com_sprintf(
szString3, szString3,
sizeof(szString3),
"%s - %d %s", "%s - %d %s",
cgi.LV_ConvertString("Allies"), cgi.LV_ConvertString("Allies"),
atoi(cgi.Argv(2 + iCurrentEntry + iDatumCount * i)), atoi(cgi.Argv(2 + iCurrentEntry + iDatumCount * i)),
@ -312,8 +313,9 @@ void CG_ParseScores_ver_15()
iCurrentEntry++; iCurrentEntry++;
break; break;
case 4: case 4:
sprintf( Com_sprintf(
szString3, szString3,
sizeof(szString3),
"%s - %d %s", "%s - %d %s",
cgi.LV_ConvertString("Axis"), cgi.LV_ConvertString("Axis"),
atoi(cgi.Argv(2 + iCurrentEntry + iDatumCount * i)), atoi(cgi.Argv(2 + iCurrentEntry + iDatumCount * i)),
@ -322,7 +324,7 @@ void CG_ParseScores_ver_15()
iCurrentEntry++; iCurrentEntry++;
break; break;
default: default:
strcpy(szString3, cgi.LV_ConvertString("No Team")); Q_strncpyz(szString3, cgi.LV_ConvertString("No Team"), sizeof(szString3));
break; break;
} }
} else if (iClientNum == -2) { } else if (iClientNum == -2) {
@ -330,14 +332,14 @@ void CG_ParseScores_ver_15()
szString2[0] = 0; szString2[0] = 0;
szString3[0] = 0; szString3[0] = 0;
} else { } else {
strcpy(szString2, va("%i", iClientNum)); Q_strncpyz(szString2, va("%i", iClientNum), sizeof(szString2));
strcpy(szString3, cg.clientinfo[iClientNum].name); Q_strncpyz(szString3, cg.clientinfo[iClientNum].name, sizeof(szString3));
} }
strcpy(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
strcpy(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
strcpy(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
strcpy(szString7, cgi.Argv(5 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString7, cgi.Argv(5 + iCurrentEntry + iDatumCount * i), sizeof(szString7));
if (cgs.gametype >= GT_TEAM_ROUNDS && iClientNum == -1 if (cgs.gametype >= GT_TEAM_ROUNDS && iClientNum == -1
&& (iClientTeam == TEAM_ALLIES || iClientTeam == TEAM_AXIS)) { && (iClientTeam == TEAM_ALLIES || iClientTeam == TEAM_AXIS)) {
@ -370,19 +372,19 @@ void CG_ParseScores_ver_15()
} else { } else {
iClientNum = atoi(cgi.Argv(iCurrentEntry + iDatumCount * i)); iClientNum = atoi(cgi.Argv(iCurrentEntry + iDatumCount * i));
if (iClientNum >= 0) { if (iClientNum >= 0) {
strcpy(szString2, va("%i", iClientNum)); Q_strncpyz(szString2, va("%i", iClientNum), sizeof(szString2));
strcpy(szString3, cg.clientinfo[iClientNum].name); Q_strncpyz(szString3, cg.clientinfo[iClientNum].name, sizeof(szString3));
strcpy(szString4, cgi.Argv(1 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString4, cgi.Argv(1 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
strcpy(szString5, cgi.Argv(2 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString5, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
strcpy(szString6, cgi.Argv(3 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString6, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
strcpy(szString7, cgi.Argv(4 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString7, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString7));
} else { } else {
szString2[0] = 0; szString2[0] = 0;
if (iClientNum == -3) { if (iClientNum == -3) {
strcpy(szString2, cgi.LV_ConvertString("Players")); Q_strncpyz(szString2, cgi.LV_ConvertString("Players"), sizeof(szString2));
bIsHeader = qtrue; bIsHeader = qtrue;
} else if (iClientNum == -2) { } else if (iClientNum == -2) {
strcpy(szString2, cgi.LV_ConvertString("Spectators")); Q_strncpyz(szString2, cgi.LV_ConvertString("Spectators"), sizeof(szString2));
bIsHeader = qtrue; bIsHeader = qtrue;
} else { } else {
// unknown // unknown
@ -535,32 +537,32 @@ void CG_ParseScores_ver_6()
switch (iClientTeam) { switch (iClientTeam) {
case 1: case 1:
strcpy(szString2, cgi.LV_ConvertString("Spectators")); Q_strncpyz(szString2, cgi.LV_ConvertString("Spectators"), sizeof(szString2));
break; break;
case 2: case 2:
strcpy(szString2, cgi.LV_ConvertString("Free-For-Allers")); Q_strncpyz(szString2, cgi.LV_ConvertString("Free-For-Allers"), sizeof(szString2));
break; break;
case 3: case 3:
strcpy(szString2, cgi.LV_ConvertString("Allies")); Q_strncpyz(szString2, cgi.LV_ConvertString("Allies"), sizeof(szString2));
break; break;
case 4: case 4:
strcpy(szString2, cgi.LV_ConvertString("Axis")); Q_strncpyz(szString2, cgi.LV_ConvertString("Axis"), sizeof(szString2));
break; break;
default: default:
strcpy(szString2, cgi.LV_ConvertString("No Team")); Q_strncpyz(szString2, cgi.LV_ConvertString("No Team"), sizeof(szString2));
break; break;
} }
} else if (iClientNum == -2) { } else if (iClientNum == -2) {
// spectating // spectating
szString2[0] = 0; szString2[0] = 0;
} else { } else {
strcpy(szString2, cg.clientinfo[iClientNum].name); Q_strncpyz(szString2, cg.clientinfo[iClientNum].name, sizeof(szString2));
} }
strcpy(szString3, cgi.Argv(2 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString3, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString3));
strcpy(szString4, cgi.Argv(3 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString4, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
strcpy(szString5, cgi.Argv(4 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString5, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
strcpy(szString6, cgi.Argv(5 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString6, cgi.Argv(5 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
if (iClientNum == cg.snap->ps.clientNum) { if (iClientNum == cg.snap->ps.clientNum) {
pItemTextColor = vThisClientTextColor; pItemTextColor = vThisClientTextColor;
@ -587,17 +589,17 @@ void CG_ParseScores_ver_6()
} else { } else {
iClientNum = atoi(cgi.Argv(iCurrentEntry + iDatumCount * i)); iClientNum = atoi(cgi.Argv(iCurrentEntry + iDatumCount * i));
if (iClientNum >= 0) { if (iClientNum >= 0) {
strcpy(szString2, cg.clientinfo[iClientNum].name); Q_strncpyz(szString2, cg.clientinfo[iClientNum].name, sizeof(szString2));
strcpy(szString3, cgi.Argv(1 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString3, cgi.Argv(1 + iCurrentEntry + iDatumCount * i), sizeof(szString3));
strcpy(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString4, cgi.Argv(2 + iCurrentEntry + iDatumCount * i), sizeof(szString4));
strcpy(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString5, cgi.Argv(3 + iCurrentEntry + iDatumCount * i), sizeof(szString5));
strcpy(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i)); Q_strncpyz(szString6, cgi.Argv(4 + iCurrentEntry + iDatumCount * i), sizeof(szString6));
} else { } else {
if (iClientNum == -3) { if (iClientNum == -3) {
strcpy(szString2, cgi.LV_ConvertString("Players")); Q_strncpyz(szString2, cgi.LV_ConvertString("Players"), sizeof(szString2));
bIsHeader = qtrue; bIsHeader = qtrue;
} else if (iClientNum == -2) { } else if (iClientNum == -2) {
strcpy(szString2, cgi.LV_ConvertString("Spectators")); Q_strncpyz(szString2, cgi.LV_ConvertString("Spectators"), sizeof(szString2));
bIsHeader = qtrue; bIsHeader = qtrue;
} else { } else {
// unknown // unknown

View file

@ -1,6 +1,7 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2023 the OpenMoHAA team Copyright (C) 2008-2024 the OpenMoHAA team
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -25,12 +26,27 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cg_local.h" #include "cg_local.h"
#include "../fgame/bg_voteoptions.h" #include "../fgame/bg_voteoptions.h"
#include "cg_servercmds_filter.h"
/*
================
IsWeaponAllowed
Returns true if the weapon is allowed
================
*/
static const char *IsWeaponAllowed(int dmFlags, int flags) static const char *IsWeaponAllowed(int dmFlags, int flags)
{ {
return (dmFlags & flags) ? "0" : "1"; return (dmFlags & flags) ? "0" : "1";
} }
/*
================
QueryLandminesAllowed2
Returns true if landmines is allowed by the map or by a dm flag
================
*/
static qboolean QueryLandminesAllowed2(const char *mapname, int dmflags) static qboolean QueryLandminesAllowed2(const char *mapname, int dmflags)
{ {
if (dmflags & DF_WEAPON_NO_LANDMINE) { if (dmflags & DF_WEAPON_NO_LANDMINE) {
@ -134,6 +150,7 @@ void CG_ParseServerinfo(void)
cgi.Cvar_Set("cg_fraglimit", Info_ValueForKey(info, "fraglimit")); cgi.Cvar_Set("cg_fraglimit", Info_ValueForKey(info, "fraglimit"));
cgi.Cvar_Set("cg_timelimit", Info_ValueForKey(info, "timelimit")); cgi.Cvar_Set("cg_timelimit", Info_ValueForKey(info, "timelimit"));
cgi.Cvar_Set("cg_maxclients", Info_ValueForKey(info, "sv_gametype")); cgi.Cvar_Set("cg_maxclients", Info_ValueForKey(info, "sv_gametype"));
cgi.Cvar_Set("cg_allowvote", Info_ValueForKey(info, "g_allowvote"));
cgi.Cvar_Set("cg_obj_alliedtext1", Info_ValueForKey(info, "g_obj_alliedtext1")); cgi.Cvar_Set("cg_obj_alliedtext1", Info_ValueForKey(info, "g_obj_alliedtext1"));
cgi.Cvar_Set("cg_obj_alliedtext2", Info_ValueForKey(info, "g_obj_alliedtext2")); cgi.Cvar_Set("cg_obj_alliedtext2", Info_ValueForKey(info, "g_obj_alliedtext2"));
cgi.Cvar_Set("cg_obj_alliedtext3", Info_ValueForKey(info, "g_obj_alliedtext3")); cgi.Cvar_Set("cg_obj_alliedtext3", Info_ValueForKey(info, "g_obj_alliedtext3"));
@ -148,10 +165,10 @@ void CG_ParseServerinfo(void)
cgi.Cvar_Set("cg_scoreboardpicover", Info_ValueForKey(info, "g_scoreboardpicover")); cgi.Cvar_Set("cg_scoreboardpicover", Info_ValueForKey(info, "g_scoreboardpicover"));
mapChecksumStr = Info_ValueForKey(info, "sv_mapChecksum"); mapChecksumStr = Info_ValueForKey(info, "sv_mapChecksum");
if (mapChecksumStr && mapChecksumStr[0]) { if (mapChecksumStr && mapChecksumStr[0]) {
cgs.mapChecksum = atoi(mapChecksumStr); cgs.mapChecksum = atoi(mapChecksumStr);
cgs.useMapChecksum = qtrue; cgs.useMapChecksum = qtrue;
} else { } else {
cgs.mapChecksum = 0; cgs.mapChecksum = 0;
cgs.useMapChecksum = qfalse; cgs.useMapChecksum = qfalse;
} }
@ -169,11 +186,15 @@ void CG_ParseServerinfo(void)
if (spawnpos) { if (spawnpos) {
Q_strncpyz(map, mapname, spawnpos - mapname + 1); Q_strncpyz(map, mapname, spawnpos - mapname + 1);
} else { } else {
strcpy(map, mapname); Q_strncpyz(map, mapname, sizeof(map));
} }
Com_sprintf(cgs.mapname, sizeof(cgs.mapname), "maps/%s.bsp", map); if (CG_UseLargeLightmaps(mapname)) {
Com_sprintf(cgs.mapname, sizeof(cgs.mapname), "maps/%s.bsp", map);
} else {
Com_sprintf(cgs.mapname, sizeof(cgs.mapname), "maps/%s_sml.bsp", map);
}
// hide/show huds // hide/show huds
if (cgs.gametype) { if (cgs.gametype) {
cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_timelimit\n"); cgi.Cmd_Execute(EXEC_NOW, "ui_addhud hud_timelimit\n");
@ -296,7 +317,7 @@ static void CG_ServerCommand(qboolean modelOnly)
} }
if (!strcmp(cmd, "cs")) { if (!strcmp(cmd, "cs")) {
CG_ConfigStringModified(atoi(cgi.Argv(1)), modelOnly); CG_ConfigStringModified(cgi.getConfigStringIdNormalized(atoi(cgi.Argv(1))), modelOnly);
return; return;
} }
@ -311,12 +332,12 @@ static void CG_ServerCommand(qboolean modelOnly)
} }
return; return;
} else if (!strcmp(cmd, "printdeathmsg")) { } else if (!strcmp(cmd, "printdeathmsg")) {
const char *s1, *s2, * attackerName, * victimName, *type; const char *s1, *s2, *attackerName, *victimName, *type;
const char *result1, *result2; const char *result1, *result2;
int hudColor; int hudColor;
result1 = NULL; result1 = NULL;
result2 = NULL; result2 = NULL;
s1 = cgi.Argv(1); s1 = cgi.Argv(1);
s2 = cgi.Argv(2); s2 = cgi.Argv(2);
attackerName = cgi.Argv(3); attackerName = cgi.Argv(3);
@ -352,7 +373,14 @@ static void CG_ServerCommand(qboolean modelOnly)
} }
if (!strcmp(cmd, "stufftext")) { if (!strcmp(cmd, "stufftext")) {
cgi.Cmd_Stuff(cgi.Argv(1)); char *cmd = cgi.Argv(1);
if (CG_IsStatementFiltered(cmd)) {
// Added in OPM
// Don't execute filtered commands
return;
}
cgi.Cmd_Stuff(cmd);
cgi.Cmd_Stuff("\n"); cgi.Cmd_Stuff("\n");
return; return;
} }

View file

@ -0,0 +1,292 @@
/*
===========================================================================
Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// DESCRIPTION:
// cg_servercmds_filter.c -- filtered server commands
#include "cg_local.h"
#include "cg_servercmds_filter.h"
//
// List of variables allowed to be changed by the server
//
static const char *whiteListedVariables[] = {
// some mods set this variable to make the sky uniform
"r_fastsky",
"ui_hud",
"subtitle0",
"subtitle1",
"subtitle2",
"subtitle3",
"name",
// for 3rd person server
"cg_3rd_person",
"cg_cameraverticaldisplacement"
};
//
// List of variables allowed to be changed by the server
//
static const char *whiteListedLocalServerVariables[] = {"ui_hidemouse", "ui_showmouse", "cg_marks_add"};
//
// List of commands allowed to be executed by the server
//
static const char *whiteListedCommands[] = {
//
// HUD
//==========
"pushmenu",
"pushmenu_teamselect",
"pushmenu_weaponselect",
"popmenu",
"globalwidgetcommand", // used for mods adding custom HUDs
"ui_addhud",
"ui_removehud",
"echo", // to print stuff client-side
//
// Sounds
//==========
"tmstart",
"tmstartloop",
"tmstop",
"tmvolume",
"play",
"playmp3",
"stopmp3",
//
// Misc
//==========
"primarydmweapon",
"wait",
"+moveup", // workaround for mods that want to prevent inactivity when handling the spectate
"-moveup",
"screenshot",
"screenshotJPEG",
"levelshot",
"`stufftext" // Stufftext detection from Reborn, the player gets kicked without it
};
//
// List of commands allowed to be executed locally
// (when the client also runs the server)
//
static const char *whiteListedLocalServerCommands[] = {
// Used by briefings
"spmap",
"map",
"disconnect",
"cinematic",
"showmenu",
"hidemenu"
};
/*
====================
CG_IsVariableFiltered
Returns whether or not the variable should be filtered
====================
*/
static qboolean CG_IsVariableFiltered(const char *name)
{
size_t i;
for (i = 0; i < ARRAY_LEN(whiteListedVariables); i++) {
if (!Q_stricmp(name, whiteListedVariables[i])) {
return qfalse;
}
}
if (cgs.localServer) {
for (i = 0; i < ARRAY_LEN(whiteListedLocalServerVariables); i++) {
if (!Q_stricmp(name, whiteListedLocalServerVariables[i])) {
return qfalse;
}
}
}
// Filtered
return qtrue;
}
/*
====================
CG_IsSetVariableFiltered
Returns whether or not the variable should be filtered
====================
*/
static qboolean CG_IsSetVariableFiltered(const char *name, char type)
{
cvar_t *var;
if (!CG_IsVariableFiltered(name)) {
return qfalse;
}
if (type != 'u' && type != 's') {
// Don't allow custom info variables to avoid flooding
// the client with many serverinfo and userinfo variables
var = cgi.Cvar_Find(name);
if (!var) {
// Allow as it doesn't exist
return qfalse;
}
if (var->flags & CVAR_USER_CREATED) {
// Allow, it's user-created, wouldn't cause issues
return qfalse;
}
}
// Filtered
return qtrue;
}
/*
====================
CG_IsCommandFiltered
Returns whether or not the variable should be filtered
====================
*/
static qboolean CG_IsCommandFiltered(const char *name)
{
size_t i;
for (i = 0; i < ARRAY_LEN(whiteListedCommands); i++) {
if (!Q_stricmp(name, whiteListedCommands[i])) {
return qfalse;
}
}
if (cgs.localServer) {
// Allow more commands when the client is hosting the server
// Mostly used on single-player mode, like when briefings switch to the next map
for (i = 0; i < ARRAY_LEN(whiteListedLocalServerCommands); i++) {
if (!Q_stricmp(name, whiteListedLocalServerCommands[i])) {
return qfalse;
}
}
}
//
// Test variables
//
return CG_IsVariableFiltered(name);
}
/*
====================
RemoveEndToken
====================
*/
static qboolean RemoveEndToken(char* com_token) {
char* p;
for (p = com_token; p[0]; p++) {
if (*p == ';') {
*p = 0;
return qtrue;
}
}
return qfalse;
}
/*
====================
CG_IsStatementFiltered
Returns whether or not the statement is filtered
====================
*/
qboolean CG_IsStatementFiltered(char *cmd)
{
char* parsed;
char com_token[256];
qboolean bNextStatement = qfalse;
parsed = cmd;
for (Q_strncpyz(com_token, COM_ParseExt(&parsed, qtrue), sizeof(com_token)); com_token[0]; Q_strncpyz(com_token, COM_ParseExt(&parsed, qtrue), sizeof(com_token))) {
bNextStatement = RemoveEndToken(com_token);
if (com_token[0] == ';') {
continue;
}
if (!Q_stricmp(com_token, "set") || !Q_stricmp(com_token, "setu") || !Q_stricmp(com_token, "seta")
|| !Q_stricmp(com_token, "sets") || !Q_stricmp(com_token, "append")) {
char type;
if (Q_stricmp(com_token, "append")) {
type = com_token[3];
} else {
type = 0;
}
//
// variable
//
Q_strncpyz(com_token, COM_ParseExt(&parsed, qfalse), sizeof(com_token));
bNextStatement |= RemoveEndToken(com_token);
if (com_token[0] == ';') {
continue;
}
if (CG_IsSetVariableFiltered(com_token, type)) {
return qtrue;
}
} else {
//
// normal command
//
if (CG_IsCommandFiltered(com_token)) {
return qtrue;
}
}
if (!bNextStatement) {
// Skip up to the next statement
while (parsed && parsed[0]) {
char c = parsed[0];
parsed++;
if (c == '\n' || c == ';') {
break;
}
}
}
}
return qfalse;
}

View file

@ -1,6 +1,6 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2023 the OpenMoHAA team Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -20,7 +20,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=========================================================================== ===========================================================================
*/ */
// tr_ghost.cpp // DESCRIPTION:
// cg_servercmds_filter.h -- filtered server commands
#include "tr_local.h" #pragma once
#include "tr_ghost.h"
#include "cg_local.h"
qboolean CG_IsStatementFiltered(char *cmd);

View file

@ -73,10 +73,10 @@ static void CG_ResetEntity(centity_t *cent)
CG_RemoveClientEntity(cent->currentState.number, tiki, cent); CG_RemoveClientEntity(cent->currentState.number, tiki, cent);
// reset the animation for the entities // reset the animation for the entities
if (tiki && tiki->a->bIsCharacter) { if (tiki) {
for (i = 0; i < MAX_FRAMEINFOS; i++) { for (i = 0; i < MAX_FRAMEINFOS; i++) {
cent->animLast[i] = cent->currentState.frameInfo[i].index; cent->animLast[i] = -1;
cent->animLastTimes[i] = cent->currentState.frameInfo[i].time; cent->animLastTimes[i] = -1;
if (cent->currentState.frameInfo[i].weight) { if (cent->currentState.frameInfo[i].weight) {
cent->animLastWeight |= 1 << i; cent->animLastWeight |= 1 << i;
} else { } else {
@ -87,7 +87,8 @@ static void CG_ResetEntity(centity_t *cent)
} else { } else {
// clear all the last animations // clear all the last animations
for (i = 0; i < MAX_FRAMEINFOS; i++) { for (i = 0; i < MAX_FRAMEINFOS; i++) {
cent->animLast[i] = -1; cent->animLast[i] = -1;
cent->animLastTimes[i] = 0.0;
} }
cent->animLastWeight = 0; cent->animLastWeight = 0;
@ -346,8 +347,10 @@ static snapshot_t *CG_ReadNextSnapshot(void)
snapshot_t *dest; snapshot_t *dest;
if (cg.latestSnapshotNum > cgs.processedSnapshotNum + 1000) { if (cg.latestSnapshotNum > cgs.processedSnapshotNum + 1000) {
cgi.Error( cgi.Printf(
ERR_DROP, "CG_ReadNextSnapshot: way out of range, %i > %i", cg.latestSnapshotNum, cgs.processedSnapshotNum "WARNING: CG_ReadNextSnapshot: way out of range, %i > %i\n",
cg.latestSnapshotNum,
cgs.processedSnapshotNum
); );
} }

View file

@ -1,6 +1,6 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2023 the OpenMoHAA team Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -38,7 +38,8 @@ static vec3_t g_vLadderstepMaxs;
ClientSpecialEffectsManager sfxManager; ClientSpecialEffectsManager sfxManager;
Event EV_SFX_EffectDelay( Event EV_SFX_EffectDelay
(
"effectdelay", "effectdelay",
EV_DEFAULT, EV_DEFAULT,
"iivvvvv", "iivvvvv",
@ -94,7 +95,7 @@ void ClientSpecialEffectsManager::LoadEffects()
cgi.DPrintf("Loading Special Effects...\n"); cgi.DPrintf("Loading Special Effects...\n");
AxisClear(axis); AxisClear(axis);
for (i = 0; i < MAX_SPECIAL_EFFECTS; i++) { for (i = 0; i < SFX_COUNT; i++) {
switch (i) { switch (i) {
case SFX_BHIT_PAPER_LITE: case SFX_BHIT_PAPER_LITE:
szEffectModel = "models/fx/bh_paper_lite.tik"; szEffectModel = "models/fx/bh_paper_lite.tik";
@ -234,9 +235,15 @@ void ClientSpecialEffectsManager::LoadEffects()
szEffectModel = "models/fx/bazookaexp_base.tik"; szEffectModel = "models/fx/bazookaexp_base.tik";
break; break;
case SFX_EXP_HEAVYSHELL_BASE: case SFX_EXP_HEAVYSHELL_BASE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/heavyshellexp_base.tik"; szEffectModel = "models/fx/heavyshellexp_base.tik";
break; break;
case SFX_EXP_TANK_BASE: case SFX_EXP_TANK_BASE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/tankexp_base.tik"; szEffectModel = "models/fx/tankexp_base.tik";
break; break;
case SFX_EXP_GREN_PAPER: case SFX_EXP_GREN_PAPER:
@ -285,30 +292,57 @@ void ClientSpecialEffectsManager::LoadEffects()
szEffectModel = "models/fx/grenexp_carpet.tik"; szEffectModel = "models/fx/grenexp_carpet.tik";
break; break;
case SFX_EXP_HEAVYSHELL_DIRT: case SFX_EXP_HEAVYSHELL_DIRT:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/heavyshellexp_dirt.tik"; szEffectModel = "models/fx/heavyshellexp_dirt.tik";
break; break;
case SFX_EXP_HEAVYSHELL_STONE: case SFX_EXP_HEAVYSHELL_STONE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/heavyshellexp_stone.tik"; szEffectModel = "models/fx/heavyshellexp_stone.tik";
break; break;
case SFX_EXP_HEAVYSHELL_SNOW: case SFX_EXP_HEAVYSHELL_SNOW:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/heavyshellexp_snow.tik"; szEffectModel = "models/fx/heavyshellexp_snow.tik";
break; break;
case SFX_EXP_TANK_DIRT: case SFX_EXP_TANK_DIRT:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/tankexp_dirt.tik"; szEffectModel = "models/fx/tankexp_dirt.tik";
break; break;
case SFX_EXP_TANK_STONE: case SFX_EXP_TANK_STONE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/tankexp_stone.tik"; szEffectModel = "models/fx/tankexp_stone.tik";
break; break;
case SFX_EXP_TANK_SNOW: case SFX_EXP_TANK_SNOW:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/tankexp_snow.tik"; szEffectModel = "models/fx/tankexp_snow.tik";
break; break;
case SFX_EXP_BAZOOKA_DIRT: case SFX_EXP_BAZOOKA_DIRT:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/bazookaexp_dirt.tik"; szEffectModel = "models/fx/bazookaexp_dirt.tik";
break; break;
case SFX_EXP_BAZOOKA_STONE: case SFX_EXP_BAZOOKA_STONE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/bazookaexp_stone.tik"; szEffectModel = "models/fx/bazookaexp_stone.tik";
break; break;
case SFX_EXP_BAZOOKA_SNOW: case SFX_EXP_BAZOOKA_SNOW:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/bazookaexp_snow.tik"; szEffectModel = "models/fx/bazookaexp_snow.tik";
break; break;
case SFX_WATER_RIPPLE_STILL: case SFX_WATER_RIPPLE_STILL:
@ -478,7 +512,7 @@ void ClientSpecialEffectsManager::ExecuteEffect(
current_tiki = NULL; current_tiki = NULL;
pCommand->emitter->cgd.origin = vPos; pCommand->emitter->cgd.origin = vPos;
if (pCommand->emitter->cgd.flags & T_ANGLES) { if (!(pCommand->emitter->cgd.flags & T_ANGLES)) {
pCommand->emitter->cgd.angles = vAngles; pCommand->emitter->cgd.angles = vAngles;
} }
@ -486,7 +520,7 @@ void ClientSpecialEffectsManager::ExecuteEffect(
AxisCopy(axis, pCommand->emitter->tag_axis); AxisCopy(axis, pCommand->emitter->tag_axis);
pCommand->emitter->cgd.createTime = cg.time; pCommand->emitter->cgd.createTime = cg.time;
commandManager.SetSpawnthing(pCommand->emitter); commandManager.SetSpawnthing(pCommand->emitter);
(commandManager.*pCommand->endfcn)(); (commandManager.*pCommand->endfcn)();
} }
} }
@ -904,7 +938,144 @@ void CG_LandingSound(centity_t *ent, refEntity_t *pREnt, float volume, int iEqui
void CG_BodyFallSound(centity_t *ent, refEntity_t *pREnt, float volume) void CG_BodyFallSound(centity_t *ent, refEntity_t *pREnt, float volume)
{ {
// FIXME: unimplemented int contents;
int surftype;
int iEffectNum = -1;
vec3_t vStart, vEnd;
vec3_t midlegs;
str sSoundName;
trace_t trace;
VectorCopy(ent->lerpOrigin, vStart);
vStart[2] += 8;
VectorCopy(vStart, vEnd);
vEnd[2] -= 64;
if (ent->currentState.eType == ET_PLAYER) {
CG_Trace(
&trace,
vStart,
g_vFootstepMins,
g_vFootstepMaxs,
vEnd,
ent->currentState.number,
MASK_PLAYERSOLID,
qtrue,
qtrue,
"Player Landing"
);
} else {
CG_Trace(
&trace,
vStart,
g_vFootstepMins,
g_vFootstepMaxs,
vEnd,
ent->currentState.number,
MASK_MONSTERSOLID,
qfalse,
qfalse,
"Monster Landing"
);
}
if (trace.fraction == 1) {
return;
}
sSoundName = "snd_bodyfall_";
contents = CG_PointContents(trace.endpos, -1);
if (contents & MASK_WATER) {
// take our ground position and trace upwards
VectorCopy(trace.endpos, midlegs);
midlegs[2] += WATER_NO_SPLASH_HEIGHT;
contents = CG_PointContents(midlegs, -1);
if (contents & MASK_WATER) {
sSoundName += "wade";
} else {
sSoundName += "puddle";
iEffectNum = SFX_FOOT_PUDDLE;
}
} else {
surftype = trace.surfaceFlags & MASK_SURF_TYPE;
switch (surftype) {
case SURF_FOLIAGE:
sSoundName += "foliage";
iEffectNum = SFX_FOOT_GRASS;
break;
case SURF_SNOW:
sSoundName += "snow";
iEffectNum = SFX_FOOT_SNOW;
break;
case SURF_CARPET:
sSoundName += "carpet";
iEffectNum = SFX_FOOT_LIGHT_DUST;
break;
case SURF_SAND:
sSoundName += "sand";
iEffectNum = SFX_FOOT_SAND;
break;
case SURF_PUDDLE:
sSoundName += "puddle";
iEffectNum = SFX_FOOT_PUDDLE;
break;
case SURF_GLASS:
sSoundName += "glass";
iEffectNum = SFX_FOOT_LIGHT_DUST;
break;
case SURF_GRAVEL:
sSoundName += "gravel";
iEffectNum = SFX_FOOT_HEAVY_DUST;
break;
case SURF_MUD:
sSoundName += "mud";
iEffectNum = SFX_FOOT_MUD;
break;
case SURF_DIRT:
sSoundName += "dirt";
iEffectNum = SFX_FOOT_DIRT;
break;
case SURF_GRILL:
sSoundName += "grill";
iEffectNum = SFX_FOOT_LIGHT_DUST;
break;
case SURF_GRASS:
sSoundName += "grass";
iEffectNum = SFX_FOOT_GRASS;
break;
case SURF_ROCK:
sSoundName += "stone";
iEffectNum = SFX_FOOT_HEAVY_DUST;
break;
case SURF_PAPER:
sSoundName += "paper";
iEffectNum = SFX_FOOT_LIGHT_DUST;
break;
case SURF_WOOD:
sSoundName += "wood";
iEffectNum = SFX_FOOT_LIGHT_DUST;
break;
case SURF_METAL:
sSoundName += "metal";
iEffectNum = SFX_FOOT_LIGHT_DUST;
break;
default:
sSoundName += "stone";
iEffectNum = SFX_FOOT_HEAVY_DUST;
break;
}
}
if (cg_debugFootsteps->integer) {
cgi.DPrintf("BodyFall: %s volume: %.2f effect = %i\n", sSoundName.c_str(), volume, iEffectNum);
}
commandManager.PlaySound(sSoundName, trace.endpos, -1, volume, -1, -1, 1);
if (iEffectNum != -1) {
sfxManager.MakeEffect_Angles(iEffectNum, trace.endpos, Vector(270, 0, 0));
}
} }
/* /*
@ -1023,5 +1194,5 @@ qboolean ClientSpecialEffectsManager::EffectsPending()
specialeffect_t *ClientSpecialEffectsManager::GetTestEffectPointer() specialeffect_t *ClientSpecialEffectsManager::GetTestEffectPointer()
{ {
return &m_effects[SPECIAL_EFFECT_TEST]; return &m_effects[SFX_TEST_EFFECT];
} }

View file

@ -170,12 +170,9 @@ public:
specialeffectcommand_t *AddNewCommand(); specialeffectcommand_t *AddNewCommand();
}; };
#define MAX_SPECIAL_EFFECTS 99
#define SPECIAL_EFFECT_TEST MAX_SPECIAL_EFFECTS - 1
class ClientSpecialEffectsManager : public Listener class ClientSpecialEffectsManager : public Listener
{ {
specialeffect_t m_effects[99]; specialeffect_t m_effects[SFX_COUNT];
qboolean m_bEffectsLoaded; qboolean m_bEffectsLoaded;
int m_iNumPendingEvents; int m_iNumPendingEvents;

View file

@ -79,6 +79,11 @@ void ClientGameCommandManager::FreeTempModel(ctempmodel_t *p)
RemoveClientEntity(p->number, p->cgd.tiki, NULL, p); RemoveClientEntity(p->number, p->cgd.tiki, NULL, p);
if (m_active_tempmodels.next == p) {
// use the next active temp model
m_active_tempmodels.next = p->next;
}
// remove from the doubly linked active list // remove from the doubly linked active list
p->prev->next = p->next; p->prev->next = p->next;
p->next->prev = p->prev; p->next->prev = p->prev;
@ -86,6 +91,22 @@ void ClientGameCommandManager::FreeTempModel(ctempmodel_t *p)
// the free list is only singly linked // the free list is only singly linked
p->next = m_free_tempmodels; p->next = m_free_tempmodels;
m_free_tempmodels = p; m_free_tempmodels = p;
if (p->m_spawnthing) {
p->m_spawnthing->numtempmodels--;
// delete unused spawnthings
if (!p->m_spawnthing->numtempmodels) {
m_emitters.RemoveObject(p->m_spawnthing);
if (p->m_spawnthing == m_spawnthing) {
m_spawnthing = NULL;
}
delete p->m_spawnthing;
}
p->m_spawnthing = NULL;
}
} }
//=============== //===============
@ -110,10 +131,10 @@ void ClientGameCommandManager::FreeAllTempModels(void)
//=============== //===============
void ClientGameCommandManager::FreeSomeTempModels(void) void ClientGameCommandManager::FreeSomeTempModels(void)
{ {
ctempmodel_t* model; ctempmodel_t *model;
int count = 0; int count = 0;
unsigned int i; unsigned int i;
unsigned int numToFree; unsigned int numToFree;
if (!m_free_tempmodels) { if (!m_free_tempmodels) {
return; return;
@ -138,10 +159,10 @@ void ClientGameCommandManager::FreeSomeTempModels(void)
//=============== //===============
// FreeSpawnthing // FreeSpawnthing
//=============== //===============
void ClientGameCommandManager::FreeSpawnthing(spawnthing_t* sp) void ClientGameCommandManager::FreeSpawnthing(spawnthing_t *sp)
{ {
ctempmodel_t* model; ctempmodel_t *model;
ctempmodel_t* prev; ctempmodel_t *prev;
if (sp->numtempmodels) { if (sp->numtempmodels) {
for (model = m_active_tempmodels.prev; model != &m_active_tempmodels; model = prev) { for (model = m_active_tempmodels.prev; model != &m_active_tempmodels; model = prev) {
@ -178,7 +199,7 @@ void ClientGameCommandManager::ResetTempModels(void)
} }
static int lastTempModelFrameTime = 0; static int lastTempModelFrameTime = 0;
int next_tempmodel_warning = 0; int next_tempmodel_warning = 0;
void CG_ResetTempModels(void) void CG_ResetTempModels(void)
{ {
@ -207,11 +228,16 @@ void ClientGameCommandManager::InitializeTempModels(void)
void ClientGameCommandManager::InitializeTempModelCvars(void) void ClientGameCommandManager::InitializeTempModelCvars(void)
{ {
cg_showtempmodels = cgi.Cvar_Get("cg_showtempmodels", "0", 0); cg_showtempmodels = cgi.Cvar_Get("cg_showtempmodels", "0", 0);
cg_detail = cgi.Cvar_Get("detail", "1", CVAR_ARCHIVE); cg_detail = cgi.Cvar_Get("detail", "1", CVAR_ARCHIVE);
cg_effectdetail = cgi.Cvar_Get("cg_effectdetail", "0.2", CVAR_ARCHIVE);
cg_effectdetail = cgi.Cvar_Get("cg_effectdetail", "0.2", CVAR_ARCHIVE);
cgi.Cvar_CheckRange(cg_effectdetail, 0.2, 1.0, qfalse);
cg_effect_physicsrate = cgi.Cvar_Get("cg_effect_physicsrate", "10", CVAR_ARCHIVE); cg_effect_physicsrate = cgi.Cvar_Get("cg_effect_physicsrate", "10", CVAR_ARCHIVE);
cg_max_tempmodels = cgi.Cvar_Get("cg_max_tempmodels", "1100", CVAR_ARCHIVE); cg_max_tempmodels = cgi.Cvar_Get("cg_max_tempmodels", "1100", CVAR_ARCHIVE);
cgi.Cvar_CheckRange(cg_max_tempmodels, 200, MAX_TEMPMODELS, qtrue);
cg_reserve_tempmodels = cgi.Cvar_Get("cg_reserve_tempmodels", "200", CVAR_ARCHIVE); cg_reserve_tempmodels = cgi.Cvar_Get("cg_reserve_tempmodels", "200", CVAR_ARCHIVE);
if (cg_max_tempmodels->integer > MAX_TEMPMODELS) { if (cg_max_tempmodels->integer > MAX_TEMPMODELS) {
@ -232,9 +258,9 @@ void ClientGameCommandManager::InitializeTempModelCvars(void)
//=============== //===============
void ClientGameCommandManager::AnimateTempModel(ctempmodel_t *p, Vector origin, refEntity_t *newEnt) void ClientGameCommandManager::AnimateTempModel(ctempmodel_t *p, Vector origin, refEntity_t *newEnt)
{ {
int numframes; int numframes;
int deltatime; int deltatime;
int frametime; int frametime;
float prev; float prev;
// This code is for animating tempmodels that are spawned from the client // This code is for animating tempmodels that are spawned from the client
@ -418,9 +444,11 @@ qboolean ClientGameCommandManager::TempModelRealtimeEffects(ctempmodel_t *p, flo
p->ent.shaderRGBA[0] = (int)((float)tempColor[0] * vLighting[0]); p->ent.shaderRGBA[0] = (int)((float)tempColor[0] * vLighting[0]);
p->ent.shaderRGBA[1] = (int)((float)tempColor[1] * vLighting[1]); p->ent.shaderRGBA[1] = (int)((float)tempColor[1] * vLighting[1]);
p->ent.shaderRGBA[2] = (int)((float)tempColor[2] * vLighting[2]);
} else { } else {
p->ent.shaderRGBA[0] = tempColor[0]; p->ent.shaderRGBA[0] = tempColor[0];
p->ent.shaderRGBA[1] = tempColor[1]; p->ent.shaderRGBA[1] = tempColor[1];
p->ent.shaderRGBA[2] = tempColor[2];
} }
if (p->cgd.flags & T_FADEIN && (fadein < 1)) // Do the fadein effect if (p->cgd.flags & T_FADEIN && (fadein < 1)) // Do the fadein effect
@ -468,16 +496,16 @@ void ClientGameCommandManager::OtherTempModelEffects(ctempmodel_t *p, Vector ori
if (p->number != -1) { if (p->number != -1) {
refEntity_t *old_entity; refEntity_t *old_entity;
dtiki_t *old_tiki; dtiki_t *old_tiki;
int oldnum; int oldnum;
float oldscale; float oldscale;
// Set the axis // Set the axis
AnglesToAxis(p->cgd.angles, axis); AnglesToAxis(p->cgd.angles, axis);
old_entity = current_entity; old_entity = current_entity;
old_tiki = current_tiki; old_tiki = current_tiki;
oldnum = current_entity_number; oldnum = current_entity_number;
oldscale = current_scale; oldscale = current_scale;
current_scale = newEnt->scale; current_scale = newEnt->scale;
current_entity = newEnt; current_entity = newEnt;
@ -502,7 +530,7 @@ void ClientGameCommandManager::OtherTempModelEffects(ctempmodel_t *p, Vector ori
if (p->cgd.flags2 & T2_ALIGNSTRETCH) { if (p->cgd.flags2 & T2_ALIGNSTRETCH) {
Vector vDelta; Vector vDelta;
float fScale; float fScale;
vDelta = p->cgd.origin - p->cgd.oldorigin; vDelta = p->cgd.origin - p->cgd.oldorigin;
fScale = vDelta.length() * p->cgd.scale2; fScale = vDelta.length() * p->cgd.scale2;
@ -518,6 +546,7 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
Vector tempangles; Vector tempangles;
trace_t trace; trace_t trace;
float dot; float dot;
int i;
VectorCopy(p->ent.origin, p->lastEnt.origin); VectorCopy(p->ent.origin, p->lastEnt.origin);
AxisCopy(p->ent.axis, p->lastEnt.axis); AxisCopy(p->ent.axis, p->lastEnt.axis);
@ -538,8 +567,8 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
// If linked to the parent or hardlinked, get the parent's origin // If linked to the parent or hardlinked, get the parent's origin
if ((p->cgd.flags & (T_PARENTLINK | T_HARDLINK)) && (p->cgd.parent != ENTITYNUM_NONE)) { if ((p->cgd.flags & (T_PARENTLINK | T_HARDLINK)) && (p->cgd.parent != ENTITYNUM_NONE)) {
centity_t* pc; centity_t *pc;
refEntity_t* e; refEntity_t *e;
pc = &cg_entities[p->cgd.parent]; pc = &cg_entities[p->cgd.parent];
if (!pc->currentValid) { if (!pc->currentValid) {
@ -553,8 +582,7 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
parentOrigin = e->origin; parentOrigin = e->origin;
vectoangles(e->axis[0], parentAngles); vectoangles(e->axis[0], parentAngles);
} } else if (p->cgd.flags & T_SWARM) {
else if (p->cgd.flags & T_SWARM) {
p->cgd.parentOrigin = p->cgd.velocity + p->cgd.accel * ftime * scale; p->cgd.parentOrigin = p->cgd.velocity + p->cgd.accel * ftime * scale;
} }
@ -633,9 +661,7 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
p->cgd.velocity.x = Q_clamp_float(p->cgd.velocity.x, p->cgd.minVel.x, p->cgd.maxVel.x); p->cgd.velocity.x = Q_clamp_float(p->cgd.velocity.x, p->cgd.minVel.x, p->cgd.maxVel.x);
p->cgd.velocity.y = Q_clamp_float(p->cgd.velocity.y, p->cgd.minVel.y, p->cgd.maxVel.y); p->cgd.velocity.y = Q_clamp_float(p->cgd.velocity.y, p->cgd.minVel.y, p->cgd.maxVel.y);
p->cgd.velocity.z = Q_clamp_float(p->cgd.velocity.z, p->cgd.minVel.z, p->cgd.maxVel.z); p->cgd.velocity.z = Q_clamp_float(p->cgd.velocity.z, p->cgd.minVel.z, p->cgd.maxVel.z);
} } else if (p->cgd.flags2 & T2_CLAMP_VEL_AXIS) {
if (p->cgd.flags2 & T2_CLAMP_VEL_AXIS) {
Vector localVelocity; Vector localVelocity;
localVelocity.x = DotProduct(p->cgd.velocity, p->ent.axis[0]); localVelocity.x = DotProduct(p->cgd.velocity, p->ent.axis[0]);
localVelocity.y = DotProduct(p->cgd.velocity, p->ent.axis[1]); localVelocity.y = DotProduct(p->cgd.velocity, p->ent.axis[1]);
@ -650,8 +676,48 @@ qboolean ClientGameCommandManager::TempModelPhysics(ctempmodel_t *p, float ftime
p->cgd.velocity.z = DotProduct(localVelocity, p->ent.axis[2]); p->cgd.velocity.z = DotProduct(localVelocity, p->ent.axis[2]);
} }
if (p->cgd.flags2 & T_ALIGN) { if (p->cgd.flags2 & T2_WIND_AFFECT) {
// FIXME: vss wind for (i = 0; i < 3; i++) {
float fWind;
switch (i) {
case 0:
fWind = vss_wind_x->value;
break;
case 1:
fWind = vss_wind_y->value;
break;
case 2:
fWind = vss_wind_z->value;
break;
}
if (fWind < 0) {
if (p->cgd.velocity[i] > fWind) {
p->cgd.velocity[i] -= ftime * vss_wind_strength->value;
if (p->cgd.velocity[i] > fWind) {
p->cgd.velocity[i] = fWind;
}
} else if (p->cgd.velocity[i] < fWind) {
p->cgd.velocity[i] += ftime * vss_movement_dampen->value;
if (p->cgd.velocity[i] < fWind) {
p->cgd.velocity[i] = fWind;
}
}
} else {
if (p->cgd.velocity[i] < fWind) {
p->cgd.velocity[i] += ftime * vss_wind_strength->value;
if (p->cgd.velocity[i] > fWind) {
p->cgd.velocity[i] = fWind;
}
} else if (p->cgd.velocity[i] > fWind) {
p->cgd.velocity[i] -= ftime * vss_wind_strength->value;
if (p->cgd.velocity[i] < fWind) {
p->cgd.velocity[i] = fWind;
}
}
}
}
} }
} else { } else {
Vector normal; Vector normal;
@ -829,10 +895,11 @@ void ClientGameCommandManager::AddTempModels(void)
refEntity_t *old_ent; refEntity_t *old_ent;
// To counteract cg.time going backwards // To counteract cg.time going backwards
if (lastTempModelFrameTime && ((cg.time < lastTempModelFrameTime) || (cg.time - lastTempModelFrameTime > TOO_MUCH_TIME_PASSED))) { if (lastTempModelFrameTime
&& ((cg.time < lastTempModelFrameTime) || (cg.time - lastTempModelFrameTime > TOO_MUCH_TIME_PASSED))) {
p = m_active_tempmodels.prev; p = m_active_tempmodels.prev;
for (; p != &m_active_tempmodels; p = next) { for (; p != &m_active_tempmodels; p = next) {
next = p->prev; next = p->prev;
p->lastPhysicsTime = cg.time; p->lastPhysicsTime = cg.time;
} }
lastTempModelFrameTime = cg.time; lastTempModelFrameTime = cg.time;
@ -913,7 +980,12 @@ void ClientGameCommandManager::AddTempModels(void)
// time of this tempmodel // time of this tempmodel
lerpfrac = (float)(cg.time - p->lastPhysicsTime) / (float)physics_rate; lerpfrac = (float)(cg.time - p->lastPhysicsTime) / (float)physics_rate;
// Clamp // Clamp
lerpfrac = Q_clamp_float(lerpfrac, 0, 1); if (lerpfrac > 1 || (p->cgd.flags2 & T2_PHYSICS_EVERYFRAME)) {
lerpfrac = 1;
}
if (lerpfrac < 0) {
lerpfrac = 0;
}
// Increment the time this tempmodel has been alive // Increment the time this tempmodel has been alive
p->aliveTime += frameTime; p->aliveTime += frameTime;
@ -927,7 +999,7 @@ void ClientGameCommandManager::AddTempModels(void)
// Run physics if the lastEnt is not valid to get a valid lerp // Run physics if the lastEnt is not valid to get a valid lerp
if (!p->lastEntValid) { if (!p->lastEntValid) {
float t; float t;
t = physics_rate / 1000.0f; t = physics_rate / 1000.0f;
ret = TempModelPhysics(p, t, scale); ret = TempModelPhysics(p, t, scale);
if (!ret) { if (!ret) {
@ -1113,7 +1185,7 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
if (m_spawnthing->cgd.flags & T_WAVE) { if (m_spawnthing->cgd.flags & T_WAVE) {
p->m_spawnthing = m_spawnthing; p->m_spawnthing = m_spawnthing;
m_spawnthing->numtempmodels++; m_spawnthing->numtempmodels++;
start = Vector(0, 0, 0); start = Vector(0, 0, 0);
} else { } else {
p->m_spawnthing = NULL; p->m_spawnthing = NULL;
start = m_spawnthing->cgd.origin; start = m_spawnthing->cgd.origin;
@ -1137,7 +1209,13 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
{ {
Vector dst; Vector dst;
// Create a circular shaped burst around the up vector // Create a circular shaped burst around the up vector
float angle = ((float)count / (float)m_spawnthing->count) * 360; // * M_PI * 2; float angle;
if (mcount == 1) {
angle = random() * 360;
} else {
angle = ((float)count / (float)m_spawnthing->count) * 360; // * M_PI * 2;
}
Vector end = Vector(vLeft) * m_spawnthing->sphereRadius * current_entity_scale; Vector end = Vector(vLeft) * m_spawnthing->sphereRadius * current_entity_scale;
RotatePointAroundVector(dst, Vector(vForward), end, angle); RotatePointAroundVector(dst, Vector(vForward), end, angle);
@ -1146,7 +1224,7 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
newForward = p->cgd.origin - m_spawnthing->cgd.origin; newForward = p->cgd.origin - m_spawnthing->cgd.origin;
newForward.normalize(); newForward.normalize();
} }
} else if (m_spawnthing->cgd.flags & T_SPHERE) { } else if (m_spawnthing->cgd.flags & T_INWARDSPHERE) {
// Project the origin along a random ray, and set the forward // Project the origin along a random ray, and set the forward
// vector pointing back to the origin // vector pointing back to the origin
Vector dir, end; Vector dir, end;
@ -1390,7 +1468,7 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
p->cgd.avelocity[i] = m_spawnthing->avelocity_amplitude[i] * random() + m_spawnthing->avelocity_base[i]; p->cgd.avelocity[i] = m_spawnthing->avelocity_amplitude[i] * random() + m_spawnthing->avelocity_base[i];
// Randomize angles or set absolute // Randomize angles or set absolute
p->cgd.angles[i] += random() * m_spawnthing->angles_amplitude[i]; p->cgd.angles[i] = m_spawnthing->angles_amplitude[i] * random() + m_spawnthing->cgd.angles[i];
} }
// If forward velocity is set, just use that otherwise use random // If forward velocity is set, just use that otherwise use random
@ -1424,18 +1502,15 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
} }
} }
// Calculate one tick of velocity based on time alive ( passed in ) if (m_spawnthing->cgd.flags2 & T2_RADIALVELOCITY) {
p->cgd.origin = p->cgd.origin + (p->cgd.velocity * ((float)p->aliveTime / 1000.0f) * current_entity_scale);
if (p->cgd.flags2 & T2_ACCEL) {
float fLength; float fLength;
p->cgd.velocity = p->cgd.origin - start; p->cgd.velocity = p->cgd.origin - start;
fLength = p->cgd.velocity.length(); fLength = p->cgd.velocity.length();
if (fLength) { if (fLength) {
float fVel = m_spawnthing->cgd.velocity.x float fVel = m_spawnthing->cgd.velocity[0]
+ (m_spawnthing->cgd.velocity.y + m_spawnthing->cgd.velocity.z * crandom()) / fLength; + (m_spawnthing->cgd.velocity[1] + m_spawnthing->cgd.velocity[2] * random()) / fLength;
p->cgd.velocity *= fVel; p->cgd.velocity *= fVel;
} }
@ -1446,20 +1521,22 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
(m_spawnthing->randvel_base[i] + m_spawnthing->randvel_amplitude[i] * random()) * current_entity_scale; (m_spawnthing->randvel_base[i] + m_spawnthing->randvel_amplitude[i] * random()) * current_entity_scale;
if (m_spawnthing->cgd.flags & T_RANDVELAXIS) { if (m_spawnthing->cgd.flags & T_RANDVELAXIS) {
p->cgd.velocity += fVel * Vector(m_spawnthing->tag_axis[i]); if (p->cgd.flags2 & T2_NOTAGAXIS) {
p->cgd.velocity += fVel * Vector(m_spawnthing->axis[i]);
} else {
p->cgd.velocity += fVel * Vector(m_spawnthing->tag_axis[i]);
}
} else { } else {
p->cgd.velocity[i] += fVel; p->cgd.velocity[i] += fVel;
} }
} }
if (p->cgd.flags & (T_ALIGN | T_DETAIL)) { if (p->cgd.flags & (T_ALIGN | T_DETAIL)) {
if (p->cgd.velocity.x && p->cgd.velocity.y) { p->cgd.angles = p->cgd.velocity.toAngles();
p->cgd.angles = p->cgd.velocity.toAngles();
}
p->cgd.origin += p->cgd.velocity * (p->aliveTime / 1000.0) * current_entity_scale;
} }
p->cgd.origin += p->cgd.velocity * (p->aliveTime / 1000.0) * current_entity_scale;
if (p->cgd.flags & T_AUTOCALCLIFE) { if (p->cgd.flags & T_AUTOCALCLIFE) {
Vector end, delta; Vector end, delta;
float length, speed; float length, speed;

File diff suppressed because it is too large Load diff

View file

@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cg_local.h" #include "cg_local.h"
#include "str.h" #include "str.h"
#include "../client/keycodes.h"
void CG_MessageMode_f(void) void CG_MessageMode_f(void)
{ {
@ -61,8 +62,8 @@ void CG_MessageMode_Private_f(void)
return; return;
} }
clientNum = atoi(cgi.Argv(1)) - 1; clientNum = atoi(cgi.Argv(1));
if (clientNum < 0 || clientNum >= MAX_CLIENTS) { if (clientNum < 1 || clientNum >= MAX_CLIENTS) {
cgi.Printf(HUD_MESSAGE_CHAT_WHITE "Message Error: %s is a bad client number\n", cgi.Argv(1)); cgi.Printf(HUD_MESSAGE_CHAT_WHITE "Message Error: %s is a bad client number\n", cgi.Argv(1));
return; return;
} }
@ -119,7 +120,7 @@ void CG_MessageSingleClient_f(void)
// copy the rest // copy the rest
for (i = 2; i < cgi.Argc(); i++) { for (i = 2; i < cgi.Argc(); i++) {
sString += va("%s", cgi.Argv(i)); sString += va(" %s", cgi.Argv(i));
} }
sString += "\n"; sString += "\n";
@ -192,8 +193,36 @@ void CG_HudPrint_f(void)
cgi.Printf("\x1%s", cgi.Argv(1)); cgi.Printf("\x1%s", cgi.Argv(1));
} }
int CG_CheckCaptureKey(int key, qboolean down, unsigned int time) qboolean CG_CheckCaptureKey(int key, qboolean down, unsigned int time)
{ {
// FIXME: unimplemented char minKey = '1', maxKey = '9';
return 0;
if (!cg.iInstaMessageMenu || !down) {
return qfalse;
}
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
maxKey = '8';
}
if (key < minKey || key > maxKey) {
if (key == K_ESCAPE || key == '0') {
cg.iInstaMessageMenu = 0;
return qtrue;
}
return qfalse;
}
if (cg.iInstaMessageMenu == -1) {
if (key > '6') {
cg.iInstaMessageMenu = 0;
} else {
cg.iInstaMessageMenu = key - '0';
}
} else if (cg.iInstaMessageMenu > 0) {
cgi.SendClientCommand(va("dmmessage 0 *%i%i\n", cg.iInstaMessageMenu, key - '0'));
cg.iInstaMessageMenu = 0;
}
return qtrue;
} }

View file

@ -242,6 +242,7 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
float mat[3][3]; float mat[3][3];
vec3_t vOldOrigin; vec3_t vOldOrigin;
vec3_t vStart, vEnd, vMins, vMaxs; vec3_t vStart, vEnd, vMins, vMaxs;
vec3_t vVelocity;
trace_t trace; trace_t trace;
VectorSet(vMins, -6, -6, -6); VectorSet(vMins, -6, -6, -6);
@ -297,6 +298,15 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
VectorCopy(origin, vOldOrigin); VectorCopy(origin, vOldOrigin);
if (!cg.predicted_player_state.walking || (!(cg.predicted_player_state.pm_flags & PMF_FROZEN) && !(cg.predicted_player_state.pm_flags & PMF_NO_MOVE))) {
VectorCopy(cg.predicted_player_state.velocity, vVelocity);
} else {
//
// Added in OPM
// When frozen, there must be no movement at all
VectorClear(vVelocity);
}
if (bUseWorldPosition) { if (bUseWorldPosition) {
iMask = MASK_VIEWSOLID; iMask = MASK_VIEWSOLID;
} else { } else {
@ -367,7 +377,7 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
} }
if (cg.predicted_player_state.walking) { if (cg.predicted_player_state.walking) {
fVel = VectorLength(cg.predicted_player_state.velocity); fVel = VectorLength(vVelocity);
fPhase = fVel * 0.0015 + 0.9; fPhase = fVel * 0.0015 + 0.9;
cg.fCurrentViewBobPhase += (cg.frametime / 1000.0 + cg.frametime / 1000.0) * M_PI * fPhase; cg.fCurrentViewBobPhase += (cg.frametime / 1000.0 + cg.frametime / 1000.0) * M_PI * fPhase;
@ -446,7 +456,7 @@ void CG_OffsetFirstPersonView(refEntity_t *pREnt, qboolean bUseWorldPosition)
AngleVectorsLeft(vDelta, mat[0], mat[1], mat[2]); AngleVectorsLeft(vDelta, mat[0], mat[1], mat[2]);
CG_CalcViewModelMovement( CG_CalcViewModelMovement(
cg.fCurrentViewBobPhase, cg.fCurrentViewBobAmp, cg.predicted_player_state.velocity, vDelta cg.fCurrentViewBobPhase, cg.fCurrentViewBobAmp, vVelocity, vDelta
); );
VectorMA(pREnt->origin, vDelta[0], mat[0], pREnt->origin); VectorMA(pREnt->origin, vDelta[0], mat[0], pREnt->origin);
@ -475,9 +485,16 @@ static int CG_CalcFov(void)
int contents; int contents;
float fov_x, fov_y; float fov_x, fov_y;
int inwater; int inwater;
float fov_ratio;
fov_x = cg.camera_fov; fov_ratio = (float)cg.refdef.width / (float)cg.refdef.height * (3.0 / 4.0);
x = cg.refdef.width / tan(fov_x / 360 * M_PI); if (fov_ratio == 1) {
fov_x = cg.camera_fov;
} else {
fov_x = RAD2DEG(atan(tan(DEG2RAD(cg.camera_fov / 2.0)) * fov_ratio)) * 2.0;
}
x = cg.refdef.width / tan(fov_x / 360 * M_PI);
fov_y = atan2(cg.refdef.height, x); fov_y = atan2(cg.refdef.height, x);
fov_y = fov_y * 360 / M_PI; fov_y = fov_y * 360 / M_PI;
@ -560,17 +577,6 @@ static int CG_CalcViewValues(void)
CG_CalcVrect(); CG_CalcVrect();
CG_SetupFog(); CG_SetupFog();
// setup fog and far clipping plane
cg.refdef.farplane_distance = cg.farplane_distance;
VectorCopy(cg.farplane_color, cg.refdef.farplane_color);
cg.refdef.farplane_cull = cg.farplane_cull;
// setup portal sky
cg.refdef.sky_alpha = cg.sky_alpha;
cg.refdef.sky_portal = cg.sky_portal;
memcpy(cg.refdef.sky_axis, cg.sky_axis, sizeof(cg.sky_axis));
VectorCopy(cg.sky_origin, cg.refdef.sky_origin);
ps = &cg.predicted_player_state; ps = &cg.predicted_player_state;
VectorCopy(ps->origin, cg.refdef.vieworg); VectorCopy(ps->origin, cg.refdef.vieworg);
@ -723,7 +729,37 @@ float CG_SensitivityScale()
void CG_AddLightShow() void CG_AddLightShow()
{ {
// FIXME: unimplemented int i;
float fSlopeY, fSlopeZ;
float x, y, z;
vec3_t vOrg;
float r, g, b;
float fMax;
fSlopeY = tan(cg.refdef.fov_x * 0.5);
fSlopeZ = tan(cg.refdef.fov_y * 0.5);
for (i = 0; i < cg_acidtrip->integer; i++) {
x = pow(random(), 1.0 / 3.0) * 2048.0;
y = crandom() * x * fSlopeY;
z = crandom() * x * fSlopeZ;
VectorCopy(cg.refdef.vieworg, vOrg);
VectorMA(vOrg, x, cg.refdef.viewaxis[0], vOrg);
VectorMA(vOrg, y, cg.refdef.viewaxis[1], vOrg);
VectorMA(vOrg, z, cg.refdef.viewaxis[2], vOrg);
r = random();
g = random();
b = random();
fMax = Q_max(r, Q_max(g, b));
r /= fMax;
g /= fMax;
b /= fMax;
cgi.R_AddLightToScene(vOrg, (rand() & 0x1FF) + 0x80, r, g, b, 0);
}
} }
qboolean CG_FrustumCullSphere(const vec3_t vPos, float fRadius) { qboolean CG_FrustumCullSphere(const vec3_t vPos, float fRadius) {
@ -811,6 +847,15 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
// no entities should be marked as interpolating // no entities should be marked as interpolating
} }
//
// Added in OPM
// Clamp the fov to avoid artifacts
if (cg_fov->value < 65) {
cgi.Cvar_Set("cg_fov", "65");
} else if (cg_fov->value > 120) {
cgi.Cvar_Set("cg_fov", "120");
}
// update cg.predicted_player_state // update cg.predicted_player_state
CG_PredictPlayerState(); CG_PredictPlayerState();
@ -882,13 +927,13 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
{ {
default: default:
case 0: case 0:
cgi.UI_HideMenu("mission_success_1", CVAR_ARCHIVE); cgi.UI_HideMenu("mission_success_1", qtrue);
break; break;
case 2: case 2:
cgi.UI_HideMenu("mission_success_2", CVAR_ARCHIVE); cgi.UI_HideMenu("mission_success_2", qtrue);
break; break;
case 3: case 3:
cgi.UI_HideMenu("mission_success_3", CVAR_ARCHIVE); cgi.UI_HideMenu("mission_success_3", qtrue);
break; break;
} }
} else { } else {
@ -896,21 +941,21 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
{ {
default: default:
case 0: case 0:
cgi.UI_HideMenu("mission_failed_1", CVAR_ARCHIVE); cgi.UI_HideMenu("mission_failed_1", qtrue);
break; break;
case 2: case 2:
cgi.UI_HideMenu("mission_failed_2", CVAR_ARCHIVE); cgi.UI_HideMenu("mission_failed_2", qtrue);
break; break;
case 3: case 3:
cgi.UI_HideMenu("mission_failed_3", CVAR_ARCHIVE); cgi.UI_HideMenu("mission_failed_3", qtrue);
break; break;
} }
} }
} else { } else {
if (cgi.Cvar_Get("g_success", "", 0)->integer) { if (cgi.Cvar_Get("g_success", "", 0)->integer) {
cgi.UI_HideMenu("StatsScreen_Success", qfalse); cgi.UI_HideMenu("StatsScreen_Success", qtrue);
} else { } else {
cgi.UI_HideMenu("StatsScreen_Failed", qfalse); cgi.UI_HideMenu("StatsScreen_Failed", qtrue);
} }
} }
} }
@ -918,6 +963,9 @@ void CG_DrawActiveFrame(int serverTime, int frameTime, stereoFrame_t stereoView,
cg.bIntermissionDisplay = qfalse; cg.bIntermissionDisplay = qfalse;
} }
// Added in OPM
CG_ProcessPlayerModel();
// build the render lists // build the render lists
if (!cg.hyperspace) { if (!cg.hyperspace) {
CG_AddPacketEntities(); // after calcViewValues, so predicted player state is correct CG_AddPacketEntities(); // after calcViewValues, so predicted player state is correct

View file

@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
static const char *AnimPrefixList[] = { static const char *AnimPrefixList[] = {
"", "",
"unarmed",
"papers", "papers",
"colt45", "colt45",
"p38", "p38",
@ -45,7 +46,6 @@ static const char *AnimPrefixList[] = {
"bazooka", "bazooka",
"panzerschreck", "panzerschreck",
"shotgun", "shotgun",
"unarmed",
// //
// Team Assault and Team Tactics weapons // Team Assault and Team Tactics weapons
"mg42portable", "mg42portable",
@ -82,6 +82,7 @@ static const char *AnimPrefixList[] = {
enum animPrefix_e { enum animPrefix_e {
WPREFIX_NONE, WPREFIX_NONE,
WPREFIX_UNARMED,
WPREFIX_PAPERS, WPREFIX_PAPERS,
WPREFIX_COLT45, WPREFIX_COLT45,
WPREFIX_P38, WPREFIX_P38,
@ -99,7 +100,6 @@ enum animPrefix_e {
WPREFIX_BAZOOKA, WPREFIX_BAZOOKA,
WPREFIX_PANZERSCHRECK, WPREFIX_PANZERSCHRECK,
WPREFIX_SHOTGUN, WPREFIX_SHOTGUN,
WPREFIX_UNARMED,
// //
// Team Assault and Team Tactics weapons // Team Assault and Team Tactics weapons
WPREFIX_MG42_PORTABLE, WPREFIX_MG42_PORTABLE,
@ -308,6 +308,9 @@ int CG_GetVMAnimPrefixIndex()
if (!Q_stricmp(szWeaponName, "Panzerschreck")) { if (!Q_stricmp(szWeaponName, "Panzerschreck")) {
return WPREFIX_PANZERSCHRECK; return WPREFIX_PANZERSCHRECK;
} }
if (!Q_stricmp(szWeaponName, "Gewehrgranate")) {
return WPREFIX_KAR98_MORTAR;
}
if (!Q_stricmp(szWeaponName, "Shotgun")) { if (!Q_stricmp(szWeaponName, "Shotgun")) {
return WPREFIX_SHOTGUN; return WPREFIX_SHOTGUN;
} }
@ -335,9 +338,11 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
char szAnimName[MAX_QPATH]; char szAnimName[MAX_QPATH];
dtiki_t *pTiki; dtiki_t *pTiki;
qboolean bAnimChanged; qboolean bAnimChanged;
qboolean bWeaponChanged;
fCrossblendFrac = 0.0; fCrossblendFrac = 0.0;
bAnimChanged = 0; bAnimChanged = qfalse;
bWeaponChanged = qfalse; // Added in OPM
pTiki = pModel->tiki; pTiki = pModel->tiki;
if (cgi.anim->g_iLastEquippedWeaponStat == cg.snap->ps.stats[STAT_EQUIPPED_WEAPON] if (cgi.anim->g_iLastEquippedWeaponStat == cg.snap->ps.stats[STAT_EQUIPPED_WEAPON]
@ -346,13 +351,15 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
} else { } else {
iAnimPrefixIndex = CG_GetVMAnimPrefixIndex(); iAnimPrefixIndex = CG_GetVMAnimPrefixIndex();
cgi.anim->g_iLastEquippedWeaponStat = cg.snap->ps.stats[STAT_EQUIPPED_WEAPON]; cgi.anim->g_iLastEquippedWeaponStat = cg.snap->ps.stats[STAT_EQUIPPED_WEAPON];
strcpy(cgi.anim->g_szLastActiveItem, CG_ConfigString(CS_WEAPONS + cg.snap->ps.activeItems[1])); Q_strncpyz(cgi.anim->g_szLastActiveItem, CG_ConfigString(CS_WEAPONS + cg.snap->ps.activeItems[1]), sizeof(cgi.anim->g_szLastActiveItem));
cgi.anim->g_iLastAnimPrefixIndex = iAnimPrefixIndex; cgi.anim->g_iLastAnimPrefixIndex = iAnimPrefixIndex;
bAnimChanged = qtrue;
bAnimChanged = qtrue;
bWeaponChanged = qtrue;
} }
if (cgi.anim->g_iLastVMAnim == -1) { if (cgi.anim->g_iLastVMAnim == -1) {
sprintf(szAnimName, "%s_idle", AnimPrefixList[iAnimPrefixIndex]); Com_sprintf(szAnimName, sizeof(szAnimName), "%s_idle", AnimPrefixList[iAnimPrefixIndex]);
cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index = cgi.Anim_NumForName(pTiki, szAnimName); cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index = cgi.Anim_NumForName(pTiki, szAnimName);
if (cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index == -1) { if (cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index == -1) {
@ -421,21 +428,28 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
break; break;
} }
sprintf(szAnimName, "%s_%s", AnimPrefixList[iAnimPrefixIndex], pszAnimSuffix); Com_sprintf(szAnimName, sizeof(szAnimName), "%s_%s", AnimPrefixList[iAnimPrefixIndex], pszAnimSuffix);
fCrossblendTime = cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index); if (!bWeaponChanged) {
fCrossblendAmount = cgi.anim->g_iCurrentVMDuration / 1000.0; fCrossblendTime =
cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index);
fCrossblendAmount = cgi.anim->g_iCurrentVMDuration / 1000.0;
if (fCrossblendAmount < fCrossblendTime && fCrossblendAmount > 0.0) { if (fCrossblendAmount < fCrossblendTime && fCrossblendAmount > 0.0) {
fCrossblendFrac = fCrossblendAmount / fCrossblendTime; fCrossblendFrac = fCrossblendAmount / fCrossblendTime;
for (i = 0; i < MAX_FRAMEINFOS; ++i) { for (i = 0; i < MAX_FRAMEINFOS; ++i) {
if (cgi.anim->g_VMFrameInfo[i].weight) { if (cgi.anim->g_VMFrameInfo[i].weight) {
if (i == cgi.anim->g_iCurrentVMAnimSlot) { if (i == cgi.anim->g_iCurrentVMAnimSlot) {
cgi.anim->g_VMFrameInfo[i].weight = fCrossblendFrac; cgi.anim->g_VMFrameInfo[i].weight = fCrossblendFrac;
} else { } else {
cgi.anim->g_VMFrameInfo[i].weight *= (1.0 - fCrossblendFrac); cgi.anim->g_VMFrameInfo[i].weight *= (1.0 - fCrossblendFrac);
}
} }
} }
} }
} else {
fCrossblendTime = 0;
fCrossblendAmount = 0;
fCrossblendFrac = 0;
} }
cgi.anim->g_iCurrentVMAnimSlot = (cgi.anim->g_iCurrentVMAnimSlot + 1) % MAX_FRAMEINFOS; cgi.anim->g_iCurrentVMAnimSlot = (cgi.anim->g_iCurrentVMAnimSlot + 1) % MAX_FRAMEINFOS;
@ -450,17 +464,31 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].weight = 1.0; cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].weight = 1.0;
cgi.anim->g_iCurrentVMDuration = 0; cgi.anim->g_iCurrentVMDuration = 0;
fCrossblendTime = cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index); if (!bWeaponChanged) {
if (!fCrossblendTime) { fCrossblendTime =
cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index);
if (!fCrossblendTime) {
for (i = 0; i < MAX_FRAMEINFOS; ++i) {
if (i != cgi.anim->g_iCurrentVMAnimSlot) {
cgi.anim->g_VMFrameInfo[i].weight = 0.0;
}
}
cgi.anim->g_bCrossblending = qfalse;
} else {
cgi.anim->g_bCrossblending = qtrue;
}
} else {
// Added in OPM
// If there is a new weapon, don't do any crossblend
cgi.anim->g_bCrossblending = qfalse;
// clear crossblend values
for (i = 0; i < MAX_FRAMEINFOS; ++i) { for (i = 0; i < MAX_FRAMEINFOS; ++i) {
if (i != cgi.anim->g_iCurrentVMAnimSlot) { if (i != cgi.anim->g_iCurrentVMAnimSlot) {
cgi.anim->g_VMFrameInfo[i].weight = 0.0; cgi.anim->g_VMFrameInfo[i].weight = 0.0;
} }
} }
cgi.anim->g_bCrossblending = qfalse;
} else {
cgi.anim->g_bCrossblending = qtrue;
} }
} }

View file

@ -42,7 +42,9 @@ const char *cg_vsstypes[] = {
"debris" "debris"
}; };
cvssource_t *vss_sorttable[16384]; #define MAX_VSS_SORTS 16384
cvssource_t *vss_sorttable[MAX_VSS_SORTS];
static int lastVSSFrameTime; static int lastVSSFrameTime;
static constexpr float MAX_VSS_COORDS = 8096.0; static constexpr float MAX_VSS_COORDS = 8096.0;
@ -78,56 +80,57 @@ void VSS_AddRepulsion(cvssource_t *pA, cvssource_t *pB)
VectorSubtract(pA->newOrigin, pB->newOrigin, vPush); VectorSubtract(pA->newOrigin, pB->newOrigin, vPush);
if (vPush[0] || vPush[1] || vPush[2]) { if (!vPush[0] && !vPush[1] && !vPush[2]) {
fDist = VectorNormalize(vPush);
f = fDist - pB->newRadius;
if (f > 0.0) {
f *= pA->ooRadius;
if (f > 1.49) {
f = 0.0;
} else {
f = f * (f * 0.0161 + -0.3104) + 1.2887;
}
if (f < 0.0) {
f = f * 1.1;
}
fForce = f;
} else {
fForce = 1.0;
}
f = fDist - pA->newRadius;
if (f > 0.0) {
f *= pB->ooRadius;
if (f > 1.49) {
f = 0.0;
} else {
f = f * (f * 0.0161 + -0.3104) + 1.2887;
}
if (f < 0.0) {
f = f * 1.1;
}
fForce += f;
} else {
fForce += 1.0;
}
if (fForce <= -0.05 && fForce >= 0.05) {
fForce = (pA->newRadius + pB->newRadius) * 0.03 * fForce;
VectorScale(vPush, fForce, vPush);
VectorAdd(pA->repulsion, vPush, pA->repulsion);
VectorSubtract(pB->repulsion, vPush, pB->repulsion);
}
} else {
VectorSet(vPush, crandom(), crandom(), crandom()); VectorSet(vPush, crandom(), crandom(), crandom());
VectorAdd(pA->repulsion, vPush, pA->repulsion); VectorAdd(pA->repulsion, vPush, pA->repulsion);
VectorSubtract(pB->repulsion, vPush, pB->repulsion); VectorSubtract(pB->repulsion, vPush, pB->repulsion);
return;
}
fDist = VectorNormalize(vPush);
f = fDist - pB->newRadius;
if (f > 0.0f) {
f *= pA->ooRadius;
if (f > 1.49f) {
f = 0.0f;
} else {
f = f * (f * 0.0161f + -0.3104f) + 1.2887f;
}
if (f < 0.0) {
f *= 1.1f;
}
fForce = f;
} else {
fForce = 1.0;
}
f = fDist - pA->newRadius;
if (f > 0.0) {
f *= pB->ooRadius;
if (f > 1.49f) {
f = 0.0f;
} else {
f = f * (f * 0.0161f + -0.3104f) + 1.2887f;
}
if (f < 0.0) {
f *= 1.1f;
}
fForce += f;
} else {
fForce += 1.0f;
}
if (fForce <= -0.05f || fForce >= 0.05f) {
fForce = (pA->newRadius + pB->newRadius) * 0.03f * fForce;
VectorScale(vPush, fForce, vPush);
VectorAdd(pA->repulsion, vPush, pA->repulsion);
VectorSubtract(pB->repulsion, vPush, pB->repulsion);
} }
} }
@ -206,7 +209,7 @@ void ClientGameCommandManager::ResetVSSSources()
void ClientGameCommandManager::ResetVSSSources(Event *ev) void ClientGameCommandManager::ResetVSSSources(Event *ev)
{ {
// FIXME: stub?? ResetVSSSources();
} }
void CG_ResetVSSSources() void CG_ResetVSSSources()
@ -286,13 +289,13 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
fWind = 0.0; fWind = 0.0;
if ((pSource->flags2 & 5) != 0) { if ((pSource->flags2 & (T2_ACCEL | T2_MOVE)) != 0) {
VectorMA(pSource->velocity, ftime, pSource->repulsion, pSource->velocity); VectorMA(pSource->velocity, ftime, pSource->repulsion, pSource->velocity);
} }
pSource->lastOrigin = pSource->newOrigin; pSource->lastOrigin = pSource->newOrigin;
if (pSource->flags & 0x800) { if (pSource->flags & T_COLLISION) {
trace.allsolid = qfalse; trace.allsolid = qfalse;
CG_ClipMoveToEntities( CG_ClipMoveToEntities(
pSource->newOrigin, vec3_origin, vec3_origin, pSource->newOrigin, -1, MASK_VOLUMETRIC_SMOKE, &trace, qfalse pSource->newOrigin, vec3_origin, vec3_origin, pSource->newOrigin, -1, MASK_VOLUMETRIC_SMOKE, &trace, qfalse
@ -312,11 +315,11 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
} }
} }
if (pSource->flags2 & 5) { if (pSource->flags2 & (T2_ACCEL | T2_MOVE)) {
VectorMA(pSource->newOrigin, ftime, pSource->velocity, pSource->newOrigin); VectorMA(pSource->newOrigin, ftime, pSource->velocity, pSource->newOrigin);
} }
if (pSource->flags & 0x800) { if (pSource->flags & T_COLLISION) {
CG_Trace( CG_Trace(
&trace, &trace,
pSource->lastOrigin, pSource->lastOrigin,
@ -334,6 +337,8 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
float fDot; float fDot;
vec3_t vNorm; vec3_t vNorm;
VectorCopy(trace.plane.normal, vNorm);
VectorAdd(trace.endpos, trace.plane.normal, pSource->newOrigin); VectorAdd(trace.endpos, trace.plane.normal, pSource->newOrigin);
fDot = DotProduct(vNorm, pSource->velocity); fDot = DotProduct(vNorm, pSource->velocity);
VectorMA(pSource->velocity, fDot, vNorm, pSource->velocity); VectorMA(pSource->velocity, fDot, vNorm, pSource->velocity);
@ -358,7 +363,7 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
} }
iSmokeType = abs(pSource->smokeType); iSmokeType = abs(pSource->smokeType);
if (pSource->flags2 & 5) { if (pSource->flags2 & (T2_ACCEL | T2_MOVE)) {
VectorCopy(pSource->velocity, vVel); VectorCopy(pSource->velocity, vVel);
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
@ -619,7 +624,7 @@ qboolean VSS_LerpSource(cvssource_t *pCurrent, cvssourcestate_t *pState, float f
{ {
int i; int i;
if (pCurrent->flags & 0xA0000) { if (pCurrent->flags & (T_HARDLINK | T_PARENTLINK)) {
Vector parentOrigin; Vector parentOrigin;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
@ -638,7 +643,7 @@ qboolean VSS_LerpSource(cvssource_t *pCurrent, cvssourcestate_t *pState, float f
parentOrigin = e->origin; parentOrigin = e->origin;
VectorAdd(pState->origin, parentOrigin, pState->origin); VectorAdd(pState->origin, parentOrigin, pState->origin);
} else if (pCurrent->flags2 & 5) { } else if (pCurrent->flags2 & (T2_ACCEL | T2_MOVE)) {
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
pState->origin[i] = pState->origin[i] =
(pCurrent->newOrigin[i] - pCurrent->lastOrigin[i]) * fLerpFrac + pCurrent->lastOrigin[i]; (pCurrent->newOrigin[i] - pCurrent->lastOrigin[i]) * fLerpFrac + pCurrent->lastOrigin[i];
@ -741,9 +746,8 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
pSource->startAlpha = (random() * 0.15 + 0.85) * fDensity; pSource->startAlpha = (random() * 0.15 + 0.85) * fDensity;
pSource->newDensity = 0.0; pSource->newDensity = 0.0;
if (m_spawnthing->cgd.flags & 1) { if (m_spawnthing->cgd.flags & T_RANDSCALE) {
pSource->newRadius = RandomizeRange(m_spawnthing->cgd.scalemin, m_spawnthing->cgd.scalemax); pSource->newRadius = RandomizeRange(m_spawnthing->cgd.scalemin, m_spawnthing->cgd.scalemax);
;
if (pSource->newRadius > 32.0) { if (pSource->newRadius > 32.0) {
pSource->newRadius = 32.0; pSource->newRadius = 32.0;
} }
@ -772,16 +776,16 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
pSource->roll = anglemod(fAngle); pSource->roll = anglemod(fAngle);
if (random() < 0.5) { if (random() < 0.5) {
pSource->flags |= 0x40000; pSource->flags |= T_RANDOMROLL;
} }
VectorCopy(m_spawnthing->axis[0], vNewForward); VectorCopy(m_spawnthing->axis[0], vNewForward);
if (m_spawnthing->cgd.flags & 4) { if (m_spawnthing->cgd.flags & T_SPHERE) {
VectorCopy(m_spawnthing->cgd.origin, pSource->newOrigin); VectorCopy(m_spawnthing->cgd.origin, pSource->newOrigin);
do { do {
vNewForward = Vector(crandom(), crandom(), crandom()); vNewForward = Vector(crandom(), crandom(), crandom());
} while (Vector::Dot(vNewForward, vNewForward) < 1.0); } while (Vector::Dot(vNewForward, vNewForward) < 1.0);
} else if (m_spawnthing->cgd.flags & 0x10) { } else if (m_spawnthing->cgd.flags & T_CIRCLE) {
if (m_spawnthing->sphereRadius != 0.0) { if (m_spawnthing->sphereRadius != 0.0) {
Vector dst, end; Vector dst, end;
@ -794,7 +798,7 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
fAngle += fAngleStep; fAngle += fAngleStep;
} }
} else if (m_spawnthing->cgd.flags & 8) { } else if (m_spawnthing->cgd.flags & T_INWARDSPHERE) {
Vector dir, end; Vector dir, end;
do { do {
dir = Vector(crandom(), crandom(), crandom()); dir = Vector(crandom(), crandom(), crandom());
@ -803,7 +807,7 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
end = m_spawnthing->cgd.origin + dir * m_spawnthing->sphereRadius; end = m_spawnthing->cgd.origin + dir * m_spawnthing->sphereRadius;
VectorCopy(end, pSource->newOrigin); VectorCopy(end, pSource->newOrigin);
vNewForward = dir * -1.0; vNewForward = dir * -1.0;
} else if (m_spawnthing->cgd.flags2 & 0x20000) { } else if (m_spawnthing->cgd.flags2 & T2_CONE) {
float fHeight, fRadius; float fHeight, fRadius;
float fAngle; float fAngle;
float sina, cosa; float sina, cosa;
@ -825,8 +829,6 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
VectorMA(m_spawnthing->cgd.origin, fRadius * cosa, m_spawnthing->axis[1], pSource->newOrigin); VectorMA(m_spawnthing->cgd.origin, fRadius * cosa, m_spawnthing->axis[1], pSource->newOrigin);
VectorMA(m_spawnthing->cgd.origin, fRadius * sina, m_spawnthing->axis[2], pSource->newOrigin); VectorMA(m_spawnthing->cgd.origin, fRadius * sina, m_spawnthing->axis[2], pSource->newOrigin);
} else if (m_spawnthing->sphereRadius) { } else if (m_spawnthing->sphereRadius) {
VectorCopy(m_spawnthing->cgd.origin, pSource->newOrigin);
} else {
Vector dir, end; Vector dir, end;
do { do {
dir = Vector(crandom(), crandom(), crandom()); dir = Vector(crandom(), crandom(), crandom());
@ -836,6 +838,8 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
end = m_spawnthing->cgd.origin + dir * m_spawnthing->sphereRadius; end = m_spawnthing->cgd.origin + dir * m_spawnthing->sphereRadius;
VectorCopy(end, pSource->newOrigin); VectorCopy(end, pSource->newOrigin);
vNewForward = dir; vNewForward = dir;
} else {
VectorCopy(m_spawnthing->cgd.origin, pSource->newOrigin);
} }
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
@ -869,15 +873,14 @@ void ClientGameCommandManager::SpawnVSSSource(int count, int timealive)
for (i = 0; i < 3; ++i) { for (i = 0; i < 3; ++i) {
float fDist = m_spawnthing->axis_offset_base[i] + random() * m_spawnthing->axis_offset_amplitude[i]; float fDist = m_spawnthing->axis_offset_base[i] + random() * m_spawnthing->axis_offset_amplitude[i];
if (pSource->flags2 & 0x80) { if (pSource->flags2 & T2_PARALLEL) {
pSource->newOrigin += Vector(m_spawnthing->axis[i]) * fDist; pSource->newOrigin += Vector(m_spawnthing->axis[i]) * fDist;
} else { } else {
pSource->newOrigin += Vector(m_spawnthing->tag_axis[i]) * fDist; pSource->newOrigin += Vector(m_spawnthing->tag_axis[i]) * fDist;
} }
} }
pSource->velocity *= pSource->lifeTime / 1000.0; pSource->newOrigin += pSource->velocity * (pSource->lifeTime / 1000.0);
pSource->newOrigin += pSource->velocity;
if (vss_lighting_fps->integer) { if (vss_lighting_fps->integer) {
cgi.R_GetLightingForSmoke(pSource->newLighting, pSource->newOrigin); cgi.R_GetLightingForSmoke(pSource->newLighting, pSource->newOrigin);
} }
@ -890,251 +893,249 @@ void VSS_CalcRepulsionForces(cvssource_t *pActiveSources)
{ {
cvssource_t *pCurrent; cvssource_t *pCurrent;
cvssource_t *pComp; cvssource_t *pComp;
qboolean bXUp, bXDown;
qboolean bYUp, bYDown;
qboolean bZDown;
int i;
int iIndex;
int iX, iY, iZ;
int iMinX, iMinY, iMinZ;
int iMaxX, iMaxY, iMaxZ;
float fOfs;
cvssource_t *pSTLatch;
pCurrent = pActiveSources->prev; pCurrent = pActiveSources->prev;
if (pCurrent != pActiveSources) { if (pCurrent == pActiveSources) {
qboolean bXUp, bXDown; return;
qboolean bYUp, bYDown; }
qboolean bZDown;
int i;
int iIndex;
int iX, iY, iZ;
int iMinX, iMinY, iMinZ;
int iMaxX, iMaxY, iMaxZ;
float fOfs;
cvssource_t *pSTLatch;
memset(vss_sorttable, 0, sizeof(vss_sorttable)); memset(vss_sorttable, 0, sizeof(vss_sorttable));
while (pCurrent != pActiveSources) { for (pCurrent = pActiveSources->prev; pCurrent != pActiveSources; pCurrent = pCurrent->prev) {
VectorClear(pCurrent->repulsion); VectorClear(pCurrent->repulsion);
iIndex = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5) / 96) % 32; iIndex = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5) / 96) % 32;
iIndex |= ((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5) / 96) % 32; iIndex |= (((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5) / 96) % 32) << 5;
iIndex |= (((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5) / 96) % 16) << 10; iIndex |= (((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5) / 96) % 16) << 10;
pCurrent->stnext = vss_sorttable[iIndex]; pCurrent->stnext = vss_sorttable[iIndex];
vss_sorttable[iIndex] = pCurrent; vss_sorttable[iIndex] = pCurrent;
pCurrent->stindex = iIndex; pCurrent->stindex = iIndex;
pCurrent = pCurrent->prev; }
for (pCurrent = pActiveSources->prev; pCurrent != pActiveSources; pCurrent = pCurrent->prev) {
if (vss_sorttable[pCurrent->stindex] == pCurrent) {
pSTLatch = (cvssource_t *)-1;
pComp = pCurrent->stnext;
} else {
pSTLatch = 0;
pComp = vss_sorttable[pCurrent->stindex];
} }
for (pCurrent = pActiveSources->prev; pCurrent != pActiveSources; pCurrent = pCurrent->prev) { for(; pComp; pComp = pComp->stnext) {
if (vss_sorttable[pCurrent->stindex] == pCurrent) { VSS_AddRepulsion(pCurrent, pComp);
pSTLatch = (cvssource_t *)-1; if (!pSTLatch && pComp->stnext == pCurrent) {
pComp = pCurrent->stnext; pSTLatch = pComp;
} else { // skip current
pSTLatch = 0; pComp = pComp->stnext;
pComp = vss_sorttable[pCurrent->stindex]; }
}
iX = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5) / 96) % 32;
iY = (((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5) / 96) % 32) << 5;
iZ = (((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5) / 96) % 16) << 10;
fOfs = pCurrent->newRadius + 1.49 + 48.0;
iMaxX = ((int)floor(pCurrent->newOrigin[0] + fOfs + 8192.0 + 0.5) / 96) % 32;
iMaxY = (((int)floor(pCurrent->newOrigin[1] + fOfs + 8192.0 + 0.5) / 96) % 32) << 5;
iMaxZ = (((int)floor(pCurrent->newOrigin[2] + fOfs + 8192.0 + 0.5) / 96) % 16) << 10;
iMinX = ((int)floor(pCurrent->newOrigin[0] - fOfs + 8192.0 + 0.5) / 96) % 32;
iMinY = (((int)floor(pCurrent->newOrigin[1] - fOfs + 8192.0 + 0.5) / 96) % 32) << 5;
iMinZ = (((int)floor(pCurrent->newOrigin[2] - fOfs + 8192.0 + 0.5) / 96) % 16) << 10;
bXUp = (iMaxX | (pCurrent->stindex & 0xFFFFFFE0)) != pCurrent->stindex;
bXDown = (iMinX | (pCurrent->stindex & 0xFFFFFFE0)) != pCurrent->stindex;
bYUp = (iMaxY | (pCurrent->stindex & 0xFFFFFC1F)) != pCurrent->stindex;
bYDown = (iMinY | (pCurrent->stindex & 0xFFFFFC1F)) != pCurrent->stindex;
iIndex = iMinZ | (pCurrent->stindex & 0xFFFFC3FF);
bZDown = iIndex != pCurrent->stindex;
if (iIndex == pCurrent->stindex) {
iIndex = iMaxY | (pCurrent->stindex & 0xFFFFFC1F);
i = 9;
} else {
i = 0;
}
for (; i < (bZDown ? 26 : 17); i++) {
switch (i) {
case 0:
iIndex = iMaxZ | (pCurrent->stindex & 0xFFFFC3FF);
break;
case 1:
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
if (bXUp) {
break;
}
continue;
case 2:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYUp) {
break;
}
continue;
case 3:
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYDown) {
break;
}
continue;
case 4:
iIndex = iMinY | (iIndex & 0xFFFFFFE0);
if (bYDown) {
break;
}
continue;
case 5:
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
if (bXDown && bYDown) {
break;
}
continue;
case 6:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXDown) {
break;
}
continue;
case 7:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXDown && bYUp) {
break;
}
continue;
case 8:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYUp) {
break;
}
continue;
case 9:
iIndex = iZ | (iIndex & 0xFFFFFFC3);
if (bYUp) {
break;
}
continue;
case 10:
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
if (bXUp && bYUp) {
break;
}
continue;
case 11:
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
if (bXDown && bYUp) {
break;
}
continue;
case 12:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXDown) {
break;
}
continue;
case 13:
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
if (bXDown && bYDown) {
break;
}
continue;
case 14:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYDown) {
break;
}
continue;
case 15:
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
if (bXUp && bYDown) {
break;
}
continue;
case 16:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXUp) {
break;
}
continue;
case 17:
iIndex = iMinZ | (iIndex & 0xFFFFFCC3);
if (bXUp) {
break;
}
continue;
case 18:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYUp) {
break;
}
continue;
case 19:
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYDown) {
break;
}
continue;
case 20:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYDown) {
break;
}
continue;
case 21:
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
if (bXDown && bYDown) {
break;
}
continue;
case 22:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXDown) {
break;
}
continue;
case 23:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXDown && bYUp) {
break;
}
continue;
case 24:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYUp) {
break;
}
continue;
case 25:
iIndex = iY | (iIndex & 0xFFFFFC1F);
break;
default:
assert(0); // This can't happen
break;
} }
while (pComp) { for (pComp = vss_sorttable[iIndex]; pComp; pComp = pComp->stnext) {
VSS_AddRepulsion(pCurrent, pComp); VSS_AddRepulsion(pCurrent, pComp);
if (!pSTLatch && pComp->stnext == pCurrent) {
pSTLatch = pComp;
pComp = pComp->stnext;
}
pComp = pComp->stnext;
} }
iX = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5) / 96) % 32; }
iY = ((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5) / 96) % 32;
iY *= 2;
iZ = ((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5) / 96) % 16;
iZ <<= 10;
fOfs = pCurrent->newRadius + 1.49 + 48.0; if (pSTLatch == (cvssource_t *)-1) {
iMaxX = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5 + fOfs) / 96) % 32; vss_sorttable[pCurrent->stindex] = pCurrent->stnext;
iMaxY = ((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5 + fOfs) / 96) % 32; } else {
iMaxY *= 2; pSTLatch->stnext = pCurrent->stnext;
iMaxZ = ((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5 + fOfs) / 96) % 16;
iMaxZ <<= 10;
iMinX = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5 - fOfs) / 96) % 32;
iMinY = ((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5 - fOfs) / 96) % 32;
iMinY *= 2;
iMinZ = ((int)floor(pCurrent->newOrigin[2] + 8192.0 + 0.5 - fOfs) / 96) % 16;
iMinZ <<= 10;
bXUp = (iMaxX | (pCurrent->stindex & 0xFFFFFFE0)) != pCurrent->stindex;
bXDown = (iMinX | (pCurrent->stindex & 0xFFFFFFE0)) != pCurrent->stindex;
bYUp = (iMaxY | (pCurrent->stindex & 0xFFFFFC1F)) != pCurrent->stindex;
bYDown = (iMinY | (pCurrent->stindex & 0xFFFFFC1F)) != pCurrent->stindex;
iIndex = iMinZ | (pCurrent->stindex & 0xFFFFFCC3);
bZDown = iIndex != pCurrent->stindex;
if (iIndex == pCurrent->stindex) {
iIndex = iMaxY | pCurrent->stindex & 0xFFFFFC1F;
i = 9;
} else {
i = 0;
}
for(; i < (bZDown ? 26 : 17); i++) {
switch (i) {
case 0:
iIndex = iMaxZ | (pCurrent->stindex & 0xFFFFFCC3);
break;
case 1:
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
if (bXUp) {
break;
}
continue;
case 2:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYUp) {
break;
}
continue;
case 3:
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYDown) {
break;
}
continue;
case 4:
iIndex = iMinY | (iIndex & 0xFFFFFFE0);
if (bYDown) {
break;
}
continue;
case 5:
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
if (bXDown && bYDown) {
break;
}
continue;
case 6:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXDown) {
break;
}
continue;
case 7:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXDown && bYUp) {
break;
}
continue;
case 8:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYUp) {
break;
}
continue;
case 9:
iIndex = iZ | (iIndex & 0xFFFFFFC3);
if (bYUp) {
break;
}
continue;
case 10:
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
if (bXUp && bYUp) {
break;
}
continue;
case 11:
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
if (bXDown && bYUp) {
break;
}
continue;
case 12:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXDown) {
break;
}
continue;
case 13:
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
if (bXDown && bYDown) {
break;
}
continue;
case 14:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYDown) {
break;
}
continue;
case 15:
iIndex = iMaxX | (iIndex & 0xFFFFFFE0);
if (bXUp && bYDown) {
break;
}
continue;
case 16:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXUp) {
break;
}
continue;
case 17:
iIndex = iMinZ | (iIndex & 0xFFFFFCC3);
if (bXUp) {
break;
}
continue;
case 18:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYUp) {
break;
}
continue;
case 19:
iIndex = iMinY | (iIndex & 0xFFFFFC1F);
if (bXUp && bYDown) {
break;
}
continue;
case 20:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYDown) {
break;
}
continue;
case 21:
iIndex = iMinX | (iIndex & 0xFFFFFFE0);
if (bXDown && bYDown) {
break;
}
continue;
case 22:
iIndex = iY | (iIndex & 0xFFFFFC1F);
if (bXDown) {
break;
}
continue;
case 23:
iIndex = iMaxY | (iIndex & 0xFFFFFC1F);
if (bXDown && bYUp) {
break;
}
continue;
case 24:
iIndex = iX | (iIndex & 0xFFFFFFE0);
if (bYUp) {
break;
}
continue;
case 25:
iIndex = iY | (iIndex & 0xFFFFFC1F);
break;
}
for (pComp = vss_sorttable[iIndex]; pComp; pComp = pComp->stnext) {
VSS_AddRepulsion(pCurrent, pComp);
}
}
if (pSTLatch == (cvssource_t *)-1) {
vss_sorttable[pCurrent->stindex] = pCurrent->stnext;
} else {
pSTLatch->stnext = pCurrent->stnext;
}
} }
} }
} }
@ -1222,13 +1223,13 @@ void ClientGameCommandManager::AddVSSSources()
pComp = pCurrent->prev; pComp = pCurrent->prev;
newEnt.renderfx = 0; newEnt.renderfx = 0;
if (pCurrent->flags < 0 && !cg_detail->integer) { if ((pCurrent->flags & T_DETAIL) && !cg_detail->integer) {
FreeVSSSource(pCurrent); FreeVSSSource(pCurrent);
continue; continue;
} }
if ((pCurrent->flags2 & 0x4000) != 0) { if ((pCurrent->flags2 & T2_ALWAYSDRAW) != 0) {
newEnt.renderfx = 0x4000000; newEnt.renderfx = RF_ALWAYSDRAW;
} }
if (pCurrent->lastPhysicsTime) { if (pCurrent->lastPhysicsTime) {
@ -1237,8 +1238,8 @@ void ClientGameCommandManager::AddVSSSources()
mstime = physics_rate; mstime = physics_rate;
} }
if (mstime >= physics_rate || (pCurrent->flags2 & 0x10) != 0) { if (mstime >= physics_rate || (pCurrent->flags2 & T2_PHYSICS_EVERYFRAME) != 0) {
if (!VSS_SourcePhysics(pCurrent, (float)mstime * 0.001)) { if (!VSS_SourcePhysics(pCurrent, (float)mstime / 1000.0)) {
FreeVSSSource(pCurrent); FreeVSSSource(pCurrent);
continue; continue;
} }
@ -1262,26 +1263,18 @@ void ClientGameCommandManager::AddVSSSources()
} }
} }
fLerpFrac = (cg.time - pCurrent->lastPhysicsTime) / physics_rate; fLerpFrac = (float)(cg.time - pCurrent->lastPhysicsTime) / (float)physics_rate;
if (fLerpFrac > 1.0) { fLerpFrac = Q_clamp_float(fLerpFrac, 0, 1);
fLerpFrac = 1.0;
} else if (fLerpFrac < 0.0) {
fLerpFrac = 0.0;
}
fLightingFrac = (cg.time - pCurrent->lastLightingTime) / lighting_rate; fLightingFrac = (float)(cg.time - pCurrent->lastLightingTime) / (float)lighting_rate;
if (fLightingFrac > 1.0) { fLightingFrac = Q_clamp_float(fLightingFrac, 0, 1);
fLightingFrac = 1.0;
} else if (fLightingFrac < 0.0) {
fLightingFrac = 0.0;
}
if (lastVSSFrameTime) { if (lastVSSFrameTime) {
pCurrent->lifeTime += frameTime; pCurrent->lifeTime += frameTime;
} }
if (!pCurrent->lastValid) { if (!pCurrent->lastValid) {
if (!VSS_SourcePhysics(pCurrent, (float)physics_rate * 0.001)) { if (!VSS_SourcePhysics(pCurrent, (float)physics_rate / 1000)) {
ClientGameCommandManager::FreeVSSSource(pCurrent); ClientGameCommandManager::FreeVSSSource(pCurrent);
continue; continue;
} }
@ -1335,12 +1328,12 @@ void ClientGameCommandManager::AddVSSSources()
pCurrent->roll -= j; pCurrent->roll -= j;
} }
if ((pCurrent->flags & 0x40000) != 0) { if ((pCurrent->flags & T_RANDOMROLL) != 0) {
newEnt.hModel = hModel; newEnt.hModel = hModel;
} else { } else {
newEnt.hModel = hModel2; newEnt.hModel = hModel2;
} }
} else if ((pCurrent->flags & 0x40000) != 0) { } else if ((pCurrent->flags & T_RANDOMROLL) != 0) {
newEnt.hModel = hModel; newEnt.hModel = hModel;
} else { } else {
newEnt.hModel = hModel2; newEnt.hModel = hModel2;

View file

@ -42,23 +42,23 @@ MemArchiver::~MemArchiver()
void MemArchiver::SetupForWriting(size_t initialSize) void MemArchiver::SetupForWriting(size_t initialSize)
{ {
state = MEMARC_WRITING; this->state = MEMARC_WRITING;
buffer = (byte*)cgi.Malloc(initialSize); this->buffer = (byte*)cgi.Malloc(initialSize);
allocatedSize = initialSize; this->allocatedSize = initialSize;
bufferSize = 0; this->bufferSize = 0;
} }
void MemArchiver::SetupForReading(byte* buffer, size_t size) void MemArchiver::SetupForReading(byte* buffer, size_t size)
{ {
state = MEMARC_READING; this->state = MEMARC_READING;
buffer = buffer; this->buffer = buffer;
allocatedSize = size; this->allocatedSize = size;
bufferSize = 0; this->bufferSize = 0;
} }
void MemArchiver::SetBaseTime(unsigned int time) void MemArchiver::SetBaseTime(unsigned int time)
{ {
svsTime = time; this->svsTime = time;
} }
size_t MemArchiver::BufferSize() const size_t MemArchiver::BufferSize() const

View file

@ -1,49 +1,84 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.12)
project(omohclient) project(omohclient)
add_subdirectory("../cgame" "./cgame") add_subdirectory("../cgame" "./cgame")
file(GLOB_RECURSE SOURCES_CLIENT "./*.c*") file(GLOB SOURCES_CLIENT "./*.c*")
file(GLOB_RECURSE SOURCES_UILIB "../uilib/*.c*") file(GLOB_RECURSE SOURCES_UILIB "../uilib/*.c*")
set(SOURCES_CLIENT ${SOURCES_CLIENT}
# Gamespy
"${CMAKE_SOURCE_DIR}/code/gamespy/cl_gamespy.c"
)
# Made as an interface and not static, as static only links used methods # Made as an interface and not static, as static only links used methods
add_library(omohclient INTERFACE) add_library(omohclient INTERFACE)
target_compile_definitions(omohclient INTERFACE APP_MODULE) target_compile_definitions(omohclient INTERFACE APP_MODULE)
target_compile_features(omohclient INTERFACE cxx_nullptr) target_compile_features(omohclient INTERFACE cxx_nullptr)
target_compile_features(omohclient INTERFACE c_variadic_macros) target_compile_features(omohclient INTERFACE c_variadic_macros)
target_link_libraries(omohclient INTERFACE omohsdl) target_link_libraries(omohclient INTERFACE omohsdl_client)
target_link_libraries(omohclient INTERFACE gcd) target_link_libraries(omohclient INTERFACE gcd)
# Sound stuff # Sound stuff
target_compile_definitions(omohclient INTERFACE USE_CODEC_MP3) target_compile_definitions(omohclient INTERFACE USE_CODEC_MP3)
if (USE_SOUND_NEW) if (NOT NO_MODERN_DMA)
# Try to use OpenAL # Use OpenAL
find_package(OpenAL) find_package(OpenAL REQUIRED)
if (OPENAL_FOUND) if (OPENAL_FOUND)
target_compile_definitions(omohclient INTERFACE USE_SOUND_NEW=1) target_compile_definitions(omohclient INTERFACE USE_OPENAL=1 NO_MODERN_DMA=0)
if (MSVC) if (MSVC)
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR}/AL) target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR}/AL)
else() else()
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR}) target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR})
endif() endif()
target_link_libraries(omohclient INTERFACE ${OPENAL_LIBRARY})
if(NOT USE_SYSTEM_LIBS)
target_compile_definitions(omohclient INTERFACE USE_OPENAL_DLOPEN=1)
else()
# Link against system OpenAL
target_link_libraries(omohclient INTERFACE OpenAL::OpenAL)
endif()
endif() endif()
list(FILTER SOURCES_CLIENT EXCLUDE REGEX "./snd_([a-zA-Z0-9_]+)\.c$") list(FILTER SOURCES_CLIENT EXCLUDE REGEX "./snd_([a-zA-Z0-9_]+)\.c$")
file(GLOB SOURCES_CLIENT_SND "./snd_*_new.c*" "./snd_codec*.c*")
list(APPEND SOURCES_CLIENT ${SOURCES_CLIENT_SND})
else()
#
# Fallback to old DMA sound system
#
message(NOTICE "OpenAL was explicitly disabled - fallback to old SDL sound system")
target_compile_definitions(omohclient INTERFACE NO_MODERN_DMA=1)
set(NO_MODERN_DMA TRUE)
list(FILTER SOURCES_CLIENT EXCLUDE REGEX "./snd_([a-zA-Z0-9_]+)\.cpp$")
file(GLOB_RECURSE SOURCES_CLIENT_SND "./new/*.c*")
list(APPEND SOURCES_CLIENT ${SOURCES_CLIENT_SND})
endif() endif()
if (USE_OPENAL) set(OLD_VALUE ${BUILD_SHARED_LIBS})
# Try to use OpenAL set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
find_package(OpenAL)
if (OPENAL_FOUND) if(USE_INTERNAL_MAD)
target_compile_definitions(omohclient INTERFACE USE_OPENAL=1) add_subdirectory("../libmad" "./libmad" EXCLUDE_FROM_ALL)
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR}/AL) target_link_libraries(omohclient INTERFACE mad)
target_link_libraries(omohclient INTERFACE ${OPENAL_LIBRARY}) else()
endif() include(FindPackageHandleStandardArgs)
find_path(LIBMAD_INCLUDE_DIRS mad.h)
find_library(LIBMAD_LIBRARIES mad)
find_package_handle_standard_args(
LibMad
DEFAULT_MSG
LIBMAD_LIBRARIES
LIBMAD_INCLUDE_DIRS
)
target_include_directories(omohclient INTERFACE ${LIBMAD_INCLUDE_DIRS})
target_link_libraries(omohclient INTERFACE ${LIBMAD_LIBRARIES})
endif() endif()
set(BUILD_SHARED_LIBS ${OLD_VALUE} CACHE BOOL "" FORCE)
target_sources(omohclient INTERFACE ${SOURCES_CLIENT} ${SOURCES_UILIB}) target_sources(omohclient INTERFACE ${SOURCES_CLIENT} ${SOURCES_UILIB})
add_subdirectory("../libmad-0.15.1b" "./libmad")
target_link_libraries(omohclient INTERFACE libmad)

View file

@ -211,20 +211,20 @@ qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
} }
snapshot->numEntities = 0; snapshot->numEntities = 0;
for ( i = 0 ; i < count ; i++ ) { for(i = 0; i < MAX_ENTITIES_IN_SNAPSHOT; i++) {
parents[i] = -1;
}
for (i = 0; i < count; i++) {
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)]; s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
pnum = s1->parent; pnum = s1->parent;
if (pnum == ENTITYNUM_NONE) { if (pnum == ENTITYNUM_NONE) {
parents[s1->number] = -2; parents[s1->number] = -2;
} } else {
else
{
if (parents[pnum] == -2) { if (parents[pnum] == -2) {
parents[s1->number] = -2; parents[s1->number] = -2;
} } else {
else
{
// add it later // add it later
parents[s1->number] = pnum; parents[s1->number] = pnum;
continue; continue;
@ -234,33 +234,37 @@ qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
snapshot->entities[snapshot->numEntities++] = *s1; snapshot->entities[snapshot->numEntities++] = *s1;
} }
for(pcount = 0; pcount < 8 && snapshot->numEntities != count; pcount++) for(pcount = 0; pcount < 8 && snapshot->numEntities != count; pcount++) {
{ for (i = 0; i < count; i++) {
for (i = 0; i < count; i++)
{
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)]; s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
pnum = parents[s1->number]; pnum = parents[s1->number];
if (pnum >= 0 && parents[pnum] == -2) { if (pnum >= 0 && parents[pnum] == -2) {
parents[s1->number] = -2;
snapshot->entities[snapshot->numEntities++] = *s1; snapshot->entities[snapshot->numEntities++] = *s1;
} }
} }
} }
if (pcount >= 8) if (snapshot->numEntities != count) {
{ Com_DPrintf("CL_GetSnapshot: Not all children could find their parents.\n");
for (i = count; i < snapshot->numEntities; i++)
for (i = snapshot->numEntities; i < count; i++)
{ {
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)]; for (pnum = 0; pnum < count; pnum++) {
if (parents[s1->number] >= 0) { s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + pnum) & (MAX_PARSE_ENTITIES - 1)];
Com_DPrintf( if (parents[s1->number] >= 0) {
"CL_GetSnapshot: entity %d with parent %d and model '%s' at %.2f %.2f %.2f, could not find parent.\n", Com_DPrintf(
s1->number, "CL_GetSnapshot: entity %d with parent %d and model '%s' at %.2f %.2f %.2f, could not find parent.\n",
s1->parent, s1->number,
CL_ConfigString(CS_MODELS + s1->modelindex), s1->parent,
s1->origin[0], CL_ConfigString(CS_MODELS + s1->modelindex),
s1->origin[1], s1->origin[0],
s1->origin[2] s1->origin[1],
); s1->origin[2]
);
parents[s1->number] = -2;
}
} }
} }
} }
@ -358,7 +362,9 @@ qboolean CL_ProcessServerCommand(const char* origString, const char* cmd, qboole
// because this function might be called from a module that would be unloaded // because this function might be called from a module that would be unloaded
// inside Com_Error // inside Com_Error
UI_ForceMenuOff(1); UI_ForceMenuOff(1);
Cbuf_AddText("disconnect;pushmenu disconnected"); // Fixed in OPM
// Added a newline for next commands
Cbuf_AddText("disconnect;pushmenu disconnected\n");
return qtrue; return qtrue;
} }
@ -578,7 +584,7 @@ CL_RestoreSavedCgameState
*/ */
void CL_RestoreSavedCgameState() { void CL_RestoreSavedCgameState() {
if (cls.savedCgameState) { if (cls.savedCgameState) {
cge->CG_LoadStateToBuffer(&cls.savedCgameState, cls.savedCgameStateSize, cl.snap.serverTime); cge->CG_LoadStateToBuffer(cls.savedCgameState, cls.savedCgameStateSize, cl.snap.serverTime);
} }
} }
@ -621,7 +627,9 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
cgi->LV_ConvertString = Sys_LV_CL_ConvertString; cgi->LV_ConvertString = Sys_LV_CL_ConvertString;
cgi->Cvar_Get = Cvar_Get; cgi->Cvar_Get = Cvar_Get;
cgi->Cvar_Find = Cvar_FindVar;
cgi->Cvar_Set = Cvar_Set; cgi->Cvar_Set = Cvar_Set;
cgi->Cvar_CheckRange = Cvar_CheckRange;
cgi->Argc = Cmd_Argc; cgi->Argc = Cmd_Argc;
cgi->Args = Cmd_Args; cgi->Args = Cmd_Args;
@ -765,7 +773,9 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
cgi->UI_ShowMenu = UI_ShowMenu; cgi->UI_ShowMenu = UI_ShowMenu;
cgi->UI_HideMenu = UI_HideMenu; cgi->UI_HideMenu = UI_HideMenu;
cgi->UI_FontStringWidth = uie.FontStringWidth; cgi->UI_FontStringWidth = CL_FontStringWidth;
cgi->UI_GetObjectivesTop = UI_GetObjectivesTop;
cgi->UI_GetHighResolutionScale = UI_GetHighResolutionScale;
cgi->Key_StringToKeynum = Key_StringToKeynum; cgi->Key_StringToKeynum = Key_StringToKeynum;
cgi->Key_KeynumToBindString = Key_KeynumToBindString; cgi->Key_KeynumToBindString = Key_KeynumToBindString;
cgi->Key_GetKeysForCommand = Key_GetKeysForCommand; cgi->Key_GetKeysForCommand = Key_GetKeysForCommand;
@ -813,6 +823,8 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
cgi->CL_RestoreSavedCgameState = CL_RestoreSavedCgameState; cgi->CL_RestoreSavedCgameState = CL_RestoreSavedCgameState;
cgi->CL_ClearSavedCgameState = CL_ClearSavedCgameState; cgi->CL_ClearSavedCgameState = CL_ClearSavedCgameState;
cgi->getConfigStringIdNormalized = CPT_NormalizeConfigstring;
cgi->fsDebug = fs_debug; cgi->fsDebug = fs_debug;
cgi->HudDrawElements = cls.HudDrawElements; cgi->HudDrawElements = cls.HudDrawElements;
cgi->anim = &cls.anim; cgi->anim = &cls.anim;
@ -912,7 +924,13 @@ void CL_InitCGame( void ) {
// find the current mapname // find the current mapname
info = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SERVERINFO ]; info = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SERVERINFO ];
mapname = Info_ValueForKey( info, "mapname" ); mapname = Info_ValueForKey( info, "mapname" );
Com_sprintf( cl.mapname, sizeof( cl.mapname ), "maps/%s.bsp", mapname );
if (CL_UseLargeLightmap(mapname)) {
Com_sprintf(cl.mapname, sizeof(cl.mapname), "maps/%s.bsp", mapname);
} else {
// Added in 2.0
Com_sprintf(cl.mapname, sizeof(cl.mapname), "maps/%s_sml.bsp", mapname);
}
S_BeginRegistration(); S_BeginRegistration();
CL_ShutdownCGame(); CL_ShutdownCGame();
@ -927,10 +945,17 @@ void CL_InitCGame( void ) {
CL_InitClientSavedData(); CL_InitClientSavedData();
} }
// init for this gamestate if (cl.snap.valid) {
// use the lastExecutedServerCommand instead of the serverCommandSequence // init for this gamestate
// otherwise server commands sent just before a gamestate are dropped // use the lastExecutedServerCommand instead of the serverCommandSequence
cge->CG_Init( &cgi, clc.serverMessageSequence, clc.lastExecutedServerCommand, clc.clientNum ); // otherwise server commands sent just before a gamestate are dropped
cge->CG_Init(&cgi, clc.serverMessageSequence, clc.lastExecutedServerCommand, clc.clientNum);
} else {
// executing client commands from previous map/server might be an issue, some commands might be cs commands,
// like old CS_SYSTEMINFO configstrings which still contain the sv_serverId from previous map.
// It would cause the client to lose the game state number
cge->CG_Init(&cgi, clc.serverMessageSequence, clc.serverCommandSequence, clc.clientNum);
}
ClearNewConfigFlag(); ClearNewConfigFlag();
TIKI_FinishLoad(); TIKI_FinishLoad();
@ -1105,6 +1130,42 @@ void CL_FirstSnapshot( void ) {
Cbuf_AddText( cl_activeAction->string ); Cbuf_AddText( cl_activeAction->string );
Cvar_Set( "activeAction", "" ); Cvar_Set( "activeAction", "" );
} }
#ifdef USE_MUMBLE
if ((cl_useMumble->integer) && !mumble_islinked()) {
int ret = mumble_link(CLIENT_WINDOW_TITLE);
Com_Printf("Mumble: Linking to Mumble application %s\n", ret==0?"ok":"failed");
}
#endif
#ifdef USE_VOIP
if (!clc.voipCodecInitialized) {
int i;
int error;
clc.opusEncoder = opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, &error);
if ( error ) {
Com_DPrintf("VoIP: Error opus_encoder_create %d\n", error);
return;
}
for (i = 0; i < MAX_CLIENTS; i++) {
clc.opusDecoder[i] = opus_decoder_create(48000, 1, &error);
if ( error ) {
Com_DPrintf("VoIP: Error opus_decoder_create(%d) %d\n", i, error);
return;
}
clc.voipIgnore[i] = qfalse;
clc.voipGain[i] = 1.0f;
}
clc.voipCodecInitialized = qtrue;
clc.voipMuteAll = qfalse;
Cmd_AddCommand ("voip", CL_Voip_f);
Cvar_Set("cl_voipSendTarget", "spatial");
Com_Memset(clc.voipTargets, ~0, sizeof(clc.voipTargets));
}
#endif
} }
static int lastSnapFlags; static int lastSnapFlags;
@ -1155,7 +1216,12 @@ void CL_SetCGameTime( void ) {
// allow pause in single player // allow pause in single player
if ( paused->integer && com_sv_running->integer ) { if ( paused->integer && com_sv_running->integer ) {
// paused // paused
CL_AdjustTimeDelta(); //CL_AdjustTimeDelta();
// Fixed in OPM
// Keep in sync with the server time.
// In OG, the game could lag for a short time
// when pausing and unpausing frequently
cl.serverTimeDelta = cl.snap.serverTime - cls.realtime;
return; return;
} }

View file

@ -35,6 +35,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../uilib/ui_public.h" #include "../uilib/ui_public.h"
#include "snd_local.h" #include "snd_local.h"
#include "cl_ui.h"
#define MAXSIZE 8 #define MAXSIZE 8
#define MINSIZE 4 #define MINSIZE 4
@ -55,6 +57,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
static void RoQ_init( void ); static void RoQ_init( void );
static void CL_FinishedCinematic();
/****************************************************************************** /******************************************************************************
* *
@ -126,6 +129,10 @@ typedef struct {
int playonwalls; int playonwalls;
byte* buf; byte* buf;
long drawX, drawY; long drawX, drawY;
long realTime;
long currTime;
long soundTime;
} cin_cache; } cin_cache;
static cinematics_t cin; static cinematics_t cin;
@ -133,6 +140,10 @@ static cin_cache cinTable[MAX_VIDEO_HANDLES];
static int currentHandle = -1; static int currentHandle = -1;
static int CL_handle = -1; static int CL_handle = -1;
static connstate_t oldClientState;
static int audioStartTime = 0;
extern "C" int s_soundtime; // sample PAIRS extern "C" int s_soundtime; // sample PAIRS
@ -160,7 +171,7 @@ static int CIN_HandleForVideo(void) {
} }
extern "C" int CL_ScaledMilliseconds(void); extern "C" int Com_Milliseconds(void);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// RllSetupTable // RllSetupTable
@ -1091,8 +1102,6 @@ static void RoQReset( void ) {
static void RoQInterrupt(void) static void RoQInterrupt(void)
{ {
// Removed in OPM
#if 0
byte *framedata; byte *framedata;
short sbuf[32768]; short sbuf[32768];
int ssize; int ssize;
@ -1144,24 +1153,20 @@ redump:
case ZA_SOUND_MONO: case ZA_SOUND_MONO:
if (!cinTable[currentHandle].silent) { if (!cinTable[currentHandle].silent) {
ssize = RllDecodeMonoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags); ssize = RllDecodeMonoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags);
S_RawSamples(0, ssize, 22050, 2, 1, (byte *)sbuf, 1.0f, -1); // S_RawSamples(0, ssize, 22050, 2, 1, (byte *)sbuf, 1.0f, -1);
} }
break; break;
case ZA_SOUND_STEREO: case ZA_SOUND_STEREO:
if (!cinTable[currentHandle].silent) { if (!cinTable[currentHandle].silent) {
if (cinTable[currentHandle].numQuads == -1) {
S_Update();
s_rawend[0] = s_soundtime;
}
ssize = RllDecodeStereoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags); ssize = RllDecodeStereoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags);
S_RawSamples(0, ssize, 22050, 2, 2, (byte *)sbuf, 1.0f, -1); // S_RawSamples(0, ssize, 22050, 2, 2, (byte *)sbuf, 1.0f, -1);
} }
break; break;
case ROQ_QUAD_INFO: case ROQ_QUAD_INFO:
if (cinTable[currentHandle].numQuads == -1) { if (cinTable[currentHandle].numQuads == -1) {
readQuadInfo( framedata ); readQuadInfo( framedata );
setupQuad( 0, 0 ); setupQuad( 0, 0 );
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = CL_ScaledMilliseconds(); cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = Com_Milliseconds();
} }
if (cinTable[currentHandle].numQuads != 1) cinTable[currentHandle].numQuads = 0; if (cinTable[currentHandle].numQuads != 1) cinTable[currentHandle].numQuads = 0;
break; break;
@ -1216,7 +1221,6 @@ redump:
// assert(cinTable[currentHandle].RoQFrameSize <= 65536); // assert(cinTable[currentHandle].RoQFrameSize <= 65536);
// r = FS_Read( cin.file, cinTable[currentHandle].RoQFrameSize+8, cinTable[currentHandle].iFile ); // r = FS_Read( cin.file, cinTable[currentHandle].RoQFrameSize+8, cinTable[currentHandle].iFile );
cinTable[currentHandle].RoQPlayed += cinTable[currentHandle].RoQFrameSize+8; cinTable[currentHandle].RoQPlayed += cinTable[currentHandle].RoQFrameSize+8;
#endif
} }
/****************************************************************************** /******************************************************************************
@ -1229,7 +1233,10 @@ redump:
static void RoQ_init( void ) static void RoQ_init( void )
{ {
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = CL_ScaledMilliseconds(); cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = Com_Milliseconds();
cinTable[currentHandle].realTime = Com_Milliseconds();
cinTable[currentHandle].currTime = 0;
cinTable[currentHandle].soundTime = 0;
cinTable[currentHandle].RoQPlayed = 24; cinTable[currentHandle].RoQPlayed = 24;
@ -1276,8 +1283,10 @@ static void RoQShutdown( void ) {
cinTable[currentHandle].iFile = 0; cinTable[currentHandle].iFile = 0;
} }
S_StopMovieAudio();
if (cinTable[currentHandle].alterGameState) { if (cinTable[currentHandle].alterGameState) {
clc.state = CA_DISCONNECTED; clc.state = oldClientState;
// we can't just do a vstr nextmap, because // we can't just do a vstr nextmap, because
// if we are aborting the intro cinematic with // if we are aborting the intro cinematic with
// a devmap command, nextmap would be valid by // a devmap command, nextmap would be valid by
@ -1289,8 +1298,29 @@ static void RoQShutdown( void ) {
} }
CL_handle = -1; CL_handle = -1;
} }
cinTable[currentHandle].fileName[0] = 0; cinTable[currentHandle].fileName[0] = 0;
currentHandle = -1; currentHandle = -1;
CL_FinishedCinematic();
}
static void CL_FinishedCinematic()
{
const char* s;
if (!CL_FinishedIntro())
{
CL_FinishedStartStage();
return;
}
s = Cvar_VariableString("nextmap");
if (*s)
{
Cbuf_ExecuteText(EXEC_APPEND, va("%s\n", s));
Cvar_Set("nextmap", "");
}
} }
/* /*
@ -1331,8 +1361,11 @@ Fetch and decompress the pending frame
e_status CIN_RunCinematic (int handle) e_status CIN_RunCinematic (int handle)
{ {
int start = 0; int deltaTime;
int thisTime = 0; int frameTime;
int soundTime;
int newTime;
long tfps;
if (handle < 0 || handle>= MAX_VIDEO_HANDLES || cinTable[handle].status == FMV_EOF) return FMV_EOF; if (handle < 0 || handle>= MAX_VIDEO_HANDLES || cinTable[handle].status == FMV_EOF) return FMV_EOF;
@ -1360,24 +1393,46 @@ e_status CIN_RunCinematic (int handle)
return cinTable[currentHandle].status; return cinTable[currentHandle].status;
} }
thisTime = CL_ScaledMilliseconds(); frameTime = Com_Milliseconds();
if (cinTable[currentHandle].shader && (abs(thisTime - cinTable[currentHandle].lastTime))>100) { deltaTime = frameTime - cinTable[currentHandle].realTime;
cinTable[currentHandle].startTime += thisTime - cinTable[currentHandle].lastTime; if (deltaTime > 100) {
deltaTime = 100;
} }
cinTable[currentHandle].tfps = (((CL_ScaledMilliseconds() - cinTable[currentHandle].startTime)*3)/100);
start = cinTable[currentHandle].startTime; newTime = cinTable[currentHandle].currTime + deltaTime;
while( (cinTable[currentHandle].tfps != cinTable[currentHandle].numQuads) if (cl_movieaudio->integer) {
soundTime = S_CurrentMoviePosition();
if (soundTime > cinTable[currentHandle].currTime || soundTime > cinTable[currentHandle].soundTime) {
cinTable[currentHandle].currTime = newTime + (deltaTime * (soundTime - newTime)) / 100;
}
else {
cinTable[currentHandle].currTime = newTime;
}
cinTable[currentHandle].soundTime = soundTime;
} else {
//
// Fixed in OPM
//
cinTable[currentHandle].currTime = newTime;
}
cinTable[currentHandle].realTime = frameTime;
tfps = (cinTable[currentHandle].currTime * 3) / 100;
while( (tfps != cinTable[currentHandle].numQuads)
&& (cinTable[currentHandle].status == FMV_PLAY) ) && (cinTable[currentHandle].status == FMV_PLAY) )
{ {
RoQInterrupt(); RoQInterrupt();
if (start != cinTable[currentHandle].startTime) {
cinTable[currentHandle].tfps = (((CL_ScaledMilliseconds() - cinTable[currentHandle].startTime)*3)/100); cinTable[currentHandle].realTime = Com_Milliseconds();
start = cinTable[currentHandle].startTime; if (cinTable[currentHandle].realTime > frameTime + 66) {
break;
} }
} }
cinTable[currentHandle].lastTime = thisTime; cinTable[currentHandle].lastTime = frameTime;
if (cinTable[currentHandle].status == FMV_LOOPED) { if (cinTable[currentHandle].status == FMV_LOOPED) {
cinTable[currentHandle].status = FMV_PLAY; cinTable[currentHandle].status = FMV_PLAY;
@ -1400,9 +1455,6 @@ CIN_PlayCinematic
================== ==================
*/ */
int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBits ) { int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBits ) {
return 0;
// Removed in OPM
#if 0
unsigned short RoQID; unsigned short RoQID;
char name[MAX_OSPATH]; char name[MAX_OSPATH];
int i; int i;
@ -1428,7 +1480,7 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
cin.currentHandle = currentHandle; cin.currentHandle = currentHandle;
strcpy(cinTable[currentHandle].fileName, name); Q_strncpyz(cinTable[currentHandle].fileName, name, sizeof(cinTable[currentHandle].fileName));
cinTable[currentHandle].ROQSize = 0; cinTable[currentHandle].ROQSize = 0;
cinTable[currentHandle].ROQSize = FS_FOpenFileRead (cinTable[currentHandle].fileName, &cinTable[currentHandle].iFile, qtrue, qtrue); cinTable[currentHandle].ROQSize = FS_FOpenFileRead (cinTable[currentHandle].fileName, &cinTable[currentHandle].iFile, qtrue, qtrue);
@ -1474,17 +1526,12 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
clc.state = CA_CINEMATIC; clc.state = CA_CINEMATIC;
} }
if (!cinTable[currentHandle].silent) {
s_rawend[0] = s_soundtime;
}
return currentHandle; return currentHandle;
} }
Com_DPrintf("trFMV::play(), invalid RoQ ID\n"); Com_DPrintf("trFMV::play(), invalid RoQ ID\n");
RoQShutdown(); RoQShutdown();
return -1; return -1;
#endif
} }
void CIN_SetExtents (int handle, int x, int y, int w, int h) { void CIN_SetExtents (int handle, int x, int y, int w, int h) {
@ -1600,33 +1647,96 @@ void CIN_DrawCinematic (int handle) {
cinTable[handle].dirty = qfalse; cinTable[handle].dirty = qfalse;
} }
static unsigned short CL_PlayRoQ(const char* name, const char* arg, const char* s) {
unsigned short RoQID;
Com_Memset(&cin, 0, sizeof(cinematics_t) );
currentHandle = CIN_HandleForVideo();
cin.currentHandle = currentHandle;
Q_strncpyz(cinTable[currentHandle].fileName, name, sizeof(cinTable[currentHandle].fileName));
cinTable[currentHandle].ROQSize = 0;
cinTable[currentHandle].ROQSize = FS_FOpenFileRead (cinTable[currentHandle].fileName, &cinTable[currentHandle].iFile, qtrue, qtrue);
if (cinTable[currentHandle].ROQSize<=0) {
Com_DPrintf("Can not find RoQ cinematic '%s'\n", name);
CL_FinishedCinematic();
return -1;
}
if ((s && s[0] == '1') || Q_stricmp(arg,"demoend.roq")==0 || Q_stricmp(arg,"end.roq")==0) {
cinTable[currentHandle].holdAtEnd = qtrue;
}
CIN_SetExtents(currentHandle, 0, 0, 640, 480);
cinTable[currentHandle].alterGameState = qtrue;
initRoQ();
FS_Read (cin.file, 16, cinTable[currentHandle].iFile);
RoQID = (unsigned short)(cin.file[0]) + (unsigned short)(cin.file[1])*256;
if (RoQID == 0x1084)
{
RoQ_init();
// FS_Read (cin.file, cinTable[currentHandle].RoQFrameSize+8, cinTable[currentHandle].iFile);
cinTable[currentHandle].status = FMV_PLAY;
Com_DPrintf("trFMV::play(), playing %s\n", arg);
if (cl_movieaudio->integer) {
audioStartTime = Com_Milliseconds();
S_SetupMovieAudio(name);
}
oldClientState = clc.state;
clc.state = CA_CINEMATIC;
if (cls.glconfig.maxTextureSize <= 256 || s && *s == '2') {
//cinTable[currentHandle].interlaced = qtrue;
}
CL_handle = currentHandle;
do {
SCR_RunCinematic();
} while (!cinTable[currentHandle].buf && cinTable[currentHandle].status == FMV_PLAY);
UI_CloseConsole();
return currentHandle;
}
Com_DPrintf("trFMV::play(), invalid RoQ ID\n");
RoQShutdown();
return -1;
}
void CL_PlayCinematic_f(void) { void CL_PlayCinematic_f(void) {
char *arg, *s; char *arg, *s;
int bits = CIN_system; char name[256];
Com_DPrintf("CL_PlayCinematic_f\n");
if (clc.state == CA_CINEMATIC) { if (clc.state == CA_CINEMATIC) {
SCR_StopCinematic(); SCR_StopCinematic();
} }
arg = Cmd_Argv( 1 ); arg = Cmd_Argv( 1 );
Com_DPrintf("CL_PlayCinematic( %s )\n", arg);
s = Cmd_Argv(2); s = Cmd_Argv(2);
if ((s && s[0] == '1') || Q_stricmp(arg,"demoend.roq")==0 || Q_stricmp(arg,"end.roq")==0) { CL_StartHunkUsers(qfalse);
bits |= CIN_hold; S_StopAllSounds2(qtrue);
}
if (s && s[0] == '2') { Com_sprintf(name, sizeof(name), "video/%s", arg);
bits |= CIN_loop;
if (Q_stricmp(&name[strlen(name) - 4], ".roq")) {
Com_Printf("Bad or missing cinematic extension.\n");
return;
} }
S_StopAllSounds2( qtrue ); CL_PlayRoQ(name, arg, s);
CL_handle = CIN_PlayCinematic( arg, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, bits );
if (CL_handle >= 0) {
do {
SCR_RunCinematic();
} while (cinTable[currentHandle].buf == NULL && cinTable[currentHandle].status == FMV_PLAY); // wait for first frame (load codebook and sound)
}
} }
@ -1646,7 +1756,5 @@ void SCR_RunCinematic (void)
void SCR_StopCinematic(void) { void SCR_StopCinematic(void) {
if (CL_handle >= 0 && CL_handle < MAX_VIDEO_HANDLES) { if (CL_handle >= 0 && CL_handle < MAX_VIDEO_HANDLES) {
CIN_StopCinematic(CL_handle); CIN_StopCinematic(CL_handle);
S_StopAllSounds2( qtrue );
CL_handle = -1;
} }
} }

View file

@ -56,6 +56,10 @@ qboolean in_guimouse;
kbutton_t in_up, in_down; kbutton_t in_up, in_down;
#ifdef USE_VOIP
kbutton_t in_voiprecord;
#endif
kbutton_t in_buttons[16]; kbutton_t in_buttons[16];
qboolean in_mlooking; qboolean in_mlooking;
@ -258,6 +262,20 @@ void IN_SpeedUp(void) {IN_KeyUp(&in_speed);}
void IN_StrafeDown(void) {IN_KeyDown(&in_strafe);} void IN_StrafeDown(void) {IN_KeyDown(&in_strafe);}
void IN_StrafeUp(void) {IN_KeyUp(&in_strafe);} void IN_StrafeUp(void) {IN_KeyUp(&in_strafe);}
#ifdef USE_VOIP
void IN_VoipRecordDown(void)
{
IN_KeyDown(&in_voiprecord);
Cvar_Set("cl_voipSend", "1");
}
void IN_VoipRecordUp(void)
{
IN_KeyUp(&in_voiprecord);
Cvar_Set("cl_voipSend", "0");
}
#endif
void IN_Button0Down(void) {IN_KeyDown(&in_buttons[0]);} void IN_Button0Down(void) {IN_KeyDown(&in_buttons[0]);}
void IN_Button0Up(void) {IN_KeyUp(&in_buttons[0]);} void IN_Button0Up(void) {IN_KeyUp(&in_buttons[0]);}
void IN_Button1Down(void) {IN_KeyDown(&in_buttons[1]);} void IN_Button1Down(void) {IN_KeyDown(&in_buttons[1]);}
@ -432,7 +450,7 @@ void CL_MouseEvent( int dx, int dy, int time ) {
if( cl.mousey > cls.glconfig.vidHeight ) if( cl.mousey > cls.glconfig.vidHeight )
cl.mousey = cls.glconfig.vidHeight; cl.mousey = cls.glconfig.vidHeight;
} }
else else if ( !paused->integer )
{ {
cl.mouseDx[cl.mouseIndex] += dx; cl.mouseDx[cl.mouseIndex] += dx;
cl.mouseDy[cl.mouseIndex] += dy; cl.mouseDy[cl.mouseIndex] += dy;
@ -461,6 +479,16 @@ CL_JoystickMove
void CL_JoystickMove( usercmd_t *cmd ) { void CL_JoystickMove( usercmd_t *cmd ) {
float anglespeed; float anglespeed;
float yaw = j_yaw->value * cl.joystickAxis[j_yaw_axis->integer];
float right = j_side->value * cl.joystickAxis[j_side_axis->integer];
float forward = j_forward->value * cl.joystickAxis[j_forward_axis->integer];
float pitch = j_pitch->value * cl.joystickAxis[j_pitch_axis->integer];
float up = j_up->value * cl.joystickAxis[j_up_axis->integer];
if ( in_speed.active ^ cl_run->integer ) {
cmd->buttons |= BUTTON_RUN;
}
if ( in_speed.active ) { if ( in_speed.active ) {
anglespeed = 0.001 * cls.frametime * cl_anglespeedkey->value; anglespeed = 0.001 * cls.frametime * cl_anglespeedkey->value;
} else { } else {
@ -468,18 +496,22 @@ void CL_JoystickMove( usercmd_t *cmd ) {
} }
if ( !in_strafe.active ) { if ( !in_strafe.active ) {
cl.viewangles[YAW] += anglespeed * cl_yawspeed->value * cl.joystickAxis[AXIS_SIDE]; cl.viewangles[YAW] += anglespeed * yaw;
cmd->rightmove = ClampChar( cmd->rightmove + (int)right );
} else { } else {
cmd->rightmove = ClampChar( cmd->rightmove + cl.joystickAxis[AXIS_SIDE] ); cl.viewangles[YAW] += anglespeed * right;
cmd->rightmove = ClampChar( cmd->rightmove + (int)yaw );
} }
if ( in_mlooking ) { if ( in_mlooking ) {
cl.viewangles[PITCH] += anglespeed * cl_pitchspeed->value * cl.joystickAxis[AXIS_FORWARD]; cl.viewangles[PITCH] += anglespeed * forward;
cmd->forwardmove = ClampChar( cmd->forwardmove + (int)pitch );
} else { } else {
cmd->forwardmove = ClampChar( cmd->forwardmove + cl.joystickAxis[AXIS_FORWARD] ); cl.viewangles[PITCH] += anglespeed * pitch;
cmd->forwardmove = ClampChar( cmd->forwardmove + (int)forward );
} }
cmd->upmove = ClampChar( cmd->upmove + cl.joystickAxis[AXIS_UP] ); cmd->upmove = ClampChar( cmd->upmove + (int)up );
} }
/* /*
@ -565,6 +597,8 @@ void CL_MouseMove( usercmd_t *cmd ) {
mx *= cgameSensitivity; mx *= cgameSensitivity;
my *= cgameSensitivity; my *= cgameSensitivity;
cmd->buttons |= BUTTON_ANY;
// add mouse X/Y movement to cmd // add mouse X/Y movement to cmd
if(in_strafe.active) if(in_strafe.active)
cmd->rightmove = ClampChar(cmd->rightmove + m_side->value * mx); cmd->rightmove = ClampChar(cmd->rightmove + m_side->value * mx);
@ -577,9 +611,9 @@ void CL_MouseMove( usercmd_t *cmd ) {
cmd->forwardmove = ClampChar(cmd->forwardmove - m_forward->value * my); cmd->forwardmove = ClampChar(cmd->forwardmove - m_forward->value * my);
if (!isfinite(cl.viewangles[PITCH]) || !isfinite(cl.viewangles[YAW])) { if (!isfinite(cl.viewangles[PITCH]) || !isfinite(cl.viewangles[YAW])) {
Com_Printf("Invalid client viewangles encountered!\n"); Com_DPrintf("Invalid client viewangles encountered (view pitch: %f, view yaw: %f)!\n", cl.viewangles[PITCH], cl.viewangles[YAW]);
Com_Printf("cgameSensitivity: %f - mx: %f - my: %f - m_pitch: %f - m_yaw: %f", cgameSensitivity, mx, my, m_pitch->value, m_yaw->value); Com_DPrintf("cgameSensitivity: %f | mx: %f | my: %f | m_pitch: %f | m_yaw: %f\n", cgameSensitivity, mx, my, m_pitch->value, m_yaw->value);
Com_Printf("Resetting client viewangles"); Com_DPrintf("Resetting client viewangles\n");
cl.viewangles[PITCH] = 0; cl.viewangles[PITCH] = 0;
cl.viewangles[YAW] = 0; cl.viewangles[YAW] = 0;
} }
@ -617,8 +651,8 @@ void CL_CmdButtons( usercmd_t *cmd ) {
if (UI_MenuActive() || UI_ConsoleIsOpen()) { if (UI_MenuActive() || UI_ConsoleIsOpen()) {
cmd->buttons |= BUTTON_TALK; cmd->buttons |= BUTTON_TALK;
} }
if (in_speed.active == !cl_run->integer) { if ( in_speed.active ^ cl_run->integer ) {
cmd->buttons |= BUTTON_RUN; cmd->buttons |= BUTTON_RUN;
} }
@ -726,6 +760,12 @@ void CL_CreateNewCommands( void ) {
frame_msec = com_frameTime - old_com_frameTime; frame_msec = com_frameTime - old_com_frameTime;
// if running over 1000fps, act as if each frame is 1ms
// prevents divisions by zero
if ( frame_msec < 1 ) {
frame_msec = 1;
}
// if running less than 5fps, truncate the extra time to prevent // if running less than 5fps, truncate the extra time to prevent
// unexpected moves after a hitch // unexpected moves after a hitch
if ( frame_msec > 200 ) { if ( frame_msec > 200 ) {
@ -826,8 +866,8 @@ qboolean CL_ReadyToSendPacket( void ) {
} }
// check for exceeding cl_maxpackets // check for exceeding cl_maxpackets
if ( cl_maxpackets->integer < 15 ) { if ( cl_maxpackets->integer < 30 ) {
Cvar_Set( "cl_maxpackets", "15" ); Cvar_Set( "cl_maxpackets", "30" );
} else if ( cl_maxpackets->integer > 125 ) { } else if ( cl_maxpackets->integer > 125 ) {
Cvar_Set( "cl_maxpackets", "125" ); Cvar_Set( "cl_maxpackets", "125" );
} }
@ -917,6 +957,58 @@ void CL_WritePacket( void ) {
count = MAX_PACKET_USERCMDS; count = MAX_PACKET_USERCMDS;
Com_Printf("MAX_PACKET_USERCMDS\n"); Com_Printf("MAX_PACKET_USERCMDS\n");
} }
#ifdef USE_VOIP
if (clc.voipOutgoingDataSize > 0)
{
if((clc.voipFlags & VOIP_SPATIAL) || Com_IsVoipTarget(clc.voipTargets, sizeof(clc.voipTargets), -1))
{
MSG_WriteByte (&buf, clc_voipOpus);
MSG_WriteByte (&buf, clc.voipOutgoingGeneration);
MSG_WriteLong (&buf, clc.voipOutgoingSequence);
MSG_WriteByte (&buf, clc.voipOutgoingDataFrames);
MSG_WriteData (&buf, clc.voipTargets, sizeof(clc.voipTargets));
MSG_WriteByte(&buf, clc.voipFlags);
MSG_WriteShort (&buf, clc.voipOutgoingDataSize);
MSG_WriteData (&buf, clc.voipOutgoingData, clc.voipOutgoingDataSize);
// If we're recording a demo, we have to fake a server packet with
// this VoIP data so it gets to disk; the server doesn't send it
// back to us, and we might as well eliminate concerns about dropped
// and misordered packets here.
if(clc.demorecording && !clc.demowaiting)
{
const int voipSize = clc.voipOutgoingDataSize;
msg_t fakemsg;
byte fakedata[MAX_MSGLEN];
MSG_Init (&fakemsg, fakedata, sizeof (fakedata));
MSG_Bitstream (&fakemsg);
MSG_WriteLong (&fakemsg, clc.reliableAcknowledge);
MSG_WriteByte (&fakemsg, svc_voipOpus);
MSG_WriteShort (&fakemsg, clc.clientNum);
MSG_WriteByte (&fakemsg, clc.voipOutgoingGeneration);
MSG_WriteLong (&fakemsg, clc.voipOutgoingSequence);
MSG_WriteByte (&fakemsg, clc.voipOutgoingDataFrames);
MSG_WriteShort (&fakemsg, clc.voipOutgoingDataSize );
MSG_WriteBits (&fakemsg, clc.voipFlags, VOIP_FLAGCNT);
MSG_WriteData (&fakemsg, clc.voipOutgoingData, voipSize);
MSG_WriteByte (&fakemsg, svc_EOF);
CL_WriteDemoMessage (&fakemsg, 0);
}
clc.voipOutgoingSequence += clc.voipOutgoingDataFrames;
clc.voipOutgoingDataSize = 0;
clc.voipOutgoingDataFrames = 0;
}
else
{
// We have data, but no targets. Silently discard all data
clc.voipOutgoingDataSize = 0;
clc.voipOutgoingDataFrames = 0;
}
}
#endif
if ( count >= 1 ) { if ( count >= 1 ) {
if ( cl_showSend->integer ) { if ( cl_showSend->integer ) {
Com_Printf( "(%i)", count ); Com_Printf( "(%i)", count );
@ -973,16 +1065,6 @@ void CL_WritePacket( void ) {
} }
CL_Netchan_Transmit (&clc.netchan, &buf); CL_Netchan_Transmit (&clc.netchan, &buf);
// clients never really should have messages large enough
// to fragment, but in case they do, fire them all off
// at once
// TTimo: this causes a packet burst, which is bad karma for winsock
// added a WARNING message, we'll see if there are legit situations where this happens
while ( clc.netchan.unsentFragments ) {
Com_DPrintf( "WARNING: #462 unsent fragments (not supposed to happen!)\n" );
CL_Netchan_TransmitNextFragment( &clc.netchan );
}
} }
/* /*
@ -999,7 +1081,7 @@ void CL_SendCmd( void ) {
} }
// don't send commands if paused // don't send commands if paused
if ( com_sv_running->integer && paused->integer && paused->integer ) { if ( com_sv_running->integer && paused->integer ) {
return; return;
} }
@ -1094,6 +1176,85 @@ void CL_InitInput( void ) {
Cmd_AddCommand("+mlook", IN_MLookDown); Cmd_AddCommand("+mlook", IN_MLookDown);
Cmd_AddCommand("-mlook", IN_MLookUp); Cmd_AddCommand("-mlook", IN_MLookUp);
#ifdef USE_VOIP
Cmd_AddCommand ("+voiprecord", IN_VoipRecordDown);
Cmd_AddCommand ("-voiprecord", IN_VoipRecordUp);
#endif
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0); cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0);
cl_debugMove = Cvar_Get ("cl_debugMove", "0", 0); cl_debugMove = Cvar_Get ("cl_debugMove", "0", 0);
} }
/*
============
CL_ShutdownInput
============
*/
void CL_ShutdownInput(void)
{
Cmd_RemoveCommand("centerview");
Cmd_RemoveCommand("+moveup");
Cmd_RemoveCommand("-moveup");
Cmd_RemoveCommand("+movedown");
Cmd_RemoveCommand("-movedown");
Cmd_RemoveCommand("+left");
Cmd_RemoveCommand("-left");
Cmd_RemoveCommand("+right");
Cmd_RemoveCommand("-right");
Cmd_RemoveCommand("+forward");
Cmd_RemoveCommand("-forward");
Cmd_RemoveCommand("+back");
Cmd_RemoveCommand("-back");
Cmd_RemoveCommand("+lookup");
Cmd_RemoveCommand("-lookup");
Cmd_RemoveCommand("+lookdown");
Cmd_RemoveCommand("-lookdown");
Cmd_RemoveCommand("+strafe");
Cmd_RemoveCommand("-strafe");
Cmd_RemoveCommand("+moveleft");
Cmd_RemoveCommand("-moveleft");
Cmd_RemoveCommand("+moveright");
Cmd_RemoveCommand("-moveright");
Cmd_RemoveCommand("+speed");
Cmd_RemoveCommand("-speed");
Cmd_RemoveCommand("+attack");
Cmd_RemoveCommand("-attack");
Cmd_RemoveCommand("+button0");
Cmd_RemoveCommand("-button0");
Cmd_RemoveCommand("+button1");
Cmd_RemoveCommand("-button1");
Cmd_RemoveCommand("+button2");
Cmd_RemoveCommand("-button2");
Cmd_RemoveCommand("+button3");
Cmd_RemoveCommand("-button3");
Cmd_RemoveCommand("+button4");
Cmd_RemoveCommand("-button4");
Cmd_RemoveCommand("+button5");
Cmd_RemoveCommand("-button5");
Cmd_RemoveCommand("+button6");
Cmd_RemoveCommand("-button6");
Cmd_RemoveCommand("+button7");
Cmd_RemoveCommand("-button7");
Cmd_RemoveCommand("+button8");
Cmd_RemoveCommand("-button8");
Cmd_RemoveCommand("+button9");
Cmd_RemoveCommand("-button9");
Cmd_RemoveCommand("+button10");
Cmd_RemoveCommand("-button10");
Cmd_RemoveCommand("+button11");
Cmd_RemoveCommand("-button11");
Cmd_RemoveCommand("+button12");
Cmd_RemoveCommand("-button12");
Cmd_RemoveCommand("+button13");
Cmd_RemoveCommand("-button13");
Cmd_RemoveCommand("+button14");
Cmd_RemoveCommand("-button14");
Cmd_RemoveCommand("+mlook");
Cmd_RemoveCommand("-mlook");
#ifdef USE_VOIP
Cmd_RemoveCommand("+voiprecord");
Cmd_RemoveCommand("-voiprecord");
#endif
}

View file

@ -0,0 +1,640 @@
/*
===========================================================================
Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "cl_ui.h"
#include "cl_instantAction.h"
#include "cl_uiserverlist.h"
#include "../gamespy/sv_gamespy.h"
Event EV_UIInstantAction_AcceptServer
(
"acceptserver",
EV_DEFAULT,
NULL,
NULL,
"Connect to the current server"
);
Event EV_UIInstantAction_RejectServer
(
"rejectserver",
EV_DEFAULT,
NULL,
NULL,
"Reject the current server"
);
Event EV_UIInstantAction_Cancel
(
"ia_cancel",
EV_DEFAULT,
NULL,
NULL,
"cancel the server update"
);
Event EV_UIInstantAction_Refresh
(
"ia_refresh",
EV_DEFAULT,
NULL,
NULL,
"Refresh the server list"
);
CLASS_DECLARATION(UIWidget, UIInstantAction, NULL) {
{&EV_UIInstantAction_AcceptServer, &UIInstantAction::Connect },
{&EV_UIInstantAction_RejectServer, &UIInstantAction::Reject },
{&EV_UIInstantAction_Cancel, &UIInstantAction::CancelRefresh},
{&EV_UIInstantAction_Refresh, &UIInstantAction::Refresh },
{NULL, NULL }
};
struct ServerListInstance {
int iServerType;
UIInstantAction *pServerList;
};
ServerListInstance g_IAServerListInst[2];
UIInstantAction::UIInstantAction()
{
state = IA_INITIALIZE;
numFoundServers = 0;
numServers = 0;
minPlayers = 3;
startingMaxPing = 100;
endingMaxPing = 1500;
maxServers = -1;
servers = NULL;
doneList[0] = false;
doneList[1] = false;
serverList[0] = NULL;
serverList[1] = NULL;
ReadIniFile();
EnableServerInfo(false);
menuManager.PassEventToWidget("ia_cancel_button", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("ia_refresh_button", new Event(EV_Widget_Disable));
}
UIInstantAction::~UIInstantAction()
{
CleanUp();
}
void UIInstantAction::CleanUp()
{
if (serverList[0]) {
ServerListFree(serverList[0]);
serverList[0] = NULL;
}
if (serverList[1]) {
ServerListFree(serverList[1]);
serverList[1] = NULL;
}
if (servers) {
delete[] servers;
servers = NULL;
}
}
void UIInstantAction::Init()
{
const char *secret_key;
const char *game_name;
static const unsigned int iNumConcurrent = 10;
numFoundServers = 0;
numServers = 0;
doneList[0] = false;
doneList[1] = false;
EnableServerInfo(false);
menuManager.PassEventToWidget("ia_cancel_button", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("ia_refresh_button", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("ia_noserverfound", new Event(EV_Widget_Disable));
Cvar_Set("ia_search_percentage", va("%d %%", 0));
if (com_target_game->integer < target_game_e::TG_MOHTT) {
g_IAServerListInst[0].iServerType = com_target_game->integer;
g_IAServerListInst[0].pServerList = this;
game_name = GS_GetGameName(com_target_game->integer);
secret_key = GS_GetGameKey(com_target_game->integer);
serverList[0] = ServerListNew(
game_name,
game_name,
secret_key,
iNumConcurrent,
(void *)&IAServerListCallBack,
1,
(void *)&g_IAServerListInst[0]
);
ServerListClear(serverList[0]);
} else {
g_IAServerListInst[0].iServerType = target_game_e::TG_MOHTT;
g_IAServerListInst[0].pServerList = this;
game_name = GS_GetGameName(target_game_e::TG_MOHTT);
secret_key = GS_GetGameKey(target_game_e::TG_MOHTT);
serverList[0] = ServerListNew(
game_name,
game_name,
secret_key,
iNumConcurrent,
(void *)&IAServerListCallBack,
1,
(void *)&g_IAServerListInst[0]
);
ServerListClear(serverList[0]);
g_IAServerListInst[1].iServerType = target_game_e::TG_MOHTA;
g_IAServerListInst[1].pServerList = this;
game_name = GS_GetGameName(target_game_e::TG_MOHTA);
secret_key = GS_GetGameKey(target_game_e::TG_MOHTA);
serverList[1] = ServerListNew(
game_name,
game_name,
secret_key,
iNumConcurrent,
(void *)&IAServerListCallBack,
1,
(void *)&g_IAServerListInst[1]
);
ServerListClear(serverList[1]);
}
state = IA_WAITING;
numFoundServers = 0;
ServerListUpdate(serverList[0], true);
if (serverList[1]) {
ServerListUpdate(serverList[1], true);
}
menuManager.PassEventToWidget("ia_cancel_button", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("searchstatus", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("searchstatuslable", new Event(EV_Widget_Enable));
}
int UIInstantAction::GetServerIndex(int maxPing, int gameType)
{
int bestPing = 1500;
int bestServer = -1;
int i;
for (i = 0; i < numFoundServers; i++) {
const IAServer_t& IAServer = servers[i];
char *gameVer;
float fGameVer;
int ping;
int numPlayers;
if (IAServer.rejected) {
continue;
}
// Skip servers that don't match the provided game type
if (ServerGetIntValue(IAServer.server, "g_gametype_i", 1) != gameType) {
continue;
}
// Skip servers with high ping
ping = ServerGetPing(IAServer.server);
if (ping > maxPing) {
continue;
}
gameVer = ServerGetStringValue(IAServer.server, "gamever", "1.00");
if (com_target_demo->integer && *gameVer != 'd') {
// Skip retail servers on demo game
continue;
} else if (!com_target_demo->integer && *gameVer == 'd') {
// Skip demo servers on retail game
continue;
}
// Skip incompatible servers
fGameVer = atof(gameVer);
if (com_target_game->integer >= target_game_e::TG_MOHTT) {
if (IAServer.serverGame.serverType == target_game_e::TG_MOHTT) {
if (fabs(fGameVer) < 2.3f) {
continue;
}
} else {
if (fabs(fGameVer) < 2.1f) {
continue;
}
}
} else {
if (fabs(fGameVer - com_target_version->value) > 0.1f) {
continue;
}
}
// Skip servers with a password
if (ServerGetIntValue(IAServer.server, "password", 0)) {
continue;
}
// Skip servers that don't match the minimum number of players
numPlayers = ServerGetIntValue(IAServer.server, "numplayers", 0);
if (numPlayers < minPlayers) {
continue;
}
// Skip full servers
if (numPlayers == ServerGetIntValue(IAServer.server, "maxplayers", 0)) {
continue;
}
// Skip servers with an higher ping than the best one
if (ping >= bestPing) {
continue;
}
//
// Found a potential server
//
bestPing = ping;
bestServer = i;
}
return bestServer;
}
void UIInstantAction::ReadIniFile()
{
char *buffer;
const char *p;
const char *pVal;
int intValue;
char value[32];
if (!FS_ReadFileEx("iaction.ini", (void **)&buffer, qtrue)) {
return;
}
for (p = buffer; p; p = strstr(pVal, "\n")) {
if (sscanf(p, "%31s", value) != 1) {
break;
}
pVal = strstr(p, "=");
if (!pVal) {
break;
}
pVal++;
if (sscanf(pVal, "%d", &intValue) != 1) {
break;
}
if (!Q_stricmpn(value, "MinPlayers", 10)) {
minPlayers = intValue;
}
if (!Q_stricmpn(value, "StartingMaxPing", 15)) {
startingMaxPing = intValue;
}
if (!Q_stricmpn(value, "EndingMaxPing", 13)) {
endingMaxPing = intValue;
}
if (!Q_stricmpn(value, "MaxServers", 10)) {
maxServers = intValue;
}
}
}
void UIInstantAction::FindServer()
{
int ping;
int i;
currentServer = -1;
state = IA_NONE;
for (ping = startingMaxPing; ping < endingMaxPing; ping += 100) {
//
// Find the best server starting from FFA gametype first
//
for (i = 1; i < 7; i++) {
currentServer = GetServerIndex(ping, i);
if (currentServer >= 0) {
break;
}
}
if (currentServer >= 0) {
break;
}
}
menuManager.PassEventToWidget("ia_refresh_button", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("ia_cancel_button", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("searchstatus", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("searchstatuslable", new Event(EV_Widget_Disable));
if (currentServer < 0) {
EnableServerInfo(false);
menuManager.PassEventToWidget("ia_noserverfound", new Event(EV_Widget_Enable));
return;
}
const IAServer_t& IAServer = servers[currentServer];
const char *hostname = ServerGetStringValue(IAServer.server, "hostname", "(NONE)");
const char *gametype = ServerGetStringValue(IAServer.server, "gametype", "(NONE)");
int numplayers = ServerGetIntValue(IAServer.server, "numplayers", 0);
int maxplayers = ServerGetIntValue(IAServer.server, "maxplayers", 0);
ping = ServerGetPing(IAServer.server);
Cvar_Set("ia_servername", va(" %s", hostname));
Cvar_Set("ia_ping", va("%d", ping));
Cvar_Set("ia_gametype", va("%s", gametype));
Cvar_Set("ia_players", va("%d", numplayers));
Cvar_Set("ia_maxplayers", va("%d", maxplayers));
EnableServerInfo(true);
}
void UIInstantAction::Connect(Event *ev)
{
char *gameVer;
float fGameVer;
bool bDiffVersion;
char command[256];
if (currentServer < 0 || currentServer < numServers) {
return;
}
const IAServer_t& IAServer = servers[currentServer];
gameVer = ServerGetStringValue(IAServer.server, "gamever", "1.00");
if (gameVer[0] == 'd') {
gameVer++;
}
// Skip incompatible servers
fGameVer = atof(gameVer);
bDiffVersion = false;
if (com_target_game->integer >= target_game_e::TG_MOHTT) {
if (IAServer.serverGame.serverType == target_game_e::TG_MOHTT) {
if (fabs(fGameVer) < 2.3f) {
bDiffVersion = true;
}
} else {
if (fabs(fGameVer) < 2.1f) {
bDiffVersion = true;
}
}
} else {
if (fabs(fGameVer - com_target_version->value) > 0.1f) {
bDiffVersion = true;
}
}
if (bDiffVersion) {
if (fGameVer - com_target_version->value > 0) {
// Older version
UI_SetReturnMenuToCurrent();
Cvar_Set("com_errormessage", va("Server is version %s, you are using %s", gameVer, "2.40"));
UI_PushMenu("wrongversion");
} else {
// Server version is newer
Cvar_Set("dm_serverstatus", va("Can not connect to v%s server, you are using v%s", gameVer, "2.40"));
}
}
UI_SetReturnMenuToCurrent();
Cvar_Set("g_servertype", va("%d", servers[currentServer].serverGame.serverType));
Com_sprintf(
command,
sizeof(command),
"connect %s:%i\n",
ServerGetAddress(IAServer.server),
ServerGetIntValue(IAServer.server, "hostport", PORT_SERVER)
);
Cbuf_AddText(command);
}
void UIInstantAction::Reject(Event *ev)
{
servers[currentServer].rejected = 1;
FindServer();
}
void UIInstantAction::Draw()
{
switch (state) {
case IA_INITIALIZE:
Init();
break;
case IA_UPDATE:
Update();
break;
case IA_FINISHED:
FindServer();
break;
default:
break;
}
if (serverList[0]) {
ServerListThink(serverList[0]);
}
if (serverList[1]) {
ServerListThink(serverList[1]);
}
}
void UIInstantAction::Update()
{
numFoundServers = 0;
// count the total number of servers from both server list
numServers = ServerListCount(serverList[0]);
if (serverList[1]) {
numServers += ServerListCount(serverList[1]);
}
state = IA_FINISHED;
servers = new IAServer_t[numServers];
ServerListHalt(serverList[0]);
if (serverList[1]) {
ServerListHalt(serverList[1]);
}
ServerListThink(serverList[0]);
if (serverList[1]) {
ServerListThink(serverList[1]);
}
state = IA_SEARCHING;
// Start updating the first list
doneList[0] = false;
ServerListClear(serverList[0]);
ServerListUpdate(serverList[0], true);
// Update the second optional list
if (serverList[1]) {
doneList[1] = false;
ServerListClear(serverList[1]);
ServerListUpdate(serverList[1], true);
}
}
int UIInstantAction::AddServer(GServer server, const ServerGame_t& serverGame)
{
servers[numFoundServers].server = server;
servers[numFoundServers].serverGame = serverGame;
servers[numFoundServers].rejected = false;
numFoundServers++;
return numFoundServers;
}
void UIInstantAction::CancelRefresh(Event *ev)
{
state = IA_FINISHED;
ServerListHalt(serverList[0]);
ServerListHalt(serverList[1]);
}
void UIInstantAction::Refresh(Event *ev)
{
state = IA_INITIALIZE;
}
void UIInstantAction::EnableServerInfo(bool enable)
{
if (enable) {
menuManager.PassEventToWidget("iaservername_label", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("ia_servername_field", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("ia_ping_label", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("ia_ping_field", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("ia_gametype_label", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("ia_gametype_field", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("ia_players_label", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("ia_players_field", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("ia_maxplayers_label", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("ia_maxplayers_field", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("acceptserver", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("rejectserver", new Event(EV_Widget_Enable));
} else {
menuManager.PassEventToWidget("iaservername_label", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("ia_servername_field", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("ia_ping_label", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("ia_ping_field", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("ia_gametype_label", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("ia_gametype_field", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("ia_players_label", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("ia_players_field", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("ia_maxplayers_label", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("ia_maxplayers_field", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("acceptserver", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("rejectserver", new Event(EV_Widget_Disable));
}
}
void UIInstantAction::IAServerListCallBack(GServerList serverlist, int msg, void *instance, void *param1, void *param2)
{
const ServerListInstance *pInstance = (const ServerListInstance *)instance;
UIInstantAction *pServerList = pInstance->pServerList;
if (msg == LIST_PROGRESS) {
if (pServerList->state == IA_WAITING) {
if (pInstance->iServerType == com_target_game->integer) {
pServerList->doneList[0] = true;
}
if (com_target_game->integer >= target_game_e::TG_MOHTT && pInstance->iServerType == target_game_e::TG_MOHTA) {
pServerList->doneList[1] = true;
}
if (pServerList->doneList[0] && (!pServerList->serverList[1] || pServerList->doneList[1])) {
pServerList->state = IA_UPDATE;
}
} else if (pServerList->state == IA_SEARCHING) {
ServerGame_t serverGame;
serverGame.serverType = pInstance->iServerType;
const int serverIndex = pServerList->AddServer((GServer)param1, serverGame);
Cvar_Set("ia_search_percentage", va("%d %%", 100 * serverIndex / pServerList->numServers));
if (pServerList->maxServers >= 0 && serverIndex >= pServerList->maxServers) {
// Reached the maximum number of servers, stop there
pServerList->doneList[0] = true;
ServerListHalt(pServerList->serverList[0]);
if (pServerList->serverList[1]) {
pServerList->doneList[1] = true;
ServerListHalt(pServerList->serverList[1]);
}
pServerList->state = IA_FINISHED;
}
}
} else if (msg == LIST_STATECHANGED && ServerListState(serverlist) == GServerListState::sl_idle) {
if (pInstance->iServerType == com_target_game->integer) {
pServerList->doneList[0] = true;
}
if (com_target_game->integer >= target_game_e::TG_MOHTT && pInstance->iServerType == target_game_e::TG_MOHTA) {
pServerList->doneList[1] = true;
}
if (pServerList->doneList[0] && (!pServerList->serverList[1] || pServerList->doneList[1])) {
if (pServerList->state == IA_WAITING) {
pServerList->state = IA_UPDATE;
}
if (pServerList->state == IA_SEARCHING) {
pServerList->state = IA_FINISHED;
}
}
}
}

View file

@ -0,0 +1,103 @@
/*
===========================================================================
Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// Added in 2.30
// Instantly find a server matching common criterias
#pragma once
#include "../gamespy/goaceng.h"
typedef struct {
int serverType;
} ServerGame_t;
typedef struct {
GServer server;
ServerGame_t serverGame;
bool rejected;
} IAServer_t;
enum IAState_e {
IA_NONE,
IA_INITIALIZE,
IA_WAITING,
IA_UPDATE,
IA_SEARCHING,
IA_FINISHED
};
class UIInstantAction : public UIWidget
{
public:
CLASS_PROTOTYPE(UIInstantAction);
public:
UIInstantAction();
~UIInstantAction() override;
void CleanUp();
void Init();
int GetServerIndex(int maxPing, int gameType);
void ReadIniFile();
void FindServer();
void Connect(Event *ev);
void Reject(Event *ev);
void Draw();
void Update();
int AddServer(GServer server, const ServerGame_t& serverGame);
void CancelRefresh(Event *ev);
void Refresh(Event *ev);
void EnableServerInfo(bool enable);
private:
static void IAServerListCallBack(GServerList serverlist, int msg, void *instance, void *param1, void *param2);
private:
//
// List
//
bool doneList[2];
GServerList serverList[2];
int maxServers;
//
// Current states
//
IAState_e state;
int numServers;
int numFoundServers;
//
// Filters
//
int minPlayers;
int startingMaxPing;
int endingMaxPing;
//
// Servers
//
IAServer_t *servers;
int currentServer;
};

View file

@ -23,8 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_ui.h" #include "cl_ui.h"
typedef struct { typedef struct {
char *string; const char *string;
int value; int value;
} equipment_event_table_t; } equipment_event_table_t;
static equipment_event_table_t s_equipTable[] = { static equipment_event_table_t s_equipTable[] = {

View file

@ -148,7 +148,7 @@ void CL_Draw3DModel(
hModel[iCurrNum] = model; hModel[iCurrNum] = model;
iIndex[iCurrNum] = -1; iIndex[iCurrNum] = -1;
strcpy(szAnimName[iCurrNum], anim); Q_strncpyz(szAnimName[iCurrNum], anim, sizeof(szAnimName[iCurrNum]));
} else { } else {
iCurrNum = i; iCurrNum = i;
@ -164,7 +164,7 @@ void CL_Draw3DModel(
} }
} else { } else {
iIndex[iCurrNum] = -1; iIndex[iCurrNum] = -1;
strcpy(szAnimName[iCurrNum], anim); Q_strncpyz(szAnimName[iCurrNum], anim, sizeof(szAnimName[iCurrNum]));
} }
} }
@ -295,7 +295,7 @@ void UI_DoInventory(qboolean activate_mouse)
if (client_inv.align == INV_ALIGN_RIGHT) { if (client_inv.align == INV_ALIGN_RIGHT) {
s_main_inv->InitFrame( s_main_inv->InitFrame(
NULL, NULL,
client_inv.horizoffset + cls.glconfig.vidWidth - client_inv.typewidth, client_inv.horizoffset + uid.vidWidth - client_inv.typewidth,
client_inv.vertoffset, client_inv.vertoffset,
client_inv.typewidth, client_inv.typewidth,
client_inv.typeheight * client_inv.types.NumObjects(), client_inv.typeheight * client_inv.types.NumObjects(),

View file

@ -984,6 +984,8 @@ CL_InitKeyCommands
*/ */
void CL_InitKeyCommands(void) void CL_InitKeyCommands(void)
{ {
int i;
// register our functions // register our functions
Cmd_AddCommand("bind", Key_Bind_f); Cmd_AddCommand("bind", Key_Bind_f);
Cmd_AddCommand("unbind", Key_Unbind_f); Cmd_AddCommand("unbind", Key_Unbind_f);
@ -997,6 +999,10 @@ void CL_InitKeyCommands(void)
Cmd_AddCommand("ctrlbindlist", Key_AltBindlist_f); Cmd_AddCommand("ctrlbindlist", Key_AltBindlist_f);
memset(menubound, 0, sizeof(menubound)); memset(menubound, 0, sizeof(menubound));
for (i = K_F1; i <= K_F15; i++) {
menubound[i] = qtrue;
}
} }
/* /*
@ -1089,7 +1095,7 @@ void CL_KeyEvent(int key, qboolean down, unsigned time)
if (clc.state > CA_DISCONNECTED && cge && !Key_GetCatcher() && cge->CG_CheckCaptureKey(key, down, time) if (clc.state > CA_DISCONNECTED && cge && !Key_GetCatcher() && cge->CG_CheckCaptureKey(key, down, time)
&& key != K_ESCAPE) { && key != K_ESCAPE) {
if (key == K_CONSOLE || (keys[K_SHIFT].down && key == K_ESCAPE)) { if (key != K_CONSOLE && (!keys[K_SHIFT].down || key != K_ESCAPE)) {
return; return;
} }
} }
@ -1134,9 +1140,9 @@ void CL_KeyEvent(int key, qboolean down, unsigned time)
if (key >= K_MOUSE1 && key <= K_MOUSE5) { if (key >= K_MOUSE1 && key <= K_MOUSE5) {
if (down) { if (down) {
cl.mouseButtons |= (1 << (key + (256 - K_MOUSE1))); cl.mouseButtons |= (1 << (key - K_MOUSE1));
} else { } else {
cl.mouseButtons &= ~(1 << (key + (256 - K_MOUSE1))); cl.mouseButtons &= ~(1 << (key - K_MOUSE1));
} }
if (in_guimouse) { if (in_guimouse) {
@ -1346,5 +1352,5 @@ Key_SetCatcher
*/ */
void Key_SetCatcher(int catcher) void Key_SetCatcher(int catcher)
{ {
keyCatchers = catcher; cls.keyCatchers = catcher;
} }

File diff suppressed because it is too large Load diff

View file

@ -132,7 +132,7 @@ CL_Netchan_TransmitNextFragment
================= =================
*/ */
void CL_Netchan_TransmitNextFragment( netchan_t *chan ) { void CL_Netchan_TransmitNextFragment( netchan_t *chan ) {
Netchan_TransmitNextFragment( chan ); Netchan_TransmitNextFragment( chan, cl_netprofile->integer ? &cls.netprofile.inPackets : NULL );
} }
/* /*
@ -144,7 +144,7 @@ void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg ) {
MSG_WriteByte( msg, clc_EOF ); MSG_WriteByte( msg, clc_EOF );
CL_Netchan_Encode( msg ); CL_Netchan_Encode( msg );
Netchan_Transmit( chan, msg->cursize, msg->data ); Netchan_Transmit( chan, msg->cursize, msg->data, cl_netprofile->integer ? &cls.netprofile.inPackets : NULL );
} }
extern int oldsize; extern int oldsize;
@ -158,10 +158,30 @@ CL_Netchan_Process
qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg ) { qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg ) {
int ret; int ret;
ret = Netchan_Process( chan, msg ); ret = Netchan_Process( chan, msg, cl_netprofile->integer ? &cls.netprofile.outPackets : NULL );
if (!ret) if (!ret)
return qfalse; return qfalse;
CL_Netchan_Decode( msg ); CL_Netchan_Decode( msg );
newsize += msg->cursize; newsize += msg->cursize;
return qtrue; return qtrue;
} }
/*
=================
CL_NET_OutOfBandPrint
=================
*/
void CL_NET_OutOfBandPrint(netadr_t adr, const char* format, ...) {
va_list argptr;
char string[MAX_MSGLEN];
va_start(argptr, format);
Q_vsnprintf(string, sizeof(string), format, argptr);
va_end(argptr);
NET_OutOfBandPrint(NS_CLIENT, adr, "%s", string);
if (cl_netprofile->integer) {
NetProfileAddPacket(&cls.netprofile.inPackets, strlen(string), NETPROF_PACKET_MESSAGE);
}
}

View file

@ -223,13 +223,13 @@ qboolean CL_UnpackNonPVSClient(int* packed, radarUnpacked_t* unpacked) {
range = 0; range = 0;
} }
unpacked->x = x * range / 63.f; unpacked->x = x * range / (MAX_CLIENTS - 1);
unpacked->y = y * range / 63.f; unpacked->y = y * range / (MAX_CLIENTS - 1);
if (!bValid) if (!bValid)
{ {
unpacked->x = x * range / 63.f * 1024; unpacked->x = x * range / (MAX_CLIENTS - 1) * 1024.0;
unpacked->y = y * range / 63.f * 1024; unpacked->y = y * range / (MAX_CLIENTS - 1) * 1024.0;
} }
unpacked->yaw = yaw * 11.25f; unpacked->yaw = yaw * 11.25f;
@ -429,12 +429,24 @@ void CL_SystemInfoChanged( void ) {
// in some cases, outdated cp commands might get sent with this news serverId // in some cases, outdated cp commands might get sent with this news serverId
cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) ); cl.serverId = atoi( Info_ValueForKey( systemInfo, "sv_serverid" ) );
#ifdef USE_VOIP
#ifdef LEGACY_PROTOCOL
if(clc.compat)
clc.voipEnabled = qfalse;
else
#endif
{
s = Info_ValueForKey( systemInfo, "sv_voipProtocol" );
clc.voipEnabled = !Q_stricmp(s, "opus");
}
#endif
// don't set any vars when playing a demo // don't set any vars when playing a demo
if ( clc.demoplaying ) { if ( clc.demoplaying ) {
return; return;
} }
s = Info_ValueForKey( systemInfo, "sv_cheats" ); s = Info_ValueForKey( systemInfo, "cheats" );
cl_connectedToCheatServer = atoi( s ); cl_connectedToCheatServer = atoi( s );
if ( !cl_connectedToCheatServer ) { if ( !cl_connectedToCheatServer ) {
Cvar_SetCheatState(); Cvar_SetCheatState();
@ -556,6 +568,7 @@ void CL_ParseGamestate( msg_t *msg ) {
csNum = CPT_NormalizeConfigstring(i); csNum = CPT_NormalizeConfigstring(i);
if (csNum < 0 || csNum >= MAX_CONFIGSTRINGS) { if (csNum < 0 || csNum >= MAX_CONFIGSTRINGS) {
Com_Error(ERR_DROP, "configstring > MAX_CONFIGSTRINGS"); Com_Error(ERR_DROP, "configstring > MAX_CONFIGSTRINGS");
return;
} }
s = MSG_ReadScrambledBigString(msg); s = MSG_ReadScrambledBigString(msg);
len = strlen(s); len = strlen(s);
@ -576,8 +589,7 @@ void CL_ParseGamestate( msg_t *msg ) {
//Com_Memset (&nullstate, 0, sizeof(nullstate)); //Com_Memset (&nullstate, 0, sizeof(nullstate));
MSG_GetNullEntityState(&nullstate); MSG_GetNullEntityState(&nullstate);
es = &cl.entityBaselines[ newnum ]; es = &cl.entityBaselines[ newnum ];
// FIXME: frametime MSG_ReadDeltaEntity( msg, &nullstate, es, newnum, cls.serverFrameTime);
MSG_ReadDeltaEntity( msg, &nullstate, es, newnum, 0.0);
} else { } else {
Com_Error( ERR_DROP, "CL_ParseGamestate: bad command byte %i", cmd ); Com_Error( ERR_DROP, "CL_ParseGamestate: bad command byte %i", cmd );
} }
@ -594,16 +606,25 @@ void CL_ParseGamestate( msg_t *msg ) {
// stop recording now so the demo won't have an unnecessary level load at the end. // stop recording now so the demo won't have an unnecessary level load at the end.
if(cl_autoRecordDemo->integer && clc.demorecording) if(cl_autoRecordDemo->integer && clc.demorecording)
CL_StopRecord_f(); CL_StopRecord_f();
// reinitialize the filesystem if the game directory has changed if (clc.state == CA_CONNECTED && !Cvar_Get("sv_paks", "", 0)->string[0]) {
FS_ConditionalRestart( clc.checksumFeed, qfalse ); // Added in 2.30
FS_Restart(clc.checksumFeed);
} else {
// reinitialize the filesystem if the game directory has changed
FS_ConditionalRestart(clc.checksumFeed, qfalse);
}
clc.state = CA_LOADING; clc.state = CA_LOADING;
if (!com_sv_running->integer) if (!com_sv_running->integer)
{ {
const char *info = cl.gameState.stringData + cl.gameState.stringOffsets[CS_SERVERINFO]; const char *info = cl.gameState.stringData + cl.gameState.stringOffsets[CS_SERVERINFO];
UI_ClearState(); const char *mapname = Info_ValueForKey(info, "mapname");
UI_BeginLoad(Info_ValueForKey(info, "mapname")); // Added in 2.0
Cvar_Set("mapname", mapname);
UI_ClearState();
UI_BeginLoad(mapname);
} }
// This used to call CL_StartHunkUsers, but now we enter the download state before loading the // This used to call CL_StartHunkUsers, but now we enter the download state before loading the
@ -784,6 +805,178 @@ void CL_ParseDownload ( msg_t *msg ) {
} }
} }
#ifdef USE_VOIP
static
qboolean CL_ShouldIgnoreVoipSender(int sender)
{
if (!cl_voip->integer)
return qtrue; // VoIP is disabled.
else if ((sender == clc.clientNum) && (!clc.demoplaying))
return qtrue; // ignore own voice (unless playing back a demo).
else if (clc.voipMuteAll)
return qtrue; // all channels are muted with extreme prejudice.
else if (clc.voipIgnore[sender])
return qtrue; // just ignoring this guy.
else if (clc.voipGain[sender] == 0.0f)
return qtrue; // too quiet to play.
return qfalse;
}
/*
=====================
CL_PlayVoip
Play raw data
=====================
*/
static void CL_PlayVoip(int sender, int samplecnt, const byte *data, int flags)
{
if(flags & VOIP_DIRECT)
{
S_RawSamples(sender + 1, samplecnt, 48000, 2, 1,
data, clc.voipGain[sender], -1);
}
if(flags & VOIP_SPATIAL)
{
S_RawSamples(sender + MAX_CLIENTS + 1, samplecnt, 48000, 2, 1,
data, 1.0f, sender);
}
}
/*
=====================
CL_ParseVoip
A VoIP message has been received from the server
=====================
*/
static
void CL_ParseVoip ( msg_t *msg, qboolean ignoreData ) {
static short decoded[VOIP_MAX_PACKET_SAMPLES*4]; // !!! FIXME: don't hard code
const int sender = MSG_ReadShort(msg);
const int generation = MSG_ReadByte(msg);
const int sequence = MSG_ReadLong(msg);
const int frames = MSG_ReadByte(msg);
const int packetsize = MSG_ReadShort(msg);
const int flags = MSG_ReadBits(msg, VOIP_FLAGCNT);
unsigned char encoded[4000];
int numSamples;
int seqdiff;
int written = 0;
int i;
Com_DPrintf("VoIP: %d-byte packet from client %d\n", packetsize, sender);
if (sender < 0)
return; // short/invalid packet, bail.
else if (generation < 0)
return; // short/invalid packet, bail.
else if (sequence < 0)
return; // short/invalid packet, bail.
else if (frames < 0)
return; // short/invalid packet, bail.
else if (packetsize < 0)
return; // short/invalid packet, bail.
if (packetsize > sizeof (encoded)) { // overlarge packet?
int bytesleft = packetsize;
while (bytesleft) {
int br = bytesleft;
if (br > sizeof (encoded))
br = sizeof (encoded);
MSG_ReadData(msg, encoded, br);
bytesleft -= br;
}
return; // overlarge packet, bail.
}
MSG_ReadData(msg, encoded, packetsize);
if (ignoreData) {
return; // just ignore legacy speex voip data
} else if (!clc.voipCodecInitialized) {
return; // can't handle VoIP without libopus!
} else if (sender >= MAX_CLIENTS) {
return; // bogus sender.
} else if (CL_ShouldIgnoreVoipSender(sender)) {
return; // Channel is muted, bail.
}
// !!! FIXME: make sure data is narrowband? Does decoder handle this?
Com_DPrintf("VoIP: packet accepted!\n");
seqdiff = sequence - clc.voipIncomingSequence[sender];
// This is a new "generation" ... a new recording started, reset the bits.
if (generation != clc.voipIncomingGeneration[sender]) {
Com_DPrintf("VoIP: new generation %d!\n", generation);
opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
clc.voipIncomingGeneration[sender] = generation;
seqdiff = 0;
} else if (seqdiff < 0) { // we're ahead of the sequence?!
// This shouldn't happen unless the packet is corrupted or something.
Com_DPrintf("VoIP: misordered sequence! %d < %d!\n",
sequence, clc.voipIncomingSequence[sender]);
// reset the decoder just in case.
opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
seqdiff = 0;
} else if (seqdiff * VOIP_MAX_PACKET_SAMPLES*2 >= sizeof (decoded)) { // dropped more than we can handle?
// just start over.
Com_DPrintf("VoIP: Dropped way too many (%d) frames from client #%d\n",
seqdiff, sender);
opus_decoder_ctl(clc.opusDecoder[sender], OPUS_RESET_STATE);
seqdiff = 0;
}
if (seqdiff != 0) {
Com_DPrintf("VoIP: Dropped %d frames from client #%d\n",
seqdiff, sender);
// tell opus that we're missing frames...
for (i = 0; i < seqdiff; i++) {
assert((written + VOIP_MAX_PACKET_SAMPLES) * 2 < sizeof (decoded));
numSamples = opus_decode(clc.opusDecoder[sender], NULL, 0, decoded + written, VOIP_MAX_PACKET_SAMPLES, 0);
if ( numSamples <= 0 ) {
Com_DPrintf("VoIP: Error decoding frame %d from client #%d\n", i, sender);
continue;
}
written += numSamples;
}
}
numSamples = opus_decode(clc.opusDecoder[sender], encoded, packetsize, decoded + written, ARRAY_LEN(decoded) - written, 0);
if ( numSamples <= 0 ) {
Com_DPrintf("VoIP: Error decoding voip data from client #%d\n", sender);
numSamples = 0;
}
#if 0
static FILE *encio = NULL;
if (encio == NULL) encio = fopen("voip-incoming-encoded.bin", "wb");
if (encio != NULL) { fwrite(encoded, packetsize, 1, encio); fflush(encio); }
static FILE *decio = NULL;
if (decio == NULL) decio = fopen("voip-incoming-decoded.bin", "wb");
if (decio != NULL) { fwrite(decoded+written, numSamples*2, 1, decio); fflush(decio); }
#endif
written += numSamples;
Com_DPrintf("VoIP: playback %d bytes, %d samples, %d frames\n",
written * 2, written, frames);
if(written > 0)
CL_PlayVoip(sender, written, (const byte *) decoded, flags);
clc.voipIncomingSequence[sender] = sequence + frames;
}
#endif
/* /*
===================== =====================
CL_ParseCommandString CL_ParseCommandString
@ -932,8 +1125,16 @@ void CL_ParseServerMessage( msg_t *msg ) {
} }
CL_ParseCGMessage( msg ); CL_ParseCGMessage( msg );
break; break;
case svc_voipSpeex:
#ifdef USE_VOIP
CL_ParseVoip( msg, qtrue );
#endif
break;
case svc_voipOpus:
#ifdef USE_VOIP
CL_ParseVoip( msg, !clc.voipEnabled );
#endif
break;
} }
} }
} }

View file

@ -343,7 +343,7 @@ void SCR_DrawDemoRecording( void ) {
} }
pos = FS_FTell( clc.demofile ); pos = FS_FTell( clc.demofile );
sprintf( string, "RECORDING %s: %ik", clc.demoName, pos / 1024 ); Com_sprintf( string, sizeof( string ), "RECORDING %s: %ik", clc.demoName, pos / 1024 );
SCR_DrawStringExt( 320 - strlen( string ) * 4, 20, 8, string, g_color_table[7], qtrue, qfalse ); SCR_DrawStringExt( 320 - strlen( string ) * 4, 20, 8, string, g_color_table[7], qtrue, qfalse );
} }
@ -520,16 +520,18 @@ text to the screen.
================== ==================
*/ */
void SCR_UpdateScreen( void ) { void SCR_UpdateScreen( void ) {
static int recursive; static qboolean screen_recursive;
if ( !scr_initialized ) { if ( !scr_initialized ) {
return; // not initialized yet return; // not initialized yet
} }
if ( ++recursive > 2 ) { if (screen_recursive) {
Com_Error( ERR_FATAL, "SCR_UpdateScreen: recursively called" ); // already called
return;
} }
recursive = 1;
screen_recursive = qtrue;
CL_StartHunkUsers(qfalse); CL_StartHunkUsers(qfalse);
SCR_SimpleUpdateScreen(); SCR_SimpleUpdateScreen();
@ -553,6 +555,6 @@ void SCR_UpdateScreen( void ) {
} }
} }
recursive = 0; screen_recursive = qfalse;
} }

View file

@ -1,6 +1,6 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2023 the OpenMoHAA team Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/q_version.h" #include "../qcommon/q_version.h"
#include "cl_ui.h" #include "cl_ui.h"
#include "cl_uigamespy.h"
#include <ctime> #include <ctime>
@ -136,18 +137,26 @@ static unsigned int startCountHigh;
static unsigned int loadCountLow; static unsigned int loadCountLow;
static unsigned int loadCountHigh; static unsigned int loadCountHigh;
static unsigned int loadCount; static unsigned int loadCount;
static unsigned int lastTime; static unsigned int lastTime = 0;
static unsigned int updateTime = 0;
static unsigned int loadNumber; static unsigned int loadNumber;
static unsigned int totalLoadTime; static unsigned int totalLoadTime;
static unsigned int currentLoadTime; static unsigned int currentLoadTime;
unsigned char UIListCtrlItem[8]; unsigned char UIListCtrlItem[8];
static const float maxWidthRes = 1920;
static const float maxHeightRes = 1080;
inventory_t client_inv; inventory_t client_inv;
bind_t client_bind; bind_t client_bind;
static str scoreboard_menuname; static str scoreboard_menuname;
static str ui_sCurrentLoadingMenu; static str ui_sCurrentLoadingMenu;
static Container<Menu *> hudList; static Container<Menu *> hudList;
const UColor UWhiteChatMessageColor(0.75, 0.75, 0.75);
const UColor URedChatMessageColor(1.0, 0.25, 0.25);
const UColor UGreenChatMessageColor(0.0, 1.0, 0.25, 1.0);
void UI_MultiplayerMenuWidgetsUpdate(void); void UI_MultiplayerMenuWidgetsUpdate(void);
void UI_MultiplayerMainMenuWidgetsUpdate(void); void UI_MultiplayerMainMenuWidgetsUpdate(void);
void UI_MainMenuWidgetsUpdate(void); void UI_MainMenuWidgetsUpdate(void);
@ -211,15 +220,15 @@ static UIRect2D getDefaultConsoleRectangle(void)
f[i] = floor(f[i]); f[i] = floor(f[i]);
} }
rect.pos.x = f[0] - cls.glconfig.vidWidth; rect.pos.x = f[0] - uid.vidWidth;
rect.pos.y = f[1] - cls.glconfig.vidHeight; rect.pos.y = f[1] - uid.vidHeight;
rect.size.width = f[2] + 50.0; rect.size.width = f[2] + 50.0;
rect.size.height = f[3] + 50.0; rect.size.height = f[3] + 50.0;
} else { } else {
rect.pos.x = 25.0; rect.pos.x = 25.0;
rect.pos.y = 25.0; rect.pos.y = 25.0;
rect.size.width = (cls.glconfig.vidWidth - 50); rect.size.width = (uid.vidWidth - 50);
rect.size.height = (cls.glconfig.vidHeight / 2); rect.size.height = (uid.vidHeight / 2);
} }
return rect; return rect;
@ -265,7 +274,7 @@ static void GetClientState(uiClientState_t *state)
{ {
state->connectPacketCount = clc.connectPacketCount; state->connectPacketCount = clc.connectPacketCount;
state->connState = clc.state; state->connState = clc.state;
Q_strncpyz(state->servername, cls.servername, sizeof(state->servername)); Q_strncpyz(state->servername, clc.servername, sizeof(state->servername));
Q_strncpyz(state->updateInfoString, cls.updateInfoString, sizeof(state->updateInfoString)); Q_strncpyz(state->updateInfoString, cls.updateInfoString, sizeof(state->updateInfoString));
Q_strncpyz(state->messageString, clc.serverMessage, sizeof(state->messageString)); Q_strncpyz(state->messageString, clc.serverMessage, sizeof(state->messageString));
state->clientNum = cl.snap.ps.clientNum; state->clientNum = cl.snap.ps.clientNum;
@ -966,15 +975,15 @@ static UIRect2D getDefaultDMConsoleRectangle(void)
f[i] = floor(f[i]); f[i] = floor(f[i]);
} }
rect.pos.x = f[0] - cls.glconfig.vidWidth; rect.pos.x = f[0] - uid.vidWidth;
rect.pos.y = f[1] - cls.glconfig.vidHeight; rect.pos.y = f[1] - uid.vidHeight;
rect.size.width = f[2] + 50.0; rect.size.width = f[2] + 50.0;
rect.size.height = f[3] + 50.0; rect.size.height = f[3] + 50.0;
} else { } else {
rect.pos.x = 0; rect.pos.x = 0;
rect.pos.y = cls.glconfig.vidHeight * 0.58; rect.pos.y = uid.vidHeight * 0.58;
rect.size.width = cls.glconfig.vidWidth; rect.size.width = uid.vidWidth;
rect.size.height = cls.glconfig.vidHeight * 0.415; rect.size.height = uid.vidHeight * 0.415;
} }
return rect; return rect;
@ -996,15 +1005,19 @@ static UIRect2D getQuickMessageDMConsoleRectangle(void)
f[i] = floor(f[i]); f[i] = floor(f[i]);
} }
rect.pos.x = f[0] - cls.glconfig.vidWidth; rect.pos.x = f[0] - uid.vidWidth;
rect.pos.y = f[1] - cls.glconfig.vidHeight; rect.pos.y = f[1] - uid.vidHeight;
rect.size.width = f[2] + 50.0; rect.size.width = f[2] + 50.0;
rect.size.height = f[3] + 50.0; rect.size.height = f[3] + 50.0;
} else { } else {
rect.pos.x = 0; rect.pos.x = 0;
rect.pos.y = cls.glconfig.vidHeight * 0.65; rect.pos.y = uid.vidHeight * 0.66;
rect.size.width = cls.glconfig.vidWidth; rect.size.width = uid.vidWidth;
rect.size.height = 38.0; // Fixed in 2.0
// Was 38.0 in 1.11 and below
// This prevents characters to be seen from the DM console
// in the quick message console
rect.size.height = 36.0 * uid.scaleRes[1];
} }
return rect; return rect;
@ -1017,7 +1030,7 @@ UI_DMMessageModesMatch
*/ */
static qboolean UI_DMMessageModesMatch(int iMode) static qboolean UI_DMMessageModesMatch(int iMode)
{ {
qboolean bQuickMessage; qboolean bQuickMessage = qfalse;
if (iMode && (iMode != 300 || dm_console->GetQuickMessageMode())) { if (iMode && (iMode != 300 || dm_console->GetQuickMessageMode())) {
if (iMode < 0) { if (iMode < 0) {
@ -1048,13 +1061,15 @@ static void UI_SetDMConsoleMode(int iMode)
return; return;
} }
bQuickMessage = qfalse;
if (iMode < 0) { if (iMode < 0) {
bQuickMessage = qtrue; bQuickMessage = qtrue;
iMode = -iMode; iMode = -iMode;
} }
if (iMode == 300) { if (iMode == 300) {
bQuickMessage = dm_console->GetMessageMode(); iMode = dm_console->GetMessageMode();
} }
if (dm_console->GetQuickMessageMode()) { if (dm_console->GetQuickMessageMode()) {
@ -1064,8 +1079,8 @@ static void UI_SetDMConsoleMode(int iMode)
} }
} else { } else {
if (bQuickMessage) { if (bQuickMessage) {
dm_console->setFrame(getDefaultDMConsoleRectangle()); dm_console->setFrame(getQuickMessageDMConsoleRectangle());
dm_console->SetQuickMessageMode(qfalse); dm_console->SetQuickMessageMode(bQuickMessage);
} }
} }
@ -1086,7 +1101,7 @@ static void UI_SetDMConsoleMode(int iMode)
dm_console->setTitle(Sys_LV_CL_ConvertString( dm_console->setTitle(Sys_LV_CL_ConvertString(
"Chat Window (Enter to send/close) (all|team|private to change mode) : Messaging to All" "Chat Window (Enter to send/close) (all|team|private to change mode) : Messaging to All"
)); ));
} else if (iMode == 100) { } else if (iMode == 200) {
dm_console->setTitle(Sys_LV_CL_ConvertString( dm_console->setTitle(Sys_LV_CL_ConvertString(
"Chat Window (Enter to send/close) (all|team|private to change mode) : Messaging to Team" "Chat Window (Enter to send/close) (all|team|private to change mode) : Messaging to Team"
)); ));
@ -1121,6 +1136,20 @@ static void DMConsoleCommandHandler(const char *txt)
CL_AddReliableCommand(szStringOut, qfalse); CL_AddReliableCommand(szStringOut, qfalse);
} }
/*
====================
getScreenWidth
====================
*/
static float getScreenWidth()
{
if (uid.bHighResScaling) {
return maxWidthRes;
} else {
return uid.vidWidth;
}
}
/* /*
==================== ====================
getNewConsole getNewConsole
@ -1182,14 +1211,14 @@ getDefaultGMBoxRectangle
static UIRect2D getDefaultGMBoxRectangle(void) static UIRect2D getDefaultGMBoxRectangle(void)
{ {
UIRect2D dmRect = getDefaultDMBoxRectangle(); UIRect2D dmRect = getDefaultDMBoxRectangle();
float height = cls.glconfig.vidHeight * ui_compass_scale->value * 0.25f; float height = uid.vidHeight * ui_compass_scale->value * 0.25f;
float y = dmRect.size.height + dmRect.pos.y; float y = dmRect.size.height + dmRect.pos.y;
if (height < y) { if (height < y) {
height = y; height = y;
} }
return UIRect2D(20.0f, height, cls.glconfig.vidWidth - 20, 128.0f); return UIRect2D(20.0f, height, (getScreenWidth() - 20) * uid.scaleRes[0], 128.0f * uid.scaleRes[1]);
} }
/* /*
@ -1199,9 +1228,37 @@ getDefaultDMBoxRectangle
*/ */
static UIRect2D getDefaultDMBoxRectangle(void) static UIRect2D getDefaultDMBoxRectangle(void)
{ {
float width = cls.glconfig.vidWidth * ui_compass_scale->value * 0.2f; float width;
float screenWidth = getScreenWidth();
width = screenWidth * uid.scaleRes[0] * ui_compass_scale->value * 0.2f;
return UIRect2D(width, 0, cls.glconfig.vidWidth - (width + 192.0f), 120.0f); return UIRect2D(width, 0, (screenWidth - (width + 192.0f)) * uid.scaleRes[0], 120.0f * uid.scaleRes[1]);
}
/*
====================
UI_GetObjectivesTop
====================
*/
float UI_GetObjectivesTop(void)
{
return getDefaultGMBoxRectangle().pos.y;
}
/*
====================
UI_GetObjectivesTop
====================
*/
void UI_GetHighResolutionScale(vec2_t scale)
{
if (uid.bHighResScaling) {
scale[0] = uid.scaleRes[0];
scale[1] = uid.scaleRes[1];
} else {
scale[0] = scale[1] = 1.0;
}
} }
/* /*
@ -1251,11 +1308,11 @@ UI_PrintConsole
*/ */
void UI_PrintConsole(const char *msg) void UI_PrintConsole(const char *msg)
{ {
UColor *pColor = NULL; const UColor *pColor = NULL;
const char *pszString; const char *pszString;
char szString[1024]; char szString[1024];
char szBlah[1024]; char szBlah[1024];
qboolean bPrintedDMBox = qfalse; qboolean bPrintedDMBox = qfalse;
pszString = msg; pszString = msg;
strncpy(szString, msg, 1024); strncpy(szString, msg, 1024);
@ -1273,7 +1330,7 @@ void UI_PrintConsole(const char *msg)
break; break;
case MESSAGE_CHAT_WHITE: case MESSAGE_CHAT_WHITE:
bDMMessage = qtrue; bDMMessage = qtrue;
pColor = &UGrey; pColor = &UWhiteChatMessageColor;
break; break;
case MESSAGE_WHITE: case MESSAGE_WHITE:
bBold = qtrue; bBold = qtrue;
@ -1281,15 +1338,17 @@ void UI_PrintConsole(const char *msg)
break; break;
case MESSAGE_CHAT_RED: case MESSAGE_CHAT_RED:
bDeathMessage = MESSAGE_CHAT_RED; bDeathMessage = MESSAGE_CHAT_RED;
pColor = &ULightRed; pColor = &URedChatMessageColor;
break; break;
case MESSAGE_CHAT_GREEN: case MESSAGE_CHAT_GREEN:
bDeathMessage = MESSAGE_CHAT_GREEN; bDeathMessage = MESSAGE_CHAT_GREEN;
pColor = &UGreen; pColor = &UGreenChatMessageColor;
break; break;
} }
pszString++; if (*pszString != 0) {
pszString++;
}
// //
// print to the deathmatch console // print to the deathmatch console
@ -1458,7 +1517,7 @@ void UI_FocusMenuIfExists(void)
currentMenu->ActivateMenu(); currentMenu->ActivateMenu();
if (ui_newvidmode->integer == -1) { if (ui_newvidmode->integer == -1) {
Cvar_Get("ui_newvidmode", va("%d", r_mode), CVAR_SERVER_CREATED); Cvar_Get("ui_newvidmode", va("%d", r_mode), CVAR_RESETSTRING);
Cvar_SetValue("ui_newvidmode", r_mode); Cvar_SetValue("ui_newvidmode", r_mode);
} }
} else { } else {
@ -1662,11 +1721,11 @@ UI_ClearBackground
void UI_ClearBackground(void) void UI_ClearBackground(void)
{ {
re.Set2DWindow( re.Set2DWindow(
0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, -1, -1 0, 0, uid.vidWidth, uid.vidHeight, 0, uid.vidWidth, uid.vidHeight, 0, -1, 1
); );
re.Scissor(0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight); re.Scissor(0, 0, uid.vidWidth, uid.vidHeight);
re.SetColor(g_color_table[0]); re.SetColor(g_color_table[0]);
re.DrawBox(0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight); re.DrawBox(0, 0, uid.vidWidth, uid.vidHeight);
re.SetColor(NULL); re.SetColor(NULL);
} }
@ -1700,7 +1759,36 @@ void UI_DrawIntro(void)
view3d->setShow(false); view3d->setShow(false);
UI_ClearBackground(); UI_ClearBackground();
// FIXME: draw intro if (cls.startStage < 3 || cls.startStage >= 12) {
return;
}
if (intro_stage.material->GetMaterial()) {
float swidth;
float sheight;
vec4_t color;
VectorSet4(color, 1, 1, 1, 1);
if (intro_stage.fadetime) {
float frac;
frac = Q_clamp_float((cls.realtime - intro_stage.starttime) / intro_stage.fadetime, 0, 1);
color[0] = color[1] = color[2] =
intro_stage.alpha_start + frac * (intro_stage.alpha_end - intro_stage.alpha_start);
}
swidth = view3d->getFrame().getMaxX();
sheight = view3d->getFrame().getMaxY();
re.SetColor(color);
re.DrawStretchPic(0.0, 0.0, swidth, sheight, 0.0, 0.0, 1.0, 1.0, intro_stage.material->GetMaterial());
re.SetColor(NULL);
}
if (cls.realtime >= intro_stage.endtime) {
CL_FinishedStartStage();
}
} }
/* /*
@ -1775,6 +1863,8 @@ void UI_Update(void)
hud_compass->GetContainerWidget()->Display(frame, 1.0); hud_compass->GetContainerWidget()->Display(frame, 1.0);
} }
} }
return;
} }
if (fakk_console) { if (fakk_console) {
@ -1805,17 +1895,9 @@ void UI_Update(void)
} }
// don't care about the intro // don't care about the intro
/* if (!CL_FinishedIntro()) {
if( CL_FinishedIntro() ) UI_DrawIntro();
{ } else if (!server_loading && (clc.state == CA_CONNECTING || clc.state == CA_CHALLENGING) && ui_pConnectingMenu) {
}
else
{
UI_DrawIntro();
}
*/
if (!server_loading && (clc.state == CA_CONNECTING || clc.state == CA_CHALLENGING) && ui_pConnectingMenu) {
view3d->setShow(false); view3d->setShow(false);
UI_ClearBackground(); UI_ClearBackground();
@ -1853,7 +1935,7 @@ void UI_Update(void)
if (clc.state <= CA_PRIMED) { if (clc.state <= CA_PRIMED) {
view3d->setShow(false); view3d->setShow(false);
UI_ClearBackground(); UI_ClearBackground();
} else if (clc.state == CA_PRIMED || clc.state == CA_ACTIVE) { } else if (clc.state == CA_ACTIVE || clc.state == CA_CINEMATIC) {
Com_FakeUnpause(); Com_FakeUnpause();
view3d->setShow(true); view3d->setShow(true);
} else { } else {
@ -1887,7 +1969,7 @@ void UI_Update(void)
UI_CloseConsole(); UI_CloseConsole();
} }
} else if (ui_static_materials.loading) { } else if (ui_static_materials.loading) {
ui_static_materials.loading->ReregisterMaterial(); ui_static_materials.loading->GetMaterial();
} }
} }
} }
@ -2634,7 +2716,7 @@ void UI_PushMenuSP_f(void)
} }
if ((!com_cl_running || !com_cl_running->integer || clc.state == CA_DISCONNECTED || !cg_gametype->integer) if ((!com_cl_running || !com_cl_running->integer || clc.state == CA_DISCONNECTED || !cg_gametype->integer)
&& (!com_sv_running || !com_sv_running->integer || !g_gametype->integer)) { && (!com_sv_running || !com_sv_running->integer || g_gametype->integer == GT_SINGLE_PLAYER)) {
UI_PushMenu(Cmd_Argv(1)); UI_PushMenu(Cmd_Argv(1));
} }
} }
@ -2655,7 +2737,7 @@ void UI_PushMenuMP_f(void)
} }
if (com_cl_running && com_cl_running->integer && clc.state != CA_DISCONNECTED && cg_gametype->integer if (com_cl_running && com_cl_running->integer && clc.state != CA_DISCONNECTED && cg_gametype->integer
&& com_sv_running && com_sv_running->integer && g_gametype->integer) { && com_sv_running && com_sv_running->integer && g_gametype->integer != GT_SINGLE_PLAYER) {
cmd = Cmd_Argv(1); cmd = Cmd_Argv(1);
// //
@ -3009,14 +3091,14 @@ void CL_PingServers_f(void)
if (!noudp->integer) { if (!noudp->integer) {
adr.type = NA_BROADCAST; adr.type = NA_BROADCAST;
adr.port = BigShort(12203); adr.port = BigShort(12203);
NET_OutOfBandPrint(NS_SERVER, adr, "info %i", 8); CL_NET_OutOfBandPrint(adr, "info %i", 8);
} }
noipx = Cvar_Get("noipx", "0", CVAR_INIT); noipx = Cvar_Get("noipx", "0", CVAR_INIT);
if (!noipx->integer) { if (!noipx->integer) {
adr.type = NA_BROADCAST_IPX; adr.type = NA_BROADCAST_IPX;
adr.port = BigShort(12203); adr.port = BigShort(12203);
NET_OutOfBandPrint(NS_SERVER, adr, "info %i", 8); CL_NET_OutOfBandPrint(adr, "info %i", 8);
} }
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
@ -3031,7 +3113,7 @@ void CL_PingServers_f(void)
adr.port = BigShort(12203); adr.port = BigShort(12203);
} }
NET_OutOfBandPrint(NS_SERVER, adr, "info %i", 8); CL_NET_OutOfBandPrint(adr, "info %i", 8);
} else { } else {
Com_Printf("Bad address: %s\n", adrstring); Com_Printf("Bad address: %s\n", adrstring);
} }
@ -3056,7 +3138,7 @@ void UI_MapList_f(void)
MapRunnerClass *map = new MapRunnerClass; MapRunnerClass *map = new MapRunnerClass;
map->Setup("maps", mappath, ".bsp", "_sml"); map->Setup("maps", mappath, ".bsp", "_sml");
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2); CL_SetMousePos(uid.vidWidth / 2, uid.vidHeight / 2);
} }
/* /*
@ -3096,7 +3178,7 @@ void UI_DMMapSelect_f(void)
MpMapPickerClass *map = new MpMapPickerClass; MpMapPickerClass *map = new MpMapPickerClass;
map->Setup(basepath, mappath, gametype); map->Setup(basepath, mappath, gametype);
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2); CL_SetMousePos(uid.vidWidth / 2, uid.vidHeight / 2);
} }
/* /*
@ -3280,7 +3362,7 @@ void UI_PlayerModel_f(void)
PlayerModelPickerClass *picker = new PlayerModelPickerClass; PlayerModelPickerClass *picker = new PlayerModelPickerClass;
picker->Setup("models/player", modelpath, bGermanModel); picker->Setup("models/player", modelpath, bGermanModel);
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2); CL_SetMousePos(uid.vidWidth / 2, uid.vidHeight / 2);
} }
/* /*
@ -3333,6 +3415,7 @@ void UI_GetPlayerModel_f(void)
Cvar_Set("ui_dm_playergermanmodel_set", pszUIPlayerModel); Cvar_Set("ui_dm_playergermanmodel_set", pszUIPlayerModel);
if (!strncmp(pszUIPlayerModel, "german_waffen_", 14)) { if (!strncmp(pszUIPlayerModel, "german_waffen_", 14)) {
Q_strncpyz(donotshowssindeorfr, "german_waffenss_", sizeof(donotshowssindeorfr));
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), pszUIPlayerModel + 14); Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), pszUIPlayerModel + 14);
Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", donotshowssindeorfr)); Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", donotshowssindeorfr));
} else { } else {
@ -3544,7 +3627,7 @@ UI_WantsKeyboard
*/ */
void UI_WantsKeyboard() void UI_WantsKeyboard()
{ {
cls.keyCatchers |= KEYCATCH_UI; Key_SetCatcher(Key_GetCatcher() | KEYCATCH_UI);
} }
struct widgettrans_s { struct widgettrans_s {
@ -3669,12 +3752,13 @@ void CL_FillUIImports(void)
uii.Rend_Scissor = re.Scissor; uii.Rend_Scissor = re.Scissor;
uii.Rend_Set2D = re.Set2DWindow; uii.Rend_Set2D = re.Set2DWindow;
uii.Rend_SetColor = re.SetColor; uii.Rend_SetColor = re.SetColor;
uii.Rend_ImageExists = re.ImageExists;
uii.Cmd_Stuff = Cbuf_AddText; uii.Cmd_Stuff = Cbuf_AddText;
uii.Cvar_GetString = CvarGetForUI; uii.Cvar_GetString = CvarGetForUI;
uii.Cvar_Reset = Cvar_Reset; uii.Cvar_Reset = Cvar_Reset;
uii.Cvar_Find = Cvar_FindVar; uii.Cvar_Find = Cvar_FindVar;
uii.Cvar_Set = Cvar_Set; uii.Cvar_Set = UI_Cvar_Set;
uii.File_PickFile = PickFile; uii.File_PickFile = PickFile;
uii.File_FreeFile = FS_FreeFile; uii.File_FreeFile = FS_FreeFile;
uii.File_ListFiles = ListFilesForUI; uii.File_ListFiles = ListFilesForUI;
@ -3708,101 +3792,8 @@ void CL_FillUIImports(void)
uii.GetConfigstring = CL_ConfigString; uii.GetConfigstring = CL_ConfigString;
uii.UI_CloseDMConsole = UI_CloseDMConsole; uii.UI_CloseDMConsole = UI_CloseDMConsole;
#if 0 uii.GetRefSequence = CL_GetRefSequence;
uii.TIKI_RegisterModel = TIKI_RegisterTiki; uii.IsRendererLoaded = CL_IsRendererLoaded;
uii.Cvar_Get = Cvar_Get;
uii.Argc = Cmd_Argc;
uii.Argv = Cmd_Argv;
uii.Cmd_ExecuteText = Cbuf_ExecuteText;
uii.FS_FOpenFile = FS_FOpenFileByMode;
uii.FS_Read = FS_Read;
uii.FS_Write = FS_Write;
uii.FS_FCloseFile = FS_FCloseFile;
uii.FS_GetFileList = FS_GetFileList;
uii.FS_Seek = FS_Seek;
uii.R_RegisterModel = re.RegisterModel;
uii.R_RegisterSkin = re.RegisterShader;
uii.R_RegisterShader = re.RegisterShader;
uii.R_RegisterShaderNoMip = re.RegisterShaderNoMip;
uii.R_ClearScene = re.ClearScene;
uii.R_AddRefEntityToScene = re.AddRefEntityToScene;
uii.R_AddPolyToScene = re.AddPolyToScene;
uii.R_AddLightToScene = re.AddLightToScene;
uii.R_RenderScene = re.RenderScene;
uii.R_SetColor = re.SetColor;
uii.R_DrawStretchPic = re.DrawStretchPic;
uii.UpdateScreen = SCR_UpdateScreen;
uii.S_StartLocalSound = S_StartLocalSound;
uii.S_RegisterSound = S_RegisterSound;
uii.Key_KeynumToStringBuf = Key_KeynumToStringBuf;
uii.Key_KeynumToString = Key_KeynumToString;
uii.Key_GetBindingBuf = Key_GetBindingBuf;
uii.Key_IsDown = Key_IsDown;
uii.Key_GetOverstrikeMode = Key_GetOverstrikeMode;
uii.Key_SetOverstrikeMode = Key_SetOverstrikeMode;
uii.Key_ClearStates = Key_ClearStates;
uii.Key_GetCatcher = Key_GetCatcher;
uii.Key_SetCatcher = Key_SetCatcher;
uii.GetClipboardData = CL_GetClipboardData;
uii.GetClientState = GetClientState;
uii.GetGlconfig = CL_GetGlconfig;
uii.GetConfigString = GetConfigString;
uii.LAN_GetServerCount = LAN_GetServerCount;
uii.LAN_GetServerAddressString = LAN_GetServerAddressString;
uii.LAN_GetServerInfo = LAN_GetServerInfo;
uii.LAN_GetPingQueueCount = LAN_GetPingQueueCount;
uii.LAN_ServerStatus = LAN_GetServerStatus;
uii.LAN_ClearPing = LAN_ClearPing;
uii.LAN_GetPing = LAN_GetPing;
uii.LAN_GetPingInfo = LAN_GetPingInfo;
uii.LAN_GetServerPing = LAN_GetServerPing;
uii.LAN_MarkServerVisible = LAN_MarkServerVisible;
uii.LAN_UpdateVisiblePings = LAN_UpdateVisiblePings;
uii.GetCDKey = CLUI_GetCDKey;
uii.SetCDKey = CLUI_SetCDKey;
uii.R_RegisterFont = re.RegisterFont;
uii.R_Text_Width = re.Text_Width;
uii.R_Text_Height = re.Text_Height;
uii.R_Text_Paint = re.Text_Paint;
uii.R_Text_PaintChar = re.Text_PaintChar;
uii.R_GetShaderName = re.GetShaderName;
uii.Cmd_Stuff = Cbuf_AddText;
uii.Cvar_GetString = CvarGetForUI;
uii.Cvar_Reset = Cvar_Reset;
uii.Cvar_Find = Cvar_FindVar;
uii.Cvar_Set = UI_Cvar_Set;
uii.File_PickFile = PickFile;
uii.File_FreeFile = FS_FreeFile;
uii.File_ListFiles = ListFilesForUI;
uii.File_OpenFile = FS_ReadFile;
uii.File_WriteFile = FS_WriteTextFile;
uii.Rend_SetColor = re.SetColor;
uii.Snd_PlaySound = UI_StartLocalSound;
uii.Snd_RegisterSound = UI_RegisterSound;
uii.Alias_Add = Alias_Add;
uii.Alias_FindRandom = Alias_FindRandom;
uii.Sys_Error = Com_Error;
uii.Sys_IsKeyDown = IsKeyDown;
uii.Sys_Milliseconds = Sys_Milliseconds;
uii.Sys_Printf = Com_Printf;
uii.Sys_DPrintf = Com_DPrintf;
uii.Sys_GetClipboard = Sys_GetWholeClipboard;
uii.Sys_SetClipboard = Sys_SetClipboard;
uii.Cmd_CompleteCommandByNumber = Cmd_CompleteCommandByNumber;
uii.Cvar_CompleteCvarByNumber = Cvar_CompleteVariableByNumber;
uii.UI_WantsKeyboard = UI_WantsKeyboard;
uii.Client_TranslateWidgetName = TranslateWidgetName;
uii.Connect = CL_Connect;
uii.Key_GetKeynameForCommand = Key_GetKeynameForCommand;
uii.Key_GetCommandForKey = Key_GetBinding;
uii.Key_SetBinding = Key_SetBinding;
uii.Key_GetKeysForCommand = Key_GetKeysForCommand;
uii.Key_KeynumToString = Key_KeynumToBindString;
uii.GetConfigstring = CL_ConfigString;
uii.UI_CloseDMConsole = UI_CloseDMConsole;
#endif
} }
/* /*
@ -3859,7 +3850,7 @@ void UI_CreateDialog(
{ {
UIDialog *dlg = new UIDialog; UIDialog *dlg = new UIDialog;
UIRect2D rect = UIRect2D rect =
UIRect2D((cls.glconfig.vidWidth - width) >> 1, (cls.glconfig.vidHeight - height) >> 1, width, height); UIRect2D((uid.vidWidth - width) / 2, (uid.vidHeight - height) / 2, width, height);
UColor bgColor = UWindowColor; UColor bgColor = UWindowColor;
dlg->Create(NULL, rect, title, bgColor, UHudColor); dlg->Create(NULL, rect, title, bgColor, UHudColor);
@ -3885,10 +3876,32 @@ void UI_ResolutionChange(void)
{ {
UIRect2D frame; UIRect2D frame;
ui_compass_scale = Cvar_Get("ui_compass_scale", "0.75", CVAR_ARCHIVE | CVAR_LATCH); if (com_target_game->integer >= TG_MOHTA) {
ui_compass_scale = Cvar_Get("ui_compass_scale", "0.75", CVAR_ARCHIVE | CVAR_LATCH);
} else {
// Older version doesn't have an adjustable compass, so assume 0.5 by default
ui_compass_scale = Cvar_Get("ui_compass_scale", "0.55", CVAR_ARCHIVE | CVAR_LATCH);
}
CL_FillUIImports(); CL_FillUIImports();
CL_FillUIDef(); CL_FillUIDef();
// Added in OPM
// Scaling for high resolutions
if (uid.vidWidth > maxWidthRes && uid.vidHeight > maxHeightRes) {
const float vidRatio = (float)uid.vidWidth / (float)uid.vidHeight;
uid.scaleRes[0] = (float)uid.vidWidth / (maxHeightRes * vidRatio);
uid.scaleRes[1] = (float)uid.vidHeight / maxHeightRes;
//uid.scaleRes[0] = (float)uid.vidWidth / maxWidthRes;
//uid.scaleRes[1] = (float)uid.vidHeight / maxHeightRes;
uid.bHighResScaling = qtrue;
} else {
uid.scaleRes[0] = 1;
uid.scaleRes[1] = 1;
uid.bHighResScaling = qfalse;
}
if (!uie.ResolutionChange) { if (!uie.ResolutionChange) {
return; return;
} }
@ -3923,7 +3936,7 @@ void UI_ResolutionChange(void)
menuManager.RealignMenus(); menuManager.RealignMenus();
if (view3d) { if (view3d) {
frame = UIRect2D(0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight); frame = UIRect2D(0, 0, uid.vidWidth, uid.vidHeight);
view3d->setFrame(frame); view3d->setFrame(frame);
} }
@ -3971,13 +3984,13 @@ void S_ServerLoaded(void)
Com_DPrintf("Loading Previous Sound State.\n"); Com_DPrintf("Loading Previous Sound State.\n");
S_StopAllSounds2(qfalse); S_StopAllSounds2(qfalse);
//S_TriggeredMusic_Stop(); S_TriggeredMusic_Stop();
//s_bSoundPaused = qtrue; s_bSoundPaused = qtrue;
//S_ReLoad( &svs.soundSystem ); S_ReLoad(&svs.soundSystem);
//
//if( svs.tm_filename[ 0 ] ) { if (svs.tm_filename[0]) {
// S_TriggeredMusic_SetupHandle( svs.tm_filename, svs.tm_loopcount, svs.tm_offset, 0 ); S_TriggeredMusic_SetupHandle(svs.tm_filename, svs.tm_loopcount, svs.tm_offset, 0);
//} }
} }
/* /*
@ -4022,6 +4035,11 @@ void UI_ServerLoaded(void)
return; return;
} }
if (ui_sCurrentLoadingMenu == "loading_default") {
UI_FinishLoadingScreen_f();
return;
}
server_loading_waiting = qtrue; server_loading_waiting = qtrue;
event = new Event(EV_Widget_Enable); event = new Event(EV_Widget_Enable);
@ -4317,7 +4335,7 @@ public:
void UpdateStats(Event *ev); void UpdateStats(Event *ev);
}; };
Event EV_StatsUpdater_UpdateStats; Event EV_StatsUpdater_UpdateStats("updatestats", EV_DEFAULT, NULL, NULL, "Update the stats on the missionLog");
CLASS_DECLARATION(Listener, StatsUpdater, NULL) { CLASS_DECLARATION(Listener, StatsUpdater, NULL) {
{NULL, NULL} {NULL, NULL}
@ -4354,10 +4372,8 @@ UI_ShowScoreboard_f
void UI_ShowScoreboard_f(const char *pszMenuName) void UI_ShowScoreboard_f(const char *pszMenuName)
{ {
if (pszMenuName) { if (pszMenuName) {
if (scoreboard_menuname.length()) { if (scoreboard_menuname.length() && str::icmp(scoreboard_menuname, pszMenuName) && scoreboard_menu) {
if (str::icmp(scoreboard_menuname, pszMenuName)) { scoreboard_menu->ForceHide();
scoreboard_menu->ForceHide();
}
} }
scoreboard_menuname = pszMenuName; scoreboard_menuname = pszMenuName;
@ -4406,7 +4422,10 @@ void UI_HideScoreboard_f(void)
} }
if (scoreboard_menuname.length()) { if (scoreboard_menuname.length()) {
scoreboard_menu->ForceHide(); // Fixed in 2.30 (scoreboard_menu check)
if (scoreboard_menu) {
scoreboard_menu->ForceHide();
}
} }
} }
@ -4451,7 +4470,7 @@ void ScoreboardListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, boo
{ {
DrawBox(drawRect, backColor, 1.0); DrawBox(drawRect, backColor, 1.0);
pFont->setColor(textColor); pFont->setColor(textColor);
pFont->Print(drawRect.pos.x + 1, drawRect.pos.y, Sys_LV_CL_ConvertString(getListItemString(iColumn)), -1, qfalse); pFont->Print((drawRect.pos.x + 1) / uid.scaleRes[0], drawRect.pos.y / uid.scaleRes[1], Sys_LV_CL_ConvertString(getListItemString(iColumn)), -1, uid.scaleRes);
if (bTitleItem) { if (bTitleItem) {
UIRect2D lineRect; UIRect2D lineRect;
@ -4504,7 +4523,7 @@ void UI_CreateScoreboard(void)
scoreboard_h = h; scoreboard_h = h;
SCR_AdjustFrom640(&x, &y, &w, &h); SCR_AdjustFrom640(&x, &y, &w, &h);
fColumnScale = cls.glconfig.vidWidth / 640.0; fColumnScale = uid.vidWidth / 640.0;
cge->CG_GetScoreBoardColor(&fR, &fG, &fB, &fA); cge->CG_GetScoreBoardColor(&fR, &fG, &fB, &fA);
cge->CG_GetScoreBoardFontColor(&fFontR, &fFontG, &fFontB, &fFontA); cge->CG_GetScoreBoardFontColor(&fFontR, &fFontG, &fFontB, &fFontA);
@ -4728,7 +4747,7 @@ CL_FinishedIntro
*/ */
qboolean CL_FinishedIntro(void) qboolean CL_FinishedIntro(void)
{ {
return !cls.startStage; return cls.startStage == 0;
} }
/* /*
@ -4738,7 +4757,87 @@ CL_FinishedStartStage
*/ */
void CL_FinishedStartStage(void) void CL_FinishedStartStage(void)
{ {
// FIXME: stub int wait;
switch (cls.startStage++) {
case 1:
Cbuf_ExecuteText(EXEC_NOW, "cinematic EAlogo.RoQ\n");
break;
case 2:
intro_stage.alpha_start = 0.0;
intro_stage.alpha_end = 1.0;
wait = ui_titlescreen_fadein->value * 1000.0;
intro_stage.fadetime = wait;
intro_stage.starttime = cls.realtime;
intro_stage.endtime = cls.realtime + wait;
intro_stage.material = uWinMan.RegisterShader("mohaa_title");
break;
case 3:
intro_stage.alpha_start = 1.0;
intro_stage.alpha_end = 1.0;
wait = ui_legalscreen_stay->value * 1000.0;
intro_stage.fadetime = 0.0;
intro_stage.starttime = cls.realtime;
intro_stage.endtime = cls.realtime + wait;
break;
case 4:
intro_stage.alpha_start = 1.0;
intro_stage.alpha_end = 0.0;
wait = ui_titlescreen_fadeout->value * 1000.0;
intro_stage.fadetime = wait;
intro_stage.starttime = cls.realtime;
intro_stage.endtime = cls.realtime + wait;
break;
case 5:
intro_stage.alpha_start = 0.0;
intro_stage.alpha_end = 1.0;
wait = ui_legalscreen_fadein->value * 1000.0;
intro_stage.fadetime = wait;
intro_stage.starttime = cls.realtime;
intro_stage.endtime = cls.realtime + wait;
intro_stage.material = uWinMan.RegisterShader("legal");
break;
case 6:
intro_stage.alpha_start = 1.0;
intro_stage.alpha_end = 1.0;
wait = ui_legalscreen_stay->value * 1000.0;
intro_stage.fadetime = 0.0;
intro_stage.starttime = cls.realtime;
intro_stage.endtime = cls.realtime + wait;
break;
case 7:
intro_stage.alpha_start = 1.0;
intro_stage.alpha_end = 0.0;
wait = ui_legalscreen_fadeout->value * 1000.0;
intro_stage.fadetime = wait;
intro_stage.starttime = cls.realtime;
intro_stage.endtime = cls.realtime + wait;
break;
case 8:
if (com_target_game->integer >= target_game_e::TG_MOHTA) {
cls.startStage = 0;
return;
}
Cbuf_ExecuteText(EXEC_NOW, "cinematic 2015intro.RoQ\n");
break;
case 9:
Cbuf_ExecuteText(EXEC_NOW, "cinematic intro.RoQ\n");
break;
case 10:
cls.startStage = 0;
break;
default:
break;
}
} }
/* /*
@ -4754,9 +4853,6 @@ void UI_StartStageKeyEvent(void)
SCR_StopCinematic(); SCR_StopCinematic();
} }
break; break;
case 12:
SCR_StopCinematic();
break;
case 3: case 3:
case 4: case 4:
case 5: case 5:
@ -4775,11 +4871,9 @@ void UI_StartStageKeyEvent(void)
break; break;
case 9: case 9:
case 10: case 10:
case 11: SCR_StopCinematic();
if (ui_skip_legalscreen->integer) { break;
cls.startStage = 11; default:
CL_FinishedStartStage();
}
break; break;
} }
} }
@ -4807,8 +4901,8 @@ void CL_TryStartIntro(void)
UI_ToggleConsole(); UI_ToggleConsole();
} else { } else {
// FIXME: no intro from now // FIXME: no intro from now
//Cvar_Set( cl_playintro->name, "0" ); Cvar_Set(cl_playintro->name, "0");
//UI_StartIntro_f(); UI_StartIntro_f();
} }
} }
@ -4969,6 +5063,20 @@ void UI_HideStatistics_f()
statsUpdater.CancelEventsOfType(EV_StatsUpdater_UpdateStats); statsUpdater.CancelEventsOfType(EV_StatsUpdater_UpdateStats);
} }
/*
====================
UI_SalesScreen_f
====================
*/
void UI_SalesScreen_f()
{
if (random() > 0.5) {
Cbuf_AddText("pushmenu sales_splash1\n");
} else {
Cbuf_AddText("pushmenu sales_splash2\n");
}
}
/* /*
==================== ====================
CL_ShutdownUI CL_ShutdownUI
@ -5164,7 +5272,7 @@ void CL_InitializeUI(void)
ui_success = Cvar_Get("ui_success", "0", 0); ui_success = Cvar_Get("ui_success", "0", 0);
ui_failed = Cvar_Get("ui_failed", "0", 0); ui_failed = Cvar_Get("ui_failed", "0", 0);
ui_returnmenu = Cvar_Get("ui_returnmenu", "0", 0); ui_returnmenu = Cvar_Get("ui_returnmenu", "0", 0);
ui_skip_eamovie = Cvar_Get("ui_skip_eamovie", "0", 0); ui_skip_eamovie = Cvar_Get("ui_skip_eamovie", "1", 0);
ui_skip_titlescreen = Cvar_Get("ui_skip_titlescreen", "1", 0); ui_skip_titlescreen = Cvar_Get("ui_skip_titlescreen", "1", 0);
ui_skip_legalscreen = Cvar_Get("ui_skip_legalscreen", "1", 0); ui_skip_legalscreen = Cvar_Get("ui_skip_legalscreen", "1", 0);
ui_titlescreen_fadein = Cvar_Get("ui_titlescreen_fadein", "1", 0); ui_titlescreen_fadein = Cvar_Get("ui_titlescreen_fadein", "1", 0);
@ -5239,6 +5347,8 @@ void CL_InitializeUI(void)
Cmd_AddCommand("-statistics", UI_HideStatistics_f); Cmd_AddCommand("-statistics", UI_HideStatistics_f);
Cmd_AddCommand("setreturnmenu", UI_SetReturnMenuToCurrent); Cmd_AddCommand("setreturnmenu", UI_SetReturnMenuToCurrent);
Cmd_AddCommand("gotoreturnmenu", UI_PushReturnMenu_f); Cmd_AddCommand("gotoreturnmenu", UI_PushReturnMenu_f);
Cmd_AddCommand("salesscreen", UI_SalesScreen_f);
Cmd_AddCommand("launchgamespy", UI_LaunchGameSpy_f);
if (developer->integer) { if (developer->integer) {
UColor bgColor; UColor bgColor;
@ -5260,7 +5370,7 @@ void CL_InitializeUI(void)
// Create the 3D view // Create the 3D view
view3d = new View3D; view3d = new View3D;
view3d->setAlwaysOnBottom(true); view3d->setAlwaysOnBottom(true);
view3d->InitFrame(NULL, 0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, -1, "facfont-20"); view3d->InitFrame(NULL, 0, 0, uid.vidWidth, uid.vidHeight, -1, "facfont-20");
view3d->setName("view3d"); view3d->setName("view3d");
view3d->InitSubtitle(); view3d->InitSubtitle();
@ -5360,6 +5470,10 @@ void CL_InitializeUI(void)
CL_ClearButtons(); CL_ClearButtons();
cls.uiStarted = qtrue; cls.uiStarted = qtrue;
if (!com_dedicated->integer) {
CL_TryStartIntro();
}
} }
static char **loadStrings; static char **loadStrings;
@ -5397,7 +5511,16 @@ void UI_BeginLoadResource(void)
UI_EndLoadResource UI_EndLoadResource
==================== ====================
*/ */
void UI_EndLoadResource(void) {} void UI_EndLoadResource(void)
{
clock_t time;
time = clock() - (((clock_t)startCountHigh << 32) | startCountLow) + (((clock_t)loadCountHigh << 32) | loadCountLow);
loadCountHigh = time >> 32;
loadCountLow = time;
loadCount = time >> 25;
}
/* /*
==================== ====================
@ -5443,7 +5566,7 @@ qboolean UI_IsResourceLoaded(const char *name)
case 107: case 107:
return S_IsSoundRegistered(name + 1); return S_IsSoundRegistered(name + 1);
case 110: case 110:
return R_ImageExists(name + 1); return uii.Rend_ImageExists(name + 1);
default: default:
return qfalse; return qfalse;
} }
@ -5463,19 +5586,17 @@ void UI_RegisterLoadResource(const char *name)
high = loadNumber - 1; high = loadNumber - 1;
while (low <= high) { while (low <= high) {
i = (high + low) / 2; i = (low + high) / 2;
j = strcmp(name, loadStrings[i]); j = strcmp(name, loadStrings[i]);
if (j >= 0) { if (j < 0) {
if (j <= 0) { high = i - 1;
currentLoadTime += loadTimes[i]; } else if (j > 0) {
loadTimes[i] = 0;
return;
}
low = i + 1; low = i + 1;
} else { } else {
high = i - 1; currentLoadTime += loadTimes[i];
loadTimes[i] = 0;
break;
} }
} }
} }
@ -5488,12 +5609,19 @@ UI_TestUpdateScreen
void UI_TestUpdateScreen(unsigned int timeout) void UI_TestUpdateScreen(unsigned int timeout)
{ {
unsigned int newTime = Sys_Milliseconds(); unsigned int newTime = Sys_Milliseconds();
unsigned int startRenderTime, endRenderTime;
if (newTime - lastTime >= timeout) { if (timeout > 0 && (newTime - lastTime) < (timeout + updateTime)) {
lastTime = newTime; return;
Sys_PumpMessageLoop();
SCR_UpdateScreen();
} }
startRenderTime = Sys_Milliseconds();
Sys_PumpMessageLoop();
SCR_UpdateScreen();
endRenderTime = Sys_Milliseconds();
updateTime = Q_min(endRenderTime - startRenderTime, 1000);
lastTime = endRenderTime;
} }
/* /*
@ -5531,7 +5659,7 @@ void UI_LoadResource(const char *name)
Cvar_SetValue("loadingbar", (float)currentLoadTime / (float)totalLoadTime); Cvar_SetValue("loadingbar", (float)currentLoadTime / (float)totalLoadTime);
} }
UI_TestUpdateScreen(333u); UI_TestUpdateScreen(33);
} }
/* /*
@ -5699,8 +5827,15 @@ void UI_BeginLoad(const char *pszMapName)
loadName = "maps/"; loadName = "maps/";
loadName += pszMapName; loadName += pszMapName;
mapfile = loadName;
loadName += ".min"; loadName += ".min";
mapfile = loadName + ".bsp";
if (CL_UseLargeLightmap(pszMapName)) {
mapfile += ".bsp";
} else {
// Added in 2.0
mapfile += "_sml.bsp";
}
if (UI_ArchiveLoadMapinfo(mapfile)) { if (UI_ArchiveLoadMapinfo(mapfile)) {
cls.loading = SS_LOADING2; cls.loading = SS_LOADING2;
@ -5807,12 +5942,12 @@ void UI_EndLoad(void)
} }
file = FS_FOpenFileWrite(loadName); file = FS_FOpenFileWrite(loadName);
sprintf(buf, "%d\n%d %d\n", 3, loadNumber, size); Com_sprintf(buf, sizeof(buf), "%d\n%d %d\n", 3, loadNumber, size);
FS_Write(buf, strlen(buf), file); FS_Write(buf, strlen(buf), file);
for (i = 0; i < loadNumber; i++) { for (i = 0; i < loadNumber; i++) {
sprintf(buf, "%s\n%d\n", base[i]->name, base[i]->loadCount); Com_sprintf(buf, sizeof(buf), "%s\n%d\n", base[i]->name, base[i]->loadCount);
FS_Write(buf, strlen(buf), file); FS_Write(buf, strlen(buf), file);
} }

View file

@ -1,6 +1,6 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2023 the OpenMoHAA team Copyright (C) 2023-2024 the OpenMoHAA team
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -35,6 +35,7 @@ typedef struct {
extern cvar_t *ui_health_start; extern cvar_t *ui_health_start;
extern cvar_t *ui_health_end; extern cvar_t *ui_health_end;
extern cvar_t *sound_overlay; extern cvar_t *sound_overlay;
extern cvar_t *cl_movieaudio;
// //
// initialization // initialization
@ -46,14 +47,20 @@ void CL_ShutdownUI(void);
// //
// general ui stuff // general ui stuff
// //
extern inventory_t client_inv; extern inventory_t client_inv;
extern bind_t client_bind; extern bind_t client_bind;
extern cvar_t *cl_greenfps; extern cvar_t *cl_greenfps;
extern qboolean server_loading;
extern const UColor UWhiteChatMessageColor;
extern const UColor URedChatMessageColor;
extern const UColor UGreenChatMessageColor;
const char *CvarGetForUI(const char *name, const char *defval); const char *CvarGetForUI(const char *name, const char *defval);
void UI_ClearState(void); void UI_ClearState(void);
void CL_BeginRegistration(void); void CL_BeginRegistration(void);
void CL_EndRegistration(void); void CL_EndRegistration(void);
float UI_GetObjectivesTop(void);
void UI_GetHighResolutionScale(vec2_t scale);
// //
// menu // menu
@ -110,6 +117,7 @@ void UI_DeleteScoreBoardItems(int iMaxIndex);
void UI_BeginLoad(const char *pszMapName); void UI_BeginLoad(const char *pszMapName);
void UI_EndLoad(void); void UI_EndLoad(void);
void UI_AbortLoad(void); void UI_AbortLoad(void);
int CL_FontStringWidth(fontheader_t* pFont, const char* pszString, int iMaxLen);
void UI_BeginLoadResource(void); void UI_BeginLoadResource(void);
void UI_EndLoadResource(void); void UI_EndLoadResource(void);
void UI_EndLoadResource(const char *name); void UI_EndLoadResource(const char *name);

View file

@ -1,6 +1,6 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2015 the OpenMoHAA team Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "cl_ui.h" #include "cl_ui.h"
#include "../qcommon/localization.h"
Event EV_DMBox_Goin Event EV_DMBox_Goin
( (
@ -40,126 +41,116 @@ Event EV_DMBox_Decay
"Event to make the dmbox console line decay" "Event to make the dmbox console line decay"
); );
static float s_dmboxWidth = 384.0; static float s_dmboxWidth = 384.0;
static float s_dmboxOffsetX = 3.0f; static float s_dmboxOffsetX = 3.0f;
static float s_dmboxOffsetY = 8.0f; static float s_dmboxOffsetY = 8.0f;
CLASS_DECLARATION( UIWidget, UIDMBox, NULL ) CLASS_DECLARATION(UIWidget, UIDMBox, NULL) {
{ {&W_SizeChanged, &UIDMBox::OnSizeChanged},
{ &W_SizeChanged, &UIDMBox::OnSizeChanged }, {&EV_DMBox_Goin, &UIDMBox::MoveInEvent },
{ &EV_DMBox_Goin, &UIDMBox::MoveInEvent }, {&EV_DMBox_Decay, &UIDMBox::DecayEvent },
{ &EV_DMBox_Decay, &UIDMBox::DecayEvent }, {NULL, NULL }
{ NULL, NULL }
}; };
UIDMBox::UIDMBox() UIDMBox::UIDMBox()
{ {
m_numitems = 0; m_numitems = 0;
m_reallyshown = true; m_reallyshown = true;
m_fontbold = NULL; m_fontbold = NULL;
m_boxstate = boxstate_t::box_out; m_boxstate = boxstate_t::box_out;
m_iBeginDecay = 0; m_iBeginDecay = 0;
m_boxtime = uid.time; m_boxtime = uid.time;
m_movespeed = 500; m_movespeed = 500;
m_drawoutline = com_target_game->integer >= target_game_e::TG_MOHTA;
} }
void UIDMBox::VerifyBoxOut( void ) void UIDMBox::VerifyBoxOut(void)
{ {
PostMoveinEvent(); PostMoveinEvent();
if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_out) if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_out) {
{ ChangeBoxState(boxstate_t::box_moving_out);
ChangeBoxState(boxstate_t::box_moving_out); }
}
} }
void UIDMBox::ChangeBoxState( boxstate_t state ) void UIDMBox::ChangeBoxState(boxstate_t state)
{ {
m_boxstate = state; m_boxstate = state;
m_boxtime = uid.time; m_boxtime = uid.time;
setShowState(); setShowState();
if (state == box_out) { if (state == box_out) {
PostMoveinEvent(); PostMoveinEvent();
} }
} }
void UIDMBox::HandleBoxMoving( void ) void UIDMBox::HandleBoxMoving(void)
{ {
int delta; int delta;
UIRect2D newRect; UIRect2D newRect;
if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_moving_in) { if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_moving_in) {
return; return;
} }
delta = m_movespeed * (uid.time - m_boxtime) / 1000; delta = m_movespeed * (uid.time - m_boxtime) / 1000;
m_boxtime = 1000 * delta / m_movespeed + m_boxtime; m_boxtime = 1000 * delta / m_movespeed + m_boxtime;
if (m_boxstate == boxstate_t::box_moving_out) if (m_boxstate == boxstate_t::box_moving_out) {
{ newRect.size.width = m_frame.size.width;
newRect.size.width = m_frame.size.width; newRect.size.height = m_frame.size.height;
newRect.size.height = m_frame.size.height; newRect.pos.x = m_frame.pos.x;
newRect.pos.x = m_frame.pos.x; newRect.pos.y = delta + m_frame.pos.y;
newRect.pos.y = delta + m_frame.pos.y;
if (newRect.pos.y <= 0.0) if (newRect.pos.y <= 0.0) {
{ newRect.pos.y = 0.0;
newRect.pos.y = 0.0; ChangeBoxState(boxstate_t::box_out);
ChangeBoxState(boxstate_t::box_out); }
} } else if (m_boxstate == boxstate_t::box_moving_in) {
} newRect.size.width = m_frame.size.width;
else if (m_boxstate == boxstate_t::box_moving_in) newRect.size.height = m_frame.size.height;
{ newRect.pos.x = m_frame.pos.x;
newRect.size.width = m_frame.size.width; newRect.pos.y = delta - m_frame.pos.y;
newRect.size.height = m_frame.size.height;
newRect.pos.x = m_frame.pos.x;
newRect.pos.y = delta - m_frame.pos.y;
if (newRect.pos.y <= -newRect.size.height) if (newRect.pos.y <= -newRect.size.height) {
{ newRect.pos.y = -newRect.size.height;
newRect.pos.y = -newRect.size.height; ChangeBoxState(boxstate_t::box_in);
ChangeBoxState(boxstate_t::box_in); }
} } else {
} newRect = m_frame;
else { }
newRect = m_frame;
}
setFrame(newRect); setFrame(newRect);
} }
void UIDMBox::PostMoveinEvent( void ) void UIDMBox::PostMoveinEvent(void)
{ {
if (m_boxstate != boxstate_t::box_out) { if (m_boxstate != boxstate_t::box_out) {
return; return;
} }
if (!EventPending(EV_DMBox_Goin)) { if (!EventPending(EV_DMBox_Goin)) {
PostEvent(EV_DMBox_Goin, 10.0); PostEvent(EV_DMBox_Goin, 10.0);
} } else {
else { PostponeEvent(EV_DMBox_Goin, 10.0);
PostponeEvent(EV_DMBox_Goin, 10.0); }
}
} }
void UIDMBox::PostDecayEvent( void ) void UIDMBox::PostDecayEvent(void)
{ {
if (!EventPending(EV_DMBox_Decay)) if (!EventPending(EV_DMBox_Decay)) {
{ float fDelayTime;
float fDelayTime; int iNumLines;
int iNumLines; int i;
int i; const char *pszString = m_items[0].string.c_str();
const char* pszString = m_items[0].string.c_str();
// //
// Calculate the number of lines // Calculate the number of lines
// //
iNumLines = 1; iNumLines = 1;
for (i = 0; pszString[i]; i++) for (i = 0; pszString[i]; i++) {
{ if (pszString[i] == '\n') {
if (pszString[i] == '\n') { iNumLines++;
iNumLines++; }
} }
}
if (m_items[0].flags & DMBOX_ITEM_FLAG_BOLD) { if (m_items[0].flags & DMBOX_ITEM_FLAG_BOLD) {
fDelayTime = iNumLines * 8.0; fDelayTime = iNumLines * 8.0;
@ -167,265 +158,268 @@ void UIDMBox::PostDecayEvent( void )
// //
// Bold as twice more decay // Bold as twice more decay
// //
else if (m_items[0].flags & DMBOX_ITEM_FLAG_DEATH) { else if (m_items[0].flags & DMBOX_ITEM_FLAG_DEATH) {
fDelayTime = iNumLines * 6.0; fDelayTime = iNumLines * 6.0;
} } else {
else { fDelayTime = iNumLines * 5.0;
fDelayTime = iNumLines * 5.0; }
}
m_iBeginDecay = cls.realtime; m_iBeginDecay = cls.realtime;
m_iEndDecay = (int)(fDelayTime * 1000.0); m_iEndDecay = (int)(fDelayTime * 1000.0);
PostEvent(EV_DMBox_Decay, fDelayTime); PostEvent(EV_DMBox_Decay, fDelayTime);
} }
} }
void UIDMBox::setShowState( void ) void UIDMBox::setShowState(void)
{ {
if (m_reallyshown) { if (m_reallyshown) {
setShow(m_boxstate != box_in); setShow(m_boxstate != box_in);
} else { } else {
setShow(false); setShow(false);
} }
} }
void UIDMBox::RemoveTopItem( void ) void UIDMBox::RemoveTopItem(void)
{ {
int i; int i;
if (m_numitems > 0) { if (m_numitems > 0) {
for (i = 0; i < m_numitems - 1; i++) { for (i = 0; i < m_numitems - 1; i++) {
m_items[i] = m_items[i + 1]; m_items[i] = m_items[i + 1];
} }
m_numitems--; m_numitems--;
} }
} }
str UIDMBox::CalculateBreaks( UIFont *font, str text, float max_width ) str UIDMBox::CalculateBreaks(UIFont *font, str text, float max_width)
{ {
str newText, sTmp; str newText;
int i; float fX;
float fX; float fwX;
float fwX, fsX; const char *current;
int count;
Cmd_TokenizeString(text.c_str()); current = text;
if (Cmd_Argc()) fX = 0.0;
{
fX = 0.0;
fsX = font->getCharWidth(' ');
for (i = 0; i < Cmd_Argc(); i++) for (count = font->DBCSGetWordBlockCount(current, -1); count;
{ current += count, count = font->DBCSGetWordBlockCount(current, -1)) {
sTmp = Cmd_Argv(i); fwX = font->getWidth(current, count);
fwX = font->getWidth(sTmp.c_str(), -1); if (fX + fwX > max_width) {
if (fwX + i <= max_width) newText += "\n" + str(current, 0, count);
{ fX = 0;
if (fwX + i + fX <= max_width) } else {
{ newText += str(current, 0, count);
newText += sTmp + " "; }
} else {
newText += "\n" + sTmp + " ";
}
}
else
{
sTmp += "\n";
fX = 0.0;
}
}
} else {
newText = "";
}
return newText; fX += fwX;
}
return newText;
} }
float UIDMBox::PrintWrap( UIFont *font, float x, float y, str text ) float UIDMBox::PrintWrap(UIFont *font, float x, float y, str text)
{ {
const char* p1, * p2; const char *p1, *p2;
size_t n, l; size_t n, l;
float fY; float fY;
fY = y; fY = y;
p1 = text.c_str(); p1 = text.c_str();
l = text.length(); l = text.length();
for (;;) for (;;) {
{ p2 = strchr(p1, '\n');
p2 = strchr(p1, '\n'); if (!p2) {
if (!p2) { break;
break; }
}
n = p2 - p1; n = p2 - p1;
if (n >= l) { if (n >= l) {
break; break;
} }
font->Print(x, fY, p1, p2 - p1, qfalse); font->Print(x, fY, p1, p2 - p1, getHighResScale());
p1 = p2 + 1; p1 = p2 + 1;
l -= n; l -= n;
fY += font->getHeight(qfalse); fY += font->getHeight();
} }
font->Print(x, fY, p1, l, qfalse); if (*p1) {
font->Print(x, fY, p1, l, getHighResScale());
fY += font->getHeight();
}
return font->getHeight(qfalse) + (fY - y); return fY - y;
} }
float UIDMBox::DrawItem( item_t *in, float x, float y, float alpha ) float UIDMBox::DrawItem(item_t *in, float x, float y, float alpha)
{ {
in->font->setColor(in->color); if (m_drawoutline) {
in->font->setAlpha(alpha); //
// Draw an outline
//
return PrintWrap(in->font, x, y, in->string); in->font->setColor(UBlack);
in->font->setAlpha(alpha);
PrintWrap(in->font, x + 1, y + 2, in->string);
PrintWrap(in->font, x + 2, y + 1, in->string);
PrintWrap(in->font, x - 1, y + 2, in->string);
PrintWrap(in->font, x - 2, y + 1, in->string);
PrintWrap(in->font, x - 1, y - 2, in->string);
PrintWrap(in->font, x - 2, y - 1, in->string);
PrintWrap(in->font, x + 1, y - 2, in->string);
PrintWrap(in->font, x + 2, y - 1, in->string);
PrintWrap(in->font, x + 2, y, in->string);
PrintWrap(in->font, x - 2, y, in->string);
PrintWrap(in->font, x, y + 2, in->string);
PrintWrap(in->font, x, y - 2, in->string);
}
in->font->setColor(in->color);
in->font->setAlpha(alpha);
return PrintWrap(in->font, x, y, in->string);
} }
void UIDMBox::Print( const char *text ) void UIDMBox::Print(const char *text)
{ {
const char* text1 = text; const char *text1 = text;
if (m_numitems > 5) if (m_numitems > 5) {
{ //
// // Overwrite an item
// Overwrite an item //
// RemoveTopItem();
RemoveTopItem(); }
}
m_items[m_numitems].flags = 0; m_items[m_numitems].flags = 0;
if (*text == MESSAGE_CHAT_WHITE) if (*text == MESSAGE_CHAT_WHITE) {
{ m_items[m_numitems].color = UWhiteChatMessageColor;
m_items[m_numitems].color = UGrey; m_items[m_numitems].font = m_fontbold;
m_items[m_numitems].font = m_fontbold; m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_BOLD;
m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_BOLD;
text1 = text + 1; text1 = text + 1;
} } else if (*text == MESSAGE_CHAT_RED) {
else if (*text == MESSAGE_CHAT_RED) m_items[m_numitems].color = URedChatMessageColor;
{ m_items[m_numitems].font = m_fontbold;
m_items[m_numitems].color = ULightRed; m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_DEATH;
m_items[m_numitems].font = m_fontbold;
m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_DEATH;
text1 = text + 1; text1 = text + 1;
} } else if (*text == MESSAGE_CHAT_GREEN) {
else if (*text == MESSAGE_CHAT_GREEN) m_items[m_numitems].color = UGreenChatMessageColor;
{
m_items[m_numitems].color = UGreen;
m_items[m_numitems].font = m_fontbold; m_items[m_numitems].font = m_fontbold;
m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_DEATH; m_items[m_numitems].flags |= DMBOX_ITEM_FLAG_DEATH;
text1 = text + 1; text1 = text + 1;
} } else {
else m_items[m_numitems].color = m_foreground_color;
{ m_items[m_numitems].font = m_font;
m_items[m_numitems].color = m_foreground_color; }
m_items[m_numitems].font = m_font;
}
m_items[m_numitems].string = CalculateBreaks(m_items[m_numitems].font, text1, s_dmboxWidth); m_items[m_numitems].string = CalculateBreaks(m_items[m_numitems].font, Sys_LV_CL_ConvertString(text1), s_dmboxWidth);
m_numitems++; m_numitems++;
VerifyBoxOut(); VerifyBoxOut();
PostDecayEvent(); PostDecayEvent();
} }
void UIDMBox::OnSizeChanged( Event *ev ) void UIDMBox::OnSizeChanged(Event *ev)
{ {
s_dmboxWidth = m_frame.size.width; s_dmboxWidth = m_frame.size.width;
} }
void UIDMBox::Create( const UIRect2D& rect, const UColor& fore, const UColor& back, float alpha ) void UIDMBox::Create(const UIRect2D& rect, const UColor& fore, const UColor& back, float alpha)
{ {
InitFrame(NULL, rect, 0, "facfont-20"); InitFrame(NULL, rect, 0, "facfont-20");
if (!m_fontbold) { if (!m_fontbold) {
m_fontbold = new UIFont("facfont-20"); m_fontbold = new UIFont("facfont-20");
} }
m_fontbold->setColor(URed); m_fontbold->setColor(URed);
setBackgroundColor(back, true); setBackgroundColor(back, true);
setForegroundColor(fore); setForegroundColor(fore);
setBackgroundAlpha(alpha); setBackgroundAlpha(alpha);
Connect(this, W_SizeChanged, W_SizeChanged); Connect(this, W_SizeChanged, W_SizeChanged);
OnSizeChanged(NULL); OnSizeChanged(NULL);
m_movespeed = rect.size.height * 3.0; m_movespeed = rect.size.height * 3.0;
setShowState(); setShowState();
} }
void UIDMBox::MoveInEvent( Event *ev ) void UIDMBox::MoveInEvent(Event *ev) {}
void UIDMBox::DecayEvent(Event *ev)
{ {
RemoveTopItem();
if (m_numitems) {
PostDecayEvent();
}
} }
void UIDMBox::DecayEvent( Event *ev ) void UIDMBox::Draw(void)
{ {
RemoveTopItem(); float fsY;
if (m_numitems) { int i;
PostDecayEvent(); float alpha;
} float alphaScale;
alphaScale = 0.8f;
HandleBoxMoving();
if (!m_numitems) {
//
// Nothing to show
//
return;
}
m_font->setColor(m_foreground_color);
alpha = (float)(cls.realtime - m_iBeginDecay) / (float)m_iEndDecay;
if (alpha > 1.0) {
alpha = 1.0;
}
alpha = (1.0 - alpha) * 4.0;
if (alpha > 1.0) {
alpha = 1.0;
}
if (cge) {
alphaScale = 1.0 - cge->CG_GetObjectiveAlpha();
}
fsY = DrawItem(m_items, s_dmboxOffsetX, s_dmboxOffsetY, alpha * alphaScale);
fsY = alpha <= 0.2 ? s_dmboxOffsetY : fsY + s_dmboxOffsetY;
for (i = 1; i < m_numitems; i++) {
fsY += DrawItem(&m_items[i], s_dmboxOffsetX, fsY, alphaScale);
if (fsY > m_frame.size.height) {
if (EventPending(EV_DMBox_Decay)) {
CancelEventsOfType(EV_DMBox_Decay);
}
PostEvent(EV_DMBox_Decay, 0.0);
break;
}
}
} }
void UIDMBox::Draw( void ) void UIDMBox::setRealShow(bool b)
{ {
float fsY; this->m_reallyshown = b;
int i; setShowState();
float alpha;
float alphaScale;
alphaScale = 0.8f;
HandleBoxMoving();
if (!m_numitems) {
//
// Nothing to show
//
return;
}
m_font->setColor(m_foreground_color);
alpha = (float)(cls.realtime - m_iBeginDecay) / (float)m_iEndDecay;
if (alpha > 1.0) alpha = 1.0;
alpha = (1.0 - alpha) * 4.0;
if (alpha > 1.0) alpha = 1.0;
if (cge) {
alphaScale = 1.0 - cge->CG_GetObjectiveAlpha();
}
fsY = DrawItem(m_items, s_dmboxOffsetX, s_dmboxOffsetY, alpha * alphaScale);
fsY = alpha <= 0.2 ? s_dmboxOffsetY : fsY + s_dmboxOffsetY;
for (i = 1; i < m_numitems; i++)
{
fsY += DrawItem(&m_items[i], s_dmboxOffsetX, fsY, alphaScale);
if (fsY > m_frame.size.height)
{
if (EventPending(EV_DMBox_Decay)) {
CancelEventsOfType(EV_DMBox_Decay);
}
PostEvent(EV_DMBox_Decay, 0.0);
break;
}
}
} }
void UIDMBox::setRealShow( bool b ) void UIDMBox::Clear(void)
{ {
this->m_reallyshown = b; m_numitems = 0;
setShowState();
}
void UIDMBox::Clear( void )
{
m_numitems = 0;
} }

View file

@ -1,6 +1,6 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2015 the OpenMoHAA team Copyright (C) 2015-2024 the OpenMoHAA team
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -20,8 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=========================================================================== ===========================================================================
*/ */
#ifndef __CL_UIDMBOX_H__ #pragma once
#define __CL_UIDMBOX_H__
static constexpr unsigned int DMBOX_ITEM_FLAG_BOLD = 2u; static constexpr unsigned int DMBOX_ITEM_FLAG_BOLD = 2u;
static constexpr unsigned int DMBOX_ITEM_FLAG_DEATH = 4u; static constexpr unsigned int DMBOX_ITEM_FLAG_DEATH = 4u;
@ -47,6 +46,8 @@ protected:
int m_movespeed; int m_movespeed;
int m_iBeginDecay; int m_iBeginDecay;
int m_iEndDecay; int m_iEndDecay;
// Added in OPM
bool m_drawoutline;
public: public:
CLASS_PROTOTYPE( UIDMBox ); CLASS_PROTOTYPE( UIDMBox );
@ -75,5 +76,3 @@ public:
void setRealShow( bool b ); void setRealShow( bool b );
void Clear( void ); void Clear( void );
}; };
#endif /* __CL_UIDMBOX_H__ */

View file

@ -47,7 +47,7 @@ FilePickerClass::FilePickerClass()
window = new UIFloatingWindow(); window = new UIFloatingWindow();
window->Create( window->Create(
NULL, NULL,
UIRect2D((cls.glconfig.vidWidth - 400) / 2, (cls.glconfig.vidHeight - 300) / 2, 400, 300), UIRect2D((uid.vidWidth - 400) / 2, (uid.vidHeight - 300) / 2, 400, 300),
"File Picker", "File Picker",
UColor(0.15f, 0.195f, 0.278f), UColor(0.15f, 0.195f, 0.278f),
UHudColor UHudColor
@ -104,8 +104,10 @@ void FilePickerClass::Initialize(
currentDirectory += "/"; currentDirectory += "/";
} }
extension = ext; extension = ext;
ignoredFiles = ignore_files; if (ignore_files) {
ignoredFiles = ignore_files;
}
SetupFiles(); SetupFiles();
} }

View file

@ -0,0 +1,118 @@
/*
===========================================================================
Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// cl_uigamespy.cpp
#include "cl_uigamespy.h"
CLASS_DECLARATION(UIFloatingWindow, GameSpyDialog, NULL) {
{&W_Deactivated, &UIFloatingWindow::ClosePressed},
{NULL, NULL }
};
GameSpyDialog::GameSpyDialog()
: overlay(NULL)
, label(NULL)
, closeButton(NULL)
{
AddFlag(WF_ALWAYS_TOP);
}
GameSpyDialog::~GameSpyDialog()
{
if (overlay) {
delete overlay;
overlay = NULL;
}
if (label) {
delete label;
label = NULL;
}
if (closeButton) {
delete closeButton;
closeButton = NULL;
}
}
void GameSpyDialog::FrameInitialized(void)
{
UIFloatingWindow::FrameInitialized();
label = new UILabel();
label->InitFrame(getChildSpace(), getChildSpace()->getClientFrame(), 0);
label->setTitle(
"GameSpy's multiplayer matchmaking\n"
"and server browsing services, which were\n"
"essential for online gaming in many classic\n"
"titles including Medal of Honor: Allied Assault,\n"
"were permanently shut down in 2014."
);
label->setForegroundColor(UHudColor);
closeButton = new UIButton();
closeButton->InitFrame(getChildSpace(), UIRect2D(100, 150, 100, 30), 0);
closeButton->setTitle("Close");
closeButton->AllowActivate(true);
closeButton->Connect(this, W_Button_Pressed, W_Deactivated);
overlay = new UIButton();
overlay->InitFrame(NULL, UIRect2D(0, 0, uid.vidWidth, uid.vidHeight), 0);
overlay->setBackgroundColor(UColor(0, 0, 0, 0.5f), true);
overlay->AllowActivate(true);
overlay->Connect(this, W_Button_Pressed, W_Deactivated);
}
void GameSpyDialog::Create(
UIWidget *parent, const UIRect2D& rect, const char *title, const UColor& bgColor, const UColor& fgColor
)
{
// First call parent's Create
UIFloatingWindow::Create(parent, rect, title, bgColor, fgColor);
// After creation, find minimize button by name and hide it
for (UIWidget *child = getFirstChild(); child; child = getNextChild(child)) {
if (strcmp(child->getName(), "minimizebutton") == 0) {
child->setShow(false);
break;
}
}
}
void UI_LaunchGameSpy_f(void)
{
GameSpyDialog *dialog = new GameSpyDialog();
dialog->Create(
NULL,
UIRect2D((uid.vidWidth - 300) / 2, (uid.vidHeight - 200) / 2, 300, 200),
"GameSpy",
UColor(0.15f, 0.195f, 0.278f),
UHudColor
);
uWinMan.ActivateControl(dialog);
dialog->Connect(dialog, W_Deactivated, W_Deactivated);
}

View file

@ -0,0 +1,50 @@
/*
===========================================================================
Copyright (C) 2025 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// cl_gamespy.h
#ifndef __CL_GAMESPY_H__
#define __CL_GAMESPY_H__
#include "cl_ui.h"
#include "keycodes.h"
class GameSpyDialog : public UIFloatingWindow
{
private:
UIButton *overlay;
UILabel *label;
UIButton *closeButton;
protected:
void FrameInitialized(void) override;
public:
GameSpyDialog();
~GameSpyDialog();
void
Create(UIWidget *parent, const UIRect2D& rect, const char *title, const UColor& bgColor, const UColor& fgColor);
CLASS_PROTOTYPE(GameSpyDialog);
};
void UI_LaunchGameSpy_f(void);
#endif

View file

@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "cl_ui.h" #include "cl_ui.h"
#include "../qcommon/localization.h"
Event EV_GMBox_Goin Event EV_GMBox_Goin
( (
@ -40,371 +41,370 @@ Event EV_GMBox_Decay
"Event to make the gmbox console line decay" "Event to make the gmbox console line decay"
); );
static float s_gmboxWidth = 640.0; static float s_gmboxWidth = 640.0;
static float s_gmboxOffsetX = 3.0f; static float s_gmboxOffsetX = 3.0f;
static float s_gmboxOffsetY = 0.0f; static float s_gmboxOffsetY = 0.0f;
CLASS_DECLARATION( UIWidget, UIGMBox, NULL ) CLASS_DECLARATION(UIWidget, UIGMBox, NULL) {
{ {&W_SizeChanged, &UIGMBox::OnSizeChanged},
{ &W_SizeChanged, &UIGMBox::OnSizeChanged }, {&EV_GMBox_Goin, &UIGMBox::MoveInEvent },
{ &EV_GMBox_Goin, &UIGMBox::MoveInEvent }, {&EV_GMBox_Decay, &UIGMBox::DecayEvent },
{ &EV_GMBox_Decay, &UIGMBox::DecayEvent }, {NULL, NULL }
{ NULL, NULL }
}; };
UIGMBox::UIGMBox() UIGMBox::UIGMBox()
{ {
m_numitems = 0; m_numitems = 0;
m_reallyshown = true; m_reallyshown = true;
m_fontbold = NULL; m_fontbold = NULL;
m_boxstate = boxstate_t::box_out; m_boxstate = boxstate_t::box_out;
m_iBeginDecay = 0; m_iBeginDecay = 0;
m_boxtime = uid.time; m_boxtime = uid.time;
m_movespeed = 500; m_movespeed = 500;
m_drawoutline = com_target_game->integer >= target_game_e::TG_MOHTA;
} }
void UIGMBox::VerifyBoxOut( void ) void UIGMBox::VerifyBoxOut(void)
{ {
PostMoveinEvent(); PostMoveinEvent();
if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_out) if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_out) {
{ ChangeBoxState(boxstate_t::box_moving_out);
ChangeBoxState(boxstate_t::box_moving_out); }
}
} }
void UIGMBox::ChangeBoxState( boxstate_t state ) void UIGMBox::ChangeBoxState(boxstate_t state)
{ {
m_boxstate = state; m_boxstate = state;
m_boxtime = uid.time; m_boxtime = uid.time;
setShowState(); setShowState();
if (state == box_out) { if (state == box_out) {
PostMoveinEvent(); PostMoveinEvent();
} }
} }
void UIGMBox::HandleBoxMoving( void ) void UIGMBox::HandleBoxMoving(void)
{ {
int delta; int delta;
UIRect2D newRect; UIRect2D newRect;
if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_moving_in) { if (m_boxstate != boxstate_t::box_moving_out && m_boxstate != boxstate_t::box_moving_in) {
return; return;
} }
delta = m_movespeed * (uid.time - m_boxtime) / 1000; delta = m_movespeed * (uid.time - m_boxtime) / 1000;
m_boxtime = 1000 * delta / m_movespeed + m_boxtime; m_boxtime = 1000 * delta / m_movespeed + m_boxtime;
if (m_boxstate == boxstate_t::box_moving_out) if (m_boxstate == boxstate_t::box_moving_out) {
{ newRect.size.width = m_frame.size.width;
newRect.size.width = m_frame.size.width; newRect.size.height = m_frame.size.height;
newRect.size.height = m_frame.size.height; newRect.pos.x = m_frame.pos.x;
newRect.pos.x = m_frame.pos.x; newRect.pos.y = delta + m_frame.pos.y;
newRect.pos.y = delta + m_frame.pos.y;
if (newRect.pos.y <= 0.0) if (newRect.pos.y <= 0.0) {
{ newRect.pos.y = 0.0;
newRect.pos.y = 0.0; ChangeBoxState(boxstate_t::box_out);
ChangeBoxState(boxstate_t::box_out); }
} } else if (m_boxstate == boxstate_t::box_moving_in) {
} newRect.size.width = m_frame.size.width;
else if (m_boxstate == boxstate_t::box_moving_in) newRect.size.height = m_frame.size.height;
{ newRect.pos.x = m_frame.pos.x;
newRect.size.width = m_frame.size.width; newRect.pos.y = delta - m_frame.pos.y;
newRect.size.height = m_frame.size.height;
newRect.pos.x = m_frame.pos.x;
newRect.pos.y = delta - m_frame.pos.y;
if (newRect.pos.y <= -newRect.size.height) if (newRect.pos.y <= -newRect.size.height) {
{ newRect.pos.y = -newRect.size.height;
newRect.pos.y = -newRect.size.height; ChangeBoxState(boxstate_t::box_in);
ChangeBoxState(boxstate_t::box_in); }
} } else {
} else { newRect = m_frame;
newRect = m_frame; }
}
setFrame(newRect); setFrame(newRect);
} }
void UIGMBox::PostMoveinEvent( void ) void UIGMBox::PostMoveinEvent(void)
{ {
if (m_boxstate != boxstate_t::box_out) { if (m_boxstate != boxstate_t::box_out) {
return; return;
} }
if (!EventPending(EV_GMBox_Goin)) { if (!EventPending(EV_GMBox_Goin)) {
PostEvent(EV_GMBox_Goin, 10.0); PostEvent(EV_GMBox_Goin, 10.0);
} else { } else {
PostponeEvent(EV_GMBox_Goin, 10.0); PostponeEvent(EV_GMBox_Goin, 10.0);
} }
} }
void UIGMBox::PostDecayEvent( void ) void UIGMBox::PostDecayEvent(void)
{ {
if (!EventPending(EV_GMBox_Decay)) if (!EventPending(EV_GMBox_Decay)) {
{ float fDelayTime;
float fDelayTime; int iNumLines;
int iNumLines; int i;
int i; const char *pszString = m_items[0].string.c_str();
const char* pszString = m_items[0].string.c_str();
// //
// Calculate the number of lines // Calculate the number of lines
// //
iNumLines = 1; iNumLines = 1;
for (i = 0; pszString[i]; i++) for (i = 0; pszString[i]; i++) {
{ if (pszString[i] == '\n') {
if (pszString[i] == '\n') { iNumLines++;
iNumLines++; }
} }
}
// //
// Bold as twice more decay // Bold as twice more decay
// //
if (m_items[0].flags & GMBOX_ITEM_FLAG_BOLD) { if (m_items[0].flags & GMBOX_ITEM_FLAG_BOLD) {
fDelayTime = iNumLines * 10.0; fDelayTime = iNumLines * 10.0;
} else { } else {
fDelayTime = iNumLines * 5.0; fDelayTime = iNumLines * 5.0;
} }
m_iBeginDecay = cls.realtime; m_iBeginDecay = cls.realtime;
m_iEndDecay = (int)(fDelayTime * 1000.0); m_iEndDecay = (int)(fDelayTime * 1000.0);
PostEvent(EV_GMBox_Decay, fDelayTime); PostEvent(EV_GMBox_Decay, fDelayTime);
} }
} }
void UIGMBox::setShowState( void ) void UIGMBox::setShowState(void)
{ {
if (m_reallyshown) { if (m_reallyshown) {
setShow(m_boxstate != box_in); setShow(m_boxstate != box_in);
} else { } else {
setShow(false); setShow(false);
} }
} }
void UIGMBox::RemoveTopItem( void ) void UIGMBox::RemoveTopItem(void)
{ {
int i; int i;
if (m_numitems > 0) { if (m_numitems > 0) {
for (i = 0; i < m_numitems - 1; i++) { for (i = 0; i < m_numitems - 1; i++) {
m_items[i] = m_items[i + 1]; m_items[i] = m_items[i + 1];
} }
m_numitems--; m_numitems--;
} }
} }
str UIGMBox::CalculateBreaks( UIFont *font, str text, float max_width ) str UIGMBox::CalculateBreaks(UIFont *font, str text, float max_width)
{ {
str newText, sTmp; str newText;
int i; float fX;
float fX; float fwX;
float fwX, fsX; const char *current;
int count;
Cmd_TokenizeString(text.c_str()); current = text;
if (Cmd_Argc()) fX = 0.0;
{
fX = 0.0;
fsX = font->getCharWidth(' ');
for (i = 0; i < Cmd_Argc(); i++) for (count = font->DBCSGetWordBlockCount(current, -1); count;
{ current += count, count = font->DBCSGetWordBlockCount(current, -1)) {
sTmp = Cmd_Argv(i); fwX = font->getWidth(current, count);
fwX = font->getWidth(sTmp.c_str(), -1); if (fX + fwX > max_width) {
if (fwX + i <= max_width) newText += "\n" + str(current, 0, count);
{ fX = 0;
if (fwX + i + fX <= max_width) } else {
{ newText += str(current, 0, count);
newText += sTmp + " "; }
} else {
newText += "\n" + sTmp + " ";
}
}
else
{
sTmp += "\n";
fX = 0.0;
}
}
} else {
newText = "";
}
return newText; fX += fwX;
}
return newText;
} }
float UIGMBox::PrintWrap( UIFont *font, float x, float y, str text ) float UIGMBox::PrintWrap(UIFont *font, float x, float y, str text)
{ {
const char* p1, * p2; const char *p1, *p2;
size_t n, l; size_t n, l;
float fY; float fY;
fY = y; fY = y;
p1 = text.c_str(); p1 = text.c_str();
l = text.length(); l = text.length();
for (;;) for (;;) {
{ p2 = strchr(p1, '\n');
p2 = strchr(p1, '\n'); if (!p2) {
if (!p2) { break;
break; }
}
n = p2 - p1; n = p2 - p1;
if (n >= l) { if (n >= l) {
break; break;
} }
font->Print(x, fY, p1, p2 - p1, qfalse); font->Print(x, fY, p1, p2 - p1, getHighResScale());
p1 = p2 + 1; p1 = p2 + 1;
l -= n; l -= n;
fY += font->getHeight(qfalse); fY += font->getHeight();
} }
font->Print(x, fY, p1, l, qfalse); if (*p1) {
font->Print(x, fY, p1, l, getHighResScale());
fY += font->getHeight();
}
return font->getHeight(qfalse) + (fY - y); return fY - y;
} }
float UIGMBox::DrawItem( item_t *in, float x, float y, float alpha ) float UIGMBox::DrawItem(item_t *in, float x, float y, float alpha)
{ {
in->font->setColor(in->color); if (m_drawoutline) {
in->font->setAlpha(alpha); //
// Draw an outline
//
return PrintWrap(in->font, x, y, in->string); in->font->setColor(UBlack);
in->font->setAlpha(alpha);
PrintWrap(in->font, x + 1, y + 2, in->string);
PrintWrap(in->font, x + 2, y + 1, in->string);
PrintWrap(in->font, x - 1, y + 2, in->string);
PrintWrap(in->font, x - 2, y + 1, in->string);
PrintWrap(in->font, x - 1, y - 2, in->string);
PrintWrap(in->font, x - 2, y - 1, in->string);
PrintWrap(in->font, x + 1, y - 2, in->string);
PrintWrap(in->font, x + 2, y - 1, in->string);
PrintWrap(in->font, x + 2, y, in->string);
PrintWrap(in->font, x - 2, y, in->string);
PrintWrap(in->font, x, y + 2, in->string);
PrintWrap(in->font, x, y - 2, in->string);
}
in->font->setColor(in->color);
in->font->setAlpha(alpha);
return PrintWrap(in->font, x, y, in->string);
} }
void UIGMBox::Print( const char *text ) void UIGMBox::Print(const char *text)
{ {
const char* text1 = text; const char *text1 = text;
if (m_numitems > 4) if (m_numitems > 4) {
{ //
// // Overwrite an item
// Overwrite an item //
// RemoveTopItem();
RemoveTopItem(); }
}
m_items[m_numitems].flags = 0; m_items[m_numitems].flags = 0;
if (*text == 3) if (*text == MESSAGE_WHITE) {
{ m_items[m_numitems].color = UWhite;
m_items[m_numitems].color = UWhite; m_items[m_numitems].font = m_fontbold;
m_items[m_numitems].font = m_fontbold; m_items[m_numitems].flags |= GMBOX_ITEM_FLAG_BOLD;
m_items[m_numitems].flags |= GMBOX_ITEM_FLAG_BOLD;
text1 = text + 1; text1 = text + 1;
} } else {
else m_items[m_numitems].color = m_foreground_color;
{ m_items[m_numitems].font = m_font;
m_items[m_numitems].color = m_foreground_color; }
m_items[m_numitems].font = m_font;
}
m_items[m_numitems].string = CalculateBreaks(m_items[m_numitems].font, text1, s_gmboxWidth); m_items[m_numitems].string = CalculateBreaks(m_items[m_numitems].font, Sys_LV_CL_ConvertString(text1), s_gmboxWidth);
m_numitems++; m_numitems++;
VerifyBoxOut(); VerifyBoxOut();
PostDecayEvent(); PostDecayEvent();
} }
void UIGMBox::OnSizeChanged( Event *ev ) void UIGMBox::OnSizeChanged(Event *ev)
{ {
s_gmboxWidth = m_frame.size.width; s_gmboxWidth = m_frame.size.width;
} }
void UIGMBox::Create( const UIRect2D& rect, const UColor& fore, const UColor& back, float alpha ) void UIGMBox::Create(const UIRect2D& rect, const UColor& fore, const UColor& back, float alpha)
{ {
InitFrame(NULL, rect, 0, "facfont-20"); InitFrame(NULL, rect, 0, "facfont-20");
if (!m_fontbold) { if (!m_fontbold) {
m_fontbold = new UIFont("facfont-20"); m_fontbold = new UIFont("facfont-20");
} }
m_fontbold->setColor(URed); m_fontbold->setColor(URed);
setBackgroundColor(back, true); setBackgroundColor(back, true);
setForegroundColor(fore); setForegroundColor(fore);
setBackgroundAlpha(alpha); setBackgroundAlpha(alpha);
Connect(this, W_SizeChanged, W_SizeChanged); Connect(this, W_SizeChanged, W_SizeChanged);
OnSizeChanged(NULL); OnSizeChanged(NULL);
m_movespeed = rect.size.height * 3.0; m_movespeed = rect.size.height * 3.0;
setShowState(); setShowState();
} }
void UIGMBox::MoveInEvent( Event *ev ) void UIGMBox::MoveInEvent(Event *ev) {}
void UIGMBox::DecayEvent(Event *ev)
{ {
RemoveTopItem();
if (m_numitems) {
PostDecayEvent();
}
} }
void UIGMBox::DecayEvent( Event *ev ) void UIGMBox::Draw(void)
{ {
RemoveTopItem(); float fsY;
if (m_numitems) { int i;
PostDecayEvent(); float alpha;
} float alphaScale;
alphaScale = 1.0;
HandleBoxMoving();
if (!m_numitems) {
//
// Nothing to show
//
return;
}
m_font->setColor(m_foreground_color);
alpha = (float)(cls.realtime - m_iBeginDecay) / (float)m_iEndDecay;
if (alpha > 1.0) {
alpha = 1.0;
}
alpha = (1.0 - alpha) * 4.0;
if (alpha > 1.0) {
alpha = 1.0;
}
if (cge) {
alphaScale = 1.0 - cge->CG_GetObjectiveAlpha();
}
fsY = DrawItem(m_items, s_gmboxOffsetX, s_gmboxOffsetY, alpha * alphaScale);
fsY = alpha <= 0.2 ? s_gmboxOffsetY : fsY + s_gmboxOffsetY;
for (i = 1; i < m_numitems; i++) {
fsY += DrawItem(&m_items[i], s_gmboxOffsetX, fsY, alphaScale);
if (fsY > m_frame.size.height) {
if (EventPending(EV_GMBox_Decay)) {
CancelEventsOfType(EV_GMBox_Decay);
}
PostEvent(EV_GMBox_Decay, 0.0);
break;
}
}
} }
void UIGMBox::Draw( void ) void UIGMBox::setRealShow(bool b)
{ {
float fsY; this->m_reallyshown = b;
int i; setShowState();
float alpha;
float alphaScale;
alphaScale = 1.0;
HandleBoxMoving();
if (!m_numitems) {
//
// Nothing to show
//
return;
}
m_font->setColor(m_foreground_color);
alpha = (float)(cls.realtime - m_iBeginDecay) / (float)m_iEndDecay;
if (alpha > 1.0) alpha = 1.0;
alpha = (1.0 - alpha) * 4.0;
if (alpha > 1.0) alpha = 1.0;
if (cge) {
alphaScale = 1.0 - cge->CG_GetObjectiveAlpha();
}
fsY = DrawItem(m_items, s_gmboxOffsetX, s_gmboxOffsetY, alpha * alphaScale);
fsY = alpha <= 0.2 ? s_gmboxOffsetY : fsY + s_gmboxOffsetY;
for (i = 1; i < m_numitems; i++)
{
fsY += DrawItem(&m_items[i], s_gmboxOffsetX, fsY, alphaScale);
if (fsY > m_frame.size.height)
{
if (EventPending(EV_GMBox_Decay)) {
CancelEventsOfType(EV_GMBox_Decay);
}
PostEvent(EV_GMBox_Decay, 0.0);
break;
}
}
} }
void UIGMBox::setRealShow( bool b ) void UIGMBox::Clear(void)
{ {
this->m_reallyshown = b; m_numitems = 0;
setShowState();
} }
void UIGMBox::Clear( void )
{
m_numitems = 0;
}

View file

@ -1,6 +1,6 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2015 the OpenMoHAA team Copyright (C) 2015-2024 the OpenMoHAA team
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -20,8 +20,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=========================================================================== ===========================================================================
*/ */
#ifndef __CL_UIGMBOX_H__ #pragma once
#define __CL_UIGMBOX_H__
static constexpr unsigned int GMBOX_ITEM_FLAG_BOLD = 1u; static constexpr unsigned int GMBOX_ITEM_FLAG_BOLD = 1u;
@ -44,6 +43,8 @@ protected:
int m_movespeed; int m_movespeed;
int m_iBeginDecay; int m_iBeginDecay;
int m_iEndDecay; int m_iEndDecay;
// Added in OPM
bool m_drawoutline;
public: public:
CLASS_PROTOTYPE( UIGMBox ); CLASS_PROTOTYPE( UIGMBox );
@ -72,5 +73,3 @@ public:
void setRealShow( bool b ); void setRealShow( bool b );
void Clear( void ); void Clear( void );
}; };
#endif

View file

@ -1,6 +1,6 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2023 the OpenMoHAA team Copyright (C) 2023-2024 the OpenMoHAA team
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -25,12 +25,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
class LANGameItem : public UIListCtrlItem class LANGameItem : public UIListCtrlItem
{ {
str strings[5]; str strings[6];
public: public:
LANGameItem(); LANGameItem();
LANGameItem( LANGameItem(
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping, const str& ipAddress
); );
int getListItemValue(int which) const override; int getListItemValue(int which) const override;
@ -65,6 +65,11 @@ UILANGameClass::UILANGameClass()
m_iLastUpdateTime = 0; m_iLastUpdateTime = 0;
m_noservers_mat = uWinMan.RegisterShader("textures/menu/noservers"); m_noservers_mat = uWinMan.RegisterShader("textures/menu/noservers");
//
// Added in OPM
//
m_bVirtual = false;
} }
void UILANGameClass::Draw(void) void UILANGameClass::Draw(void)
@ -102,11 +107,12 @@ void UILANGameClass::UpdateUIElement(void)
width = getClientFrame().size.width - 16.f; width = getClientFrame().size.width - 16.f;
AddColumn(Sys_LV_CL_ConvertString("Server Name"), 0, width * 0.4f, false, false); AddColumn(Sys_LV_CL_ConvertString("Server Name"), 0, width * 0.27f, false, false); // was 0.4
AddColumn(Sys_LV_CL_ConvertString("Map"), 1, width * 0.15f, false, false); AddColumn(Sys_LV_CL_ConvertString("Map"), 1, width * 0.12f, false, false); // was 0.15
AddColumn(Sys_LV_CL_ConvertString("Players"), 2, width * 0.165f, true, true); AddColumn(Sys_LV_CL_ConvertString("Players"), 2, width * 0.08f, true, true); // was 0.165
AddColumn(Sys_LV_CL_ConvertString("GameType"), 3, width * 0.22f, false, false); AddColumn(Sys_LV_CL_ConvertString("GameType"), 3, width * 0.118f, false, false); // was 0.22
AddColumn(Sys_LV_CL_ConvertString("Ping"), 4, width * 0.065f, true, false); AddColumn(Sys_LV_CL_ConvertString("Ping"), 4, width * 0.052f, true, false); // was 0.065
AddColumn(Sys_LV_CL_ConvertString("IP"), 5, width * 0.36f, false, false); // Added in OPM
uWinMan.ActivateControl(this); uWinMan.ActivateControl(this);
@ -134,7 +140,9 @@ void UILANGameClass::SetupServers(void)
pServerInfo->mapName, pServerInfo->mapName,
va("%02i/%02i", pServerInfo->clients, pServerInfo->maxClients), va("%02i/%02i", pServerInfo->clients, pServerInfo->maxClients),
pServerInfo->gameTypeString, pServerInfo->gameTypeString,
str(pServerInfo->ping) str(pServerInfo->ping),
// Added in OPM
NET_AdrToStringwPort(pServerInfo->adr)
); );
} }
@ -167,7 +175,7 @@ void UILANGameClass::JoinServer(Event *ev)
const serverInfo_t& serverInfo = cls.localServers[getCurrentItem() - 1]; const serverInfo_t& serverInfo = cls.localServers[getCurrentItem() - 1];
UI_SetReturnMenuToCurrent(); UI_SetReturnMenuToCurrent();
CL_Connect(NET_AdrToString(serverInfo.adr), netadrtype_t::NA_UNSPEC); CL_Connect(NET_AdrToStringwPort(serverInfo.adr), netadrtype_t::NA_UNSPEC);
} }
qboolean UILANGameClass::KeyEvent(int key, unsigned int time) qboolean UILANGameClass::KeyEvent(int key, unsigned int time)
@ -197,7 +205,7 @@ qboolean UILANGameClass::KeyEvent(int key, unsigned int time)
LANGameItem::LANGameItem() {} LANGameItem::LANGameItem() {}
LANGameItem::LANGameItem( LANGameItem::LANGameItem(
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping, const str& ipAddress
) )
{ {
strings[0] = hostName; strings[0] = hostName;
@ -205,6 +213,12 @@ LANGameItem::LANGameItem(
strings[2] = players; strings[2] = players;
strings[3] = gameTypeString; strings[3] = gameTypeString;
strings[4] = ping; strings[4] = ping;
//
// Added in OPM
//
strings[5] = ipAddress;
} }
int LANGameItem::getListItemValue(int which) const int LANGameItem::getListItemValue(int which) const

View file

@ -95,7 +95,7 @@ UIFAKKLoadGameClass::UIFAKKLoadGameClass()
{ {
Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked); Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected); Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
AllowActivate(false); AllowActivate(true);
m_bRemovePending = false; m_bRemovePending = false;
setHeaderFont("facfont-20"); setHeaderFont("facfont-20");
@ -155,12 +155,17 @@ void UIFAKKLoadGameClass::SetupFiles(void)
FS_Read(&save, sizeof(savegamestruct_t), f); FS_Read(&save, sizeof(savegamestruct_t), f);
FS_FCloseFile(f); FS_FCloseFile(f);
Com_SwapSaveStruct(&save);
if (save.version != SAVEGAME_STRUCT_VERSION) { if (save.version != SAVEGAME_STRUCT_VERSION) {
// wrong save game version // wrong save game version
continue; continue;
} }
if (save.type != com_target_game->integer) {
continue;
}
gametime = (save.mapTime / 1000); gametime = (save.mapTime / 1000);
date = save.time; date = save.time;
@ -282,7 +287,7 @@ qboolean UIFAKKLoadGameClass::KeyEvent(int key, unsigned int time)
} }
break; break;
default: default:
return UIListBase::KeyEvent(key, time); return UIListCtrl::KeyEvent(key, time);
} }
return qfalse; return qfalse;
@ -328,6 +333,7 @@ str FAKKLoadGameItem::getListItemString(int which) const
{ {
int numseconds; int numseconds;
int numseconds_hours; int numseconds_hours;
int seconds;
// hours // hours
numseconds = atol(strings[1]); numseconds = atol(strings[1]);
@ -336,17 +342,18 @@ str FAKKLoadGameItem::getListItemString(int which) const
// minutes // minutes
numseconds_hours = numseconds % 3600; numseconds_hours = numseconds % 3600;
if (numseconds_hours / 60 <= 9) { if (numseconds_hours / 60 < 10) {
itemstring += "0"; itemstring += "0";
} }
itemstring += (numseconds_hours / 60); itemstring += (numseconds_hours / 60);
itemstring += ":"; itemstring += ":";
// seconds // seconds
if (numseconds_hours / 60 <= 9) { seconds = numseconds_hours % 60;
if (seconds < 10) {
itemstring += "0"; itemstring += "0";
} }
itemstring += (numseconds_hours % 60); itemstring += seconds;
} }
break; break;
case 2: case 2:
@ -355,7 +362,7 @@ str FAKKLoadGameItem::getListItemString(int which) const
char buffer[2048]; char buffer[2048];
time = atol(strings[2]); time = atol(strings[2]);
strftime(buffer, sizeof(buffer), "%a %b %d %H:%M:%S %Y", localtime(&time)); strftime(buffer, sizeof(buffer), "%a %b %d %Y %H:%M:%S", localtime(&time));
itemstring = buffer; itemstring = buffer;
} }
break; break;

View file

@ -76,7 +76,7 @@ void UIMapRotationListBox::PopulateRotationList()
maplistVar = Cvar_Get("ui_maplist_ffa", "", 0); maplistVar = Cvar_Get("ui_maplist_ffa", "", 0);
} }
strcpy(mapBuffer, maplistVar->string); Q_strncpyz(mapBuffer, maplistVar->string, sizeof(mapBuffer));
for (token = strtok(mapBuffer, " /"); token; token = strtok(NULL, " /")) { for (token = strtok(mapBuffer, " /"); token; token = strtok(NULL, " /")) {
if (!Q_stricmp(token, "dm")) { if (!Q_stricmp(token, "dm")) {
@ -143,7 +143,7 @@ void UIMapListBox::PopulateMapList()
bool bHasTOW = false; bool bHasTOW = false;
bool bHasLib = false; bool bHasLib = false;
strcpy(mapName, filename); Q_strncpyz(mapName, filename, sizeof(mapName));
mapName[strlen(mapName) - 4] = 0; mapName[strlen(mapName) - 4] = 0;
if (!COM_IsMapValid(mapName)) { if (!COM_IsMapValid(mapName)) {
@ -151,7 +151,7 @@ void UIMapListBox::PopulateMapList()
} }
if (bTugOfWar || bLiberation) { if (bTugOfWar || bLiberation) {
strcpy(tokenized, mapName); Q_strncpyz(tokenized, mapName, sizeof(tokenized));
for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) { for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) {
if (bLiberation) { if (bLiberation) {
@ -181,7 +181,7 @@ void UIMapListBox::PopulateMapList()
} }
} }
} else if (bObjective) { } else if (bObjective) {
strcpy(tokenized, mapName); Q_strncpyz(tokenized, mapName, sizeof(tokenized));
for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) { for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) {
if (!Q_stricmp(token, "obj")) { if (!Q_stricmp(token, "obj")) {
@ -209,9 +209,9 @@ void UIMapListBox::PopulateMapList()
char mapName[256]; char mapName[256];
char tokenized[256]; char tokenized[256];
strcpy(mapName, filename); Q_strncpyz(mapName, filename, sizeof(mapName));
mapName[strlen(mapName) - 4] = 0; mapName[strlen(mapName) - 4] = 0;
strcpy(tokenized, mapName); Q_strncpyz(tokenized, mapName, sizeof(tokenized));
token = strtok(tokenized, "_"); token = strtok(tokenized, "_");
if (!Q_stricmp(token, "obj") || !Q_stricmp(mapName, "mp_ship_lib")) { if (!Q_stricmp(token, "obj") || !Q_stricmp(mapName, "mp_ship_lib")) {
@ -237,7 +237,7 @@ void UIMapListBox::PopulateMapList()
const char *filename = filenames[i]; const char *filename = filenames[i];
char mapName[256]; char mapName[256];
strcpy(mapName, filename); Q_strncpyz(mapName, filename, sizeof(mapName));
mapName[strlen(mapName) - 4] = 0; mapName[strlen(mapName) - 4] = 0;
if (!COM_IsMapValid(mapName)) { if (!COM_IsMapValid(mapName)) {
@ -277,20 +277,27 @@ void UIAddToRotationButton::Released(Event *ev)
if (mapList && rotationList) { if (mapList && rotationList) {
size_t mapLength = 0; size_t mapLength = 0;
int item = mapList->getCurrentItem(); int item = mapList->getCurrentItem();
str currentItemText;
if (item) {
currentItemText = mapList->getItemText(item);
}
for (i = 1; i <= rotationList->getNumItems(); i++) { for (i = 1; i <= rotationList->getNumItems(); i++) {
str text = rotationList->getItemText(i); str text = rotationList->getItemText(i);
if (text == currentItemText) {
// Added in OPM
// Prevent adding duplicates
item = 0;
break;
}
mapLength += text.length(); mapLength += text.length();
} }
if (item) { if (item && prefixLength + mapLength + currentItemText.length() < 256) {
str text = mapList->getItemText(item); rotationList->AddItem(currentItemText, NULL);
if (prefixLength + mapLength + text.length() < 256) {
rotationList->AddItem(text, NULL);
}
} }
} }
@ -356,7 +363,7 @@ void UIRotationApplyButton::Released(Event *ev)
char map[256]; char map[256];
bool bHasTOW = false, bHasObj = false, bHasLib = false, bHasShip = false; bool bHasTOW = false, bHasObj = false, bHasLib = false, bHasShip = false;
strcpy(map, text); Q_strncpyz(map, text, sizeof(map));
for (token = strtok(map, "_"); token; token = strtok(NULL, "_")) { for (token = strtok(map, "_"); token; token = strtok(NULL, "_")) {
if (!Q_stricmp(token, "TOW")) { if (!Q_stricmp(token, "TOW")) {
bHasTOW = true; bHasTOW = true;
@ -387,11 +394,12 @@ void UIRotationApplyButton::Released(Event *ev)
} }
maplistStr += text; maplistStr += text;
maplistStr += " ";
if (i == 1) { if (i == 1) {
Cvar_Set("ui_dmmap", maplistStr); Cvar_Set("ui_dmmap", maplistStr);
} }
maplistStr += " ";
} }
} }
@ -413,10 +421,10 @@ void UIRotationMoveItemUpButton::Released(Event *ev)
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List")); list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
item = list->getCurrentItem(); item = list->getCurrentItem();
if (item < list->getNumItems() && list->getNumItems() > 1) { if (item > 1 && list->getNumItems() > 1) {
str text = list->getItemText(item + 1); str text = list->getItemText(item - 1);
list->DeleteItem(list->getCurrentItem() - 1); list->DeleteItem(item - 1);
list->InsertItem(text, item); list->InsertItem(text, item);
list->setCurrentItem(item - 1); list->setCurrentItem(item - 1);
} }
@ -440,7 +448,7 @@ void UIRotationMoveItemDownButton::Released(Event *ev)
if (item < list->getNumItems() && list->getNumItems() > 1) { if (item < list->getNumItems() && list->getNumItems() > 1) {
str text = list->getItemText(item + 1); str text = list->getItemText(item + 1);
list->DeleteItem(list->getCurrentItem() + 1); list->DeleteItem(item + 1);
list->InsertItem(text, item); list->InsertItem(text, item);
list->setCurrentItem(item + 1); list->setCurrentItem(item + 1);
} }

View file

@ -1,6 +1,6 @@
/* /*
=========================================================================== ===========================================================================
Copyright (C) 2023 the OpenMoHAA team Copyright (C) 2023-2024 the OpenMoHAA team
This file is part of OpenMoHAA source code. This file is part of OpenMoHAA source code.
@ -83,7 +83,7 @@ void PickFile(const char *name, Listener *obj, Event& event)
if (name && *name && strchr(name, '/')) { if (name && *name && strchr(name, '/')) {
currentpath = name; currentpath = name;
for (i = currentpath.length(); i > 0; i--) { for (i = currentpath.length() - 1; i > 0; i--) {
if (currentpath[i] == '/') { if (currentpath[i] == '/') {
break; break;
} }
@ -94,7 +94,7 @@ void PickFile(const char *name, Listener *obj, Event& event)
currentpath = ""; currentpath = "";
} }
picker->Setup("", currentpath, ".*"); picker->Setup("", currentpath, ".*", "");
} }
CLASS_DECLARATION(FilePickerClass, ViewSpawnerClass, NULL) { CLASS_DECLARATION(FilePickerClass, ViewSpawnerClass, NULL) {

View file

@ -112,7 +112,7 @@ void FakkMiniconsole::PostMoveinEvent(void)
void FakkMiniconsole::OnSizeChanged(Event *ev) void FakkMiniconsole::OnSizeChanged(Event *ev)
{ {
m_maxlines = m_frame.size.height / m_font->getHeight(false); m_maxlines = m_frame.size.height / m_font->getHeight(getHighResScale());
} }
void FakkMiniconsole::MoveInEvent(Event *ev) void FakkMiniconsole::MoveInEvent(Event *ev)
@ -163,14 +163,14 @@ void FakkMiniconsole::Draw(void)
HandleBoxMoving(); HandleBoxMoving();
m_font->setColor(m_foreground_color); m_font->setColor(m_foreground_color);
aty = m_frame.size.height - m_font->getHeight(false); aty = m_frame.size.height - m_font->getHeight(getHighResScale());
for (i = m_lines.NumObjects(); i > 0; i--) { for (i = m_lines.NumObjects(); i > 0; i--) {
if (-m_font->getHeight(false) >= aty) { if (-m_font->getHeight(getHighResScale()) >= aty) {
break; break;
} }
m_font->Print(0, aty, m_lines.ObjectAt(i), -1, false); m_font->Print(0, aty / getHighResScale()[1], m_lines.ObjectAt(i), -1, getHighResScale());
aty -= m_font->getHeight(false); aty -= m_font->getHeight(getHighResScale());
} }
} }

View file

@ -51,7 +51,7 @@ MpMapPickerClass::MpMapPickerClass()
window = new UIFloatingWindow(); window = new UIFloatingWindow();
window->Create( window->Create(
NULL, NULL,
UIRect2D((cls.glconfig.vidWidth - 300) / 2, (cls.glconfig.vidHeight - 200) / 2, 300, 200), UIRect2D((uid.vidWidth - 300) / 2, (uid.vidHeight - 200) / 2, 300, 200),
"Select a Map", "Select a Map",
UColor(0.15f, 0.195f, 0.278f), UColor(0.15f, 0.195f, 0.278f),
UHudColor UHudColor
@ -180,12 +180,14 @@ void MpMapPickerClass::SetupFiles(void)
FS_FreeFileList(filenames); FS_FreeFileList(filenames);
} }
if (currentDirectory.length()) { if (com_target_game->integer > target_game_e::TG_MOH) {
if (currentDirectory == "maps/-/") { if (currentDirectory.length()) {
SetupSecondaryFiles(currentDirectory, bTugOfWar, bObjective, bLiberation); if (currentDirectory == "maps/-/") {
} else { SetupSecondaryFiles(currentDirectory, bTugOfWar, bObjective, bLiberation);
SetupSecondaryFiles("maps/obj/", bTugOfWar, bObjective, bLiberation); } else {
SetupSecondaryFiles("maps/lib/", bTugOfWar, bObjective, bLiberation); SetupSecondaryFiles("maps/obj/", bTugOfWar, bObjective, bLiberation);
SetupSecondaryFiles("maps/lib/", bTugOfWar, bObjective, bLiberation);
}
} }
} }
@ -278,9 +280,9 @@ void MpMapPickerClass::FileSelected(Event *ev)
uii.Snd_PlaySound("sound/menu/apply.wav"); uii.Snd_PlaySound("sound/menu/apply.wav");
UIListCtrlItem* item = listbox->GetItem(listbox->getCurrentItem()); UIListCtrlItem *item = listbox->GetItem(listbox->getCurrentItem());
str name = item->getListItemString(0); str name = item->getListItemString(0);
str directory = item->getListItemString(1); str directory = item->getListItemString(1);
FileSelected(directory, name, directory + name); FileSelected(directory, name, directory + name);
} }
@ -305,9 +307,9 @@ void MpMapPickerClass::FileChosen(Event *ev)
uii.Snd_PlaySound("sound/menu/apply.wav"); uii.Snd_PlaySound("sound/menu/apply.wav");
UIListCtrlItem* item = listbox->GetItem(listbox->getCurrentItem()); UIListCtrlItem *item = listbox->GetItem(listbox->getCurrentItem());
str name = item->getListItemString(0); str name = item->getListItemString(0);
str directory = item->getListItemString(1); str directory = item->getListItemString(1);
FileSelected(directory, name, directory + name); FileSelected(directory, name, directory + name);
} }

View file

@ -155,7 +155,7 @@ PlayerModelPickerClass::PlayerModelPickerClass()
window = new UIFloatingWindow(); window = new UIFloatingWindow();
window->Create( window->Create(
NULL, NULL,
UIRect2D((cls.glconfig.vidWidth - 400) / 2, (cls.glconfig.vidHeight - 300) / 2, 400, 300), UIRect2D((uid.vidWidth - 400) / 2, (uid.vidHeight - 300) / 2, 400, 300),
"Player Model Select...", "Player Model Select...",
UColor(0.15f, 0.195f, 0.278f), UColor(0.15f, 0.195f, 0.278f),
UHudColor UHudColor
@ -295,7 +295,7 @@ void PlayerModelPickerClass::FileSelected(Event *ev)
fullname = PM_DisplaynameToFilename(name); fullname = PM_DisplaynameToFilename(name);
if (!Q_stricmpn(fullname, "german_waffen_", 14)) { if (!Q_stricmpn(fullname, "german_waffen_", 14)) {
Q_strncpyz(donotshowssindeorfr, "german_waffen_", sizeof(donotshowssindeorfr)); Q_strncpyz(donotshowssindeorfr, "german_waffenss_", sizeof(donotshowssindeorfr));
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), fullname.c_str() + 14); Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), fullname.c_str() + 14);
} else { } else {
Q_strncpyz(donotshowssindeorfr, fullname, sizeof(donotshowssindeorfr)); Q_strncpyz(donotshowssindeorfr, fullname, sizeof(donotshowssindeorfr));

View file

@ -58,7 +58,7 @@ void UIRadar::Draw(void)
float inv; float inv;
float iconSize; float iconSize;
int blinkTime, speakTime; int blinkTime, speakTime;
float origin[2], axis[2]; vec2_t origin, axis;
float halfScale; float halfScale;
int i; int i;
@ -105,17 +105,17 @@ void UIRadar::Draw(void)
halfScale = iconSize * 0.5f; halfScale = iconSize * 0.5f;
for (i = 0; i < MAX_CLIENTS; i++) { for (i = 0; i < MAX_CLIENTS; i++) {
float delta[2]; vec2_t delta;
float newOrg[2]; vec2_t newOrg;
float screenOrg[2]; vec2_t screenOrg;
float length; float length;
radar = &g_radarClients[i]; radar = &g_radarClients[i];
if (i == g_radarClientNum) { if (i == g_radarClientNum) {
continue; continue;
} }
if (!g_radarClients[i].time) { if (!radar->time) {
continue; continue;
} }
@ -128,10 +128,13 @@ void UIRadar::Draw(void)
// make the icon blink // make the icon blink
if (delta >= 0 && delta < speakTime && ((delta / blinkTime) % 2) == 0) { if (delta >= 0 && delta < speakTime && ((delta / blinkTime) % 2) == 0) {
continue; continue;
}
if (delta < 0 || delta >= speakTime) {
radar->lastSpeakTime = 0;
} }
} }
radar->lastSpeakTime = 0;
delta[0] = radar->origin[0] - origin[0]; delta[0] = radar->origin[0] - origin[0];
delta[1] = radar->origin[1] - origin[1]; delta[1] = radar->origin[1] - origin[1];
newOrg[0] = -(delta[0] * axis[0] + delta[1] * axis[1]) * inv; newOrg[0] = -(delta[0] * axis[0] + delta[1] * axis[1]) * inv;
@ -140,12 +143,12 @@ void UIRadar::Draw(void)
if (length > 1) if (length > 1)
{ {
newOrg[0] = -(delta[0] * axis[0] + delta[1] * axis[1]) * inv * (1.f / length); newOrg[0] *= 1.f / length;
newOrg[1] = (delta[0] * axis[1] + delta[1] * -axis[0]) * inv * (1.f / length); newOrg[1] *= 1.f / length;
} }
screenOrg[0] = -((halfScale * (1.141f * newOrg[1] + m_vVirtualScale[0])) - ((1.f + newOrg[1]) * 0.5f * m_frame.size.width)); screenOrg[0] = -((halfScale * (1.414f * newOrg[1] + m_vVirtualScale[0])) - ((1.f + newOrg[1]) * 0.5f * m_frame.size.width));
screenOrg[1] = -((halfScale * (1.141f * newOrg[0] + m_vVirtualScale[1])) - ((1.f + newOrg[0]) * 0.5f * m_frame.size.height)); screenOrg[1] = -((halfScale * (1.414f * newOrg[0] + m_vVirtualScale[1])) - ((1.f + newOrg[0]) * 0.5f * m_frame.size.height));
uii.Rend_DrawPicStretched2( uii.Rend_DrawPicStretched2(
screenOrg[0], screenOrg[0],

File diff suppressed because it is too large Load diff

View file

@ -22,6 +22,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#pragma once #pragma once
#include "../gamespy/goaceng.h"
class UIFAKKServerList : public UIListCtrl { class UIFAKKServerList : public UIListCtrl {
protected: protected:
// need a new struct instead of gamespy // need a new struct instead of gamespy
@ -47,6 +49,7 @@ protected:
void MakeLANListing( Event *ev ); void MakeLANListing( Event *ev );
void UpdateServer( Event *ev ); void UpdateServer( Event *ev );
static int ServerCompareFunction( const UIListCtrlItem *i1, const UIListCtrlItem *i2, int columnname ); static int ServerCompareFunction( const UIListCtrlItem *i1, const UIListCtrlItem *i2, int columnname );
static void UpdateServerListCallBack(GServerList serverlist, int msg, void *instance, void *param1, void *param2);
public: public:
UIFAKKServerList(); UIFAKKServerList();

View file

@ -439,8 +439,11 @@ void UIFakkLabel::LayoutRenderModelAnim(Event *ev)
void UIFakkLabel::DrawStatbar(float frac) void UIFakkLabel::DrawStatbar(float frac)
{ {
vec4_t col; vec4_t col;
float alpha; float alpha;
qhandle_t hMat;
float w, h;
float fvWidth, fvHeight;
col[0] = col[1] = col[2] = col[3] = 1.0; col[0] = col[1] = col[2] = col[3] = 1.0;
@ -475,11 +478,7 @@ void UIFakkLabel::DrawStatbar(float frac)
m_lastfrac = frac; m_lastfrac = frac;
alpha = 1.0 - ((float)uid.time - m_flashtime) / 1500.0; alpha = 1.0 - ((float)uid.time - m_flashtime) / 1500.0;
if (alpha < 0.0) { alpha = Q_clamp_float(alpha, 0, 1);
alpha = 0.0;
} else if (alpha > 1.0) {
alpha = 1.0;
}
col[3] = alpha; col[3] = alpha;
@ -490,13 +489,38 @@ void UIFakkLabel::DrawStatbar(float frac)
{ {
float width = frac * m_frame.size.width; float width = frac * m_frame.size.width;
m_statbar_material->ReregisterMaterial(); fvWidth = m_frame.size.width / m_vVirtualScale[0] / uii.Rend_GetShaderWidth(m_statbar_material->GetMaterial());
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material->GetMaterial()); fvHeight = m_frame.size.height / m_vVirtualScale[1] / uii.Rend_GetShaderHeight(m_statbar_material->GetMaterial());
re.DrawStretchPic(0.0, 0.0, width, m_frame.size.height, 0, 0, fvWidth, fvHeight, m_statbar_material->GetMaterial());
//re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material->GetMaterial());
if (alpha != 0.0 && m_statbar_material_flash) { if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col); re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material_flash->GetMaterial()); fvWidth = m_frame.size.width / m_vVirtualScale[0] / uii.Rend_GetShaderWidth(m_statbar_material_flash->GetMaterial());
fvHeight = m_frame.size.height / m_vVirtualScale[1] / uii.Rend_GetShaderHeight(m_statbar_material_flash->GetMaterial());
re.DrawStretchPic(0.0, 0.0, width, m_frame.size.height, 0, 0, fvWidth, fvHeight, m_statbar_material_flash->GetMaterial());
//re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material_flash->GetMaterial());
}
if (m_statbar_material_marker) {
hMat = m_statbar_material_marker->GetMaterial();
w = re.GetShaderWidth(hMat);
h = re.GetShaderHeight(hMat);
re.DrawStretchPic(
m_frame.size.width * frac - w * 0.5,
m_frame.size.height * 0.5 - h * 0.5,
w,
h,
0,
0,
1,
1,
hMat
);
} }
break; break;
} }
@ -507,14 +531,39 @@ void UIFakkLabel::DrawStatbar(float frac)
{ {
float y = m_frame.size.height * (1.0 - frac); float y = m_frame.size.height * (1.0 - frac);
m_statbar_material->ReregisterMaterial(); fvWidth = m_frame.size.width / m_vVirtualScale[0] / uii.Rend_GetShaderWidth(m_statbar_material->GetMaterial());
re.DrawTilePic(0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material->GetMaterial()); fvHeight = m_frame.size.height / m_vVirtualScale[1] / uii.Rend_GetShaderHeight(m_statbar_material->GetMaterial());
re.DrawStretchPic(0.0, y, m_frame.size.width, m_frame.size.height, 0, 0, fvWidth, fvHeight, m_statbar_material->GetMaterial());
//re.DrawTilePic(0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material->GetMaterial());
if (alpha != 0.0 && m_statbar_material_flash) { if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col); re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTilePic( fvWidth = m_frame.size.width / m_vVirtualScale[0] / uii.Rend_GetShaderWidth(m_statbar_material_flash->GetMaterial());
0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material_flash->GetMaterial() fvHeight = m_frame.size.height / m_vVirtualScale[1] / uii.Rend_GetShaderHeight(m_statbar_material_flash->GetMaterial());
re.DrawStretchPic(0.0, y, m_frame.size.width, m_frame.size.height, 0, 0, fvWidth, fvHeight, m_statbar_material_flash->GetMaterial());
//re.DrawTilePic(
// 0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material_flash->GetMaterial()
//);
}
if (m_statbar_material_marker) {
hMat = m_statbar_material_marker->GetMaterial();
w = re.GetShaderWidth(hMat);
h = re.GetShaderHeight(hMat);
re.DrawStretchPic(
m_frame.size.width * frac - w * 0.5,
m_frame.size.height * 0.5 - h * 0.5,
w,
h,
0,
0,
1,
1,
hMat
); );
} }
break; break;
@ -528,14 +577,12 @@ void UIFakkLabel::DrawStatbar(float frac)
{ {
float width = frac * m_frame.size.width; float width = frac * m_frame.size.width;
m_statbar_material->ReregisterMaterial();
re.DrawStretchPic( re.DrawStretchPic(
0.0, 0.0, width, m_frame.size.height, 0.0, 0.0, 1.0, 1.0, m_statbar_material->GetMaterial() 0.0, 0.0, width, m_frame.size.height, 0.0, 0.0, 1.0, 1.0, m_statbar_material->GetMaterial()
); );
if (alpha != 0.0 && m_statbar_material_flash) { if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col); re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawStretchPic( re.DrawStretchPic(
0.0, 0.0,
0.0, 0.0,
@ -548,6 +595,24 @@ void UIFakkLabel::DrawStatbar(float frac)
m_statbar_material_flash->GetMaterial() m_statbar_material_flash->GetMaterial()
); );
} }
if (m_statbar_material_marker) {
hMat = m_statbar_material_marker->GetMaterial();
w = re.GetShaderWidth(hMat);
h = re.GetShaderHeight(hMat);
re.DrawStretchPic(
m_frame.size.width * frac - w * 0.5,
m_frame.size.height * 0.5 - h * 0.5,
w,
h,
0,
0,
1,
1,
hMat
);
}
break; break;
} }
case L_STATBAR_VERTICAL: case L_STATBAR_VERTICAL:
@ -557,14 +622,12 @@ void UIFakkLabel::DrawStatbar(float frac)
float y = m_frame.size.height * (1.0 - frac); float y = m_frame.size.height * (1.0 - frac);
float height = m_frame.size.height * frac; float height = m_frame.size.height * frac;
m_statbar_material->ReregisterMaterial();
re.DrawStretchPic( re.DrawStretchPic(
0.0, y, m_frame.size.width, height, 0.0, 1.0 - frac, 1.0, 1.0, m_statbar_material->GetMaterial() 0.0, y, m_frame.size.width, height, 0.0, 1.0 - frac, 1.0, 1.0, m_statbar_material->GetMaterial()
); );
if (alpha != 0.0 && m_statbar_material_flash) { if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col); re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawStretchPic( re.DrawStretchPic(
0.0, 0.0,
y, y,
@ -577,20 +640,36 @@ void UIFakkLabel::DrawStatbar(float frac)
m_statbar_material_flash->GetMaterial() m_statbar_material_flash->GetMaterial()
); );
} }
if (m_statbar_material_marker) {
hMat = m_statbar_material_marker->GetMaterial();
w = re.GetShaderWidth(hMat);
h = re.GetShaderHeight(hMat);
re.DrawStretchPic(
m_frame.size.width * frac - w * 0.5,
m_frame.size.height * 0.5 - h * 0.5,
w,
h,
0,
0,
1,
1,
hMat
);
}
break; break;
} }
case L_STATBAR_VERTICAL_REVERSE: case L_STATBAR_VERTICAL_REVERSE:
{ {
float height = m_frame.size.height * frac; float height = m_frame.size.height * frac;
m_statbar_material->ReregisterMaterial();
re.DrawStretchPic( re.DrawStretchPic(
0.0, 0.0, m_frame.size.width, height, 0.0, 0.0, 1.0, frac, m_statbar_material->GetMaterial() 0.0, 0.0, m_frame.size.width, height, 0.0, 0.0, 1.0, frac, m_statbar_material->GetMaterial()
); );
if (alpha != 0.0 && m_statbar_material_flash) { if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col); re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawStretchPic( re.DrawStretchPic(
0.0, 0.0,
0.0, 0.0,
@ -686,12 +765,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
re.SetColor(m_foreground_color); re.SetColor(m_foreground_color);
} }
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) { if (alpha && m_statbar_material_flash) {
re.SetColor(col); re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
} }
} else { } else {
@ -709,12 +786,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
re.SetColor(m_foreground_color); re.SetColor(m_foreground_color);
} }
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) { if (alpha && m_statbar_material_flash) {
re.SetColor(col); re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
} }
@ -739,12 +814,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
re.SetColor(m_foreground_color); re.SetColor(m_foreground_color);
} }
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) { if (alpha && m_statbar_material_flash) {
re.SetColor(col); re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
} }
} else { } else {
@ -766,12 +839,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
re.SetColor(m_foreground_color); re.SetColor(m_foreground_color);
} }
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) { if (alpha && m_statbar_material_flash) {
re.SetColor(col); re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
} }
@ -846,12 +917,10 @@ void UIFakkLabel::DrawStatNeedle(float frac)
re.SetColor(m_foreground_color); re.SetColor(m_foreground_color);
} }
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) { if (alpha != 0.f && m_statbar_material_flash) {
re.SetColor(col); re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
} }
@ -867,11 +936,9 @@ void UIFakkLabel::DrawStatNeedle(float frac)
re.SetColor(m_foreground_color); re.SetColor(m_foreground_color);
} }
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) { if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
} }
} }
@ -913,8 +980,8 @@ void UIFakkLabel::DrawStatRotator(float frac)
vNeedleDir[0] = fSinVal; vNeedleDir[0] = fSinVal;
vNeedleDir[1] = -fCosVal; vNeedleDir[1] = -fCosVal;
vSize[0] = (m_frame.size.width + m_frame.size.height) / m_frame.size.width * m_angles[2] * m_vVirtualScale[0]; vSize[0] = (m_frame.size.width + m_frame.size.height) / m_frame.size.width * m_angles[2] * getVirtualScale()[0];
vSize[1] = (m_frame.size.width + m_frame.size.height) / m_frame.size.height * m_scale * m_vVirtualScale[1]; vSize[1] = (m_frame.size.width + m_frame.size.height) / m_frame.size.height * m_scale * getVirtualScale()[1];
vCenter[0] = (m_frame.size.width * 0.5f - vSize[0]) * vNeedleDir[0] + m_frame.size.width * 0.5f; vCenter[0] = (m_frame.size.width * 0.5f - vSize[0]) * vNeedleDir[0] + m_frame.size.width * 0.5f;
vCenter[1] = (m_frame.size.height * 0.5f - vSize[1]) * vNeedleDir[1] + m_frame.size.height * 0.5f; vCenter[1] = (m_frame.size.height * 0.5f - vSize[1]) * vNeedleDir[1] + m_frame.size.height * 0.5f;
@ -937,11 +1004,9 @@ void UIFakkLabel::DrawStatRotator(float frac)
re.SetColor(m_foreground_color); re.SetColor(m_foreground_color);
} }
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) { if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
} }
@ -959,11 +1024,9 @@ void UIFakkLabel::DrawStatRotator(float frac)
re.SetColor(m_foreground_color); re.SetColor(m_foreground_color);
} }
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) { if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
} }
} }
@ -1137,7 +1200,6 @@ void UIFakkLabel::DrawStatCompass(float frac)
vVerts[1][1] = vCenter[1] + vCompassDir[1] * vCenter[1] + fSinVal * vCenter[0]; vVerts[1][1] = vCenter[1] + vCompassDir[1] * vCenter[1] + fSinVal * vCenter[0];
vVerts[2][1] = vCenter[1] - vCompassDir[1] * vCenter[1] - fSinVal * vCenter[0]; vVerts[2][1] = vCenter[1] - vCompassDir[1] * vCenter[1] - fSinVal * vCenter[0];
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
vVerts[0][0] = vVerts[2][0]; vVerts[0][0] = vVerts[2][0];
@ -1150,7 +1212,6 @@ void UIFakkLabel::DrawStatCompass(float frac)
vVerts[2][0] = vCenter[0] + fCosVal * vCenter[1] - vCompassDir[0] * vCenter[0]; vVerts[2][0] = vCenter[0] + fCosVal * vCenter[1] - vCompassDir[0] * vCenter[0];
vVerts[2][1] = vCenter[1] * fSinVal + vCenter[0] - vCompassDir[1] * vCenter[1]; vVerts[2][1] = vCenter[1] * fSinVal + vCenter[0] - vCompassDir[1] * vCenter[1];
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
} }
@ -1227,11 +1288,9 @@ void UIFakkLabel::DrawStatSpinner(float frac)
re.SetColor(m_foreground_color); re.SetColor(m_foreground_color);
} }
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) { if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
} }
@ -1249,11 +1308,9 @@ void UIFakkLabel::DrawStatSpinner(float frac)
re.SetColor(m_foreground_color); re.SetColor(m_foreground_color);
} }
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) { if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial()); re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
} }
} }
@ -1319,7 +1376,7 @@ void UIFakkLabel::Draw(void)
m_iFontAlignmentVertical, m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))), Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))),
UBlack, UBlack,
m_bVirtual ? m_vVirtualScale : NULL getVirtualScale()
); );
} else { } else {
m_font->PrintJustified( m_font->PrintJustified(
@ -1327,7 +1384,7 @@ void UIFakkLabel::Draw(void)
m_iFontAlignmentHorizontal, m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical, m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))), Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))),
m_bVirtual ? m_vVirtualScale : NULL getVirtualScale()
); );
} }
return; return;
@ -1346,7 +1403,7 @@ void UIFakkLabel::Draw(void)
m_iFontAlignmentVertical, m_iFontAlignmentVertical,
va("%d", delta), va("%d", delta),
UBlack, UBlack,
m_bVirtual ? m_vVirtualScale : NULL getVirtualScale()
); );
} else { } else {
m_font->PrintJustified( m_font->PrintJustified(
@ -1354,7 +1411,7 @@ void UIFakkLabel::Draw(void)
m_iFontAlignmentHorizontal, m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical, m_iFontAlignmentVertical,
va("%d", delta), va("%d", delta),
m_bVirtual ? m_vVirtualScale : NULL getVirtualScale()
); );
} }
return; return;
@ -1425,6 +1482,12 @@ void UIFakkLabel::Draw(void)
return; return;
} }
if (cl.snap.ps.activeItems[m_itemindex] < 0 || cl.snap.ps.activeItems[m_itemindex] >= MAX_WEAPONS) {
// Fixed in OPM
// Make sure to not overflow configstrings
return;
}
m_font->setColor(m_foreground_color); m_font->setColor(m_foreground_color);
if (m_bOutlinedText) { if (m_bOutlinedText) {
@ -1434,7 +1497,7 @@ void UIFakkLabel::Draw(void)
m_iFontAlignmentVertical, m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))), Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
UBlack, UBlack,
m_bVirtual ? m_vVirtualScale : NULL getVirtualScale()
); );
} else { } else {
m_font->PrintJustified( m_font->PrintJustified(
@ -1442,7 +1505,7 @@ void UIFakkLabel::Draw(void)
m_iFontAlignmentHorizontal, m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical, m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))), Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
m_bVirtual ? m_vVirtualScale : NULL getVirtualScale()
); );
} }

File diff suppressed because it is too large Load diff

View file

@ -51,6 +51,9 @@ protected:
void OnDeactivate(Event *ev); void OnDeactivate(Event *ev);
void DrawSubtitleOverlay(void); void DrawSubtitleOverlay(void);
// Added in 2.0
void DrawNetProfile(void);
public: public:
View3D(); View3D();

View file

@ -36,6 +36,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_curl.h" #include "cl_curl.h"
#endif /* USE_CURL */ #endif /* USE_CURL */
#ifdef USE_VOIP
#include <opus.h>
#endif
// file full of random crap that gets used to create cl_guid // file full of random crap that gets used to create cl_guid
#define QKEY_FILE "qkey" #define QKEY_FILE "qkey"
#define QKEY_SIZE 2048 #define QKEY_SIZE 2048
@ -174,6 +178,7 @@ typedef struct {
int lastPacketSentTime; // for retransmits during connection int lastPacketSentTime; // for retransmits during connection
int lastPacketTime; // for timeouts int lastPacketTime; // for timeouts
char servername[MAX_OSPATH]; // name of server from original connect (used by reconnect)
netadr_t serverAddress; netadr_t serverAddress;
int connectTime; // for connection retransmits int connectTime; // for connection retransmits
int connectStartTime; int connectStartTime;
@ -239,15 +244,42 @@ typedef struct {
int timeDemoMaxDuration; // maximum frame duration int timeDemoMaxDuration; // maximum frame duration
unsigned char timeDemoDurations[ MAX_TIMEDEMO_DURATIONS ]; // log of frame durations unsigned char timeDemoDurations[ MAX_TIMEDEMO_DURATIONS ]; // log of frame durations
float aviVideoFrameRemainder;
float aviSoundFrameRemainder;
#ifdef USE_VOIP
qboolean voipEnabled;
qboolean voipCodecInitialized;
// incoming data...
// !!! FIXME: convert from parallel arrays to array of a struct.
OpusDecoder *opusDecoder[MAX_CLIENTS];
byte voipIncomingGeneration[MAX_CLIENTS];
int voipIncomingSequence[MAX_CLIENTS];
float voipGain[MAX_CLIENTS];
qboolean voipIgnore[MAX_CLIENTS];
qboolean voipMuteAll;
// outgoing data...
// if voipTargets[i / 8] & (1 << (i % 8)),
// then we are sending to clientnum i.
uint8_t voipTargets[(MAX_CLIENTS + 7) / 8];
uint8_t voipFlags;
OpusEncoder *opusEncoder;
int voipOutgoingDataSize;
int voipOutgoingDataFrames;
int voipOutgoingSequence;
byte voipOutgoingGeneration;
byte voipOutgoingData[1024];
float voipPower;
#endif
#ifdef LEGACY_PROTOCOL #ifdef LEGACY_PROTOCOL
qboolean compat; qboolean compat;
#endif #endif
// big stuff at end of structure so most offsets are 15 bits or less // big stuff at end of structure so most offsets are 15 bits or less
netchan_t netchan; netchan_t netchan;
float aviVideoFrameRemainder;
float aviSoundFrameRemainder;
} clientConnection_t; } clientConnection_t;
extern clientConnection_t clc; extern clientConnection_t clc;
@ -297,8 +329,6 @@ typedef struct {
qboolean cddialog; // bring up the cd needed dialog next frame qboolean cddialog; // bring up the cd needed dialog next frame
qboolean no_menus; qboolean no_menus;
char servername[MAX_OSPATH]; // name of server from original connect (used by reconnect)
// when the server clears the hunk, all of these must be restarted // when the server clears the hunk, all of these must be restarted
qboolean rendererRegistered; qboolean rendererRegistered;
qboolean cgameStarted; qboolean cgameStarted;
@ -353,12 +383,14 @@ typedef struct {
void* savedCgameState; void* savedCgameState;
size_t savedCgameStateSize; size_t savedCgameStateSize;
char gcdResponse[73]; char gcdResponse[73];
int unknown3_0; // Added in 2.0
int currentRate; netprofclient_t netprofile;
qhandle_t charSetShader; qhandle_t charSetShader;
qhandle_t whiteShader; qhandle_t whiteShader;
qhandle_t consoleShader; qhandle_t consoleShader;
fontInfo_t consoleFont; fontInfo_t consoleFont;
int refSequence;
} clientStatic_t; } clientStatic_t;
extern clientStatic_t cls; extern clientStatic_t cls;
@ -385,6 +417,8 @@ extern cvar_t *cl_connect_timeout;
extern cvar_t *cl_maxpackets; extern cvar_t *cl_maxpackets;
extern cvar_t *cl_packetdup; extern cvar_t *cl_packetdup;
extern cvar_t *cl_shownet; extern cvar_t *cl_shownet;
extern cvar_t *cl_netprofile;
extern cvar_t *cl_netprofileoverlay;
extern cvar_t *cl_showSend; extern cvar_t *cl_showSend;
extern cvar_t *cl_timeNudge; extern cvar_t *cl_timeNudge;
extern cvar_t *cl_showTimeDelta; extern cvar_t *cl_showTimeDelta;
@ -445,6 +479,32 @@ extern cvar_t *cl_r_fullscreen;
extern cvar_t *cl_consoleKeys; extern cvar_t *cl_consoleKeys;
#ifdef USE_MUMBLE
extern cvar_t *cl_useMumble;
extern cvar_t *cl_mumbleScale;
#endif
#ifdef USE_VOIP
// cl_voipSendTarget is a string: "all" to broadcast to everyone, "none" to
// send to no one, or a comma-separated list of client numbers:
// "0,7,2,23" ... an empty string is treated like "all".
extern cvar_t *cl_voipUseVAD;
extern cvar_t *cl_voipVADThreshold;
extern cvar_t *cl_voipSend;
extern cvar_t *cl_voipSendTarget;
extern cvar_t *cl_voipGainDuringCapture;
extern cvar_t *cl_voipCaptureMult;
extern cvar_t *cl_voipShowMeter;
extern cvar_t *cl_voip;
// 20ms at 48k
#define VOIP_MAX_FRAME_SAMPLES ( 20 * 48 )
// 3 frame is 60ms of audio, the max opus will encode at once
#define VOIP_MAX_PACKET_FRAMES 3
#define VOIP_MAX_PACKET_SAMPLES ( VOIP_MAX_FRAME_SAMPLES * VOIP_MAX_PACKET_FRAMES )
#endif
extern cvar_t *cg_gametype; extern cvar_t *cg_gametype;
extern cvar_t* j_pitch; extern cvar_t* j_pitch;
@ -499,6 +559,10 @@ void UI_LoadResource( const char *name );
qboolean CL_CheckPaused(void); qboolean CL_CheckPaused(void);
int CL_GetRefSequence(void);
qboolean CL_IsRendererLoaded(void);
void CL_ApplyOriginalConfigTweaks();
// //
// cl_input // cl_input
// //
@ -520,6 +584,7 @@ void IN_MouseOn( void );
void IN_MouseOff( void ); void IN_MouseOff( void );
void CL_InitInput (void); void CL_InitInput (void);
void CL_ShutdownInput(void);
void CL_SendCmd (void); void CL_SendCmd (void);
void CL_ClearState (void); void CL_ClearState (void);
void CL_ReadPackets (void); void CL_ReadPackets (void);
@ -545,6 +610,10 @@ extern int cl_connectedToPureServer;
extern int cl_connectedToCheatServer; extern int cl_connectedToCheatServer;
extern msg_t *cl_currentMSG; extern msg_t *cl_currentMSG;
#ifdef USE_VOIP
void CL_Voip_f( void );
#endif
void CL_SystemInfoChanged( void ); void CL_SystemInfoChanged( void );
void CL_ParseServerMessage( msg_t *msg ); void CL_ParseServerMessage( msg_t *msg );
@ -583,6 +652,7 @@ void Con_DrawCharacter (int cx, int line, int num);
void Con_CheckResize (void); void Con_CheckResize (void);
void Con_Init (void); void Con_Init (void);
void Con_Shutdown (void);
void Con_Clear_f (void); void Con_Clear_f (void);
void Con_ToggleConsole_f (void); void Con_ToggleConsole_f (void);
void Con_DrawNotify (void); void Con_DrawNotify (void);
@ -670,6 +740,7 @@ void LAN_SaveServersToCache( void );
void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg); //int length, const byte *data ); void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg); //int length, const byte *data );
void CL_Netchan_TransmitNextFragment( netchan_t *chan ); void CL_Netchan_TransmitNextFragment( netchan_t *chan );
qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg ); qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg );
void CL_NET_OutOfBandPrint( netadr_t adr, const char* format, ... );
// //
// cl_avi.c // cl_avi.c

View file

@ -59,6 +59,9 @@ typedef struct {
void S_ChannelFree_Callback(channel_t* v); void S_ChannelFree_Callback(channel_t* v);
void S_LoadData(soundsystemsavegame_t* pSave); void S_LoadData(soundsystemsavegame_t* pSave);
void S_SaveData(soundsystemsavegame_t* pSave); void S_SaveData(soundsystemsavegame_t* pSave);
void S_ReLoad(soundsystemsavegame_t* pSave);
extern qboolean s_bSoundPaused;
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -21,8 +21,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "../snd_local.h" #include "../snd_local.h"
#include "../client.h"
#if !defined(USE_SOUND_NEW) || !USE_SOUND_NEW #if defined(NO_MODERN_DMA) && NO_MODERN_DMA
qboolean s_bSoundPaused = qfalse;
void S_Init2() void S_Init2()
{ {
@ -32,6 +35,10 @@ void S_Init2()
// HACK: S_RegisterSound returns 0 when unsuccessful, or it returns the the sfx handle // HACK: S_RegisterSound returns 0 when unsuccessful, or it returns the the sfx handle
// But the first sfx handle is also 0... // But the first sfx handle is also 0...
S_RegisterSound("sound/null.wav", qfalse); S_RegisterSound("sound/null.wav", qfalse);
Cmd_AddCommand("tmstart", S_TriggeredMusic_Start);
Cmd_AddCommand("tmstartloop", S_TriggeredMusic_StartLoop);
Cmd_AddCommand("tmstop", S_TriggeredMusic_Stop);
} }
/* /*
@ -52,7 +59,18 @@ S_AddLoopingSound
*/ */
void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle, float volume, float minDist, float maxDist, float pitch, int flags) void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle, float volume, float minDist, float maxDist, float pitch, int flags)
{ {
if (!sfxHandle) {
return;
}
// FIXME: unimplemented // FIXME: unimplemented
if (VectorCompare(origin, vec3_origin)) {
// Consider it to be a local sound, uses the player origin
S_AddLoopingSound(cl.snap.ps.clientNum, cl.snap.ps.origin, velocity, sfxHandle);
return;
}
S_AddLoopingSound(ENTITYNUM_WORLD, origin, velocity, sfxHandle); S_AddLoopingSound(ENTITYNUM_WORLD, origin, velocity, sfxHandle);
} }
@ -363,6 +381,16 @@ void MUSIC_CheckForStoppedSongs(void)
STUB(); STUB();
} }
/*
==============
S_CurrentSoundtrack
==============
*/
const char* S_CurrentSoundtrack()
{
return "";
}
/* /*
================= =================
S_IsSoundRegistered S_IsSoundRegistered
@ -427,28 +455,166 @@ void S_FadeSound(float fTime)
// FIXME: unimplemented // FIXME: unimplemented
} }
/*
==============
S_TriggeredMusic_Start
==============
*/
void S_TriggeredMusic_Start()
{
if (Cmd_Argc() != 2) {
Com_Printf("tmstart <sound file>\n");
return;
}
S_StartBackgroundTrack(Cmd_Argv(1), "");
}
/*
==============
S_TriggeredMusic_StartLoop
==============
*/
void S_TriggeredMusic_StartLoop()
{
if (Cmd_Argc() != 2) {
Com_Printf("tmstartloop <sound file>\n");
return;
}
S_StartBackgroundTrack(Cmd_Argv(1), Cmd_Argv(1));
}
/*
==============
S_TriggeredMusic_Stop
==============
*/
void S_TriggeredMusic_Stop()
{
S_StopBackgroundTrack();
}
/*
==============
S_TriggeredMusic_PlayIntroMusic
==============
*/
void S_TriggeredMusic_PlayIntroMusic() { void S_TriggeredMusic_PlayIntroMusic() {
S_StartBackgroundTrack("sound/music/mus_MainTheme.mp3", "");
}
/*
==============
S_TriggeredMusic_SetupHandle
==============
*/
void S_TriggeredMusic_SetupHandle(const char* pszName, int iLoopCount, int iOffset, qboolean autostart) {
// FIXME: unimplemented // FIXME: unimplemented
} }
/*
==============
S_GetMusicFilename
==============
*/
const char* S_GetMusicFilename() {
// FIXME: unimplemented
return "";
}
/*
==============
S_GetMusicLoopCount
==============
*/
int S_GetMusicLoopCount() {
// FIXME: unimplemented
return 0;
}
/*
==============
S_GetMusicOffset
==============
*/
unsigned int S_GetMusicOffset() {
// FIXME: unimplemented
return 0;
}
/*
==============
callbackServer
==============
*/
void callbackServer(int entnum, int channel_number, const char* name) { void callbackServer(int entnum, int channel_number, const char* name) {
if (com_sv_running->integer) { if (com_sv_running->integer) {
SV_SoundCallback(entnum, channel_number, name); SV_SoundCallback(entnum, channel_number, name);
} }
} }
/*
==============
S_ChannelFree_Callback
==============
*/
void S_ChannelFree_Callback(channel_t* v) { void S_ChannelFree_Callback(channel_t* v) {
if (v->entnum & S_FLAG_DO_CALLBACK) { if (v->entnum & S_FLAG_DO_CALLBACK) {
callbackServer(v->entnum & ~S_FLAG_DO_CALLBACK, v - s_channels, v->thesfx->soundName); callbackServer(v->entnum & ~S_FLAG_DO_CALLBACK, v - s_channels, v->thesfx->soundName);
} }
} }
/*
==============
S_LoadData
==============
*/
void S_LoadData(soundsystemsavegame_t* pSave) { void S_LoadData(soundsystemsavegame_t* pSave) {
// FIXME: unimplemented // FIXME: unimplemented
} }
/*
==============
S_SaveData
==============
*/
void S_SaveData(soundsystemsavegame_t* pSave) { void S_SaveData(soundsystemsavegame_t* pSave) {
// FIXME: unimplemented // FIXME: unimplemented
} }
/*
==============
S_ReLoad
==============
*/
void S_ReLoad(soundsystemsavegame_t* pSave) {
// FIXME: unimplemented
}
/*
==============
S_StopMovieAudio
==============
*/
void S_StopMovieAudio() {
}
/*
==============
S_CurrentMoviePosition
==============
*/
int S_CurrentMoviePosition() {
return 0;
}
/*
==============
S_SetupMovieAudio
==============
*/
void S_SetupMovieAudio(const char* pszMovieName) {
}
#endif #endif

View file

@ -64,6 +64,12 @@ qboolean MUSIC_PlaySong(const char* alias);
void MUSIC_UpdateMusicVolumes(void); void MUSIC_UpdateMusicVolumes(void);
void MUSIC_CheckForStoppedSongs(void); void MUSIC_CheckForStoppedSongs(void);
void S_TriggeredMusic_Start();
void S_TriggeredMusic_StartLoop();
void S_TriggeredMusic_Stop();
const char* S_CurrentSoundtrack();
void S_StopSound(int entnum, int channel); void S_StopSound(int entnum, int channel);
void S_StopAllSounds2(qboolean stop_music); void S_StopAllSounds2(qboolean stop_music);
float S_GetSoundTime(sfxHandle_t handle); float S_GetSoundTime(sfxHandle_t handle);
@ -74,6 +80,15 @@ qboolean S_IsSoundPlaying(int channelNumber, const char* name);
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t velocity, qboolean use_listener); void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t velocity, qboolean use_listener);
void S_FadeSound(float fTime); void S_FadeSound(float fTime);
void S_TriggeredMusic_PlayIntroMusic(); void S_TriggeredMusic_PlayIntroMusic();
void S_TriggeredMusic_SetupHandle(const char* pszName, int iLoopCount, int iOffset, qboolean autostart);
const char* S_GetMusicFilename();
int S_GetMusicLoopCount();
unsigned int S_GetMusicOffset();
void S_StopMovieAudio();
int S_CurrentMoviePosition();
void S_SetupMovieAudio(const char* pszMovieName);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -66,6 +66,7 @@ LPALGETSOURCEF qalGetSourcef;
LPALGETSOURCE3F qalGetSource3f; LPALGETSOURCE3F qalGetSource3f;
LPALGETSOURCEFV qalGetSourcefv; LPALGETSOURCEFV qalGetSourcefv;
LPALGETSOURCEI qalGetSourcei; LPALGETSOURCEI qalGetSourcei;
LPALGETSOURCEIV qalGetSourceiv;
LPALSOURCEPLAYV qalSourcePlayv; LPALSOURCEPLAYV qalSourcePlayv;
LPALSOURCESTOPV qalSourceStopv; LPALSOURCESTOPV qalSourceStopv;
LPALSOURCEREWINDV qalSourceRewindv; LPALSOURCEREWINDV qalSourceRewindv;
@ -80,7 +81,9 @@ LPALGENBUFFERS qalGenBuffers;
LPALDELETEBUFFERS qalDeleteBuffers; LPALDELETEBUFFERS qalDeleteBuffers;
LPALISBUFFER qalIsBuffer; LPALISBUFFER qalIsBuffer;
LPALBUFFERDATA qalBufferData; LPALBUFFERDATA qalBufferData;
LPALBUFFERI qalBufferi;
LPALGETBUFFERF qalGetBufferf; LPALGETBUFFERF qalGetBufferf;
LPALGETBUFFERFV qalGetBufferfv;
LPALGETBUFFERI qalGetBufferi; LPALGETBUFFERI qalGetBufferi;
LPALDOPPLERFACTOR qalDopplerFactor; LPALDOPPLERFACTOR qalDopplerFactor;
LPALSPEEDOFSOUND qalSpeedOfSound; LPALSPEEDOFSOUND qalSpeedOfSound;
@ -184,6 +187,7 @@ qboolean QAL_Init(const char *libname)
qalGetSource3f = GPA("alGetSource3f"); qalGetSource3f = GPA("alGetSource3f");
qalGetSourcefv = GPA("alGetSourcefv"); qalGetSourcefv = GPA("alGetSourcefv");
qalGetSourcei = GPA("alGetSourcei"); qalGetSourcei = GPA("alGetSourcei");
qalGetSourceiv = GPA("alGetSourceiv");
qalSourcePlayv = GPA("alSourcePlayv"); qalSourcePlayv = GPA("alSourcePlayv");
qalSourceStopv = GPA("alSourceStopv"); qalSourceStopv = GPA("alSourceStopv");
qalSourceRewindv = GPA("alSourceRewindv"); qalSourceRewindv = GPA("alSourceRewindv");
@ -198,7 +202,9 @@ qboolean QAL_Init(const char *libname)
qalDeleteBuffers = GPA("alDeleteBuffers"); qalDeleteBuffers = GPA("alDeleteBuffers");
qalIsBuffer = GPA("alIsBuffer"); qalIsBuffer = GPA("alIsBuffer");
qalBufferData = GPA("alBufferData"); qalBufferData = GPA("alBufferData");
qalBufferi = GPA("alBufferi");
qalGetBufferf = GPA("alGetBufferf"); qalGetBufferf = GPA("alGetBufferf");
qalGetBufferfv = GPA("alGetBufferfv");
qalGetBufferi = GPA("alGetBufferi"); qalGetBufferi = GPA("alGetBufferi");
qalDopplerFactor = GPA("alDopplerFactor"); qalDopplerFactor = GPA("alDopplerFactor");
qalSpeedOfSound = GPA("alSpeedOfSound"); qalSpeedOfSound = GPA("alSpeedOfSound");
@ -283,6 +289,7 @@ void QAL_Shutdown( void )
qalGetSource3f = NULL; qalGetSource3f = NULL;
qalGetSourcefv = NULL; qalGetSourcefv = NULL;
qalGetSourcei = NULL; qalGetSourcei = NULL;
qalGetSourceiv = NULL;
qalSourcePlayv = NULL; qalSourcePlayv = NULL;
qalSourceStopv = NULL; qalSourceStopv = NULL;
qalSourceRewindv = NULL; qalSourceRewindv = NULL;
@ -298,6 +305,7 @@ void QAL_Shutdown( void )
qalIsBuffer = NULL; qalIsBuffer = NULL;
qalBufferData = NULL; qalBufferData = NULL;
qalGetBufferf = NULL; qalGetBufferf = NULL;
qalGetBufferfv = NULL;
qalGetBufferi = NULL; qalGetBufferi = NULL;
qalDopplerFactor = NULL; qalDopplerFactor = NULL;
qalSpeedOfSound = NULL; qalSpeedOfSound = NULL;

View file

@ -36,15 +36,18 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifdef USE_LOCAL_HEADERS #ifdef USE_LOCAL_HEADERS
#include "../AL/al.h" #include "../AL/al.h"
#include "../AL/alc.h" #include "../AL/alc.h"
#include "../AL/alext.h"
#else #else
#if defined(_MSC_VER) || defined(__APPLE__) #if defined(_MSC_VER) || defined(__APPLE__)
// MSVC users must install the OpenAL SDK which doesn't use the AL/*.h scheme. // MSVC users must install the OpenAL SDK which doesn't use the AL/*.h scheme.
// OSX framework also needs this // OSX framework also needs this
#include <al.h> #include <al.h>
#include <alc.h> #include <alc.h>
#include <alext.h>
#else #else
#include <AL/al.h> #include <AL/al.h>
#include <AL/alc.h> #include <AL/alc.h>
#include <AL/alext.h>
#endif #endif
#endif #endif
@ -55,6 +58,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# define ALC_ALL_DEVICES_SPECIFIER 0x1013 # define ALC_ALL_DEVICES_SPECIFIER 0x1013
#endif #endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef USE_OPENAL_DLOPEN #ifdef USE_OPENAL_DLOPEN
extern LPALENABLE qalEnable; extern LPALENABLE qalEnable;
extern LPALDISABLE qalDisable; extern LPALDISABLE qalDisable;
@ -116,7 +123,7 @@ extern LPALBUFFERDATA qalBufferData;
extern LPALBUFFERF qalBufferf; extern LPALBUFFERF qalBufferf;
extern LPALBUFFER3F qalBuffer3f; extern LPALBUFFER3F qalBuffer3f;
extern LPALBUFFERFV qalBufferfv; extern LPALBUFFERFV qalBufferfv;
extern LPALBUFFERF qalBufferi; extern LPALBUFFERI qalBufferi;
extern LPALBUFFER3F qalBuffer3i; extern LPALBUFFER3F qalBuffer3i;
extern LPALBUFFERFV qalBufferiv; extern LPALBUFFERFV qalBufferiv;
extern LPALGETBUFFERF qalGetBufferf; extern LPALGETBUFFERF qalGetBufferf;
@ -248,4 +255,8 @@ extern LPALCCAPTURESAMPLES qalcCaptureSamples;
qboolean QAL_Init(const char *libname); qboolean QAL_Init(const char *libname);
void QAL_Shutdown( void ); void QAL_Shutdown( void );
#ifdef __cplusplus
}
#endif
#endif // __QAL_H__ #endif // __QAL_H__

View file

@ -27,14 +27,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/q_shared.h" #include "../qcommon/q_shared.h"
#include "../qcommon/qcommon.h" #include "../qcommon/qcommon.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct snd_info_s typedef struct snd_info_s
{ {
int rate; int rate;
int width; float width;
int channels; int channels;
int samples; int samples;
int size; int size;
int dataofs; int dataofs;
int dataalign;
} snd_info_t; } snd_info_t;
typedef struct snd_codec_s snd_codec_t; typedef struct snd_codec_s snd_codec_t;
@ -113,4 +118,8 @@ void S_OggOpus_CodecCloseStream(snd_stream_t *stream);
int S_OggOpus_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer); int S_OggOpus_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer);
#endif // USE_CODEC_OPUS #endif // USE_CODEC_OPUS
#ifdef __cplusplus
}
#endif
#endif // !_SND_CODEC_H_ #endif // !_SND_CODEC_H_

View file

@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "snd_codec.h" #include "snd_codec.h"
// includes for the MP3 codec // includes for the MP3 codec
#include "../libmad-0.15.1b/synth.h" #include "mad.h"
#define MP3_SAMPLE_WIDTH 2 #define MP3_SAMPLE_WIDTH 2
#define MP3_PCMSAMPLES_PERSLICE 32 #define MP3_PCMSAMPLES_PERSLICE 32
@ -622,7 +622,7 @@ int S_MP3_CodecReadStream(snd_stream_t* stream, int bytes, void* buffer)
mp3info = stream->ptr; mp3info = stream->ptr;
// Make sure we get complete frames all the way through. // Make sure we get complete frames all the way through.
bytes -= bytes % (stream->info.channels * stream->info.width); bytes -= fmod(bytes, (stream->info.channels * stream->info.width));
if (mp3info->buflen) if (mp3info->buflen)
{ {

View file

@ -133,6 +133,7 @@ static qboolean S_ReadRIFFHeader(fileHandle_t file, snd_info_t *info)
char dump[16]; char dump[16];
int bits; int bits;
int fmtlen = 0; int fmtlen = 0;
int bytealign;
// skip the riff wav header // skip the riff wav header
FS_Read(dump, 12, file); FS_Read(dump, 12, file);
@ -149,17 +150,22 @@ static qboolean S_ReadRIFFHeader(fileHandle_t file, snd_info_t *info)
info->channels = FGetLittleShort(file); info->channels = FGetLittleShort(file);
info->rate = FGetLittleLong(file); info->rate = FGetLittleLong(file);
FGetLittleLong(file); FGetLittleLong(file);
FGetLittleShort(file); bytealign = FGetLittleShort(file);
bits = FGetLittleShort(file); bits = FGetLittleShort(file);
if( bits < 8 ) //if( bits < 8 )
{ //{
Com_Printf( S_COLOR_RED "ERROR: Less than 8 bit sound is not supported\n"); // Com_Printf( S_COLOR_RED "ERROR: Less than 8 bit sound is not supported\n");
return qfalse; // return qfalse;
} //}
info->width = bits / 8; info->width = bits / 8.0;
info->dataofs = 0; info->dataofs = 0;
if (bits == 16) {
info->dataalign = 1;
} else {
info->dataalign = (bytealign / info->channels - 4) / 4 * 8 + 1;
}
// Skip the rest of the format chunk if required // Skip the rest of the format chunk if required
if(fmtlen > 16) if(fmtlen > 16)

View file

@ -161,12 +161,12 @@ void S_Base_SoundList( void ) {
char type[4][16]; char type[4][16];
char mem[2][16]; char mem[2][16];
strcpy(type[0], "16bit"); Q_strncpyz(type[0], "16bit", sizeof(type[0]));
strcpy(type[1], "adpcm"); Q_strncpyz(type[1], "adpcm", sizeof(type[1]));
strcpy(type[2], "daub4"); Q_strncpyz(type[2], "daub4", sizeof(type[2]));
strcpy(type[3], "mulaw"); Q_strncpyz(type[3], "mulaw", sizeof(type[3]));
strcpy(mem[0], "paged out"); Q_strncpyz(mem[0], "paged out", sizeof(mem[0]));
strcpy(mem[1], "resident "); Q_strncpyz(mem[1], "resident ", sizeof(mem[1]));
total = 0; total = 0;
for (sfx=s_knownSfx, i=0 ; i<s_numSfx ; i++, sfx++) { for (sfx=s_knownSfx, i=0 ; i<s_numSfx ; i++, sfx++) {
size = sfx->soundLength; size = sfx->soundLength;
@ -303,7 +303,7 @@ static sfx_t *S_FindName( const char *name ) {
sfx = &s_knownSfx[i]; sfx = &s_knownSfx[i];
Com_Memset (sfx, 0, sizeof(*sfx)); Com_Memset (sfx, 0, sizeof(*sfx));
strcpy (sfx->soundName, name); Q_strncpyz (sfx->soundName, name, sizeof(sfx->soundName));
sfx->next = sfxHash[hash]; sfx->next = sfxHash[hash];
sfxHash[hash] = sfx; sfxHash[hash] = sfx;
@ -785,7 +785,11 @@ void S_Base_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t ve
} }
if ( !sfx->soundLength ) { if ( !sfx->soundLength ) {
Com_Error( ERR_DROP, "%s has length 0", sfx->soundName ); // Fixed in OPM
// Why should it crash???
//Com_Error( ERR_DROP, "%s has length 0", sfx->soundName );
Com_Printf( "%s has length 0\n", sfx->soundName );
return;
} }
VectorCopy( origin, loopSounds[entityNum].origin ); VectorCopy( origin, loopSounds[entityNum].origin );
@ -848,7 +852,11 @@ void S_Base_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_
} }
if ( !sfx->soundLength ) { if ( !sfx->soundLength ) {
Com_Error( ERR_DROP, "%s has length 0", sfx->soundName ); // Fixed in OPM
// Why should it crash???
//Com_Error( ERR_DROP, "%s has length 0", sfx->soundName );
Com_Printf( "%s has length 0", sfx->soundName );
return;
} }
VectorCopy( origin, loopSounds[entityNum].origin ); VectorCopy( origin, loopSounds[entityNum].origin );
VectorCopy( velocity, loopSounds[entityNum].velocity ); VectorCopy( velocity, loopSounds[entityNum].velocity );

View file

@ -20,10 +20,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=========================================================================== ===========================================================================
*/ */
#if USE_SOUND_NEW
#include "snd_local.h" #include "snd_local.h"
#include "snd_openal_new.h" #include "snd_openal_new.h"
#include "client.h"
#include "cl_ui.h"
typedef struct { typedef struct {
vec3_t origin; vec3_t origin;
@ -32,10 +32,6 @@ typedef struct {
int mergeFrame; int mergeFrame;
} loopSound_t; } loopSound_t;
# define MAX_SFX 1400
# define MAX_SFX_INFOS 1000
# define MAX_LOOP_SOUNDS 64
qboolean s_bLastInitSound = qfalse; qboolean s_bLastInitSound = qfalse;
qboolean s_bSoundStarted = qfalse; qboolean s_bSoundStarted = qfalse;
qboolean s_bSoundPaused = qfalse; qboolean s_bSoundPaused = qfalse;
@ -70,81 +66,412 @@ cvar_t *s_dialogscale;
int numLoopSounds; int numLoopSounds;
loopSound_t loopSounds[MAX_LOOP_SOUNDS]; loopSound_t loopSounds[MAX_LOOP_SOUNDS];
/*
==============
S_SoundInfo_f
==============
*/
void S_SoundInfo_f() void S_SoundInfo_f()
{ {
// FIXME: unimplemented S_PrintInfo();
} }
/*
==============
S_SoundDump_f
==============
*/
void S_SoundDump_f() void S_SoundDump_f()
{ {
// FIXME: unimplemented S_DumpInfo();
} }
/*
==============
S_Init
==============
*/
void S_Init(qboolean full_startup) void S_Init(qboolean full_startup)
{ {
// FIXME: unimplemented int iStart, iEnd;
cvar_t *cv;
Com_Printf("------- Sound Initialization (%s) -------\n", full_startup ? "full" : "partial");
iStart = Sys_Milliseconds();
s_volume = Cvar_Get("s_volume", "0.9", CVAR_ARCHIVE);
s_musicVolume = Cvar_Get("s_musicvolume", "0.9", CVAR_ARCHIVE);
s_ambientVolume = Cvar_Get("s_ambientvolume", "1.00", CVAR_ARCHIVE);
s_separation = Cvar_Get("s_separation", "0.5", CVAR_ARCHIVE);
s_khz = Cvar_Get("s_khz", "44", CVAR_ARCHIVE | CVAR_SOUND_LATCH);
s_loadas8bit = Cvar_Get("s_loadas8bit", "0", CVAR_ARCHIVE | CVAR_LATCH);
s_mixPreStep = Cvar_Get("s_mixPreStep", "0.05", CVAR_ARCHIVE);
s_show = Cvar_Get("s_show", "0", CVAR_CHEAT);
s_testsound = Cvar_Get("s_testsound", "0", CVAR_CHEAT);
s_dialogscale = Cvar_Get("s_dialogscale", "1", CVAR_ARCHIVE);
s_bLastInitSound = false;
cv = Cvar_Get("s_initsound", "1", 0);
if (cv->integer) {
Cmd_AddCommand("play", S_Play);
Cmd_AddCommand("soundlist", S_SoundList);
Cmd_AddCommand("soundinfo", S_SoundInfo_f);
Cmd_AddCommand("sounddump", S_SoundDump_f);
if (S_Driver_Init()) {
s_bLastInitSound = true;
s_bSoundStarted = true;
if (full_startup) {
s_numSfx = 0;
S_StopAllSounds(true);
}
S_FindName("***DEFAULT***", -1);
S_SoundInfo_f();
}
} else {
Com_Printf("Sound Not Initializing.\n");
s_bSoundStarted = 0;
}
iEnd = Sys_Milliseconds();
Com_Printf("------- Sound Initialization Complete ------- %i ms\n", iEnd - iStart);
} }
/*
==============
S_Shutdown
==============
*/
void S_Shutdown(qboolean full_shutdown) void S_Shutdown(qboolean full_shutdown)
{ {
// FIXME: unimplemented int i;
sfx_t *sfx;
if (!s_bSoundStarted) {
return;
}
Com_Printf("------- Sound Shutdown (%s) -------\n", full_shutdown ? "full" : "partial");
S_Driver_Shutdown();
s_bSoundStarted = false;
Cmd_RemoveCommand("play");
Cmd_RemoveCommand("music");
Cmd_RemoveCommand("stopsound");
Cmd_RemoveCommand("soundlist");
Cmd_RemoveCommand("soundinfo");
if (full_shutdown) {
for (i = 0; i < s_numSfx; i++) {
sfx = &s_knownSfx[i];
if (sfx->name[0]) {
if (sfx->data) {
Z_Free(sfx->data);
}
*sfx = {};
}
}
s_numSfx = 0;
}
Com_Printf("------- Sound Shutdown Complete -------\n");
} }
/*
==============
S_NameExists
==============
*/
qboolean S_NameExists(const char *name) qboolean S_NameExists(const char *name)
{ {
// FIXME: unimplemented int i;
if (strlen(name) >= MAX_RES_NAME) {
Com_DPrintf("Sound name too long: %s", name);
return qfalse;
}
for (i = 0; i < s_numSfx; i++) {
if (!strcmp(s_knownSfx[i].name, name)) {
return qtrue;
}
}
return qfalse; return qfalse;
} }
/*
==============
S_FindName
==============
*/
sfx_t *S_FindName(const char *name, int sequenceNumber) sfx_t *S_FindName(const char *name, int sequenceNumber)
{ {
// FIXME: unimplemented int i;
return NULL; sfx_t *sfx;
if (!name) {
Com_DPrintf("S_FindName: NULL\n");
return NULL;
}
if (!name[0]) {
Com_DPrintf("S_FindName: empty name\n");
return NULL;
}
if (strlen(name) >= MAX_RES_NAME) {
Com_DPrintf("Sound name too long: %s", name);
return NULL;
}
for (i = 0; i < s_numSfx; i++) {
sfx = &s_knownSfx[i];
if (!strcmp(sfx->name, name)) {
if (sfx->registration_sequence != -1) {
sfx->registration_sequence = sequenceNumber;
}
return sfx;
}
}
sfx = &s_knownSfx[0];
for (i = 0; i < s_numSfx; i++) {
sfx = &s_knownSfx[i];
if (!sfx->name[0]) {
break;
}
}
if (i == s_numSfx) {
if (i == MAX_SFX) {
Com_Error(ERR_FATAL, "S_FindName: out of sfx_t");
}
sfx = &s_knownSfx[s_numSfx];
s_numSfx++;
}
*sfx = {};
// Fixed in OPM
// strcpy was used before
//strcpy(sfx->name, name);
Q_strncpyz(sfx->name, name, sizeof(sfx->name));
sfx->registration_sequence = sequenceNumber;
return sfx;
} }
/*
==============
S_BeginRegistration
==============
*/
void S_BeginRegistration() void S_BeginRegistration()
{ {
// FIXME: unimplemented int i;
Com_Printf("------- Sound Begin Registration -------\n");
S_StopAllSounds(true);
s_registrationSequence++;
s_inRegistration = true;
s_knownSfx[0].registration_sequence = s_registrationSequence;
Com_Printf("------- Sound Begin Registration Complete -------\n");
// Added in OPM
// Reset all sound entities
// OG doesn't do this but this makes sure
// entities don't leak info from previous sessions
for (i = 0; i < ARRAY_LEN(s_entity); i++) {
s_entity[i] = s_entity_t{};
}
} }
/*
==============
S_DefaultSound
==============
*/
void S_DefaultSound(sfx_t *sfx) void S_DefaultSound(sfx_t *sfx)
{ {
// FIXME: unimplemented sfx->data = NULL;
sfx->iFlags |= SFX_FLAG_DEFAULT_SOUND;
} }
/*
==============
S_IsSoundRegistered
==============
*/
qboolean S_IsSoundRegistered(const char *name) qboolean S_IsSoundRegistered(const char *name)
{ {
// FIXME: unimplemented char szCacheName[MAX_QPATH];
return qfalse; int i;
if (!s_bSoundStarted) {
return qfalse;
}
for (i = 0; name[i] && i < MAX_QPATH; i++) {
szCacheName[i] = tolower(name[i]);
}
szCacheName[i] = 0;
if (i >= MAX_QPATH) {
Com_Printf("Sound name exceeds MAX_QPATH\n");
return qfalse;
}
return S_NameExists(szCacheName);
} }
/*
==============
S_RegisterSound
==============
*/
sfxHandle_t S_RegisterSound(const char *name, int streamed, qboolean force_load) sfxHandle_t S_RegisterSound(const char *name, int streamed, qboolean force_load)
{ {
// FIXME: unimplemented char szCacheName[MAX_QPATH];
return 0; sfx_t *sfx;
int i;
if (!s_bSoundStarted) {
Com_Printf("ERROR: Trying to register sound %s when soundsystem hasn't started.\n", name);
return 0;
}
if (!name) {
return 0;
}
for (i = 0; name[i] && i < MAX_QPATH; i++) {
szCacheName[i] = tolower(name[i]);
}
szCacheName[i] = 0;
if (i >= MAX_QPATH) {
Com_Printf("Sound name exceeds MAX_QPATH\n");
return 0;
}
sfx = S_FindName(szCacheName, s_registrationSequence);
if (!sfx) {
return 0;
}
if (!sfx->data) {
if (!S_LoadSound(sfx->name, sfx, streamed, force_load)) {
Com_DPrintf("Couldn't load sound: %s\n", sfx->name);
if (!S_LoadSound("sound/default.wav", sfx, streamed, 0)) {
Com_DPrintf("Couldn't load sound: sound/default.wav\n");
sfx->iFlags |= SFX_FLAG_DEFAULT_SOUND;
return 0;
}
}
sfx->iFlags &= ~SFX_FLAG_DEFAULT_SOUND;
sfx->sfx_info_index = 0;
for (i = 0; i < number_of_sfx_infos; i++) {
if (!Q_stricmp(sfx->name, sfx_infos[i].name)) {
sfx->sfx_info_index = i;
break;
}
}
}
return sfx - s_knownSfx;
} }
/*
==============
S_GetSoundTime
==============
*/
float S_GetSoundTime(sfxHandle_t handle) float S_GetSoundTime(sfxHandle_t handle)
{ {
// FIXME: unimplemented return s_knownSfx[handle].time_length;
return 0;
} }
/*
==============
S_EndRegistration
==============
*/
void S_EndRegistration() void S_EndRegistration()
{ {
// FIXME: unimplemented int i;
sfx_t *sfx;
Com_Printf("------- Sound End Registration -------\n");
s_inRegistration = qfalse;
for (i = 0; i < s_numSfx; i++) {
sfx = &s_knownSfx[i];
if (!sfx->name[0]) {
continue;
}
if (sfx->registration_sequence && sfx->registration_sequence != s_registrationSequence) {
if (sfx->data) {
Z_Free(sfx->data);
}
*sfx = {};
}
}
Com_Printf("------- Sound End Registration Complete -------\n");
} }
/*
==============
S_UpdateEntity
==============
*/
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t vel, qboolean use_listener) void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t vel, qboolean use_listener)
{ {
// FIXME: unimplemented if (entityNum > MAX_GENTITIES) {
Com_Error(ERR_DROP, "S_UpdateEntityPosition: bad entitynum %i", entityNum);
}
VectorCopy(origin, s_entity[entityNum].position);
VectorCopy(vel, s_entity[entityNum].velocity);
s_entity[entityNum].use_listener = use_listener;
s_entity[entityNum].time = cl.serverTime;
} }
/*
==============
S_SetGlobalAmbientVolumeLevel
==============
*/
void S_SetGlobalAmbientVolumeLevel(float volume) void S_SetGlobalAmbientVolumeLevel(float volume)
{ {
// FIXME: unimplemented s_fAmbientVolume = volume;
} }
/*
==============
S_StartSound
==============
*/
void S_StartSound( void S_StartSound(
const vec3_t origin, const vec3_t origin,
int entnum, int entnum,
@ -157,29 +484,171 @@ void S_StartSound(
int streamed int streamed
) )
{ {
// FIXME: unimplemented if (s_show_sounds->integer > 0 && sfxHandle > 0 && sfxHandle < s_numSfx) {
Com_DPrintf("S_StartSound: %s\n", s_knownSfx[sfxHandle].name);
}
if (!s_bSoundStarted) {
if (s_show_sounds->integer > 0) {
Com_DPrintf("^~^~^ sound system not yet started\n");
}
return;
}
if (server_loading) {
if (s_show_sounds->integer > 0) {
Com_DPrintf("^~^~^ cannot start sounds while loading a server\n");
}
return;
}
if (sfxHandle < 0 || sfxHandle >= s_numSfx) {
Com_Error(ERR_DROP, "S_StartSound: handle %i out of range", sfxHandle);
}
if (!sfxHandle) {
if (s_show_sounds->integer > 0) {
Com_DPrintf("^~^~^ null handle\n");
}
return;
}
if (entnum && (entchannel == CHAN_DIALOG || entchannel == CHAN_DIALOG_SECONDARY) && s_dialogscale->value > 0) {
volume *= s_dialogscale->value;
}
S_Driver_StartSound(origin, entnum, entchannel, sfxHandle, volume, min_dist, pitch, maxDist, streamed);
} }
/*
==============
S_StartLocalSound
==============
*/
void S_StartLocalSound(const char *sound_name, qboolean force_load) void S_StartLocalSound(const char *sound_name, qboolean force_load)
{ {
// FIXME: unimplemented sfxHandle_t sfxHandle;
const char *name;
AliasListNode_t *pSoundAlias = NULL;
if (!s_bSoundStarted) {
return;
}
if (!sound_name) {
return;
}
name = Alias_FindRandom(sound_name, &pSoundAlias);
if (!name) {
name = sound_name;
}
sfxHandle = S_RegisterSound(name, pSoundAlias ? pSoundAlias->streamed : qfalse, force_load);
if (!pSoundAlias) {
S_StartSound(NULL, s_iListenerNumber, CHAN_MENU, sfxHandle, -1.0, -1.0, 1.0, -1.0, qfalse);
return;
}
S_StartSound(
NULL,
s_iListenerNumber,
CHAN_MENU,
sfxHandle,
pSoundAlias->volume + random() * pSoundAlias->volumeMod,
-1.0,
pSoundAlias->pitch + random() * pSoundAlias->pitchMod,
pSoundAlias->maxDist,
pSoundAlias->streamed
);
} }
/*
==============
S_StartLocalSoundChannel
Added in 2.0
Starts a local sound, with the specified channel
==============
*/
void S_StartLocalSoundChannel(const char *sound_name, qboolean force_load, soundChannel_t channel) void S_StartLocalSoundChannel(const char *sound_name, qboolean force_load, soundChannel_t channel)
{ {
// FIXME: unimplemented sfxHandle_t sfxHandle;
const char *name;
AliasListNode_t *pSoundAlias = NULL;
if (!s_bSoundStarted) {
return;
}
if (!sound_name) {
return;
}
name = Alias_FindRandom(sound_name, &pSoundAlias);
if (!name) {
name = sound_name;
}
sfxHandle = S_RegisterSound(name, pSoundAlias ? pSoundAlias->streamed : qfalse, force_load);
if (!pSoundAlias) {
S_StartSound(NULL, s_iListenerNumber, channel, sfxHandle, -1.0, -1.0, 1.0, -1.0, qfalse);
return;
}
S_StartSound(
0,
s_iListenerNumber,
channel,
sfxHandle,
pSoundAlias->volume + random() * pSoundAlias->volumeMod,
-1.0,
pSoundAlias->pitch + random() * pSoundAlias->pitchMod,
pSoundAlias->maxDist,
pSoundAlias->streamed
);
} }
/*
==============
S_StopAllSounds
==============
*/
void S_StopAllSounds(qboolean stop_music) void S_StopAllSounds(qboolean stop_music)
{ {
// FIXME: unimplemented if (!s_bSoundStarted) {
return;
}
Com_Printf("------- S_StopAllSounds (%s) -------\n", stop_music ? "stop music" : "don't stop music");
// Tell the driver to stop all sounds
S_Driver_StopAllSounds(stop_music);
Com_Printf("------- S_StopAllSounds Complete-------\n");
} }
/*
==============
S_ClearLoopingSounds
==============
*/
void S_ClearLoopingSounds() void S_ClearLoopingSounds()
{ {
// FIXME: unimplemented if (!s_bSoundStarted) {
return;
}
S_Driver_ClearLoopingSounds();
} }
/*
==============
S_AddLoopingSound
==============
*/
void S_AddLoopingSound( void S_AddLoopingSound(
const vec3_t origin, const vec3_t origin,
const vec3_t velocity, const vec3_t velocity,
@ -191,42 +660,171 @@ void S_AddLoopingSound(
int flags int flags
) )
{ {
// FIXME: unimplemented if (!s_bSoundStarted) {
return;
}
if (sfxHandle < 0 || sfxHandle >= s_numSfx) {
Com_Error(ERR_DROP, "S_AddLoopingSound: handle %i out of range", sfxHandle);
}
if (!sfxHandle) {
return;
}
S_Driver_AddLoopingSound(origin, velocity, sfxHandle, volume, min_dist, max_dist, pitch, flags);
} }
/*
==============
S_Respatialize
==============
*/
void S_Respatialize(int entityNum, const vec3_t head, vec3_t axis[3]) void S_Respatialize(int entityNum, const vec3_t head, vec3_t axis[3])
{ {
// FIXME: unimplemented if (!s_bSoundStarted) {
return;
}
S_Driver_Respatialize(entityNum, head, axis);
} }
/*
==============
S_Update
==============
*/
void S_Update() void S_Update()
{ {
// FIXME: unimplemented if (!s_bSoundStarted) {
return;
}
if (server_loading) {
return;
}
S_Driver_Update();
} }
/*
==============
S_StopSound
==============
*/
void S_StopSound(int entnum, int channel) void S_StopSound(int entnum, int channel)
{ {
// FIXME: unimplemented if (!s_bSoundStarted) {
return;
}
if (channel == CHAN_AUTO) {
return;
}
S_Driver_StopSound(entnum, channel);
} }
/*
==============
S_SetReverb
==============
*/
void S_SetReverb(int reverb_type, float reverb_level) void S_SetReverb(int reverb_type, float reverb_level)
{ {
// FIXME: unimplemented if (!s_bSoundStarted) {
return;
}
S_Driver_SetReverb(reverb_type, reverb_level);
} }
/*
==============
S_Play
==============
*/
void S_Play() void S_Play()
{ {
// FIXME: unimplemented int i;
char name[MAX_QPATH];
if (Cmd_Argc() < 2) {
return;
}
for (i = 1; i < Cmd_Argc(); i++) {
if (strrchr(Cmd_Argv(i), '.')) {
Q_strncpyz(name, Cmd_Argv(i), sizeof(name));
} else {
Com_sprintf(name, sizeof(name), "%s.wav", Cmd_Argv(1));
}
}
S_StartLocalSound(name, qfalse);
} }
/*
==============
S_SoundList
==============
*/
void S_SoundList() void S_SoundList()
{ {
// FIXME: unimplemented int i;
sfx_t *sfx;
int size;
int total = 0;
for (i = 0; i < s_numSfx; i++) {
sfx = &s_knownSfx[i];
if (sfx->registration_sequence) {
size = sfx->length * sfx->width;
total += size;
Com_Printf("(%2db) %6i : %s\n", sfx->width * 8, size, sfx->name);
}
}
Com_Printf("Total resident: %i\n", total);
} }
/*
==============
S_ClearSoundBuffer
==============
*/
void S_ClearSoundBuffer() void S_ClearSoundBuffer()
{ {
// TODO: Remove once AL is fully implemented // TODO: Remove once AL is fully implemented
} }
#endif /*
==============
S_GetMusicFilename
==============
*/
const char* S_GetMusicFilename()
{
return S_Driver_GetMusicFilename();
}
/*
==============
S_GetMusicLoopCount
==============
*/
int S_GetMusicLoopCount()
{
return S_Driver_GetMusicLoopCount();
}
/*
==============
S_GetMusicOffset
==============
*/
unsigned int S_GetMusicOffset()
{
return S_Driver_GetMusicOffset();
}

95
code/client/snd_info.cpp Normal file
View file

@ -0,0 +1,95 @@
/*
===========================================================================
Copyright (C) 2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "snd_local.h"
#include "../qcommon/tiki.h"
void load_sfx_info()
{
TikiScript tiki;
const char *token;
int current_sound_file;
char file_name[MAX_QPATH];
sfx_infos[0].name[0] = 0;
sfx_infos[0].max_factor = -1.0;
sfx_infos[0].loop_start = -1;
sfx_infos[0].loop_end = -1;
sfx_infos[0].max_number_playing = DEFAULT_SFX_NUMBER_PLAYING;
number_of_sfx_infos = 1;
for (current_sound_file = 0; current_sound_file < 10; current_sound_file++) {
Com_sprintf(file_name, sizeof(file_name), "global/sound%d.txt", current_sound_file);
if (!tiki.LoadFile(file_name, qtrue)) {
continue;
}
Com_Printf("Loading %s\n", file_name);
while (tiki.TokenAvailable(qtrue)) {
token = tiki.GetToken(qtrue);
if (!Q_stricmp(token, "sound")) {
if (tiki.TokenAvailable(qtrue)) {
token = tiki.GetToken(qtrue);
if (number_of_sfx_infos == 1000) {
Com_DPrintf("Too many sound infos specified\n");
break;
}
Q_strncpyz(sfx_infos[number_of_sfx_infos].name, token, sizeof(sfx_infos[number_of_sfx_infos].name));
sfx_infos[number_of_sfx_infos].max_factor = -1.f;
sfx_infos[number_of_sfx_infos].loop_start = -1;
sfx_infos[number_of_sfx_infos].loop_end = -1;
sfx_infos[number_of_sfx_infos].max_number_playing = DEFAULT_SFX_NUMBER_PLAYING;
number_of_sfx_infos++;
}
} else if (!Q_stricmp(token, "loopstart")) {
if (!tiki.TokenAvailable(qtrue)) {
token = tiki.GetToken(qtrue);
sfx_infos[number_of_sfx_infos - 1].loop_start = atoi(token);
}
} else if (!Q_stricmp(token, "loopend")) {
if (!tiki.TokenAvailable(qtrue)) {
token = tiki.GetToken(qtrue);
sfx_infos[number_of_sfx_infos - 1].loop_end = atoi(token);
}
} else if (!Q_stricmp(token, "maxnumber")) {
if (!tiki.TokenAvailable(qtrue)) {
token = tiki.GetToken(qtrue);
sfx_infos[number_of_sfx_infos - 1].max_number_playing = atoi(token);
}
} else if (!Q_stricmp(token, "maxfactor")) {
if (!tiki.TokenAvailable(qtrue)) {
token = tiki.GetToken(qtrue);
sfx_infos[number_of_sfx_infos - 1].max_factor = atoi(token);
}
}
}
}
tiki.Close();
sfx_infos[0].name[0] = 0;
}

Some files were not shown because too many files have changed in this diff Show more