Add Welcome Screen
This commit is contained in:
parent
3088a13725
commit
0e44bb5f06
@ -78,5 +78,8 @@ mcpi_option(APP_TITLE "App Title" STRING "${DEFAULT_APP_TITLE}")
|
|||||||
# Skin Server
|
# Skin Server
|
||||||
mcpi_option(SKIN_SERVER "Skin Server" STRING "https://raw.githubusercontent.com/MCPI-Revival/Skins/data")
|
mcpi_option(SKIN_SERVER "Skin Server" STRING "https://raw.githubusercontent.com/MCPI-Revival/Skins/data")
|
||||||
|
|
||||||
# Discord Invite
|
# Discord Invite URL
|
||||||
mcpi_option(DISCORD_INVITE "Discord Invite URL" STRING "https://discord.gg/mcpi-revival-740287937727561779")
|
mcpi_option(DISCORD_INVITE "Discord Invite URL" STRING "https://discord.gg/mcpi-revival-740287937727561779")
|
||||||
|
|
||||||
|
# Documentation URL
|
||||||
|
mcpi_option(DOCUMENTATION "Documentation URL" STRING "https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/src/branch/master/docs/")
|
@ -67,3 +67,4 @@ TRUE Optimized Chunk Sorting
|
|||||||
TRUE Fix Held Item Caching
|
TRUE Fix Held Item Caching
|
||||||
TRUE Add Reborn Info To Options
|
TRUE Add Reborn Info To Options
|
||||||
FALSE Track FPS
|
FALSE Track FPS
|
||||||
|
TRUE Add Welcome Screen
|
@ -15,3 +15,4 @@
|
|||||||
#cmakedefine MCPI_SKIN_SERVER "@MCPI_SKIN_SERVER@"
|
#cmakedefine MCPI_SKIN_SERVER "@MCPI_SKIN_SERVER@"
|
||||||
#cmakedefine MCPI_USE_QEMU
|
#cmakedefine MCPI_USE_QEMU
|
||||||
#cmakedefine MCPI_DISCORD_INVITE "@MCPI_DISCORD_INVITE@"
|
#cmakedefine MCPI_DISCORD_INVITE "@MCPI_DISCORD_INVITE@"
|
||||||
|
#cmakedefine MCPI_DOCUMENTATION "@MCPI_DOCUMENTATION@"
|
||||||
|
@ -94,6 +94,7 @@ else()
|
|||||||
# title-screen
|
# title-screen
|
||||||
src/title-screen/title-screen.cpp
|
src/title-screen/title-screen.cpp
|
||||||
src/title-screen/splashes.txt # Show In IDE
|
src/title-screen/splashes.txt # Show In IDE
|
||||||
|
src/title-screen/welcome.cpp
|
||||||
# skin
|
# skin
|
||||||
src/skin/skin.cpp
|
src/skin/skin.cpp
|
||||||
src/skin/loader.cpp
|
src/skin/loader.cpp
|
||||||
|
9
mods/include/mods/options/info.h
Normal file
9
mods/include/mods/options/info.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define CHANGELOG_FILE "CHANGELOG.md"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
void open_url(const std::string &url);
|
||||||
|
}
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <mods/touch/touch.h>
|
#include <mods/touch/touch.h>
|
||||||
#include <mods/misc/misc.h>
|
#include <mods/misc/misc.h>
|
||||||
|
#include <mods/options/info.h>
|
||||||
|
|
||||||
#include "options-internal.h"
|
#include "options-internal.h"
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ static info_line info[] = {
|
|||||||
.get_text = []() {
|
.get_text = []() {
|
||||||
return std::string("Version: v") + reborn_get_version() + extra_version_info_full;
|
return std::string("Version: v") + reborn_get_version() + extra_version_info_full;
|
||||||
},
|
},
|
||||||
.button_url = "https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/src/branch/master/docs/CHANGELOG.md",
|
.button_url = MCPI_DOCUMENTATION CHANGELOG_FILE,
|
||||||
.button_text = "Changelog"
|
.button_text = "Changelog"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -77,7 +78,7 @@ static info_line info[] = {
|
|||||||
.get_text = []() {
|
.get_text = []() {
|
||||||
return std::string("Sound Data: ") + info_sound_data_state;
|
return std::string("Sound Data: ") + info_sound_data_state;
|
||||||
},
|
},
|
||||||
.button_url = "https://gitea.thebrokenrail.com/minecraft-pi-reborn/minecraft-pi-reborn/src/branch/master/docs/SOUND.md",
|
.button_url = MCPI_DOCUMENTATION "SOUND.md",
|
||||||
.button_text = "More Info"
|
.button_text = "More Info"
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -148,7 +149,7 @@ static void position_info(Font *font, int width, int height) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open URL
|
// Open URL
|
||||||
static void open_url(const std::string &url) {
|
void open_url(const std::string &url) {
|
||||||
int return_code;
|
int return_code;
|
||||||
const char *command[] = {"xdg-open", url.c_str(), nullptr};
|
const char *command[] = {"xdg-open", url.c_str(), nullptr};
|
||||||
char *output = run_command(command, &return_code, nullptr);
|
char *output = run_command(command, &return_code, nullptr);
|
||||||
|
3
mods/src/title-screen/title-screen-internal.h
Normal file
3
mods/src/title-screen/title-screen-internal.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
__attribute__((visibility("internal"))) void _init_welcome();
|
@ -11,6 +11,8 @@
|
|||||||
#include <mods/touch/touch.h>
|
#include <mods/touch/touch.h>
|
||||||
#include <mods/title-screen/title-screen.h>
|
#include <mods/title-screen/title-screen.h>
|
||||||
|
|
||||||
|
#include "title-screen-internal.h"
|
||||||
|
|
||||||
// Improved Title Screen Background
|
// Improved Title Screen Background
|
||||||
static void StartMenuScreen_render_Screen_renderBackground_injection(Screen *screen) {
|
static void StartMenuScreen_render_Screen_renderBackground_injection(Screen *screen) {
|
||||||
// Draw
|
// Draw
|
||||||
@ -165,4 +167,9 @@ void init_title_screen() {
|
|||||||
// Init Random
|
// Init Random
|
||||||
srand(time(nullptr));
|
srand(time(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Init Welcome Screen
|
||||||
|
if (feature_has("Add Welcome Screen", server_disabled)) {
|
||||||
|
_init_welcome();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
150
mods/src/title-screen/welcome.cpp
Normal file
150
mods/src/title-screen/welcome.cpp
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#include <libreborn/libreborn.h>
|
||||||
|
#include <symbols/minecraft.h>
|
||||||
|
|
||||||
|
#include <mods/home/home.h>
|
||||||
|
#include <mods/touch/touch.h>
|
||||||
|
#include <mods/options/info.h>
|
||||||
|
|
||||||
|
#include "title-screen-internal.h"
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
static std::string line1 = "Welcome to " MCPI_APP_BASE_TITLE " v" MCPI_VERSION "!";
|
||||||
|
static int line_height = 8;
|
||||||
|
static int button_width = 120;
|
||||||
|
static int button_height = 24;
|
||||||
|
static int line_padding = 28;
|
||||||
|
static int button_padding = 4;
|
||||||
|
|
||||||
|
// Track Whether To Show Screen
|
||||||
|
static std::string get_tracker_file() {
|
||||||
|
return std::string(home_get()) + "/.welcome-tracker";
|
||||||
|
}
|
||||||
|
static bool should_show_welcome() {
|
||||||
|
// Open File
|
||||||
|
std::ifstream stream(get_tracker_file());
|
||||||
|
if (!stream) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// Read Line
|
||||||
|
std::string line;
|
||||||
|
std::getline(stream, line);
|
||||||
|
bool invalid = line != MCPI_VERSION;
|
||||||
|
// Close File
|
||||||
|
stream.close();
|
||||||
|
// Return
|
||||||
|
return invalid;
|
||||||
|
}
|
||||||
|
static void mark_welcome_as_shown() {
|
||||||
|
// Open File
|
||||||
|
std::ofstream stream(get_tracker_file());
|
||||||
|
if (!stream) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Write
|
||||||
|
stream << MCPI_VERSION << std::endl;
|
||||||
|
// Close File
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Position GUI
|
||||||
|
static Button *getting_started;
|
||||||
|
static Button *changelog;
|
||||||
|
static Button *proceed;
|
||||||
|
static int text_y;
|
||||||
|
static void position_screen(int width, int height) {
|
||||||
|
// Width/Height
|
||||||
|
getting_started->width = changelog->width = proceed->width = button_width;
|
||||||
|
getting_started->height = changelog->height = proceed->height = button_height;
|
||||||
|
// X
|
||||||
|
proceed->x = (width / 2) - (button_width / 2);
|
||||||
|
getting_started->x = (width / 2) - button_padding - button_width;
|
||||||
|
changelog->x = (width / 2) + button_padding;
|
||||||
|
// Y
|
||||||
|
text_y = 0;
|
||||||
|
getting_started->y = changelog->y = line_height + line_padding;
|
||||||
|
proceed->y = getting_started->y + button_height + (button_padding * 2);
|
||||||
|
// Center
|
||||||
|
int content_height = proceed->y + proceed->height;
|
||||||
|
int y_offset = (height - content_height) / 2;
|
||||||
|
text_y += y_offset;
|
||||||
|
getting_started->y += y_offset;
|
||||||
|
changelog->y += y_offset;
|
||||||
|
proceed->y += y_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Welcome Screen
|
||||||
|
CUSTOM_VTABLE(welcome_screen, Screen) {
|
||||||
|
// Init
|
||||||
|
vtable->init = [](__attribute__((unused)) Screen *self) {
|
||||||
|
// Buttons
|
||||||
|
getting_started = touch_create_button(0, "Getting Started");
|
||||||
|
changelog = touch_create_button(1, "Changelog");
|
||||||
|
proceed = touch_create_button(2, "Proceed");
|
||||||
|
for (Button *button : {getting_started, changelog, proceed}) {
|
||||||
|
self->rendered_buttons.push_back(button);
|
||||||
|
self->selectable_buttons.push_back(button);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Rendering
|
||||||
|
static Screen_render_t original_render = vtable->render;
|
||||||
|
vtable->render = [](Screen *self, int x, int y, float param_1) {
|
||||||
|
// Background
|
||||||
|
self->renderBackground();
|
||||||
|
// Call Original Method
|
||||||
|
original_render(self, x, y, param_1);
|
||||||
|
// Text
|
||||||
|
self->drawCenteredString(self->font, &line1, self->width / 2, text_y, 0xFFFFFFFF);
|
||||||
|
};
|
||||||
|
// Positioning
|
||||||
|
vtable->setupPositions = [](Screen *self) {
|
||||||
|
position_screen(self->width, self->height);
|
||||||
|
};
|
||||||
|
// Cleanup
|
||||||
|
vtable->removed = [](Screen *self) {
|
||||||
|
for (Button *button : self->rendered_buttons) {
|
||||||
|
button->destructor_deleting();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Handle Button Click
|
||||||
|
vtable->buttonClicked = [](Screen *self, Button *button) {
|
||||||
|
if (button == getting_started) {
|
||||||
|
open_url(MCPI_DOCUMENTATION "GETTING_STARTED.md");
|
||||||
|
} else if (button == changelog) {
|
||||||
|
open_url(MCPI_DOCUMENTATION CHANGELOG_FILE);
|
||||||
|
} else if (button == proceed) {
|
||||||
|
mark_welcome_as_shown();
|
||||||
|
self->minecraft->screen_chooser.setScreen(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
static Screen *create_welcome_screen() {
|
||||||
|
// Allocate
|
||||||
|
Screen *screen = new Screen;
|
||||||
|
ALLOC_CHECK(screen);
|
||||||
|
screen->constructor();
|
||||||
|
|
||||||
|
// Set VTable
|
||||||
|
screen->vtable = get_welcome_screen_vtable();
|
||||||
|
|
||||||
|
// Return
|
||||||
|
return screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show Welcome Screen
|
||||||
|
static void NinecraftApp_init_ScreenChooser_setScreen_injection(ScreenChooser *self, int id) {
|
||||||
|
if (should_show_welcome()) {
|
||||||
|
// Show Welcome Screen
|
||||||
|
self->minecraft->setScreen(create_welcome_screen());
|
||||||
|
} else {
|
||||||
|
// Show Start Screen
|
||||||
|
self->setScreen(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init
|
||||||
|
void _init_welcome() {
|
||||||
|
// Hijack Start Screen
|
||||||
|
overwrite_call((void *) 0x14a34, (void *) NinecraftApp_init_ScreenChooser_setScreen_injection);
|
||||||
|
}
|
@ -1 +1,3 @@
|
|||||||
method void setScreen(uint id) = 0x29490;
|
method void setScreen(uint id) = 0x29490;
|
||||||
|
|
||||||
|
property Minecraft *minecraft = 0x0;
|
Loading…
Reference in New Issue
Block a user