List of commits:
Subject Hash Author Date (UTC)
Add haptic rumble for combat 65ff172308b0ba26b8930e8e83eb41bd36c6b008 mse 2021-08-15 06:11:25
Reduce joystick sensitivity 3804492a52d36c40cd51d42a971fe92f4fdd52ba mse 2021-08-14 22:37:19
Set audio buffer 1024 to reduce latency b1733b33b3342b32f08e1bafb5baf63ed7db419e mse 2021-07-11 02:56:22
Update readme, deps, bump to v0.5.0 2f96bc1fe9af48874750f2ba507eda5d704313b0 mse 2021-07-05 12:14:52
New license c9932a52aaa81e6b136510157bfc3ce3e10ab800 mse 2021-07-04 16:01:57
Fix joystick dead zone 303dc3276d27f2a123e5370b31b79cdf87afc879 mse 2021-06-26 07:09:28
Windows-compatible locale 65244a8360ad6a65fea64f43f115f5c93bf966dd mse 2021-06-11 17:13:26
Detect language using std::locale 60f1680d73e559dc85f6b85e9ca69cb9be717ae6 mse 2021-06-09 16:11:30
Rename data -> base and load game as mod ec3b8aa10ee005d89d897b43c68cecd4b9ea8a75 mse 2021-06-07 12:31:53
Replace function with macro cc34567bf5b5503d90ea989004606fcca240d3cd mse 2021-05-30 20:14:02
Bump version to 0.4.4 4b4eb20f18d047f34a94456b441ee55cc4c6248b mse 2021-05-30 03:48:53
Initial modding support with -m parameters 94429b99dd3c85d67d8a9fe8b2faee06c1e9fcde mse 2021-05-29 22:01:40
Moddable dialogue loading via FileOpen 6183fb4b8dde53f07f8e7bf6835a8fe7ca0a8a8c mse 2021-05-29 10:54:24
Moddable sound file loading via FileOpen ed4d1680cfb17f573fe799908d35e6856c183076 mse 2021-05-29 07:21:32
Update en_to_zh, start implementing moddable FileOpen, fix -Wsign-compare 89d00440e1c35d46851fb1d300107da9725d261d mse 2021-05-27 21:29:27
Add a third procedural basket and winnerberry translation string 9b970d581d5094fd3ea7b9da2b4e397c4f4c94db mse 2021-05-27 09:29:02
Add STOPSOUNDS command 22507196106fcd8db7b4bae15b6a2bf9168dd61e mse 2021-05-27 05:56:57
Wake player when hit b2bc7d9cb37a9c9a707e9b8428e6f4d3fa2f27b7 mse 2021-05-26 08:50:53
Minor clarifications d5a83695acdf78b21610239d530b1317dc4003cc mse 2021-05-24 00:11:59
DRM-free dynamic target c51ae66a80c38d4d8aec606ad04492ea12a56fcd mse 2021-05-23 23:53:32
Commit 65ff172308b0ba26b8930e8e83eb41bd36c6b008 - Add haptic rumble for combat
Author: mse
Author date (UTC): 2021-08-15 06:11
Committer name: mse
Committer date (UTC): 2021-08-15 06:11
Parent(s): 3804492a52d36c40cd51d42a971fe92f4fdd52ba
Signing key:
Tree: a8d98e7c51dd211c82105c3501b7a84e57f338a4
File Lines added Lines deleted
confec.cpp 11 0
include/fg2/fg2.h 32 2
include/fg3/fg3.h 36 2
File confec.cpp changed (mode: 100644) (index a12c9ae..33863e4)
... ... void HitCallback( fworld::Entity *ent_a, fworld::Entity *ent_b, int damage ){
2520 2520 sleep_mode = false; sleep_mode = false;
2521 2521 } }
2522 2522 } }
2523 // Blood.
2523 2524 MakeGibs( MakeGibs(
2524 2525 ent_b->x + 0.5, ent_b->x + 0.5,
2525 2526 ent_b->y + 1.0 - ent_b->height * 0.75 / world.tileSize, ent_b->y + 1.0 - ent_b->height * 0.75 / world.tileSize,
2526 2527 linalg::normalize( linalg::vec<double,3>( ent_b->x - ent_a->x, ent_b->y - ent_a->y, 0.0 ) ) * 10.0, linalg::normalize( linalg::vec<double,3>( ent_b->x - ent_a->x, ent_b->y - ent_a->y, 0.0 ) ) * 10.0,
2527 2528 std::max( damage, 3 ) std::max( damage, 3 )
2528 2529 ); );
2530 // Controller rumble.
2531 float intensity = std::fminf( std::max( damage, 3 ) / 50.0f, 1.0f );
2532 // Assuming conventional rumblers (motor with asymmetrical weight).
2533 // The uppermost third of rumble voltage delivers the desired effect.
2534 // ~150 ms is the minimum duration for rumblers to work.
2535 fgl::hapticRumble(
2536 lerp( 0.667, 1.0, intensity ),
2537 std::max( (int)( intensity * 1000 ), 150 )
2538 );
2539 // Sound.
2529 2540 csPlaySound( "melee_hit", false ); csPlaySound( "melee_hit", false );
2530 2541 } }
2531 2542
File include/fg2/fg2.h changed (mode: 100755) (index 4b35a45..a2f3ce4)
... ... bool touchStart = false;
318 318 SDL_Window* window = nullptr; SDL_Window* window = nullptr;
319 319 SDL_GLContext ctx = 0; SDL_GLContext ctx = 0;
320 320 SDL_GameController* controller = nullptr; SDL_GameController* controller = nullptr;
321 SDL_Haptic* haptic = nullptr;
321 322
322 323 SDL_Rect textInputRect = {}; SDL_Rect textInputRect = {};
323 324 bool textInputEnabled = false; bool textInputEnabled = false;
 
... ... Display createDisplay( unsigned int width, unsigned int height, std::string titl
1617 1618
1618 1619 Display disp = newDisplay; Display disp = newDisplay;
1619 1620
1620 if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER ) < 0 ){
1621 if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC ) < 0 ){
1621 1622 fprintf( stderr, "Failed to initialize SDL.\n" ); fprintf( stderr, "Failed to initialize SDL.\n" );
1622 1623 return disp; return disp;
1623 1624 } }
 
... ... Display createDisplay( unsigned int width, unsigned int height, std::string titl
1864 1865 if( SDL_IsGameController( i ) ){ if( SDL_IsGameController( i ) ){
1865 1866 controller = SDL_GameControllerOpen( i ); controller = SDL_GameControllerOpen( i );
1866 1867 if( controller ){ if( controller ){
1868 // Open the controller's haptic device.
1869 haptic = SDL_HapticOpenFromJoystick( SDL_GameControllerGetJoystick( controller ) );
1870 // Verify rumble support.
1871 if( SDL_HapticRumbleInit( haptic ) < 0 ){
1872 SDL_HapticClose( haptic );
1873 haptic = nullptr;
1874 }
1867 1875 break; break;
1868 1876 }else{ }else{
1869 1877 fprintf( stderr, "Failed to open game controller %d: %s\n", i, SDL_GetError() ); fprintf( stderr, "Failed to open game controller %d: %s\n", i, SDL_GetError() );
 
... ... void syncEvents(){
1996 2004 // Handle controller hotplugging. // Handle controller hotplugging.
1997 2005 if( !controller || !SDL_GameControllerGetAttached( controller ) ){ if( !controller || !SDL_GameControllerGetAttached( controller ) ){
1998 2006 controller = nullptr; controller = nullptr;
2007 if( haptic ){
2008 // Clean up haptic device.
2009 SDL_HapticClose( haptic );
2010 haptic = nullptr;
2011 }
1999 2012 // Open the first available controller. // Open the first available controller.
2000 2013 for( int i = 0; i < SDL_NumJoysticks(); i++ ){ for( int i = 0; i < SDL_NumJoysticks(); i++ ){
2001 2014 if( SDL_IsGameController( i ) ){ if( SDL_IsGameController( i ) ){
2002 2015 // Open the controller. // Open the controller.
2003 2016 controller = SDL_GameControllerOpen( i ); controller = SDL_GameControllerOpen( i );
2004 if( controller ) break;
2017 if( controller ){
2018 // Open the controller's haptic device.
2019 haptic = SDL_HapticOpenFromJoystick( SDL_GameControllerGetJoystick( controller ) );
2020 // Verify rumble support.
2021 if( SDL_HapticRumbleInit( haptic ) < 0 ){
2022 SDL_HapticClose( haptic );
2023 haptic = nullptr;
2024 }
2025 break;
2026 }
2005 2027 } }
2006 2028 } }
2007 2029 } }
 
... ... void trapMouse( bool trap ){
2269 2291 } }
2270 2292 } }
2271 2293
2294 void hapticRumble( float strength, unsigned int length ){
2295 if( haptic )
2296 SDL_HapticRumblePlay( haptic, strength, (Uint32)length );
2297 }
2298
2272 2299 void end(){ void end(){
2300 if( haptic ){
2301 SDL_HapticClose( haptic );
2302 }
2273 2303 if( controller ){ if( controller ){
2274 2304 SDL_GameControllerClose( controller ); SDL_GameControllerClose( controller );
2275 2305 } }
File include/fg3/fg3.h changed (mode: 100644) (index 4eea18a..9a8e24e)
... ... bool touchStart = false;
499 499 SDL_Window* window; SDL_Window* window;
500 500 SDL_GLContext ctx; SDL_GLContext ctx;
501 501 SDL_GameController* controller = nullptr; SDL_GameController* controller = nullptr;
502 SDL_Haptic* haptic = nullptr;
502 503
503 504 // TODO: SFML text input. // TODO: SFML text input.
504 505 SDL_Rect textInputRect = {}; SDL_Rect textInputRect = {};
 
... ... Display createDisplay( unsigned int width, unsigned int height, std::string titl
1791 1792 Display disp = newDisplay; Display disp = newDisplay;
1792 1793
1793 1794 # ifdef SDL_MAJOR_VERSION # ifdef SDL_MAJOR_VERSION
1794 if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER ) < 0 ){
1795 if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_HAPTIC ) < 0 ){
1795 1796 _ERROUT_ << "Failed to initialize SDL." << std::endl; _ERROUT_ << "Failed to initialize SDL." << std::endl;
1796 1797 return disp; return disp;
1797 1798 } }
 
... ... Display createDisplay( unsigned int width, unsigned int height, std::string titl
1885 1886 if( SDL_IsGameController( i ) ){ if( SDL_IsGameController( i ) ){
1886 1887 controller = SDL_GameControllerOpen( i ); controller = SDL_GameControllerOpen( i );
1887 1888 if( controller ){ if( controller ){
1889 // Open the controller's haptic device.
1890 haptic = SDL_HapticOpenFromJoystick( SDL_GameControllerGetJoystick( controller ) );
1891 // Verify rumble support.
1892 if( SDL_HapticRumbleInit( haptic ) < 0 ){
1893 SDL_HapticClose( haptic );
1894 haptic = nullptr;
1895 }
1888 1896 break; break;
1889 1897 }else{ }else{
1890 1898 _ERROUT_ << "Failed to open game controller " << i << ": " << SDL_GetError() << std::endl; _ERROUT_ << "Failed to open game controller " << i << ": " << SDL_GetError() << std::endl;
 
... ... void syncEvents(){
2166 2174 // Handle controller hotplugging. // Handle controller hotplugging.
2167 2175 if( !controller || !SDL_GameControllerGetAttached( controller ) ){ if( !controller || !SDL_GameControllerGetAttached( controller ) ){
2168 2176 controller = nullptr; controller = nullptr;
2177 if( haptic ){
2178 // Clean up haptic device.
2179 SDL_HapticClose( haptic );
2180 haptic = nullptr;
2181 }
2169 2182 // Open the first available controller. // Open the first available controller.
2170 2183 for( int i = 0; i < SDL_NumJoysticks(); i++ ){ for( int i = 0; i < SDL_NumJoysticks(); i++ ){
2171 2184 if( SDL_IsGameController( i ) ){ if( SDL_IsGameController( i ) ){
2172 2185 // Open the controller. // Open the controller.
2173 2186 controller = SDL_GameControllerOpen( i ); controller = SDL_GameControllerOpen( i );
2174 if( controller ) break;
2187 if( controller ){
2188 // Open the controller's haptic device.
2189 haptic = SDL_HapticOpenFromJoystick( SDL_GameControllerGetJoystick( controller ) );
2190 // Verify rumble support.
2191 if( SDL_HapticRumbleInit( haptic ) < 0 ){
2192 SDL_HapticClose( haptic );
2193 haptic = nullptr;
2194 }
2195 break;
2196 }
2175 2197 } }
2176 2198 } }
2177 2199 } }
 
... ... void trapMouse( bool trap ){
2382 2404 } }
2383 2405 } }
2384 2406
2407 void hapticRumble( float strength, unsigned int length ){
2408 if( haptic )
2409 SDL_HapticRumblePlay( haptic, strength, (Uint32)length );
2410 }
2411
2385 2412 void end(){ void end(){
2413 if( haptic ){
2414 SDL_HapticClose( haptic );
2415 }
2386 2416 if( controller ){ if( controller ){
2387 2417 SDL_GameControllerClose( controller ); SDL_GameControllerClose( controller );
2388 2418 } }
 
... ... void trapMouse( bool trap ){
2499 2529 mouseTrapped = trap; mouseTrapped = trap;
2500 2530 } }
2501 2531
2532 void hapticRumble( float strength, unsigned int length ){
2533 // TODO: SFML haptic rumble.
2534 }
2535
2502 2536 void end(){ void end(){
2503 2537 window.close(); window.close();
2504 2538 exit( 0 ); exit( 0 );
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/mse/ConfectionerEngine

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/mse/ConfectionerEngine

Clone this repository using git:
git clone git://git.rocketgit.com/user/mse/ConfectionerEngine

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main