Compare commits
11 Commits
title-scre
...
master
Author | SHA1 | Date | |
---|---|---|---|
5472576606 | |||
4a6aa5dbf7 | |||
c3bbc8661d | |||
eadc85bfda | |||
ca8ac6e7b6 | |||
0638794a80 | |||
e6e55a6c40 | |||
57a86b544e | |||
b18eac44b8 | |||
c3c8a6e5e0 | |||
fe01e1b81c |
49
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
49
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
name: Bug Report
|
||||||
|
description: Let us know about a problem
|
||||||
|
labels: [bug]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Use this template to report identified problems. If the game suddenly crashed, and you need help identifying the cause of a crashreport, please use the Investigate Crashreport template instead.
|
||||||
|
|
||||||
|
**Do not forget to give your issue a descriptive title.**
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce
|
||||||
|
description: |
|
||||||
|
What did you do just before the problem appeared, or where can it be observed?
|
||||||
|
|
||||||
|
If the issue occurs unreliably, please estimate the probability of the crash.
|
||||||
|
placeholder: |
|
||||||
|
1. Look at a cow
|
||||||
|
2. Wait for the cow to look back
|
||||||
|
3. The cow turns away after a minute
|
||||||
|
|
||||||
|
The issue occurs approximately once every 10 attempts.
|
||||||
|
|
||||||
|
Player inventory must be empty. Does not occur in multiplayer. Occurred inside a virtual machine.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Expected behaviour
|
||||||
|
description: |
|
||||||
|
What should happen?
|
||||||
|
placeholder: |
|
||||||
|
The cow should stare back indefinitely, because obviously it should, and because comedy.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Other information
|
||||||
|
description: What else can you tell us about this bug?
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Crashreport
|
||||||
|
description: If you have a relevant crashreport, paste the contents of the crashreport file here
|
||||||
|
render: text
|
||||||
|
validations:
|
||||||
|
required: false
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
blank_issues_enabled: true
|
||||||
|
contact_links:
|
||||||
|
- name: Official Progressia Discord
|
||||||
|
url: https://discord.gg/TWuXbVmX23
|
||||||
|
about: Ask developers or community members for help
|
41
.github/ISSUE_TEMPLATE/crashreport.yml
vendored
Normal file
41
.github/ISSUE_TEMPLATE/crashreport.yml
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
name: Investigate Crashreport
|
||||||
|
description: Submit a crashreport to determine the problem
|
||||||
|
labels: [bug, crashreport]
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Use this template to submit crashreports for initial analisys. If you don't have a crashreport, or you have a good understanding of the underlying cause, please use the Bug Report template instead.
|
||||||
|
|
||||||
|
Crashreports can be found in `WORKING-DIRECTORY/crashreports` (take notice of the timestamp). `WORKING-DIRECTORY` is `C:\Users\<windows-user>\AppData\Roaming\Progressia` on Windows when using the installer.
|
||||||
|
|
||||||
|
**Do not forget to give your issue a descriptive title.**
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Steps to reproduce
|
||||||
|
description: |
|
||||||
|
What did you do just before the crash? How could someone else reproduce it? What other context might be relevant?
|
||||||
|
|
||||||
|
If the issue occurs unreliably, please estimate the probability of the crash.
|
||||||
|
placeholder: |
|
||||||
|
1. Enter a new world
|
||||||
|
2. Turn around
|
||||||
|
3. Wait 5 minutes
|
||||||
|
4. Game crashes half of the time
|
||||||
|
|
||||||
|
Player inventory must be empty. Does not crash in multiplayer. Occurred inside a virtual machine.
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Other information
|
||||||
|
description: What else can you tell us about this crashreport?
|
||||||
|
validations:
|
||||||
|
required: false
|
||||||
|
- type: textarea
|
||||||
|
attributes:
|
||||||
|
label: Crashreport
|
||||||
|
description: Paste the contents of the crashreport file here
|
||||||
|
render: text
|
||||||
|
validations:
|
||||||
|
required: true
|
189
build.gradle
189
build.gradle
@ -42,6 +42,16 @@ compileJava {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set encoding
|
||||||
|
*/
|
||||||
|
|
||||||
|
compileJava {
|
||||||
|
options.encoding = 'utf8'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dependencies
|
* Dependencies
|
||||||
*/
|
*/
|
||||||
@ -60,7 +70,7 @@ repositories {
|
|||||||
dependencies {
|
dependencies {
|
||||||
// Google Guava
|
// Google Guava
|
||||||
// A generic utilities library
|
// A generic utilities library
|
||||||
implementation 'com.google.guava:guava:30.0-jre'
|
implementation 'com.google.guava:guava:31.0.1-jre'
|
||||||
|
|
||||||
// Trove4j
|
// Trove4j
|
||||||
// Provides optimized Collections for primitive types
|
// Provides optimized Collections for primitive types
|
||||||
@ -73,8 +83,8 @@ dependencies {
|
|||||||
|
|
||||||
// Log4j
|
// Log4j
|
||||||
// A logging library
|
// A logging library
|
||||||
implementation 'org.apache.logging.log4j:log4j-api:2.17.0'
|
implementation 'org.apache.logging.log4j:log4j-api:2.17.1'
|
||||||
implementation 'org.apache.logging.log4j:log4j-core:2.17.0'
|
implementation 'org.apache.logging.log4j:log4j-core:2.17.1'
|
||||||
|
|
||||||
// JUnit
|
// JUnit
|
||||||
// A unit-testing library
|
// A unit-testing library
|
||||||
@ -163,49 +173,85 @@ task resolveVersion {
|
|||||||
description 'Resolves version information from Git repository or project properties.'
|
description 'Resolves version information from Git repository or project properties.'
|
||||||
|
|
||||||
doFirst {
|
doFirst {
|
||||||
|
|
||||||
|
project.ext.commit = System.env.GIT_COMMIT
|
||||||
|
project.ext.branch = System.env.GIT_BRANCH
|
||||||
|
|
||||||
try {
|
try {
|
||||||
def git = Grgit.open(dir: project.projectDir)
|
def git = Grgit.open(dir: project.projectDir)
|
||||||
|
|
||||||
project.ext.commit = git.head().id
|
project.ext.commit = commit ?: git.head().id
|
||||||
project.ext.branch = git.branch.current().name
|
project.ext.branch = branch ?: git.branch.current().name
|
||||||
|
|
||||||
if (project.version != 'unspecified') {
|
if (project.version != 'unspecified') {
|
||||||
// Leave version as-is
|
// 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 {
|
} else {
|
||||||
|
|
||||||
project.version = version_parseVersion(tag.name, tag.commit != git.head())
|
// Resolve version from Git
|
||||||
|
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) {
|
} catch (org.eclipse.jgit.errors.RepositoryNotFoundException e) {
|
||||||
if (project.version == 'unspecified') project.version = 'dev'
|
if (project.version == 'unspecified') project.version = 'dev'
|
||||||
project.ext.commit = '-'
|
project.ext.commit = commit ?: '-'
|
||||||
project.ext.branch = '-'
|
project.ext.branch = 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
|
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 (branch.contains '/') {
|
||||||
|
// Strip remote - no one wants that
|
||||||
|
project.ext.branch = branch.takeAfter '/'
|
||||||
|
}
|
||||||
|
|
||||||
if (!project.hasProperty('buildId')) {
|
if (!project.hasProperty('buildId')) {
|
||||||
project.ext.buildId = '-'
|
project.ext.buildId = '-'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apply LWJGL logic
|
||||||
|
*/
|
||||||
|
apply from: 'build_logic/lwjgl.gradle'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy libraries into build/libs/lib directory, next to Progressia.jar
|
||||||
|
*/
|
||||||
|
|
||||||
|
task exportLibs(type: Sync) {
|
||||||
|
description 'Copies runtime libraries into a subdirectory next to the output JAR.'
|
||||||
|
|
||||||
|
jar.dependsOn exportLibs
|
||||||
|
dependsOn lwjgl_addNativesToRuntimeOnly
|
||||||
|
|
||||||
|
// from defined in configureManifest
|
||||||
|
into 'build/libs/lib'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -219,11 +265,16 @@ task configureManifest {
|
|||||||
|
|
||||||
jar.dependsOn configureManifest
|
jar.dependsOn configureManifest
|
||||||
dependsOn resolveVersion
|
dependsOn resolveVersion
|
||||||
|
dependsOn lwjgl_addNativesToRuntimeOnly
|
||||||
|
|
||||||
doFirst {
|
doFirst {
|
||||||
|
def classPath = project.lwjgl.replaceNativesIn(configurations.runtimeClasspath)
|
||||||
|
|
||||||
|
exportLibs.from classPath
|
||||||
|
|
||||||
jar.manifest.attributes(
|
jar.manifest.attributes(
|
||||||
'Main-Class': 'ru.windcorp.progressia.client.ProgressiaClientMain',
|
'Main-Class': 'ru.windcorp.progressia.client.ProgressiaClientMain',
|
||||||
'Class-Path': configurations.runtimeClasspath.collect { "lib/${it.name}" } .join(' '),
|
'Class-Path': classPath.collect { "lib/${java.net.URLEncoder.encode it.name}" } .join(' '),
|
||||||
|
|
||||||
'Specification-Title': 'Progressia',
|
'Specification-Title': 'Progressia',
|
||||||
|
|
||||||
@ -238,28 +289,6 @@ task configureManifest {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy libraries into buil/libs/lib directory, next to Progressia.jar
|
|
||||||
*/
|
|
||||||
|
|
||||||
task exportLibs(type: Sync) {
|
|
||||||
description 'Copies runtime libraries into a subdirectory next to the output JAR.'
|
|
||||||
|
|
||||||
jar.dependsOn exportLibs
|
|
||||||
|
|
||||||
from configurations.runtimeClasspath
|
|
||||||
into 'build/libs/lib'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Apply LWJGL logic
|
|
||||||
*/
|
|
||||||
apply from: 'build_logic/lwjgl.gradle'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Packaging working directory configuration
|
* Packaging working directory configuration
|
||||||
*/
|
*/
|
||||||
@ -267,64 +296,40 @@ apply from: 'build_logic/lwjgl.gradle'
|
|||||||
import java.nio.file.*
|
import java.nio.file.*
|
||||||
import java.nio.file.attribute.*
|
import java.nio.file.attribute.*
|
||||||
|
|
||||||
task createPackagingDirs() {
|
task deletePackagingDirs(type: Delete) {
|
||||||
description 'Resets build/tmp/packaging directory.'
|
description 'Deletes build/tmp/packaging directory.'
|
||||||
|
followSymlinks = false
|
||||||
doLast {
|
delete 'build/tmp/packaging'
|
||||||
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 linkBuildOutputForPackaging() {
|
task linkBuildOutputForPackaging {
|
||||||
description 'Symlinks the contents of build/libs into packaging working directory.'
|
description 'Symlinks the contents of build/libs into packaging working directory.'
|
||||||
|
|
||||||
dependsOn build
|
dependsOn build
|
||||||
dependsOn createPackagingDirs
|
mustRunAfter deletePackagingDirs
|
||||||
|
|
||||||
onlyIf { preparePackaging.ext.mode == 'symlink' }
|
onlyIf { preparePackaging.ext.mode == 'symlink' }
|
||||||
|
|
||||||
|
ext.from = 'build/libs'
|
||||||
|
ext.into = "build/tmp/packaging/workingDir/${ -> preparePackaging.ext.buildDest}"
|
||||||
|
|
||||||
|
inputs.dir from
|
||||||
|
outputs.dir into
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
def from = buildDir.toPath().resolve 'libs'
|
def fromPath = Paths.get from
|
||||||
def into = buildDir.toPath().resolve "tmp/packaging/workingDir/${preparePackaging.ext.buildDest}"
|
def intoPath = Paths.get into
|
||||||
|
|
||||||
Files.createDirectories into
|
Files.createDirectories intoPath
|
||||||
|
|
||||||
Files.list(from).each {
|
Files.list(fromPath).each {
|
||||||
def fileName = it.fileName.toString()
|
def fileName = it.fileName.toString()
|
||||||
|
|
||||||
// Exclude all JARs except the current one
|
// Exclude all JARs except the current one
|
||||||
if (fileName ==~ "${project.name}.*\\.jar" && fileName != tasks.jar.archiveFileName.get())
|
if (fileName ==~ "${project.name}.*\\.jar" && fileName != tasks.jar.archiveFileName.get())
|
||||||
return
|
return
|
||||||
|
|
||||||
Files.createSymbolicLink into.resolve(it.fileName), it
|
Files.createSymbolicLink intoPath.resolve(it.fileName), intoPath.relativize(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,7 +338,7 @@ task copyBuildOutputForPackaging(type: Copy) {
|
|||||||
description 'Copies the contents of build/libs into packaging working directory.'
|
description 'Copies the contents of build/libs into packaging working directory.'
|
||||||
|
|
||||||
dependsOn build
|
dependsOn build
|
||||||
dependsOn createPackagingDirs
|
mustRunAfter deletePackagingDirs
|
||||||
|
|
||||||
onlyIf { preparePackaging.ext.mode == 'copy' }
|
onlyIf { preparePackaging.ext.mode == 'copy' }
|
||||||
|
|
||||||
@ -348,7 +353,7 @@ task preparePackaging {
|
|||||||
preparePackaging.ext.buildDest = ''
|
preparePackaging.ext.buildDest = ''
|
||||||
preparePackaging.ext.mode = 'symlink'
|
preparePackaging.ext.mode = 'symlink'
|
||||||
|
|
||||||
dependsOn createPackagingDirs
|
dependsOn deletePackagingDirs
|
||||||
dependsOn linkBuildOutputForPackaging
|
dependsOn linkBuildOutputForPackaging
|
||||||
dependsOn copyBuildOutputForPackaging
|
dependsOn copyBuildOutputForPackaging
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,14 @@
|
|||||||
project.ext.lwjgl = new HashMap<>()
|
project.ext.lwjgl = new HashMap<>()
|
||||||
|
|
||||||
// Version of LWJGL
|
// Version of LWJGL
|
||||||
lwjgl.version = '3.2.3'
|
lwjgl.version = '3.3.0'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Target platforms for current operation.
|
* Target platforms for current operation.
|
||||||
* This is filled in by the request* tasks. This is referenced by the addLwjglNatives task.
|
* This is filled in by the request* tasks. This is referenced by the addLwjglNatives task.
|
||||||
* When empty, current platform is assumed.
|
* When empty, current platform is assumed.
|
||||||
*/
|
*/
|
||||||
lwjgl.targets = new HashSet<>()
|
lwjgl.targets = new HashSet<String>()
|
||||||
|
|
||||||
// LWJGL components. To include org.lwjgl:lwjgl-foobar, add 'foobar' to this list.
|
// LWJGL components. To include org.lwjgl:lwjgl-foobar, add 'foobar' to this list.
|
||||||
lwjgl.libraries = [
|
lwjgl.libraries = [
|
||||||
@ -33,34 +33,49 @@ switch (OperatingSystem.current()) {
|
|||||||
: 'linux'
|
: 'linux'
|
||||||
break
|
break
|
||||||
case OperatingSystem.MAC_OS:
|
case OperatingSystem.MAC_OS:
|
||||||
lwjgl.localArch = 'macos'
|
lwjgl.localArch = System.getProperty('os.arch').startsWith('aarch64') ? 'macos-arm64' : 'macos'
|
||||||
break
|
break
|
||||||
case OperatingSystem.WINDOWS:
|
case OperatingSystem.WINDOWS:
|
||||||
lwjgl.localArch = System.getProperty('os.arch').contains('64') ? 'windows' : 'windows-x86'
|
def osArch = System.getProperty('os.arch')
|
||||||
|
lwjgl.localArch = osArch.contains('64')
|
||||||
|
? "windows${osArch.startsWith('aarch64') ? '-arm64' : ''}"
|
||||||
|
: 'windows-x86'
|
||||||
break
|
break
|
||||||
|
default:
|
||||||
|
logger.info "Unknown or unsupported OS type according to Gradle's org.gradle.internal.os.OperatingSystem: ${OperatingSystem.current()}"
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
create 'lwjglNatives'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declare pure-Java dependencies
|
// Declare pure-Java dependencies
|
||||||
dependencies {
|
dependencies {
|
||||||
// BOM
|
// BOM
|
||||||
implementation platform("org.lwjgl:lwjgl-bom:${lwjgl.version}")
|
|
||||||
|
def bom = platform("org.lwjgl:lwjgl-bom:${lwjgl.version}")
|
||||||
|
implementation bom
|
||||||
|
lwjglNatives bom
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
implementation 'org.lwjgl:lwjgl'
|
implementation 'org.lwjgl:lwjgl'
|
||||||
|
// Local natives for core
|
||||||
|
runtimeOnly "org.lwjgl:lwjgl::natives-${lwjgl.localArch}"
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
lwjgl.libraries.each { implementation "org.lwjgl:lwjgl-$it" }
|
lwjgl.libraries.each { lib ->
|
||||||
|
implementation "org.lwjgl:lwjgl-$lib"
|
||||||
|
// Local natives for component
|
||||||
|
runtimeOnly "org.lwjgl:lwjgl-$lib::natives-${lwjgl.localArch}"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adds LWJGL native libraries to runtimeOnly configuration
|
* Adds LWJGL native libraries to lwjglNatives configuration
|
||||||
*/
|
*/
|
||||||
task lwjgl_addNativesToRuntimeOnly {
|
task lwjgl_addNativesToRuntimeOnly {
|
||||||
// Make sure runtimeOnly has not been resolved
|
|
||||||
compileJava.dependsOn lwjgl_addNativesToRuntimeOnly
|
|
||||||
configureManifest.dependsOn lwjgl_addNativesToRuntimeOnly
|
|
||||||
exportLibs.dependsOn lwjgl_addNativesToRuntimeOnly
|
|
||||||
|
|
||||||
doFirst {
|
doFirst {
|
||||||
if (project.hasProperty('forceTargets')) {
|
if (project.hasProperty('forceTargets')) {
|
||||||
try {
|
try {
|
||||||
@ -82,17 +97,34 @@ task lwjgl_addNativesToRuntimeOnly {
|
|||||||
logger.info 'Adding LWJGL native dependencies for platforms: {}', lwjgl.targets.sort().join(', ')
|
logger.info 'Adding LWJGL native dependencies for platforms: {}', lwjgl.targets.sort().join(', ')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lwjgl.targets.contains(null)) {
|
||||||
|
if (lwjgl.localArch != null) {
|
||||||
|
throw new GradleException("Requested local LWJGL natives; could not determine local architecture for OS ${OperatingSystem.current()} with os.arch ${System.getProperty('os.arch')}")
|
||||||
|
} else {
|
||||||
|
throw new GradleException("LWJGL targets resolved to ${lwjgl.targets}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
lwjgl.targets.each { target ->
|
lwjgl.targets.each { target ->
|
||||||
runtimeOnly "org.lwjgl:lwjgl::natives-$target"
|
lwjglNatives "org.lwjgl:lwjgl::natives-$target"
|
||||||
lwjgl.libraries.each { lib ->
|
lwjgl.libraries.each { lib ->
|
||||||
runtimeOnly "org.lwjgl:lwjgl-$lib::natives-$target"
|
lwjglNatives "org.lwjgl:lwjgl-$lib::natives-$target"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replaces LWJGL natives in the given configuration with the requested ones
|
||||||
|
lwjgl.replaceNativesIn = { config ->
|
||||||
|
new ArrayList<File>().tap {
|
||||||
|
addAll config
|
||||||
|
removeIf { it.name ==~ /.*lwjgl.*natives.*/ }
|
||||||
|
addAll project.configurations.lwjglNatives
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
task requestCrossPlatformDependencies {
|
task requestCrossPlatformDependencies {
|
||||||
description 'Adds LWJGL natives for all available platforms.'
|
description 'Adds LWJGL natives for all available platforms.'
|
||||||
|
|
||||||
@ -113,5 +145,5 @@ def requestTask(String name, String... targets) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
requestTask 'Linux', 'linux', 'linux-arm32', 'linux-arm64'
|
requestTask 'Linux', 'linux', 'linux-arm32', 'linux-arm64'
|
||||||
requestTask 'Windows', 'windows', 'windows-x86'
|
requestTask 'Windows', 'windows', 'windows-arm64', 'windows-x86'
|
||||||
requestTask 'MacOS', 'macos'
|
requestTask 'MacOS', 'macos', 'macos-arm64'
|
||||||
|
@ -15,7 +15,7 @@ task packageDeb_configure() {
|
|||||||
preparePackaging.mustRunAfter packageDeb_configure
|
preparePackaging.mustRunAfter packageDeb_configure
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
tasks.preparePackaging.ext.buildDest = '/usr/share/progressia'
|
tasks.preparePackaging.ext.buildDest = 'usr/share/progressia'
|
||||||
tasks.preparePackaging.ext.mode = 'copy'
|
tasks.preparePackaging.ext.mode = 'copy'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -31,6 +31,10 @@ task packageDeb(type: Exec) {
|
|||||||
|
|
||||||
dependsOn packageDeb_processResources
|
dependsOn packageDeb_processResources
|
||||||
|
|
||||||
|
doFirst {
|
||||||
|
mkdir 'build/packages'
|
||||||
|
}
|
||||||
|
|
||||||
executable 'dpkg-deb'
|
executable 'dpkg-deb'
|
||||||
args '--root-owner-group'
|
args '--root-owner-group'
|
||||||
args '--build', 'build/tmp/packaging/workingDir'
|
args '--build', 'build/tmp/packaging/workingDir'
|
||||||
|
@ -40,6 +40,10 @@ task packageNsis(type: Exec) {
|
|||||||
dependsOn packageNsis_generateIcon
|
dependsOn packageNsis_generateIcon
|
||||||
dependsOn packageNsis_generateLeftSide
|
dependsOn packageNsis_generateLeftSide
|
||||||
|
|
||||||
|
doFirst {
|
||||||
|
mkdir 'build/packages'
|
||||||
|
}
|
||||||
|
|
||||||
executable 'makensis'
|
executable 'makensis'
|
||||||
args '-NOCONFIG'
|
args '-NOCONFIG'
|
||||||
args "-DPROJECT_NAME=${project.name}"
|
args "-DPROJECT_NAME=${project.name}"
|
||||||
|
@ -36,6 +36,10 @@ task packageZip(type: Zip) {
|
|||||||
archiveVersion = project.version
|
archiveVersion = project.version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doFirst {
|
||||||
|
mkdir 'build/packages'
|
||||||
|
}
|
||||||
|
|
||||||
from 'build/tmp/packaging/workingDir'
|
from 'build/tmp/packaging/workingDir'
|
||||||
destinationDirectory = file('build/packages')
|
destinationDirectory = file('build/packages')
|
||||||
}
|
}
|
||||||
|
@ -143,8 +143,8 @@ build.
|
|||||||
Some users might find the need to build for a specific set of platforms. Inclusion of GNU/Linux, Windows or MacOS
|
Some users might find the need to build for a specific set of platforms. Inclusion of GNU/Linux, Windows or MacOS
|
||||||
dependencies individually can be controlled with the following arguments to the `./gradlew build` command:
|
dependencies individually can be controlled with the following arguments to the `./gradlew build` command:
|
||||||
- `requestLinuxDependencies` requests that `natives-linux`, `natives-linux-arm32` and `natives-linux-arm64` binaries are included;
|
- `requestLinuxDependencies` requests that `natives-linux`, `natives-linux-arm32` and `natives-linux-arm64` binaries are included;
|
||||||
- `requestWindowsDependencies` requests that `natives-windows` and `natives-windows-x86` binaries are included;
|
- `requestWindowsDependencies` requests that `natives-windows`, `natives-windows-arm64` and `natives-windows-x86` binaries are included;
|
||||||
- `requestMacOSDependencies` requests that `natives-macos` binaries are included.
|
- `requestMacOSDependencies` requests that `natives-macos`, `natives-macos-arm64` binaries are included.
|
||||||
These requests can be applied in any combination. For example, the following command produces a build containing only
|
These requests can be applied in any combination. For example, the following command produces a build containing only
|
||||||
GNU/Linux and Windows natives:
|
GNU/Linux and Windows natives:
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ This document is a user's reference for the build script of Progressia. For a be
|
|||||||
- `packageDeb` – creates a Debian package. 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.
|
- `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.
|
- `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.
|
- `requestWindowsDependencies` – requests that `natives-windows`, `natives-windows-arm64` and `natives-windows-x86` binaries are included when building.
|
||||||
- `requestMacOSDependencies` – requests that `natives-macos` binaries are included when building.
|
- `requestMacOSDependencies` – requests that `natives-macos` and `natives-macos-arm64` binaries are included when building.
|
||||||
- `requestCrossPlatformDependencies` – requests that all binaries are included when building.
|
- `requestCrossPlatformDependencies` – requests that all binaries are included when building.
|
||||||
|
|
||||||
To execute a task, run `./gradlew <task-name>`.
|
To execute a task, run `./gradlew <task-name>`.
|
||||||
@ -60,14 +60,21 @@ In all other cases, a fallback dummy value is used for version, appended with bu
|
|||||||
|
|
||||||
### Git metadata
|
### Git metadata
|
||||||
|
|
||||||
Git commit and Git branch are correspond to the state of the local Git repository, if any. In case Git metadata is
|
Git commit is determined from `GIT_COMMIT` environment variable if it exists, or the state of the local Git
|
||||||
unavailable, `-` fallback is used for both fields.
|
repository, if any, or `-`.
|
||||||
|
|
||||||
|
Git branch is determined from `GIT_BRANCH` environment variable if it exists, or the state of the local Git
|
||||||
|
repository, if any, or `-`.
|
||||||
|
|
||||||
|
The names of the environment variables are picked to assist Jenkins builds.
|
||||||
|
|
||||||
### Build ID
|
### Build ID
|
||||||
|
|
||||||
Build ID uniquely identifies artifacts produced by automated build systems. For example, builds executed by WindCorp
|
Build ID uniquely identifies artifacts produced by automated build systems. Build ID must be provided explicitly; it
|
||||||
Jenkins suite have build IDs like `WJ3` or `WJ142`. Build ID must be provided explicitly; it is `-` unless specified
|
is `-` unless specified otherwise.
|
||||||
otherwise.
|
|
||||||
|
The proposed scheme for naming build IDs is `<builder><build-system><build attempt no.>`. For example, builds
|
||||||
|
executed by WindCorp Jenkins suite have build IDs like `WJ3` or `WJ142`.
|
||||||
|
|
||||||
Build ID may be set with `buildId` project property. This may be done in a variety of ways, for example with command
|
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`
|
line argument `-PbuildId=WJ3`
|
||||||
@ -93,11 +100,13 @@ detected current architecture.
|
|||||||
|
|
||||||
### Available targets
|
### Available targets
|
||||||
|
|
||||||
| Name | Task |
|
| Name | Task |
|
||||||
|---------------|------------------------------|
|
|-----------------|------------------------------|
|
||||||
| `linux` | `requestLinuxDependencies` |
|
| `linux` | `requestLinuxDependencies` |
|
||||||
| `linux-arm32` | `requestLinuxDependencies` |
|
| `linux-arm32` | `requestLinuxDependencies` |
|
||||||
| `linux-arm64` | `requestLinuxDependencies` |
|
| `linux-arm64` | `requestLinuxDependencies` |
|
||||||
| `windows` | `requestWindowsDependencies` |
|
| `windows` | `requestWindowsDependencies` |
|
||||||
| `windows-x86` | `requestWindowsDependencies` |
|
| `windows-arm64` | `requestWindowsDependencies` |
|
||||||
| `macos` | `requestMacOSDependencies` |
|
| `windows-x86` | `requestWindowsDependencies` |
|
||||||
|
| `macos` | `requestMacOSDependencies` |
|
||||||
|
| `macos-arm64` | `requestMacOSDependencies` |
|
||||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
269
gradlew
vendored
269
gradlew
vendored
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright 2015 the original author or authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -17,78 +17,113 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
#
|
||||||
## Gradle start up script for UN*X
|
# Gradle start up script for POSIX generated by Gradle.
|
||||||
##
|
#
|
||||||
|
# Important for running:
|
||||||
|
#
|
||||||
|
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||||
|
# noncompliant, but you have some other compliant shell such as ksh or
|
||||||
|
# bash, then to run this script, type that shell name before the whole
|
||||||
|
# command line, like:
|
||||||
|
#
|
||||||
|
# ksh Gradle
|
||||||
|
#
|
||||||
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
|
# requires all of these POSIX shell features:
|
||||||
|
# * functions;
|
||||||
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
|
#
|
||||||
|
# Important for patching:
|
||||||
|
#
|
||||||
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
|
#
|
||||||
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
|
# space-separated string is a well documented source of bugs and security
|
||||||
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
|
# options in "$@", and eventually passing that to Java.
|
||||||
|
#
|
||||||
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
|
# see the in-line comments for details.
|
||||||
|
#
|
||||||
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
|
# Darwin, MinGW, and NonStop.
|
||||||
|
#
|
||||||
|
# (3) This script is generated from the Groovy template
|
||||||
|
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
|
# within the Gradle project.
|
||||||
|
#
|
||||||
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
# Resolve links: $0 may be a link
|
# Resolve links: $0 may be a link
|
||||||
PRG="$0"
|
app_path=$0
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
# Need this for daisy-chained symlinks.
|
||||||
ls=`ls -ld "$PRG"`
|
while
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
[ -h "$app_path" ]
|
||||||
PRG="$link"
|
do
|
||||||
else
|
ls=$( ls -ld "$app_path" )
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
link=${ls#*' -> '}
|
||||||
fi
|
case $link in #(
|
||||||
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
APP_NAME="Gradle"
|
||||||
APP_BASE_NAME=`basename "$0"`
|
APP_BASE_NAME=${0##*/}
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD=maximum
|
||||||
|
|
||||||
warn () {
|
warn () {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
die () {
|
die () {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
echo "$*"
|
||||||
echo
|
echo
|
||||||
exit 1
|
exit 1
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
# OS specific support (must be 'true' or 'false').
|
||||||
cygwin=false
|
cygwin=false
|
||||||
msys=false
|
msys=false
|
||||||
darwin=false
|
darwin=false
|
||||||
nonstop=false
|
nonstop=false
|
||||||
case "`uname`" in
|
case "$( uname )" in #(
|
||||||
CYGWIN* )
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
cygwin=true
|
Darwin* ) darwin=true ;; #(
|
||||||
;;
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
Darwin* )
|
NONSTOP* ) nonstop=true ;;
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
NONSTOP* )
|
|
||||||
nonstop=true
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java command to use to start the JVM.
|
||||||
if [ -n "$JAVA_HOME" ] ; then
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
else
|
else
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
fi
|
fi
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
@ -97,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
|||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD="java"
|
JAVACMD=java
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
@ -105,79 +140,95 @@ location of your Java installation."
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
case $MAX_FD in #(
|
||||||
if [ $? -eq 0 ] ; then
|
max*)
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
warn "Could not query maximum file descriptor limit"
|
||||||
fi
|
esac
|
||||||
ulimit -n $MAX_FD
|
case $MAX_FD in #(
|
||||||
if [ $? -ne 0 ] ; then
|
'' | soft) :;; #(
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
*)
|
||||||
fi
|
ulimit -n "$MAX_FD" ||
|
||||||
else
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
|
||||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=`expr $i + 1`
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
0) set -- ;;
|
|
||||||
1) set -- "$args0" ;;
|
|
||||||
2) set -- "$args0" "$args1" ;;
|
|
||||||
3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Escape application args
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
save () {
|
# * args from the command line
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
# * the main class name
|
||||||
echo " "
|
# * -classpath
|
||||||
}
|
# * -D...appname settings
|
||||||
APP_ARGS=`save "$@"`
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Collect all arguments for the java command;
|
||||||
|
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||||
|
# shell script including quotes and variable substitutions, so put them in
|
||||||
|
# double quotes to make sure that they get re-expanded; and
|
||||||
|
# * put everything else in single quotes, so that it's not re-expanded.
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
25
gradlew.bat
vendored
25
gradlew.bat
vendored
@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
|||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
@ -37,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if "%ERRORLEVEL%" == "0" goto init
|
if "%ERRORLEVEL%" == "0" goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
@ -51,7 +54,7 @@ goto fail
|
|||||||
set JAVA_HOME=%JAVA_HOME:"=%
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
if exist "%JAVA_EXE%" goto init
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
@ -61,28 +64,14 @@ echo location of your Java installation.
|
|||||||
|
|
||||||
goto fail
|
goto fail
|
||||||
|
|
||||||
:init
|
|
||||||
@rem Get command-line arguments, handling Windows variants
|
|
||||||
|
|
||||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
|
||||||
|
|
||||||
:win9xME_args
|
|
||||||
@rem Slurp the command line arguments.
|
|
||||||
set CMD_LINE_ARGS=
|
|
||||||
set _SKIP=2
|
|
||||||
|
|
||||||
:win9xME_args_slurp
|
|
||||||
if "x%~1" == "x" goto execute
|
|
||||||
|
|
||||||
set CMD_LINE_ARGS=%*
|
|
||||||
|
|
||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the command line
|
||||||
|
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
@rem Execute Gradle
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
@ -1 +0,0 @@
|
|||||||
22:26:25.948 [Music Thread ] WARN ru.windcorp.progressia.test.TestMusicPlayer > No music found
|
|
45
src/main/java/ru/windcorp/jputil/ConstantsMapException.java
Normal file
45
src/main/java/ru/windcorp/jputil/ConstantsMapException.java
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* JPUtil
|
||||||
|
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil;
|
||||||
|
|
||||||
|
public class ConstantsMapException extends RuntimeException {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -4298704891780063127L;
|
||||||
|
|
||||||
|
public ConstantsMapException() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConstantsMapException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||||
|
super(message, cause, enableSuppression, writableStackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConstantsMapException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConstantsMapException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConstantsMapException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
307
src/main/java/ru/windcorp/jputil/IntConstantsMap.java
Normal file
307
src/main/java/ru/windcorp/jputil/IntConstantsMap.java
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
/*
|
||||||
|
* JPUtil
|
||||||
|
* Copyright (C) 2019-2022 OLEGSHA/Javapony 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.jputil;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.IntPredicate;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class IntConstantsMap {
|
||||||
|
|
||||||
|
private final Map<Integer, String> namesByValue;
|
||||||
|
private final Map<String, Integer> valuesByName;
|
||||||
|
|
||||||
|
protected IntConstantsMap(Map<Integer, String> namesByValue, Map<String, Integer> valuesByName) {
|
||||||
|
this.namesByValue = namesByValue;
|
||||||
|
this.valuesByName = valuesByName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue(String name) {
|
||||||
|
Integer value = valuesByName.get(name);
|
||||||
|
if (value == null) {
|
||||||
|
throw new NoSuchElementException("No constant with name " + name);
|
||||||
|
}
|
||||||
|
return value.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasConstant(String name) {
|
||||||
|
return valuesByName.containsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName(int value) {
|
||||||
|
String name = namesByValue.get(value);
|
||||||
|
if (name == null) {
|
||||||
|
throw new NoSuchElementException("No constant with value " + value);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasConstant(int value) {
|
||||||
|
return namesByValue.containsKey(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Integer> getAll() {
|
||||||
|
return valuesByName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return valuesByName.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder from(Class<?> clazz) {
|
||||||
|
return new Builder(clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public static interface Filter {
|
||||||
|
boolean test(String name, int value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ConstantSpec {
|
||||||
|
public String name;
|
||||||
|
public int value;
|
||||||
|
|
||||||
|
public void drop() {
|
||||||
|
if (!extra.contains(name)) {
|
||||||
|
name = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final List<Consumer<ConstantSpec>> transforms = new ArrayList<>();
|
||||||
|
private final Set<String> extra = new HashSet<>();
|
||||||
|
|
||||||
|
private final Class<?> source;
|
||||||
|
|
||||||
|
public Builder(Class<?> source) {
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder apply(Consumer<ConstantSpec> transform) {
|
||||||
|
transforms.add(transform);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder only(Filter filter) {
|
||||||
|
return apply(s -> {
|
||||||
|
if (!filter.test(s.name, s.value)) {
|
||||||
|
s.drop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder only(Predicate<String> nameFilter) {
|
||||||
|
return apply(s -> {
|
||||||
|
if (!nameFilter.test(s.name)) {
|
||||||
|
s.drop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder onlyValued(IntPredicate valueFilter) {
|
||||||
|
return apply(s -> {
|
||||||
|
if (!valueFilter.test(s.value)) {
|
||||||
|
s.drop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder regex(String regex) {
|
||||||
|
return only(Pattern.compile(regex).asPredicate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder prefix(String prefix) {
|
||||||
|
return only(n -> n.startsWith(prefix) && n.length() > prefix.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder exclude(Filter filter) {
|
||||||
|
return only((n, v) -> !filter.test(n, v));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder exclude(Predicate<String> nameFilter) {
|
||||||
|
return only(nameFilter.negate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder exclude(String... names) {
|
||||||
|
Set<String> excluded = new HashSet<>();
|
||||||
|
for (String name : names) {
|
||||||
|
excluded.add(name);
|
||||||
|
}
|
||||||
|
return exclude(excluded::contains);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder excludeRegex(String... nameRegexes) {
|
||||||
|
List<Predicate<String>> tests = new ArrayList<>();
|
||||||
|
for (String regex : nameRegexes) {
|
||||||
|
tests.add(Pattern.compile(regex).asPredicate());
|
||||||
|
}
|
||||||
|
return only((n, v) -> {
|
||||||
|
for (Predicate<String> test : tests) {
|
||||||
|
if (test.test(n)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder extra(String... names) {
|
||||||
|
for (String name : names) {
|
||||||
|
extra.add(name);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder rename(Function<String, String> renamer) {
|
||||||
|
apply(s -> {
|
||||||
|
s.name = renamer.apply(s.name);
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder stripPrefix(String prefix) {
|
||||||
|
return apply(s -> {
|
||||||
|
if (s.name.startsWith(prefix)) {
|
||||||
|
s.name = s.name.substring(prefix.length());
|
||||||
|
} else if (extra.contains(s.name)) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
s.drop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntConstantsMap scan() {
|
||||||
|
return build(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntConstantsMap scanAll() {
|
||||||
|
return build(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IntConstantsMap build(boolean onlyPublic) {
|
||||||
|
Map<Integer, String> namesByValue = new HashMap<>();
|
||||||
|
Map<String, Integer> valuesByName = new HashMap<>();
|
||||||
|
|
||||||
|
BiConsumer<String, Integer> putter = (name, value) -> {
|
||||||
|
if (namesByValue.containsKey(value)) {
|
||||||
|
throw newDuplicateException("value", value, name, namesByValue.get(value));
|
||||||
|
}
|
||||||
|
if (valuesByName.containsKey(name)) {
|
||||||
|
throw newDuplicateException("name", name, value, valuesByName.get(name));
|
||||||
|
}
|
||||||
|
namesByValue.put(value, name);
|
||||||
|
valuesByName.put(name, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (Field field : source.getDeclaredFields()) {
|
||||||
|
processField(field, putter, onlyPublic);
|
||||||
|
}
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new ConstantsMapException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new IntConstantsMap(
|
||||||
|
Collections.unmodifiableMap(namesByValue),
|
||||||
|
Collections.unmodifiableMap(valuesByName)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processField(Field field, BiConsumer<String, Integer> putter, boolean onlyPublic)
|
||||||
|
throws IllegalAccessException {
|
||||||
|
if (!Modifier.isStatic(field.getModifiers())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Modifier.isFinal(field.getModifiers())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean clearAccessible = false;
|
||||||
|
if (!Modifier.isPublic(field.getModifiers())) {
|
||||||
|
if (onlyPublic) {
|
||||||
|
return;
|
||||||
|
} else if (!isAccessibleFlagSet(field)) {
|
||||||
|
field.setAccessible(true);
|
||||||
|
clearAccessible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
ConstantSpec spec = new ConstantSpec();
|
||||||
|
spec.name = field.getName();
|
||||||
|
spec.value = field.getInt(null);
|
||||||
|
|
||||||
|
for (Consumer<ConstantSpec> t : transforms) {
|
||||||
|
t.accept(spec);
|
||||||
|
if (spec.name == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
putter.accept(spec.name, spec.value);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
if (clearAccessible) {
|
||||||
|
field.setAccessible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Yes, this method exists only so that neither Java 8 nor Java 9 complain about deprecation.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
private boolean isAccessibleFlagSet(Field f) {
|
||||||
|
return f.isAccessible();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConstantsMapException newDuplicateException(String what, Object common, Object current, Object old) {
|
||||||
|
return new ConstantsMapException(
|
||||||
|
String.format(
|
||||||
|
"Duplicate %1$s: %2$s -> %3$s and %2$s -> %4$s",
|
||||||
|
what,
|
||||||
|
common,
|
||||||
|
current,
|
||||||
|
old
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -25,6 +25,7 @@ import ru.windcorp.progressia.client.graphics.backend.RenderTaskQueue;
|
|||||||
import ru.windcorp.progressia.client.graphics.flat.FlatRenderProgram;
|
import ru.windcorp.progressia.client.graphics.flat.FlatRenderProgram;
|
||||||
import ru.windcorp.progressia.client.graphics.font.GNUUnifontLoader;
|
import ru.windcorp.progressia.client.graphics.font.GNUUnifontLoader;
|
||||||
import ru.windcorp.progressia.client.graphics.font.Typefaces;
|
import ru.windcorp.progressia.client.graphics.font.Typefaces;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.ColorScheme;
|
||||||
import ru.windcorp.progressia.client.graphics.texture.Atlases;
|
import ru.windcorp.progressia.client.graphics.texture.Atlases;
|
||||||
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
|
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
|
||||||
import ru.windcorp.progressia.client.localization.Localizer;
|
import ru.windcorp.progressia.client.localization.Localizer;
|
||||||
@ -51,6 +52,7 @@ public class ClientProxy implements Proxy {
|
|||||||
throw CrashReports.report(e, "ClientProxy failed");
|
throw CrashReports.report(e, "ClientProxy failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ColorScheme.load(ResourceManager.getResource("assets/default.colorScheme"));
|
||||||
Localizer.getInstance().setLanguage("en-US");
|
Localizer.getInstance().setLanguage("en-US");
|
||||||
|
|
||||||
TestContent.registerContent();
|
TestContent.registerContent();
|
||||||
|
@ -34,13 +34,7 @@ public class Colors {
|
|||||||
DEBUG_BLUE = toVector(0xFF0000FF),
|
DEBUG_BLUE = toVector(0xFF0000FF),
|
||||||
DEBUG_CYAN = toVector(0xFF00FFFF),
|
DEBUG_CYAN = toVector(0xFF00FFFF),
|
||||||
DEBUG_MAGENTA = toVector(0xFFFF00FF),
|
DEBUG_MAGENTA = toVector(0xFFFF00FF),
|
||||||
DEBUG_YELLOW = toVector(0xFFFFFF00),
|
DEBUG_YELLOW = toVector(0xFFFFFF00);
|
||||||
|
|
||||||
LIGHT_GRAY = toVector(0xFFCBCBD0),
|
|
||||||
BLUE = toVector(0xFF37A2E6),
|
|
||||||
HOVER_BLUE = toVector(0xFFC3E4F7),
|
|
||||||
DISABLED_GRAY = toVector(0xFFE5E5E5),
|
|
||||||
DISABLED_BLUE = toVector(0xFFB2D8ED);
|
|
||||||
|
|
||||||
public static Vec4 toVector(int argb) {
|
public static Vec4 toVector(int argb) {
|
||||||
return toVector(argb, new Vec4());
|
return toVector(argb, new Vec4());
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Progressia
|
||||||
|
* Copyright (C) 2020-2022 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.client.graphics.backend;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||||
|
|
||||||
|
import ru.windcorp.jputil.ConstantsMapException;
|
||||||
|
import ru.windcorp.jputil.IntConstantsMap;
|
||||||
|
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||||
|
|
||||||
|
public class GLFWErrorHandler {
|
||||||
|
|
||||||
|
private static final IntConstantsMap ERROR_CODES;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
ERROR_CODES = IntConstantsMap.from(GLFW.class)
|
||||||
|
.stripPrefix("GLFW_")
|
||||||
|
.onlyValued(i -> i >= 0x10000 && i <= 0x1FFFF)
|
||||||
|
.extra("GLFW_NO_ERROR")
|
||||||
|
.scan();
|
||||||
|
} catch (ConstantsMapException e) {
|
||||||
|
throw CrashReports.report(e, "Could not analyze GLFW error codes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onError(int errorCode, long descriptionPointer) {
|
||||||
|
String description = GLFWErrorCallback.getDescription(descriptionPointer);
|
||||||
|
|
||||||
|
String errorCodeName;
|
||||||
|
if (ERROR_CODES.hasConstant(errorCode)) {
|
||||||
|
errorCodeName = ERROR_CODES.getName(errorCode);
|
||||||
|
} else {
|
||||||
|
errorCodeName = "<unknown " + Integer.toHexString(errorCode) + ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
throw CrashReports.report(null, "GLFW error detected: " + errorCodeName + " %s", description);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -24,6 +24,7 @@ import static org.lwjgl.system.MemoryUtil.*;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.lwjgl.glfw.GLFWErrorCallback;
|
||||||
import org.lwjgl.glfw.GLFWImage;
|
import org.lwjgl.glfw.GLFWImage;
|
||||||
import org.lwjgl.opengl.GL;
|
import org.lwjgl.opengl.GL;
|
||||||
|
|
||||||
@ -55,6 +56,7 @@ class LWJGLInitializer {
|
|||||||
setupWindowCallbacks();
|
setupWindowCallbacks();
|
||||||
|
|
||||||
glfwShowWindow(GraphicsBackend.getWindowHandle());
|
glfwShowWindow(GraphicsBackend.getWindowHandle());
|
||||||
|
GraphicsBackend.onFrameResized(GraphicsBackend.getWindowHandle(), 800, 600);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void checkEnvironment() {
|
private static void checkEnvironment() {
|
||||||
@ -62,8 +64,12 @@ class LWJGLInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void initializeGLFW() {
|
private static void initializeGLFW() {
|
||||||
// TODO Do GLFW error handling: check glfwInit, setup error callback
|
GLFWErrorCallback.create(new GLFWErrorHandler()::onError).set();
|
||||||
glfwInit();
|
|
||||||
|
if (!glfwInit()) {
|
||||||
|
throw CrashReports.report(null, "GLFW could not be initialized: glfwInit() has failed");
|
||||||
|
}
|
||||||
|
|
||||||
GraphicsBackend.setGLFWInitialized(true);
|
GraphicsBackend.setGLFWInitialized(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,17 +77,13 @@ class LWJGLInitializer {
|
|||||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||||
glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
|
glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
|
||||||
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
|
|
||||||
|
|
||||||
long handle = glfwCreateWindow(
|
String windowTitle = Progressia.getName() + " " + Progressia.getFullerVersion();
|
||||||
800,
|
long handle = glfwCreateWindow(800, 600, windowTitle, NULL, NULL);
|
||||||
600,
|
|
||||||
Progressia.getName() + " " + Progressia.getFullerVersion(),
|
|
||||||
NULL,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
// TODO Check that handle != NULL
|
if (handle == 0) {
|
||||||
|
throw CrashReports.report(null, "Could not create game window");
|
||||||
|
}
|
||||||
|
|
||||||
GraphicsBackend.setWindowHandle(handle);
|
GraphicsBackend.setWindowHandle(handle);
|
||||||
|
|
||||||
@ -95,8 +97,8 @@ class LWJGLInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void createWindowIcons() {
|
private static void createWindowIcons() {
|
||||||
if (glfwGetVersionString().toLowerCase().contains("wayland")) {
|
if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) {
|
||||||
// glfwSetWindowIcon is not supported on Wayland
|
// Wayland does not support changing window icons
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -18,15 +18,9 @@
|
|||||||
|
|
||||||
package ru.windcorp.progressia.client.graphics.gui;
|
package ru.windcorp.progressia.client.graphics.gui;
|
||||||
|
|
||||||
import glm.vec._4.Vec4;
|
|
||||||
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
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;
|
|
||||||
|
|
||||||
/** 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) {
|
||||||
@ -43,43 +37,26 @@ public class Button extends BasicButton {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assembleSelf(RenderTarget target) {
|
protected void assembleSelf(RenderTarget target) {
|
||||||
// Border
|
String state;
|
||||||
|
if (!isEnabled()) {
|
||||||
Vec4 borderColor;
|
state = "Disabled";
|
||||||
if (isPressed() || isHovered() || isFocused()) {
|
} else if (isPressed()) {
|
||||||
borderColor = Colors.BLUE;
|
state = "Pressed";
|
||||||
|
} else if (isHovered()) {
|
||||||
|
state = "Hovered";
|
||||||
|
} else if (isFocused()) {
|
||||||
|
state = "Focused";
|
||||||
} else {
|
} else {
|
||||||
borderColor = Colors.LIGHT_GRAY;
|
state = "Inactive";
|
||||||
}
|
}
|
||||||
target.fill(getX(), getY(), getWidth(), getHeight(), borderColor);
|
|
||||||
|
// Border
|
||||||
|
target.fill(getX(), getY(), getWidth(), getHeight(), ColorScheme.get("Core:ButtonBorder" + state));
|
||||||
|
|
||||||
// Inside area
|
// Inside area
|
||||||
|
target.fill(getX() + 2, getY() + 2, getWidth() - 4, getHeight() - 4, ColorScheme.get("Core:ButtonFill" + state));
|
||||||
if (!isPressed()) {
|
|
||||||
Vec4 backgroundColor;
|
|
||||||
if (isHovered() && isEnabled()) {
|
|
||||||
backgroundColor = Colors.HOVER_BLUE;
|
|
||||||
} else {
|
|
||||||
backgroundColor = Colors.WHITE;
|
|
||||||
}
|
|
||||||
target.fill(getX() + 2, getY() + 2, getWidth() - 4, getHeight() - 4, backgroundColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change label font color
|
// Change label font color
|
||||||
|
getLabel().setFont(getLabel().getFont().withColor(ColorScheme.get("Core:ButtonText" + state)));
|
||||||
if (isPressed()) {
|
|
||||||
getLabel().setFont(getLabel().getFont().withColor(Colors.WHITE));
|
|
||||||
} else {
|
|
||||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void postAssembleSelf(RenderTarget target) {
|
|
||||||
// Apply disable tint
|
|
||||||
|
|
||||||
if (!isEnabled()) {
|
|
||||||
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
package ru.windcorp.progressia.client.graphics.gui;
|
package ru.windcorp.progressia.client.graphics.gui;
|
||||||
|
|
||||||
import glm.vec._2.i.Vec2i;
|
import glm.vec._2.i.Vec2i;
|
||||||
import glm.vec._4.Vec4;
|
|
||||||
import ru.windcorp.progressia.client.graphics.Colors;
|
|
||||||
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
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.font.Typefaces;
|
import ru.windcorp.progressia.client.graphics.font.Typefaces;
|
||||||
@ -43,34 +41,28 @@ public class Checkbox extends BasicButton {
|
|||||||
int x = getX();
|
int x = getX();
|
||||||
int y = getY() + (getHeight() - size) / 2;
|
int y = getY() + (getHeight() - size) / 2;
|
||||||
|
|
||||||
// Border
|
String state;
|
||||||
|
if (!Checkbox.this.isEnabled()) {
|
||||||
Vec4 borderColor;
|
state = "Disabled";
|
||||||
if (Checkbox.this.isPressed() || Checkbox.this.isHovered() || Checkbox.this.isFocused()) {
|
} else if (Checkbox.this.isPressed()) {
|
||||||
borderColor = Colors.BLUE;
|
state = "Pressed";
|
||||||
|
} else if (Checkbox.this.isHovered()) {
|
||||||
|
state = "Hovered";
|
||||||
|
} else if (Checkbox.this.isFocused()) {
|
||||||
|
state = "Focused";
|
||||||
} else {
|
} else {
|
||||||
borderColor = Colors.LIGHT_GRAY;
|
state = "Inactive";
|
||||||
}
|
}
|
||||||
target.fill(x, y, size, size, borderColor);
|
|
||||||
|
// Border
|
||||||
|
target.fill(x, y, size, size, ColorScheme.get("Core:CheckboxBorder" + state));
|
||||||
|
|
||||||
// Inside area
|
// Inside area
|
||||||
|
target.fill(x + 2, y + 2, size - 4, size - 4, ColorScheme.get("Core:CheckboxFill" + state));
|
||||||
if (Checkbox.this.isPressed()) {
|
|
||||||
// Do nothing
|
|
||||||
} else {
|
|
||||||
Vec4 backgroundColor;
|
|
||||||
if (Checkbox.this.isHovered() && Checkbox.this.isEnabled()) {
|
|
||||||
backgroundColor = Colors.HOVER_BLUE;
|
|
||||||
} else {
|
|
||||||
backgroundColor = Colors.WHITE;
|
|
||||||
}
|
|
||||||
target.fill(x + 2, y + 2, size - 4, size - 4, backgroundColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// "Tick"
|
// "Tick"
|
||||||
|
|
||||||
if (Checkbox.this.isChecked()) {
|
if (Checkbox.this.isChecked()) {
|
||||||
target.fill(x + 4, y + 4, size - 8, size - 8, Colors.BLUE);
|
target.fill(x + 4, y + 4, size - 8, size - 8, ColorScheme.get("Core:CheckboxCheck" + state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,22 +120,21 @@ public class Checkbox extends BasicButton {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assembleSelf(RenderTarget target) {
|
protected void assembleSelf(RenderTarget target) {
|
||||||
// Change label font color
|
String state;
|
||||||
|
if (!Checkbox.this.isEnabled()) {
|
||||||
if (isPressed()) {
|
state = "Disabled";
|
||||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLUE));
|
} else if (Checkbox.this.isPressed()) {
|
||||||
|
state = "Pressed";
|
||||||
|
} else if (Checkbox.this.isHovered()) {
|
||||||
|
state = "Hovered";
|
||||||
|
} else if (Checkbox.this.isFocused()) {
|
||||||
|
state = "Focused";
|
||||||
} else {
|
} else {
|
||||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
|
state = "Inactive";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
// Change label font color
|
||||||
protected void postAssembleSelf(RenderTarget target) {
|
getLabel().setFont(getLabel().getFont().withColor(ColorScheme.get("Core:CheckboxText" + state)));
|
||||||
// Apply disable tint
|
|
||||||
|
|
||||||
if (!isEnabled()) {
|
|
||||||
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* Progressia
|
||||||
|
* Copyright (C) 2020-2022 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.client.graphics.gui;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
|
import glm.vec._4.Vec4;
|
||||||
|
import ru.windcorp.jputil.SyntaxException;
|
||||||
|
import ru.windcorp.jputil.chars.StringUtil;
|
||||||
|
import ru.windcorp.progressia.common.resource.Resource;
|
||||||
|
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||||
|
import ru.windcorp.progressia.common.util.namespaces.IllegalIdException;
|
||||||
|
import ru.windcorp.progressia.common.util.namespaces.NamespacedUtil;
|
||||||
|
|
||||||
|
public class ColorScheme {
|
||||||
|
|
||||||
|
private static Map<String, Vec4> defaultScheme;
|
||||||
|
|
||||||
|
public static Vec4 get(String key) {
|
||||||
|
Vec4 color = defaultScheme.get(key);
|
||||||
|
if (color == null) {
|
||||||
|
throw CrashReports.report(null, "ColorScheme does not contain color %s", key);
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void load(Resource resource) {
|
||||||
|
Map<String, Vec4> tmpMap = new HashMap<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (String fullLine : StringUtil.split(resource.readAsString(), '\n')) {
|
||||||
|
String line = fullLine.trim();
|
||||||
|
if (line.isEmpty() || line.startsWith("#")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] parts = StringUtil.split(line, '=', 2);
|
||||||
|
if (parts[1] == null) {
|
||||||
|
throw new SyntaxException("Could not parse \"" + line + "\": '=' not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = parts[0].trim();
|
||||||
|
checkKeyName(key);
|
||||||
|
if (tmpMap.containsKey(key)) {
|
||||||
|
throw new SyntaxException("Duplicate key " + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
String value = parts[1].trim();
|
||||||
|
Vec4 color;
|
||||||
|
|
||||||
|
if (value.startsWith("#")) {
|
||||||
|
color = parseValueAsHex(value);
|
||||||
|
} else if (value.startsWith("$")) {
|
||||||
|
color = parseValueAsReference(value, tmpMap);
|
||||||
|
} else {
|
||||||
|
throw new SyntaxException("Unknown value format \"" + value + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpMap.put(key, color);
|
||||||
|
}
|
||||||
|
} catch (SyntaxException e) {
|
||||||
|
throw CrashReports.report(e, "Could not load ColorScheme from %s", resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultScheme = ImmutableMap.copyOf(tmpMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkKeyName(String key) throws SyntaxException {
|
||||||
|
try {
|
||||||
|
NamespacedUtil.checkId(key);
|
||||||
|
} catch (IllegalIdException e) {
|
||||||
|
throw new SyntaxException("Illegal key name \"" + key + "\"", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int parseHex(String from, int start, int length) {
|
||||||
|
return Integer.parseInt(from.substring(start, start + length), 0x10);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vec4 parseValueAsHex(String value) throws SyntaxException {
|
||||||
|
int a = 0xFF;
|
||||||
|
int r, g, b;
|
||||||
|
|
||||||
|
switch (value.length() - 1) {
|
||||||
|
case 3:
|
||||||
|
// #RGB
|
||||||
|
r = parseHex(value, 1, 1) * 0x11;
|
||||||
|
g = parseHex(value, 2, 1) * 0x11;
|
||||||
|
b = parseHex(value, 3, 1) * 0x11;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
// #ARGB
|
||||||
|
a = parseHex(value, 1, 1) * 0x11;
|
||||||
|
r = parseHex(value, 2, 1) * 0x11;
|
||||||
|
g = parseHex(value, 3, 1) * 0x11;
|
||||||
|
b = parseHex(value, 4, 1) * 0x11;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
// #RRGGBB
|
||||||
|
r = parseHex(value, 1, 2);
|
||||||
|
g = parseHex(value, 3, 2);
|
||||||
|
b = parseHex(value, 5, 2);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
// #AARRGGBB
|
||||||
|
a = parseHex(value, 1, 2);
|
||||||
|
r = parseHex(value, 3, 2);
|
||||||
|
g = parseHex(value, 5, 2);
|
||||||
|
b = parseHex(value, 7, 2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new SyntaxException("Could not parse hex color \"" + value + "\": expecting #RGB, #ARGB, #RRGGBB or #AARRGGBB");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Vec4(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Vec4 parseValueAsReference(String value, Map<String, Vec4> map) throws SyntaxException {
|
||||||
|
String otherKey = value.substring(1);
|
||||||
|
checkKeyName(otherKey);
|
||||||
|
if (!map.containsKey(otherKey)) {
|
||||||
|
throw new SyntaxException("Key $" + otherKey + " not found");
|
||||||
|
}
|
||||||
|
return map.get(otherKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -20,7 +20,6 @@ package ru.windcorp.progressia.client.graphics.gui;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import glm.vec._4.Vec4;
|
import glm.vec._4.Vec4;
|
||||||
import ru.windcorp.progressia.client.graphics.Colors;
|
|
||||||
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
||||||
|
|
||||||
public class Panel extends Group {
|
public class Panel extends Group {
|
||||||
@ -36,7 +35,7 @@ public class Panel extends Group {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Panel(String name, Layout layout) {
|
public Panel(String name, Layout layout) {
|
||||||
this(name, layout, Colors.WHITE, Colors.LIGHT_GRAY);
|
this(name, layout, ColorScheme.get("Core:Background"), ColorScheme.get("Core:Border"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,7 +21,6 @@ import org.lwjgl.glfw.GLFW;
|
|||||||
|
|
||||||
import glm.vec._2.i.Vec2i;
|
import glm.vec._2.i.Vec2i;
|
||||||
import glm.vec._4.Vec4;
|
import glm.vec._4.Vec4;
|
||||||
import ru.windcorp.progressia.client.graphics.Colors;
|
|
||||||
import ru.windcorp.progressia.client.graphics.flat.RenderTarget;
|
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.font.Typefaces;
|
import ru.windcorp.progressia.client.graphics.font.Typefaces;
|
||||||
@ -52,34 +51,28 @@ public class RadioButton extends BasicButton {
|
|||||||
int x = getX();
|
int x = getX();
|
||||||
int y = getY() + (getHeight() - size) / 2;
|
int y = getY() + (getHeight() - size) / 2;
|
||||||
|
|
||||||
// Border
|
String state;
|
||||||
|
if (!RadioButton.this.isEnabled()) {
|
||||||
Vec4 borderColor;
|
state = "Disabled";
|
||||||
if (RadioButton.this.isPressed() || RadioButton.this.isHovered() || RadioButton.this.isFocused()) {
|
} else if (RadioButton.this.isPressed()) {
|
||||||
borderColor = Colors.BLUE;
|
state = "Pressed";
|
||||||
|
} else if (RadioButton.this.isHovered()) {
|
||||||
|
state = "Hovered";
|
||||||
|
} else if (RadioButton.this.isFocused()) {
|
||||||
|
state = "Focused";
|
||||||
} else {
|
} else {
|
||||||
borderColor = Colors.LIGHT_GRAY;
|
state = "Inactive";
|
||||||
}
|
}
|
||||||
cross(target, x, y, size, borderColor);
|
|
||||||
|
// Border
|
||||||
|
cross(target, x, y, size, ColorScheme.get("Core:RadioButtonBorder" + state));
|
||||||
|
|
||||||
// Inside area
|
// Inside area
|
||||||
|
cross(target, x + 2, y + 2, size - 4, ColorScheme.get("Core:RadioButtonFill" + state));
|
||||||
if (RadioButton.this.isPressed()) {
|
|
||||||
// Do nothing
|
|
||||||
} else {
|
|
||||||
Vec4 backgroundColor;
|
|
||||||
if (RadioButton.this.isHovered() && RadioButton.this.isEnabled()) {
|
|
||||||
backgroundColor = Colors.HOVER_BLUE;
|
|
||||||
} else {
|
|
||||||
backgroundColor = Colors.WHITE;
|
|
||||||
}
|
|
||||||
cross(target, x + 2, y + 2, size - 4, backgroundColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// "Tick"
|
// "Tick"
|
||||||
|
|
||||||
if (RadioButton.this.isChecked()) {
|
if (RadioButton.this.isChecked()) {
|
||||||
cross(target, x + 4, y + 4, size - 8, Colors.BLUE);
|
cross(target, x + 4, y + 4, size - 8, ColorScheme.get("Core:RadioButtonCheck" + state));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,8 +139,8 @@ public class RadioButton extends BasicButton {
|
|||||||
group.selectNext();
|
group.selectNext();
|
||||||
removeAction(group.listener);
|
removeAction(group.listener);
|
||||||
group.buttons.remove(this);
|
group.buttons.remove(this);
|
||||||
group.getSelected(); // Clear reference if this was the only button
|
// Clear reference if this was the only button in the group
|
||||||
// in the group
|
group.getSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.group = group;
|
this.group = group;
|
||||||
@ -183,22 +176,21 @@ public class RadioButton extends BasicButton {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assembleSelf(RenderTarget target) {
|
protected void assembleSelf(RenderTarget target) {
|
||||||
// Change label font color
|
String state;
|
||||||
|
if (!RadioButton.this.isEnabled()) {
|
||||||
if (isPressed()) {
|
state = "Disabled";
|
||||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLUE));
|
} else if (RadioButton.this.isPressed()) {
|
||||||
|
state = "Pressed";
|
||||||
|
} else if (RadioButton.this.isHovered()) {
|
||||||
|
state = "Hovered";
|
||||||
|
} else if (RadioButton.this.isFocused()) {
|
||||||
|
state = "Focused";
|
||||||
} else {
|
} else {
|
||||||
getLabel().setFont(getLabel().getFont().withColor(Colors.BLACK));
|
state = "Inactive";
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
// Change label font color
|
||||||
protected void postAssembleSelf(RenderTarget target) {
|
getLabel().setFont(getLabel().getFont().withColor(ColorScheme.get("Core:RadioButtonText" + state)));
|
||||||
// Apply disable tint
|
|
||||||
|
|
||||||
if (!isEnabled()) {
|
|
||||||
target.fill(getX(), getY(), getWidth(), getHeight(), Colors.toVector(0x88FFFFFF));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
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 {
|
||||||
|
|
||||||
protected final int margin;
|
private final int margin;
|
||||||
protected double alignX, alignY;
|
private 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(Component::getPreferredSize)
|
.map(child -> child.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);
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,9 +20,9 @@ package ru.windcorp.progressia.client.graphics.gui.menu;
|
|||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
import glm.vec._2.i.Vec2i;
|
import glm.vec._2.i.Vec2i;
|
||||||
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.ColorScheme;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Component;
|
import ru.windcorp.progressia.client.graphics.gui.Component;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
|
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Label;
|
import ru.windcorp.progressia.client.graphics.gui.Label;
|
||||||
@ -50,7 +50,7 @@ public class MenuLayer extends GUILayer {
|
|||||||
|
|
||||||
setCursorPolicy(CursorPolicy.REQUIRE);
|
setCursorPolicy(CursorPolicy.REQUIRE);
|
||||||
|
|
||||||
this.background = new Panel(name + ".Background", new LayoutAlign(10), Colors.toVector(0x66000000), null);
|
this.background = new Panel(name + ".Background", new LayoutAlign(10), ColorScheme.get("Core:MenuLayerTint"), null);
|
||||||
this.content = content;
|
this.content = content;
|
||||||
|
|
||||||
background.addChild(content);
|
background.addChild(content);
|
||||||
@ -76,12 +76,12 @@ public class MenuLayer extends GUILayer {
|
|||||||
protected void addTitle() {
|
protected void addTitle() {
|
||||||
String translationKey = "Layer" + getName() + ".Title";
|
String translationKey = "Layer" + getName() + ".Title";
|
||||||
MutableString titleText = new MutableStringLocalized(translationKey);
|
MutableString titleText = new MutableStringLocalized(translationKey);
|
||||||
Font titleFont = new Font().deriveBold().withColor(Colors.BLACK).withAlign(0.5f);
|
Font titleFont = new Font().deriveBold().withColor(ColorScheme.get("Core:Text")).withAlign(0.5f);
|
||||||
|
|
||||||
Label label = new Label(getName() + ".Title", titleFont, titleText);
|
Label label = new Label(getName() + ".Title", titleFont, titleText);
|
||||||
getContent().addChild(label);
|
getContent().addChild(label);
|
||||||
|
|
||||||
Panel panel = new Panel(getName() + ".Title.Underscore", null, Colors.BLUE, null);
|
Panel panel = new Panel(getName() + ".Title.Underscore", null, ColorScheme.get("Core:Accent"), null);
|
||||||
panel.setLayout(new LayoutFill() {
|
panel.setLayout(new LayoutFill() {
|
||||||
@Override
|
@Override
|
||||||
public Vec2i calculatePreferredSize(Component c) {
|
public Vec2i calculatePreferredSize(Component c) {
|
||||||
|
@ -43,8 +43,10 @@ public class Region {
|
|||||||
|
|
||||||
private static final boolean RESET_CORRUPTED = true;
|
private static final boolean RESET_CORRUPTED = true;
|
||||||
|
|
||||||
private final AtomicBoolean isUsing = new AtomicBoolean(false);
|
public int loadedChunks;
|
||||||
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;
|
||||||
|
|
||||||
@ -58,7 +60,6 @@ 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);
|
||||||
}
|
}
|
||||||
@ -131,7 +132,7 @@ public class Region {
|
|||||||
DecodingException {
|
DecodingException {
|
||||||
isUsing.set(true);
|
isUsing.set(true);
|
||||||
|
|
||||||
int dataOffset;
|
int dataOffset = 0;
|
||||||
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 enum SectorType {
|
public static 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<>();
|
Set<Integer> used = new HashSet<Integer>();
|
||||||
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,10 +63,9 @@ public class RegionFile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
byte prog;
|
char prog;
|
||||||
file.seek(0);
|
|
||||||
for (int i=0;i<4;i++) {
|
for (int i=0;i<4;i++) {
|
||||||
prog = file.readByte();
|
prog = file.readChar();
|
||||||
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");
|
||||||
@ -110,7 +109,7 @@ public class RegionFile {
|
|||||||
throw new IOException("A sector is used twice");
|
throw new IOException("A sector is used twice");
|
||||||
}
|
}
|
||||||
|
|
||||||
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * offset);
|
file.seek(HEADER_SIZE + SECTOR_SIZE * offset);
|
||||||
byte type = file.readByte();
|
byte type = file.readByte();
|
||||||
|
|
||||||
if (type == SectorType.Data.data) {
|
if (type == SectorType.Data.data) {
|
||||||
@ -132,26 +131,25 @@ 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 + (long) SECTOR_SIZE * dataOffset);
|
file.seek(HEADER_SIZE + 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 + (long) SECTOR_SIZE * (dataOffset + 1)) {
|
if (file.length() > HEADER_SIZE + SECTOR_SIZE * (dataOffset + 1)) {
|
||||||
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * (dataOffset + 1));
|
file.seek(HEADER_SIZE + 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();
|
||||||
@ -159,7 +157,7 @@ public class RegionFile {
|
|||||||
// partition place
|
// partition place
|
||||||
{
|
{
|
||||||
int newOffset = allocateEmptySector();
|
int newOffset = allocateEmptySector();
|
||||||
file.seek(HEADER_SIZE + (long) SECTOR_SIZE * dataOffset);
|
file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset);
|
||||||
file.write(2);
|
file.write(2);
|
||||||
file.writeInt(newOffset);
|
file.writeInt(newOffset);
|
||||||
dataOffset = newOffset;
|
dataOffset = newOffset;
|
||||||
@ -181,7 +179,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 + (long) SECTOR_SIZE * dataOffset);
|
file.seek(HEADER_SIZE + SECTOR_SIZE * dataOffset);
|
||||||
dataOffset++;
|
dataOffset++;
|
||||||
file.write(tempBuffer);
|
file.write(tempBuffer);
|
||||||
}
|
}
|
||||||
@ -199,7 +197,7 @@ public class RegionFile {
|
|||||||
file.seek(definitionOffset);
|
file.seek(definitionOffset);
|
||||||
file.writeInt(dataOffset + 1);
|
file.writeInt(dataOffset + 1);
|
||||||
|
|
||||||
file.setLength(HEADER_SIZE + (long) dataOffset * SECTOR_SIZE);
|
file.setLength(HEADER_SIZE + dataOffset * SECTOR_SIZE);
|
||||||
return dataOffset;
|
return dataOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,17 +206,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 + (long) dataOffset * SECTOR_SIZE);
|
file.setLength(HEADER_SIZE + 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 + (long) SECTOR_SIZE * dataOffset);
|
file.seek(HEADER_SIZE + 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;
|
||||||
@ -231,24 +229,31 @@ 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 " + counter
|
"Sectors were read out of order\nExpected chunk number " + Byte.toString(counter)
|
||||||
+ " but encountered number " + tempBuffer[1]
|
+ " but encountered number " + Byte.toString(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];
|
||||||
System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
|
for (int i = 0; i < buffer.length; i++) // TODO dedicated
|
||||||
|
// copy, java-y at
|
||||||
|
// least
|
||||||
|
{
|
||||||
|
newBuffer[i] = buffer[i];
|
||||||
|
}
|
||||||
buffer = newBuffer;
|
buffer = newBuffer;
|
||||||
}
|
}
|
||||||
System.arraycopy(tempBuffer, 2, buffer, bufferPos, SECTOR_SIZE - SECTOR_HEADER_SIZE - 1);
|
for (int i = 0; i < SECTOR_SIZE - SECTOR_HEADER_SIZE - 1; i++) {
|
||||||
|
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 + (long) SECTOR_SIZE * newOffset);
|
file.seek(HEADER_SIZE + SECTOR_SIZE * newOffset);
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("Invalid sector ID.");
|
throw new IOException("Invalid sector ID.");
|
||||||
}
|
}
|
||||||
|
@ -1,108 +0,0 @@
|
|||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,6 +22,7 @@ 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;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.ColorScheme;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
|
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Label;
|
import ru.windcorp.progressia.client.graphics.gui.Label;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Group;
|
import ru.windcorp.progressia.client.graphics.gui.Group;
|
||||||
@ -31,15 +32,13 @@ 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));
|
||||||
|
|
||||||
Group group = new Group("ControlDisplays", new LayoutVertical(5));
|
Group group = new Group("ControlDisplays", new LayoutVertical(5));
|
||||||
|
|
||||||
Font font = new Font().withColor(Colors.WHITE).deriveOutlined().withAlign(Typeface.ALIGN_RIGHT);
|
Font font = new Font().withColor(Colors.WHITE).deriveOutlined().withAlign(Typeface.ALIGN_RIGHT);
|
||||||
Font aboutFont = font.withColor(0xFF37A3E6).deriveBold();
|
Font aboutFont = font.withColor(ColorScheme.get("Core:Accent")).deriveBold();
|
||||||
|
|
||||||
group.addChild(
|
group.addChild(
|
||||||
new Label(
|
new Label(
|
||||||
|
@ -20,11 +20,11 @@ package ru.windcorp.progressia.test;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
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.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.Button;
|
import ru.windcorp.progressia.client.graphics.gui.Button;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Checkbox;
|
import ru.windcorp.progressia.client.graphics.gui.Checkbox;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.ColorScheme;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Label;
|
import ru.windcorp.progressia.client.graphics.gui.Label;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.RadioButton;
|
import ru.windcorp.progressia.client.graphics.gui.RadioButton;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.RadioButtonGroup;
|
import ru.windcorp.progressia.client.graphics.gui.RadioButtonGroup;
|
||||||
@ -65,7 +65,7 @@ public class LayerButtonTest extends MenuLayer {
|
|||||||
|
|
||||||
getContent().getChild(getContent().getChildren().size() - 1).setEnabled(false);
|
getContent().getChild(getContent().getChildren().size() - 1).setEnabled(false);
|
||||||
|
|
||||||
getContent().addChild(new Label("Hint", new Font().withColor(Colors.LIGHT_GRAY), "This is a MenuLayer"));
|
getContent().addChild(new Label("Hint", new Font().withColor(ColorScheme.get("Core:Border")), "This is a MenuLayer"));
|
||||||
|
|
||||||
getContent().addChild(new Button("Continue", "Continue").addAction(b -> {
|
getContent().addChild(new Button("Continue", "Continue").addAction(b -> {
|
||||||
getCloseAction().run();
|
getCloseAction().run();
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
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,11 +1,13 @@
|
|||||||
package ru.windcorp.progressia.test;
|
package ru.windcorp.progressia.test;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
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.gui.ColorScheme;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
|
import ru.windcorp.progressia.client.graphics.gui.GUILayer;
|
||||||
import ru.windcorp.progressia.client.graphics.gui.Label;
|
import ru.windcorp.progressia.client.graphics.gui.Label;
|
||||||
|
import ru.windcorp.progressia.client.graphics.gui.Panel;
|
||||||
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.LayoutFill;
|
||||||
import ru.windcorp.progressia.client.localization.MutableString;
|
import ru.windcorp.progressia.client.localization.MutableString;
|
||||||
|
|
||||||
public class LayerTestText extends GUILayer {
|
public class LayerTestText extends GUILayer {
|
||||||
@ -13,11 +15,13 @@ public class LayerTestText extends GUILayer {
|
|||||||
private final Consumer<LayerTestText> remover;
|
private final Consumer<LayerTestText> remover;
|
||||||
|
|
||||||
public LayerTestText(String name, MutableString value, Consumer<LayerTestText> remover) {
|
public LayerTestText(String name, MutableString value, Consumer<LayerTestText> remover) {
|
||||||
super(name, new LayoutAlign(15));
|
super(name, new LayoutFill());
|
||||||
this.remover = remover;
|
this.remover = remover;
|
||||||
|
|
||||||
Font titleFont = new Font().deriveBold().withColor(Colors.BLACK).withAlign(0.5f);
|
Panel panel = new Panel(name + ".Background", new LayoutAlign(15), ColorScheme.get("Core:Background"), null);
|
||||||
getRoot().addChild(new Label(name + ".Text", titleFont, value));
|
Font titleFont = new Font().deriveBold().withColor(ColorScheme.get("Core:Text")).withAlign(0.5f);
|
||||||
|
panel.addChild(new Label(name + ".Text", titleFont, value));
|
||||||
|
getRoot().addChild(panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
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;
|
||||||
@ -28,58 +24,34 @@ 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 Background {
|
public class LayerTitle extends GUILayer {
|
||||||
|
|
||||||
private final BasicButton resetButton;
|
private final BasicButton resetButton;
|
||||||
|
|
||||||
public LayerTitle(String name) {
|
public LayerTitle(String name) {
|
||||||
super(name, new LayoutAlign(0, 1f, 15), SimpleTextures.get("title/background"));
|
super(name, new LayoutAlign(0.5f, 0.7f, 15));
|
||||||
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));
|
|
||||||
|
|
||||||
Font titleFont = new Font().deriveBold().withColor(Colors.BLUE).withAlign(0.5f);
|
MutableString title = new MutableStringLocalized("Layer" + name + ".Title");
|
||||||
content.addChild(new TextureComponent(name + ".Title", SimpleTextures.get("title/progressia")));
|
Font titleFont = new Font().deriveBold().withColor(Colors.BLACK).withAlign(0.5f);
|
||||||
|
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");
|
||||||
buttonContent.addChild(new Button(name + ".Play", new Label(name + ".Play", buttonFont, playText)).addAction(this::startGame));
|
content.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);
|
||||||
buttonContent.addChild(resetButton);
|
content.addChild(resetButton);
|
||||||
|
|
||||||
updateResetButton();
|
updateResetButton();
|
||||||
|
|
||||||
MutableString settingsText = new MutableStringLocalized("Layer" + name + ".Options");
|
|
||||||
buttonContent.addChild(new Button(name + ".Options", new Label(name + ".Options", buttonFont, settingsText)).addAction(this::openOptions));
|
|
||||||
|
|
||||||
MutableString quitText = new MutableStringLocalized("Layer" + name + ".Quit");
|
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(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() {
|
||||||
@ -120,9 +92,4 @@ public class LayerTitle extends Background {
|
|||||||
updateResetButton();
|
updateResetButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openOptions(BasicButton basicButton) {
|
|
||||||
GUI.removeLayer(this);
|
|
||||||
GUI.addTopLayer(new LayerOptions("Options"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
80
src/main/resources/assets/default.colorScheme
Normal file
80
src/main/resources/assets/default.colorScheme
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
# Default color scheme for Progressia
|
||||||
|
#
|
||||||
|
# Line format:
|
||||||
|
# KEY = VALUE
|
||||||
|
# KEY must be a legal ID
|
||||||
|
# VALUE may be one of the following:
|
||||||
|
# #RGB
|
||||||
|
# #ARGB
|
||||||
|
# #RRGGBB
|
||||||
|
# #AARRGGBB
|
||||||
|
# $OTHER_KEY
|
||||||
|
|
||||||
|
Core:Background = #EFF0F1
|
||||||
|
Core:Border = #CBCBD0
|
||||||
|
Core:DisabledBackground = $Core:Background
|
||||||
|
Core:DisabledBorder = #DEDFE1
|
||||||
|
Core:Accent = #37A3E6
|
||||||
|
Core:AccentLighter = #C3E4F7
|
||||||
|
|
||||||
|
Core:Text = #31363B
|
||||||
|
|
||||||
|
Core:ButtonBorderDisabled = $Core:DisabledBorder
|
||||||
|
Core:ButtonBorderPressed = $Core:Accent
|
||||||
|
Core:ButtonBorderHovered = $Core:Accent
|
||||||
|
Core:ButtonBorderFocused = $Core:Accent
|
||||||
|
Core:ButtonBorderInactive = $Core:Border
|
||||||
|
Core:ButtonFillDisabled = $Core:DisabledBackground
|
||||||
|
Core:ButtonFillPressed = $Core:Accent
|
||||||
|
Core:ButtonFillHovered = $Core:AccentLighter
|
||||||
|
Core:ButtonFillFocused = $Core:Background
|
||||||
|
Core:ButtonFillInactive = $Core:Background
|
||||||
|
Core:ButtonTextDisabled = $Core:DisabledBorder
|
||||||
|
Core:ButtonTextPressed = $Core:Background
|
||||||
|
Core:ButtonTextHovered = $Core:Text
|
||||||
|
Core:ButtonTextFocused = $Core:Text
|
||||||
|
Core:ButtonTextInactive = $Core:Text
|
||||||
|
|
||||||
|
Core:CheckboxBorderDisabled = $Core:DisabledBorder
|
||||||
|
Core:CheckboxBorderPressed = $Core:Accent
|
||||||
|
Core:CheckboxBorderHovered = $Core:Accent
|
||||||
|
Core:CheckboxBorderFocused = $Core:Accent
|
||||||
|
Core:CheckboxBorderInactive = $Core:Border
|
||||||
|
Core:CheckboxFillDisabled = $Core:DisabledBackground
|
||||||
|
Core:CheckboxFillPressed = $Core:Accent
|
||||||
|
Core:CheckboxFillHovered = $Core:AccentLighter
|
||||||
|
Core:CheckboxFillFocused = $Core:Background
|
||||||
|
Core:CheckboxFillInactive = $Core:Background
|
||||||
|
Core:CheckboxTextDisabled = $Core:DisabledBorder
|
||||||
|
Core:CheckboxTextPressed = $Core:Accent
|
||||||
|
Core:CheckboxTextHovered = $Core:Text
|
||||||
|
Core:CheckboxTextFocused = $Core:Text
|
||||||
|
Core:CheckboxTextInactive = $Core:Text
|
||||||
|
Core:CheckboxCheckDisabled = $Core:DisabledBorder
|
||||||
|
Core:CheckboxCheckPressed = $Core:Accent
|
||||||
|
Core:CheckboxCheckHovered = $Core:Accent
|
||||||
|
Core:CheckboxCheckFocused = $Core:Accent
|
||||||
|
Core:CheckboxCheckInactive = $Core:Accent
|
||||||
|
|
||||||
|
Core:RadioButtonBorderDisabled = $Core:DisabledBorder
|
||||||
|
Core:RadioButtonBorderPressed = $Core:Accent
|
||||||
|
Core:RadioButtonBorderHovered = $Core:Accent
|
||||||
|
Core:RadioButtonBorderFocused = $Core:Accent
|
||||||
|
Core:RadioButtonBorderInactive = $Core:Border
|
||||||
|
Core:RadioButtonFillDisabled = $Core:DisabledBackground
|
||||||
|
Core:RadioButtonFillPressed = $Core:Accent
|
||||||
|
Core:RadioButtonFillHovered = $Core:AccentLighter
|
||||||
|
Core:RadioButtonFillFocused = $Core:Background
|
||||||
|
Core:RadioButtonFillInactive = $Core:Background
|
||||||
|
Core:RadioButtonTextDisabled = $Core:DisabledBorder
|
||||||
|
Core:RadioButtonTextPressed = $Core:Accent
|
||||||
|
Core:RadioButtonTextHovered = $Core:Text
|
||||||
|
Core:RadioButtonTextFocused = $Core:Text
|
||||||
|
Core:RadioButtonTextInactive = $Core:Text
|
||||||
|
Core:RadioButtonCheckDisabled = $Core:DisabledBorder
|
||||||
|
Core:RadioButtonCheckPressed = $Core:Accent
|
||||||
|
Core:RadioButtonCheckHovered = $Core:Accent
|
||||||
|
Core:RadioButtonCheckFocused = $Core:Accent
|
||||||
|
Core:RadioButtonCheckInactive = $Core:Accent
|
||||||
|
|
||||||
|
Core:MenuLayerTint = #6000
|
@ -24,8 +24,5 @@ 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,8 +24,5 @@ LayerTitle.Reset = Сбросить мир
|
|||||||
LayerTitle.Options = Настройки
|
LayerTitle.Options = Настройки
|
||||||
LayerTitle.Quit = Выход
|
LayerTitle.Quit = Выход
|
||||||
|
|
||||||
LayerOptions.Return = Главное меню
|
|
||||||
LayerOptions.Language = Русский
|
|
||||||
|
|
||||||
LayerText.Load = Загрузка...
|
LayerText.Load = Загрузка...
|
||||||
LayerText.Save = Сохранение...
|
LayerText.Save = Сохранение...
|
Binary file not shown.
Before Width: | Height: | Size: 133 B |
Binary file not shown.
Before Width: | Height: | Size: 12 KiB |
Reference in New Issue
Block a user