void EMISound::restoreState(SaveGame *savedState) { // Clear any current music flushStack(); setMusicState(0); freeAllChannels(); // Actually load: savedState->beginSection('SOUN'); _musicPrefix = savedState->readString(); // Stack: uint32 stackSize = savedState->readLEUint32(); for (uint32 i = 0; i < stackSize; i++) { SoundTrack *track = nullptr; Common::String soundName = savedState->readString(); if (!soundName.empty()) { track = createEmptyMusicTrack(); if (initTrack(soundName, track)) { track->play(); track->pause(); } else { error("Couldn't reopen %s", soundName.c_str()); } } _stateStack.push(track); } // Currently playing music: uint32 hasActiveTrack = savedState->readLEUint32(); if (hasActiveTrack) { _music = createEmptyMusicTrack(); Common::String soundName = savedState->readString(); if (initTrack(soundName, _music)) { _music->play(); } else { error("Couldn't reopen %s", soundName.c_str()); } } // Channels: uint32 numChannels = savedState->readLEUint32(); if (numChannels > NUM_CHANNELS) { error("Save game made with more channels than we have now: %d > %d", numChannels, NUM_CHANNELS); } for (uint32 i = 0; i < numChannels; i++) { uint32 channelIsActive = savedState->readLEUint32(); if (channelIsActive) { Common::String soundName = savedState->readString(); uint32 volume = savedState->readLEUint32(); uint32 pan = savedState->readLEUint32(); /*uint32 pos = */savedState->readLEUint32(); /*bool isPlaying = */savedState->readByte(); startVoice(soundName.c_str(), volume, pan); } } savedState->endSection(); }
//-------------------------------------------------------------- // initialize application void DontHitMe::appInit() { // get the important directories mgString shaderDir; m_options.getFileName("shaderDir", m_options.m_sourceFileName, "docs/shaders", shaderDir); mgString uiDir; m_options.getFileName("uiDir", m_options.m_sourceFileName, "docs/ui", uiDir); mgString fontDir; m_options.getFileName("fontDir", m_options.m_sourceFileName, "docs/fonts", fontDir); mgInitDisplayServices(shaderDir, fontDir); mgDisplay->setFOV(m_options.getDouble("FOV", 60.0)); mgDisplay->setDPI(m_options.getInteger("DPI", 0)); // load cursor pattern loadCursor(); setDeskMode(true); initMovement(); // load the shaders we might use mgVertex::loadShader("litTexture"); mgVertex::loadShader("unlitTexture"); mgVertex::loadShader("litTextureCube"); mgVertex::loadShader("unlitTextureCube"); mgVertexTA::loadShader("litTextureArray"); mgVertexTA::loadShader("unlitTextureArray"); m_sky = new StarrySky(m_options); m_sky->enableSkyBox(true); m_sky->enableStars(true); m_sky->enableSun(true); mgPoint3 lightDir(0, 1, 1); lightDir.normalize(); m_sky->setSunDir(lightDir); mgDisplay->setLightDir(lightDir); m_saucer = new Saucer(m_options); m_planet = new Planet(m_options); m_wreck = new Wreck(m_options); m_tower1 = new Tower(m_options, false); m_tower2 = new Tower(m_options, false); mgString fileName; m_options.getFileName("tube", m_options.m_sourceFileName, "tube.jpg", fileName); m_tubeTexture = mgDisplay->loadTexture(fileName); initTrack(); initBall(); updateBallPt(); m_intro = new Intro(m_options, m_ballOrigin); m_showingIntro = false; m_lastAnimate = mgOSGetTime(); // now! }
void EMISound::setMusicState(int stateId) { if (stateId == _curMusicState) return; if (_music) { delete _music; _music = nullptr; } if (stateId == 0) return; if (_musicTable == nullptr) { Debug::debug(Debug::Sound, "No music table loaded"); return; } if (_musicTable[stateId]._id != stateId) { Debug::debug(Debug::Sound, "Attempted to play track #%d, not found in music table!", stateId); return; } Common::String filename; if (g_grim->getGamePlatform() == Common::kPlatformPS2) { Debug::debug(Debug::Sound, "PS2 doesn't have musictable yet %d ignored, just playing 1195.SCX", stateId); // So, we just rig up the menu-song hardcoded for now, as a test of the SCX-code. filename = "1195.SCX"; } else { filename = _musicTable[stateId]._filename; } _curMusicState = stateId; _music = createEmptyMusicTrack(); Debug::debug(Debug::Sound, "Loading music: %s", filename.c_str()); if (initTrack(filename, _music)) { _music->play(); } }
//-------------------------------------------------------------- // constructor Intro::Intro( const mgOptionsFile& options, const mgPoint3& origin) { m_origin = origin; // load wall texture mgString fileName; options.getFileName("tube", options.m_sourceFileName, "tube.jpg", fileName); m_tubeTexture = mgDisplay->loadTexture(fileName); options.getFileName("intro-wall", options.m_sourceFileName, "tube.jpg", fileName); m_wallTexture = mgDisplay->loadTexture(fileName); m_saucer = new Saucer(options); m_tube = new Tube(TUBE_RADIUS, TUBE_STEPS); m_wall = new Tube(WALL_RADIUS, WALL_STEPS); initTrack(); m_ballPosn = 0.0; updateBallPt(); }
void AudioMixerController::mixOneFrame() { _isMixingFrame = true; _activeTracksMutex.lock(); auto mixStart = clockNow(); std::vector<Track*> tracksToRemove; tracksToRemove.reserve(_activeTracks.size()); // FOR TESTING BEGIN // Track* track = _activeTracks[0]; // // AudioBufferProvider::Buffer buffer; // buffer.frameCount = _bufferSizeInFrames; // status_t r = track->getNextBuffer(&buffer); //// ALOG_ASSERT(buffer.frameCount == _mixing->size / 2, "buffer.frameCount:%d, _mixing->size/2:%d", buffer.frameCount, _mixing->size/2); // if (r == NO_ERROR) // { // ALOGV("getNextBuffer succeed ..."); // memcpy(_mixing->buf, buffer.raw, _mixing->size); // } // if (buffer.raw == nullptr) // { // ALOGV("Play over ..."); // tracksToRemove.push_back(track); // } // else // { // track->releaseBuffer(&buffer); // } // // _mixing->state = BufferState::FULL; // _activeTracksMutex.unlock(); // FOR TESTING END Track::State state; // set up the tracks. for (auto&& track : _activeTracks) { state = track->getState(); if (state == Track::State::IDLE) { initTrack(track, tracksToRemove); } else if (state == Track::State::PLAYING) { if (!track->isInitialized()) { initTrack(track, tracksToRemove); } int name = track->getName(); ALOG_ASSERT(name >= 0); std::lock_guard<std::mutex> lk(track->_volumeDirtyMutex); if (track->isVolumeDirty()) { gain_minifloat_packed_t volume = track->getVolumeLR(); float lVolume = float_from_gain(gain_minifloat_unpack_left(volume)); float rVolume = float_from_gain(gain_minifloat_unpack_right(volume)); ALOGV("Track (name: %d)'s volume is dirty, update volume to L: %f, R: %f", name, lVolume, rVolume); _mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, &lVolume); _mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1, &rVolume); track->setVolumeDirty(false); } } else if (state == Track::State::RESUMED) { if (!track->isInitialized()) { initTrack(track, tracksToRemove); } if (track->getPrevState() == Track::State::PAUSED) { _mixer->enable(track->getName()); track->setState(Track::State::PLAYING); } else { ALOGW("Previous state (%d) isn't PAUSED, couldn't resume!", static_cast<int>(track->getPrevState())); } } else if (state == Track::State::PAUSED) { if (!track->isInitialized()) { initTrack(track, tracksToRemove); } if (track->getPrevState() == Track::State::PLAYING || track->getPrevState() == Track::State::RESUMED) { _mixer->disable(track->getName()); } else { ALOGW("Previous state (%d) isn't PLAYING, couldn't pause!", static_cast<int>(track->getPrevState())); } } else if (state == Track::State::STOPPED) { if (track->isInitialized()) { if (track->getPrevState() != Track::State::IDLE) { _mixer->deleteTrackName(track->getName()); } else { ALOGV("Stop track (%p) while it's in IDLE state!", track); } } else { ALOGV("Track (%p) hasn't been initialized yet!", track); } tracksToRemove.push_back(track); } if (track->isPlayOver()) { if (track->isLoop()) { track->reset(); } else { ALOGV("Play over ..."); _mixer->deleteTrackName(track->getName()); tracksToRemove.push_back(track); track->setState(Track::State::OVER); } } } bool hasAvailableTracks = _activeTracks.size() - tracksToRemove.size() > 0; if (hasAvailableTracks) { ALOGV_IF(_activeTracks.size() > 8, "More than 8 active tracks: %d", (int) _activeTracks.size()); _mixer->process(AudioBufferProvider::kInvalidPTS); } else { ALOGV("Doesn't have enough tracks: %d, %d", (int) _activeTracks.size(), (int) tracksToRemove.size()); } // Remove stopped or playover tracks for active tracks container for (auto&& track : tracksToRemove) { removeItemFromVector(_activeTracks, track); if (track != nullptr && track->onStateChanged != nullptr) { track->onStateChanged(Track::State::DESTROYED); } else { ALOGE("track (%p) was released ...", track); } } _activeTracksMutex.unlock(); auto mixEnd = clockNow(); float mixInterval = intervalInMS(mixStart, mixEnd); ALOGV_IF(mixInterval > 1.0f, "Mix a frame waste: %fms", mixInterval); _isMixingFrame = false; }
void trainTask() { int trainNum, reply = 0, src; Receive(&src, (char *)&trainNum, sizeof(int)); Reply(src, (char *)&reply, sizeof(int)); track_node track[TRACK_MAX]; initTrack(track); int velocity[15]; initVelocities(trainNum, velocity); //find your location int location; struct TrainMessage msg; int dest,i,j, sensorsPassed; int oldSensor, sensor, oldTime, time; while(true) { Receive(&src, (char *)&msg, sizeof(struct TrainMessage)); switch(msg.type) { case TRAINGOTO: resetSensorBuffer(); dest = 0; while(dest < TRACK_MAX && strcmp(track[dest].name, msg.dest) != 0) dest++; location = moveToLocation(trainNum, location, dest, track, msg.doReverse, msg.speed, velocity); Reply(src, (char *)&reply, sizeof(int)); break; case TRAININIT: Reply(src, (char *)&reply, sizeof(int)); Putc2(1, (char)2, (char)trainNum); location = waitOnAnySensor(); Putc2(1, (char)0, (char)trainNum); break; case TRAINCONFIGVELOCITY: Putc2(1, (char)2, (char)trainNum); location = waitOnAnySensor(); Putc2(1, (char)0, (char)trainNum); //move to sensor B15 location = moveToLocation(trainNum, location, 30, track, false, 10, velocity); setSwitchState(14, 'C'); setSwitchState(13, 'S'); setSwitchState(10, 'S'); setSwitchState(9, 'C'); setSwitchState(8, 'C'); setSwitchState(17, 'S'); setSwitchState(16, 'S'); setSwitchState(15, 'C'); for(i=8; i<15; i++) { Putc2(1, (char)i, (char)trainNum); oldSensor = waitOnAnySensor(); oldTime = Time(); sensorsPassed = 0; for(j=0; j<15; j++) { sensor = waitOnAnySensor(); time = Time(); int distance = 1000*BFS(oldSensor, sensor, track, NULL, false); int newVelocity = distance/(time - oldTime); if(velocity[i] - newVelocity < velocity[i]/200 && sensorsPassed >= 10) break; velocity[i] *= 95; velocity[i] += 5*newVelocity; velocity[i] /= 100; ++sensorsPassed; } printf("Configured speed %d to %dmm/s\r", i, velocity[i]/10); } Putc2(1, (char)0, (char)trainNum); Reply(src, (char *)&reply, sizeof(int)); break; } } }
void parseCommand(char *command, int *trainSpeeds, int *train) { char *argv[MAX_ARGS]; int argc = formatArgs(command, argv); if(strcmp(argv[0], "tr") == 0) { if(numArgs(argc, argv) != 2) { printColored(RED, BLACK, "Error: command tr expects 2 arguments\r"); }else{ int trainNumber = strToInt(getArgument(argc, argv, 0)); int trainSpeed = strToInt(getArgument(argc, argv, 1)); if(trainNumber == -1 || trainNumber < 1 || trainNumber > 80) { printColored(RED, BLACK, "Error: train number must be a number between 1 and 80\r"); }else if(trainSpeed == -1 || trainSpeed < 0 || trainSpeed > 14) { printColored(RED, BLACK, "Error: train speed must be a number between 0 and 14\r"); }else { Putc2(1, (char)trainSpeed, (char)trainNumber); trainSpeeds[trainNumber] = trainSpeed; } } }else if(strcmp(argv[0], "rv") == 0) { if(numArgs(argc, argv) != 1) { printColored(RED, BLACK, "Error: command rv expects an argument\r"); }else{ int trainNumber = strToInt(getArgument(argc, argv, 0)); if(trainNumber == -1 || trainNumber < 1 || trainNumber > 80) { printColored(RED, BLACK, "Error: train number must be a number between 1 and 80\r"); }else{ Putc2(1, (char)0, (char)trainNumber); int reverseTask = Create(1, reverser); int reply; struct trainInfo info; info.speed = trainSpeeds[trainNumber]; info.number = trainNumber; Send(reverseTask, (char *)&info, sizeof(struct trainInfo), (char *)&reply, sizeof(int)); } } }else if(strcmp(argv[0], "sw") == 0) { if(numArgs(argc, argv) != 2) { printColored(RED, BLACK, "Error: command sw expects two arguments\r"); }else{ int switchNumber = strToInt(getArgument(argc, argv, 0)); if(strcmp(getArgument(argc, argv, 1), "S") == 0) { setSwitchState(switchNumber, 'S'); }else if(strcmp(getArgument(argc, argv, 1), "C") == 0) { setSwitchState(switchNumber, 'C'); }else{ printColored(RED, BLACK, "Error: switch direction must be 'S' or 'C'\r"); } } }else if(strcmp(argv[0], "q") == 0) { outputEscape("[2J"); moveCursor(1,1); Shutdown(); }else if(strcmp(argv[0], "setTrack") == 0) { if(numArgs(argc, argv) != 1) { printColored(RED, BLACK, "Error: command setTrack expects an argument\r"); }else{ if(strcmp(getArgument(argc, argv, 0), "A") == 0) { setTrack(TRACKA); }else if(strcmp(getArgument(argc, argv, 0), "B") == 0) { setTrack(TRACKB); }else{ printColored(RED, BLACK, "Error: track must be A or B\r"); } } }else if(strcmp(argv[0], "move") == 0) { if(numArgs(argc, argv) != 3) { printColored(RED, BLACK, "Error: command move expects two arguments\r"); }else{ struct TrainMessage msg; int trainNum = strToInt(getArgument(argc, argv, 0)); msg.type = TRAINGOTO; strcpy(msg.dest, getArgument(argc, argv, 1)); msg.doReverse = getFlag(argc, argv, "r"); msg.speed = strToInt(getArgument(argc, argv, 2)); if(train[trainNum] == -1) { printColored(RED, BLACK, "Error: train %d has not been initialized\r", trainNum); }else{ int reply; Send(train[trainNum], (char *)&msg, sizeof(struct TrainMessage), (char *)&reply, sizeof(int)); } } }else if(strcmp(argv[0], "randomizeSwitches") == 0) { int i; seed(Time()); for(i=1; i<19; i++) { int dir = random() % 2; if(dir == 0) { setSwitchState(i, 'S'); }else{ setSwitchState(i, 'C'); } } for(i=153; i<157; i++) { int dir = random() % 2; if(dir == 0) { setSwitchState(i, 'S'); }else{ setSwitchState(i, 'C'); } } }else if(strcmp(argv[0], "init") == 0) { if(numArgs(argc, argv) != 1) { printColored(RED, BLACK, "Error: command init expects an argument\r"); }else{ struct TrainMessage msg; int trainNum = strToInt(getArgument(argc, argv, 0)); int reply; if(train[trainNum] == -1) { train[trainNum] = Create(2, trainTask); Send(train[trainNum], (char *)&trainNum, sizeof(int), (char *)&reply, sizeof(int)); } msg.type = TRAININIT; Send(train[trainNum], (char *)&msg, sizeof(struct TrainMessage), (char *)&reply, sizeof(int)); } }else if(strcmp(argv[0], "d") == 0) { track_node track[TRACK_MAX]; initTrack(track); int trainNum = 45; int trainSpeed = strToInt(getArgument(argc, argv, 0)); Putc2(1, (char)trainSpeed, (char)trainNum); int sensor, lastSensor = waitOnAnySensor(), lastTime = Time(), time; int v = 0; while(true) { sensor = waitOnAnySensor(); time = Time(); if(sensor == 71) break; int timeDelta = (time - lastTime); int distance = BFS(lastSensor, sensor, track, NULL, false); int newVelocity = (500*distance)/timeDelta; v *= 95; v += newVelocity; v /= 100; lastTime = time; lastSensor = sensor; printAt(9, 1, "Velocity: %dmm/s\r", v); } Putc2(1, (char)0, (char)trainNum); }else if(strcmp(argv[0], "a") == 0) { track_node track[TRACK_MAX]; initTrack(track); int trainNum = 45; int trainSpeed = strToInt(getArgument(argc, argv, 2)); int source = 0, dest = 0; int velocity[15]; initVelocities(trainNum, velocity); while(source < TRACK_MAX && strcmp(track[source].name, getArgument(argc, argv, 0)) != 0) source++; while(dest < TRACK_MAX && strcmp(track[dest].name, getArgument(argc, argv, 1)) != 0) dest++; int distance = BFS(source, dest, track, NULL, false); Putc2(1, (char)trainSpeed, (char)trainNum); int t0 = Time(); printf("Time 0: %d\r", t0); waitOnSensor(dest); int t2 = Time(); Putc2(1, (char)0, (char)trainNum); printf("Time 2: %d\r", t2); int t1 = -(200*distance)/velocity[trainSpeed]; t1 -= t0; t1 += 2*t2; printf("Time 1: %d\r", t1); printf("Accelerating to speed %d takes %d ticks\r", trainSpeed, t1-t0); }else if(strcmp(argv[0], "clear") == 0) { moveCursor(13, 1); outputEscape("[J"); }else if(strcmp(argv[0], "configureVelocities") == 0) { struct TrainMessage msg; msg.type = TRAINCONFIGVELOCITY; if(argc != 2) { printColored(RED, BLACK, "Command configureVelocities expects an argument\r"); }else{ int trainNum = strToInt(getArgument(argc, argv, 0)); int reply; if(train[trainNum] == -1) { train[trainNum] = Create(2, trainTask); Send(train[trainNum], (char *)&trainNum, sizeof(int), (char *)&reply, sizeof(int)); } Send(train[trainNum], (char *)&msg, sizeof(struct TrainMessage), (char *)&reply, sizeof(int)); } }else{ printColored(RED, BLACK, "Unrecognized command: \"%s\"\r", command); } }