diff --git a/src/platform/gba/common.h b/src/platform/gba/common.h index 9c66f8c3..2e509677 100644 --- a/src/platform/gba/common.h +++ b/src/platform/gba/common.h @@ -136,6 +136,7 @@ typedef int16 Index; // system int32 osGetSystemTimeMS(); +void osJoyVibrate(int32 index, int32 L, int32 R); #ifdef PROFILING #define PROFILE_FRAME\ diff --git a/src/platform/gba/lara.h b/src/platform/gba/lara.h index 6e7d7caa..8da13ac3 100644 --- a/src/platform/gba/lara.h +++ b/src/platform/gba/lara.h @@ -1479,7 +1479,7 @@ struct Lara : Item { if ((state == STATE_FAST_DIVE || state == STATE_ROLL_AIR) && vSpeed > 133) { - health = 0; + hit(LARA_MAX_HEALTH, pos, 0); return true; } @@ -1495,9 +1495,9 @@ struct Lara : Item return false; if (vSpeed > 154) { - health = 0; + hit(LARA_MAX_HEALTH, pos, 0); } else { - health -= (X_SQR(vSpeed - 140) * LARA_MAX_HEALTH) / 196; + hit((X_SQR(vSpeed - 140) * LARA_MAX_HEALTH) / 196, pos, 0); } return health <= 0; @@ -1799,6 +1799,7 @@ struct Lara : Item vSpeed = 1; } } else if (!slide && ((cinfo.type == CT_FRONT) || (cinfo.type == CT_FRONT_CEILING))) { + osJoyVibrate(0, 0xFF, 0xFF); animSet(ANIM_SMASH_JUMP, true, 1); extraL->moveAngle += ANGLE_180; hSpeed >>= 2; @@ -3720,6 +3721,15 @@ struct Lara : Item } } + virtual void hit(int32 damage, const vec3i &point, int32 soundId) + { + if (health <= 0 || damage <= 0) + return; + + osJoyVibrate(0, 0xFF, 0xFF); + health -= damage; + } + virtual void update() { gCamera = extraL->camera; @@ -3738,7 +3748,7 @@ struct Lara : Item if (oxygen > 0) { oxygen--; } else { - health -= 5; + hit(5, pos, 0); } } else { oxygen = X_MIN(oxygen + 10, LARA_MAX_OXYGEN); diff --git a/src/platform/gba/main.cpp b/src/platform/gba/main.cpp index 9748e08e..d51fa8e8 100644 --- a/src/platform/gba/main.cpp +++ b/src/platform/gba/main.cpp @@ -59,6 +59,44 @@ int32 fpsCounter = 0; { return 0; // TODO } + + #define GPIO_RUMBLE_DATA (*(vu16*)0x80000C4) + #define GPIO_RUMBLE_DIRECTION (*(vu16*)0x80000C6) + #define GPIO_RUMBLE_CONTROL (*(vu16*)0x80000C8) + #define GPIO_RUMBLE_MASK (1 << 3) + + #define CART_RUMBLE_TICKS 3 + + int32 cartRumbleTick = 0; + + void rumbleInit() + { + GPIO_RUMBLE_DIRECTION = GPIO_RUMBLE_MASK; + GPIO_RUMBLE_CONTROL = 1; + } + + void rumbleSet(bool enable) + { + if (enable) { + GPIO_RUMBLE_DATA |= GPIO_RUMBLE_MASK; + cartRumbleTick = CART_RUMBLE_TICKS; + } else { + GPIO_RUMBLE_DATA &= ~GPIO_RUMBLE_MASK; + cartRumbleTick = 0; + } + } + + void rumbleUpdate() + { + if (!cartRumbleTick || --cartRumbleTick) + return; + rumbleSet(false); + } + + void osJoyVibrate(int32 index, int32 L, int32 R) + { + rumbleSet(X_MAX(L, R) > 0); + } #elif defined(__TNS__) unsigned int osTime; volatile unsigned int *timerBUS; @@ -552,6 +590,7 @@ int main(void) { } } + rumbleInit(); soundInit(); game.init(); @@ -564,7 +603,10 @@ int main(void) { int32 lastFrameIndex = -1; - while (1) { + while (1) + { + rumbleUpdate(); + { // input keys = 0; key_poll();