mirror of https://github.com/sm64pc/sm64pc.git
[WIP - Textures] Changed preload system to load on the fly
This commit is contained in:
parent
1224f89d3a
commit
f13b32f363
|
@ -191,8 +191,8 @@ Vtx *make_skybox_rect(s32 tileIndex, s8 colorIndex) {
|
|||
s16 ty = ((tileIndex / SKYBOX_COLS) * h) % SKYBOX_IMAGE_SIZE;
|
||||
|
||||
if (verts != NULL) {
|
||||
make_vertex(verts, 0, x, y, -1, tx << 5, ty << 5, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], sSkyboxColors[colorIndex][2], 255);
|
||||
make_vertex(verts, 1, x, y - SKYBOX_TILE_HEIGHT, -1, tx << 5, (ty + w) << 5, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], sSkyboxColors[colorIndex][2], 255);
|
||||
make_vertex(verts, 0, x, y, -1, tx << 5, ty << 5, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], sSkyboxColors[colorIndex][2], 255);
|
||||
make_vertex(verts, 1, x, y - SKYBOX_TILE_HEIGHT, -1, tx << 5, (ty + w) << 5, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], sSkyboxColors[colorIndex][2], 255);
|
||||
make_vertex(verts, 2, x + tw, y - SKYBOX_TILE_HEIGHT, -1, (tx + w) << 5, (ty + h) << 5, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], sSkyboxColors[colorIndex][2], 255);
|
||||
make_vertex(verts, 3, x + tw, y, -1, (tx + w) << 5, ty << 5, sSkyboxColors[colorIndex][0], sSkyboxColors[colorIndex][1], sSkyboxColors[colorIndex][2], 255);
|
||||
}
|
||||
|
|
|
@ -15,21 +15,27 @@ using json = nlohmann::json;
|
|||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include <map>
|
||||
#include <chrono>
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb/stb_image.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
vector<BitModule*> addons;
|
||||
map<string, TextureData*> textureMap;
|
||||
|
||||
map<string, TextureFileEntry*> baseGameTextures;
|
||||
|
||||
map<string, TextureFileEntry*> textureCache;
|
||||
std::map<std::string, TextureFileEntry*> baseGameTextures;
|
||||
map<string, BitModule*> textureCache;
|
||||
|
||||
extern "C" {
|
||||
#include "moon/libs/lua/lualib.h"
|
||||
#include "moon/libs/lua/lauxlib.h"
|
||||
#include "moon/libs/lua/lua.h"
|
||||
#include "text/libs/io_utils.h"
|
||||
#include "pc/gfx/gfx_rendering_api.h"
|
||||
#include "pc/platform.h"
|
||||
#include "pc/fs/fs.h"
|
||||
}
|
||||
|
||||
void Moon_LoadDefaultAddon(){
|
||||
|
@ -59,6 +65,7 @@ void Moon_LoadAddon(string path){
|
|||
bit->website = j["bit"]["website"];
|
||||
bit->icon = j["bit"]["icon"];
|
||||
bit->main = j["bit"]["main"];
|
||||
bit->path = path;
|
||||
bit->readOnly = false;
|
||||
|
||||
if(file.has_file(bit->main)){
|
||||
|
@ -68,9 +75,7 @@ void Moon_LoadAddon(string path){
|
|||
if(file.has_file(bit->icon)){
|
||||
vector<string> allowedTextures = {"png", "jpg", "jpeg"};
|
||||
if(std::count(allowedTextures.begin(), allowedTextures.end(), string(get_filename_ext(bit->icon.c_str())))){
|
||||
TextureFileEntry *entry = new TextureFileEntry();
|
||||
file.read_texture(bit->icon, &entry);
|
||||
bit->textures.insert(pair<string, TextureFileEntry*>("mod-icons://"+bit->name, entry));
|
||||
bit->textures.insert(pair<string, TextureFileEntry*>("mod-icons://"+bit->name, new TextureFileEntry({.path = bit->icon})));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,6 +89,7 @@ void Moon_LoadAddon(string path){
|
|||
if(std::count(allowedTextures.begin(), allowedTextures.end(), string(get_filename_ext(name.c_str())))){
|
||||
string texName = name.substr(graphicsPath.length());
|
||||
string rawname = texName.substr(0, texName.find_last_of("."));
|
||||
|
||||
TextureFileEntry *entry = new TextureFileEntry();
|
||||
file.read_texture(name, &entry);
|
||||
bit->textures.insert(pair<string, TextureFileEntry*>(rawname, entry));
|
||||
|
@ -105,35 +111,83 @@ void Moon_LoadAddon(string path){
|
|||
}
|
||||
}
|
||||
|
||||
void Moon_BakeTextureCache(){
|
||||
textureMap.clear();
|
||||
void Moon_BakeTextureCache(vector<int> order){
|
||||
textureCache.clear();
|
||||
|
||||
for(auto &addon : addons){
|
||||
// BitModule *addon = addons[order[i]];
|
||||
for(int i=0; i < order.size(); i++){
|
||||
BitModule *addon = addons[order[i]];
|
||||
|
||||
for (map<string, TextureFileEntry*>::iterator entry = addon->textures.begin(); entry != addon->textures.end(); ++entry) {
|
||||
map<string, TextureFileEntry*>::iterator texIt = textureCache.find(entry->first);
|
||||
auto texIt = textureCache.find(entry->first);
|
||||
if(texIt != textureCache.end()) textureCache.erase(texIt);
|
||||
|
||||
TextureFileEntry* texEntry = entry->second;
|
||||
if(texEntry->data != nullptr)
|
||||
textureCache.insert(pair<string, TextureFileEntry*>(entry->first, texEntry));
|
||||
textureCache.insert(pair<string, BitModule*>(entry->first, addon));
|
||||
}
|
||||
}
|
||||
|
||||
//for(auto &addon: addons){
|
||||
//}
|
||||
textureMap.clear();
|
||||
}
|
||||
|
||||
void Moon_UploadCacheToGPU(){
|
||||
for (map<string, TextureFileEntry*>::iterator entry = textureCache.begin(); entry != textureCache.end(); ++entry) {
|
||||
TextureFileEntry* texEntry = entry->second;
|
||||
if(texEntry->data != nullptr) {
|
||||
overload_memory_texture(texEntry->data, texEntry->size, entry->first.c_str());
|
||||
// free(entry->second);
|
||||
TextureFileEntry *Moon_getTextureData(const char *fullpath){
|
||||
char texname[SYS_MAX_PATH];
|
||||
strncpy(texname, fullpath, sizeof(texname));
|
||||
texname[sizeof(texname)-1] = 0;
|
||||
char *dot = strrchr(texname, '.');
|
||||
if (dot) *dot = 0;
|
||||
|
||||
char *actualname = texname;
|
||||
if (!strncmp(FS_TEXTUREDIR "/", actualname, 4)) actualname += 4;
|
||||
actualname = sys_strdup(actualname);
|
||||
assert(actualname);
|
||||
|
||||
auto cacheEntry = textureCache.find(actualname);
|
||||
BitModule *addon = cacheEntry->second;
|
||||
|
||||
TextureFileEntry * data = NULL;
|
||||
|
||||
if(addon != NULL){
|
||||
TextureFileEntry *fileEntry = addon->textures.find(actualname)->second;
|
||||
|
||||
if(fileEntry != NULL){
|
||||
if(fileEntry->data != NULL) data = fileEntry;
|
||||
else if(!fileEntry->path.empty()){
|
||||
miniz_cpp::zip_file file(addon->path);
|
||||
TextureFileEntry *newData = new TextureFileEntry();
|
||||
file.read_texture(fileEntry->path, &newData);
|
||||
data = newData;
|
||||
}
|
||||
}
|
||||
}
|
||||
textureCache.clear();
|
||||
return data;
|
||||
}
|
||||
|
||||
void Moon_LoadTexture(int tile, const char *fullpath, struct GfxRenderingAPI *gfx_rapi){
|
||||
|
||||
int w, h;
|
||||
u64 imgsize = 0;
|
||||
|
||||
TextureFileEntry * imgdata = Moon_getTextureData(fullpath);
|
||||
if (imgdata) {
|
||||
u8 *data = stbi_load_from_memory(reinterpret_cast<const stbi_uc *>(imgdata->data), imgdata->size, &w, &h, NULL, 4);
|
||||
if (data) {
|
||||
gfx_rapi->upload_texture(data, w, h);
|
||||
stbi_image_free(data);
|
||||
return;
|
||||
} else {
|
||||
cout << "Failed to convert texture" << endl;
|
||||
std::cout << stbi_failure_reason() << std::endl;
|
||||
}
|
||||
} else {
|
||||
cout << "Failed to load texture" << endl;
|
||||
}
|
||||
|
||||
int missingW = 2;
|
||||
int missingH = 2;
|
||||
vector<uint8_t> missingTexture = {
|
||||
0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0x00, 0x00,
|
||||
};
|
||||
|
||||
gfx_rapi->upload_texture(missingTexture.data(), missingW, missingH);
|
||||
}
|
||||
|
||||
void Moon_ScanAddonsDirectory( char *exePath, char *gamedir ){
|
||||
|
@ -142,7 +196,6 @@ void Moon_ScanAddonsDirectory( char *exePath, char *gamedir ){
|
|||
string languages_dir = l_path.substr(0, l_path.find_last_of("/\\")) + "/addons/";
|
||||
printf("Loading Directory: %s\n", languages_dir.c_str());
|
||||
|
||||
// Scan directory for JSON files
|
||||
DIR *dir = opendir(languages_dir.c_str());
|
||||
if (dir) {
|
||||
struct dirent *de;
|
||||
|
@ -164,7 +217,7 @@ void Moon_SaveTexture(TextureData* data, string tex){
|
|||
|
||||
void Moon_LoadBaseTexture(char* data, long size, string texture){
|
||||
if(baseGameTextures.find(texture) == baseGameTextures.end()){
|
||||
baseGameTextures.insert(pair<string, TextureFileEntry*>(texture, new TextureFileEntry({.size = size, .data = data})));
|
||||
baseGameTextures.insert(pair<string, TextureFileEntry*>(texture, new TextureFileEntry({.path = "", .size = size, .data = data})));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,32 +226,7 @@ TextureData* Moon_GetTexture(string texture){
|
|||
}
|
||||
|
||||
void Moon_TextFlyLoad(int id){
|
||||
switch(id){
|
||||
case 0:
|
||||
Moon_LoadDefaultAddon();
|
||||
break;
|
||||
case 1:
|
||||
Moon_LoadDefaultAddon();
|
||||
Moon_LoadAddon("/home/alex/Downloads/packs/converted/mc.bit");
|
||||
|
||||
Moon_LoadAddon("/home/alex/Downloads/packs/converted/beta-hud.bit");
|
||||
Moon_LoadAddon("/home/alex/Downloads/packs/converted/moon64-demo.bit");
|
||||
break;
|
||||
case 2:
|
||||
Moon_LoadDefaultAddon();
|
||||
Moon_LoadAddon("/home/alex/Downloads/packs/converted/owo.bit");
|
||||
|
||||
Moon_LoadAddon("/home/alex/Downloads/packs/converted/beta-hud.bit");
|
||||
Moon_LoadAddon("/home/alex/Downloads/packs/converted/moon64-demo.bit");
|
||||
break;
|
||||
case 3:
|
||||
Moon_LoadDefaultAddon();
|
||||
Moon_LoadAddon("/home/alex/Downloads/packs/converted/r96-hd.bit");
|
||||
|
||||
Moon_LoadAddon("/home/alex/Downloads/packs/converted/beta-hud.bit");
|
||||
Moon_LoadAddon("/home/alex/Downloads/packs/converted/moon64-demo.bit");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Moon_PreInitModEngine(){
|
||||
|
@ -206,11 +234,19 @@ void Moon_PreInitModEngine(){
|
|||
}
|
||||
|
||||
void Moon_TestRebuildOrder(vector<int> order){
|
||||
|
||||
Moon_BakeTextureCache(order);
|
||||
}
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
void Moon_InitModEngine( char *exePath, char *gamedir ){
|
||||
Moon_ScanAddonsDirectory(exePath, gamedir);
|
||||
Moon_BakeTextureCache();
|
||||
Moon_UploadCacheToGPU();
|
||||
|
||||
milliseconds start_ms = duration_cast< milliseconds >( system_clock::now().time_since_epoch() );
|
||||
Moon_LoadAddon("/home/alex/Music/Moon64-Packs/converted/minecraft.bit");
|
||||
Moon_LoadAddon("/home/alex/Music/Moon64-Packs/converted/beta-hud.bit");
|
||||
Moon_LoadAddon("/home/alex/disks/uwu/Projects/UnderVolt/Moon64-Packs/converted/owo.bit");
|
||||
Moon_BakeTextureCache({1, 0, 2, 3});
|
||||
milliseconds end_ms = duration_cast< milliseconds >( system_clock::now().time_since_epoch() );
|
||||
|
||||
std::cout << "Finised loading in " << ((end_ms.count() - start_ms.count()) / 1000) << " seconds" << std::endl;
|
||||
}
|
|
@ -21,5 +21,6 @@ void Moon_LoadBaseTexture(char* data, long size, std::string texture);
|
|||
// TESTS
|
||||
void Moon_TextFlyLoad(int id);
|
||||
void Moon_TestRebuildOrder(std::vector<int> order);
|
||||
void Moon_LoadTexture(int tile, const char *fullpath, struct GfxRenderingAPI *gfx_rapi);
|
||||
|
||||
#endif
|
|
@ -6,6 +6,8 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class zip_file;
|
||||
|
||||
extern "C" {
|
||||
#include "pc/gfx/gfx_pc.h"
|
||||
}
|
||||
|
@ -18,8 +20,8 @@ public:
|
|||
std::string website;
|
||||
std::string icon;
|
||||
std::string main;
|
||||
std::string path;
|
||||
std::map<std::string, TextureFileEntry*> textures;
|
||||
// GFXTextureCache* textureCache;
|
||||
bool readOnly;
|
||||
bool enabled;
|
||||
};
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#ifndef Moon64FileEntry
|
||||
#define Moon64FileEntry
|
||||
#include <string>
|
||||
|
||||
struct TextureFileEntry {
|
||||
std::string path;
|
||||
long size;
|
||||
char* data;
|
||||
};
|
||||
|
|
|
@ -102,4 +102,8 @@ void moon_load_base_texture(char* data, long size, char* texture){
|
|||
Moon_LoadBaseTexture(data, size, string(texture));
|
||||
}
|
||||
|
||||
void moon_load_texture(int tile, const char *fullpath, struct GfxRenderingAPI *gfx_rapi){
|
||||
Moon_LoadTexture(tile, fullpath, gfx_rapi);
|
||||
}
|
||||
|
||||
}
|
|
@ -26,6 +26,7 @@ void moon_engine_save_texture(struct TextureData* data, char* tex);
|
|||
struct TextureData* moon_engine_get_texture(char* tex);
|
||||
struct TextureData* moon_engine_init_texture();
|
||||
void moon_load_base_texture(char* data, long size, char* texture);
|
||||
void moon_load_texture(int tile, const char *fullpath, struct GfxRenderingAPI *gfx_rapi);
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -12,9 +12,7 @@ extern "C" {
|
|||
#include "pc/configfile.h"
|
||||
}
|
||||
|
||||
std::vector<int> order = {
|
||||
0, 2, 1
|
||||
};
|
||||
std::vector<int> order = {1, 0, 2, 3};
|
||||
|
||||
MWValue *tmpButton;
|
||||
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb/stb_image.h>
|
||||
|
||||
#ifndef _LANGUAGE_C
|
||||
#define _LANGUAGE_C
|
||||
#endif
|
||||
|
@ -278,7 +275,7 @@ static bool gfx_texture_cache_lookup(int tile, struct TextureData **n, const uin
|
|||
node->fmt = fmt;
|
||||
node->siz = siz;
|
||||
moon_engine_save_texture(node, orig_addr);
|
||||
|
||||
if(n != NULL) *n = node;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -304,27 +301,6 @@ static bool preload_base_texture(void* user, const char *fullpath) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline void load_texture(const char *fullpath) {
|
||||
int w, h;
|
||||
u64 imgsize = 0;
|
||||
|
||||
u8 *imgdata = fs_load_file(fullpath, &imgsize);
|
||||
if (imgdata) {
|
||||
// TODO: implement stbi_callbacks or some shit instead of loading the whole texture
|
||||
u8 *data = stbi_load_from_memory(imgdata, imgsize, &w, &h, NULL, 4);
|
||||
free(imgdata);
|
||||
if (data) {
|
||||
gfx_rapi->upload_texture(data, w, h);
|
||||
stbi_image_free(data); // don't need this anymore
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "could not load texture: `%s`\n", fullpath);
|
||||
// replace with missing texture
|
||||
gfx_rapi->upload_texture(missing_texture, MISSING_W, MISSING_H);
|
||||
}
|
||||
|
||||
static inline void load_memory_texture(void *imgdata, long size) {
|
||||
int w, h;
|
||||
|
||||
|
@ -417,7 +393,7 @@ static void import_texture(int tile) {
|
|||
// load it from an external image in our data path
|
||||
char texname[SYS_MAX_PATH];
|
||||
snprintf(texname, sizeof(texname), FS_TEXTUREDIR "/%s.png", (const char*)rdp.loaded_texture[tile].addr);
|
||||
load_texture(texname);
|
||||
moon_load_texture(tile, texname, gfx_rapi);
|
||||
}
|
||||
|
||||
static void gfx_normalize_vector(float v[3]) {
|
||||
|
|
Loading…
Reference in New Issue