Compare commits
12 Commits
add-items
...
title-scre
Author | SHA1 | Date | |
---|---|---|---|
22a744f65a | |||
c6de19cf19 | |||
c1a57f7d7a | |||
162b2249b1
|
|||
dececb4589
|
|||
ec17eb7065
|
|||
e4d0570200
|
|||
576cfed99f
|
|||
5af1b7309d | |||
0f0a94811f | |||
51bcca1499 | |||
ce9e95e5ce |
2
.gitattributes
vendored
@ -6,4 +6,4 @@
|
|||||||
* text=auto eol=lf
|
* text=auto eol=lf
|
||||||
|
|
||||||
*.bat text eol=crlf
|
*.bat text eol=crlf
|
||||||
|
*.nsi text eol=crlf
|
||||||
|
472
build.gradle
@ -1,23 +1,29 @@
|
|||||||
/*
|
/*
|
||||||
* build.gradle for Progressia
|
* Build logic for Progressia
|
||||||
|
* build.gradle
|
||||||
|
*
|
||||||
|
* Please refer to
|
||||||
|
*
|
||||||
|
* docs/building/BuildScriptReference.md
|
||||||
|
*
|
||||||
|
* for user reference.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
// Apply the java-library plugin to add support for Java Library
|
id 'java'
|
||||||
id 'java-library'
|
|
||||||
|
|
||||||
/*
|
// GrGit
|
||||||
* Uncomment the following line to enable the Eclipse plugin.
|
// A JGit wrapper for Groovy used to access git commit info
|
||||||
* This is only necessary if you don't use Buildship plugin from the IDE
|
id 'org.ajoberstar.grgit' version '4.1.1'
|
||||||
*/
|
|
||||||
//id 'eclipse'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
|
||||||
/*
|
|
||||||
* We're Java 8 for now.
|
/*
|
||||||
* Why? As of 2020, most users have Oracle Java, which only supports Java 8.
|
* Configure Java version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
java {
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
@ -34,6 +40,8 @@ compileJava {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dependencies
|
* Dependencies
|
||||||
*/
|
*/
|
||||||
@ -42,7 +50,7 @@ repositories {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Specify Windcorp Maven repository
|
* Windcorp Maven repository
|
||||||
* Currently used by:
|
* Currently used by:
|
||||||
* - ru.windcorp.fork.io.github.java-graphics:glm:1.0.1
|
* - ru.windcorp.fork.io.github.java-graphics:glm:1.0.1
|
||||||
*/
|
*/
|
||||||
@ -72,231 +80,309 @@ dependencies {
|
|||||||
// A unit-testing library
|
// A unit-testing library
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
|
|
||||||
// See LWJGL dependencies below
|
// Also see LWJGL dependencies in build_logic/lwjgl.gradle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Progressia uses the following LWJGL libraries:
|
* Version resolution
|
||||||
* - Core libraries
|
|
||||||
* - OpenGL
|
|
||||||
* - OpenAL
|
|
||||||
* - GLFW
|
|
||||||
* - STB
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
import org.ajoberstar.grgit.*
|
||||||
* LWJGL
|
|
||||||
* (auto-generated script)
|
|
||||||
* ((here be dragons))
|
|
||||||
*/
|
|
||||||
|
|
||||||
import org.gradle.internal.os.OperatingSystem
|
// Pattern: vMAJOR.MINOR.PATCH[-SUFFIX]
|
||||||
|
project.ext.tagFormat = /^v(\d+)\.(\d+)\.(\d+)(-[\w\-]*)?$/
|
||||||
|
|
||||||
project.ext.lwjglVersion = "3.2.3"
|
String version_parseVersion(String tag, boolean increment) {
|
||||||
|
try {
|
||||||
|
|
||||||
switch (OperatingSystem.current()) {
|
def data = (tag =~ tagFormat)[0]
|
||||||
case OperatingSystem.LINUX:
|
|
||||||
def osArch = System.getProperty("os.arch")
|
|
||||||
project.ext.lwjglNatives = osArch.startsWith("arm") || osArch.startsWith("aarch64")
|
|
||||||
? "natives-linux-${osArch.contains("64") || osArch.startsWith("armv8") ? "arm64" : "arm32"}"
|
|
||||||
: "natives-linux"
|
|
||||||
break
|
|
||||||
case OperatingSystem.MAC_OS:
|
|
||||||
project.ext.lwjglNatives = "natives-macos"
|
|
||||||
break
|
|
||||||
case OperatingSystem.WINDOWS:
|
|
||||||
project.ext.lwjglNatives = System.getProperty("os.arch").contains("64") ? "natives-windows" : "natives-windows-x86"
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
def major = data[1]
|
||||||
implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
|
def minor = data[2]
|
||||||
|
def patch = data[3] as int
|
||||||
|
def suffix = data[4] ?: ''
|
||||||
|
|
||||||
implementation "org.lwjgl:lwjgl"
|
if (increment) {
|
||||||
implementation "org.lwjgl:lwjgl-glfw"
|
def oldVersion = "$major.$minor.$patch$suffix"
|
||||||
implementation "org.lwjgl:lwjgl-openal"
|
patch++
|
||||||
implementation "org.lwjgl:lwjgl-opengl"
|
def newVersion = "$major.$minor.$patch$suffix"
|
||||||
implementation "org.lwjgl:lwjgl-stb"
|
|
||||||
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl::$lwjglNatives"
|
logger.info "Version parsed from Git: $oldVersion, incremented to $newVersion"
|
||||||
runtimeOnly "org.lwjgl:lwjgl-glfw::$lwjglNatives"
|
return newVersion
|
||||||
runtimeOnly "org.lwjgl:lwjgl-openal::$lwjglNatives"
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl-opengl::$lwjglNatives"
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl-stb::$lwjglNatives"
|
|
||||||
}
|
|
||||||
|
|
||||||
// LWJGL END
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tasks
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Additional native libraries specification
|
|
||||||
*/
|
|
||||||
|
|
||||||
project.ext.platforms = new HashSet<>()
|
|
||||||
|
|
||||||
task addNativeDependencies {
|
|
||||||
doFirst {
|
|
||||||
def archs = project.ext.platforms
|
|
||||||
|
|
||||||
switch (archs.size()) {
|
|
||||||
case 0:
|
|
||||||
println "Adding LWJGL native dependencies for local platform only:\n\t$lwjglNatives"
|
|
||||||
archs.add project.ext.lwjglNatives
|
|
||||||
break
|
|
||||||
case 1:
|
|
||||||
println "Adding LWJGL native dependencies for platform\n\t" + archs.get(0)
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
println "Adding LWJGL native dependencies for platforms:\n\t" + archs.join("\n\t")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project.ext.lwjglNatives.isEmpty()) println "WTF"
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
archs.each { arch ->
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl::$arch"
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl-glfw::$arch"
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl-openal::$arch"
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl-opengl::$arch"
|
|
||||||
runtimeOnly "org.lwjgl:lwjgl-stb::$arch"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
compileJava.mustRunAfter addNativeDependencies // Make sure runtimeOnly has not been resolved
|
|
||||||
|
|
||||||
task requestLinuxDependencies {
|
|
||||||
description 'Adds linux, linux-arm64 and linux-arm32 native libraries to built artifacts.'
|
|
||||||
doFirst {
|
|
||||||
project.ext.platforms.addAll([
|
|
||||||
'natives-linux',
|
|
||||||
'natives-linux-arm64',
|
|
||||||
'natives-linux-arm32'
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
task requestWindowsDependencies {
|
|
||||||
description 'Adds windows and windows-x86 native libraries to built artifacts.'
|
|
||||||
doFirst {
|
|
||||||
project.ext.platforms.addAll([
|
|
||||||
'natives-windows',
|
|
||||||
'natives-windows-x86'
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
task requestMacOSDependencies {
|
|
||||||
description 'Adds macos native libraries to built artifacts.'
|
|
||||||
doFirst {
|
|
||||||
project.ext.platforms.addAll(['natives-macos'])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def dependencySpecificationTasks = tasks.findAll { task -> task.name.startsWith('request') && task.name.endsWith('Dependencies') }
|
|
||||||
|
|
||||||
task requestCrossPlatformDependencies {
|
|
||||||
description 'Adds native libraries for all available platforms to built artifacts.'
|
|
||||||
dependsOn dependencySpecificationTasks
|
|
||||||
}
|
|
||||||
|
|
||||||
addNativeDependencies.mustRunAfter dependencySpecificationTasks
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Determines if the provided dependency should be packaged
|
|
||||||
*/
|
|
||||||
def isDependencyRequested(String dep) {
|
|
||||||
if (dep.endsWith(".jar")) {
|
|
||||||
dep = dep.substring(0, dep.length() - ".jar".length())
|
|
||||||
}
|
|
||||||
|
|
||||||
return !dep.contains("natives-") ||
|
|
||||||
project.ext.platforms.contains(dep.substring(dep.indexOf("natives-"), dep.length()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Manifest specification
|
|
||||||
*/
|
|
||||||
|
|
||||||
task specifyLocalManifest {
|
|
||||||
dependsOn addNativeDependencies // Make sure all native dependencies are specified
|
|
||||||
|
|
||||||
doFirst {
|
|
||||||
def classPath = []
|
|
||||||
|
|
||||||
configurations.runtimeClasspath.each {
|
|
||||||
if (isDependencyRequested(it.getName())) {
|
|
||||||
classPath.add("lib/" + it.getName())
|
|
||||||
} else {
|
} else {
|
||||||
println "\tRemoving from JAR classpath (not requested): " + it.getName()
|
def newVersion = "$major.$minor.$patch$suffix"
|
||||||
|
logger.info "Version parsed from Git: $newVersion"
|
||||||
|
return newVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (any) {
|
||||||
|
logger.warn "Could not parse version from tag \"$tag\""
|
||||||
|
return tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Tag version_findRelevantTag(Grgit git) {
|
||||||
|
def tags = git.tag.list()
|
||||||
|
|
||||||
|
def commits = [ git.head() ]
|
||||||
|
def visited = new HashSet<>()
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (commits.isEmpty()) return null
|
||||||
|
|
||||||
|
def nextCommits = new HashSet<>()
|
||||||
|
|
||||||
|
def formatSpecificationPrinted = false
|
||||||
|
for (def commit : commits) {
|
||||||
|
def tag = tags.findAll { it.commit == commit } ?.max { it.dateTime }
|
||||||
|
|
||||||
|
if (tag != null) {
|
||||||
|
if (tag.name ==~ tagFormat) {
|
||||||
|
return tag
|
||||||
|
} else {
|
||||||
|
if (!formatSpecificationPrinted) {
|
||||||
|
formatSpecificationPrinted = true
|
||||||
|
logger.info 'Expecting tag format: vMAJOR.MINOR.PATCH[-SUFFIX]'
|
||||||
|
}
|
||||||
|
logger.info 'Ignoring tag due to invalid format: {}', tag.name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classPath.size() == configurations.runtimeClasspath.size()) {
|
nextCommits.addAll commit.parentIds.collect(git.resolve.&toCommit)
|
||||||
println "Nothing removed from JAR classpath"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
visited.addAll commits
|
||||||
manifest {
|
nextCommits.removeAll visited
|
||||||
attributes(
|
commits = nextCommits
|
||||||
"Main-Class": "ru.windcorp.progressia.client.ProgressiaClientMain",
|
}
|
||||||
"Class-Path": configurations.runtimeClasspath.collect { "lib/" + it.getName() } .findAll { isDependencyRequested(it) } .join(' ')
|
}
|
||||||
|
|
||||||
|
task resolveVersion {
|
||||||
|
description 'Resolves version information from Git repository or project properties.'
|
||||||
|
|
||||||
|
doFirst {
|
||||||
|
try {
|
||||||
|
def git = Grgit.open(dir: project.projectDir)
|
||||||
|
|
||||||
|
project.ext.commit = git.head().id
|
||||||
|
project.ext.branch = git.branch.current().name
|
||||||
|
|
||||||
|
if (project.version != 'unspecified') {
|
||||||
|
// Leave version as-is
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
def tag = version_findRelevantTag(git)
|
||||||
|
if (tag == null) {
|
||||||
|
|
||||||
|
String suffix
|
||||||
|
if (project.hasProperty('buildId')) {
|
||||||
|
suffix = project.buildId;
|
||||||
|
} else {
|
||||||
|
suffix = java.time.ZonedDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern('yyyy_MM_dd'))
|
||||||
|
}
|
||||||
|
project.version = "999.0.0-$suffix"
|
||||||
|
|
||||||
|
logger.warn 'Git repository does not contain an applicable tag, using dummy version {}\nSpecify version with -Pversion=1.2.3 or create a Git tag named v1.2.3', project.version
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
project.version = version_parseVersion(tag.name, tag.commit != git.head())
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (org.eclipse.jgit.errors.RepositoryNotFoundException e) {
|
||||||
|
if (project.version == 'unspecified') project.version = 'dev'
|
||||||
|
project.ext.commit = '-'
|
||||||
|
project.ext.branch = '-'
|
||||||
|
|
||||||
|
logger.warn 'No Git repository found in project root, using dummy version {}\nSpecify version with -Pversion=1.2.3 or create a Git tag named v1.2.3', project.version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
if (!project.hasProperty('buildId')) {
|
||||||
|
project.ext.buildId = '-'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Configure JAR manifest
|
||||||
|
*/
|
||||||
|
|
||||||
|
task configureManifest {
|
||||||
|
description 'Populates JAR manifest with Main-Class, Class-Path and version metadata.'
|
||||||
|
|
||||||
|
jar.dependsOn configureManifest
|
||||||
|
dependsOn resolveVersion
|
||||||
|
|
||||||
|
doFirst {
|
||||||
|
jar.manifest.attributes(
|
||||||
|
'Main-Class': 'ru.windcorp.progressia.client.ProgressiaClientMain',
|
||||||
|
'Class-Path': configurations.runtimeClasspath.collect { "lib/${it.name}" } .join(' '),
|
||||||
|
|
||||||
|
'Specification-Title': 'Progressia',
|
||||||
|
|
||||||
|
'Implementation-Title': 'Progressia',
|
||||||
|
'Implementation-Version': project.version,
|
||||||
|
'Implementation-Version-Git-Commit': project.commit,
|
||||||
|
'Implementation-Version-Git-Branch': project.branch,
|
||||||
|
'Implementation-Version-BuildId': project.buildId,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jar.dependsOn specifyLocalManifest
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Library export
|
* Copy libraries into buil/libs/lib directory, next to Progressia.jar
|
||||||
*/
|
*/
|
||||||
|
|
||||||
task exportLibs(type: Sync) {
|
task exportLibs(type: Sync) {
|
||||||
mustRunAfter addNativeDependencies
|
description 'Copies runtime libraries into a subdirectory next to the output JAR.'
|
||||||
|
|
||||||
|
jar.dependsOn exportLibs
|
||||||
|
|
||||||
into libsDirectory.get().getAsFile().getPath() + "/lib"
|
|
||||||
exclude { !isDependencyRequested(it.getName()) }
|
|
||||||
from configurations.runtimeClasspath
|
from configurations.runtimeClasspath
|
||||||
|
into 'build/libs/lib'
|
||||||
}
|
}
|
||||||
|
|
||||||
jar.dependsOn(exportLibs)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packaging
|
* Apply LWJGL logic
|
||||||
|
*/
|
||||||
|
apply from: 'build_logic/lwjgl.gradle'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Packaging working directory configuration
|
||||||
*/
|
*/
|
||||||
|
|
||||||
task packageDebian(type: Exec) {
|
import java.nio.file.*
|
||||||
description 'Builds the project and creates a Debain package.'
|
import java.nio.file.attribute.*
|
||||||
group 'Progressia'
|
|
||||||
|
|
||||||
dependsOn build
|
task createPackagingDirs() {
|
||||||
dependsOn requestLinuxDependencies
|
description 'Resets build/tmp/packaging directory.'
|
||||||
|
|
||||||
commandLine './buildPackages.sh', 'debian'
|
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
println "Debian package available in build_packages/"
|
def tmpDir = buildDir.toPath().resolve 'tmp/packaging'
|
||||||
|
|
||||||
|
def nuke = new SimpleFileVisitor<Path>() {
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||||
|
Files.delete(file);
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
|
||||||
|
if (e == null) {
|
||||||
|
Files.delete(dir);
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
} else {
|
||||||
|
// directory iteration failed
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fckn nuke tmpDir from orbit
|
||||||
|
// I'm so done with deleting file trees in Java/Groovy/whatever
|
||||||
|
// ...Not using File.deleteDir() because the latter recurses into symlinks, and we don't want to wipe build/libs/lib
|
||||||
|
if (Files.exists(tmpDir)) {
|
||||||
|
Files.walkFileTree tmpDir, nuke
|
||||||
|
}
|
||||||
|
|
||||||
|
Files.createDirectories tmpDir.resolve('workingDir')
|
||||||
|
Files.createDirectories buildDir.toPath().resolve('packages')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task packageWindows(type: Exec) {
|
task linkBuildOutputForPackaging() {
|
||||||
description 'Builds the project and creates a Windows installer.'
|
description 'Symlinks the contents of build/libs into packaging working directory.'
|
||||||
group 'Progressia'
|
|
||||||
|
|
||||||
dependsOn build
|
dependsOn build
|
||||||
dependsOn requestWindowsDependencies
|
dependsOn createPackagingDirs
|
||||||
|
|
||||||
commandLine './buildPackages.sh', 'windows'
|
onlyIf { preparePackaging.ext.mode == 'symlink' }
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
println "Windows installer available in build_packages/"
|
def from = buildDir.toPath().resolve 'libs'
|
||||||
|
def into = buildDir.toPath().resolve "tmp/packaging/workingDir/${preparePackaging.ext.buildDest}"
|
||||||
|
|
||||||
|
Files.createDirectories into
|
||||||
|
|
||||||
|
Files.list(from).each {
|
||||||
|
def fileName = it.fileName.toString()
|
||||||
|
|
||||||
|
// Exclude all JARs except the current one
|
||||||
|
if (fileName ==~ "${project.name}.*\\.jar" && fileName != tasks.jar.archiveFileName.get())
|
||||||
|
return
|
||||||
|
|
||||||
|
Files.createSymbolicLink into.resolve(it.fileName), it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task copyBuildOutputForPackaging(type: Copy) {
|
||||||
|
description 'Copies the contents of build/libs into packaging working directory.'
|
||||||
|
|
||||||
|
dependsOn build
|
||||||
|
dependsOn createPackagingDirs
|
||||||
|
|
||||||
|
onlyIf { preparePackaging.ext.mode == 'copy' }
|
||||||
|
|
||||||
|
from 'build/libs'
|
||||||
|
filesMatching("${project.name}*.jar") {
|
||||||
|
include tasks.jar.archiveFileName.get()
|
||||||
|
}
|
||||||
|
into "build/tmp/packaging/workingDir/${ -> preparePackaging.ext.buildDest}"
|
||||||
|
}
|
||||||
|
|
||||||
|
task preparePackaging {
|
||||||
|
preparePackaging.ext.buildDest = ''
|
||||||
|
preparePackaging.ext.mode = 'symlink'
|
||||||
|
|
||||||
|
dependsOn createPackagingDirs
|
||||||
|
dependsOn linkBuildOutputForPackaging
|
||||||
|
dependsOn copyBuildOutputForPackaging
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apply all packaging scripts
|
||||||
|
*/
|
||||||
|
|
||||||
|
new File(projectDir, 'build_logic/packaging').list().each {
|
||||||
|
apply from: "build_logic/packaging/$it/script.gradle"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure no more than one packaging task is scheduled
|
||||||
|
*/
|
||||||
|
|
||||||
|
gradle.taskGraph.whenReady { graph ->
|
||||||
|
if (graph.allTasks.count { it.name ==~ /package[^_]*/ } > 1) {
|
||||||
|
def offenders = graph.allTasks.findAll { it.name ==~ /package[^_]*/ }
|
||||||
|
throw new GradleException("Cannot execute multiple package tasks within a single build\n" +
|
||||||
|
"\tOffending tasks: $offenders")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convenience build tasks
|
||||||
|
*/
|
||||||
|
|
||||||
task buildCrossPlatform {
|
task buildCrossPlatform {
|
||||||
description 'Builds the project including native libraries for all available platforms.'
|
description 'Builds the project including native libraries for all available platforms.'
|
||||||
group 'Progressia'
|
group 'Progressia'
|
||||||
@ -305,17 +391,17 @@ task buildCrossPlatform {
|
|||||||
dependsOn build
|
dependsOn build
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
println "Native libraries for all platforms have been added"
|
logger.info 'Native libraries for all platforms have been added'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task buildLocal {
|
task buildLocal {
|
||||||
description "Builds the project including only native libraries for current platform ($lwjglNatives)."
|
description "Builds the project including only native libraries for current platform (${lwjgl.localArch})."
|
||||||
group 'Progressia'
|
group 'Progressia'
|
||||||
|
|
||||||
dependsOn build
|
dependsOn build
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
println "Native libraries only for platform $lwjglNatives have been added"
|
logger.info "Native libraries only for platform ${lwjgl.localArch} have been added"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
191
buildPackages.sh
@ -1,191 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
#
|
|
||||||
# Progressia
|
|
||||||
# Copyright (C) 2020-2021 Wind Corporation and contributors
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License as published by
|
|
||||||
# the Free Software Foundation, either version 3 of the License, or
|
|
||||||
# (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
|
|
||||||
echoerr() { echo "$@" 1>&2; }
|
|
||||||
|
|
||||||
buildDebianPackage() {
|
|
||||||
|
|
||||||
# Commands that must be available to execute this action
|
|
||||||
requiredCommands='dpkg-deb fakeroot'
|
|
||||||
|
|
||||||
# Package name. Sync with control file manually!
|
|
||||||
name='progressia-techdemo'
|
|
||||||
# Version that the package will receive. Sync with control file manually!
|
|
||||||
version='1.0_all'
|
|
||||||
|
|
||||||
# This directory will be copied into $tmpDir
|
|
||||||
templateDirectory="build_packages/DEB/template"
|
|
||||||
|
|
||||||
# Files that must be present
|
|
||||||
requiredFiles="$templateDirectory/DEBIAN/control"
|
|
||||||
|
|
||||||
nameAndVersion="$name-$version"
|
|
||||||
tmpDir="build_packages/DEB/$nameAndVersion"
|
|
||||||
outputFile="build_packages/DEB/$nameAndVersion.deb"
|
|
||||||
|
|
||||||
echo "Checking environment to build Debian package"
|
|
||||||
|
|
||||||
for item in $requiredCommands; do
|
|
||||||
if command -v "$item" &> /dev/null; then
|
|
||||||
echo "- $item found"
|
|
||||||
else
|
|
||||||
echoerr "Command $item not found, cannot package"
|
|
||||||
exit 100
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
for file in $requiredFiles; do
|
|
||||||
if ! [ -r "$file" ]; then
|
|
||||||
echoerr "$file is missing or not readable, cannot package"
|
|
||||||
exit 101
|
|
||||||
else
|
|
||||||
echo "- $file is present and readable"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Environment OK; packaging Debian package"
|
|
||||||
exitCode=0
|
|
||||||
|
|
||||||
{
|
|
||||||
shareDir="$tmpDir/usr/share/progressia"
|
|
||||||
|
|
||||||
mkdir -p "$tmpDir" &&
|
|
||||||
mkdir -p "$shareDir" &&
|
|
||||||
cp -r "$templateDirectory"/* "$tmpDir" &&
|
|
||||||
cp -r 'build/libs/lib' "$shareDir/lib" &&
|
|
||||||
cp 'build/libs/Progressia.jar' "$shareDir/Progressia.jar" &&
|
|
||||||
echo "------ DPKG-DEB ------" &&
|
|
||||||
fakeroot dpkg-deb --build "$tmpDir" &&
|
|
||||||
echo "---- DPKG-DEB END ----" &&
|
|
||||||
mv "$outputFile" build_packages
|
|
||||||
} || {
|
|
||||||
echoerr "Could not create Debian package"
|
|
||||||
exitCode=1
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
if [ -d "$tmpDir" ]; then
|
|
||||||
rm -r "$tmpDir"
|
|
||||||
fi
|
|
||||||
echo "Cleaned up"
|
|
||||||
} || {
|
|
||||||
echoerr "Could not clean up after packaging Debian package"
|
|
||||||
exitCode=2
|
|
||||||
}
|
|
||||||
|
|
||||||
exit "$exitCode"
|
|
||||||
}
|
|
||||||
|
|
||||||
buildWindowsInstaller() {
|
|
||||||
|
|
||||||
# Commands that must be available to execute this action
|
|
||||||
requiredCommands='makensis'
|
|
||||||
|
|
||||||
# NSIS configuration file that must be present
|
|
||||||
configurationFile='build_packages/NSIS/ProgressiaInstaller.nsi'
|
|
||||||
|
|
||||||
# File that will be output
|
|
||||||
outputFile='build_packages/NSIS/ProgressiaInstaller.exe'
|
|
||||||
|
|
||||||
echo "Checking environment to build Windows installer"
|
|
||||||
|
|
||||||
for item in $requiredCommands; do
|
|
||||||
if command -v "$item" &> /dev/null; then
|
|
||||||
echo "- $item found"
|
|
||||||
else
|
|
||||||
echoerr "Command $item not found, cannot build"
|
|
||||||
exit 100
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if ! [ -r "$configurationFile" ]; then
|
|
||||||
echoerr "$configurationFile is missing or not readable, cannot build"
|
|
||||||
exit 101
|
|
||||||
else
|
|
||||||
echo "- $configurationFile is present and readable"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Environment OK; building Windows installer"
|
|
||||||
exitCode=0
|
|
||||||
|
|
||||||
{
|
|
||||||
cp -r 'build/libs/lib' 'build_packages/NSIS/lib' &&
|
|
||||||
cp 'build/libs/Progressia.jar' 'build_packages/NSIS/Progressia.jar' &&
|
|
||||||
cp 'LICENSE' 'build_packages/NSIS/LICENSE.txt' &&
|
|
||||||
echo "------ NSIS ------" &&
|
|
||||||
makensis "$configurationFile" &&
|
|
||||||
echo "---- NSIS END ----" &&
|
|
||||||
mv "$outputFile" build_packages
|
|
||||||
} || {
|
|
||||||
echoerr "Could not build Windows installer"
|
|
||||||
exitCode=1
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
if [ -d 'build_packages/NSIS/lib' ]; then
|
|
||||||
rm -r 'build_packages/NSIS/lib'
|
|
||||||
fi
|
|
||||||
if [ -e 'build_packages/NSIS/Progressia.jar' ]; then
|
|
||||||
rm 'build_packages/NSIS/Progressia.jar'
|
|
||||||
fi
|
|
||||||
if [ -e 'build_packages/NSIS/LICENSE.txt' ]; then
|
|
||||||
rm 'build_packages/NSIS/LICENSE.txt'
|
|
||||||
fi
|
|
||||||
echo "Cleaned up"
|
|
||||||
} || {
|
|
||||||
echoerr "Could not clean up after building Windows installer"
|
|
||||||
exitCode=2
|
|
||||||
}
|
|
||||||
|
|
||||||
exit "$exitCode"
|
|
||||||
}
|
|
||||||
|
|
||||||
printUsage() {
|
|
||||||
echoerr "Usage: $0 TARGET"
|
|
||||||
echoerr " where TARGET is 'debian' or 'windows'"
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ -n "$2" ]; then
|
|
||||||
echoerr "Too many arguments."
|
|
||||||
printUsage
|
|
||||||
exit 202
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
"debian")
|
|
||||||
buildDebianPackage
|
|
||||||
;;
|
|
||||||
"windows")
|
|
||||||
buildWindowsInstaller
|
|
||||||
;;
|
|
||||||
"")
|
|
||||||
echoerr "No action specified"
|
|
||||||
printUsage
|
|
||||||
exit 200
|
|
||||||
;;
|
|
||||||
"--help" | "-help" | "help" | "?")
|
|
||||||
printUsage
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echoerr "Unknown action '$1'"
|
|
||||||
printUsage
|
|
||||||
exit 201
|
|
||||||
;;
|
|
||||||
esac
|
|
117
build_logic/lwjgl.gradle
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Build logic for Progressia
|
||||||
|
* LWJGL dependency logic
|
||||||
|
*/
|
||||||
|
|
||||||
|
project.ext.lwjgl = new HashMap<>()
|
||||||
|
|
||||||
|
// Version of LWJGL
|
||||||
|
lwjgl.version = '3.2.3'
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Target platforms for current operation.
|
||||||
|
* This is filled in by the request* tasks. This is referenced by the addLwjglNatives task.
|
||||||
|
* When empty, current platform is assumed.
|
||||||
|
*/
|
||||||
|
lwjgl.targets = new HashSet<>()
|
||||||
|
|
||||||
|
// LWJGL components. To include org.lwjgl:lwjgl-foobar, add 'foobar' to this list.
|
||||||
|
lwjgl.libraries = [
|
||||||
|
'opengl',
|
||||||
|
'glfw',
|
||||||
|
'openal',
|
||||||
|
'stb'
|
||||||
|
]
|
||||||
|
|
||||||
|
// Determine the architecture of the build environment
|
||||||
|
import org.gradle.internal.os.OperatingSystem
|
||||||
|
switch (OperatingSystem.current()) {
|
||||||
|
case OperatingSystem.LINUX:
|
||||||
|
def osArch = System.getProperty('os.arch')
|
||||||
|
lwjgl.localArch = osArch.startsWith('arm') || osArch.startsWith('aarch64')
|
||||||
|
? "linux-${osArch.contains('64') || osArch.startsWith('armv8') ? 'arm64' : 'arm32'}"
|
||||||
|
: 'linux'
|
||||||
|
break
|
||||||
|
case OperatingSystem.MAC_OS:
|
||||||
|
lwjgl.localArch = 'macos'
|
||||||
|
break
|
||||||
|
case OperatingSystem.WINDOWS:
|
||||||
|
lwjgl.localArch = System.getProperty('os.arch').contains('64') ? 'windows' : 'windows-x86'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Declare pure-Java dependencies
|
||||||
|
dependencies {
|
||||||
|
// BOM
|
||||||
|
implementation platform("org.lwjgl:lwjgl-bom:${lwjgl.version}")
|
||||||
|
|
||||||
|
// Core
|
||||||
|
implementation 'org.lwjgl:lwjgl'
|
||||||
|
|
||||||
|
// Components
|
||||||
|
lwjgl.libraries.each { implementation "org.lwjgl:lwjgl-$it" }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds LWJGL native libraries to runtimeOnly configuration
|
||||||
|
*/
|
||||||
|
task lwjgl_addNativesToRuntimeOnly {
|
||||||
|
// Make sure runtimeOnly has not been resolved
|
||||||
|
compileJava.dependsOn lwjgl_addNativesToRuntimeOnly
|
||||||
|
configureManifest.dependsOn lwjgl_addNativesToRuntimeOnly
|
||||||
|
exportLibs.dependsOn lwjgl_addNativesToRuntimeOnly
|
||||||
|
|
||||||
|
doFirst {
|
||||||
|
if (project.hasProperty('forceTargets')) {
|
||||||
|
try {
|
||||||
|
def oldTargets = lwjgl.targets.join(',')
|
||||||
|
|
||||||
|
lwjgl.targets.clear()
|
||||||
|
lwjgl.targets.addAll project.forceTargets.split(',')*.trim().collect { it == 'local' ? lwjgl.localArch : it }
|
||||||
|
|
||||||
|
logger.info 'Overriding selected platforms {} with {}', oldTargets, lwjgl.targets.join(',')
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new GradleException("Could not parse forceTargets \"${project.forceTargets}\", expecting platform-1,platform-2,local", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lwjgl.targets.isEmpty()) {
|
||||||
|
logger.info 'Adding LWJGL native dependencies for local platform only: {}', lwjgl.localArch
|
||||||
|
lwjgl.targets.add lwjgl.localArch
|
||||||
|
} else {
|
||||||
|
logger.info 'Adding LWJGL native dependencies for platforms: {}', lwjgl.targets.sort().join(', ')
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
lwjgl.targets.each { target ->
|
||||||
|
runtimeOnly "org.lwjgl:lwjgl::natives-$target"
|
||||||
|
lwjgl.libraries.each { lib ->
|
||||||
|
runtimeOnly "org.lwjgl:lwjgl-$lib::natives-$target"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task requestCrossPlatformDependencies {
|
||||||
|
description 'Adds LWJGL natives for all available platforms.'
|
||||||
|
|
||||||
|
lwjgl_addNativesToRuntimeOnly.mustRunAfter requestCrossPlatformDependencies
|
||||||
|
}
|
||||||
|
|
||||||
|
def requestTask(String name, String... targets) {
|
||||||
|
def theTask = task "request${name}Dependencies"
|
||||||
|
|
||||||
|
theTask.doFirst {
|
||||||
|
lwjgl.targets.addAll targets
|
||||||
|
}
|
||||||
|
|
||||||
|
theTask.description "Adds LWJGL natives for $name (${targets.join(', ')})."
|
||||||
|
|
||||||
|
requestCrossPlatformDependencies.dependsOn theTask
|
||||||
|
lwjgl_addNativesToRuntimeOnly.mustRunAfter theTask
|
||||||
|
}
|
||||||
|
|
||||||
|
requestTask 'Linux', 'linux', 'linux-arm32', 'linux-arm64'
|
||||||
|
requestTask 'Windows', 'windows', 'windows-x86'
|
||||||
|
requestTask 'MacOS', 'macos'
|
38
build_logic/packaging/deb/script.gradle
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
task packageDeb_processResources(type: Copy) {
|
||||||
|
dependsOn resolveVersion
|
||||||
|
dependsOn preparePackaging
|
||||||
|
|
||||||
|
from 'src/packaging/deb'
|
||||||
|
|
||||||
|
filesMatching('DEBIAN/control') {
|
||||||
|
expand(version: { -> project.version})
|
||||||
|
}
|
||||||
|
|
||||||
|
into 'build/tmp/packaging/workingDir'
|
||||||
|
}
|
||||||
|
|
||||||
|
task packageDeb_configure() {
|
||||||
|
preparePackaging.mustRunAfter packageDeb_configure
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
tasks.preparePackaging.ext.buildDest = '/usr/share/progressia'
|
||||||
|
tasks.preparePackaging.ext.mode = 'copy'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task packageDeb(type: Exec) {
|
||||||
|
description 'Builds the project and creates a Debian package.'
|
||||||
|
group 'Progressia'
|
||||||
|
|
||||||
|
dependsOn packageDeb_configure
|
||||||
|
dependsOn requestLinuxDependencies
|
||||||
|
dependsOn build
|
||||||
|
dependsOn preparePackaging
|
||||||
|
|
||||||
|
dependsOn packageDeb_processResources
|
||||||
|
|
||||||
|
executable 'dpkg-deb'
|
||||||
|
args '--root-owner-group'
|
||||||
|
args '--build', 'build/tmp/packaging/workingDir'
|
||||||
|
args 'build/packages'
|
||||||
|
}
|
50
build_logic/packaging/nsis/script.gradle
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
task packageNsis_processResources(type: Copy) {
|
||||||
|
dependsOn preparePackaging
|
||||||
|
|
||||||
|
from ('src/packaging/nsis') {
|
||||||
|
exclude 'left_side.png'
|
||||||
|
}
|
||||||
|
from('LICENSE') {
|
||||||
|
rename 'LICENSE', 'LICENSE.txt'
|
||||||
|
}
|
||||||
|
into 'build/tmp/packaging/workingDir'
|
||||||
|
}
|
||||||
|
|
||||||
|
task packageNsis_generateIcon(type: Exec) {
|
||||||
|
mustRunAfter preparePackaging
|
||||||
|
|
||||||
|
executable 'convert'
|
||||||
|
args files('src/main/resources/assets/icons/*.original.png').files*.path
|
||||||
|
args 'build/tmp/packaging/workingDir/logo.ico'
|
||||||
|
}
|
||||||
|
|
||||||
|
task packageNsis_generateLeftSide(type: Exec) {
|
||||||
|
mustRunAfter preparePackaging
|
||||||
|
|
||||||
|
executable 'convert'
|
||||||
|
args 'src/packaging/nsis/left_side.png'
|
||||||
|
args '-alpha', 'off'
|
||||||
|
args 'BMP3:build/tmp/packaging/workingDir/left_side.bmp'
|
||||||
|
}
|
||||||
|
|
||||||
|
task packageNsis(type: Exec) {
|
||||||
|
description 'Builds the project and creates a Windows NSIS installer.'
|
||||||
|
group 'Progressia'
|
||||||
|
|
||||||
|
dependsOn requestWindowsDependencies
|
||||||
|
dependsOn build
|
||||||
|
dependsOn resolveVersion
|
||||||
|
dependsOn preparePackaging
|
||||||
|
|
||||||
|
dependsOn packageNsis_processResources
|
||||||
|
dependsOn packageNsis_generateIcon
|
||||||
|
dependsOn packageNsis_generateLeftSide
|
||||||
|
|
||||||
|
executable 'makensis'
|
||||||
|
args '-NOCONFIG'
|
||||||
|
args "-DPROJECT_NAME=${project.name}"
|
||||||
|
args "-DPROJECT_VERSION=${ -> project.version}"
|
||||||
|
args "-DMAIN_JAR_FILE=${ -> project.tasks.jar.archiveFileName.get()}"
|
||||||
|
args "-DOUTPUT_DIR=${project.buildDir.absolutePath}/packages"
|
||||||
|
args 'build/tmp/packaging/workingDir/config.nsi'
|
||||||
|
}
|
41
build_logic/packaging/zip/script.gradle
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
task packageZip_processResources(type: Copy) {
|
||||||
|
dependsOn preparePackaging
|
||||||
|
|
||||||
|
from ('src/packaging/zip') {
|
||||||
|
filesMatching('start.*') {
|
||||||
|
filter(
|
||||||
|
org.apache.tools.ant.filters.ReplaceTokens,
|
||||||
|
tokens: [mainJarFile: project.tasks.jar.archiveFileName.get()]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
from ('src/main/resource/assets/icons/logo256.original.png') {
|
||||||
|
rename 'logo256.original.png', 'logo.png'
|
||||||
|
}
|
||||||
|
from('LICENSE') {
|
||||||
|
rename 'LICENSE', 'LICENSE.txt'
|
||||||
|
}
|
||||||
|
into 'build/tmp/packaging/workingDir'
|
||||||
|
}
|
||||||
|
|
||||||
|
task packageZip(type: Zip) {
|
||||||
|
description 'Builds the project and creates a cross-platform ZIP package.'
|
||||||
|
group 'Progressia'
|
||||||
|
|
||||||
|
dependsOn resolveVersion
|
||||||
|
dependsOn requestCrossPlatformDependencies
|
||||||
|
dependsOn build
|
||||||
|
dependsOn preparePackaging
|
||||||
|
|
||||||
|
dependsOn packageZip_processResources
|
||||||
|
|
||||||
|
archiveBaseName = project.name
|
||||||
|
archiveAppendix = 'universal'
|
||||||
|
|
||||||
|
doFirst {
|
||||||
|
archiveVersion = project.version
|
||||||
|
}
|
||||||
|
|
||||||
|
from 'build/tmp/packaging/workingDir'
|
||||||
|
destinationDirectory = file('build/packages')
|
||||||
|
}
|
Before Width: | Height: | Size: 151 KiB |
Before Width: | Height: | Size: 187 KiB |
@ -1,8 +1,10 @@
|
|||||||
# Build Guide
|
# Build Guide
|
||||||
|
|
||||||
This document is a guide to building Progressia from source.
|
This document is a guide to building Progressia from source. For quick reference, see
|
||||||
|
[Build Script Reference](BuildScriptReference.md).
|
||||||
|
|
||||||
Compilation should be possible on all platforms that support JDK 8 or later, however, packaging scripts require Bash.
|
Compilation should be possible on all platforms that support JDK 8 or later, however, packaging scripts require
|
||||||
|
additional programs in `PATH`.
|
||||||
|
|
||||||
This guide assumes you are familiar with using a terminal or Windows Command Prompt or PowerShell.
|
This guide assumes you are familiar with using a terminal or Windows Command Prompt or PowerShell.
|
||||||
|
|
||||||
@ -150,54 +152,46 @@ GNU/Linux and Windows natives:
|
|||||||
./gradlew build requestLinuxDependencies requestWindowsDependencies
|
./gradlew build requestLinuxDependencies requestWindowsDependencies
|
||||||
```
|
```
|
||||||
|
|
||||||
For finer control please edit `build.gradle` manually by adding the desired natives to the `project.ext.platforms` set like so:
|
|
||||||
|
|
||||||
```
|
|
||||||
project.ext.platforms = new HashSet<>()
|
|
||||||
project.ext.platforms.add 'natives-windows-x86'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Packaging
|
## Packaging
|
||||||
|
|
||||||
A Debian package and a Windows installer can be created automatically on systems that support Bash. These tasks are delegated
|
A universal ZIP distribution, a Debian package and a Windows NSIS installer may be created automatically by the build
|
||||||
by Gradle to `buildPackages.sh` in repository root. This script checks the environment and assembles the requested output; the
|
script.
|
||||||
resulting files are moved into `build_packages`.
|
|
||||||
|
### Creating a universal ZIP package
|
||||||
|
|
||||||
|
A universal cross-platform ZIP archive can be created with the following Gradle task:
|
||||||
|
|
||||||
|
```
|
||||||
|
./gradlew packageZip
|
||||||
|
```
|
||||||
|
|
||||||
|
Gradle will then build all artifacts necessary to run the game on all available platforms and package game files,
|
||||||
|
libraries, launch scripts, etc. into a compressed ZIP archive.
|
||||||
|
|
||||||
|
The resulting file can be found in `build/packages/`
|
||||||
|
|
||||||
### Creating a Debian package
|
### Creating a Debian package
|
||||||
|
|
||||||
A Debian package can be created with the following Gradle task:
|
A Debian package can be created with the following Gradle task:
|
||||||
|
|
||||||
```
|
```
|
||||||
./gradlew packageDebian
|
./gradlew packageDeb
|
||||||
```
|
```
|
||||||
|
|
||||||
Gradle will then build all artifacts necessary to run the game on GNU/Linux (all three architectures) and invoke
|
Gradle will then build all artifacts necessary to run the game on GNU/Linux (all three architectures) and invoke
|
||||||
`./buildPackages.sh debian`. Commands `dpkg-deb` and `fakeroot` must be available in system path in order to build the package.
|
`dpkg-deb`. Commands `dpkg-deb` must be available in system path in order to build the package.
|
||||||
|
|
||||||
### Creating a Windows installer
|
### Creating a Windows installer
|
||||||
|
|
||||||
A Windows installer can be created with the following Gradle task:
|
A Windows NSIS installer can be created with the following Gradle task:
|
||||||
|
|
||||||
```
|
```
|
||||||
./gradlew packageWindows
|
./gradlew packageNsis
|
||||||
```
|
```
|
||||||
|
|
||||||
Gradle will then build all artifacts necessary to run the game on Windows (both x64 and x86 architectures) and invoke
|
Gradle will then build all artifacts necessary to run the game on Windows (both x64 and x86 architectures) and invoke
|
||||||
`./buildPackages.sh windows`.
|
`makensis`.
|
||||||
|
|
||||||
Windows installers are implemented with [NSIS](https://nsis.sourceforge.io/). Command `makensis` must be available in system
|
Windows installers are implemented with [NSIS](https://nsis.sourceforge.io/). [ImageMagick](https://imagemagick.org),
|
||||||
path in order to build the installer.
|
a command-line image editing tool, is used to generate some assets for the installer. Commands `makensis` and
|
||||||
|
`convert` (from ImageMagick) must be available in system path in order to build the installer.
|
||||||
## Gradle tasks summary
|
|
||||||
|
|
||||||
- `buildLocal` – creates a build optimized for current platform. Use this to quickly build the game during development.
|
|
||||||
- `buildCrossPlatform` – creates a build that supports all known architectures. Use this to build a universal version of the game.
|
|
||||||
- `build` – currently a synonym of `buildLocal`; creates a default build.
|
|
||||||
- `packageDebian` – creates a Debian package. Do not invoke together with `packageWindows`.
|
|
||||||
- `packageWindows` – creates a Windows installer. Do not invoke together with `packageDebian`.
|
|
||||||
- `requestLinuxDependencies` – requests that `natives-linux`, `natives-linux-arm32` and `natives-linux-arm64` binaries are included when building.
|
|
||||||
- `requestWindowsDependencies` – requests that `natives-windows` and `natives-windows-x86` binaries are included when building.
|
|
||||||
- `requestMacOSDependencies` – requests that `natives-macos` binaries are included when building.
|
|
||||||
- `requestCrossPlatformDependencies` – requests that all binaries are included when building.
|
|
||||||
|
|
||||||
All other basic and Java-related Gradle tasks are available as well.
|
|
||||||
|
103
docs/building/BuildScriptReference.md
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
# Build Script Reference
|
||||||
|
|
||||||
|
This document is a user's reference for the build script of Progressia. For a beginner-friendly guide, see
|
||||||
|
[Build Guide](BuildGuide.md).
|
||||||
|
|
||||||
|
## Gradle tasks summary
|
||||||
|
|
||||||
|
- `buildLocal` – creates a build optimized for current platform. Use this to quickly build the game during development.
|
||||||
|
- `buildCrossPlatform` – creates a build that supports all known architectures. Use this to build a universal version of the game.
|
||||||
|
- `build` – currently a synonym of `buildLocal`; creates a default build.
|
||||||
|
- `packageZip` – creates a universal ZIP. Incompatible with other `package` tasks.
|
||||||
|
- `packageDeb` – creates a Debian package. Incompatible with other `package` tasks.
|
||||||
|
- `packageNsis` – creates a Windows NSIS installer. Incompatible with other `package` tasks.
|
||||||
|
- `requestLinuxDependencies` – requests that `natives-linux`, `natives-linux-arm32` and `natives-linux-arm64` binaries are included when building.
|
||||||
|
- `requestWindowsDependencies` – requests that `natives-windows` and `natives-windows-x86` binaries are included when building.
|
||||||
|
- `requestMacOSDependencies` – requests that `natives-macos` binaries are included when building.
|
||||||
|
- `requestCrossPlatformDependencies` – requests that all binaries are included when building.
|
||||||
|
|
||||||
|
To execute a task, run `./gradlew <task-name>`.
|
||||||
|
|
||||||
|
`build`-type tasks output the executable JAR and all libraries required at runtime into `build/libs`. `package`-type
|
||||||
|
tasks output packages into `build/packages`.
|
||||||
|
|
||||||
|
## Packaging tasks
|
||||||
|
|
||||||
|
Some packaging tasks require additional software in `PATH`.
|
||||||
|
|
||||||
|
| Task | Commands required in `PATH` |
|
||||||
|
|---------------|------------------------------------------|
|
||||||
|
| `packageDeb` | `dpkg-deb` |
|
||||||
|
| `packageZip` | _none_ |
|
||||||
|
| `packageNsis` | `makensis`, `convert` (from ImageMagick) |
|
||||||
|
|
||||||
|
## Version and metadata
|
||||||
|
|
||||||
|
### Version scheme
|
||||||
|
|
||||||
|
Progressia builds are identified by four parameters: version, Git commit, Git branch and build ID.
|
||||||
|
|
||||||
|
Versions roughly follow [semantic versioning](https://semver.org/spec/v2.0.0.html), with each version fitting the
|
||||||
|
`MAJOR.MINOR.PATCH[-SUFFIX]` pattern. Depending on the build environment (see below), version is either "real" with
|
||||||
|
no metadata (e.g. `0.43.2` or `1.2.1-beta`) or a dummy fallback with build metadata (e.g. `999.0.0-2021_07_23` or
|
||||||
|
`999.0.0-WJ3`).
|
||||||
|
|
||||||
|
### Version detection
|
||||||
|
|
||||||
|
Build script considers three scenarios when determining the version:
|
||||||
|
|
||||||
|
1. `version` project property is set explicitly. This may be done in a variety of ways, for example with command line
|
||||||
|
argument `-Pversion=1.2.3`
|
||||||
|
(see [Gradle docs](https://docs.gradle.org/current/userguide/build_environment.html#sec:project_properties))
|
||||||
|
2. Local Git repository is found, and HEAD is tagged appropriately: version is the tag name with leading `v`
|
||||||
|
stripped. Example: `v1.2.3` is version `1.2.3`
|
||||||
|
3. Local Git repository is found, and some ancestor of HEAD is tagged appropriately: version is the tag name with
|
||||||
|
leading `v` stripped and PATCH incremented by one. Example: `v1.2.3` is version `1.2.4`
|
||||||
|
|
||||||
|
Tags not named like `vMAJOR.MINOR.PATCH[-SUFFIX]` are ignored for cases 2 and 3.
|
||||||
|
|
||||||
|
In all other cases, a fallback dummy value is used for version, appended with build ID or current date.
|
||||||
|
|
||||||
|
### Git metadata
|
||||||
|
|
||||||
|
Git commit and Git branch are correspond to the state of the local Git repository, if any. In case Git metadata is
|
||||||
|
unavailable, `-` fallback is used for both fields.
|
||||||
|
|
||||||
|
### Build ID
|
||||||
|
|
||||||
|
Build ID uniquely identifies artifacts produced by automated build systems. For example, builds executed by WindCorp
|
||||||
|
Jenkins suite have build IDs like `WJ3` or `WJ142`. Build ID must be provided explicitly; it is `-` unless specified
|
||||||
|
otherwise.
|
||||||
|
|
||||||
|
Build ID may be set with `buildId` project property. This may be done in a variety of ways, for example with command
|
||||||
|
line argument `-PbuildId=WJ3`
|
||||||
|
(see [Gradle docs](https://docs.gradle.org/current/userguide/build_environment.html#sec:project_properties)).
|
||||||
|
|
||||||
|
## Native libraries
|
||||||
|
|
||||||
|
LWJGL uses native libraries. Build script declares platform-specific dependencies based on the set of target
|
||||||
|
platforms, `project.ext.lwjgl.targets` (aka `lwjgl.targets`). These dependencies are added to `runtimeOnly`
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
When this set is empty, the script selects natives for current platform. Otherwise, all platforms in the set are
|
||||||
|
included.
|
||||||
|
|
||||||
|
`lwjgl.targets` is populated automatically by packaging tasks and by `buildCrossPlatform`. To add extra targets,
|
||||||
|
``requestXxxDependencies` tasks may be used.
|
||||||
|
|
||||||
|
Target selection mechanism may be overridden with `forceTargets` project property. This may be done in a variety of
|
||||||
|
ways, for example with command line argument `-PforceTargets=windows-x86,local`
|
||||||
|
(see [Gradle docs](https://docs.gradle.org/current/userguide/build_environment.html#sec:project_properties)). The
|
||||||
|
value is a comma-separated list of target architectures. `local` target will be replaced with the automatically
|
||||||
|
detected current architecture.
|
||||||
|
|
||||||
|
### Available targets
|
||||||
|
|
||||||
|
| Name | Task |
|
||||||
|
|---------------|------------------------------|
|
||||||
|
| `linux` | `requestLinuxDependencies` |
|
||||||
|
| `linux-arm32` | `requestLinuxDependencies` |
|
||||||
|
| `linux-arm64` | `requestLinuxDependencies` |
|
||||||
|
| `windows` | `requestWindowsDependencies` |
|
||||||
|
| `windows-x86` | `requestWindowsDependencies` |
|
||||||
|
| `macos` | `requestMacOSDependencies` |
|
1
logs/game.log
Normal file
@ -0,0 +1 @@
|
|||||||
|
22:26:25.948 [Music Thread ] WARN ru.windcorp.progressia.test.TestMusicPlayer > No music found
|
@ -18,6 +18,177 @@
|
|||||||
|
|
||||||
package ru.windcorp.progressia;
|
package ru.windcorp.progressia;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.jar.Attributes;
|
||||||
|
import java.util.jar.Manifest;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class providing access to build metadata.
|
||||||
|
*/
|
||||||
public class Progressia {
|
public class Progressia {
|
||||||
|
|
||||||
|
private static final String NAME = "Progressia";
|
||||||
|
private static String version;
|
||||||
|
private static String gitCommit;
|
||||||
|
private static String gitBranch;
|
||||||
|
private static String buildId;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
Manifest manifest = findManifest();
|
||||||
|
|
||||||
|
if (manifest == null) {
|
||||||
|
setDevelopmentMetadata();
|
||||||
|
LogManager.getLogger().info(
|
||||||
|
"Manifest with Specification-Title not found. "
|
||||||
|
+ "Either you are in a development environment or something has gone horribly wrong with classloaders."
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
fillMetadata(manifest);
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
CrashReports.crash(t, "Something went wrong while loading metadata");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Manifest findManifest() {
|
||||||
|
try {
|
||||||
|
Enumeration<URL> resources = Progressia.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
|
||||||
|
Collection<IOException> exceptions = new ArrayList<>();
|
||||||
|
|
||||||
|
while (resources.hasMoreElements()) {
|
||||||
|
URL url = resources.nextElement();
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
Manifest manifest = new Manifest(url.openStream());
|
||||||
|
Attributes mainAttributes = manifest.getMainAttributes();
|
||||||
|
if (NAME.equals(mainAttributes.getValue("Specification-Title"))) {
|
||||||
|
return manifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
exceptions.add(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exceptions.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOException scapegoat = null;
|
||||||
|
for (IOException e : exceptions) {
|
||||||
|
if (scapegoat == null) {
|
||||||
|
scapegoat = e;
|
||||||
|
} else {
|
||||||
|
scapegoat.addSuppressed(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw CrashReports.report(scapegoat, "Could not read manifest");
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw CrashReports.report(e, "Could not read manifest");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setDevelopmentMetadata() {
|
||||||
|
version = "dev";
|
||||||
|
gitCommit = "-";
|
||||||
|
gitBranch = "-";
|
||||||
|
buildId = "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void fillMetadata(Manifest manifest) {
|
||||||
|
version = getAttributeOrCrash(manifest, "Implementation-Version");
|
||||||
|
gitCommit = getAttributeOrCrash(manifest, "Implementation-Version-Git-Commit");
|
||||||
|
gitBranch = getAttributeOrCrash(manifest, "Implementation-Version-Git-Branch");
|
||||||
|
buildId = getAttributeOrCrash(manifest, "Implementation-Version-BuildId");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getAttributeOrCrash(Manifest manifest, String key) {
|
||||||
|
String result = manifest.getMainAttributes().getValue(key);
|
||||||
|
if (result == null) {
|
||||||
|
throw CrashReports.report(null, "Manifest exists but attribute " + key + " not found");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the version of the game as a String. Version data is retrieved
|
||||||
|
* from a {@code META-INF/MANIFEST.MF} file located in the main JAR. Version
|
||||||
|
* format depends on way the game was built:
|
||||||
|
* <ul>
|
||||||
|
* <li><code>dev</code> if no matching manifest was found, e.g. when launching from an IDE</li>
|
||||||
|
* <li>The value of <code>Implementation-Version</code> specified in the manifest:
|
||||||
|
* <ul>
|
||||||
|
* <li>[Stage-]Major.Minor.Patch, e.g. <code>alpha-0.3.2</code> or <code>1.4.2</code>, for released versions</li>
|
||||||
|
* <li>BuildId, e.g. <code>WJ7</code>, for snapshots built by automation systems</li>
|
||||||
|
* <li>YYYY-MM-DD, e.g. <code>2021-12-32</code>, for snapshots built manually</li>
|
||||||
|
* </ul>
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @return the version
|
||||||
|
*/
|
||||||
|
public static String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFullerVersion() {
|
||||||
|
if (isDefaultGitBranch() || "-".equals(gitBranch)) {
|
||||||
|
return version;
|
||||||
|
} else {
|
||||||
|
return String.format("%s/%s", version, gitBranch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the buildId or <code>"-"</code>
|
||||||
|
*/
|
||||||
|
public static String getBuildId() {
|
||||||
|
return buildId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the Git commit or <code>"-"</code>
|
||||||
|
*/
|
||||||
|
public static String getGitCommit() {
|
||||||
|
return gitCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getGitCommitShort() {
|
||||||
|
if (gitCommit == null || "-".equals(gitCommit)) {
|
||||||
|
return gitCommit;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gitCommit.substring(0, Math.min(7, gitCommit.length()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the Git branch or <code>"-"</code>
|
||||||
|
*/
|
||||||
|
public static String getGitBranch() {
|
||||||
|
return gitBranch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDefaultGitBranch() {
|
||||||
|
return "master".equals(gitBranch) || "main".equals(gitBranch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFullVersion() {
|
||||||
|
return String.format("%s/%s/%s/%s", version, gitBranch, getGitCommitShort(), buildId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
package ru.windcorp.progressia;
|
package ru.windcorp.progressia;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
|
||||||
import ru.windcorp.progressia.client.graphics.GUI;
|
import ru.windcorp.progressia.client.graphics.GUI;
|
||||||
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||||
import ru.windcorp.progressia.common.util.crash.analyzers.OutOfMemoryAnalyzer;
|
import ru.windcorp.progressia.common.util.crash.analyzers.OutOfMemoryAnalyzer;
|
||||||
@ -33,6 +35,8 @@ public class ProgressiaLauncher {
|
|||||||
arguments = args.clone();
|
arguments = args.clone();
|
||||||
setupCrashReports();
|
setupCrashReports();
|
||||||
|
|
||||||
|
LogManager.getRootLogger().info("Launching " + Progressia.getName() + " version " + Progressia.getFullVersion());
|
||||||
|
|
||||||
proxy.initialize();
|
proxy.initialize();
|
||||||
ProgressiaLauncher.proxy = proxy;
|
ProgressiaLauncher.proxy = proxy;
|
||||||
GUI.addTopLayer(new LayerTitle("Title"));
|
GUI.addTopLayer(new LayerTitle("Title"));
|
||||||
@ -44,6 +48,7 @@ public class ProgressiaLauncher {
|
|||||||
|
|
||||||
private static void setupCrashReports() {
|
private static void setupCrashReports() {
|
||||||
// Context providers
|
// Context providers
|
||||||
|
CrashReports.registerProvider(new VersionProvider());
|
||||||
CrashReports.registerProvider(new OSContextProvider());
|
CrashReports.registerProvider(new OSContextProvider());
|
||||||
CrashReports.registerProvider(new RAMContextProvider());
|
CrashReports.registerProvider(new RAMContextProvider());
|
||||||
CrashReports.registerProvider(new JavaVersionContextProvider());
|
CrashReports.registerProvider(new JavaVersionContextProvider());
|
||||||
|
@ -22,13 +22,23 @@ import static org.lwjgl.opengl.GL11.*;
|
|||||||
import static org.lwjgl.glfw.GLFW.*;
|
import static org.lwjgl.glfw.GLFW.*;
|
||||||
import static org.lwjgl.system.MemoryUtil.*;
|
import static org.lwjgl.system.MemoryUtil.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFWImage;
|
||||||
import org.lwjgl.opengl.GL;
|
import org.lwjgl.opengl.GL;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.Progressia;
|
||||||
import ru.windcorp.progressia.client.graphics.GUI;
|
import ru.windcorp.progressia.client.graphics.GUI;
|
||||||
import ru.windcorp.progressia.client.graphics.input.FrameResizeEvent;
|
import ru.windcorp.progressia.client.graphics.input.FrameResizeEvent;
|
||||||
import ru.windcorp.progressia.client.graphics.input.InputEvent;
|
import ru.windcorp.progressia.client.graphics.input.InputEvent;
|
||||||
|
import ru.windcorp.progressia.client.graphics.texture.TextureDataEditor;
|
||||||
|
import ru.windcorp.progressia.client.graphics.texture.TextureLoader;
|
||||||
|
import ru.windcorp.progressia.client.graphics.texture.TextureSettings;
|
||||||
|
import ru.windcorp.progressia.common.resource.Resource;
|
||||||
|
import ru.windcorp.progressia.common.resource.ResourceManager;
|
||||||
|
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||||
|
|
||||||
class LWJGLInitializer {
|
class LWJGLInitializer {
|
||||||
|
|
||||||
@ -63,7 +73,13 @@ class LWJGLInitializer {
|
|||||||
glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
|
glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
|
||||||
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
|
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
|
||||||
|
|
||||||
long handle = glfwCreateWindow(900, 900, "ProgressiaTest", NULL, NULL);
|
long handle = glfwCreateWindow(
|
||||||
|
800,
|
||||||
|
600,
|
||||||
|
Progressia.getName() + " " + Progressia.getFullerVersion(),
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
// TODO Check that handle != NULL
|
// TODO Check that handle != NULL
|
||||||
|
|
||||||
@ -79,8 +95,30 @@ class LWJGLInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void createWindowIcons() {
|
private static void createWindowIcons() {
|
||||||
// TODO Auto-generated method stub
|
if (glfwGetVersionString().toLowerCase().contains("wayland")) {
|
||||||
|
// glfwSetWindowIcon is not supported on Wayland
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String prefix = "assets/icons/";
|
||||||
|
|
||||||
|
String[] sizes = ResourceManager.getResource(prefix + "logoSizes.txt").readAsString().split(" ");
|
||||||
|
|
||||||
|
try (GLFWImage.Buffer buffer = GLFWImage.malloc(sizes.length)) {
|
||||||
|
for (int i = 0; i < sizes.length; ++i) {
|
||||||
|
Resource resource = ResourceManager.getResource(prefix + "logo" + sizes[i].trim() + ".png");
|
||||||
|
TextureDataEditor icon = TextureLoader.loadPixels(resource, new TextureSettings(false, true));
|
||||||
|
|
||||||
|
buffer.position(i)
|
||||||
|
.width(icon.getContentWidth())
|
||||||
|
.height(icon.getContentHeight())
|
||||||
|
.pixels(icon.getData().getData());
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwSetWindowIcon(GraphicsBackend.getWindowHandle(), buffer);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw CrashReports.report(e, "Could not load window icons");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void initializeOpenGL() {
|
private static void initializeOpenGL() {
|
||||||
|
@ -45,7 +45,7 @@ public class GNUUnifontLoader {
|
|||||||
|
|
||||||
private static final AtlasGroup ATLAS_GROUP_GNU_UNIFONT = new AtlasGroup("GNUUnifont", 1 << 12);
|
private static final AtlasGroup ATLAS_GROUP_GNU_UNIFONT = new AtlasGroup("GNUUnifont", 1 << 12);
|
||||||
|
|
||||||
private static final TextureSettings TEXTURE_SETTINGS = new TextureSettings(false);
|
private static final TextureSettings TEXTURE_SETTINGS = new TextureSettings(false, false);
|
||||||
|
|
||||||
private static final int BITS_PER_HEX_DIGIT = 4;
|
private static final int BITS_PER_HEX_DIGIT = 4;
|
||||||
private static final int PREFIX_LENGTH = "0000:".length();
|
private static final int PREFIX_LENGTH = "0000:".length();
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package ru.windcorp.progressia.client.graphics.gui;
|
||||||
|
|
||||||
|
import glm.mat._4.Mat4;
|
||||||
|
import glm.vec._3.Vec3;
|
||||||
|
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||||
|
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||||
|
|
||||||
|
public class Background extends GUILayer {
|
||||||
|
|
||||||
|
protected Texture backgroundTexture;
|
||||||
|
|
||||||
|
public Background(String name, Layout layout, Texture inTexture) {
|
||||||
|
super(name, layout);
|
||||||
|
|
||||||
|
backgroundTexture = inTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assemble(RenderTarget target) {
|
||||||
|
getRoot().setBounds(0, 0, getWidth(), getHeight());
|
||||||
|
getRoot().invalidate();
|
||||||
|
target.pushTransform(new Mat4(1).translate(new Vec3(0,0,500)));
|
||||||
|
target.drawTexture(0, 0, getWidth(), getHeight(), backgroundTexture);
|
||||||
|
target.popTransform();
|
||||||
|
getRoot().assemble(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -23,6 +23,10 @@ import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
|||||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||||
import ru.windcorp.progressia.client.graphics.Colors;
|
import ru.windcorp.progressia.client.graphics.Colors;
|
||||||
|
|
||||||
|
/** Class for a traditional button that gets clicked to activate
|
||||||
|
*
|
||||||
|
* @author opfromthestart
|
||||||
|
*/
|
||||||
public class Button extends BasicButton {
|
public class Button extends BasicButton {
|
||||||
|
|
||||||
public Button(String name, String label, Font labelFont) {
|
public Button(String name, String label, Font labelFont) {
|
||||||
@ -51,9 +55,7 @@ public class Button extends BasicButton {
|
|||||||
|
|
||||||
// Inside area
|
// Inside area
|
||||||
|
|
||||||
if (isPressed()) {
|
if (!isPressed()) {
|
||||||
// Do nothing
|
|
||||||
} else {
|
|
||||||
Vec4 backgroundColor;
|
Vec4 backgroundColor;
|
||||||
if (isHovered() && isEnabled()) {
|
if (isHovered() && isEnabled()) {
|
||||||
backgroundColor = Colors.HOVER_BLUE;
|
backgroundColor = Colors.HOVER_BLUE;
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package ru.windcorp.progressia.client.graphics.gui;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||||
|
import ru.windcorp.progressia.client.graphics.texture.Texture;
|
||||||
|
|
||||||
|
public class TextureComponent extends Component {
|
||||||
|
|
||||||
|
private final Texture texture;
|
||||||
|
|
||||||
|
public TextureComponent(String name, Texture texture2) {
|
||||||
|
super(name);
|
||||||
|
|
||||||
|
texture = texture2;
|
||||||
|
setPreferredSize(texture.getSprite().getWidth(),texture.getSprite().getHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assembleSelf(RenderTarget target)
|
||||||
|
{
|
||||||
|
target.drawTexture(getX(), getY(), getWidth(), getHeight(), texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -27,8 +27,8 @@ import ru.windcorp.progressia.client.graphics.gui.Layout;
|
|||||||
|
|
||||||
public class LayoutAlign implements Layout {
|
public class LayoutAlign implements Layout {
|
||||||
|
|
||||||
private final int margin;
|
protected final int margin;
|
||||||
private double alignX, alignY;
|
protected double alignX, alignY;
|
||||||
|
|
||||||
public LayoutAlign(double alignX, double alignY, int margin) {
|
public LayoutAlign(double alignX, double alignY, int margin) {
|
||||||
this.alignX = alignX;
|
this.alignX = alignX;
|
||||||
@ -72,7 +72,7 @@ public class LayoutAlign implements Layout {
|
|||||||
Vec2i result = new Vec2i(0, 0);
|
Vec2i result = new Vec2i(0, 0);
|
||||||
|
|
||||||
c.getChildren().stream()
|
c.getChildren().stream()
|
||||||
.map(child -> child.getPreferredSize())
|
.map(Component::getPreferredSize)
|
||||||
.forEach(size -> {
|
.forEach(size -> {
|
||||||
result.x = max(size.x, result.x);
|
result.x = max(size.x, result.x);
|
||||||
result.y = max(size.y, result.y);
|
result.y = max(size.y, result.y);
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
package ru.windcorp.progressia.client.graphics.gui.layout;
|
||||||
|
|
||||||
|
import glm.vec._2.i.Vec2i;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.Component;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.Layout;
|
||||||
|
import static java.lang.Math.max;
|
||||||
|
import static java.lang.Math.min;
|
||||||
|
|
||||||
|
public class LayoutEdges implements Layout {
|
||||||
|
|
||||||
|
private final int margin;
|
||||||
|
|
||||||
|
public LayoutEdges(int margin) {
|
||||||
|
this.margin = margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void layout(Component c) {
|
||||||
|
for (int i=0;i<2;i++)
|
||||||
|
{
|
||||||
|
Component child = c.getChild(i);
|
||||||
|
|
||||||
|
Vec2i size = child.getPreferredSize();
|
||||||
|
|
||||||
|
int cWidth = c.getWidth() - 2 * margin;
|
||||||
|
int cHeight = c.getHeight() - 2 * margin;
|
||||||
|
|
||||||
|
size.x = min(size.x, cWidth);
|
||||||
|
size.y = min(size.y, cHeight);
|
||||||
|
|
||||||
|
if (i==0) {
|
||||||
|
child.setBounds(
|
||||||
|
c.getX() + margin,
|
||||||
|
c.getY(),
|
||||||
|
size
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
child.setBounds(
|
||||||
|
1920 - size.x - margin,
|
||||||
|
c.getY(),
|
||||||
|
size
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vec2i calculatePreferredSize(Component c) {
|
||||||
|
Vec2i result = new Vec2i(1920,0);
|
||||||
|
c.getChildren().stream()
|
||||||
|
.map(Component::getPreferredSize)
|
||||||
|
.forEach(size -> result.y = max(Math.abs(size.y), result.y));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -163,7 +163,7 @@ public class Atlases {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final TextureSettings SETTINGS = new TextureSettings(false);
|
private static final TextureSettings SETTINGS = new TextureSettings(false, false);
|
||||||
|
|
||||||
private static final Map<Resource, Sprite> LOADED = new HashMap<>();
|
private static final Map<Resource, Sprite> LOADED = new HashMap<>();
|
||||||
private static final Multimap<AtlasGroup, Atlas> ATLASES = MultimapBuilder.hashKeys().arrayListValues().build();
|
private static final Multimap<AtlasGroup, Atlas> ATLASES = MultimapBuilder.hashKeys().arrayListValues().build();
|
||||||
|
@ -28,7 +28,7 @@ import ru.windcorp.progressia.common.util.crash.CrashReports;
|
|||||||
|
|
||||||
public class SimpleTextures {
|
public class SimpleTextures {
|
||||||
|
|
||||||
private static final TextureSettings SETTINGS = new TextureSettings(false);
|
private static final TextureSettings SETTINGS = new TextureSettings(false, false);
|
||||||
|
|
||||||
private static final Map<Resource, Texture> TEXTURES = new HashMap<>();
|
private static final Map<Resource, Texture> TEXTURES = new HashMap<>();
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import static org.lwjgl.opengl.GL12.*;
|
|||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
class TextureData {
|
public class TextureData {
|
||||||
|
|
||||||
private final ByteBuffer data;
|
private final ByteBuffer data;
|
||||||
|
|
||||||
|
@ -42,8 +42,16 @@ public class TextureLoader {
|
|||||||
int width = readResult.getWidth();
|
int width = readResult.getWidth();
|
||||||
int height = readResult.getHeight();
|
int height = readResult.getHeight();
|
||||||
|
|
||||||
int bufferWidth = BinUtil.roundToGreaterPowerOf2(width);
|
int bufferWidth;
|
||||||
int bufferHeight = BinUtil.roundToGreaterPowerOf2(height);
|
int bufferHeight;
|
||||||
|
|
||||||
|
if (settings.allocateExactBuffer()) {
|
||||||
|
bufferWidth = width;
|
||||||
|
bufferHeight = height;
|
||||||
|
} else {
|
||||||
|
bufferWidth = BinUtil.roundToGreaterPowerOf2(width);
|
||||||
|
bufferHeight = BinUtil.roundToGreaterPowerOf2(height);
|
||||||
|
}
|
||||||
|
|
||||||
WritableRaster raster = TextureUtil.createRaster(
|
WritableRaster raster = TextureUtil.createRaster(
|
||||||
bufferWidth,
|
bufferWidth,
|
||||||
|
@ -21,13 +21,19 @@ package ru.windcorp.progressia.client.graphics.texture;
|
|||||||
public class TextureSettings {
|
public class TextureSettings {
|
||||||
|
|
||||||
private final boolean isFiltered;
|
private final boolean isFiltered;
|
||||||
|
private final boolean allocateExactBuffer;
|
||||||
|
|
||||||
public TextureSettings(boolean isFiltered) {
|
public TextureSettings(boolean isFiltered, boolean allocateExactBuffer) {
|
||||||
this.isFiltered = isFiltered;
|
this.isFiltered = isFiltered;
|
||||||
|
this.allocateExactBuffer = allocateExactBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFiltered() {
|
public boolean isFiltered() {
|
||||||
return isFiltered;
|
return isFiltered;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean allocateExactBuffer() {
|
||||||
|
return allocateExactBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ public class EntityRenderRegistry extends NamespacedInstanceRegistry<EntityRende
|
|||||||
ResourceManager.getTextureResource(
|
ResourceManager.getTextureResource(
|
||||||
"entities/" + name
|
"entities/" + name
|
||||||
),
|
),
|
||||||
new TextureSettings(false)
|
new TextureSettings(false, false)
|
||||||
).getData()
|
).getData()
|
||||||
);
|
);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Progressia
|
||||||
|
* Copyright (C) 2020-2021 Wind Corporation and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package ru.windcorp.progressia.common.util.crash.providers;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.Progressia;
|
||||||
|
import ru.windcorp.progressia.common.util.crash.ContextProvider;
|
||||||
|
|
||||||
|
public class VersionProvider implements ContextProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void provideContext(Map<String, String> output) {
|
||||||
|
output.put("Version", Progressia.getVersion());
|
||||||
|
output.put("Git commit", Progressia.getGitCommit());
|
||||||
|
output.put("Git branch", Progressia.getGitBranch());
|
||||||
|
output.put("Build ID", Progressia.getBuildId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Version Provider";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -43,10 +43,8 @@ public class Region {
|
|||||||
|
|
||||||
private static final boolean RESET_CORRUPTED = true;
|
private static final boolean RESET_CORRUPTED = true;
|
||||||
|
|
||||||
public int loadedChunks;
|
private final AtomicBoolean isUsing = new AtomicBoolean(false);
|
||||||
|
private final AtomicBoolean isClosed = new AtomicBoolean(false);
|
||||||
private AtomicBoolean isUsing = new AtomicBoolean(false);
|
|
||||||
private AtomicBoolean isClosed = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
private final RegionFile file;
|
private final RegionFile file;
|
||||||
|
|
||||||
@ -60,6 +58,7 @@ public class Region {
|
|||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
||||||
RegionWorldContainer.LOG.debug("Uh the file broke");
|
RegionWorldContainer.LOG.debug("Uh the file broke");
|
||||||
|
RegionWorldContainer.LOG.debug(e.getLocalizedMessage());
|
||||||
if (RESET_CORRUPTED) {
|
if (RESET_CORRUPTED) {
|
||||||
this.file.makeHeader(regionCoords);
|
this.file.makeHeader(regionCoords);
|
||||||
}
|
}
|
||||||
@ -132,7 +131,7 @@ public class Region {
|
|||||||
DecodingException {
|
DecodingException {
|
||||||
isUsing.set(true);
|
isUsing.set(true);
|
||||||
|
|
||||||
int dataOffset = 0;
|
int dataOffset;
|
||||||
Vec3i pos = RegionWorldContainer.getInRegionCoords(chunkPos);
|
Vec3i pos = RegionWorldContainer.getInRegionCoords(chunkPos);
|
||||||
|
|
||||||
if (hasOffset(pos)) {
|
if (hasOffset(pos)) {
|
||||||
|
@ -26,9 +26,9 @@ public class RegionFile {
|
|||||||
private static final int ID_HEADER_SIZE = 16;
|
private static final int ID_HEADER_SIZE = 16;
|
||||||
private static final byte[] HEADER_ID = {'P','R','O','G'};
|
private static final byte[] HEADER_ID = {'P','R','O','G'};
|
||||||
|
|
||||||
final byte endBytes[] = new byte[SECTOR_SIZE];
|
final byte[] endBytes = new byte[SECTOR_SIZE];
|
||||||
|
|
||||||
public static enum SectorType {
|
public enum SectorType {
|
||||||
Ending(0), // Just an empty block
|
Ending(0), // Just an empty block
|
||||||
Data(1), // has a byte counting up in position 1, and then
|
Data(1), // has a byte counting up in position 1, and then
|
||||||
PartitionLink(2),
|
PartitionLink(2),
|
||||||
@ -54,7 +54,7 @@ public class RegionFile {
|
|||||||
|
|
||||||
public void confirmHeaderHealth(ChunkMap<Integer> offsets, Vec3i regionCoords) throws IOException {
|
public void confirmHeaderHealth(ChunkMap<Integer> offsets, Vec3i regionCoords) throws IOException {
|
||||||
|
|
||||||
Set<Integer> used = new HashSet<Integer>();
|
Set<Integer> used = new HashSet<>();
|
||||||
int maxUsed = 0;
|
int maxUsed = 0;
|
||||||
final int chunksPerRegion = REGION_DIAMETER * REGION_DIAMETER * REGION_DIAMETER;
|
final int chunksPerRegion = REGION_DIAMETER * REGION_DIAMETER * REGION_DIAMETER;
|
||||||
|
|
||||||
@ -63,9 +63,10 @@ public class RegionFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char prog;
|
byte prog;
|
||||||
|
file.seek(0);
|
||||||
for (int i=0;i<4;i++) {
|
for (int i=0;i<4;i++) {
|
||||||
prog = file.readChar();
|
prog = file.readByte();
|
||||||
if (prog != HEADER_ID[i])
|
if (prog != HEADER_ID[i])
|
||||||
{
|
{
|
||||||
throw new IOException("File is not a .progressia_chunk file");
|
throw new IOException("File is not a .progressia_chunk file");
|
||||||
@ -109,7 +110,7 @@ public class RegionFile {
|
|||||||
throw new IOException("A sector is used twice");
|
throw new IOException("A sector is used twice");
|
||||||
}
|
}
|
||||||
|
|
||||||
file.seek(HEADER_SIZE + SECTOR_SIZE * offset);
|
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * offset);
|
||||||
byte type = file.readByte();
|
byte type = file.readByte();
|
||||||
|
|
||||||
if (type == SectorType.Data.data) {
|
if (type == SectorType.Data.data) {
|
||||||
@ -131,25 +132,26 @@ public class RegionFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void makeHeader(Vec3i regionCoords) throws IOException {
|
public void makeHeader(Vec3i regionCoords) throws IOException {
|
||||||
|
file.seek(0);
|
||||||
|
for (int i = 0; i < HEADER_SIZE; i++) {
|
||||||
|
file.write(0);
|
||||||
|
}
|
||||||
file.seek(0);
|
file.seek(0);
|
||||||
file.write(HEADER_ID);
|
file.write(HEADER_ID);
|
||||||
file.writeInt(regionCoords.x);
|
file.writeInt(regionCoords.x);
|
||||||
file.writeInt(regionCoords.y);
|
file.writeInt(regionCoords.y);
|
||||||
file.writeInt(regionCoords.z);
|
file.writeInt(regionCoords.z);
|
||||||
for (int i = 0; i < HEADER_SIZE; i++) {
|
|
||||||
file.write(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeBuffer(byte[] buffer, int dataOffset, Vec3i pos) throws IOException {
|
public void writeBuffer(byte[] buffer, int dataOffset, Vec3i pos) throws IOException {
|
||||||
file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset);
|
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * dataOffset);
|
||||||
int loc = 0;
|
int loc = 0;
|
||||||
byte tempBuffer[] = new byte[SECTOR_SIZE];
|
byte[] tempBuffer = new byte[SECTOR_SIZE];
|
||||||
byte counter = 0;
|
byte counter = 0;
|
||||||
boolean isDone = false;
|
boolean isDone = false;
|
||||||
while (!isDone) {
|
while (!isDone) {
|
||||||
if (file.length() > HEADER_SIZE + SECTOR_SIZE * (dataOffset + 1)) {
|
if (file.length() > HEADER_SIZE + (long) SECTOR_SIZE * (dataOffset + 1)) {
|
||||||
file.seek(HEADER_SIZE + SECTOR_SIZE * (dataOffset + 1));
|
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * (dataOffset + 1));
|
||||||
byte header = file.readByte();
|
byte header = file.readByte();
|
||||||
if (header == SectorType.Data.data) {
|
if (header == SectorType.Data.data) {
|
||||||
byte fileCounter = file.readByte();
|
byte fileCounter = file.readByte();
|
||||||
@ -157,7 +159,7 @@ public class RegionFile {
|
|||||||
// partition place
|
// partition place
|
||||||
{
|
{
|
||||||
int newOffset = allocateEmptySector();
|
int newOffset = allocateEmptySector();
|
||||||
file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset);
|
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * dataOffset);
|
||||||
file.write(2);
|
file.write(2);
|
||||||
file.writeInt(newOffset);
|
file.writeInt(newOffset);
|
||||||
dataOffset = newOffset;
|
dataOffset = newOffset;
|
||||||
@ -179,7 +181,7 @@ public class RegionFile {
|
|||||||
if (file.getFilePointer() < 256)
|
if (file.getFilePointer() < 256)
|
||||||
LogManager.getLogger("Region")
|
LogManager.getLogger("Region")
|
||||||
.debug("at {}, ({},{},{}), {}", file.getFilePointer(), pos.x, pos.y, pos.z, dataOffset);
|
.debug("at {}, ({},{},{}), {}", file.getFilePointer(), pos.x, pos.y, pos.z, dataOffset);
|
||||||
file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset);
|
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * dataOffset);
|
||||||
dataOffset++;
|
dataOffset++;
|
||||||
file.write(tempBuffer);
|
file.write(tempBuffer);
|
||||||
}
|
}
|
||||||
@ -197,7 +199,7 @@ public class RegionFile {
|
|||||||
file.seek(definitionOffset);
|
file.seek(definitionOffset);
|
||||||
file.writeInt(dataOffset + 1);
|
file.writeInt(dataOffset + 1);
|
||||||
|
|
||||||
file.setLength(HEADER_SIZE + dataOffset * SECTOR_SIZE);
|
file.setLength(HEADER_SIZE + (long) dataOffset * SECTOR_SIZE);
|
||||||
return dataOffset;
|
return dataOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,17 +208,17 @@ public class RegionFile {
|
|||||||
|
|
||||||
int dataOffset = (int) Math.ceil((double) (outputLen - HEADER_SIZE) / SECTOR_SIZE);
|
int dataOffset = (int) Math.ceil((double) (outputLen - HEADER_SIZE) / SECTOR_SIZE);
|
||||||
|
|
||||||
file.setLength(HEADER_SIZE + dataOffset * SECTOR_SIZE);
|
file.setLength(HEADER_SIZE + (long) dataOffset * SECTOR_SIZE);
|
||||||
|
|
||||||
return dataOffset;
|
return dataOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] readBuffer(int dataOffset) throws IOException {
|
public byte[] readBuffer(int dataOffset) throws IOException {
|
||||||
file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset);
|
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * dataOffset);
|
||||||
|
|
||||||
int bufferPos = 0;
|
int bufferPos = 0;
|
||||||
byte buffer[] = new byte[SECTOR_SIZE * 16];
|
byte[] buffer = new byte[SECTOR_SIZE * 16];
|
||||||
byte tempBuffer[] = new byte[SECTOR_SIZE];
|
byte[] tempBuffer = new byte[SECTOR_SIZE];
|
||||||
|
|
||||||
boolean reachedEnd = false;
|
boolean reachedEnd = false;
|
||||||
byte counter = 0;
|
byte counter = 0;
|
||||||
@ -229,31 +231,24 @@ public class RegionFile {
|
|||||||
if (tempBuffer[0] == SectorType.Data.data) {
|
if (tempBuffer[0] == SectorType.Data.data) {
|
||||||
if (tempBuffer[1] != counter) {
|
if (tempBuffer[1] != counter) {
|
||||||
throw new IOException(
|
throw new IOException(
|
||||||
"Sectors were read out of order\nExpected chunk number " + Byte.toString(counter)
|
"Sectors were read out of order\nExpected chunk number " + counter
|
||||||
+ " but encountered number " + Byte.toString(tempBuffer[1])
|
+ " but encountered number " + tempBuffer[1]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
counter++;
|
counter++;
|
||||||
if (buffer.length - bufferPos < SECTOR_SIZE - SECTOR_HEADER_SIZE - 1) {
|
if (buffer.length - bufferPos < SECTOR_SIZE - SECTOR_HEADER_SIZE - 1) {
|
||||||
byte newBuffer[] = new byte[buffer.length + SECTOR_SIZE * 16];
|
byte[] newBuffer = new byte[buffer.length + SECTOR_SIZE * 16];
|
||||||
for (int i = 0; i < buffer.length; i++) // TODO dedicated
|
System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
|
||||||
// copy, java-y at
|
|
||||||
// least
|
|
||||||
{
|
|
||||||
newBuffer[i] = buffer[i];
|
|
||||||
}
|
|
||||||
buffer = newBuffer;
|
buffer = newBuffer;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < SECTOR_SIZE - SECTOR_HEADER_SIZE - 1; i++) {
|
System.arraycopy(tempBuffer, 2, buffer, bufferPos, SECTOR_SIZE - SECTOR_HEADER_SIZE - 1);
|
||||||
buffer[bufferPos + i] = tempBuffer[i + 2];
|
|
||||||
}
|
|
||||||
bufferPos += SECTOR_SIZE - SECTOR_HEADER_SIZE - 1;
|
bufferPos += SECTOR_SIZE - SECTOR_HEADER_SIZE - 1;
|
||||||
} else if (tempBuffer[0] == SectorType.Ending.data) {
|
} else if (tempBuffer[0] == SectorType.Ending.data) {
|
||||||
reachedEnd = true;
|
reachedEnd = true;
|
||||||
} else if (tempBuffer[0] == SectorType.PartitionLink.data) {
|
} else if (tempBuffer[0] == SectorType.PartitionLink.data) {
|
||||||
ByteBuffer intBuffer = ByteBuffer.wrap(tempBuffer);
|
ByteBuffer intBuffer = ByteBuffer.wrap(tempBuffer);
|
||||||
int newOffset = intBuffer.getInt(1);
|
int newOffset = intBuffer.getInt(1);
|
||||||
file.seek(HEADER_SIZE + SECTOR_SIZE * newOffset);
|
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * newOffset);
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("Invalid sector ID.");
|
throw new IOException("Invalid sector ID.");
|
||||||
}
|
}
|
||||||
|
108
src/main/java/ru/windcorp/progressia/test/CubeComponent.java
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package ru.windcorp.progressia.test;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import glm.mat._4.Mat4;
|
||||||
|
import glm.vec._3.Vec3;
|
||||||
|
import glm.vec._4.Vec4;
|
||||||
|
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.Component;
|
||||||
|
|
||||||
|
public class CubeComponent extends Component {
|
||||||
|
|
||||||
|
private final Mat4[] transforms;
|
||||||
|
private final Vec4[] normals;
|
||||||
|
private final long startTime;
|
||||||
|
|
||||||
|
private final double r3 = Math.sqrt(3+.01);
|
||||||
|
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
public CubeComponent(String name, int size) {
|
||||||
|
super(name);
|
||||||
|
this.size = size;
|
||||||
|
transforms = new Mat4[6];
|
||||||
|
normals = new Vec4[6];
|
||||||
|
setPreferredSize((int) Math.ceil(r3*size),(int) Math.ceil(r3*size));
|
||||||
|
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
|
||||||
|
executor.scheduleAtFixedRate(this::requestReassembly, 1, 60, TimeUnit.MILLISECONDS);
|
||||||
|
startTime = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notes to me
|
||||||
|
// z axis is through the screen
|
||||||
|
// y is horizontal spin
|
||||||
|
// x is vertical spin
|
||||||
|
|
||||||
|
|
||||||
|
private void computeTransforms()
|
||||||
|
{
|
||||||
|
//Creates all of the sides
|
||||||
|
transforms[0] = new Mat4(1);
|
||||||
|
transforms[1] = new Mat4(1);
|
||||||
|
transforms[2] = new Mat4(1);
|
||||||
|
transforms[3] = new Mat4(1);
|
||||||
|
transforms[4] = new Mat4(1);
|
||||||
|
transforms[5] = new Mat4(1);
|
||||||
|
|
||||||
|
//Gets time since creation(for rotation amount)
|
||||||
|
long time = System.currentTimeMillis()-startTime;
|
||||||
|
|
||||||
|
//Initializes the way each face is facing
|
||||||
|
normals[0] = new Vec4(0,0,-1,0);
|
||||||
|
normals[1] = new Vec4(0,1,0,0);
|
||||||
|
normals[2] = new Vec4(1,0,0,0);
|
||||||
|
normals[3] = new Vec4(0,0,1,0);
|
||||||
|
normals[4] = new Vec4(0,-1,0,0);
|
||||||
|
normals[5] = new Vec4(-1,0,0,0);
|
||||||
|
|
||||||
|
for (int i=0;i<6;i++)
|
||||||
|
{
|
||||||
|
//Rotates given side with the time one first, then ot get it on its off axis, then gets the image of each axis under the given rotation
|
||||||
|
//The rotate functions do change the transforms, but the multiplication does not
|
||||||
|
normals[i] = transforms[i].rotate((float) (time%(6000*6.28) )/ 6000, new Vec3(0,1,0)).rotate((float) 24, new Vec3(1,.5,0)).mul_(normals[i]);
|
||||||
|
}
|
||||||
|
double pi2 = Math.PI / 2;
|
||||||
|
|
||||||
|
//Move and rotate the sides from the middle of the cube to the appropriate edges
|
||||||
|
transforms[0].translate(new Vec3(-size/2f,-size/2f,size/2f));
|
||||||
|
transforms[1].translate(new Vec3(-size/2f,-size/2f,-size/2f)).rotate((float) pi2, new Vec3(1,0,0));
|
||||||
|
transforms[2].translate(new Vec3(-size/2f,-size/2f,size/2f)).rotate((float) pi2, new Vec3(0,1,0));
|
||||||
|
transforms[3].translate(new Vec3(-size/2f,-size/2f,-size/2f));
|
||||||
|
transforms[4].translate(new Vec3(-size/2f,size/2f,-size/2f)).rotate((float) pi2, new Vec3(1,0,0));
|
||||||
|
transforms[5].translate(new Vec3(size/2f,-size/2f,size/2f)).rotate((float) pi2, new Vec3(0,1,0));
|
||||||
|
|
||||||
|
for (int i=0;i<6;i++) // I have no clue why this is necessary, without it the sides of the cube mess up; may need to be changed if the title screen changes position.
|
||||||
|
{
|
||||||
|
transforms[i] = transforms[i].translate(new Vec3(0,0,17.5-3*(i<2 ? 1 : 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void assembleSelf(RenderTarget target)
|
||||||
|
{
|
||||||
|
computeTransforms();
|
||||||
|
|
||||||
|
setPosition(750,780);
|
||||||
|
|
||||||
|
target.pushTransform(new Mat4(1).translate(new Vec3(getX()+size*r3/2,getY()-size*r3/2,0))); //-size*r3/2
|
||||||
|
|
||||||
|
for (int b=0; b<6;b++)
|
||||||
|
{
|
||||||
|
target.pushTransform(transforms[b]);
|
||||||
|
|
||||||
|
float dot = normals[b].dot(new Vec4(-1,0,0,0)); //Gets the "amount" the given side is pointing in the -x direction
|
||||||
|
|
||||||
|
Vec4 color = new Vec4(.4+.3*dot, .4+.3*dot, .6+.4*dot,1.0); //More aligned means brighter color
|
||||||
|
|
||||||
|
target.fill(0,0, size, size, color);
|
||||||
|
|
||||||
|
target.popTransform();
|
||||||
|
}
|
||||||
|
|
||||||
|
target.popTransform();
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package ru.windcorp.progressia.test;
|
package ru.windcorp.progressia.test;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.Progressia;
|
||||||
import ru.windcorp.progressia.client.graphics.Colors;
|
import ru.windcorp.progressia.client.graphics.Colors;
|
||||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||||
import ru.windcorp.progressia.client.graphics.font.Typeface;
|
import ru.windcorp.progressia.client.graphics.font.Typeface;
|
||||||
@ -30,6 +31,8 @@ import ru.windcorp.progressia.client.localization.MutableStringLocalized;
|
|||||||
|
|
||||||
public class LayerAbout extends GUILayer {
|
public class LayerAbout extends GUILayer {
|
||||||
|
|
||||||
|
public static String version = "pre-alpha 3";
|
||||||
|
|
||||||
public LayerAbout() {
|
public LayerAbout() {
|
||||||
super("LayerAbout", new LayoutAlign(1, 1, 5));
|
super("LayerAbout", new LayoutAlign(1, 1, 5));
|
||||||
|
|
||||||
@ -50,7 +53,7 @@ public class LayerAbout extends GUILayer {
|
|||||||
new Label(
|
new Label(
|
||||||
"Version",
|
"Version",
|
||||||
font,
|
font,
|
||||||
new MutableStringLocalized("LayerAbout.Version").format("pre-alpha 3")
|
new MutableStringLocalized("LayerAbout.Version").format(Progressia.getFullerVersion())
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
53
src/main/java/ru/windcorp/progressia/test/LayerOptions.java
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package ru.windcorp.progressia.test;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.client.graphics.Colors;
|
||||||
|
import ru.windcorp.progressia.client.graphics.GUI;
|
||||||
|
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.*;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical;
|
||||||
|
import ru.windcorp.progressia.client.graphics.texture.SimpleTextures;
|
||||||
|
import ru.windcorp.progressia.client.localization.Localizer;
|
||||||
|
import ru.windcorp.progressia.client.localization.MutableString;
|
||||||
|
import ru.windcorp.progressia.client.localization.MutableStringLocalized;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LayerOptions extends Background {
|
||||||
|
public LayerOptions(String name) {
|
||||||
|
super(name, new LayoutAlign(0, 1f, 15), SimpleTextures.get("title/background"));
|
||||||
|
|
||||||
|
Group content = new Group("Layer" + name + ".Group", new LayoutVertical(15));
|
||||||
|
|
||||||
|
Font font = new Font().withColor(Colors.BLUE).withAlign(0.5f);
|
||||||
|
|
||||||
|
MutableString languageText = new MutableStringLocalized("Layer" + name + ".Language");
|
||||||
|
content.addChild(new Button(name + ".Language", new Label(name + ".Language", font, languageText)).addAction(this::toggleLanguage));
|
||||||
|
|
||||||
|
MutableString playText = new MutableStringLocalized("Layer" + name + ".Return");
|
||||||
|
content.addChild(new Button(name + ".Return", new Label(name + ".Return", font, playText)).addAction(this::openTitle));
|
||||||
|
|
||||||
|
getRoot().addChild(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openTitle(BasicButton basicButton) {
|
||||||
|
GUI.removeLayer(this);
|
||||||
|
GUI.addTopLayer(new LayerTitle("Title"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleLanguage(BasicButton basicButton)
|
||||||
|
{
|
||||||
|
String curLang = Localizer.getInstance().getLanguage();
|
||||||
|
List<String> allLangs = Localizer.getInstance().getLanguages();
|
||||||
|
int pos = allLangs.indexOf(curLang);
|
||||||
|
pos++;
|
||||||
|
if (pos >= allLangs.size())
|
||||||
|
{
|
||||||
|
Localizer.getInstance().setLanguage(allLangs.get(0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Localizer.getInstance().setLanguage(allLangs.get(pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,20 @@
|
|||||||
package ru.windcorp.progressia.test;
|
package ru.windcorp.progressia.test;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.Progressia;
|
||||||
import ru.windcorp.progressia.client.ClientState;
|
import ru.windcorp.progressia.client.ClientState;
|
||||||
import ru.windcorp.progressia.client.graphics.Colors;
|
import ru.windcorp.progressia.client.graphics.Colors;
|
||||||
import ru.windcorp.progressia.client.graphics.GUI;
|
import ru.windcorp.progressia.client.graphics.GUI;
|
||||||
import ru.windcorp.progressia.client.graphics.font.Font;
|
import ru.windcorp.progressia.client.graphics.font.Font;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.Background;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.BasicButton;
|
import ru.windcorp.progressia.client.graphics.gui.BasicButton;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Button;
|
import ru.windcorp.progressia.client.graphics.gui.Button;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
|
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Group;
|
import ru.windcorp.progressia.client.graphics.gui.Group;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Label;
|
import ru.windcorp.progressia.client.graphics.gui.Label;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.TextureComponent;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutAlign;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutEdges;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical;
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical;
|
||||||
|
import ru.windcorp.progressia.client.graphics.texture.SimpleTextures;
|
||||||
import ru.windcorp.progressia.client.localization.MutableString;
|
import ru.windcorp.progressia.client.localization.MutableString;
|
||||||
import ru.windcorp.progressia.client.localization.MutableStringLocalized;
|
import ru.windcorp.progressia.client.localization.MutableStringLocalized;
|
||||||
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||||
@ -24,34 +28,58 @@ import java.nio.file.Paths;
|
|||||||
import java.nio.file.SimpleFileVisitor;
|
import java.nio.file.SimpleFileVisitor;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
|
||||||
public class LayerTitle extends GUILayer {
|
public class LayerTitle extends Background {
|
||||||
|
|
||||||
private final BasicButton resetButton;
|
private final BasicButton resetButton;
|
||||||
|
|
||||||
public LayerTitle(String name) {
|
public LayerTitle(String name) {
|
||||||
super(name, new LayoutAlign(0.5f, 0.7f, 15));
|
super(name, new LayoutAlign(0, 1f, 15), SimpleTextures.get("title/background"));
|
||||||
Group content = new Group("Layer" + name + ".Group", new LayoutVertical(15));
|
Group content = new Group("Layer" + name + ".Group", new LayoutVertical(15));
|
||||||
|
Group info = new Group("Layer"+name+".InfoGroup", new LayoutEdges(30));
|
||||||
|
Group buttonContent = new Group("Layer" + name + ".ButtonGroup", new LayoutColumn(15, 320));
|
||||||
|
|
||||||
MutableString title = new MutableStringLocalized("Layer" + name + ".Title");
|
Font titleFont = new Font().deriveBold().withColor(Colors.BLUE).withAlign(0.5f);
|
||||||
Font titleFont = new Font().deriveBold().withColor(Colors.BLACK).withAlign(0.5f);
|
content.addChild(new TextureComponent(name + ".Title", SimpleTextures.get("title/progressia")));
|
||||||
content.addChild(new Label(name + ".Title", titleFont, title));
|
|
||||||
|
info.addChild(new Label(
|
||||||
|
"About",
|
||||||
|
titleFont,
|
||||||
|
new MutableStringLocalized("LayerAbout.Title")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
info.addChild(
|
||||||
|
new Label(
|
||||||
|
"Version",
|
||||||
|
titleFont,
|
||||||
|
Progressia.getFullerVersion()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
content.addChild(info);
|
||||||
|
|
||||||
Font buttonFont = titleFont.deriveNotBold();
|
Font buttonFont = titleFont.deriveNotBold();
|
||||||
MutableString playText = new MutableStringLocalized("Layer" + name + ".Play");
|
MutableString playText = new MutableStringLocalized("Layer" + name + ".Play");
|
||||||
content.addChild(new Button(name + ".Play", new Label(name + ".Play", buttonFont, playText)).addAction(this::startGame));
|
buttonContent.addChild(new Button(name + ".Play", new Label(name + ".Play", buttonFont, playText)).addAction(this::startGame));
|
||||||
|
|
||||||
MutableString resetText = new MutableStringLocalized("Layer" + name + ".Reset");
|
MutableString resetText = new MutableStringLocalized("Layer" + name + ".Reset");
|
||||||
this.resetButton = new Button(name + ".Reset", new Label(name + ".Reset", buttonFont, resetText)).addAction(this::resetWorld);
|
this.resetButton = new Button(name + ".Reset", new Label(name + ".Reset", buttonFont, resetText)).addAction(this::resetWorld);
|
||||||
content.addChild(resetButton);
|
buttonContent.addChild(resetButton);
|
||||||
|
|
||||||
updateResetButton();
|
updateResetButton();
|
||||||
|
|
||||||
MutableString quitText = new MutableStringLocalized("Layer" + name + ".Quit");
|
MutableString settingsText = new MutableStringLocalized("Layer" + name + ".Options");
|
||||||
content.addChild(new Button(name + "Quit", new Label(name + ".Quit", buttonFont, quitText)).addAction(b -> {
|
buttonContent.addChild(new Button(name + ".Options", new Label(name + ".Options", buttonFont, settingsText)).addAction(this::openOptions));
|
||||||
System.exit(0);
|
|
||||||
}));
|
|
||||||
|
|
||||||
|
MutableString quitText = new MutableStringLocalized("Layer" + name + ".Quit");
|
||||||
|
buttonContent.addChild(new Button(name + "Quit", new Label(name + ".Quit", buttonFont, quitText)).addAction(b -> System.exit(0)));
|
||||||
|
|
||||||
|
content.addChild(buttonContent);
|
||||||
getRoot().addChild(content);
|
getRoot().addChild(content);
|
||||||
|
buttonContent.setPreferredSize(500, 1000);
|
||||||
|
|
||||||
|
CubeComponent cube = new CubeComponent(name+".Cube",300);
|
||||||
|
|
||||||
|
getRoot().addChild(cube);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateResetButton() {
|
private void updateResetButton() {
|
||||||
@ -92,4 +120,9 @@ public class LayerTitle extends GUILayer {
|
|||||||
updateResetButton();
|
updateResetButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void openOptions(BasicButton basicButton) {
|
||||||
|
GUI.removeLayer(this);
|
||||||
|
GUI.addTopLayer(new LayerOptions("Options"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
33
src/main/java/ru/windcorp/progressia/test/LayoutColumn.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package ru.windcorp.progressia.test;
|
||||||
|
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.Component;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.layout.LayoutVertical;
|
||||||
|
|
||||||
|
public class LayoutColumn extends LayoutVertical {
|
||||||
|
|
||||||
|
protected int maxWidth;
|
||||||
|
private final int margin;
|
||||||
|
|
||||||
|
public LayoutColumn(int gap, int maxWidth)
|
||||||
|
{
|
||||||
|
super(gap);
|
||||||
|
this.maxWidth = maxWidth;
|
||||||
|
margin = gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void layout(Component c) {
|
||||||
|
int x = c.getX() + margin,
|
||||||
|
y = c.getY() + c.getHeight();
|
||||||
|
|
||||||
|
synchronized (c.getChildren()) {
|
||||||
|
for (Component child : c.getChildren()) {
|
||||||
|
|
||||||
|
int height = child.getPreferredSize().y;
|
||||||
|
y -= margin + height;
|
||||||
|
child.setBounds(x, y, maxWidth, height);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
src/main/resources/assets/icons/logo128.original.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
src/main/resources/assets/icons/logo128.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/main/resources/assets/icons/logo16.original.png
Executable file
After Width: | Height: | Size: 342 B |
BIN
src/main/resources/assets/icons/logo16.png
Normal file
After Width: | Height: | Size: 424 B |
BIN
src/main/resources/assets/icons/logo20.original.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
BIN
src/main/resources/assets/icons/logo20.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
src/main/resources/assets/icons/logo22.original.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
src/main/resources/assets/icons/logo22.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
src/main/resources/assets/icons/logo24.original.png
Executable file
After Width: | Height: | Size: 8.5 KiB |
BIN
src/main/resources/assets/icons/logo24.png
Normal file
After Width: | Height: | Size: 485 B |
BIN
src/main/resources/assets/icons/logo256.original.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
src/main/resources/assets/icons/logo256.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
src/main/resources/assets/icons/logo32.original.png
Executable file
After Width: | Height: | Size: 407 B |
BIN
src/main/resources/assets/icons/logo32.png
Normal file
After Width: | Height: | Size: 476 B |
BIN
src/main/resources/assets/icons/logo40.original.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
src/main/resources/assets/icons/logo40.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
src/main/resources/assets/icons/logo48.original.png
Executable file
After Width: | Height: | Size: 529 B |
BIN
src/main/resources/assets/icons/logo48.png
Normal file
After Width: | Height: | Size: 541 B |
BIN
src/main/resources/assets/icons/logo64.original.png
Executable file
After Width: | Height: | Size: 6.6 KiB |
BIN
src/main/resources/assets/icons/logo64.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
src/main/resources/assets/icons/logo96.original.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/main/resources/assets/icons/logo96.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
1
src/main/resources/assets/icons/logoSizes.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
16 20 22 24 32 40 48 64 96 128 256
|
@ -24,5 +24,8 @@ LayerTitle.Reset = Reset World
|
|||||||
LayerTitle.Options = Options
|
LayerTitle.Options = Options
|
||||||
LayerTitle.Quit = Quit
|
LayerTitle.Quit = Quit
|
||||||
|
|
||||||
|
LayerOptions.Return = Back To Menu
|
||||||
|
LayerOptions.Language = US English
|
||||||
|
|
||||||
LayerText.Load = Loading...
|
LayerText.Load = Loading...
|
||||||
LayerText.Save = Saving...
|
LayerText.Save = Saving...
|
@ -24,5 +24,8 @@ LayerTitle.Reset = Сбросить мир
|
|||||||
LayerTitle.Options = Настройки
|
LayerTitle.Options = Настройки
|
||||||
LayerTitle.Quit = Выход
|
LayerTitle.Quit = Выход
|
||||||
|
|
||||||
|
LayerOptions.Return = Главное меню
|
||||||
|
LayerOptions.Language = Русский
|
||||||
|
|
||||||
LayerText.Load = Загрузка...
|
LayerText.Load = Загрузка...
|
||||||
LayerText.Save = Сохранение...
|
LayerText.Save = Сохранение...
|
BIN
src/main/resources/assets/textures/title/background.png
Normal file
After Width: | Height: | Size: 133 B |
BIN
src/main/resources/assets/textures/title/progressia.png
Normal file
After Width: | Height: | Size: 12 KiB |
@ -1,8 +1,8 @@
|
|||||||
Package: progressia-techdemo
|
Package: progressia
|
||||||
Version: 1.0
|
Version: ${version}
|
||||||
Section: custom
|
Section: custom
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Maintainer: Javapony <kvadropups@gmail.com>
|
Maintainer: Javapony <kvadropups@gmail.com>
|
||||||
Depends: java8-runtime
|
Depends: java8-runtime
|
||||||
Description: Progressia Techdemo release
|
Description: Progressia - a 3D sandbox survival game
|
@ -10,7 +10,10 @@
|
|||||||
;--------------------------------
|
;--------------------------------
|
||||||
;General
|
;General
|
||||||
|
|
||||||
!define PROJECT_NAME "Progressia"
|
; Expecting the following symbols from caller:
|
||||||
|
; PROJECT_NAME
|
||||||
|
; PROJECT_VERSION
|
||||||
|
; MAIN_JAR_FILE
|
||||||
|
|
||||||
; MUI Settings / Icons
|
; MUI Settings / Icons
|
||||||
!define MUI_ICON "logo.ico"
|
!define MUI_ICON "logo.ico"
|
||||||
@ -28,7 +31,7 @@
|
|||||||
|
|
||||||
;Name and file
|
;Name and file
|
||||||
Name "${PROJECT_NAME}"
|
Name "${PROJECT_NAME}"
|
||||||
OutFile "${PROJECT_NAME}Installer.exe"
|
OutFile "${OUTPUT_DIR}/${PROJECT_NAME}-${PROJECT_VERSION}-installer.exe"
|
||||||
Unicode True
|
Unicode True
|
||||||
|
|
||||||
;Default installation folder
|
;Default installation folder
|
||||||
@ -79,12 +82,12 @@ Section "Install ${PROJECT_NAME}" SEC0000
|
|||||||
SetOverwrite on
|
SetOverwrite on
|
||||||
|
|
||||||
;Files
|
;Files
|
||||||
File Progressia.jar
|
File "${MAIN_JAR_FILE}"
|
||||||
File logo.ico
|
File logo.ico
|
||||||
File /r lib
|
File /r lib
|
||||||
|
|
||||||
;Store installation folder
|
;Store installation folder
|
||||||
WriteRegStr HKLM SOFTWARE\Progressia "Install_Dir" "$INSTDIR"
|
WriteRegStr HKLM "SOFTWARE\${PROJECT_NAME}" "Install_Dir" "$INSTDIR"
|
||||||
|
|
||||||
;Create uninstaller
|
;Create uninstaller
|
||||||
|
|
||||||
@ -96,14 +99,14 @@ SectionEnd
|
|||||||
|
|
||||||
Section "Create Desktop Shortcut" SEC0001
|
Section "Create Desktop Shortcut" SEC0001
|
||||||
SetOutPath "$APPDATA\${PROJECT_NAME}"
|
SetOutPath "$APPDATA\${PROJECT_NAME}"
|
||||||
CreateShortCut "$DESKTOP\${PROJECT_NAME}.lnk" "$INSTDIR\${PROJECT_NAME}.jar" "" "$INSTDIR\logo.ico"
|
CreateShortCut "$DESKTOP\${PROJECT_NAME}.lnk" "$INSTDIR\${MAIN_JAR_FILE}" "" "$INSTDIR\logo.ico"
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
||||||
Section "Start Menu Shortcuts" SEC0002
|
Section "Start Menu Shortcuts" SEC0002
|
||||||
|
|
||||||
CreateDirectory "$SMPROGRAMS\${PROJECT_NAME}"
|
CreateDirectory "$SMPROGRAMS\${PROJECT_NAME}"
|
||||||
CreateShortcut "$SMPROGRAMS\${PROJECT_NAME}\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
|
CreateShortcut "$SMPROGRAMS\${PROJECT_NAME}\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
|
||||||
CreateShortcut "$SMPROGRAMS\${PROJECT_NAME}\${PROJECT_NAME}.lnk" "$INSTDIR\${PROJECT_NAME}.jar" "" "$INSTDIR\logo.ico"
|
CreateShortcut "$SMPROGRAMS\${PROJECT_NAME}\${PROJECT_NAME}.lnk" "$INSTDIR\${MAIN_JAR_FILE}" "" "$INSTDIR\logo.ico"
|
||||||
|
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
||||||
@ -115,7 +118,7 @@ Section "Uninstall"
|
|||||||
;ADD YOUR OWN FILES HERE...
|
;ADD YOUR OWN FILES HERE...
|
||||||
|
|
||||||
Delete $INSTDIR\Uninstall.exe
|
Delete $INSTDIR\Uninstall.exe
|
||||||
Delete $INSTDIR\Progressia.jar
|
Delete "$INSTDIR\${MAIN_JAR_FILE}"
|
||||||
Delete $INSTDIR\lib\*.*
|
Delete $INSTDIR\lib\*.*
|
||||||
Delete $INSTDIR\logo.ico
|
Delete $INSTDIR\logo.ico
|
||||||
|
|
||||||
@ -146,7 +149,7 @@ SectionEnd
|
|||||||
|
|
||||||
Function LaunchLink
|
Function LaunchLink
|
||||||
SetOutPath "$APPDATA\${PROJECT_NAME}"
|
SetOutPath "$APPDATA\${PROJECT_NAME}"
|
||||||
ExecShell "" "$INSTDIR\${PROJECT_NAME}.jar"
|
ExecShell "" "$INSTDIR\${MAIN_JAR_FILE}"
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
;--------------------------------
|
;--------------------------------
|
BIN
src/packaging/nsis/left_side.png
Normal file
After Width: | Height: | Size: 35 KiB |
2
src/packaging/zip/start.bat
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
@ECHO OFF
|
||||||
|
java -jar "@mainJarFile@"
|
11
src/packaging/zip/start.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
jvmFlags=""
|
||||||
|
|
||||||
|
case "$OSTYPE" in
|
||||||
|
"darwin"*)
|
||||||
|
# On MacOS, use -XstartOnFirstThread to resolve an issue with OpenGL contexts
|
||||||
|
jvmFlags="$jvmFlags -XstartOnFirstThread"
|
||||||
|
esac
|
||||||
|
|
||||||
|
java $jvmFlags -jar "@mainJarFile@"
|