Adaptation to be able to play on android

This commit is contained in:
2026-05-12 14:59:04 +02:00
parent f1111d06c2
commit 7d9328b865
15 changed files with 122 additions and 73 deletions

View File

@@ -207,6 +207,7 @@ options.graphics.fancy=Fancy
options.graphics.fast=Fast
options.guiScale=GUI Scale
options.guiScale.auto=Auto
options.guiScale.tiny=Tiny
options.guiScale.small=Small
options.guiScale.medium=Medium
options.guiScale.large=Large
@@ -225,6 +226,7 @@ options.smoothCamera=Smooth camera
options.destroyVibration=Destroy vibration
options.isLeftHanded=Left handed
options.useTouchscreen=Use touchscreen
options.touchOverride=Touch Mode Override
options.fancyGraphics=Fancy graphics
options.renderDebug=Debug render
options.anaglyph3d=3D anaglyph

View File

@@ -167,6 +167,7 @@ options.graphics.fancy=Fancy
options.graphics.fast=Fast
options.guiScale=GUI Scale
options.guiScale.auto=Auto
options.guiScale.tiny=Tiny
options.guiScale.small=Small
options.guiScale.medium=Medium
options.guiScale.large=Large

View File

@@ -167,6 +167,7 @@ options.graphics.fancy=Fancy
options.graphics.fast=Fast
options.guiScale=GUI Scale
options.guiScale.auto=Auto
options.guiScale.tiny=Tiny
options.guiScale.small=Small
options.guiScale.medium=Medium
options.guiScale.large=Large

View File

@@ -115,10 +115,11 @@ void NinecraftApp::init()
LOGI("This: %p\n", this);
screenChooser.setScreen(SCREEN_STARTMENU);
if (options.getBooleanValue(OPTIONS_FIRST_LAUNCH)) {
options.toggle(OPTIONS_FIRST_LAUNCH);
setScreen(new UsernameScreen());
}
// Disabled: Show username screen on first launch
// if (options.getBooleanValue(OPTIONS_FIRST_LAUNCH)) {
// options.toggle(OPTIONS_FIRST_LAUNCH);
// setScreen(new UsernameScreen());
// }
#else
hostMultiplayer();
#endif

View File

@@ -1125,6 +1125,9 @@ bool Minecraft::useTouchscreen() {
#elif defined(RPI)
return false;
#endif
if (options.getBooleanValue(OPTIONS_TOUCH_OVERRIDE)) {
return options.getBooleanValue(OPTIONS_USE_TOUCHSCREEN);
}
return options.getBooleanValue(OPTIONS_USE_TOUCHSCREEN) && !_supportsNonTouchscreen;
}
bool Minecraft::supportNonTouchScreen() {
@@ -1217,13 +1220,14 @@ void Minecraft::setSize(int w, int h) {
// determine gui scale, optionally overriding auto
if (guiScale != 0) {
// manual selection: 1->small, 2->medium, 3->large, 4->larger, 5->largest
// manual selection: 1->tiny, 2->small, 3->medium, 4->large, 5->larger, 6->largest
switch (guiScale) {
case 1: Gui::GuiScale = 2.0f; break;
case 2: Gui::GuiScale = 3.0f; break;
case 3: Gui::GuiScale = 4.0f; break;
case 4: Gui::GuiScale = 5.0f; break;
case 5: Gui::GuiScale = 6.0f; break;
case 1: Gui::GuiScale = 1.0f; break;
case 2: Gui::GuiScale = 2.0f; break;
case 3: Gui::GuiScale = 3.0f; break;
case 4: Gui::GuiScale = 4.0f; break;
case 5: Gui::GuiScale = 5.0f; break;
case 6: Gui::GuiScale = 6.0f; break;
default: Gui::GuiScale = 1.0f; break; // auto
}
} else {
@@ -1283,16 +1287,15 @@ void Minecraft::setSize(int w, int h) {
void Minecraft::reloadOptions() {
options.save();
bool wasTouchscreen = options.getBooleanValue(OPTIONS_USE_TOUCHSCREEN);
options.set(OPTIONS_USE_TOUCHSCREEN, useTouchscreen());
options.save();
if ((wasTouchscreen != useTouchscreen()) || (inputHolder == 0))
_reloadInput();
bool useTouch = useTouchscreen();
_reloadInput();
gui.refreshTouchState();
// user->name = options.username;
LOGI("Reloading-options\n");
LOGI("Reloading-options (touch=%d)\n", useTouch);
// @todo @fix Android and iOS behaves a bit differently when leaving
// an options screen (Android recreates OpenGL surface)

View File

@@ -22,3 +22,5 @@ const char* OptionStrings::Controls_AutoJump = "ctrl_autojump";
const char* OptionStrings::Game_DifficultyLevel = "game_difficulty";
const char* OptionStrings::Tweaks_TouchOverride = "options.touchOverride";

View File

@@ -30,6 +30,7 @@ public:
static const char* Tweaks_Sprint;
static const char* Tweaks_BarOnTop;
static const char* Tweaks_TouchOverride;
};

View File

@@ -27,14 +27,14 @@ OptionBool autoJump("autoJump", true);
OptionFloat flySpeed("flySpeed", 1.f);
OptionFloat cameraSpeed("cameraSpeed", 1.f);
OptionInt guiScale("guiScale", 0, 0, 5);
OptionInt guiScale("guiScale", 0, 0, 6);
OptionString skin("skin", "Default");
#ifdef RPI
OptionString username("username", "StevePi");
#else
OptionString username("username", "Steve");
OptionString username("username", "test");
#else
OptionString username("username", "test");
#endif
OptionBool destroyVibration("destroyVibration", true);
@@ -64,6 +64,8 @@ OptionBool useVignette("useVignette", true);
OptionBool useTouchscreen("useTouchscreen", true);
OptionBool touchOverride("touchOverride", false);
OptionBool serverVisible("servervisible", true);
OptionBool foliageTint("foliagetint", true);
@@ -173,6 +175,8 @@ void Options::initTable() {
m_options[OPTIONS_RESTORED_ANIMS] = &restoredAnims;
m_options[OPTIONS_TOUCH_OVERRIDE] = &touchOverride;
m_options[OPTIONS_SERVER_VISIBLE] = &serverVisible;
m_options[OPTIONS_MENU_STYLE] = &menuStyle;

View File

@@ -92,6 +92,7 @@ enum OptionId {
OPTIONS_FOG_TYPE,
OPTIONS_JAVA_HUD,
OPTIONS_RESTORED_ANIMS,
OPTIONS_TOUCH_OVERRIDE,
OPTIONS_TINTED_SIDE,
OPTIONS_BETA_SKY,
OPTIONS_BEAUTIFUL_SKY,

View File

@@ -423,6 +423,10 @@ void Gui::inventoryUpdated() {
_inventoryNeedsUpdate = true;
}
void Gui::refreshTouchState() {
_openInventorySlot = minecraft->useTouchscreen();
}
void Gui::onGraphicsReset() {
inventoryUpdated();
}

View File

@@ -71,6 +71,7 @@ public:
void onGraphicsReset();
void inventoryUpdated();
void refreshTouchState();
void setNowPlaying(const std::string& string);
void displayClientMessage(const std::string& messageId);

View File

@@ -27,11 +27,12 @@ void OptionsItem::render( Minecraft* minecraft, int xm, int ym ) {
std::string scaleText;
switch (value) {
case 0: scaleText = I18n::get("options.guiScale.auto"); break;
case 1: scaleText = I18n::get("options.guiScale.small"); break;
case 2: scaleText = I18n::get("options.guiScale.medium"); break;
case 3: scaleText = I18n::get("options.guiScale.large"); break;
case 4: scaleText = I18n::get("options.guiScale.larger"); break;
case 5: scaleText = I18n::get("options.guiScale.largest"); break;
case 1: scaleText = I18n::get("options.guiScale.tiny"); break;
case 2: scaleText = I18n::get("options.guiScale.small"); break;
case 3: scaleText = I18n::get("options.guiScale.medium"); break;
case 4: scaleText = I18n::get("options.guiScale.large"); break;
case 5: scaleText = I18n::get("options.guiScale.larger"); break;
case 6: scaleText = I18n::get("options.guiScale.largest"); break;
default: scaleText = I18n::get("options.guiScale.auto"); break;
}
text += ": " + scaleText;

View File

@@ -148,7 +148,7 @@ void OptionsScreen::removed() {
void OptionsScreen::buttonClicked(Button* button) {
if (button == btnClose) {
minecraft->options.save();
minecraft->reloadOptions();
if (minecraft->screen != NULL) {
minecraft->setScreen(NULL);
} else {
@@ -195,11 +195,11 @@ void OptionsScreen::generateOptionScreens() {
.addOptionItem(OPTIONS_SENSITIVITY, minecraft);
// Game Pane
optionPanes[1]->addOptionItem(OPTIONS_DIFFICULTY, minecraft)
optionPanes[1]->addOptionItem(OPTIONS_GUI_SCALE, minecraft)
.addOptionItem(OPTIONS_DIFFICULTY, minecraft)
.addOptionItem(OPTIONS_SERVER_VISIBLE, minecraft)
.addOptionItem(OPTIONS_THIRD_PERSON_VIEW, minecraft)
.addOptionItem(OPTIONS_WINDOW_SCALE, minecraft)
.addOptionItem(OPTIONS_GUI_SCALE, minecraft)
.addOptionItem(OPTIONS_SENSITIVITY, minecraft)
.addOptionItem(OPTIONS_MUSIC_VOLUME, minecraft)
.addOptionItem(OPTIONS_SOUND_VOLUME, minecraft)
@@ -234,7 +234,8 @@ void OptionsScreen::generateOptionScreens() {
.addOptionItem(OPTIONS_BEAUTIFUL_SKY, minecraft)
.addOptionItem(OPTIONS_VIGNETTE, minecraft);
optionPanes[4]->addOptionItem(OPTIONS_ALLOW_SPRINT, minecraft)
optionPanes[4]->addOptionItem(OPTIONS_TOUCH_OVERRIDE, minecraft)
.addOptionItem(OPTIONS_ALLOW_SPRINT, minecraft)
.addOptionItem(OPTIONS_BAR_ON_TOP, minecraft)
.addOptionItem(OPTIONS_MENU_STYLE, minecraft)
.addOptionItem(OPTIONS_RPI_CURSOR, minecraft)
@@ -271,8 +272,8 @@ void OptionsScreen::mouseWheel(int dx, int dy, int xm, int ym) {
void OptionsScreen::keyPressed(int eventKey) {
if (currentOptionsGroup != NULL)
currentOptionsGroup->keyPressed(minecraft, eventKey);
if (eventKey == Keyboard::KEY_ESCAPE)
minecraft->options.save();
if (eventKey == Keyboard::KEY_ESCAPE)
minecraft->reloadOptions();
super::keyPressed(eventKey);
}

View File

@@ -118,22 +118,15 @@ void SimpleChooseLevelScreen::setupPositions()
bGamemode->x = centerX - totalButtonWidth / 2;
bCheats->x = bGamemode->x + buttonWidth + buttonSpacing;
// compute vertical centre for buttons in remaining space
{
int bottomPad = 20;
int availTop = buttonHeight + 20 + 30 + 10; // just below seed
int availBottom = height - bottomPad - bCreate->height - 10; // leave some gap before create
int availHeight = availBottom - availTop;
if (availHeight < 0) availHeight = 0;
int y = availTop + (availHeight - bGamemode->height) / 2;
bGamemode->y = y;
bCheats->y = y;
}
// position Survival/Cheats buttons below the seed field
int buttonY = tSeed.y + tSeed.height + 20;
bGamemode->y = buttonY;
bCheats->y = buttonY;
// position Create button just below with a small gap
bCreate->width = 100;
bCreate->x = centerX - bCreate->width / 2;
int bottomPadding = 20;
bCreate->y = height - bottomPadding - bCreate->height;
bCreate->y = buttonY + bGamemode->height + 40;
}
void SimpleChooseLevelScreen::tick()

View File

@@ -4,6 +4,7 @@
#include "../../../gui/Gui.h"
#include "../../../renderer/Tesselator.h"
#include "../../../../world/entity/player/Player.h"
#include "../../../../util/Mth.h"
#include "../../../Minecraft.h"
#include "../../../../platform/log.h"
@@ -125,48 +126,80 @@ void TouchscreenInput_TestFps::onConfigChanged(const Config& c) {
*/
// Code for "D-pad with jump in center"
float Bw = w * 0.11f;//0.08f;
float Bh = Bw;//0.15f;
// If too large (like playing on Tablet)
// Calculate button size so the full 3x3 grid fits on screen with margins
const float margin = 12.0f;
float availW = w - margin * 2; // horizontal space available
float availH = h - margin * 2; // vertical space available
// Each button: 3 wide, 3 tall
float Bw = availW / 3.0f;
float Bh = availH / 3.0f;
// Use the smaller of the two to maintain square buttons
float btnSize = Mth::Min(Bw, Bh);
// Scale down to 65% of max available for a more comfortable, non-obtrusive size
btnSize *= 0.65f;
// Clamp to physical millimeters for consistency across DPIs
PixelCalc& pc = _minecraft->pixelCalc;
if (pc.pixelsToMillimeters(Bw) > 200) { //14
Bw = Bh = pc.millimetersToPixels(200); //14
}
float minBtnPx = pc.millimetersToPixels(35); // minimum touch target
float maxBtnPx = pc.millimetersToPixels(90); // maximum
if (btnSize < minBtnPx) btnSize = minBtnPx;
if (btnSize > maxBtnPx) btnSize = maxBtnPx;
float Bw2 = btnSize;
float Bh2 = btnSize;
// temp data
float xx;
float yy;
const float BaseY = -8 + h - 3.0f * Bh;
const float BaseX = _options->getBooleanValue(OPTIONS_IS_LEFT_HANDED)? -8 + w - 3 * Bw
: 8 + 0;
// Position from top-left (or top-right for left-handed)
float dpadTotalW = 3.0f * Bw2;
float dpadTotalH = 3.0f * Bh2;
// Place at top of screen instead of bottom
float BaseY = margin;
if (BaseY + dpadTotalH > h - margin) BaseY = h - dpadTotalH - margin;
float BaseX = _options->getBooleanValue(OPTIONS_IS_LEFT_HANDED) ? w - dpadTotalW - margin : margin;
if (BaseX < margin) BaseX = margin;
if (BaseX + dpadTotalW > w - margin) BaseX = w - dpadTotalW - margin;
// Setup the bounding rectangle
_boundingRectangle = RectangleArea(BaseX, BaseY, BaseX + 3 * Bw, BaseY + 3 * Bh);
_boundingRectangle = RectangleArea(BaseX, BaseY, BaseX + dpadTotalW, BaseY + dpadTotalH);
xx = BaseX + Bw; yy = BaseY;
_model.addArea(AREA_DPAD_N, aUp = new RectangleArea(xx, yy, xx+Bw, yy+Bh));
xx = BaseX + Bw2; yy = BaseY;
_model.addArea(AREA_DPAD_N, aUp = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2));
xx = BaseX;
aUpLeft = new RectangleArea(xx, yy, xx+Bw, yy+Bh);
xx = BaseX + 2 * Bw;
aUpRight = new RectangleArea(xx, yy, xx+Bw, yy+Bh);
aUpLeft = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2);
xx = BaseX + 2 * Bw2;
aUpRight = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2);
xx = BaseX + Bw; yy = BaseY + Bh;
_model.addArea(AREA_DPAD_C, aJump = new RectangleArea(xx, yy, xx+Bw, yy+Bh));
xx = BaseX + Bw2; yy = BaseY + Bh2;
_model.addArea(AREA_DPAD_C, aJump = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2));
xx = BaseX + Bw; yy = BaseY + 2 * Bh;
_model.addArea(AREA_DPAD_S, aDown = new RectangleArea(xx, yy, xx+Bw, yy+Bh));
xx = BaseX + Bw2; yy = BaseY + 2 * Bh2;
_model.addArea(AREA_DPAD_S, aDown = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2));
xx = BaseX; yy = BaseY + Bh;
_model.addArea(AREA_DPAD_W, aLeft = new RectangleArea(xx, yy, xx+Bw, yy+Bh));
xx = BaseX; yy = BaseY + Bh2;
_model.addArea(AREA_DPAD_W, aLeft = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2));
xx = BaseX + 2 * Bw; yy = BaseY + Bh;
_model.addArea(AREA_DPAD_E, aRight = new RectangleArea(xx, yy, xx+Bw, yy+Bh));
xx = BaseX + 2 * Bw2; yy = BaseY + Bh2;
_model.addArea(AREA_DPAD_E, aRight = new RectangleArea(xx, yy, xx+Bw2, yy+Bh2));
float maxPixels = _minecraft->pixelCalc.millimetersToPixels(10);
// float btnSize = Mth::Min(18 * Gui::GuiScale, maxPixels);
float btnSize = pc.millimetersToPixels(18 * Gui::GuiScale);
_model.addArea(AREA_PAUSE, aPause = new RectangleArea(w - 4 - btnSize, 4, w - 4, 4 + btnSize));
_model.addArea(AREA_CHAT, aChat = new RectangleArea(w - 8 - btnSize * 2, 4, w - 8 - btnSize, 4 + btnSize));
// Pause and chat buttons - sized relative to D-pad buttons, with bounds checking
float actionBtnSize = Bw2 * 0.7f;
float actionBtnMargin = 8.0f;
// Clamp action button size
if (actionBtnSize < pc.millimetersToPixels(30)) actionBtnSize = pc.millimetersToPixels(30);
if (actionBtnSize > pc.millimetersToPixels(120)) actionBtnSize = pc.millimetersToPixels(120);
_model.addArea(AREA_PAUSE, aPause = new RectangleArea(
w - actionBtnMargin - actionBtnSize, actionBtnMargin,
w - actionBtnMargin, actionBtnMargin + actionBtnSize));
_model.addArea(AREA_CHAT, aChat = new RectangleArea(
w - actionBtnMargin * 2 - actionBtnSize * 2, actionBtnMargin,
w - actionBtnMargin * 2 - actionBtnSize, actionBtnMargin + actionBtnSize));
//rebuild();
}