Sprite::Sprite(const std::shared_ptr<zeug::window> &base_window, std::string sprite_path, std::int32_t id) : base_window(base_window), id(id), frame_number(0) { // load zip/apk archive auto pakpath = [] () { if (zeug::this_app::apkpath() == "Unknown") { return zeug::this_app::name() + ".pak"; } else { return zeug::this_app::apkpath(); } }; zeug::zipreader pakfile(pakpath()); // parse json descs { std::string error; auto json_object = json11::Json::parse(pakfile.text_file(sprite_path + "/" + "idle.json"), error); if (!error.empty()) { std::runtime_error(error.c_str()); } this->json_objects.push_back(json_object); } { std::string error; auto json_object = json11::Json::parse(pakfile.text_file(sprite_path + "/" + "walk.json"), error); if (!error.empty()) { std::runtime_error(error.c_str()); } this->json_objects.push_back(json_object); } auto vertexshader_string = R"( #version 100 #ifdef GL_FRAGMENT_PRECISION_HIGH varying highp vec2 vertTexCoord; #else varying mediump vec2 vertTexCoord; #endif uniform mat4 ProjectionMatrix; attribute vec2 Position; attribute vec2 TexCoord; void main(void) { vertTexCoord = TexCoord; gl_Position = ProjectionMatrix * vec4( Position, 0.0, 1.0 ); } )"; auto fragmentshader_string = R"( #version 100 #ifdef GL_FRAGMENT_PRECISION_HIGH precision highp float; #else precision mediump float; #endif uniform sampler2D TexUnit; varying vec2 vertTexCoord; void main(void) { gl_FragColor = texture2D( TexUnit, vertTexCoord ); } )"; this->shaderprog = std::make_unique<zeug::opengl::program>(); this->shaderprog.get()->attach(std::make_unique<zeug::opengl::shader>(vertexshader_string, GL_VERTEX_SHADER)); this->shaderprog.get()->attach(std::make_unique<zeug::opengl::shader>(fragmentshader_string, GL_FRAGMENT_SHADER)); this->shaderprog.get()->link(); this->position_attrib= glGetAttribLocation(shaderprog->native_handle(), "Position"); this->texcoord_attrib= glGetAttribLocation(shaderprog->native_handle(), "TexCoord"); this->texunit_uniform = glGetUniformLocation(this->shaderprog.get()->native_handle(), "TexUnit"); this->proj_uniform = glGetUniformLocation(shaderprog->native_handle(), "ProjectionMatrix"); auto width = float(this->base_window->width()); auto aspect = float(this->base_window->width() / this->base_window->height()); auto near = 1.0f; auto far = -1.0f; auto right = width / 2.0f; auto left = -right; auto bottom = left / aspect; auto top = right / aspect; auto a = 2.0f / (right - left); auto b = 2.0f / (top - bottom); auto c = -2.0f / (far - near); auto tx = - (right + left)/(right - left); auto ty = - (top + bottom)/(top - bottom); auto tz = - (far + near)/(far - near); this->ortho_projection = {{ a, 0.0f, 0.0f, 0.0f, 0.0f, b, 0.0f, 0.0f, 0.0f, 0.0f, c, 0.0f, tx, ty, tz, 1.0f }}; for( std::uint32_t i=0; i < this->json_objects.size(); i++) { auto name = json11::Json(this->json_objects.at(i))["meta"]["image"].string_value(); // Texturepacker creates a nice unique id for us auto uid = json11::Json(this->json_objects.at(i))["meta"]["smartupdate"].string_value(); uid.erase (1,26); auto w =json11::Json(this->json_objects.at(i))["meta"]["size"]["w"].int_value(); auto h = json11::Json(this->json_objects.at(i))["meta"]["size"]["h"].int_value(); auto texture = std::make_unique<zeug::opengl::texture>(uid, pakfile.file(sprite_path + "/" + name), std::make_pair(w, h)); texture_slots.push_back(texture->native_slot()); textures.push_back(std::move(texture)); } }
void ResourceListBuilder::BuildPakResourceList(const std::string &pakfilename) { // open the pak file in binary read mode File pakfile(pakfilename, "rb"); if (pakfile == NULL) { // error opening pakfile! printf("Could not find pakfile \"%s\".\n", pakfilename.c_str()); return; } // Check a pakfile for resources // get the header size_t pakheadersize = sizeof(pakheader_s); pakheader_s pakheader; size_t retval = fread(&pakheader, 1, pakheadersize, pakfile); if (retval != pakheadersize) { // unexpected size. if (verbal) { printf("Reading pakfile header failed. Wrong size (" SIZE_T_SPECIFIER " read, " SIZE_T_SPECIFIER " expected).\n", retval, pakheadersize); printf("Is \"%s\" a valid pakfile?\n", pakfilename.c_str()); } return; } // verify pak identity if (pakheader.pakid != 1262698832) { if (verbal) { printf("Pakfile \"%s\" does not appear to be a Half-Life pakfile (ID mismatch).\n", pakfilename.c_str()); } return; } // count the number of files in the pak size_t fileinfosize = sizeof(fileinfo_s); size_t filecount = pakheader.dirsize / fileinfosize; // re-verify integrity of header if (pakheader.dirsize % fileinfosize != 0 || filecount == 0) { if (verbal) { printf("Pakfile \"%s\" does not appear to be a Half-Life pakfile (invalid dirsize).\n", pakfilename.c_str()); } return; } // load file list to memory if(fseek(pakfile, pakheader.diroffset, SEEK_SET)) { if (verbal) { printf("Error seeking for file list.\nPakfile \"%s\" is not a pakfile, or is corrupted.\n", pakfilename.c_str()); } return; } std::vector<fileinfo_s> filelist(filecount); retval = fread(filelist.data(), 1, pakheader.dirsize, pakfile); if (retval != pakheader.dirsize) { if (verbal) { printf("Error seeking for file list.\nPakfile \"%s\" is not a pakfile, or is corrupted.\n", pakfilename.c_str()); } return; } if (verbal) { printf("Scanning pak file \"%s\" for resources (" SIZE_T_SPECIFIER " files in pak)\n", pakfilename.c_str(), filecount); } // Read filelist for possible resources for (size_t i = 0; i < filecount; i++) { const std::string fileLower = strToLowerCopy(filelist[i].name); const size_t dotIndex = fileLower.find_last_of('.'); if(dotIndex != std::string::npos) { const std::string extension = fileLower.substr(dotIndex + 1); if ( extension == "mdl" || extension == "wav" || extension == "spr" || extension == "bmp" || extension == "tga" || extension == "txt" || extension == "wad" ) { // resource, add to list std::string resStr = replaceCharAllCopy(filelist[i].name, '\\', '/'); resources[strToLowerCopy(resStr)] = resStr; if (resourcedisp) { printf("Added \"%s\" to resource list\n", resStr.c_str()); } } } } }
bool pak::bin( const std::string &bin_import ) //const { this->clear(); std::vector<pakfile> result; if( !bin_import.size() ) return true; // :) if( type == paktype::ZIP ) { // Try to open the archive. mz_zip_archive zip_archive; memset(&zip_archive, 0, sizeof(zip_archive)); mz_bool status = mz_zip_reader_init_mem( &zip_archive, (void *)bin_import.c_str(), bin_import.size(), 0 ); if( !status ) return "mz_zip_reader_init_file() failed!", false; // Get and print information about each file in the archive. for( unsigned int i = 0; i < mz_zip_reader_get_num_files(&zip_archive); i++ ) { mz_zip_archive_file_stat file_stat; if( !mz_zip_reader_file_stat( &zip_archive, i, &file_stat ) ) { mz_zip_reader_end( &zip_archive ); return "mz_zip_reader_file_stat() failed!", false; } result.push_back( pakfile() ); result.back()["filename"] = file_stat.m_filename; result.back()["comment"] = file_stat.m_comment; result.back()["size"] = (unsigned int)file_stat.m_uncomp_size; result.back()["size_z"] = (unsigned int)file_stat.m_comp_size; //result.back()["modify_time"] = ze.mtime; //result.back()["access_time"] = ze.atime; //result.back()["create_time"] = ze.ctime; //result.back()["attributes"] = ze.attr; if( const bool decode = true ) { // Try to extract file to the heap. size_t uncomp_size; void *p = mz_zip_reader_extract_file_to_heap(&zip_archive, file_stat.m_filename, &uncomp_size, 0); if( !p ) { mz_zip_reader_end(&zip_archive); return "mz_zip_reader_extract_file_to_heap() failed!", false; } // Make sure the extraction really succeeded. /* if ((uncomp_size != strlen(s_pStr)) || (memcmp(p, s_pStr, strlen(s_pStr)))) { free(p); mz_zip_reader_end(&zip_archive); return "mz_zip_reader_extract_file_to_heap() failed to extract the proper data", false; } */ result.back()["content"].resize( uncomp_size ); memcpy( (void *)result.back()["content"].data(), p, uncomp_size ); free(p); } } // We're done. mz_zip_reader_end(&zip_archive); } else {} this->resize( result.size() ); std::copy( result.begin(), result.end(), this->begin() ); return true; }