mirror of https://github.com/sm64pc/sm64pc.git
[WIP] Started texture support on addons
This commit is contained in:
parent
f902e98cb4
commit
356561a5b4
|
@ -32,6 +32,7 @@
|
|||
#include <cstring>
|
||||
#include <time.h>
|
||||
#include <vector>
|
||||
#include "moon/mod-engine/interfaces/file-entry.h"
|
||||
|
||||
/* miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
|
||||
See "unlicense" statement at the end of this file.
|
||||
|
@ -5456,6 +5457,21 @@ class zip_file
|
|||
return extracted;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
throw std::runtime_error("file couldn't be read");
|
||||
}
|
||||
(*entry)->data = data;
|
||||
(*entry)->size = size;
|
||||
}
|
||||
|
||||
void read_texture(const std::string &name, TextureFileEntry** entry){
|
||||
read_texture(getinfo(name), entry);
|
||||
}
|
||||
|
||||
std::string read(const std::string &name)
|
||||
{
|
||||
return read(getinfo(name));
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "moon/mod-engine/interfaces/mod-module.h"
|
||||
#include "moon/mod-engine/modules/test-module.h"
|
||||
#include "moon/mod-engine/interfaces/bit-module.h"
|
||||
#include "interfaces/file-entry.h"
|
||||
|
||||
#include "moon/wrapper.h"
|
||||
#include "moon/libs/nlohmann/json.hpp"
|
||||
|
@ -14,10 +15,14 @@ using json = nlohmann::json;
|
|||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
vector<BitModule*> addons;
|
||||
map<string, TextureData*> textureMap;
|
||||
|
||||
map<string, TextureFileEntry*> baseGameTextures;
|
||||
|
||||
extern "C" {
|
||||
#include "moon/libs/lua/lualib.h"
|
||||
|
@ -26,6 +31,21 @@ extern "C" {
|
|||
#include "text/libs/io_utils.h"
|
||||
}
|
||||
|
||||
void Moon_LoadAddonTextures(BitModule* module);
|
||||
|
||||
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);
|
||||
Moon_LoadAddonTextures(bit);
|
||||
}
|
||||
|
||||
|
||||
void Moon_LoadAddon(string path){
|
||||
miniz_cpp::zip_file file(path);
|
||||
|
||||
|
@ -42,6 +62,7 @@ void Moon_LoadAddon(string path){
|
|||
bit->website = j["bit"]["website"];
|
||||
bit->icon = j["bit"]["icon"];
|
||||
bit->main = j["bit"]["main"];
|
||||
bit->readOnly = false;
|
||||
|
||||
if(file.has_file(bit->main)){
|
||||
std::cout << file.read(bit->main) << std::endl;
|
||||
|
@ -55,8 +76,11 @@ void Moon_LoadAddon(string path){
|
|||
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(), name.length() - 1);
|
||||
// std::cout << texName << std::endl;
|
||||
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*>(texName, entry));
|
||||
}
|
||||
}
|
||||
if(!name.rfind(textsPath, 0)){
|
||||
|
@ -66,6 +90,11 @@ void Moon_LoadAddon(string path){
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!bit->textures.empty())
|
||||
Moon_LoadAddonTextures(bit);
|
||||
|
||||
addons.push_back(bit);
|
||||
}
|
||||
} else {
|
||||
std::cout << "Failed to load addon: [" << file.get_filename() << "]" << std::endl;
|
||||
|
@ -95,6 +124,48 @@ void Moon_ScanAddonsDirectory( char *exePath, char *gamedir ){
|
|||
}
|
||||
}
|
||||
|
||||
void Moon_InitModEngine(){
|
||||
void Moon_LoadAddonTextures(BitModule* module){
|
||||
if(module->textures.empty()) return;
|
||||
cout << "Loading from " << module->name << " " << to_string(module->textures.size()) << " textures " << endl;
|
||||
|
||||
for (map<string, TextureFileEntry*>::iterator entry = module->textures.begin(); entry != module->textures.end(); ++entry) {
|
||||
|
||||
map<string, TextureData*>::iterator texIt;
|
||||
texIt = textureMap.find(entry->first);
|
||||
|
||||
if(texIt != textureMap.end()){
|
||||
cout << "Erasing: " << entry->first << endl;
|
||||
textureMap.erase(texIt);
|
||||
}
|
||||
|
||||
TextureFileEntry* texEntry = entry->second;
|
||||
if(texEntry->data != nullptr) {
|
||||
overload_memory_texture(texEntry->data, texEntry->size, entry->first.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Moon_SaveTexture(TextureData* data, string tex){
|
||||
cout << "Saving: " << tex << endl;
|
||||
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.substr(4), new TextureFileEntry({.size = size, .data = data})));
|
||||
}
|
||||
}
|
||||
|
||||
TextureData* Moon_GetTexture(string texture){
|
||||
return textureMap.find(texture) != textureMap.end() ? textureMap.find(texture)->second : nullptr;
|
||||
}
|
||||
|
||||
void Moon_PreInitModEngine(){
|
||||
// Moon_LoadDefaultAddon();
|
||||
Moon_LoadAddon("/home/alex/disks/uwu/Projects/UnderVolt/example.bit");
|
||||
Moon_LoadAddon("/home/alex/disks/uwu/Projects/UnderVolt/owo.bit");
|
||||
}
|
||||
|
||||
void Moon_InitModEngine(){
|
||||
|
||||
}
|
|
@ -1,6 +1,15 @@
|
|||
#ifndef Moon64ModEngine
|
||||
#define Moon64ModEngine
|
||||
|
||||
extern "C" {
|
||||
#include "pc/gfx/gfx_pc.h"
|
||||
}
|
||||
|
||||
void Moon_SaveTexture(TextureData* data, string tex);
|
||||
TextureData* Moon_GetTexture(string texture);
|
||||
void Moon_PreInitModEngine();
|
||||
void Moon_InitModEngine();
|
||||
|
||||
void Moon_LoadBaseTexture(char* data, long size, string texture);
|
||||
|
||||
#endif
|
|
@ -1,9 +1,14 @@
|
|||
#ifndef Moon64BitModule
|
||||
#define Moon64BitModule
|
||||
#include "file-entry.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
extern "C" {
|
||||
#include "pc/gfx/gfx_pc.h"
|
||||
}
|
||||
class BitModule{
|
||||
public:
|
||||
std::string name;
|
||||
|
@ -13,6 +18,9 @@ public:
|
|||
std::string website;
|
||||
std::string icon;
|
||||
std::string main;
|
||||
std::map<std::string, TextureFileEntry*> textures;
|
||||
// GFXTextureCache* textureCache;
|
||||
bool readOnly;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef Moon64FileEntry
|
||||
#define Moon64FileEntry
|
||||
|
||||
struct TextureFileEntry {
|
||||
long size;
|
||||
char* data;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -78,4 +78,28 @@ void moon_update_window(void* window){
|
|||
if(tmp != NULL) tmp->window = window;
|
||||
}
|
||||
|
||||
void moon_mod_engine_preinit(){
|
||||
Moon_PreInitModEngine();
|
||||
}
|
||||
|
||||
void moon_mod_engine_init(){
|
||||
Moon_InitModEngine();
|
||||
}
|
||||
|
||||
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(){
|
||||
return new TextureData();
|
||||
}
|
||||
|
||||
void moon_load_base_texture(char* data, long size, char* texture){
|
||||
Moon_LoadBaseTexture(data, size, string(texture));
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
#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 );
|
||||
|
@ -18,5 +19,13 @@ void moon_modules_init();
|
|||
void moon_modules_update();
|
||||
void moon_update_window(void* window);
|
||||
|
||||
void moon_mod_engine_preinit();
|
||||
void moon_mod_engine_init();
|
||||
|
||||
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);
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -25,6 +25,7 @@
|
|||
#include "../platform.h"
|
||||
#include "../configfile.h"
|
||||
#include "../fs/fs.h"
|
||||
#include "moon/moon64.h"
|
||||
|
||||
#define SUPPORT_CHECK(x) assert(x)
|
||||
|
||||
|
@ -48,12 +49,6 @@
|
|||
#define MAX_LIGHTS 2
|
||||
#define MAX_VERTICES 64
|
||||
|
||||
# define MAX_CACHED_TEXTURES 4096 // for preloading purposes
|
||||
# define HASH_SHIFT 0
|
||||
|
||||
#define HASHMAP_LEN (MAX_CACHED_TEXTURES * 2)
|
||||
#define HASH_MASK (HASHMAP_LEN - 1)
|
||||
|
||||
struct RGBA {
|
||||
uint8_t r, g, b, a;
|
||||
};
|
||||
|
@ -69,22 +64,6 @@ struct LoadedVertex {
|
|||
uint8_t clip_rej;
|
||||
};
|
||||
|
||||
struct TextureHashmapNode {
|
||||
struct TextureHashmapNode *next;
|
||||
|
||||
const uint8_t *texture_addr;
|
||||
uint8_t fmt, siz;
|
||||
|
||||
uint32_t texture_id;
|
||||
uint8_t cms, cmt;
|
||||
bool linear_filter;
|
||||
};
|
||||
static struct {
|
||||
struct TextureHashmapNode *hashmap[HASHMAP_LEN];
|
||||
struct TextureHashmapNode pool[MAX_CACHED_TEXTURES];
|
||||
uint32_t pool_pos;
|
||||
} gfx_texture_cache;
|
||||
|
||||
struct ColorCombiner {
|
||||
uint32_t cc_id;
|
||||
struct ShaderProgram *prg;
|
||||
|
@ -97,24 +76,24 @@ static uint8_t color_combiner_pool_size;
|
|||
static struct RSP {
|
||||
float modelview_matrix_stack[11][4][4];
|
||||
uint8_t modelview_matrix_stack_size;
|
||||
|
||||
|
||||
float MP_matrix[4][4];
|
||||
float P_matrix[4][4];
|
||||
|
||||
|
||||
Light_t current_lights[MAX_LIGHTS + 1];
|
||||
float current_lights_coeffs[MAX_LIGHTS][3];
|
||||
float current_lookat_coeffs[2][3]; // lookat_x, lookat_y
|
||||
uint8_t current_num_lights; // includes ambient light
|
||||
bool lights_changed;
|
||||
|
||||
|
||||
uint32_t geometry_mode;
|
||||
int16_t fog_mul, fog_offset;
|
||||
|
||||
|
||||
struct {
|
||||
// U0.16
|
||||
uint16_t s, t;
|
||||
} texture_scaling_factor;
|
||||
|
||||
|
||||
struct LoadedVertex loaded_vertices[MAX_VERTICES + 4];
|
||||
} rsp;
|
||||
|
||||
|
@ -137,10 +116,10 @@ static struct RDP {
|
|||
uint32_t line_size_bytes;
|
||||
} texture_tile;
|
||||
bool textures_changed[2];
|
||||
|
||||
|
||||
uint32_t other_mode_l, other_mode_h;
|
||||
uint32_t combine_mode;
|
||||
|
||||
|
||||
struct RGBA env_color, prim_color, fog_color, fill_color;
|
||||
struct XYWidthHeight viewport, scissor;
|
||||
bool viewport_or_scissor_changed;
|
||||
|
@ -155,7 +134,7 @@ static struct RenderingState {
|
|||
bool alpha_blend;
|
||||
struct XYWidthHeight viewport, scissor;
|
||||
struct ShaderProgram *shader_program;
|
||||
struct TextureHashmapNode *textures[2];
|
||||
struct TextureData *textures[2];
|
||||
} rendering_state;
|
||||
|
||||
struct GfxDimensions gfx_current_dimensions;
|
||||
|
@ -266,7 +245,7 @@ static struct ColorCombiner *gfx_lookup_or_create_color_combiner(uint32_t cc_id)
|
|||
if (prev_combiner != NULL && prev_combiner->cc_id == cc_id) {
|
||||
return prev_combiner;
|
||||
}
|
||||
|
||||
|
||||
for (size_t i = 0; i < color_combiner_pool_size; i++) {
|
||||
if (color_combiner_pool[i].cc_id == cc_id) {
|
||||
return prev_combiner = &color_combiner_pool[i];
|
||||
|
@ -278,43 +257,37 @@ static struct ColorCombiner *gfx_lookup_or_create_color_combiner(uint32_t cc_id)
|
|||
return prev_combiner = comb;
|
||||
}
|
||||
|
||||
static bool gfx_texture_cache_lookup(int tile, struct TextureHashmapNode **n, const uint8_t *orig_addr, uint32_t fmt, uint32_t siz) {
|
||||
size_t hash = string_hash(orig_addr);
|
||||
#define CMPADDR(x, y) (x && !sys_strcasecmp((const char *)x, (const char *)y))
|
||||
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);
|
||||
|
||||
hash = (hash >> HASH_SHIFT) & HASH_MASK;
|
||||
if(node != NULL){
|
||||
gfx_rapi->select_texture(tile, node->texture_id);
|
||||
if(n != NULL) *n = node;
|
||||
return true;
|
||||
} else node = moon_engine_init_texture();
|
||||
|
||||
struct TextureHashmapNode **node = &gfx_texture_cache.hashmap[hash];
|
||||
while (*node != NULL && *node - gfx_texture_cache.pool < gfx_texture_cache.pool_pos) {
|
||||
if (CMPADDR((*node)->texture_addr, orig_addr) && (*node)->fmt == fmt && (*node)->siz == siz) {
|
||||
gfx_rapi->select_texture(tile, (*node)->texture_id);
|
||||
*n = *node;
|
||||
return true;
|
||||
}
|
||||
node = &(*node)->next;
|
||||
}
|
||||
if (gfx_texture_cache.pool_pos == sizeof(gfx_texture_cache.pool) / sizeof(struct TextureHashmapNode)) {
|
||||
// Pool is full. We just invalidate everything and start over.
|
||||
gfx_texture_cache.pool_pos = 0;
|
||||
node = &gfx_texture_cache.hashmap[hash];
|
||||
// puts("Clearing texture cache");
|
||||
}
|
||||
*node = &gfx_texture_cache.pool[gfx_texture_cache.pool_pos++];
|
||||
if ((*node)->texture_addr == NULL) {
|
||||
(*node)->texture_id = gfx_rapi->new_texture();
|
||||
}
|
||||
gfx_rapi->select_texture(tile, (*node)->texture_id);
|
||||
if (node->texture_addr == NULL)
|
||||
node->texture_id = gfx_rapi->new_texture();
|
||||
|
||||
gfx_rapi->select_texture(tile, node->texture_id);
|
||||
gfx_rapi->set_sampler_parameters(tile, false, 0, 0);
|
||||
(*node)->cms = 0;
|
||||
(*node)->cmt = 0;
|
||||
(*node)->linear_filter = false;
|
||||
(*node)->next = NULL;
|
||||
(*node)->texture_addr = orig_addr;
|
||||
(*node)->fmt = fmt;
|
||||
(*node)->siz = siz;
|
||||
*n = *node;
|
||||
node->cms = 0;
|
||||
node->cmt = 0;
|
||||
node->linear_filter = false;
|
||||
node->texture_addr = orig_addr;
|
||||
node->fmt = fmt;
|
||||
node->siz = siz;
|
||||
moon_engine_save_texture(node, orig_addr);
|
||||
|
||||
return false;
|
||||
#undef CMPADDR
|
||||
}
|
||||
|
||||
static inline void preload_base_texture(const char *fullpath) {
|
||||
int w, h;
|
||||
u64 imgsize = 0;
|
||||
|
||||
u8 *imgdata = fs_load_file(fullpath, &imgsize);
|
||||
if (imgdata) moon_load_base_texture(imgdata, imgsize, fullpath);
|
||||
}
|
||||
|
||||
static inline void load_texture(const char *fullpath) {
|
||||
|
@ -338,6 +311,25 @@ static inline void load_texture(const char *fullpath) {
|
|||
gfx_rapi->upload_texture(missing_texture, MISSING_W, MISSING_H);
|
||||
}
|
||||
|
||||
static inline void load_memory_texture(void *imgdata, long size) {
|
||||
int w, h;
|
||||
|
||||
if (imgdata) {
|
||||
// TODO: implement stbi_callbacks or some shit instead of loading the whole texture
|
||||
u8 *data = stbi_load_from_memory(imgdata, size, &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 memory texture\n");
|
||||
// replace with missing texture
|
||||
gfx_rapi->upload_texture(missing_texture, MISSING_W, MISSING_H);
|
||||
}
|
||||
|
||||
|
||||
// this is taken straight from n64graphics
|
||||
static bool texname_to_texformat(const char *name, u8 *fmt, u8 *siz) {
|
||||
|
@ -398,9 +390,33 @@ static bool preload_texture(void *user, const char *path) {
|
|||
actualname = sys_strdup(actualname);
|
||||
assert(actualname);
|
||||
|
||||
struct TextureHashmapNode *n;
|
||||
if (!gfx_texture_cache_lookup(0, &n, actualname, fmt, siz))
|
||||
load_texture(path); // new texture, load it
|
||||
preload_base_texture(path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
char *dot = strrchr(texname, '.');
|
||||
if (dot) *dot = 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;
|
||||
}
|
||||
|
@ -477,7 +493,7 @@ static void gfx_sp_matrix(uint8_t parameters, const int32_t *addr) {
|
|||
#else
|
||||
memcpy(matrix, addr, sizeof(matrix));
|
||||
#endif
|
||||
|
||||
|
||||
if (parameters & G_MTX_PROJECTION) {
|
||||
if (parameters & G_MTX_LOAD) {
|
||||
memcpy(rsp.P_matrix, matrix, sizeof(matrix));
|
||||
|
@ -519,17 +535,17 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
|
|||
const Vtx_t *v = &vertices[i].v;
|
||||
const Vtx_tn *vn = &vertices[i].n;
|
||||
struct LoadedVertex *d = &rsp.loaded_vertices[dest_index];
|
||||
|
||||
|
||||
float x = v->ob[0] * rsp.MP_matrix[0][0] + v->ob[1] * rsp.MP_matrix[1][0] + v->ob[2] * rsp.MP_matrix[2][0] + rsp.MP_matrix[3][0];
|
||||
float y = v->ob[0] * rsp.MP_matrix[0][1] + v->ob[1] * rsp.MP_matrix[1][1] + v->ob[2] * rsp.MP_matrix[2][1] + rsp.MP_matrix[3][1];
|
||||
float z = v->ob[0] * rsp.MP_matrix[0][2] + v->ob[1] * rsp.MP_matrix[1][2] + v->ob[2] * rsp.MP_matrix[2][2] + rsp.MP_matrix[3][2];
|
||||
float w = v->ob[0] * rsp.MP_matrix[0][3] + v->ob[1] * rsp.MP_matrix[1][3] + v->ob[2] * rsp.MP_matrix[2][3] + rsp.MP_matrix[3][3];
|
||||
|
||||
|
||||
x = gfx_adjust_x_for_aspect_ratio(x);
|
||||
|
||||
|
||||
short U = v->tc[0] * rsp.texture_scaling_factor.s >> 16;
|
||||
short V = v->tc[1] * rsp.texture_scaling_factor.t >> 16;
|
||||
|
||||
|
||||
if (rsp.geometry_mode & G_LIGHTING) {
|
||||
if (rsp.lights_changed) {
|
||||
for (int i = 0; i < rsp.current_num_lights - 1; i++) {
|
||||
|
@ -541,11 +557,11 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
|
|||
calculate_normal_dir(&lookat_y, rsp.current_lookat_coeffs[1]);
|
||||
rsp.lights_changed = false;
|
||||
}
|
||||
|
||||
|
||||
int r = rsp.current_lights[rsp.current_num_lights - 1].col[0];
|
||||
int g = rsp.current_lights[rsp.current_num_lights - 1].col[1];
|
||||
int b = rsp.current_lights[rsp.current_num_lights - 1].col[2];
|
||||
|
||||
|
||||
for (int i = 0; i < rsp.current_num_lights - 1; i++) {
|
||||
float intensity = 0;
|
||||
intensity += vn->n[0] * rsp.current_lights_coeffs[i][0];
|
||||
|
@ -558,11 +574,11 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
|
|||
b += intensity * rsp.current_lights[i].col[2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
d->color.r = r > 255 ? 255 : r;
|
||||
d->color.g = g > 255 ? 255 : g;
|
||||
d->color.b = b > 255 ? 255 : b;
|
||||
|
||||
|
||||
if (rsp.geometry_mode & G_TEXTURE_GEN) {
|
||||
float dotx = 0, doty = 0;
|
||||
dotx += vn->n[0] * rsp.current_lookat_coeffs[0][0];
|
||||
|
@ -571,7 +587,7 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
|
|||
doty += vn->n[0] * rsp.current_lookat_coeffs[1][0];
|
||||
doty += vn->n[1] * rsp.current_lookat_coeffs[1][1];
|
||||
doty += vn->n[2] * rsp.current_lookat_coeffs[1][2];
|
||||
|
||||
|
||||
U = (int32_t)((dotx / 127.0f + 1.0f) / 4.0f * rsp.texture_scaling_factor.s);
|
||||
V = (int32_t)((doty / 127.0f + 1.0f) / 4.0f * rsp.texture_scaling_factor.t);
|
||||
}
|
||||
|
@ -580,10 +596,10 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
|
|||
d->color.g = v->cn[1];
|
||||
d->color.b = v->cn[2];
|
||||
}
|
||||
|
||||
|
||||
d->u = U;
|
||||
d->v = V;
|
||||
|
||||
|
||||
// trivial clip rejection
|
||||
d->clip_rej = 0;
|
||||
if (x < -w) d->clip_rej |= 1;
|
||||
|
@ -592,23 +608,23 @@ static void gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *verti
|
|||
if (y > w) d->clip_rej |= 8;
|
||||
if (z < -w) d->clip_rej |= 16;
|
||||
if (z > w) d->clip_rej |= 32;
|
||||
|
||||
|
||||
d->x = x;
|
||||
d->y = y;
|
||||
d->z = z;
|
||||
d->w = w;
|
||||
|
||||
|
||||
if (rsp.geometry_mode & G_FOG) {
|
||||
if (fabsf(w) < 0.001f) {
|
||||
// To avoid division by zero
|
||||
w = 0.001f;
|
||||
}
|
||||
|
||||
|
||||
float winv = 1.0f / w;
|
||||
if (winv < 0.0f) {
|
||||
winv = 32767.0f;
|
||||
}
|
||||
|
||||
|
||||
float fog_z = z * winv * rsp.fog_mul + rsp.fog_offset;
|
||||
if (fog_z < 0) fog_z = 0;
|
||||
if (fog_z > 255) fog_z = 255;
|
||||
|
@ -624,27 +640,27 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
|
|||
struct LoadedVertex *v2 = &rsp.loaded_vertices[vtx2_idx];
|
||||
struct LoadedVertex *v3 = &rsp.loaded_vertices[vtx3_idx];
|
||||
struct LoadedVertex *v_arr[3] = {v1, v2, v3};
|
||||
|
||||
|
||||
//if (rand()%2) return;
|
||||
|
||||
|
||||
if (v1->clip_rej & v2->clip_rej & v3->clip_rej) {
|
||||
// The whole triangle lies outside the visible area
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ((rsp.geometry_mode & G_CULL_BOTH) != 0) {
|
||||
float dx1 = v1->x / (v1->w) - v2->x / (v2->w);
|
||||
float dy1 = v1->y / (v1->w) - v2->y / (v2->w);
|
||||
float dx2 = v3->x / (v3->w) - v2->x / (v2->w);
|
||||
float dy2 = v3->y / (v3->w) - v2->y / (v2->w);
|
||||
float cross = dx1 * dy2 - dy1 * dx2;
|
||||
|
||||
|
||||
if ((v1->w < 0) ^ (v2->w < 0) ^ (v3->w < 0)) {
|
||||
// If one vertex lies behind the eye, negating cross will give the correct result.
|
||||
// If all vertices lie behind the eye, the triangle will be rejected anyway.
|
||||
cross = -cross;
|
||||
}
|
||||
|
||||
|
||||
switch (rsp.geometry_mode & G_CULL_BOTH) {
|
||||
case G_CULL_FRONT:
|
||||
if (cross <= 0) return;
|
||||
|
@ -657,28 +673,28 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool depth_test = (rsp.geometry_mode & G_ZBUFFER) == G_ZBUFFER;
|
||||
if (depth_test != rendering_state.depth_test) {
|
||||
gfx_flush();
|
||||
gfx_rapi->set_depth_test(depth_test);
|
||||
rendering_state.depth_test = depth_test;
|
||||
}
|
||||
|
||||
|
||||
bool z_upd = (rdp.other_mode_l & Z_UPD) == Z_UPD;
|
||||
if (z_upd != rendering_state.depth_mask) {
|
||||
gfx_flush();
|
||||
gfx_rapi->set_depth_mask(z_upd);
|
||||
rendering_state.depth_mask = z_upd;
|
||||
}
|
||||
|
||||
|
||||
bool zmode_decal = (rdp.other_mode_l & ZMODE_DEC) == ZMODE_DEC;
|
||||
if (zmode_decal != rendering_state.decal_mode) {
|
||||
gfx_flush();
|
||||
gfx_rapi->set_zmode_decal(zmode_decal);
|
||||
rendering_state.decal_mode = zmode_decal;
|
||||
}
|
||||
|
||||
|
||||
if (rdp.viewport_or_scissor_changed) {
|
||||
if (memcmp(&rdp.viewport, &rendering_state.viewport, sizeof(rdp.viewport)) != 0) {
|
||||
gfx_flush();
|
||||
|
@ -692,27 +708,27 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
|
|||
}
|
||||
rdp.viewport_or_scissor_changed = false;
|
||||
}
|
||||
|
||||
|
||||
uint32_t cc_id = rdp.combine_mode;
|
||||
|
||||
|
||||
bool use_alpha = (rdp.other_mode_l & (G_BL_A_MEM << 18)) == 0;
|
||||
bool use_fog = (rdp.other_mode_l >> 30) == G_BL_CLR_FOG;
|
||||
bool texture_edge = (rdp.other_mode_l & CVG_X_ALPHA) == CVG_X_ALPHA;
|
||||
bool use_noise = (rdp.other_mode_l & G_AC_DITHER) == G_AC_DITHER;
|
||||
|
||||
|
||||
if (texture_edge) {
|
||||
use_alpha = true;
|
||||
}
|
||||
|
||||
|
||||
if (use_alpha) cc_id |= SHADER_OPT_ALPHA;
|
||||
if (use_fog) cc_id |= SHADER_OPT_FOG;
|
||||
if (texture_edge) cc_id |= SHADER_OPT_TEXTURE_EDGE;
|
||||
if (use_noise) cc_id |= SHADER_OPT_NOISE;
|
||||
|
||||
|
||||
if (!use_alpha) {
|
||||
cc_id &= ~0xfff000;
|
||||
}
|
||||
|
||||
|
||||
struct ColorCombiner *comb = gfx_lookup_or_create_color_combiner(cc_id);
|
||||
struct ShaderProgram *prg = comb->prg;
|
||||
if (prg != rendering_state.shader_program) {
|
||||
|
@ -729,7 +745,7 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
|
|||
uint8_t num_inputs;
|
||||
bool used_textures[2];
|
||||
gfx_rapi->shader_get_info(prg, &num_inputs, used_textures);
|
||||
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (used_textures[i]) {
|
||||
if (rdp.textures_changed[i]) {
|
||||
|
@ -747,13 +763,13 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool use_texture = used_textures[0] || used_textures[1];
|
||||
uint32_t tex_width = (rdp.texture_tile.lrs - rdp.texture_tile.uls + 4) / 4;
|
||||
uint32_t tex_height = (rdp.texture_tile.lrt - rdp.texture_tile.ult + 4) / 4;
|
||||
|
||||
|
||||
bool z_is_from_0_to_1 = gfx_rapi->z_is_from_0_to_1();
|
||||
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
float z = v_arr[i]->z, w = v_arr[i]->w;
|
||||
if (z_is_from_0_to_1) {
|
||||
|
@ -763,7 +779,7 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
|
|||
buf_vbo[buf_vbo_len++] = v_arr[i]->y;
|
||||
buf_vbo[buf_vbo_len++] = z;
|
||||
buf_vbo[buf_vbo_len++] = w;
|
||||
|
||||
|
||||
if (use_texture) {
|
||||
float u = (v_arr[i]->u - rdp.texture_tile.uls * 8) / 32.0f;
|
||||
float v = (v_arr[i]->v - rdp.texture_tile.ult * 8) / 32.0f;
|
||||
|
@ -775,14 +791,14 @@ static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx) {
|
|||
buf_vbo[buf_vbo_len++] = u / tex_width;
|
||||
buf_vbo[buf_vbo_len++] = v / tex_height;
|
||||
}
|
||||
|
||||
|
||||
if (use_fog) {
|
||||
buf_vbo[buf_vbo_len++] = rdp.fog_color.r / 255.0f;
|
||||
buf_vbo[buf_vbo_len++] = rdp.fog_color.g / 255.0f;
|
||||
buf_vbo[buf_vbo_len++] = rdp.fog_color.b / 255.0f;
|
||||
buf_vbo[buf_vbo_len++] = v_arr[i]->color.a / 255.0f; // fog factor (not alpha)
|
||||
}
|
||||
|
||||
|
||||
for (int j = 0; j < num_inputs; j++) {
|
||||
struct RGBA *color;
|
||||
struct RGBA tmp;
|
||||
|
@ -847,17 +863,17 @@ static void gfx_calc_and_set_viewport(const Vp_t *viewport) {
|
|||
float height = 2.0f * viewport->vscale[1] / 4.0f;
|
||||
float x = (viewport->vtrans[0] / 4.0f) - width / 2.0f;
|
||||
float y = SCREEN_HEIGHT - ((viewport->vtrans[1] / 4.0f) + height / 2.0f);
|
||||
|
||||
|
||||
width *= RATIO_X;
|
||||
height *= RATIO_Y;
|
||||
x *= RATIO_X;
|
||||
y *= RATIO_Y;
|
||||
|
||||
|
||||
rdp.viewport.x = x;
|
||||
rdp.viewport.y = y;
|
||||
rdp.viewport.width = width;
|
||||
rdp.viewport.height = height;
|
||||
|
||||
|
||||
rdp.viewport_or_scissor_changed = true;
|
||||
}
|
||||
|
||||
|
@ -922,12 +938,12 @@ static void gfx_dp_set_scissor(uint32_t mode, uint32_t ulx, uint32_t uly, uint32
|
|||
float y = (SCREEN_HEIGHT - lry / 4.0f) * RATIO_Y;
|
||||
float width = (lrx - ulx) / 4.0f * RATIO_X;
|
||||
float height = (lry - uly) / 4.0f * RATIO_Y;
|
||||
|
||||
|
||||
rdp.scissor.x = x;
|
||||
rdp.scissor.y = y;
|
||||
rdp.scissor.width = width;
|
||||
rdp.scissor.height = height;
|
||||
|
||||
|
||||
rdp.viewport_or_scissor_changed = true;
|
||||
}
|
||||
|
||||
|
@ -937,7 +953,7 @@ static void gfx_dp_set_texture_image(uint32_t format, uint32_t size, uint32_t wi
|
|||
}
|
||||
|
||||
static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t tmem, uint8_t tile, uint32_t palette, uint32_t cmt, uint32_t maskt, uint32_t shiftt, uint32_t cms, uint32_t masks, uint32_t shifts) {
|
||||
|
||||
|
||||
if (tile == G_TX_RENDERTILE) {
|
||||
SUPPORT_CHECK(palette == 0); // palette should set upper 4 bits of color index in 4b mode
|
||||
rdp.texture_tile.fmt = fmt;
|
||||
|
@ -948,7 +964,7 @@ static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t t
|
|||
rdp.textures_changed[0] = true;
|
||||
rdp.textures_changed[1] = true;
|
||||
}
|
||||
|
||||
|
||||
if (tile == G_TX_LOADTILE) {
|
||||
rdp.texture_to_load.tile_number = tmem / 256;
|
||||
}
|
||||
|
@ -976,7 +992,7 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t
|
|||
SUPPORT_CHECK(tile == G_TX_LOADTILE);
|
||||
SUPPORT_CHECK(uls == 0);
|
||||
SUPPORT_CHECK(ult == 0);
|
||||
|
||||
|
||||
// The lrs field rather seems to be number of pixels to load
|
||||
uint32_t word_size_shift;
|
||||
switch (rdp.texture_to_load.siz) {
|
||||
|
@ -996,7 +1012,7 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t
|
|||
uint32_t size_bytes = (lrs + 1) << word_size_shift;
|
||||
rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes;
|
||||
rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr;
|
||||
|
||||
|
||||
rdp.textures_changed[rdp.texture_to_load.tile_number] = true;
|
||||
}
|
||||
|
||||
|
@ -1102,66 +1118,66 @@ static void gfx_dp_set_fill_color(uint32_t packed_color) {
|
|||
static void gfx_draw_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t lry) {
|
||||
uint32_t saved_other_mode_h = rdp.other_mode_h;
|
||||
uint32_t cycle_type = (rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE));
|
||||
|
||||
|
||||
if (cycle_type == G_CYC_COPY) {
|
||||
rdp.other_mode_h = (rdp.other_mode_h & ~(3U << G_MDSFT_TEXTFILT)) | G_TF_POINT;
|
||||
}
|
||||
|
||||
|
||||
// U10.2 coordinates
|
||||
float ulxf = ulx;
|
||||
float ulyf = uly;
|
||||
float lrxf = lrx;
|
||||
float lryf = lry;
|
||||
|
||||
|
||||
ulxf = ulxf / (4.0f * HALF_SCREEN_WIDTH) - 1.0f;
|
||||
ulyf = -(ulyf / (4.0f * HALF_SCREEN_HEIGHT)) + 1.0f;
|
||||
lrxf = lrxf / (4.0f * HALF_SCREEN_WIDTH) - 1.0f;
|
||||
lryf = -(lryf / (4.0f * HALF_SCREEN_HEIGHT)) + 1.0f;
|
||||
|
||||
|
||||
ulxf = gfx_adjust_x_for_aspect_ratio(ulxf);
|
||||
lrxf = gfx_adjust_x_for_aspect_ratio(lrxf);
|
||||
|
||||
|
||||
struct LoadedVertex* ul = &rsp.loaded_vertices[MAX_VERTICES + 0];
|
||||
struct LoadedVertex* ll = &rsp.loaded_vertices[MAX_VERTICES + 1];
|
||||
struct LoadedVertex* lr = &rsp.loaded_vertices[MAX_VERTICES + 2];
|
||||
struct LoadedVertex* ur = &rsp.loaded_vertices[MAX_VERTICES + 3];
|
||||
|
||||
|
||||
ul->x = ulxf;
|
||||
ul->y = ulyf;
|
||||
ul->z = -1.0f;
|
||||
ul->w = 1.0f;
|
||||
|
||||
|
||||
ll->x = ulxf;
|
||||
ll->y = lryf;
|
||||
ll->z = -1.0f;
|
||||
ll->w = 1.0f;
|
||||
|
||||
|
||||
lr->x = lrxf;
|
||||
lr->y = lryf;
|
||||
lr->z = -1.0f;
|
||||
lr->w = 1.0f;
|
||||
|
||||
|
||||
ur->x = lrxf;
|
||||
ur->y = ulyf;
|
||||
ur->z = -1.0f;
|
||||
ur->w = 1.0f;
|
||||
|
||||
|
||||
// The coordinates for texture rectangle shall bypass the viewport setting
|
||||
struct XYWidthHeight default_viewport = {0, 0, gfx_current_dimensions.width, gfx_current_dimensions.height};
|
||||
struct XYWidthHeight viewport_saved = rdp.viewport;
|
||||
uint32_t geometry_mode_saved = rsp.geometry_mode;
|
||||
|
||||
|
||||
rdp.viewport = default_viewport;
|
||||
rdp.viewport_or_scissor_changed = true;
|
||||
rsp.geometry_mode = 0;
|
||||
|
||||
|
||||
gfx_sp_tri1(MAX_VERTICES + 0, MAX_VERTICES + 1, MAX_VERTICES + 3);
|
||||
gfx_sp_tri1(MAX_VERTICES + 1, MAX_VERTICES + 2, MAX_VERTICES + 3);
|
||||
|
||||
|
||||
rsp.geometry_mode = geometry_mode_saved;
|
||||
rdp.viewport = viewport_saved;
|
||||
rdp.viewport_or_scissor_changed = true;
|
||||
|
||||
|
||||
if (cycle_type == G_CYC_COPY) {
|
||||
rdp.other_mode_h = saved_other_mode_h;
|
||||
}
|
||||
|
@ -1173,15 +1189,15 @@ static void gfx_dp_texture_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int3
|
|||
// Per RDP Command Summary Set Tile's shift s and this dsdx should be set to 4 texels
|
||||
// Divide by 4 to get 1 instead
|
||||
dsdx >>= 2;
|
||||
|
||||
|
||||
// Color combiner is turned off in copy mode
|
||||
gfx_dp_set_combine_mode(color_comb(0, 0, 0, G_CCMUX_TEXEL0), color_comb(0, 0, 0, G_ACMUX_TEXEL0));
|
||||
|
||||
|
||||
// Per documentation one extra pixel is added in this modes to each edge
|
||||
lrx += 1 << 2;
|
||||
lry += 1 << 2;
|
||||
}
|
||||
|
||||
|
||||
// uls and ult are S10.5
|
||||
// dsdx and dtdy are S5.10
|
||||
// lrx, lry, ulx, uly are U10.2
|
||||
|
@ -1194,7 +1210,7 @@ static void gfx_dp_texture_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int3
|
|||
int16_t height = !flip ? lry - uly : lrx - ulx;
|
||||
float lrs = ((uls << 7) + dsdx * width) >> 7;
|
||||
float lrt = ((ult << 7) + dtdy * height) >> 7;
|
||||
|
||||
|
||||
struct LoadedVertex* ul = &rsp.loaded_vertices[MAX_VERTICES + 0];
|
||||
struct LoadedVertex* ll = &rsp.loaded_vertices[MAX_VERTICES + 1];
|
||||
struct LoadedVertex* lr = &rsp.loaded_vertices[MAX_VERTICES + 2];
|
||||
|
@ -1214,7 +1230,7 @@ static void gfx_dp_texture_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int3
|
|||
ur->u = uls;
|
||||
ur->v = lrt;
|
||||
}
|
||||
|
||||
|
||||
gfx_draw_rectangle(ulx, uly, lrx, lry);
|
||||
rdp.combine_mode = saved_combine_mode;
|
||||
}
|
||||
|
@ -1225,18 +1241,18 @@ static void gfx_dp_fill_rectangle(int32_t ulx, int32_t uly, int32_t lrx, int32_t
|
|||
return;
|
||||
}
|
||||
uint32_t mode = (rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE));
|
||||
|
||||
|
||||
if (mode == G_CYC_COPY || mode == G_CYC_FILL) {
|
||||
// Per documentation one extra pixel is added in this modes to each edge
|
||||
lrx += 1 << 2;
|
||||
lry += 1 << 2;
|
||||
}
|
||||
|
||||
|
||||
for (int i = MAX_VERTICES; i < MAX_VERTICES + 4; i++) {
|
||||
struct LoadedVertex* v = &rsp.loaded_vertices[i];
|
||||
v->color = rdp.fill_color;
|
||||
}
|
||||
|
||||
|
||||
uint32_t saved_combine_mode = rdp.combine_mode;
|
||||
gfx_dp_set_combine_mode(color_comb(0, 0, 0, G_CCMUX_SHADE), color_comb(0, 0, 0, G_ACMUX_SHADE));
|
||||
gfx_draw_rectangle(ulx, uly, lrx, lry);
|
||||
|
@ -1270,7 +1286,7 @@ static void gfx_run_dl(Gfx* cmd) {
|
|||
int dummy = 0;
|
||||
for (;;) {
|
||||
uint32_t opcode = cmd->words.w0 >> 24;
|
||||
|
||||
|
||||
switch (opcode) {
|
||||
// RSP commands:
|
||||
case G_MTX:
|
||||
|
@ -1369,7 +1385,7 @@ static void gfx_run_dl(Gfx* cmd) {
|
|||
gfx_sp_set_other_mode(C0(8, 8) + 32, C0(0, 8), (uint64_t) cmd->words.w1 << 32);
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
||||
// RDP Commands:
|
||||
case G_SETTIMG:
|
||||
gfx_dp_set_texture_image(C0(21, 3), C0(19, 2), C0(0, 10), seg_addr(cmd->words.w1));
|
||||
|
@ -1487,7 +1503,7 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, co
|
|||
gfx_rapi = rapi;
|
||||
gfx_wapi->init(window_title);
|
||||
gfx_rapi->init();
|
||||
|
||||
|
||||
// Used in the 120 star TAS
|
||||
static uint32_t precomp_shaders[] = {
|
||||
0x01200200,
|
||||
|
@ -1543,15 +1559,15 @@ void gfx_start_frame(void) {
|
|||
|
||||
void gfx_run(Gfx *commands) {
|
||||
gfx_sp_reset();
|
||||
|
||||
|
||||
//puts("New frame");
|
||||
|
||||
|
||||
if (!gfx_wapi->start_frame()) {
|
||||
dropped_frame = true;
|
||||
return;
|
||||
}
|
||||
dropped_frame = false;
|
||||
|
||||
|
||||
double t0 = gfx_wapi->get_time();
|
||||
gfx_rapi->start_frame();
|
||||
gfx_run_dl(commands);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef GFX_PC_H
|
||||
#define GFX_PC_H
|
||||
|
||||
#include <PR/gbi.h>
|
||||
|
||||
struct GfxRenderingAPI;
|
||||
struct GfxWindowManagerAPI;
|
||||
|
||||
|
@ -9,6 +11,21 @@ struct GfxDimensions {
|
|||
float aspect_ratio;
|
||||
};
|
||||
|
||||
# define MAX_CACHED_TEXTURES 4096 // for preloading purposes
|
||||
# define HASH_SHIFT 0
|
||||
|
||||
#define HASHMAP_LEN (MAX_CACHED_TEXTURES * 2)
|
||||
#define HASH_MASK (HASHMAP_LEN - 1)
|
||||
|
||||
struct TextureData {
|
||||
const uint8_t *texture_addr;
|
||||
uint8_t fmt, siz;
|
||||
|
||||
uint32_t texture_id;
|
||||
uint8_t cms, cmt;
|
||||
char linear_filter;
|
||||
};
|
||||
|
||||
extern struct GfxDimensions gfx_current_dimensions;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -22,7 +39,7 @@ void gfx_run(Gfx *commands);
|
|||
void gfx_end_frame(void);
|
||||
void gfx_precache_textures(void);
|
||||
void gfx_shutdown(void);
|
||||
|
||||
void overload_memory_texture(void* data, long size, const char *path);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -192,7 +192,6 @@ 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);
|
||||
|
||||
if (gCLIOpts.FullScreen == 1)
|
||||
|
@ -251,12 +250,11 @@ void main_func(char *argv[]) {
|
|||
thread5_game_loop(NULL);
|
||||
inited = true;
|
||||
|
||||
// precache data if needed
|
||||
if (configPrecacheRes) {
|
||||
fprintf(stdout, "precaching data\n");
|
||||
fflush(stdout);
|
||||
gfx_precache_textures();
|
||||
}
|
||||
fprintf(stdout, "precaching data\n");
|
||||
fflush(stdout);
|
||||
gfx_precache_textures();
|
||||
moon_mod_engine_preinit();
|
||||
moon_mod_engine_init();
|
||||
|
||||
#ifdef DISCORDRPC
|
||||
discord_init();
|
||||
|
|
Loading…
Reference in New Issue