animate ball from pedestal

add camera shake and rumble when auto portals open
This commit is contained in:
James Lambert 2023-10-21 21:35:50 -06:00
parent 3d3c012fea
commit 7a5267195d
11 changed files with 88 additions and 39 deletions

View file

@ -210,12 +210,13 @@ That will generate the rom at `/build/portal64.z64`
<br />
## Current New Feature TODO List
- [ ] valve intro
- [ ] figure out why portals somtimes are in front of window
- [ ] optimize static culling
- [ ] jump animation
- [ ] crashed when dying in test chamber 05 when hit by pellet in mid air while touching a portal
- [ ] rumble pak support
- [ ] pausing while glados is speaking can end her speech early
- [x] valve intro
- [x] polish up subtitles
- [x] more sound settings
- [x] add desk chairs and monitors

View file

@ -1180,10 +1180,11 @@ materials:
gDPSetRenderMode:
flags:
- Z_CMP
- IM_RD
- CVG_DST_FULL
- FORCE_BL
- ZMODE_OPA
- ZMODE_XLU
blend:
- G_BL_CLR_IN
- G_BL_A_IN
@ -1194,8 +1195,8 @@ materials:
color: ["1", "PRIMITIVE", "TEXEL0", "PRIMITIVE"]
alpha: ["TEXEL0", "PRIMITIVE", "SHADE", "0"]
gSPGeometryMode:
clear: [G_CULL_BACK, G_CULL_FRONT, G_ZBUFFER]
set: [G_FOG]
clear: [G_CULL_BACK, G_CULL_FRONT]
set: [G_FOG, G_ZBUFFER]
lab_monitor_screen_text:
gDPSetTile:

View file

@ -32,19 +32,19 @@ cutscenes:
portal_loop:
- open_portal portal_exit 0
- label loop_start
- open_portal portal_0 1
- open_portal portal_0 1 pedestal
- delay 3
- point_pedestal portal_1
- delay 4
- open_portal portal_1 1
- open_portal portal_1 1 pedestal
- delay 3 2
- point_pedestal portal_2
- delay 4 2
- open_portal portal_2 1
- open_portal portal_2 1 pedestal
- delay 3 3
- point_pedestal portal_3
- delay 4 3
- open_portal portal_3 1
- open_portal portal_3 1 pedestal
- delay 3 4
- point_pedestal portal_0
- delay 4 4

View file

@ -38,15 +38,15 @@ cutscenes:
- q_sound 07_PART2_SUCCESS_1 CH_GLADOS PORTAL_07_PART2_SUCCESS_1
portal_loop:
- label loop_start
- open_portal portal_0 0
- delay 3.001
- open_portal portal_0 0 pedestal
- delay 3
- point_pedestal portal_1
- delay 4.001
- open_portal portal_1 0
- delay 4
- open_portal portal_1 0 pedestal
- delay 3 2
- point_pedestal portal_2
- delay 4 2
- open_portal portal_2 0
- open_portal portal_2 0 pedestal
- delay 3 3
- point_pedestal portal_3
- delay 4 3

View file

@ -7,9 +7,22 @@
#include "../util/memory.h"
#include "../savefile/checkpoint.h"
#include "../locales/locales.h"
#include "../controls/rumble_pak.h"
#include <math.h>
unsigned char gPortalOpenRumbleData[] = {
0xFF, 0xE9, 0x99,
};
struct RumblePakWave gPortalOpenRumbleWave = {
.samples = gPortalOpenRumbleData,
.sampleCount = 12,
.samplesPerTick = 1 << 5,
};
#define RUMBLE_PLAYER_DISTANCE 8.0f
struct CutsceneRunner* gRunningCutscenes;
struct CutsceneRunner* gUnusedRunners;
u64 gTriggeredCutscenes;
@ -154,14 +167,26 @@ void cutsceneRunnerStartStep(struct CutsceneRunner* runner) {
case CutsceneStepTypeOpenPortal:
{
struct Location* location = &gCurrentLevel->locations[step->openPortal.locationIndex];
struct Ray firingRay;
struct Vector3 transformUp;
firingRay.origin = location->transform.position;
quatMultVector(&location->transform.rotation, &gForward, &firingRay.dir);
quatMultVector(&location->transform.rotation, &gRight, &transformUp);
vector3Negate(&transformUp, &transformUp);
vector3AddScaled(&location->transform.position, &firingRay.dir, -0.1f, &firingRay.origin);
sceneFirePortal(&gScene, &firingRay, &transformUp, step->openPortal.portalIndex, location->roomIndex, 0, 0);
if (step->openPortal.fromPedestal && gCurrentLevel->pedestalCount) {
struct Vector3 fireFrom = gScene.pedestals[0].transform.position;
fireFrom.y += 0.75f;
portalGunFireWorld(&gScene.portalGun, step->openPortal.portalIndex, &fireFrom, &location->transform.position, gScene.pedestals[0].roomIndex);
} else {
struct Ray firingRay;
struct Vector3 transformUp;
firingRay.origin = location->transform.position;
quatMultVector(&location->transform.rotation, &gForward, &firingRay.dir);
quatMultVector(&location->transform.rotation, &gRight, &transformUp);
vector3Negate(&transformUp, &transformUp);
vector3AddScaled(&location->transform.position, &firingRay.dir, -0.1f, &firingRay.origin);
sceneFirePortal(&gScene, &firingRay, &transformUp, step->openPortal.portalIndex, location->roomIndex, 0, 0);
if (vector3DistSqrd(&location->transform.position, &gScene.player.lookTransform.position) < RUMBLE_PLAYER_DISTANCE * RUMBLE_PLAYER_DISTANCE) {
gScene.player.shakeTimer = 0.5f;
rumblePakClipPlay(&gPortalOpenRumbleWave);
}
}
break;
}
case CutsceneStepTypeClosePortal:

View file

@ -90,7 +90,8 @@ struct CutsceneStep {
} waitForChannel;
struct {
u16 locationIndex;
u16 portalIndex;
u8 portalIndex;
u8 fromPedestal;
} openPortal;
struct {
u16 portalIndex;

View file

@ -262,18 +262,17 @@ void playerShakeUpdate(struct Player* player) {
if (player->shakeTimer > 0.0f){
player->shakeTimer -= FIXED_DELTA_TIME;
float max = SHAKE_DISTANCE;
float min = -SHAKE_DISTANCE;
float x;
x = ((float)rand()/(float)(RAND_MAX));
x = min + x * ( max - min );
player->lookTransform.position.x += x;
x = ((float)rand()/(float)(RAND_MAX));
x = min + x * ( max - min );
player->lookTransform.position.y += x;
x = ((float)rand()/(float)(RAND_MAX));
x = min + x * ( max - min );
player->lookTransform.position.z += x;
float magnitude = 1.0f;
if (player->shakeTimer < 1.0f) {
magnitude = player->shakeTimer;
}
float max = SHAKE_DISTANCE * magnitude;
float min = -SHAKE_DISTANCE * magnitude;
player->lookTransform.position.x += randomInRangef(min, max);
player->lookTransform.position.y += randomInRangef(min, max);
player->lookTransform.position.z += randomInRangef(min, max);
if (player->shakeTimer < 0.0f){
player->shakeTimer = 0.0f;

View file

@ -114,7 +114,7 @@ void portalBallRender(struct PortalGunProjectile* projectile, struct RenderState
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
}
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState, struct Camera* fromCamera) {
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState, struct Camera* fromCamera, int portalGunVisible) {
struct MaterialState materialState;
materialStateInit(&materialState, DEFAULT_INDEX);
@ -130,6 +130,10 @@ void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* render
portalBallRender(projectile, renderState, &materialState, &fromCamera->transform, i);
}
if (!portalGunVisible) {
return;
}
portalGun->rigidBody.transform.scale = gOneVec;
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
@ -267,6 +271,24 @@ void portalGunFire(struct PortalGun* portalGun, int portalIndex, struct Ray* ray
portalTrailPlay(&projectile->trail, &fireFrom, &hit.at);
}
void portalGunFireWorld(struct PortalGun* portalGun, int portalIndex, struct Vector3* from, struct Vector3* to, int roomIndex) {
struct PortalGunProjectile* projectile = &portalGun->projectiles[portalIndex];
vector3Sub(to, from, &projectile->positionDirection.dir);
vector3Normalize(&projectile->positionDirection.dir, &projectile->positionDirection.dir);
projectile->positionDirection.origin = *from;
projectile->roomIndex = roomIndex;
projectile->playerUp = gUp;
projectile->distance = 0.0f;
projectile->maxDistance = sqrtf(vector3DistSqrd(from, to));
projectile->effectOffset = gZeroVec;
portalTrailPlay(&projectile->trail, from, to);
}
int portalGunIsFiring(struct PortalGun* portalGun){
if (portalGun->shootTotalAnimationTimer > 0.0f){
return 1;

View file

@ -39,9 +39,10 @@ struct PortalGun {
void portalGunInit(struct PortalGun* portalGun, struct Transform* at);
// void portalGunDummyRender(void* data, struct DynamicRenderDataList* renderList, struct RenderState* renderState);
void portalGunUpdate(struct PortalGun* portalGun, struct Player* player);
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState, struct Camera* fromCamera);
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState, struct Camera* fromCamera, int portalGunVisible);
void portalGunFire(struct PortalGun* portalGun, int portalIndex, struct Ray* ray, struct Vector3* playerUp, int roomIndex);
void portalGunFireWorld(struct PortalGun* portalGun, int portalIndex, struct Vector3* from, struct Vector3* to, int roomIndex);
int portalGunIsFiring(struct PortalGun* portalGun);
#endif

View file

@ -306,9 +306,7 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr
// contactSolverDebugDraw(&gContactSolver, renderState);
if (scene->portalGun.portalGunVisible){
portalGunRenderReal(&scene->portalGun, renderState, &scene->camera);
}
portalGunRenderReal(&scene->portalGun, renderState, &scene->camera, scene->portalGun.portalGunVisible);
gDPPipeSync(renderState->dl++);
gDPSetRenderMode(renderState->dl++, G_RM_OPA_SURF, G_RM_OPA_SURF2);

View file

@ -120,6 +120,7 @@ local function generate_cutscene_step(cutscene_name, step, step_index, label_loc
result.openPortal = {
find_location_index(step.args[1]),
step.args[2] == "1" and 1 or 0,
step.args[3] == "pedestal" and 1 or 0
}
elseif step.command == "close_portal" and #step.args >= 1 then
result.type = sk_definition_writer.raw('CutsceneStepTypeClosePortal')