bool Text::doRender() { // Font-Resource locken. FontResource *fontPtr = lockFontResource(); if (!fontPtr) return false; // Charactermap-Resource locken. ResourceManager *rmPtr = getResourceManager(); BitmapResource *charMapPtr; { Resource *pResource = rmPtr->requestResource(fontPtr->getCharactermapFileName()); if (!pResource) { BS_LOG_ERRORLN("Could not request resource \"%s\".", fontPtr->getCharactermapFileName().c_str()); return false; } if (pResource->getType() != Resource::TYPE_BITMAP) { BS_LOG_ERRORLN("Requested resource \"%s\" is not a bitmap.", fontPtr->getCharactermapFileName().c_str()); return false; } charMapPtr = static_cast<BitmapResource *>(pResource); } // Framebufferobjekt holen. GraphicEngine *gfxPtr = Kernel::getInstance()->getGfx(); BS_ASSERT(gfxPtr); bool result = true; Common::Array<Line>::iterator iter = _lines.begin(); for (; iter != _lines.end(); ++iter) { // Feststellen, ob überhaupt Buchstaben der aktuellen Zeile vom Update betroffen sind. Common::Rect checkRect = (*iter).bbox; checkRect.translate(_absoluteX, _absoluteY); // Jeden Buchstaben einzeln Rendern. int curX = _absoluteX + (*iter).bbox.left; int curY = _absoluteY + (*iter).bbox.top; for (uint i = 0; i < (*iter).text.size(); ++i) { Common::Rect curRect = fontPtr->getCharacterRect((byte)(*iter).text[i]); Common::Rect renderRect(curX, curY, curX + curRect.width(), curY + curRect.height()); int renderX = curX + (renderRect.left - renderRect.left); int renderY = curY + (renderRect.top - renderRect.top); renderRect.translate(curRect.left - curX, curRect.top - curY); result = charMapPtr->blit(renderX, renderY, Image::FLIP_NONE, &renderRect, _modulationColor); if (!result) break; curX += curRect.width() + fontPtr->getGapWidth(); } } // Charactermap-Resource freigeben. charMapPtr->release(); // Font-Resource freigeben. fontPtr->release(); return result; }
AnimationResource::AnimationResource(const Common::String &filename) : Resource(filename, Resource::TYPE_ANIMATION), Common::XMLParser(), _valid(false) { // Get a pointer to the package manager _pPackage = Kernel::getInstance()->getPackage(); BS_ASSERT(_pPackage); // Switch to the folder the specified Xml fiile is in Common::String oldDirectory = _pPackage->getCurrentDirectory(); if (getFileName().contains('/')) { Common::String dir = Common::String(getFileName().c_str(), strrchr(getFileName().c_str(), '/')); _pPackage->changeDirectory(dir); } // Load the contents of the file uint fileSize; char *xmlData = _pPackage->getXmlFile(getFileName(), &fileSize); if (!xmlData) { BS_LOG_ERRORLN("Could not read \"%s\".", getFileName().c_str()); return; } // Parse the contents if (!loadBuffer((const byte *)xmlData, fileSize)) return; _valid = parse(); close(); free(xmlData); // Switch back to the previous folder _pPackage->changeDirectory(oldDirectory); // Give an error message if there weren't any frames specified if (_frames.empty()) { BS_LOG_ERRORLN("\"%s\" does not have any frames.", getFileName().c_str()); return; } // Pre-cache all the frames if (!precacheAllFrames()) { BS_LOG_ERRORLN("Could not precache all frames of \"%s\".", getFileName().c_str()); return; } // Post processing to compute animation features if (!computeFeatures()) { BS_LOG_ERRORLN("Could not determine the features of \"%s\".", getFileName().c_str()); return; } _valid = true; }
void LuaCallback::invokeCallbackFunctions(lua_State *L, uint objectHandle) { ensureObjectCallbackTableExists(L, objectHandle); // Iterate through the table and perform all the callbacks lua_pushnil(L); while (lua_next(L, -2) != 0) { // The value of the current element is at the top of the stack, including the index // If the value is a function, execute it if (lua_type(L, -1) == LUA_TFUNCTION) { // Pre-Function Call // Derived classes can function in this parameter onto the stack. // The return value indicates the number of parameters int argumentCount = preFunctionInvokation(L); // Lua_pcall the function and the parameters pop themselves from the stack if (lua_pcall(L, argumentCount, 0, 0) != 0) { // An error has occurred BS_LOG_ERRORLN("An error occured executing a callback function: %s", lua_tostring(L, -1)); // Pop error message from the stack lua_pop(L, 1); } } else { // Pop value from the stack. The index is then ready for the next call to lua_next() lua_pop(L, 1); } } }
bool AnimationResource::computeFeatures() { BS_ASSERT(_frames.size()); // Alle Features werden als vorhanden angenommen _scalingAllowed = true; _alphaAllowed = true; _colorModulationAllowed = true; // Alle Frame durchgehen und alle Features deaktivieren, die auch nur von einem Frame nicht unterstützt werden. Common::Array<Frame>::const_iterator iter = _frames.begin(); for (; iter != _frames.end(); ++iter) { BitmapResource *pBitmap; if (!(pBitmap = static_cast<BitmapResource *>(Kernel::getInstance()->getResourceManager()->requestResource((*iter).fileName)))) { BS_LOG_ERRORLN("Could not request \"%s\".", (*iter).fileName.c_str()); return false; } if (!pBitmap->isScalingAllowed()) _scalingAllowed = false; if (!pBitmap->isAlphaAllowed()) _alphaAllowed = false; if (!pBitmap->isColorModulationAllowed()) _colorModulationAllowed = false; pBitmap->release(); } return true; }
PackageManager::PackageManager(Kernel *pKernel) : Service(pKernel), _currentDirectory(PATH_SEPARATOR), _rootFolder(ConfMan.get("path")) { if (!registerScriptBindings()) BS_LOG_ERRORLN("Script bindings could not be registered."); else BS_LOGLN("Script bindings registered."); }
Kernel::Kernel() : _resourceManager(NULL), _initSuccess(false), _gfx(0), _sfx(0), _input(0), _package(0), _script(0), _fmv(0) { // Log that the kernel is beign created BS_LOGLN("created."); _instance = this; // Create the resource manager _resourceManager = new ResourceManager(this); // Initialise the script engine _script = new LuaScriptEngine(this); if (!_script || !_script->init()) { _initSuccess = false; return; } // Register kernel script bindings if (!registerScriptBindings()) { BS_LOG_ERRORLN("Script bindings could not be registered."); _initSuccess = false; return; } BS_LOGLN("Script bindings registered."); _input = new InputEngine(this); assert(_input); _gfx = new GraphicEngine(this); assert(_gfx); _sfx = new SoundEngine(this); assert(_sfx); _package = new PackageManager(this); assert(_package); _geometry = new Geometry(this); assert(_geometry); #ifdef USE_THEORADEC _fmv = new MoviePlayer(this); assert(_fmv); #endif _initSuccess = true; }
bool AnimationResource::precacheAllFrames() const { Common::Array<Frame>::const_iterator iter = _frames.begin(); for (; iter != _frames.end(); ++iter) { if (!Kernel::getInstance()->getResourceManager()->precacheResource((*iter).fileName)) { BS_LOG_ERRORLN("Could not precache \"%s\".", (*iter).fileName.c_str()); return false; } } return true; }
bool RenderObject::detatchChildren(RenderObjectPtr<RenderObject> pObject) { // Kinderliste durchgehen und Objekt entfernen falls vorhanden RENDEROBJECT_ITER it = _children.begin(); for (; it != _children.end(); ++it) if (*it == pObject) { _children.erase(it); return true; } BS_LOG_ERRORLN("Tried to detach children from a render object that isn't its parent."); return false; }
FontResource *Text::lockFontResource() { ResourceManager *rmPtr = getResourceManager(); // Font-Resource locken. FontResource *fontPtr; { Resource *resourcePtr = rmPtr->requestResource(_font); if (!resourcePtr) { BS_LOG_ERRORLN("Could not request resource \"%s\".", _font.c_str()); return NULL; } if (resourcePtr->getType() != Resource::TYPE_FONT) { BS_LOG_ERRORLN("Requested resource \"%s\" is not a font.", _font.c_str()); return NULL; } fontPtr = static_cast<FontResource *>(resourcePtr); } return fontPtr; }
bool Text::setFont(const Common::String &font) { // Font precachen. if (getResourceManager()->precacheResource(font)) { _font = font; updateFormat(); forceRefresh(); return true; } else { BS_LOG_ERRORLN("Could not precache font \"%s\". Font probably does not exist.", font.c_str()); return false; } }
bool RenderObject::addObject(RenderObjectPtr<RenderObject> pObject) { if (!pObject.isValid()) { BS_LOG_ERRORLN("Tried to add a null object to a renderobject."); return false; } // Objekt in die Kinderliste einfügen. _children.push_back(pObject); // Sicherstellen, dass vor dem nächsten Rendern die Renderreihenfolge aktualisiert wird. if (_parentPtr.isValid()) _parentPtr->signalChildChange(); return true; }
byte *PackageManager::getFile(const Common::String &fileName, uint *fileSizePtr) { const Common::String B25S_EXTENSION(".b25s"); Common::SeekableReadStream *in; if (fileName.hasSuffix(B25S_EXTENSION)) { // Savegame loading logic Common::SaveFileManager *sfm = g_system->getSavefileManager(); Common::InSaveFile *file = sfm->openForLoading( FileSystemUtil::getPathFilename(fileName)); if (!file) { BS_LOG_ERRORLN("Could not load savegame \"%s\".", fileName.c_str()); return 0; } if (fileSizePtr) *fileSizePtr = file->size(); byte *buffer = new byte[file->size()]; file->read(buffer, file->size()); delete file; return buffer; } Common::ArchiveMemberPtr fileNode = getArchiveMember(normalizePath(fileName, _currentDirectory)); if (!fileNode) return 0; if (!(in = fileNode->createReadStream())) return 0; // If the filesize is desired, then output the size if (fileSizePtr) *fileSizePtr = in->size(); // Read the file byte *buffer = new byte[in->size()]; int bytesRead = in->read(buffer, in->size()); delete in; if (!bytesRead) { delete[] buffer; return NULL; } return buffer; }
RenderObject::RenderObject(RenderObjectPtr<RenderObject> parentPtr, TYPES type, uint handle) : _managerPtr(0), _parentPtr(parentPtr), _x(0), _y(0), _z(0), _oldX(-1), _oldY(-1), _oldZ(-1), _width(0), _height(0), _visible(true), _oldVisible(false), _childChanged(true), _type(type), _initSuccess(false), _refreshForced(true), _handle(0) { // Renderobject registrieren, abhängig vom Handle-Parameter entweder mit beliebigem oder vorgegebenen Handle. if (handle == 0) _handle = RenderObjectRegistry::instance().registerObject(this); else _handle = RenderObjectRegistry::instance().registerObject(this, handle); if (_handle == 0) return; updateAbsolutePos(); // Dieses Objekt zu den Kindern der Elternobjektes hinzufügen, falls nicht Wurzel (ParentPtr ungültig) und dem // selben RenderObjektManager zuweisen. if (_parentPtr.isValid()) { _managerPtr = _parentPtr->getManager(); _parentPtr->addObject(this->getHandle()); } else { if (getType() != TYPE_ROOT) { BS_LOG_ERRORLN("Tried to create a non-root render object and has no parent. All non-root render objects have to have a parent."); return; } } updateObjectState(); _initSuccess = true; }
bool PackageManager::loadDirectoryAsPackage(const Common::String &directoryName, const Common::String &mountPosition) { Common::FSNode directory(directoryName); Common::Archive *folderArchive = new Common::FSDirectory(directory, 6); if (!directory.exists() || (folderArchive == NULL)) { BS_LOG_ERRORLN("Unable to mount directory \"%s\" to \"%s\".", directoryName.c_str(), mountPosition.c_str()); return false; } else { BS_LOGLN("Directory '%s' mounted as '%s'.", directoryName.c_str(), mountPosition.c_str()); Common::ArchiveMemberList files; folderArchive->listMembers(files); debug(0, "Capacity %d", files.size()); _archiveList.push_front(new ArchiveEntry(folderArchive, mountPosition)); return true; } }
bool PackageManager::loadPackage(const Common::String &fileName, const Common::String &mountPosition) { debug(3, "loadPackage(%s, %s)", fileName.c_str(), mountPosition.c_str()); Common::Archive *zipFile = Common::makeZipArchive(fileName); if (zipFile == NULL) { BS_LOG_ERRORLN("Unable to mount file \"%s\" to \"%s\"", fileName.c_str(), mountPosition.c_str()); return false; } else { BS_LOGLN("Package '%s' mounted as '%s'.", fileName.c_str(), mountPosition.c_str()); Common::ArchiveMemberList files; zipFile->listMembers(files); debug(3, "Capacity %d", files.size()); for (Common::ArchiveMemberList::iterator it = files.begin(); it != files.end(); ++it) debug(3, "%s", (*it)->getName().c_str()); _archiveList.push_front(new ArchiveEntry(zipFile, mountPosition)); return true; } }
RenderObjectPtr<RenderObject> RenderObject::recreatePersistedRenderObject(InputPersistenceBlock &reader) { RenderObjectPtr<RenderObject> result; // Typ und Handle auslesen. uint type; uint handle; reader.read(type); reader.read(handle); if (!reader.isGood()) return result; switch (type) { case TYPE_PANEL: result = (new Panel(reader, this->getHandle(), handle))->getHandle(); break; case TYPE_STATICBITMAP: result = (new StaticBitmap(reader, this->getHandle(), handle))->getHandle(); break; case TYPE_DYNAMICBITMAP: result = (new DynamicBitmap(reader, this->getHandle(), handle))->getHandle(); break; case TYPE_TEXT: result = (new Text(reader, this->getHandle(), handle))->getHandle(); break; case TYPE_ANIMATION: result = (new Animation(reader, this->getHandle(), handle))->getHandle(); break; default: BS_LOG_ERRORLN("Cannot recreate render object of unknown type %d.", type); } return result; }
void RenderObject::setZ(int z) { if (z < 0) BS_LOG_ERRORLN("Tried to set a negative Z value (%d).", z); else _z = z; }
bool AnimationResource::parserCallback_frame(ParserNode *node) { Frame frame; const char *fileString = node->values["file"].c_str(); if (!fileString) { BS_LOG_ERRORLN("<frame> tag without file attribute occurred in \"%s\".", getFileName().c_str()); return false; } frame.fileName = _pPackage->getAbsolutePath(fileString); if (frame.fileName.empty()) { BS_LOG_ERRORLN("Could not create absolute path for file specified in <frame> tag in \"%s\": \"%s\".", getFileName().c_str(), fileString); return false; } const char *actionString = node->values["action"].c_str(); if (actionString) frame.action = actionString; const char *hotspotxString = node->values["hotspotx"].c_str(); const char *hotspotyString = node->values["hotspoty"].c_str(); if ((!hotspotxString && hotspotyString) || (hotspotxString && !hotspotyString)) BS_LOG_WARNINGLN("%s attribute occurred without %s attribute in <frame> tag in \"%s\". Assuming default (\"0\").", hotspotxString ? "hotspotx" : "hotspoty", !hotspotyString ? "hotspoty" : "hotspotx", getFileName().c_str()); frame.hotspotX = 0; if (hotspotxString && !parseIntegerKey(hotspotxString, 1, &frame.hotspotX)) BS_LOG_WARNINGLN("Illegal hotspotx value (\"%s\") in frame tag in \"%s\". Assuming default (\"%s\").", hotspotxString, getFileName().c_str(), frame.hotspotX); frame.hotspotY = 0; if (hotspotyString && !parseIntegerKey(hotspotyString, 1, &frame.hotspotY)) BS_LOG_WARNINGLN("Illegal hotspoty value (\"%s\") in frame tag in \"%s\". Assuming default (\"%s\").", hotspotyString, getFileName().c_str(), frame.hotspotY); Common::String flipVString = node->values["flipv"]; if (!flipVString.empty()) { if (!parseBooleanKey(flipVString, frame.flipV)) { BS_LOG_WARNINGLN("Illegal flipv value (\"%s\") in <frame> tag in \"%s\". Assuming default (\"false\").", flipVString.c_str(), getFileName().c_str()); frame.flipV = false; } } else frame.flipV = false; Common::String flipHString = node->values["fliph"]; if (!flipHString.empty()) { if (!parseBooleanKey(flipVString, frame.flipV)) { BS_LOG_WARNINGLN("Illegal fliph value (\"%s\") in <frame> tag in \"%s\". Assuming default (\"false\").", flipHString.c_str(), getFileName().c_str()); frame.flipH = false; } } else frame.flipH = false; _frames.push_back(frame); return true; }