示例#1
0
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();
}
示例#2
0
//--------------------------------------------------------------
// 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!
}
示例#3
0
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();
	}
}
示例#4
0
//--------------------------------------------------------------
// 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;
}
示例#6
0
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;
    }
  } 
}
示例#7
0
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);
  }
}