static void postprocessCommand (void *state, int command, int handled) { PrecommandState *pre = state; if (pre) { resumeUpdates(0); if (handled) scheduleUpdate("command executed"); if ((ses->winx != pre->motionColumn) || (ses->winy != pre->motionRow)) { /* The window has been manually moved. */ ses->motx = ses->winx; ses->moty = ses->winy; #ifdef ENABLE_CONTRACTED_BRAILLE isContracted = 0; #endif /* ENABLE_CONTRACTED_BRAILLE */ #ifdef ENABLE_SPEECH_SUPPORT if (ses->trackCursor && spk.track.isActive && (scr.number == spk.track.screenNumber)) { ses->trackCursor = 0; playTune(&tune_cursor_unlinked); } #endif /* ENABLE_SPEECH_SUPPORT */ } if (!(command & BRL_MSK_BLK)) { if (command & BRL_FLG_MOTION_ROUTE) { int left = ses->winx; int right = MIN(left+textCount, scr.cols) - 1; int top = ses->winy; int bottom = MIN(top+brl.textRows, scr.rows) - 1; if ((scr.posx < left) || (scr.posx > right) || (scr.posy < top) || (scr.posy > bottom)) { if (routeCursor(MIN(MAX(scr.posx, left), right), MIN(MAX(scr.posy, top), bottom), scr.number)) { playTune(&tune_routing_started); checkRoutingStatus(ROUTING_WRONG_COLUMN, 1); { ScreenDescription description; describeScreen(&description); if (description.number == scr.number) { slideWindowVertically(description.posy); placeWindowHorizontally(description.posx); } } } } } } free(pre); } }
void cpbBeginOperation (int column, int row) { beginColumn = column; beginRow = row; beginOffset = clipboardLength; playTune(&tune_clipboard_begin); }
static int cpbEndOperation (const wchar_t *characters, size_t length) { cpbTruncateContent(beginOffset); if (!cpbAddContent(characters, length)) return 0; playTune(&tune_clipboard_end); return 1; }
void Troll::gameOver() { // We do a check to see if the game should quit. Without this, the game show the picture, plays the // music, and then quits. So if the game is quitting, we shouldn't run the "game over" part. if (_vm->shouldQuit()) return; char szMoves[40]; _vm->clearTextArea(); drawPic(42, true, true); playTune(4, 25); printUserMessage(16); printUserMessage(33); _vm->clearTextArea(); drawPic(46, true, true); sprintf(szMoves, IDS_TRO_GAMEOVER_0, _moves); _vm->drawStr(21, 1, kColorDefault, szMoves); _vm->drawStr(22, 1, kColorDefault, IDS_TRO_GAMEOVER_1); _vm->_gfx->doUpdate(); pressAnyKey(); }
static void handleRoutingDone (const void *data) { const TuneDefinition *tune = data; playTune(tune); ses->spkx = scr.posx; ses->spky = scr.posy; }
static void checkRoutingStatus (RoutingStatus ok, int wait) { RoutingStatus status = getRoutingStatus(wait); if (status != ROUTING_NONE) { playTune((status > ok)? &tune_routing_failed: &tune_routing_succeeded); ses->spkx = scr.posx; ses->spky = scr.posy; } }
ToggleResult toggleBit ( int *bits, int bit, int command, const TuneDefinition *offTune, const TuneDefinition *onTune ) { int oldBits = *bits; switch (command & BRL_FLG_TOGGLE_MASK) { case 0: *bits ^= bit; break; case BRL_FLG_TOGGLE_ON: *bits |= bit; break; case BRL_FLG_TOGGLE_OFF: *bits &= ~bit; break; default: playTune(&tune_command_rejected); return TOGGLE_ERROR; } { int isOn = (*bits & bit) != 0; const TuneDefinition *tune = isOn? onTune: offTune; playTune(tune); if (*bits != oldBits) return isOn? TOGGLE_ON: TOGGLE_OFF; asyncWait(TUNE_TOGGLE_REPEAT_DELAY); playTune(tune); return TOGGLE_SAME; } }
void Troll::printUserMessage(int msgId) { int i; _vm->clearTextArea(); for (i = 0; i < _userMessages[msgId - 1].num; i++) { _vm->drawStr(21 + i, 1, kColorDefault, _userMessages[msgId - 1].msg[i]); } if (msgId == 34) { for (i = 0; i < 2; i++) playTune(5, 11); } pressAnyKey(); }
int main (int argc, char *argv[]) { { static const OptionsDescriptor descriptor = { OPTION_TABLE(programOptions), .applicationName = "tunetest", .argumentsSummary = "{note duration} ..." }; PROCESS_OPTIONS(descriptor, argc, argv); } resetPreferences(); if (opt_tuneDevice && *opt_tuneDevice) { unsigned int device; if (!validateChoice(&device, opt_tuneDevice, deviceNames)) { logMessage(LOG_ERR, "%s: %s", "invalid tune device", opt_tuneDevice); return PROG_EXIT_SYNTAX; } prefs.tuneDevice = device; } #ifdef HAVE_MIDI_SUPPORT if (opt_midiInstrument && *opt_midiInstrument) { unsigned char instrument; if (!validateInstrument(&instrument, opt_midiInstrument)) { logMessage(LOG_ERR, "%s: %s", "invalid musical instrument", opt_midiInstrument); return PROG_EXIT_SYNTAX; } prefs.midiInstrument = instrument; } #endif /* HAVE_MIDI_SUPPORT */ if (opt_outputVolume && *opt_outputVolume) { static const int minimum = 0; static const int maximum = 100; int volume; if (!validateInteger(&volume, opt_outputVolume, &minimum, &maximum)) { logMessage(LOG_ERR, "%s: %s", "invalid volume percentage", opt_outputVolume); return PROG_EXIT_SYNTAX; } switch (prefs.tuneDevice) { case tdPcm: prefs.pcmVolume = volume; break; case tdMidi: prefs.midiVolume = volume; break; case tdFm: prefs.fmVolume = volume; break; default: break; } } if (!argc) { logMessage(LOG_ERR, "missing tune."); return PROG_EXIT_SYNTAX; } if (argc % 2) { logMessage(LOG_ERR, "missing note duration."); return PROG_EXIT_SYNTAX; } { unsigned int count = argc / 2; TuneElement *elements = malloc((sizeof(*elements) * count) + 1); if (elements) { TuneElement *element = elements; while (argc) { int note; int duration; { static const int minimum = 0X01; static const int maximum = 0X7F; const char *argument = *argv++; if (!validateInteger(¬e, argument, &minimum, &maximum)) { logMessage(LOG_ERR, "%s: %s", "invalid note number", argument); return PROG_EXIT_SYNTAX; } --argc; } { static const int minimum = 1; static const int maximum = 255; const char *argument = *argv++; if (!validateInteger(&duration, argument, &minimum, &maximum)) { logMessage(LOG_ERR, "%s: %s", "invalid note duration", argument); return PROG_EXIT_SYNTAX; } --argc; } { TuneElement te = TUNE_NOTE(duration, note); *(element++) = te; } } { TuneElement te = TUNE_STOP(); *element = te; } } else { logMallocError(); return PROG_EXIT_FATAL; } if (!setTuneDevice(prefs.tuneDevice)) { logMessage(LOG_ERR, "unsupported tune device: %s", deviceNames[prefs.tuneDevice]); return PROG_EXIT_SEMANTIC; } { playTune(elements); closeTuneDevice(); } free(elements); } return PROG_EXIT_SUCCESS; }
static int handleUnhandledCommand (int command, void *datga) { playTune(&tune_command_rejected); return 0; }
int handleSpeechCommand (int command, void *datga) { switch (command & BRL_MSK_CMD) { case BRL_CMD_RESTARTSPEECH: restartSpeechDriver(); break; case BRL_CMD_SPKHOME: if (scr.number == spk.track.screenNumber) { trackSpeech(); } else { playTune(&tune_command_rejected); } break; case BRL_CMD_AUTOSPEAK: toggleFeatureSetting(&prefs.autospeak, command); break; case BRL_CMD_ASPK_SEL_LINE: toggleFeatureSetting(&prefs.autospeakSelectedLine, command); break; case BRL_CMD_ASPK_SEL_CHAR: toggleFeatureSetting(&prefs.autospeakSelectedCharacter, command); break; case BRL_CMD_ASPK_INS_CHARS: toggleFeatureSetting(&prefs.autospeakInsertedCharacters, command); break; case BRL_CMD_ASPK_DEL_CHARS: toggleFeatureSetting(&prefs.autospeakDeletedCharacters, command); break; case BRL_CMD_ASPK_REP_CHARS: toggleFeatureSetting(&prefs.autospeakReplacedCharacters, command); break; case BRL_CMD_ASPK_CMP_WORDS: toggleFeatureSetting(&prefs.autospeakCompletedWords, command); break; case BRL_CMD_MUTE: muteSpeech("command"); break; case BRL_CMD_SAY_LINE: sayScreenLines(ses->winy, 1, 0, prefs.sayLineMode); break; case BRL_CMD_SAY_ABOVE: sayScreenLines(0, ses->winy+1, 1, sayImmediate); break; case BRL_CMD_SAY_BELOW: sayScreenLines(ses->winy, scr.rows-ses->winy, 1, sayImmediate); break; case BRL_CMD_SAY_SLOWER: if (!canSetSpeechRate()) { playTune(&tune_command_rejected); } else if (prefs.speechRate > 0) { setSpeechRate(--prefs.speechRate, 1); } else { playTune(&tune_no_change); } break; case BRL_CMD_SAY_FASTER: if (!canSetSpeechRate()) { playTune(&tune_command_rejected); } else if (prefs.speechRate < SPK_RATE_MAXIMUM) { setSpeechRate(++prefs.speechRate, 1); } else { playTune(&tune_no_change); } break; case BRL_CMD_SAY_SOFTER: if (!canSetSpeechVolume()) { playTune(&tune_command_rejected); } else if (prefs.speechVolume > 0) { setSpeechVolume(--prefs.speechVolume, 1); } else { playTune(&tune_no_change); } break; case BRL_CMD_SAY_LOUDER: if (!canSetSpeechVolume()) { playTune(&tune_command_rejected); } else if (prefs.speechVolume < SPK_VOLUME_MAXIMUM) { setSpeechVolume(++prefs.speechVolume, 1); } else { playTune(&tune_no_change); } break; case BRL_CMD_SPEAK_CURR_CHAR: speakCurrentCharacter(); break; case BRL_CMD_SPEAK_PREV_CHAR: if (ses->spkx > 0) { ses->spkx -= 1; speakCurrentCharacter(); } else if (ses->spky > 0) { ses->spky -= 1; ses->spkx = scr.cols - 1; playTune(&tune_wrap_up); speakCurrentCharacter(); } else { playTune(&tune_bounce); } break; case BRL_CMD_SPEAK_NEXT_CHAR: if (ses->spkx < (scr.cols - 1)) { ses->spkx += 1; speakCurrentCharacter(); } else if (ses->spky < (scr.rows - 1)) { ses->spky += 1; ses->spkx = 0; playTune(&tune_wrap_down); speakCurrentCharacter(); } else { playTune(&tune_bounce); } break; case BRL_CMD_SPEAK_FRST_CHAR: { ScreenCharacter characters[scr.cols]; int column; readScreen(0, ses->spky, scr.cols, 1, characters); if ((column = findFirstNonSpaceCharacter(characters, scr.cols)) >= 0) { ses->spkx = column; speakDone(characters, column, 1, 0); } else { playTune(&tune_command_rejected); } break; } case BRL_CMD_SPEAK_LAST_CHAR: { ScreenCharacter characters[scr.cols]; int column; readScreen(0, ses->spky, scr.cols, 1, characters); if ((column = findLastNonSpaceCharacter(characters, scr.cols)) >= 0) { ses->spkx = column; speakDone(characters, column, 1, 0); } else { playTune(&tune_command_rejected); } break; } { int direction; int spell; case BRL_CMD_SPEAK_PREV_WORD: direction = -1; spell = 0; goto speakWord; case BRL_CMD_SPEAK_NEXT_WORD: direction = 1; spell = 0; goto speakWord; case BRL_CMD_SPEAK_CURR_WORD: direction = 0; spell = 0; goto speakWord; case BRL_CMD_SPELL_CURR_WORD: direction = 0; spell = 1; goto speakWord; speakWord: { int row = ses->spky; int column = ses->spkx; ScreenCharacter characters[scr.cols]; ScreenCharacterType type; int onCurrentWord; int from = column; int to = from + 1; findWord: readScreen(0, row, scr.cols, 1, characters); type = (row == ses->spky)? getScreenCharacterType(&characters[column]): SCT_SPACE; onCurrentWord = type != SCT_SPACE; if (direction < 0) { while (1) { if (column == 0) { if ((type != SCT_SPACE) && !onCurrentWord) { ses->spkx = from = column; ses->spky = row; break; } if (row == 0) goto noWord; if (row-- == ses->spky) playTune(&tune_wrap_up); column = scr.cols; goto findWord; } { ScreenCharacterType newType = getScreenCharacterType(&characters[--column]); if (newType != type) { if (onCurrentWord) { onCurrentWord = 0; } else if (type != SCT_SPACE) { ses->spkx = from = column + 1; ses->spky = row; break; } if (newType != SCT_SPACE) to = column + 1; type = newType; } } } } else if (direction > 0) { while (1) { if (++column == scr.cols) { if ((type != SCT_SPACE) && !onCurrentWord) { to = column; ses->spkx = from; ses->spky = row; break; } if (row == (scr.rows - 1)) goto noWord; if (row++ == ses->spky) playTune(&tune_wrap_down); column = -1; goto findWord; } { ScreenCharacterType newType = getScreenCharacterType(&characters[column]); if (newType != type) { if (onCurrentWord) { onCurrentWord = 0; } else if (type != SCT_SPACE) { to = column; ses->spkx = from; ses->spky = row; break; } if (newType != SCT_SPACE) from = column; type = newType; } } } } else if (type != SCT_SPACE) { while (from > 0) { if (getScreenCharacterType(&characters[--from]) != type) { from += 1; break; } } while (to < scr.cols) { if (getScreenCharacterType(&characters[to]) != type) break; to += 1; } } speakDone(characters, from, to-from, spell); break; } noWord: playTune(&tune_bounce); break; } case BRL_CMD_SPEAK_CURR_LINE: speakCurrentLine(); break; { int increment; int limit; case BRL_CMD_SPEAK_PREV_LINE: increment = -1; limit = 0; goto speakLine; case BRL_CMD_SPEAK_NEXT_LINE: increment = 1; limit = scr.rows - 1; goto speakLine; speakLine: if (ses->spky == limit) { playTune(&tune_bounce); } else { if (prefs.skipIdenticalLines) { ScreenCharacter original[scr.cols]; ScreenCharacter current[scr.cols]; int count = 0; readScreen(0, ses->spky, scr.cols, 1, original); do { readScreen(0, ses->spky+=increment, scr.cols, 1, current); if (!isSameRow(original, current, scr.cols, isSameText)) break; if (!count) { playTune(&tune_skip_first); } else if (count < 4) { playTune(&tune_skip); } else if (!(count % 4)) { playTune(&tune_skip_more); } count += 1; } while (ses->spky != limit); } else { ses->spky += increment; } speakCurrentLine(); } break; } case BRL_CMD_SPEAK_FRST_LINE: { ScreenCharacter characters[scr.cols]; int row = 0; while (row < scr.rows) { readScreen(0, row, scr.cols, 1, characters); if (!isAllSpaceCharacters(characters, scr.cols)) break; row += 1; } if (row < scr.rows) { ses->spky = row; ses->spkx = 0; speakCurrentLine(); } else { playTune(&tune_command_rejected); } break; } case BRL_CMD_SPEAK_LAST_LINE: { ScreenCharacter characters[scr.cols]; int row = scr.rows - 1; while (row >= 0) { readScreen(0, row, scr.cols, 1, characters); if (!isAllSpaceCharacters(characters, scr.cols)) break; row -= 1; } if (row >= 0) { ses->spky = row; ses->spkx = 0; speakCurrentLine(); } else { playTune(&tune_command_rejected); } break; } case BRL_CMD_DESC_CURR_CHAR: { char description[0X50]; formatCharacterDescription(description, sizeof(description), ses->spkx, ses->spky); sayString(description, 1); break; } case BRL_CMD_ROUTE_CURR_LOCN: if (routeCursor(ses->spkx, ses->spky, scr.number)) { playTune(&tune_routing_started); } else { playTune(&tune_command_rejected); } break; case BRL_CMD_SPEAK_CURR_LOCN: { char buffer[0X50]; snprintf(buffer, sizeof(buffer), "%s %d, %s %d", gettext("line"), ses->spky+1, gettext("column"), ses->spkx+1); sayString(buffer, 1); break; } case BRL_CMD_SHOW_CURR_LOCN: toggleFeatureSetting(&prefs.showSpeechCursor, command); break; default: return 0; } return 1; }
void Troll::gameLoop() { bool done = false; char menu[160+5]; int currentOption, numberOfOptions; int roomParam; int haveFlashlight; _moves = 0; _roomPicture = 1; _treasuresLeft = IDI_TRO_MAX_TREASURE; haveFlashlight = false; _currentRoom = 0; _isTrollAway = true; _soundOn = true; memset(_roomStates, 0, sizeof(_roomStates)); memset(_inventory, 0, sizeof(_inventory)); while (!done && !_vm->shouldQuit()) { *menu = 0; currentOption = 0; numberOfOptions = drawRoom(menu); if (getMenuSel(menu, ¤tOption, numberOfOptions)) { _moves++; } else { continue; } roomParam = _roomDescs[_roomPicture - 1].roomDescIndex[currentOption]; switch (_roomDescs[_roomPicture - 1].optionTypes[currentOption]) { case OT_FLASHLIGHT: if (!haveFlashlight) { printUserMessage(13); break; } // fall down case OT_GO: _currentRoom = roomParam; _roomPicture = _roomPicStartIdx[_currentRoom]; _roomPicture += _roomStates[_currentRoom]; if (_currentRoom < 6 || _treasuresLeft == 0) { _isTrollAway = true; } else { // make odd 1:3 _isTrollAway = (_vm->rnd(3) != 2); } break; case OT_GET: if (!_isTrollAway) { printUserMessage(34); } else { for (int i = 0; i < 4; i++) { playTune(1, 3); // delayMillis() } _roomStates[_currentRoom] = 1; _roomPicDeltas[_currentRoom] = 0; _roomPicture++; if (_roomConnects[roomParam - 1] != 0xff) { _roomStates[_roomConnects[roomParam - 1]] = 1; } if (roomParam == 1) haveFlashlight = true; _locMessagesIdx[_currentRoom] = IDO_TRO_LOCMESSAGES + (roomParam + 42) * 39; pickupTreasure(roomParam); } break; case OT_DO: if (roomParam != 16) { printUserMessage(roomParam); break; } done = true; break; default: break; } } }
bool Troll::getMenuSel(const char *szMenu, int *iSel, int nSel) { Common::Event event; int y; drawMenu(szMenu, *iSel); while (!_vm->shouldQuit()) { while (_vm->_system->getEventManager()->pollEvent(event)) { switch (event.type) { case Common::EVENT_RTL: case Common::EVENT_QUIT: return 0; case Common::EVENT_MOUSEMOVE: y = event.mouse.y / 8; if (y >= 22) if (nSel > y - 22) *iSel = y - 22; drawMenu(szMenu, *iSel); break; case Common::EVENT_LBUTTONUP: return true; case Common::EVENT_KEYDOWN: switch (event.kbd.keycode) { case Common::KEYCODE_t: case Common::KEYCODE_f: inventory(); return false; case Common::KEYCODE_DOWN: case Common::KEYCODE_SPACE: *iSel += 1; if (*iSel == nSel) *iSel = IDI_TRO_SEL_OPTION_1; drawMenu(szMenu, *iSel); break; case Common::KEYCODE_UP: *iSel -= 1; if (*iSel == IDI_TRO_SEL_OPTION_1 - 1) *iSel = nSel - 1; drawMenu(szMenu, *iSel); break; case Common::KEYCODE_RETURN: case Common::KEYCODE_KP_ENTER: return true; case Common::KEYCODE_s: if (event.kbd.hasFlags(Common::KBD_CTRL)) { if (_soundOn) { playTune(2, 1); _soundOn = !_soundOn; } else { _soundOn = !_soundOn; playTune(3, 1); } } default: break; } break; default: break; } } _vm->_system->updateScreen(); _vm->_system->delayMillis(10); } return true; }