From d18733b14c6fa4114756c1f3fd74aa9b29bc535d Mon Sep 17 00:00:00 2001 From: StevenSYS <139715581+StevenSYS@users.noreply.github.com> Date: Thu, 26 Mar 2026 06:28:39 +0000 Subject: [PATCH] Ported over the Java Edition's title screen panorama. --- Minecraft.Client/Minecraft.cpp | 6 +- Minecraft.Client/Textures/Texture.cpp | 12 +- Minecraft.Client/UI/Screens/TitleScreen.cpp | 180 +++++++++++++++----- Minecraft.Client/UI/Screens/TitleScreen.h | 7 +- 4 files changed, 154 insertions(+), 51 deletions(-) diff --git a/Minecraft.Client/Minecraft.cpp b/Minecraft.Client/Minecraft.cpp index bb2610813..ee7ac2623 100644 --- a/Minecraft.Client/Minecraft.cpp +++ b/Minecraft.Client/Minecraft.cpp @@ -1967,7 +1967,11 @@ void Minecraft::run_middle() { player->ullButtonsPressed = 0LL; } else if (screen != NULL) { screen->updateEvents(); - screen->tick(); + // 4jcraft: this fixes the title screen panorama running + // faster than it should + if (!idx) { + screen->tick(); + } } } diff --git a/Minecraft.Client/Textures/Texture.cpp b/Minecraft.Client/Textures/Texture.cpp index 5cd1fbbdd..5d54d9a09 100644 --- a/Minecraft.Client/Textures/Texture.cpp +++ b/Minecraft.Client/Textures/Texture.cpp @@ -471,10 +471,10 @@ void Texture::blit(int x, int y, Texture* source, bool rotated) { } void Texture::transferFromBuffer(intArray buffer) { - //if (depth == 1) { - // return; - //} - // 4jcraft - move pos out of loops + // if (depth == 1) { + // return; + // } + // 4jcraft - move pos out of loops data[0]->clear(); // #ifdef __PS3__ // int byteRemapRGBA[] = { 3, 0, 1, 2 }; @@ -487,7 +487,7 @@ void Texture::transferFromBuffer(intArray buffer) { int totalPixels = width * height * depth; - for (int i = 0; i < totalPixels; i++){ + for (int i = 0; i < totalPixels; i++) { int pixel = buffer[i]; int offset = i * 4; @@ -501,7 +501,7 @@ void Texture::transferFromBuffer(intArray buffer) { updateOnGPU(); } - + /* for (int z = 0; z < depth; z++) { int plane = z * height * width * 4; for (int y = 0; y < height; y++) { diff --git a/Minecraft.Client/UI/Screens/TitleScreen.cpp b/Minecraft.Client/UI/Screens/TitleScreen.cpp index 600ee8199..dcf055456 100644 --- a/Minecraft.Client/UI/Screens/TitleScreen.cpp +++ b/Minecraft.Client/UI/Screens/TitleScreen.cpp @@ -17,7 +17,8 @@ Random* TitleScreen::random = new Random(); TitleScreen::TitleScreen() { // 4J - added initialisers - vo = 0; + // vo = 0; // 4jcraft removed + panoramaTimer = 0.0f; multiplayerButton = NULL; splash = L"missingno"; @@ -66,10 +67,18 @@ TitleScreen::TitleScreen() { } splash = splashes.at(splashIndex); + + titlePanoramaPaths[0] = L"title/bg/panorama0.png"; + titlePanoramaPaths[1] = L"title/bg/panorama1.png"; + titlePanoramaPaths[2] = L"title/bg/panorama2.png"; + titlePanoramaPaths[3] = L"title/bg/panorama3.png"; + titlePanoramaPaths[4] = L"title/bg/panorama4.png"; + titlePanoramaPaths[5] = L"title/bg/panorama5.png"; } void TitleScreen::tick() { - vo += 1.0f; + panoramaTimer += 1.0f; + // vo += 1.0f; // 4jcraft removed // if( vo > 100.0f ) minecraft->setScreen(new SelectWorldScreen(this)); // // 4J - temp testing } @@ -78,6 +87,10 @@ void TitleScreen::keyPressed(wchar_t eventCharacter, int eventKey) {} void TitleScreen::init() { app.DebugPrintf("TitleScreen::init() START\n"); + + // 4jcraft: this is for the blured panorama background + viewportTexture = + minecraft->textures->getTexture(new BufferedImage(256, 256, 2)); /* 4J - removed Calendar c = Calendar.getInstance(); c.setTime(new Date()); @@ -157,80 +170,161 @@ void TitleScreen::buttonClicked(Button* button) { // 4jcraft: render our panorama // uses the TU panorama instead of JE panorama and as such a different rendering // method -void TitleScreen::renderPanorama() { +void TitleScreen::renderPanorama(float a) { #ifdef ENABLE_JAVA_GUIS Tesselator* t = Tesselator::getInstance(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - glOrtho(0, width, height, 0, 1000, 3000); + gluPerspective(120.0f, 1.0f, 0.05f, 10.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - glTranslatef(0, 0, -2000); - - glDisable(GL_LIGHTING); - glDisable(GL_FOG); - glEnable(GL_TEXTURE_2D); - glDisable(GL_ALPHA_TEST); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glRotatef(180.0f, 1.0f, 0.0f, 0.0f); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_ALPHA_TEST); + glDisable(GL_CULL_FACE); glDepthMask(false); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + char offsetPasses = 8; - glBindTexture(GL_TEXTURE_2D, - minecraft->textures->loadTexture(TN_TITLE_BG_PANORAMA)); + for (int i = 0; i < (offsetPasses * offsetPasses); i++) { + glPushMatrix(); + float x = + ((float)(i % offsetPasses) / (float)offsetPasses - 0.5f) / 64.0f; + float y = + ((float)(i / offsetPasses) / (float)offsetPasses - 0.5f) / 64.0f; + float z = 0.0f; + glTranslatef(x, y, z); + glRotatef(sin((panoramaTimer + a) / 400.0f) * 25.0f + 20.0f, 1.0f, 0.0f, + 0.0f); + glRotatef(-(panoramaTimer + a) * 0.1f, 0.0f, 1.0f, 0.0f); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + for (int j = 0; j < 6; j++) { + glPushMatrix(); - float off = vo * 0.0001f; + switch (j) { + case 1: + glRotatef(90.0f, 0.0f, 1.0f, 0.0f); + break; + case 2: + glRotatef(180.0f, 0.0f, 1.0f, 0.0f); + break; + case 3: + glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); + break; + case 4: + glRotatef(90.0f, 1.0f, 0.0f, 0.0f); + break; + case 5: + glRotatef(-90.0f, 1.0f, 0.0f, 0.0f); + break; + default: + break; + } - float screenAspect = (float)width / (float)height; - float texAspect = 1748.0f / 144.0f; - float scale; - if (screenAspect > texAspect) { - scale = (float)width / 1748.0f; - } else { - scale = (float)height / 144.0f; + minecraft->textures->bindTexture(titlePanoramaPaths[j]); + t->begin(); + t->color(16777215, 255 / (i + 1)); + t->vertexUV(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f); + t->vertexUV(1.0f, -1.0f, 1.0f, 1.0f, 0.0f); + t->vertexUV(1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + t->vertexUV(-1.0f, 1.0f, 1.0f, 0.0f, 1.0f); + t->end(); + glPopMatrix(); + } + glPopMatrix(); + glColorMask(true, true, true, false); } - float texWidth = 1748.0f * scale; - float texHeight = 144.0f * scale; - float yOff = (height - texHeight) / 2.0f; - - float uMax = off + (texWidth / 1748.0f); - - t->begin(GL_QUADS); - t->color(0xffffff, 255); - t->vertexUV(0, yOff + texHeight, 0, off, 1.0f); - t->vertexUV(texWidth, yOff + texHeight, 0, uMax, 1.0f); - t->vertexUV(texWidth, yOff, 0, uMax, 0.0f); - t->vertexUV(0, yOff, 0, off, 0.0f); - t->end(); - - glDepthMask(true); - glDisable(GL_BLEND); - glEnable(GL_ALPHA_TEST); + t->offset(0.0f, 0.0f, 0.0f); + glColorMask(true, true, true, true); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); + glDepthMask(true); + glEnable(GL_CULL_FACE); + glEnable(GL_ALPHA_TEST); + glEnable(GL_DEPTH_TEST); +#endif +} + +// 4jcraft +void TitleScreen::renderSkybox(float a) { + glViewport(0, 0, 256, 256); + renderPanorama(a); + glDisable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_2D); + + for (int i = 0; i < 8; i++) { + rotateAndBlur(a); + } + + glViewport(0, 0, minecraft->width, minecraft->height); + + Tesselator* t = Tesselator::getInstance(); + t->begin(); + float aspect = + width > height ? 120.0f / (float)width : 120.0f / (float)height; + float sWidth = (float)height * aspect / 256.0f; + float sHeight = (float)width * aspect / 256.0f; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + t->color(1.0f, 1.0f, 1.0f, 1.0f); + t->vertexUV(0.0f, height, 0.0f, (0.5f - sWidth), (0.5f + sHeight)); + t->vertexUV(width, height, 0.0f, (0.5f - sWidth), (0.5f - sHeight)); + t->vertexUV(width, 0.0f, 0.0f, (0.5f + sWidth), (0.5f - sHeight)); + t->vertexUV(0.0f, 0.0f, 0.0f, (0.5f + sWidth), (0.5f + sHeight)); + t->end(); + return; +} + +// 4jcraft +void TitleScreen::rotateAndBlur(float a) { +#ifdef ENABLE_JAVA_GUIS + glBindTexture(GL_TEXTURE_2D, viewportTexture); + // this.mc.renderEngine.resetBoundTexture(); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 256, 256); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColorMask(true, true, true, false); + Tesselator* t = Tesselator::getInstance(); + t->begin(); + char blurPasses = 3; + + for (int i = 0; i < blurPasses; i++) { + t->color(1.0f, 1.0f, 1.0f, 1.0f / (float)(i + 1)); + float offset = (float)(i - blurPasses / 2) / 256.0f; + t->vertexUV(width, height, 0.0f, (0.0f + offset), 0.0f); + t->vertexUV(width, 0.0f, 0.0f, (1.0f + offset), 0.0f); + t->vertexUV(0.0f, 0.0f, 0.0f, (1.0f + offset), 1.0f); + t->vertexUV(0.0f, height, 0.0f, (0.0f + offset), 1.0f); + } + + t->end(); + glColorMask(true, true, true, true); + // this.mc.renderEngine.resetBoundTexture(); #endif } void TitleScreen::render(int xm, int ym, float a) { // 4J Unused - Iggy Flash UI renders the title screen on consoles #ifdef ENABLE_JAVA_GUIS - renderPanorama(); + // 4jcraft: panorama + renderSkybox(a); + Tesselator* t = Tesselator::getInstance(); int logoWidth = 155 + 119; int logoX = width / 2 - logoWidth / 2; int logoY = 30; + // 4jcraft: gradient + fillGradient(0, 0, width, height, -2130706433, 16777215); + fillGradient(0, 0, width, height, 0, INT_MIN); + glBindTexture(GL_TEXTURE_2D, minecraft->textures->loadTexture(TN_TITLE_MCLOGO)); glColor4f(1, 1, 1, 1); diff --git a/Minecraft.Client/UI/Screens/TitleScreen.h b/Minecraft.Client/UI/Screens/TitleScreen.h index f729cea2e..9bb7ffdca 100644 --- a/Minecraft.Client/UI/Screens/TitleScreen.h +++ b/Minecraft.Client/UI/Screens/TitleScreen.h @@ -13,7 +13,12 @@ private: Button* multiplayerButton; // 4jcraft: panorama - void renderPanorama(); + void renderPanorama(float a); + void renderSkybox(float a); + void rotateAndBlur(float a); + int viewportTexture; + float panoramaTimer; + std::wstring titlePanoramaPaths[6]; // 4jcraft: taken from UIScene_MainMenu // 4J Added