Load the caption file with the given name and parse the subs/captions from it
| 319 | |
| 320 | // Load the caption file with the given name and parse the subs/captions from it |
| 321 | void loadCaptions(const string path) |
| 322 | { |
| 323 | s_captionMap.clear(); |
| 324 | |
| 325 | // Try to open the file |
| 326 | s_currentCaptionFile.path = path; |
| 327 | if (!s_captionsStream.open(path.c_str(), Stream::AccessMode::MODE_READ)) |
| 328 | { |
| 329 | onFileError(path); |
| 330 | return; |
| 331 | } |
| 332 | |
| 333 | // Parse language name; for example, if file name is "subtitles-de.txt", the language is "de". |
| 334 | // The idea is for the language name to be an ISO 639-1 two-letter code, but for now the system |
| 335 | // doesn't actually care how long the language name is or whether it's a valid 639-1 code. |
| 336 | size_t start = path.find(FILE_NAME_START); |
| 337 | if (start != string::npos) |
| 338 | { |
| 339 | s_currentCaptionFile.name = path.substr(start); |
| 340 | string language = path.substr(start + FILE_NAME_START.length()); |
| 341 | language = language.substr(0, language.length() - FILE_NAME_EXT.length()); |
| 342 | TFE_Settings::getA11ySettings()->language = language; |
| 343 | } |
| 344 | |
| 345 | // Read file into buffer. |
| 346 | auto size = (u32)s_captionsStream.getSize(); |
| 347 | s_captionsBuffer = (char*)malloc(size); |
| 348 | s_captionsStream.readBuffer(s_captionsBuffer, size); |
| 349 | |
| 350 | // Init parser (configured to ignore comment lines). |
| 351 | s_parser.init(s_captionsBuffer, size); |
| 352 | s_parser.addCommentString("#"); |
| 353 | s_parser.addCommentString("//"); |
| 354 | |
| 355 | // Parse each line from the caption file. |
| 356 | size_t bufferPos = 0; |
| 357 | while (bufferPos < size) |
| 358 | { |
| 359 | const char* line = s_parser.readLine(bufferPos); |
| 360 | if (!line) { break; } |
| 361 | |
| 362 | TokenList tokens; |
| 363 | s_parser.tokenizeLine(line, tokens); |
| 364 | if (tokens.size() < 2) { continue; } |
| 365 | |
| 366 | Caption caption = Caption(); |
| 367 | caption.text = tokens[1]; |
| 368 | |
| 369 | // Optional third field is duration in seconds, mainly useful for cutscenes. |
| 370 | if (tokens.size() > 2) |
| 371 | { |
| 372 | try |
| 373 | { |
| 374 | caption.microsecondsRemaining = secondsToMicroseconds(std::stof(tokens[2])); |
| 375 | } |
| 376 | catch(...) { |
| 377 | } |
| 378 | } |
no test coverage detected