/////////////////////////////////////////////////////////////////////////////// /// \brief Loads a texture font from the specified sandwich database. /// /// \param sandwich The database from which to load the TextureFont. /// \param texture_id Identifies the TextureFont to load from the database. /// \param rm The ResourceManager from which to retrieve the texture for the /// font. /// \return A unique_ptr to the font, or an empty unique_ptr if a problem /// occurs during the load. std::unique_ptr<TextureFont> loadTextureFont(sw::Sandwich& sandwich, const Id& id, sw::ResourceManager& rm) { std::unique_ptr<TextureFont> result; try { db::StmtCache& cache = sandwich.getStmtCache(); db::CachedStmt get_font = cache.hold(Id(PBJ_GFX_TEXTURE_FONT_SQLID_LOAD), PBJ_GFX_TEXTURE_FONT_SQL_LOAD); get_font.bind(1, id.value()); if (get_font.step()) { Id texture_id = Id(get_font.getUInt64(0)); F32 cap_height = float(get_font.getDouble(1)); std::vector<TextureFontCharacter> chars; db::CachedStmt get_chars = cache.hold(Id(PBJ_GFX_TEXTURE_FONT_SQLID_LOAD_CHARS), PBJ_GFX_TEXTURE_FONT_SQL_LOAD_CHARS); get_chars.bind(1, id.value()); while (get_chars.step()) { TextureFontCharacter ch; ch.codepoint = get_chars.getInt(0); ch.texture_offset.x = float(get_chars.getDouble(1)); ch.texture_offset.y = float(get_chars.getDouble(2)); ch.texture_dimensions.x = float(get_chars.getDouble(3)); ch.texture_dimensions.y = float(get_chars.getDouble(4)); ch.character_offset.x = float(get_chars.getDouble(5)); ch.character_offset.y = float(get_chars.getDouble(6)); ch.character_advance = float(get_chars.getDouble(7)); chars.push_back(ch); } const Texture& texture = rm.getTexture(sw::ResourceId(sandwich.getId(), texture_id)); result.reset(new TextureFont(texture, cap_height, chars)); } else throw std::runtime_error("Texture not found!"); } catch (const db::Db::error& err) { PBJ_LOG(VWarning) << "Database error while loading texture font!" << PBJ_LOG_NL << " Sandwich ID: " << sandwich.getId() << PBJ_LOG_NL << "TextureFont ID: " << id << PBJ_LOG_NL << " Exception: " << err.what() << PBJ_LOG_NL << " SQL: " << err.sql() << PBJ_LOG_END; } catch (const std::exception& err) { PBJ_LOG(VWarning) << "Exception while loading texture font!" << PBJ_LOG_NL << " Sandwich ID: " << sandwich.getId() << PBJ_LOG_NL << "TextureFont ID: " << id << PBJ_LOG_NL << " Exception: " << err.what() << PBJ_LOG_END; } return result; }
void BuiltIns::logWarning(const char* type, const sw::ResourceId id, const std::string& what_arg) const { PBJ_LOG(VWarning) << "Exception while initializing built-in resource!" << PBJ_LOG_NL << "Resource Type: " << type << PBJ_LOG_NL << " Resource ID: " << id.resource << PBJ_LOG_NL << " Exception: " << what_arg << PBJ_LOG_END; }
/////////////////////////////////////////////////////////////////////////////// /// \brief Retrieves a modifiable sandwich by opening a new db::Db object. /// The Sandwich object returned will always be unique from previously /// returned sandwiches, or those returned from open(). std::shared_ptr<Sandwich> openWritable(const Id& id) { SandwichInfo* swi = getSWI(id); if (!swi) { PBJ_LOG(VWarning) << "Attempted to open unknown sandwich!" << PBJ_LOG_NL << "Sandwich ID: " << id << PBJ_LOG_END; return std::shared_ptr<Sandwich>(); } return std::shared_ptr<Sandwich>(new Sandwich(swi->path, false)); }
//////////////////////////////////////////////////////////////////////////////// /// \fn std::unique_ptr<AudioBuffer> loadSound(sw::Sandwich& sandwich, /// const Id& id) /// /// \brief Loads a sound. /// /// \author Ben Crist /// \date 2013-08-22 /// /// \exception std::runtime_error Thrown when a runtime error error /// condition occurs. /// /// \param [in,out] sandwich The sandwich. /// \param id The identifier. /// /// \return The sound. std::unique_ptr<Buffer> loadSound(sw::Sandwich& sandwich, const Id& id) { std::unique_ptr<Buffer> result; try { db::StmtCache& cache = sandwich.getStmtCache(); db::CachedStmt stmt = cache.hold(Id(PBJSQLID_LOAD), PBJSQL_LOAD); stmt.bind(1, id.value()); if (stmt.step()) { const void* data; size_t data_length = stmt.getBlob(0, data); result.reset(new Buffer(static_cast<const ALubyte*>(data), data_length)); } else throw std::runtime_error("Sound not found!"); } catch (const db::Db::error& err) { PBJ_LOG(VWarning) << "Database error while loading sound!" << PBJ_LOG_NL << "Sandwich ID: " << sandwich.getId() << PBJ_LOG_NL << " Sound ID: " << id << PBJ_LOG_NL << " Exception: " << err.what() << PBJ_LOG_NL << " SQL: " << err.sql() << PBJ_LOG_END; } catch (const std::exception& err) { PBJ_LOG(VWarning) << "Exception while loading sound!" << PBJ_LOG_NL << "Sandwich ID: " << sandwich.getId() << PBJ_LOG_NL << " Sound ID: " << id << PBJ_LOG_NL << " Exception: " << err.what() << PBJ_LOG_END; } return result; }
/////////////////////////////////////////////////////////////////////////////// /// \brief Retrieves a shared_ptr to a read-only sandwich which is already /// open, or opens the sanwich if it is not (saving it for future calls /// to open()). std::shared_ptr<Sandwich> open(const Id& id) { SandwichInfo* swi = getSWI(id); if (!swi) { PBJ_LOG(VWarning) << "Attempted to open unknown sandwich!" << PBJ_LOG_NL << "Sandwich ID: " << id << PBJ_LOG_END; return std::shared_ptr<Sandwich>(); } std::shared_ptr<Sandwich> ptr(swi->sandwich.lock()); if (!ptr) // previous instance has already been destroyed { ptr.reset(new Sandwich(swi->path, true)); swi->sandwich = std::weak_ptr<Sandwich>(ptr); } return std::move(ptr); }
/////////////////////////////////////////////////////////////////////////////// /// \brief Application entry point /// \details Parses any command line arguments, then initializes game engine. int main(int argc, char* argv[]) { #ifdef BE_CRT_BUILD _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif #ifdef DEBUG int verbosity = pbj::VAll; #else int verbosity = pbj::VErrorsAndWarnings; #endif std::ofstream cerr_log_file; std::string cerr_log("pbjed.log"); if (argc != 1) { std::cout << "PBJgame " << PBJ_VERSION_MAJOR << '.' << PBJ_VERSION_MINOR << " (" << __DATE__ " " __TIME__ << ')' << std::endl << PBJ_COPYRIGHT << std::endl; return 1; } // Set the appropriate verbosity level be::setVerbosity(verbosity); // Redirect PBJ_LOG_STREAM to a log file if not in DEBUG mode #ifndef DEBUG if (cerr_log.length() > 0) { PBJ_LOG(pbj::VNotice) << "Redirecting log to " << cerr_log << PBJ_LOG_END; cerr_log_file.open(cerr_log, std::ofstream::trunc); PBJ_LOG_STREAM.rdbuf(cerr_log_file.rdbuf()); PBJ_LOG(pbj::VInfo) << "Starting Editor..." << PBJ_LOG_NL << " PBJgame Version: " << PBJ_VERSION_MAJOR << '.' << PBJ_VERSION_MINOR << PBJ_LOG_NL << " Build Date: " << __DATE__ " " __TIME__ << PBJ_LOG_END; } #endif // Initialize game engine pbj::Engine engine; pbj::gfx::TextureFontText text(engine.getBuiltIns().getTextureFont(pbj::Id("TextureFont.default")), "ABCDEFG"); pbj::mat4 transform = glm::ortho(0.0f, 320.0f, -120.0f, 120.0f); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); while (true) { glfwPollEvents(); pbj::Window* wnd = engine.getWindow(); if (!wnd || wnd->isClosePending()) break; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); text.draw(transform); glfwSwapBuffers(wnd->getGlfwHandle()); GLenum gl_error; while ((gl_error = glGetError()) != GL_NO_ERROR) { PBJ_LOG(pbj::VWarning) << "OpenGL error while rendering frame!" << PBJ_LOG_NL << "Error Code: " << gl_error << PBJ_LOG_NL << " Error: " << pbj::getGlErrorString(gl_error) << PBJ_LOG_END; } } };
/////////////////////////////////////////////////////////////////////////////// /// \brief Scans the provided directory path for files with the extension /// ".sw", then tries to see if they are sandwiches. /// /// \details Any sandwiches found will have their Ids added to an internal /// structure and will henceforth be accessible through open() or /// openWritable(). void readDirectory(const std::string& path) { dirent *ent; DIR* dir = opendir(path.c_str()); if (dir != NULL) { while ((ent = readdir(dir)) != NULL) { switch (ent->d_type) { case DT_REG: { std::string fullpath = path + ent->d_name; std::string extension = fullpath.substr(fullpath.length() - 3, 3); std::transform(extension.begin(), extension.end(), extension.begin(), tolower); if (extension == ".sw") // SW for sandwich (i.e. PB & J Sandwich) { try { Sandwich sw(fullpath, true); Id swid = sw.getId(); if (swid == Id()) throw std::runtime_error("Sandwich has no Id!"); SandwichInfo swi; swi.path = fullpath; sandwiches[swid] = swi; } catch (const db::Db::error& e) { PBJ_LOG(VWarning) << "Database error while opening sandwich!" << PBJ_LOG_NL << " Path: " << fullpath << PBJ_LOG_NL << "Exception: " << e.what() << PBJ_LOG_NL << " SQL: " << e.sql() << PBJ_LOG_END; } catch (const std::exception& e) { PBJ_LOG(VWarning) << "Exception while opening sandwich!" << PBJ_LOG_NL << " Path: " << fullpath << PBJ_LOG_NL << "Exception: " << e.what() << PBJ_LOG_END; } } break; } default: //non-file break; } } closedir(dir); } else { /* Could not open directory */ PBJ_LOG(VWarning) << "Could not open directory!" << PBJ_LOG_NL << "Path: " << path << PBJ_LOG_END; } }