/** * Copyright (c) 2021 Dominic Msters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "asset.h" char * assetStringLoad(char *assetName) { // Open a buffer. assetbuffer_t *fptr = assetBufferOpen(assetName); if(fptr == NULL) return NULL; // Read the count of bytes in the file fseek(fptr, 0, SEEK_END);// Seek to the end size_t length = ftell(fptr);// Get our current position (the end) fseek(fptr, 0, SEEK_SET);// Reset the seek // Create the string buffer char *str = malloc(length + 1);// Add 1 for the null terminator. if(str == NULL) { assetBufferClose(fptr); return NULL; } // Read and seal the string. fread(str, 1, length, fptr);// Read all the bytes str[length] = '\0';// Null terminate. assetBufferClose(fptr); // Close the buffer. return str; } assetbuffer_t * assetBufferOpen(char *assetName) { // Get the directory based on the raw input by creating a new string. size_t lenAsset = strlen(assetName);// Get the length of asset size_t lenPrefix = strlen(ASSET_PREFIX);// Get the length of the prefix // Create str to house both the prefix and asset, and null terminator char *joined = malloc(lenAsset + lenPrefix + 1); if(joined == NULL) return NULL;// Mem okay? joined[0] = '\0';//Start at null strcat(joined, ASSET_PREFIX);//Add prefix strcat(joined, assetName);//Add body // Open the file pointer now. FILE *fptr = fopen(joined, "rb"); free(joined);// Free the string we just created if(!fptr) return NULL;// File available? return (assetbuffer_t *)fptr; } bool assetBufferClose(assetbuffer_t *buffer) { return fclose((FILE *)buffer); } int32_t assetBufferRead(assetbuffer_t *buffer, char *data, int32_t size) { return (int32_t)fread(data, 1, size, (FILE *)buffer); } int32_t assetBufferEnd(assetbuffer_t *buffer) { return feof((FILE *)buffer); } int32_t assetBufferStart(assetbuffer_t *buffer) { return fseek((FILE *)buffer, 0, SEEK_SET); } int32_t assetBufferSkip(assetbuffer_t *buffer, int32_t n) { return fseek((FILE *)buffer, n, SEEK_CUR); } void assetShaderLoad(shader_t *shader, char *fileVertex, char *fileFragment) { // Load the vertex shader into memory char *vertexShader = assetStringLoad(fileVertex); if(vertexShader == NULL) return; // Load the fragment shader into memory char *fragmentShader = assetStringLoad(fileFragment); if(fragmentShader == NULL) { free(vertexShader); return; } // Now attempt to load the shader shaderInit(shader, vertexShader, fragmentShader); //Cleanup free(vertexShader); free(fragmentShader); } void assetTextureLoad(texture_t *texture, char *fileName) { assetbuffer_t *buffer; int channels, width, height; pixel_t *data; stbi_io_callbacks OPENGL_STBI_CALLBACKS; buffer = assetBufferOpen(fileName); if(buffer == NULL) return; // Setup the interface for STBI OPENGL_STBI_CALLBACKS.read = &assetBufferRead; OPENGL_STBI_CALLBACKS.skip = &assetBufferSkip; OPENGL_STBI_CALLBACKS.eof = &assetBufferEnd; // Buffer the image channels = 0; data = (pixel_t *)stbi_load_from_callbacks( &OPENGL_STBI_CALLBACKS, buffer, &width, &height, &channels, STBI_rgb_alpha ); // Close the buffer assetBufferClose(buffer); if(data == NULL) return; // Turn into a texture. textureInit(texture, width, height, data); stbi_image_free(data); } void assetFontLoad(font_t *font, char *assetName) { char *data = assetStringLoad(assetName); fontInit(font, data); free(data); }