Merge remote-tracking branch 'origin/refactor/experimental' into experimental

This commit is contained in:
KiritoDv 2021-05-10 18:22:30 +00:00
parent c303911550
commit f242833526
27 changed files with 630 additions and 493 deletions

View File

@ -284,6 +284,9 @@ SRC_DIRS += src/moon/entity src/moon/entity/interfaces
# Moon64 SRC [Mod-Engine]
SRC_DIRS += src/moon/mod-engine src/moon/mod-engine/modules
# Moon64 SRC [Mod-Engine - Texture Module]
SRC_DIRS += src/moon/mod-engine/textures src/moon/mod-engine/textures/assets
# Moon64 LIB [RapidJSON]
SRC_DIRS += src/moon/libs/rapidjson src/moon/libs/rapidjson/error src/moon/libs/rapidjson/internal src/moon/libs/rapidjson/msinttypes
@ -296,6 +299,9 @@ SRC_DIRS += src/moon/libs/miniz
# Moon64 LIB [nlohmann json]
SRC_DIRS += src/moon/libs/nlohmann
# Moon64 LIB [Miniz-Wrapper]
SRC_DIRS += src/moon/zip
################################
ifeq ($(DISCORDRPC),1)

View File

@ -2,13 +2,25 @@
#include "moon/io/io-module.h"
#include "moon/io/modules/mouse-io.h"
vector<MIOModule*> modules;
using namespace std;
void InitIOModules(){
modules.push_back(new MouseIO());
for(auto &module : modules) module->init();
namespace Moon {
vector<MIOModule*> modules;
}
void UpdateIOModules(){
for(auto &module : modules) module->update();
namespace MoonInternal {
void setupIOModuleEngine( string state ){
if(state == "PreInit"){
Moon::modules.push_back(new MouseIO());
return;
}
if(state == "Init"){
for(auto &module : Moon::modules) module->init();
return;
}
if(state == "Update"){
for(auto &module : Moon::modules) module->update();
return;
}
}
}

View File

@ -1,22 +1,27 @@
#ifndef MoonIOManager
#define MoonIOManager
#include <iostream>
#include <vector>
#include "io-module.h"
using namespace std;
extern vector<MIOModule*> modules;
#include <iostream>
#include <vector>
#include <string>
void InitIOModules();
void UpdateIOModules();
template< typename T > T* GetIOModule() {
for(int id = 0; id < modules.size(); id++){
T* m = dynamic_cast<T*>(modules[id]);
if (m) return m;
namespace Moon {
extern std::vector<MIOModule*> modules;
template< typename T > T* GetIOModule() {
for(int id = 0; id < modules.size(); id++){
T* m = dynamic_cast<T*>(modules[id]);
if (m) return m;
}
return NULL;
}
return NULL;
}
namespace MoonInternal {
void setupIOModuleEngine( std::string state );
}
#endif

View File

@ -5457,7 +5457,7 @@ class zip_file
return extracted;
}
void read_texture(const zip_info &info, TextureFileEntry** entry) {
void _read_texture(const zip_info &info, TextureFileEntry** entry) {
std::size_t size;
char *data = static_cast<char *>(mz_zip_reader_extract_file_to_heap(archive_.get(), info.filename.c_str(), &size, 0));
if(data == nullptr)
@ -5469,7 +5469,7 @@ class zip_file
}
void read_texture(const std::string &name, TextureFileEntry** entry){
read_texture(getinfo(name), entry);
_read_texture(getinfo(name), entry);
}
std::string read(const std::string &name)

View File

@ -1,246 +1,124 @@
#include "engine.h"
#include "moon/mod-engine/interfaces/mod-module.h"
#include "moon/mod-engine/modules/test-module.h"
#include "interfaces/file-entry.h"
#include "moon/wrapper.h"
#include "moon/utils/moon-env.h"
#include "interfaces/file-entry.h"
#include "textures/mod-texture.h"
#include "moon/zip/straw.h"
#include "moon/libs/nlohmann/json.hpp"
using json = nlohmann::json;
using namespace std;
#include <iostream>
#include <string>
#include <unistd.h>
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <dirent.h>
#include <map>
#include <chrono>
#include "missing.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>
using namespace std;
vector<BitModule*> addons;
map<string, TextureData*> textureMap;
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(){
BitModule* bit = new BitModule();
bit->name = "Moon64";
bit->description = "SM64 Original Textures";
bit->author = "Nintendo";
bit->version = 1.0f;
bit->readOnly = true;
bit->textures = baseGameTextures;
addons.push_back(bit);
}
namespace Moon {
void Moon_LoadAddon(string path){
miniz_cpp::zip_file file(path);
vector<BitModule*> addons;
if(file.has_file("properties.json")){
string tjson = file.read("properties.json");
void loadAddon(string addonPath){
StrawFile file(addonPath);
json j = json::parse(tjson);
if(j.contains("bit") && j["bit"].contains("name")){
BitModule* bit = new BitModule();
bit->name = j["bit"]["name"];
bit->description = j["bit"]["description"];
bit->author = j["bit"]["author"];
bit->version = j["bit"]["version"];
bit->website = j["bit"]["website"];
bit->icon = j["bit"]["icon"];
bit->main = j["bit"]["main"];
bit->path = path;
bit->readOnly = false;
cout << "Loading addon: " << addonPath << endl;
if(file.has_file(bit->main)){
std::cout << file.read(bit->main) << std::endl;
}
if(file.exists("properties.json")){
string tjson = file.read("properties.json");
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())))){
bit->textures.insert(pair<string, TextureFileEntry*>("mod-icons://"+bit->name, new TextureFileEntry({.path = bit->icon})));
json j = json::parse(tjson);
if(j.contains("bit") && j["bit"].contains("name")){
BitModule* bit = new BitModule();
bit->name = j["bit"]["name"];
bit->description = j["bit"]["description"];
bit->author = j["bit"]["author"];
bit->version = j["bit"]["version"];
bit->website = j["bit"]["website"];
bit->icon = j["bit"]["icon"];
bit->main = j["bit"]["main"];
bit->path = addonPath;
bit->readOnly = false;
if(file.exists(bit->main)){
std::cout << file.read(bit->main) << std::endl;
}
}
if(file.has_file("assets/")){
for(auto &name : file.namelist()){
string graphicsPath = "assets/graphics/";
string textsPath = "assets/texts/";
if(!name.rfind(graphicsPath, 0)){
vector<string> allowedTextures = {"png", "jpg", "jpeg"};
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));
}
if(file.exists(bit->icon)){
vector<string> allowedTextures = {"png", "jpg", "jpeg"};
if(std::count(allowedTextures.begin(), allowedTextures.end(), string(get_filename_ext(bit->icon.c_str())))){
Moon::saveAddonTexture(bit, "mod-icons://"+bit->name, new TextureFileEntry({.path = bit->icon}));
}
if(!name.rfind(textsPath, 0)){
if(!string(get_filename_ext(name.c_str())).compare("json")){
// std::cout << name << std::endl;
}
if(file.exists("assets/")){
for(auto &name : file.entries()){
string graphicsPath = "assets/graphics/";
string textsPath = "assets/texts/";
if(!name.rfind(graphicsPath, 0)){
vector<string> allowedTextures = {"png", "jpg", "jpeg"};
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(name, entry);
Moon::saveAddonTexture(bit, rawname, entry);
}
}
if(!name.rfind(textsPath, 0)){
if(!string(get_filename_ext(name.c_str())).compare("json")){
// std::cout << name << std::endl;
}
}
}
}
addons.push_back(bit);
}
addons.push_back(bit);
}
} else {
std::cout << "Failed to load addon: [" << file.get_filename() << "]" << std::endl;
std::cout << "Missing properties.json" << std::endl;
}
}
void Moon_BakeTextureCache(vector<int> order){
textureCache.clear();
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) {
auto texIt = textureCache.find(entry->first);
if(texIt != textureCache.end()) textureCache.erase(texIt);
textureCache.insert(pair<string, BitModule*>(entry->first, addon));
}
}
textureMap.clear();
}
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;
}
}
}
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;
std::cout << "Failed to load addon: [" << file.getPath() << "]" << std::endl;
std::cout << "Missing properties.json" << std::endl;
}
} else {
cout << "Failed to load texture" << endl;
}
gfx_rapi->upload_texture(missing_image.pixel_data, missing_image.width, missing_image.height);
}
void Moon_ScanAddonsDirectory( char *exePath, char *gamedir ){
string l_path(exePath);
namespace MoonInternal {
void scanAddonsDirectory() {
string cwd = MoonInternal::getEnvironmentVar("MOON_CWD");
string addonsDir = cwd.substr(0, cwd.find_last_of("/\\")) + "/addons/";
string languages_dir = l_path.substr(0, l_path.find_last_of("/\\")) + "/addons/";
printf("Loading Directory: %s\n", languages_dir.c_str());
DIR *dir = opendir(languages_dir.c_str());
if (dir) {
struct dirent *de;
while ((de = readdir(dir)) != NULL) {
string extension = string(get_filename_ext(de->d_name));
if (extension.compare("bit") == 0) {
string file = languages_dir + de->d_name;
printf("Loading Addon: %s\n", file.c_str());
Moon_LoadAddon(file);
DIR *dir = opendir(addonsDir.c_str());
if (dir) {
struct dirent *de;
while ((de = readdir(dir)) != NULL) {
string extension = string(get_filename_ext(de->d_name));
if (extension.compare("bit") == 0) {
string file = addonsDir + de->d_name;
Moon::loadAddon(file);
}
}
closedir(dir);
}
closedir(dir);
}
}
void Moon_SaveTexture(TextureData* data, string tex){
textureMap.insert(pair<string, TextureData*>(tex, data));
}
void Moon_LoadBaseTexture(char* data, long size, string texture){
if(baseGameTextures.find(texture) == baseGameTextures.end()){
baseGameTextures.insert(pair<string, TextureFileEntry*>(texture, new TextureFileEntry({.path = "", .size = size, .data = data})));
void setupModEngine( string state ){
if(state == "PreInit"){
MoonInternal::buildDefaultAddon();
return;
}
if(state == "Init"){
MoonInternal::scanAddonsDirectory();
vector<int> order;
for(int i = 0; i < Moon::addons.size(); i++) order.push_back(i);
MoonInternal::buildTextureCache(order);
return;
}
}
}
TextureData* Moon_GetTexture(string texture){
return textureMap.find(texture) != textureMap.end() ? textureMap.find(texture)->second : nullptr;
}
void Moon_TextFlyLoad(int id){
}
void Moon_PreInitModEngine(){
Moon_LoadDefaultAddon();
}
void Moon_TestRebuildOrder(vector<int> order){
Moon_BakeTextureCache(order);
}
using namespace std::chrono;
void Moon_InitModEngine( char *exePath, char *gamedir ){
milliseconds start_ms = duration_cast< milliseconds >( system_clock::now().time_since_epoch() );
Moon_ScanAddonsDirectory( exePath, gamedir );
vector<int> order;
for(int i = 0; i < addons.size(); i++) order.push_back(i);
Moon_BakeTextureCache(order);
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;
}

View File

@ -3,24 +3,19 @@
#include "moon/mod-engine/interfaces/bit-module.h"
#include <vector>
#include <string>
extern "C" {
#include "pc/gfx/gfx_pc.h"
}
namespace Moon {
extern std::vector<BitModule*> addons;
void loadAddon(std::string addonPath);
}
extern std::vector<BitModule*> addons;
namespace MoonInternal {
void setupModEngine( std::string state );
}
void Moon_SaveTexture(TextureData* data, std::string tex);
TextureData* Moon_GetTexture(std::string texture);
void Moon_PreInitModEngine();
void Moon_InitModEngine( char *exePath, char *gamedir );
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

View File

@ -0,0 +1,135 @@
#include "mod-texture.h"
#include "moon/zip/straw.h"
#include "moon/libs/nlohmann/json.hpp"
#include "moon/mod-engine/engine.h"
#include "assets/missing.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>
extern "C" {
#include "text/libs/io_utils.h"
#include "pc/gfx/gfx_rendering_api.h"
#include "pc/platform.h"
#include "pc/fs/fs.h"
}
#include <iostream>
#include <vector>
#include <map>
using namespace std;
using json = nlohmann::json;
std::map<std::string, TextureFileEntry*> baseGameTextures;
map<string, TextureData*> textureMap;
map<string, BitModule*> textureCache;
namespace Moon {
void saveAddonTexture(BitModule *addon, std::string texturePath, TextureFileEntry* data){
addon->textures.insert(pair<string, TextureFileEntry*>(texturePath, data));
}
void precacheBaseTexture(char* data, long size, std::string texturePath){
if(baseGameTextures.find(texturePath) == baseGameTextures.end())
baseGameTextures.insert(pair<string, TextureFileEntry*>(
texturePath,
new TextureFileEntry({.path = "", .size = size, .data = data}))
);
}
TextureData *getCachedTexture(string texturePath){
return textureMap.find(texturePath) != textureMap.end() ? textureMap.find(texturePath)->second : nullptr;
}
}
namespace MoonInternal {
TextureFileEntry *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()){
StrawFile file(addon->path);
TextureFileEntry *newData = new TextureFileEntry();
file.read(fileEntry->path, newData);
data = newData;
}
}
}
return data;
}
void loadTexture(int tile, const char *fullpath, struct GfxRenderingAPI *gfx_rapi){
int w, h;
u64 imgsize = 0;
TextureFileEntry * imgdata = 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;
}
gfx_rapi->upload_texture(missing_image.pixel_data, missing_image.width, missing_image.height);
}
void saveTexture(TextureData *data, string texturePath){
textureMap.insert(pair<string, TextureData*>(texturePath, data));
}
void buildTextureCache(vector<int> order){
textureCache.clear();
for(int i=0; i < order.size(); i++){
BitModule *addon = Moon::addons[order[i]];
for (map<string, TextureFileEntry*>::iterator entry = addon->textures.begin(); entry != addon->textures.end(); ++entry) {
auto texIt = textureCache.find(entry->first);
if(texIt != textureCache.end()) textureCache.erase(texIt);
textureCache.insert(pair<string, BitModule*>(entry->first, addon));
}
}
textureMap.clear();
}
void buildDefaultAddon(){
BitModule* bit = new BitModule();
bit->name = "Moon64";
bit->description = "SM64 Original Textures";
bit->author = "Nintendo";
bit->version = 1.0f;
bit->readOnly = true;
bit->textures = baseGameTextures;
Moon::addons.push_back(bit);
}
}

View File

@ -0,0 +1,28 @@
#ifndef ModEngineTextureModule
#define ModEngineTextureModule
#include "moon/mod-engine/interfaces/file-entry.h"
#include "moon/mod-engine/interfaces/bit-module.h"
#include <string>
#include <vector>
#include <map>
extern "C" {
#include "pc/gfx/gfx_pc.h"
}
namespace Moon {
void saveAddonTexture(BitModule *addon, std::string texturePath, TextureFileEntry* data);
void precacheBaseTexture(char* data, long size, std::string texturePath);
TextureData *getCachedTexture(std::string texturePath);
}
namespace MoonInternal {
TextureFileEntry *getTextureData(const char *fullpath);
void loadTexture(int tile, const char *fullpath, struct GfxRenderingAPI *gfx_rapi);
void saveTexture(TextureData *data, std::string texturePath);
void buildTextureCache(std::vector<int> order);
void buildDefaultAddon();
}
#endif

View File

@ -1,4 +0,0 @@
#ifndef MoonTextureWorkspaces
#define MoonTextureWorkspaces
#endif

View File

@ -1,42 +1,47 @@
#include "moon/texts/moon-loader.h"
#include "moon/ui/moon-ui-manager.h"
#include "moon/io/moon-io.h"
#include <iostream>
#include "moon/mod-engine/engine.h"
#include "moon/io/moon-io.h"
#include "moon/mod-engine/textures/mod-texture.h"
#include "moon/io/modules/mouse-io.h"
#include "moon/ui/moon-ui-manager.h"
#include "moon/texts/moon-loader.h"
#include "moon/io/moon-io.h"
#include "moon/utils/moon-env.h"
#include "moon/mod-engine/engine.h"
#include "moon/mod-engine/test.h"
#include "moon/io/moon-io.h"
#include <iostream>
#include "moon/libs/nlohmann/json.hpp"
using json = nlohmann::json;
using namespace std;
extern "C" {
#include "game/game_init.h"
#include "types.h"
void moon_setup(char *state){
MoonInternal::setupModEngine(string(state));
MoonInternal::setupLanguageEngine(string(state));
MoonInternal::setupIOModuleEngine(string(state));
}
/*
########################
Moon Environment
########################
*/
void moon_environment_save(char* key, char* value){
MoonInternal::saveEnvironmentVar(string(key), string(value));
}
/*
#######################
Moon Languagues
#######################
*/
void moon_init_languages(char *executable, char *gamedir) {
Moon_InitLanguages(executable, gamedir);
// Moon_InitModEngine();
// exit(0);
}
u8 * moon_language_get_key( char* key ){
return getTranslatedText(Moon_GetKey(std::string(key)).c_str());
}
void moon_set_language( int id ) {
Moon_SetLanguage(languages[id]);
}
const char* moon_get_language_name( int id ) {
return languages[id]->name.c_str();
return getTranslatedText(Moon::getLanguageKey(std::string(key)).c_str());
}
/*
@ -67,43 +72,36 @@ u8 moon_ui_open(){
#######################
*/
void moon_modules_init(){
InitIOModules();
}
void moon_modules_update(){
UpdateIOModules();
}
void moon_update_window(void* window){
MouseIO* tmp = GetIOModule<MouseIO>();
MouseIO* tmp = Moon::GetIOModule<MouseIO>();
if(tmp != NULL) tmp->window = window;
}
void moon_mod_engine_preinit(){
Moon_PreInitModEngine();
/*
######################
Moon Texture
######################
*/
void moon_save_texture(struct TextureData* data, char* tex){
MoonInternal::saveTexture(data, string(tex));
}
void moon_mod_engine_init(char *executable, char *gamedir){
Moon_InitModEngine(executable, gamedir);
struct TextureData* moon_get_texture(char* tex){
return Moon::getCachedTexture(string(tex));
}
void moon_engine_save_texture(struct TextureData* data, char* tex){
Moon_SaveTexture(data, string(tex));
}
struct TextureData* moon_engine_get_texture(char* tex){
return Moon_GetTexture(string(tex));
}
struct TextureData* moon_engine_init_texture(){
struct TextureData* moon_create_texture(){
return new TextureData();
}
void moon_load_base_texture(char* data, long size, char* texture){
Moon_LoadBaseTexture(data, size, string(texture));
Moon::precacheBaseTexture(data, size, string(texture));
}
void moon_load_texture(int tile, const char *fullpath, struct GfxRenderingAPI *gfx_rapi){
Moon_LoadTexture(tile, fullpath, gfx_rapi);
MoonInternal::loadTexture(tile, fullpath, gfx_rapi);
}
}

View File

@ -1,30 +1,51 @@
#ifndef MOON_WRAPPER
#define MOON_WRAPPER
#ifndef __cplusplus
#include "types.h"
#include "pc/gfx/gfx_pc.h"
void moon_init_languages(char *executable, char *gamedir);
u8 * moon_language_get_key( char* key );
void moon_set_language( int id );
const char* moon_get_language_name( int id );
void moon_setup(char *state);
void moon_environment_save(char* key, char* value);
/*
#######################
Moon Languagues
#######################
*/
u8 *moon_language_get_key( char* key );
/*
#######################
Moon UI
#######################
*/
void moon_draw_ui();
void moon_change_ui(int index);
u8 moon_ui_open();
void moon_ui_toggle();
void moon_change_ui(int index);
u8 moon_ui_open();
/*
#######################
Moon IO
#######################
*/
void moon_modules_init();
void moon_modules_update();
void moon_update_window(void* window);
void moon_mod_engine_preinit();
void moon_mod_engine_init(char *executable, char *gamedir);
/*
######################
Moon Texture
######################
*/
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_save_texture(struct TextureData* data, char* tex);
struct TextureData* moon_get_texture(char* tex);
struct TextureData* moon_create_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);

View File

@ -1,6 +1,8 @@
#include "moon-loader.h"
#include <iostream>
#include "moon/utils/moon-env.h"
#include <unistd.h>
#include <stdio.h>
#include <limits.h>
@ -21,171 +23,183 @@ using namespace rapidjson;
typedef GenericDocument<UTF16<>> WDocument;
typedef GenericValue<UTF16<>> WValue;
vector<LanguageEntry*> languages;
LanguageEntry *current;
#define SECRET_NULL 24
void Moon_LoadLanguage( string path ) {
namespace Moon {
FILE* fp = fopen(path.c_str(), "r");
char readBuffer[65536];
FileReadStream is(fp, readBuffer, sizeof(readBuffer));
AutoUTFInputStream<unsigned, FileReadStream> eis(is);
vector<LanguageEntry*> languages;
LanguageEntry *current;
WDocument raw;
raw.ParseStream<0, AutoUTF<unsigned>>(eis);
void loadLanguage( string path ) {
WValue manifest, dialogs, courses, secrets, options, strings;
FILE* fp = fopen(path.c_str(), "r");
char readBuffer[65536];
FileReadStream is(fp, readBuffer, sizeof(readBuffer));
AutoUTFInputStream<unsigned, FileReadStream> eis(is);
if(!raw.HasMember(L"manifest")) {
cout << "Failed to load language" << endl;
cout << "Missing manifest" << endl;
return;
}
WDocument raw;
raw.ParseStream<0, AutoUTF<unsigned>>(eis);
manifest = raw[L"manifest"];
WValue manifest, dialogs, courses, secrets, options, strings;
bool isChild = manifest.HasMember(L"parent");
if(!raw.HasMember(L"manifest")) {
cout << "Failed to load language" << endl;
cout << "Missing manifest" << endl;
return;
}
LanguageEntry * language;
manifest = raw[L"manifest"];
if(!isChild){
language = new LanguageEntry();
} else {
isChild = false;
string parentName = narrow(manifest[L"langLogo"].GetString());
for(auto &lng : languages){
if(lng->name == parentName){
language = lng;
isChild = true;
break;
bool isChild = manifest.HasMember(L"parent");
LanguageEntry * language;
if(!isChild){
language = new LanguageEntry();
} else {
isChild = false;
string parentName = narrow(manifest[L"langLogo"].GetString());
for(auto &lng : languages){
if(lng->name == parentName){
language = lng;
isChild = true;
break;
}
}
}
}
if(!isChild){
language->name = narrow(manifest[L"langName"].GetString());
language->logo = narrow(manifest[L"langLogo"].GetString());
}
if(!isChild){
language->name = narrow(manifest[L"langName"].GetString());
language->logo = narrow(manifest[L"langLogo"].GetString());
}
if(raw.HasMember(L"dialogs")){
dialogs = raw[L"dialogs"];
for (WValue& dialog : dialogs.GetArray()) {
int linesPerBox = dialog[L"linesPerBox"].GetInt();
int leftOffset = dialog[L"leftOffset"].GetInt();
int width = dialog[L"width"].GetInt();
int id = dialog[L"ID"].GetInt();
if(raw.HasMember(L"dialogs")){
dialogs = raw[L"dialogs"];
for (WValue& dialog : dialogs.GetArray()) {
int linesPerBox = dialog[L"linesPerBox"].GetInt();
int leftOffset = dialog[L"leftOffset"].GetInt();
int width = dialog[L"width"].GetInt();
int id = dialog[L"ID"].GetInt();
DialogEntry *entry = new DialogEntry();
entry->linesPerBox = linesPerBox;
entry->leftOffset = leftOffset;
entry->width = width;
entry->unused = 1;
DialogEntry *entry = new DialogEntry();
entry->linesPerBox = linesPerBox;
entry->leftOffset = leftOffset;
entry->width = width;
entry->unused = 1;
wstring base;
wstring base;
for (WValue& line : dialog[L"lines"].GetArray()){
base += line.GetString();
base += L"\n";
for (WValue& line : dialog[L"lines"].GetArray()){
base += line.GetString();
base += L"\n";
}
entry->str = getTranslatedText(narrow(base).c_str());
language->dialogs.push_back(entry);
}
}
if(raw.HasMember(L"courses") && raw.HasMember(L"secrets")){
courses = raw[L"courses"];
secrets = raw[L"secrets"];
int course_name_table_size = courses.Size() + secrets.Size();
int courseId = 0;
int padding = 0;
u8* tmpCourses[course_name_table_size];
for (WValue& course : courses.GetArray()){
if(courseId + 1 <= courses.Size() - 1) {
tmpCourses[courseId] = getTranslatedText(narrow(course[L"course"].GetString()).c_str());
courseId++;
}
for (WValue& act : course[L"acts"].GetArray()){
language->acts.push_back(getTranslatedText(narrow(act.GetString()).c_str()));
}
}
entry->str = getTranslatedText(narrow(base).c_str());
language->dialogs.push_back(entry);
}
}
for (WValue& secret : secrets.GetArray()){
if(courseId == SECRET_NULL) {
tmpCourses[courseId] = getTranslatedText(0);
padding++;
}
if(raw.HasMember(L"courses") && raw.HasMember(L"secrets")){
courses = raw[L"courses"];
secrets = raw[L"secrets"];
int course_name_table_size = courses.Size() + secrets.Size();
int courseId = 0;
int padding = 0;
u8* tmpCourses[course_name_table_size];
for (WValue& course : courses.GetArray()){
if(courseId + 1 <= courses.Size() - 1) {
tmpCourses[courseId] = getTranslatedText(narrow(course[L"course"].GetString()).c_str());
tmpCourses[courseId + padding] = getTranslatedText(narrow(secret.GetString()).c_str());
courseId++;
}
for (WValue& act : course[L"acts"].GetArray()){
language->acts.push_back(getTranslatedText(narrow(act.GetString()).c_str()));
language->courses.insert(language->courses.end(), &tmpCourses[0], &tmpCourses[course_name_table_size]);
}
if(raw.HasMember(L"options")){
options = raw[L"options"];
for (WValue::ConstMemberIterator option = options.MemberBegin(); option != options.MemberEnd(); ++option) {
language->strings.insert(pair<string, string>(
narrow(option->name.GetString()),
narrow(option->value.GetString())
));
}
}
for (WValue& secret : secrets.GetArray()){
if(courseId == SECRET_NULL) {
tmpCourses[courseId] = getTranslatedText(0);
padding++;
}
tmpCourses[courseId + padding] = getTranslatedText(narrow(secret.GetString()).c_str());
courseId++;
}
language->courses.insert(language->courses.end(), &tmpCourses[0], &tmpCourses[course_name_table_size]);
}
if(raw.HasMember(L"options")){
options = raw[L"options"];
for (WValue::ConstMemberIterator option = options.MemberBegin(); option != options.MemberEnd(); ++option) {
language->strings.insert(pair<string, string>(
narrow(option->name.GetString()),
narrow(option->value.GetString())
));
}
}
if(raw.HasMember(L"secrets")){
strings = raw[L"strings"];
for (WValue::ConstMemberIterator item = strings.MemberBegin(); item != strings.MemberEnd(); ++item) {
language->strings.insert(pair<string, string>(
narrow(item->name.GetString()),
narrow(item->value.GetString())
));
}
}
if(!isChild) languages.push_back(language);
languagesAmount = languages.size();
}
string Moon_GetKey(string key) {
return current->strings[key];
}
void Moon_InitLanguages( char *exePath, char *gamedir ) {
string l_path(exePath);
string languages_dir = l_path.substr(0, l_path.find_last_of("/\\")) + "/" + gamedir + "/texts/";
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;
while ((de = readdir(dir)) != NULL) {
const char *extension = get_filename_ext(de->d_name);
if (strcmp(extension, "json") == 0) {
string file = languages_dir + de->d_name;
printf("Loading File: %s\n", file.c_str());
Moon_LoadLanguage( file );
if(raw.HasMember(L"secrets")){
strings = raw[L"strings"];
for (WValue::ConstMemberIterator item = strings.MemberBegin(); item != strings.MemberEnd(); ++item) {
language->strings.insert(pair<string, string>(
narrow(item->name.GetString()),
narrow(item->value.GetString())
));
}
}
closedir(dir);
if(!isChild) languages.push_back(language);
languagesAmount = languages.size();
}
Moon_SetLanguage(languages[configLanguage]);
void setCurrentLanguage(LanguageEntry *new_language) {
current = new_language;
dialogPool = current->dialogs.data();
seg2_act_name_table = current->acts.data();
seg2_course_name_table = current->courses.data();
}
string getLanguageKey(string key){
return current->strings[key];
}
}
void Moon_SetLanguage(LanguageEntry *new_language) {
current = new_language;
dialogPool = current->dialogs.data();
seg2_act_name_table = current->acts.data();
seg2_course_name_table = current->courses.data();
namespace MoonInternal {
void scanLanguagesDirectory(){
string cwd = MoonInternal::getEnvironmentVar("MOON_CWD");
string gameDir = MoonInternal::getEnvironmentVar("ASSETS_DIR");
string languagesDir = cwd.substr(0, cwd.find_last_of("/\\")) + "/" + gameDir + "/texts/";
// Scan directory for JSON files
DIR *dir = opendir(languagesDir.c_str());
if (dir) {
struct dirent *de;
while ((de = readdir(dir)) != NULL) {
const char *extension = get_filename_ext(de->d_name);
if (strcmp(extension, "json") == 0) {
string file = languagesDir + de->d_name;
Moon::loadLanguage( file );
}
}
closedir(dir);
}
}
void setupLanguageEngine( string state ){
if(state == "PreInit"){
MoonInternal::scanLanguagesDirectory();
return;
}
if(state == "Init"){
Moon::setCurrentLanguage(Moon::languages[configLanguage]);
return;
}
}
}

View File

@ -1,6 +1,6 @@
#ifndef MOON_TEXT_LOADER
#define MOON_TEXT_LOADER
#ifdef __cplusplus
#include <vector>
#include <list>
#include <map>
@ -34,12 +34,18 @@ struct LanguageEntry {
std::vector<u8*> courses;
};
extern std::vector<LanguageEntry*> languages;
namespace Moon {
extern std::vector<LanguageEntry*> languages;
extern LanguageEntry *current;
void Moon_LoadLanguage( std::string path );
void Moon_InitLanguages( char *exePath, char *gamedir ) ;
std::string Moon_GetKey(std::string key);
void Moon_SetLanguage(LanguageEntry *new_language);
void loadLanguage(std::string path);
void setCurrentLanguage(LanguageEntry *new_language);
std::string getLanguageKey(std::string key);
}
namespace MoonInternal {
void scanLanguagesDirectory();
void setupLanguageEngine( std::string state );
}
#endif
#endif

View File

@ -14,11 +14,11 @@ int languageIdx;
vector<string> lngNames;
MGameCategory::MGameCategory() : MoonCategory("TEXT_OPT_GAME"){
for (auto &lng : languages) {
for (auto &lng : Moon::languages) {
lngNames.push_back(lng->name);
}
this->catOptions.push_back(new MWValue(22, 57, "TEXT_OPT_LANGUAGE", {.index = &languageIdx, .values = &lngNames, .callback = [](){
Moon_SetLanguage(languages[languageIdx]);
Moon::setCurrentLanguage(Moon::languages[languageIdx]);
}}, true));
this->catOptions.push_back(new MWValue(22, 74, "TEXT_OPT_PRECACHE", {.bvar = &configPrecacheRes}, true));
int exitY;

View File

@ -3,6 +3,7 @@
#include "moon/texts/moon-loader.h"
#include "moon/ui/widgets/mw-value.h"
#include "moon/mod-engine/engine.h"
#include "moon/mod-engine/textures/mod-texture.h"
#include <algorithm>
using namespace std;
@ -17,12 +18,12 @@ MWValue *tmpButton;
MTexturesCategory::MTexturesCategory() : MoonCategory("Textures"){
this->titleKey = false;
for(int i = 0; i < addons.size(); i++) order.push_back(i);
for(int i = 0; i < Moon::addons.size(); i++) order.push_back(i);
this->catOptions.push_back(tmpButton = new MWValue(22, 57, "Randomize packs", {.btn = [](){
tmpButton->title = "Randomize on progress";
std::random_shuffle ( order.begin(), order.end() );
Moon_TestRebuildOrder(order);
MoonInternal::buildTextureCache(order);
tmpButton->title = "Randomize packs";
}}, false));
}

View File

@ -82,7 +82,7 @@ void MoonOptMain::Update(){
}
void MoonOptMain::Draw(){
string curTitle = categories[categoryIndex]->titleKey ? Moon_GetKey(categories[categoryIndex]->categoryName) : categories[categoryIndex]->categoryName;
string curTitle = categories[categoryIndex]->titleKey ? Moon::getLanguageKey(categories[categoryIndex]->categoryName) : categories[categoryIndex]->categoryName;
float txtWidth = MoonGetTextWidth(curTitle, 1.0, true);
MoonDrawRectangle(0, 0, GetScreenWidth(false), GetScreenHeight(), {0, 0, 0, 100}, false);

View File

@ -45,7 +45,7 @@ void MWValue::Draw(){
focusAnimation += step * (focusAnimationPingPong ? -1 : 1);
string rawTitle = this->titleKey ? Moon_GetKey(this->title) : this->title;
string rawTitle = this->titleKey ? Moon::getLanguageKey(this->title) : this->title;
float scale = 1;
float titleWidth = MoonGetTextWidth(rawTitle + " ", scale, false);
int barWidth = SCREEN_WIDTH - 50 - 14;
@ -68,14 +68,14 @@ void MWValue::Draw(){
{61, 255, 113, 255},
{255, 61, 61, 255}
};
string statusText = status ? Moon_GetKey("TEXT_OPT_ENABLED") : Moon_GetKey("TEXT_OPT_DISABLED");
string statusText = status ? Moon::getLanguageKey("TEXT_OPT_ENABLED") : Moon::getLanguageKey("TEXT_OPT_DISABLED");
tmpWidth += MoonGetTextWidth(statusText, scale, false);
MoonDrawText(this->x + ( 10 + barWidth / 2 ) - tmpWidth / 2 + titleWidth, this->y, statusText, scale, toggleColors[status ? 0 : 1] , true, true);
} else if(this->bind.values != NULL && this->bind.index != NULL){
int index = *this->bind.index;
string text = this->bind.valueKeys ? Moon_GetKey((*this->bind.values)[index]) : (*this->bind.values)[index];
string text = this->bind.valueKeys ? Moon::getLanguageKey((*this->bind.values)[index]) : (*this->bind.values)[index];
tmpWidth += MoonGetTextWidth(text, scale, false);
MoonDrawText(this->x + ( 10 + barWidth / 2 ) - tmpWidth / 2 + titleWidth, this->y, text, scale, {58, 249, 252, 255}, true, true);

View File

@ -0,0 +1,15 @@
#include "moon-env.h"
#include <map>
using namespace std;
map<string, string> environmentVars;
namespace MoonInternal {
void saveEnvironmentVar(std::string key, std::string value){
environmentVars.insert(pair<string, string>(key, value));
}
std::string getEnvironmentVar(std::string key){
return environmentVars[key];
}
}

11
src/moon/utils/moon-env.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef MoonEnvironmentVars
#define MoonEnvironmentVars
#include <string>
namespace MoonInternal {
void saveEnvironmentVar(std::string key, std::string value);
std::string getEnvironmentVar(std::string key);
}
#endif

27
src/moon/zip/straw.cpp Normal file
View File

@ -0,0 +1,27 @@
#include "straw.h"
#include "moon/libs/miniz/zip_file.hpp"
using namespace std;
using namespace miniz_cpp;
zip_file zipFile;
void StrawFile::open(){
zipFile.load(this->path);
}
bool StrawFile::exists(string path){
return zipFile.has_file(path);
}
vector<string> StrawFile::entries(){
return zipFile.namelist();
}
string StrawFile::read(string file){
return zipFile.read(file);
}
void StrawFile::read(string file, TextureFileEntry *entry){
zipFile.read_texture(file, &entry);
}
string StrawFile::getPath(){
return this->path;
}

24
src/moon/zip/straw.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef StrawZipLoader
#define StrawZipLoader
#include "moon/mod-engine/interfaces/file-entry.h"
#include <vector>
#include <string>
class StrawFile {
public:
StrawFile(std::string path){
this->path = path;
}
void open();
bool exists(std::string path);
std::vector<std::string> entries();
std::string read(std::string file);
void read(std::string file, TextureFileEntry *entry);
std::string getPath();
void close();
protected:
std::string path;
};
#endif

View File

@ -255,13 +255,13 @@ static struct ColorCombiner *gfx_lookup_or_create_color_combiner(uint32_t cc_id)
}
static bool gfx_texture_cache_lookup(int tile, struct TextureData **n, const uint8_t *orig_addr, uint32_t fmt, uint32_t siz) {
struct TextureData *node = moon_engine_get_texture(orig_addr);
struct TextureData *node = moon_get_texture(orig_addr);
if(node != NULL){
gfx_rapi->select_texture(tile, node->texture_id);
if(n != NULL) *n = node;
return true;
} else node = moon_engine_init_texture();
} else node = moon_create_texture();
if (node->texture_addr == NULL)
node->texture_id = gfx_rapi->new_texture();
@ -274,7 +274,7 @@ static bool gfx_texture_cache_lookup(int tile, struct TextureData **n, const uin
node->texture_addr = orig_addr;
node->fmt = fmt;
node->siz = siz;
moon_engine_save_texture(node, orig_addr);
moon_save_texture(node, orig_addr);
if(n != NULL) *n = node;
return false;
}
@ -351,30 +351,6 @@ static bool texname_to_texformat(const char *name, u8 *fmt, u8 *siz) {
return false;
}
void overload_memory_texture(void* data, long size, const char *path) {
// strip off the extension
char texname[SYS_MAX_PATH];
strncpy(texname, path, sizeof(texname));
texname[sizeof(texname)-1] = 0;
// get the format and size from filename
u8 fmt, siz;
if (!texname_to_texformat(texname, &fmt, &siz)) {
// fprintf(stderr, "unknown texture format: `%s`, skipping\n", texname);
return true; // just skip it, might be a stray skybox or something
}
char *actualname = texname;
if (!strncmp(FS_TEXTUREDIR "/", actualname, 4)) actualname += 4;
actualname = sys_strdup(actualname);
assert(actualname);
if (!gfx_texture_cache_lookup(0, NULL, actualname, fmt, siz))
load_memory_texture(data, size);
return true;
}
static void import_texture(int tile) {
uint8_t fmt = rdp.texture_tile.fmt;
uint8_t siz = rdp.texture_tile.siz;

View File

@ -91,7 +91,7 @@ void send_display_list(struct SPTask *spTask) {
#endif
void produce_one_frame(void) {
moon_modules_update();
moon_setup("Update");
gfx_start_frame();
const f32 master_mod = (f32)configMasterVolume / 127.0f;
@ -192,8 +192,8 @@ void main_func(char *argv[]) {
const char *userpath = gCLIOpts.SavePath[0] ? gCLIOpts.SavePath : sys_user_path();
fs_init(sys_ropaths, gamedir, userpath);
configfile_load(configfile_name());
moon_init_languages(argv[0], gamedir);
moon_environment_save("MOON_CWD", argv[0]);
moon_environment_save("ASSETS_DIR", gamedir);
if (gCLIOpts.FullScreen == 1)
configWindow.fullscreen = true;
else if (gCLIOpts.FullScreen == 2)
@ -233,7 +233,6 @@ void main_func(char *argv[]) {
#endif
;
moon_modules_init();
gfx_init(wm_api, rendering_api, window_title);
wm_api->set_keyboard_callbacks(keyboard_on_key_down, keyboard_on_key_up, keyboard_on_all_keys_up);
@ -253,8 +252,8 @@ void main_func(char *argv[]) {
fprintf(stdout, "precaching data\n");
fflush(stdout);
gfx_precache_textures();
moon_mod_engine_preinit();
moon_mod_engine_init(argv[0], gamedir);
moon_setup("PreInit");
moon_setup("Init");
#ifdef DISCORDRPC
discord_init();

View File

@ -12,14 +12,6 @@ u8 * *seg2_act_name_table;
struct DialogEntry * *dialogPool;
u8 languagesAmount = 0;
const char* get_language_name(int language) {
return moon_get_language_name(language);
}
void set_language(int new_language) {
moon_set_language(new_language);
}
u8 *get_key_string(char *id) {
return moon_language_get_key(id);
}

View File

@ -17,7 +17,5 @@ struct StringTable {
extern void alloc_dialog_pool(char* exePath, char* gamedir);
extern void dealloc_dialog_pool(void);
extern const char* get_language_name(int language);
extern void set_language(int new_language);
extern u8* get_key_string(char* id);
#endif