Example #1
0
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());
				}
			}
		}
	}
}
Example #3
0
    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;
    }