void Sound::playSpeech(const Common::String &name) { Resources &res = *_vm->_res; Scene &scene = *_vm->_scene; stopSpeech(); // TODO: Technically Scalpel has an sfx command which I've set to call this method because it sets the // _voice variable as if it were speech. Need to do a play-through of Scalpel and see if it's ever called. // If so, will need to enhance this method to handle the Serrated Scalpel voice resources assert(IS_ROSE_TATTOO); // Figure out which speech library to use Common::String libraryName = Common::String::format("speech%02d.lib", scene._currentScene); if ((!scumm_strnicmp(name.c_str(), "SLVE12S", 7)) || (!scumm_strnicmp(name.c_str(), "WATS12X", 7)) || (!scumm_strnicmp(name.c_str(), "HOLM12X", 7))) libraryName = "SPEECH12.LIB"; // If the speech library file doesn't even exist, then we can't play anything Common::File f; if (!f.exists(libraryName)) return; // Ensure the given library is in the cache res.addToCache(libraryName); if (playSoundResource(name, libraryName, Audio::Mixer::kSpeechSoundType, _speechHandle)) _speechPlaying = true; }
void DemoPlayer::evaluateVideoMode(const char *mode) { debugC(2, kDebugDemo, "Video mode \"%s\"", mode); _autoDouble = false; _doubleMode = false; // Only applicable when we actually can double if (_vm->is640x480() || _vm->is800x600()) { if (!scumm_strnicmp(mode, "AUTO", 4)) _autoDouble = true; else if (!scumm_strnicmp(mode, "VGA", 3)) _doubleMode = true; } }
void LocationParser_ns::parseCommandFlag(CommandPtr cmd, const char *flag, Table *table) { if (!scumm_stricmp(flag, "exit")) { cmd->_flagsOn |= kFlagsExit; } else if (!scumm_stricmp(flag, "exittrap")) { cmd->_flagsOn |= kFlagsExit; } else if (!scumm_stricmp(flag, "enter")) { cmd->_flagsOn |= kFlagsEnter; } else if (!scumm_stricmp(flag, "entertrap")) { cmd->_flagsOn |= kFlagsEnter; } else if (!scumm_strnicmp(flag, "no", 2)) { byte _al = table->lookup(flag+2); if (_al != Table::notFound) { cmd->_flagsOff |= 1 << (_al - 1); } else { warning("Flag '%s' not found", flag); } } else { byte _al = table->lookup(flag); if (_al != Table::notFound) { cmd->_flagsOn |= 1 << (_al - 1); } else { warning("Flag '%s' not found", flag); } } }
void LocationParser_ns::parseAnswerFlags(Answer *answer) { if (!_tokens[1][0]) { return; } Table* flagNames; uint16 token; if (!scumm_stricmp(_tokens[1], "global")) { token = 2; flagNames = _vm->_globalFlagsNames; answer->_yesFlags |= kFlagsGlobal; } else { token = 1; flagNames = _vm->_localFlagNames; } do { if (!scumm_strnicmp(_tokens[token], "no", 2)) { byte _al = flagNames->lookup(_tokens[token]+2); answer->_noFlags |= 1 << (_al - 1); } else { byte _al = flagNames->lookup(_tokens[token]); answer->_yesFlags |= 1 << (_al - 1); } token++; } while (!scumm_stricmp(_tokens[token++], "|")); }
Common::SeekableReadStream *BaseFileManager::openFileRaw(const Common::String &filename) { Common::SeekableReadStream *ret = NULL; if (scumm_strnicmp(filename.c_str(), "savegame:", 9) == 0) { if (!BaseEngine::instance().getGameRef()) { error("Attempt to load filename: %s without BaseEngine-object, this is unsupported", filename.c_str()); } BaseSaveThumbFile *saveThumbFile = new BaseSaveThumbFile(); if (DID_SUCCEED(saveThumbFile->open(filename))) { ret = saveThumbFile->getMemStream(); } delete saveThumbFile; return ret; } ret = openDiskFile(filename); if (ret) { return ret; } ret = openPkgFile(filename); if (ret) { return ret; } ret = BaseResources::getFile(filename); if (ret) { return ret; } debugC(kWintermuteDebugFileAccess ,"BFileManager::OpenFileRaw - Failed to open %s", filename.c_str()); return NULL; }
BtKeypack *ResourceManager::find(const char *key) { debugC(1, kCGEDebugFile, "ResourceManager::find(%s)", key); int lev = 0; uint16 nxt = kBtValRoot; while (!_catFile->eos()) { BtPage *pg = getPage(lev, nxt); if (!pg) return nullptr; // search if (pg->_header._down != kBtValNone) { int i; for (i = 0; i < pg->_header._count; i++) { if (scumm_strnicmp((const char *)key, (const char*)pg->_inner[i]._key, kBtKeySize) < 0) break; } nxt = (i) ? pg->_inner[i - 1]._down : pg->_header._down; _buff[lev]._index = i - 1; lev++; } else { int i; for (i = 0; i < pg->_header._count - 1; i++) { if (scumm_stricmp((const char *)key, (const char *)pg->_leaf[i]._key) <= 0) break; } _buff[lev]._index = i; return &pg->_leaf[i]; } } return nullptr; }
int32 BaseParser::getObject(char **buf, const TokenDesc *tokens, char **name, char **data) { skipCharacters(buf, _whiteSpace); // skip comment lines. while (**buf == ';') { *buf = strchr(*buf, '\n'); _parserLine++; skipCharacters(buf, _whiteSpace); } if (! **buf) { // at end of file return PARSERR_EOF; } // find the token. // TODO: for now just use brute force. Improve later. while (tokens->id != 0) { if (!scumm_strnicmp(tokens->token, *buf, strlen(tokens->token))) { // here we could be matching PART of a string // we could detect this here or the token list // could just have the longer tokens first in the list break; } ++tokens; } if (tokens->id == 0) { char *p = strchr(*buf, '\n'); if (p && p > *buf) { strncpy(_lastOffender, *buf, MIN((uint32)255, (uint32)(p - *buf))); // TODO, clean } else { strcpy(_lastOffender, ""); } return PARSERR_TOKENNOTFOUND; } // skip the token *buf += strlen(tokens->token); skipCharacters(buf, _whiteSpace); // get optional name *name = getSubText(buf, '\'', '\''); // single quotes skipCharacters(buf, _whiteSpace); // get optional data if (**buf == '=') { // An assignment rather than a command/object. *data = getAssignmentText(buf); } else { *data = getSubText(buf, '{', '}'); } return tokens->id; }
int AGOSEngine_PN::wrdmatch(uint8 *word1, int mask1, uint8 *word2, int mask2) { uint8 sv; if ((mask1 & mask2) == 0) return 0; sv = *word1; *word1 &= 127; if (scumm_strnicmp((const char *)word1, (const char *)word2, _dataBase[57])) { *word1 = sv; return 0; } *word1 = sv; return 1; }
void SoundPC98::loadSoundFile(uint file) { if (!scumm_strnicmp(fileListEntry(0), "INTRO", 5)) { delete[] _sfxTrackData; _sfxTrackData = 0; int dataSize = 0; const uint8 *tmp = _vm->staticres()->loadRawData(k1PC98IntroSfx, dataSize); if (!tmp) { warning("Could not load static intro sound effects data\n"); return; } _sfxTrackData = new uint8[dataSize]; memcpy(_sfxTrackData, tmp, dataSize); } }
HRESULT CBSaveThumbFile::Open(Common::String Filename) { Close(); if (scumm_strnicmp(Filename.c_str(), "savegame:", 9) != 0) return E_FAIL; char *TempFilename = new char[strlen(Filename.c_str()) - 8]; strcpy(TempFilename, Filename.c_str() + 9); for (int i = 0; i < strlen(TempFilename); i++) { if (TempFilename[i] < '0' || TempFilename[i] > '9') { TempFilename[i] = '\0'; break; } } // get slot number from name int Slot = atoi(TempFilename); delete [] TempFilename; char SlotFilename[MAX_PATH + 1]; Game->GetSaveSlotFilename(Slot, SlotFilename); CBPersistMgr *pm = new CBPersistMgr(Game); if (!pm) return E_FAIL; Game->m_DEBUG_AbsolutePathWarning = false; if (FAILED(pm->InitLoad(SlotFilename))) { Game->m_DEBUG_AbsolutePathWarning = true; delete pm; return E_FAIL; } Game->m_DEBUG_AbsolutePathWarning = true; HRESULT res; if (pm->m_ThumbnailDataSize != 0) { m_Data = new byte[pm->m_ThumbnailDataSize]; memcpy(m_Data, pm->m_ThumbnailData, pm->m_ThumbnailDataSize); m_Size = pm->m_ThumbnailDataSize; res = S_OK; } else res = E_FAIL; delete pm; return res; }
bool BaseFileManager::hasFile(const Common::String &filename) { if (scumm_strnicmp(filename.c_str(), "savegame:", 9) == 0) { BasePersistenceManager pm(BaseEngine::instance().getGameId()); if (filename.size() <= 9) { return false; } int slot = atoi(filename.c_str() + 9); return pm.getSaveExists(slot); } if (diskFileExists(filename)) { return true; } if (_packages.hasFile(filename)) { return true; // We don't bother checking if the file can actually be opened, something bigger is wrong if that is the case. } if (BaseResources::hasFile(filename)) { return true; } return false; }
bool BaseSurfaceOSystem::finishLoad() { BaseImage *image = new BaseImage(); if (!image->loadFile(_filename)) { delete image; return false; } _width = image->getSurface()->w; _height = image->getSurface()->h; bool isSaveGameGrayscale = scumm_strnicmp(_filename.c_str(), "savegame:", 9) == 0 && (_filename.c_str()[_filename.size() - 1] == 'g' || _filename.c_str()[_filename.size() - 1] == 'G'); if (isSaveGameGrayscale) { warning("grayscaleConversion not yet implemented"); // FIBITMAP *newImg = FreeImage_ConvertToGreyscale(img); TODO } // no alpha, set color key /* if (surface->format.bytesPerPixel != 4) SDL_SetColorKey(surf, SDL_TRUE, SDL_MapRGB(surf->format, ck_red, ck_green, ck_blue));*/ // convert 32-bit BMPs to 24-bit or they appear totally transparent (does any app actually write alpha in BMP properly?) // Well, actually, we don't convert via 24-bit as the color-key application overwrites the Alpha-channel anyhow. _surface->free(); delete _surface; bool needsColorKey = false; bool replaceAlpha = true; if (_filename.hasSuffix(".bmp") && image->getSurface()->format.bytesPerPixel == 4) { _surface = image->getSurface()->convertTo(g_system->getScreenFormat(), image->getPalette()); needsColorKey = true; replaceAlpha = false; } else if (image->getSurface()->format.bytesPerPixel == 1 && image->getPalette()) { _surface = image->getSurface()->convertTo(g_system->getScreenFormat(), image->getPalette()); needsColorKey = true; } else if (image->getSurface()->format.bytesPerPixel >= 3 && image->getSurface()->format != g_system->getScreenFormat()) { _surface = image->getSurface()->convertTo(g_system->getScreenFormat()); if (image->getSurface()->format.bytesPerPixel == 3) { needsColorKey = true; } } else { _surface = new Graphics::Surface(); _surface->copyFrom(*image->getSurface()); if (_surface->format.aBits() == 0) { needsColorKey = true; } } if (needsColorKey) { TransparentSurface trans(*_surface); trans.applyColorKey(_ckRed, _ckGreen, _ckBlue, replaceAlpha); } _hasAlpha = hasTransparency(_surface); _valid = true; _gameRef->addMem(_width * _height * 4); delete image; _loaded = true; return true; }
int32 BaseParser::scanStr(const char *in, const char *format, ...) { va_list arg; va_start(arg, format); int32 num = 0; in += strspn(in, " \t\n\f"); while (*format && *in) { if (*format == '%') { format++; switch (*format) { case 'd': { int *a = va_arg(arg, int *); in += strspn(in, " \t\n\f"); *a = atoi(in); in += strspn(in, "0123456789+- \t\n\f"); num++; break; } case 'D': { int i; int *list = va_arg(arg, int *); int *nr = va_arg(arg, int *); in += strspn(in, " \t\n\f"); i = 0; while ((*in >= '0' && *in <= '9') || *in == '+' || *in == '-') { list[i++] = atoi(in); in += strspn(in, "0123456789+-"); in += strspn(in, " \t\n\f"); if (*in != ',') { break; } in++; in += strspn(in, " \t\n\f"); } *nr = i; num++; break; } case 'b': { bool *a = va_arg(arg, bool *); in += strspn(in, " \t\n\f"); const char *in2 = in + strspn(in, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); int l = (int)(in2 - in); *a = (bool)(!scumm_strnicmp(in, "yes", l) || !scumm_strnicmp(in, "true", l) || !scumm_strnicmp(in, "on", l) || !scumm_strnicmp(in, "1", l)); in = in2 + strspn(in2, " \t\n\f"); num++; break; } case 'f': { float *a = va_arg(arg, float *); in += strspn(in, " \t\n\f"); *a = (float)atof(in); in += strspn(in, "0123456789.eE+- \t\n\f"); num++; break; } case 'F': { int i; float *list = va_arg(arg, float *); int *nr = va_arg(arg, int *); in += strspn(in, " \t\n\f"); i = 0; while ((*in >= '0' && *in <= '9') || *in == '.' || *in == '+' || *in == '-' || *in == 'e' || *in == 'E') { list[i++] = (float)atof(in); in += strspn(in, "0123456789.eE+-"); in += strspn(in, " \t\n\f"); if (*in != ',') { break; } in++; in += strspn(in, " \t\n\f"); } *nr = i; num++; break; } case 's': { char *a = va_arg(arg, char *); in += strspn(in, " \t\n\f"); if (*in == '\'') { in++; const char *in2 = strchr(in, '\''); if (in2) { Common::strlcpy(a, in, (int)(in2 - in) + 1); in = in2 + 1; } else { strcpy(a, in); in = strchr(in, 0); } } else { const char *in2 = in + strspn(in, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789."); Common::strlcpy(a, in, (int)(in2 - in) + 1); in = in2; } in += strspn(in, " \t\n\f"); num++; break; } case 'S': { char *a = va_arg(arg, char *); in += strspn(in, " \t\n\f"); if (*in == '\"') { in++; while (*in != '\"') { if (*in == '\\') { in++; switch (*in) { case '\\': *a++ = '\\'; break; case 'n': *a++ = '\n'; break; case 'r': *a++ = '\r'; break; case 't': *a++ = '\t'; break; case '"': *a++ = '"'; break; default: *a++ = '\\'; *a++ = *in; break; } //switch in++; } else { *a++ = *in++; } } //while in string in++; num++; } //if string started //terminate string *a = '\0'; break; } } if (*format) { format++; } } else if (*format == ' ') {
void WidgetText::centerWindowOnSpeaker(int speaker) { TattooPeople &people = *(TattooPeople *)_vm->_people; TattooScene &scene = *(TattooScene *)_vm->_scene; Common::Point pt; speaker &= 0x7f; bool flag = _vm->readFlags(FLAG_PLAYER_IS_HOLMES); if (people[HOLMES]._type == CHARACTER && ((speaker == HOLMES && flag) || (speaker == WATSON && !flag))) { // Place the window centered above the player pt.x = people[HOLMES]._position.x / FIXED_INT_MULTIPLIER - _bounds.width() / 2; int scaleVal = scene.getScaleVal(people[HOLMES]._position); if (scaleVal == SCALE_THRESHOLD) { pt.x += people[HOLMES].frameWidth() / 2; pt.y = people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES].frameHeight() - _bounds.height() - _surface.fontHeight(); } else { pt.x += people[HOLMES]._imageFrame->sDrawXSize(scaleVal) / 2; pt.y = people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES]._imageFrame->sDrawYSize(scaleVal) - _bounds.height() - _surface.fontHeight(); } } else { pt.y = -1; // Check each NPC to see if they are the one that is talking for (int idx = 1; idx < MAX_CHARACTERS; ++idx) { // WORKAROUND: Fixes an original game bug where the positioning for Watson's dialogs // during conversations at the Park Lake lake scene is in the incorrect position if (speaker == 1 && scene._currentScene == 30) continue; if (people[idx]._type == CHARACTER) { if (!scumm_strnicmp(people[idx]._npcName.c_str(), people._characters[speaker]._portrait, 4)) { // Place the window above the player pt.x = people[idx]._position.x / FIXED_INT_MULTIPLIER - _bounds.width() / 2; int scaleVal = scene.getScaleVal(people[idx]._position); if (scaleVal == SCALE_THRESHOLD) { pt.x += people[idx].frameWidth() / 2; pt.y = people[idx]._position.y / FIXED_INT_MULTIPLIER - people[idx].frameHeight() - _bounds.height() - _surface.fontHeight(); } else { pt.x += people[idx]._imageFrame->sDrawXSize(scaleVal) / 2; pt.y = people[idx]._position.y / FIXED_INT_MULTIPLIER - people[idx]._imageFrame->sDrawYSize(scaleVal) - _bounds.height() - _surface.fontHeight(); } if (pt.y < 0) pt.y = 0; break; } } } if (pt.y == -1) { for (uint idx = 0; idx < scene._bgShapes.size(); ++idx) { Object &obj = scene._bgShapes[idx]; if (obj._type == ACTIVE_BG_SHAPE && !scumm_strnicmp(obj._name.c_str(), people._characters[speaker]._portrait, 4)) { // Place the window centered above the character pt.x = obj._position.x - _bounds.width() / 2; pt.y = obj._position.y - _bounds.height() - _surface.fontHeight(); if (pt.y < 0) pt.y = 0; if (obj._scaleVal == SCALE_THRESHOLD) pt.x += obj.frameWidth() / 2; else pt.x += obj._imageFrame->sDrawXSize(obj._scaleVal) / 2; break; } } } if (pt.y == -1) { pt.x = SHERLOCK_SCREEN_WIDTH / 2 - _bounds.width() / 2; pt.y = SHERLOCK_SCREEN_HEIGHT / 2 - _bounds.height() / 2; } } _bounds.moveTo(pt); }
HRESULT CBSurfaceSDL::Create(char *Filename, bool default_ck, byte ck_red, byte ck_green, byte ck_blue, int LifeTime, bool KeepLoaded) { CBRenderSDL *renderer = static_cast<CBRenderSDL *>(Game->m_Renderer); Common::String strFileName(Filename); Graphics::ImageDecoder *imgDecoder; if (strFileName.hasSuffix(".png")) { imgDecoder = new Graphics::PNGDecoder(); } else if (strFileName.hasSuffix(".bmp")) { imgDecoder = new Graphics::BitmapDecoder(); } else { error("CBSurfaceSDL::Create : Unsupported fileformat %s", Filename); } CBFile *file = Game->m_FileManager->OpenFile(Filename); if (!file) return E_FAIL; imgDecoder->loadStream(*file->getMemStream()); const Graphics::Surface *surface = imgDecoder->getSurface(); Game->m_FileManager->CloseFile(file); if (default_ck) { ck_red = 255; ck_green = 0; ck_blue = 255; } m_Width = surface->w; m_Height = surface->h; bool isSaveGameGrayscale = scumm_strnicmp(Filename, "savegame:", 9) == 0 && (Filename[strFileName.size() - 1] == 'g' || Filename[strFileName.size() - 1] == 'G'); if (isSaveGameGrayscale) { warning("grayscaleConversion not yet implemented"); /* FIBITMAP *newImg = FreeImage_ConvertToGreyscale(img); if (newImg) { FreeImage_Unload(img); img = newImg; }*/ } // convert 32-bit BMPs to 24-bit or they appear totally transparent (does any app actually write alpha in BMP properly?) /* if (FreeImage_GetBPP(img) != 32 || (imgFormat == FIF_BMP && FreeImage_GetBPP(img) != 24)) { FIBITMAP *newImg = FreeImage_ConvertTo24Bits(img); if (newImg) { FreeImage_Unload(img); img = newImg; } else { FreeImage_Unload(img); return -1; } } FreeImage_FlipVertical(img);*/ //TODO: This is rather endian-specific, but should be replaced by non-SDL-code anyhow: uint32 rmask = surface->format.rMax() << surface->format.rShift; uint32 gmask = surface->format.gMax() << surface->format.gShift; uint32 bmask = surface->format.bMax() << surface->format.bShift; uint32 amask = surface->format.aMax(); SDL_Surface *surf = SDL_CreateRGBSurfaceFrom(surface->pixels, m_Width, m_Height, surface->format.bytesPerPixel * 8, surface->pitch, rmask, gmask, bmask, amask); // no alpha, set color key if (surface->format.bytesPerPixel != 4) SDL_SetColorKey(surf, SDL_TRUE, SDL_MapRGB(surf->format, ck_red, ck_green, ck_blue)); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best"); //m_Texture = SdlUtil::CreateTextureFromSurface(renderer->GetSdlRenderer(), surf); m_Texture = SDL_CreateTextureFromSurface(renderer->GetSdlRenderer(), surf); if (!m_Texture) { SDL_FreeSurface(surf); delete imgDecoder; return E_FAIL; } GenAlphaMask(surf); SDL_FreeSurface(surf); delete imgDecoder; // TODO: Update this if ImageDecoder doesn't end up owning the surface. m_CKDefault = default_ck; m_CKRed = ck_red; m_CKGreen = ck_green; m_CKBlue = ck_blue; if (!m_Filename || scumm_stricmp(m_Filename, Filename) != 0) { SetFilename(Filename); } if (m_LifeTime == 0 || LifeTime == -1 || LifeTime > m_LifeTime) m_LifeTime = LifeTime; m_KeepLoaded = KeepLoaded; if (m_KeepLoaded) m_LifeTime = -1; m_Valid = true; Game->AddMem(m_Width * m_Height * 4); return S_OK; }
/** * Parses a JSON encoded value to a JSONValue object * * @access protected * * @param char** data Pointer to a char* that contains the data * * @return JSONValue* Returns a pointer to a JSONValue object on success, NULL on error */ JSONValue *JSONValue::parse(const char **data) { // Is it a string? if (**data == '"') { String str; if (!JSON::extractString(&(++(*data)), str)) return NULL; else return new JSONValue(str); } // Is it a boolean? else if ((simplejson_wcsnlen(*data, 4) && scumm_strnicmp(*data, "true", 4) == 0) || (simplejson_wcsnlen(*data, 5) && scumm_strnicmp(*data, "false", 5) == 0)) { bool value = scumm_strnicmp(*data, "true", 4) == 0; (*data) += value ? 4 : 5; return new JSONValue(value); } // Is it a null? else if (simplejson_wcsnlen(*data, 4) && scumm_strnicmp(*data, "null", 4) == 0) { (*data) += 4; return new JSONValue(); } // Is it a number? else if (**data == '-' || (**data >= '0' && **data <= '9')) { // Negative? bool neg = **data == '-'; if (neg) (*data)++; long long int integer = 0; double number = 0.0; bool onlyInteger = true; // Parse the whole part of the number - only if it wasn't 0 if (**data == '0') (*data)++; else if (**data >= '1' && **data <= '9') number = integer = JSON::parseInt(data); else return NULL; // Could be a decimal now... if (**data == '.') { (*data)++; // Not get any digits? if (!(**data >= '0' && **data <= '9')) return NULL; // Find the decimal and sort the decimal place out // Use ParseDecimal as ParseInt won't work with decimals less than 0.1 // thanks to Javier Abadia for the report & fix double decimal = JSON::parseDecimal(data); // Save the number number += decimal; onlyInteger = false; } // Could be an exponent now... if (**data == 'E' || **data == 'e') { (*data)++; // Check signage of expo bool neg_expo = false; if (**data == '-' || **data == '+') { neg_expo = **data == '-'; (*data)++; } // Not get any digits? if (!(**data >= '0' && **data <= '9')) return NULL; // Sort the expo out double expo = JSON::parseInt(data); for (double i = 0.0; i < expo; i++) number = neg_expo ? (number / 10.0) : (number * 10.0); onlyInteger = false; } // Was it neg? if (neg) number *= -1; if (onlyInteger) return new JSONValue(neg ? -integer : integer); return new JSONValue(number); } // An object? else if (**data == '{') { JSONObject object; (*data)++; while (**data != 0) { // Whitespace at the start? if (!JSON::skipWhitespace(data)) { FREE_OBJECT(object); return NULL; } // Special case - empty object if (object.size() == 0 && **data == '}') { (*data)++; return new JSONValue(object); } // We want a string now... String name; if (!JSON::extractString(&(++(*data)), name)) { FREE_OBJECT(object); return NULL; } // More whitespace? if (!JSON::skipWhitespace(data)) { FREE_OBJECT(object); return NULL; } // Need a : now if (*((*data)++) != ':') { FREE_OBJECT(object); return NULL; } // More whitespace? if (!JSON::skipWhitespace(data)) { FREE_OBJECT(object); return NULL; } // The value is here JSONValue *value = parse(data); if (value == NULL) { FREE_OBJECT(object); return NULL; } // Add the name:value if (object.find(name) != object.end()) delete object[name]; object[name] = value; // More whitespace? if (!JSON::skipWhitespace(data)) { FREE_OBJECT(object); return NULL; } // End of object? if (**data == '}') { (*data)++; return new JSONValue(object); } // Want a , now if (**data != ',') { FREE_OBJECT(object); return NULL; } (*data)++; } // Only here if we ran out of data FREE_OBJECT(object); return NULL; } // An array? else if (**data == '[') { JSONArray array; (*data)++; while (**data != 0) { // Whitespace at the start? if (!JSON::skipWhitespace(data)) { FREE_ARRAY(array); return NULL; } // Special case - empty array if (array.size() == 0 && **data == ']') { (*data)++; return new JSONValue(array); } // Get the value JSONValue *value = parse(data); if (value == NULL) { FREE_ARRAY(array); return NULL; } // Add the value array.push_back(value); // More whitespace? if (!JSON::skipWhitespace(data)) { FREE_ARRAY(array); return NULL; } // End of array? if (**data == ']') { (*data)++; return new JSONValue(array); } // Want a , now if (**data != ',') { FREE_ARRAY(array); return NULL; } (*data)++; } // Only here if we ran out of data FREE_ARRAY(array); return NULL; } // Ran out of possibilites, it's bad! else { return NULL; } }
/** * Checks whether the start of an extracted command matches a specified given command constant */ bool Dialog::matchCommand(const char *s1, const char *s2) { bool result = scumm_strnicmp(s1, s2, strlen(s2)) == 0; _commandCase = isupper(*s1); return result; }
void WidgetVerbs::load(bool objectsOn) { Events &events = *_vm->_events; Talk &talk = *_vm->_talk; TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui; TattooPeople &people = *(TattooPeople *)_vm->_people; Common::Point mousePos = events.mousePos(); bool isWatson = false; if (talk._talkToAbort) return; _outsideMenu = false; _verbCommands.clear(); // Check if we need to show options for the highlighted object if (objectsOn) { // Set the verb list accordingly, depending on the target being a // person or an object if (ui._personFound) { TattooPerson &person = people[ui._activeObj - 1000]; TattooPerson &npc = people[ui._activeObj - 1001]; if (!scumm_strnicmp(npc._npcName.c_str(), "WATS", 4)) isWatson = true; if (scumm_strnicmp(person._examine.c_str(), "_EXIT", 5)) _verbCommands.push_back(FIXED(Look)); _verbCommands.push_back(FIXED(Talk)); // Add any extra active verbs from the NPC's verb list for (int idx = 0; idx < 2; ++idx) { if (!person._use[idx]._verb.empty() && !person._use[idx]._verb.hasPrefix(" ") && (person._use[idx]._target.empty() || person._use[idx]._target.hasPrefix(" "))) { _verbCommands.push_back(person._use[idx]._verb); } } } else { if (!scumm_strnicmp(ui._bgShape->_name.c_str(), "WATS", 4)) // Looking at Watson isWatson = true; if (scumm_strnicmp(ui._bgShape->_examine.c_str(), "_EXIT", 5)) // It's not an exit, so include Look as an option _verbCommands.push_back(FIXED(Look)); if (ui._bgShape->_aType == PERSON) _verbCommands.push_back(FIXED(Talk)); // Add any extra active verbs from the object's verb list for (int idx = 0; idx < 6; ++idx) { if (!ui._bgShape->_use[idx]._verb.empty() && !ui._bgShape->_use[idx]._verb.hasPrefix(" ") && (ui._bgShape->_use[idx]._target.empty() || ui._bgShape->_use[idx]._target.hasPrefix(" "))) { _verbCommands.push_back(ui._bgShape->_use[idx]._verb); } } } } // If clicked on Watson, have Journal as an option if (isWatson) _verbCommands.push_back(FIXED(Journal)); // Add the system commands _verbCommands.push_back(FIXED(Inventory)); _verbCommands.push_back(FIXED(Options)); // Figure out the needed width to show the commands int width = 0; for (uint idx = 0; idx < _verbCommands.size(); ++idx) width = MAX(width, _surface.stringWidth(_verbCommands[idx])); width += _surface.widestChar() * 2 + 6; int height = (_surface.fontHeight() + 7) * _verbCommands.size() + 3; // Set the bounds _bounds = Common::Rect(width, height); _bounds.moveTo(mousePos.x - _bounds.width() / 2, mousePos.y - _bounds.height() / 2); // Render the window on the internal surface render(); }