Compare commits

...
904 Commits
Author SHA1 Message Date
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
smallmodel 08d97e0277 Added snd_miles source files 2024-01-07 23:50:02 +01:00
smallmodel 21d0675035 Using vec3_t instead of a pointer to float 2024-01-07 23:42:32 +01:00
smallmodel 1dfb81917c Added public driver functions 2024-01-07 23:38:57 +01:00
smallmodel af8c92f090 Added public OPENAL driver declarations 2024-01-07 23:36:32 +01:00
smallmodel 04e0242422 Added source files for OpenAL FAKK (unimplemented) 2024-01-07 20:10:53 +01:00
pryon 110ffc3a01 Implement UIField (#90)
* Implement UIField

* Formatting and naming fixes

- Ran clang-format on previously modified files
- Replaced ifdef guards with `#pragma once`
- Changed wording in comments above OPM-only changes for easier searchability
2024-01-04 23:51:16 +01:00
smallmodel 6b4a8bd627 Fixed jumpstart modheight not working on AA 2024-01-02 23:32:06 +01:00
smallmodel 0d851fdb68 Players now get correct weapons depending on the target game version 2024-01-02 18:38:21 +01:00
smallmodel 5064f2c16d Added g_target_game 2024-01-02 18:30:46 +01:00
smallmodel ac46d0eef0 Added sv_minplayers variable 2024-01-02 18:14:13 +01:00
smallmodel 70c71b69ee Added a feature to let each team have their own objective location 2024-01-02 00:52:25 +01:00
smallmodel 4487113c58 Fixed dlight image name 2024-01-01 23:52:38 +01:00
smallmodel 983f5b9ca4 Fixed UI sounds 2024-01-01 23:17:09 +01:00
smallmodel 13612d3de9 r_fastdlights is not a cheat-protected cvar 2024-01-01 22:52:08 +01:00
smallmodel 6317ca7183 Fixed the origin of cone emitters 2024-01-01 22:33:05 +01:00
smallmodel 2b96aac1c8 PointToSelectionPoint: the p parameter must be a constant 2024-01-01 21:57:49 +01:00
smallmodel a6b75aefa4 Implemented UIMultiLineEdit 2024-01-01 20:34:50 +01:00
smallmodel 7dc72b435e Formatted multiline edit source file 2024-01-01 15:57:44 +01:00
smallmodel 5a586f4700 Implemented UIHorizScroll 2024-01-01 15:45:40 +01:00
smallmodel ef50a5f2cd Prepared UIHorizScroll for implementation 2024-01-01 15:01:23 +01:00
smallmodel c2c3f6aa1b Implemented miniconsole 2024-01-01 14:53:16 +01:00
smallmodel 9c8ca98e68 Added anisotropic filtering 2024-01-01 14:25:02 +01:00
smallmodel 3a18c9f327 Fixed PrintJustified virtual parameter 2024-01-01 01:53:23 +01:00
smallmodel 9438f6497d Added partial implementations 2024-01-01 01:50:10 +01:00
smallmodel 5c3c3f8e70 Finished View3D implementation (implemented PrintSound, LocationPrint, DrawSubtitleOverlay, and CenterPrint) 2024-01-01 01:42:44 +01:00
smallmodel 3d3c99cd22 Formatted cl_uiview3d source files 2024-01-01 00:32:31 +01:00
smallmodel b3464e620e Updated features implementation 2023-12-31 23:43:30 +01:00
smallmodel 72a38b0b68 Implemented UIDialog 2023-12-31 23:43:22 +01:00
smallmodel 46e7f29820 Fixed dialog bad cancel command 2023-12-31 23:43:05 +01:00
smallmodel cb36015a38 Updated features implementation 2023-12-31 23:15:22 +01:00
smallmodel 66cb10a3bf Added a fix that reset the viewangles if it is NaN 2023-12-31 23:14:22 +01:00
smallmodel bfdd99a028 Added m_parent to get values from parent 2023-12-31 23:13:24 +01:00
smallmodel 63ef75222e Added isVirtual and getVirtualScale 2023-12-31 23:12:40 +01:00
smallmodel 072ba0a38f Fixed fullbright light not setting the colors correctly 2023-12-31 22:15:19 +01:00
smallmodel 576869bda0 Fixed UIFakkLabel::Draw() implementation 2023-12-31 22:02:59 +01:00
smallmodel 0d556b1b40 Implemented cl_invrender 2023-12-31 22:02:47 +01:00
smallmodel 0cd217b484 Fixed RB_Sphere_SetupGlobals() setting up sphere in leafs when there is no world loaded 2023-12-31 21:53:13 +01:00
smallmodel 907255837e Added INV_ALIGN_NONE 2023-12-31 15:35:00 +01:00
smallmodel ebf33349a3 Added EV_ClearInvItemReference declaration 2023-12-31 15:34:53 +01:00
smallmodel ea6920b711 Added CL_Key_ForceCommand 2023-12-31 15:34:45 +01:00
smallmodel 53a47d470a Implemented cl_inv 2023-12-31 14:19:57 +01:00
smallmodel 7fe7b6ce79 Formatted cl_inv* source files 2023-12-31 13:32:46 +01:00
smallmodel 0110704abd Fixed after a map change when setting sv_maxclients 2023-12-31 01:17:16 +01:00
smallmodel aca23fc62f Fixed call vote button not working 2023-12-31 01:01:38 +01:00
smallmodel c0a284927e Fixed vote item name being empty 2023-12-31 00:53:26 +01:00
smallmodel 2d911c37a4 Added vote commands for cgame 2023-12-31 00:39:43 +01:00
smallmodel 1e7af27227 Fixed DM map selection having the incorrect map path 2023-12-31 00:38:41 +01:00
smallmodel 06678a8b0a Added UI_MultiplayerMainMenuWidgetsUpdate from mohaas/mohaab 2023-12-31 00:38:22 +01:00
smallmodel e1706610c4 Fixed versions for mohaas server 2023-12-30 23:52:25 +01:00
smallmodel 7bb940d819 Implemented LAN game list 2023-12-30 23:03:56 +01:00
smallmodel b4e0120428 Using ioquake3 code for IPv6 support and network fixes 2023-12-30 23:03:49 +01:00
smallmodel db1013d926 Use clc.connectStartTime instead of clc.connectTime 2023-12-30 22:59:57 +01:00
smallmodel 759dacd345 Added com_gamename 2023-12-30 21:36:54 +01:00
smallmodel 903fd28953 set cls.bNewLocalServerInfo to tell when there are new local servers 2023-12-30 21:10:27 +01:00
smallmodel 6c520babf0 Make sure to register the material for each GetMaterial() call 2023-12-30 21:09:23 +01:00
smallmodel 9bb2fda6df Fixed events declaration 2023-12-30 19:50:15 +01:00
smallmodel d48b37ece1 Implemented UIGlobalGameList 2023-12-30 19:18:59 +01:00
smallmodel f4164e84e1 Made fields and methods protected instead of private 2023-12-30 19:18:54 +01:00
smallmodel 33aabadaf5 Implemented FAKK Load game class 2023-12-30 19:09:48 +01:00
smallmodel e815fda908 Fixed save's comment being set to the filename 2023-12-30 19:09:31 +01:00
smallmodel fe04adee1d Formatted source files 2023-12-30 17:36:01 +01:00
smallmodel 115647a8c0 Use ApplyPlayerModel/GetPlayerModel from mohaab 2.40 2023-12-30 17:23:30 +01:00
smallmodel ddd70eadf6 Exported PM_FilenameToDisplayname and PM_DisplaynameT 2023-12-30 17:23:11 +01:00
smallmodel 319e00214e Refactored DeactivateCurrentSmart 2023-12-30 17:11:25 +01:00
smallmodel 6bdcfc2b6f Fixed PassEventToWidget improperly passing events to widgets not matching the name 2023-12-30 17:11:12 +01:00
smallmodel ae0a2238da Set mouse position with player model 2023-12-30 16:55:06 +01:00
smallmodel a69f9fe88b Implemented UI player model picker 2023-12-30 16:54:57 +01:00
smallmodel 696b57f990 Formatted uWinMan source file 2023-12-30 16:54:46 +01:00
smallmodel 998c1b78c7 Added all picker models from mohaa 1.0 up to mohaab 2.40 2023-12-30 14:10:06 +01:00
smallmodel 8c207f094d Implemented PMPickerItem and added name parameter to FileSelected/FileChosen methods 2023-12-30 02:22:41 +01:00
smallmodel 09c9c0ef51 Added UI map rotation from BT 2.40 2023-12-30 01:59:03 +01:00
smallmodel 8cd571c96c Implemented all UIListBox methods and implemented Draw() from BT 2.40 2023-12-30 01:50:12 +01:00
smallmodel 979af2925d Fixed hide commands and show commands not executing properly 2023-12-30 01:09:11 +01:00
smallmodel f092eab842 Added InsertItem() and setCurrentItem() for UIListBox 2023-12-30 00:03:21 +01:00
smallmodel 3d4832ca85 Formatted uilistbox source files 2023-12-30 00:01:14 +01:00
smallmodel b120fc6f2f Fixed sorting being wrong 2023-12-29 23:03:08 +01:00
smallmodel c299ad92aa Improver UI_DMMapSelect_f for SH/BT 2023-12-29 22:06:49 +01:00
smallmodel 956cd59385 Implemented MP map picker 2023-12-29 22:06:36 +01:00
smallmodel acbd802790 Make COM_IsMapValid always return true from now 2023-12-29 21:59:23 +01:00
smallmodel c4bcecf5e0 Added COM_IsMapValid 2023-12-29 21:24:23 +01:00
smallmodel 09949251ac Implemented cl_uisoundpicker 2023-12-29 20:23:42 +01:00
smallmodel 43218f1685 Use a const str& reference 2023-12-29 20:19:28 +01:00
smallmodel eb7d01b3e7 Implemented cl_uimaprunner 2023-12-29 20:18:04 +01:00
smallmodel c58e6d58b4 Filter "_sml" maps for maplist 2023-12-29 20:05:36 +01:00
smallmodel 3a892e1a47 Implemented file picker class 2023-12-29 20:05:29 +01:00
smallmodel 5bb487e1fa Set default parameter for fontname 2023-12-29 20:04:57 +01:00
smallmodel 4ae091be4b Added a slash at the end of the scripts folder name 2023-12-29 19:56:34 +01:00
smallmodel 7654ab6be6 FS_ListFilteredFiles: Fixed subdirectory listing and added support for searching multiple extensions 2023-12-29 19:56:23 +01:00
smallmodel 193cc9dc10 Added FS_FileTime (unimplemented) 2023-12-29 18:59:06 +01:00
smallmodel a6d268e1a1 Added subdirectory and directory search support for FS_ListFilteredFiles 2023-12-29 18:27:41 +01:00
smallmodel 7822e94e61 Formatted picker source files 2023-12-29 14:38:55 +01:00
smallmodel eb663fdbc1 Fixed a crash due to subtitle when there is no player 2023-12-28 21:08:07 +01:00
smallmodel c738a40c05 Fixed links 2023-12-28 21:03:58 +01:00
smallmodel 2ca3443b7f Moved Playing with bots section to getting_started_running.md doc 2023-12-28 21:02:05 +01:00
smallmodel 06be4c03fa Use htmlpreview to open the g_allclasses.html file 2023-12-28 20:59:43 +01:00
smallmodel 32d77f4a7d Split README into multiple docs 2023-12-28 20:54:05 +01:00
smallmodel d217b1d561 Fixed some events having wrong parameters for documentation 2023-12-28 20:50:47 +01:00
smallmodel 0167f0a3a4 Using Added in OPM comments 2023-12-28 20:35:33 +01:00
smallmodel 4304ad0faa Fixed weapon attachment not correcting properly 2023-12-28 19:16:54 +01:00
smallmodel 3be17376e4 Fixed wrong landmine defuse direction 2023-12-28 18:55:43 +01:00
smallmodel 0b4fd4c17e Fixed isabandoned returning 1 if the player has a landmine 2023-12-28 18:53:32 +01:00
smallmodel 66c4499b2e Fixed ScriptThreadLabel::Execute with other/owner param 2023-12-28 18:30:15 +01:00
smallmodel cde13177a4 Don't set the ground entity in Entity::droptofloor 2023-12-28 18:22:10 +01:00
smallmodel 9fce2575ab Commented out the code that makes triggers only respond to killed/activate messages 2023-12-28 18:21:58 +01:00
smallmodel 8f8e92c8c3 Don't cound the number of shots if the owner is the world 2023-12-28 17:47:18 +01:00
smallmodel 8683d317fe Set origin2 and player's num shots fired when placing landmine 2023-12-28 17:45:53 +01:00
smallmodel 1178c619bc Fixed variables not being restored properly 2023-12-28 17:31:36 +01:00
smallmodel 2fa568eb01 CL_KeyEvent must not handle GUI mouse events, as it's the job of the UIWindowManager 2023-12-28 17:26:32 +01:00
smallmodel d62242d653 use PRINT_WARNING instead of PRINT_DEVELOPER when an image couldn't be found 2023-12-28 17:25:51 +01:00
smallmodel 991bf2f1f5 Fixed m_firstResponder being nulled out in UIWindowManager::getFirstResponder() 2023-12-28 17:21:56 +01:00
smallmodel 2f241343ff Don't accept the bind for null and pause keys 2023-12-28 17:21:32 +01:00
smallmodel 035de09c15 Formatted cl_keys.cpp source file 2023-12-28 17:21:02 +01:00
smallmodel d3a4407391 Make sure to not service a view event if the first responder is NULL 2023-12-28 13:04:29 +01:00
smallmodel 395c16ce24 Fixed bind label selection 2023-12-28 12:50:40 +01:00
smallmodel f7accc01ad Fixed bind selection and highlight 2023-12-28 12:47:27 +01:00
smallmodel 3733154e63 Fixed alternate binding not working properly 2023-12-28 01:29:46 +01:00
smallmodel 2ef95ddba9 Fixed improper binding and text location 2023-12-28 01:29:33 +01:00
smallmodel 043f8cba22 Implemented UIFakkBindList and UIFakkBindListLabel 2023-12-28 01:12:43 +01:00
smallmodel 09ab172630 Added UIBindButton events 2023-12-28 01:12:19 +01:00
smallmodel c23a182bec Added bindlistener events 2023-12-28 01:11:17 +01:00
smallmodel c321470382 Implemented CL_LoadBind 2023-12-27 22:53:49 +01:00
smallmodel 932bdd402c Implemented UIBindButton 2023-12-27 22:47:01 +01:00
smallmodel 3692671f49 Implemented bind_t and bindlistener 2023-12-27 20:19:58 +01:00
smallmodel 1cd4c35a79 Bumped version number 2023-12-27 18:54:57 +01:00
smallmodel c0f7a48649 Formatted ui source files 2023-12-27 18:54:20 +01:00
smallmodel c1258f160b Do not clear sv_fps cvar when restarting/switching map 2023-12-27 18:43:37 +01:00
smallmodel bdb9feb7c5 Updated README 2023-12-27 18:18:45 +01:00
smallmodel 830cbe7af2 Fixed issues with animation when sv_fps was above 20 2023-12-27 18:04:41 +01:00
smallmodel 4eb83c0766 Fixed weapon attachments not being detached 2023-12-27 16:29:00 +01:00
smallmodel 210f2fef77 Formatted source file 2023-12-27 16:28:28 +01:00
smallmodel d19a6160d2 Call SetWeaponAnim() instead of NewAnim() for weapon animation 2023-12-27 16:25:37 +01:00
smallmodel cd773cf73f Set last active weapon only if the weapon is not an inventory item 2023-12-27 16:13:12 +01:00
smallmodel f3b9a10f7a Detach weapons already attached to the attach tag only if the current weapon attach tag is valid 2023-12-27 15:54:55 +01:00
smallmodel 709283ff33 Fixed MAX_ACTIVE_WEAPONS check (out of bounds) 2023-12-27 15:49:33 +01:00
smallmodel fae261d7da UI game message fix 2023-12-27 15:43:28 +01:00
smallmodel 6b5e527b6b Fixed callvote line breaks 2023-12-27 15:38:17 +01:00
smallmodel b7005a310e Fixed callvote still executing kick with an invalid player 2023-12-27 15:14:08 +01:00
smallmodel edd25b9264 Readded support for supporting configstrings in multiple chunks 2023-12-27 15:13:42 +01:00
smallmodel 65a8b03ee4 Fixed infinite loop in SV_SendConfigstring when sending multiple chunks 2023-12-27 15:13:17 +01:00
smallmodel 0044ec0ac0 Increased MAX_CMD_LINE for testing purposes 2023-12-27 15:11:17 +01:00
smallmodel 73111d854d Fixed an infinite loop bug when selecting the previous/next weapon 2023-12-27 14:07:57 +01:00
smallmodel 065ab98175 Added a comment in CondMinChargeTime about the crash fix 2023-12-27 14:07:34 +01:00
smallmodel cbeaeba828 Use IsSubclassOfWeapon() and IsSubclassOfPlayer() 2023-12-27 14:06:22 +01:00
smallmodel 7af2a9444e Updated paragraph about bug reports 2023-12-26 18:40:54 +01:00
smallmodel f476f3690a Another README update 2023-12-26 12:22:37 +01:00
smallmodel fae02da4b1 Updated README 2023-12-26 12:14:38 +01:00
smallmodel b0e4e29ce3 Merge pull request #88 from pryon/misc-fixes
Misc fixes
2023-12-20 19:34:26 +01:00
pryon 11f7728b9d Move strdup'd string cleanup to uipopup_describe's dtor 2023-12-20 17:52:02 +01:00
pryon 7510b05d25 Properly free memory allocated by strdup calls 2023-12-18 19:56:26 +01:00
pryon e467f91262 Fix pulldown menu labels showing raw cvar values 2023-12-18 17:49:01 +01:00
pryon b03afb899d Add thirdparties dir and generated parser/lexer files to .gitignore 2023-12-18 17:46:52 +01:00
pryon ec71ff3c3c Implement UIPopupMenu (#87)
* Implement UIPopupMenu

* Use `std::fmax` for floats
2023-12-17 22:51:18 +01:00
smallmodel 02ce50ace2 Treat "not all control paths return a value" warning as an error 2023-12-07 18:32:10 +01:00
smallmodel 4a4a552a05 Fixed crash due to corrupted stack values 2023-12-07 18:04:57 +01:00
pryon 5b3615d262 Implement UIPulldownMenuContainer (#86)
* Implement UIPulldownMenuContainer

* Review suggestions:
 - remove unnecessary extern declarations
 - add comment about a possible memleak
2023-12-05 23:27:27 +01:00
pryon 2821488c93 Implement UIPulldownMenu (#85)
* Implement UIPulldownMenu

* Remove unnecessary value-type member initialization
2023-12-05 19:50:41 +01:00
smallmodel 9814887b10 Don't execute Git if the source directory is not a working Git repo 2023-11-29 19:04:24 +01:00
smallmodel 3f86381541 Only allow builds on branches (and not tags), as tags are built during the deployment 2023-11-29 18:18:30 +01:00
smallmodel 7736966dc1 Fixed the README 2023-11-29 18:17:14 +01:00
406 changed files with 69593 additions and 21378 deletions

No files matched your search

+39
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.
+76 -12
View File
@@ -2,6 +2,8 @@ name: Build
on:
push:
branches:
- '**'
pull_request:
workflow_call:
@@ -18,10 +20,13 @@ jobs:
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: 'amd64', triple: 'x86_64-linux-gnu'},
{name: 'i686', triple: 'i686-linux-gnu'},
{name: 'arm64', triple: 'aarch64-linux-gnu'},
{name: 'armhf', triple: 'arm-linux-gnueabihf'},
{name: 'powerpc', triple: 'powerpc-linux-gnu'},
{name: 'ppc64', triple: 'powerpc64-linux-gnu'},
{name: 'ppc64el', triple: 'powerpc64le-linux-gnu'}
]
name: "Building for platform linux-${{matrix.architecture.name}}"
@@ -36,7 +41,8 @@ jobs:
- name: Install required packages
run: |
sudo apt update && sudo apt install -y flex bison
sudo apt update && sudo apt install -y flex bison \
libpulse-dev portaudio19-dev libasound2-dev libjack-dev libpipewire-0.3-dev qtbase5-dev libdbus-1-dev
- name: Install required cross-platform packages (${{ matrix.architecture.triple }})
if: matrix.architecture.name != 'amd64'
@@ -54,7 +60,27 @@ jobs:
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }}
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }}"
- uses: actions/checkout@v3
# 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
uses: actions/checkout@v4
with:
repository: 'kcat/openal-soft'
path: 'thirdparties/soft-oal'
ref: '1.23.1'
- name: Configure and install soft-oal
working-directory: ${{github.workspace}}/thirdparties/soft-oal
run: |
cmake -B ./build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DCMAKE_INSTALL_PREFIX='${{github.workspace}}/thirdparties/soft-oal/install' \
-DCMAKE_C_COMPILER=${{ matrix.architecture.triple }}-gcc-12 \
-DCMAKE_CXX_COMPILER=${{ matrix.architecture.triple }}-g++-12
cmake --build ./build --config ${{env.BUILD_TYPE}}
cmake --install ./build --config ${{env.BUILD_TYPE}}
- uses: actions/checkout@v4
with:
path: 'source'
@@ -67,6 +93,8 @@ jobs:
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_C_FLAGS=--target=${{ matrix.architecture.triple }} \
-DCMAKE_CXX_FLAGS=--target=${{ matrix.architecture.triple }} \
-DOPENAL_LIBRARY='${{github.workspace}}/thirdparties/soft-oal' \
-DOPENAL_INCLUDE_DIR='${{github.workspace}}/thirdparties/soft-oal/include' \
-DGIT_REVISION_BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
- name: Configure CMake
@@ -92,9 +120,11 @@ jobs:
# 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'
# Create hard-link and copy symbolic links
cp -l ${{steps.sdl.outputs.prefix}}/lib/libSDL2-2.0.so.0 '${{github.workspace}}/install/'
cp -l ${{github.workspace}}/thirdparties/soft-oal/install/lib/libopenal.so.1 '${{github.workspace}}/install/'
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: out-linux-${{matrix.architecture.name}}
if-no-files-found: error
@@ -119,7 +149,7 @@ jobs:
run: |
echo "CMAKE_BUILD_PARALLEL_LEVEL=$((Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors * 16)" >> $GITHUB_ENV
# Setup SDL
# Setup SDL
- name: Set up SDL
id: sdl
uses: libsdl-org/setup-sdl@main
@@ -137,7 +167,38 @@ jobs:
cmake --build winflexbison-build --config Release --parallel
cmake --install winflexbison-build
- uses: actions/checkout@v3
# soft-oal setup
- name: Checkout soft-oal
uses: actions/checkout@v4
with:
repository: 'kcat/openal-soft'
path: 'thirdparties/soft-oal'
ref: '1.23.1'
# soft-oal build
# Statically link the CRT runtime into OAL as a workaround to prevent crashes
- name: Configure and install soft-oal
working-directory: ${{github.workspace}}/thirdparties/soft-oal
run: |
cmake -B ./build -A ${{ matrix.architecture.config }} `
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
-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 ${{env.BUILD_TYPE}}
cmake --install ./build --config ${{env.BUILD_TYPE}}
# 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' }
- uses: actions/checkout@v4
with:
path: 'source'
@@ -149,6 +210,8 @@ jobs:
-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/include' `
-DFLEX_EXECUTABLE='${{github.workspace}}/thirdparties/winflexbison-install/win_flex.exe'".Replace("`r", "").Replace("`n", "") >> $env:GITHUB_ENV
- name: Configure CMake
@@ -175,8 +238,9 @@ jobs:
run: |
cmake --install ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
Copy-Item '${{steps.sdl.outputs.prefix}}/bin/*.dll' -Destination '${{github.workspace}}/install'
Copy-Item '${{github.workspace}}/thirdparties/soft-oal/install/bin/*.dll' -Destination '${{github.workspace}}/install'
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: out-windows-${{matrix.architecture.name}}
if-no-files-found: error
@@ -184,7 +248,7 @@ jobs:
${{github.workspace}}/install
!${{github.workspace}}/install/**/*.pdb
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: out-windows-${{matrix.architecture.name}}-pdb
if-no-files-found: error
+4 -4
View File
@@ -41,7 +41,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
# Setup SDL
- name: Set up SDL
@@ -52,7 +52,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -66,7 +66,7 @@ jobs:
# 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)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v3
# ℹ️ 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
@@ -79,6 +79,6 @@ jobs:
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
+6 -3
View File
@@ -25,8 +25,11 @@ jobs:
target_os: [
'linux-amd64',
'linux-i686',
'linux-aarch64',
'linux-arm64',
'linux-armhf',
'linux-powerpc',
'linux-ppc64',
'linux-ppc64el',
'windows-x64',
'windows-x86',
'windows-x64-pdb',
@@ -43,7 +46,7 @@ jobs:
RELEASE_NAME: ${{ github.event.repository.name }}-${{github.ref_name}}-${{matrix.target_os}}
steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: 'out-${{matrix.target_os}}'
path: ${{github.workspace}}/${{matrix.target_os}}
@@ -53,7 +56,7 @@ jobs:
run: zip -r ../${{ env.RELEASE_NAME }}.zip ./
- name: Release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
name: '${{github.ref_name}}-${{env.RELEASE_TYPE}}'
prerelease: ${{env.RELEASE_IS_PRERELEASE}}
+4 -1
View File
@@ -5,6 +5,8 @@ Makefile.local
*.swp
*tags
*~
/.vscode/
/baseq3
# OS X
####################
@@ -44,5 +46,6 @@ profile
*.suo
.vs
out
code_unfinished/*
thirdparties/
code/parser/generated/*
+12 -12
View File
@@ -16,8 +16,17 @@ set(CMAKE_DEBUG_POSTFIX "-dbg")
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Treat no return type as error
add_compile_options(/we4715)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Wno-comment)
# Treat no return type as error
add_compile_options(-Werror=return-type)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Ignore warnings for code like 'assert("Assert string")'
add_compile_options(-Wno-pointer-bool-conversion)
endif()
@@ -96,10 +105,10 @@ INSTALL(TARGETS omohaaded DESTINATION "./")
if (NOT BUILD_NO_CLIENT)
## Client app
add_subdirectory("code/client")
add_subdirectory("code/renderer")
add_subdirectory("code/sdl")
add_subdirectory("code/client")
#include("code/renderergl2/glsl/shaders.cmake")
#file(GLOB_RECURSE SOURCES_RENDERER "code/sdl/*.c" "code/renderercommon/*.c" "code/renderergl2/*.c" "code/renderergl2/*.cpp")
@@ -119,15 +128,6 @@ if (NOT BUILD_NO_CLIENT)
set_target_properties(openmohaa PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
target_link_libraries(openmohaa PRIVATE jpeg8)
if (USE_OPENAL)
# Try to use OpenAL
find_package(OpenAL)
if (OPENAL_FOUND)
target_compile_definitions(openmohaa PRIVATE USE_OPENAL=1)
target_include_directories(openmohaa PRIVATE ${OPENAL_INCLUDE_DIR})
target_link_libraries(openmohaa PRIVATE ${OPENAL_LIBRARY})
endif()
endif()
if (MSVC)
target_link_options(openmohaa PRIVATE "/MANIFEST:NO")
+15 -151
View File
@@ -15,139 +15,38 @@
|_|
```
## Current State
OpenMoHAA is still under development. The single-player campaign is not yet functional due to AI not being fully stable. But the `training` map can be played from start to end. The current focus is on multiplayer.
## 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).
## Running
## Getting started
Ensure that you download the binaries compatible with your platform.
- [Installing OpenMoHAA](docs/getting_started_installation.md)
- [Running OpenMoHAA and using expansion assets](docs/getting_started_running.md)
### Requirements
## Current state
You may need to install Microsoft Visual C++ 2015/2017/2019/2022 Redistributable from https://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-170
### Single-player
### Client
The entire single-player campaign can be played from start to end. There may be occasional bugs though; if you encounter any, please create a new [GitHub issue](https://github.com/openmoh/openmohaa/issues) describing them.
a) extract archive to your MOHAA installation directory.
### Multiplayer
-or-
The Multiplayer part is almost fully stable.
b) extract archive somewhere on your hard drive, create a shortcut to openmohaa (or omohaaded), and set the start directory to your MOHAA installation directory.
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.
### 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.
Extract the archive to your MOHAA server installation directory. Then proceed like you would do with mohaa server:
## Features
- `.\omohaaded.exe +exec server.cfg` on Windows
- `./omohaaded +exec server.cfg` on Linux
Only `omohaaded*` and `game*` binaries are required for the server version, other binaries can be omitted.
### Config file
The config file can be found in different locations depending on the platform:
- `%APPDATA%\openmohaa\<game_name>\configs\omconfig.cfg` on Windows
- `~/.openmohaa/<game_name>/configs/omconfig.cfg` on Linux
This has two advantages:
- On a multi-user system, each user will have their own configuration file
- It doesn't overwrite the existing MOHAA configuration in the MOHAA installation directory.
### Game selection
**Medal of Honor: Allied Assault Spearhead** and **Medal of Honor: Allied Assault Breakthrough** are supported in OpenMoHAA using the `com_target_game` variable. To play an expansion, append the following command-line arguments to the executable:
- `+set com_target_game 1` for Spearhead (mohaas/mohta)
- `+set com_target_game 2` for Breakthrough (mohaab/mohtt)
On Windows, you can create a shortcut to OpenMoHAA with these command-line arguments.
The default value of `com_target_game` is 0 for the base game (main).
With `com_target_game`, OpenMoHAA will support the network protocol accordingly.
You can now start a local OpenMOHAA server or play on a server.
### Playing with bots
OpenMoHAA has a basic bot system that emulates real players. The maximum number of bots is defined by the `sv_maxbots` variable, and the number of initial bots is defined by the `sv_numbots` variable. Bots can also be added or removed using the `addbot` and `removebot` commands.
This feature is a great way to test the gameplay and mods.
## Builds
### Server
The server version can be built successfully, but some features are not functional. For example, the Actor system is almost fully implemented, but it is not yet stable. This means that Actor may not work as expected and could cause crashes.
Overall, the server and the fgame components are almost fully implemented, but they may not be completely stable. There could be some minor bugs (and rare crashes), but the game should be playable.
### Client
The client version of OpenMoHAA has undergone partial implementation, with the cgame module being nearly completed. Credits to the SDK of **Heavy Metal: F.A.K.K. 2** both the cgame and fgame modules.
The current operational status for each component is as follow:
| Component | Full | Almost | Half | Early | Bad | Not working | Comment |
|-------------------------|------|--------|------|-------|-----|-------------|-------------------------------------------------------------------|
| Audio | | | | | x | | Very basic implementation from Quake III |
| CG Module | | x | | | | | Missing FX, Marks and decals |
| Client | | x | | | | | Missing GameSpy, server list, binds, map picker, ... |
| Collision | x | | | | | | |
| Model/TIKI/Skeletor | x | | | | | | |
| Renderer | | x | | | | | Missing ghost, marks, sphere lights, sky portal, sun flare, swipe |
| Server | | x | | | | | Probably a few bugs remaining |
| Server module (fgame) | | x | | | | | Actor, and few gameplay bugs |
| UI | | | x | | | | Has core features only (menu, widgets, console, hud, urc loading) |
- [What's working](docs/features_implementation.md)
- [New features](docs/features.md)
- [Scripting commands](https://htmlpreview.github.io/?https://github.com/openmoh/openmohaa/blob/main/docs/features_g_allclasses.html)
## Compiling
OpenMoHAA supports any architecture, thanks to the CMake build system and cross-platform code/libraries. While the most common little-Endian architectures (arm, aarch64, x86, x86_64) have been tested and confirmed to work, big-Endian architectures should be supported as well; however, they remain untested.
The following tools are required for all platforms:
- CMake >= 3.5
- Flex (>= 2.6.4) and Bison (>= 3.5.1)
- A C++11 compiler is also required.
The installation directory can be set to the MOHAA directory.
By default, the build will produce both the client and dedicated server versions. The client can be omitted from the build by appending `-DBUILD_NO_CLIENT=1` to the CMake command-line arguments. Using this parameter will result in only the server portion being built.
### Linux
These are the tools required on Linux :
- Clang >= 3.3 or GCC >= 4.8.5
- libsdl2-dev
**clang-3.5** and **gcc-4.8.5** should work (tested on Ubuntu 16.04), but the latest version should be used.
Ubuntu 20.04 is the minimum version required to fully compile the project successfully.
1 line install command with clang:
```sh
sudo apt-get install -y cmake ninja-build clang lld flex bison libsdl2-dev
```
Example with **CMake** and **ninja-build** installed:
```sh
mkdir .cmake && cd .cmake
cmake -G Ninja ../
```
Other compilers can be specified by appending `-DCMAKE_C_COMPILER=/path/to/compiler -DCMAKE_CXX_COMPILER=path/to/compiler` to the CMake command-line.
### Windows
Visual Studio (2019 or 2022) is generally preferred.
Flex and Bison can be downloaded from here: https://github.com/lexxmark/winflexbison/releases/tag/v2.5.25
Append `-DFLEX_EXECUTABLE=...\win_flex.exe -DBISON_EXECUTABLE=...\win_bison.exe` to the CMake command-line to use the package from the link above.
- See [Compiling OpenMoHAA](docs/compiling.md)
## Screenshots
@@ -159,41 +58,6 @@ Append `-DFLEX_EXECUTABLE=...\win_flex.exe -DBISON_EXECUTABLE=...\win_bison.exe`
*More screenshots [here](docs/images)*
## Features
### Features added and not present in MOH:AA
#### Server-side
- Bots
- Spectate players in first-person
- Demo recording
- More script commands for mods
- Non-PVS optimization
##### Non-PVS optimization
For each client, the server optimizes by only sending them information about other players that they can see. Clients won't see other players they can't see.
Enable this feature with `set sv_netoptimize 2`.
#### Client-side and server-side
- Security fixes and features from ioquake3
- IPv6 support (from ioquake3)
### Objectives / planned features
This is a non-exhaustive list of objectives and planned features.
#### Server-side
- 100% compatibility with mohaa content
- More feature for mods
- Anticheat
- Stats system
- Multiple roles/abilities for server admins to reduce password-stealing
## Third party
### SDL
+13 -5
View File
@@ -3,8 +3,12 @@ set(archdetect_c_code "
# error cmake_ARCH x86
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
# error cmake_ARCH x86_64
#elif defined(__ppc64__) || defined(__powerpc64__)
# error cmake_ARCH ppc64
#elif defined(__PPC64__) || defined(__ppc64__) || defined(__powerpc64__) || defined(_ARCH_PPC64)
# if __BIG_ENDIAN__
# error cmake_ARCH ppc64
# else
# error cmake_ARCH ppc64el
# endif
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__)
# error cmake_ARCH ppc
#elif defined __s390__
@@ -19,10 +23,14 @@ set(archdetect_c_code "
# error cmake_ARCH alpha
#elif defined __sparc__
# error cmake_ARCH sparc
#elif defined __arm__ || defined (_M_ARM)
# error cmake_ARCH arm
#elif defined(__aarch64__) || defined(__ARM64__) || defined(_M_ARM64)
# error cmake_ARCH aarch64
# error cmake_ARCH arm64
#elif defined __arm__ || defined (_M_ARM)
# if defined(__ARM_PCS_VFP) && (__ARM_PCS_VFP)
# error cmake_ARCH armhf
# else
# error cmake_ARCH armel
# endif
#elif defined __cris__
# error cmake_ARCH cris
#elif defined __hppa__
+4 -1
View File
@@ -933,10 +933,13 @@ static void waitToApplyUpdates(void)
OS forcibly closes the pipe), we will unblock. Then we can loop on
kill() until the process is truly gone. */
int x = 0;
struct timespec req;
req.tv_sec = 0;
req.tv_nsec = 100000000;
read(3, &x, sizeof (x));
info("Pipe has closed, waiting for process to fully go away now.");
while (kill(options.waitforprocess, 0) == 0) {
usleep(100000);
nanosleep(&req, NULL);
}
#endif
}
+4 -4
View File
@@ -113,7 +113,7 @@ void CG_ArchiveModelHandle(MemArchiver& archiver, qhandle_t* handle)
if (tmp.length()) {
*handle = cgi.R_RegisterModel(tmp.c_str());
} else {
*handle = NULL;
*handle = (qhandle_t)0;
}
} else {
if (*handle) {
@@ -135,7 +135,7 @@ void CG_ArchiveShaderHandle(MemArchiver& archiver, qhandle_t* handle)
if (tmp.length()) {
*handle = cgi.R_RegisterShader(tmp.c_str());
} else {
*handle = NULL;
*handle = (qhandle_t)0;
}
} else {
if (*handle) {
@@ -163,7 +163,7 @@ void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref)
archiver.ArchiveVec3(ref->axis[2]);
archiver.ArchiveBoolean(&ref->nonNormalizedAxes);
archiver.ArchiveVec3(ref->origin);
archiver.ArchiveRaw(ref->frameInfo, 192);
archiver.ArchiveRaw(ref->frameInfo, sizeof(ref->frameInfo));
archiver.ArchiveFloat(&ref->actionWeight);
archiver.ArchiveShort(&ref->wasframe);
archiver.ArchiveFloat(&ref->scale);
@@ -171,7 +171,7 @@ void CG_ArchiveRefEntity(MemArchiver& archiver, refEntity_t* ref)
archiver.ArchiveInteger(&ref->skinNum);
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[1]);
archiver.ArchiveFloat(&ref->shaderTime);
+25 -3
View File
@@ -196,7 +196,8 @@ Event EV_Client_SetColorVelocity
"rVel gVel bVel",
"Set the color velocity of the spawned dlight tempmodel"
);
Event EV_Client_SetRandomVelocity(
Event EV_Client_SetRandomVelocity
(
"randvel",
EV_DEFAULT,
"SfFSfFSfF",
@@ -210,7 +211,8 @@ Event EV_Client_SetRandomVelocity(
"without randomness.\n"
"This velocity is applied using the world axis"
);
Event EV_Client_SetRandomVelocityAlongAxis(
Event EV_Client_SetRandomVelocityAlongAxis
(
"randvelaxis",
EV_DEFAULT,
"SfFSfFSfF",
@@ -225,6 +227,14 @@ Event EV_Client_SetRandomVelocityAlongAxis(
"without randomness.\n"
"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
(
"accel",
@@ -1221,6 +1231,7 @@ CLASS_DECLARATION(Listener, ClientGameCommandManager, NULL) {
{&EV_Client_SetColorVelocity, &ClientGameCommandManager::SetAngularVelocity },
{&EV_Client_SetRandomVelocity, &ClientGameCommandManager::SetRandomVelocity },
{&EV_Client_SetRandomVelocityAlongAxis, &ClientGameCommandManager::SetRandomVelocityAlongAxis},
{&EV_Client_NoTagAxis, &ClientGameCommandManager::SetNoTagAxis },
{&EV_Client_SetAccel, &ClientGameCommandManager::SetAccel },
{&EV_Client_SetFriction, &ClientGameCommandManager::SetFriction },
{&EV_Client_SetSpin, &ClientGameCommandManager::SetSpin },
@@ -2157,7 +2168,9 @@ void ClientGameCommandManager::SetInwardSphere(Event *ev)
}
m_spawnthing->cgd.flags |= T_INWARDSPHERE;
m_spawnthing->sphereRadius = ev->GetFloat(1);
if (ev->NumArgs() > 0) {
m_spawnthing->sphereRadius = ev->GetFloat(1);
}
}
//=============
@@ -2666,6 +2679,15 @@ void ClientGameCommandManager::SetRandomVelocityAlongAxis(Event *ev)
SetRandomVelocity(ev);
}
void ClientGameCommandManager::SetNoTagAxis(Event* ev)
{
if (!m_spawnthing) {
return;
}
m_spawnthing->cgd.flags2 |= T2_NOTAGAXIS;
}
void ClientGameCommandManager::SetRadialVelocity(Event *ev)
{
if (!m_spawnthing) {
+2
View File
@@ -113,6 +113,7 @@ TIKI file, similar to ScriptMaster in the server game dll.
#define T2_VARYCOLOR (1 << 20)
#define T2_SPIN (1 << 21)
#define T2_RELATIVEANGLES (1 << 22)
#define T2_NOTAGAXIS (1 << 23)
class spawnthing_t;
class specialeffect_t;
@@ -788,6 +789,7 @@ private:
void SetScaleRate(Event *ev);
void SetRandomVelocity(Event *ev);
void SetRandomVelocityAlongAxis(Event *ev);
void SetNoTagAxis(Event *ev); // Added in 2.0
void SetAccel(Event *ev);
void SetFriction(Event *ev);
void SetSpin(Event *ev);
+60 -50
View File
@@ -25,6 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// text commands typed in at the local console, or executed by a key binding
#include "cg_local.h"
#include "../fgame/bg_voteoptions.h"
void CG_TargetCommand_f(void);
@@ -339,56 +340,65 @@ typedef struct {
} consoleCommand_t;
static consoleCommand_t commands[] = {
{"useweaponclass", &CG_UseWeaponClass_f },
{"weapnext", &CG_NextWeapon_f },
{"weapprev", &CG_PrevWeapon_f },
{"uselast", &CG_UseLastWeapon_f },
{"holster", &CG_HolsterWeapon_f },
{"weapdrop", &CG_DropWeapon_f },
{"toggleitem", &CG_ToggleItem_f },
{"+scores", &CG_ScoresDown_f },
{"-scores", &CG_ScoresUp_f },
{"viewpos", &CG_Viewpos_f },
{"sizeup", &CG_SizeUp_f },
{"sizedown", &CG_SizeDown_f },
{"cg_eventlist", &CG_EventList_f },
{"cg_eventhelp", &CG_EventHelp_f },
{"cg_dumpevents", &CG_DumpEventHelp_f },
{"cg_pendingevents", &CG_PendingEvents_f },
{"cg_classlist", &CG_ClassList_f },
{"cg_classtree", &CG_ClassTree_f },
{"cg_classevents", &CG_ClassEvents_f },
{"cg_dumpclassevents", &CG_DumpClassEvents_f },
{"cg_dumpallclasses", &CG_DumpAllClasses_f },
{"testemitter", &CG_TestEmitter_f },
{"triggertestemitter", &CG_TriggerTestEmitter_f },
{"prevemittercommand", &CG_PrevEmitterCommand_f },
{"nextemittercommand", &CG_NextEmitterCommand_f },
{"newemittercommand", &CG_NewEmitterCommand_f },
{"deleteemittercommand", &CG_DeleteEmitterCommand_f},
{"dumpemitter", &CG_DumpEmitter_f },
{"loademitter", &CG_LoadEmitter_f },
{"resetvss", &CG_ResetVSSSources },
{"getchshader", &CG_GetCHShader },
{"editchshader", &CG_EditCHShader },
{"messagemode", &CG_MessageMode_f },
{"messagemode_all", &CG_MessageMode_All_f },
{"messagemode_team", &CG_MessageMode_Team_f },
{"messagemode_private", &CG_MessageMode_Private_f },
{"say", &CG_MessageSingleAll_f },
{"sayteam", &CG_MessageSingleTeam_f },
{"teamsay", &CG_MessageSingleTeam_f },
{"sayprivate", &CG_MessageSingleClient_f },
{"sayone", &CG_MessageSingleClient_f },
{"wisper", &CG_MessageSingleClient_f },
{"instamsg_main", &CG_InstaMessageMain_f },
{"instamsg_group_a", &CG_InstaMessageGroupA_f },
{"instamsg_group_b", &CG_InstaMessageGroupB_f },
{"instamsg_group_c", &CG_InstaMessageGroupC_f },
{"instamsg_group_d", &CG_InstaMessageGroupD_f },
{"instamsg_group_e", &CG_InstaMessageGroupE_f },
{"pushmenu_teamselect", &CG_PushMenuTeamSelect_f },
{"pushmenu_weaponselect", &CG_PushMenuWeaponSelect_f},
{"useweaponclass", &CG_UseWeaponClass_f },
{"weapnext", &CG_NextWeapon_f },
{"weapprev", &CG_PrevWeapon_f },
{"uselast", &CG_UseLastWeapon_f },
{"holster", &CG_HolsterWeapon_f },
{"weapdrop", &CG_DropWeapon_f },
{"toggleitem", &CG_ToggleItem_f },
{"+scores", &CG_ScoresDown_f },
{"-scores", &CG_ScoresUp_f },
{"viewpos", &CG_Viewpos_f },
{"sizeup", &CG_SizeUp_f },
{"sizedown", &CG_SizeDown_f },
{"cg_eventlist", &CG_EventList_f },
{"cg_eventhelp", &CG_EventHelp_f },
{"cg_dumpevents", &CG_DumpEventHelp_f },
{"cg_pendingevents", &CG_PendingEvents_f },
{"cg_classlist", &CG_ClassList_f },
{"cg_classtree", &CG_ClassTree_f },
{"cg_classevents", &CG_ClassEvents_f },
{"cg_dumpclassevents", &CG_DumpClassEvents_f },
{"cg_dumpallclasses", &CG_DumpAllClasses_f },
{"testemitter", &CG_TestEmitter_f },
{"triggertestemitter", &CG_TriggerTestEmitter_f },
{"prevemittercommand", &CG_PrevEmitterCommand_f },
{"nextemittercommand", &CG_NextEmitterCommand_f },
{"newemittercommand", &CG_NewEmitterCommand_f },
{"deleteemittercommand", &CG_DeleteEmitterCommand_f },
{"dumpemitter", &CG_DumpEmitter_f },
{"loademitter", &CG_LoadEmitter_f },
{"resetvss", &CG_ResetVSSSources },
{"getchshader", &CG_GetCHShader },
{"editchshader", &CG_EditCHShader },
{"messagemode", &CG_MessageMode_f },
{"messagemode_all", &CG_MessageMode_All_f },
{"messagemode_team", &CG_MessageMode_Team_f },
{"messagemode_private", &CG_MessageMode_Private_f },
{"say", &CG_MessageSingleAll_f },
{"sayteam", &CG_MessageSingleTeam_f },
{"teamsay", &CG_MessageSingleTeam_f },
{"sayprivate", &CG_MessageSingleClient_f },
{"sayone", &CG_MessageSingleClient_f },
{"wisper", &CG_MessageSingleClient_f },
{"instamsg_main", &CG_InstaMessageMain_f },
{"instamsg_group_a", &CG_InstaMessageGroupA_f },
{"instamsg_group_b", &CG_InstaMessageGroupB_f },
{"instamsg_group_c", &CG_InstaMessageGroupC_f },
{"instamsg_group_d", &CG_InstaMessageGroupD_f },
{"instamsg_group_e", &CG_InstaMessageGroupE_f },
{"pushmenu_teamselect", &CG_PushMenuTeamSelect_f },
{"pushmenu_weaponselect", &CG_PushMenuWeaponSelect_f },
// Added in 2.0
{"pushcallvote", &CG_PushCallVote_f },
{"pushcallvotesublist", &CG_PushCallVoteSubList_f },
{"pushcallvotesubtext", &CG_PushCallVoteSubText_f },
{"pushcallvotesubinteger",&CG_PushCallVoteSubInteger_f },
{"pushcallvotesubfloat", &CG_PushCallVoteSubFloat_f },
{"pushcallvotesubclient", &CG_PushCallVoteSubClient_f },
{"pushvote", &CG_PushVote_f },
{"callentryvote", &CG_CallEntryVote_f },
};
/*
+1 -1
View File
@@ -1180,7 +1180,7 @@ void CG_DrawCrosshair()
float x, y;
float width, height;
shader = NULL;
shader = (qhandle_t)0;
if (!cg_hud->integer || !ui_crosshair->integer) {
return;
+1 -1
View File
@@ -59,7 +59,7 @@ qboolean CG_LightStyleColor(int style, int realtime, vec4_t color, qboolean clam
time = realtime / 50;
frac = (realtime - (time * 50.0f)) / 50.0f;
memset(color, 0, sizeof(color));
VectorClear4(color);
if ((style < 0) || (style >= (MAX_LIGHTSTYLES * 2))) {
cgi.DPrintf("CG_LightStyleColor: style out of range.\n");
return qtrue;
+3
View File
@@ -187,6 +187,7 @@ extern "C" {
float min_dist;
float width;
char shader[MAX_RAIN_SHADERS][MAX_STRING_CHARS];
char currentShader[MAX_STRING_CHARS];
int numshaders;
} crain_t;
@@ -340,6 +341,7 @@ extern "C" {
float ObjectivesBaseAlpha;
float ObjectivesDesiredAlpha;
float ObjectivesCurrentAlpha;
int ObjectivesCurrentIndex;
// misc
crain_t rain;
@@ -429,6 +431,7 @@ extern "C" {
extern cgs_t cgs;
extern cg_t cg;
extern clientGameImport_t cgi;
extern target_game_e cg_target_game;
extern int cg_protocol;
extern centity_t cg_entities[MAX_GENTITIES];
extern markPoly_t *cg_markPolys;
+28 -16
View File
@@ -35,12 +35,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
clientGameImport_t cgi;
static clientGameExport_t cge;
cvar_t *paused;
cvar_t *developer;
cg_t cg;
cgs_t cgs;
int cg_protocol;
centity_t cg_entities[MAX_GENTITIES];
cvar_t *paused;
cvar_t *developer;
cg_t cg;
cgs_t cgs;
target_game_e cg_target_game = TG_INVALID;
int cg_protocol;
centity_t cg_entities[MAX_GENTITIES];
cvar_t *cg_animSpeed;
cvar_t *cg_debugAnim;
@@ -154,9 +155,9 @@ void CG_RegisterCvars(void)
cg_shadowdebug = cgi.Cvar_Get("cg_shadowdebug", "0", 0);
developer = cgi.Cvar_Get("developer", "0", 0);
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_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_acidtrip = cgi.Cvar_Get("cg_acidtrip", "0", CVAR_CHEAT);
cg_hud = cgi.Cvar_Get("cg_hud", "0", 0);
@@ -252,13 +253,11 @@ CG_IsHandleUnique
Check if the model handle is unique
================
*/
static qboolean CG_IsHandleUnique(int num) {
qhandle_t handle;
static qboolean CG_IsHandleUnique(qhandle_t handle) {
int i;
int numRef;
numRef = 0;
handle = cgs.model_draw[num];
for (i = 0; i < MAX_MODELS; i++) {
if (cgs.model_draw[i] == handle) {
numRef++;
@@ -335,22 +334,33 @@ void CG_ProcessConfigString(int num, qboolean modelOnly)
cg.rain.width = atof(str);
return;
case CS_RAIN_SHADER:
Q_strncpyz(cg.rain.currentShader, str, sizeof(cg.rain.currentShader));
if (cg.rain.numshaders) {
for (i = 0; i < cg.rain.numshaders; i++) {
sprintf(cg.rain.shader[i], "%s%i", str, i);
// Fixed in OPM
// not sure why some maps set a digit at the end...
int 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;
case CS_RAIN_NUMSHADERS:
cg.rain.numshaders = atoi(str);
if (cg.rain.numshaders) {
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;
case CS_CURRENT_OBJECTIVE:
cg.ObjectivesCurrentIndex = atoi(str);
return;
}
if (num >= CS_OBJECTIVES && num < CS_OBJECTIVES + MAX_OBJECTIVES) {
@@ -623,6 +633,8 @@ void CG_Init(clientGameImport_t *imported, int serverMessageNum, int serverComma
cgi = *imported;
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_InitScoresAPI(&cge);
+7 -6
View File
@@ -191,7 +191,7 @@ int CG_GetMarkFragments(
}
iNewPoints = 0;
for (j = 0, pFragment = pCurrFragment; j < iNewPoints; j++, pFragment++) {
for (j = 0, pFragment = pCurrFragment; j < iNewFragments; j++, pFragment++) {
pFragment->firstPoint += iCurrPoints;
pFragment->iIndex = -pEnt->number;
iNewPoints += pFragment->numPoints;
@@ -219,10 +219,11 @@ static qboolean CG_GetMarkInlineModelOrientation(int iIndex) {
}
pCEnt = &cg_entities[-iIndex];
if (pCEnt->currentValid && pCEnt->currentState.modelindex < cgs.inlineDrawModel[ENTITYNUM_NONE])
if (pCEnt->currentValid && pCEnt->currentState.modelindex < cgs.numInlineModels)
{
VectorCopy(pCEnt->lerpAngles, cg_vEntAngles);
VectorCopy(pCEnt->lerpOrigin, cg_vEntOrigin);
cg_bLastEntValid = qtrue;
if (cg_vEntAngles[0] || cg_vEntAngles[1] || cg_vEntAngles[2]) {
AngleVectorsLeft(cg_vEntAngles, cg_fEntAxis[0], cg_fEntAxis[1], cg_fEntAxis[2]);
@@ -937,15 +938,15 @@ void CG_AddMarks(void)
}
if (pMark->markPolys->iIndex < 0) {
if (CG_FrustumCullSphere(pMark->pos, pMark->radius)) {
continue;
}
} else {
vec3_t vWorldPos;
CG_FragmentPosToWorldPos(pMark->pos, vWorldPos);
if (CG_FrustumCullSphere(vWorldPos, pMark->radius)) {
continue;
}
} else {
if (CG_FrustumCullSphere(pMark->pos, pMark->radius)) {
continue;
}
}
pMark->lastVisTime = cg.time;
+6 -1
View File
@@ -1323,7 +1323,12 @@ void CG_ModelAnim(centity_t *cent, qboolean bDoShaderTime)
if (model.frameInfo[i].weight) {
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);
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);
+1 -1
View File
@@ -58,7 +58,7 @@ void ClientGameCommandManager::InitializeRainCvars()
{
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 =
cgi.Cvar_Get("cg_rain_drawcoverage", "0", CVAR_SAVEGAME | CVAR_SERVER_CREATED | CVAR_SYSTEMINFO);
+222 -167
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.
@@ -160,49 +160,49 @@ static void CG_MakeBulletHoleType(
float fVolume;
switch (iEffectNum) {
case 0:
case SFX_BHIT_PAPER_LITE:
sBulletHole += "paper";
break;
case 2:
case SFX_BHIT_WOOD_LITE:
sBulletHole += "wood";
break;
case 4:
case SFX_BHIT_METAL_LITE:
sBulletHole += "metal";
break;
case 6:
case SFX_BHIT_STONE_LITE:
sBulletHole += "stone";
break;
case 8:
case SFX_BHIT_DIRT_LITE:
sBulletHole += "dirt";
break;
case 10:
case SFX_BHIT_GRILL_LITE:
sBulletHole += "grill";
break;
case 12:
case SFX_BHIT_GRASS_LITE:
sBulletHole += "grass";
break;
case 14:
case SFX_BHIT_MUD_LITE:
sBulletHole += "mud";
break;
case 16:
case SFX_BHIT_PUDDLE_LITE:
sBulletHole += "puddle";
break;
case 18:
case SFX_BHIT_GLASS_LITE:
sBulletHole += "glass";
break;
case 20:
case SFX_BHIT_GRAVEL_LITE:
sBulletHole += "gravel";
break;
case 22:
case SFX_BHIT_SAND_LITE:
sBulletHole += "sand";
break;
case 24:
case SFX_BHIT_FOLIAGE_LITE:
sBulletHole += "foliage";
break;
case 26:
case SFX_BHIT_SNOW_LITE:
sBulletHole += "snow";
break;
case 28:
case SFX_BHIT_CARPET_LITE:
sBulletHole += "carpet";
break;
default:
@@ -267,7 +267,7 @@ CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t
break;
case SURF_SNOW:
sBulletHole += "snow";
iEffect = SFX_BHIT_FOLIAGE_LITE;
iEffect = SFX_BHIT_SNOW_LITE;
break;
case SURF_CARPET:
sBulletHole += "carpet";
@@ -283,7 +283,7 @@ CG_MakeBulletHole(const vec3_t i_vPos, const vec3_t i_vNorm, int iLarge, trace_t
break;
case SURF_GLASS:
sBulletHole += "glass";
iEffect = SFX_BHIT_GRASS_LITE;
iEffect = SFX_BHIT_GLASS_LITE;
break;
case SURF_GRAVEL:
fRadius = 0.f;
@@ -366,7 +366,7 @@ static void CG_MakeBubbleTrail(const vec3_t i_vStart, const vec3_t i_vEnd, int i
fDist -= fMove;
while (fDist > 0.f) {
VectorMA(vPos, fMove, vDir, vPos);
sfxManager.MakeEffect_Angles(32, vPos, vec_zero);
sfxManager.MakeEffect_Angles(SFX_WATER_TRAIL_BUBBLE, vPos, vec_zero);
fMove = 16.f + crandom() * 8.f * alpha;
fDist -= fMove;
@@ -535,7 +535,7 @@ static void CG_MakeBulletTracerInternal(
while (trace.fraction < 1) {
if (bIgnoreEntities) {
cgi.CM_BoxTrace(&trace, vTraceStart, vTraceEnd, vec_zero, vec_zero, 0, MASK_SHOT, qfalse);
cgi.CM_BoxTrace(&trace, vTraceStart, vTraceEnd, vec_zero, vec_zero, 0, MASK_SHOT_FLUID, qfalse);
if (trace.fraction == 1.0f) {
trace.entityNum = ENTITYNUM_NONE;
@@ -554,7 +554,7 @@ static void CG_MakeBulletTracerInternal(
vec_zero,
vTraceStart,
ENTITYNUM_NONE,
MASK_SHOT,
MASK_SHOT_FLUID,
qfalse,
qfalse,
"CG_MakeBulletTracerInternal"
@@ -564,11 +564,11 @@ static void CG_MakeBulletTracerInternal(
if (trace.contents & CONTENTS_FLUID) {
fDist = DotProduct(vDir, trace.plane.normal) * -2.0f;
VectorMA(vDir, fDist, trace.plane.normal, vTmp);
VectorAdd(vTmp, vTmp, trace.plane.normal);
VectorMA(trace.plane.normal, 2.0, vTmp, trace.plane.normal);
VectorNormalizeFast(trace.plane.normal);
}
if (!bInWater && trace.fraction < 1.0f && iNumImpacts <= 127) {
if (!bInWater && trace.fraction < 1.0f && iNumImpacts < ARRAY_LEN(tImpacts)) {
memcpy(&tImpacts[iNumImpacts], &trace, sizeof(trace_t));
iNumImpacts++;
}
@@ -859,14 +859,14 @@ void CG_AddBulletImpacts()
}
if (fImpSndDistRA < fImpSndDistLA) {
if (wall_impact_type[iImpSndIndexRA]) {
if (wall_impact_type[iImpSndIndexRA] != SFX_BHIT_PAPER_LITE) {
if (wall_impact_large[iImpSndIndexRA]) {
fVolume = 1.f;
} else {
fVolume = 0.75f;
}
if (wall_impact_type[iImpSndIndexRA] == 2 || wall_impact_type[iImpSndIndexRA] == 3) {
if (wall_impact_type[iImpSndIndexRA] == SFX_BHIT_WOOD_LITE || wall_impact_type[iImpSndIndexRA] == SFX_BHIT_WOOD_HARD) {
sSoundName = "snd_bh_metal";
} else {
sSoundName = "snd_bh_wood";
@@ -897,7 +897,7 @@ void CG_AddBulletImpacts()
fVolume = 0.75f;
}
if (wall_impact_type[iImpSndIndexRB] == 2 || wall_impact_type[iImpSndIndexRB] == 3) {
if (wall_impact_type[iImpSndIndexRB] == SFX_BHIT_WOOD_LITE || wall_impact_type[iImpSndIndexRB] == SFX_BHIT_WOOD_HARD) {
sSoundName = "snd_bh_metal";
} else {
sSoundName = "snd_bh_wood";
@@ -923,14 +923,14 @@ void CG_AddBulletImpacts()
}
if (fImpSndDistLA > 9999.0f) {
if (wall_impact_type[0]) {
if (wall_impact_type[0] != SFX_BHIT_PAPER_LITE) {
if (wall_impact_large[0]) {
fVolume = 1.f;
} else {
fVolume = 0.75f;
}
if (wall_impact_type[0] == 2 || wall_impact_type[0] == 3) {
if (wall_impact_type[0] == SFX_BHIT_WOOD_LITE || wall_impact_type[0] == SFX_BHIT_WOOD_HARD) {
sSoundName = "snd_bh_metal";
} else {
sSoundName = "snd_bh_wood";
@@ -945,14 +945,14 @@ void CG_AddBulletImpacts()
}
if (fImpSndDistLB < fImpSndDistLA) {
if (wall_impact_type[iImpSndIndexLB]) {
if (wall_impact_type[iImpSndIndexLB] != SFX_BHIT_PAPER_LITE) {
if (wall_impact_large[iImpSndIndexLB]) {
fVolume = 1.f;
} else {
fVolume = 0.75f;
}
if (wall_impact_type[iImpSndIndexLB] == 2 || wall_impact_type[iImpSndIndexLB] == 3) {
if (wall_impact_type[iImpSndIndexLB] == SFX_BHIT_WOOD_LITE || wall_impact_type[iImpSndIndexLB] == SFX_BHIT_WOOD_HARD) {
sSoundName = "snd_bh_metal";
} else {
sSoundName = "snd_bh_wood";
@@ -987,14 +987,16 @@ void CG_AddBulletImpacts()
if (flesh_impact_count) {
if (flesh_impact_count > 1) {
fImpSndDistRA = 9999.0;
fImpSndDistRB = 9999.0;
iImpSndIndexRA = 0;
iImpSndIndexRB = 0;
for (i = 0; i < flesh_impact_count; i++) {
VectorSubtract(wall_impact_pos[i], cg.SoundOrg, vTmp);
VectorSubtract(flesh_impact_pos[i], cg.SoundOrg, vTmp);
iHeadDist = VectorLength(vTmp);
if (DotProduct(vTmp, cg.SoundAxis[1]) > 0.f) {
if (iHeadDist < fImpSndDistRA) {
if (iHeadDist < fImpSndDistRB) {
fImpSndDistRA = iHeadDist;
iImpSndIndexRA = i;
}
@@ -1003,6 +1005,30 @@ void CG_AddBulletImpacts()
iImpSndIndexRA = i;
}
}
if (fImpSndDistRA < 9999) {
sfxManager.MakeEffect_Normal(
flesh_impact_large[iImpSndIndexRA] ? SFX_BHIT_HUMAN_UNIFORM_HARD : SFX_BHIT_HUMAN_UNIFORM_LITE,
flesh_impact_pos[iImpSndIndexRA],
flesh_impact_norm[iImpSndIndexRA]
);
}
if (fImpSndDistRB < 9999) {
sfxManager.MakeEffect_Normal(
flesh_impact_large[iImpSndIndexRB] ? SFX_BHIT_HUMAN_UNIFORM_HARD : SFX_BHIT_HUMAN_UNIFORM_LITE,
flesh_impact_pos[iImpSndIndexRB],
flesh_impact_norm[iImpSndIndexRB]
);
}
} else {
for (i = 0; i < flesh_impact_count; i++) {
sfxManager.MakeEffect_Normal(
flesh_impact_large[i] ? SFX_BHIT_HUMAN_UNIFORM_HARD : SFX_BHIT_HUMAN_UNIFORM_LITE,
flesh_impact_pos[i],
flesh_impact_norm[i]
);
}
}
flesh_impact_count = 0;
@@ -1031,22 +1057,33 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
return;
}
switch (iType) {
case 13:
iBaseEffect = SFX_EXP_GREN_BASE;
break;
case 14:
iBaseEffect = SFX_EXP_BAZOOKA_BASE;
break;
case 15:
iBaseEffect = SFX_EXP_HEAVYSHELL_BASE;
break;
case 16:
iBaseEffect = SFX_EXP_TANK_BASE;
break;
default:
iBaseEffect = SFX_EXP_GREN_BASE;
break;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
switch (iType) {
case CGM_EXPLOSION_EFFECT_1:
iBaseEffect = SFX_EXP_GREN_BASE;
break;
case CGM_EXPLOSION_EFFECT_2:
iBaseEffect = SFX_EXP_BAZOOKA_BASE;
break;
case CGM_EXPLOSION_EFFECT_3:
iBaseEffect = SFX_EXP_HEAVYSHELL_BASE;
break;
case CGM_EXPLOSION_EFFECT_4:
iBaseEffect = SFX_EXP_TANK_BASE;
break;
default:
iBaseEffect = SFX_EXP_GREN_BASE;
break;
}
} else {
switch (iType) {
case CGM6_EXPLOSION_EFFECT_2:
iBaseEffect = SFX_EXP_BAZOOKA_BASE;
break;
default:
iBaseEffect = SFX_EXP_GREN_BASE;
break;
}
}
CG_Trace(
@@ -1074,14 +1111,18 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
break;
case SFX_EXP_BAZOOKA_BASE:
iSurfEffect = SFX_EXP_BAZOOKA_SNOW;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
case SFX_EXP_HEAVYSHELL_BASE:
iSurfEffect = SFX_EXP_HEAVYSHELL_SNOW;
break;
default:
iSurfEffect = SFX_EXP_GREN_SNOW;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
}
fRadius = 0;
@@ -1115,14 +1156,18 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
break;
case SFX_EXP_BAZOOKA_BASE:
iSurfEffect = SFX_EXP_BAZOOKA_DIRT;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
case SFX_EXP_HEAVYSHELL_BASE:
iSurfEffect = SFX_EXP_HEAVYSHELL_DIRT;
break;
default:
iSurfEffect = SFX_EXP_GREN_DIRT;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
}
fRadius = 0;
@@ -1144,7 +1189,9 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
break;
default:
iSurfEffect = SFX_EXP_GREN_GRASS;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
}
fRadius = 0;
@@ -1156,14 +1203,18 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
break;
case SFX_EXP_BAZOOKA_BASE:
iSurfEffect = SFX_EXP_BAZOOKA_STONE;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
case SFX_EXP_HEAVYSHELL_BASE:
iSurfEffect = SFX_EXP_HEAVYSHELL_STONE;
break;
default:
iSurfEffect = SFX_EXP_GREN_STONE;
iBaseEffect = -1;
if (cg_protocol >= protocol_e::PROTOCOL_MOHTA_MIN) {
iBaseEffect = -1;
}
break;
}
break;
@@ -1211,7 +1262,9 @@ void CG_MakeExplosionEffect(const vec3_t vPos, int iType)
);
}
sfxManager.MakeEffect_Normal(iBaseEffect, vEnd, trace.plane.normal);
if (iBaseEffect != -1) {
sfxManager.MakeEffect_Normal(iBaseEffect, vEnd, trace.plane.normal);
}
}
void CG_MakeVehicleEffect(vec3_t i_vStart, vec3_t i_vEnd, vec3_t i_vDir)
@@ -1247,10 +1300,10 @@ void CG_ParseCGMessage_ver_15()
iType = cgi.MSG_ReadBits(6);
switch (iType) {
case 1:
case 2:
case 5:
if (iType == 1) {
case CGM_BULLET_1:
case CGM_BULLET_2:
case CGM_BULLET_5:
if (iType == CGM_BULLET_1) {
vTmp[0] = cgi.MSG_ReadCoord();
vTmp[1] = cgi.MSG_ReadCoord();
vTmp[2] = cgi.MSG_ReadCoord();
@@ -1259,7 +1312,7 @@ void CG_ParseCGMessage_ver_15()
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
if (iType != 1) {
if (iType != CGM_BULLET_1) {
vTmp[0] = vStart[0];
vTmp[1] = vStart[1];
vTmp[2] = vStart[2];
@@ -1279,18 +1332,18 @@ void CG_ParseCGMessage_ver_15()
alpha = 1.0f;
}
if (iType == 1) {
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue, alpha);
} else if (iType == 2) {
if (iType == CGM_BULLET_1) {
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qtrue, qtrue, alpha);
} else if (iType == CGM_BULLET_2) {
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue, alpha);
} else {
CG_MakeBubbleTrail(vStart, vEndArray[0], iLarge, alpha);
}
break;
case 3:
case 4:
if (iType == 3) {
case CGM_BULLET_3:
case CGM_BULLET_4:
if (iType == CGM_BULLET_3) {
vTmp[0] = cgi.MSG_ReadCoord();
vTmp[1] = cgi.MSG_ReadCoord();
vTmp[2] = cgi.MSG_ReadCoord();
@@ -1324,12 +1377,12 @@ void CG_ParseCGMessage_ver_15()
CG_MakeBulletTracer(vTmp, vStart, vEndArray, iCount, iLarge, iInfo, qtrue, alpha);
}
break;
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case CGM_BULLET_6:
case CGM_BULLET_7:
case CGM_BULLET_8:
case CGM_BULLET_9:
case CGM_BULLET_10:
case CGM_BULLET_11:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
@@ -1337,7 +1390,7 @@ void CG_ParseCGMessage_ver_15()
iLarge = cgi.MSG_ReadBits(2);
switch (iType) {
case 6:
case CGM_BULLET_6:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
@@ -1346,16 +1399,16 @@ void CG_ParseCGMessage_ver_15()
wall_impact_count++;
}
break;
case 7:
case CGM_BULLET_7:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
wall_impact_large[wall_impact_count] = iLarge;
wall_impact_type[wall_impact_count] = 6;
wall_impact_type[wall_impact_count] = SFX_BHIT_STONE_LITE;
wall_impact_count++;
}
break;
case 8:
case CGM_BULLET_8:
if (flesh_impact_count < MAX_IMPACTS) {
// negative
VectorNegate(vEnd, vEnd);
@@ -1365,7 +1418,7 @@ void CG_ParseCGMessage_ver_15()
flesh_impact_count++;
}
break;
case 9:
case CGM_BULLET_9:
if (flesh_impact_count < MAX_IMPACTS) {
// negative
VectorNegate(vEnd, vEnd);
@@ -1375,21 +1428,21 @@ void CG_ParseCGMessage_ver_15()
flesh_impact_count++;
}
break;
case 10:
case CGM_BULLET_10:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
wall_impact_large[wall_impact_count] = iLarge;
wall_impact_type[wall_impact_count] = 2;
wall_impact_type[wall_impact_count] = SFX_BHIT_WOOD_LITE;
wall_impact_count++;
}
break;
case 11:
case CGM_BULLET_11:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
wall_impact_large[wall_impact_count] = iLarge;
wall_impact_type[wall_impact_count] = 4;
wall_impact_type[wall_impact_count] = SFX_BHIT_METAL_LITE;
wall_impact_count++;
}
break;
@@ -1398,7 +1451,7 @@ void CG_ParseCGMessage_ver_15()
}
break;
case 12:
case CGM_MELEE_IMPACT:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
@@ -1407,33 +1460,33 @@ void CG_ParseCGMessage_ver_15()
vEnd[2] = cgi.MSG_ReadCoord();
CG_MeleeImpact(vStart, vEnd);
break;
case 13:
case 14:
case 15:
case 16:
case CGM_EXPLOSION_EFFECT_1:
case CGM_EXPLOSION_EFFECT_2:
case CGM_EXPLOSION_EFFECT_3:
case CGM_EXPLOSION_EFFECT_4:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
CG_MakeExplosionEffect(vStart, iType);
break;
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case CGM_MAKE_EFFECT_1:
case CGM_MAKE_EFFECT_2:
case CGM_MAKE_EFFECT_3:
case CGM_MAKE_EFFECT_4:
case CGM_MAKE_EFFECT_5:
case CGM_MAKE_EFFECT_6:
case CGM_MAKE_EFFECT_7:
case CGM_MAKE_EFFECT_8:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
cgi.MSG_ReadDir(vEnd);
sfxManager.MakeEffect_Normal(iType + SFX_EXP_GREN_PUDDLE, vStart, vEnd);
sfxManager.MakeEffect_Normal(SFX_EXP_GREN_PUDDLE + iType, vStart, vEnd);
break;
case 26:
case 27:
case CGM_MAKE_CRATE_DEBRIS:
case CGM_MAKE_WINDOW_DEBRIS:
{
str sEffect;
char cTmp[8];
@@ -1446,7 +1499,7 @@ void CG_ParseCGMessage_ver_15()
// get the integer as string
snprintf(cTmp, sizeof(cTmp), "%d", iLarge);
if (iType == 26) {
if (iType == CGM_MAKE_CRATE_DEBRIS) {
sEffect = "models/fx/crates/debris_";
} else {
sEffect = "models/fx/windows/debris_";
@@ -1463,7 +1516,7 @@ void CG_ParseCGMessage_ver_15()
}
break;
case 28:
case CGM_BULLET_NO_BARREL_1:
vTmp[0] = cgi.MSG_ReadCoord();
vTmp[1] = cgi.MSG_ReadCoord();
vTmp[2] = cgi.MSG_ReadCoord();
@@ -1474,6 +1527,7 @@ void CG_ParseCGMessage_ver_15()
vEndArray[0][1] = cgi.MSG_ReadCoord();
vEndArray[0][2] = cgi.MSG_ReadCoord();
iLarge = cgi.MSG_ReadBits(2);
if (cgi.MSG_ReadBits(1)) {
int iAlpha = cgi.MSG_ReadBits(10);
alpha = (float)iAlpha / 512.0;
@@ -1487,7 +1541,7 @@ void CG_ParseCGMessage_ver_15()
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qtrue, qtrue, alpha);
break;
case 29:
case CGM_BULLET_NO_BARREL_2:
memset(vTmp, 0, sizeof(vTmp));
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
@@ -1496,6 +1550,7 @@ void CG_ParseCGMessage_ver_15()
vEndArray[0][1] = cgi.MSG_ReadCoord();
vEndArray[0][2] = cgi.MSG_ReadCoord();
iLarge = cgi.MSG_ReadBits(1);
if (cgi.MSG_ReadBits(1)) {
int iAlpha = cgi.MSG_ReadBits(10);
alpha = (float)iAlpha / 512.0;
@@ -1509,7 +1564,7 @@ void CG_ParseCGMessage_ver_15()
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue, alpha);
break;
case 30:
case CGM_HUDDRAW_SHADER:
iInfo = cgi.MSG_ReadByte();
strcpy(cgi.HudDrawElements[iInfo].shaderName, cgi.MSG_ReadString());
cgi.HudDrawElements[iInfo].string[0] = 0;
@@ -1519,13 +1574,13 @@ void CG_ParseCGMessage_ver_15()
CG_HudDrawShader(iInfo);
break;
case 31:
case CGM_HUDDRAW_ALIGN:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].iHorizontalAlign = cgi.MSG_ReadBits(2);
cgi.HudDrawElements[iInfo].iVerticalAlign = cgi.MSG_ReadBits(2);
break;
case 32:
case CGM_HUDDRAW_RECT:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].iX = cgi.MSG_ReadShort();
cgi.HudDrawElements[iInfo].iY = cgi.MSG_ReadShort();
@@ -1533,30 +1588,30 @@ void CG_ParseCGMessage_ver_15()
cgi.HudDrawElements[iInfo].iHeight = cgi.MSG_ReadShort();
break;
case 33:
case CGM_HUDDRAW_VIRTUALSIZE:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].bVirtualScreen = cgi.MSG_ReadBits(1);
break;
case 34:
case CGM_HUDDRAW_COLOR:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].vColor[0] = cgi.MSG_ReadByte() / 255.0;
cgi.HudDrawElements[iInfo].vColor[1] = cgi.MSG_ReadByte() / 255.0;
cgi.HudDrawElements[iInfo].vColor[2] = cgi.MSG_ReadByte() / 255.0;
break;
case 35:
case CGM_HUDDRAW_ALPHA:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].vColor[3] = cgi.MSG_ReadByte() / 255.0;
break;
case 36:
case CGM_HUDDRAW_STRING:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].hShader = 0;
strcpy(cgi.HudDrawElements[iInfo].string, cgi.MSG_ReadString());
break;
case 37:
case CGM_HUDDRAW_FONT:
iInfo = cgi.MSG_ReadByte();
strcpy(cgi.HudDrawElements[iInfo].fontName, cgi.MSG_ReadString());
cgi.HudDrawElements[iInfo].hShader = 0;
@@ -1565,14 +1620,14 @@ void CG_ParseCGMessage_ver_15()
CG_HudDrawFont(iInfo);
break;
case 38:
case 39:
case CGM_NOTIFY_KILL:
case CGM_NOTIFY_HIT:
{
int iOldEnt;
iOldEnt = current_entity_number;
current_entity_number = cg.snap->ps.clientNum;
if (iType == 36) {
if (iType == CGM_NOTIFY_HIT) {
commandManager.PlaySound("dm_kill_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
} else {
commandManager.PlaySound("dm_hit_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
@@ -1582,7 +1637,7 @@ void CG_ParseCGMessage_ver_15()
}
break;
case 40:
case CGM_VOICE_CHAT:
{
int iOldEnt;
@@ -1608,7 +1663,7 @@ void CG_ParseCGMessage_ver_15()
current_entity_number = iOldEnt;
}
break;
case 41:
case CGM_FENCEPOST:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
@@ -1647,10 +1702,10 @@ void CG_ParseCGMessage_ver_6()
iType = cgi.MSG_ReadBits(6);
switch (iType) {
case 1:
case 2:
case 5:
if (iType == 1) {
case CGM6_BULLET_1:
case CGM6_BULLET_2:
case CGM6_BULLET_5:
if (iType == CGM6_BULLET_1) {
vTmp[0] = cgi.MSG_ReadCoord();
vTmp[1] = cgi.MSG_ReadCoord();
vTmp[2] = cgi.MSG_ReadCoord();
@@ -1659,7 +1714,7 @@ void CG_ParseCGMessage_ver_6()
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
if (iType != 1) {
if (iType != CGM6_BULLET_1) {
vTmp[0] = vStart[0];
vTmp[1] = vStart[1];
vTmp[2] = vStart[2];
@@ -1670,18 +1725,18 @@ void CG_ParseCGMessage_ver_6()
vEndArray[0][2] = cgi.MSG_ReadCoord();
iLarge = cgi.MSG_ReadBits(1);
if (iType == 1) {
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue);
} else if (iType == 2) {
if (iType == CGM6_BULLET_1) {
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qtrue, qtrue);
} else if (iType == CGM6_BULLET_2) {
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue);
} else {
CG_MakeBubbleTrail(vStart, vEndArray[0], iLarge);
}
break;
case 3:
case 4:
if (iType == 3) {
case CGM6_BULLET_3:
case CGM6_BULLET_4:
if (iType == CGM6_BULLET_3) {
vTmp[0] = cgi.MSG_ReadCoord();
vTmp[1] = cgi.MSG_ReadCoord();
vTmp[2] = cgi.MSG_ReadCoord();
@@ -1705,11 +1760,11 @@ void CG_ParseCGMessage_ver_6()
CG_MakeBulletTracer(vTmp, vStart, vEndArray, iCount, iLarge, iInfo, qtrue);
}
break;
case 6:
case 7:
case 8:
case 9:
case 10:
case CGM6_BULLET_6:
case CGM6_BULLET_7:
case CGM6_BULLET_8:
case CGM6_BULLET_9:
case CGM6_BULLET_10:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
@@ -1717,16 +1772,16 @@ void CG_ParseCGMessage_ver_6()
iLarge = cgi.MSG_ReadBits(1);
switch (iType) {
case 6:
case CGM6_BULLET_6:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
wall_impact_large[wall_impact_count] = iLarge;
wall_impact_type[wall_impact_count] = 0;
wall_impact_type[wall_impact_count] = SFX_BHIT_PAPER_LITE;
wall_impact_count++;
}
break;
case 7:
case CGM6_BULLET_7:
if (flesh_impact_count < MAX_IMPACTS) {
// negative
VectorNegate(vEnd, vEnd);
@@ -1736,7 +1791,7 @@ void CG_ParseCGMessage_ver_6()
flesh_impact_count++;
}
break;
case 8:
case CGM6_BULLET_8:
if (flesh_impact_count < MAX_IMPACTS) {
// negative
VectorNegate(vEnd, vEnd);
@@ -1746,21 +1801,21 @@ void CG_ParseCGMessage_ver_6()
flesh_impact_count++;
}
break;
case 9:
case CGM6_BULLET_9:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
wall_impact_large[wall_impact_count] = iLarge;
wall_impact_type[wall_impact_count] = (iLarge != 0) + 2;
wall_impact_type[wall_impact_count] = iLarge ? SFX_BHIT_WOOD_HARD : SFX_BHIT_WOOD_LITE;
wall_impact_count++;
}
break;
case 10:
case CGM6_BULLET_10:
if (wall_impact_count < MAX_IMPACTS) {
VectorCopy(vStart, wall_impact_pos[wall_impact_count]);
VectorCopy(vEnd, wall_impact_norm[wall_impact_count]);
wall_impact_large[wall_impact_count] = iLarge;
wall_impact_type[wall_impact_count] = (iLarge != 0) + 4;
wall_impact_type[wall_impact_count] = iLarge ? SFX_BHIT_METAL_HARD : SFX_BHIT_METAL_LITE;
wall_impact_count++;
}
break;
@@ -1769,7 +1824,7 @@ void CG_ParseCGMessage_ver_6()
}
break;
case 11:
case CGM6_MELEE_IMPACT:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
@@ -1778,31 +1833,31 @@ void CG_ParseCGMessage_ver_6()
vEnd[2] = cgi.MSG_ReadCoord();
CG_MeleeImpact(vStart, vEnd);
break;
case 12:
case 13:
case CGM6_EXPLOSION_EFFECT_1:
case CGM6_EXPLOSION_EFFECT_2:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
CG_MakeExplosionEffect(vStart, iType);
break;
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case CGM6_MAKE_EFFECT_1:
case CGM6_MAKE_EFFECT_2:
case CGM6_MAKE_EFFECT_3:
case CGM6_MAKE_EFFECT_4:
case CGM6_MAKE_EFFECT_5:
case CGM6_MAKE_EFFECT_6:
case CGM6_MAKE_EFFECT_7:
case CGM6_MAKE_EFFECT_8:
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
vStart[2] = cgi.MSG_ReadCoord();
cgi.MSG_ReadDir(vEnd);
sfxManager.MakeEffect_Normal(iType + SFX_EXP_GREN_PUDDLE, vStart, vEnd);
sfxManager.MakeEffect_Normal(SFX_EXP_GREN_PUDDLE + iType, vStart, vEnd);
break;
case 23:
case 24:
case CGM6_MAKE_CRATE_DEBRIS:
case CGM6_MAKE_WINDOW_DEBRIS:
{
str sEffect;
char cTmp[8];
@@ -1815,7 +1870,7 @@ void CG_ParseCGMessage_ver_6()
// get the integer as string
snprintf(cTmp, sizeof(cTmp), "%d", iLarge);
if (iType == 23) {
if (iType == CGM6_MAKE_CRATE_DEBRIS) {
sEffect = "models/fx/crates/debris_";
} else {
sEffect = "models/fx/windows/debris_";
@@ -1832,7 +1887,7 @@ void CG_ParseCGMessage_ver_6()
}
break;
case 25:
case CGM6_BULLET_NO_BARREL_1:
vTmp[0] = cgi.MSG_ReadCoord();
vTmp[1] = cgi.MSG_ReadCoord();
vTmp[2] = cgi.MSG_ReadCoord();
@@ -1847,7 +1902,7 @@ void CG_ParseCGMessage_ver_6()
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qtrue, qtrue);
break;
case 26:
case CGM6_BULLET_NO_BARREL_2:
memset(vTmp, 0, sizeof(vTmp));
vStart[0] = cgi.MSG_ReadCoord();
vStart[1] = cgi.MSG_ReadCoord();
@@ -1860,7 +1915,7 @@ void CG_ParseCGMessage_ver_6()
CG_MakeBulletTracer(vTmp, vStart, vEndArray, 1, iLarge, qfalse, qtrue);
break;
case 27:
case CGM6_HUDDRAW_SHADER:
iInfo = cgi.MSG_ReadByte();
strcpy(cgi.HudDrawElements[iInfo].shaderName, cgi.MSG_ReadString());
cgi.HudDrawElements[iInfo].string[0] = 0;
@@ -1870,13 +1925,13 @@ void CG_ParseCGMessage_ver_6()
CG_HudDrawShader(iInfo);
break;
case 28:
case CGM6_HUDDRAW_ALIGN:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].iHorizontalAlign = cgi.MSG_ReadBits(2);
cgi.HudDrawElements[iInfo].iVerticalAlign = cgi.MSG_ReadBits(2);
break;
case 29:
case CGM6_HUDDRAW_RECT:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].iX = cgi.MSG_ReadShort();
cgi.HudDrawElements[iInfo].iY = cgi.MSG_ReadShort();
@@ -1884,30 +1939,30 @@ void CG_ParseCGMessage_ver_6()
cgi.HudDrawElements[iInfo].iHeight = cgi.MSG_ReadShort();
break;
case 30:
case CGM6_HUDDRAW_VIRTUALSIZE:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].bVirtualScreen = cgi.MSG_ReadBits(1);
break;
case 31:
case CGM6_HUDDRAW_COLOR:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].vColor[0] = cgi.MSG_ReadByte() / 255.0;
cgi.HudDrawElements[iInfo].vColor[1] = cgi.MSG_ReadByte() / 255.0;
cgi.HudDrawElements[iInfo].vColor[2] = cgi.MSG_ReadByte() / 255.0;
break;
case 32:
case CGM6_HUDDRAW_ALPHA:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].vColor[3] = cgi.MSG_ReadByte() / 255.0;
break;
case 33:
case CGM6_HUDDRAW_STRING:
iInfo = cgi.MSG_ReadByte();
cgi.HudDrawElements[iInfo].hShader = 0;
strcpy(cgi.HudDrawElements[iInfo].string, cgi.MSG_ReadString());
break;
case 34:
case CGM6_HUDDRAW_FONT:
iInfo = cgi.MSG_ReadByte();
strcpy(cgi.HudDrawElements[iInfo].fontName, cgi.MSG_ReadString());
cgi.HudDrawElements[iInfo].hShader = 0;
@@ -1916,14 +1971,14 @@ void CG_ParseCGMessage_ver_6()
CG_HudDrawFont(iInfo);
break;
case 35:
case 36:
case CGM6_NOTIFY_KILL:
case CGM6_NOTIFY_HIT:
{
int iOldEnt;
iOldEnt = current_entity_number;
current_entity_number = cg.snap->ps.clientNum;
if (iType == 36) {
if (iType == CGM6_NOTIFY_HIT) {
commandManager.PlaySound("dm_kill_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
} else {
commandManager.PlaySound("dm_hit_notify", NULL, CHAN_LOCAL, 2.0, -1, -1, 1);
@@ -1933,7 +1988,7 @@ void CG_ParseCGMessage_ver_6()
}
break;
case 37:
case CGM6_VOICE_CHAT:
{
int iOldEnt;
+2
View File
@@ -430,6 +430,8 @@ functions exported to the main executable
void (*CL_RestoreSavedCgameState)();
void (*CL_ClearSavedCgameState)();
size_t (*getConfigStringIdNormalized)(size_t num);
cvar_t *fsDebug;
hdelement_t *HudDrawElements;
clientAnim_t *anim;
+1 -1
View File
@@ -296,7 +296,7 @@ static void CG_ServerCommand(qboolean modelOnly)
}
if (!strcmp(cmd, "cs")) {
CG_ConfigStringModified(atoi(cgi.Argv(1)), modelOnly);
CG_ConfigStringModified(cgi.getConfigStringIdNormalized(atoi(cgi.Argv(1))), modelOnly);
return;
}
+175 -4
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.
@@ -38,7 +38,8 @@ static vec3_t g_vLadderstepMaxs;
ClientSpecialEffectsManager sfxManager;
Event EV_SFX_EffectDelay(
Event EV_SFX_EffectDelay
(
"effectdelay",
EV_DEFAULT,
"iivvvvv",
@@ -234,9 +235,15 @@ void ClientSpecialEffectsManager::LoadEffects()
szEffectModel = "models/fx/bazookaexp_base.tik";
break;
case SFX_EXP_HEAVYSHELL_BASE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/heavyshellexp_base.tik";
break;
case SFX_EXP_TANK_BASE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/tankexp_base.tik";
break;
case SFX_EXP_GREN_PAPER:
@@ -285,30 +292,57 @@ void ClientSpecialEffectsManager::LoadEffects()
szEffectModel = "models/fx/grenexp_carpet.tik";
break;
case SFX_EXP_HEAVYSHELL_DIRT:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/heavyshellexp_dirt.tik";
break;
case SFX_EXP_HEAVYSHELL_STONE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/heavyshellexp_stone.tik";
break;
case SFX_EXP_HEAVYSHELL_SNOW:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/heavyshellexp_snow.tik";
break;
case SFX_EXP_TANK_DIRT:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/tankexp_dirt.tik";
break;
case SFX_EXP_TANK_STONE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/tankexp_stone.tik";
break;
case SFX_EXP_TANK_SNOW:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/tankexp_snow.tik";
break;
case SFX_EXP_BAZOOKA_DIRT:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/bazookaexp_dirt.tik";
break;
case SFX_EXP_BAZOOKA_STONE:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/bazookaexp_stone.tik";
break;
case SFX_EXP_BAZOOKA_SNOW:
if (cg_protocol < protocol_e::PROTOCOL_MOHTA_MIN) {
continue;
}
szEffectModel = "models/fx/bazookaexp_snow.tik";
break;
case SFX_WATER_RIPPLE_STILL:
@@ -486,7 +520,7 @@ void ClientSpecialEffectsManager::ExecuteEffect(
AxisCopy(axis, pCommand->emitter->tag_axis);
pCommand->emitter->cgd.createTime = cg.time;
commandManager.SetSpawnthing(pCommand->emitter);
(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)
{
// 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));
}
}
/*
+4 -5
View File
@@ -1146,7 +1146,7 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
newForward = p->cgd.origin - m_spawnthing->cgd.origin;
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
// vector pointing back to the origin
Vector dir, end;
@@ -1182,10 +1182,9 @@ void ClientGameCommandManager::SpawnTempModel(int mcount)
cosa = cos(fAngle);
p->cgd.origin = start + vForward * fHeight;
p->cgd.origin += start + vLeft * (cosa * fRadius);
p->cgd.origin += start + vUp * (sina * fRadius);
} else if (m_spawnthing->sphereRadius != 0) // Offset in a spherical pattern
{
p->cgd.origin += vLeft * (cosa * fRadius);
p->cgd.origin += vUp * (sina * fRadius);
} else if (m_spawnthing->sphereRadius != 0) { // Offset in a spherical pattern
Vector dir, end;
dir = Vector(crandom(), crandom(), crandom());
-11
View File
@@ -560,17 +560,6 @@ static int CG_CalcViewValues(void)
CG_CalcVrect();
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;
VectorCopy(ps->origin, cg.refdef.vieworg);
+48 -20
View File
@@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
static const char *AnimPrefixList[] = {
"",
"unarmed",
"papers",
"colt45",
"p38",
@@ -45,7 +46,6 @@ static const char *AnimPrefixList[] = {
"bazooka",
"panzerschreck",
"shotgun",
"unarmed",
//
// Team Assault and Team Tactics weapons
"mg42portable",
@@ -82,6 +82,7 @@ static const char *AnimPrefixList[] = {
enum animPrefix_e {
WPREFIX_NONE,
WPREFIX_UNARMED,
WPREFIX_PAPERS,
WPREFIX_COLT45,
WPREFIX_P38,
@@ -99,7 +100,6 @@ enum animPrefix_e {
WPREFIX_BAZOOKA,
WPREFIX_PANZERSCHRECK,
WPREFIX_SHOTGUN,
WPREFIX_UNARMED,
//
// Team Assault and Team Tactics weapons
WPREFIX_MG42_PORTABLE,
@@ -308,6 +308,9 @@ int CG_GetVMAnimPrefixIndex()
if (!Q_stricmp(szWeaponName, "Panzerschreck")) {
return WPREFIX_PANZERSCHRECK;
}
if (!Q_stricmp(szWeaponName, "Gewehrgranate")) {
return WPREFIX_KAR98_MORTAR;
}
if (!Q_stricmp(szWeaponName, "Shotgun")) {
return WPREFIX_SHOTGUN;
}
@@ -335,9 +338,11 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
char szAnimName[MAX_QPATH];
dtiki_t *pTiki;
qboolean bAnimChanged;
qboolean bWeaponChanged;
fCrossblendFrac = 0.0;
bAnimChanged = 0;
bAnimChanged = qfalse;
bWeaponChanged = qfalse; // Added in OPM
pTiki = pModel->tiki;
if (cgi.anim->g_iLastEquippedWeaponStat == cg.snap->ps.stats[STAT_EQUIPPED_WEAPON]
@@ -348,7 +353,9 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
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]));
cgi.anim->g_iLastAnimPrefixIndex = iAnimPrefixIndex;
bAnimChanged = qtrue;
bAnimChanged = qtrue;
bWeaponChanged = qtrue;
}
if (cgi.anim->g_iLastVMAnim == -1) {
@@ -422,20 +429,27 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
}
sprintf(szAnimName, "%s_%s", AnimPrefixList[iAnimPrefixIndex], pszAnimSuffix);
fCrossblendTime = cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index);
fCrossblendAmount = cgi.anim->g_iCurrentVMDuration / 1000.0;
if (!bWeaponChanged) {
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) {
fCrossblendFrac = fCrossblendAmount / fCrossblendTime;
for (i = 0; i < MAX_FRAMEINFOS; ++i) {
if (cgi.anim->g_VMFrameInfo[i].weight) {
if (i == cgi.anim->g_iCurrentVMAnimSlot) {
cgi.anim->g_VMFrameInfo[i].weight = fCrossblendFrac;
} else {
cgi.anim->g_VMFrameInfo[i].weight *= (1.0 - fCrossblendFrac);
if (fCrossblendAmount < fCrossblendTime && fCrossblendAmount > 0.0) {
fCrossblendFrac = fCrossblendAmount / fCrossblendTime;
for (i = 0; i < MAX_FRAMEINFOS; ++i) {
if (cgi.anim->g_VMFrameInfo[i].weight) {
if (i == cgi.anim->g_iCurrentVMAnimSlot) {
cgi.anim->g_VMFrameInfo[i].weight = fCrossblendFrac;
} else {
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;
@@ -450,17 +464,31 @@ void CG_ViewModelAnimation(refEntity_t *pModel)
cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].weight = 1.0;
cgi.anim->g_iCurrentVMDuration = 0;
fCrossblendTime = cgi.Anim_CrossblendTime(pTiki, cgi.anim->g_VMFrameInfo[cgi.anim->g_iCurrentVMAnimSlot].index);
if (!fCrossblendTime) {
if (!bWeaponChanged) {
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) {
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;
}
}
+283 -280
View File
@@ -42,7 +42,9 @@ const char *cg_vsstypes[] = {
"debris"
};
cvssource_t *vss_sorttable[16384];
#define MAX_VSS_SORTS 16384
cvssource_t *vss_sorttable[MAX_VSS_SORTS];
static int lastVSSFrameTime;
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);
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 {
if (!vPush[0] && !vPush[1] && !vPush[2]) {
VectorSet(vPush, crandom(), crandom(), crandom());
VectorAdd(pA->repulsion, vPush, pA->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);
}
}
@@ -334,6 +337,8 @@ qboolean VSS_SourcePhysics(cvssource_t *pSource, float ftime)
float fDot;
vec3_t vNorm;
VectorCopy(trace.plane.normal, vNorm);
VectorAdd(trace.endpos, trace.plane.normal, pSource->newOrigin);
fDot = DotProduct(vNorm, pSource->velocity);
VectorMA(pSource->velocity, fDot, vNorm, pSource->velocity);
@@ -890,251 +895,249 @@ void VSS_CalcRepulsionForces(cvssource_t *pActiveSources)
{
cvssource_t *pCurrent;
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;
if (pCurrent != pActiveSources) {
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;
if (pCurrent == pActiveSources) {
return;
}
memset(vss_sorttable, 0, sizeof(vss_sorttable));
memset(vss_sorttable, 0, sizeof(vss_sorttable));
while (pCurrent != pActiveSources) {
VectorClear(pCurrent->repulsion);
for (pCurrent = pActiveSources->prev; pCurrent != pActiveSources; pCurrent = pCurrent->prev) {
VectorClear(pCurrent->repulsion);
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[2] + 8192.0 + 0.5) / 96) % 16) << 10;
iIndex = ((int)floor(pCurrent->newOrigin[0] + 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;
pCurrent->stnext = vss_sorttable[iIndex];
vss_sorttable[iIndex] = pCurrent;
pCurrent->stindex = iIndex;
pCurrent = pCurrent->prev;
pCurrent->stnext = vss_sorttable[iIndex];
vss_sorttable[iIndex] = pCurrent;
pCurrent->stindex = iIndex;
}
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) {
if (vss_sorttable[pCurrent->stindex] == pCurrent) {
pSTLatch = (cvssource_t *)-1;
pComp = pCurrent->stnext;
} else {
pSTLatch = 0;
pComp = vss_sorttable[pCurrent->stindex];
for(; pComp; pComp = pComp->stnext) {
VSS_AddRepulsion(pCurrent, pComp);
if (!pSTLatch && pComp->stnext == pCurrent) {
pSTLatch = pComp;
// skip current
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) << 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);
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;
iMaxX = ((int)floor(pCurrent->newOrigin[0] + 8192.0 + 0.5 + fOfs) / 96) % 32;
iMaxY = ((int)floor(pCurrent->newOrigin[1] + 8192.0 + 0.5 + fOfs) / 96) % 32;
iMaxY *= 2;
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;
}
if (pSTLatch == (cvssource_t *)-1) {
vss_sorttable[pCurrent->stindex] = pCurrent->stnext;
} else {
pSTLatch->stnext = pCurrent->stnext;
}
}
}
+9 -9
View File
@@ -42,23 +42,23 @@ MemArchiver::~MemArchiver()
void MemArchiver::SetupForWriting(size_t initialSize)
{
state = MEMARC_WRITING;
buffer = (byte*)cgi.Malloc(initialSize);
allocatedSize = initialSize;
bufferSize = 0;
this->state = MEMARC_WRITING;
this->buffer = (byte*)cgi.Malloc(initialSize);
this->allocatedSize = initialSize;
this->bufferSize = 0;
}
void MemArchiver::SetupForReading(byte* buffer, size_t size)
{
state = MEMARC_READING;
buffer = buffer;
allocatedSize = size;
bufferSize = 0;
this->state = MEMARC_READING;
this->buffer = buffer;
this->allocatedSize = size;
this->bufferSize = 0;
}
void MemArchiver::SetBaseTime(unsigned int time)
{
svsTime = time;
this->svsTime = time;
}
size_t MemArchiver::BufferSize() const
+51 -4
View File
@@ -1,15 +1,17 @@
cmake_minimum_required(VERSION 3.5)
project(omohclient)
option(NO_OPENAL "Use older sound-system" FALSE)
add_subdirectory("../cgame" "./cgame")
file(GLOB_RECURSE SOURCES_CLIENT "./*.c*")
file(GLOB SOURCES_CLIENT "./*.c*")
file(GLOB_RECURSE SOURCES_UILIB "../uilib/*.c*")
# Made as an interface and not static, as static only links used methods
add_library(omohclient INTERFACE)
target_sources(omohclient INTERFACE ${SOURCES_CLIENT} ${SOURCES_UILIB})
target_compile_definitions(omohclient INTERFACE APP_MODULE)
target_compile_definitions(omohclient INTERFACE USE_OPENAL_DLOPEN=1)
target_compile_features(omohclient INTERFACE cxx_nullptr)
target_compile_features(omohclient INTERFACE c_variadic_macros)
target_link_libraries(omohclient INTERFACE omohsdl)
@@ -18,5 +20,50 @@ target_link_libraries(omohclient INTERFACE gcd)
# Sound stuff
target_compile_definitions(omohclient INTERFACE USE_CODEC_MP3)
add_subdirectory("../libmad-0.15.1b" "./libmad")
target_link_libraries(omohclient INTERFACE libmad)
if (NOT NO_OPENAL)
# Use OpenAL
find_package(OpenAL REQUIRED)
if (OPENAL_FOUND)
target_compile_definitions(omohclient INTERFACE USE_OPENAL=1 NO_MODERN_DMA=0)
if (MSVC)
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR}/AL)
else()
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR})
endif()
target_link_libraries(omohclient INTERFACE ${OPENAL_LIBRARY})
endif()
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()
set(OLD_VALUE ${BUILD_SHARED_LIBS})
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
add_subdirectory("../libmad" "./libmad" EXCLUDE_FROM_ALL)
target_link_libraries(omohclient INTERFACE mad)
set(BUILD_SHARED_LIBS ${OLD_VALUE} CACHE BOOL "" FORCE)
if (USE_OPENAL)
# Try to use OpenAL
find_package(OpenAL)
if (OPENAL_FOUND)
target_compile_definitions(omohclient INTERFACE USE_OPENAL=1)
target_include_directories(omohclient INTERFACE ${OPENAL_INCLUDE_DIR}/AL)
target_link_libraries(omohclient INTERFACE ${OPENAL_LIBRARY})
endif()
endif()
target_sources(omohclient INTERFACE ${SOURCES_CLIENT} ${SOURCES_UILIB})
+4
View File
@@ -334,6 +334,9 @@ writing the actual data can begin
*/
qboolean CL_OpenAVIForWriting( const char *fileName )
{
return qfalse;
// Removed in OPM
#if 0
if( afd.fileOpen )
return qfalse;
@@ -425,6 +428,7 @@ qboolean CL_OpenAVIForWriting( const char *fileName )
afd.fileOpen = qtrue;
return qtrue;
#endif
}
/*
+54 -18
View File
@@ -211,20 +211,20 @@ qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
}
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)];
pnum = s1->parent;
if (pnum == ENTITYNUM_NONE) {
parents[s1->number] = -2;
}
else
{
} else {
if (parents[pnum] == -2) {
parents[s1->number] = -2;
}
else
{
} else {
// add it later
parents[s1->number] = pnum;
continue;
@@ -234,20 +234,20 @@ qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
snapshot->entities[snapshot->numEntities++] = *s1;
}
for(pcount = 0; pcount < 8 && snapshot->numEntities != count; pcount++)
{
for (i = 0; i < count; i++)
{
for(pcount = 0; pcount < 8 && snapshot->numEntities != count; pcount++) {
for (i = 0; i < count; i++) {
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
pnum = parents[s1->number];
if (pnum >= 0 && parents[pnum] == -2) {
parents[s1->number] = -2;
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++)
{
s1 = &cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
@@ -261,6 +261,8 @@ qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
s1->origin[1],
s1->origin[2]
);
parents[s1->number] = -2;
}
}
}
@@ -358,7 +360,9 @@ qboolean CL_ProcessServerCommand(const char* origString, const char* cmd, qboole
// because this function might be called from a module that would be unloaded
// inside Com_Error
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;
}
@@ -395,8 +399,8 @@ Set up argc/argv for the given command
===================
*/
qboolean CL_GetServerCommand( int serverCommandNumber, qboolean differentServer ) {
char *s;
char *cmd;
char *s;
char *cmd;
static char bigConfigString[BIG_INFO_STRING];
// if we have irretrievably lost a reliable command, drop the connection
@@ -421,9 +425,39 @@ qboolean CL_GetServerCommand( int serverCommandNumber, qboolean differentServer
Com_DPrintf( "serverCommand: %i : %s\n", serverCommandNumber, s );
}
Cmd_TokenizeString( s );
Cmd_TokenizeString(s);
cmd = Cmd_Argv(0);
// Readded in OPM (from ioquake)
// Configstring big buffer
if (!strcmp(cmd, "bcs0")) {
Com_sprintf(bigConfigString, BIG_INFO_STRING, "cs %s \"%s", Cmd_Argv(1), Cmd_Argv(2));
return qfalse;
}
if (!strcmp(cmd, "bcs1")) {
s = Cmd_Argv(2);
if (strlen(bigConfigString) + strlen(s) >= BIG_INFO_STRING) {
Com_Error(ERR_DROP, "bcs exceeded BIG_INFO_STRING");
}
strcat(bigConfigString, s);
return qfalse;
}
if (!strcmp(cmd, "bcs2")) {
s = Cmd_Argv(2);
if (strlen(bigConfigString) + strlen(s) + 1 >= BIG_INFO_STRING) {
Com_Error(ERR_DROP, "bcs exceeded BIG_INFO_STRING");
}
strcat(bigConfigString, s);
strcat(bigConfigString, "\"");
s = bigConfigString;
// reparse
Cmd_TokenizeString(s);
cmd = Cmd_Argv(0);
}
return CL_ProcessServerCommand(s, cmd, differentServer);
}
@@ -548,7 +582,7 @@ CL_RestoreSavedCgameState
*/
void CL_RestoreSavedCgameState() {
if (cls.savedCgameState) {
cge->CG_LoadStateToBuffer(&cls.savedCgameState, cls.savedCgameStateSize, cl.snap.serverTime);
cge->CG_LoadStateToBuffer(cls.savedCgameState, cls.savedCgameStateSize, cl.snap.serverTime);
}
}
@@ -783,6 +817,8 @@ void CL_InitCGameDLL( clientGameImport_t *cgi, clientGameExport_t **cge ) {
cgi->CL_RestoreSavedCgameState = CL_RestoreSavedCgameState;
cgi->CL_ClearSavedCgameState = CL_ClearSavedCgameState;
cgi->getConfigStringIdNormalized = CPT_NormalizeConfigstring;
cgi->fsDebug = fs_debug;
cgi->HudDrawElements = cls.HudDrawElements;
cgi->anim = &cls.anim;
+7
View File
@@ -1091,6 +1091,8 @@ static void RoQReset( void ) {
static void RoQInterrupt(void)
{
// Removed in OPM
#if 0
byte *framedata;
short sbuf[32768];
int ssize;
@@ -1214,6 +1216,7 @@ redump:
// assert(cinTable[currentHandle].RoQFrameSize <= 65536);
// r = FS_Read( cin.file, cinTable[currentHandle].RoQFrameSize+8, cinTable[currentHandle].iFile );
cinTable[currentHandle].RoQPlayed += cinTable[currentHandle].RoQFrameSize+8;
#endif
}
/******************************************************************************
@@ -1397,6 +1400,9 @@ CIN_PlayCinematic
==================
*/
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;
char name[MAX_OSPATH];
int i;
@@ -1478,6 +1484,7 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
RoQShutdown();
return -1;
#endif
}
void CIN_SetExtents (int handle, int x, int y, int w, int h) {
+10 -2
View File
@@ -432,7 +432,7 @@ void CL_MouseEvent( int dx, int dy, int time ) {
if( cl.mousey > cls.glconfig.vidHeight )
cl.mousey = cls.glconfig.vidHeight;
}
else
else if ( !paused->integer )
{
cl.mouseDx[cl.mouseIndex] += dx;
cl.mouseDy[cl.mouseIndex] += dy;
@@ -575,6 +575,14 @@ void CL_MouseMove( usercmd_t *cmd ) {
cl.viewangles[PITCH] += m_pitch->value * my;
else
cmd->forwardmove = ClampChar(cmd->forwardmove - m_forward->value * my);
if (!isfinite(cl.viewangles[PITCH]) || !isfinite(cl.viewangles[YAW])) {
Com_DPrintf("Invalid client viewangles encountered (view pitch: %f, view yaw: %f)!\n", cl.viewangles[PITCH], cl.viewangles[YAW]);
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_DPrintf("Resetting client viewangles\n");
cl.viewangles[PITCH] = 0;
cl.viewangles[YAW] = 0;
}
}
/*
@@ -991,7 +999,7 @@ void CL_SendCmd( void ) {
}
// don't send commands if paused
if ( com_sv_running->integer && paused->integer && paused->integer ) {
if ( com_sv_running->integer && paused->integer ) {
return;
}
+973 -130
View File
File diff suppressed because it is too large. Load diff
+173 -150
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,175 +20,198 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_INV_H__
#define __CL_INV_H__
#pragma once
typedef enum { INV_MOVE_NONE, INV_MOVE_BOB, INV_MOVE_SPIN } inv_move_type;
typedef enum { INV_CASCADE_LEFT, INV_CASCADE_RIGHT } inv_cascade_type;
typedef enum { INV_HUDANGLES_BASE, INV_HUDANGLES_COMPASS, INV_HUDANGLES_COMPASS_NEEDLE } inv_hudangles_type;
typedef enum {
INV_MOVE_NONE,
INV_MOVE_BOB,
INV_MOVE_SPIN
} inv_move_type;
class item_properties_t : public Class {
public:
float scale;
Vector angles;
Vector angledeltas;
Vector rotateoffset;
Vector offset;
inv_move_type move;
str model;
str anim;
};
typedef enum {
INV_ALIGN_NONE,
INV_ALIGN_LEFT,
INV_ALIGN_RIGHT
} inv_align_type;
class inventory_item_t : public Class {
public:
str name;
str ammoname;
int equip;
int width;
int height;
int barwidth;
int barheight;
int baroffsetY;
int baroffsetX;
float modelWindowX;
float modelWindowY;
float modelWindowWidth;
float modelWindowHeight;
bool selShaderOnTop;
bool checkammo;
str command;
inv_hudangles_type anglesType;
item_properties_t hudprops;
item_properties_t invprops;
UIReggedMaterial *bgshader;
UIReggedMaterial *barshader;
UIReggedMaterial *selshader;
};
typedef enum {
INV_CASCADE_LEFT,
INV_CASCADE_RIGHT
} inv_cascade_type;
class inventory_type_t {
public:
str name;
bool bg_tile;
UIReggedMaterial *texture;
UIReggedMaterial *bg;
UIReggedMaterial *hoverTexture;
UIReggedMaterial *selTexture;
Container<inventory_item_t *> items;
typedef enum {
INV_HUDANGLES_BASE,
INV_HUDANGLES_COMPASS,
INV_HUDANGLES_COMPASS_NEEDLE
} inv_hudangles_type;
int IndexOfItemPtr( inventory_item_t *item );
};
inline
int inventory_type_t::IndexOfItemPtr( inventory_item_t *item )
class item_properties_t : public Class
{
for( int i = items.NumObjects(); i > 0; i-- )
{
if( items.ObjectAt( i ) == item )
{
return i;
}
}
public:
float scale;
Vector angles;
Vector angledeltas;
Vector rotateoffset;
Vector offset;
inv_move_type move;
str model;
str anim;
};
return 0;
class inventory_item_t : public Class
{
public:
str name;
str ammoname;
int equip;
int width;
int height;
int barwidth;
int barheight;
int baroffsetY;
int baroffsetX;
float modelWindowX;
float modelWindowY;
float modelWindowWidth;
float modelWindowHeight;
bool selShaderOnTop;
bool checkammo;
str command;
inv_hudangles_type anglesType;
item_properties_t hudprops;
item_properties_t invprops;
UIReggedMaterial *bgshader;
UIReggedMaterial *barshader;
UIReggedMaterial *selshader;
};
class inventory_type_t
{
public:
str name;
bool bg_tile;
UIReggedMaterial *texture;
UIReggedMaterial *bg;
UIReggedMaterial *hoverTexture;
UIReggedMaterial *selTexture;
Container<inventory_item_t *> items;
int IndexOfItemPtr(inventory_item_t *item);
};
inline int inventory_type_t::IndexOfItemPtr(inventory_item_t *item)
{
for (int i = items.NumObjects(); i > 0; i--) {
if (items.ObjectAt(i) == item) {
return i;
}
}
return 0;
}
class inventory_t {
class inventory_t
{
public:
int typewidth;
int typeheight;
int horizoffset;
int vertoffset;
int align;
inv_cascade_type cascade;
str selectsound;
str rejectsound;
str changesound;
Container<inventory_type_t *> types;
int typewidth;
int typeheight;
int horizoffset;
int vertoffset;
inv_align_type align;
inv_cascade_type cascade;
str selectsound;
str rejectsound;
str changesound;
Container<inventory_type_t *> types;
void Clear() { types.ClearObjectList(); }
public:
inventory_t();
~inventory_t();
inventory_t(const inventory_t& other);
inventory_t& operator=(const inventory_t& other);
void Clear();
};
class invlistener : public Listener {
class invlistener : public Listener
{
protected:
inventory_t *inv;
inventory_type_t *curtype;
inventory_item_t *curitem;
int defaultWidth;
int defaultHeight;
int defaultBarWidth;
int defaultBarHeight;
int defaultBarOffsetX;
int defaultBarOffsetY;
inventory_t *inv;
inventory_type_t *curtype;
inventory_item_t *curitem;
int defaultWidth;
int defaultHeight;
int defaultBarWidth;
int defaultBarHeight;
int defaultBarOffsetX;
int defaultBarOffsetY;
public:
CLASS_PROTOTYPE( invlistener );
CLASS_PROTOTYPE(invlistener);
protected:
void verify_curitem( void );
void verify_curtype( void );
void verify_one_arg( Event *ev );
void verify_curitem(void);
void verify_curtype(void);
void verify_one_arg(Event *ev);
public:
invlistener( inventory_t *i );
invlistener();
invlistener(inventory_t *i);
invlistener();
bool Load( Script& script );
void InvSelectSound( Event *ev );
void InvRejectSound( Event *ev );
void InvChangeSound( Event *ev );
void InvWidth( Event *ev );
void InvHeight( Event *ev );
void InvHorizOffset( Event *ev );
void InvVertOffset( Event *ev );
void InvAlign( Event *ev );
void InvCascade( Event *ev );
void Typedef( Event *ev );
void OpenBrace( Event *ev );
void CloseBrace( Event *ev );
void ButtonShader( Event *ev );
void HoverShader( Event *ev );
void SelShader( Event *ev );
void Background( Event *ev );
void BackgroundTile( Event *ev );
void Width( Event *ev );
void Height( Event *ev );
void BarWidth( Event *ev );
void BarHeight( Event *ev );
void BarOffsetX( Event *ev );
void BarOffsetY( Event *ev );
void Item( Event *ev );
void Ammo( Event *ev );
void Equip( Event *ev );
void CheckAmmo( Event *ev );
void Command( Event *ev );
void BGShader( Event *ev );
void BarShader( Event *ev );
void SelItemShader( Event *ev );
void SelItemShaderOnTop( Event *ev );
void RotateOffset( Event *ev );
void Offset( Event *ev );
void Model( Event *ev );
void Anim( Event *ev );
void Scale( Event *ev );
void Angles( Event *ev );
void AngleDeltas( Event *ev );
void Move( Event *ev );
void ModelWindow( Event *ev );
void HudRotateOffset( Event *ev );
void HudOffset( Event *ev );
void HudModel( Event *ev );
void HudAnim( Event *ev );
void HudScale( Event *ev );
void HudAngles( Event *ev );
void HudAngleDeltas( Event *ev );
void HudMove( Event *ev );
void HudCompassAngles( Event *ev );
void HudCompassNeedleAngles( Event *ev );
bool Load(Script& script);
void InvSelectSound(Event *ev);
void InvRejectSound(Event *ev);
void InvChangeSound(Event *ev);
void InvWidth(Event *ev);
void InvHeight(Event *ev);
void InvHorizOffset(Event *ev);
void InvVertOffset(Event *ev);
void InvAlign(Event *ev);
void InvCascade(Event *ev);
void Typedef(Event *ev);
void OpenBrace(Event *ev);
void CloseBrace(Event *ev);
void ButtonShader(Event *ev);
void HoverShader(Event *ev);
void SelShader(Event *ev);
void Background(Event *ev);
void BackgroundTile(Event *ev);
void Width(Event *ev);
void Height(Event *ev);
void BarWidth(Event *ev);
void BarHeight(Event *ev);
void BarOffsetX(Event *ev);
void BarOffsetY(Event *ev);
void Item(Event *ev);
void Ammo(Event *ev);
void Equip(Event *ev);
void CheckAmmo(Event *ev);
void Command(Event *ev);
void BGShader(Event *ev);
void BarShader(Event *ev);
void SelItemShader(Event *ev);
void SelItemShaderOnTop(Event *ev);
void RotateOffset(Event *ev);
void Offset(Event *ev);
void Model(Event *ev);
void Anim(Event *ev);
void Scale(Event *ev);
void Angles(Event *ev);
void AngleDeltas(Event *ev);
void Move(Event *ev);
void ModelWindow(Event *ev);
void HudRotateOffset(Event *ev);
void HudOffset(Event *ev);
void HudModel(Event *ev);
void HudAnim(Event *ev);
void HudScale(Event *ev);
void HudAngles(Event *ev);
void HudAngleDeltas(Event *ev);
void HudMove(Event *ev);
void HudCompassAngles(Event *ev);
void HudCompassNeedleAngles(Event *ev);
};
bool CL_LoadInventory( const char *filename, inventory_t *inv );
inventory_item_t *CL_GetInvItemByName( inventory_t *inv, const char *name );
qboolean CL_HasInventoryItem( const char *name );
void CL_AmmoCount( const char *name, int *ammo_count, int *max_ammo_count );
#endif // __CL_INV_H__
bool CL_LoadInventory(const char *filename, inventory_t *inv);
inventory_item_t *CL_GetInvItemByName(inventory_t *inv, const char *name);
qboolean CL_HasInventoryItem(const char *name);
void CL_AmmoCount(const char *name, int *ammo_count, int *max_ammo_count);
File diff suppressed because it is too large. Load diff
+81 -58
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,79 +20,102 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_INVRENDER_H__
#define __CL_INVRENDER_H__
#pragma once
class FakkInventory;
typedef enum { selectsound, rejectsound, changesound } invsound_t;
class FakkItemList : public UIWidget {
typedef enum {
selectsound,
rejectsound,
changesound
} invsound_t;
class FakkItemList : public UIWidget
{
protected:
inventory_type_t *type;
uipopup_describe m_describe[ 10 ];
inventory_item_t *m_hoveritem;
inventory_item_t *m_lastmenuitem;
FakkInventory *m_parent;
float m_hovertop;
inventory_type_t *type;
uipopup_describe m_describe[10];
inventory_item_t *m_hoveritem;
inventory_item_t *m_lastmenuitem;
FakkInventory *m_parent;
float m_hovertop;
public:
CLASS_PROTOTYPE( FakkItemList );
CLASS_PROTOTYPE(FakkItemList);
FakkItemList();
~FakkItemList();
FakkItemList();
~FakkItemList();
void VerifyItemUp( inventory_item_t *item, qboolean warpmouse );
void setType( inventory_type_t *t );
void Create( float x, float y, FakkInventory *parent );
bool HasAnyItems( void );
void Draw( void ) override;
void OnLeftMouseDown( Event *ev );
void OnRightMouseDown( Event *ev );
void OnLeftMouseUp( Event *ev );
void OnRightMouseUp( Event *ev );
void OnMouseMove( Event *ev );
void OnMouseEnter( Event *ev );
void OnMouseLeave( Event *ev );
void OnMenuKilled( Event *ev );
void EquipItem( Event *ev );
void VerifyItemUp(inventory_item_t *item, qboolean warpmouse);
void setType(inventory_type_t *t);
void Create(float x, float y, FakkInventory *parent);
bool HasAnyItems(void);
void Draw(void) override;
void OnLeftMouseDown(Event *ev);
void OnRightMouseDown(Event *ev);
void OnLeftMouseUp(Event *ev);
void OnRightMouseUp(Event *ev);
void OnMouseMove(Event *ev);
void OnMouseEnter(Event *ev);
void OnMouseLeave(Event *ev);
void OnMenuKilled(Event *ev);
void EquipItem(Event *ev);
inventory_item_t *getHoverItem() const;
};
class FakkInventory : public UIWidget {
class FakkInventory : public UIWidget
{
protected:
inventory_t *m_inv;
SafePtr<FakkItemList> m_currentlist;
inventory_type_t *m_currenttype;
int m_currentitemnum;
inventory_t *m_inv;
SafePtr<FakkItemList> m_currentlist;
inventory_type_t *m_currenttype;
int m_currentitemnum;
public:
CLASS_PROTOTYPE( FakkInventory );
protected:
void VerifyItemUp( inventory_item_t *item, qboolean warpmouse );
CLASS_PROTOTYPE(FakkInventory);
public:
FakkInventory();
~FakkInventory();
qboolean m_mouse_active;
void setInventory( inventory_t *i );
void Draw( void ) override;
void OnMouseMove( Event *ev );
void OnMouseLeave( Event *ev );
void OnMouseEnter( Event *ev );
void OnMouseDown( Event *ev );
void WarpTo( const char *name );
void WarpTo( int slotnum );
void NextItem( void );
void PrevItem( void );
qboolean isDying( void );
qboolean KeyEvent( int key, unsigned int time ) override;
void PlaySound( invsound_t type );
void Timeout( Event *ev );
void ChangeItem( int sign );
int FindFirstItem( int itemindex, int sign );
protected:
void VerifyTypeUp(inventory_type_t *t, qboolean warpmouse);
public:
FakkInventory();
~FakkInventory();
void setInventory(inventory_t *i);
void Draw(void) override;
void OnMouseMove(Event *ev);
void OnMouseLeave(Event *ev);
void OnMouseEnter(Event *ev);
void OnMouseDown(Event *ev);
void WarpTo(const char *name);
void WarpTo(int slotnum);
void NextItem(void);
void PrevItem(void);
qboolean isDying(void);
qboolean KeyEvent(int key, unsigned int time) override;
void PlaySound(invsound_t type);
void Timeout(Event *ev);
void ChangeItem(int sign);
int FindFirstItem(int itemindex, int sign);
};
void CL_Draw3DModel( float x, float y, float w, float h, qhandle_t model, vec3_t origin, vec3_t rotateoffset, vec3_t offset, vec3_t angle, vec3_t color, str anim );
qboolean UI_CloseInventory( void );
void CL_Draw3DModel(
float x,
float y,
float w,
float h,
qhandle_t model,
vec3_t origin,
vec3_t rotateoffset,
vec3_t offset,
vec3_t angle,
vec3_t color,
str anim
);
#endif // __CL_INVRENDER_H__
void UI_DoInventory(qboolean activate_mouse);
qboolean UI_CloseInventory(void);
+927 -915
View File
File diff suppressed because it is too large. Load diff
+395 -183
View File
@@ -769,7 +769,9 @@ void CL_ShutdownAll(qboolean shutdownRef) {
CL_cURL_Shutdown();
#endif
// clear sounds
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
S_DisableSounds();
#endif
// shutdown CGame
CL_ShutdownCGame();
// shutdown UI
@@ -1484,7 +1486,7 @@ void CL_SendPureChecksums( void ) {
Q_strcat(cMsg, sizeof(cMsg), va("%d ", cl.serverId) );
Q_strcat(cMsg, sizeof(cMsg), pChecksums);
for (i = 0; i < 2; i++) {
cMsg[i] += 10;
cMsg[i] += '\n';
}
CL_AddReliableCommand( cMsg, qfalse );
}
@@ -1513,6 +1515,12 @@ because the renderer doesn't know what graphics to reload
=================
*/
void CL_Vid_Restart_f( void ) {
soundsystemsavegame_t save;
char tm_filename[MAX_RES_NAME];
int tm_loopcount;
int tm_offset;
char current_soundtrack[128];
if (!CL_Allowed_Vid_Restart()) {
return;
}
@@ -1520,11 +1528,18 @@ void CL_Vid_Restart_f( void ) {
Com_Printf("-------- CL_Vid_Restart_f --------\n");
cls.vid_restart = qtrue;
// don't let them loop during the restart
S_StopAllSounds2(qtrue);
//
// Save the current music
//
Q_strncpyz(tm_filename, S_GetMusicFilename(), sizeof(tm_filename));
tm_loopcount = S_GetMusicLoopCount();
tm_offset = S_GetMusicOffset();
SV_ClearSvsTimeFixups();
S_SaveData(&save);
Q_strncpyz(current_soundtrack, S_CurrentSoundtrack(), sizeof(current_soundtrack));
S_BeginRegistration();
// shutdown the renderer and clear the renderer interface
@@ -1545,9 +1560,22 @@ void CL_Vid_Restart_f( void ) {
CL_StartHunkUsers(qfalse);
#if !defined(NO_MODERN_DMA) || !NO_MODERN_DMA
s_bSoundPaused = true;
S_LoadData(&save);
#else
S_Init();
#endif
SV_FinishSvsTimeFixups();
S_Init();
S_ReLoad(&save);
if (tm_filename[0]) {
S_TriggeredMusic_SetupHandle(tm_filename, tm_loopcount, tm_offset, 0);
}
MUSIC_NewSoundtrack(current_soundtrack);
if (clc.state > CA_CONNECTED && clc.state != CA_CINEMATIC)
{
@@ -1569,10 +1597,52 @@ handles will be invalid
=================
*/
void CL_Snd_Restart_f( void ) {
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
S_Shutdown();
S_Init();
CL_Vid_Restart_f();
#else
qboolean full;
soundsystemsavegame_t save;
char tm_filename[MAX_RES_NAME];
int tm_loopcount;
int tm_offset;
char current_soundtrack[128];
CL_Vid_Restart_f();
full = S_NeedFullRestart();
//
// Save the current music
//
Q_strncpyz(tm_filename, S_GetMusicFilename(), sizeof(tm_filename));
tm_loopcount = S_GetMusicLoopCount();
tm_offset = S_GetMusicOffset();
SV_ClearSvsTimeFixups();
S_SaveData(&save);
Q_strncpyz(current_soundtrack, S_CurrentSoundtrack(), sizeof(current_soundtrack));
S_Shutdown(qfalse);
S_Init(qfalse);
s_bSoundPaused = true;
S_LoadData(&save);
SV_FinishSvsTimeFixups();
S_ReLoad(&save);
if (tm_filename[0]) {
S_TriggeredMusic_SetupHandle(tm_filename, tm_loopcount, tm_offset, 0);
}
MUSIC_NewSoundtrack(current_soundtrack);
if (full) {
CL_Vid_Restart_f();
}
#endif
}
@@ -2017,13 +2087,8 @@ void CL_MotdPacket( netadr_t from ) {
CL_InitServerInfo
===================
*/
void CL_InitServerInfo( serverInfo_t *server, serverAddress_t *address ) {
server->adr.type = NA_IP;
server->adr.ip[0] = address->ip[0];
server->adr.ip[1] = address->ip[1];
server->adr.ip[2] = address->ip[2];
server->adr.ip[3] = address->ip[3];
server->adr.port = address->port;
void CL_InitServerInfo( serverInfo_t *server, netadr_t *address ) {
server->adr = *address;
server->clients = 0;
server->hostName[0] = '\0';
server->mapName[0] = '\0';
@@ -2043,14 +2108,14 @@ void CL_InitServerInfo( serverInfo_t *server, serverAddress_t *address ) {
CL_ServersResponsePacket
===================
*/
void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
int i, count, max, total;
serverAddress_t addresses[MAX_SERVERSPERPACKET];
void CL_ServersResponsePacket( const netadr_t* from, msg_t *msg, qboolean extended ) {
int i, j, count, total;
netadr_t addresses[MAX_SERVERSPERPACKET];
int numservers;
byte* buffptr;
byte* buffend;
Com_Printf("CL_ServersResponsePacket\n");
Com_Printf("CL_ServersResponsePacket from %s\n", NET_AdrToStringwPort(*from));
if (cls.numglobalservers == -1) {
// state to detect lack of servers or lack of response
@@ -2058,71 +2123,84 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
cls.numGlobalServerAddresses = 0;
}
if (cls.nummplayerservers == -1) {
cls.nummplayerservers = 0;
}
// parse through server response string
numservers = 0;
buffptr = msg->data;
buffend = buffptr + msg->cursize;
while (buffptr+1 < buffend) {
// advance to initial token
do {
if (*buffptr++ == '\\')
break;
}
while (buffptr < buffend);
if ( buffptr >= buffend - 6 ) {
// advance to initial token
do
{
if(*buffptr == '\\' || (extended && *buffptr == '/'))
break;
buffptr++;
} while (buffptr < buffend);
while (buffptr + 1 < buffend)
{
// IPv4 address
if (*buffptr == '\\')
{
buffptr++;
if (buffend - buffptr < sizeof(addresses[numservers].ip) + sizeof(addresses[numservers].port) + 1)
break;
for(i = 0; i < sizeof(addresses[numservers].ip); i++)
addresses[numservers].ip[i] = *buffptr++;
addresses[numservers].type = NA_IP;
}
// IPv6 address, if it's an extended response
else if (extended && *buffptr == '/')
{
buffptr++;
// parse out ip
addresses[numservers].ip[0] = *buffptr++;
addresses[numservers].ip[1] = *buffptr++;
addresses[numservers].ip[2] = *buffptr++;
addresses[numservers].ip[3] = *buffptr++;
if (buffend - buffptr < sizeof(addresses[numservers].ip6) + sizeof(addresses[numservers].port) + 1)
break;
for(i = 0; i < sizeof(addresses[numservers].ip6); i++)
addresses[numservers].ip6[i] = *buffptr++;
addresses[numservers].type = NA_IP6;
addresses[numservers].scope_id = from->scope_id;
}
else
// syntax error!
break;
// parse out port
addresses[numservers].port = (*buffptr++)<<8;
addresses[numservers].port = (*buffptr++) << 8;
addresses[numservers].port += *buffptr++;
addresses[numservers].port = BigShort( addresses[numservers].port );
// syntax check
if (*buffptr != '\\') {
if (*buffptr != '\\' && *buffptr != '/')
break;
}
Com_DPrintf( "server: %d ip: %d.%d.%d.%d:%d\n",numservers,
addresses[numservers].ip[0],
addresses[numservers].ip[1],
addresses[numservers].ip[2],
addresses[numservers].ip[3],
addresses[numservers].port );
numservers++;
if (numservers >= MAX_SERVERSPERPACKET) {
if (numservers >= MAX_SERVERSPERPACKET)
break;
}
// parse out EOT
if (buffptr[1] == 'E' && buffptr[2] == 'O' && buffptr[3] == 'T') {
break;
}
}
if (cls.masterNum == 0) {
count = cls.numglobalservers;
max = MAX_GLOBAL_SERVERS;
} else {
count = cls.nummplayerservers;
max = MAX_OTHER_SERVERS;
}
count = cls.numglobalservers;
for (i = 0; i < numservers && count < max; i++) {
for (i = 0; i < numservers && count < MAX_GLOBAL_SERVERS; i++) {
// build net address
serverInfo_t *server = (cls.masterNum == 0) ? &cls.globalServers[count] : &cls.mplayerServers[count];
serverInfo_t *server = &cls.globalServers[count];
// Tequila: It's possible to have sent many master server requests. Then
// we may receive many times the same addresses from the master server.
// We just avoid to add a server if it is still in the global servers list.
for (j = 0; j < count; j++)
{
if (NET_CompareAdr(cls.globalServers[j].adr, addresses[i]))
break;
}
if (j < count)
continue;
CL_InitServerInfo( server, &addresses[i] );
// advance to next slot
@@ -2130,29 +2208,18 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
}
// if getting the global list
if (cls.masterNum == 0) {
if ( cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS ) {
// if we couldn't store the servers in the main list anymore
for (; i < numservers && count >= max; i++) {
serverAddress_t *addr;
// just store the addresses in an additional list
addr = &cls.globalServerAddresses[cls.numGlobalServerAddresses++];
addr->ip[0] = addresses[i].ip[0];
addr->ip[1] = addresses[i].ip[1];
addr->ip[2] = addresses[i].ip[2];
addr->ip[3] = addresses[i].ip[3];
addr->port = addresses[i].port;
}
if ( count >= MAX_GLOBAL_SERVERS && cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS )
{
// if we couldn't store the servers in the main list anymore
for (; i < numservers && cls.numGlobalServerAddresses < MAX_GLOBAL_SERVERS; i++)
{
// just store the addresses in an additional list
cls.globalServerAddresses[cls.numGlobalServerAddresses++] = addresses[i];
}
}
if (cls.masterNum == 0) {
cls.numglobalservers = count;
total = count + cls.numGlobalServerAddresses;
} else {
cls.nummplayerservers = count;
total = count;
}
cls.numglobalservers = count;
total = count + cls.numGlobalServerAddresses;
Com_Printf("%d servers parsed (total %d)\n", numservers, total);
}
@@ -2280,7 +2347,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
// echo request from server
if ( !Q_strncmp(c, "getserversResponse", 18) ) {
CL_ServersResponsePacket( from, msg );
CL_ServersResponsePacket( &from, msg, qfalse );
return;
}
@@ -2375,6 +2442,13 @@ CL_CheckTimeout
==================
*/
void CL_CheckTimeout( void ) {
if (com_sv_running->integer) {
// Added in OPM
// Timeout should not be possible if the client is hosting the game
// (like in single-player mode)
return;
}
//
// check timeout
//
@@ -2382,10 +2456,37 @@ void CL_CheckTimeout( void ) {
&& clc.state >= CA_CONNECTED && clc.state != CA_CINEMATIC
&& cls.realtime - clc.lastPacketTime > cl_timeout->value*1000) {
if (++cl.timeoutcount > 5) { // timeoutcount saves debugger
Com_Printf ("\nServer connection timed out.\n");
Cbuf_AddText( "pushmenu servertimeout\n" );
CL_Disconnect();
return;
const char* info;
const char* maxclients;
info = &cl.gameState.stringData[cl.gameState.stringOffsets[CS_SERVERINFO]];
maxclients = Info_ValueForKey(info, "maxclients");
//
// Disconnect if the player isn't alone (single-player mode)
//
if (!maxclients || atoi(maxclients) != 1) {
qboolean bConsoleState;
bConsoleState = UI_ConsoleIsOpen();
Com_Printf("\nServer connection timed out.\n");
SV_Shutdown("\nServer connection timed out\n");
if (com_cl_running && com_cl_running->integer) {
CL_AbnormalDisconnect();
CL_FlushMemory();
CL_StartHunkUsers(qfalse);
}
UI_ForceMenuOff(qtrue);
UI_PushMenu("servertimeout");
if (bConsoleState) {
UI_OpenConsole();
} else {
UI_CloseConsole();
}
}
}
} else {
cl.timeoutcount = 0;
@@ -2478,6 +2579,7 @@ void CL_Frame ( int msec ) {
&& !com_sv_running->integer ) {
// if disconnected, bring up the menu
S_StopAllSounds2( qtrue );
S_TriggeredMusic_PlayIntroMusic();
UI_MenuEscape( "main" );
}
@@ -3390,7 +3492,11 @@ void CL_Init( void ) {
Cvar_Set( "cl_running", "1" );
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
S_Init2();
#else
S_Init(qtrue);
#endif
// fixme: should we leave it?
CL_GenerateQKey();
@@ -3431,7 +3537,11 @@ void CL_Shutdown(const char* finalmsg, qboolean disconnect, qboolean quit) {
if(disconnect)
CL_Disconnect();
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
S_Shutdown();
#else
S_Shutdown(qtrue);
#endif
CL_ShutdownRef();
CL_ShutdownUI();
@@ -3523,15 +3633,39 @@ CL_ServerInfoPacket
void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
int i, type;
char info[MAX_INFO_STRING];
const char* str;
char *infoString;
int prot;
char *gamename;
qboolean gameMismatch;
infoString = MSG_ReadString( msg );
// if this isn't the correct gamename, ignore it
gamename = Info_ValueForKey( infoString, "gamename" );
#ifdef LEGACY_PROTOCOL
// gamename is optional for legacy protocol
if (com_legacyprotocol->integer && !*gamename)
gameMismatch = qfalse;
else
#endif
gameMismatch = !*gamename || strcmp(gamename, com_gamename->string) != 0;
if (gameMismatch)
{
Com_DPrintf( "Game mismatch in info packet: %s\n", infoString );
return;
}
// if this isn't the correct protocol version, ignore it
prot = atoi( Info_ValueForKey( infoString, "protocol" ) );
if ( prot != PROTOCOL_VERSION ) {
if(prot != com_protocol->integer
#ifdef LEGACY_PROTOCOL
&& prot != com_legacyprotocol->integer
#endif
)
{
Com_DPrintf( "Different protocol info packet: %s\n", infoString );
return;
}
@@ -3542,7 +3676,7 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
if ( cl_pinglist[i].adr.port && !cl_pinglist[i].time && NET_CompareAdr( from, cl_pinglist[i].adr ) )
{
// calc ping time
cl_pinglist[i].time = cls.realtime - cl_pinglist[i].start + 1;
cl_pinglist[i].time = Sys_Milliseconds() - cl_pinglist[i].start;
Com_DPrintf( "ping time %dms from %s\n", cl_pinglist[i].time, NET_AdrToString( from ) );
// save of info
@@ -3554,12 +3688,12 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
{
case NA_BROADCAST:
case NA_IP:
str = "udp";
type = 1;
break;
case NA_IP6:
type = 2;
break;
default:
str = "???";
type = 0;
break;
}
@@ -3594,24 +3728,16 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
// add this to the list
cls.numlocalservers = i+1;
cls.localServers[i].adr = from;
cls.localServers[i].clients = 0;
cls.localServers[i].hostName[0] = '\0';
cls.localServers[i].mapName[0] = '\0';
cls.localServers[i].maxClients = 0;
cls.localServers[i].maxPing = 0;
cls.localServers[i].minPing = 0;
cls.localServers[i].ping = -1;
cls.localServers[i].game[0] = '\0';
cls.localServers[i].gameType = 0;
cls.localServers[i].netType = from.type;
cls.bNewLocalServerInfo = true;
CL_InitServerInfo( &cls.localServers[i], &from );
CL_SetServerInfo( &cls.localServers[i], infoString, 0 );
Q_strncpyz( info, MSG_ReadString( msg ), MAX_INFO_STRING );
if (strlen(info)) {
if (info[strlen(info)-1] != '\n') {
strncat(info, "\n", sizeof(info) - 1);
Q_strcat(info, sizeof(info), "\n");
}
Com_Printf( "%s: %s", NET_AdrToString( from ), info );
Com_Printf( "%s: %s", NET_AdrToStringwPort( from ), info );
}
}
@@ -3621,10 +3747,8 @@ CL_GetServerStatus
===================
*/
serverStatus_t *CL_GetServerStatus( netadr_t from ) {
serverStatus_t *serverStatus;
int i, oldest, oldestTime;
serverStatus = NULL;
for (i = 0; i < MAX_SERVERSTATUSREQUESTS; i++) {
if ( NET_CompareAdr( from, cl_serverStatusList[i].address ) ) {
return &cl_serverStatusList[i];
@@ -3643,11 +3767,7 @@ serverStatus_t *CL_GetServerStatus( netadr_t from ) {
oldestTime = cl_serverStatusList[i].startTime;
}
}
if (oldest != -1) {
return &cl_serverStatusList[oldest];
}
serverStatusCount++;
return &cl_serverStatusList[serverStatusCount & (MAX_SERVERSTATUSREQUESTS-1)];
return &cl_serverStatusList[oldest];
}
/*
@@ -3669,7 +3789,7 @@ int CL_ServerStatus( const char *serverAddress, char *serverStatusString, int ma
return qfalse;
}
// get the address
if ( !NET_StringToAdr( serverAddress, &to, NA_IP ) ) {
if ( !NET_StringToAdr( serverAddress, &to, NA_UNSPEC) ) {
return qfalse;
}
serverStatus = CL_GetServerStatus( to );
@@ -3681,7 +3801,7 @@ int CL_ServerStatus( const char *serverAddress, char *serverStatusString, int ma
// if this server status request has the same address
if ( NET_CompareAdr( to, serverStatus->address) ) {
// if we recieved an response for this server status request
// if we received a response for this server status request
if (!serverStatus->pending) {
Q_strncpyz(serverStatusString, serverStatus->string, maxLen);
serverStatus->retrieved = qtrue;
@@ -3719,10 +3839,10 @@ CL_ServerStatusResponse
===================
*/
void CL_ServerStatusResponse( netadr_t from, msg_t *msg ) {
const char *s;
char *s;
char info[MAX_INFO_STRING];
int i, l, score, ping;
size_t len;
int len;
serverStatus_t *serverStatus;
serverStatus = NULL;
@@ -3821,6 +3941,7 @@ void CL_LocalServers_f( void ) {
// reset the list, waiting for response
cls.numlocalservers = 0;
cls.bNewLocalServerInfo = true;
cls.pingUpdateSource = AS_LOCAL;
for (i = 0; i < MAX_OTHER_SERVERS; i++) {
@@ -3845,6 +3966,9 @@ void CL_LocalServers_f( void ) {
to.type = NA_BROADCAST;
NET_SendPacket( NS_CLIENT, strlen( message ), message, to );
// Added in OPM (from ioquake3)
to.type = NA_MULTICAST6;
NET_SendPacket( NS_CLIENT, strlen( message ), message, to );
}
}
}
@@ -3972,47 +4096,101 @@ void CL_GamespyServers_f( void ) {
/*
==================
CL_GlobalServers_f
Originally master 0 was Internet and master 1 was MPlayer.
ioquake3 2008; added support for requesting five separate master servers using 0-4.
ioquake3 2017; made master 0 fetch all master servers and 1-5 request a single master server.
==================
*/
void CL_GlobalServers_f( void ) {
netadr_t to;
int i;
int count;
char *buffptr;
char command[1024];
int count, i, masterNum;
char command[1024], *masteraddress;
if ((count = Cmd_Argc()) < 3 || (masterNum = atoi(Cmd_Argv(1))) < 0 || masterNum > MAX_MASTER_SERVERS)
{
Com_Printf("usage: globalservers <master# 0-%d> <protocol> [keywords]\n", MAX_MASTER_SERVERS);
return;
}
if ( Cmd_Argc() < 3) {
Com_Printf( "usage: globalservers <master# 0-1> <protocol> [keywords]\n");
// request from all master servers
if ( masterNum == 0 ) {
int numAddress = 0;
for ( i = 1; i <= MAX_MASTER_SERVERS; i++ ) {
sprintf(command, "sv_master%d", i);
masteraddress = Cvar_VariableString(command);
if(!*masteraddress)
continue;
numAddress++;
Com_sprintf(command, sizeof(command), "globalservers %d %s %s\n", i, Cmd_Argv(2), Cmd_ArgsFrom(3));
Cbuf_AddText(command);
}
if ( !numAddress ) {
Com_Printf( "CL_GlobalServers_f: Error: No master server addresses.\n");
}
return;
}
cls.masterNum = atoi( Cmd_Argv(1) );
Com_Printf( "Requesting servers from the master...\n");
sprintf(command, "sv_master%d", masterNum);
masteraddress = Cvar_VariableString(command);
if(!*masteraddress)
{
Com_Printf( "CL_GlobalServers_f: Error: No master server address given.\n");
return;
}
// reset the list, waiting for response
// -1 is used to distinguish a "no response"
NET_StringToAdr( cl_master->string, &to, NA_IP );
if( cls.masterNum == 1 ) {
cls.nummplayerservers = -1;
cls.pingUpdateSource = AS_MPLAYER;
i = NET_StringToAdr(masteraddress, &to, NA_UNSPEC);
if(!i)
{
Com_Printf( "CL_GlobalServers_f: Error: could not resolve address of master %s\n", masteraddress);
return;
}
else {
cls.numglobalservers = -1;
cls.pingUpdateSource = AS_GLOBAL;
else if(i == 2)
to.port = BigShort(PORT_MASTER);
Com_Printf("Requesting servers from %s (%s)...\n", masteraddress, NET_AdrToStringwPort(to));
cls.numglobalservers = -1;
cls.pingUpdateSource = AS_GLOBAL;
// Use the extended query for IPv6 masters
if (to.type == NA_IP6 || to.type == NA_MULTICAST6)
{
int v4enabled = Cvar_VariableIntegerValue("net_enabled") & NET_ENABLEV4;
if(v4enabled)
{
Com_sprintf(command, sizeof(command), "getserversExt %s %s",
com_gamename->string, Cmd_Argv(2));
}
else
{
Com_sprintf(command, sizeof(command), "getserversExt %s %s ipv6",
com_gamename->string, Cmd_Argv(2));
}
}
to.type = NA_IP;
to.port = BigShort(PORT_MASTER);
//else if ( !Q_stricmp( com_gamename->string, LEGACY_MASTER_GAMENAME ) )
// Com_sprintf(command, sizeof(command), "getservers %s",
// Cmd_Argv(2));
else
Com_sprintf(command, sizeof(command), "getservers %s %s",
com_gamename->string, Cmd_Argv(2));
sprintf( command, "getservers %s", Cmd_Argv(2) );
// tack on keywords
buffptr = command + strlen( command );
count = Cmd_Argc();
for (i=3; i<count; i++)
buffptr += sprintf( buffptr, " %s", Cmd_Argv(i) );
for (i=3; i < count; i++)
{
Q_strcat(command, sizeof(command), " ");
Q_strcat(command, sizeof(command), Cmd_Argv(i));
}
NET_OutOfBandPrint( NS_SERVER, to, "%s", command );
}
@@ -4029,22 +4207,22 @@ void CL_GetPing( int n, char *buf, int buflen, int *pingtime )
int time;
int maxPing;
if (!cl_pinglist[n].adr.port)
if (n < 0 || n >= MAX_PINGREQUESTS || !cl_pinglist[n].adr.port)
{
// empty slot
// empty or invalid slot
buf[0] = '\0';
*pingtime = 0;
return;
}
str = NET_AdrToString( cl_pinglist[n].adr );
str = NET_AdrToStringwPort( cl_pinglist[n].adr );
Q_strncpyz( buf, str, buflen );
time = cl_pinglist[n].time;
if (!time)
{
// check for timeout
time = cls.realtime - cl_pinglist[n].start;
time = Sys_Milliseconds() - cl_pinglist[n].start;
maxPing = Cvar_VariableIntegerValue( "cl_maxPing" );
if( maxPing < 100 ) {
maxPing = 100;
@@ -4083,9 +4261,9 @@ CL_GetPingInfo
*/
void CL_GetPingInfo( int n, char *buf, int buflen )
{
if (!cl_pinglist[n].adr.port)
if (n < 0 || n >= MAX_PINGREQUESTS || !cl_pinglist[n].adr.port)
{
// empty slot
// empty or invalid slot
if (buflen)
buf[0] = '\0';
return;
@@ -4138,7 +4316,7 @@ CL_GetFreePing
ping_t* CL_GetFreePing( void )
{
ping_t* pingptr;
ping_t* best;
ping_t* best;
int oldest;
int i;
int time;
@@ -4151,7 +4329,7 @@ ping_t* CL_GetFreePing( void )
{
if (!pingptr->time)
{
if (cls.realtime - pingptr->start < 500)
if (Sys_Milliseconds() - pingptr->start < 500)
{
// still waiting for response
continue;
@@ -4176,7 +4354,7 @@ ping_t* CL_GetFreePing( void )
for (i=0; i<MAX_PINGREQUESTS; i++, pingptr++ )
{
// scan for oldest
time = cls.realtime - pingptr->start;
time = Sys_Milliseconds() - pingptr->start;
if (time > oldest)
{
oldest = time;
@@ -4196,29 +4374,45 @@ void CL_Ping_f( void ) {
netadr_t to;
ping_t* pingptr;
char* server;
int argc;
netadrtype_t family = NA_UNSPEC;
if ( Cmd_Argc() != 2 ) {
Com_Printf( "usage: ping [server]\n");
return;
argc = Cmd_Argc();
if ( argc != 2 && argc != 3 ) {
Com_Printf( "usage: ping [-4|-6] server\n");
return;
}
if(argc == 2)
server = Cmd_Argv(1);
else
{
if(!strcmp(Cmd_Argv(1), "-4"))
family = NA_IP;
else if(!strcmp(Cmd_Argv(1), "-6"))
family = NA_IP6;
else
Com_Printf( "warning: only -4 or -6 as address type understood.\n");
server = Cmd_Argv(2);
}
Com_Memset( &to, 0, sizeof(netadr_t) );
server = Cmd_Argv(1);
if ( !NET_StringToAdr( server, &to, NA_IP ) ) {
if ( !NET_StringToAdr( server, &to, family ) ) {
return;
}
pingptr = CL_GetFreePing();
memcpy( &pingptr->adr, &to, sizeof (netadr_t) );
pingptr->start = cls.realtime;
pingptr->start = Sys_Milliseconds();
pingptr->time = 0;
CL_SetServerInfoByAddress(pingptr->adr, NULL, 0);
NET_OutOfBandPrint( NS_CLIENT, to, "\x02getinfo" );
NET_OutOfBandPrint( NS_CLIENT, to, "\x02getinfo xxx" );
}
/*
@@ -4342,16 +4536,11 @@ qboolean CL_UpdateVisiblePings_f(int source) {
if (slots < MAX_PINGREQUESTS) {
serverInfo_t *server = NULL;
max = (source == AS_GLOBAL) ? MAX_GLOBAL_SERVERS : MAX_OTHER_SERVERS;
switch (source) {
case AS_LOCAL :
server = &cls.localServers[0];
max = cls.numlocalservers;
break;
case AS_MPLAYER :
server = &cls.mplayerServers[0];
max = cls.nummplayerservers;
break;
case AS_GLOBAL :
server = &cls.globalServers[0];
max = cls.numglobalservers;
@@ -4360,6 +4549,8 @@ qboolean CL_UpdateVisiblePings_f(int source) {
server = &cls.favoriteServers[0];
max = cls.numfavoriteservers;
break;
default:
return qfalse;
}
for (i = 0; i < max; i++) {
if (server[i].visible) {
@@ -4386,7 +4577,7 @@ qboolean CL_UpdateVisiblePings_f(int source) {
}
}
memcpy(&cl_pinglist[j].adr, &server[i].adr, sizeof(netadr_t));
cl_pinglist[j].start = cls.realtime;
cl_pinglist[j].start = Sys_Milliseconds();
cl_pinglist[j].time = 0;
NET_OutOfBandPrint( NS_CLIENT, cl_pinglist[j].adr, "getinfo xxx" );
slots++;
@@ -4408,7 +4599,7 @@ qboolean CL_UpdateVisiblePings_f(int source) {
}
}
}
}
}
if (slots) {
status = qtrue;
@@ -4433,32 +4624,53 @@ CL_ServerStatus_f
==================
*/
void CL_ServerStatus_f(void) {
netadr_t to;
netadr_t to, *toptr = NULL;
char *server;
serverStatus_t *serverStatus;
int argc;
netadrtype_t family = NA_UNSPEC;
Com_Memset( &to, 0, sizeof(netadr_t) );
argc = Cmd_Argc();
if ( Cmd_Argc() != 2 ) {
if ( clc.state != CA_ACTIVE || clc.demoplaying ) {
if ( argc != 2 && argc != 3 )
{
if (clc.state != CA_ACTIVE || clc.demoplaying)
{
Com_Printf ("Not connected to a server.\n");
Com_Printf( "Usage: serverstatus [server]\n");
Com_Printf( "usage: serverstatus [-4|-6] server\n");
return;
}
server = cls.servername;
toptr = &clc.serverAddress;
}
else {
server = Cmd_Argv(1);
if(!toptr)
{
Com_Memset( &to, 0, sizeof(netadr_t) );
if(argc == 2)
server = Cmd_Argv(1);
else
{
if(!strcmp(Cmd_Argv(1), "-4"))
family = NA_IP;
else if(!strcmp(Cmd_Argv(1), "-6"))
family = NA_IP6;
else
Com_Printf( "warning: only -4 or -6 as address type understood.\n");
server = Cmd_Argv(2);
}
toptr = &to;
if ( !NET_StringToAdr( server, toptr, family ) )
return;
}
if ( !NET_StringToAdr( server, &to, NA_IP ) ) {
return;
}
NET_OutOfBandPrint( NS_CLIENT, *toptr, "getstatus" );
NET_OutOfBandPrint( NS_CLIENT, to, "getstatus" );
serverStatus = CL_GetServerStatus( to );
serverStatus->address = to;
serverStatus = CL_GetServerStatus( *toptr );
serverStatus->address = *toptr;
serverStatus->print = qtrue;
serverStatus->pending = qtrue;
}
+181 -84
View File
@@ -149,6 +149,7 @@ static str ui_sCurrentLoadingMenu;
static Container<Menu *> hudList;
void UI_MultiplayerMenuWidgetsUpdate(void);
void UI_MultiplayerMainMenuWidgetsUpdate(void);
void UI_MainMenuWidgetsUpdate(void);
static UIRect2D getDefaultGMBoxRectangle(void);
@@ -1250,20 +1251,22 @@ UI_PrintConsole
*/
void UI_PrintConsole(const char *msg)
{
UColor *pColor = NULL;
char szString[1024];
char szBlah[1024];
qboolean bPrintedDMBox = qfalse;
UColor *pColor = NULL;
const char *pszString;
char szString[1024];
char szBlah[1024];
qboolean bPrintedDMBox = qfalse;
memcpy(szString, msg, sizeof(szString));
pszString = msg;
strncpy(szString, msg, 1024);
if (*szString < MESSAGE_MAX) {
if (*pszString < MESSAGE_MAX) {
qboolean bNormalMessage = qfalse;
qboolean bDMMessage = qfalse;
qboolean bBold = qfalse;
qboolean bDeathMessage = qfalse;
switch (*szString) {
switch (*pszString) {
case MESSAGE_YELLOW:
bNormalMessage = qtrue;
pColor = &UHudColor;
@@ -1277,16 +1280,18 @@ void UI_PrintConsole(const char *msg)
pColor = &UWhite;
break;
case MESSAGE_CHAT_RED:
bDeathMessage = qtrue;
bDeathMessage = MESSAGE_CHAT_RED;
pColor = &ULightRed;
break;
case MESSAGE_CHAT_GREEN:
bDeathMessage = qtrue;
bDeathMessage = MESSAGE_CHAT_GREEN;
pColor = &UGreen;
break;
}
msg++;
if (*pszString != 0) {
pszString++;
}
//
// print to the deathmatch console
@@ -1306,10 +1311,11 @@ void UI_PrintConsole(const char *msg)
if (bDMMessage) {
*szString = MESSAGE_CHAT_WHITE;
dmbox->Print(szString);
pszString = msg + 1;
bPrintedDMBox = qtrue;
} else if (bDeathMessage) {
dmbox->Print(szString);
*szString = MESSAGE_CHAT_RED;
*szString = bDeathMessage;
bPrintedDMBox = qtrue;
}
}
@@ -1322,6 +1328,7 @@ void UI_PrintConsole(const char *msg)
*szString = MESSAGE_WHITE;
gmbox->Print(szString);
uii.Snd_PlaySound("objective_text");
pszString = msg + 1;
} else {
gmbox->Print(szString + 1);
}
@@ -1330,15 +1337,18 @@ void UI_PrintConsole(const char *msg)
return;
}
memcpy(szBlah, "Game Message: ", 15);
Q_strcat(szBlah, sizeof(szBlah), szString + 1);
if (!bDMMessage) {
memcpy(szBlah, "Game Message: ", 15);
Q_strcat(szBlah, sizeof(szBlah), pszString);
pszString = szBlah;
}
}
}
if (*msg == 7) {
msg++;
if (*pszString == '\a') {
pszString++;
if (mini_console) {
mini_console->Print(msg + 1);
mini_console->Print(pszString);
return;
}
}
@@ -1350,10 +1360,10 @@ void UI_PrintConsole(const char *msg)
s_intermediateconsole = NULL;
}
fakk_console->AddText(msg, pColor);
fakk_console->AddText(pszString, pColor);
if (mini_console) {
mini_console->Print(msg);
mini_console->Print(pszString);
}
} else {
if (!s_intermediateconsole) {
@@ -1767,6 +1777,8 @@ void UI_Update(void)
hud_compass->GetContainerWidget()->Display(frame, 1.0);
}
}
return;
}
if (fakk_console) {
@@ -1792,6 +1804,8 @@ void UI_Update(void)
if (currentMenu == menuManager.FindMenu("main")) {
UI_MainMenuWidgetsUpdate();
} else if (currentMenu == menuManager.FindMenu("dm_main")) {
UI_MultiplayerMainMenuWidgetsUpdate();
}
// don't care about the intro
@@ -1820,7 +1834,7 @@ void UI_Update(void)
}
}
if (clc.connectTime >= cls.realtime - 1000 * cl_connect_timeout->integer) {
if (clc.connectStartTime >= cls.realtime - 1000 * cl_connect_timeout->integer) {
if (currentMenu != ui_pConnectingMenu) {
UI_ForceMenuOff(true);
UI_DeactiveFloatingWindows();
@@ -1877,7 +1891,7 @@ void UI_Update(void)
UI_CloseConsole();
}
} else if (ui_static_materials.loading) {
ui_static_materials.loading->ReregisterMaterial();
ui_static_materials.loading->GetMaterial();
}
}
}
@@ -2382,6 +2396,44 @@ void UI_MainMenuWidgetsUpdate(void)
UI_UpdateContinueGame();
}
/*
====================
UI_MultiplayerMainMenuWidgetsUpdate
====================
*/
// Added in 2.0
void UI_MultiplayerMainMenuWidgetsUpdate(void)
{
static const cvar_t *cg_allowvote = Cvar_Get("cg_allowvote", "1", 0);
if (cg_allowvote->integer) {
menuManager.PassEventToWidget("cantvote", new Event(EV_Widget_Disable));
if (atoi(CL_ConfigString(CS_VOTE_TIME))) {
menuManager.PassEventToWidget("callvotebutton", new Event(EV_Widget_Disable));
if (cl.snap.ps.voted) {
menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Enable));
} else {
menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Disable));
}
} else {
menuManager.PassEventToWidget("callvotebutton", new Event(EV_Widget_Enable));
menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Disable));
}
} else {
menuManager.PassEventToWidget("callvotebutton", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("votebutton", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("alreadyvoted", new Event(EV_Widget_Disable));
menuManager.PassEventToWidget("cantvote", new Event(EV_Widget_Enable));
}
UI_UpdateContinueGame();
}
/*
====================
UI_ToggleMenu
@@ -2446,9 +2498,11 @@ void UI_PopMenu(qboolean restore_cvars)
menu = menuManager.CurrentMenu();
if (menu) {
if (!memcmp(menu->m_name.c_str(), "main", 5)) {
if (!str::cmp(menu->m_name, "main")) {
UI_MainMenuWidgetsUpdate();
} else if (!memcmp(menu->m_name.c_str(), "multiplayer", 12)) {
} else if (!str::cmp(menu->m_name, "dm_main")) {
UI_MultiplayerMainMenuWidgetsUpdate();
} else if (!str::cmp(menu->m_name, "multiplayer")) {
UI_MultiplayerMenuWidgetsUpdate();
}
}
@@ -2484,9 +2538,11 @@ void UI_PushMenu(const char *name)
UI_FocusMenuIfExists();
if (!memcmp(name, "main", 5)) {
if (!str::cmp(name, "main")) {
UI_MainMenuWidgetsUpdate();
} else if (!memcmp(name, "multiplayer", 12)) {
} else if (!str::cmp(name, "dm_main")) {
UI_MultiplayerMainMenuWidgetsUpdate();
} else if (!str::cmp(name, "multiplayer")) {
UI_MultiplayerMenuWidgetsUpdate();
}
}
@@ -2819,9 +2875,11 @@ qboolean UI_PushReturnMenu()
return qfalse;
}
if (!memcmp(sMenuName.c_str(), "main", 5)) {
if (!str::cmp(sMenuName, "main")) {
UI_MainMenuWidgetsUpdate();
} else if (!memcmp(sMenuName.c_str(), "multiplayer", 12)) {
} else if (!str::cmp(sMenuName, "dm_main")) {
UI_MultiplayerMainMenuWidgetsUpdate();
} else if (!str::cmp(sMenuName, "multiplayer")) {
UI_MultiplayerMenuWidgetsUpdate();
}
@@ -2851,33 +2909,44 @@ void UI_MenuEscape(const char *name)
if (uWinMan.BindActive()) {
UI_KeyEvent(K_ESCAPE, qfalse);
} else if (menuManager.CurrentMenu() != mainmenu || clc.state != CA_DISCONNECTED) {
if (uWinMan.DialogExists()) {
uWinMan.RemoveAllDialogBoxes();
} else {
if (menuManager.CurrentMenu()) {
menuManager.PopMenu(qtrue);
} else if (!Q_stricmp(name, "main") && clc.state > CA_PRIMED && cg_gametype->integer > 0) {
UI_PushMenu("dm_main");
return;
}
if (menuManager.CurrentMenu() == mainmenu && clc.state == CA_DISCONNECTED) {
if (developer->integer) {
if (UI_ConsoleIsVisible()) {
UI_CloseConsole();
} else {
UI_PushMenu(name);
}
UI_FocusMenuIfExists();
if (menuManager.CurrentMenu()) {
if (!memcmp(name, "main", 5)) {
UI_MainMenuWidgetsUpdate();
} else if (!memcmp(name, "multiplayer", 12)) {
UI_MultiplayerMenuWidgetsUpdate();
}
UI_OpenConsole();
}
}
} else if (developer->integer) {
if (UI_ConsoleIsVisible()) {
UI_CloseConsole();
} else {
UI_OpenConsole();
return;
}
if (uWinMan.DialogExists()) {
uWinMan.RemoveAllDialogBoxes();
return;
}
if (menuManager.CurrentMenu()) {
menuManager.PopMenu(qtrue);
} else if (!Q_stricmp(name, "main") && clc.state > CA_PRIMED && cg_gametype->integer > 0) {
// multiplayer
UI_PushMenu("dm_main");
} else {
// single-player
UI_PushMenu(name);
}
UI_FocusMenuIfExists();
if (menuManager.CurrentMenu()) {
if (!str::cmp(name, "main")) {
UI_MainMenuWidgetsUpdate();
} else if (!str::cmp(name, "dm_main")) {
UI_MultiplayerMainMenuWidgetsUpdate();
} else if (!str::cmp(name, "multiplayer")) {
UI_MultiplayerMenuWidgetsUpdate();
}
}
}
@@ -2989,7 +3058,7 @@ void UI_MapList_f(void)
}
MapRunnerClass *map = new MapRunnerClass;
map->Setup("maps", mappath, ".bsp");
map->Setup("maps", mappath, ".bsp", "_sml");
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2);
}
@@ -3002,20 +3071,34 @@ UI_DMMapSelect_f
void UI_DMMapSelect_f(void)
{
str basepath = "maps";
str mappath = "maps";
str mappath;
str gametype;
if (Cmd_Argc() > 1) {
mappath += "/";
mappath += Cmd_Argv(1);
}
const char *path;
if (Cmd_Argc() > 2) {
basepath += "/";
basepath += Cmd_Argv(2);
path = Cmd_Argv(1);
if (strcmp(path, ".")) {
basepath += "/";
basepath += path;
}
if (Cmd_Argc() > 2) {
path = Cmd_Argv(2);
if (strcmp(path, ".")) {
mappath += "maps/";
mappath += path;
}
}
if (Cmd_Argc() > 3) {
gametype = Cmd_Argv(3);
}
}
MpMapPickerClass *map = new MpMapPickerClass;
map->Setup(basepath, mappath);
map->Setup(basepath, mappath, gametype);
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2);
}
@@ -3200,6 +3283,8 @@ void UI_PlayerModel_f(void)
PlayerModelPickerClass *picker = new PlayerModelPickerClass;
picker->Setup("models/player", modelpath, bGermanModel);
CL_SetMousePos(cls.glconfig.vidWidth / 2, cls.glconfig.vidHeight / 2);
}
/*
@@ -3210,14 +3295,20 @@ UI_ApplyPlayerModel_f
void UI_ApplyPlayerModel_f(void)
{
const char *pszUIPlayerModel;
char donotshowssindeorfr[64];
pszUIPlayerModel = CvarGetForUI("ui_dm_playermodel", "american_army");
pszUIPlayerModel = CvarGetForUI("ui_dm_playermodel_set", "american_army");
Cvar_Set("dm_playermodel", pszUIPlayerModel);
pszUIPlayerModel = CvarGetForUI("ui_dm_playergermanmodel", "german_wehrmacht_soldier");
Cvar_Set("ui_dm_playergermanmodel", pszUIPlayerModel);
pszUIPlayerModel = CvarGetForUI("ui_dm_playergermanmodel_set", "german_wehrmacht_soldier");
if (!Q_stricmpn(pszUIPlayerModel, "german_waffen", 14)) {
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), pszUIPlayerModel + 14);
Cvar_Set("dm_playergermanmodel", donotshowssindeorfr);
} else {
Cvar_Set("dm_playergermanmodel", pszUIPlayerModel);
}
Cvar_Set("name", CvarGetForUI("ui_name", "*** Blank Name ***"));
Cvar_Set("name", CvarGetForUI("ui_name", "UnnamedSoldier"));
}
/*
@@ -3230,24 +3321,30 @@ void UI_GetPlayerModel_f(void)
const char *pszUIPlayerModel;
char donotshowssindeorfr[64];
//
// Allies
//
pszUIPlayerModel = CvarGetForUI("dm_playermodel", "american_army");
Cvar_Set("ui_dm_playermodel", pszUIPlayerModel);
Cvar_Set("ui_dm_playermodel", PM_FilenameToDisplayname(pszUIPlayerModel));
Cvar_Set("ui_dm_playermodel_set", pszUIPlayerModel);
Cvar_Set("ui_disp_playermodel", va("models/player/%s.tik", pszUIPlayerModel));
//
// Axis
//
pszUIPlayerModel = CvarGetForUI("dm_playergermanmodel", "german_wehrmacht_soldier");
Cvar_Set("ui_dm_playergermanmodel", pszUIPlayerModel);
Cvar_Set("ui_dm_playergermanmodel", PM_FilenameToDisplayname(pszUIPlayerModel));
Cvar_Set("ui_dm_playergermanmodel_set", pszUIPlayerModel);
if (!strncmp(pszUIPlayerModel, "german_waffen_", 14)) {
memcpy(donotshowssindeorfr, "german_waffenss_", 17);
strncat(donotshowssindeorfr, pszUIPlayerModel + 14, 48);
Q_strncpyz(donotshowssindeorfr, "german_waffenss_", sizeof(donotshowssindeorfr));
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), pszUIPlayerModel + 14);
Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", donotshowssindeorfr));
} else {
strncpy(donotshowssindeorfr, pszUIPlayerModel, sizeof(donotshowssindeorfr));
Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", pszUIPlayerModel));
}
Cvar_Set("ui_disp_playergermanmodel", va("models/player/%s.tik", donotshowssindeorfr));
Cvar_Set("ui_name", CvarGetForUI("name", "*** Blank Name ***"));
Cvar_Set("ui_name", CvarGetForUI("name", "UnnamedSoldier"));
}
/*
@@ -3582,7 +3679,7 @@ void CL_FillUIImports(void)
uii.Cvar_GetString = CvarGetForUI;
uii.Cvar_Reset = Cvar_Reset;
uii.Cvar_Find = Cvar_FindVar;
uii.Cvar_Set = Cvar_Set;
uii.Cvar_Set = UI_Cvar_Set;
uii.File_PickFile = PickFile;
uii.File_FreeFile = FS_FreeFile;
uii.File_ListFiles = ListFilesForUI;
@@ -3773,7 +3870,7 @@ void UI_CreateDialog(
dlg->Create(NULL, rect, title, bgColor, UHudColor);
dlg->LinkCvar(cvarname);
dlg->SetOKCommand(command);
dlg->SetCancelCommand(command);
dlg->SetCancelCommand(cancelCommand);
dlg->SetLabelMaterial(uWinMan.RegisterShader(shader));
dlg->SetOkMaterial(uWinMan.RegisterShader(okshader));
@@ -3879,13 +3976,13 @@ void S_ServerLoaded(void)
Com_DPrintf("Loading Previous Sound State.\n");
S_StopAllSounds2(qfalse);
//S_TriggeredMusic_Stop();
//s_bSoundPaused = qtrue;
//S_ReLoad( &svs.soundSystem );
//
//if( svs.tm_filename[ 0 ] ) {
// S_TriggeredMusic_SetupHandle( svs.tm_filename, svs.tm_loopcount, svs.tm_offset, 0 );
//}
S_TriggeredMusic_Stop();
s_bSoundPaused = qtrue;
S_ReLoad( &svs.soundSystem );
if( svs.tm_filename[ 0 ] ) {
S_TriggeredMusic_SetupHandle( svs.tm_filename, svs.tm_loopcount, svs.tm_offset, 0 );
}
}
/*
@@ -4178,7 +4275,7 @@ public:
virtual griditemtype_t getListItemType(int which) const;
virtual str getListItemString(int i) const;
virtual int getListItemValue(int which) const;
virtual void DrawListItem(int iColumn, const UIRect2D &drawRect, bool bSelected, UIFont *pFont);
virtual void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont);
virtual qboolean IsHeaderEntry(void) const;
};
@@ -4342,8 +4439,8 @@ public:
virtual griditemtype_t getListItemType(int which) const;
virtual str getListItemString(int i) const;
virtual int getListItemValue(int which) const;
virtual void DrawListItem(int iColumn, const UIRect2D &drawRect, bool bSelected, UIFont *pFont);
void SetColors(const UColor &newTextColor, const UColor &newBackColor);
virtual void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont);
void SetColors(const UColor& newTextColor, const UColor& newBackColor);
void ClearColors(void);
void SetTitleItem(qboolean bSet);
virtual qboolean IsHeaderEntry(void) const;
+1
View File
@@ -49,6 +49,7 @@ void CL_ShutdownUI(void);
extern inventory_t client_inv;
extern bind_t client_bind;
extern cvar_t *cl_greenfps;
extern qboolean server_loading;
const char *CvarGetForUI(const char *name, const char *defval);
void UI_ClearState(void);
+430 -182
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -24,281 +24,529 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
bind_t::bind_t()
{
// FIXME: stub
int i;
commandwidth = 100;
commandheight = 20;
primarykeywidth = 100;
primarykeyheight = 20;
alternatekeywidth = 100;
alternatekeyheight = 20;
fillwidth = 16;
fillmaterial = NULL;
for (i = 0; i < ARRAY_LEN(headermats); i++) {
headermats[i] = NULL;
}
}
bind_t::~bind_t()
{
Clear();
Clear();
}
void bind_t::Clear
(
void
)
void bind_t::Clear(void)
{
// FIXME: stub
for (int i = binds.NumObjects(); i > 0; i--) {
bind_item_t *bi;
bi = binds.ObjectAt(i);
binds.RemoveObjectAt(i);
if (bi) {
delete bi;
}
}
}
CLASS_DECLARATION( Listener, bindlistener, NULL )
{
{ NULL, NULL }
Event EV_Bind_Header
(
"header",
EV_DEFAULT,
"iss",
"column_num name material",
"Set the header of each column"
);
Event EV_Bind_Width
(
"bind_width",
EV_DEFAULT,
"i",
"width",
"Width of the bind menu"
);
Event EV_Bind_Height
(
"bind_height",
EV_DEFAULT,
"i",
"height",
"Height of the bind menu"
);
Event EV_Bind_FillWidth
(
"bind_fillwidth",
EV_DEFAULT,
"iS",
"width material",
"Width of the filling between widgets"
);
Event EV_Bind_CommandWidth
(
"bind_commandwidth",
EV_DEFAULT,
"i",
"width",
"Width of the command item"
);
Event EV_Bind_CommandHeight
(
"bind_commandheight",
EV_DEFAULT,
"i",
"height",
"Height of the command item"
);
Event EV_Bind_PrimaryKeyWidth
(
"bind_primarykeywidth",
EV_DEFAULT,
"i",
"width",
"Width of the primary key item"
);
Event EV_Bind_PrimaryKeyHeight
(
"bind_primarykeyheight",
EV_DEFAULT,
"i",
"height",
"Height of the primary key item"
);
Event EV_Bind_AlternateKeyWidth
(
"bind_alternatekeywidth",
EV_DEFAULT,
"i",
"width",
"Width of the alternate key item"
);
Event EV_Bind_AlternateKeyHeight
(
"bind_alternatekeyheight",
EV_DEFAULT,
"i",
"height",
"Height of the alternate key item"
);
Event EV_Bind_NewItem
(
"binditem",
EV_DEFAULT,
"ss",
"name command",
"Create a new bind item in the interface"
);
Event EV_Bind_Align
(
"align",
EV_DEFAULT,
"sSSSSS",
"arg1 arg2 arg3 arg4 arg5 arg6",
"Set the alignment on the bind menu"
);
Event EV_Bind_TitleForegroundColor
(
"titleforegroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the title foreground"
);
Event EV_Bind_TitleBackgroundColor
(
"titlebackgroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the title background"
);
Event EV_Bind_InactiveForegroundColor
(
"inactiveforegroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the inactive button foreground"
);
Event EV_Bind_InactiveBackgroundColor
(
"inactivebackgroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the inactive button background"
);
Event EV_Bind_ActiveForegroundColor
(
"activeforegroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the active button foreground"
);
Event EV_Bind_ActiveBackgroundColor
(
"activebackgroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the active button background"
);
Event EV_Bind_ActiveBorderColor
(
"activebordercolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the active button border"
);
Event EV_Bind_HighlightForegroundColor
(
"highlightforegroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the highlighted button foreground"
);
Event EV_Bind_HighlightBackgroundColor
(
"highlightbackgroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the highlighted button background"
);
Event EV_Bind_SelectForegroundColor
(
"selectforegroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the selected button foreground"
);
Event EV_Bind_SelectBackgroundColor
(
"selectbackgroundcolor",
EV_DEFAULT,
"ffff",
"r g b a",
"Set the color for the selected button background"
);
Event EV_Bind_ChangeSound
(
"changesound",
EV_DEFAULT,
"s",
"soundname",
"Set the name of the sound to play when the highlighted item changes"
);
Event EV_Bind_ActiveSound
(
"activesound",
EV_DEFAULT,
"s",
"soundname",
"Set the name of the sound to play when the item is made active"
);
Event EV_Bind_EnterSound
(
"entersound",
EV_DEFAULT,
"s",
"soundname",
"Set the name of the sound to play when the key is entered"
);
CLASS_DECLARATION(Listener, bindlistener, NULL) {
{&EV_Bind_Width, &bindlistener::Width },
{&EV_Bind_Height, &bindlistener::Height },
{&EV_Bind_FillWidth, &bindlistener::FillWidth },
{&EV_Bind_CommandWidth, &bindlistener::CommandWidth },
{&EV_Bind_CommandHeight, &bindlistener::CommandHeight },
{&EV_Bind_PrimaryKeyWidth, &bindlistener::PrimaryKeyWidth },
{&EV_Bind_PrimaryKeyHeight, &bindlistener::PrimaryKeyHeight },
{&EV_Bind_AlternateKeyWidth, &bindlistener::AlternateKeyWidth },
{&EV_Bind_AlternateKeyHeight, &bindlistener::AlternateKeyHeight },
{&EV_Bind_Header, &bindlistener::Header },
{&EV_Bind_NewItem, &bindlistener::NewItem },
{&EV_Bind_Align, &bindlistener::Align },
{&EV_Bind_TitleForegroundColor, &bindlistener::TitleForegroundColor },
{&EV_Bind_TitleBackgroundColor, &bindlistener::TitleBackgroundColor },
{&EV_Bind_InactiveForegroundColor, &bindlistener::InactiveForegroundColor },
{&EV_Bind_InactiveBackgroundColor, &bindlistener::InactiveBackgroundColor },
{&EV_Bind_ActiveForegroundColor, &bindlistener::ActiveForegroundColor },
{&EV_Bind_ActiveBackgroundColor, &bindlistener::ActiveBackgroundColor },
{&EV_Bind_ActiveBorderColor, &bindlistener::ActiveBorderColor },
{&EV_Bind_HighlightForegroundColor, &bindlistener::HighlightForegroundColor},
{&EV_Bind_HighlightBackgroundColor, &bindlistener::HighlightBackgroundColor},
{&EV_Bind_SelectForegroundColor, &bindlistener::SelectForegroundColor },
{&EV_Bind_SelectBackgroundColor, &bindlistener::SelectBackgroundColor },
{&EV_Bind_ChangeSound, &bindlistener::ChangeSound },
{&EV_Bind_ActiveSound, &bindlistener::ActiveSound },
{&EV_Bind_EnterSound, &bindlistener::EnterSound },
{NULL, NULL }
};
bindlistener::bindlistener()
bindlistener::bindlistener() {}
bindlistener::bindlistener(bind_t *b)
{
bind = b;
}
bindlistener::bindlistener
(
bind_t *b
)
void bindlistener::Header(Event *ev)
{
bind = b;
int num;
num = ev->GetInteger(1) - 1;
if (num > ARRAY_LEN(bind_t::headers)) {
return;
}
bind->headers[num] = ev->GetString(2);
if (ev->NumArgs() > 2) {
bind->headermats[num] = uWinMan.RegisterShader(ev->GetString(3));
}
}
bool bindlistener::Load
(
Script& script
)
void bindlistener::ChangeSound(Event *ev)
{
// FIXME: stub
return false;
bind->changesound = ev->GetString(1);
}
void bindlistener::Header
(
Event *ev
)
void bindlistener::ActiveSound(Event *ev)
{
// FIXME: stub
bind->activesound = ev->GetString(1);
}
void bindlistener::Width
(
Event *ev
)
void bindlistener::EnterSound(Event *ev)
{
// FIXME: stub
bind->entersound = ev->GetString(1);
}
void bindlistener::FillWidth
(
Event *ev
)
void bindlistener::SelectForegroundColor(Event *ev)
{
// FIXME: stub
bind->selectfgcolor.r = ev->GetFloat(1);
bind->selectfgcolor.g = ev->GetFloat(2);
bind->selectfgcolor.b = ev->GetFloat(3);
bind->selectfgcolor.a = ev->GetFloat(4);
}
void bindlistener::Height
(
Event *ev
)
void bindlistener::SelectBackgroundColor(Event *ev)
{
// FIXME: stub
bind->selectbgcolor.r = ev->GetFloat(1);
bind->selectbgcolor.g = ev->GetFloat(2);
bind->selectbgcolor.b = ev->GetFloat(3);
bind->selectbgcolor.a = ev->GetFloat(4);
}
void bindlistener::CommandWidth
(
Event *ev
)
void bindlistener::TitleForegroundColor(Event *ev)
{
// FIXME: stub
bind->titlefgcolor.r = ev->GetFloat(1);
bind->titlefgcolor.g = ev->GetFloat(2);
bind->titlefgcolor.b = ev->GetFloat(3);
bind->titlefgcolor.a = ev->GetFloat(4);
}
void bindlistener::CommandHeight
(
Event *ev
)
void bindlistener::TitleBackgroundColor(Event *ev)
{
// FIXME: stub
bind->titlebgcolor.r = ev->GetFloat(1);
bind->titlebgcolor.g = ev->GetFloat(2);
bind->titlebgcolor.b = ev->GetFloat(3);
bind->titlebgcolor.a = ev->GetFloat(4);
}
void bindlistener::PrimaryKeyWidth
(
Event *ev
)
void bindlistener::ActiveBorderColor(Event *ev)
{
// FIXME: stub
bind->activebordercolor.r = ev->GetFloat(1);
bind->activebordercolor.g = ev->GetFloat(2);
bind->activebordercolor.b = ev->GetFloat(3);
bind->activebordercolor.a = ev->GetFloat(4);
}
void bindlistener::PrimaryKeyHeight
(
Event *ev
)
void bindlistener::ActiveForegroundColor(Event *ev)
{
// FIXME: stub
bind->activefgcolor.r = ev->GetFloat(1);
bind->activefgcolor.g = ev->GetFloat(2);
bind->activefgcolor.b = ev->GetFloat(3);
bind->activefgcolor.a = ev->GetFloat(4);
}
void bindlistener::AlternateKeyWidth
(
Event *ev
)
void bindlistener::ActiveBackgroundColor(Event *ev)
{
// FIXME: stub
bind->activebgcolor.r = ev->GetFloat(1);
bind->activebgcolor.g = ev->GetFloat(2);
bind->activebgcolor.b = ev->GetFloat(3);
bind->activebgcolor.a = ev->GetFloat(4);
}
void bindlistener::AlternateKeyHeight
(
Event *ev
)
void bindlistener::InactiveForegroundColor(Event *ev)
{
// FIXME: stub
bind->inactivefgcolor.r = ev->GetFloat(1);
bind->inactivefgcolor.g = ev->GetFloat(2);
bind->inactivefgcolor.b = ev->GetFloat(3);
bind->inactivefgcolor.a = ev->GetFloat(4);
}
void bindlistener::NewItem
(
Event *ev
)
void bindlistener::InactiveBackgroundColor(Event *ev)
{
// FIXME: stub
bind->inactivebgcolor.r = ev->GetFloat(1);
bind->inactivebgcolor.g = ev->GetFloat(2);
bind->inactivebgcolor.b = ev->GetFloat(3);
bind->inactivebgcolor.a = ev->GetFloat(4);
}
void bindlistener::Align
(
Event *ev
)
void bindlistener::HighlightForegroundColor(Event *ev)
{
// FIXME: stub
bind->highlightfgcolor.r = ev->GetFloat(1);
bind->highlightfgcolor.g = ev->GetFloat(2);
bind->highlightfgcolor.b = ev->GetFloat(3);
bind->highlightfgcolor.a = ev->GetFloat(4);
}
void bindlistener::TitleForegroundColor
(
Event *ev
)
void bindlistener::HighlightBackgroundColor(Event *ev)
{
// FIXME: stub
bind->highlightbgcolor.r = ev->GetFloat(1);
bind->highlightbgcolor.g = ev->GetFloat(2);
bind->highlightbgcolor.b = ev->GetFloat(3);
bind->highlightbgcolor.a = ev->GetFloat(4);
}
void bindlistener::TitleBackgroundColor
(
Event *ev
)
void bindlistener::Align(Event *ev)
{
// FIXME: stub
int i;
for (i = 1; i <= ev->NumArgs(); i++) {
str align = ev->GetString(i);
if (!str::icmp(align, "left")) {
bind->align |= WA_LEFT;
} else if (!str::icmp(align, "right")) {
bind->align |= WA_RIGHT;
} else if (!str::icmp(align, "top")) {
bind->align |= WA_TOP;
} else if (!str::icmp(align, "bottom")) {
bind->align |= WA_BOTTOM;
} else if (!str::icmp(align, "centerx")) {
bind->align |= WA_CENTERX;
} else if (!str::icmp(align, "centery")) {
bind->align |= WA_CENTERY;
}
}
}
void bindlistener::InactiveForegroundColor
(
Event *ev
)
void bindlistener::NewItem(Event *ev)
{
// FIXME: stub
bind_item_t *bt;
UIReggedMaterial *mat = NULL;
if (ev->NumArgs() > 2) {
mat = uWinMan.RegisterShader(ev->GetString(3));
}
str n = ev->GetString(1);
str c = ev->GetString(2);
bt = new bind_item_t;
bt->name = n;
bt->command = c;
bt->nameMaterial = mat;
bind->binds.AddObject(bt);
}
void bindlistener::InactiveBackgroundColor
(
Event *ev
)
void bindlistener::Width(Event *ev)
{
// FIXME: stub
bind->width = ev->GetInteger(1);
}
void bindlistener::ActiveForegroundColor
(
Event *ev
)
void bindlistener::Height(Event *ev)
{
// FIXME: stub
bind->height = ev->GetInteger(1);
}
void bindlistener::ActiveBackgroundColor
(
Event *ev
)
void bindlistener::FillWidth(Event *ev)
{
// FIXME: stub
bind->fillwidth = ev->GetInteger(1);
if (ev->NumArgs() > 1) {
bind->fillmaterial = uWinMan.RegisterShader(ev->GetString(2));
}
}
void bindlistener::ActiveBorderColor
(
Event *ev
)
void bindlistener::CommandWidth(Event *ev)
{
// FIXME: stub
bind->commandwidth = ev->GetInteger(1);
}
void bindlistener::HighlightForegroundColor
(
Event *ev
)
void bindlistener::CommandHeight(Event *ev)
{
// FIXME: stub
bind->commandheight = ev->GetInteger(1);
}
void bindlistener::HighlightBackgroundColor
(
Event *ev
)
void bindlistener::PrimaryKeyWidth(Event *ev)
{
// FIXME: stub
bind->primarykeywidth = ev->GetInteger(1);
}
void bindlistener::SelectForegroundColor
(
Event *ev
)
void bindlistener::PrimaryKeyHeight(Event *ev)
{
// FIXME: stub
bind->primarykeyheight = ev->GetInteger(1);
}
void bindlistener::SelectBackgroundColor
(
Event *ev
)
void bindlistener::AlternateKeyWidth(Event *ev)
{
// FIXME: stub
bind->alternatekeywidth = ev->GetInteger(1);
}
void bindlistener::ChangeSound
(
Event *ev
)
void bindlistener::AlternateKeyHeight(Event *ev)
{
// FIXME: stub
bind->alternatekeyheight = ev->GetInteger(1);
}
void bindlistener::ActiveSound
(
Event *ev
)
bool bindlistener::Load(Script& script)
{
// FIXME: stub
str token;
str errortext;
while (script.TokenAvailable(true)) {
token = script.GetToken(true);
if (!token.length() || !ValidEvent(token)) {
throw "invalid token";
}
Event *event = new Event(token);
while (script.TokenAvailable(false)) {
event->AddToken(script.GetToken(false));
}
ProcessEvent(event);
}
return true;
}
void bindlistener::EnterSound
(
Event *ev
)
bool CL_LoadBind(const char *filename, bind_t *bind)
{
// FIXME: stub
Script script;
bind->Clear();
bindlistener listener(bind);
script.LoadFile(filename);
// Load the bind file
return listener.Load(script);
}
+82 -88
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,115 +20,109 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIBIND_H__
#define __CL_UIBIND_H__
#pragma once
class bind_item_t {
class bind_item_t
{
public:
str name;
str command;
UIReggedMaterial *nameMaterial;
str name;
str command;
UIReggedMaterial *nameMaterial;
bind_item_t();
bind_item_t( str name, str command, UIReggedMaterial *nameMaterial );
bind_item_t();
bind_item_t(str name, str command, UIReggedMaterial *nameMaterial);
};
inline
bind_item_t::bind_item_t()
inline bind_item_t::bind_item_t()
{
nameMaterial = NULL;
nameMaterial = NULL;
}
inline
bind_item_t::bind_item_t
(
str name,
str command,
UIReggedMaterial *nameMaterial
)
inline bind_item_t::bind_item_t(str name, str command, UIReggedMaterial *nameMaterial)
{
this->name = name;
this->command = command;
this->nameMaterial = nameMaterial;
this->name = name;
this->command = command;
this->nameMaterial = nameMaterial;
}
class bind_t {
class bind_t
{
public:
int width;
int height;
int fillwidth;
int commandwidth;
int commandheight;
int primarykeywidth;
int primarykeyheight;
int alternatekeywidth;
int alternatekeyheight;
int align;
UColor titlebgcolor;
UColor titlefgcolor;
UColor activefgcolor;
UColor activebgcolor;
UColor activebordercolor;
UColor inactivefgcolor;
UColor inactivebgcolor;
UColor highlightfgcolor;
UColor highlightbgcolor;
UColor selectfgcolor;
UColor selectbgcolor;
str changesound;
str activesound;
str entersound;
str headers[ 3 ];
UIReggedMaterial *headermats[ 3 ];
UIReggedMaterial *fillmaterial;
Container<bind_item_t *> binds;
int width;
int height;
int fillwidth;
int commandwidth;
int commandheight;
int primarykeywidth;
int primarykeyheight;
int alternatekeywidth;
int alternatekeyheight;
int align;
UColor titlebgcolor;
UColor titlefgcolor;
UColor activefgcolor;
UColor activebgcolor;
UColor activebordercolor;
UColor inactivefgcolor;
UColor inactivebgcolor;
UColor highlightfgcolor;
UColor highlightbgcolor;
UColor selectfgcolor;
UColor selectbgcolor;
str changesound;
str activesound;
str entersound;
str headers[3];
UIReggedMaterial *headermats[3];
UIReggedMaterial *fillmaterial;
Container<bind_item_t *> binds;
public:
bind_t();
~bind_t();
bind_t();
~bind_t();
void Clear( void );
void Clear(void);
};
class bindlistener : public Listener {
class bindlistener : public Listener
{
protected:
bind_t *bind;
bind_t *bind;
public:
CLASS_PROTOTYPE( bindlistener );
CLASS_PROTOTYPE(bindlistener);
public:
bindlistener();
bindlistener( bind_t *b );
bindlistener();
bindlistener(bind_t *b);
bool Load( Script& script );
void Header( Event *ev );
void Width( Event *ev );
void FillWidth( Event *ev );
void Height( Event *ev );
void CommandWidth( Event *ev );
void CommandHeight( Event *ev );
void PrimaryKeyWidth( Event *ev );
void PrimaryKeyHeight( Event *ev );
void AlternateKeyWidth( Event *ev );
void AlternateKeyHeight( Event *ev );
void NewItem( Event *ev );
void Align( Event *ev );
void TitleForegroundColor( Event *ev );
void TitleBackgroundColor( Event *ev );
void InactiveForegroundColor( Event *ev );
void InactiveBackgroundColor( Event *ev );
void ActiveForegroundColor( Event *ev );
void ActiveBackgroundColor( Event *ev );
void ActiveBorderColor( Event *ev );
void HighlightForegroundColor( Event *ev );
void HighlightBackgroundColor( Event *ev );
void SelectForegroundColor( Event *ev );
void SelectBackgroundColor( Event *ev );
void ChangeSound( Event *ev );
void ActiveSound( Event *ev );
void EnterSound( Event *ev );
bool Load(Script& script);
void Header(Event *ev);
void Width(Event *ev);
void FillWidth(Event *ev);
void Height(Event *ev);
void CommandWidth(Event *ev);
void CommandHeight(Event *ev);
void PrimaryKeyWidth(Event *ev);
void PrimaryKeyHeight(Event *ev);
void AlternateKeyWidth(Event *ev);
void AlternateKeyHeight(Event *ev);
void NewItem(Event *ev);
void Align(Event *ev);
void TitleForegroundColor(Event *ev);
void TitleBackgroundColor(Event *ev);
void InactiveForegroundColor(Event *ev);
void InactiveBackgroundColor(Event *ev);
void ActiveForegroundColor(Event *ev);
void ActiveBackgroundColor(Event *ev);
void ActiveBorderColor(Event *ev);
void HighlightForegroundColor(Event *ev);
void HighlightBackgroundColor(Event *ev);
void SelectForegroundColor(Event *ev);
void SelectBackgroundColor(Event *ev);
void ChangeSound(Event *ev);
void ActiveSound(Event *ev);
void EnterSound(Event *ev);
};
#endif
bool CL_LoadBind(const char* filename, bind_t* bind);
+209 -27
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -22,72 +22,254 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_ui.h"
CLASS_DECLARATION( USignal, FilePickerClass, NULL )
class FilePickerItem : public UIListCtrlItem
{
{ NULL, NULL }
str strings[3];
public:
FilePickerItem(const str& fileName, const str& date, const str& size);
int getListItemValue(int which) const override;
griditemtype_t getListItemType(int which) const override;
str getListItemString(int which) const override;
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
qboolean IsHeaderEntry() const override;
};
CLASS_DECLARATION(USignal, FilePickerClass, NULL) {
{&EV_UIListBase_ItemSelected, &FilePickerClass::FileSelected },
{&EV_UIListBase_ItemDoubleClicked, &FilePickerClass::FileChosen },
{&W_Deactivated, &FilePickerClass::OnDeactivated},
{NULL, NULL }
};
FilePickerClass::FilePickerClass()
{
// FIXME: stub
window = new UIFloatingWindow();
window->Create(
NULL,
UIRect2D((cls.glconfig.vidWidth - 400) / 2, (cls.glconfig.vidHeight - 300) / 2, 400, 300),
"File Picker",
UColor(0.15f, 0.195f, 0.278f),
UHudColor
);
window->Connect(this, W_Deactivated, W_Deactivated);
listbox = new UIListCtrl();
listbox->InitFrame(window->getChildSpace(), window->getChildSpace()->getClientFrame(), 0);
listbox->setBackgroundColor(UColor(0.02f, 0.07f, 0.005f), true);
listbox->setForegroundColor(UHudColor);
listbox->AddColumn("File Name", 0, 175, false, false);
listbox->AddColumn("Date", 1, 125, false, false);
listbox->AddColumn("Size", 2, 100, true, false);
listbox->Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
listbox->Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
listbox->AllowActivate(true);
// Added in 2.0
// Don't localize elements
listbox->SetDontLocalize();
}
FilePickerClass::~FilePickerClass()
{
// FIXME: stub
if (listbox) {
delete listbox;
listbox = NULL;
}
if (window) {
delete window;
window = NULL;
}
}
void FilePickerClass::SetupFiles( void )
void FilePickerClass::Setup(
const char *root_directory, const char *current_directory, const char *ext, const char *ignore_files
)
{
// FIXME: stub
Initialize(root_directory, current_directory, ext, ignore_files);
}
void FilePickerClass::GotoParentDirectory( void )
void FilePickerClass::Initialize(
const char *root_directory, const char *current_directory, const char *ext, const char *ignore_files
)
{
// FIXME: stub
rootDirectory = root_directory;
if (rootDirectory.length() > 1 && rootDirectory[rootDirectory.length() - 1] != '/') {
rootDirectory += "/";
}
currentDirectory = current_directory;
if (currentDirectory.length() > 1 && currentDirectory[currentDirectory.length() - 1] != '/') {
currentDirectory += "/";
}
extension = ext;
ignoredFiles = ignore_files;
SetupFiles();
}
void FilePickerClass::GotoSubDirectory( str subdir )
void FilePickerClass::GotoParentDirectory(void)
{
// FIXME: stub
int i;
if (currentDirectory == rootDirectory) {
return;
}
for (i = currentDirectory.length() - 2; i > 0; i--) {
if (currentDirectory[i] == '/') {
break;
}
}
if (currentDirectory[i] == '/') {
i++;
}
currentDirectory = str(currentDirectory, 0, i);
// refresh files
SetupFiles();
}
void FilePickerClass::Initialize( const char *root_directory, const char *current_directory, const char *ext )
void FilePickerClass::GotoSubDirectory(str subdir)
{
// FIXME: stub
currentDirectory += subdir + "/";
// refresh files
SetupFiles();
}
void FilePickerClass::CloseWindow( void )
void FilePickerClass::SetupFiles(void)
{
// FIXME: stub
str mappath;
str work;
char **filenames;
int numfiles;
int i;
char date[128];
char size[128];
listbox->DeleteAllItems();
if (currentDirectory != rootDirectory) {
// create the parent directory item
listbox->AddItem(new FilePickerItem("..", "", ""));
}
// retrieve directories
filenames = FS_ListFiles(currentDirectory, "/", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
if (filename[0] == '.' || !strlen(filename)) {
continue;
}
work = "[";
work += filename;
work += "]";
FS_FileTime(currentDirectory + filename, date, size);
listbox->AddItem(new FilePickerItem(work, date, size));
}
FS_FreeFileList(filenames);
filenames = FS_ListFiles(currentDirectory, extension, qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
if (ignoredFiles.length() && strstr(filename, ignoredFiles)) {
// Added in 2.0
// Check for ignored files
continue;
}
work = filename;
FS_FileTime(currentDirectory + work, date, size);
listbox->AddItem(new FilePickerItem(work, date, size));
}
FS_FreeFileList(filenames);
window->setTitle(currentDirectory);
}
void FilePickerClass::FileSelected( Event *ev )
void FilePickerClass::FileSelected(const str& currentDirectory, const str& partialName, const str& fullname) {}
void FilePickerClass::FileSelected(Event *ev)
{
// FIXME: stub
str name = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
if (*name != '[' && *name != '.') {
FileSelected(currentDirectory, name, currentDirectory + name);
}
uii.Snd_PlaySound("sound/menu/scroll.wav");
}
void FilePickerClass::FileSelected( str &currentDirectory, str &partialName, str &fullname )
void FilePickerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) {}
void FilePickerClass::FileChosen(Event *ev)
{
// FIXME: stub
str filename = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
if (*filename == '[') {
uii.Snd_PlaySound("sound/menu/scroll.wav");
GotoSubDirectory(str(filename, 1, filename.length() - 1));
} else if (*filename == '.') {
GotoParentDirectory();
} else {
uii.Snd_PlaySound("sound/menu/apply.wav");
FileChosen(currentDirectory, filename, currentDirectory + filename);
}
}
void FilePickerClass::FileChosen( Event *ev )
void FilePickerClass::CloseWindow(void)
{
// FIXME: stub
PostEvent(EV_Remove, 0);
}
void FilePickerClass::FileChosen( str &currentDirectory, str &partialName, str &fullname )
void FilePickerClass::OnDeactivated(Event *ev)
{
// FIXME: stub
CloseWindow();
}
void FilePickerClass::OnDeactivated( Event *ev )
FilePickerItem::FilePickerItem(const str& fileName, const str& date, const str& size)
{
// FIXME: stub
strings[0] = fileName;
strings[1] = date;
strings[2] = size;
}
void FilePickerClass::Setup( const char *root_directory, const char *current_directory, const char *ext )
int FilePickerItem::getListItemValue(int which) const
{
// FIXME: stub
return atoi(strings[which]);
}
griditemtype_t FilePickerItem::getListItemType(int which) const
{
return griditemtype_t::TYPE_STRING;
}
str FilePickerItem::getListItemString(int which) const
{
return strings[which];
}
void FilePickerItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
qboolean FilePickerItem::IsHeaderEntry() const
{
return qfalse;
}
+26 -25
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,40 +20,41 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIFILEPICKER_H__
#define __CL_UIFILEPICKER_H__
#pragma once
class UIListCtrl;
class FilePickerClass : public USignal {
UIFloatingWindow *window;
UIListCtrl *listbox;
str currentDirectory;
str rootDirectory;
str extension;
class FilePickerClass : public USignal
{
UIFloatingWindow *window;
UIListCtrl *listbox;
str currentDirectory;
str rootDirectory;
str extension;
// Added in 2.0
str ignoredFiles;
public:
CLASS_PROTOTYPE( FilePickerClass );
CLASS_PROTOTYPE(FilePickerClass);
private:
void SetupFiles( void );
void GotoParentDirectory( void );
void GotoSubDirectory( str subdir );
void Initialize( const char *root_directory, const char *current_directory, const char *ext );
void SetupFiles(void);
void GotoParentDirectory(void);
void GotoSubDirectory(str subdir);
// ignore_files parameter, added in 2.0
void Initialize(const char *root_directory, const char *current_directory, const char *ext, const char* ignore_files);
protected:
void CloseWindow( void );
void FileSelected( Event *ev );
virtual void FileSelected( str &currentDirectory, str &partialName, str &fullname );
void FileChosen( Event *ev );
virtual void FileChosen( str &currentDirectory, str &partialName, str &fullname );
void OnDeactivated( Event *ev );
void CloseWindow(void);
void FileSelected(Event *ev);
virtual void FileSelected(const str& currentDirectory, const str& partialName, const str& fullname);
void FileChosen(Event *ev);
virtual void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname);
void OnDeactivated(Event *ev);
public:
FilePickerClass();
~FilePickerClass();
FilePickerClass();
~FilePickerClass();
void Setup( const char *root_directory, const char *current_directory, const char *ext );
void Setup(const char *root_directory, const char *current_directory, const char *ext, const char* ignore_files = NULL);
};
#endif /* __CL_UIFILEPICKER_H__ */
+183 -17
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -21,44 +21,210 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "cl_ui.h"
#include "../qcommon/localization.h"
CLASS_DECLARATION( UIListCtrl, UILANGameClass, NULL )
class LANGameItem : public UIListCtrlItem
{
{ NULL, NULL }
str strings[5];
public:
LANGameItem();
LANGameItem(
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping
);
int getListItemValue(int which) const override;
griditemtype_t getListItemType(int which) const override;
str getListItemString(int which) const override;
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
qboolean IsHeaderEntry() const override;
};
Event EV_LANGame_JoinGame
(
"joingame",
EV_DEFAULT,
NULL,
NULL,
"Join the currently selected server"
);
CLASS_DECLARATION(UIListCtrl, UILANGameClass, NULL) {
{&EV_UIListBase_ItemSelected, &UILANGameClass::SelectServer},
{&EV_UIListBase_ItemDoubleClicked, &UILANGameClass::JoinServer },
{&EV_LANGame_JoinGame, &UILANGameClass::JoinServer },
{NULL, NULL }
};
UILANGameClass::UILANGameClass()
{
// FIXME: stub
Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
AllowActivate(true);
setHeaderFont("facfont-20");
m_iLastUpdateTime = 0;
m_noservers_mat = uWinMan.RegisterShader("textures/menu/noservers");
}
void UILANGameClass::SetupServers( void )
void UILANGameClass::Draw(void)
{
// FIXME: stub
if (cls.bNewLocalServerInfo) {
SetupServers();
}
UIListCtrl::Draw();
if (!getNumItems() && m_noservers_mat) {
float x, y, w, h;
w = re.GetShaderWidth(m_noservers_mat->GetMaterial()) * m_vVirtualScale[0];
h = re.GetShaderHeight(m_noservers_mat->GetMaterial()) * m_vVirtualScale[1];
UIRect2D frame = getClientFrame();
x = (frame.size.width - w) * 0.5f;
y = (frame.size.height - h) * 0.5f;
re.DrawStretchPic(x, y, w, h, 0, 0, 1, 1, m_noservers_mat->GetMaterial());
}
if (m_iLastUpdateTime && m_iLastUpdateTime < cls.realtime) {
Cvar_Set("cl_langamerefreshstatus", "Ready");
m_iLastUpdateTime = 0;
}
}
void UILANGameClass::Draw( void )
void UILANGameClass::UpdateUIElement(void)
{
// FIXME: stub
float width;
RemoveAllColumns();
width = getClientFrame().size.width - 16.f;
AddColumn(Sys_LV_CL_ConvertString("Server Name"), 0, width * 0.4f, false, false);
AddColumn(Sys_LV_CL_ConvertString("Map"), 1, width * 0.15f, false, false);
AddColumn(Sys_LV_CL_ConvertString("Players"), 2, width * 0.165f, true, true);
AddColumn(Sys_LV_CL_ConvertString("GameType"), 3, width * 0.22f, false, false);
AddColumn(Sys_LV_CL_ConvertString("Ping"), 4, width * 0.065f, true, false);
uWinMan.ActivateControl(this);
SetupServers();
}
void UILANGameClass::SelectServer( Event *ev )
void UILANGameClass::SetupServers(void)
{
// FIXME: stub
int i;
LANGameItem *pItem;
const serverInfo_t *pServerInfo;
for (i = 1; i <= cls.numlocalservers; i++) {
pServerInfo = &cls.localServers[i - 1];
if (i > getNumItems()) {
pItem = new LANGameItem();
AddItem(pItem);
} else {
pItem = static_cast<LANGameItem *>(GetItem(i));
}
*pItem = LANGameItem(
pServerInfo->hostName,
pServerInfo->mapName,
va("%02i/%02i", pServerInfo->clients, pServerInfo->maxClients),
pServerInfo->gameTypeString,
str(pServerInfo->ping)
);
}
while (cls.numlocalservers < getNumItems()) {
DeleteItem(getNumItems());
}
cls.bNewLocalServerInfo = false;
m_iLastUpdateTime = 0;
}
void UILANGameClass::JoinServer( Event *ev )
void UILANGameClass::SelectServer(Event *ev)
{
// FIXME: stub
const serverInfo_t& serverInfo = cls.localServers[getCurrentItem() - 1];
static const char info[] = "\xFF\xFF\xFF\xFF\x02getinfo xxx";
Com_Printf("Requesting updated info from server...\n");
Cvar_Set("cl_langamerefreshstatus", "Requesting updated info from server...");
NET_SendPacket(NS_CLIENT, sizeof(info), info, serverInfo.adr);
m_iLastUpdateTime = cls.realtime + 3000;
}
qboolean UILANGameClass::KeyEvent( int key, unsigned int time )
void UILANGameClass::JoinServer(Event *ev)
{
// FIXME: stub
return qfalse;
if (!getCurrentItem()) {
return;
}
const serverInfo_t& serverInfo = cls.localServers[getCurrentItem() - 1];
UI_SetReturnMenuToCurrent();
CL_Connect(NET_AdrToString(serverInfo.adr), netadrtype_t::NA_UNSPEC);
}
void UILANGameClass::UpdateUIElement( void )
qboolean UILANGameClass::KeyEvent(int key, unsigned int time)
{
// FIXME: stub
switch (key) {
case K_ENTER:
case K_KP_ENTER:
JoinServer(NULL);
return true;
case K_UPARROW:
if (getCurrentItem() > 1) {
TrySelectItem(getCurrentItem() - 1);
SelectServer(NULL);
}
return false;
case K_DOWNARROW:
if (getCurrentItem() < getNumItems()) {
TrySelectItem(getCurrentItem() + 1);
SelectServer(NULL);
}
return false;
}
return UIListBase::KeyEvent(key, time);
}
LANGameItem::LANGameItem() {}
LANGameItem::LANGameItem(
const str& hostName, const str& mapName, const str& players, const str& gameTypeString, const str& ping
)
{
strings[0] = hostName;
strings[1] = mapName;
strings[2] = players;
strings[3] = gameTypeString;
strings[4] = ping;
}
int LANGameItem::getListItemValue(int which) const
{
return atoi(strings[which]);
}
griditemtype_t LANGameItem::getListItemType(int which) const
{
return griditemtype_t::TYPE_STRING;
}
str LANGameItem::getListItemString(int which) const
{
return strings[which];
}
void LANGameItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
qboolean LANGameItem::IsHeaderEntry() const
{
return qfalse;
}
+14 -16
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,29 +20,27 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UILANGAME_H__
#define __CL_UILANGAME_H__
#pragma once
class UILANGameClass : public UIListCtrl {
class UILANGameClass : public UIListCtrl
{
protected:
int m_iLastUpdateTime;
UIReggedMaterial *m_noservers_mat;
int m_iLastUpdateTime;
UIReggedMaterial *m_noservers_mat;
public:
CLASS_PROTOTYPE( UILANGameClass );
CLASS_PROTOTYPE(UILANGameClass);
private:
void SetupServers( void );
void SetupServers(void);
protected:
void Draw( void ) override;
void SelectServer( Event *ev );
void JoinServer( Event *ev );
qboolean KeyEvent( int key, unsigned int time ) override;
void UpdateUIElement( void ) override;
void Draw(void) override;
void SelectServer(Event *ev);
void JoinServer(Event *ev);
qboolean KeyEvent(int key, unsigned int time) override;
void UpdateUIElement(void) override;
public:
UILANGameClass();
UILANGameClass();
};
#endif /* __CL_UILANGAME_H__ */
+319 -25
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -21,63 +21,357 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "cl_ui.h"
#include "../qcommon/localization.h"
CLASS_DECLARATION( UIListCtrl, UIFAKKLoadGameClass, NULL )
class FAKKLoadGameItem : public UIListCtrlItem
{
{ NULL, NULL }
str strings[4];
public:
FAKKLoadGameItem(const str& missionName, const str& elapsedTime, const str& dateTime, const str& fileName);
int getListItemValue(int which) const override;
griditemtype_t getListItemType(int which) const override;
str getListItemString(int which) const override;
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
qboolean IsHeaderEntry() const override;
};
static UIFAKKLoadGameClass *loadgame_ui = NULL;
Event EV_FAKKLoadGame_LoadGame
(
"loadgame",
EV_DEFAULT,
NULL,
NULL,
"Load the currently selected game"
);
Event EV_FAKKLoadGame_RemoveGame
(
"removegame",
EV_DEFAULT,
NULL,
NULL,
"Delete the currently selected game"
);
Event EV_FAKKLoadGame_DeleteGame
(
"deletegame",
EV_DEFAULT,
NULL,
NULL,
"Delete the currently selected game... for real"
);
Event EV_FAKKLoadGame_NoDeleteGame
(
"nodeletegame",
EV_DEFAULT,
NULL,
NULL,
"Delete the currently selected game... for real"
);
Event EV_FAKKLoadGame_SaveGame
(
"savegame",
EV_DEFAULT,
NULL,
NULL,
"Save the currently selected game"
);
CLASS_DECLARATION(UIListCtrl, UIFAKKLoadGameClass, NULL) {
{&EV_UIListBase_ItemSelected, &UIFAKKLoadGameClass::SelectGame },
{&EV_UIListBase_ItemDoubleClicked, &UIFAKKLoadGameClass::LoadGame },
{&EV_FAKKLoadGame_RemoveGame, &UIFAKKLoadGameClass::RemoveGame },
{&EV_FAKKLoadGame_DeleteGame, &UIFAKKLoadGameClass::DeleteGame },
{&EV_FAKKLoadGame_NoDeleteGame, &UIFAKKLoadGameClass::NoDeleteGame},
{&EV_FAKKLoadGame_LoadGame, &UIFAKKLoadGameClass::LoadGame },
{&EV_FAKKLoadGame_SaveGame, &UIFAKKLoadGameClass::SaveGame },
{NULL, NULL }
};
UIFAKKLoadGameClass::UIFAKKLoadGameClass()
{
// FIXME: stub
Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
AllowActivate(false);
m_bRemovePending = false;
setHeaderFont("facfont-20");
loadgame_ui = this;
}
void UIFAKKLoadGameClass::SelectGame( Event *ev )
UIFAKKLoadGameClass::~UIFAKKLoadGameClass()
{
// FIXME: stub
loadgame_ui = NULL;
}
void UIFAKKLoadGameClass::LoadGame( Event *ev )
void UIFAKKLoadGameClass::UpdateUIElement(void)
{
// FIXME: stub
float width;
RemoveAllColumns();
width = getClientFrame().size.width;
AddColumn(Sys_LV_CL_ConvertString("Mission"), 0, width * 0.555, false, false);
AddColumn(Sys_LV_CL_ConvertString("Elapsed Time"), 1, width * 0.17f, true, true);
AddColumn(Sys_LV_CL_ConvertString("Date & Time Logged"), 2, width * 0.275f, true, true);
uWinMan.ActivateControl(this);
SetupFiles();
}
void UIFAKKLoadGameClass::SaveGame( Event *ev )
void UIFAKKLoadGameClass::SetupFiles(void)
{
// FIXME: stub
char **filenames;
int numfiles;
int i;
const char *searchFolder = Com_GetArchiveFolder();
// cleanup
DeleteAllItems();
filenames = FS_ListFiles(searchFolder, "ssv", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename;
str work;
str gametime;
str date;
fileHandle_t f;
savegamestruct_t save;
filename = filenames[i];
work = searchFolder;
work += "/";
work += filename;
FS_FOpenFileRead(work, &f, qfalse, qtrue);
if (!f) {
continue;
}
FS_Read(&save, sizeof(savegamestruct_t), f);
FS_FCloseFile(f);
Com_SwapSaveStruct(&save);
if (save.version != SAVEGAME_STRUCT_VERSION) {
// wrong save game version
continue;
}
if (save.type != com_target_game->integer) {
continue;
}
gametime = (save.mapTime / 1000);
date = save.time;
AddItem(new FAKKLoadGameItem(save.comment, gametime, date, save.saveName));
}
FS_FreeFileList(filenames);
// sort by date
SortByColumn(2);
// select the first item
TrySelectItem(1);
SelectGame(NULL);
}
void UIFAKKLoadGameClass::RemoveGame( Event *ev )
void UIFAKKLoadGameClass::SelectGame(Event *ev)
{
// FIXME: stub
UIWidget *wid;
const char *shotName;
if (getCurrentItem() > 0) {
shotName = Com_GetArchiveFileName(GetItem(getCurrentItem())->getListItemString(3), "tga");
} else {
shotName = "textures/menu/no_saved_games.tga";
}
wid = findSibling("LoadSaveShot");
if (!wid) {
return;
}
wid->setMaterial(uWinMan.RefreshShader(shotName));
}
void UIFAKKLoadGameClass::DeleteGame( Event *ev )
void UIFAKKLoadGameClass::RemoveGame(Event *ev)
{
// FIXME: stub
if (m_bRemovePending || getCurrentItem() <= 0) {
return;
}
Cbuf_ExecuteText(
EXEC_NOW,
"dialog \"\" \"\" \"widgetcommand LoadSaveList deletegame\" \"widgetcommand LoadSaveList nodeletegame\" 256 64 "
"confirm_delete menu_button_trans menu_button_trans\n"
);
m_bRemovePending = true;
}
void UIFAKKLoadGameClass::NoDeleteGame( Event *ev )
void UIFAKKLoadGameClass::NoDeleteGame(Event *ev)
{
// FIXME: stub
m_bRemovePending = false;
}
qboolean UIFAKKLoadGameClass::KeyEvent( int key, unsigned int time )
void UIFAKKLoadGameClass::DeleteGame(Event *ev)
{
// FIXME: stub
return qfalse;
str name;
cvar_t *var;
m_bRemovePending = false;
if (getCurrentItem() <= 0) {
return;
}
name = GetItem(getCurrentItem())->getListItemString(3);
var = Cvar_Get("g_lastsave", "", 0);
if (!strcmp(name, var->string)) {
// Make sure the last save is not the save being deleted
Cvar_Set("g_lastsave", "");
}
Com_WipeSavegame(name);
SetupFiles();
}
void UIFAKKLoadGameClass::UpdateUIElement( void )
void UIFAKKLoadGameClass::LoadGame(Event *ev)
{
// FIXME: stub
char cmdString[266];
str name;
if (getCurrentItem() <= 0) {
return;
}
name = GetItem(getCurrentItem())->getListItemString(3);
// Execute the command
Com_sprintf(cmdString, sizeof(cmdString), "loadgame %s\n", name.c_str());
Cbuf_AddText(cmdString);
}
void UIFAKKLoadGameClass::SetupFiles( void )
void UIFAKKLoadGameClass::SaveGame(Event *ev)
{
// FIXME: stub
Cbuf_ExecuteText(EXEC_NOW, "savegame");
}
void UI_SetupFiles( void ) {
// FIXME: stub
qboolean UIFAKKLoadGameClass::KeyEvent(int key, unsigned int time)
{
switch (key) {
case K_DEL:
RemoveGame(NULL);
return qtrue;
case K_ENTER:
case K_KP_ENTER:
LoadGame(NULL);
return qtrue;
case K_UPARROW:
if (getCurrentItem() > 1) {
TrySelectItem(getCurrentItem() - 1);
SelectGame(NULL);
return qtrue;
}
break;
case K_DOWNARROW:
if (getCurrentItem() < getNumItems()) {
TrySelectItem(getCurrentItem() + 1);
SelectGame(NULL);
return qtrue;
}
break;
default:
return UIListBase::KeyEvent(key, time);
}
return qfalse;
}
void UI_SetupFiles(void)
{
if (loadgame_ui && loadgame_ui->getShow()) {
loadgame_ui->SetupFiles();
}
}
FAKKLoadGameItem::FAKKLoadGameItem(
const str& missionName, const str& elapsedTime, const str& dateTime, const str& fileName
)
{
strings[0] = missionName;
strings[1] = elapsedTime;
strings[2] = dateTime;
strings[3] = fileName;
}
int FAKKLoadGameItem::getListItemValue(int which) const
{
return atoi(strings[which]);
}
griditemtype_t FAKKLoadGameItem::getListItemType(int which) const
{
return griditemtype_t::TYPE_STRING;
}
str FAKKLoadGameItem::getListItemString(int which) const
{
str itemstring;
switch (which) {
case 0:
case 3:
itemstring = strings[which];
break;
case 1:
{
int numseconds;
int numseconds_hours;
// hours
numseconds = atol(strings[1]);
itemstring += (numseconds / 3600);
itemstring += ":";
// minutes
numseconds_hours = numseconds % 3600;
if (numseconds_hours / 60 <= 9) {
itemstring += "0";
}
itemstring += (numseconds_hours / 60);
itemstring += ":";
// seconds
if (numseconds_hours / 60 <= 9) {
itemstring += "0";
}
itemstring += (numseconds_hours % 60);
}
break;
case 2:
{
time_t time;
char buffer[2048];
time = atol(strings[2]);
strftime(buffer, sizeof(buffer), "%a %b %d %H:%M:%S %Y", localtime(&time));
itemstring = buffer;
}
break;
}
return itemstring;
}
void FAKKLoadGameItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
qboolean FAKKLoadGameItem::IsHeaderEntry() const
{
return qfalse;
}
+18 -15
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -22,23 +22,26 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#pragma once
class UIFAKKLoadGameClass : public UIListCtrl {
bool m_bRemovePending;
class UIFAKKLoadGameClass : public UIListCtrl
{
bool m_bRemovePending;
public:
CLASS_PROTOTYPE( UIFAKKLoadGameClass );
CLASS_PROTOTYPE(UIFAKKLoadGameClass);
protected:
void SelectGame( Event *ev );
void LoadGame( Event *ev );
void SaveGame( Event *ev );
void RemoveGame( Event *ev );
void DeleteGame( Event *ev );
void NoDeleteGame( Event *ev );
qboolean KeyEvent( int key, unsigned int time ) override;
void UpdateUIElement( void ) override;
public:
UIFAKKLoadGameClass();
void SelectGame(Event *ev);
void LoadGame(Event *ev);
void SaveGame(Event *ev);
void RemoveGame(Event *ev);
void DeleteGame(Event *ev);
void NoDeleteGame(Event *ev);
qboolean KeyEvent(int key, unsigned int time) override;
void UpdateUIElement(void) override;
void SetupFiles( void );
public:
UIFAKKLoadGameClass();
~UIFAKKLoadGameClass();
void SetupFiles(void);
};
+449
View File
@@ -0,0 +1,449 @@
/*
===========================================================================
Copyright (C) 2023 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_uimaprotationsetup.h"
Event EV_MapListBox_RefreshMapList
(
"RefreshMapList",
EV_DEFAULT,
NULL,
NULL,
"Refreshes the map list."
);
Event EV_MapRotationListBox_RefreshRotationList
(
"RefreshRotationList",
EV_DEFAULT,
NULL,
NULL,
"Refreshed the map rotation list."
);
CLASS_DECLARATION(UIListBox, UIMapRotationListBox, NULL) {
{&EV_MapRotationListBox_RefreshRotationList, &UIMapRotationListBox::RefreshRotationList},
{NULL, NULL }
};
UIMapRotationListBox::UIMapRotationListBox() {}
void UIMapRotationListBox::RefreshRotationList(Event *ev)
{
DeleteAllItems();
PopulateRotationList();
}
void UIMapRotationListBox::PopulateRotationList()
{
cvar_t *filter;
cvar_t *maplistVar;
const char *token;
char mapBuffer[1024];
filter = Cvar_Get("g_maprotation_filter", "ffa", 0);
if (!Q_stricmp(filter->string, "obj")) {
maplistVar = Cvar_Get("ui_maplist_obj", "", 0);
} else if (!Q_stricmp(filter->string, "tow")) {
maplistVar = Cvar_Get("ui_maplist_tow", "", 0);
} else if (!Q_stricmp(filter->string, "lib")) {
maplistVar = Cvar_Get("ui_maplist_lib", "", 0);
} else if (!Q_stricmp(filter->string, "team")) {
maplistVar = Cvar_Get("ui_maplist_team", "", 0);
} else if (!Q_stricmp(filter->string, "round")) {
maplistVar = Cvar_Get("ui_maplist_round", "", 0);
} else {
maplistVar = Cvar_Get("ui_maplist_ffa", "", 0);
}
strcpy(mapBuffer, maplistVar->string);
for (token = strtok(mapBuffer, " /"); token; token = strtok(NULL, " /")) {
if (!Q_stricmp(token, "dm")) {
continue;
}
if (!Q_stricmp(token, "obj")) {
continue;
}
if (!Q_stricmp(token, "lib")) {
continue;
}
AddItem(token, NULL);
}
}
CLASS_DECLARATION(UIListBox, UIMapListBox, NULL) {
{&EV_MapListBox_RefreshMapList, &UIMapListBox::RefreshMapList},
{NULL, NULL }
};
UIMapListBox::UIMapListBox() {}
void UIMapListBox::RefreshMapList(Event *ev)
{
DeleteAllItems();
PopulateMapList();
}
void UIMapListBox::PopulateMapList()
{
cvar_t *filter;
char **filenames;
int numfiles;
str path;
int i;
bool bTugOfWar = false;
bool bObjective = false;
bool bLiberation = false;
filter = Cvar_Get("g_maprotation_filter", "ffa", 0);
if (!Q_stricmp(filter->string, "lib")) {
path = "maps/lib/";
bLiberation = true;
} else if (!Q_stricmp(filter->string, "obj") || !Q_stricmp(filter->string, "tow")) {
path = "maps/obj/";
if (!Q_stricmp(filter->string, "tow")) {
bTugOfWar = true;
} else {
bObjective = true;
}
} else {
path = "maps/dm/";
}
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
const char *token;
char mapName[256];
char tokenized[256];
bool bHasMP = false;
bool bHasTOW = false;
bool bHasLib = false;
strcpy(mapName, filename);
mapName[strlen(mapName) - 4] = 0;
if (!COM_IsMapValid(mapName)) {
continue;
}
if (bTugOfWar || bLiberation) {
strcpy(tokenized, mapName);
for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) {
if (bLiberation) {
if (!Q_stricmp(token, "MP")) {
bHasMP = true;
}
if (!Q_stricmp(token, "LIB")) {
bHasLib = true;
}
if (bHasMP && bHasLib) {
AddItem(mapName, NULL);
break;
}
}
if (bTugOfWar) {
if (!Q_stricmp(token, "MP")) {
bHasMP = true;
}
if (!Q_stricmp(token, "TOW")) {
bHasTOW = true;
}
if (bHasMP && bHasTOW) {
AddItem(mapName, NULL);
break;
}
}
}
} else if (bObjective) {
strcpy(tokenized, mapName);
for (token = strtok(tokenized, "_"); token; token = strtok(NULL, "_")) {
if (!Q_stricmp(token, "obj")) {
AddItem(mapName, NULL);
break;
}
}
if (!Q_stricmp(mapName, "mp_ship_lib")) {
AddItem(mapName, NULL);
}
} else {
AddItem(mapName, NULL);
}
}
if (bObjective) {
path = "maps/lib/";
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
const char *token;
char mapName[256];
char tokenized[256];
strcpy(mapName, filename);
mapName[strlen(mapName) - 4] = 0;
strcpy(tokenized, mapName);
token = strtok(tokenized, "_");
if (!Q_stricmp(token, "obj") || !Q_stricmp(mapName, "mp_ship_lib")) {
AddItem(mapName, NULL);
break;
}
}
}
if (!bTugOfWar && !bObjective && !bLiberation) {
int type;
for (type = 0; type < 2; type++) {
if (type == 0) {
path = "maps/obj/";
} else {
path = "maps/lib/";
}
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
char mapName[256];
strcpy(mapName, filename);
mapName[strlen(mapName) - 4] = 0;
if (!COM_IsMapValid(mapName)) {
continue;
}
if (!Q_stricmp(mapName, "obj_team2") || !Q_stricmp(mapName, "obj_team4")) {
continue;
}
AddItem(mapName, NULL);
}
}
}
}
CLASS_DECLARATION(UIButton, UIAddToRotationButton, NULL) {
{&W_LeftMouseUp, &UIAddToRotationButton::Released},
{NULL, NULL }
};
void UIAddToRotationButton::Released(Event *ev)
{
UIListBox *mapList;
UIListBox *rotationList;
size_t prefixLength;
int i;
mapList = static_cast<UIListBox *>(uWinMan.FindWidget("Map List"));
rotationList = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
if (Cvar_Get("g_maprotation_filter", "ffa", 0)) {
prefixLength = strlen("obj/") + 1;
} else {
prefixLength = 1;
}
if (mapList && rotationList) {
size_t mapLength = 0;
int item = mapList->getCurrentItem();
for (i = 1; i <= rotationList->getNumItems(); i++) {
str text = rotationList->getItemText(i);
mapLength += text.length();
}
if (item) {
str text = mapList->getItemText(item);
if (prefixLength + mapLength + text.length() < 256) {
rotationList->AddItem(text, NULL);
}
}
}
UIButtonBase::Released(ev);
}
CLASS_DECLARATION(UIButton, UIRemoveFromRotationButton, NULL) {
{&W_LeftMouseUp, &UIRemoveFromRotationButton::Released},
{NULL, NULL }
};
void UIRemoveFromRotationButton::Released(Event *ev)
{
UIListBox *list;
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
if (list) {
list->DeleteItem(list->getCurrentItem());
}
UIButtonBase::Released(ev);
}
CLASS_DECLARATION(UIButton, UIRotationApplyButton, NULL) {
{&W_LeftMouseUp, &UIRotationApplyButton::Released},
{NULL, NULL }
};
void UIRotationApplyButton::Released(Event *ev)
{
UIListBox *list;
cvar_t *filter;
str cvarName;
str maplistStr;
int i;
bool bObjective = false;
bool bLiberation = false;
filter = Cvar_Get("g_maprotation_filter", "ffa", 0);
if (!Q_stricmp(filter->string, "obj")) {
cvarName = "ui_maplist_obj";
bObjective = true;
} else if (!Q_stricmp(filter->string, "tow")) {
cvarName = "ui_maplist_obj";
bObjective = true;
} else if (!Q_stricmp(filter->string, "lib")) {
cvarName = "ui_maplist_lib";
bLiberation = true;
} else if (!Q_stricmp(filter->string, "team")) {
cvarName = "ui_maplist_team";
} else if (!Q_stricmp(filter->string, "round")) {
cvarName = "ui_maplist_round";
} else {
cvarName = "ui_maplist_ffa";
}
Cvar_Set(cvarName, "");
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
if (list) {
for (i = 1; i <= list->getNumItems(); i++) {
const char *token;
str text = list->getItemText(i);
char map[256];
bool bHasTOW = false, bHasObj = false, bHasLib = false, bHasShip = false;
strcpy(map, text);
for (token = strtok(map, "_"); token; token = strtok(NULL, "_")) {
if (!Q_stricmp(token, "TOW")) {
bHasTOW = true;
break;
}
if (!Q_stricmp(token, "obj")) {
bHasObj = true;
break;
}
if (!Q_stricmp(token, "lib")) {
bHasLib = true;
break;
}
if (!Q_stricmp(token, "ship")) {
bHasShip = true;
break;
}
}
if (bHasShip) {
maplistStr += "lib/";
} else if (bObjective || bHasTOW || bHasObj) {
maplistStr += "obj/";
} else if (bHasLib || bLiberation) {
maplistStr += "lib/";
} else {
maplistStr += "dm/";
}
maplistStr += text;
maplistStr += " ";
if (i == 1) {
Cvar_Set("ui_dmmap", maplistStr);
}
}
}
Cvar_Set(cvarName, maplistStr);
UIButtonBase::Released(ev);
}
CLASS_DECLARATION(UIButton, UIRotationMoveItemUpButton, NULL) {
{&W_LeftMouseUp, &UIRotationMoveItemUpButton::Released},
{NULL, NULL }
};
void UIRotationMoveItemUpButton::Released(Event *ev)
{
UIListBox *list;
int item;
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
item = list->getCurrentItem();
if (item < list->getNumItems() && list->getNumItems() > 1) {
str text = list->getItemText(item + 1);
list->DeleteItem(list->getCurrentItem() - 1);
list->InsertItem(text, item);
list->setCurrentItem(item - 1);
}
UIButtonBase::Released(ev);
}
CLASS_DECLARATION(UIButton, UIRotationMoveItemDownButton, NULL) {
{&W_LeftMouseUp, &UIRotationMoveItemDownButton::Released},
{NULL, NULL }
};
void UIRotationMoveItemDownButton::Released(Event *ev)
{
UIListBox *list;
int item;
list = static_cast<UIListBox *>(uWinMan.FindWidget("Rotation List"));
item = list->getCurrentItem();
if (item < list->getNumItems() && list->getNumItems() > 1) {
str text = list->getItemText(item + 1);
list->DeleteItem(list->getCurrentItem() + 1);
list->InsertItem(text, item);
list->setCurrentItem(item + 1);
}
UIButtonBase::Released(ev);
}
+87
View File
@@ -0,0 +1,87 @@
/*
===========================================================================
Copyright (C) 2023 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
===========================================================================
*/
#pragma once
#include "../uilib/uilistbox.h"
class UIMapRotationListBox : public UIListBox
{
CLASS_PROTOTYPE(UIMapRotationListBox);
public:
UIMapRotationListBox();
void RefreshRotationList(Event *ev);
void PopulateRotationList();
};
class UIMapListBox : public UIListBox
{
CLASS_PROTOTYPE(UIMapListBox);
public:
UIMapListBox();
void RefreshMapList(Event *ev);
void PopulateMapList();
};
class UIAddToRotationButton : public UIButton
{
CLASS_PROTOTYPE(UIAddToRotationButton);
public:
void Released(Event *ev);
};
class UIRemoveFromRotationButton : public UIButton
{
CLASS_PROTOTYPE(UIRemoveFromRotationButton);
public:
void Released(Event *ev);
};
class UIRotationApplyButton : public UIButton
{
CLASS_PROTOTYPE(UIRotationApplyButton);
public:
void Released(Event *ev);
};
class UIRotationMoveItemUpButton : public UIButton
{
CLASS_PROTOTYPE(UIRotationMoveItemUpButton);
public:
void Released(Event *ev);
};
class UIRotationMoveItemDownButton : public UIButton
{
CLASS_PROTOTYPE(UIRotationMoveItemDownButton);
public:
void Released(Event *ev);
};
+84 -24
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023-2024 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -22,47 +22,107 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_ui.h"
CLASS_DECLARATION( FilePickerClass, MapRunnerClass, NULL )
{
{ NULL, NULL }
CLASS_DECLARATION(FilePickerClass, MapRunnerClass, NULL) {
{NULL, NULL}
};
void MapRunnerClass::FileChosen( str &currentDirectory, str &partialName, str &fullname )
void MapRunnerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
{
// FIXME: stub
str newName;
newName = "spmap " + str(fullname, 5, fullname.length() - 4) + "\n";
// insert the command
Cbuf_AddText(newName);
CloseWindow();
}
CLASS_DECLARATION( FilePickerClass, ViewSpawnerClass, NULL )
{
{ NULL, NULL }
CLASS_DECLARATION(FilePickerClass, UIPickFileClass, NULL) {
{NULL, NULL}
};
void ViewSpawnerClass::FileChosen( str &currentDirectory, str &partialName, str &fullname )
UIPickFileClass::UIPickFileClass()
{
// FIXME: stub
retobj = NULL;
retevent = NULL;
}
CLASS_DECLARATION( FilePickerClass, LODSpawnerClass, NULL )
UIPickFileClass::~UIPickFileClass()
{
{ NULL, NULL }
if (retevent) {
delete retevent;
}
}
void UIPickFileClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
{
if (!retobj || !retevent) {
CloseWindow();
return;
}
retevent->AddString(fullname);
retobj->ProcessEvent(retevent);
retevent = NULL;
retobj = NULL;
CloseWindow();
}
void PickFile(const char *name, Listener *obj, Event& event)
{
UIPickFileClass *picker;
str currentpath;
int i;
picker = new UIPickFileClass();
picker->retevent = new Event(event);
picker->retobj = obj;
if (name && *name && strchr(name, '/')) {
currentpath = name;
for (i = currentpath.length(); i > 0; i--) {
if (currentpath[i] == '/') {
break;
}
}
currentpath = str(currentpath, 0, i + 1);
} else {
currentpath = "";
}
picker->Setup("", currentpath, ".*", "");
}
CLASS_DECLARATION(FilePickerClass, ViewSpawnerClass, NULL) {
{NULL, NULL}
};
void LODSpawnerClass::FileChosen( str &currentDirectory, str &partialName, str &fullname )
void ViewSpawnerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
{
// FIXME: stub
str newName;
newName = "viewspawn " + fullname + "\n";
// insert the command
Cbuf_AddText(newName);
CloseWindow();
}
CLASS_DECLARATION( FilePickerClass, UIPickFileClass, NULL )
{
{ NULL, NULL }
CLASS_DECLARATION(FilePickerClass, LODSpawnerClass, NULL) {
{NULL, NULL}
};
void UIPickFileClass::FileChosen( str &currentDirectory, str &partialName, str &fullname )
void LODSpawnerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
{
// FIXME: stub
}
str newName;
void PickFile( const char *name, Listener *obj, Event& event )
{
// FIXME: stub
newName = "lod_spawn " + fullname + "\n";
// insert the command
Cbuf_AddText(newName);
CloseWindow();
}
+24 -20
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,40 +20,44 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIMAPRUNNER_H__
#define __CL_UIMAPRUNNER_H__
#pragma once
class MapRunnerClass : public FilePickerClass {
class MapRunnerClass : public FilePickerClass
{
public:
CLASS_PROTOTYPE( MapRunnerClass );
CLASS_PROTOTYPE(MapRunnerClass);
void FileChosen( str &currentDirectory, str &partialName, str &fullname ) override;
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
};
class ViewSpawnerClass : public FilePickerClass {
class ViewSpawnerClass : public FilePickerClass
{
public:
CLASS_PROTOTYPE( ViewSpawnerClass );
CLASS_PROTOTYPE(ViewSpawnerClass);
void FileChosen( str &currentDirectory, str &partialName, str &fullname ) override;
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
};
class LODSpawnerClass : public FilePickerClass {
class LODSpawnerClass : public FilePickerClass
{
public:
CLASS_PROTOTYPE( LODSpawnerClass );
CLASS_PROTOTYPE(LODSpawnerClass);
void FileChosen( str &currentDirectory, str &partialName, str &fullname ) override;
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
};
class UIPickFileClass : public FilePickerClass {
class UIPickFileClass : public FilePickerClass
{
public:
Listener *retobj;
Event *retevent;
Listener *retobj;
Event *retevent;
CLASS_PROTOTYPE( UIPickFileClass );
CLASS_PROTOTYPE(UIPickFileClass);
void FileChosen( str &currentDirectory, str &partialName, str &fullname ) override;
UIPickFileClass();
~UIPickFileClass();
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
};
void PickFile( const char *name, Listener *obj, Event& event );
#endif /* __CL_UIMAPRUNNER_H__ */
void PickFile(const char *name, Listener *obj, Event& event);
+138 -27
View File
@@ -22,68 +22,179 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_ui.h"
CLASS_DECLARATION( UIWidget, FakkMiniconsole, NULL )
{
{ NULL, NULL }
Event EV_Minicon_Goin("_minicon_goin", EV_DEFAULT, NULL, NULL, "Event to make the miniconsole disappear");
CLASS_DECLARATION(UIWidget, FakkMiniconsole, NULL) {
{&W_SizeChanged, &FakkMiniconsole::OnSizeChanged},
{&EV_Minicon_Goin, &FakkMiniconsole::MoveInEvent },
{NULL, NULL }
};
FakkMiniconsole::FakkMiniconsole()
{
// FIXME: stub
m_maxlines = 0;
m_reallyshown = true;
m_boxstate = boxstate_t::box_in;
m_boxtime = uid.time;
m_movespeed = 500;
}
void FakkMiniconsole::VerifyBoxOut( void )
void FakkMiniconsole::setShowState(void)
{
// FIXME: stub
if (m_reallyshown) {
setShow(m_boxstate != boxstate_t::box_in);
} else {
setShow(false);
}
}
void FakkMiniconsole::ChangeBoxState( boxstate_t state )
void FakkMiniconsole::setRealShow(bool b)
{
// FIXME: stub
m_reallyshown = b;
setShowState();
}
void FakkMiniconsole::HandleBoxMoving( void )
void FakkMiniconsole::VerifyBoxOut(void)
{
// FIXME: stub
PostMoveinEvent();
if (m_boxstate && m_boxstate != boxstate_t::box_out) {
ChangeBoxState(box_moving_out);
}
}
void FakkMiniconsole::PostMoveinEvent( void )
void FakkMiniconsole::Print(const char *text)
{
// FIXME: stub
str *lastline;
const char *p;
if (!m_lines.NumObjects()) {
m_lines.AddObject({});
}
lastline = &m_lines.ObjectAt(m_lines.NumObjects());
if (*text) {
for (p = text; *p; p++) {
if (*p != '\n') {
*lastline += *p;
} else {
m_lines.AddObject({});
lastline = &m_lines.ObjectAt(m_lines.NumObjects());
}
}
}
if (lastline && lastline->length() > 128) {
Print("\n");
}
if (m_maxlines < 0) {
m_maxlines = 1;
}
while (m_lines.NumObjects() > this->m_maxlines) {
m_lines.RemoveObjectAt(1);
}
VerifyBoxOut();
}
void FakkMiniconsole::setShowState( void )
void FakkMiniconsole::PostMoveinEvent(void)
{
// FIXME: stub
if (m_boxstate != boxstate_t::box_out) {
return;
}
CancelEventsOfType(EV_Minicon_Goin);
PostEvent(new Event(EV_Minicon_Goin), 5.f);
}
void FakkMiniconsole::OnSizeChanged( Event *ev )
void FakkMiniconsole::OnSizeChanged(Event *ev)
{
// FIXME: stub
m_maxlines = m_frame.size.height / m_font->getHeight(false);
}
void FakkMiniconsole::Print( const char *text )
void FakkMiniconsole::MoveInEvent(Event *ev)
{
// FIXME: stub
ChangeBoxState(boxstate_t::box_moving_in);
}
void FakkMiniconsole::Create( const UISize2D& size, const UColor& fore, const UColor& back, float alpha )
void FakkMiniconsole::HandleBoxMoving(void)
{
// FIXME: stub
int delta;
UIRect2D newRect;
if (m_boxstate == boxstate_t::box_out || m_boxstate == boxstate_t::box_in) {
return;
}
delta = m_movespeed * (uid.time - m_boxtime) / 1000;
m_boxtime = 1000 * delta / m_movespeed + m_boxtime;
switch (m_boxstate) {
case boxstate_t::box_moving_in:
newRect = UIRect2D(delta + m_frame.pos.x, m_frame.pos.y, m_frame.size.width, m_frame.size.height);
if (newRect.pos.x >= uid.vidWidth) {
newRect.pos.x = uid.vidWidth;
ChangeBoxState(boxstate_t::box_in);
}
break;
case boxstate_t::box_moving_out:
newRect = UIRect2D(-delta + m_frame.pos.x, m_frame.pos.y, m_frame.size.width, m_frame.size.height);
if (newRect.pos.x <= uid.vidWidth - newRect.size.width) {
newRect.pos.x = uid.vidWidth - newRect.size.width;
ChangeBoxState(boxstate_t::box_out);
}
break;
default:
ChangeBoxState(boxstate_t::box_in);
break;
}
setFrame(newRect);
}
void FakkMiniconsole::MoveInEvent( Event *ev )
void FakkMiniconsole::Draw(void)
{
// FIXME: stub
float aty;
int i;
HandleBoxMoving();
m_font->setColor(m_foreground_color);
aty = m_frame.size.height - m_font->getHeight(false);
for (i = m_lines.NumObjects(); i > 0; i--) {
if (-m_font->getHeight(false) >= aty) {
break;
}
m_font->Print(0, aty, m_lines.ObjectAt(i), -1, false);
aty -= m_font->getHeight(false);
}
}
void FakkMiniconsole::Draw( void )
void FakkMiniconsole::Create(const UISize2D& size, const UColor& fore, const UColor& back, float alpha)
{
// FIXME: stub
InitFrame(NULL, uid.vidWidth, 0, size.width, size.height, 0);
setBackgroundColor(back, true);
setForegroundColor(fore);
setBackgroundAlpha(alpha);
Connect(this, W_SizeChanged, W_SizeChanged);
OnSizeChanged(NULL);
m_movespeed = size.width * 3;
setShowState();
}
void FakkMiniconsole::setRealShow( bool b )
void FakkMiniconsole::ChangeBoxState(boxstate_t state)
{
// FIXME: stub
m_boxstate = state;
m_boxtime = uid.time;
setShowState();
if (state == boxstate_t::box_out) {
PostMoveinEvent();
}
}
+23 -25
View File
@@ -20,38 +20,36 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIMINICON_H__
#define __CL_UIMINICON_H__
#pragma once
class FakkMiniconsole : public UIWidget {
class FakkMiniconsole : public UIWidget
{
protected:
Container<str> m_lines;
int m_maxlines;
bool m_reallyshown;
bool m_boxmovingout;
boxstate_t m_boxstate;
int m_boxtime;
int m_movespeed;
Container<str> m_lines;
int m_maxlines;
bool m_reallyshown;
bool m_boxmovingout;
boxstate_t m_boxstate;
int m_boxtime;
int m_movespeed;
public:
CLASS_PROTOTYPE( FakkMiniconsole );
CLASS_PROTOTYPE(FakkMiniconsole);
protected:
void VerifyBoxOut( void );
void ChangeBoxState( boxstate_t state );
void HandleBoxMoving( void );
void PostMoveinEvent( void );
void setShowState( void );
void VerifyBoxOut(void);
void ChangeBoxState(boxstate_t state);
void HandleBoxMoving(void);
void PostMoveinEvent(void);
void setShowState(void);
public:
FakkMiniconsole();
FakkMiniconsole();
void OnSizeChanged( Event *ev );
void Print( const char *text );
void Create( const UISize2D& size, const UColor& fore, const UColor& back, float alpha );
void MoveInEvent( Event *ev );
void Draw( void ) override;
void setRealShow( bool b );
void OnSizeChanged(Event *ev);
void Print(const char *text);
void Create(const UISize2D& size, const UColor& fore, const UColor& back, float alpha);
void MoveInEvent(Event *ev);
void Draw(void) override;
void setRealShow(bool b);
};
#endif
+293 -27
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -21,73 +21,339 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "cl_ui.h"
#include "../qcommon/localization.h"
CLASS_DECLARATION( USignal, MpMapPickerClass, NULL )
class MpMapPickerItem : public UIListCtrlItem
{
{ NULL, NULL }
str m_string;
// Added in 2.0
str m_directory;
public:
MpMapPickerItem(const str& string, const str& directory);
int getListItemValue(int which) const override;
griditemtype_t getListItemType(int which) const override;
str getListItemString(int which) const override;
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
qboolean IsHeaderEntry() const override;
};
CLASS_DECLARATION(USignal, MpMapPickerClass, NULL) {
{&EV_UIListBase_ItemSelected, &MpMapPickerClass::FileSelected },
{&EV_UIListBase_ItemDoubleClicked, &MpMapPickerClass::FileChosen },
{&W_Deactivated, &MpMapPickerClass::OnDeactivated},
{NULL, NULL }
};
MpMapPickerClass::MpMapPickerClass()
{
// FIXME: stub
window = new UIFloatingWindow();
window->Create(
NULL,
UIRect2D((cls.glconfig.vidWidth - 300) / 2, (cls.glconfig.vidHeight - 200) / 2, 300, 200),
"Select a Map",
UColor(0.15f, 0.195f, 0.278f),
UHudColor
);
window->setFont("facfont-20");
window->PassEventToWidget("closebutton", new Event(EV_Widget_Disable));
window->PassEventToWidget("minimizebutton", new Event(EV_Widget_Disable));
window->Connect(this, W_Deactivated, W_Deactivated);
listbox = new UIListCtrl();
listbox->InitFrame(window->getChildSpace(), window->getChildSpace()->getClientFrame(), 0);
listbox->SetDrawHeader(false);
listbox->setFont("facfont-20");
listbox->FrameInitialized();
listbox->AddColumn(Sys_LV_CL_ConvertString("Select a Map"), 0, 400, false, false);
listbox->Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
listbox->Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
listbox->AllowActivate(true);
// Added in 2.0
// Don't localize elements
listbox->SetDontLocalize();
}
MpMapPickerClass::~MpMapPickerClass()
{
// FIXME: stub
if (listbox) {
delete listbox;
listbox = NULL;
}
if (window) {
delete window;
window = NULL;
}
}
void MpMapPickerClass::SetupFiles( void )
void MpMapPickerClass::Setup(const char *root_directory, const char *current_directory, const char *game_type)
{
// FIXME: stub
Initialize(root_directory, current_directory, game_type);
}
void MpMapPickerClass::GotoParentDirectory( void )
void MpMapPickerClass::Initialize(const char *root_directory, const char *current_directory, const char *game_type)
{
// FIXME: stub
rootDirectory = root_directory;
if (rootDirectory.length() > 1 && rootDirectory[rootDirectory.length() - 1] != '/') {
rootDirectory += "/";
}
currentDirectory = current_directory;
if (currentDirectory.length() > 1 && currentDirectory[currentDirectory.length() - 1] != '/') {
currentDirectory += "/";
}
if (game_type) {
gameType = game_type;
}
SetupFiles();
}
void MpMapPickerClass::GotoSubDirectory( str subdir )
void MpMapPickerClass::GotoParentDirectory(void)
{
// FIXME: stub
uintptr_t i;
if (currentDirectory == rootDirectory) {
return;
}
for (i = currentDirectory.length() - 2; i > 0; i--) {
if (currentDirectory[i] == '/') {
break;
}
}
if (currentDirectory[i] == '/') {
i++;
}
currentDirectory = str(currentDirectory, 0, i);
// refresh files
SetupFiles();
}
void MpMapPickerClass::Initialize( const char *root_directory, const char *current_directory )
void MpMapPickerClass::GotoSubDirectory(str subdir)
{
// FIXME: stub
currentDirectory += subdir + "/";
// refresh files
SetupFiles();
}
void MpMapPickerClass::CloseWindow( void )
void MpMapPickerClass::SetupFiles(void)
{
// FIXME: stub
char **filenames;
int numfiles;
int i;
char mapname[128];
bool bTugOfWar = false, bObjective = false, bLiberation = false;
listbox->DeleteAllItems();
if (gameType == "tow") {
bTugOfWar = true;
} else if (gameType == "obj") {
bObjective = true;
} else if (gameType == "lib") {
bLiberation = true;
} else {
// retrieve directories
filenames = FS_ListFiles(rootDirectory, ".bsp", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
strcpy(mapname, filename);
mapname[strlen(mapname) - 4] = 0;
if (COM_IsMapValid(mapname)) {
listbox->AddItem(new MpMapPickerItem(mapname, rootDirectory));
}
}
FS_FreeFileList(filenames);
}
if (com_target_game->integer > target_game_e::TG_MOH) {
if (currentDirectory.length()) {
if (currentDirectory == "maps/-/") {
SetupSecondaryFiles(currentDirectory, bTugOfWar, bObjective, bLiberation);
} else {
SetupSecondaryFiles("maps/obj/", bTugOfWar, bObjective, bLiberation);
SetupSecondaryFiles("maps/lib/", bTugOfWar, bObjective, bLiberation);
}
}
}
listbox->SortByColumn(0);
}
void MpMapPickerClass::FileSelected( Event *ev )
void MpMapPickerClass::SetupSecondaryFiles(const char *path, bool bTugOfWar, bool bObjective, bool bLiberation)
{
// FIXME: stub
char **filenames;
int numfiles;
int i;
char mapname[128];
char string[1024];
filenames = FS_ListFiles(path, ".bsp", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
const char *filename = filenames[i];
const char *token;
strcpy(mapname, filename);
mapname[strlen(mapname) - 4] = 0;
if (!COM_IsMapValid(mapname)) {
continue;
}
if (bTugOfWar || bObjective || bLiberation) {
bool bHasMP = false, bHasTOW = false, bHasLib = false;
strcpy(string, mapname);
for (token = strtok(string, "_"); token; token = strtok(NULL, "_")) {
if (bObjective) {
if (!Q_stricmp(token, "obj")) {
listbox->AddItem(new MpMapPickerItem(mapname, path));
} else if (!Q_stricmp(token, "ship")) {
listbox->AddItem(new MpMapPickerItem(mapname, path));
}
}
if (bTugOfWar) {
if (!Q_stricmp(token, "MP")) {
bHasMP = true;
}
if (!Q_stricmp(token, "TOW")) {
bHasTOW = true;
}
if (bHasMP && bHasTOW) {
listbox->AddItem(new MpMapPickerItem(mapname, path));
}
}
if (bLiberation) {
if (!Q_stricmp(token, "MP")) {
bHasMP = true;
}
if (!Q_stricmp(token, "LIB")) {
bHasLib = true;
}
if (bHasMP && bHasLib) {
listbox->AddItem(new MpMapPickerItem(mapname, path));
}
}
}
} else {
if (!Q_stricmp(mapname, "obj_team2") || !Q_stricmp(mapname, "obj_team4")) {
continue;
}
listbox->AddItem(new MpMapPickerItem(mapname, path));
}
}
FS_FreeFileList(filenames);
}
void MpMapPickerClass::FileSelected( str& currentDirectory, str& partialName, str& fullname )
void MpMapPickerClass::FileSelected(const str& currentDirectory, const str& partialName, const str& fullname)
{
// FIXME: stub
FileChosen(currentDirectory, partialName, fullname);
}
void MpMapPickerClass::FileChosen( Event *ev )
void MpMapPickerClass::FileSelected(Event *ev)
{
// FIXME: stub
if (!listbox->getCurrentItem()) {
return;
}
uii.Snd_PlaySound("sound/menu/apply.wav");
UIListCtrlItem *item = listbox->GetItem(listbox->getCurrentItem());
str name = item->getListItemString(0);
str directory = item->getListItemString(1);
FileSelected(directory, name, directory + name);
}
void MpMapPickerClass::FileChosen( str& currentDirectory, str& partialName, str& fullname )
void MpMapPickerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
{
// FIXME: stub
const char *pszFilename;
str sCommand;
pszFilename = fullname.c_str();
sCommand = va("ui_dmmap %s\n", pszFilename + 5);
Cbuf_AddText(sCommand);
CloseWindow();
}
void MpMapPickerClass::OnDeactivated( Event *ev )
void MpMapPickerClass::FileChosen(Event *ev)
{
// FIXME: stub
if (!listbox->getCurrentItem()) {
return;
}
uii.Snd_PlaySound("sound/menu/apply.wav");
UIListCtrlItem *item = listbox->GetItem(listbox->getCurrentItem());
str name = item->getListItemString(0);
str directory = item->getListItemString(1);
FileSelected(directory, name, directory + name);
}
void MpMapPickerClass::Setup( const char *root_directory, const char *current_directory )
void MpMapPickerClass::CloseWindow(void)
{
// FIXME: stub
PostEvent(EV_Remove, 0);
}
void MpMapPickerClass::OnDeactivated(Event *ev)
{
CloseWindow();
}
MpMapPickerItem::MpMapPickerItem(const str& string, const str& directory)
{
m_string = string;
m_directory = directory;
}
int MpMapPickerItem::getListItemValue(int which) const
{
return atoi(m_string);
}
griditemtype_t MpMapPickerItem::getListItemType(int which) const
{
return griditemtype_t::TYPE_STRING;
}
str MpMapPickerItem::getListItemString(int which) const
{
switch (which) {
default:
case 0:
return m_string;
case 1:
return m_directory;
}
}
void MpMapPickerItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
qboolean MpMapPickerItem::IsHeaderEntry() const
{
return qfalse;
}
+25 -24
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,39 +20,40 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIMPMAPPICKER_H__
#define __CL_UIMPMAPPICKER_H__
#pragma once
class UIFloatingWindow;
class MpMapPickerClass : public USignal {
UIFloatingWindow *window;
UIListCtrl *listbox;
str currentDirectory;
str rootDirectory;
class MpMapPickerClass : public USignal
{
UIFloatingWindow *window;
UIListCtrl *listbox;
str currentDirectory;
str rootDirectory;
str gameType;
public:
CLASS_PROTOTYPE( MpMapPickerClass );
CLASS_PROTOTYPE(MpMapPickerClass);
private:
void SetupFiles( void );
void GotoParentDirectory( void );
void GotoSubDirectory( str subdir );
void Initialize( const char *root_directory, const char *current_directory );
void SetupFiles(void);
void SetupSecondaryFiles(const char *path, bool bTugOfWar, bool bObjective, bool bLiberation);
void GotoParentDirectory(void);
void GotoSubDirectory(str subdir);
void Initialize(const char *root_directory, const char *current_directory, const char *game_type);
protected:
void CloseWindow( void );
void FileSelected( Event *ev );
virtual void FileSelected( str& currentDirectory, str& partialName, str& fullname );
void FileChosen( Event *ev );
virtual void FileChosen( str& currentDirectory, str& partialName, str& fullname );
void OnDeactivated( Event *ev );
void CloseWindow(void);
void FileSelected(Event *ev);
virtual void FileSelected(const str& currentDirectory, const str& partialName, const str& fullname);
void FileChosen(Event *ev);
virtual void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname);
void OnDeactivated(Event *ev);
public:
MpMapPickerClass();
~MpMapPickerClass();
MpMapPickerClass();
~MpMapPickerClass();
void Setup( const char *root_directory, const char *current_directory );
// game_type was added in 2.0
void Setup(const char *root_directory, const char *current_directory, const char *game_type = NULL);
};
#endif /* __CL_UIMPMAPPICKER_H__ */
+322 -23
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -22,62 +22,361 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_ui.h"
CLASS_DECLARATION( USignal, PlayerModelPickerClass, NULL )
class PMPickerItem : public UIListCtrlItem
{
{ NULL, NULL }
str m_string;
public:
PMPickerItem(const str& string);
int getListItemValue(int which) const override;
griditemtype_t getListItemType(int which) const override;
str getListItemString(int which) const override;
void DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) override;
qboolean IsHeaderEntry() const override;
};
typedef struct {
const char *fileName;
const char *displayName;
} PMPickerModel_t;
static const PMPickerModel_t pickerModels[] = {
// 2.0 skins
{"allied_101st_captain", "US - 101st Airborne Captain" },
{"allied_101st_infantry", "US - 101st Airborne Private 1" },
{"allied_101st_scout", "US - 101st Airborne Private 2" },
{"allied_501st_pir_scout", "US - 501st Paratrooper 1" },
{"allied_501st_pir_soldier", "US - 501st Paratrooper 2" },
// 1.0 skins
{"allied_airborne", "US - 501st Paratrooper 3" },
// Readded in OPM (was removed in 2.0)
{"allied_manon", "US - Manon" },
// 2.0 skins
{"allied_british_6th_airborne_captain", "UK - 6th Airborne Captain" },
{"allied_british_6th_airborne_paratrooper", "UK - 6th Airborne Paratrooper" },
// 1.0 skins
{"allied_pilot", "US - Army Pilot" },
// 2.0 skins
{"allied_russian_corporal", "RA - Corporal" },
{"allied_russian_crazy_boris", "RA - Crazy Boris" },
{"allied_russian_recon_scout", "RA - Junior Lieutenant" },
{"allied_russian_recon_soldier", "RA - Black Sea Petty Officer" },
// 1.0 skins
{"allied_sas", "UK - SAS Officer" },
{"american_army", "US - Soldier" },
{"american_ranger", "US - Ranger" },
// 1.0 skins
{"german_afrika_officer", "DE - Afrika Officer" },
{"german_afrika_private", "DE - Afrika Private" },
// 2.0 skins
{"german_ardennes_artillery_commander", "DE - Artillery Commander" },
{"german_dday_colonel", "DE - Normandy Colonel" },
// 1.0 skins
{"german_elite_officer", "DE - Elite Officer" },
{"german_elite_sentry", "DE - Elite Sentry" },
{"german_kradshutzen", "DE - Kradshutzen" },
{"german_panzer_grenadier", "DE - Panzer Grenadier" },
{"german_panzer_obershutze", "DE - Panzer Obershutze" },
{"german_panzer_shutze", "DE - Panzer Shutze" },
{"german_panzer_tankcommander", "DE - Panzer Tank Commander" },
{"german_scientist", "DE - German Scientist" },
// Those skins were superseded by german_waffenss
{"german_waffen_officer", "DE - Waffen Officer" },
{"german_waffen_shutze", "DE - Waffen Shutze" },
// 1.0 skins
{"german_waffenss_officer", "DE - Waffen Officer" },
{"german_waffenss_shutze", "DE - Waffen Shutze" },
{"german_wehrmacht_officer", "DE - Wehrmacht Officer" },
{"german_wehrmacht_soldier", "DE - Wehrmacht Soldier" },
{"german_winter_1", "DE - Winter Infantry 1" },
{"german_winter_2", "DE - Winter Infantry 2" },
{"german_worker", "DE - German Mechanic" },
// 2.11 skins
{"allied_british_tank_corporal", "UK - 6th Royal Tank Regiment" },
{"allied_russian_seaman", "RA - Red Navy Seaman" },
{"german_Panzer_Corporal", "DE - 1st Panzer Regiment" },
{"allied_technician", "US - Air Force Technician" },
{"german_stukageschwader", "DE - Stukageschwader" },
// 2.30 skins
{"It_AX_Ital_Vol", "IT - 10th Army XXI Corps" },
{"SC_AX_Ital_Inf", "IT - 6th Army 202nd Coastal Div"},
{"SC_AX_Ital_Inf2", "IT - 114th Inf Regiment" },
{"SC_AX_ITAL_PARA", "IT - Paracadutista Militare" },
// 2.40 skins
{"allied_Wheathers", "US - General Wheathers" },
{"allied_US_Tank", "US - II Corps Tank Commander" },
{"allied_US_Mask", "US - II Corps Infantry" },
{"allied_british_Cmd", "UK - 10th Corps" },
{"allied_british_Tank", "UK - 8th Army" },
{NULL, NULL }
};
const char *PM_FilenameToDisplayname(const char *fileName)
{
int i;
for (i = 0; pickerModels[i].fileName; i++) {
const PMPickerModel_t& model = pickerModels[i];
if (!Q_stricmp(model.fileName, fileName)) {
return model.displayName;
}
}
return fileName;
}
const char *PM_DisplaynameToFilename(const char *displayName)
{
int i;
for (i = 0; pickerModels[i].fileName; i++) {
const PMPickerModel_t& model = pickerModels[i];
if (!Q_stricmp(model.displayName, displayName)) {
return model.fileName;
}
}
return displayName;
}
CLASS_DECLARATION(USignal, PlayerModelPickerClass, NULL) {
{&EV_UIListBase_ItemSelected, &PlayerModelPickerClass::FileSelected },
{&EV_UIListBase_ItemDoubleClicked, &PlayerModelPickerClass::FileChosen },
{&UIFloatingWindow::W_ClosePressed, &PlayerModelPickerClass::OnDeactivated},
{&W_Deactivated, &PlayerModelPickerClass::OnDeactivated},
{NULL, NULL }
};
PlayerModelPickerClass::PlayerModelPickerClass()
{
// FIXME: stub
window = new UIFloatingWindow();
window->Create(
NULL,
UIRect2D((cls.glconfig.vidWidth - 400) / 2, (cls.glconfig.vidHeight - 300) / 2, 400, 300),
"Player Model Select...",
UColor(0.15f, 0.195f, 0.278f),
UHudColor
);
window->setFont("facfont-20");
window->PassEventToWidget("closebutton", new Event(EV_Widget_Disable));
window->PassEventToWidget("minimizebutton", new Event(EV_Widget_Disable));
window->Connect(this, W_Deactivated, W_Deactivated);
listbox = new UIListCtrl();
listbox->InitFrame(window->getChildSpace(), window->getChildSpace()->getClientFrame(), 0);
listbox->SetDrawHeader(false);
listbox->setFont("facfont-20");
listbox->FrameInitialized();
listbox->AddColumn("Player Model", 0, 400, false, false);
listbox->Connect(this, EV_UIListBase_ItemDoubleClicked, EV_UIListBase_ItemDoubleClicked);
listbox->Connect(this, EV_UIListBase_ItemSelected, EV_UIListBase_ItemSelected);
listbox->AllowActivate(true);
// Added in 2.0
// Don't localize elements
listbox->SetDontLocalize();
m_bGermanModels = false;
}
PlayerModelPickerClass::~PlayerModelPickerClass()
{
// FIXME: stub
if (listbox) {
delete listbox;
listbox = NULL;
}
if (window) {
delete window;
window = NULL;
}
}
void PlayerModelPickerClass::SetupFiles( void )
void PlayerModelPickerClass::Setup(const char *root_directory, const char *current_directory, qboolean bGermanModels)
{
// FIXME: stub
Initialize(root_directory, current_directory, bGermanModels);
}
void PlayerModelPickerClass::Initialize( const char *root_directory, const char *current_directory, qboolean bGermanModels )
void PlayerModelPickerClass::Initialize(
const char *root_directory, const char *current_directory, qboolean bGermanModels
)
{
// FIXME: stub
rootDirectory = root_directory;
m_bGermanModels = bGermanModels;
if (rootDirectory.length() > 1 && rootDirectory[rootDirectory.length() - 1] != '/') {
rootDirectory += "/";
}
currentDirectory = current_directory;
if (currentDirectory.length() > 1 && currentDirectory[currentDirectory.length() - 1] != '/') {
currentDirectory += "/";
}
SetupFiles();
}
void PlayerModelPickerClass::CloseWindow( void )
void PlayerModelPickerClass::SetupFiles(void)
{
// FIXME: stub
str mappath;
char work[128];
char **filenames;
const char *displayName;
int numfiles;
int i;
int iLen;
qboolean bIsGerman;
// cleanup
listbox->DeleteAllItems();
if (m_bGermanModels) {
window->setTitle("Select Your Axis Player Model");
} else {
window->setTitle("Select Your Allied Player Model");
}
filenames = FS_ListFiles(currentDirectory, ".tik", qfalse, &numfiles);
for (i = 0; i < numfiles; i++) {
Q_strncpyz(work, filenames[i], sizeof(work));
if (strstr(work, "_fps")) {
// ignore view models
continue;
}
if (work[0] == '_') {
// ignore hidden models
continue;
}
// allied_manon readded in OPM
//if (!Q_stricmpn(work, "allied_manon")) {
// continue;
//}
bIsGerman = !Q_stricmpn(work, "german", 6u) || !Q_stricmpn(work, "axis", 4u) || !Q_stricmpn(work, "it", 2u)
|| !Q_stricmpn(work, "sc", 2u);
if (m_bGermanModels != bIsGerman) {
continue;
}
// strip the extension
work[strlen(work) - 4] = 0;
displayName = PM_FilenameToDisplayname(work);
listbox->AddItem(new PMPickerItem(displayName));
}
FS_FreeFileList(filenames);
listbox->SortByColumn(0);
}
void PlayerModelPickerClass::FileSelected( Event *ev )
void PlayerModelPickerClass::FileSelected(
const str& name, const str& currentDirectory, const str& partialName, const str& fullname
)
{
// FIXME: stub
FileChosen(name, currentDirectory, partialName, fullname);
}
void PlayerModelPickerClass::FileSelected( str& currentDirectory, str& partialName, str& fullname )
void PlayerModelPickerClass::FileSelected(Event *ev)
{
// FIXME: stub
str name;
char donotshowssindeorfr[64];
str fullname;
name = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
fullname = PM_DisplaynameToFilename(name);
if (!Q_stricmpn(fullname, "german_waffen_", 14)) {
Q_strncpyz(donotshowssindeorfr, "german_waffenss_", sizeof(donotshowssindeorfr));
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), fullname.c_str() + 14);
} else {
Q_strncpyz(donotshowssindeorfr, fullname, sizeof(donotshowssindeorfr));
}
FileSelected(name, currentDirectory, fullname, currentDirectory + donotshowssindeorfr);
}
void PlayerModelPickerClass::FileChosen( Event *ev )
void PlayerModelPickerClass::FileChosen(
const str& name, const str& currentDirectory, const str& partialName, const str& fullname
)
{
// FIXME: stub
str sCommand;
if (m_bGermanModels) {
sCommand += "ui_dm_playergermanmodel \"" + name;
sCommand += "\" ; ui_dm_playergermanmodel_set " + partialName;
sCommand += " ; ui_disp_playergermanmodel " + fullname + ".tik";
} else {
sCommand += "ui_dm_playermodel \"" + name;
sCommand += "\" ; ui_dm_playermodel_set " + partialName;
sCommand += " ; ui_disp_playermodel " + fullname + ".tik";
}
sCommand += "\n";
Cbuf_AddText(sCommand);
CloseWindow();
}
void PlayerModelPickerClass::FileChosen( str& currentDirectory, str& partialName, str& fullname )
void PlayerModelPickerClass::FileChosen(Event *ev)
{
// FIXME: stub
str name;
char donotshowssindeorfr[64];
str fullname;
name = listbox->GetItem(listbox->getCurrentItem())->getListItemString(0);
fullname = PM_DisplaynameToFilename(name);
if (!Q_stricmpn(fullname, "german_waffen_", 14)) {
Q_strncpyz(donotshowssindeorfr, "german_waffen_", sizeof(donotshowssindeorfr));
Q_strcat(donotshowssindeorfr, sizeof(donotshowssindeorfr), fullname.c_str() + 14);
} else {
Q_strncpyz(donotshowssindeorfr, fullname, sizeof(donotshowssindeorfr));
}
FileChosen(name, currentDirectory, fullname, currentDirectory + donotshowssindeorfr);
}
void PlayerModelPickerClass::OnDeactivated( Event *ev )
void PlayerModelPickerClass::CloseWindow(void)
{
// FIXME: stub
PostEvent(EV_Remove, 0);
}
void PlayerModelPickerClass::Setup( const char *root_directory, const char *current_directory, qboolean bGermanModels )
void PlayerModelPickerClass::OnDeactivated(Event *ev)
{
// FIXME: stub
CloseWindow();
}
PMPickerItem::PMPickerItem(const str& string)
{
m_string = string;
}
int PMPickerItem::getListItemValue(int which) const
{
return atoi(m_string);
}
griditemtype_t PMPickerItem::getListItemType(int which) const
{
return griditemtype_t::TYPE_STRING;
}
str PMPickerItem::getListItemString(int which) const
{
return m_string;
}
void PMPickerItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont *pFont) {}
qboolean PMPickerItem::IsHeaderEntry() const
{
return qfalse;
}
+26 -22
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,37 +20,41 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIPLAYERMODELPICKER_H__
#define __CL_UIPLAYERMODELPICKER_H__
#pragma once
class UIFloatingWindow;
class PlayerModelPickerClass : public USignal {
UIFloatingWindow *window;
UIListCtrl *listbox;
str currentDirectory;
str rootDirectory;
qboolean m_bGermanModels;
class PlayerModelPickerClass : public USignal
{
UIFloatingWindow *window;
UIListCtrl *listbox;
str currentDirectory;
str rootDirectory;
qboolean m_bGermanModels;
public:
CLASS_PROTOTYPE( PlayerModelPickerClass );
CLASS_PROTOTYPE(PlayerModelPickerClass);
private:
void SetupFiles( void );
void Initialize( const char *root_directory, const char *current_directory, qboolean bGermanModels );
void SetupFiles(void);
void Initialize(const char *root_directory, const char *current_directory, qboolean bGermanModels);
protected:
void CloseWindow( void );
void FileSelected( Event *ev );
virtual void FileSelected( str& currentDirectory, str& partialName, str& fullname );
void FileChosen( Event *ev );
virtual void FileChosen( str& currentDirectory, str& partialName, str& fullname );
void OnDeactivated( Event *ev );
void CloseWindow(void);
void FileSelected(Event *ev);
// The name parameter was added in 2.0.
virtual void FileSelected(const str& name, const str& currentDirectory, const str& partialName, const str& fullname);
void FileChosen(Event *ev);
// The name parameter was added in 2.0.
virtual void FileChosen(const str& name, const str& currentDirectory, const str& partialName, const str& fullname);
void OnDeactivated(Event *ev);
public:
PlayerModelPickerClass();
~PlayerModelPickerClass();
PlayerModelPickerClass();
~PlayerModelPickerClass();
void Setup( const char *root_directory, const char *current_directory, qboolean bGermanModels );
void Setup(const char *root_directory, const char *current_directory, qboolean bGermanModels);
};
#endif /* __CL_UIPLAYERMODELPICKER_H__ */
const char* PM_FilenameToDisplayname(const char* fileName);
const char* PM_DisplaynameToFilename(const char* displayName);
+68 -34
View File
@@ -79,6 +79,7 @@ struct ServerListInstance {
};
class FAKKServerListItem : public UIListCtrlItem {
UIFAKKServerList* m_parent; // Added in OPM
str m_strings[6];
str m_sVersion;
bool m_bDifferentVersion;
@@ -94,7 +95,7 @@ public:
int m_iGameSpyPort;
public:
FAKKServerListItem(str string1, str string2, str string3, str string4, str string5, str string6, str ver);
FAKKServerListItem(UIFAKKServerList* parent, str string1, str string2, str string3, str string4, str string5, str string6, str ver);
griditemtype_t getListItemType(int index) const override;
int getListItemValue(int i) const override;
@@ -125,8 +126,9 @@ ServerListInstance g_ServerListInst[2];
void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, void* param1, void* param2);
static void AddFilter(char* filter, const char* value);
FAKKServerListItem::FAKKServerListItem(str string1, str string2, str string3, str string4, str string5, str string6, str ver)
FAKKServerListItem::FAKKServerListItem(UIFAKKServerList* parent, str string1, str string2, str string3, str string4, str string5, str string6, str ver)
{
m_parent = parent;
m_strings[0] = string1;
m_strings[1] = string2;
m_strings[2] = string3;
@@ -164,84 +166,95 @@ void FAKKServerListItem::setListItemString(int i, str sNewString)
void FAKKServerListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, bool bSelected, UIFont* pFont)
{
static cvar_t *pColoringType = Cvar_Get("cl_browserdetailedcolors", "0", CVAR_ARCHIVE);
UIRect2D newRect = drawRect;
vec2_t virtualScale = { 1.f, 1.f };
/*
if (m_parent->isVirtual()) {
virtualScale[0] = uid.vidWidth / 640.f;
virtualScale[1] = uid.vidHeight / 480.f;
newRect.size.width *= uid.vidWidth / 1024;
newRect.size.height *= uid.vidHeight / 768;
}
*/
if (!pColoringType->integer) {
if (IfQueryFailed() || (IsDifferentVersion() && IsQueried())) {
if (bSelected) {
DrawBox(drawRect, UColor(0.2f, 0.0f, 0.0f), 1.0);
DrawBox(newRect, UColor(0.2f, 0.0f, 0.0f), 1.0);
pFont->setColor(UColor(0.9f, 0.0f, 0.0f));
} else {
DrawBox(drawRect, UColor(0.1f, 0.0f, 0.0f), 1.0);
DrawBox(newRect, UColor(0.1f, 0.0f, 0.0f), 1.0);
pFont->setColor(UColor(0.55f, 0.0f, 0.0f));
}
} else if (IsQueried()) {
if (bSelected) {
DrawBox(drawRect, UColor(0.2f, 0.18f, 0.015f), 1.0);
DrawBox(newRect, UColor(0.2f, 0.18f, 0.015f), 1.0);
pFont->setColor(UColor(0.9f, 0.8f, 0.6f));
} else {
DrawBox(drawRect, UColor(0.02f, 0.07f, 0.004f), 1.0);
DrawBox(newRect, UColor(0.02f, 0.07f, 0.004f), 1.0);
pFont->setColor(UHudColor);
}
} else {
if (bSelected) {
DrawBox(drawRect, UColor(0.15f, 0.18f, 0.18f), 1.0);
DrawBox(newRect, UColor(0.15f, 0.18f, 0.18f), 1.0);
pFont->setColor(UColor(0.6f, 0.7f, 0.8f));
} else {
DrawBox(drawRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
DrawBox(newRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
pFont->setColor(UColor(0.05f, 0.5f, 0.6f));
}
}
pFont->Print(
drawRect.pos.x + 1.0,
drawRect.pos.y,
newRect.pos.x / virtualScale[0] + 1.0,
newRect.pos.y / virtualScale[1],
getListItemString(iColumn).c_str(),
-1,
qfalse
false //m_parent->isVirtual()
);
} else {
if (IsDifferentVersion()) {
if (IsQueried()) {
if (bSelected) {
DrawBox(drawRect, UColor(0.25f, 0.0f, 0.0f), 1.0);
DrawBox(newRect, UColor(0.25f, 0.0f, 0.0f), 1.0);
pFont->setColor(UColor(0.0f, 0.5f, 0.0f));
} else {
DrawBox(drawRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
DrawBox(newRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
pFont->setColor(UColor(0.0f, 0.35f, 0.0f));
}
} else {
if (bSelected) {
DrawBox(drawRect, UColor(0.25f, 0.0f, 0.0f), 1.0);
DrawBox(newRect, UColor(0.25f, 0.0f, 0.0f), 1.0);
pFont->setColor(UColor(0.5f, 0.6f, 0.7f));
} else {
DrawBox(drawRect, UColor(0.15f, 0.0f, 0.0f), 1.0);
DrawBox(newRect, UColor(0.15f, 0.0f, 0.0f), 1.0);
pFont->setColor(UColor(0.05f, 0.4f, 0.5f));
}
}
} else if (IsQueried()) {
if (bSelected) {
DrawBox(drawRect, UColor(0.2f, 0.18f, 0.015f), 1.0);
DrawBox(newRect, UColor(0.2f, 0.18f, 0.015f), 1.0);
pFont->setColor(UColor(0.9f, 0.8f, 0.6f));
} else {
DrawBox(drawRect, UColor(0.02f, 0.07f, 0.005f), 1.0);
DrawBox(newRect, UColor(0.02f, 0.07f, 0.005f), 1.0);
pFont->setColor(UHudColor);
}
} else {
if (bSelected) {
DrawBox(drawRect, UColor(0.15f, 0.18f, 0.18f), 1.0);
DrawBox(newRect, UColor(0.15f, 0.18f, 0.18f), 1.0);
pFont->setColor(UColor(0.6f, 0.7f, 0.8f));
} else {
DrawBox(drawRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
DrawBox(newRect, UColor(0.005f, 0.07f, 0.02f), 1.0);
pFont->setColor(UColor(0.05f, 0.5f, 0.6f));
}
if (IfQueryFailed()) {
DrawBox(
UIRect2D(
drawRect.pos.x,
drawRect.pos.y + drawRect.size.height * 0.5 - 1.0 + drawRect.pos.y,
drawRect.size.width,
drawRect.size.height * 0.5 - 1.0 + drawRect.pos.y
newRect.pos.x,
newRect.pos.y + newRect.size.height * 0.5 - 1.0 + newRect.pos.y,
newRect.size.width,
newRect.size.height * 0.5 - 1.0 + newRect.pos.y
),
URed,
0.3f
@@ -249,19 +262,19 @@ void FAKKServerListItem::DrawListItem(int iColumn, const UIRect2D& drawRect, boo
}
pFont->Print(
drawRect.pos.x + 1.0,
drawRect.pos.y,
newRect.pos.x / virtualScale[0] + 1.0,
newRect.pos.y / virtualScale[1],
getListItemString(iColumn).c_str(),
-1,
qfalse
false //m_parent->isVirtual()
);
if (IsDifferentVersion()) {
DrawBox(
UIRect2D(
drawRect.pos.x,
drawRect.pos.y + drawRect.size.height * 0.5 - 1.0 + drawRect.pos.y,
drawRect.size.width,
newRect.pos.x,
newRect.pos.y + newRect.size.height * 0.5 - 1.0 + newRect.pos.y,
newRect.size.width,
1.0
),
URed,
@@ -730,6 +743,14 @@ void UIFAKKServerList::UpdateServer( Event *ev )
FAKKServerListItem* item = (FAKKServerListItem*)GetItem(getCurrentItem());
ServerListAuxUpdate(m_serverList[0], item->m_sIP.c_str(), item->m_iGameSpyPort, true, GQueryType::qt_status);
if (com_target_game->integer >= target_game_e::TG_MOHTT) {
const cvar_t* dm_omit_spearhead = Cvar_Get("dm_omit_spearhead", "0", CVAR_ARCHIVE);
// check for Spearhead
if (!dm_omit_spearhead->integer) {
ServerListAuxUpdate(m_serverList[1], item->m_sIP.c_str(), item->m_iGameSpyPort, true, GQueryType::qt_status);
}
}
}
int UIFAKKServerList::ServerCompareFunction( const UIListCtrlItem *i1, const UIListCtrlItem *i2, int columnname )
@@ -1019,23 +1040,36 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
str sServerName;
str sPlayers;
const char* pszGameVer;
const char* pszGameVerNumber;
pszHostName = ServerGetStringValue(server, "hostname", "(NONE)");
bDiffVersion = false;
pszGameVer = ServerGetStringValue(server, "gamever", "1.00");
pszGameVerNumber = pszGameVer;
if (pszGameVerNumber[0] == 'd') {
// demo server
pszGameVerNumber++;
}
if (com_target_game->integer >= target_game_e::TG_MOHTT) {
if (iServerType == target_game_e::TG_MOHTT) {
if (fabs(atof(pszGameVer) - com_target_version->value) > 0.1f) {
//if (fabs(atof(pszGameVerNumber) - com_target_version->value) > 0.1f) {
// bDiffVersion = true;
//}
if (fabs(atof(pszGameVerNumber)) < 2.3f) {
bDiffVersion = true;
}
} else {
if (fabs(atof(pszGameVer) - com_target_version->value) > 0.3f) {
//if (fabs(atof(pszGameVerNumber) - com_target_version->value) > 0.3f) {
// bDiffVersion = true;
//}
if (fabs(atof(pszGameVerNumber)) < 2.1f) {
bDiffVersion = true;
}
}
} else {
if (fabs(atof(pszGameVer) - com_target_version->value) > 0.1f) {
if (fabs(atof(pszGameVerNumber) - com_target_version->value) > 0.1f) {
bDiffVersion = true;
}
}
@@ -1056,7 +1090,7 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
}
if (i > uiServerList->getNumItems() || !pNewServerItem) {
pNewServerItem = new FAKKServerListItem("?", sAddress, "?", "?/?", "?", "?", "?");
pNewServerItem = new FAKKServerListItem(uiServerList, "?", sAddress, "?", "?/?", "?", "?", "?");
pNewServerItem->m_sIP = ServerGetAddress(server);
pNewServerItem->m_uiRealIP = iRealIP;
pNewServerItem->m_iGameSpyPort = iGameSpyPort;
@@ -1154,7 +1188,7 @@ void UpdateServerListCallBack(GServerList serverlist, int msg, void* instance, v
continue;
}
pNewServerItem = new FAKKServerListItem("?", sAddress, "?", "?/?", "?", "?", "?");
pNewServerItem = new FAKKServerListItem(uiServerList, "?", sAddress, "?", "?/?", "?", "?", "?");
pNewServerItem->m_sIP = ServerGetAddress(arrayServer);
pNewServerItem->m_uiRealIP = iRealIP;
pNewServerItem->m_iPort = PORT_SERVER;
+29 -9
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -22,22 +22,42 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "cl_ui.h"
CLASS_DECLARATION( FilePickerClass, SoundPickerClass, NULL )
{
{ NULL, NULL }
CLASS_DECLARATION(FilePickerClass, SoundPickerClass, NULL) {
{NULL, NULL}
};
SoundPickerClass::SoundPickerClass()
{
// FIXME: stub
str soundpath;
str currentpath;
const char *varValue;
int i;
soundpath = "sound";
varValue = UI_GetCvarString("ui_pickedsound", NULL);
if (varValue && *varValue) {
currentpath = varValue;
for (i = currentpath.length(); i > 0; i--) {
if (currentpath[i] == '/') {
break;
}
}
currentpath = str(currentpath, 0, i + 1);
} else {
currentpath = soundpath;
}
}
void SoundPickerClass::FileSelected( str &currentDirectory, str &partialName, str &fullname )
void SoundPickerClass::FileSelected(const str& currentDirectory, const str& partialName, const str& fullname)
{
uii.Snd_PlaySound(fullname);
}
void SoundPickerClass::FileChosen( str &currentDirectory, str &partialName, str &fullname )
void SoundPickerClass::FileChosen(const str& currentDirectory, const str& partialName, const str& fullname)
{
uii.Cvar_Set("ui_pickedsound", fullname);
CloseWindow();
}
+8 -10
View File
@@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
Copyright (C) 2023 the OpenMoHAA team
This file is part of OpenMoHAA source code.
@@ -20,17 +20,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UISOUNDPICKER_H__
#define __CL_UISOUNDPICKER_H__
#pragma once
class SoundPickerClass : public FilePickerClass {
class SoundPickerClass : public FilePickerClass
{
public:
CLASS_PROTOTYPE( SoundPickerClass );
CLASS_PROTOTYPE(SoundPickerClass);
SoundPickerClass();
SoundPickerClass();
void FileSelected( str &currentDirectory, str &partialName, str &fullname ) override;
void FileChosen( str &currentDirectory, str &partialName, str &fullname ) override;
void FileSelected(const str& currentDirectory, const str& partialName, const str& fullname) override;
void FileChosen(const str& currentDirectory, const str& partialName, const str& fullname) override;
};
#endif /* __CL_UISOUNDPICKER_H__ */
+174 -229
View File
@@ -490,12 +490,10 @@ void UIFakkLabel::DrawStatbar(float frac)
{
float width = frac * m_frame.size.width;
m_statbar_material->ReregisterMaterial();
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material->GetMaterial());
if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material_flash->GetMaterial());
}
break;
@@ -507,12 +505,10 @@ void UIFakkLabel::DrawStatbar(float frac)
{
float y = m_frame.size.height * (1.0 - frac);
m_statbar_material->ReregisterMaterial();
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) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTilePic(
0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material_flash->GetMaterial()
);
@@ -528,14 +524,12 @@ void UIFakkLabel::DrawStatbar(float frac)
{
float width = frac * m_frame.size.width;
m_statbar_material->ReregisterMaterial();
re.DrawStretchPic(
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) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawStretchPic(
0.0,
0.0,
@@ -557,14 +551,12 @@ void UIFakkLabel::DrawStatbar(float frac)
float y = m_frame.size.height * (1.0 - frac);
float height = m_frame.size.height * frac;
m_statbar_material->ReregisterMaterial();
re.DrawStretchPic(
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) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawStretchPic(
0.0,
y,
@@ -583,14 +575,12 @@ void UIFakkLabel::DrawStatbar(float frac)
{
float height = m_frame.size.height * frac;
m_statbar_material->ReregisterMaterial();
re.DrawStretchPic(
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) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawStretchPic(
0.0,
0.0,
@@ -686,12 +676,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
} else {
@@ -709,12 +697,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
@@ -739,12 +725,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
} else {
@@ -766,12 +750,10 @@ void UIFakkLabel::DrawStatCircle(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
@@ -846,12 +828,10 @@ void UIFakkLabel::DrawStatNeedle(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
re.SetColor(col);
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
@@ -867,11 +847,9 @@ void UIFakkLabel::DrawStatNeedle(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
}
@@ -937,11 +915,9 @@ void UIFakkLabel::DrawStatRotator(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
@@ -959,11 +935,9 @@ void UIFakkLabel::DrawStatRotator(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
}
@@ -1137,7 +1111,6 @@ void UIFakkLabel::DrawStatCompass(float frac)
vVerts[1][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());
vVerts[0][0] = vVerts[2][0];
@@ -1150,7 +1123,6 @@ void UIFakkLabel::DrawStatCompass(float frac)
vVerts[2][0] = vCenter[0] + fCosVal * vCenter[1] - vCompassDir[0] * vCenter[0];
vVerts[2][1] = vCenter[1] * fSinVal + vCenter[0] - vCompassDir[1] * vCenter[1];
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
}
@@ -1227,11 +1199,9 @@ void UIFakkLabel::DrawStatSpinner(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
@@ -1249,11 +1219,9 @@ void UIFakkLabel::DrawStatSpinner(float frac)
re.SetColor(m_foreground_color);
}
m_statbar_material->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
m_statbar_material_flash->ReregisterMaterial();
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
}
@@ -1294,40 +1262,16 @@ void UIFakkLabel::Draw(void)
{
if (m_stat_alpha != -1) {
float frac;
frac = (cl.snap.ps.stats[m_stat_alpha] + 1) / 100.0;
frac = Q_clamp_float(frac, 0, 1);
m_alpha = frac;
}
if (m_stat == -1 && m_itemindex == -1 && m_inventoryrendermodelindex == -1) {
if (m_stat_configstring != -1) {
m_font->setColor(m_foreground_color);
if (m_bOutlinedText) {
m_font->PrintOutlinedJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))),
UBlack,
m_bVirtual ? m_vVirtualScale : NULL
);
} else {
m_font->PrintJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))),
m_bVirtual ? m_vVirtualScale : NULL
);
}
return;
}
if (!m_rendermodel && m_statbar_or == L_STATBAR_NONE && !m_sDrawModelName.length()) {
if (m_stat == -1 && m_itemindex == -1 && m_inventoryrendermodelindex == -1 && m_stat_configstring == -1
&& !m_rendermodel && m_statbar_or == L_STATBAR_NONE) {
if (!m_sDrawModelName.length()) {
UILabel::Draw();
return;
}
@@ -1354,28 +1298,13 @@ void UIFakkLabel::Draw(void)
m_bVirtual ? m_vVirtualScale : NULL
);
}
return;
}
if (m_stat == -1) {
float scale;
qhandle_t handle;
vec3_t origin;
vec3_t mins;
vec3_t maxs;
vec3_t angles;
vec3_t offset;
vec3_t rotateoffset;
vec4_t color;
str sAnimName;
float height;
if (m_itemindex != -1) {
if (m_itemindex < 0) {
return;
}
if (m_stat != -1) {
int delta = cl.snap.ps.stats[m_stat];
if (m_statbar_or == L_STATBAR_NONE) {
m_font->setColor(m_foreground_color);
if (m_bOutlinedText) {
@@ -1383,7 +1312,7 @@ void UIFakkLabel::Draw(void)
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
va("%d", delta),
UBlack,
m_bVirtual ? m_vVirtualScale : NULL
);
@@ -1392,143 +1321,13 @@ void UIFakkLabel::Draw(void)
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
va("%d", delta),
m_bVirtual ? m_vVirtualScale : NULL
);
}
return;
}
if (m_inventoryrendermodelindex == -1 && !m_sDrawModelName.length() || !m_rendermodel) {
float frac = 0.0;
if (m_statbar_or == L_STATBAR_NONE) {
return;
}
if (m_cvarname.length()) {
frac = Cvar_VariableValue(m_cvarname) / (m_statbar_max - m_statbar_min);
}
if (frac > 1.0) {
frac = 1.0;
}
if (frac < 0.0) {
frac = 0.0;
}
DrawStatbar(frac);
return;
}
VectorSet4(color, 255, 255, 255, 255);
if (m_rendermodel) {
if (!m_cvarname.length()) {
return;
}
handle = re.RegisterModel(Cvar_VariableString(m_cvarname));
if (!handle) {
return;
}
VectorCopy(m_angles, angles);
VectorCopy(m_rotateoffset, rotateoffset);
VectorCopy(m_offset, offset);
scale = m_scale;
sAnimName = m_anim;
} else if (m_sDrawModelName.length()) {
if (m_lastitemindex != cl.snap.ps.activeItems[m_inventoryrendermodelindex]) {
if (!m_lastitem) {
m_lastitem = CL_GetInvItemByName(&client_inv, m_sDrawModelName);
}
}
_shitlabel01:
if (!m_lastitem) {
return;
}
VectorCopy(m_lastitem->hudprops.rotateoffset, rotateoffset);
VectorCopy(m_lastitem->hudprops.offset, offset);
handle = re.RegisterModel(m_lastitem->hudprops.model);
VectorCopy(m_lastitem->hudprops.angledeltas, angles);
if (m_lastitem->hudprops.move == INV_MOVE_BOB) {
float frac = uid.time / 600.0;
angles[0] += sin(frac) * m_lastitem->hudprops.angledeltas[0];
angles[1] += sin(frac) * m_lastitem->hudprops.angledeltas[1];
angles[2] += sin(frac) * m_lastitem->hudprops.angledeltas[2];
} else if (m_lastitem->hudprops.model == INV_MOVE_SPIN) {
float frac = uid.time / 600.0;
angles[0] += frac * m_lastitem->hudprops.angledeltas[0];
angles[1] += frac * m_lastitem->hudprops.angledeltas[1];
angles[2] += frac * m_lastitem->hudprops.angledeltas[2];
}
if (m_rendermodel) {
VectorSet(mins, -16, -16, 0);
VectorSet(maxs, 16, 16, 96);
} else {
re.ModelBounds(handle, mins, maxs);
}
origin[1] = (mins[1] + maxs[1]) * 0.5;
origin[2] = (mins[1] + maxs[1]) * -0.5;
height = maxs[2] - mins[2];
if (height < maxs[1] - mins[1]) {
height = maxs[1] - mins[1];
}
if (height <= maxs[0] - mins[0]) {
height = maxs[0] - mins[0];
}
origin[0] = height * scale * 0.5 / 0.268f;
CL_Draw3DModel(
m_screenframe.pos.x,
m_screenframe.pos.y,
m_screenframe.size.width,
m_screenframe.size.height,
handle,
origin,
rotateoffset,
offset,
angles,
color,
sAnimName
);
return;
}
if (m_lastitemindex == cl.snap.ps.activeItems[m_inventoryrendermodelindex]) {
goto _shitlabel01;
}
if (m_lastitem
== CL_GetInvItemByName(
&client_inv, CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_inventoryrendermodelindex])
)) {
m_lastitemindex = cl.snap.ps.activeItems[m_inventoryrendermodelindex];
goto _shitlabel01;
}
m_lastitem = CL_GetInvItemByName(
&client_inv, CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_inventoryrendermodelindex])
);
goto _shitlabel01;
}
int delta = cl.snap.ps.stats[m_stat];
if (m_statbar_or) {
if (m_statbar_or == L_STATBAR_VERTICAL_STAGGER_EVEN || m_statbar_or == L_STATBAR_VERTICAL_STAGGER_ODD) {
int stat;
@@ -1574,28 +1373,174 @@ void UIFakkLabel::Draw(void)
}
DrawStatbar(frac);
return;
}
float scale;
qhandle_t handle;
vec3_t origin;
vec3_t mins;
vec3_t maxs;
vec3_t angles;
vec3_t offset;
vec3_t rotateoffset;
vec4_t color;
str sAnimName;
float height;
if (m_itemindex != -1) {
if (m_itemindex < 0) {
return;
}
m_font->setColor(m_foreground_color);
if (m_bOutlinedText) {
m_font->PrintOutlinedJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
UBlack,
m_bVirtual ? m_vVirtualScale : NULL
);
} else {
m_font->PrintJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
m_bVirtual ? m_vVirtualScale : NULL
);
}
return;
}
m_font->setColor(m_foreground_color);
if (m_inventoryrendermodelindex == -1 && !m_sDrawModelName.length() && !m_rendermodel) {
float frac = 0.0;
if (m_bOutlinedText) {
m_font->PrintOutlinedJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
va("%d", delta),
UBlack,
m_bVirtual ? m_vVirtualScale : NULL
);
} else {
m_font->PrintJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
va("%d", delta),
m_bVirtual ? m_vVirtualScale : NULL
);
if (m_statbar_or == L_STATBAR_NONE) {
return;
}
if (m_cvarname.length()) {
frac = Cvar_VariableValue(m_cvarname) / (m_statbar_max - m_statbar_min);
}
if (frac > 1.0) {
frac = 1.0;
}
if (frac < 0.0) {
frac = 0.0;
}
DrawStatbar(frac);
return;
}
VectorSet4(color, 255, 255, 255, 255);
if (m_rendermodel) {
if (!m_cvarname.length()) {
return;
}
handle = re.RegisterModel(Cvar_VariableString(m_cvarname));
if (!handle) {
return;
}
VectorCopy(m_angles, angles);
VectorCopy(m_rotateoffset, rotateoffset);
VectorCopy(m_offset, offset);
scale = m_scale;
sAnimName = m_anim;
// Added in 2.11
// Tunak easter egg
if (Cvar_Get("tunak", "0", 0)->integer) {
// Since 2.15, those animations start has 'zz' prefix
if (strstr(m_anim, "american")) {
sAnimName = "zzamericanspecialidle";
} else {
// Added in 2.15
sAnimName = "zzgermanspecialidle";
}
}
} else {
if (m_sDrawModelName.length()) {
if (!m_lastitem) {
m_lastitem = CL_GetInvItemByName(&client_inv, m_sDrawModelName);
}
} else {
if (m_inventoryrendermodelindex >= 0
&& m_lastitemindex != cl.snap.ps.activeItems[m_inventoryrendermodelindex]) {
m_lastitem = CL_GetInvItemByName(
&client_inv, CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_inventoryrendermodelindex])
);
m_lastitemindex = cl.snap.ps.activeItems[m_inventoryrendermodelindex];
}
}
if (!m_lastitem) {
return;
}
VectorCopy(m_lastitem->hudprops.rotateoffset, rotateoffset);
VectorCopy(m_lastitem->hudprops.offset, offset);
scale = m_lastitem->hudprops.scale;
handle = re.RegisterModel(m_lastitem->hudprops.model);
VectorCopy(m_lastitem->hudprops.angledeltas, angles);
if (m_lastitem->hudprops.move == INV_MOVE_BOB) {
float frac = uid.time / 600.0;
angles[0] += sin(frac) * m_lastitem->hudprops.angledeltas[0];
angles[1] += sin(frac) * m_lastitem->hudprops.angledeltas[1];
angles[2] += sin(frac) * m_lastitem->hudprops.angledeltas[2];
} else if (m_lastitem->hudprops.model == INV_MOVE_SPIN) {
float frac = uid.time / 600.0;
angles[0] += frac * m_lastitem->hudprops.angledeltas[0];
angles[1] += frac * m_lastitem->hudprops.angledeltas[1];
angles[2] += frac * m_lastitem->hudprops.angledeltas[2];
}
}
if (m_rendermodel) {
VectorSet(mins, -16, -16, 0);
VectorSet(maxs, 16, 16, 96);
} else {
re.ModelBounds(handle, mins, maxs);
}
origin[1] = (mins[1] + maxs[1]) * 0.5;
origin[2] = (mins[2] + maxs[2]) * -0.5;
height = maxs[2] - mins[2];
if (height < maxs[1] - mins[1]) {
height = maxs[1] - mins[1];
}
if (height < maxs[0] - mins[0]) {
height = maxs[0] - mins[0];
}
origin[0] = height * scale * 0.5 / 0.268f;
CL_Draw3DModel(
m_screenframe.pos.x,
m_screenframe.pos.y,
m_screenframe.size.width,
m_screenframe.size.height,
handle,
origin,
rotateoffset,
offset,
angles,
color,
sAnimName
);
set2D();
}
+2
View File
@@ -37,6 +37,8 @@ typedef enum {
L_STATBAR_HEADING_SPINNER
} statbar_orientation_t;
extern Event EV_ClearInvItemReference;
class UIFakkLabel : public UILabel
{
protected:
+513 -364
View File
@@ -21,424 +21,573 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "cl_ui.h"
#include "../qcommon/localization.h"
CLASS_DECLARATION( UIWidget, View3D, NULL )
{
{ &W_Activated, &View3D::OnActivate },
{ &W_Deactivated, &View3D::OnDeactivate },
{ &W_LeftMouseDown, &View3D::Pressed },
{ NULL, NULL }
CLASS_DECLARATION(UIWidget, View3D, NULL) {
{&W_Activated, &View3D::OnActivate },
{&W_Deactivated, &View3D::OnDeactivate},
{&W_LeftMouseDown, &View3D::Pressed },
{NULL, NULL }
};
#define MAX_SUBTITLES 4
cvar_t* subs[MAX_SUBTITLES];
cvar_t* teams[MAX_SUBTITLES];
float fadeTime[MAX_SUBTITLES];
float subLife[MAX_SUBTITLES];
float alpha[MAX_SUBTITLES];
char oldStrings[MAX_SUBTITLES][2048];
cvar_t *subs[MAX_SUBTITLES];
cvar_t *teams[MAX_SUBTITLES];
float fadeTime[MAX_SUBTITLES];
float subLife[MAX_SUBTITLES];
float alpha[MAX_SUBTITLES];
char oldStrings[MAX_SUBTITLES][2048];
View3D::View3D()
{
// set as transparent
setBackgroundColor(UClear, true);
// no border
setBorderStyle(border_none);
AllowActivate(true);
// set as transparent
setBackgroundColor(UClear, true);
// no border
setBorderStyle(border_none);
AllowActivate(true);
m_printfadetime = 0.0;
m_print_mat = NULL;
m_locationprint = qfalse;
m_printfadetime = 0.0;
m_print_mat = NULL;
m_locationprint = qfalse;
}
void View3D::Draw
(
void
)
void View3D::UpdateLocationPrint(int x, int y, const char *s, float alpha)
{
if (clc.state != CA_DISCONNECTED) {
SCR_DrawScreenField();
}
set2D();
re.SavePerformanceCounters();
Draw2D();
m_printstring = s;
m_printalpha = alpha;
m_printfadetime = 4000.0;
m_x_coord = x;
m_y_coord = y;
m_locationprint = qtrue;
}
void View3D::DrawLetterbox
(
void
)
void View3D::UpdateCenterPrint(const char *s, float alpha)
{
float frac;
vec4_t col;
m_printstring = s;
col[0] = col[1] = col[2] = 0;
col[3] = 1;
if (s[0] == '@') {
m_print_mat = uWinMan.RegisterShader(s + 1);
} else {
m_print_mat = NULL;
}
frac = cl.snap.ps.stats[STAT_LETTERBOX] / 32767.0;
if (frac > 0.0) {
m_letterbox_active = true;
re.SetColor(col);
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
re.DrawBox(0.0, m_screenframe.size.height - m_screenframe.size.height * frac, m_screenframe.size.width, m_screenframe.size.height);
} else {
m_letterbox_active = false;
}
m_printalpha = alpha;
m_printfadetime = 4000.0;
m_locationprint = qfalse;
}
void View3D::DrawFades
(
void
)
void View3D::PrintSound(int channel, const char *name, float vol, int rvol, float pitch, float base, int& line)
{
if (cl.snap.ps.blend[3] > 0) {
re.SetColor(cl.snap.ps.blend);
if (cl.snap.ps.stats[STAT_ADDFADE]) {
re.AddBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
} else {
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
}
}
char buf[255];
float x;
float xStep;
float height;
height = m_font->getHeight(false);
xStep = height;
x = 0;
sprintf(buf, "%d", channel);
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
x += xStep + xStep;
sprintf(buf, "%s", name);
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
x += xStep * 30.0;
sprintf(buf, "vol:%.2f", vol);
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
x += xStep * 8;
sprintf(buf, "rvol:%.2f", (float)(rvol / 128.f));
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
x += xStep * 5;
sprintf(buf, "pit:%.2f", pitch);
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
x += xStep * 5;
sprintf(buf, "base:%d", (int)base);
m_font->Print(x, height * line + m_frame.pos.y, buf, -1, false);
line++;
}
void View3D::Draw2D
(
void
)
void View3D::Pressed(Event *ev)
{
if (!cls.no_menus) {
DrawFades();
}
DrawLetterbox();
if ((cl_debuggraph->integer || cl_timegraph->integer) && !cls.no_menus)
{
SCR_DrawDebugGraph();
}
else if (!cls.no_menus)
{
if (cge) {
cge->CG_Draw2D();
}
if (m_locationprint) {
LocationPrint();
} else {
CenterPrint();
}
if (!cls.no_menus)
{
DrawSoundOverlay();
DrawSubtitleOverlay();
}
}
if (fps->integer && !cls.no_menus)
{
DrawFPS();
DrawProf();
}
IN_MouseOff();
OnActivate(ev);
}
void View3D::DrawFPS
(
void
)
void View3D::OnDeactivate(Event *ev)
{
char string[128];
setFont("verdana-14");
if (fps->integer == 2)
{
re.SetColor(UBlack);
re.DrawBox(
0.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
m_frame.pos.x + m_frame.size.width,
m_font->getHeight(qfalse) * 4.0
);
}
sprintf(string, "FPS %4.1f", currentfps);
if (currentfps > 23.94) {
if (cl_greenfps->integer) {
m_font->setColor(UGreen);
} else {
m_font->setColor(UWhite);
}
} else if (currentfps > 18.0) {
m_font->setColor(UYellow);
} else {
// low fps
m_font->setColor(URed);
}
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
string,
-1,
qfalse
);
// Draw elements count
if (cl_greenfps->integer) {
m_font->setColor(UGreen);
}
else {
m_font->setColor(UWhite);
}
sprintf(string, "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
string,
-1,
qfalse
);
sprintf(string, "t%5d v%5d Mtex%5.2f", cls.total_tris, cls.total_verts, (float)cls.total_texels * 0.00000095367432);
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
string,
-1,
qfalse
);
m_font->setColor(UBlack);
cls.keyCatchers |= KEYCATCH_UI;
}
void View3D::DrawProf
(
void
)
void View3D::OnActivate(Event *ev)
{
// Normal empty function
}
void View3D::PrintSound
(
int channel,
const char *name,
float vol,
int rvol,
float pitch,
float base,
int& line
)
{
// FIXME: unimplemented
}
void View3D::DrawSoundOverlay
(
void
)
{
setFont("verdana-14");
m_font->setColor(UWhite);
if (sound_overlay->integer) {
Com_Printf("sound_overlay isn't supported with OpenAL/SDL right now.\n");
Cvar_Set("sound_overlay", "0");
}
}
void View3D::CenterPrint
(
void
)
{
// FIXME: unimplemented
}
void View3D::LocationPrint
(
void
)
{
// FIXME: unimplemented
}
void View3D::OnActivate
(
Event *ev
)
{
UIWidget* wid;
UList<UIWidget*> widgets;
UIWidget *wid;
UList<UIWidget *> widgets;
UI_CloseInventory();
cls.keyCatchers &= ~KEYCATCH_UI;
for (wid = getParent()->getFirstChild(); wid; wid = getParent()->getNextChild(wid))
{
if (wid->getAlwaysOnBottom() && wid != this) {
widgets.AddTail(wid);
}
}
for (wid = getParent()->getFirstChild(); wid; wid = getParent()->getNextChild(wid)) {
if (wid->getAlwaysOnBottom() && wid != this) {
widgets.AddTail(wid);
}
}
widgets.IterateFromHead();
while (widgets.IsCurrentValid())
{
widgets.getCurrent()->BringToFrontPropogated();
widgets.IterateNext();
}
widgets.IterateFromHead();
while (widgets.IsCurrentValid()) {
widgets.getCurrent()->BringToFrontPropogated();
widgets.IterateNext();
}
}
void View3D::OnDeactivate
(
Event *ev
)
void View3D::LocationPrint(void)
{
cls.keyCatchers |= KEYCATCH_UI;
fonthorzjustify_t horiz;
fontvertjustify_t vert;
int x, y;
const char *p;
float alpha;
UIRect2D frame;
if (!m_printfadetime) {
m_locationprint = false;
return;
}
horiz = FONT_JUSTHORZ_LEFT;
vert = FONT_JUSTVERT_TOP;
p = Sys_LV_CL_ConvertString(m_printstring);
if (m_printfadetime > 3250) {
alpha = 1.f - (m_printfadetime - 3250.f) / 750.f * m_printalpha;
} else if (m_printfadetime >= 750) {
alpha = 1.f;
} else {
alpha = m_printfadetime / 750.f * m_printalpha;
}
alpha = Q_clamp_float(alpha, 0, 1);
x = m_x_coord / 640.f * m_screenframe.size.width;
y = (480 - m_font->getHeight(false) - m_y_coord) / 480.f * m_screenframe.size.height;
if (m_x_coord == -1) {
horiz = FONT_JUSTHORZ_CENTER;
x = 0;
}
if (m_y_coord == -1) {
vert = FONT_JUSTVERT_CENTER;
y = 0;
}
m_font->setColor(UColor(0, 0, 0, alpha));
frame = getClientFrame();
m_font->PrintJustified(
UIRect2D(frame.pos.x + x + 1, frame.pos.y + y + 1, frame.size.width, frame.size.height),
horiz,
vert,
p,
m_bVirtual ? m_vVirtualScale : NULL
);
m_font->setColor(UColor(1, 1, 1, alpha));
frame = getClientFrame();
m_font->PrintJustified(
UIRect2D(frame.pos.x + x, frame.pos.y + y, frame.size.width, frame.size.height),
horiz,
vert,
p,
m_bVirtual ? m_vVirtualScale : NULL
);
m_font->setColor(UBlack);
m_printfadetime -= cls.frametime;
if (m_printfadetime < 0) {
m_printfadetime = 0;
}
}
void View3D::DrawSubtitleOverlay
(
void
)
qboolean View3D::LetterboxActive(void)
{
// FIXME: unimplemented
}
void View3D::ClearCenterPrint
(
void
)
{
m_printfadetime = 0.0;
}
void View3D::UpdateCenterPrint
(
const char *s,
float alpha
)
{
m_printstring = s;
if (s[0] == '@') {
m_print_mat = uWinMan.RegisterShader(s + 1);
} else {
m_print_mat = NULL;
}
m_printalpha = alpha;
m_printfadetime = 4000.0;
m_locationprint = qfalse;
}
void View3D::UpdateLocationPrint
(
int x,
int y,
const char *s,
float alpha
)
{
m_printstring = s;
m_printalpha = alpha;
m_printfadetime = 4000.0;
m_x_coord = x;
m_y_coord = y;
m_locationprint = qtrue;
}
qboolean View3D::LetterboxActive
(
void
)
{
return m_letterbox_active;
return m_letterbox_active;
}
float avWidth = 0.0;
void View3D::InitSubtitle
(
void
)
void View3D::InitSubtitle(void)
{
float totalWidth;
float totalWidth;
for (int i = 0; i < 4; i++) {
subs[i] = Cvar_Get(va("subtitle%d", i), "", 0);
teams[i] = Cvar_Get(va("subteam%d", i), "0", 0);
strcpy(oldStrings[i], subs[i]->string);
fadeTime[i] = 4000.0;
subLife[i] = 4000.0;
}
for (int i = 0; i < 4; i++) {
subs[i] = Cvar_Get(va("subtitle%d", i), "", 0);
teams[i] = Cvar_Get(va("subteam%d", i), "0", 0);
strcpy(oldStrings[i], subs[i]->string);
fadeTime[i] = 4000.0;
subLife[i] = 4000.0;
}
totalWidth = 0.0;
for (char j = 'A'; j <= 'Z'; j++) {
totalWidth += m_font->getCharWidth(j);
}
totalWidth = 0.0;
for (char j = 'A'; j <= 'Z'; j++) {
totalWidth += m_font->getCharWidth(j);
}
avWidth = totalWidth / 26.0;
avWidth = totalWidth / 26.0;
}
void View3D::FrameInitialized
(
void
)
void View3D::FrameInitialized(void)
{
Connect(this, W_Activated, W_Activated);
Connect(this, W_Deactivated, W_Deactivated);
Connect(this, W_Activated, W_Activated);
Connect(this, W_Deactivated, W_Deactivated);
}
void View3D::Pressed
(
Event *ev
)
void View3D::DrawSubtitleOverlay(void)
{
IN_MouseOff();
OnActivate(ev);
cvar_t *subAlpha;
int i;
float minX, maxY;
int line;
subAlpha = Cvar_Get("subAlpha", "0.5", 0);
setFont("facfont-20");
m_font->setColor(URed);
for (i = 0; i < MAX_SUBTITLES; i++) {
if (strcmp(oldStrings[i], subs[i]->string)) {
fadeTime[i] = 2500 * ((strlen(subs[i]->string) / 68) + 1.f) + 1500;
subLife[i] = fadeTime[i];
Q_strncpyz(oldStrings[i], subs[i]->string, sizeof(oldStrings[i]));
}
if (fadeTime[i] > subLife[i] - 750.f) {
alpha[i] = 1.f - (fadeTime[i] - (subLife[i] - 750.f)) / 750.f;
} else if (fadeTime[i] < 750) {
alpha[i] = fadeTime[i] / 750.f;
} else {
alpha[i] = 1.f;
}
fadeTime[i] -= cls.frametime;
if (fadeTime[i] < 0) {
// Clear the subtitle
fadeTime[i] = 0;
oldStrings[i][0] = 0;
Cvar_Set(va("subtitle%d", i), "");
}
}
minX = m_screenframe.size.height - m_font->getHeight(false) * 10;
maxY = (m_frame.pos.x + m_frame.size.width) - (m_frame.pos.x + m_frame.size.width) * 0.2f;
line = 0;
for (i = 0; i < MAX_SUBTITLES; i++) {
if (m_font->getWidth(subs[i]->string, sizeof(oldStrings[i])) > maxY) {
char buf[2048];
char *c;
char *end;
char *start;
float total;
int blockcount;
c = buf;
strcpy(buf, subs[i]->string);
total = 0;
end = NULL;
start = buf;
while (*c) {
blockcount = m_font->DBCSGetWordBlockCount(c, -1);
if (!blockcount) {
break;
}
total += m_font->getWidth(c, blockcount);
c += blockcount;
if (total > maxY) {
total = 0;
if (end < start) {
Com_DPrintf("ERROR - word longer than possible line\n");
break;
}
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, start, -1, false);
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
m_font->Print(20, m_font->getHeight(false) * line + minX, start, -1, false);
start = end + 1;
c = end + 1;
line++;
}
}
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, start, -1, qfalse);
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
m_font->Print(20, m_font->getHeight(false) * line + minX, start, -1, qfalse);
line++;
} else {
m_font->setColor(UColor(0, 0, 0, alpha[i] * subAlpha->value));
m_font->Print(18, m_font->getHeight(false) * line + minX + 1.f, subs[i]->string, -1, qfalse);
m_font->setColor(UColor(1, 1, 1, alpha[i] * subAlpha->value));
m_font->Print(20, m_font->getHeight(false) * line + minX, subs[i]->string, -1, qfalse);
line++;
}
}
}
CLASS_DECLARATION( UIWidget, ConsoleView, NULL )
void View3D::DrawSoundOverlay(void)
{
{ NULL, NULL }
setFont("verdana-14");
m_font->setColor(UWhite);
// FIXME: TODO
if (sound_overlay->integer) {
Com_Printf("sound_overlay isn't supported with OpenAL/SDL right now.\n");
Cvar_Set("sound_overlay", "0");
}
}
void View3D::DrawProf(void)
{
// Normal empty function
}
void View3D::DrawLetterbox(void)
{
float frac;
vec4_t col;
col[0] = col[1] = col[2] = 0;
col[3] = 1;
frac = cl.snap.ps.stats[STAT_LETTERBOX] / 32767.0;
if (frac > 0.0) {
m_letterbox_active = true;
re.SetColor(col);
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
re.DrawBox(
0.0,
m_screenframe.size.height - m_screenframe.size.height * frac,
m_screenframe.size.width,
m_screenframe.size.height
);
} else {
m_letterbox_active = false;
}
}
void View3D::DrawFades(void)
{
if (cl.snap.ps.blend[3] > 0) {
re.SetColor(cl.snap.ps.blend);
if (cl.snap.ps.stats[STAT_ADDFADE]) {
re.AddBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
} else {
re.DrawBox(0.0, 0.0, m_screenframe.size.width, m_screenframe.size.height);
}
}
}
void View3D::DrawFPS(void)
{
char string[128];
setFont("verdana-14");
if (fps->integer == 2) {
re.SetColor(UBlack);
re.DrawBox(
0.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 4.0,
m_frame.pos.x + m_frame.size.width,
m_font->getHeight(qfalse) * 4.0
);
}
sprintf(string, "FPS %4.1f", currentfps);
if (currentfps > 23.94) {
if (cl_greenfps->integer) {
m_font->setColor(UGreen);
} else {
m_font->setColor(UWhite);
}
} else if (currentfps > 18.0) {
m_font->setColor(UYellow);
} else {
// low fps
m_font->setColor(URed);
}
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 3.0,
string,
-1,
qfalse
);
// Draw elements count
if (cl_greenfps->integer) {
m_font->setColor(UGreen);
} else {
m_font->setColor(UWhite);
}
sprintf(string, "wt%5d wv%5d cl%d", cls.world_tris, cls.world_verts, cls.character_lights);
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse) * 2.0,
string,
-1,
qfalse
);
sprintf(string, "t%5d v%5d Mtex%5.2f", cls.total_tris, cls.total_verts, (float)cls.total_texels * 0.00000095367432);
m_font->Print(
m_font->getHeight(qfalse) * 10.0,
m_frame.pos.y + m_frame.size.height - m_font->getHeight(qfalse),
string,
-1,
qfalse
);
m_font->setColor(UBlack);
}
void View3D::Draw2D(void)
{
if (!cls.no_menus) {
DrawFades();
}
DrawLetterbox();
if ((cl_debuggraph->integer || cl_timegraph->integer) && !cls.no_menus) {
SCR_DrawDebugGraph();
} else if (!cls.no_menus) {
if (cge) {
cge->CG_Draw2D();
}
if (m_locationprint) {
LocationPrint();
} else {
CenterPrint();
}
if (!cls.no_menus) {
DrawSoundOverlay();
DrawSubtitleOverlay();
}
}
if (fps->integer && !cls.no_menus) {
DrawFPS();
DrawProf();
}
}
void View3D::Draw(void)
{
if (clc.state != CA_DISCONNECTED) {
SCR_DrawScreenField();
}
set2D();
re.SavePerformanceCounters();
Draw2D();
}
void View3D::ClearCenterPrint(void)
{
m_printfadetime = 0.0;
}
void View3D::CenterPrint(void)
{
float alpha;
const char *p;
qhandle_t mat;
float x, y;
float w, h;
if (!m_printfadetime) {
return;
}
p = Sys_LV_CL_ConvertString(m_printstring);
if (m_printfadetime > 3250) {
alpha = 1.f - (m_printfadetime - 3250.f) / 750.f * m_printalpha;
} else if (m_printfadetime >= 750) {
alpha = 1.f;
} else {
alpha = m_printfadetime / 750.f * m_printalpha;
}
alpha = Q_clamp_float(alpha, 0, 1);
if (!m_print_mat) {
UIRect2D frame;
m_font->setColor(UColor(0, 0, 0, alpha));
frame = getClientFrame();
m_font->PrintJustified(
UIRect2D(frame.pos.x + 1, frame.pos.y + 1, frame.size.width, frame.size.height),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
p,
m_bVirtual ? m_vVirtualScale : NULL
);
m_font->setColor(UColor(1, 1, 1, alpha));
frame = getClientFrame();
m_font->PrintJustified(
frame, m_iFontAlignmentHorizontal, m_iFontAlignmentVertical, p, m_bVirtual ? m_vVirtualScale : NULL
);
m_font->setColor(UBlack);
} else if ((mat = m_print_mat->GetMaterial())) {
vec4_t col {alpha, alpha, alpha, alpha};
re.SetColor(col);
w = re.GetShaderWidth(mat);
h = re.GetShaderHeight(mat);
x = (m_frame.pos.x + m_frame.size.width - w) * 0.5f;
y = (m_frame.pos.y + m_frame.size.height - h) * 0.5f;
re.DrawStretchPic(x, y, w, h, 0, 0, 1, 1, mat);
}
m_printfadetime -= cls.frametime;
if (m_printfadetime < 0) {
m_printfadetime = 0;
}
}
CLASS_DECLARATION(UIWidget, ConsoleView, NULL) {
{NULL, NULL}
};
void ConsoleView::Draw
(
void
)
{
// FIXME: unimplemented
}
void ConsoleView::Draw(void) {}
+37 -38
View File
@@ -20,55 +20,54 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef __CL_UIVIEW3D__
#define __CL_UIVIEW3D__
#pragma once
class View3D : public UIWidget {
float m_printfadetime;
float m_printalpha;
str m_printstring;
UIReggedMaterial *m_print_mat;
qboolean m_locationprint;
int m_x_coord;
int m_y_coord;
qboolean m_letterbox_active;
class View3D : public UIWidget
{
float m_printfadetime;
float m_printalpha;
str m_printstring;
UIReggedMaterial *m_print_mat;
qboolean m_locationprint;
int m_x_coord;
int m_y_coord;
qboolean m_letterbox_active;
public:
CLASS_PROTOTYPE( View3D );
CLASS_PROTOTYPE(View3D);
protected:
void Draw( void ) override;
void DrawLetterbox( void );
void DrawFades( void );
void Draw2D( void );
void DrawFPS( void );
void DrawProf( void );
void PrintSound( int channel, const char *name, float vol, int rvol, float pitch, float base, int& line );
void DrawSoundOverlay( void );
void CenterPrint( void );
void LocationPrint( void );
void OnActivate( Event *ev );
void OnDeactivate( Event *ev );
void DrawSubtitleOverlay( void );
void Draw(void) override;
void DrawLetterbox(void);
void DrawFades(void);
void Draw2D(void);
void DrawFPS(void);
void DrawProf(void);
void PrintSound(int channel, const char *name, float vol, int rvol, float pitch, float base, int& line);
void DrawSoundOverlay(void);
void CenterPrint(void);
void LocationPrint(void);
void OnActivate(Event *ev);
void OnDeactivate(Event *ev);
void DrawSubtitleOverlay(void);
public:
View3D();
View3D();
void ClearCenterPrint( void );
void UpdateCenterPrint( const char *s, float alpha );
void UpdateLocationPrint( int x, int y, const char *s, float alpha );
qboolean LetterboxActive( void );
void InitSubtitle( void );
void FrameInitialized( void ) override;
virtual void Pressed( Event *ev );
void ClearCenterPrint(void);
void UpdateCenterPrint(const char *s, float alpha);
void UpdateLocationPrint(int x, int y, const char *s, float alpha);
qboolean LetterboxActive(void);
void InitSubtitle(void);
void FrameInitialized(void) override;
virtual void Pressed(Event *ev);
};
class ConsoleView : public UIWidget {
class ConsoleView : public UIWidget
{
public:
CLASS_PROTOTYPE( ConsoleView );
CLASS_PROTOTYPE(ConsoleView);
protected:
void Draw( void ) override;
void Draw(void) override;
};
#endif /* __CL_UIVIEW3D__ */
+1 -1
View File
@@ -320,7 +320,7 @@ typedef struct {
serverInfo_t globalServers[MAX_GLOBAL_SERVERS];
// additional global servers
int numGlobalServerAddresses;
serverAddress_t globalServerAddresses[MAX_GLOBAL_SERVERS];
netadr_t globalServerAddresses[MAX_GLOBAL_SERVERS];
int numfavoriteservers;
serverInfo_t favoriteServers[MAX_OTHER_SERVERS];
+3
View File
@@ -59,6 +59,9 @@ typedef struct {
void S_ChannelFree_Callback(channel_t* v);
void S_LoadData(soundsystemsavegame_t* pSave);
void S_SaveData(soundsystemsavegame_t* pSave);
void S_ReLoad(soundsystemsavegame_t* pSave);
extern qboolean s_bSoundPaused;
#ifdef __cplusplus
}
+156 -1
View File
@@ -21,11 +21,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../snd_local.h"
#include "../client.h"
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
qboolean s_bSoundPaused = qfalse;
void S_Init2()
{
S_Init();
SND_setup();
// HACK: S_RegisterSound returns 0 when unsuccessful, or it returns the the sfx handle
// But the first sfx handle is also 0...
S_RegisterSound("sound/null.wav", qfalse);
Cmd_AddCommand("tmstart", S_TriggeredMusic_Start);
Cmd_AddCommand("tmstartloop", S_TriggeredMusic_StartLoop);
Cmd_AddCommand("tmstop", S_TriggeredMusic_Stop);
}
/*
@@ -46,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)
{
if (!sfxHandle) {
return;
}
// 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);
}
@@ -91,7 +115,13 @@ S_StartLocalSoundChannel
*/
void S_StartLocalSound(const char* sound_name, qboolean force_load)
{
// FIXME: unimplemented
sfxHandle_t h;
h = S_RegisterSound(sound_name, qfalse);
if (h) {
S_StartLocalSound(h, CHAN_LOCAL_SOUND);
}
}
/*
@@ -351,6 +381,16 @@ void MUSIC_CheckForStoppedSongs(void)
STUB();
}
/*
==============
S_CurrentSoundtrack
==============
*/
const char* S_CurrentSoundtrack()
{
return "";
}
/*
=================
S_IsSoundRegistered
@@ -415,26 +455,141 @@ void S_FadeSound(float fTime)
// 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() {
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
}
/*
==============
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) {
if (com_sv_running->integer) {
SV_SoundCallback(entnum, channel_number, name);
}
}
/*
==============
S_ChannelFree_Callback
==============
*/
void S_ChannelFree_Callback(channel_t* v) {
if (v->entnum & S_FLAG_DO_CALLBACK) {
callbackServer(v->entnum & ~S_FLAG_DO_CALLBACK, v - s_channels, v->thesfx->soundName);
}
}
/*
==============
S_LoadData
==============
*/
void S_LoadData(soundsystemsavegame_t* pSave) {
// FIXME: unimplemented
}
/*
==============
S_SaveData
==============
*/
void S_SaveData(soundsystemsavegame_t* pSave) {
// FIXME: unimplemented
}
/*
==============
S_ReLoad
==============
*/
void S_ReLoad(soundsystemsavegame_t* pSave) {
// FIXME: unimplemented
}
#endif
+11
View File
@@ -64,6 +64,12 @@ qboolean MUSIC_PlaySong(const char* alias);
void MUSIC_UpdateMusicVolumes(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_StopAllSounds2(qboolean stop_music);
float S_GetSoundTime(sfxHandle_t handle);
@@ -74,6 +80,11 @@ 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_FadeSound(float fTime);
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();
#ifdef __cplusplus
}
+6
View File
@@ -66,6 +66,7 @@ LPALGETSOURCEF qalGetSourcef;
LPALGETSOURCE3F qalGetSource3f;
LPALGETSOURCEFV qalGetSourcefv;
LPALGETSOURCEI qalGetSourcei;
LPALGETSOURCEIV qalGetSourceiv;
LPALSOURCEPLAYV qalSourcePlayv;
LPALSOURCESTOPV qalSourceStopv;
LPALSOURCEREWINDV qalSourceRewindv;
@@ -81,6 +82,7 @@ LPALDELETEBUFFERS qalDeleteBuffers;
LPALISBUFFER qalIsBuffer;
LPALBUFFERDATA qalBufferData;
LPALGETBUFFERF qalGetBufferf;
LPALGETBUFFERFV qalGetBufferfv;
LPALGETBUFFERI qalGetBufferi;
LPALDOPPLERFACTOR qalDopplerFactor;
LPALSPEEDOFSOUND qalSpeedOfSound;
@@ -184,6 +186,7 @@ qboolean QAL_Init(const char *libname)
qalGetSource3f = GPA("alGetSource3f");
qalGetSourcefv = GPA("alGetSourcefv");
qalGetSourcei = GPA("alGetSourcei");
qalGetSourceiv = GPA("alGetSourceiv");
qalSourcePlayv = GPA("alSourcePlayv");
qalSourceStopv = GPA("alSourceStopv");
qalSourceRewindv = GPA("alSourceRewindv");
@@ -199,6 +202,7 @@ qboolean QAL_Init(const char *libname)
qalIsBuffer = GPA("alIsBuffer");
qalBufferData = GPA("alBufferData");
qalGetBufferf = GPA("alGetBufferf");
qalGetBufferfv = GPA("alGetBufferfv");
qalGetBufferi = GPA("alGetBufferi");
qalDopplerFactor = GPA("alDopplerFactor");
qalSpeedOfSound = GPA("alSpeedOfSound");
@@ -283,6 +287,7 @@ void QAL_Shutdown( void )
qalGetSource3f = NULL;
qalGetSourcefv = NULL;
qalGetSourcei = NULL;
qalGetSourceiv = NULL;
qalSourcePlayv = NULL;
qalSourceStopv = NULL;
qalSourceRewindv = NULL;
@@ -298,6 +303,7 @@ void QAL_Shutdown( void )
qalIsBuffer = NULL;
qalBufferData = NULL;
qalGetBufferf = NULL;
qalGetBufferfv = NULL;
qalGetBufferi = NULL;
qalDopplerFactor = NULL;
qalSpeedOfSound = NULL;
+8
View File
@@ -55,6 +55,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# define ALC_ALL_DEVICES_SPECIFIER 0x1013
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef USE_OPENAL_DLOPEN
extern LPALENABLE qalEnable;
extern LPALDISABLE qalDisable;
@@ -248,4 +252,8 @@ extern LPALCCAPTURESAMPLES qalcCaptureSamples;
qboolean QAL_Init(const char *libname);
void QAL_Shutdown( void );
#ifdef __cplusplus
}
#endif
#endif // __QAL_H__
+8
View File
@@ -27,6 +27,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/q_shared.h"
#include "../qcommon/qcommon.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct snd_info_s
{
int rate;
@@ -113,4 +117,8 @@ void S_OggOpus_CodecCloseStream(snd_stream_t *stream);
int S_OggOpus_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer);
#endif // USE_CODEC_OPUS
#ifdef __cplusplus
}
#endif
#endif // !_SND_CODEC_H_
+1 -1
View File
@@ -31,7 +31,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "snd_codec.h"
// includes for the MP3 codec
#include "../libmad-0.15.1b/synth.h"
#include "mad.h"
#define MP3_SAMPLE_WIDTH 2
#define MP3_PCMSAMPLES_PERSLICE 32
+13 -3
View File
@@ -785,7 +785,11 @@ void S_Base_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t ve
}
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 );
@@ -848,7 +852,11 @@ void S_Base_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_
}
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( velocity, loopSounds[entityNum].velocity );
@@ -1581,7 +1589,9 @@ qboolean S_Base_Init( soundInterface_t *si ) {
if ( r ) {
s_soundStarted = 1;
s_soundMuted = 1;
// Fixed in OPM
// The UI must be able to play sounds
// s_soundMuted = 1;
// s_numSfx = 0;
Com_Memset(sfxHash, 0, sizeof(sfx_t *)*LOOP_HASH);
+816
View File
@@ -0,0 +1,816 @@
/*
===========================================================================
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 "snd_openal_new.h"
#include "client.h"
#include "cl_ui.h"
typedef struct {
vec3_t origin;
vec3_t velocity;
sfx_t *sfx;
int mergeFrame;
} loopSound_t;
qboolean s_bLastInitSound = qfalse;
qboolean s_bSoundStarted = qfalse;
qboolean s_bSoundPaused = qfalse;
qboolean s_bTryUnpause = qfalse;
int s_iListenerNumber = 0;
float s_fAmbientVolume = 1.f;
int number_of_sfx_infos = 0;
cvar_t *s_volume;
cvar_t *s_loadas8bit;
cvar_t *s_khz;
cvar_t *s_show;
cvar_t *s_testsound;
cvar_t *s_separation;
cvar_t *s_musicVolume;
cvar_t *s_ambientVolume;
sfx_info_t sfx_infos[MAX_SFX_INFOS];
sfx_t s_knownSfx[MAX_SFX];
int s_numSfx;
s_entity_t s_entity[MAX_GENTITIES];
static int s_registrationSequence;
static qboolean s_inRegistration;
cvar_t *s_mixPreStep;
cvar_t *s_dialogscale;
int numLoopSounds;
loopSound_t loopSounds[MAX_LOOP_SOUNDS];
/*
==============
S_SoundInfo_f
==============
*/
void S_SoundInfo_f()
{
S_PrintInfo();
}
/*
==============
S_SoundDump_f
==============
*/
void S_SoundDump_f()
{
S_DumpInfo();
}
/*
==============
S_Init
==============
*/
void S_Init(qboolean full_startup)
{
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", "11", 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)
{
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)
{
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;
}
/*
==============
S_FindName
==============
*/
sfx_t *S_FindName(const char *name, int sequenceNumber)
{
int i;
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()
{
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");
}
/*
==============
S_DefaultSound
==============
*/
void S_DefaultSound(sfx_t *sfx)
{
sfx->data = NULL;
sfx->iFlags |= SFX_FLAG_DEFAULT_SOUND;
}
/*
==============
S_IsSoundRegistered
==============
*/
qboolean S_IsSoundRegistered(const char *name)
{
char szCacheName[MAX_QPATH];
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)
{
char szCacheName[MAX_QPATH];
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)
{
return s_knownSfx[handle].time_length;
}
/*
==============
S_EndRegistration
==============
*/
void S_EndRegistration()
{
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)
{
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)
{
s_fAmbientVolume = volume;
}
/*
==============
S_StartSound
==============
*/
void S_StartSound(
const vec3_t origin,
int entnum,
int entchannel,
sfxHandle_t sfxHandle,
float volume,
float min_dist,
float pitch,
float maxDist,
int streamed
)
{
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)
{
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(
0,
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)
{
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)
{
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()
{
if (!s_bSoundStarted) {
return;
}
S_Driver_ClearLoopingSounds();
}
/*
==============
S_AddLoopingSound
==============
*/
void S_AddLoopingSound(
const vec3_t origin,
const vec3_t velocity,
sfxHandle_t sfxHandle,
float volume,
float min_dist,
float max_dist,
float pitch,
int flags
)
{
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])
{
if (!s_bSoundStarted) {
return;
}
S_Driver_Respatialize(entityNum, head, axis);
}
/*
==============
S_Update
==============
*/
void S_Update()
{
if (!s_bSoundStarted) {
return;
}
if (server_loading) {
return;
}
S_Driver_Update();
}
/*
==============
S_StopSound
==============
*/
void S_StopSound(int entnum, int channel)
{
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)
{
if (!s_bSoundStarted) {
return;
}
S_Driver_SetReverb(reverb_type, reverb_level);
}
/*
==============
S_Play
==============
*/
void S_Play()
{
int i;
char name[MAX_QPATH];
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()
{
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()
{
// TODO: Remove once AL is fully implemented
}
/*
==============
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
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 = 5;
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 = 5;
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;
}
+6
View File
@@ -27,6 +27,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/qcommon.h"
#include "snd_public.h"
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
#define PAINTBUFFER_SIZE 4096 // this is in samples
#define SND_CHUNK_SIZE 1024 // samples
@@ -281,3 +283,7 @@ void S_PaintChannelFrom16_altivec( portable_samplepair_t paintbuffer[PAINTBUFFER
#ifdef __cplusplus
}
#endif
#else
# include "snd_local_new.h"
#endif
+234
View File
@@ -0,0 +1,234 @@
/*
===========================================================================
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
===========================================================================
*/
#pragma once
#include "../qcommon/q_shared.h"
#include "../qcommon/qcommon.h"
#ifdef __cplusplus
extern "C" {
#endif
extern cvar_t *s_volume;
extern cvar_t *s_khz;
extern cvar_t *s_loadas8bit;
extern cvar_t *s_separation;
extern cvar_t *s_musicVolume;
extern cvar_t *s_ambientVolume;
typedef struct {
int format;
float rate;
float width;
int channels;
int samples;
int dataofs;
int datasize;
} wavinfo_t;
typedef struct sfx_s {
int iFlags;
int length;
int width;
byte *data;
char name[64];
int registration_sequence;
int sfx_info_index;
float time_length;
wavinfo_t info;
unsigned int buffer;
} sfx_t;
typedef struct {
unsigned short wFormatTag;
unsigned short nChannels;
unsigned int nSamplesPerSec;
unsigned int nAvgBytesPerSec;
unsigned short nBlockAlign;
unsigned short wBitsPerSample;
unsigned short cbSize;
} wavinfo_x_t;
typedef struct {
char name[64];
int loop_start;
int loop_end;
int max_number_playing;
float max_factor;
} sfx_info_t;
typedef struct {
vec3_t position;
vec3_t velocity;
int time;
qboolean use_listener;
} s_entity_t;
typedef struct {
char alias[32];
char path[64];
int mood_num;
int flags;
float volume;
float fadetime;
int current_pos;
int current_state;
} song_t;
typedef struct {
int iFlags;
char szName[64];
} sfxsavegame_t;
typedef struct {
qboolean bPlaying;
int iStatus;
sfxsavegame_t sfx;
int iEntNum;
int iEntChannel;
vec3_t vOrigin;
float fVolume;
int iBaseRate;
float fNewPitchMult;
float fMinDist;
float fMaxDist;
int iStartTime;
int iTime;
int iNextCheckObstructionTime;
int iEndTime;
int iFlags;
int iOffset;
int iLoopCount;
} channelbasesavegame_t;
typedef struct {
channelbasesavegame_t Channels[96];
} soundsystemsavegame_t;
enum channel_flags_t {
CHANNEL_FLAG_PLAY_DEFERRED = 1,
CHANNEL_FLAG_LOCAL_LISTENER = 16,
CHANNEL_FLAG_NO_ENTITY = 32,
CHANNEL_FLAG_PAUSED = 64,
CHANNEL_FLAG_LOOPING = 128,
// Added in OPM
CHANNEL_FLAG_MISSING_ENT = 256,
};
enum sfx_flags_t {
SFX_FLAG_DEFAULT_SOUND = 1,
SFX_FLAG_MP3 = 2,
SFX_FLAG_STREAMED = 4,
SFX_FLAG_NO_OFFSET = 8,
SFX_FLAG_NULL = 16,
};
enum loopsound_flags_t {
LOOPSOUND_FLAG_NO_PAN = 1
};
#define MAX_SFX 1400
#define MAX_SFX_INFOS 1000
#define MAX_LOOP_SOUNDS 64
extern qboolean s_bLastInitSound;
extern qboolean s_bSoundStarted;
extern qboolean s_bSoundPaused;
extern qboolean s_bTryUnpause;
extern int s_iListenerNumber;
extern float s_fAmbientVolume;
extern int number_of_sfx_infos;
extern sfx_info_t sfx_infos[];
extern sfx_t s_knownSfx[];
extern int s_numSfx;
extern s_entity_t s_entity[];
// The current sound driver.
// Currently OPENAL
#define SOUND_DRIVER OPENAL
//
// snd_info.cpp
//
void load_sfx_info();
//
// snd_dma_new.cpp
//
sfx_t *S_FindName(const char *name, int sequenceNumber);
void S_DefaultSound(sfx_t *sfx);
void S_LoadData(soundsystemsavegame_t *pSave);
void S_SaveData(soundsystemsavegame_t *pSave);
void S_ClearSoundBuffer();
//
// snd_mem.c
//
qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean force_load);
#define S_StopAllSounds2 S_StopAllSounds
//
// Driver-specific functions
//
#define S_Call_SndDriver(driver, func) S_##driver##_##func
#define S_Call_SndDriverX(driver, func) S_Call_SndDriver(driver, func)
#define S_Driver_Init S_Call_SndDriverX(SOUND_DRIVER, Init)
#define S_Driver_Shutdown S_Call_SndDriverX(SOUND_DRIVER, Shutdown)
#define S_Driver_StartSound S_Call_SndDriverX(SOUND_DRIVER, StartSound)
#define S_Driver_AddLoopingSound S_Call_SndDriverX(SOUND_DRIVER, AddLoopingSound)
#define S_Driver_ClearLoopingSounds S_Call_SndDriverX(SOUND_DRIVER, ClearLoopingSounds)
#define S_Driver_StopSound S_Call_SndDriverX(SOUND_DRIVER, StopSound)
#define S_Driver_StopAllSounds S_Call_SndDriverX(SOUND_DRIVER, StopAllSounds)
#define S_Driver_Respatialize S_Call_SndDriverX(SOUND_DRIVER, Respatialize)
#define S_Driver_SetReverb S_Call_SndDriverX(SOUND_DRIVER, SetReverb)
#define S_Driver_Update S_Call_SndDriverX(SOUND_DRIVER, Update)
#define S_Driver_GetMusicFilename S_Call_SndDriverX(SOUND_DRIVER, GetMusicFilename)
#define S_Driver_GetMusicLoopCount S_Call_SndDriverX(SOUND_DRIVER, GetMusicLoopCount)
#define S_Driver_GetMusicOffset S_Call_SndDriverX(SOUND_DRIVER, GetMusicOffset)
void S_PrintInfo();
void S_DumpInfo();
qboolean S_NeedFullRestart();
void S_ReLoad(soundsystemsavegame_t* pSave);
extern cvar_t *s_show_sounds;
#ifdef __cplusplus
}
#endif
+567
View File
@@ -0,0 +1,567 @@
/*
===========================================================================
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 "cl_ui.h"
byte *data_p;
byte *iff_end;
byte *last_chunk;
byte *iff_data;
int iff_chunk_len;
qboolean S_LoadMP3(const char *fileName, sfx_t *sfx);
/*
==============
GetLittleShort
==============
*/
short int GetLittleShort()
{
union {
short value;
byte bytes[2];
} val;
# ifdef Q3_LITTLE_ENDIAN
val.bytes[0] = data_p[0];
val.bytes[1] = data_p[1];
# else
val.bytes[0] = data_p[1];
val.bytes[1] = data_p[0];
# endif
data_p += sizeof(short);
return val.value;
}
/*
==============
GetLittleLong
==============
*/
int GetLittleLong()
{
union {
int value;
byte bytes[4];
} val;
# ifdef Q3_LITTLE_ENDIAN
val.bytes[0] = data_p[0];
val.bytes[1] = data_p[1];
val.bytes[2] = data_p[2];
val.bytes[3] = data_p[3];
# else
val.bytes[0] = data_p[3];
val.bytes[1] = data_p[2];
val.bytes[2] = data_p[1];
val.bytes[3] = data_p[0];
# endif
data_p += sizeof(int);
return val.value;
}
/*
==============
SetLittleShort
==============
*/
void SetLittleShort(int i)
{
union {
short value;
byte bytes[2];
} val;
val.value = i;
# ifdef Q3_LITTLE_ENDIAN
data_p[0] = val.bytes[0];
data_p[1] = val.bytes[1];
# else
data_p[0] = val.bytes[1];
data_p[1] = val.bytes[0];
# endif
data_p += sizeof(short);
}
/*
==============
SetLittleLong
==============
*/
void SetLittleLong(int i)
{
union {
int value;
byte bytes[4];
} val;
val.value = i;
# ifdef Q3_LITTLE_ENDIAN
data_p[0] = val.bytes[0];
data_p[1] = val.bytes[1];
data_p[2] = val.bytes[2];
data_p[3] = val.bytes[3];
# else
data_p[0] = val.bytes[3];
data_p[1] = val.bytes[2];
data_p[2] = val.bytes[1];
data_p[3] = val.bytes[0];
# endif
data_p += sizeof(int);
}
/*
==============
FindNextChunk
==============
*/
void FindNextChunk(const char *name)
{
int value;
while (1) {
data_p = last_chunk;
if (last_chunk >= (byte *)iff_end) {
break;
}
data_p = last_chunk + 4;
value = GetLittleLong();
iff_chunk_len = value;
if (value < 0) {
break;
}
data_p -= 8;
value++;
value &= ~1;
last_chunk = data_p + value + 8;
if (!strncmp((const char *)data_p, name, 4u)) {
return;
}
}
data_p = NULL;
}
/*
==============
FindChunk
==============
*/
void FindChunk(const char *name)
{
last_chunk = iff_data;
FindNextChunk(name);
}
/*
==============
DumpChunks
==============
*/
void DumpChunks()
{
char str[5];
str[4] = 0;
data_p = iff_data;
do {
memcpy(str, data_p, 4);
data_p += 4;
iff_chunk_len = GetLittleLong();
Com_Printf("0x%x : %s (%d)\n", data_p - 4, str, iff_chunk_len);
data_p += (iff_chunk_len + 1) & ~1;
} while (data_p < (byte *)iff_end);
}
/*
==============
GetWavinfo
==============
*/
wavinfo_t GetWavinfo(const char *name, byte *wav, int wavlength)
{
wavinfo_t info;
int samples;
memset(&info, 0, sizeof(wavinfo_t));
if (!wav) {
return info;
}
iff_data = wav;
iff_end = &wav[wavlength];
FindChunk("RIFF");
if (!data_p || strncmp((const char *)data_p + 8, "WAVE", 4u)) {
Com_Printf("Missing RIFF/WAVE chunks\n");
return info;
}
iff_data = data_p + 12;
FindChunk("fmt ");
if (!data_p) {
Com_Printf("Missing fmt chunk\n");
return info;
}
data_p += 8;
info.format = GetLittleShort();
if (info.format == 17) {
info.channels = GetLittleShort();
info.rate = (float)GetLittleLong();
data_p += 6;
info.width = (float)GetLittleShort() / 8.f;
data_p += 2;
FindChunk("data");
if (!data_p) {
Com_Printf("Missing data chunk\n");
return info;
}
data_p += 4;
if (info.width >= 1.0) {
samples = (int)((float)GetLittleLong() / info.width);
} else {
samples = (int)((float)GetLittleLong() * info.width);
}
if (!info.samples) {
info.samples = samples;
} else if (samples < info.samples) {
Com_Error(ERR_DROP, "Sound %s has a bad loop length", name);
}
info.dataofs = 0;
} else if (info.format == 1) {
info.channels = GetLittleShort();
info.rate = (float)GetLittleLong();
data_p += 6;
info.width = (float)(GetLittleShort() / 8);
FindChunk("data");
if (!data_p) {
Com_Printf("Missing data chunk\n");
return info;
}
data_p += 4;
samples = (float)GetLittleLong() / info.width;
if (!info.samples) {
info.samples = samples;
} else if (samples < info.samples) {
Com_Error(ERR_DROP, "Sound %s has a bad loop length", name);
}
info.dataofs = data_p - wav;
} else {
Com_Printf("Microsoft PCM format only\n");
return info;
}
info.datasize = iff_chunk_len;
return info;
}
/*
==============
DownSampleWav
==============
*/
qboolean DownSampleWav(wavinfo_t *info, byte *wav, int wavlength, int newkhz, byte **newdata)
{
int newdatasize;
byte* datap;
int i;
int ii;
int error;
int width;
int oldsamples;
int oldrate;
newdatasize = 0;
datap = &wav[info->dataofs];
if (info->channels > 1)
{
Com_DPrintf("Could not downsample WAV file. Stereo WAVs not supported!\n");
return 0;
}
if (info->format != 1 || !info->dataofs)
{
Com_DPrintf("Could not downsample WAV file. Not PCM format!\n");
return 0;
}
if (info->rate <= newkhz) {
return 0;
}
error = 0;
width = info->width;
for (i = 0; i < info->samples; i++) {
error += newkhz;
while (error > info->rate) {
error -= info->rate;
newdatasize += width;
}
}
oldsamples = info->samples;
oldrate = info->rate;
info->samples = newdatasize / width;
info->rate = (float)newkhz;
newdatasize += info->dataofs;
*newdata = (byte*)Z_TagMalloc(newdatasize, TAG_SOUND);
memcpy(*newdata, wav, info->dataofs);
iff_data = *newdata;
iff_end = *newdata + newdatasize;
FindChunk("RIFF");
if (!data_p || strncmp((const char*)data_p + 8, "WAVE", 4u))
{
Com_DPrintf("Missing RIFF/WAVE chunks\n");
return 0;
}
iff_data = data_p + 12;
FindChunk("fmt ");
if (!data_p)
{
Com_DPrintf("Missing fmt chunk\n");
return 0;
}
data_p += 12;
SetLittleShort((int)info->rate);
data_p += 8;
FindChunk("data");
if (!data_p)
{
Com_DPrintf("Missing data chunk\n");
return 0;
}
data_p += 4;
SetLittleLong((int)(info->samples * info->width));
error = 0;
for (i = 0; i < oldsamples; i++) {
error += newkhz;
while (error > oldrate) {
error -= oldrate;
for (ii = 0; ii < width; ii++) {
data_p[ii] = datap[ii];
}
data_p += width;
}
datap += width;
}
return newdatasize;
}
/*
==============
DownSampleWav_MILES
==============
*/
int DownSampleWav_MILES(wavinfo_t *info, byte *wav, int wavlength, int newkhz, byte **newdata)
{
//STUB_DESC("sound stuff");
//return 0;
// FIXME: unimplemented
// Fallback to software downsampling
return DownSampleWav(info, wav, wavlength, newkhz, newdata);
}
/*
==============
S_LoadSound
==============
*/
qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean force_load)
{
int size;
fileHandle_t file_handle;
char tempName[MAX_RES_NAME + 1];
int realKhz;
sfx->buffer = 0;
if (fileName[0] == '*') {
return qfalse;
}
if (streamed) {
//
// Added in 2.0
// Will be loaded next time
sfx->length = 5000;
sfx->width = 1;
sfx->iFlags |= SFX_FLAG_STREAMED;
sfx->time_length = 5000.0;
sfx->data = NULL;
return qtrue;
}
if (clc.state != CA_LOADING && !force_load) {
Com_Printf("**************S_LoadSound: %s\n", fileName);
}
if (strstr(fileName, ".mp3")) {
return S_LoadMP3(fileName, sfx);
}
size = FS_FOpenFileRead(fileName, &file_handle, qfalse, qtrue);
if (size <= 0)
{
if (file_handle) {
FS_FCloseFile(file_handle);
}
return qfalse;
}
sfx->data = (byte*)Z_TagMalloc(size, TAG_SOUND);
FS_Read(sfx->data, size, file_handle);
FS_FCloseFile(file_handle);
sfx->info = GetWavinfo(fileName, sfx->data, size);
if (sfx->info.channels != 1 && !streamed)
{
Com_Printf("%s is a stereo wav file\n", fileName);
Z_Free(sfx->data);
sfx->data = NULL;
return qfalse;
}
if (!sfx->info.dataofs) {
sfx->iFlags |= SFX_FLAG_NO_OFFSET;
}
switch (s_khz->integer) {
case 11:
realKhz = 11025;
break;
case 22:
default:
realKhz = 22050;
break;
case 44:
realKhz = 44100;
break;
}
if (!(sfx->iFlags & SFX_FLAG_STREAMED) && realKhz < sfx->info.rate) {
byte* newdata;
int newdatasize;
newdata = NULL;
if (sfx->iFlags & SFX_FLAG_NO_OFFSET) {
newdatasize = DownSampleWav_MILES(&sfx->info, sfx->data, size, realKhz, &newdata);
} else {
newdatasize = DownSampleWav(&sfx->info, sfx->data, size, realKhz, &newdata);
}
if (newdatasize) {
Z_Free(sfx->data);
sfx->data = newdata;
}
}
sfx->length = sfx->info.samples;
sfx->width = sfx->info.width;
sfx->time_length = sfx->info.samples / sfx->info.rate * 1000.f;
if (sfx->iFlags & SFX_FLAG_STREAMED) {
Z_Free(sfx->data);
sfx->data = NULL;
}
sprintf(tempName, "k%s", fileName);
UI_LoadResource(tempName);
if (strstr(fileName, "sound/null.wav")) {
sfx->iFlags |= SFX_FLAG_NULL;
return qtrue;
}
return qtrue;
}
/*
==============
S_LoadMP3
==============
*/
qboolean S_LoadMP3(const char *fileName, sfx_t *sfx)
{
int length;
fileHandle_t file_handle;
length = FS_FOpenFileRead(fileName, &file_handle, 0, 1);
if (length <= 0) {
if (file_handle) {
FS_FCloseFile(file_handle);
}
return qfalse;
}
memset(&sfx->info, 0, sizeof(sfx->info));
sfx->data = (byte*)Z_TagMalloc(length, TAG_SOUND);
sfx->length = length;
sfx->width = 1;
FS_Read(sfx->data, length, file_handle);
FS_FCloseFile(file_handle);
sfx->iFlags |= SFX_FLAG_MP3;
return qtrue;
}
+25
View File
@@ -0,0 +1,25 @@
/*
===========================================================================
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
===========================================================================
*/
// See the header file for information
#include "snd_miles_new.h"
+28
View File
@@ -0,0 +1,28 @@
/*
===========================================================================
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
===========================================================================
*/
//
// This file exists in the original source code.
// But this driver won't be implemented, as OpenAL is a better sound system!
//
#pragma once
File diff suppressed because it is too large. Load diff
+248
View File
@@ -0,0 +1,248 @@
/*
===========================================================================
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
===========================================================================
*/
#pragma once
#include "qal.h"
#undef OPENAL
typedef int S32;
typedef unsigned int U32;
#define MAX_OPENAL_CHANNELS_3D 32
#define MAX_OPENAL_CHANNELS_2D 32
#define MAX_OPENAL_CHANNELS_2D_STREAM 32
#define MAX_OPENAL_POSITION_CHANNELS (MAX_OPENAL_CHANNELS_3D + MAX_OPENAL_CHANNELS_2D + MAX_OPENAL_CHANNELS_2D_STREAM)
#define MAX_OPENAL_SONGS 2
#define MAX_OPENAL_MISC_CHANNELS 3
#define MAX_OPENAL_CHANNELS \
(MAX_OPENAL_CHANNELS_3D + MAX_OPENAL_CHANNELS_2D + MAX_OPENAL_CHANNELS_2D_STREAM + MAX_OPENAL_SONGS \
+ MAX_OPENAL_MISC_CHANNELS)
#define MAX_OPENAL_LOOP_SOUNDS 64
#define OPENAL_CHANNEL_MP3_ID \
(MAX_OPENAL_CHANNELS_3D + MAX_OPENAL_CHANNELS_2D + MAX_OPENAL_CHANNELS_2D_STREAM + MAX_OPENAL_SONGS)
#define OPENAL_CHANNEL_TRIGGER_MUSIC_ID (OPENAL_CHANNEL_MP3_ID + 1)
#define OPENAL_CHANNEL_MOVIE_ID (OPENAL_CHANNEL_TRIGGER_MUSIC_ID + 1)
#define MAX_STREAM_BUFFERS 16
#define MAX_BUFFER_SAMPLES 16384
typedef enum {
FADE_NONE,
FADE_IN,
FADE_OUT
} fade_t;
typedef struct {
vec3_t vOrigin;
vec3_t vRelativeOrigin;
vec3_t vVelocity;
sfx_t *pSfx;
qboolean bPlaying;
int iChannel;
float fVolume;
float fPitch;
int iStartTime;
qboolean bInUse;
qboolean bCombine;
float fBaseVolume;
float fMinDist;
float fMaxDist;
int iFlags;
} openal_loop_sound_t;
struct openal_channel {
sfx_t *pSfx;
int iEntNum;
int iEntChannel;
vec3_t vOrigin;
float fVolume;
int iBaseRate;
float fNewPitchMult;
float fMinDist;
float fMaxDist;
int iStartTime;
int iTime;
int iEndTime;
int iFlags;
int iPausedOffset;
int song_number;
fade_t fading;
int fade_time;
int fade_start_time;
ALuint source;
ALuint buffer;
ALubyte *bufferdata;
public:
void play();
virtual void stop();
void pause();
void set_no_3d();
void set_3d();
void set_gain(float gain);
void set_velocity(float v0, float v1, float v2);
void set_position(float v0, float v1, float v2);
bool is_free();
bool is_paused();
bool is_playing();
void force_free();
virtual bool set_sfx(sfx_t *pSfx);
void start_sample();
void stop_sample();
void resume_sample();
void end_sample();
void set_sample_pan(S32 pan);
void set_sample_playback_rate(S32 pan);
S32 sample_playback_rate();
S32 sample_volume();
virtual U32 sample_offset();
U32 sample_ms_offset();
U32 sample_loop_count();
virtual void set_sample_offset(U32 offset);
void set_sample_ms_offset(U32 offset);
virtual void set_sample_loop_count(S32 count);
void set_sample_loop_block(S32 start_offset, S32 end_offset);
U32 sample_status();
public:
virtual void update();
virtual U32 buffer_frequency() const;
};
struct openal_channel_two_d_stream : public openal_channel {
private:
char fileName[64];
void *streamHandle;
unsigned int buffers[MAX_STREAM_BUFFERS];
unsigned int currentBuf;
unsigned int sampleLoopCount;
unsigned int sampleLooped;
unsigned int streamNextOffset;
bool streaming;
public:
openal_channel_two_d_stream();
~openal_channel_two_d_stream();
void stop() override;
bool set_sfx(sfx_t *pSfx) override;
void set_sample_loop_count(S32 count) override;
void update() override;
U32 sample_offset() override;
void set_sample_offset(U32 offset) override;
bool queue_stream(const char *fileName);
protected:
U32 buffer_frequency() const override;
private:
void clear_stream();
unsigned int getQueueLength() const;
unsigned int getCurrentStreamPosition() const;
unsigned int getBytesPerSample() const;
};
struct openal_internal_t {
openal_channel chan_3D[MAX_OPENAL_CHANNELS_3D];
openal_channel chan_2D[MAX_OPENAL_CHANNELS_2D];
openal_channel_two_d_stream chan_2D_stream[MAX_OPENAL_CHANNELS_2D_STREAM];
openal_channel_two_d_stream chan_song[MAX_OPENAL_SONGS];
openal_channel_two_d_stream chan_mp3;
openal_channel_two_d_stream chan_trig_music;
openal_channel_two_d_stream chan_movie;
// Pointers to channels
openal_channel *channel[MAX_OPENAL_CHANNELS];
openal_loop_sound_t loop_sounds[MAX_OPENAL_LOOP_SOUNDS];
openal_channel movieChannel;
sfx_t movieSFX;
char tm_filename[MAX_RES_NAME];
int tm_loopcount;
};
#ifdef __cplusplus
extern "C" {
#endif
qboolean S_OPENAL_Init();
void S_OPENAL_Shutdown();
void S_OPENAL_StartSound(
const vec3_t vOrigin,
int iEntNum,
int iEntChannel,
sfxHandle_t sfxHandle,
float fVolume,
float fMinDist,
float fPitch,
float fMaxDist,
qboolean bStreamed
);
void S_OPENAL_AddLoopingSound(
const vec3_t vOrigin,
const vec3_t vVelocity,
sfxHandle_t sfxHandle,
float fVolume,
float fMinDist,
float fMaxDist,
float fPitch,
int iFlags
);
void S_OPENAL_ClearLoopingSounds();
void S_OPENAL_StopSound(int iEntNum, int iEntChannel);
void S_OPENAL_StopAllSounds(qboolean bStopMusic);
void S_OPENAL_Respatialize(int iEntNum, const vec3_t vHeadPos, const vec3_t vAxis[3]);
void S_OPENAL_SetReverb(int iType, float fLevel);
void S_OPENAL_Update();
const char *S_OPENAL_GetMusicFilename();
int S_OPENAL_GetMusicLoopCount();
unsigned int S_OPENAL_GetMusicOffset();
#ifdef __cplusplus
}
#endif
+77
View File
@@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#if defined(NO_MODERN_DMA) && NO_MODERN_DMA
#ifdef __cplusplus
extern "C" {
#endif
@@ -89,3 +91,78 @@ void S_MasterGain(float gain);
#endif
#include "new/snd_public_new.h"
#else
#ifdef __cplusplus
extern "C" {
#endif
void S_SoundInfo_f();
void S_SoundDump_f();
void S_Init(qboolean full_startup);
void S_Shutdown(qboolean full_shutdown);
qboolean S_NameExists(const char* name);
void S_BeginRegistration();
qboolean S_IsSoundRegistered(const char* name);
sfxHandle_t S_RegisterSound(const char* name, int streamed, qboolean force_load);
float S_GetSoundTime(sfxHandle_t handle);
void S_EndRegistration();
void S_UpdateEntity(int entityNum, const vec3_t origin, const vec3_t vel, qboolean use_listener);
void S_SetGlobalAmbientVolumeLevel(float volume);
void S_StartSound(const vec3_t origin, int entnum, int entchannel, sfxHandle_t sfxHandle, float volume, float min_dist, float pitch, float maxDist, int streamed);
void S_StartLocalSound(const char* sound_name, qboolean force_load);
void S_StartLocalSoundChannel(const char* sound_name, qboolean force_load, soundChannel_t channel);
void S_StopAllSounds(qboolean stop_music);
void S_ClearLoopingSounds();
void S_AddLoopingSound(const vec3_t origin, const vec3_t velocity, sfxHandle_t sfxHandle, float volume, float min_dist, float max_dist, float pitch, int flags);
void S_Respatialize(int entityNum, const vec3_t head, vec3_t axis[3]);
void S_Update();
void S_StopSound(int entnum, int channel);
void S_SetReverb(int reverb_type, float reverb_level);
void S_Play();
void S_SoundList();
qboolean S_IsSoundPlaying(int channel_number, const char* sfxName);
void S_FadeSound(float fTime);
qboolean MUSIC_LoadSoundtrackFile(const char* filename);
qboolean MUSIC_SongValid(const char* mood);
qboolean MUSIC_Loaded();
void Music_Update();
void MUSIC_SongEnded();
void MUSIC_NewSoundtrack(const char* name);
void MUSIC_UpdateMood(int current, int fallback);
void MUSIC_UpdateVolume(float volume, float fade_time);
void MUSIC_StopAllSongs();
void MUSIC_FreeAllSongs();
qboolean MUSIC_Playing();
int MUSIC_FindSong(const char* name);
void S_loadsoundtrack();
const char* S_CurrentSoundtrack();
void S_PlaySong();
int MUSIC_CurrentSongChannel();
void MUSIC_StopChannel(int channel_number);
qboolean MUSIC_PlaySong(const char* alias);
void MUSIC_UpdateMusicVolumes();
void MUSIC_CheckForStoppedSongs();
void S_TriggeredMusic_SetupHandle(const char* pszName, int iLoopCount, int iOffset, qboolean autostart);
void S_TriggeredMusic_Start();
void S_TriggeredMusic_StartLoop();
void S_TriggeredMusic_Stop();
void S_TriggeredMusic_Pause();
void S_TriggeredMusic_Unpause();
void S_TriggeredMusic_PlayIntroMusic();
void S_StopMovieAudio();
void S_SetupMovieAudio(const char* pszMovieName);
int S_CurrentMoviePosition();
const char* S_GetMusicFilename();
int S_GetMusicLoopCount();
unsigned int S_GetMusicOffset();
#ifdef __cplusplus
}
#endif
#endif
+138 -13
View File
@@ -80,7 +80,8 @@ Event EV_PG_MaxDuration
"Sets the maximum duration of bursts(in seconds)\nDefault=3",
EV_NORMAL
);
Event EV_PG_MinNumShots(
Event EV_PG_MinNumShots
(
"MinNumShots",
EV_DEFAULT,
"i",
@@ -88,7 +89,8 @@ Event EV_PG_MinNumShots(
"Sets the minimum # of shots to fire in a cycle\nDefault=1",
EV_NORMAL
);
Event EV_PG_MaxNumShots(
Event EV_PG_MaxNumShots
(
"MaxNumShots",
EV_DEFAULT,
"i",
@@ -275,7 +277,8 @@ Event EV_PG_SetPreImpactSoundTime
"Set the time before impact to play the preimpact sound.",
EV_NORMAL
);
Event EV_PG_SetPreImpactSoundProbability(
Event EV_PG_SetPreImpactSoundProbability
(
"preimpactsoundprob",
EV_DEFAULT,
"f",
@@ -492,6 +495,7 @@ void ProjectileGenerator::TurnOn(Event *ev)
if (!m_bIsTurnedOn) {
CancelEventsOfType(EV_PG_BeginCycle);
CancelEventsOfType(EV_TickCycle);
SetupNextCycle();
m_bIsTurnedOn = true;
}
}
@@ -519,6 +523,7 @@ void ProjectileGenerator::SetupNextCycle()
// get a random delay
m_fShotsPerSec = numShots / m_fCycleTime;
delay = 0.01f;
if (m_bIsTurnedOn || !m_bFireOnStartUp) {
delay = G_Random(m_fMaxDelay - m_fMinDelay) + m_fMinDelay;
}
@@ -1571,8 +1576,8 @@ Event EV_SetTriggered
"triggered",
EV_DEFAULT,
"i",
"0 or 1",
"Set the triggered status",
"triggered",
"Set the triggered status (0 or 1)",
EV_NORMAL
);
Event EV_SetExplosionEffect
@@ -1580,7 +1585,7 @@ Event EV_SetExplosionEffect
"explosioneffect",
EV_DEFAULT,
"s",
"effect model",
"effectModel",
"Set the explosion effect model",
EV_NORMAL
);
@@ -1589,7 +1594,7 @@ Event EV_SetExplosionOffset
"explosionoffset",
EV_DEFAULT,
"v",
"offset vector",
"offset",
"Set the explosion offset",
EV_NORMAL
);
@@ -1986,6 +1991,26 @@ CLASS_DECLARATION(ThrobbingBox_Explosive, ThrobbingBox_Stickybomb, "ThrobbingBox
{NULL, NULL }
};
ThrobbingBox_Stickybomb::ThrobbingBox_Stickybomb()
{
if (LoadingSavegame) {
return;
}
setModel("items/pulse_stickybomb.tik");
m_sUsedModel = "items/stickybomb.tik";
m_sSound = "explode_flak88";
m_sActivateSound = "stickybomb_plant";
m_sTickSound = "stickybomb_fuse";
health = 10;
m_fStopwatchStartTime = 0;
setSolidType(SOLID_BBOX);
takedamage = DAMAGE_NO;
setContents(CONTENTS_WEAPONCLIP);
}
void ThrobbingBox_Stickybomb::OnStickyBombWet(Event *ev)
{
Player *player;
@@ -2193,10 +2218,110 @@ int Objective::GetObjectiveIndex() const
*/
CLASS_DECLARATION(Entity, FencePost, "func_fencepost") {
{&EV_Killed, NULL},
{NULL, NULL}
{&EV_Killed, &FencePost::Killed},
{NULL, NULL }
};
FencePost::FencePost()
{
max_health = 20;
health = 20;
damage_type = MOD_AAGUN;
if (!LoadingSavegame) {
PostEvent(EV_BecomeSolid, EV_POSTSPAWN);
}
takedamage = DAMAGE_YES;
}
void FencePost::Killed(Event *ev)
{
Vector vMins, vMaxs;
Vector vStart, vEnd;
Vector vCenter;
float fHalf;
vCenter = mins - maxs;
vCenter *= 0.5;
if (size.x > size.y) {
if (size.x > size.z) {
if (size.y > size.z) {
fHalf = size.y / 2.f;
} else {
fHalf = size.z / 2.f;
}
vMins[0] = mins[0];
vMaxs[0] = maxs[0];
vMins[1] = vCenter[1];
vMaxs[1] = vCenter[1];
vMins[2] = vCenter[2];
vMaxs[2] = vCenter[2];
} else {
fHalf = size.x / 2.f;
vMins[2] = mins[2];
vMaxs[2] = maxs[2];
vMins[1] = vCenter[1];
vMaxs[1] = vCenter[1];
vMins[0] = vCenter[0];
vMaxs[0] = vCenter[0];
}
} else {
if (size.y > size.z) {
if (size.x > size.z) {
fHalf = size.x / 2.f;
} else {
fHalf = size.z / 2.f;
}
vMins[1] = mins[1];
vMaxs[1] = maxs[1];
vMins[0] = vCenter[0];
vMaxs[0] = vCenter[0];
vMins[2] = vCenter[2];
vMaxs[2] = vCenter[2];
} else {
fHalf = size.y / 2.f;
vMins[2] = mins[2];
vMaxs[2] = maxs[2];
vMins[1] = vCenter[1];
vMaxs[1] = vCenter[1];
vMins[0] = vCenter[0];
vMaxs[0] = vCenter[0];
}
}
MatrixTransformVector(vMins, orientation, vStart);
MatrixTransformVector(vMaxs, orientation, vEnd);
vStart += origin;
vEnd += origin;
if (fHalf > 255) {
fHalf = 255;
}
gi.SetBroadcastVisible(vStart, vEnd);
gi.MSG_StartCGM(CGM_FENCEPOST);
gi.MSG_WriteCoord(vStart[0]);
gi.MSG_WriteCoord(vStart[1]);
gi.MSG_WriteCoord(vStart[2]);
gi.MSG_WriteCoord(vEnd[0]);
gi.MSG_WriteCoord(vEnd[1]);
gi.MSG_WriteCoord(vEnd[2]);
gi.MSG_WriteByte((int)fHalf);
gi.MSG_WriteByte(0);
gi.MSG_EndCGM();
deadflag = DEAD_DEAD;
PostEvent(EV_Remove, 0);
}
Event EV_SetEnemyName
(
"enemyname",
@@ -2213,7 +2338,7 @@ Event EV_SetEnemyName2
"s",
"enemyname",
"",
EV_GETTER
EV_SETTER
);
Event EV_GetEnemyName
(
@@ -2222,7 +2347,7 @@ Event EV_GetEnemyName
"s",
"enemyname",
"",
EV_SETTER
EV_GETTER
);
Event EV_Sentient_GetDontDropWeapons
(
@@ -2538,12 +2663,12 @@ void AISpawnPoint::SetFov(Event *ev)
void AISpawnPoint::SetSight(Event *ev)
{
ev->AddFloat(m_fSight);
m_fSight = ev->GetFloat(1);
}
void AISpawnPoint::GetSight(Event *ev)
{
m_fSight = ev->GetFloat(1);
ev->AddFloat(m_fSight);
}
void AISpawnPoint::GetHearing(Event *ev)
+36 -30
View File
@@ -26,19 +26,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "animate.h"
typedef enum {
CONTROLLER_ALLIES,
CONTROLLER_AXIS,
CONTROLLER_ALLIES,
CONTROLLER_AXIS,
CONTROLLER_DRAW
} eController;
#define PT_SPAWNFLAG_PLAY_FIRE_SOUND 1
#define PT_SPAWNFLAG_PLAY_MOTION_SOUND 2
#define PT_SPAWNFLAG_TARGET_RANDOM 4
#define PT_SPAWNFLAG_TURN_ON 8
#define PT_SPAWNFLAG_ROTATE_YAW 16
#define PT_SPAWNFLAG_ROTATE_ROLL 32
#define PT_SPAWNFLAG_TARGET_PLAYER 64
#define PT_SPAWNFLAG_HIDDEN 128
#define PT_SPAWNFLAG_PLAY_FIRE_SOUND 1
#define PT_SPAWNFLAG_PLAY_MOTION_SOUND 2
#define PT_SPAWNFLAG_TARGET_RANDOM 4
#define PT_SPAWNFLAG_TURN_ON 8
#define PT_SPAWNFLAG_ROTATE_YAW 16
#define PT_SPAWNFLAG_ROTATE_ROLL 32
#define PT_SPAWNFLAG_TARGET_PLAYER 64
#define PT_SPAWNFLAG_HIDDEN 128
void ClearProjectileTargets();
@@ -53,7 +53,7 @@ public:
ProjectileTarget();
void EventSetId(Event *ev);
int GetTarget() const;
int GetTarget() const;
};
#define MAX_PROJECTILE_GENERATOR_TARGETS 16
@@ -106,16 +106,16 @@ public:
bool ShouldRotateYaw() const;
bool ShouldRotateRoll() const;
void EventIsTurnedOn(Event *ev);
void EventGetTargetEntity(Event *ev);
void EventLaunchSound(Event *ev);
void SetTarget(Event *ev);
void SetTarget(Entity* ent);
void OnInitialize(Event *ev);
void TurnOff(Event *ev);
void TurnOn(Event *ev);
bool ShouldTargetRandom() const;
Entity* ChooseTarget();
void EventIsTurnedOn(Event *ev);
void EventGetTargetEntity(Event *ev);
void EventLaunchSound(Event *ev);
void SetTarget(Event *ev);
void SetTarget(Entity *ent);
void OnInitialize(Event *ev);
void TurnOff(Event *ev);
void TurnOn(Event *ev);
bool ShouldTargetRandom() const;
Entity *ChooseTarget();
void GetLocalTargets();
bool ShouldTargetPlayer() const;
@@ -123,7 +123,7 @@ public:
void GetMuzzlePos(Vector& pos);
void Fire();
void TryLaunchSound();
void SetWeaponAnim(const char* name, Event* ev);
void SetWeaponAnim(const char *name, Event *ev);
void EventAccuracy(Event *ev);
void EventMaxDelay(Event *ev);
void EventMinDelay(Event *ev);
@@ -134,11 +134,11 @@ public:
void EventMaxDuration(Event *ev);
void EventMinDuration(Event *ev);
void SetWeaponModel(Event *ev);
void EventSetId(Event* ev);
void EventmaxDonut(Event* ev);
void EventminDonut(Event* ev);
void EventarcDonut(Event* ev);
void EventisDonut(Event* ev);
void EventSetId(Event *ev);
void EventmaxDonut(Event *ev);
void EventminDonut(Event *ev);
void EventarcDonut(Event *ev);
void EventisDonut(Event *ev);
virtual bool Attack(int count);
void Archive(Archiver& arc) override;
@@ -164,8 +164,8 @@ public:
void SetProjectileModel(Event *ev);
float EstimateImpactTime(const Vector& targetOrigin, const Vector& fromOrigin, float speed) const;
bool Attack(int count) override;
void Archive(Archiver& arc) override;
bool Attack(int count) override;
void Archive(Archiver& arc) override;
};
class ProjectileGenerator_Gun : public ProjectileGenerator
@@ -306,6 +306,8 @@ private:
public:
CLASS_PROTOTYPE(ThrobbingBox_Stickybomb);
ThrobbingBox_Stickybomb();
void OnStickyBombWet(Event *ev);
void OnStickyBombUse(Event *ev);
@@ -325,7 +327,7 @@ public:
Objective();
void Archive(Archiver &arc) override;
void Archive(Archiver& arc) override;
void TurnOn(Event *ev);
void TurnOff(Event *ev);
void Complete(Event *ev);
@@ -340,6 +342,10 @@ class FencePost : public Entity
{
public:
CLASS_PROTOTYPE(FencePost);
FencePost();
void Killed(Event* ev) override;
};
class AISpawnPoint : public SimpleArchivedEntity
+53 -45
View File
@@ -24,69 +24,77 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "VehicleCollisionEntity.h"
#include "g_phys.h"
CLASS_DECLARATION( Entity, VehicleCollisionEntity, NULL )
{
{ &EV_Damage, &VehicleCollisionEntity::EventDamage },
{ NULL, NULL }
Event EV_Owner
(
"owner",
EV_DEFAULT,
NULL,
NULL,
"owner",
EV_GETTER
);
CLASS_DECLARATION(Entity, VehicleCollisionEntity, NULL) {
{&EV_Damage, &VehicleCollisionEntity::EventDamage},
{&EV_Owner, &VehicleCollisionEntity::GetOwner },
{NULL, NULL }
};
VehicleCollisionEntity::VehicleCollisionEntity
(
Entity *ent
)
VehicleCollisionEntity::VehicleCollisionEntity(Entity *ent)
{
if( LoadingSavegame )
{
return;
}
if (LoadingSavegame) {
return;
}
edict->s.eType = ET_GENERAL;
edict->s.eType = ET_GENERAL;
m_pOwner = ent;
takedamage = DAMAGE_YES;
m_pOwner = ent;
takedamage = DAMAGE_YES;
showModel();
setMoveType( MOVETYPE_PUSH );
setSolidType(SOLID_NOT);
showModel();
setMoveType(MOVETYPE_PUSH);
setSolidType(SOLID_NOT);
edict->clipmask |= MASK_VEHICLE;
edict->s.eFlags |= EF_LINKANGLES;
edict->clipmask |= MASK_VEHICLE;
edict->s.eFlags |= EF_LINKANGLES;
}
VehicleCollisionEntity::VehicleCollisionEntity
(
void
)
VehicleCollisionEntity::VehicleCollisionEntity(void)
{
if( LoadingSavegame )
{
return;
}
if (LoadingSavegame) {
return;
}
gi.Error( ERR_DROP, "VehicleCollisionEntity Created with no parameters!\n" );
gi.Error(ERR_DROP, "VehicleCollisionEntity Created with no parameters!\n");
}
void VehicleCollisionEntity::EventDamage
(
Event *ev
)
void VehicleCollisionEntity::GetOwner(Event *ev)
{
m_pOwner->ProcessEvent(*ev);
ev->AddListener(m_pOwner);
}
void VehicleCollisionEntity::Solid
(
void
)
void VehicleCollisionEntity::Solid(void)
{
setContents( CONTENTS_SOLID );
setSolidType( SOLID_BSP );
setContents(CONTENTS_SOLID);
setSolidType(SOLID_BSP);
}
void VehicleCollisionEntity::NotSolid
(
void
)
void VehicleCollisionEntity::NotSolid(void)
{
setSolidType( SOLID_NOT );
setSolidType(SOLID_NOT);
}
void VehicleCollisionEntity::EventDamage(Event *ev)
{
m_pOwner->ProcessEvent(*ev);
}
void VehicleCollisionEntity::Used(Event *ev)
{
m_pOwner->ProcessEvent(*ev);
}
Entity *VehicleCollisionEntity::GetOwner() const
{
return m_pOwner;
}
+15 -19
View File
@@ -21,40 +21,36 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// VehicleCollisionEntity.h : MOHAA vehicle collision
#ifndef __VEHICLECOLLISIONENTITY_H__
#define __VEHICLECOLLISIONENTITY_H__
#pragma once
#include "entity.h"
class VehicleCollisionEntity : public Entity
{
private:
EntityPtr m_pOwner;
EntityPtr m_pOwner;
private:
void EventDamage( Event *ev );
void EventDamage(Event *ev);
void GetOwner(Event *ev);
void Used(Event *ev);
public:
CLASS_PROTOTYPE( VehicleCollisionEntity );
CLASS_PROTOTYPE(VehicleCollisionEntity);
VehicleCollisionEntity( Entity *ent );
VehicleCollisionEntity();
VehicleCollisionEntity(Entity *ent);
VehicleCollisionEntity();
void Archive( Archiver& arc ) override;
void Archive(Archiver& arc) override;
void Solid( void );
void NotSolid( void );
void Solid(void);
void NotSolid(void);
Entity *GetOwner() const;
};
inline
void VehicleCollisionEntity::Archive
(
Archiver& arc
)
inline void VehicleCollisionEntity::Archive(Archiver& arc)
{
Entity::Archive( arc );
Entity::Archive(arc);
arc.ArchiveSafePointer( &m_pOwner );
arc.ArchiveSafePointer(&m_pOwner);
}
#endif // __VEHICLECOLLISIONENTITY_H__
+85 -116
View File
@@ -26,159 +26,128 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "vehicle.h"
Event EV_VehicleSoundEntity_PostSpawn
(
"vehiclesoundentity_post",
EV_DEFAULT,
NULL,
NULL,
"PostSpawn of a Vehicle Sound Entity"
);
(
"vehiclesoundentity_post",
EV_DEFAULT,
NULL,
NULL,
"PostSpawn of a Vehicle Sound Entity"
);
Event EV_VehicleSoundEntity_UpdateTraces
(
"vehiclesoudnentity_updatetraces",
EV_DEFAULT,
NULL,
NULL,
"Updates the traces of a Vehicle Sound Entity"
);
(
"vehiclesoudnentity_updatetraces",
EV_DEFAULT,
NULL,
NULL,
"Updates the traces of a Vehicle Sound Entity"
);
CLASS_DECLARATION( Entity, VehicleSoundEntity, NULL )
{
{ &EV_VehicleSoundEntity_PostSpawn, &VehicleSoundEntity::EventPostSpawn },
{ &EV_VehicleSoundEntity_UpdateTraces, &VehicleSoundEntity::EventUpdateTraces },
{ NULL, NULL }
CLASS_DECLARATION(Entity, VehicleSoundEntity, NULL) {
{&EV_VehicleSoundEntity_PostSpawn, &VehicleSoundEntity::EventPostSpawn },
{&EV_VehicleSoundEntity_UpdateTraces, &VehicleSoundEntity::EventUpdateTraces},
{NULL, NULL }
};
VehicleSoundEntity::VehicleSoundEntity()
{
if( LoadingSavegame )
{
return;
}
if (LoadingSavegame) {
return;
}
gi.Error( ERR_DROP, "VehicleSoundEntity Created with no parameters!\n" );
gi.Error(ERR_DROP, "VehicleSoundEntity Created with no parameters!\n");
}
VehicleSoundEntity::VehicleSoundEntity( Vehicle *owner )
VehicleSoundEntity::VehicleSoundEntity(Vehicle *owner)
{
m_pVehicle = owner;
m_bDoSoundStuff = false;
m_iTraceSurfaceFlags = 0;
m_pVehicle = owner;
m_bDoSoundStuff = false;
m_iTraceSurfaceFlags = 0;
PostEvent( EV_VehicleSoundEntity_PostSpawn, EV_POSTSPAWN );
PostEvent(EV_VehicleSoundEntity_PostSpawn, EV_POSTSPAWN);
}
void VehicleSoundEntity::Start
(
void
)
void VehicleSoundEntity::Start(void)
{
m_bDoSoundStuff = true;
m_bDoSoundStuff = true;
}
void VehicleSoundEntity::Stop
(
void
)
void VehicleSoundEntity::Stop(void)
{
m_bDoSoundStuff = false;
m_bDoSoundStuff = false;
}
void VehicleSoundEntity::Think
(
void
)
void VehicleSoundEntity::Think(void)
{
DoSoundStuff();
DoSoundStuff();
}
void VehicleSoundEntity::EventPostSpawn
(
Event *ev
)
void VehicleSoundEntity::EventPostSpawn(Event *ev)
{
setModel( "models/vehicles/vehiclesoundentity.tik" );
setModel("models/vehicles/vehiclesoundentity.tik");
PostEvent( EV_VehicleSoundEntity_UpdateTraces, 1.0f );
flags |= FL_THINK;
PostEvent(EV_VehicleSoundEntity_UpdateTraces, 1.0f);
flags |= FL_THINK;
}
void VehicleSoundEntity::EventUpdateTraces
(
Event *ev
)
void VehicleSoundEntity::EventUpdateTraces(Event *ev)
{
if( m_bDoSoundStuff )
{
m_pVehicle->SetSlotsNonSolid();
if (m_bDoSoundStuff) {
m_pVehicle->SetSlotsNonSolid();
trace_t trace = G_Trace(
origin,
vec3_origin,
vec3_origin,
Vector( origin[ 0 ], origin[ 1 ], origin[ 2 ] - 256.0f ),
m_pVehicle->edict,
MASK_SOUND,
qfalse,
"VehicleSoundEntity::DoSoundStuff"
);
trace_t trace = G_Trace(
origin,
vec3_origin,
vec3_origin,
Vector(origin[0], origin[1], origin[2] - 256.0f),
m_pVehicle->edict,
MASK_SOUND,
qfalse,
"VehicleSoundEntity::DoSoundStuff"
);
if( trace.fraction >= 1.0f )
m_iTraceSurfaceFlags = 0;
else
m_iTraceSurfaceFlags = trace.surfaceFlags;
if (trace.fraction >= 1.0f) {
m_iTraceSurfaceFlags = 0;
} else {
m_iTraceSurfaceFlags = trace.surfaceFlags;
}
m_pVehicle->SetSlotsSolid();
}
m_pVehicle->SetSlotsSolid();
}
PostEvent( EV_VehicleSoundEntity_UpdateTraces, 1.0f );
PostEvent(EV_VehicleSoundEntity_UpdateTraces, 1.0f);
}
void VehicleSoundEntity::DoSoundStuff
(
void
)
void VehicleSoundEntity::DoSoundStuff(void)
{
float pitch;
float pitch;
if( !m_bDoSoundStuff )
{
StopLoopSound();
return;
}
if (!m_bDoSoundStuff) {
StopLoopSound();
return;
}
pitch = ( velocity.length() - m_pVehicle->m_fSoundMinSpeed ) / ( m_pVehicle->m_fSoundMaxSpeed - m_pVehicle->m_fSoundMinSpeed );
if( pitch > 1.0f ) {
pitch = 1.0f;
} else if( pitch < 0.0f ) {
pitch = 0.0f;
}
pitch = (velocity.length() - m_pVehicle->m_fSoundMinSpeed)
/ (m_pVehicle->m_fSoundMaxSpeed - m_pVehicle->m_fSoundMinSpeed);
if (pitch > 1.0f) {
pitch = 1.0f;
} else if (pitch < 0.0f) {
pitch = 0.0f;
}
pitch *= m_pVehicle->m_fSoundMinPitch + ( m_pVehicle->m_fSoundMaxPitch - m_pVehicle->m_fSoundMinPitch );
pitch *= m_pVehicle->m_fSoundMinPitch + (m_pVehicle->m_fSoundMaxPitch - m_pVehicle->m_fSoundMinPitch);
if( m_iTraceSurfaceFlags & SURF_DIRT )
{
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_dirt", -1.0f, -1.0f, -1.0f, pitch );
}
else if( m_iTraceSurfaceFlags & SURF_GRASS )
{
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_grass", -1.0f, -1.0f, -1.0f, pitch );
}
else if( m_iTraceSurfaceFlags & SURF_WOOD )
{
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_wood", -1.0f, -1.0f, -1.0f, pitch );
}
else if( m_iTraceSurfaceFlags & SURF_MUD )
{
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_mud", -1.0f, -1.0f, -1.0f, pitch );
}
else if( m_iTraceSurfaceFlags & ( SURF_GRAVEL | SURF_ROCK ) )
{
LoopSound( m_pVehicle->m_sSoundSet + "treat_snd_stone", -1.0f, -1.0f, -1.0f, pitch );
}
else
{
StopLoopSound();
}
if (m_iTraceSurfaceFlags & SURF_DIRT) {
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_dirt", -1.0f, -1.0f, -1.0f, pitch);
} else if (m_iTraceSurfaceFlags & SURF_GRASS) {
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_grass", -1.0f, -1.0f, -1.0f, pitch);
} else if (m_iTraceSurfaceFlags & SURF_WOOD) {
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_wood", -1.0f, -1.0f, -1.0f, pitch);
} else if (m_iTraceSurfaceFlags & SURF_MUD) {
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_mud", -1.0f, -1.0f, -1.0f, pitch);
} else if (m_iTraceSurfaceFlags & (SURF_GRAVEL | SURF_ROCK) || m_iTraceSurfaceFlags == 0) {
LoopSound(m_pVehicle->m_sSoundSet + "tread_snd_stone", -1.0f, -1.0f, -1.0f, pitch);
} else {
StopLoopSound();
}
}
+21 -27
View File
@@ -21,47 +21,41 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// VehicleSoundEntity.h : Sound helper for vehicles
#ifndef __VEHICLESOUNDENTITY_H__
#define __VEHICLESOUNDENTITY_H__
#pragma once
#include "entity.h"
class Vehicle;
class VehicleSoundEntity : public Entity {
class VehicleSoundEntity : public Entity
{
private:
SafePtr<Vehicle> m_pVehicle;
bool m_bDoSoundStuff;
int m_iTraceSurfaceFlags;
SafePtr<Vehicle> m_pVehicle;
bool m_bDoSoundStuff;
int m_iTraceSurfaceFlags;
public:
CLASS_PROTOTYPE( VehicleSoundEntity );
CLASS_PROTOTYPE(VehicleSoundEntity);
VehicleSoundEntity();
VehicleSoundEntity( Vehicle *owner );
VehicleSoundEntity();
VehicleSoundEntity(Vehicle *owner);
void Start( void );
void Stop( void );
void Think( void ) override;
void Archive( Archiver& arc ) override;
void Start(void);
void Stop(void);
void Think(void) override;
void Archive(Archiver& arc) override;
private:
void EventPostSpawn( Event *ev );
void EventUpdateTraces( Event *ev );
void DoSoundStuff( void );
void EventPostSpawn(Event *ev);
void EventUpdateTraces(Event *ev);
void DoSoundStuff(void);
};
inline
void VehicleSoundEntity::Archive
(
Archiver& arc
)
inline void VehicleSoundEntity::Archive(Archiver& arc)
{
Entity::Archive( arc );
Entity::Archive(arc);
arc.ArchiveSafePointer( &m_pVehicle );
arc.ArchiveBool( &m_bDoSoundStuff );
arc.ArchiveInteger( &m_iTraceSurfaceFlags );
arc.ArchiveSafePointer(&m_pVehicle);
arc.ArchiveBool(&m_bDoSoundStuff);
arc.ArchiveInteger(&m_iTraceSurfaceFlags);
}
#endif // __VEHICLECOLLISIONENTITY_H__
+969 -56
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -1714,7 +1714,7 @@ inline bool Actor::CanSeeFOV(Entity *ent)
bCanSee = false;
if (InFOV(ent->centroid) && gi.AreasConnected(edict->r.areanum, ent->edict->r.areanum)) {
if (InFOV(ent) && AreasConnected(ent)) {
bCanSee = CanSee(ent, 0, 0, false);
}
+2
View File
@@ -120,6 +120,8 @@ void Actor::Think_Alarm(void)
Com_Printf("Actor::Think_Alarm: invalid think state %i\n", m_State);
break;
}
PostThink(true);
}
void Actor::FinishedAnimation_Alarm(void)
+1 -1
View File
@@ -264,7 +264,7 @@ bool Actor::CalcFallPath(void)
loop = currentPos;
mm.desired_speed = 0;
mm.groundPlane = NULL;
mm.groundPlane = qfalse;
mm.walking = false;
VectorSet(mm.velocity, 0, 0, -171);
+3 -3
View File
@@ -79,7 +79,7 @@ bool Actor::Cover_SetPath(PathNode *node)
fPathDist = PathDist();
fMinDistSquared = Square(fPathDist);
if ((node->origin - origin).lengthSquared() <= fMinDistSquared * 4.0f && fPathDist > 128.0f) {
if ((node->origin - origin).lengthSquared() * 4 <= fMinDistSquared && fPathDist > 128.0f) {
return false;
}
@@ -343,7 +343,7 @@ void Actor::State_Cover_Hide(void)
bool bCanShoot, bCanSee;
if (m_Enemy) {
SetEnemyPos(origin);
SetEnemyPos(m_Enemy->origin);
}
if (!m_pCoverNode) {
@@ -380,7 +380,7 @@ void Actor::State_Cover_Hide(void)
return;
}
if (bCanShoot || bCanShoot) {
if (bCanSee || bCanShoot) {
m_pCoverNode->Relinquish();
m_pCoverNode->MarkTemporarilyBad();
m_pCoverNode = NULL;
+3 -3
View File
@@ -31,7 +31,7 @@ void Actor::InitCurious(GlobalFuncs_t *func)
func->EndState = &Actor::End_Curious;
func->ResumeState = &Actor::Resume_Curious;
func->SuspendState = &Actor::Suspend_Curious;
func->FinishedAnimation = &Actor::FinishedAnimation_Cover;
func->FinishedAnimation = &Actor::FinishedAnimation_Curious;
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Curious;
func->IsState = &Actor::IsCuriousState;
}
@@ -246,8 +246,8 @@ void Actor::LookAtCuriosity(void)
iSeed = 0x19660D * (m_iCuriousTime - 0x2EB71B09 * ((level.inttime - m_iCuriousTime) & 0xFFFFFF00)) + 0x3C6EF35F;
vAngles[0] = m_DesiredLookAngles[0] + (float)iSeed / 0x4444444 * fLookScale;
vAngles[1] = m_DesiredLookAngles[1] + (float)iSeed / 0x2222222 * fLookScale;
vAngles[0] = m_DesiredLookAngles[0] + (float)iSeed / (float)0x4444444 * fLookScale;
vAngles[1] = m_DesiredLookAngles[1] + (float)iSeed / (float)0x2222222 * fLookScale;
vAngles[2] = m_DesiredLookAngles[2];
// clamp
vAngles[0] = Q_clamp_float(vAngles[0], -90, 90);
+8 -2
View File
@@ -31,6 +31,7 @@ void Actor::InitDisguiseSalute(GlobalFuncs_t *func)
func->EndState = &Actor::End_DisguiseSalute;
func->ResumeState = &Actor::Resume_DisguiseSalute;
func->SuspendState = &Actor::Suspend_DisguiseSalute;
func->FinishedAnimation = &Actor::FinishedAnimation_DisguiseSalute;
func->PassesTransitionConditions = &Actor::PassesTransitionConditions_Disguise;
func->IsState = &Actor::IsDisguiseState;
}
@@ -51,7 +52,7 @@ void Actor::Begin_DisguiseSalute(void)
SetDesiredYawDest(m_Enemy->origin);
SetDesiredLookDir(m_Enemy->origin - origin);
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_PAPERS_SCR);
DesiredAnimation(ANIM_MODE_NORMAL, STRING_ANIM_DISGUISE_SALUTE_SCR);
} else {
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
}
@@ -85,7 +86,12 @@ void Actor::Think_DisguiseSalute(void)
return;
}
if ((!EnemyIsDisguised() && !(m_Enemy->flags & FL_NOTARGET)) || level.m_bAlarm != qtrue) {
if (!EnemyIsDisguised() && !(m_Enemy->flags & FL_NOTARGET)) {
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
return;
}
if (level.m_bAlarm == qtrue) {
SetThinkState(THINKSTATE_ATTACK, THINKLEVEL_IDLE);
return;
}
+15 -4
View File
@@ -89,8 +89,11 @@ void Actor::End_MachineGunner(void)
}
Unholster();
if (m_pTurret && m_pTurret->GetOwner() == this) {
m_pTurret->TurretEndUsed();
if (m_pTurret) {
m_pTurret->m_bHadOwner = true;
if (m_pTurret->GetOwner() == this) {
m_pTurret->TurretEndUsed();
}
}
}
@@ -154,7 +157,7 @@ void Actor::ThinkHoldGun_TurretGun(void)
}
}
VectorScale2D(orientation[0], m_fCrouchWeight * -9.3f + 23.4f, offset);
VectorScale2D(orientation[0], -(m_fCrouchWeight * -9.3f + 23.4f), offset);
VectorAdd2D(newOrigin, offset, newOrigin);
VectorScale2D(orientation[1], m_fCrouchWeight * 2.6f + 10.3f, offset);
VectorAdd2D(newOrigin, offset, newOrigin);
@@ -164,7 +167,7 @@ void Actor::ThinkHoldGun_TurretGun(void)
m_fCrouchWeight = 1.0;
}
VectorScale2D(orientation[0], m_fCrouchWeight * -3.f + 23.4f, offset);
VectorScale2D(orientation[0], -(m_fCrouchWeight * -3.f + 23.4f), offset);
VectorAdd2D(newOrigin, offset, newOrigin);
VectorScale2D(orientation[1], m_fCrouchWeight * -1.6f + 10.3f, offset);
VectorAdd2D(newOrigin, offset, newOrigin);
@@ -179,6 +182,8 @@ void Actor::ThinkHoldGun_TurretGun(void)
UpdateAimMotion();
UpdateAnim();
newOrigin[2] += 18;
end[0] = newOrigin[0];
end[1] = newOrigin[1];
end[2] = newOrigin[2] - 94;
@@ -207,6 +212,12 @@ void Actor::Think_MachineGunner_TurretGun(void)
UpdateEnemyInternal();
if (m_Team == TEAM_AMERICAN) {
// Added in 2.30
ThinkHoldGun_TurretGun();
return;
}
if (m_pTurret->AI_CanTarget(G_GetEntity(0)->centroid)) {
ThinkHoldGun_TurretGun();
return;
Loaded 100 of 406 files, more files were not shown because too many files have changed in this diff. Show more