Adjusted for the web port
This commit is contained in:
154
html/build.gradle
Normal file
154
html/build.gradle
Normal file
@@ -0,0 +1,154 @@
|
||||
apply plugin: 'java-library'
|
||||
|
||||
dependencies {
|
||||
implementation "com.badlogicgames.gdx:gdx:$gdxVersion"
|
||||
implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion"
|
||||
implementation "com.github.xpenatan.gdx-teavm:backend-teavm:$gdxTeaVMVersion"
|
||||
implementation "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
|
||||
implementation "com.github.xpenatan.gdx-teavm:gdx-freetype-teavm:$gdxTeaVMVersion"
|
||||
implementation project(':core')
|
||||
implementation "org.teavm:teavm-jso:$teaVMVersion"
|
||||
implementation "org.teavm:teavm-core:$teaVMVersion"
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url 'https://teavm.org/maven/repository' }
|
||||
}
|
||||
|
||||
tasks.register('compileClient', JavaExec) {
|
||||
classpath(sourceSets.main.runtimeClasspath)
|
||||
mainClass.set('com.shatteredpixel.shatteredpixeldungeon.html.Compile')
|
||||
jvmArgs('-Xms8g', '-Xmx14g', '-Xss16m', '-XX:MaxMetaspaceSize=12g', '-Dfile.encoding=UTF-8')
|
||||
outputs.dir '../release/webapp'
|
||||
doFirst {
|
||||
println "Running compileClient..."
|
||||
}
|
||||
doLast {
|
||||
println "compileClient completed!"
|
||||
}
|
||||
}
|
||||
|
||||
task modifyHtml {
|
||||
doLast {
|
||||
def htmlFile = file("../release/webapp/index.html")
|
||||
def destinationDir = file("../release/webapp/assets")
|
||||
def sourceFavicon = file("../desktop/src/main/assets/icons/windows.ico")
|
||||
def sourceGif = file("../html/src/main/assets/logo.gif")
|
||||
def destinationStartupLogo = file("../release/webapp/startup-logo.png")
|
||||
|
||||
// copy windows.ico
|
||||
if (sourceFavicon.exists()) {
|
||||
def destinationFile = new File(destinationDir, "windows.ico")
|
||||
sourceFavicon.withInputStream { input ->
|
||||
destinationFile.withOutputStream { output ->
|
||||
output << input
|
||||
}
|
||||
}
|
||||
println "Copied windows.ico to assets folder."
|
||||
} else {
|
||||
println "windows.ico does not exist. Skipping copy step."
|
||||
}
|
||||
|
||||
if (sourceGif.exists()) {
|
||||
destinationStartupLogo.parentFile.mkdirs()
|
||||
sourceGif.withInputStream { input ->
|
||||
destinationStartupLogo.withOutputStream { output ->
|
||||
output << input
|
||||
}
|
||||
}
|
||||
println "Replaced startup-logo.png with a gif."
|
||||
} else {
|
||||
println "Gif does not exist. Skipping replacement step."
|
||||
}
|
||||
|
||||
if (htmlFile.exists()) {
|
||||
def faviconLink = '<link rel="icon" href="assets/windows.ico" type="image/x-icon">'
|
||||
def content = htmlFile.text
|
||||
|
||||
// add a link for the favicon
|
||||
if (content.contains("</head>")) {
|
||||
content = content.replace("</head>", faviconLink + "\n</head>")
|
||||
println "Favicon link added to index.html."
|
||||
}
|
||||
|
||||
// Change page title
|
||||
if (content.contains("<title>")) {
|
||||
content = content.replaceFirst("<title>.*?</title>", "<title>Shattered Pixel Dungeon</title>")
|
||||
println "Title updated to 'Shattered Pixel Dungeon'."
|
||||
} else {
|
||||
println "No <title> tag found in index.html. Skipping title update."
|
||||
}
|
||||
|
||||
if (content.contains("<style>") && content.contains("</style>")) {
|
||||
content = content.replaceAll(
|
||||
"(?s)<style>.*?</style>",
|
||||
"""<style>
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: #000;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
#progress {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
#progress-img {
|
||||
display: flex;
|
||||
width: 850px;
|
||||
height: auto;
|
||||
margin-bottom: -20px;
|
||||
}
|
||||
#progress-box {
|
||||
background: rgba(255,255,255,0.1);
|
||||
border: 2px solid #fff;
|
||||
display: flex;
|
||||
margin-top: -20px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
height: 30px;
|
||||
width: 600px;
|
||||
}
|
||||
#progress-bar {
|
||||
display: block;
|
||||
background: #44FF82;
|
||||
height: 20px;
|
||||
width: 0%;
|
||||
}
|
||||
</style>"""
|
||||
)
|
||||
|
||||
println "Successfully replaced the <style> block in index.html."
|
||||
} else {
|
||||
println "No <style> block found in index.html. Skipping style replacement."
|
||||
}
|
||||
|
||||
htmlFile.text = content
|
||||
} else {
|
||||
println "index.html does not exist. Skipping favicon injection."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named('modifyHtml') {
|
||||
mustRunAfter('compileClient')
|
||||
}
|
||||
|
||||
tasks.named('build') {
|
||||
dependsOn 'compileClient'
|
||||
finalizedBy 'modifyHtml'
|
||||
}
|
||||
7
html/buildTestWeb.sh
Executable file
7
html/buildTestWeb.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
../gradlew :html:build
|
||||
wait
|
||||
if [[ -d ../release/webapp/ ]]; then
|
||||
python3 -m http.server 8100 -d ../release/webapp/
|
||||
fi
|
||||
BIN
html/src/main/assets/logo.gif
Normal file
BIN
html/src/main/assets/logo.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 776 KiB |
62
html/src/main/java/Compile.java
Normal file
62
html/src/main/java/Compile.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* This file is derived from micronaut-libgdx-teavm (https://github.com/hollingsworthd/micronaut-libgdx-teavm),
|
||||
* originally licensed under the Apache License, Version 2.0.
|
||||
*
|
||||
* Modifications made by Konsthol on 13/4/25:
|
||||
* - Adjusted to compile Shattered Pixel Dungeon
|
||||
*
|
||||
* Copyright 2022 Daniel Hollingsworth
|
||||
*/
|
||||
|
||||
package com.shatteredpixel.shatteredpixeldungeon.html;
|
||||
|
||||
import com.github.xpenatan.gdx.backends.teavm.config.AssetFileHandle;
|
||||
import com.github.xpenatan.gdx.backends.teavm.config.TeaBuildConfiguration;
|
||||
import com.github.xpenatan.gdx.backends.teavm.config.TeaBuilder;
|
||||
import com.github.xpenatan.gdx.backends.teavm.gen.SkipClass;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.teavm.tooling.TeaVMTool;
|
||||
import org.teavm.vm.TeaVMOptimizationLevel;
|
||||
|
||||
@SkipClass
|
||||
public class Compile {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
deleteDir(new File("../release/webapp"));
|
||||
|
||||
TeaBuildConfiguration conf = new TeaBuildConfiguration();
|
||||
|
||||
conf.webappPath = new File("../release").getAbsolutePath();
|
||||
conf.assetsPath.add(new AssetFileHandle("../core/src/main/assets"));
|
||||
|
||||
TeaVMTool tool = TeaBuilder.config(conf);
|
||||
tool.setMainClass(TeaVMLauncher.class.getName());
|
||||
tool.setOptimizationLevel(TeaVMOptimizationLevel.ADVANCED);
|
||||
tool.setObfuscated(true);
|
||||
tool.setShortFileNames(true);
|
||||
tool.setSourceFilesCopied(false);
|
||||
tool.setStrict(false);
|
||||
tool.setSourceMapsFileGenerated(false);
|
||||
tool.setDebugInformationGenerated(false);
|
||||
tool.setIncremental(false);
|
||||
|
||||
TeaBuilder.build(tool);
|
||||
}
|
||||
|
||||
private static void deleteDir(File dir) {
|
||||
File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
deleteDir(file);
|
||||
}
|
||||
}
|
||||
dir.delete();
|
||||
}
|
||||
}
|
||||
122
html/src/main/java/HtmlPlatformSupport.java
Normal file
122
html/src/main/java/HtmlPlatformSupport.java
Normal file
@@ -0,0 +1,122 @@
|
||||
package com.shatteredpixel.shatteredpixeldungeon.html;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.Graphics;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.graphics.g2d.PixmapPacker;
|
||||
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.SPDSettings;
|
||||
import com.watabou.input.ControllerHandler;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.watabou.utils.PlatformSupport;
|
||||
import org.teavm.jso.JSBody;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class HtmlPlatformSupport extends PlatformSupport {
|
||||
|
||||
@Override
|
||||
public void updateDisplaySize() {
|
||||
if (Gdx.app == null || Gdx.graphics == null) {
|
||||
System.err.println("Gdx is not initialized yet. Skipping display size update.");
|
||||
return;
|
||||
}
|
||||
|
||||
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSystemUI() {
|
||||
Gdx.app.postRunnable( new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Object canvas = getCanvasElement("canvas");
|
||||
if (SPDSettings.fullscreen()) {
|
||||
System.out.println("Requesting fullscreen.");
|
||||
requestFullscreen("canvas");
|
||||
} else {
|
||||
System.out.println("Exiting fullscreen.");
|
||||
exitFullscreen();
|
||||
setCanvasSize("canvas", SPDSettings.windowResolution().x, SPDSettings.windowResolution().y);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@JSBody(script = ""
|
||||
+ "document.body.addEventListener('click', function() {"
|
||||
+ " console.log('User clicked. Triggering fullscreen and audio...');"
|
||||
+ " document.getElementById('canvas').requestFullscreen();"
|
||||
+ " if (!window.audioContext) {"
|
||||
+ " window.audioContext = new (window.AudioContext || window.webkitAudioContext)();"
|
||||
+ " }"
|
||||
+ " window.audioContext.resume().then(() => {"
|
||||
+ " console.log('AudioContext resumed successfully.');"
|
||||
+ " }).catch((err) => {"
|
||||
+ " console.error('Failed to resume AudioContext:', err);"
|
||||
+ " });"
|
||||
+ "}, { once: true });")
|
||||
public static native void setupClickListener();
|
||||
|
||||
@JSBody(params = {"id"}, script = "document.getElementById(id).requestFullscreen();")
|
||||
private static native void requestFullscreen(String id);
|
||||
|
||||
@JSBody(params = {"id"}, script = "return document.getElementById(id);")
|
||||
private static native Object getCanvasElement(String id);
|
||||
|
||||
@JSBody(params = {}, script = "document.exitFullscreen();")
|
||||
private static native void exitFullscreen();
|
||||
|
||||
@JSBody(params = {"id", "width", "height"}, script = "var canvas = document.getElementById(id); canvas.width = width; canvas.height = height;")
|
||||
private static native void setCanvasSize(String id, int width, int height);
|
||||
|
||||
@Override
|
||||
public boolean connectedToUnmeteredNetwork() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsVibration() {
|
||||
return ControllerHandler.vibrationSupported();
|
||||
}
|
||||
|
||||
private static FreeTypeFontGenerator basicFontGenerator;
|
||||
|
||||
@Override
|
||||
public void setupFontGenerators(int pageSize, boolean systemfont) {
|
||||
//don't bother doing anything if nothing has changed
|
||||
if (fonts != null && this.pageSize == pageSize && this.systemfont == systemfont) {
|
||||
return;
|
||||
}
|
||||
this.pageSize = pageSize;
|
||||
this.systemfont = systemfont;
|
||||
|
||||
resetGenerators(false);
|
||||
fonts = new HashMap<>();
|
||||
|
||||
basicFontGenerator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/pixel_font.ttf"));
|
||||
|
||||
fonts.put(basicFontGenerator, new HashMap<>());
|
||||
|
||||
packer = new PixmapPacker(pageSize, pageSize, Pixmap.Format.RGBA8888, 1, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FreeTypeFontGenerator getGeneratorForString( String input ) {
|
||||
return basicFontGenerator;
|
||||
}
|
||||
|
||||
private final Pattern regularsplitter = Pattern.compile("(?<=\n)|(?=\n)|(?<=_)|(?=_)|(?<=\\*\\*)|(?=\\*\\*)");
|
||||
|
||||
private final Pattern regularsplitterMultiline = Pattern.compile("(?<= )|(?= )|(?<=\n)|(?=\n)|(?<=_)|(?=_)|(?<=\\*\\*)|(?=\\*\\*)");
|
||||
|
||||
@Override
|
||||
public String[] splitforTextBlock(String text, boolean multiline) {
|
||||
if (multiline) {
|
||||
return regularsplitterMultiline.split(text);
|
||||
} else {
|
||||
return regularsplitter.split(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
46
html/src/main/java/TeaVMLauncher.java
Normal file
46
html/src/main/java/TeaVMLauncher.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package com.shatteredpixel.shatteredpixeldungeon.html;
|
||||
|
||||
import com.badlogic.gdx.Files;
|
||||
import com.watabou.noosa.Game;
|
||||
import com.shatteredpixel.shatteredpixeldungeon.ShatteredPixelDungeon;
|
||||
import com.github.xpenatan.gdx.backends.teavm.TeaApplicationConfiguration;
|
||||
import com.github.xpenatan.gdx.backends.teavm.TeaApplication;
|
||||
import com.watabou.utils.FileUtils;
|
||||
|
||||
public class TeaVMLauncher {
|
||||
|
||||
public static void main(String[] args) {
|
||||
TeaApplicationConfiguration config = new TeaApplicationConfiguration("canvas");
|
||||
config.width = 0;
|
||||
config.height = 0;
|
||||
config.useGL30 = true;
|
||||
config.preloadListener = assetLoader -> {
|
||||
try {
|
||||
assetLoader.loadScript("freetype.js");
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error loading freetype.js: " + e.getMessage());
|
||||
}
|
||||
};
|
||||
|
||||
initializeServices();
|
||||
FileUtils.setDefaultFileProperties(Files.FileType.Local, "");
|
||||
|
||||
try {
|
||||
|
||||
HtmlPlatformSupport platformSupport = new HtmlPlatformSupport();
|
||||
|
||||
platformSupport.setupClickListener();
|
||||
|
||||
new TeaApplication(new ShatteredPixelDungeon(platformSupport), config);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("Error launching TeaApplication: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void initializeServices() {
|
||||
Game.version = "3.0.2";
|
||||
Game.versionCode = 833;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user