mirror of
https://github.com/Vita3K/Vita3K.git
synced 2026-07-11 01:34:23 +02:00
emulator: Refactor file structure (#557)
Also: - external: update some submodules.
This commit is contained in:
committed by
Nick Renieris
parent
dd195445cc
commit
06299de242
@@ -0,0 +1,3 @@
|
||||
add_executable(gen-modules gen-modules.cpp)
|
||||
target_link_libraries(gen-modules PRIVATE yaml)
|
||||
add_dependencies(gen-modules vita-headers)
|
||||
@@ -0,0 +1,190 @@
|
||||
// Vita3K emulator project
|
||||
// Copyright (C) 2018 Vita3K team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace YAML;
|
||||
|
||||
typedef std::map<std::string, std::string> Functions;
|
||||
typedef std::map<std::string, Functions> Libraries;
|
||||
typedef std::map<std::string, Libraries> Modules;
|
||||
typedef Functions::value_type Function;
|
||||
typedef Libraries::value_type Library;
|
||||
typedef Modules::value_type Module;
|
||||
|
||||
static const std::string indent(" ");
|
||||
|
||||
static std::string dedupe(const std::string &name, const std::set<std::string> existing) {
|
||||
std::string candidate = name;
|
||||
while (existing.find(candidate) != existing.end()) {
|
||||
candidate += "_dupe";
|
||||
}
|
||||
|
||||
return candidate;
|
||||
}
|
||||
|
||||
static Modules parse_db(const Node &db) {
|
||||
Modules modules;
|
||||
std::set<std::string> functions;
|
||||
|
||||
for (const auto &module : db["modules"]) {
|
||||
const auto module_name = module.first.as<std::string>();
|
||||
|
||||
for (const auto &library : module.second["libraries"]) {
|
||||
const auto library_name = library.first.as<std::string>();
|
||||
const bool kernel = library.second["kernel"].as<bool>();
|
||||
if (kernel) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto &function : library.second["functions"]) {
|
||||
const auto original_name = function.first.as<std::string>();
|
||||
const auto deduped_name = dedupe(original_name, functions);
|
||||
const auto function_nid = function.second.as<std::string>();
|
||||
|
||||
modules[module_name][library_name][deduped_name] = function_nid;
|
||||
functions.insert(deduped_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modules;
|
||||
}
|
||||
|
||||
static void gen_license_comment(std::ostream &dst) {
|
||||
dst << "// Vita3K emulator project" << std::endl;
|
||||
dst << "// Copyright (C) 2018 Vita3K team" << std::endl;
|
||||
dst << "//" << std::endl;
|
||||
dst << "// This program is free software; you can redistribute it and/or modify" << std::endl;
|
||||
dst << "// it under the terms of the GNU General Public License as published by" << std::endl;
|
||||
dst << "// the Free Software Foundation; either version 2 of the License, or" << std::endl;
|
||||
dst << "// (at your option) any later version." << std::endl;
|
||||
dst << "//" << std::endl;
|
||||
dst << "// This program is distributed in the hope that it will be useful," << std::endl;
|
||||
dst << "// but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl;
|
||||
dst << "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << std::endl;
|
||||
dst << "// GNU General Public License for more details." << std::endl;
|
||||
dst << "//" << std::endl;
|
||||
dst << "// You should have received a copy of the GNU General Public License along" << std::endl;
|
||||
dst << "// with this program; if not, write to the Free Software Foundation, Inc.," << std::endl;
|
||||
dst << "// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA." << std::endl;
|
||||
dst << std::endl;
|
||||
}
|
||||
|
||||
static void gen_nids_h(const Modules &modules) {
|
||||
std::ofstream out("src/emulator/nids/include/nids/nids.h");
|
||||
gen_license_comment(out);
|
||||
|
||||
for (const Module &module : modules) {
|
||||
out << "// Module \"" << module.first << "\"" << std::endl;
|
||||
|
||||
for (const Library &library : module.second) {
|
||||
out << "// Library \"" << library.first << "\"" << std::endl;
|
||||
|
||||
for (const auto &function : library.second) {
|
||||
out << "NID(" << function.first << ", " << function.second << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_library_cpp(std::ostream &dst, const Library &library) {
|
||||
gen_license_comment(dst);
|
||||
dst << "#include \"" << library.first << ".h\"" << std::endl;
|
||||
|
||||
for (const Function &function : library.second) {
|
||||
dst << std::endl;
|
||||
dst << "EXPORT(int, " << function.first << ") {" << std::endl;
|
||||
dst << indent << "return UNIMPLEMENTED();" << std::endl;
|
||||
dst << "}" << std::endl;
|
||||
}
|
||||
|
||||
dst << std::endl;
|
||||
for (const Function &function : library.second) {
|
||||
dst << "BRIDGE_IMPL(" << function.first << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_library_h(std::ostream &dst, const Library &library) {
|
||||
gen_license_comment(dst);
|
||||
dst << "#pragma once" << std::endl;
|
||||
dst << std::endl;
|
||||
dst << "#include <module/module.h>" << std::endl;
|
||||
dst << std::endl;
|
||||
|
||||
for (const auto &function : library.second) {
|
||||
dst << "BRIDGE_DECL(" << function.first << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_module_stubs(const Modules &modules) {
|
||||
for (const Module &module : modules) {
|
||||
const std::string module_path = "src/emulator/modules/" + module.first;
|
||||
|
||||
#ifdef WIN32
|
||||
CreateDirectoryA(module_path.c_str(), nullptr);
|
||||
#else
|
||||
const int mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
|
||||
mkdir(module_path.c_str(), mode);
|
||||
#endif
|
||||
|
||||
for (const Library &library : module.second) {
|
||||
const std::string library_cpp_path = module_path + "/" + library.first + ".cpp";
|
||||
const std::string library_h_path = module_path + "/" + library.first + ".h";
|
||||
std::ofstream library_cpp(library_cpp_path.c_str());
|
||||
gen_library_cpp(library_cpp, library);
|
||||
std::ofstream library_h(library_h_path.c_str());
|
||||
gen_library_h(library_h, library);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gen_modules_cmakelists(const Modules &modules) {
|
||||
std::ofstream out("src/emulator/modules/CMakeLists.txt");
|
||||
out << "add_library(modules STATIC";
|
||||
|
||||
for (const Module &module : modules) {
|
||||
for (const Library &library : module.second) {
|
||||
out << "\n\t" << module.first << "/" << library.first << ".cpp";
|
||||
out << " " << module.first << "/" << library.first << ".h";
|
||||
}
|
||||
}
|
||||
|
||||
out << ")" << std::endl;
|
||||
out << "target_link_libraries(modules PRIVATE module)" << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
const Node db = LoadFile("src/external/vita-headers/db.yml");
|
||||
const Modules modules = parse_db(db);
|
||||
|
||||
gen_nids_h(modules);
|
||||
gen_module_stubs(modules);
|
||||
gen_modules_cmakelists(modules);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
PHONY := all package clean
|
||||
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
|
||||
|
||||
CC := arm-vita-eabi-gcc
|
||||
CXX := arm-vita-eabi-g++
|
||||
STRIP := arm-vita-eabi-strip
|
||||
|
||||
PROJECT_TITLE := NativeTool
|
||||
PROJECT_TITLEID := FFFF00001
|
||||
|
||||
PROJECT := native-tool
|
||||
CXXFLAGS += -std=c++11
|
||||
|
||||
SRC_C :=$(call rwildcard, src/, *.c)
|
||||
SRC_CPP :=$(call rwildcard, src/, *.cpp)
|
||||
SRC_GXP :=$(call rwildcard, src/, *.gxp)
|
||||
|
||||
OBJ_DIRS := $(addprefix out/, $(dir $(SRC_C:src/%.c=%.o))) $(addprefix out/, $(dir $(SRC_CPP:src/%.cpp=%.o)))
|
||||
OBJS := $(addprefix out/, $(SRC_C:src/%.c=%.o)) $(addprefix out/, $(SRC_CPP:src/%.cpp=%.o))
|
||||
GXP_HS := $(SRC_GXP:%.gxp=%.h)
|
||||
|
||||
.SECONDARY: $(GXP_HS)
|
||||
|
||||
all: package
|
||||
|
||||
package: $(PROJECT).vpk
|
||||
|
||||
$(PROJECT).vpk: eboot.bin param.sfo
|
||||
vita-pack-vpk -s param.sfo -b eboot.bin \
|
||||
--add sce_sys/icon0.png=sce_sys/icon0.png \
|
||||
--add sce_sys/livearea/contents/bg.png=sce_sys/livearea/contents/bg.png \
|
||||
--add sce_sys/livearea/contents/startup.png=sce_sys/livearea/contents/startup.png \
|
||||
--add sce_sys/livearea/contents/template.xml=sce_sys/livearea/contents/template.xml \
|
||||
$(PROJECT).vpk
|
||||
|
||||
eboot.bin: $(PROJECT).velf
|
||||
vita-make-fself $(PROJECT).velf eboot.bin
|
||||
|
||||
param.sfo:
|
||||
vita-mksfoex -s TITLE_ID="$(PROJECT_TITLEID)" "$(PROJECT_TITLE)" param.sfo
|
||||
|
||||
$(PROJECT).velf: $(PROJECT).elf
|
||||
$(STRIP) -g $<
|
||||
vita-elf-create $< $@
|
||||
|
||||
$(PROJECT).elf: $(OBJS)
|
||||
$(CXX) -Wl,-q -o $@ $^ -lSceGxm_stub
|
||||
|
||||
$(OBJ_DIRS):
|
||||
mkdir -p $@
|
||||
|
||||
out/%.o : src/%.cpp | $(OBJ_DIRS) $(GXP_HS)
|
||||
echo $(SRC_GXP)
|
||||
arm-vita-eabi-g++ -c $(CXXFLAGS) -o $@ $<
|
||||
|
||||
out/%.o : src/%.c | $(OBJ_DIRS) $(GXP_HS)
|
||||
arm-vita-eabi-g++ -c -o $@ $<
|
||||
|
||||
%.h : %.gxp
|
||||
xxd -i <$< >$@
|
||||
|
||||
clean:
|
||||
rm -f $(PROJECT).velf $(PROJECT).elf $(PROJECT).vpk param.sfo eboot.bin $(OBJS) $(GXP_HS)
|
||||
rm -r $(abspath $(OBJ_DIRS))
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 324 B |
Binary file not shown.
|
After Width: | Height: | Size: 928 B |
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<livearea style="a1" format-ver="01.00" content-rev="1">
|
||||
<livearea-background>
|
||||
<image>bg.png</image>
|
||||
</livearea-background>
|
||||
|
||||
<gate>
|
||||
<startup-image>startup.png</startup-image>
|
||||
</gate>
|
||||
</livearea>
|
||||
@@ -0,0 +1,139 @@
|
||||
// Vita3K emulator project
|
||||
// Copyright (C) 2018 Vita3K team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
#include <psp2/gxm.h>
|
||||
#include <psp2/kernel/processmgr.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static const uint8_t clear_f_gxp[] = {
|
||||
#include "shaders/clear_f.h"
|
||||
};
|
||||
|
||||
static const uint8_t clear_v_gxp[] = {
|
||||
#include "shaders/clear_v.h"
|
||||
};
|
||||
|
||||
static const uint8_t color_f_gxp[] = {
|
||||
#include "shaders/color_f.h"
|
||||
};
|
||||
|
||||
static const uint8_t color_v_gxp[] = {
|
||||
#include "shaders/color_v.h"
|
||||
};
|
||||
|
||||
static const uint8_t texture_f_gxp[] = {
|
||||
#include "shaders/texture_f.h"
|
||||
};
|
||||
|
||||
static const uint8_t texture_tint_f_gxp[] = {
|
||||
#include "shaders/texture_tint_f.h"
|
||||
};
|
||||
|
||||
static const uint8_t texture_v_gxp[] = {
|
||||
#include "shaders/texture_v.h"
|
||||
};
|
||||
|
||||
static void check(int result, const char *function, FILE *fp) {
|
||||
if (result != 0) {
|
||||
fprintf(fp, "%s failed (%d, 0x%x).\n", function, result, result);
|
||||
|
||||
fclose(fp);
|
||||
fp = nullptr;
|
||||
|
||||
sceKernelExitProcess(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void dump(FILE *fp, const SceGxmProgram *program, const char *name) {
|
||||
fprintf(fp, "Program %s at address %p:\n", name, program);
|
||||
|
||||
const unsigned int size = sceGxmProgramGetSize(program);
|
||||
const SceGxmProgramType type = sceGxmProgramGetType(program);
|
||||
const SceBool is_discard_used = sceGxmProgramIsDiscardUsed(program);
|
||||
const SceBool is_depth_replace_used = sceGxmProgramIsDepthReplaceUsed(program);
|
||||
const SceBool is_sprite_coord_used = sceGxmProgramIsSpriteCoordUsed(program);
|
||||
const unsigned int default_uniform_buffer_size = sceGxmProgramGetDefaultUniformBufferSize(program);
|
||||
const unsigned int param_count = sceGxmProgramGetParameterCount(program);
|
||||
|
||||
fprintf(fp, "\tSize = %u\n", size);
|
||||
fprintf(fp, "\tType = %u\n", type);
|
||||
fprintf(fp, "\tIs discard used? = %u\n", is_discard_used);
|
||||
fprintf(fp, "\tIs depth replace used? = %u\n", is_depth_replace_used);
|
||||
fprintf(fp, "\tIs sprite coord used? = %u\n", is_sprite_coord_used);
|
||||
fprintf(fp, "\tDefault uniform buffer size = %u\n", default_uniform_buffer_size);
|
||||
fprintf(fp, "\t%u parameter(s)\n", param_count);
|
||||
|
||||
for (unsigned int param_index = 0; param_index < param_count; ++param_index) {
|
||||
const SceGxmProgramParameter *const parameter = sceGxmProgramGetParameter(program, param_index);
|
||||
const int offset = reinterpret_cast<const char *>(parameter) - reinterpret_cast<const char *>(program);
|
||||
fprintf(fp, "\tParameter %u at address %p (offset = %d)\n", param_index, parameter, offset);
|
||||
|
||||
const SceGxmParameterCategory category = sceGxmProgramParameterGetCategory(parameter);
|
||||
const char *const name = sceGxmProgramParameterGetName(parameter);
|
||||
const SceGxmParameterSemantic semantic = sceGxmProgramParameterGetSemantic(parameter);
|
||||
const unsigned int semantic_index = sceGxmProgramParameterGetSemanticIndex(parameter);
|
||||
const SceGxmParameterType param_type = sceGxmProgramParameterGetType(parameter);
|
||||
const unsigned int component_count = sceGxmProgramParameterGetComponentCount(parameter);
|
||||
const unsigned int array_size = sceGxmProgramParameterGetArraySize(parameter);
|
||||
const unsigned int resource_index = sceGxmProgramParameterGetResourceIndex(parameter);
|
||||
const unsigned int container_index = sceGxmProgramParameterGetContainerIndex(parameter);
|
||||
const SceBool is_sampler_cube = sceGxmProgramParameterIsSamplerCube(parameter);
|
||||
|
||||
fprintf(fp, "\t\tCategory = %u\n", category);
|
||||
fprintf(fp, "\t\tName = %s\n", name);
|
||||
fprintf(fp, "\t\tSemantic = %u\n", semantic);
|
||||
fprintf(fp, "\t\tSemantic index = %u\n", semantic_index);
|
||||
fprintf(fp, "\t\tType = %u\n", param_type);
|
||||
fprintf(fp, "\t\tComponent count = %u\n", component_count);
|
||||
fprintf(fp, "\t\tArray size = %u\n", array_size);
|
||||
fprintf(fp, "\t\tResource index = %u\n", resource_index);
|
||||
fprintf(fp, "\t\tContainer index = %u\n", container_index);
|
||||
fprintf(fp, "\t\tIs sampler cube = %u\n", is_sampler_cube);
|
||||
}
|
||||
}
|
||||
|
||||
static void display_callback(const void *data) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
FILE *fp = fopen("ux0:/data/hello.txt", "w");
|
||||
if (fp == nullptr) {
|
||||
sceKernelExitProcess(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fprintf(fp, "Started.\n");
|
||||
|
||||
SceGxmInitializeParams params = {};
|
||||
params.displayQueueCallback = &display_callback;
|
||||
params.displayQueueCallbackDataSize = 4;
|
||||
params.displayQueueMaxPendingCount = 2;
|
||||
params.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE;
|
||||
|
||||
check(sceGxmInitialize(¶ms), "sceGxmInitialize", fp);
|
||||
#define SHADER(name) dump(fp, reinterpret_cast<const SceGxmProgram *>(name##_gxp), #name);
|
||||
#include "shaders.h"
|
||||
#undef SHADER
|
||||
|
||||
fprintf(fp, "Exiting normally.\n");
|
||||
fclose(fp);
|
||||
fp = nullptr;
|
||||
|
||||
sceKernelExitProcess(0);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Vita3K emulator project
|
||||
// Copyright (C) 2018 Vita3K team
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
SHADER(clear_f)
|
||||
SHADER(clear_v)
|
||||
SHADER(color_f)
|
||||
SHADER(color_v)
|
||||
SHADER(texture_f)
|
||||
SHADER(texture_tint_f)
|
||||
SHADER(texture_v)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user