* Added button indicators to options menu
* Added toggleable level of detail * Fixed and enhanced discord rpc * Fixed lenguage select menu * [WIP] Started barebones marketplace view * Fixed bugs
|
@ -67,6 +67,7 @@ moon64config.txt
|
|||
/sound/**/*.m64
|
||||
/sound/**/*.aiff
|
||||
!/textures/special/*.png
|
||||
!/textures/moon/*.png
|
||||
!/textures/icons/*.png
|
||||
!/levels/**/*custom*.png
|
||||
!/levels/**/*custom*/**/*.png
|
||||
|
|
|
@ -1851,7 +1851,7 @@ void play_dialog_sound(u8 dialogID) {
|
|||
}
|
||||
|
||||
void set_sequence_player_volume(s32 player, f32 volume) {
|
||||
gSequencePlayers[player].volumeScale = volume;
|
||||
gSequencePlayers[player].volumeScale = pow(volume, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "save_file.h"
|
||||
#include "skybox.h"
|
||||
#include "sound_init.h"
|
||||
#include "pc/configfile.h"
|
||||
|
||||
#define TOAD_STAR_1_REQUIREMENT 12
|
||||
#define TOAD_STAR_2_REQUIREMENT 25
|
||||
|
@ -346,8 +347,7 @@ Gfx *geo_switch_mario_stand_run(s32 callContext, struct GraphNode *node, UNUSED
|
|||
struct MarioBodyState *bodyState = &gBodyStates[switchCase->numCases];
|
||||
|
||||
if (callContext == GEO_CONTEXT_RENDER) {
|
||||
// assign result. 0 if moving, 1 if stationary.
|
||||
switchCase->selectedCase = ((bodyState->action & ACT_FLAG_STATIONARY) == FALSE);
|
||||
switchCase->selectedCase = configLODMode == 1 ? 1 : ((bodyState->action & ACT_FLAG_STATIONARY) == FALSE);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "rendering_graph_node.h"
|
||||
#include "shadow.h"
|
||||
#include "sm64.h"
|
||||
#include "pc/configfile.h"
|
||||
|
||||
/**
|
||||
* This file contains the code that processes the scene graph for rendering.
|
||||
|
@ -272,6 +273,11 @@ static void geo_process_level_of_detail(struct GraphNodeLevelOfDetail *node) {
|
|||
Mtx *mtx = gMatStackFixed[gMatStackIndex];
|
||||
s16 distanceFromCam = (s32) -mtx->m[3][2]; // z-component of the translation column
|
||||
|
||||
if(configLODMode == 1)
|
||||
distanceFromCam = 30000;
|
||||
if(configLODMode == 2)
|
||||
distanceFromCam = 0;
|
||||
|
||||
if (node->minDistance <= distanceFromCam && distanceFromCam < node->maxDistance) {
|
||||
if (node->node.children != 0) {
|
||||
geo_process_node_and_siblings(node->node.children);
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "moon/utils/moon-env.h"
|
||||
#ifdef DISCORDRPC
|
||||
#include "pc/discord/discordrpc.h"
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
@ -165,6 +168,9 @@ namespace Moon {
|
|||
dialogPool = current->dialogs.data();
|
||||
seg2_act_name_table = current->acts.data();
|
||||
seg2_course_name_table = current->courses.data();
|
||||
#ifdef DISCORDRPC
|
||||
DiscordUpdatePresence(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
string getLanguageKey(string key){
|
||||
|
|
|
@ -11,13 +11,17 @@ extern "C" {
|
|||
#include "audio/external.h"
|
||||
}
|
||||
|
||||
int scrollWidgetModifier = 0;
|
||||
|
||||
void MoonScreen::Init(){
|
||||
this->scrollIndex = 0;
|
||||
this->selected = NULL;
|
||||
|
||||
if(this->enabledWidgets)
|
||||
for(int i = 0; i < widgets.size(); i++)
|
||||
for(int i = 0; i < widgets.size(); i++){
|
||||
widgets[i]->Init();
|
||||
widgets[i]->parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
void MoonScreen::Mount(){
|
||||
|
@ -27,6 +31,7 @@ void MoonScreen::Mount(){
|
|||
for(int i = 0; i < widgets.size(); i++) {
|
||||
widgets[i]->selected = false;
|
||||
widgets[i]->focused = false;
|
||||
widgets[i]->parent = this;
|
||||
}
|
||||
MoonWidget* sel = this->widgets[this->scrollIndex];
|
||||
sel->selected = true;
|
||||
|
@ -35,13 +40,54 @@ void MoonScreen::Mount(){
|
|||
}
|
||||
|
||||
void MoonScreen::Draw(){
|
||||
if(this->enabledWidgets)
|
||||
if(this->enabledWidgets){
|
||||
for(int i = 0; i < widgets.size(); i++)
|
||||
widgets[i]->Draw();
|
||||
//int widgetAmount = widgets.size();
|
||||
//int maxWidgets = 8;
|
||||
//int iMod = scrollWidgetModifier;
|
||||
|
||||
//for(int i = 0; i < min(widgetAmount, maxWidgets); i++){
|
||||
// int index = i + iMod;
|
||||
|
||||
// if(index > widgetAmount - 1){
|
||||
// this->scrollIndex = 0;
|
||||
// scrollWidgetModifier = 0;
|
||||
// return;
|
||||
// }
|
||||
|
||||
// widgets[index]->parent = this;
|
||||
// widgets[index]->Draw();
|
||||
// widgets[index]->mY = 15 * iMod;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
bool stickExecuted;
|
||||
|
||||
|
||||
void MoonScreen::changeScroll(int idx){
|
||||
if(idx < 0){
|
||||
if(this->scrollIndex > 0){
|
||||
if(scrollWidgetModifier > 0 && this->scrollIndex == scrollWidgetModifier)
|
||||
scrollWidgetModifier--;
|
||||
this->scrollIndex--;
|
||||
return;
|
||||
}
|
||||
this->scrollIndex = this->widgets.size() - 1;
|
||||
scrollWidgetModifier = this->scrollIndex - 4;
|
||||
return;
|
||||
}
|
||||
if(this->scrollIndex < this->widgets.size() - 1){
|
||||
if(this->scrollIndex > 3 && !((this->scrollIndex - scrollWidgetModifier) % 4)) scrollWidgetModifier++;
|
||||
this->scrollIndex++;
|
||||
return;
|
||||
}
|
||||
|
||||
this->scrollIndex = 0;
|
||||
scrollWidgetModifier = 0;
|
||||
}
|
||||
|
||||
void MoonScreen::Update(){
|
||||
if(this->enabledWidgets && !this->widgets.empty()) {
|
||||
if(this->useMouseInstead){
|
||||
|
@ -70,10 +116,9 @@ void MoonScreen::Update(){
|
|||
if(stickExecuted) return;
|
||||
if(this->selected != NULL) return;
|
||||
this->widgets[this->scrollIndex]->selected = false;
|
||||
if(this->scrollIndex > 0)
|
||||
this->scrollIndex--;
|
||||
else
|
||||
this->scrollIndex = this->widgets.size() - 1;
|
||||
|
||||
MoonScreen::changeScroll(-1);
|
||||
|
||||
this->widgets[this->scrollIndex]->selected = true;
|
||||
stickExecuted = true;
|
||||
}
|
||||
|
@ -81,10 +126,9 @@ void MoonScreen::Update(){
|
|||
if(stickExecuted) return;
|
||||
if(this->selected != NULL) return;
|
||||
this->widgets[this->scrollIndex]->selected = false;
|
||||
if(this->scrollIndex < this->widgets.size() - 1)
|
||||
this->scrollIndex++;
|
||||
else
|
||||
this->scrollIndex = 0;
|
||||
|
||||
MoonScreen::changeScroll(1);
|
||||
|
||||
this->widgets[this->scrollIndex]->selected = true;
|
||||
stickExecuted = true;
|
||||
}
|
||||
|
@ -102,8 +146,10 @@ void MoonScreen::Update(){
|
|||
this->selected = NULL;
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < widgets.size(); i++)
|
||||
for(int i = 0; i < widgets.size(); i++){
|
||||
widgets[i]->parent = this;
|
||||
widgets[i]->Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,7 +181,8 @@ float GetStickValue(MoonButtons button, bool absolute){
|
|||
}
|
||||
|
||||
float GetScreenWidth(bool u4_3){
|
||||
return GFX_DIMENSIONS_ASPECT_RATIO > 1 || !u4_3 ? SCREEN_WIDTH + abs(GFX_DIMENSIONS_FROM_LEFT_EDGE(0)) * 2 : SCREEN_WIDTH;
|
||||
int brds = GFX_DIMENSIONS_FROM_LEFT_EDGE(0);
|
||||
return ceil(brds < 0 && !u4_3 ? SCREEN_WIDTH + abs(brds) * 2 : SCREEN_WIDTH - abs(brds) * 2);
|
||||
}
|
||||
|
||||
float GetScreenHeight() {
|
||||
|
|
|
@ -16,17 +16,19 @@ enum MoonButtons {
|
|||
|
||||
class MoonScreen {
|
||||
protected:
|
||||
std::vector<MoonWidget*> widgets;
|
||||
MoonWidget* selected;
|
||||
bool enabledWidgets = true;
|
||||
bool useMouseInstead = false; // unused
|
||||
int scrollIndex = 0;
|
||||
public:
|
||||
std::vector<MoonWidget*> widgets;
|
||||
MoonWidget* selected;
|
||||
int scrollIndex = 0;
|
||||
virtual void Init();
|
||||
virtual void Mount();
|
||||
virtual void Draw();
|
||||
virtual void Update();
|
||||
virtual void Dispose();
|
||||
private:
|
||||
void changeScroll(int idx);
|
||||
};
|
||||
|
||||
bool IsBtnPressed(MoonButtons button);
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
#ifndef MoonWidgetInterface
|
||||
#define MoonWidgetInterface
|
||||
|
||||
class MoonWidget {
|
||||
class MoonScreen;
|
||||
class MoonWidget {
|
||||
public:
|
||||
float x;
|
||||
float y;
|
||||
float mY;
|
||||
bool enabled = true;
|
||||
bool centered = true;
|
||||
bool selectable = true;
|
||||
bool selected = false;
|
||||
bool focused = false;
|
||||
MoonScreen *parent;
|
||||
virtual void Init(){}
|
||||
virtual void Draw(){}
|
||||
virtual void Update(){}
|
||||
|
|
|
@ -11,15 +11,18 @@ extern "C" {
|
|||
#include "pc/pc_main.h"
|
||||
}
|
||||
|
||||
int languageIdx;
|
||||
vector<string> lngNames;
|
||||
vector<string> modes = {
|
||||
"Auto", "Low", "Disabled"
|
||||
};
|
||||
|
||||
MGameCategory::MGameCategory() : MoonCategory("TEXT_OPT_GAME"){
|
||||
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::setCurrentLanguage(Moon::languages[languageIdx]);
|
||||
|
||||
this->catOptions.push_back(new MWValue(22, 57, "TEXT_OPT_LANGUAGE", {.index = reinterpret_cast<int*>(&configLanguage), .values = &lngNames, .callback = [](){
|
||||
Moon::setCurrentLanguage(Moon::languages[configLanguage]);
|
||||
}}, true));
|
||||
this->catOptions.push_back(new MWValue(22, 74, "TEXT_OPT_PRECACHE", {.bvar = &configPrecacheRes}, true));
|
||||
int exitY;
|
||||
|
@ -29,8 +32,9 @@ MGameCategory::MGameCategory() : MoonCategory("TEXT_OPT_GAME"){
|
|||
#else
|
||||
exitY = 91;
|
||||
#endif
|
||||
this->catOptions.push_back(new MWValue(22, exitY, "Texture Packs", { .btn = [](){
|
||||
this->catOptions.push_back(new MWValue(22, exitY, "Level of detail", {.index = reinterpret_cast<int*>(&configLODMode), .values = &modes }, false));
|
||||
this->catOptions.push_back(new MWValue(22, exitY + 17, "Texture Packs", { .btn = [](){
|
||||
MoonChangeUI(1);
|
||||
}}, false));
|
||||
this->catOptions.push_back(new MWValue(22, exitY + 17, "TEXT_EXIT_GAME", { .btn = game_exit}, true));
|
||||
this->catOptions.push_back(new MWValue(22, exitY + 34, "TEXT_EXIT_GAME", { .btn = game_exit}, true));
|
||||
}
|
|
@ -24,6 +24,8 @@ extern "C" {
|
|||
#include "gfx_dimensions.h"
|
||||
#include "pc/configfile.h"
|
||||
#include "audio/external.h"
|
||||
#include "game/game_init.h"
|
||||
#include "pc/platform.h"
|
||||
}
|
||||
|
||||
vector<MoonCategory*> categories;
|
||||
|
@ -55,7 +57,13 @@ void MoonOptMain::Mount(){
|
|||
MoonScreen::Mount();
|
||||
}
|
||||
|
||||
bool stickAnim = 0;
|
||||
|
||||
void MoonOptMain::Update(){
|
||||
|
||||
if(!(gGlobalTimer % 20))
|
||||
stickAnim = !stickAnim;
|
||||
|
||||
if(this->selected == NULL) {
|
||||
if(IsBtnPressed(MoonButtons::B_BTN)){
|
||||
isOpen = false;
|
||||
|
@ -85,6 +93,19 @@ void MoonOptMain::Update(){
|
|||
MoonScreen::Update();
|
||||
}
|
||||
|
||||
void drawButton(int x, int y, string text, string texture, int size, int offset, bool rtl){
|
||||
if(!rtl){
|
||||
MoonDrawTexture(GFX_DIMENSIONS_FROM_LEFT_EDGE(x), y - 3 + offset, size, size, sys_strdup(texture.c_str()));
|
||||
MoonDrawText(x + 16 + 3, y, text, 0.8, {255, 255, 255, 255}, true, false);
|
||||
} else {
|
||||
x = GetScreenWidth(false) - x;
|
||||
int txtWidth = MoonGetTextWidth(text, 0.8, false);
|
||||
|
||||
MoonDrawTexture(GFX_DIMENSIONS_FROM_LEFT_EDGE(x) - txtWidth - size - 3, y - 3 + offset, size, size, sys_strdup(texture.c_str()));
|
||||
MoonDrawText(x - txtWidth, y, text, 0.8, {255, 255, 255, 255}, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
void MoonOptMain::Draw(){
|
||||
string curTitle = categories[categoryIndex]->titleKey ? Moon::getLanguageKey(categories[categoryIndex]->categoryName) : categories[categoryIndex]->categoryName;
|
||||
|
||||
|
@ -93,6 +114,18 @@ void MoonOptMain::Draw(){
|
|||
MoonDrawColoredText(SCREEN_WIDTH / 2 - txtWidth / 2, 20, curTitle, 1.0, {255, 255, 255, 255}, true, true);
|
||||
MoonDrawRectangle(25, 50, SCREEN_WIDTH - 50, GetScreenHeight() * 0.6, {0, 0, 0, 100}, true);
|
||||
|
||||
string stickTexture = "textures/moon/";
|
||||
|
||||
if(this->selected == NULL){
|
||||
stickTexture.append(stickAnim ? "stick-down.rgba16" : "stick-up.rgba16");
|
||||
drawButton(5, GetScreenHeight() - 24, "Move", stickTexture, 16, 0, false);
|
||||
} else{
|
||||
stickTexture.append(stickAnim ? "stick-left.rgba16" : "stick-right.rgba16");
|
||||
drawButton(5, GetScreenHeight() - 24, "Change value", stickTexture, 16, 0, false);
|
||||
}
|
||||
|
||||
drawButton(7, GetScreenHeight() - 24, this->selected == NULL ? "Select" : "Back", this->selected == NULL ? "textures/moon/a-alt-btn.rgba16" : "textures/moon/b-alt-btn.rgba16", 10, 4, true);
|
||||
|
||||
MoonScreen::Draw();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,238 @@
|
|||
#include "store-view.h"
|
||||
#include <iostream>
|
||||
#include "moon/ui/utils/moon-draw-utils.h"
|
||||
#include "moon/ui/moon-ui-manager.h"
|
||||
#include "moon/mod-engine/engine.h"
|
||||
#include "moon/mod-engine/textures/mod-texture.h"
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" {
|
||||
#include "sm64.h"
|
||||
#include "gfx_dimensions.h"
|
||||
#include "pc/configfile.h"
|
||||
}
|
||||
|
||||
BitModule* currentPack;
|
||||
vector<BitModule*> texturePackList;
|
||||
|
||||
int scrollModifier = 0;
|
||||
|
||||
int currentSubItem = 0;
|
||||
int focusFlag;
|
||||
int focusRange = 80;
|
||||
float focusAnim = focusRange / 2;
|
||||
|
||||
enum ItemButtons{
|
||||
UP,
|
||||
DOWN,
|
||||
TOGGLE
|
||||
};
|
||||
|
||||
void MoonStoreScreen::Init(){
|
||||
if(texturePackList.empty()){
|
||||
texturePackList.clear();
|
||||
copy(Moon::addons.begin(), Moon::addons.end(), back_inserter(texturePackList));
|
||||
reverse(texturePackList.begin(), texturePackList.end());
|
||||
}
|
||||
this->scrollIndex = 0;
|
||||
scrollModifier = 0;
|
||||
currentPack = NULL;
|
||||
}
|
||||
|
||||
void MoonStoreScreen::Mount(){
|
||||
|
||||
}
|
||||
|
||||
bool dispatched;
|
||||
|
||||
void rebuildTextureCache(){
|
||||
vector<int> order;
|
||||
for(auto &addon : texturePackList){
|
||||
vector<BitModule*>::iterator itr = find(Moon::addons.begin(), Moon::addons.end(), addon);
|
||||
order.push_back(distance(Moon::addons.begin(), itr));
|
||||
}
|
||||
reverse(order.begin(), order.end());
|
||||
MoonInternal::buildTextureCache(order);
|
||||
}
|
||||
|
||||
void MoonStoreScreen::changeScroll(int idx){
|
||||
if(idx < 0){
|
||||
if(this->scrollIndex > 0){
|
||||
if(scrollModifier > 0 && this->scrollIndex == scrollModifier)
|
||||
scrollModifier--;
|
||||
this->scrollIndex--;
|
||||
return;
|
||||
}
|
||||
this->scrollIndex = texturePackList.size() - 1;
|
||||
scrollModifier = this->scrollIndex - 4;
|
||||
return;
|
||||
}
|
||||
if(this->scrollIndex < texturePackList.size() - 1){
|
||||
if(this->scrollIndex > 3 && !((this->scrollIndex - scrollModifier) % 4)) scrollModifier++;
|
||||
this->scrollIndex++;
|
||||
return;
|
||||
}
|
||||
this->scrollIndex = 0;
|
||||
scrollModifier = 0;
|
||||
}
|
||||
|
||||
void MoonStoreScreen::Update(){
|
||||
float yStick = GetStickValue(MoonButtons::U_STICK, false);
|
||||
if(yStick > 0) {
|
||||
if(dispatched) return;
|
||||
if(currentPack != NULL){
|
||||
if(currentSubItem > 0)
|
||||
currentSubItem--;
|
||||
else
|
||||
currentSubItem = 2;
|
||||
dispatched = true;
|
||||
return;
|
||||
}
|
||||
MoonStoreScreen::changeScroll(-1);
|
||||
dispatched = true;
|
||||
}
|
||||
if(yStick < 0) {
|
||||
if(dispatched) return;
|
||||
if(currentPack != NULL){
|
||||
if(currentSubItem < 2)
|
||||
currentSubItem++;
|
||||
else
|
||||
currentSubItem = 0;
|
||||
dispatched = true;
|
||||
return;
|
||||
}
|
||||
MoonStoreScreen::changeScroll(1);
|
||||
dispatched = true;
|
||||
}
|
||||
if(!yStick)
|
||||
dispatched = false;
|
||||
|
||||
if(IsBtnPressed(MoonButtons::A_BTN)) {
|
||||
if(currentPack != NULL){
|
||||
switch(currentSubItem){
|
||||
case ItemButtons::UP:
|
||||
if(this->scrollIndex > 0){
|
||||
std::swap(texturePackList[this->scrollIndex], texturePackList[this->scrollIndex - 1]);
|
||||
MoonStoreScreen::changeScroll(-1);
|
||||
currentPack = texturePackList[this->scrollIndex];
|
||||
rebuildTextureCache();
|
||||
}
|
||||
break;
|
||||
case ItemButtons::DOWN:
|
||||
if(this->scrollIndex < texturePackList.size() - 1){
|
||||
std::swap(texturePackList[this->scrollIndex], texturePackList[this->scrollIndex + 1]);
|
||||
MoonStoreScreen::changeScroll(1);
|
||||
currentPack = texturePackList[this->scrollIndex];
|
||||
rebuildTextureCache();
|
||||
}
|
||||
break;
|
||||
case ItemButtons::TOGGLE:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
currentPack = texturePackList[this->scrollIndex];
|
||||
currentSubItem = 0;
|
||||
}
|
||||
if(IsBtnPressed(MoonButtons::B_BTN)) {
|
||||
if(currentPack != NULL){
|
||||
currentPack = NULL;
|
||||
return;
|
||||
}
|
||||
MoonChangeUI(0);
|
||||
}
|
||||
MoonScreen::Update();
|
||||
}
|
||||
|
||||
static std::string cropTxt(string txt, int length){
|
||||
int currLngt = min((int) txt.length(), length);
|
||||
string desc = txt.substr(0, currLngt);
|
||||
desc.erase(find_if(desc.rbegin(), desc.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), desc.end());
|
||||
return currLngt >= length ? desc + " ..." : desc;
|
||||
}
|
||||
|
||||
char *strdup(const char *src_str) noexcept {
|
||||
char *new_str = new char[std::strlen(src_str) + 1];
|
||||
std::strcpy(new_str, src_str);
|
||||
return new_str;
|
||||
}
|
||||
|
||||
void MoonStoreScreen::Draw(){
|
||||
string curTitle = "Texture packs";
|
||||
float step = 1.5;
|
||||
|
||||
if(focusAnim >= focusRange)
|
||||
focusFlag = 1;
|
||||
else if (focusAnim <= focusRange / 2)
|
||||
focusFlag = 0;
|
||||
|
||||
focusAnim += step * (focusFlag ? -1 : 1);
|
||||
|
||||
int boxWidth = SCREEN_WIDTH - 50;
|
||||
int boxHeight = GetScreenHeight() * 0.8;
|
||||
|
||||
float txtWidth = MoonGetTextWidth(curTitle, 1.0, true);
|
||||
|
||||
MoonDrawRectangle(0, 0, GetScreenWidth(false), GetScreenHeight(), {0, 0, 0, 100}, false);
|
||||
MoonDrawColoredText(SCREEN_WIDTH / 2 - txtWidth / 2, 10, curTitle, 1.0, {255, 255, 255, 255}, true, true);
|
||||
MoonDrawRectangle(25, 35, boxWidth, boxHeight, {0, 0, 0, 100}, true);
|
||||
|
||||
Color focusColor = {255, 255, 255, 40 + focusAnim};
|
||||
|
||||
int packAmount = texturePackList.size();
|
||||
int maxPacks = 5;
|
||||
int iMod = scrollModifier;
|
||||
|
||||
for(int i = 0; i < min(packAmount, maxPacks); i++){
|
||||
int index = i + iMod;
|
||||
|
||||
if(index > packAmount - 1){
|
||||
this->scrollIndex = 0;
|
||||
scrollModifier = 0;
|
||||
cout << "Triggered overflow, coming back to 0" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
auto &addon = texturePackList[index];
|
||||
|
||||
if(addon == NULL) return;
|
||||
|
||||
bool selected = (i + iMod) == this->scrollIndex && currentPack != NULL;
|
||||
int itemWidth = boxWidth - (selected ? 15 : 0);
|
||||
|
||||
MoonDrawRectangle(35, 45 + (i * 35), itemWidth - 20, 31, (i + iMod) == this->scrollIndex && !selected ? focusColor : (Color){0, 0, 0, 100}, true);
|
||||
string pathPrefix = "mod-icons://";
|
||||
string iconPath = pathPrefix.append(addon->name);
|
||||
char* parsed = strdup(iconPath.c_str());
|
||||
if(parsed != nullptr)
|
||||
MoonDrawTexture(35, 45 + (i * 35), 30, 30, parsed);
|
||||
MoonDrawText(35 + 26, 46 + (i * 35), to_string(i + iMod + 1), 0.5, {255, 255, 255, 255}, true, true);
|
||||
|
||||
MoonDrawText(70, 45 + (i * 35) + 3, cropTxt(addon->name, 37), 0.8, {255, 255, 255, 255}, true, true);
|
||||
|
||||
int maxDesc = 37;
|
||||
int currLngt = min((int) addon->description.length(), maxDesc);
|
||||
MoonDrawText(70, 45 + (i * 35) + 16, cropTxt(addon->description, 37), 0.8, {255, 255, 255, 255}, true, true);
|
||||
|
||||
string rawVer = to_string(addon->version);
|
||||
string version = "v"+rawVer.substr(0, rawVer.find(".")+2);
|
||||
|
||||
MoonDrawText(itemWidth + 13 - MoonGetTextWidth(version, 0.5, false), 45 + (i * 35) + 2, version, 0.5, {255, 255, 255, 255}, true, true);
|
||||
MoonDrawText(itemWidth + 13 - MoonGetTextWidth(addon->authors[0], 0.5, false), 45 + (i * 35) + 22, addon->authors[0], 0.5, {255, 255, 255, 255}, true, true);
|
||||
|
||||
if(selected){
|
||||
MoonDrawRectangle(itemWidth + 16, 45 + (i * 35), 13, 9.3, currentSubItem == ItemButtons::UP ? focusColor : (Color){0, 0, 0, 100}, true);
|
||||
MoonDrawTexture (itemWidth + 18, 45 + (i * 35), 8, 8, "textures/special/up.rgba16");
|
||||
|
||||
MoonDrawRectangle(itemWidth + 16, 45 + (i * 35) + 10.9, 13, 9.3, currentSubItem == ItemButtons::DOWN ? focusColor : (Color){0, 0, 0, 100}, true);
|
||||
MoonDrawTexture (itemWidth + 18, 46 + (i * 35) + 10.9, 8, 8, "textures/special/down.rgba16");
|
||||
|
||||
MoonDrawRectangle(itemWidth + 16, 45 + (i * 35) + 21.7, 13, 9.3, currentSubItem == ItemButtons::TOGGLE ? focusColor : (Color){0, 0, 0, 100}, true);
|
||||
MoonDrawTexture (itemWidth + 18, 46 + (i * 35) + 21.7, 8, 8, "textures/special/remove.rgba16");
|
||||
}
|
||||
}
|
||||
|
||||
MoonScreen::Draw();
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef MoonScreenStore
|
||||
#define MoonScreenStore
|
||||
#include "moon/ui/interfaces/moon-screen.h"
|
||||
|
||||
class MoonStoreScreen : public MoonScreen {
|
||||
public:
|
||||
void Init();
|
||||
void Update();
|
||||
void Draw();
|
||||
void Mount();
|
||||
private:
|
||||
void changeScroll(int idx);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,5 @@
|
|||
#ifndef UVServicesAPI
|
||||
#define UVServicesAPI
|
||||
|
||||
|
||||
#endif
|
|
@ -100,6 +100,14 @@ bool configHUD = true;
|
|||
bool configDiscordRPC = true;
|
||||
#endif
|
||||
|
||||
/*
|
||||
################################
|
||||
# Moon64 Configuration #
|
||||
################################
|
||||
*/
|
||||
|
||||
unsigned int configLODMode = 0;
|
||||
|
||||
static const struct ConfigOption options[] = {
|
||||
{.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configWindow.fullscreen},
|
||||
{.name = "window_x", .type = CONFIG_TYPE_UINT, .uintValue = &configWindow.x},
|
||||
|
@ -148,7 +156,8 @@ static const struct ConfigOption options[] = {
|
|||
{.name = "skip_intro", .type = CONFIG_TYPE_BOOL, .boolValue = &configSkipIntro},
|
||||
#ifdef DISCORDRPC
|
||||
{.name = "discordrpc_enable", .type = CONFIG_TYPE_BOOL, .boolValue = &configDiscordRPC},
|
||||
#endif
|
||||
#endif
|
||||
{.name = "lodMode", .type = CONFIG_TYPE_UINT, .uintValue = &configLODMode},
|
||||
};
|
||||
|
||||
// Reads an entire line from a file (excluding the newline character) and returns an allocated string
|
||||
|
|
|
@ -62,6 +62,8 @@ extern bool configSkipIntro;
|
|||
extern bool configDiscordRPC;
|
||||
#endif
|
||||
|
||||
extern unsigned int configLODMode;
|
||||
|
||||
void configfile_load(const char *filename);
|
||||
void configfile_save(const char *filename);
|
||||
const char *configfile_name(void);
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "macros.h"
|
||||
#include "PR/ultratypes.h"
|
||||
|
@ -9,7 +11,9 @@
|
|||
#include "game/save_file.h"
|
||||
#include "pc/configfile.h"
|
||||
#include "discordrpc.h"
|
||||
#include "text/text-loader.h"
|
||||
#include "moon/texts/moon-loader.h"
|
||||
#include "moon/utils/moon-env.h"
|
||||
|
||||
#define DISCORDLIBFILE "libdiscord-rpc"
|
||||
|
||||
// Thanks Microsoft for being non posix compliant
|
||||
|
@ -34,10 +38,10 @@
|
|||
#define DISCORD_APP_ID "709083908708237342"
|
||||
#define DISCORD_UPDATE_RATE 5
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern s16 gCurrCourseNum;
|
||||
extern s16 gCurrActNum;
|
||||
extern u8 seg2_course_name_table[];
|
||||
extern u8 seg2_act_name_table[];
|
||||
|
||||
static time_t lastUpdatedTime;
|
||||
|
||||
|
@ -46,14 +50,20 @@ static bool initd = false;
|
|||
|
||||
static void* handle;
|
||||
|
||||
void (*Discord_Initialize)(const char *, DiscordEventHandlers *, int, const char *);
|
||||
void (*Discord_Shutdown)(void);
|
||||
void (*Discord_ClearPresence)(void);
|
||||
void (*Discord_UpdatePresence)(DiscordRichPresence *);
|
||||
typedef void (*Discord_Initialize)(const char *, DiscordEventHandlers *, int, const char *);
|
||||
typedef void (*Discord_Shutdown)(void);
|
||||
typedef void (*Discord_ClearPresence)(void);
|
||||
typedef void (*Discord_UpdatePresence)(DiscordRichPresence *);
|
||||
|
||||
Discord_Initialize discordInit;
|
||||
Discord_Shutdown discordShutdown;
|
||||
Discord_ClearPresence discordClearPresence;
|
||||
Discord_UpdatePresence discordUpdatePresence;
|
||||
|
||||
static s16 lastCourseNum = -1;
|
||||
static s16 lastActNum = -1;
|
||||
|
||||
bool reloadRPC = false;
|
||||
static char stage[188];
|
||||
static char act[188];
|
||||
|
||||
|
@ -141,33 +151,16 @@ static void init_discord(void) {
|
|||
memset(&handlers, 0, sizeof(handlers));
|
||||
handlers.ready = on_ready;
|
||||
|
||||
Discord_Initialize(DISCORD_APP_ID, &handlers, false, "");
|
||||
discordInit(DISCORD_APP_ID, &handlers, false, "");
|
||||
|
||||
initd = true;
|
||||
}
|
||||
|
||||
static void set_details(void) {
|
||||
if (lastCourseNum != gCurrCourseNum) {
|
||||
if (lastCourseNum != gCurrCourseNum || reloadRPC) {
|
||||
// If we are in in Course 0 we are in the castle which doesn't have a string
|
||||
if (gCurrCourseNum) {
|
||||
void **courseNameTbl;
|
||||
|
||||
#ifndef VERSION_EU
|
||||
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
||||
#else
|
||||
switch (gInGameLanguage) {
|
||||
case LANGUAGE_ENGLISH:
|
||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
||||
break;
|
||||
case LANGUAGE_FRENCH:
|
||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
||||
break;
|
||||
case LANGUAGE_GERMAN:
|
||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
u8 *courseName = segmented_to_virtual(courseNameTbl[gCurrCourseNum - 1]);
|
||||
u8 *courseName = Moon::current->courses[gCurrCourseNum - 1];
|
||||
|
||||
convertstring(&courseName[3], stage);
|
||||
} else {
|
||||
|
@ -179,28 +172,12 @@ static void set_details(void) {
|
|||
}
|
||||
|
||||
static void set_state(void) {
|
||||
if (lastActNum != gCurrActNum || lastCourseNum != gCurrCourseNum) {
|
||||
if (lastActNum != gCurrActNum || lastCourseNum != gCurrCourseNum || reloadRPC) {
|
||||
// when exiting a stage the act doesn't get reset
|
||||
if (gCurrActNum && gCurrCourseNum) {
|
||||
// any stage over 19 is a special stage without acts
|
||||
if (gCurrCourseNum < COURSE_STAGES_MAX) {
|
||||
void **actNameTbl;
|
||||
#ifndef VERSION_EU
|
||||
actNameTbl = segmented_to_virtual(seg2_act_name_table);
|
||||
#else
|
||||
switch (gInGameLanguage) {
|
||||
case LANGUAGE_ENGLISH:
|
||||
actNameTbl = segmented_to_virtual(act_name_table_eu_en);
|
||||
break;
|
||||
case LANGUAGE_FRENCH:
|
||||
actNameTbl = segmented_to_virtual(act_name_table_eu_fr);
|
||||
break;
|
||||
case LANGUAGE_GERMAN:
|
||||
actNameTbl = segmented_to_virtual(act_name_table_eu_de);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
u8 *actName = actName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + gCurrActNum - 1]);
|
||||
u8 *actName = actName = Moon::current->acts[(gCurrCourseNum - 1) * 6 + gCurrActNum - 1];
|
||||
|
||||
convertstring(actName, act);
|
||||
} else {
|
||||
|
@ -221,51 +198,53 @@ void set_logo(void) {
|
|||
else
|
||||
strcpy(largeImageKey, "0");
|
||||
|
||||
/*
|
||||
if (lastActNum)
|
||||
snprintf(smallImageKey, sizeof(largeImageKey), "%d", lastActNum);
|
||||
else
|
||||
smallImageKey[0] = '\0';
|
||||
*/
|
||||
|
||||
discordRichPresence.largeImageKey = largeImageKey;
|
||||
//discordRichPresence.largeImageText = "";
|
||||
//discordRichPresence.smallImageKey = smallImageKey;
|
||||
//discordRichPresence.smallImageText = "";
|
||||
}
|
||||
|
||||
void discord_update_rich_presence(void) {
|
||||
void DiscordUpdatePresence(bool force){
|
||||
if(force)
|
||||
reloadRPC = true;
|
||||
if (!configDiscordRPC || !initd) return;
|
||||
if (time(NULL) < lastUpdatedTime + DISCORD_UPDATE_RATE) return;
|
||||
|
||||
lastUpdatedTime = time(NULL);
|
||||
|
||||
set_state();
|
||||
set_details();
|
||||
set_logo();
|
||||
Discord_UpdatePresence(&discordRichPresence);
|
||||
discordUpdatePresence(&discordRichPresence);
|
||||
reloadRPC = false;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void discord_update_rich_presence(bool force) {
|
||||
DiscordUpdatePresence(force);
|
||||
}
|
||||
|
||||
void discord_shutdown(void) {
|
||||
if (handle) {
|
||||
Discord_ClearPresence();
|
||||
Discord_Shutdown();
|
||||
discordClearPresence();
|
||||
discordShutdown();
|
||||
dlclose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
void discord_init(void) {
|
||||
if (configDiscordRPC) {
|
||||
handle = dlopen(DISCORDLIB, RTLD_LAZY);
|
||||
string cwd = MoonInternal::getEnvironmentVar("MOON_CWD");
|
||||
string libPath = cwd.substr(0, cwd.find_last_of("/\\")) + "/lib/discord/" + DISCORDLIB;
|
||||
|
||||
cout << "Loading discord lib from " << libPath << endl;
|
||||
|
||||
handle = dlopen(libPath.c_str(), RTLD_LAZY);
|
||||
if (!handle) {
|
||||
fprintf(stderr, "Unable to load Discord\n%s\n", dlerror());
|
||||
return;
|
||||
}
|
||||
|
||||
Discord_Initialize = dlsym(handle, "Discord_Initialize");
|
||||
Discord_Shutdown = dlsym(handle, "Discord_Shutdown");
|
||||
Discord_ClearPresence = dlsym(handle, "Discord_ClearPresence");
|
||||
Discord_UpdatePresence = dlsym(handle, "Discord_UpdatePresence");
|
||||
discordInit = (Discord_Initialize) dlsym(handle, "Discord_Initialize");
|
||||
discordShutdown = (Discord_Shutdown) dlsym(handle, "Discord_Shutdown");
|
||||
discordClearPresence = (Discord_ClearPresence) dlsym(handle, "Discord_ClearPresence");
|
||||
discordUpdatePresence = (Discord_UpdatePresence) dlsym(handle, "Discord_UpdatePresence");
|
||||
|
||||
init_discord();
|
||||
|
||||
|
@ -275,6 +254,7 @@ void discord_init(void) {
|
|||
lastUpdatedTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void discord_reset(void) {
|
||||
memset( &discordRichPresence, 0, sizeof( discordRichPresence ) );
|
||||
|
@ -282,5 +262,5 @@ void discord_reset(void) {
|
|||
set_state();
|
||||
set_details();
|
||||
set_logo();
|
||||
Discord_UpdatePresence(&discordRichPresence);
|
||||
}
|
||||
discordUpdatePresence(&discordRichPresence);
|
||||
}
|
|
@ -40,10 +40,14 @@ typedef struct DiscordEventHandlers {
|
|||
#define DISCORD_REPLY_NO 0
|
||||
#define DISCORD_REPLY_YES 1
|
||||
#define DISCORD_REPLY_IGNORE 2
|
||||
|
||||
void discord_update_rich_presence(void);
|
||||
void discord_shutdown(void);
|
||||
void discord_init(void);
|
||||
void discord_reset(void);
|
||||
|
||||
#endif // DISCORDRPC_H
|
||||
#ifndef __cplusplus
|
||||
void discord_update_rich_presence(bool force);
|
||||
void discord_shutdown(void);
|
||||
void discord_init(void);
|
||||
#else
|
||||
void DiscordUpdatePresence(bool force);
|
||||
#endif
|
||||
|
||||
#endif // DISCORDRPC_H
|
||||
|
|
|
@ -266,7 +266,7 @@ void main_func(char *argv[]) {
|
|||
while (true) {
|
||||
wm_api->main_loop(produce_one_frame);
|
||||
#ifdef DISCORDRPC
|
||||
discord_update_rich_presence();
|
||||
discord_update_rich_presence(0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
After Width: | Height: | Size: 712 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 698 B |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.0 KiB |