mirror of https://github.com/sm64pc/sm64pc.git
250 lines
8.4 KiB
C++
250 lines
8.4 KiB
C++
#include "addons-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 "moon/mod-engine/audio/mod-audio.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 MoonAddonsScreen::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 MoonAddonsScreen::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);
|
|
//MoonInternal::buildAudioCache(order);
|
|
//MoonInternal::resetSoundSystem();
|
|
}
|
|
|
|
void MoonAddonsScreen::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 MoonAddonsScreen::Update(){
|
|
float yStick = GetStickValue(MoonButtons::U_STICK, false);
|
|
if(yStick > 5) {
|
|
if(dispatched) return;
|
|
if(currentPack != NULL){
|
|
if(currentSubItem > 0)
|
|
currentSubItem--;
|
|
else
|
|
currentSubItem = 2;
|
|
dispatched = true;
|
|
return;
|
|
}
|
|
MoonAddonsScreen::changeScroll(-1);
|
|
dispatched = true;
|
|
}
|
|
if(yStick < -5) {
|
|
if(dispatched) return;
|
|
if(currentPack != NULL){
|
|
if(currentSubItem < 2)
|
|
currentSubItem++;
|
|
else
|
|
currentSubItem = 0;
|
|
dispatched = true;
|
|
return;
|
|
}
|
|
MoonAddonsScreen::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]);
|
|
MoonAddonsScreen::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]);
|
|
MoonAddonsScreen::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);
|
|
}
|
|
|
|
if(!(gGlobalTimer % 20))
|
|
stickAnim = !stickAnim;
|
|
|
|
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 MoonAddonsScreen::Draw(){
|
|
string curTitle = "Addons";
|
|
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");
|
|
}
|
|
|
|
string basePath = "textures/moon/controller/";
|
|
basePath.append(stickAnim ? "stick-down.rgba16" : "stick-up.rgba16");
|
|
|
|
MoonDrawButton(5, GetScreenHeight() - 24, "Move", basePath, 16, 0, false, false);
|
|
}
|
|
|
|
MoonScreen::Draw();
|
|
} |