mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-19 22:27:36 -04:00
Merge branch 'lambertjamesd:master' into german-audio
This commit is contained in:
commit
7982bb408a
10
Makefile
10
Makefile
|
@ -17,7 +17,7 @@ $(SKELATOOL64):
|
|||
skelatool64/setup_dependencies.sh
|
||||
make -C skelatool64
|
||||
|
||||
OPTIMIZER := -Og
|
||||
OPTIMIZER := -Os
|
||||
LCDEFS := -DDEBUG -g -Isrc/ -I/usr/include/n64/nustd -Werror -Wall
|
||||
N64LIB := -lultra_rom -lnustd
|
||||
|
||||
|
@ -113,6 +113,7 @@ src/models/sphere.h src/models/sphere_geo.inc.h: assets/fbx/Sphere.fbx
|
|||
portal_pak_dir: vpk/portal_pak_dir.vpk
|
||||
vpk -x portal_pak_dir vpk/portal_pak_dir.vpk
|
||||
vpk -x portal_pak_dir vpk/hl2_sound_misc_dir.vpk
|
||||
vpk -x portal_pak_dir vpk/hl2_misc_dir.vpk
|
||||
|
||||
TEXTURE_SCRIPTS = $(shell find assets/ -type f -name '*.ims')
|
||||
TEXTURE_IMAGES = $(TEXTURE_SCRIPTS:assets/%.ims=portal_pak_modified/%.png) \
|
||||
|
@ -276,6 +277,7 @@ build/src/menu/main_menu.o: build/src/audio/clips.h build/assets/materials/ui.h
|
|||
build/src/menu/new_game_menu.o: build/src/audio/clips.h build/assets/materials/ui.h build/assets/materials/images.h build/assets/test_chambers/test_chamber_00/test_chamber_00.h
|
||||
build/src/menu/options_menu.o: build/assets/materials/ui.h
|
||||
build/src/menu/save_game_menu.o: build/src/audio/clips.h
|
||||
build/src/scene/scene_animator.o: build/src/audio/clips.h
|
||||
build/src/menu/savefile_list.o: build/assets/materials/ui.h build/src/audio/clips.h
|
||||
build/src/player/player.o: build/assets/models/player/chell.h build/assets/materials/static.h
|
||||
build/src/scene/ball_catcher.o: build/assets/models/props/combine_ball_catcher.h build/assets/materials/static.h build/assets/models/dynamic_animated_model_list.h
|
||||
|
@ -387,6 +389,10 @@ $(INS_SOUNDS): portal_pak_dir
|
|||
|
||||
portal_pak_dir/sound/music/%.wav: portal_pak_dir/sound/music/%.mp3
|
||||
|
||||
build/assets/sound/vehicles/tank_turret_loop1.wav: portal_pak_dir
|
||||
@mkdir -p $(@D)
|
||||
sox portal_pak_dir/sound/vehicles/tank_turret_loop1.wav -b 16 $@
|
||||
|
||||
build/%.aifc: %.sox portal_pak_dir
|
||||
@mkdir -p $(@D)
|
||||
sox $(<:assets/%.sox=portal_pak_dir/%.wav) $(shell cat $<) $(@:%.aifc=%.wav)
|
||||
|
@ -403,7 +409,7 @@ build/%.aifc: %.msox portal_pak_dir
|
|||
sox $(<:assets/%.msox=portal_pak_dir/%.wav) $(shell cat $<) $(@:%.aifc=%.wav)
|
||||
$(SFZ2N64) -o $@ $(@:%.aifc=%.wav)
|
||||
|
||||
build/assets/sound/sounds.sounds build/assets/sound/sounds.sounds.tbl: $(SOUND_CLIPS)
|
||||
build/assets/sound/sounds.sounds build/assets/sound/sounds.sounds.tbl: $(SOUND_CLIPS) build/assets/sound/vehicles/tank_turret_loop1.wav
|
||||
@mkdir -p $(@D)
|
||||
$(SFZ2N64) -o $@ $^
|
||||
|
||||
|
|
|
@ -154,10 +154,10 @@ That will generate the rom at `/build/portal64.z64`
|
|||
|
||||
## Current New Feature TODO List
|
||||
- [ ] rumble pak support?
|
||||
- [ ] Investigate crash after falling into death water on test chamber 8
|
||||
- [ ] Add auto save checkpoints
|
||||
- [ ] Correct elevator timing
|
||||
- [ ] pausing while glados is speaking can end her speech early
|
||||
- [x] Investigate crash after falling into death water on test chamber 8
|
||||
- [x] wake up objects after opening a portal under them
|
||||
- [x] button prompts
|
||||
- [x] investigate no_portals surface under portal pedestal
|
||||
|
|
BIN
assets/closecaption_english.txt
Normal file
BIN
assets/closecaption_english.txt
Normal file
Binary file not shown.
1
assets/sound/plats/elevator_stop1.sox
Normal file
1
assets/sound/plats/elevator_stop1.sox
Normal file
|
@ -0,0 +1 @@
|
|||
-c 1 -r 22050
|
15
assets/sound/vehicles/tank_turret_loop1.ins
Normal file
15
assets/sound/vehicles/tank_turret_loop1.ins
Normal file
|
@ -0,0 +1,15 @@
|
|||
envelope Envelope {
|
||||
attackTime = 0
|
||||
attackVolume = 127
|
||||
decayTime = -1
|
||||
decayVolume = 127
|
||||
releaseTime = 0
|
||||
}
|
||||
|
||||
sound Sound {
|
||||
use("../../../build/assets/sound/vehicles/tank_turret_loop1.wav")
|
||||
loopCount = -1
|
||||
loopEnd = -1
|
||||
pan=64
|
||||
envelope = Envelope
|
||||
}
|
1
assets/sound/vehicles/tank_turret_start1.sox
Normal file
1
assets/sound/vehicles/tank_turret_start1.sox
Normal file
|
@ -0,0 +1 @@
|
|||
-c 1 -r 22050 -b 16
|
|
@ -12,13 +12,13 @@ cutscenes:
|
|||
- delay 2
|
||||
- show_prompt CutscenePromptTypeJump
|
||||
- delay 3
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_1 CH_GLADOS
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_2 CH_GLADOS
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_3 CH_GLADOS
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_4 CH_GLADOS
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_5 CH_GLADOS
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_6 CH_GLADOS
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_7 CH_GLADOS
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_1 CH_GLADOS SUBTITLE_00_PART1_ENTRY_1
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_2 CH_GLADOS SUBTITLE_00_PART1_ENTRY_2
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_3 CH_GLADOS SUBTITLE_00_PART1_ENTRY_3
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_4 CH_GLADOS SUBTITLE_00_PART1_ENTRY_4
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_5 CH_GLADOS SUBTITLE_00_PART1_ENTRY_5
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_6 CH_GLADOS SUBTITLE_00_PART1_ENTRY_6
|
||||
- q_sound SOUNDS_00_PART1_ENTRY_7 CH_GLADOS SUBTITLE_00_PART1_ENTRY_7
|
||||
- delay 7
|
||||
- show_prompt CutscenePromptTypeNone
|
||||
- wait_for_channel CH_GLADOS
|
||||
|
@ -30,9 +30,9 @@ cutscenes:
|
|||
- set_signal cube_dropper
|
||||
- show_prompt CutscenePromptTypePickup
|
||||
- wait_for_signal success
|
||||
- q_sound SOUNDS_00_PART1_SUCCESS_1 CH_GLADOS
|
||||
- q_sound SOUNDS_00_PART1_SUCCESS_2 CH_GLADOS
|
||||
- q_sound SOUNDS_00_PART1_SUCCESS_3 CH_GLADOS
|
||||
- q_sound SOUNDS_00_PART1_SUCCESS_1 CH_GLADOS SUBTITLE_00_PART1_SUCCESS_1
|
||||
- q_sound SOUNDS_00_PART1_SUCCESS_2 CH_GLADOS SUBTITLE_00_PART1_SUCCESS_2
|
||||
- q_sound SOUNDS_00_PART1_SUCCESS_3 CH_GLADOS SUBTITLE_00_PART1_SUCCESS_3
|
||||
START_SECOND_ROOM:
|
||||
- start_cutscene SECOND_ROOM_INSTRUCTIONS
|
||||
- open_portal stationary_portal 1
|
||||
|
@ -45,8 +45,8 @@ cutscenes:
|
|||
- delay 5
|
||||
- goto portal_loop
|
||||
SECOND_ROOM_INSTRUCTIONS:
|
||||
- q_sound SOUNDS_00_PART2_ENTRY_1 CH_GLADOS
|
||||
- q_sound SOUNDS_00_PART2_ENTRY_1 CH_GLADOS SUBTITLE_00_PART2_ENTRY_1
|
||||
- wait_for_signal success_1
|
||||
- q_sound SOUNDS_00_PART2_SUCCESS_1 CH_GLADOS
|
||||
- q_sound SOUNDS_00_PART2_SUCCESS_1 CH_GLADOS SUBTITLE_00_PART2_SUCCESS_1
|
||||
HOVER_CUBE_PROMPT:
|
||||
- show_prompt CutscenePromptTypeDrop
|
||||
|
|
|
@ -6,8 +6,8 @@ cutscenes:
|
|||
- start_cutscene portal_loop
|
||||
- set_signal FIRST_ELEVATOR
|
||||
INTRO_CUTSCENE:
|
||||
- q_sound SOUNDS_01_PART1_ENTRY_1 CH_GLADOS
|
||||
- q_sound SOUNDS_01_PART1_ENTRY_2 CH_GLADOS
|
||||
- q_sound SOUNDS_01_PART1_ENTRY_1 CH_GLADOS SUBTITLE_01_PART1_ENTRY_1
|
||||
- q_sound SOUNDS_01_PART1_ENTRY_2 CH_GLADOS SUBTITLE_01_PART1_ENTRY_2
|
||||
- wait_for_channel CH_GLADOS
|
||||
- set_signal room_0_entrance
|
||||
GET_GUN:
|
||||
|
@ -16,19 +16,19 @@ cutscenes:
|
|||
- hide_pedestal
|
||||
- stop_cutscene portal_loop
|
||||
- show_prompt CutscenePromptTypePortal1
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_1 CH_GLADOS
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_2 CH_GLADOS
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_3 CH_GLADOS
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_4 CH_GLADOS
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_5 CH_GLADOS
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_6 CH_GLADOS
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_7 CH_GLADOS
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_8 CH_GLADOS
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_1 CH_GLADOS SUBTITLE_01_PART1_GET_PORTAL_GUN_1
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_2 CH_GLADOS SUBTITLE_01_PART1_GET_PORTAL_GUN_2
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_3 CH_GLADOS SUBTITLE_01_PART1_GET_PORTAL_GUN_3
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_4 CH_GLADOS SUBTITLE_01_PART1_GET_PORTAL_GUN_4
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_5 CH_GLADOS SUBTITLE_01_PART1_GET_PORTAL_GUN_5
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_6 CH_GLADOS SUBTITLE_01_PART1_GET_PORTAL_GUN_6
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_7 CH_GLADOS SUBTITLE_01_PART1_GET_PORTAL_GUN_7
|
||||
- q_sound 01_PART1_GET_PORTAL_GUN_8 CH_GLADOS SUBTITLE_01_PART1_GET_PORTAL_GUN_8
|
||||
MIND_THE_GAP:
|
||||
- open_portal portal_gap 0
|
||||
- q_sound SOUNDS_01_PART2_ENTRY_1 CH_GLADOS
|
||||
- q_sound SOUNDS_01_PART2_ENTRY_1 CH_GLADOS SUBTITLE_01_PART2_ENTRY_1
|
||||
FINISH_03:
|
||||
- q_sound SOUNDS_01_PART2_SUCCESS_1 CH_GLADOS
|
||||
- q_sound SOUNDS_01_PART2_SUCCESS_1 CH_GLADOS SUBTITLE_01_PART2_SUCCESS_1
|
||||
portal_loop:
|
||||
- open_portal portal_exit 0
|
||||
- label loop_start
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
cutscenes:
|
||||
INTRO:
|
||||
- q_sound SOUNDS_02_PART1_ENTRY_1 CH_GLADOS
|
||||
- q_sound SOUNDS_02_PART1_ENTRY_1 CH_GLADOS SUBTITLE_02_PART1_ENTRY_1
|
||||
- wait_for_channel CH_GLADOS
|
||||
- open_portal portal_0 0
|
||||
- q_sound SOUNDS_02_PART1_ENTRY_2 CH_GLADOS
|
||||
- q_sound SOUNDS_02_PART1_ENTRY_2 CH_GLADOS SUBTITLE_02_PART1_ENTRY_2
|
||||
- wait_for_signal success
|
||||
- q_sound SOUNDS_02_PART1_SUCCESS_1 CH_GLADOS
|
||||
- q_sound SOUNDS_02_PART1_SUCCESS_2 CH_GLADOS
|
||||
- q_sound SOUNDS_02_PART1_SUCCESS_1 CH_GLADOS SUBTITLE_02_PART1_SUCCESS_1
|
||||
- q_sound SOUNDS_02_PART1_SUCCESS_2 CH_GLADOS SUBTITLE_02_PART1_SUCCESS_2
|
||||
DROP_CUBE:
|
||||
- set_signal cube_dropper
|
||||
ENTER_BUTTON_ROOM:
|
||||
- open_portal portal_1
|
||||
BAD_PERSON:
|
||||
- q_sound SOUNDS_ESCAPE_01_PART1_NAG01_1 CH_GLADOS
|
||||
- q_sound SOUNDS_ESCAPE_01_PART1_NAG01_1 CH_GLADOS SUBTITLE_ESCAPE_01_PART1_NAG01_1
|
||||
- wait_for_channel CH_GLADOS
|
||||
- set_signal bad_person
|
||||
ENTER_SMALL_ROOM:
|
||||
- set_signal in_room
|
||||
- open_portal portal_2 0
|
||||
- q_sound SOUNDS_02_PART2_SUCCESS_1 CH_GLADOS
|
||||
- q_sound SOUNDS_02_PART2_SUCCESS_2 CH_GLADOS
|
||||
- q_sound SOUNDS_02_PART2_SUCCESS_1 CH_GLADOS SUBTITLE_02_PART2_SUCCESS_1
|
||||
- q_sound SOUNDS_02_PART2_SUCCESS_2 CH_GLADOS SUBTITLE_02_PART2_SUCCESS_2
|
||||
operators:
|
||||
- should_open_door = exit_2_0 and exit_2_1
|
||||
- should_open_door = should_open_door or bad_person
|
||||
|
|
|
@ -13,16 +13,16 @@ cutscenes:
|
|||
- save_checkpoint 0.001
|
||||
- open_portal ground_portal_2
|
||||
- start_cutscene BALL_2
|
||||
- q_sound SOUNDS_03_PART2_ENTRY_1 CH_GLADOS
|
||||
- q_sound SOUNDS_03_PART2_ENTRY_1 CH_GLADOS SUBTITLE_03_PART2_ENTRY_1
|
||||
- wait_for_signal horizontal_activiate 2
|
||||
- q_sound 03_PART2_PLATFORM_ACTIVATED_1 CH_GLADOS
|
||||
- q_sound 03_PART2_PLATFORM_ACTIVATED_1 CH_GLADOS SUBTITLE_03_PART2_PLATFORM_ACTIVATED_1
|
||||
INTRO:
|
||||
- save_checkpoint 0
|
||||
- open_portal ground_portal 0
|
||||
- q_sound SOUNDS_03_PART1_ENTRY_1 CH_GLADOS
|
||||
- q_sound SOUNDS_03_PART1_ENTRY_2 CH_GLADOS
|
||||
- q_sound SOUNDS_03_PART1_ENTRY_1 CH_GLADOS SUBTITLE_03_PART1_ENTRY_1
|
||||
- q_sound SOUNDS_03_PART1_ENTRY_2 CH_GLADOS SUBTITLE_03_PART1_ENTRY_2
|
||||
- wait_for_signal exit_activate 2
|
||||
- q_sound SOUNDS_03_PART1_SUCCESS_1 CH_GLADOS
|
||||
- q_sound SOUNDS_03_PART1_SUCCESS_1 CH_GLADOS SUBTITLE_03_PART1_SUCCESS_1
|
||||
START_BALL:
|
||||
- set_signal launch_ball
|
||||
- wait_for_signal exit_activate
|
||||
|
|
Binary file not shown.
|
@ -1,8 +1,8 @@
|
|||
cutscenes:
|
||||
SUCCESS:
|
||||
- q_sound SOUNDS_04_PART1_SUCCESS_1 CH_GLADOS
|
||||
- q_sound SOUNDS_04_PART1_SUCCESS_1 CH_GLADOS SUBTITLE_04_PART1_SUCCESS_1
|
||||
INTRO_CUTSCENE:
|
||||
- q_sound SOUNDS_04_PART1_ENTRY_1 CH_GLADOS
|
||||
- q_sound SOUNDS_04_PART1_ENTRY_1 CH_GLADOS SUBTITLE_04_PART1_ENTRY_1
|
||||
DROWN_PLAYER:
|
||||
- kill_player water
|
||||
OPEN_PORTAL:
|
||||
|
|
|
@ -4,20 +4,20 @@ cutscenes:
|
|||
INTRO_CUTSCENE:
|
||||
- set_signal cube_dropper
|
||||
- open_portal portal_0 0
|
||||
- q_sound SOUNDS_05_PART1_ENTRY_1 CH_GLADOS
|
||||
- q_sound SOUNDS_05_PART1_ENTRY_2 CH_GLADOS
|
||||
- q_sound SOUNDS_05_PART1_ENTRY_1 CH_GLADOS SUBTITLE_05_PART1_ENTRY_1
|
||||
- q_sound SOUNDS_05_PART1_ENTRY_2 CH_GLADOS SUBTITLE_05_PART1_ENTRY_2
|
||||
- start_cutscene NAG
|
||||
- wait_for_signal success
|
||||
- stop_cutscene NAG
|
||||
- q_sound SOUNDS_05_PART1_SUCCESS_1 CH_GLADOS
|
||||
- q_sound SOUNDS_05_PART1_SUCCESS_1 CH_GLADOS SUBTITLE_05_PART1_SUCCESS_1
|
||||
NAG:
|
||||
- delay 28
|
||||
- q_sound SOUNDS_05_PART1_NAG1_1 CH_GLADOS
|
||||
- q_sound SOUNDS_05_PART1_NAG1_1 CH_GLADOS SUBTITLE_05_PART1_NAG1_1
|
||||
- delay 20
|
||||
- q_sound SOUNDS_05_PART1_NAG2_1 CH_GLADOS
|
||||
- q_sound SOUNDS_05_PART1_NAG2_1 CH_GLADOS SUBTITLE_05_PART1_NAG2_1
|
||||
- delay 25
|
||||
- q_sound SOUNDS_05_PART1_NAG3_1 CH_GLADOS
|
||||
- q_sound SOUNDS_05_PART1_NAG3_1 CH_GLADOS SUBTITLE_05_PART1_NAG3_1
|
||||
- delay 25.001
|
||||
- q_sound SOUNDS_05_PART1_NAG4_1 CH_GLADOS
|
||||
- q_sound SOUNDS_05_PART1_NAG4_1 CH_GLADOS SUBTITLE_05_PART1_NAG4_1
|
||||
- delay 26
|
||||
- q_sound SOUNDS_05_PART1_NAG5_1 CH_GLADOS
|
||||
- q_sound SOUNDS_05_PART1_NAG5_1 CH_GLADOS SUBTITLE_05_PART1_NAG5_1
|
Binary file not shown.
|
@ -8,16 +8,16 @@ cutscenes:
|
|||
- play_animation piston_top piston_top_0
|
||||
- play_animation piston_bottom piston_bottom_0
|
||||
FIRST_ROOM:
|
||||
- q_sound SOUNDS_06_PART1_ENTRY_1 CH_GLADOS
|
||||
- q_sound SOUNDS_06_PART1_ENTRY_1 CH_GLADOS SUBTITLE_06_PART1_ENTRY_1
|
||||
- delay 4
|
||||
- open_portal first_room_portal 0
|
||||
OPEN_FIRST_DOOR:
|
||||
- set_signal room_0_exit
|
||||
SECOND_SUCCESS:
|
||||
- q_sound SOUNDS_06_PART1_SUCCESS_2_1 CH_GLADOS
|
||||
- q_sound SOUNDS_06_PART1_SUCCESS_2_1 CH_GLADOS SUBTITLE_06_PART1_SUCCESS_2_1
|
||||
- play_animation piston_top piston_top_1
|
||||
FIRST_SUCCESS:
|
||||
- q_sound SOUNDS_06_PART1_SUCCESS_1_1 CH_GLADOS
|
||||
- q_sound SOUNDS_06_PART1_SUCCESS_1_1 CH_GLADOS SUBTITLE_06_PART1_SUCCESS_1_1
|
||||
SECOND_ROOM:
|
||||
- close_portal 0
|
||||
- close_portal 1
|
||||
|
|
Binary file not shown.
|
@ -25,17 +25,17 @@ cutscenes:
|
|||
- start_cutscene portal_loop
|
||||
- start_cutscene platform_ferry
|
||||
- set_signal launch_ball
|
||||
- q_sound 07_PART1_ENTRY_1 CH_GLADOS
|
||||
- q_sound 07_PART1_ENTRY_2 CH_GLADOS
|
||||
- q_sound 07_PART1_ENTRY_3 CH_GLADOS
|
||||
- q_sound 07_PART1_ENTRY_1 CH_GLADOS SUBTITLE_07_PART1_ENTRY_1
|
||||
- q_sound 07_PART1_ENTRY_2 CH_GLADOS SUBTITLE_07_PART1_ENTRY_2
|
||||
- q_sound 07_PART1_ENTRY_3 CH_GLADOS SUBTITLE_07_PART1_ENTRY_3
|
||||
TILT:
|
||||
- delay 4
|
||||
- set_signal cube_dropper
|
||||
- play_animation tilt tilt
|
||||
START_1:
|
||||
- q_sound 07_PART2_ENTRY_1 CH_GLADOS
|
||||
- q_sound 07_PART2_ENTRY_1 CH_GLADOS SUBTITLE_07_PART2_ENTRY_1
|
||||
- wait_for_signal weeeee
|
||||
- q_sound 07_PART2_SUCCESS_1 CH_GLADOS
|
||||
- q_sound 07_PART2_SUCCESS_1 CH_GLADOS SUBTITLE_07_PART2_SUCCESS_1
|
||||
portal_loop:
|
||||
- label loop_start
|
||||
- open_portal portal_0 0
|
||||
|
@ -60,12 +60,12 @@ cutscenes:
|
|||
- start_cutscene platform_loop
|
||||
- close_portal 0
|
||||
- show_prompt CutscenePromptTypePortal0
|
||||
- q_sound 07_PART1_GET_DEVICE_COMPONENT_1 CH_GLADOS
|
||||
- q_sound 07_PART1_GET_DEVICE_COMPONENT_2 CH_GLADOS
|
||||
- q_sound 07_PART1_GET_DEVICE_COMPONENT_3 CH_GLADOS
|
||||
- q_sound 07_PART1_GET_DEVICE_COMPONENT_1 CH_GLADOS SUBTITLE_07_PART1_GET_DEVICE_COMPONENT_1
|
||||
- q_sound 07_PART1_GET_DEVICE_COMPONENT_2 CH_GLADOS SUBTITLE_07_PART1_GET_DEVICE_COMPONENT_2
|
||||
- q_sound 07_PART1_GET_DEVICE_COMPONENT_3 CH_GLADOS SUBTITLE_07_PART1_GET_DEVICE_COMPONENT_3
|
||||
- wait_for_signal trapped
|
||||
- q_sound 07_PART1_TRAPPED_1 CH_GLADOS
|
||||
- q_sound 07_PART1_TRAPPED_2 CH_GLADOS
|
||||
- q_sound 07_PART1_TRAPPED_1 CH_GLADOS SUBTITLE_07_PART1_TRAPPED_1
|
||||
- q_sound 07_PART1_TRAPPED_2 CH_GLADOS SUBTITLE_07_PART1_TRAPPED_2
|
||||
- wait_for_channel CH_GLADOS
|
||||
- set_signal trap_door
|
||||
PROMPT_SWITCH:
|
||||
|
|
|
@ -3,13 +3,11 @@
|
|||
|
||||
#include "../../build/src/audio/clips.h"
|
||||
|
||||
unsigned short soundsSkippable[10] = {
|
||||
unsigned short soundsSkippable[8] = {
|
||||
SOUNDS_PORTAL_ENTER1,
|
||||
SOUNDS_PORTAL_ENTER2,
|
||||
SOUNDS_PORTAL_EXIT1,
|
||||
SOUNDS_PORTAL_EXIT2,
|
||||
SOUNDS_PORTALGUN_SHOOT_RED1,
|
||||
SOUNDS_PORTALGUN_SHOOT_BLUE1,
|
||||
SOUNDS_CONCRETE1, //left foot
|
||||
SOUNDS_CONCRETE2, //right foot
|
||||
SOUNDS_CONCRETE3, //land
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __AUDIO_CLIPS_H__
|
||||
#define __AUDIO_CLIPS_H__
|
||||
|
||||
extern unsigned short soundsSkippable[10];
|
||||
extern unsigned short soundsSkippable[8];
|
||||
|
||||
extern unsigned short soundsPortalEnter[2];
|
||||
extern unsigned short soundsPortalExit[2];
|
||||
|
|
|
@ -42,10 +42,13 @@ unsigned short gActionSourceButtonMask[ControllerActionSourceCount] = {
|
|||
};
|
||||
|
||||
int gActionState = 0;
|
||||
int gMutedActions = 0;
|
||||
struct Vector2 gDirections[2];
|
||||
|
||||
#define ACTION_TO_BITMASK(action) (1 << (action))
|
||||
|
||||
void controllerActionApply(enum ControllerAction action) {
|
||||
gActionState |= (1 << action);
|
||||
gActionState |= ACTION_TO_BITMASK(action);
|
||||
}
|
||||
|
||||
#define DEADZONE_SIZE 5
|
||||
|
@ -126,6 +129,8 @@ void controllerActionRead() {
|
|||
gDirections[0] = gZeroVec2;
|
||||
gDirections[1] = gZeroVec2;
|
||||
|
||||
int nextMutedState = 0;
|
||||
|
||||
for (int controllerIndex = 0; controllerIndex < 2; ++controllerIndex) {
|
||||
for (int sourceIndex = 0; sourceIndex < ControllerActionSourceCount; ++sourceIndex) {
|
||||
enum ControllerAction action = gSaveData.controls.controllerSettings[controllerIndex][sourceIndex];
|
||||
|
@ -136,6 +141,12 @@ void controllerActionRead() {
|
|||
if (sourceIndex == ControllerActionSourceCUpButton || sourceIndex == ControllerActionSourceDUpButton) {
|
||||
sourceIndex += 3;
|
||||
}
|
||||
} else if (IS_HOLDABLE_ACTION(action) && controllerGetButton(controllerIndex, gActionSourceButtonMask[sourceIndex])) {
|
||||
if (ACTION_TO_BITMASK(action) & gMutedActions) {
|
||||
nextMutedState |= ACTION_TO_BITMASK(action);
|
||||
} else {
|
||||
controllerActionApply(action);
|
||||
}
|
||||
} else if (controllerGetButtonDown(controllerIndex, gActionSourceButtonMask[sourceIndex])) {
|
||||
controllerActionApply(action);
|
||||
}
|
||||
|
@ -146,6 +157,8 @@ void controllerActionRead() {
|
|||
gDirections[i].x = clampf(gDirections[i].x, -1.0f, 1.0f);
|
||||
gDirections[i].y = clampf(gDirections[i].y, -1.0f, 1.0f);
|
||||
}
|
||||
|
||||
gMutedActions = nextMutedState;
|
||||
}
|
||||
|
||||
struct Vector2 controllerDirectionGet(enum ControllerAction direction) {
|
||||
|
@ -160,6 +173,10 @@ int controllerActionGet(enum ControllerAction action) {
|
|||
return (gActionState & (1 << action)) != 0;
|
||||
}
|
||||
|
||||
void controllerActionMuteActive() {
|
||||
gMutedActions = gActionState;
|
||||
}
|
||||
|
||||
int controllerSourcesForAction(enum ControllerAction action, struct ControllerSourceWithController* sources, int maxSources) {
|
||||
int index = 0;
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ enum ControllerAction {
|
|||
};
|
||||
|
||||
#define IS_DIRECTION_ACTION(action) ((action) >= ControllerActionMove && (action) <= ControllerActionRotate)
|
||||
#define IS_HOLDABLE_ACTION(action) ((action) >= ControllerActionOpenPortal0 && (action) <= ControllerActionOpenPortal1)
|
||||
#define IS_VALID_SOURCE(source) ((source) >= 0 && (source) < ControllerActionSourceCount)
|
||||
|
||||
#define MAX_DEADZONE 0.25f
|
||||
|
@ -60,6 +61,7 @@ void controllerActionRead();
|
|||
void controllerSetDeadzone(float percent);
|
||||
struct Vector2 controllerDirectionGet(enum ControllerAction direction);
|
||||
int controllerActionGet(enum ControllerAction action);
|
||||
void controllerActionMuteActive();
|
||||
|
||||
int controllerSourcesForAction(enum ControllerAction action, struct ControllerSourceWithController* sources, int maxSources);
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ u64 gTriggeredCutscenes;
|
|||
struct QueuedSound {
|
||||
struct QueuedSound* next;
|
||||
u16 soundId;
|
||||
u16 subtitleId;
|
||||
float volume;
|
||||
};
|
||||
|
||||
|
@ -94,7 +95,7 @@ void cutsceneRunnerCancel(struct CutsceneRunner* runner) {
|
|||
runner->currentCutscene = NULL;
|
||||
}
|
||||
|
||||
void cutsceneQueueSound(int soundId, float volume, int channel) {
|
||||
void cutsceneQueueSound(int soundId, float volume, int channel, int subtitleId) {
|
||||
struct QueuedSound* next = gCutsceneNextFreeSound;
|
||||
|
||||
if (!next) {
|
||||
|
@ -106,6 +107,7 @@ void cutsceneQueueSound(int soundId, float volume, int channel) {
|
|||
next->next = NULL;
|
||||
next->soundId = soundId;
|
||||
next->volume = volume;
|
||||
next->subtitleId = subtitleId;
|
||||
|
||||
struct QueuedSound* tail = gCutsceneSoundQueues[channel];
|
||||
|
||||
|
@ -140,7 +142,7 @@ void cutsceneRunnerStartStep(struct CutsceneRunner* runner) {
|
|||
break;
|
||||
case CutsceneStepTypeQueueSound:
|
||||
{
|
||||
cutsceneQueueSoundInChannel(step->queueSound.soundId, step->queueSound.volume * (1.0f / 255.0f), step->queueSound.channel);
|
||||
cutsceneQueueSoundInChannel(step->queueSound.soundId, step->queueSound.volume * (1.0f / 255.0f), step->queueSound.channel, step->queueSound.subtitleId);
|
||||
break;
|
||||
}
|
||||
case CutsceneStepTypeDelay:
|
||||
|
@ -395,6 +397,8 @@ void cutscenesUpdateSounds() {
|
|||
struct QueuedSound* curr = gCutsceneSoundQueues[i];
|
||||
|
||||
gCutsceneCurrentSound[i] = soundPlayerPlay(curr->soundId, curr->volume, gCutsceneChannelPitch[i], NULL, NULL);
|
||||
hudShowSubtitle(&gScene.hud, curr->subtitleId);
|
||||
|
||||
gCutsceneSoundQueues[i] = curr->next;
|
||||
|
||||
curr->next = gCutsceneNextFreeSound;
|
||||
|
@ -402,6 +406,7 @@ void cutscenesUpdateSounds() {
|
|||
} else {
|
||||
if (gCutsceneCurrentSound[i] != SOUND_ID_NONE) {
|
||||
soundPlayerPlay(soundsIntercom[1], 1.0f, gCutsceneChannelPitch[i], NULL, NULL);
|
||||
hudResolveSubtitle(&gScene.hud);
|
||||
}
|
||||
|
||||
gCutsceneCurrentSound[i] = SOUND_ID_NONE;
|
||||
|
@ -563,20 +568,23 @@ void cutsceneSerializeRead(struct Serializer* serializer) {
|
|||
for (int i = 0; i < CH_COUNT; ++i) {
|
||||
s16 nextId;
|
||||
serializeRead(serializer, &nextId, sizeof(nextId));
|
||||
|
||||
|
||||
while (nextId != SOUND_ID_NONE) {
|
||||
s16 nextSubtitleId;
|
||||
serializeRead(serializer, &nextSubtitleId, sizeof(nextSubtitleId));
|
||||
u8 volume;
|
||||
serializeRead(serializer, &volume, sizeof(volume));
|
||||
cutsceneQueueSound(nextId, volume * (1.0f / 255.0f), i);
|
||||
cutsceneQueueSound(nextId, volume * (1.0f / 255.0f), i, nextSubtitleId);
|
||||
serializeRead(serializer, &nextId, sizeof(nextId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cutsceneQueueSoundInChannel(int soundId, float volume, int channel) {
|
||||
void cutsceneQueueSoundInChannel(int soundId, float volume, int channel, int subtitleId) {
|
||||
if (!gCutsceneSoundQueues[channel] && !soundPlayerIsPlaying(gCutsceneCurrentSound[channel])) {
|
||||
cutsceneQueueSound(soundsIntercom[0], volume, channel);
|
||||
cutsceneQueueSound(soundsIntercom[0], volume, channel, subtitleId);
|
||||
}
|
||||
|
||||
cutsceneQueueSound(soundId, volume, channel);
|
||||
cutsceneQueueSound(soundId, volume, channel, subtitleId);
|
||||
}
|
|
@ -43,6 +43,6 @@ void cutsceneSerializeWrite(struct Serializer* serializer, SerializeAction actio
|
|||
void cutsceneSerializeRead(struct Serializer* serializer);
|
||||
|
||||
int cutsceneRunnerIsChannelPlaying(int channel);
|
||||
void cutsceneQueueSoundInChannel(int soundId, float volume, int channel);
|
||||
void cutsceneQueueSoundInChannel(int soundId, float volume, int channel, int subtitleId);
|
||||
|
||||
#endif
|
|
@ -63,6 +63,70 @@ enum CutscenePromptType {
|
|||
CutscenePromptTypeJump,
|
||||
};
|
||||
|
||||
enum CutsceneSubtitleType {
|
||||
CutsceneSubtitleTypeNone,
|
||||
SUBTITLE_00_PART1_ENTRY_1,
|
||||
SUBTITLE_00_PART1_ENTRY_2,
|
||||
SUBTITLE_00_PART1_ENTRY_3,
|
||||
SUBTITLE_00_PART1_ENTRY_4,
|
||||
SUBTITLE_00_PART1_ENTRY_5,
|
||||
SUBTITLE_00_PART1_ENTRY_6,
|
||||
SUBTITLE_00_PART1_ENTRY_7,
|
||||
SUBTITLE_00_PART1_SUCCESS_1,
|
||||
SUBTITLE_00_PART1_SUCCESS_2,
|
||||
SUBTITLE_00_PART1_SUCCESS_3,
|
||||
SUBTITLE_00_PART2_ENTRY_1,
|
||||
SUBTITLE_00_PART2_SUCCESS_1,
|
||||
SUBTITLE_01_PART1_ENTRY_1,
|
||||
SUBTITLE_01_PART1_ENTRY_2,
|
||||
SUBTITLE_01_PART1_GET_PORTAL_GUN_1,
|
||||
SUBTITLE_01_PART1_GET_PORTAL_GUN_2,
|
||||
SUBTITLE_01_PART1_GET_PORTAL_GUN_3,
|
||||
SUBTITLE_01_PART1_GET_PORTAL_GUN_4,
|
||||
SUBTITLE_01_PART1_GET_PORTAL_GUN_5,
|
||||
SUBTITLE_01_PART1_GET_PORTAL_GUN_6,
|
||||
SUBTITLE_01_PART1_GET_PORTAL_GUN_7,
|
||||
SUBTITLE_01_PART1_GET_PORTAL_GUN_8,
|
||||
SUBTITLE_01_PART2_ENTRY_1,
|
||||
SUBTITLE_01_PART2_SUCCESS_1,
|
||||
SUBTITLE_02_PART1_ENTRY_1,
|
||||
SUBTITLE_02_PART1_ENTRY_2,
|
||||
SUBTITLE_02_PART1_SUCCESS_1,
|
||||
SUBTITLE_02_PART1_SUCCESS_2,
|
||||
SUBTITLE_ESCAPE_01_PART1_NAG01_1,
|
||||
SUBTITLE_02_PART2_SUCCESS_1,
|
||||
SUBTITLE_02_PART2_SUCCESS_2,
|
||||
SUBTITLE_03_PART2_ENTRY_1,
|
||||
SUBTITLE_03_PART2_PLATFORM_ACTIVATED_1,
|
||||
SUBTITLE_03_PART1_ENTRY_1,
|
||||
SUBTITLE_03_PART1_ENTRY_2,
|
||||
SUBTITLE_03_PART1_SUCCESS_1,
|
||||
SUBTITLE_04_PART1_SUCCESS_1,
|
||||
SUBTITLE_04_PART1_ENTRY_1,
|
||||
SUBTITLE_05_PART1_ENTRY_1,
|
||||
SUBTITLE_05_PART1_ENTRY_2,
|
||||
SUBTITLE_05_PART1_SUCCESS_1,
|
||||
SUBTITLE_05_PART1_NAG1_1,
|
||||
SUBTITLE_05_PART1_NAG2_1,
|
||||
SUBTITLE_05_PART1_NAG3_1,
|
||||
SUBTITLE_05_PART1_NAG4_1,
|
||||
SUBTITLE_05_PART1_NAG5_1,
|
||||
SUBTITLE_06_PART1_ENTRY_1,
|
||||
SUBTITLE_06_PART1_SUCCESS_2_1,
|
||||
SUBTITLE_06_PART1_SUCCESS_1_1,
|
||||
SUBTITLE_07_PART1_ENTRY_1,
|
||||
SUBTITLE_07_PART1_ENTRY_2,
|
||||
SUBTITLE_07_PART1_ENTRY_3,
|
||||
SUBTITLE_07_PART2_ENTRY_1,
|
||||
SUBTITLE_07_PART2_SUCCESS_1,
|
||||
SUBTITLE_07_PART1_GET_DEVICE_COMPONENT_1,
|
||||
SUBTITLE_07_PART1_GET_DEVICE_COMPONENT_2,
|
||||
SUBTITLE_07_PART1_GET_DEVICE_COMPONENT_3,
|
||||
SUBTITLE_07_PART1_TRAPPED_1,
|
||||
SUBTITLE_07_PART1_TRAPPED_2,
|
||||
};
|
||||
|
||||
|
||||
#define CH_NONE 0xFF
|
||||
#define CH_GLADOS 0
|
||||
|
||||
|
@ -80,6 +144,7 @@ struct CutsceneStep {
|
|||
struct {
|
||||
u16 soundId;
|
||||
u8 channel;
|
||||
u16 subtitleId;
|
||||
u8 volume;
|
||||
} queueSound;
|
||||
struct {
|
||||
|
@ -241,6 +306,7 @@ enum AnimationSoundType {
|
|||
AnimationSoundTypeNone,
|
||||
AnimationSoundTypeLightRail,
|
||||
AnimationSoundTypePiston,
|
||||
AnimationSoundTypeArm,
|
||||
};
|
||||
|
||||
struct AnimationInfo {
|
||||
|
|
|
@ -235,6 +235,9 @@ static void gameProc(void* arg) {
|
|||
levelLoadWithCallbacks(levelGetQueued());
|
||||
cutsceneRunnerReset();
|
||||
dynamicAssetsReset();
|
||||
// if a portal fire button is being held
|
||||
// don't fire portals until it is released
|
||||
controllerActionMuteActive();
|
||||
gSceneCallbacks->initCallback(gSceneCallbacks->data);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,22 @@
|
|||
#include "audio_options.h"
|
||||
|
||||
#include "../controls/controller.h"
|
||||
#include "../savefile/savefile.h"
|
||||
#include "../font/dejavusans.h"
|
||||
#include "../audio/soundplayer.h"
|
||||
#include "../build/assets/materials/ui.h"
|
||||
#include "../build/src/audio/clips.h"
|
||||
|
||||
#define GAMEPLAY_Y 54
|
||||
#define GAMEPLAY_WIDTH 252
|
||||
#define GAMEPLAY_HEIGHT 124
|
||||
#define GAMEPLAY_X ((SCREEN_WD - GAMEPLAY_WIDTH) / 2)
|
||||
|
||||
void audioOptionsInit(struct AudioOptions* audioOptions) {
|
||||
audioOptions->selectedItem = 0;
|
||||
audioOptions->selectedItem = AudioOptionSubtitlesEnabled;
|
||||
|
||||
audioOptions->subtitlesEnabled = menuBuildCheckbox(&gDejaVuSansFont, "Closed Captions", GAMEPLAY_X + 8, GAMEPLAY_Y + 8);
|
||||
audioOptions->subtitlesEnabled.checked = (gSaveData.controls.flags & ControlSaveSubtitlesEnabled) != 0;
|
||||
}
|
||||
|
||||
enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) {
|
||||
|
@ -13,6 +26,38 @@ enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) {
|
|||
return MenuDirectionUp;
|
||||
}
|
||||
|
||||
if (controllerDir & ControllerDirectionDown) {
|
||||
++audioOptions->selectedItem;
|
||||
|
||||
if (audioOptions->selectedItem == AudioOptionCount) {
|
||||
audioOptions->selectedItem = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (controllerDir & ControllerDirectionUp) {
|
||||
if (audioOptions->selectedItem == 0) {
|
||||
audioOptions->selectedItem = AudioOptionCount - 1;
|
||||
} else {
|
||||
--audioOptions->selectedItem;
|
||||
}
|
||||
}
|
||||
|
||||
switch (audioOptions->selectedItem) {
|
||||
case AudioOptionSubtitlesEnabled:
|
||||
if (controllerGetButtonDown(0, A_BUTTON)) {
|
||||
audioOptions->subtitlesEnabled.checked = !audioOptions->subtitlesEnabled.checked;
|
||||
soundPlayerPlay(SOUNDS_BUTTONCLICKRELEASE, 1.0f, 0.5f, NULL, NULL);
|
||||
|
||||
if (audioOptions->subtitlesEnabled.checked) {
|
||||
gSaveData.controls.flags |= ControlSaveSubtitlesEnabled;
|
||||
} else {
|
||||
gSaveData.controls.flags &= ~ControlSaveSubtitlesEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ((controllerDir & ControllerDirectionLeft || controllerGetButtonDown(0, L_TRIG) || controllerGetButtonDown(0, Z_TRIG))) {
|
||||
return MenuDirectionLeft;
|
||||
}
|
||||
|
@ -25,5 +70,18 @@ enum MenuDirection audioOptionsUpdate(struct AudioOptions* audioOptions) {
|
|||
}
|
||||
|
||||
void audioOptionsRender(struct AudioOptions* audioOptions, struct RenderState* renderState, struct GraphicsTask* task) {
|
||||
gSPDisplayList(renderState->dl++, ui_material_list[SOLID_ENV_INDEX]);
|
||||
|
||||
gSPDisplayList(renderState->dl++, audioOptions->subtitlesEnabled.outline);
|
||||
renderState->dl = menuCheckboxRender(&audioOptions->subtitlesEnabled, renderState->dl);
|
||||
|
||||
gSPDisplayList(renderState->dl++, ui_material_revert_list[SOLID_ENV_INDEX]);
|
||||
|
||||
gSPDisplayList(renderState->dl++, ui_material_list[DEJAVU_SANS_INDEX]);
|
||||
|
||||
gDPPipeSync(renderState->dl++);
|
||||
menuSetRenderColor(renderState, audioOptions->selectedItem == AudioOptionSubtitlesEnabled, &gSelectionGray, &gColorWhite);
|
||||
gSPDisplayList(renderState->dl++, audioOptions->subtitlesEnabled.text);
|
||||
|
||||
gSPDisplayList(renderState->dl++, ui_material_revert_list[DEJAVU_SANS_INDEX]);
|
||||
}
|
|
@ -4,7 +4,14 @@
|
|||
#include "./menu.h"
|
||||
#include "../graphics/graphics.h"
|
||||
|
||||
enum AudioOption {
|
||||
AudioOptionSubtitlesEnabled,
|
||||
|
||||
AudioOptionCount,
|
||||
};
|
||||
|
||||
struct AudioOptions {
|
||||
struct MenuCheckbox subtitlesEnabled;
|
||||
short selectedItem;
|
||||
};
|
||||
|
||||
|
|
|
@ -461,6 +461,11 @@ void controlsMenuRender(struct ControlsMenu* controlsMenu, struct RenderState* r
|
|||
#define CONTROL_PROMPT_HEIGHT 24
|
||||
#define CONTROL_PROMPT_PADDING 6
|
||||
|
||||
#define SUBTITLE_LEFT_MARGIN 10
|
||||
#define SUBTITLE_BOTTOM_MARGIN 10
|
||||
#define SUBTITLE_PADDING 5
|
||||
|
||||
|
||||
void controlsRenderPrompt(enum ControllerAction action, char* message, float opacity, struct RenderState* renderState) {
|
||||
struct Vector2s16 size = fontMeasure(&gDejaVuSansFont, message);
|
||||
|
||||
|
@ -503,4 +508,41 @@ void controlsRenderPrompt(enum ControllerAction action, char* message, float opa
|
|||
gDPSetEnvColor(renderState->dl++, 232, 206, 80, opacityAsInt);
|
||||
renderState->dl = controlsRenderIcons(renderState->dl, action, textPositionX - CONTROL_PROMPT_PADDING, textPositionY);
|
||||
gSPDisplayList(renderState->dl++, ui_material_revert_list[BUTTON_ICONS_INDEX]);
|
||||
}
|
||||
|
||||
void controlsRenderSubtitle(char* message, float opacity, struct RenderState* renderState) {
|
||||
struct Vector2s16 size = fontMeasure(&gDejaVuSansFont, message);
|
||||
|
||||
int opacityAsInt = (int)(255 * opacity);
|
||||
|
||||
if (opacityAsInt > 255) {
|
||||
opacityAsInt = 255;
|
||||
} else if (opacityAsInt < 0) {
|
||||
opacityAsInt = 0;
|
||||
}
|
||||
|
||||
int textPositionX = (SUBTITLE_LEFT_MARGIN + SUBTITLE_PADDING);
|
||||
int textPositionY = (SCREEN_HT - SUBTITLE_BOTTOM_MARGIN - SUBTITLE_PADDING) - size.y;
|
||||
|
||||
gSPDisplayList(renderState->dl++, ui_material_list[SOLID_TRANSPARENT_OVERLAY_INDEX]);
|
||||
gDPSetEnvColor(renderState->dl++, 0, 0, 0, opacityAsInt / 3);
|
||||
gDPFillRectangle(
|
||||
renderState->dl++,
|
||||
textPositionX - CONTROL_PROMPT_PADDING,
|
||||
textPositionY - CONTROL_PROMPT_PADDING,
|
||||
textPositionX + size.x + CONTROL_PROMPT_PADDING,
|
||||
SCREEN_HT - SUBTITLE_BOTTOM_MARGIN
|
||||
);
|
||||
gSPDisplayList(renderState->dl++, ui_material_revert_list[SOLID_TRANSPARENT_OVERLAY_INDEX]);
|
||||
|
||||
gSPDisplayList(renderState->dl++, ui_material_list[DEJAVU_SANS_INDEX]);
|
||||
gDPSetEnvColor(renderState->dl++, 255, 60, 60, opacityAsInt);
|
||||
renderState->dl = fontRender(
|
||||
&gDejaVuSansFont,
|
||||
message,
|
||||
textPositionX,
|
||||
textPositionY,
|
||||
renderState->dl
|
||||
);
|
||||
gSPDisplayList(renderState->dl++, ui_material_revert_list[DEJAVU_SANS_INDEX]);
|
||||
}
|
|
@ -42,5 +42,6 @@ enum MenuDirection controlsMenuUpdate(struct ControlsMenu* controlsMenu);
|
|||
void controlsMenuRender(struct ControlsMenu* controlsMenu, struct RenderState* renderState, struct GraphicsTask* task);
|
||||
|
||||
void controlsRenderPrompt(enum ControllerAction action, char* message, float opacity, struct RenderState* renderState);
|
||||
void controlsRenderSubtitle(char* message, float opacity, struct RenderState* renderState);
|
||||
|
||||
#endif
|
|
@ -38,6 +38,8 @@ enum ControlSaveFlags {
|
|||
ControlSaveFlagsInvertYaw = (1 << 1),
|
||||
ControlSaveTankControls = (1 << 2),
|
||||
|
||||
ControlSaveSubtitlesEnabled = (1 << 5),
|
||||
|
||||
ControlSaveMoveablePortals = (1 << 8),
|
||||
ControlSaveWideScreen = (1 << 9),
|
||||
};
|
||||
|
|
|
@ -115,7 +115,7 @@ void ballInit(struct Ball* ball, struct Vector3* position, struct Vector3* veloc
|
|||
|
||||
dynamicSceneSetRoomFlags(ball->dynamicId, ROOM_FLAG_FROM_INDEX(startingRoom));
|
||||
|
||||
ball->soundLoopId = soundPlayerPlay(soundsBallLoop, 1.0f, 1.0f, &ball->rigidBody.transform.position, &ball->rigidBody.velocity);
|
||||
ball->soundLoopId = soundPlayerPlay(soundsBallLoop, 1.5f, 1.0f, &ball->rigidBody.transform.position, &ball->rigidBody.velocity);
|
||||
}
|
||||
|
||||
void ballTurnOnCollision(struct Ball* ball) {
|
||||
|
@ -134,7 +134,11 @@ void ballInitBurn(struct Ball* ball, struct ContactManifold* manifold) {
|
|||
vector3Negate(&normal, &normal);
|
||||
}
|
||||
effectsSplashPlay(&gScene.effects, &gBallBounce, &ball->rigidBody.transform.position, &manifold->normal);
|
||||
soundPlayerPlay(soundsBallBounce, 1.0f, 1.0f, &manifold->contacts[0].contactAWorld, &gZeroVec);
|
||||
struct Vector3 position = manifold->contacts[0].contactAWorld;
|
||||
if (manifold->shapeA->body) {
|
||||
transformPoint(&manifold->shapeA->body->transform, &position, &position);
|
||||
}
|
||||
soundPlayerPlay(soundsBallBounce, 1.5f, 1.0f, &position, &gZeroVec);
|
||||
ball->flags |= BallJustBounced;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "../util/time.h"
|
||||
#include "../levels/levels.h"
|
||||
#include "./scene.h"
|
||||
#include "../savefile/savefile.h"
|
||||
|
||||
#define HUD_CENTER_WIDTH 6
|
||||
#define HUD_CENTER_HEIGHT 8
|
||||
|
@ -35,6 +36,7 @@
|
|||
void hudInit(struct Hud* hud) {
|
||||
hud->promptType = CutscenePromptTypeNone;
|
||||
hud->promptOpacity = 0.0f;
|
||||
hud->subtitleOpacity = 0.0f;
|
||||
|
||||
hud->flags = 0;
|
||||
hud->resolvedPrompts = 0;
|
||||
|
@ -58,14 +60,20 @@ void hudUpdate(struct Hud* hud) {
|
|||
}
|
||||
|
||||
float targetPromptOpacity = (hud->flags & HudFlagsShowingPrompt) ? 1.0 : 0.0f;
|
||||
float targetSubtitleOpacity = (hud->flags & HudFlagsShowingSubtitle) ? 0.7: 0.0f;
|
||||
|
||||
if (targetPromptOpacity != hud->promptOpacity) {
|
||||
hud->promptOpacity = mathfMoveTowards(hud->promptOpacity, targetPromptOpacity, FIXED_DELTA_TIME / PROMPT_FADE_TIME);
|
||||
}
|
||||
|
||||
if (targetSubtitleOpacity != hud->subtitleOpacity) {
|
||||
hud->subtitleOpacity = mathfMoveTowards(hud->subtitleOpacity, targetSubtitleOpacity, FIXED_DELTA_TIME / PROMPT_FADE_TIME);
|
||||
}
|
||||
|
||||
if (targetPromptOpacity && (hud->resolvedPrompts & (1 << hud->promptType)) != 0) {
|
||||
hudShowActionPrompt(hud, CutscenePromptTypeNone);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void hudUpdatePortalIndicators(struct Hud* hud, struct Ray* raycastRay, struct Vector3* playerUp) {
|
||||
|
@ -117,6 +125,71 @@ char* gPromptText[] = {
|
|||
"TO JUMP",
|
||||
};
|
||||
|
||||
char* gSubtitleText[] = {
|
||||
"",
|
||||
"Hello and, again, welcome to the Aperture Science \ncomputer-aided enrichment center.",
|
||||
"We hope your brief detention in the relaxation \nvault has been a pleasant one.",
|
||||
"Your specimen has been processed and we are now\nready to begin the test proper.",
|
||||
"Before we start, however, keep in mind that \nalthough fun and learning are the primary goals of\nall enrichment center activities, serious\ninjuries may occur.",
|
||||
"For your own safety and the safety of others, \nplease refrain from t-*bzzzzzt*",
|
||||
"Por favor bordón de fallar. Muchos gracias de \nfallar gra-*bzzt*",
|
||||
"Stand back. The portal will open in three, two, one.",
|
||||
"Excellent. Please proceed into the chamberlock\nafter completing each test.",
|
||||
"First, however, note the incandescent particle\nfield across the exit.",
|
||||
"This Aperture Science Material Emancipation Grid\nwill vaporize any unauthorized equipment that\npasses through it - for instance, the Aperture\nScience Weighted Storage Cube.",
|
||||
"Please place the Weighted Storage Cube on the \nFifteen Hundred Megawatt Aperture Science Heavy \nDuty Super-Colliding Super Button.",
|
||||
"Perfect. Please move quickly to the chamberlock,\nas the effects of prolonged exposure to the \nbutton are not part of this test.",
|
||||
"You're doing very well!",
|
||||
"Please be advised that a noticeable taste of blood\nis not part of any test protocol but is an \nunintended side effect of the Aperture Science \nMaterial Emancipation Grill, which may,\nin semi-rare cases, emancipate dental \nfillings, crowns, tooth enamel and teeth.",
|
||||
"Very good! You are now in possession of the \nAperture Science Handheld Portal Device.",
|
||||
"With it, you can create your own portals.",
|
||||
"These intra dimensional gates have proven to \nbe completely safe.",
|
||||
"The device, however, has not.",
|
||||
"Do not touch the operational end of the device.",
|
||||
"Do not look directly at the operational end of the\ndevice.",
|
||||
"Do not submerge the device in liquid, even partially.",
|
||||
"Most importantly, under no circumstances should \nyou-*bzzzpt*",
|
||||
"Please proceed to the chamberlock. Mind the gap.",
|
||||
"Well done! Remember: The Aperture Science Bring \nYour Daughter to Work Day is the perfect time to\nhave her tested.",
|
||||
"Welcome to test chamber four.",
|
||||
"You're doing quite well.",
|
||||
"Once again, excellent work.",
|
||||
"As part of a required test protocol, we will not \nmonitor the next test chamber. You will be \nentirely on your own.Good luck.",
|
||||
"You're not a good person. You know that, right?",
|
||||
"As part of a required test protocol, our previous\nstatement suggesting that we would not monitor \nthis chamber was an outright fabrication.",
|
||||
"Good job! As part of a required test protocol, we\nwill stop enhancing the truth in three, two, o-\n*bzzt*",
|
||||
"Warning devices are required on all mobile \nequipment. However, alarms and flashing hazard lights \nhave been found to agitate the high energy pellet\nand have therefore been disabled for \nyour safety.",
|
||||
"Good. Now use the Aperture Science Unstationary\nScaffold to reach the chamberlock.",
|
||||
"While safety is one of many Enrichment Center goals,\nthe Aperture Science High Energy Pellet, seen \nto the left of the chamber, can and has \ncaused permanent disabilities such as \nvaporization.",
|
||||
"Please be careful.",
|
||||
"Unbelievable! You, <B>Subject Name Here<B>, must be\nthe pride of <B>Subject Hometown Here<B>.",
|
||||
"Very impressive. Please note that any appearance of\ndanger is merely a device to enhance your \ntesting experience.",
|
||||
"Please note that we have added a consequence for \nfailure. Any contact with the chamber floor will \nresult in an 'unsatisfactory' mark on your \nofficial testing record followed by \ndeath. Good luck!",
|
||||
"The Enrichment Center regrets to inform you that\nthis next test is impossible.",
|
||||
"Make no attempt to solve it.",
|
||||
"Fantastic! You remained resolute and resourceful in\nan atmosphere of extreme pessimism.",
|
||||
"The Enrichment Center apologizes for this clearly \nbroken test chamber.",
|
||||
"Once again, the Enrichment Center offers its most \nsincere apologies on the occasion of this \nunsolvable test environment.",
|
||||
"Frankly, this chamber was a mistake. If we were you,\nwe would quit now.",
|
||||
"No one will blame you for giving up. In fact, quitting\nat this point is a perfectly reasonable \nresponse.",
|
||||
"Quit now and cake will be served immediately.",
|
||||
"Hello again. To reiterate our previous warning: This\ntest (garbled) -ard momentum.",
|
||||
"Momentum, a function of mass and velocity, is\nconserved between portals. In layman's terms: speedy\nthing goes in, speedy thing comes out.",
|
||||
"Spectacular. You appear to understand how a portal\naffects forward momentum, or to be more precise,\nhow it does not.",
|
||||
"The Enrichment Center promises to always provide a\nsafe testing environment.",
|
||||
"In dangerous testing environments, the Enrichment \nCenter promises to always provide useful advice.",
|
||||
"For instance, the floor here will kill you - try to \navoid it.",
|
||||
"Get ot ydaer f-f-fling yourself. F-Fling into sp\n-*bzzt*",
|
||||
"Weeeeeeeeeeeeeeeeeeeeee-*bzzt*",
|
||||
"The device has been modified so that it can now \nmanufacture two linked portals at once.",
|
||||
"As part of an optional test protocol, we are pleased\nto present an amusing fact:",
|
||||
"The device is now more valuable than the organs \nand combined incomes of everyone in <B>Subject \nHometown Here<B>.",
|
||||
"Through no fault of the Enrichment Center, you \nhave managed to trap yourself in this room.",
|
||||
"An escape hatch will open in three, two, one."
|
||||
};
|
||||
|
||||
|
||||
|
||||
void hudShowActionPrompt(struct Hud* hud, enum CutscenePromptType promptType) {
|
||||
if (promptType == CutscenePromptTypeNone) {
|
||||
hud->flags &= ~HudFlagsShowingPrompt;
|
||||
|
@ -127,10 +200,24 @@ void hudShowActionPrompt(struct Hud* hud, enum CutscenePromptType promptType) {
|
|||
hud->promptType = promptType;
|
||||
}
|
||||
|
||||
void hudShowSubtitle(struct Hud* hud, enum CutsceneSubtitleType subtitleType) {
|
||||
if (subtitleType == CutsceneSubtitleTypeNone) {
|
||||
hud->flags &= ~HudFlagsShowingSubtitle;
|
||||
return;
|
||||
}
|
||||
|
||||
hud->flags |= HudFlagsShowingSubtitle;
|
||||
hud->subtitleType = subtitleType;
|
||||
}
|
||||
|
||||
void hudResolvePrompt(struct Hud* hud, enum CutscenePromptType promptType) {
|
||||
hud->resolvedPrompts |= (1 << promptType);
|
||||
}
|
||||
|
||||
void hudResolveSubtitle(struct Hud* hud) {
|
||||
hud->flags &= ~HudFlagsShowingSubtitle;
|
||||
}
|
||||
|
||||
void hudRender(struct Hud* hud, struct Player* player, struct RenderState* renderState) {
|
||||
if (player->flags & PlayerIsDead) {
|
||||
gSPDisplayList(renderState->dl++, hud_death_overlay);
|
||||
|
@ -245,4 +332,8 @@ void hudRender(struct Hud* hud, struct Player* player, struct RenderState* rende
|
|||
if (hud->promptOpacity > 0.0f && hud->promptType != CutscenePromptTypeNone) {
|
||||
controlsRenderPrompt(gPromptActions[hud->promptType], gPromptText[hud->promptType], hud->promptOpacity, renderState);
|
||||
}
|
||||
|
||||
if (hud->subtitleOpacity > 0.0f && gSaveData.controls.flags & ControlSaveSubtitlesEnabled) {
|
||||
controlsRenderSubtitle(gSubtitleText[hud->subtitleType], hud->subtitleOpacity, renderState);
|
||||
}
|
||||
}
|
|
@ -13,11 +13,14 @@ enum HudFlags {
|
|||
HudFlagsLookedPortalable0 = (1 << 0),
|
||||
HudFlagsLookedPortalable1 = (1 << 1),
|
||||
HudFlagsShowingPrompt = (1 << 2),
|
||||
HudFlagsShowingSubtitle= (1 << 3),
|
||||
};
|
||||
|
||||
struct Hud {
|
||||
enum CutscenePromptType promptType;
|
||||
enum CutsceneSubtitleType subtitleType;
|
||||
float promptOpacity;
|
||||
float subtitleOpacity;
|
||||
|
||||
float fadeInTimer;
|
||||
|
||||
|
@ -35,6 +38,8 @@ void hudUpdatePortalIndicators(struct Hud* hud, struct Ray* raycastRay, struct
|
|||
void hudPortalFired(struct Hud* hud, int index);
|
||||
void hudShowActionPrompt(struct Hud* hud, enum CutscenePromptType promptType);
|
||||
void hudResolvePrompt(struct Hud* hud, enum CutscenePromptType promptType);
|
||||
void hudShowSubtitle(struct Hud* hud, enum CutsceneSubtitleType subtitleType);
|
||||
void hudResolveSubtitle(struct Hud* hud);
|
||||
|
||||
void hudRender(struct Hud* hud, struct Player* player, struct RenderState* renderState);
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "../../build/assets/models/portal_gun/v_portalgun.h"
|
||||
#include "../../build/assets/materials/static.h"
|
||||
|
||||
#define PORTAL_GUN_RECOIL_TIME (0.18f)
|
||||
#define PORTAL_GUN_RECOIL_TIME (0.22f)
|
||||
|
||||
#define PORTAL_GUN_NEAR_PLANE 0.05f
|
||||
|
||||
|
@ -52,6 +52,7 @@ void portalGunInit(struct PortalGun* portalGun, struct Transform* at){
|
|||
portalGun->rigidBody.angularVelocity = gZeroVec;
|
||||
portalGun->portalGunVisible = 0;
|
||||
portalGun->shootAnimationTimer = 0.0;
|
||||
portalGun->shootTotalAnimationTimer = 0.0;
|
||||
|
||||
portalGunCalcTargetPosition(portalGun, at, &portalGun->rigidBody.transform.position, 0);
|
||||
|
||||
|
@ -180,6 +181,7 @@ void portalGunUpdate(struct PortalGun* portalGun, struct Player* player) {
|
|||
|
||||
if (player->flags & PlayerJustShotPortalGun && portalGun->shootAnimationTimer <= 0.0f) {
|
||||
portalGun->shootAnimationTimer = PORTAL_GUN_RECOIL_TIME;
|
||||
portalGun->shootTotalAnimationTimer = PORTAL_GUN_RECOIL_TIME * 2.0f;
|
||||
}
|
||||
|
||||
if (portalGun->shootAnimationTimer >= 0.0f) {
|
||||
|
@ -189,6 +191,12 @@ void portalGunUpdate(struct PortalGun* portalGun, struct Player* player) {
|
|||
player->flags &= ~PlayerJustShotPortalGun;
|
||||
}
|
||||
}
|
||||
if (portalGun->shootTotalAnimationTimer >= 0.0f) {
|
||||
portalGun->shootTotalAnimationTimer -= FIXED_DELTA_TIME;
|
||||
if (portalGun->shootTotalAnimationTimer <= 0.0f){
|
||||
portalGun->shootTotalAnimationTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
struct PortalGunProjectile* projectile = &portalGun->projectiles[i];
|
||||
|
@ -258,4 +266,10 @@ void portalGunFire(struct PortalGun* portalGun, int portalIndex, struct Ray* ray
|
|||
vector3Add(&projectile->effectOffset, &ray->origin, &fireFrom);
|
||||
|
||||
portalTrailPlay(&projectile->trail, &fireFrom, &hit.at);
|
||||
}
|
||||
int portalGunIsFiring(struct PortalGun* portalGun){
|
||||
if (portalGun->shootTotalAnimationTimer > 0.0f){
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -31,6 +31,7 @@ struct PortalGun {
|
|||
struct RigidBody rigidBody;
|
||||
int portalGunVisible;
|
||||
float shootAnimationTimer;
|
||||
float shootTotalAnimationTimer;
|
||||
|
||||
struct PortalGunProjectile projectiles[2];
|
||||
};
|
||||
|
@ -41,5 +42,6 @@ void portalGunUpdate(struct PortalGun* portalGun, struct Player* player);
|
|||
void portalGunRenderReal(struct PortalGun* portalGun, struct RenderState* renderState, struct Camera* fromCamera);
|
||||
|
||||
void portalGunFire(struct PortalGun* portalGun, int portalIndex, struct Ray* ray, struct Vector3* playerUp, int roomIndex);
|
||||
int portalGunIsFiring(struct PortalGun* portalGun);
|
||||
|
||||
#endif
|
|
@ -347,14 +347,14 @@ void sceneCheckPortals(struct Scene* scene) {
|
|||
sceneFirePortal(scene, &scene->savedPortal.ray, &scene->savedPortal.transformUp, scene->savedPortal.portalIndex, scene->savedPortal.roomIndex, 0, 0);
|
||||
}
|
||||
|
||||
if (fireOrange && hasOrange && !playerIsGrabbing(&scene->player)) {
|
||||
if (fireOrange && !fireBlue && hasOrange && !playerIsGrabbing(&scene->player) && !portalGunIsFiring(&scene->portalGun)) {
|
||||
portalGunFire(&scene->portalGun, 0, &raycastRay, &playerUp, scene->player.body.currentRoom);
|
||||
scene->player.flags |= PlayerJustShotPortalGun;
|
||||
hudPortalFired(&scene->hud, 0);
|
||||
soundPlayerPlay(soundsPortalgunShoot[0], 1.0f, 1.0f, NULL, NULL);
|
||||
}
|
||||
|
||||
if ((fireBlue || (!hasOrange && fireOrange)) && hasBlue && !playerIsGrabbing(&scene->player)) {
|
||||
if (((fireBlue && !fireOrange) || (!hasOrange && fireOrange)) && hasBlue && !playerIsGrabbing(&scene->player) && !portalGunIsFiring(&scene->portalGun)) {
|
||||
portalGunFire(&scene->portalGun, 1, &raycastRay, &playerUp, scene->player.body.currentRoom);
|
||||
scene->player.flags |= PlayerJustShotPortalGun;
|
||||
hudPortalFired(&scene->hud, 1);
|
||||
|
|
|
@ -9,14 +9,17 @@
|
|||
#include "../build/src/audio/clips.h"
|
||||
|
||||
struct AnimatedAudioInfo {
|
||||
short soundId;
|
||||
short startSoundId;
|
||||
short loopSoundId;
|
||||
short endSoundId;
|
||||
float pitch;
|
||||
};
|
||||
|
||||
struct AnimatedAudioInfo gAnimatedAudioInfo[] = {
|
||||
{.soundId = SOUND_ID_NONE},
|
||||
{.soundId = SOUNDS_BEAM_PLATFORM_LOOP1, .pitch = 0.5f},
|
||||
{.soundId = SOUNDS_BEAM_PLATFORM_LOOP1, .pitch = 0.5f},
|
||||
{.startSoundId = SOUND_ID_NONE, .loopSoundId = SOUND_ID_NONE, .endSoundId = SOUND_ID_NONE},
|
||||
{.startSoundId = SOUND_ID_NONE, .loopSoundId = SOUNDS_BEAM_PLATFORM_LOOP1, .endSoundId = SOUND_ID_NONE, .pitch = 0.5f},
|
||||
{.startSoundId = SOUNDS_DOORMOVE1, .loopSoundId = SOUND_ID_NONE, .endSoundId = SOUND_ID_NONE, .pitch = 0.4f},
|
||||
{.startSoundId = SOUNDS_TANK_TURRET_START1, .loopSoundId = SOUNDS_TANK_TURRET_LOOP1, .endSoundId = SOUNDS_ELEVATOR_STOP1, .pitch = 0.5f},
|
||||
};
|
||||
|
||||
void sceneAnimatorInit(struct SceneAnimator* sceneAnimator, struct AnimationInfo* animationInfo, int animatorCount) {
|
||||
|
@ -34,6 +37,7 @@ void sceneAnimatorInit(struct SceneAnimator* sceneAnimator, struct AnimationInfo
|
|||
skAnimatorInit(&sceneAnimator->animators[i], animationInfo[i].armature.numberOfBones);
|
||||
sceneAnimator->state[i].playbackSpeed = 1.0f;
|
||||
sceneAnimator->state[i].soundId = SOUND_ID_NONE;
|
||||
sceneAnimator->state[i].flags = 0;
|
||||
vector3Scale(&sceneAnimator->armatures[i].pose[0].position, &sceneAnimator->state[i].lastPosition, 1.0f / SCENE_SCALE);
|
||||
|
||||
sceneAnimator->boneCount += animationInfo[i].armature.numberOfBones;
|
||||
|
@ -48,24 +52,36 @@ void sceneAnimatorUpdate(struct SceneAnimator* sceneAnimator) {
|
|||
|
||||
struct AnimatedAudioInfo* audioInfo = &gAnimatedAudioInfo[sceneAnimator->animationInfo[i].soundType];
|
||||
|
||||
if (audioInfo->soundId == SOUND_ID_NONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
struct Vector3 currentPos;
|
||||
vector3Scale(&sceneAnimator->armatures[i].pose[0].position, ¤tPos, 1.0f / SCENE_SCALE);
|
||||
int isMoving = currentPos.x != state->lastPosition.x || currentPos.y != state->lastPosition.y || currentPos.z != state->lastPosition.z;
|
||||
int wasMoving = (state->flags & SceneAnimatorStateWasMoving) != 0;
|
||||
|
||||
if (isMoving && state->soundId == SOUND_ID_NONE) {
|
||||
state->soundId = soundPlayerPlay(audioInfo->soundId, 1.0f, audioInfo->pitch, ¤tPos, &gZeroVec);
|
||||
} else if (isMoving && state->soundId != SOUND_ID_NONE) {
|
||||
soundPlayerUpdatePosition(state->soundId, ¤tPos, &gZeroVec);
|
||||
} else if (!isMoving && state->soundId != SOUND_ID_NONE) {
|
||||
soundPlayerStop(state->soundId);
|
||||
state->soundId = SOUND_ID_NONE;
|
||||
if (audioInfo->loopSoundId != SOUND_ID_NONE) {
|
||||
if (isMoving && state->soundId == SOUND_ID_NONE) {
|
||||
state->soundId = soundPlayerPlay(audioInfo->loopSoundId, 1.0f, audioInfo->pitch, ¤tPos, &gZeroVec);
|
||||
} else if (isMoving && state->soundId != SOUND_ID_NONE) {
|
||||
soundPlayerUpdatePosition(state->soundId, ¤tPos, &gZeroVec);
|
||||
} else if (!isMoving && state->soundId != SOUND_ID_NONE) {
|
||||
soundPlayerStop(state->soundId);
|
||||
state->soundId = SOUND_ID_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
if (isMoving && !wasMoving && audioInfo->startSoundId != SOUND_ID_NONE) {
|
||||
soundPlayerPlay(audioInfo->startSoundId, 1.0f, audioInfo->pitch, ¤tPos, &gZeroVec);
|
||||
}
|
||||
|
||||
if (!wasMoving && isMoving && audioInfo->endSoundId != SOUND_ID_NONE) {
|
||||
soundPlayerPlay(audioInfo->endSoundId, 1.0f, audioInfo->pitch, ¤tPos, &gZeroVec);
|
||||
}
|
||||
|
||||
state->lastPosition = currentPos;
|
||||
state->flags &= ~SceneAnimatorStateWasMoving;
|
||||
if (isMoving) {
|
||||
state->flags |= SceneAnimatorStateWasMoving;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,9 +8,14 @@
|
|||
|
||||
#include "../graphics/renderstate.h"
|
||||
|
||||
enum SceneAnimatorStateFlags {
|
||||
SceneAnimatorStateWasMoving = (1 << 0),
|
||||
};
|
||||
|
||||
struct SceneAnimatorState {
|
||||
float playbackSpeed;
|
||||
ALSndId soundId;
|
||||
short flags;
|
||||
struct Vector3 lastPosition;
|
||||
};
|
||||
|
||||
|
|
|
@ -171,7 +171,7 @@ void securityCamerasCheckPortal(struct SecurityCamera* securityCameras, int came
|
|||
|
||||
if (!cutsceneRunnerIsChannelPlaying(CH_GLADOS)) {
|
||||
short clipIndex = randomInRange(0, sizeof(gCameraDestroyClips) / sizeof(*gCameraDestroyClips));
|
||||
cutsceneQueueSoundInChannel(gCameraDestroyClips[clipIndex], 1.0f, CH_GLADOS);
|
||||
cutsceneQueueSoundInChannel(gCameraDestroyClips[clipIndex], 1.0f, CH_GLADOS, CutsceneSubtitleTypeNone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,12 +99,13 @@ local function generate_cutscene_step(cutscene_name, step, step_index, label_loc
|
|||
tonumber(step.args[2] or "1") * 255,
|
||||
math.floor(tonumber(step.args[3] or "1") * 64 + 0.5),
|
||||
}
|
||||
elseif step.command == "q_sound" and #step.args >= 2 then
|
||||
elseif step.command == "q_sound" and #step.args >= 3 then
|
||||
result.type = sk_definition_writer.raw('CutsceneStepTypeQueueSound')
|
||||
result.queueSound = {
|
||||
sk_definition_writer.raw(string_starts_with(step.args[1], "SOUNDS_") and step.args[1] or ("SOUNDS_" .. step.args[1])),
|
||||
sk_definition_writer.raw(step.args[2]),
|
||||
tonumber(step.args[3] or "1") * 255,
|
||||
sk_definition_writer.raw(step.args[3]),
|
||||
tonumber(step.args[4] or "1") * 255,
|
||||
}
|
||||
elseif step.command == "wait_for_channel" and #step.args >= 1 then
|
||||
result.type = sk_definition_writer.raw('CutsceneStepTypeWaitForChannel')
|
||||
|
|
Loading…
Reference in a new issue