diff --git a/.gitignore b/.gitignore index 6143e53..78b7f88 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# IDE files +.idea + # Compiled class file *.class diff --git a/THIRD PARTY LICENSES/LibGDX.txt b/THIRD PARTY LICENSES/LibGDX.txt new file mode 100644 index 0000000..f433b1a --- /dev/null +++ b/THIRD PARTY LICENSES/LibGDX.txt @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/THIRD PARTY LICENSES/Oswald font.txt b/THIRD PARTY LICENSES/Oswald font.txt new file mode 100644 index 0000000..d248541 --- /dev/null +++ b/THIRD PARTY LICENSES/Oswald font.txt @@ -0,0 +1,46 @@ +License obtained from: https://www.fontsquirrel.com/license/oswald (02/02/2017) + +Copyright (c) 2012, Vernon Adams (vern@newtypography.co.uk), +with Reserved Font Name Oswald + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. + +The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the copyright statement(s). + +"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. + +"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. + +5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..9ec9d91 --- /dev/null +++ b/build.gradle @@ -0,0 +1,81 @@ +buildscript { + repositories { + mavenLocal() + mavenCentral() + maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } + jcenter() + } + dependencies { + classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6' + } +} + +allprojects { + apply plugin: "eclipse" + apply plugin: "idea" + + version = '1.0' + ext { + appName = "qwas" + gdxVersion = '1.9.4' + roboVMVersion = '2.2.0' + box2DLightsVersion = '1.4' + ashleyVersion = '1.7.0' + aiVersion = '1.8.0' + } + + repositories { + mavenLocal() + mavenCentral() + maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } + maven { url "https://oss.sonatype.org/content/repositories/releases/" } + } +} + +project(":desktop") { + apply plugin: "java" + + + dependencies { + compile project(":core") + compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion" + compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" + compile "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop" + compile "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-desktop" + compile "com.badlogicgames.gdx:gdx-tools:$gdxVersion" + } +} + +project(":html") { + apply plugin: "gwt" + apply plugin: "war" + + + dependencies { + compile project(":core") + compile "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion" + compile "com.badlogicgames.gdx:gdx:$gdxVersion:sources" + compile "com.badlogicgames.gdx:gdx-backend-gwt:$gdxVersion:sources" + compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion:sources" + compile "com.badlogicgames.gdx:gdx-box2d-gwt:$gdxVersion:sources" + compile "com.badlogicgames.ashley:ashley:$ashleyVersion:sources" + compile "com.badlogicgames.gdx:gdx-ai:$aiVersion:sources" + } +} + +project(":core") { + apply plugin: "java" + + + dependencies { + compile "com.badlogicgames.gdx:gdx:$gdxVersion" + compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion" + compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion" + compile "com.badlogicgames.ashley:ashley:$ashleyVersion" + compile "com.badlogicgames.gdx:gdx-ai:$aiVersion" + } +} + +tasks.eclipse.doLast { + delete ".project" +} \ No newline at end of file diff --git a/core/assets/bg.png b/core/assets/bg.png new file mode 100644 index 0000000..916efbd Binary files /dev/null and b/core/assets/bg.png differ diff --git a/core/assets/blue.bmp b/core/assets/blue.bmp new file mode 100644 index 0000000..54542f3 Binary files /dev/null and b/core/assets/blue.bmp differ diff --git a/core/assets/charbg.png b/core/assets/charbg.png new file mode 100644 index 0000000..bb53d87 Binary files /dev/null and b/core/assets/charbg.png differ diff --git a/core/assets/checkbox_ticked.png b/core/assets/checkbox_ticked.png new file mode 100644 index 0000000..1d25cd0 Binary files /dev/null and b/core/assets/checkbox_ticked.png differ diff --git a/core/assets/checkbox_unticked.png b/core/assets/checkbox_unticked.png new file mode 100644 index 0000000..46928ce Binary files /dev/null and b/core/assets/checkbox_unticked.png differ diff --git a/core/assets/exercises/sentences/alphabet.txt b/core/assets/exercises/sentences/alphabet.txt new file mode 100644 index 0000000..89ab5a2 --- /dev/null +++ b/core/assets/exercises/sentences/alphabet.txt @@ -0,0 +1 @@ +abcd efgh ijkl mnop qrst uvwx yz \ No newline at end of file diff --git a/core/assets/exercises/sentences/fox.txt b/core/assets/exercises/sentences/fox.txt new file mode 100644 index 0000000..ff3bb63 --- /dev/null +++ b/core/assets/exercises/sentences/fox.txt @@ -0,0 +1 @@ +The quick brown fox jumps over the lazy dog \ No newline at end of file diff --git a/core/assets/fonts/oswald/Oswald-Bold.ttf b/core/assets/fonts/oswald/Oswald-Bold.ttf new file mode 100644 index 0000000..8d36c8d Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-Bold.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-BoldItalic.ttf b/core/assets/fonts/oswald/Oswald-BoldItalic.ttf new file mode 100644 index 0000000..a2c5007 Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-BoldItalic.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-Demi-BoldItalic.ttf b/core/assets/fonts/oswald/Oswald-Demi-BoldItalic.ttf new file mode 100644 index 0000000..f4ed443 Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-Demi-BoldItalic.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-DemiBold.ttf b/core/assets/fonts/oswald/Oswald-DemiBold.ttf new file mode 100644 index 0000000..f230704 Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-DemiBold.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-Extra-LightItalic.ttf b/core/assets/fonts/oswald/Oswald-Extra-LightItalic.ttf new file mode 100644 index 0000000..8d3e04b Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-Extra-LightItalic.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-ExtraLight.ttf b/core/assets/fonts/oswald/Oswald-ExtraLight.ttf new file mode 100644 index 0000000..1753dca Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-ExtraLight.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-Heavy.ttf b/core/assets/fonts/oswald/Oswald-Heavy.ttf new file mode 100644 index 0000000..0db6cf0 Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-Heavy.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-HeavyItalic.ttf b/core/assets/fonts/oswald/Oswald-HeavyItalic.ttf new file mode 100644 index 0000000..f156d3e Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-HeavyItalic.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-Light.ttf b/core/assets/fonts/oswald/Oswald-Light.ttf new file mode 100644 index 0000000..18cac63 Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-Light.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-LightItalic.ttf b/core/assets/fonts/oswald/Oswald-LightItalic.ttf new file mode 100644 index 0000000..47b448d Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-LightItalic.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-Medium.ttf b/core/assets/fonts/oswald/Oswald-Medium.ttf new file mode 100644 index 0000000..8210fc3 Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-Medium.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-MediumItalic.ttf b/core/assets/fonts/oswald/Oswald-MediumItalic.ttf new file mode 100644 index 0000000..cdf8a00 Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-MediumItalic.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-Regular.ttf b/core/assets/fonts/oswald/Oswald-Regular.ttf new file mode 100644 index 0000000..3f3a1d2 Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-Regular.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-RegularItalic.ttf b/core/assets/fonts/oswald/Oswald-RegularItalic.ttf new file mode 100644 index 0000000..8dc3ceb Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-RegularItalic.ttf differ diff --git a/core/assets/fonts/oswald/Oswald-Stencil.ttf b/core/assets/fonts/oswald/Oswald-Stencil.ttf new file mode 100644 index 0000000..77df397 Binary files /dev/null and b/core/assets/fonts/oswald/Oswald-Stencil.ttf differ diff --git a/core/assets/fonts/oswald/SIL Open Font License.txt b/core/assets/fonts/oswald/SIL Open Font License.txt new file mode 100644 index 0000000..d4bc2f0 --- /dev/null +++ b/core/assets/fonts/oswald/SIL Open Font License.txt @@ -0,0 +1,44 @@ +Copyright (c) 2012, Vernon Adams (vern@newtypography.co.uk), +with Reserved Font Name Oswald + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. + +The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the copyright statement(s). + +"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. + +"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. + +5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file diff --git a/core/assets/fonts/oswald/bm/oswald-regular-128.fnt b/core/assets/fonts/oswald/bm/oswald-regular-128.fnt new file mode 100644 index 0000000..5153d77 --- /dev/null +++ b/core/assets/fonts/oswald/bm/oswald-regular-128.fnt @@ -0,0 +1,211 @@ +info face="Oswald Regular" size=128 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=1,1,1,1 spacing=-2,-2 +common lineHeight=175 base=140 scaleW=512 scaleH=512 pages=2 packed=0 +page id=0 file="oswald-regular-1281.png" +page id=1 file="oswald-regular-1282.png" +chars count=96 +char id=10 x=0 y=0 width=0 height=0 xoffset=0 yoffset=0 xadvance=0 page=0 chnl=0 +char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=139 xadvance=29 page=0 chnl=0 +char id=33 x=493 y=347 width=16 height=105 xoffset=5 yoffset=36 xadvance=26 page=0 chnl=0 +char id=34 x=256 y=453 width=34 height=34 xoffset=10 yoffset=35 xadvance=49 page=0 chnl=0 +char id=36 x=255 y=0 width=54 height=125 xoffset=4 yoffset=26 xadvance=63 page=0 chnl=0 +char id=37 x=375 y=239 width=107 height=107 xoffset=4 yoffset=35 xadvance=115 page=0 chnl=0 +char id=38 x=0 y=239 width=65 height=108 xoffset=6 yoffset=34 xadvance=77 page=0 chnl=0 +char id=39 x=290 y=453 width=15 height=34 xoffset=10 yoffset=35 xadvance=47 page=0 chnl=0 +char id=40 x=0 y=0 width=27 height=131 xoffset=9 yoffset=35 xadvance=38 page=0 chnl=0 +char id=41 x=27 y=0 width=27 height=131 xoffset=2 yoffset=35 xadvance=33 page=0 chnl=0 +char id=42 x=118 y=453 width=46 height=46 xoffset=4 yoffset=35 xadvance=51 page=0 chnl=0 +char id=43 x=69 y=453 width=49 height=54 xoffset=2 yoffset=60 xadvance=53 page=0 chnl=0 +char id=44 x=305 y=453 width=17 height=34 xoffset=3 yoffset=124 xadvance=23 page=0 chnl=0 +char id=45 x=413 y=453 width=31 height=13 xoffset=5 yoffset=95 xadvance=41 page=0 chnl=0 +char id=46 x=397 y=453 width=16 height=17 xoffset=5 yoffset=124 xadvance=24 page=0 chnl=0 +char id=48 x=414 y=131 width=53 height=108 xoffset=5 yoffset=34 xadvance=63 page=0 chnl=0 +char id=50 x=215 y=239 width=53 height=107 xoffset=4 yoffset=34 xadvance=61 page=0 chnl=0 +char id=51 x=202 y=131 width=53 height=108 xoffset=4 yoffset=34 xadvance=60 page=0 chnl=0 +char id=53 x=268 y=239 width=53 height=107 xoffset=5 yoffset=35 xadvance=61 page=0 chnl=0 +char id=54 x=255 y=131 width=53 height=108 xoffset=6 yoffset=34 xadvance=63 page=0 chnl=0 +char id=56 x=308 y=131 width=53 height=108 xoffset=4 yoffset=34 xadvance=61 page=0 chnl=0 +char id=57 x=361 y=131 width=53 height=108 xoffset=5 yoffset=34 xadvance=63 page=0 chnl=0 +char id=58 x=53 y=453 width=16 height=58 xoffset=7 yoffset=71 xadvance=26 page=0 chnl=0 +char id=61 x=215 y=453 width=41 height=35 xoffset=6 yoffset=70 xadvance=53 page=0 chnl=0 +char id=63 x=321 y=239 width=54 height=107 xoffset=4 yoffset=34 xadvance=62 page=0 chnl=0 +char id=64 x=309 y=0 width=105 height=123 xoffset=6 yoffset=35 xadvance=116 page=0 chnl=0 +char id=65 x=0 y=347 width=61 height=106 xoffset=1 yoffset=35 xadvance=63 page=0 chnl=0 +char id=66 x=61 y=347 width=56 height=106 xoffset=7 yoffset=35 xadvance=67 page=0 chnl=0 +char id=67 x=441 y=0 width=56 height=108 xoffset=5 yoffset=34 xadvance=66 page=0 chnl=0 +char id=68 x=117 y=347 width=55 height=106 xoffset=7 yoffset=35 xadvance=67 page=0 chnl=0 +char id=69 x=467 y=131 width=43 height=106 xoffset=7 yoffset=35 xadvance=52 page=0 chnl=0 +char id=70 x=172 y=347 width=42 height=106 xoffset=7 yoffset=35 xadvance=50 page=0 chnl=0 +char id=71 x=0 y=131 width=58 height=108 xoffset=5 yoffset=34 xadvance=69 page=0 chnl=0 +char id=72 x=214 y=347 width=57 height=106 xoffset=7 yoffset=35 xadvance=71 page=0 chnl=0 +char id=73 x=482 y=239 width=16 height=106 xoffset=8 yoffset=35 xadvance=32 page=0 chnl=0 +char id=74 x=58 y=131 width=31 height=108 xoffset=0 yoffset=35 xadvance=38 page=0 chnl=0 +char id=75 x=271 y=347 width=57 height=106 xoffset=7 yoffset=35 xadvance=63 page=0 chnl=0 +char id=76 x=328 y=347 width=43 height=106 xoffset=7 yoffset=35 xadvance=51 page=0 chnl=0 +char id=77 x=371 y=347 width=69 height=106 xoffset=8 yoffset=35 xadvance=85 page=0 chnl=0 +char id=78 x=440 y=347 width=53 height=106 xoffset=7 yoffset=35 xadvance=67 page=0 chnl=0 +char id=79 x=89 y=131 width=59 height=108 xoffset=5 yoffset=34 xadvance=69 page=0 chnl=0 +char id=80 x=0 y=453 width=53 height=106 xoffset=7 yoffset=35 xadvance=61 page=0 chnl=0 +char id=81 x=181 y=0 width=59 height=128 xoffset=5 yoffset=34 xadvance=69 page=0 chnl=0 +char id=83 x=148 y=131 width=54 height=108 xoffset=4 yoffset=34 xadvance=60 page=0 chnl=0 +char id=85 x=65 y=239 width=57 height=107 xoffset=6 yoffset=35 xadvance=69 page=0 chnl=0 +char id=91 x=120 y=0 width=30 height=129 xoffset=7 yoffset=36 xadvance=43 page=0 chnl=0 +char id=93 x=150 y=0 width=31 height=129 xoffset=2 yoffset=36 xadvance=40 page=0 chnl=0 +char id=94 x=164 y=453 width=51 height=44 xoffset=3 yoffset=35 xadvance=57 page=0 chnl=0 +char id=95 x=444 y=453 width=46 height=13 xoffset=-1 yoffset=145 xadvance=44 page=0 chnl=0 +char id=96 x=322 y=453 width=24 height=28 xoffset=6 yoffset=35 xadvance=36 page=0 chnl=0 +char id=98 x=122 y=239 width=47 height=107 xoffset=6 yoffset=35 xadvance=58 page=0 chnl=0 +char id=100 x=169 y=239 width=46 height=107 xoffset=5 yoffset=35 xadvance=57 page=0 chnl=0 +char id=106 x=414 y=0 width=27 height=120 xoffset=-3 yoffset=40 xadvance=30 page=0 chnl=0 +char id=108 x=482 y=239 width=16 height=106 xoffset=7 yoffset=35 xadvance=29 page=0 chnl=0 +char id=123 x=54 y=0 width=33 height=131 xoffset=4 yoffset=34 xadvance=39 page=0 chnl=0 +char id=124 x=240 y=0 width=15 height=125 xoffset=8 yoffset=35 xadvance=31 page=0 chnl=0 +char id=125 x=87 y=0 width=33 height=131 xoffset=4 yoffset=34 xadvance=41 page=0 chnl=0 +char id=126 x=346 y=453 width=51 height=20 xoffset=3 yoffset=75 xadvance=57 page=0 chnl=0 +char id=35 x=238 y=106 width=56 height=106 xoffset=3 yoffset=35 xadvance=62 page=1 chnl=0 +char id=47 x=152 y=106 width=43 height=106 xoffset=2 yoffset=35 xadvance=47 page=1 chnl=0 +char id=49 x=474 y=0 width=34 height=106 xoffset=9 yoffset=35 xadvance=60 page=1 chnl=0 +char id=52 x=51 y=106 width=58 height=106 xoffset=4 yoffset=35 xadvance=63 page=1 chnl=0 +char id=55 x=109 y=106 width=43 height=106 xoffset=2 yoffset=35 xadvance=48 page=1 chnl=0 +char id=59 x=86 y=212 width=17 height=80 xoffset=6 yoffset=67 xadvance=28 page=1 chnl=0 +char id=60 x=254 y=311 width=39 height=69 xoffset=3 yoffset=68 xadvance=48 page=1 chnl=0 +char id=62 x=293 y=311 width=39 height=69 xoffset=6 yoffset=68 xadvance=48 page=1 chnl=0 +char id=82 x=0 y=0 width=55 height=106 xoffset=7 yoffset=35 xadvance=66 page=1 chnl=0 +char id=84 x=55 y=0 width=54 height=106 xoffset=-1 yoffset=35 xadvance=52 page=1 chnl=0 +char id=86 x=109 y=0 width=61 height=106 xoffset=2 yoffset=35 xadvance=65 page=1 chnl=0 +char id=87 x=170 y=0 width=87 height=106 xoffset=3 yoffset=35 xadvance=93 page=1 chnl=0 +char id=88 x=257 y=0 width=62 height=106 xoffset=0 yoffset=35 xadvance=62 page=1 chnl=0 +char id=89 x=319 y=0 width=62 height=106 xoffset=0 yoffset=35 xadvance=62 page=1 chnl=0 +char id=90 x=381 y=0 width=48 height=106 xoffset=4 yoffset=35 xadvance=54 page=1 chnl=0 +char id=92 x=195 y=106 width=43 height=106 xoffset=2 yoffset=35 xadvance=47 page=1 chnl=0 +char id=97 x=281 y=212 width=47 height=78 xoffset=4 yoffset=64 xadvance=54 page=1 chnl=0 +char id=99 x=103 y=212 width=44 height=79 xoffset=5 yoffset=63 xadvance=53 page=1 chnl=0 +char id=101 x=147 y=212 width=45 height=79 xoffset=5 yoffset=63 xadvance=55 page=1 chnl=0 +char id=102 x=294 y=106 width=36 height=103 xoffset=1 yoffset=38 xadvance=37 page=1 chnl=0 +char id=103 x=330 y=106 width=57 height=101 xoffset=1 yoffset=63 xadvance=55 page=1 chnl=0 +char id=104 x=429 y=0 width=45 height=106 xoffset=6 yoffset=35 xadvance=57 page=1 chnl=0 +char id=105 x=387 y=106 width=16 height=101 xoffset=7 yoffset=40 xadvance=30 page=1 chnl=0 +char id=107 x=0 y=106 width=51 height=106 xoffset=6 yoffset=35 xadvance=55 page=1 chnl=0 +char id=109 x=328 y=212 width=76 height=77 xoffset=6 yoffset=64 xadvance=87 page=1 chnl=0 +char id=110 x=404 y=212 width=45 height=77 xoffset=6 yoffset=64 xadvance=56 page=1 chnl=0 +char id=111 x=192 y=212 width=45 height=79 xoffset=5 yoffset=63 xadvance=55 page=1 chnl=0 +char id=112 x=403 y=106 width=47 height=101 xoffset=6 yoffset=64 xadvance=57 page=1 chnl=0 +char id=113 x=450 y=106 width=46 height=101 xoffset=5 yoffset=64 xadvance=57 page=1 chnl=0 +char id=114 x=449 y=212 width=34 height=77 xoffset=6 yoffset=64 xadvance=41 page=1 chnl=0 +char id=115 x=237 y=212 width=44 height=79 xoffset=2 yoffset=63 xadvance=48 page=1 chnl=0 +char id=116 x=0 y=212 width=35 height=99 xoffset=2 yoffset=43 xadvance=39 page=1 chnl=0 +char id=117 x=0 y=311 width=45 height=77 xoffset=5 yoffset=65 xadvance=56 page=1 chnl=0 +char id=118 x=45 y=311 width=49 height=76 xoffset=0 yoffset=65 xadvance=49 page=1 chnl=0 +char id=119 x=94 y=311 width=71 height=76 xoffset=2 yoffset=65 xadvance=75 page=1 chnl=0 +char id=120 x=165 y=311 width=50 height=76 xoffset=0 yoffset=65 xadvance=50 page=1 chnl=0 +char id=121 x=35 y=212 width=51 height=95 xoffset=0 yoffset=64 xadvance=50 page=1 chnl=0 +char id=122 x=215 y=311 width=39 height=76 xoffset=3 yoffset=65 xadvance=44 page=1 chnl=0 +kernings count=109 +kerning first=76 second=34 amount=-1 +kerning first=87 second=44 amount=-1 +kerning first=68 second=65 amount=-1 +kerning first=86 second=67 amount=-1 +kerning first=80 second=74 amount=-3 +kerning first=75 second=85 amount=-1 +kerning first=76 second=89 amount=-4 +kerning first=100 second=100 amount=-1 +kerning first=102 second=102 amount=-3 +kerning first=89 second=111 amount=-2 +kerning first=70 second=114 amount=-2 +kerning first=86 second=122 amount=-1 +kerning first=87 second=119 amount=-1 +kerning first=65 second=121 amount=-1 +kerning first=76 second=119 amount=-1 +kerning first=75 second=79 amount=-1 +kerning first=69 second=103 amount=-3 +kerning first=80 second=101 amount=-1 +kerning first=86 second=79 amount=-1 +kerning first=89 second=113 amount=-3 +kerning first=76 second=67 amount=-1 +kerning first=76 second=87 amount=-3 +kerning first=86 second=46 amount=-1 +kerning first=75 second=81 amount=-1 +kerning first=98 second=118 amount=-1 +kerning first=65 second=89 amount=-3 +kerning first=84 second=113 amount=-1 +kerning first=70 second=115 amount=-2 +kerning first=80 second=99 amount=-1 +kerning first=65 second=87 amount=-2 +kerning first=65 second=118 amount=-1 +kerning first=76 second=86 amount=-4 +kerning first=86 second=111 amount=-1 +kerning first=102 second=99 amount=-1 +kerning first=89 second=115 amount=-3 +kerning first=65 second=86 amount=-4 +kerning first=75 second=115 amount=-3 +kerning first=80 second=44 amount=-10 +kerning first=86 second=115 amount=-3 +kerning first=86 second=101 amount=-1 +kerning first=80 second=65 amount=-5 +kerning first=76 second=121 amount=-1 +kerning first=112 second=121 amount=-1 +kerning first=68 second=87 amount=-1 +kerning first=70 second=46 amount=-6 +kerning first=75 second=71 amount=-1 +kerning first=80 second=111 amount=-1 +kerning first=71 second=89 amount=-1 +kerning first=70 second=121 amount=-1 +kerning first=70 second=44 amount=-6 +kerning first=76 second=115 amount=-1 +kerning first=68 second=89 amount=-1 +kerning first=89 second=99 amount=-3 +kerning first=87 second=115 amount=-1 +kerning first=111 second=120 amount=-1 +kerning first=76 second=39 amount=-1 +kerning first=86 second=65 amount=-4 +kerning first=87 second=122 amount=-1 +kerning first=75 second=99 amount=-3 +kerning first=89 second=44 amount=-3 +kerning first=86 second=99 amount=-1 +kerning first=89 second=101 amount=-3 +kerning first=86 second=113 amount=-1 +kerning first=89 second=65 amount=-3 +kerning first=76 second=81 amount=-1 +kerning first=84 second=101 amount=-1 +kerning first=111 second=119 amount=-1 +kerning first=76 second=103 amount=-1 +kerning first=89 second=97 amount=-2 +kerning first=112 second=106 amount=-2 +kerning first=75 second=67 amount=-1 +kerning first=98 second=106 amount=-2 +kerning first=87 second=101 amount=-1 +kerning first=68 second=46 amount=-2 +kerning first=69 second=115 amount=-3 +kerning first=86 second=71 amount=-1 +kerning first=76 second=79 amount=-1 +kerning first=70 second=103 amount=-3 +kerning first=84 second=99 amount=-2 +kerning first=86 second=97 amount=-1 +kerning first=87 second=79 amount=-1 +kerning first=86 second=44 amount=-1 +kerning first=89 second=46 amount=-3 +kerning first=89 second=119 amount=-1 +kerning first=82 second=87 amount=-1 +kerning first=101 second=106 amount=-2 +kerning first=87 second=65 amount=-4 +kerning first=87 second=111 amount=-1 +kerning first=76 second=71 amount=-1 +kerning first=89 second=103 amount=-2 +kerning first=97 second=116 amount=-1 +kerning first=99 second=106 amount=-2 +kerning first=87 second=97 amount=-2 +kerning first=84 second=111 amount=-1 +kerning first=103 second=103 amount=-1 +kerning first=102 second=46 amount=-2 +kerning first=65 second=84 amount=-4 +kerning first=87 second=99 amount=-1 +kerning first=68 second=86 amount=-1 +kerning first=87 second=113 amount=-1 +kerning first=80 second=46 amount=-11 +kerning first=84 second=97 amount=-2 +kerning first=68 second=44 amount=-2 +kerning first=70 second=65 amount=-2 +kerning first=86 second=103 amount=-1 +kerning first=76 second=84 amount=-3 +kerning first=75 second=103 amount=-3 +kerning first=80 second=113 amount=-1 +kerning first=89 second=117 amount=-1 diff --git a/core/assets/fonts/oswald/bm/oswald-regular-1281.png b/core/assets/fonts/oswald/bm/oswald-regular-1281.png new file mode 100644 index 0000000..73d9776 Binary files /dev/null and b/core/assets/fonts/oswald/bm/oswald-regular-1281.png differ diff --git a/core/assets/fonts/oswald/bm/oswald-regular-1282.png b/core/assets/fonts/oswald/bm/oswald-regular-1282.png new file mode 100644 index 0000000..08cc968 Binary files /dev/null and b/core/assets/fonts/oswald/bm/oswald-regular-1282.png differ diff --git a/core/assets/fonts/oswald/bm/oswald-regular-256.fnt b/core/assets/fonts/oswald/bm/oswald-regular-256.fnt new file mode 100644 index 0000000..2f1f4b4 --- /dev/null +++ b/core/assets/fonts/oswald/bm/oswald-regular-256.fnt @@ -0,0 +1,233 @@ +info face="Oswald Regular" size=256 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=1,1,1,1 spacing=-2,-2 +common lineHeight=349 base=280 scaleW=512 scaleH=512 pages=7 packed=0 +page id=0 file="oswald-regular-2561.png" +page id=1 file="oswald-regular-2562.png" +page id=2 file="oswald-regular-2563.png" +page id=3 file="oswald-regular-2564.png" +page id=4 file="oswald-regular-2565.png" +page id=5 file="oswald-regular-2566.png" +page id=6 file="oswald-regular-2567.png" +chars count=96 +char id=10 x=0 y=0 width=0 height=0 xoffset=0 yoffset=0 xadvance=0 page=0 chnl=0 +char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=278 xadvance=59 page=0 chnl=0 +char id=36 x=0 y=256 width=106 height=248 xoffset=9 yoffset=52 xadvance=125 page=0 chnl=0 +char id=40 x=0 y=0 width=51 height=261 xoffset=19 yoffset=69 xadvance=77 page=0 chnl=0 +char id=41 x=51 y=0 width=51 height=261 xoffset=6 yoffset=69 xadvance=66 page=0 chnl=0 +char id=64 x=106 y=256 width=207 height=244 xoffset=14 yoffset=70 xadvance=231 page=0 chnl=0 +char id=67 x=366 y=256 width=110 height=214 xoffset=11 yoffset=68 xadvance=132 page=0 chnl=0 +char id=71 x=0 y=504 width=113 height=214 xoffset=11 yoffset=68 xadvance=137 page=0 chnl=0 +char id=73 x=476 y=256 width=30 height=209 xoffset=17 yoffset=71 xadvance=63 page=0 chnl=0 +char id=81 x=346 y=0 width=115 height=254 xoffset=11 yoffset=68 xadvance=138 page=0 chnl=0 +char id=91 x=228 y=0 width=59 height=256 xoffset=15 yoffset=71 xadvance=87 page=0 chnl=0 +char id=93 x=287 y=0 width=59 height=256 xoffset=6 yoffset=71 xadvance=80 page=0 chnl=0 +char id=106 x=313 y=256 width=53 height=238 xoffset=-6 yoffset=79 xadvance=59 page=0 chnl=0 +char id=123 x=102 y=0 width=63 height=260 xoffset=9 yoffset=69 xadvance=77 page=0 chnl=0 +char id=124 x=461 y=0 width=27 height=248 xoffset=17 yoffset=70 xadvance=61 page=0 chnl=0 +char id=125 x=165 y=0 width=63 height=260 xoffset=10 yoffset=69 xadvance=82 page=0 chnl=0 +char id=33 x=471 y=214 width=30 height=209 xoffset=12 yoffset=71 xadvance=54 page=1 chnl=0 +char id=34 x=194 y=428 width=65 height=66 xoffset=21 yoffset=70 xadvance=97 page=1 chnl=0 +char id=38 x=0 y=214 width=128 height=214 xoffset=14 yoffset=68 xadvance=156 page=1 chnl=0 +char id=39 x=259 y=428 width=27 height=66 xoffset=21 yoffset=70 xadvance=94 page=1 chnl=0 +char id=44 x=286 y=428 width=31 height=65 xoffset=8 yoffset=249 xadvance=47 page=1 chnl=0 +char id=45 x=0 y=640 width=59 height=23 xoffset=11 yoffset=190 xadvance=82 page=1 chnl=0 +char id=46 x=461 y=428 width=30 height=32 xoffset=11 yoffset=248 xadvance=48 page=1 chnl=0 +char id=48 x=336 y=214 width=105 height=213 xoffset=11 yoffset=69 xadvance=126 page=1 chnl=0 +char id=51 x=128 y=214 width=104 height=213 xoffset=9 yoffset=69 xadvance=119 page=1 chnl=0 +char id=54 x=282 y=0 width=104 height=214 xoffset=13 yoffset=68 xadvance=125 page=1 chnl=0 +char id=56 x=232 y=214 width=104 height=213 xoffset=9 yoffset=69 xadvance=122 page=1 chnl=0 +char id=57 x=386 y=0 width=105 height=214 xoffset=10 yoffset=68 xadvance=125 page=1 chnl=0 +char id=61 x=113 y=428 width=81 height=68 xoffset=13 yoffset=140 xadvance=107 page=1 chnl=0 +char id=74 x=0 y=0 width=61 height=214 xoffset=1 yoffset=71 xadvance=77 page=1 chnl=0 +char id=79 x=61 y=0 width=115 height=214 xoffset=11 yoffset=68 xadvance=137 page=1 chnl=0 +char id=83 x=176 y=0 width=106 height=214 xoffset=9 yoffset=68 xadvance=121 page=1 chnl=0 +char id=85 x=0 y=428 width=113 height=212 xoffset=13 yoffset=70 xadvance=139 page=1 chnl=0 +char id=96 x=317 y=428 width=45 height=53 xoffset=13 yoffset=70 xadvance=71 page=1 chnl=0 +char id=108 x=441 y=214 width=30 height=209 xoffset=15 yoffset=71 xadvance=59 page=1 chnl=0 +char id=126 x=362 y=428 width=99 height=39 xoffset=8 yoffset=148 xadvance=114 page=1 chnl=0 +char id=37 x=106 y=0 width=212 height=212 xoffset=8 yoffset=69 xadvance=228 page=2 chnl=0 +char id=50 x=0 y=212 width=105 height=211 xoffset=9 yoffset=69 xadvance=122 page=2 chnl=0 +char id=53 x=105 y=212 width=104 height=211 xoffset=11 yoffset=71 xadvance=122 page=2 chnl=0 +char id=63 x=0 y=0 width=106 height=212 xoffset=9 yoffset=68 xadvance=125 page=2 chnl=0 +char id=76 x=209 y=212 width=84 height=210 xoffset=15 yoffset=70 xadvance=102 page=2 chnl=0 +char id=80 x=293 y=212 width=105 height=210 xoffset=15 yoffset=70 xadvance=123 page=2 chnl=0 +char id=86 x=0 y=423 width=120 height=210 xoffset=5 yoffset=70 xadvance=129 page=2 chnl=0 +char id=94 x=120 y=423 width=99 height=85 xoffset=7 yoffset=70 xadvance=114 page=2 chnl=0 +char id=95 x=219 y=423 width=90 height=23 xoffset=-1 yoffset=291 xadvance=88 page=2 chnl=0 +char id=98 x=318 y=0 width=91 height=211 xoffset=13 yoffset=71 xadvance=114 page=2 chnl=0 +char id=100 x=409 y=0 width=90 height=211 xoffset=10 yoffset=71 xadvance=113 page=2 chnl=0 +char id=107 x=398 y=212 width=99 height=210 xoffset=13 yoffset=70 xadvance=110 page=2 chnl=0 +char id=42 x=83 y=420 width=88 height=89 xoffset=10 yoffset=71 xadvance=102 page=3 chnl=0 +char id=47 x=0 y=210 width=82 height=210 xoffset=6 yoffset=70 xadvance=95 page=3 chnl=0 +char id=52 x=291 y=0 width=113 height=210 xoffset=9 yoffset=70 xadvance=126 page=3 chnl=0 +char id=55 x=404 y=0 width=85 height=210 xoffset=6 yoffset=70 xadvance=99 page=3 chnl=0 +char id=65 x=164 y=210 width=120 height=209 xoffset=3 yoffset=71 xadvance=126 page=3 chnl=0 +char id=66 x=284 y=210 width=111 height=209 xoffset=15 yoffset=71 xadvance=134 page=3 chnl=0 +char id=68 x=395 y=210 width=108 height=209 xoffset=15 yoffset=71 xadvance=134 page=3 chnl=0 +char id=69 x=0 y=420 width=83 height=209 xoffset=15 yoffset=71 xadvance=104 page=3 chnl=0 +char id=87 x=0 y=0 width=171 height=210 xoffset=8 yoffset=70 xadvance=187 page=3 chnl=0 +char id=89 x=171 y=0 width=120 height=210 xoffset=2 yoffset=70 xadvance=124 page=3 chnl=0 +char id=92 x=82 y=210 width=82 height=210 xoffset=6 yoffset=70 xadvance=95 page=3 chnl=0 +char id=49 x=443 y=0 width=66 height=209 xoffset=20 yoffset=71 xadvance=120 page=4 chnl=0 +char id=70 x=0 y=0 width=82 height=209 xoffset=15 yoffset=71 xadvance=100 page=4 chnl=0 +char id=72 x=82 y=0 width=113 height=209 xoffset=15 yoffset=71 xadvance=143 page=4 chnl=0 +char id=75 x=195 y=0 width=112 height=209 xoffset=15 yoffset=71 xadvance=127 page=4 chnl=0 +char id=77 x=307 y=0 width=136 height=209 xoffset=16 yoffset=71 xadvance=169 page=4 chnl=0 +char id=78 x=0 y=209 width=105 height=209 xoffset=15 yoffset=71 xadvance=135 page=4 chnl=0 +char id=82 x=105 y=209 width=109 height=209 xoffset=15 yoffset=71 xadvance=133 page=4 chnl=0 +char id=84 x=214 y=209 width=105 height=209 xoffset=-1 yoffset=71 xadvance=103 page=4 chnl=0 +char id=88 x=319 y=209 width=120 height=209 xoffset=2 yoffset=71 xadvance=123 page=4 chnl=0 +char id=90 x=0 y=418 width=94 height=209 xoffset=9 yoffset=71 xadvance=107 page=4 chnl=0 +char id=102 x=439 y=209 width=70 height=203 xoffset=4 yoffset=77 xadvance=74 page=4 chnl=0 +char id=35 x=89 y=0 width=111 height=209 xoffset=7 yoffset=71 xadvance=125 page=5 chnl=0 +char id=58 x=472 y=209 width=30 height=113 xoffset=14 yoffset=142 xadvance=50 page=5 chnl=0 +char id=59 x=480 y=0 width=31 height=158 xoffset=13 yoffset=133 xadvance=55 page=5 chnl=0 +char id=99 x=210 y=209 width=86 height=155 xoffset=10 yoffset=127 xadvance=106 page=5 chnl=0 +char id=101 x=296 y=209 width=88 height=155 xoffset=10 yoffset=127 xadvance=108 page=5 chnl=0 +char id=103 x=0 y=209 width=112 height=199 xoffset=4 yoffset=127 xadvance=112 page=5 chnl=0 +char id=104 x=0 y=0 width=89 height=209 xoffset=13 yoffset=71 xadvance=114 page=5 chnl=0 +char id=105 x=200 y=0 width=30 height=201 xoffset=15 yoffset=79 xadvance=59 page=5 chnl=0 +char id=111 x=384 y=209 width=88 height=155 xoffset=10 yoffset=127 xadvance=108 page=5 chnl=0 +char id=112 x=230 y=0 width=91 height=201 xoffset=13 yoffset=128 xadvance=114 page=5 chnl=0 +char id=113 x=321 y=0 width=90 height=201 xoffset=10 yoffset=128 xadvance=113 page=5 chnl=0 +char id=115 x=0 y=408 width=85 height=155 xoffset=5 yoffset=127 xadvance=96 page=5 chnl=0 +char id=116 x=411 y=0 width=69 height=196 xoffset=5 yoffset=86 xadvance=80 page=5 chnl=0 +char id=121 x=112 y=209 width=98 height=187 xoffset=2 yoffset=130 xadvance=100 page=5 chnl=0 +char id=43 x=76 y=304 width=96 height=106 xoffset=5 yoffset=120 xadvance=106 page=6 chnl=0 +char id=60 x=408 y=154 width=76 height=134 xoffset=6 yoffset=137 xadvance=95 page=6 chnl=0 +char id=62 x=0 y=304 width=76 height=134 xoffset=14 yoffset=137 xadvance=96 page=6 chnl=0 +char id=97 x=0 y=0 width=91 height=154 xoffset=10 yoffset=128 xadvance=110 page=6 chnl=0 +char id=109 x=91 y=0 width=149 height=153 xoffset=13 yoffset=127 xadvance=174 page=6 chnl=0 +char id=110 x=240 y=0 width=88 height=152 xoffset=13 yoffset=128 xadvance=113 page=6 chnl=0 +char id=114 x=328 y=0 width=66 height=152 xoffset=13 yoffset=128 xadvance=82 page=6 chnl=0 +char id=117 x=394 y=0 width=88 height=152 xoffset=12 yoffset=130 xadvance=113 page=6 chnl=0 +char id=118 x=0 y=154 width=94 height=150 xoffset=2 yoffset=130 xadvance=99 page=6 chnl=0 +char id=119 x=94 y=154 width=139 height=150 xoffset=6 yoffset=130 xadvance=151 page=6 chnl=0 +char id=120 x=233 y=154 width=98 height=150 xoffset=1 yoffset=130 xadvance=100 page=6 chnl=0 +char id=122 x=331 y=154 width=77 height=150 xoffset=7 yoffset=130 xadvance=89 page=6 chnl=0 +kernings count=126 +kerning first=76 second=34 amount=-2 +kerning first=76 second=39 amount=-2 +kerning first=80 second=74 amount=-5 +kerning first=65 second=79 amount=-1 +kerning first=75 second=85 amount=-1 +kerning first=76 second=87 amount=-6 +kerning first=76 second=89 amount=-7 +kerning first=100 second=100 amount=-1 +kerning first=102 second=102 amount=-7 +kerning first=89 second=111 amount=-5 +kerning first=86 second=122 amount=-2 +kerning first=87 second=119 amount=-2 +kerning first=119 second=44 amount=-1 +kerning first=65 second=121 amount=-2 +kerning first=76 second=119 amount=-3 +kerning first=103 second=111 amount=-1 +kerning first=75 second=79 amount=-1 +kerning first=89 second=115 amount=-6 +kerning first=69 second=103 amount=-6 +kerning first=65 second=119 amount=-1 +kerning first=80 second=101 amount=-1 +kerning first=86 second=79 amount=-2 +kerning first=89 second=113 amount=-5 +kerning first=76 second=67 amount=-2 +kerning first=86 second=46 amount=-1 +kerning first=75 second=81 amount=-1 +kerning first=98 second=118 amount=-2 +kerning first=102 second=44 amount=-1 +kerning first=84 second=113 amount=-3 +kerning first=70 second=115 amount=-4 +kerning first=80 second=99 amount=-1 +kerning first=121 second=46 amount=-1 +kerning first=65 second=118 amount=-2 +kerning first=76 second=86 amount=-7 +kerning first=86 second=111 amount=-3 +kerning first=102 second=99 amount=-1 +kerning first=65 second=86 amount=-7 +kerning first=75 second=115 amount=-6 +kerning first=80 second=44 amount=-19 +kerning first=86 second=101 amount=-3 +kerning first=80 second=65 amount=-9 +kerning first=76 second=121 amount=-2 +kerning first=112 second=121 amount=-1 +kerning first=68 second=87 amount=-2 +kerning first=70 second=46 amount=-12 +kerning first=75 second=71 amount=-1 +kerning first=80 second=111 amount=-1 +kerning first=87 second=111 amount=-3 +kerning first=86 second=71 amount=-1 +kerning first=87 second=44 amount=-1 +kerning first=65 second=87 amount=-4 +kerning first=98 second=106 amount=-3 +kerning first=70 second=121 amount=-2 +kerning first=89 second=101 amount=-5 +kerning first=76 second=115 amount=-3 +kerning first=65 second=84 amount=-8 +kerning first=68 second=89 amount=-2 +kerning first=68 second=44 amount=-3 +kerning first=111 second=121 amount=-1 +kerning first=89 second=99 amount=-5 +kerning first=111 second=120 amount=-1 +kerning first=86 second=65 amount=-7 +kerning first=87 second=122 amount=-2 +kerning first=70 second=114 amount=-3 +kerning first=75 second=99 amount=-6 +kerning first=84 second=115 amount=-1 +kerning first=102 second=46 amount=-3 +kerning first=89 second=44 amount=-6 +kerning first=65 second=81 amount=-1 +kerning first=86 second=99 amount=-3 +kerning first=70 second=44 amount=-11 +kerning first=86 second=115 amount=-6 +kerning first=86 second=113 amount=-2 +kerning first=87 second=46 amount=-1 +kerning first=89 second=65 amount=-5 +kerning first=76 second=81 amount=-2 +kerning first=84 second=101 amount=-3 +kerning first=112 second=118 amount=1 +kerning first=111 second=119 amount=-2 +kerning first=76 second=103 amount=-3 +kerning first=89 second=97 amount=-3 +kerning first=71 second=89 amount=-1 +kerning first=112 second=106 amount=-4 +kerning first=75 second=67 amount=-1 +kerning first=87 second=101 amount=-3 +kerning first=114 second=99 amount=-1 +kerning first=68 second=46 amount=-3 +kerning first=69 second=115 amount=-6 +kerning first=76 second=79 amount=-2 +kerning first=118 second=46 amount=-1 +kerning first=70 second=103 amount=-6 +kerning first=65 second=89 amount=-5 +kerning first=84 second=99 amount=-3 +kerning first=86 second=97 amount=-2 +kerning first=84 second=65 amount=-1 +kerning first=87 second=79 amount=-2 +kerning first=86 second=44 amount=-2 +kerning first=89 second=46 amount=-5 +kerning first=89 second=119 amount=-2 +kerning first=82 second=87 amount=-1 +kerning first=101 second=106 amount=-3 +kerning first=87 second=65 amount=-7 +kerning first=76 second=71 amount=-2 +kerning first=89 second=103 amount=-4 +kerning first=97 second=116 amount=-2 +kerning first=99 second=106 amount=-3 +kerning first=87 second=97 amount=-4 +kerning first=121 second=44 amount=-1 +kerning first=84 second=111 amount=-3 +kerning first=103 second=103 amount=-2 +kerning first=87 second=99 amount=-2 +kerning first=68 second=86 amount=-3 +kerning first=87 second=113 amount=-2 +kerning first=86 second=67 amount=-1 +kerning first=80 second=46 amount=-22 +kerning first=65 second=71 amount=-1 +kerning first=84 second=97 amount=-3 +kerning first=68 second=65 amount=-3 +kerning first=70 second=65 amount=-4 +kerning first=86 second=103 amount=-2 +kerning first=76 second=84 amount=-6 +kerning first=87 second=115 amount=-3 +kerning first=75 second=103 amount=-6 +kerning first=80 second=113 amount=-1 +kerning first=89 second=117 amount=-2 +kerning first=118 second=44 amount=-1 diff --git a/core/assets/fonts/oswald/bm/oswald-regular-2561.png b/core/assets/fonts/oswald/bm/oswald-regular-2561.png new file mode 100644 index 0000000..5794fbf Binary files /dev/null and b/core/assets/fonts/oswald/bm/oswald-regular-2561.png differ diff --git a/core/assets/fonts/oswald/bm/oswald-regular-2562.png b/core/assets/fonts/oswald/bm/oswald-regular-2562.png new file mode 100644 index 0000000..302f5c9 Binary files /dev/null and b/core/assets/fonts/oswald/bm/oswald-regular-2562.png differ diff --git a/core/assets/fonts/oswald/bm/oswald-regular-2563.png b/core/assets/fonts/oswald/bm/oswald-regular-2563.png new file mode 100644 index 0000000..0d80d6b Binary files /dev/null and b/core/assets/fonts/oswald/bm/oswald-regular-2563.png differ diff --git a/core/assets/fonts/oswald/bm/oswald-regular-2564.png b/core/assets/fonts/oswald/bm/oswald-regular-2564.png new file mode 100644 index 0000000..7bdc545 Binary files /dev/null and b/core/assets/fonts/oswald/bm/oswald-regular-2564.png differ diff --git a/core/assets/fonts/oswald/bm/oswald-regular-2565.png b/core/assets/fonts/oswald/bm/oswald-regular-2565.png new file mode 100644 index 0000000..5bd6466 Binary files /dev/null and b/core/assets/fonts/oswald/bm/oswald-regular-2565.png differ diff --git a/core/assets/fonts/oswald/bm/oswald-regular-2566.png b/core/assets/fonts/oswald/bm/oswald-regular-2566.png new file mode 100644 index 0000000..ccf4898 Binary files /dev/null and b/core/assets/fonts/oswald/bm/oswald-regular-2566.png differ diff --git a/core/assets/fonts/oswald/bm/oswald-regular-2567.png b/core/assets/fonts/oswald/bm/oswald-regular-2567.png new file mode 100644 index 0000000..94d5fef Binary files /dev/null and b/core/assets/fonts/oswald/bm/oswald-regular-2567.png differ diff --git a/core/assets/fonts/oswald/bm/oswald-regular-32.fnt b/core/assets/fonts/oswald/bm/oswald-regular-32.fnt new file mode 100644 index 0000000..1cf6d7d --- /dev/null +++ b/core/assets/fonts/oswald/bm/oswald-regular-32.fnt @@ -0,0 +1,136 @@ +info face="Oswald Regular" size=32 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=1,1,1,1 spacing=-2,-2 +common lineHeight=44 base=35 scaleW=512 scaleH=512 pages=1 packed=0 +page id=0 file="oswald-regular-32.png" +chars count=96 +char id=10 x=0 y=0 width=0 height=0 xoffset=0 yoffset=0 xadvance=0 page=0 chnl=0 +char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=34 xadvance=7 page=0 chnl=0 +char id=33 x=213 y=35 width=6 height=28 xoffset=1 yoffset=8 xadvance=7 page=0 chnl=0 +char id=34 x=170 y=63 width=11 height=10 xoffset=2 yoffset=8 xadvance=13 page=0 chnl=0 +char id=35 x=290 y=35 width=16 height=28 xoffset=0 yoffset=8 xadvance=16 page=0 chnl=0 +char id=36 x=115 y=0 width=15 height=33 xoffset=0 yoffset=5 xadvance=15 page=0 chnl=0 +char id=37 x=261 y=35 width=29 height=28 xoffset=0 yoffset=8 xadvance=29 page=0 chnl=0 +char id=38 x=306 y=35 width=18 height=28 xoffset=1 yoffset=8 xadvance=19 page=0 chnl=0 +char id=39 x=181 y=63 width=6 height=10 xoffset=2 yoffset=8 xadvance=12 page=0 chnl=0 +char id=40 x=0 y=0 width=8 height=35 xoffset=1 yoffset=8 xadvance=9 page=0 chnl=0 +char id=41 x=8 y=0 width=9 height=35 xoffset=0 yoffset=8 xadvance=9 page=0 chnl=0 +char id=42 x=122 y=63 width=14 height=14 xoffset=0 yoffset=8 xadvance=13 page=0 chnl=0 +char id=43 x=108 y=63 width=14 height=15 xoffset=0 yoffset=14 xadvance=14 page=0 chnl=0 +char id=44 x=151 y=63 width=7 height=11 xoffset=-1 yoffset=30 xadvance=6 page=0 chnl=0 +char id=45 x=217 y=63 width=9 height=5 xoffset=1 yoffset=23 xadvance=11 page=0 chnl=0 +char id=46 x=211 y=63 width=6 height=6 xoffset=1 yoffset=30 xadvance=7 page=0 chnl=0 +char id=47 x=235 y=35 width=13 height=28 xoffset=-1 yoffset=8 xadvance=12 page=0 chnl=0 +char id=48 x=198 y=35 width=15 height=28 xoffset=0 yoffset=8 xadvance=15 page=0 chnl=0 +char id=49 x=67 y=35 width=11 height=28 xoffset=1 yoffset=8 xadvance=15 page=0 chnl=0 +char id=50 x=78 y=35 width=15 height=28 xoffset=0 yoffset=8 xadvance=15 page=0 chnl=0 +char id=51 x=93 y=35 width=15 height=28 xoffset=0 yoffset=8 xadvance=15 page=0 chnl=0 +char id=52 x=108 y=35 width=17 height=28 xoffset=0 yoffset=8 xadvance=16 page=0 chnl=0 +char id=53 x=125 y=35 width=15 height=28 xoffset=0 yoffset=8 xadvance=14 page=0 chnl=0 +char id=54 x=140 y=35 width=15 height=28 xoffset=1 yoffset=8 xadvance=16 page=0 chnl=0 +char id=55 x=155 y=35 width=12 height=28 xoffset=0 yoffset=8 xadvance=12 page=0 chnl=0 +char id=56 x=167 y=35 width=15 height=28 xoffset=0 yoffset=8 xadvance=15 page=0 chnl=0 +char id=57 x=182 y=35 width=16 height=28 xoffset=-1 yoffset=8 xadvance=15 page=0 chnl=0 +char id=58 x=502 y=35 width=6 height=16 xoffset=1 yoffset=17 xadvance=6 page=0 chnl=0 +char id=59 x=398 y=35 width=7 height=22 xoffset=0 yoffset=15 xadvance=7 page=0 chnl=0 +char id=60 x=86 y=63 width=11 height=19 xoffset=0 yoffset=16 xadvance=12 page=0 chnl=0 +char id=61 x=158 y=63 width=12 height=11 xoffset=1 yoffset=16 xadvance=14 page=0 chnl=0 +char id=62 x=97 y=63 width=11 height=19 xoffset=1 yoffset=16 xadvance=12 page=0 chnl=0 +char id=63 x=219 y=35 width=16 height=28 xoffset=0 yoffset=8 xadvance=16 page=0 chnl=0 +char id=64 x=87 y=0 width=28 height=33 xoffset=1 yoffset=8 xadvance=29 page=0 chnl=0 +char id=65 x=130 y=0 width=18 height=28 xoffset=-1 yoffset=8 xadvance=16 page=0 chnl=0 +char id=66 x=148 y=0 width=16 height=28 xoffset=1 yoffset=8 xadvance=17 page=0 chnl=0 +char id=67 x=164 y=0 width=16 height=28 xoffset=1 yoffset=8 xadvance=17 page=0 chnl=0 +char id=68 x=180 y=0 width=15 height=28 xoffset=1 yoffset=8 xadvance=17 page=0 chnl=0 +char id=69 x=195 y=0 width=12 height=28 xoffset=1 yoffset=8 xadvance=13 page=0 chnl=0 +char id=70 x=207 y=0 width=12 height=28 xoffset=1 yoffset=8 xadvance=13 page=0 chnl=0 +char id=71 x=219 y=0 width=16 height=28 xoffset=1 yoffset=8 xadvance=17 page=0 chnl=0 +char id=72 x=235 y=0 width=16 height=28 xoffset=1 yoffset=8 xadvance=18 page=0 chnl=0 +char id=73 x=251 y=0 width=6 height=28 xoffset=1 yoffset=8 xadvance=8 page=0 chnl=0 +char id=74 x=257 y=0 width=10 height=28 xoffset=0 yoffset=8 xadvance=11 page=0 chnl=0 +char id=75 x=267 y=0 width=16 height=28 xoffset=1 yoffset=8 xadvance=16 page=0 chnl=0 +char id=76 x=283 y=0 width=12 height=28 xoffset=1 yoffset=8 xadvance=13 page=0 chnl=0 +char id=77 x=295 y=0 width=19 height=28 xoffset=1 yoffset=8 xadvance=21 page=0 chnl=0 +char id=78 x=314 y=0 width=15 height=28 xoffset=1 yoffset=8 xadvance=17 page=0 chnl=0 +char id=79 x=329 y=0 width=16 height=28 xoffset=1 yoffset=8 xadvance=18 page=0 chnl=0 +char id=80 x=345 y=0 width=15 height=28 xoffset=1 yoffset=8 xadvance=16 page=0 chnl=0 +char id=81 x=37 y=0 width=16 height=34 xoffset=1 yoffset=8 xadvance=18 page=0 chnl=0 +char id=82 x=360 y=0 width=16 height=28 xoffset=1 yoffset=8 xadvance=17 page=0 chnl=0 +char id=83 x=376 y=0 width=15 height=28 xoffset=0 yoffset=8 xadvance=15 page=0 chnl=0 +char id=84 x=391 y=0 width=15 height=28 xoffset=-1 yoffset=8 xadvance=13 page=0 chnl=0 +char id=85 x=406 y=0 width=16 height=28 xoffset=1 yoffset=8 xadvance=18 page=0 chnl=0 +char id=86 x=422 y=0 width=18 height=28 xoffset=-1 yoffset=8 xadvance=16 page=0 chnl=0 +char id=87 x=440 y=0 width=24 height=28 xoffset=0 yoffset=8 xadvance=23 page=0 chnl=0 +char id=88 x=464 y=0 width=18 height=28 xoffset=-1 yoffset=8 xadvance=15 page=0 chnl=0 +char id=89 x=482 y=0 width=18 height=28 xoffset=-1 yoffset=8 xadvance=15 page=0 chnl=0 +char id=90 x=0 y=35 width=13 height=28 xoffset=0 yoffset=8 xadvance=13 page=0 chnl=0 +char id=91 x=53 y=0 width=9 height=34 xoffset=1 yoffset=8 xadvance=11 page=0 chnl=0 +char id=92 x=248 y=35 width=13 height=28 xoffset=-1 yoffset=8 xadvance=12 page=0 chnl=0 +char id=93 x=62 y=0 width=10 height=34 xoffset=-1 yoffset=8 xadvance=9 page=0 chnl=0 +char id=94 x=136 y=63 width=15 height=13 xoffset=0 yoffset=7 xadvance=14 page=0 chnl=0 +char id=95 x=226 y=63 width=13 height=5 xoffset=-1 yoffset=35 xadvance=11 page=0 chnl=0 +char id=96 x=187 y=63 width=9 height=9 xoffset=0 yoffset=7 xadvance=9 page=0 chnl=0 +char id=97 x=405 y=35 width=14 height=21 xoffset=0 yoffset=15 xadvance=14 page=0 chnl=0 +char id=98 x=13 y=35 width=13 height=28 xoffset=1 yoffset=8 xadvance=14 page=0 chnl=0 +char id=99 x=419 y=35 width=13 height=21 xoffset=0 yoffset=15 xadvance=13 page=0 chnl=0 +char id=100 x=26 y=35 width=13 height=28 xoffset=0 yoffset=8 xadvance=14 page=0 chnl=0 +char id=101 x=432 y=35 width=13 height=21 xoffset=0 yoffset=15 xadvance=13 page=0 chnl=0 +char id=102 x=500 y=0 width=10 height=28 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=103 x=324 y=35 width=17 height=27 xoffset=0 yoffset=14 xadvance=15 page=0 chnl=0 +char id=104 x=39 y=35 width=13 height=28 xoffset=1 yoffset=8 xadvance=15 page=0 chnl=0 +char id=105 x=341 y=35 width=6 height=27 xoffset=1 yoffset=9 xadvance=7 page=0 chnl=0 +char id=106 x=72 y=0 width=9 height=33 xoffset=-1 yoffset=8 xadvance=8 page=0 chnl=0 +char id=107 x=52 y=35 width=15 height=28 xoffset=1 yoffset=8 xadvance=14 page=0 chnl=0 +char id=108 x=251 y=0 width=6 height=28 xoffset=1 yoffset=8 xadvance=7 page=0 chnl=0 +char id=109 x=445 y=35 width=21 height=21 xoffset=1 yoffset=15 xadvance=22 page=0 chnl=0 +char id=110 x=466 y=35 width=13 height=21 xoffset=1 yoffset=15 xadvance=14 page=0 chnl=0 +char id=111 x=479 y=35 width=13 height=21 xoffset=0 yoffset=15 xadvance=13 page=0 chnl=0 +char id=112 x=347 y=35 width=13 height=27 xoffset=1 yoffset=15 xadvance=14 page=0 chnl=0 +char id=113 x=360 y=35 width=13 height=27 xoffset=0 yoffset=15 xadvance=14 page=0 chnl=0 +char id=114 x=492 y=35 width=10 height=21 xoffset=1 yoffset=15 xadvance=11 page=0 chnl=0 +char id=115 x=0 y=63 width=13 height=21 xoffset=-1 yoffset=15 xadvance=12 page=0 chnl=0 +char id=116 x=373 y=35 width=10 height=27 xoffset=0 yoffset=9 xadvance=10 page=0 chnl=0 +char id=117 x=13 y=63 width=13 height=21 xoffset=1 yoffset=15 xadvance=14 page=0 chnl=0 +char id=118 x=26 y=63 width=14 height=21 xoffset=-1 yoffset=15 xadvance=12 page=0 chnl=0 +char id=119 x=40 y=63 width=20 height=21 xoffset=-1 yoffset=15 xadvance=19 page=0 chnl=0 +char id=120 x=60 y=63 width=15 height=21 xoffset=-1 yoffset=15 xadvance=12 page=0 chnl=0 +char id=121 x=383 y=35 width=15 height=26 xoffset=-2 yoffset=15 xadvance=13 page=0 chnl=0 +char id=122 x=75 y=63 width=11 height=21 xoffset=0 yoffset=15 xadvance=11 page=0 chnl=0 +char id=123 x=17 y=0 width=10 height=35 xoffset=0 yoffset=8 xadvance=9 page=0 chnl=0 +char id=124 x=81 y=0 width=6 height=33 xoffset=1 yoffset=8 xadvance=8 page=0 chnl=0 +char id=125 x=27 y=0 width=10 height=35 xoffset=0 yoffset=8 xadvance=10 page=0 chnl=0 +char id=126 x=196 y=63 width=15 height=7 xoffset=0 yoffset=17 xadvance=14 page=0 chnl=0 +kernings count=35 +kerning first=89 second=44 amount=-1 +kerning first=75 second=99 amount=-1 +kerning first=80 second=74 amount=-1 +kerning first=65 second=89 amount=-1 +kerning first=102 second=102 amount=-1 +kerning first=112 second=106 amount=-1 +kerning first=89 second=113 amount=-1 +kerning first=89 second=99 amount=-1 +kerning first=70 second=103 amount=-1 +kerning first=76 second=86 amount=-1 +kerning first=65 second=86 amount=-1 +kerning first=80 second=44 amount=-2 +kerning first=89 second=103 amount=-1 +kerning first=76 second=84 amount=-1 +kerning first=70 second=44 amount=-1 +kerning first=80 second=46 amount=-3 +kerning first=89 second=101 amount=-1 +kerning first=65 second=84 amount=-1 +kerning first=69 second=103 amount=-1 +kerning first=89 second=65 amount=-1 +kerning first=86 second=65 amount=-1 +kerning first=89 second=46 amount=-1 +kerning first=69 second=115 amount=-1 +kerning first=76 second=89 amount=-1 +kerning first=70 second=65 amount=-1 +kerning first=80 second=65 amount=-1 +kerning first=89 second=111 amount=-1 +kerning first=75 second=103 amount=-1 +kerning first=76 second=87 amount=-1 +kerning first=87 second=65 amount=-1 +kerning first=70 second=115 amount=-1 +kerning first=86 second=115 amount=-1 +kerning first=75 second=115 amount=-1 +kerning first=89 second=115 amount=-1 +kerning first=70 second=46 amount=-1 diff --git a/core/assets/fonts/oswald/bm/oswald-regular-32.png b/core/assets/fonts/oswald/bm/oswald-regular-32.png new file mode 100644 index 0000000..289465e Binary files /dev/null and b/core/assets/fonts/oswald/bm/oswald-regular-32.png differ diff --git a/core/assets/fonts/oswald/bm/oswald-regular-48.fnt b/core/assets/fonts/oswald/bm/oswald-regular-48.fnt new file mode 100644 index 0000000..540ff86 --- /dev/null +++ b/core/assets/fonts/oswald/bm/oswald-regular-48.fnt @@ -0,0 +1,158 @@ +info face="Oswald Regular" size=48 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=1,1,1,1 spacing=-2,-2 +common lineHeight=66 base=53 scaleW=512 scaleH=512 pages=1 packed=0 +page id=0 file="oswald-regular-48.png" +chars count=96 +char id=10 x=0 y=0 width=0 height=0 xoffset=0 yoffset=0 xadvance=0 page=0 chnl=0 +char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=51 xadvance=11 page=0 chnl=0 +char id=33 x=0 y=92 width=8 height=41 xoffset=1 yoffset=12 xadvance=10 page=0 chnl=0 +char id=34 x=137 y=133 width=14 height=14 xoffset=3 yoffset=12 xadvance=18 page=0 chnl=0 +char id=35 x=107 y=92 width=22 height=41 xoffset=1 yoffset=12 xadvance=23 page=0 chnl=0 +char id=36 x=102 y=0 width=22 height=49 xoffset=1 yoffset=8 xadvance=23 page=0 chnl=0 +char id=37 x=66 y=92 width=41 height=41 xoffset=1 yoffset=12 xadvance=43 page=0 chnl=0 +char id=38 x=129 y=92 width=26 height=41 xoffset=2 yoffset=12 xadvance=29 page=0 chnl=0 +char id=39 x=151 y=133 width=7 height=14 xoffset=3 yoffset=12 xadvance=18 page=0 chnl=0 +char id=40 x=0 y=0 width=11 height=51 xoffset=3 yoffset=12 xadvance=14 page=0 chnl=0 +char id=41 x=11 y=0 width=13 height=51 xoffset=0 yoffset=12 xadvance=13 page=0 chnl=0 +char id=42 x=97 y=133 width=19 height=19 xoffset=1 yoffset=12 xadvance=19 page=0 chnl=0 +char id=43 x=77 y=133 width=20 height=21 xoffset=0 yoffset=22 xadvance=20 page=0 chnl=0 +char id=44 x=158 y=133 width=9 height=14 xoffset=0 yoffset=46 xadvance=9 page=0 chnl=0 +char id=45 x=224 y=133 width=13 height=6 xoffset=1 yoffset=35 xadvance=15 page=0 chnl=0 +char id=46 x=216 y=133 width=8 height=8 xoffset=1 yoffset=45 xadvance=9 page=0 chnl=0 +char id=47 x=30 y=92 width=18 height=41 xoffset=0 yoffset=12 xadvance=18 page=0 chnl=0 +char id=48 x=489 y=51 width=22 height=41 xoffset=1 yoffset=12 xadvance=23 page=0 chnl=0 +char id=49 x=493 y=0 width=15 height=41 xoffset=3 yoffset=12 xadvance=23 page=0 chnl=0 +char id=50 x=317 y=51 width=22 height=41 xoffset=1 yoffset=12 xadvance=23 page=0 chnl=0 +char id=51 x=339 y=51 width=22 height=41 xoffset=1 yoffset=12 xadvance=23 page=0 chnl=0 +char id=52 x=361 y=51 width=23 height=41 xoffset=1 yoffset=12 xadvance=23 page=0 chnl=0 +char id=53 x=384 y=51 width=21 height=41 xoffset=1 yoffset=12 xadvance=23 page=0 chnl=0 +char id=54 x=405 y=51 width=22 height=41 xoffset=2 yoffset=12 xadvance=24 page=0 chnl=0 +char id=55 x=427 y=51 width=18 height=41 xoffset=0 yoffset=12 xadvance=19 page=0 chnl=0 +char id=56 x=445 y=51 width=22 height=41 xoffset=1 yoffset=12 xadvance=23 page=0 chnl=0 +char id=57 x=467 y=51 width=22 height=41 xoffset=0 yoffset=12 xadvance=23 page=0 chnl=0 +char id=58 x=69 y=133 width=8 height=22 xoffset=2 yoffset=26 xadvance=10 page=0 chnl=0 +char id=59 x=276 y=92 width=9 height=31 xoffset=1 yoffset=24 xadvance=11 page=0 chnl=0 +char id=60 x=37 y=133 width=16 height=28 xoffset=0 yoffset=24 xadvance=17 page=0 chnl=0 +char id=61 x=167 y=133 width=17 height=14 xoffset=2 yoffset=26 xadvance=21 page=0 chnl=0 +char id=62 x=53 y=133 width=16 height=28 xoffset=2 yoffset=24 xadvance=18 page=0 chnl=0 +char id=63 x=8 y=92 width=22 height=41 xoffset=1 yoffset=12 xadvance=24 page=0 chnl=0 +char id=64 x=132 y=0 width=41 height=47 xoffset=2 yoffset=12 xadvance=44 page=0 chnl=0 +char id=65 x=185 y=0 width=25 height=41 xoffset=-1 yoffset=12 xadvance=24 page=0 chnl=0 +char id=66 x=210 y=0 width=23 height=41 xoffset=2 yoffset=12 xadvance=25 page=0 chnl=0 +char id=67 x=233 y=0 width=23 height=41 xoffset=1 yoffset=12 xadvance=24 page=0 chnl=0 +char id=68 x=256 y=0 width=22 height=41 xoffset=2 yoffset=12 xadvance=25 page=0 chnl=0 +char id=69 x=278 y=0 width=17 height=41 xoffset=2 yoffset=12 xadvance=19 page=0 chnl=0 +char id=70 x=295 y=0 width=17 height=41 xoffset=2 yoffset=12 xadvance=19 page=0 chnl=0 +char id=71 x=312 y=0 width=23 height=41 xoffset=1 yoffset=12 xadvance=26 page=0 chnl=0 +char id=72 x=335 y=0 width=23 height=41 xoffset=2 yoffset=12 xadvance=27 page=0 chnl=0 +char id=73 x=358 y=0 width=8 height=41 xoffset=2 yoffset=12 xadvance=11 page=0 chnl=0 +char id=74 x=366 y=0 width=14 height=41 xoffset=-1 yoffset=12 xadvance=14 page=0 chnl=0 +char id=75 x=380 y=0 width=23 height=41 xoffset=2 yoffset=12 xadvance=24 page=0 chnl=0 +char id=76 x=403 y=0 width=18 height=41 xoffset=2 yoffset=12 xadvance=19 page=0 chnl=0 +char id=77 x=421 y=0 width=27 height=41 xoffset=2 yoffset=12 xadvance=31 page=0 chnl=0 +char id=78 x=448 y=0 width=21 height=41 xoffset=2 yoffset=12 xadvance=25 page=0 chnl=0 +char id=79 x=469 y=0 width=24 height=41 xoffset=1 yoffset=12 xadvance=26 page=0 chnl=0 +char id=80 x=0 y=51 width=22 height=41 xoffset=2 yoffset=12 xadvance=23 page=0 chnl=0 +char id=81 x=78 y=0 width=24 height=49 xoffset=1 yoffset=12 xadvance=26 page=0 chnl=0 +char id=82 x=22 y=51 width=22 height=41 xoffset=2 yoffset=12 xadvance=25 page=0 chnl=0 +char id=83 x=44 y=51 width=22 height=41 xoffset=1 yoffset=12 xadvance=22 page=0 chnl=0 +char id=84 x=66 y=51 width=21 height=41 xoffset=-1 yoffset=12 xadvance=19 page=0 chnl=0 +char id=85 x=87 y=51 width=23 height=41 xoffset=2 yoffset=12 xadvance=27 page=0 chnl=0 +char id=86 x=110 y=51 width=25 height=41 xoffset=0 yoffset=12 xadvance=24 page=0 chnl=0 +char id=87 x=135 y=51 width=35 height=41 xoffset=0 yoffset=12 xadvance=35 page=0 chnl=0 +char id=88 x=170 y=51 width=25 height=41 xoffset=-1 yoffset=12 xadvance=23 page=0 chnl=0 +char id=89 x=195 y=51 width=25 height=41 xoffset=-1 yoffset=12 xadvance=23 page=0 chnl=0 +char id=90 x=220 y=51 width=19 height=41 xoffset=1 yoffset=12 xadvance=20 page=0 chnl=0 +char id=91 x=24 y=0 width=13 height=50 xoffset=2 yoffset=12 xadvance=16 page=0 chnl=0 +char id=92 x=48 y=92 width=18 height=41 xoffset=0 yoffset=12 xadvance=18 page=0 chnl=0 +char id=93 x=37 y=0 width=14 height=50 xoffset=0 yoffset=12 xadvance=15 page=0 chnl=0 +char id=94 x=116 y=133 width=21 height=18 xoffset=0 yoffset=12 xadvance=21 page=0 chnl=0 +char id=95 x=237 y=133 width=19 height=6 xoffset=-1 yoffset=53 xadvance=17 page=0 chnl=0 +char id=96 x=184 y=133 width=11 height=12 xoffset=1 yoffset=12 xadvance=13 page=0 chnl=0 +char id=97 x=285 y=92 width=19 height=30 xoffset=1 yoffset=23 xadvance=21 page=0 chnl=0 +char id=98 x=239 y=51 width=19 height=41 xoffset=2 yoffset=12 xadvance=22 page=0 chnl=0 +char id=99 x=304 y=92 width=18 height=30 xoffset=1 yoffset=23 xadvance=20 page=0 chnl=0 +char id=100 x=258 y=51 width=19 height=41 xoffset=1 yoffset=12 xadvance=21 page=0 chnl=0 +char id=101 x=322 y=92 width=19 height=30 xoffset=1 yoffset=23 xadvance=20 page=0 chnl=0 +char id=102 x=155 y=92 width=15 height=39 xoffset=0 yoffset=14 xadvance=15 page=0 chnl=0 +char id=103 x=170 y=92 width=24 height=39 xoffset=0 yoffset=22 xadvance=21 page=0 chnl=0 +char id=104 x=277 y=51 width=19 height=41 xoffset=2 yoffset=12 xadvance=22 page=0 chnl=0 +char id=105 x=194 y=92 width=8 height=39 xoffset=2 yoffset=14 xadvance=11 page=0 chnl=0 +char id=106 x=173 y=0 width=12 height=46 xoffset=-2 yoffset=14 xadvance=11 page=0 chnl=0 +char id=107 x=296 y=51 width=21 height=41 xoffset=2 yoffset=12 xadvance=21 page=0 chnl=0 +char id=108 x=358 y=0 width=8 height=41 xoffset=2 yoffset=12 xadvance=11 page=0 chnl=0 +char id=109 x=341 y=92 width=30 height=30 xoffset=2 yoffset=23 xadvance=33 page=0 chnl=0 +char id=110 x=371 y=92 width=18 height=30 xoffset=2 yoffset=23 xadvance=21 page=0 chnl=0 +char id=111 x=389 y=92 width=19 height=30 xoffset=1 yoffset=23 xadvance=20 page=0 chnl=0 +char id=112 x=202 y=92 width=19 height=39 xoffset=2 yoffset=23 xadvance=22 page=0 chnl=0 +char id=113 x=221 y=92 width=19 height=39 xoffset=1 yoffset=23 xadvance=21 page=0 chnl=0 +char id=114 x=408 y=92 width=14 height=30 xoffset=2 yoffset=23 xadvance=16 page=0 chnl=0 +char id=115 x=422 y=92 width=18 height=30 xoffset=0 yoffset=23 xadvance=18 page=0 chnl=0 +char id=116 x=240 y=92 width=15 height=38 xoffset=0 yoffset=15 xadvance=15 page=0 chnl=0 +char id=117 x=440 y=92 width=18 height=30 xoffset=1 yoffset=23 xadvance=21 page=0 chnl=0 +char id=118 x=458 y=92 width=20 height=30 xoffset=-1 yoffset=23 xadvance=18 page=0 chnl=0 +char id=119 x=478 y=92 width=28 height=30 xoffset=0 yoffset=23 xadvance=28 page=0 chnl=0 +char id=120 x=0 y=133 width=21 height=30 xoffset=-1 yoffset=23 xadvance=19 page=0 chnl=0 +char id=121 x=255 y=92 width=21 height=37 xoffset=-1 yoffset=23 xadvance=19 page=0 chnl=0 +char id=122 x=21 y=133 width=16 height=30 xoffset=1 yoffset=23 xadvance=17 page=0 chnl=0 +char id=123 x=51 y=0 width=14 height=50 xoffset=1 yoffset=12 xadvance=15 page=0 chnl=0 +char id=124 x=124 y=0 width=8 height=48 xoffset=2 yoffset=12 xadvance=12 page=0 chnl=0 +char id=125 x=65 y=0 width=13 height=50 xoffset=1 yoffset=12 xadvance=15 page=0 chnl=0 +char id=126 x=195 y=133 width=21 height=9 xoffset=0 yoffset=27 xadvance=21 page=0 chnl=0 +kernings count=57 +kerning first=68 second=44 amount=-1 +kerning first=70 second=46 amount=-2 +kerning first=86 second=65 amount=-1 +kerning first=80 second=74 amount=-1 +kerning first=76 second=86 amount=-1 +kerning first=89 second=113 amount=-1 +kerning first=68 second=46 amount=-1 +kerning first=76 second=119 amount=-1 +kerning first=68 second=86 amount=-1 +kerning first=69 second=103 amount=-1 +kerning first=76 second=89 amount=-1 +kerning first=80 second=65 amount=-2 +kerning first=65 second=84 amount=-2 +kerning first=102 second=46 amount=-1 +kerning first=76 second=84 amount=-1 +kerning first=84 second=111 amount=-1 +kerning first=75 second=99 amount=-1 +kerning first=70 second=115 amount=-1 +kerning first=68 second=65 amount=-1 +kerning first=76 second=87 amount=-1 +kerning first=89 second=101 amount=-1 +kerning first=87 second=111 amount=-1 +kerning first=76 second=115 amount=-1 +kerning first=70 second=114 amount=-1 +kerning first=89 second=115 amount=-1 +kerning first=86 second=115 amount=-1 +kerning first=65 second=87 amount=-1 +kerning first=80 second=46 amount=-4 +kerning first=75 second=115 amount=-1 +kerning first=99 second=106 amount=-1 +kerning first=89 second=65 amount=-1 +kerning first=87 second=97 amount=-1 +kerning first=84 second=99 amount=-1 +kerning first=102 second=102 amount=-1 +kerning first=89 second=44 amount=-1 +kerning first=70 second=103 amount=-1 +kerning first=89 second=111 amount=-1 +kerning first=87 second=101 amount=-1 +kerning first=70 second=65 amount=-1 +kerning first=84 second=97 amount=-1 +kerning first=70 second=44 amount=-2 +kerning first=69 second=115 amount=-1 +kerning first=76 second=103 amount=-1 +kerning first=89 second=46 amount=-1 +kerning first=112 second=106 amount=-1 +kerning first=86 second=111 amount=-1 +kerning first=101 second=106 amount=-1 +kerning first=87 second=65 amount=-1 +kerning first=80 second=44 amount=-4 +kerning first=65 second=86 amount=-1 +kerning first=75 second=103 amount=-1 +kerning first=98 second=106 amount=-1 +kerning first=89 second=97 amount=-1 +kerning first=65 second=89 amount=-1 +kerning first=84 second=101 amount=-1 +kerning first=89 second=103 amount=-1 +kerning first=89 second=99 amount=-1 diff --git a/core/assets/fonts/oswald/bm/oswald-regular-48.png b/core/assets/fonts/oswald/bm/oswald-regular-48.png new file mode 100644 index 0000000..0d84342 Binary files /dev/null and b/core/assets/fonts/oswald/bm/oswald-regular-48.png differ diff --git a/core/assets/fonts/oswald/bm/oswald-regular-64.fnt b/core/assets/fonts/oswald/bm/oswald-regular-64.fnt new file mode 100644 index 0000000..7f73958 --- /dev/null +++ b/core/assets/fonts/oswald/bm/oswald-regular-64.fnt @@ -0,0 +1,173 @@ +info face="Oswald Regular" size=64 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=1,1,1,1 spacing=-2,-2 +common lineHeight=88 base=70 scaleW=512 scaleH=512 pages=1 packed=0 +page id=0 file="oswald-regular-64.png" +chars count=96 +char id=10 x=0 y=0 width=0 height=0 xoffset=0 yoffset=0 xadvance=0 page=0 chnl=0 +char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=69 xadvance=15 page=0 chnl=0 +char id=33 x=403 y=127 width=9 height=55 xoffset=2 yoffset=16 xadvance=13 page=0 chnl=0 +char id=34 x=120 y=235 width=18 height=18 xoffset=4 yoffset=16 xadvance=24 page=0 chnl=0 +char id=35 x=458 y=127 width=29 height=55 xoffset=1 yoffset=16 xadvance=31 page=0 chnl=0 +char id=36 x=126 y=0 width=28 height=65 xoffset=2 yoffset=11 xadvance=32 page=0 chnl=0 +char id=37 x=0 y=70 width=54 height=57 xoffset=1 yoffset=15 xadvance=56 page=0 chnl=0 +char id=38 x=54 y=70 width=34 height=57 xoffset=3 yoffset=15 xadvance=39 page=0 chnl=0 +char id=39 x=138 y=235 width=9 height=18 xoffset=4 yoffset=16 xadvance=23 page=0 chnl=0 +char id=40 x=0 y=0 width=14 height=70 xoffset=4 yoffset=15 xadvance=19 page=0 chnl=0 +char id=41 x=14 y=0 width=15 height=70 xoffset=0 yoffset=15 xadvance=17 page=0 chnl=0 +char id=42 x=46 y=235 width=25 height=25 xoffset=1 yoffset=16 xadvance=25 page=0 chnl=0 +char id=43 x=21 y=235 width=25 height=28 xoffset=1 yoffset=29 xadvance=27 page=0 chnl=0 +char id=44 x=147 y=235 width=10 height=18 xoffset=1 yoffset=62 xadvance=12 page=0 chnl=0 +char id=45 x=207 y=235 width=16 height=8 xoffset=2 yoffset=46 xadvance=20 page=0 chnl=0 +char id=46 x=198 y=235 width=9 height=10 xoffset=2 yoffset=61 xadvance=12 page=0 chnl=0 +char id=47 x=412 y=127 width=23 height=55 xoffset=0 yoffset=16 xadvance=24 page=0 chnl=0 +char id=48 x=460 y=0 width=28 height=57 xoffset=2 yoffset=15 xadvance=32 page=0 chnl=0 +char id=49 x=332 y=127 width=18 height=55 xoffset=4 yoffset=16 xadvance=30 page=0 chnl=0 +char id=50 x=166 y=70 width=28 height=56 xoffset=2 yoffset=15 xadvance=31 page=0 chnl=0 +char id=51 x=348 y=0 width=28 height=57 xoffset=2 yoffset=15 xadvance=31 page=0 chnl=0 +char id=52 x=350 y=127 width=30 height=55 xoffset=2 yoffset=16 xadvance=32 page=0 chnl=0 +char id=53 x=194 y=70 width=27 height=56 xoffset=2 yoffset=16 xadvance=30 page=0 chnl=0 +char id=54 x=376 y=0 width=28 height=57 xoffset=2 yoffset=15 xadvance=31 page=0 chnl=0 +char id=55 x=380 y=127 width=23 height=55 xoffset=1 yoffset=16 xadvance=25 page=0 chnl=0 +char id=56 x=404 y=0 width=28 height=57 xoffset=2 yoffset=15 xadvance=31 page=0 chnl=0 +char id=57 x=432 y=0 width=28 height=57 xoffset=1 yoffset=15 xadvance=31 page=0 chnl=0 +char id=58 x=496 y=182 width=9 height=30 xoffset=3 yoffset=35 xadvance=13 page=0 chnl=0 +char id=59 x=252 y=182 width=10 height=42 xoffset=2 yoffset=32 xadvance=14 page=0 chnl=0 +char id=60 x=475 y=182 width=21 height=36 xoffset=1 yoffset=33 xadvance=24 page=0 chnl=0 +char id=61 x=98 y=235 width=22 height=19 xoffset=2 yoffset=34 xadvance=26 page=0 chnl=0 +char id=62 x=0 y=235 width=21 height=36 xoffset=3 yoffset=33 xadvance=24 page=0 chnl=0 +char id=63 x=221 y=70 width=29 height=56 xoffset=1 yoffset=15 xadvance=32 page=0 chnl=0 +char id=64 x=163 y=0 width=53 height=63 xoffset=3 yoffset=16 xadvance=58 page=0 chnl=0 +char id=65 x=250 y=70 width=32 height=55 xoffset=0 yoffset=16 xadvance=31 page=0 chnl=0 +char id=66 x=282 y=70 width=29 height=55 xoffset=3 yoffset=16 xadvance=33 page=0 chnl=0 +char id=67 x=231 y=0 width=29 height=57 xoffset=2 yoffset=15 xadvance=33 page=0 chnl=0 +char id=68 x=311 y=70 width=28 height=55 xoffset=3 yoffset=16 xadvance=33 page=0 chnl=0 +char id=69 x=339 y=70 width=22 height=55 xoffset=3 yoffset=16 xadvance=26 page=0 chnl=0 +char id=70 x=361 y=70 width=22 height=55 xoffset=3 yoffset=16 xadvance=25 page=0 chnl=0 +char id=71 x=260 y=0 width=30 height=57 xoffset=2 yoffset=15 xadvance=34 page=0 chnl=0 +char id=72 x=383 y=70 width=30 height=55 xoffset=3 yoffset=16 xadvance=36 page=0 chnl=0 +char id=73 x=413 y=70 width=9 height=55 xoffset=3 yoffset=16 xadvance=15 page=0 chnl=0 +char id=74 x=488 y=0 width=17 height=56 xoffset=-1 yoffset=16 xadvance=19 page=0 chnl=0 +char id=75 x=422 y=70 width=30 height=55 xoffset=3 yoffset=16 xadvance=31 page=0 chnl=0 +char id=76 x=452 y=70 width=23 height=55 xoffset=3 yoffset=16 xadvance=25 page=0 chnl=0 +char id=77 x=475 y=70 width=36 height=55 xoffset=3 yoffset=16 xadvance=42 page=0 chnl=0 +char id=78 x=0 y=127 width=28 height=55 xoffset=3 yoffset=16 xadvance=34 page=0 chnl=0 +char id=79 x=290 y=0 width=30 height=57 xoffset=2 yoffset=15 xadvance=34 page=0 chnl=0 +char id=80 x=28 y=127 width=28 height=55 xoffset=3 yoffset=16 xadvance=31 page=0 chnl=0 +char id=81 x=64 y=0 width=30 height=67 xoffset=2 yoffset=15 xadvance=34 page=0 chnl=0 +char id=82 x=56 y=127 width=29 height=55 xoffset=3 yoffset=16 xadvance=33 page=0 chnl=0 +char id=83 x=320 y=0 width=28 height=57 xoffset=2 yoffset=15 xadvance=31 page=0 chnl=0 +char id=84 x=85 y=127 width=28 height=55 xoffset=-1 yoffset=16 xadvance=26 page=0 chnl=0 +char id=85 x=88 y=70 width=30 height=56 xoffset=3 yoffset=16 xadvance=36 page=0 chnl=0 +char id=86 x=113 y=127 width=32 height=55 xoffset=0 yoffset=16 xadvance=32 page=0 chnl=0 +char id=87 x=145 y=127 width=45 height=55 xoffset=1 yoffset=16 xadvance=47 page=0 chnl=0 +char id=88 x=190 y=127 width=33 height=55 xoffset=-1 yoffset=16 xadvance=31 page=0 chnl=0 +char id=89 x=223 y=127 width=33 height=55 xoffset=-1 yoffset=16 xadvance=31 page=0 chnl=0 +char id=90 x=256 y=127 width=25 height=55 xoffset=1 yoffset=16 xadvance=26 page=0 chnl=0 +char id=91 x=94 y=0 width=16 height=67 xoffset=3 yoffset=16 xadvance=22 page=0 chnl=0 +char id=92 x=435 y=127 width=23 height=55 xoffset=0 yoffset=16 xadvance=24 page=0 chnl=0 +char id=93 x=110 y=0 width=16 height=67 xoffset=1 yoffset=16 xadvance=20 page=0 chnl=0 +char id=94 x=71 y=235 width=27 height=23 xoffset=1 yoffset=16 xadvance=28 page=0 chnl=0 +char id=95 x=223 y=235 width=24 height=8 xoffset=-1 yoffset=72 xadvance=22 page=0 chnl=0 +char id=96 x=157 y=235 width=14 height=15 xoffset=2 yoffset=16 xadvance=18 page=0 chnl=0 +char id=97 x=133 y=182 width=25 height=42 xoffset=2 yoffset=30 xadvance=28 page=0 chnl=0 +char id=98 x=118 y=70 width=24 height=56 xoffset=3 yoffset=16 xadvance=29 page=0 chnl=0 +char id=99 x=158 y=182 width=23 height=42 xoffset=2 yoffset=30 xadvance=27 page=0 chnl=0 +char id=100 x=142 y=70 width=24 height=56 xoffset=2 yoffset=16 xadvance=28 page=0 chnl=0 +char id=101 x=181 y=182 width=24 height=42 xoffset=2 yoffset=30 xadvance=28 page=0 chnl=0 +char id=102 x=487 y=127 width=19 height=53 xoffset=0 yoffset=18 xadvance=19 page=0 chnl=0 +char id=103 x=0 y=182 width=30 height=53 xoffset=0 yoffset=30 xadvance=28 page=0 chnl=0 +char id=104 x=281 y=127 width=24 height=55 xoffset=3 yoffset=16 xadvance=29 page=0 chnl=0 +char id=105 x=78 y=182 width=9 height=52 xoffset=3 yoffset=19 xadvance=15 page=0 chnl=0 +char id=106 x=216 y=0 width=15 height=62 xoffset=-3 yoffset=18 xadvance=14 page=0 chnl=0 +char id=107 x=305 y=127 width=27 height=55 xoffset=3 yoffset=16 xadvance=28 page=0 chnl=0 +char id=108 x=413 y=70 width=9 height=55 xoffset=3 yoffset=16 xadvance=15 page=0 chnl=0 +char id=109 x=262 y=182 width=38 height=41 xoffset=2 yoffset=30 xadvance=42 page=0 chnl=0 +char id=110 x=300 y=182 width=23 height=41 xoffset=2 yoffset=30 xadvance=27 page=0 chnl=0 +char id=111 x=205 y=182 width=24 height=42 xoffset=2 yoffset=30 xadvance=28 page=0 chnl=0 +char id=112 x=30 y=182 width=24 height=53 xoffset=2 yoffset=30 xadvance=28 page=0 chnl=0 +char id=113 x=54 y=182 width=24 height=53 xoffset=2 yoffset=30 xadvance=28 page=0 chnl=0 +char id=114 x=323 y=182 width=18 height=41 xoffset=3 yoffset=30 xadvance=21 page=0 chnl=0 +char id=115 x=229 y=182 width=23 height=42 xoffset=1 yoffset=30 xadvance=25 page=0 chnl=0 +char id=116 x=87 y=182 width=19 height=52 xoffset=0 yoffset=20 xadvance=20 page=0 chnl=0 +char id=117 x=341 y=182 width=23 height=41 xoffset=2 yoffset=31 xadvance=28 page=0 chnl=0 +char id=118 x=364 y=182 width=26 height=40 xoffset=-1 yoffset=31 xadvance=25 page=0 chnl=0 +char id=119 x=390 y=182 width=37 height=40 xoffset=0 yoffset=31 xadvance=38 page=0 chnl=0 +char id=120 x=427 y=182 width=27 height=40 xoffset=-1 yoffset=31 xadvance=25 page=0 chnl=0 +char id=121 x=106 y=182 width=27 height=49 xoffset=-1 yoffset=31 xadvance=25 page=0 chnl=0 +char id=122 x=454 y=182 width=21 height=40 xoffset=1 yoffset=31 xadvance=22 page=0 chnl=0 +char id=123 x=29 y=0 width=18 height=68 xoffset=1 yoffset=15 xadvance=19 page=0 chnl=0 +char id=124 x=154 y=0 width=9 height=64 xoffset=3 yoffset=16 xadvance=15 page=0 chnl=0 +char id=125 x=47 y=0 width=17 height=68 xoffset=2 yoffset=15 xadvance=21 page=0 chnl=0 +char id=126 x=171 y=235 width=27 height=11 xoffset=1 yoffset=36 xadvance=29 page=0 chnl=0 +kernings count=72 +kerning first=80 second=74 amount=-1 +kerning first=86 second=79 amount=-1 +kerning first=87 second=119 amount=-1 +kerning first=97 second=116 amount=-1 +kerning first=86 second=122 amount=-1 +kerning first=68 second=46 amount=-1 +kerning first=76 second=119 amount=-1 +kerning first=68 second=44 amount=-1 +kerning first=87 second=113 amount=-1 +kerning first=68 second=86 amount=-1 +kerning first=69 second=103 amount=-1 +kerning first=87 second=115 amount=-1 +kerning first=76 second=89 amount=-2 +kerning first=75 second=99 amount=-1 +kerning first=80 second=65 amount=-2 +kerning first=65 second=84 amount=-2 +kerning first=102 second=46 amount=-1 +kerning first=76 second=84 amount=-1 +kerning first=84 second=111 amount=-1 +kerning first=70 second=115 amount=-1 +kerning first=68 second=65 amount=-1 +kerning first=76 second=87 amount=-2 +kerning first=89 second=101 amount=-1 +kerning first=86 second=99 amount=-1 +kerning first=87 second=111 amount=-1 +kerning first=76 second=115 amount=-1 +kerning first=89 second=115 amount=-2 +kerning first=86 second=115 amount=-1 +kerning first=70 second=114 amount=-1 +kerning first=86 second=65 amount=-2 +kerning first=65 second=87 amount=-1 +kerning first=80 second=46 amount=-5 +kerning first=75 second=115 amount=-1 +kerning first=89 second=65 amount=-1 +kerning first=87 second=97 amount=-1 +kerning first=86 second=113 amount=-1 +kerning first=84 second=99 amount=-1 +kerning first=102 second=102 amount=-2 +kerning first=89 second=44 amount=-1 +kerning first=70 second=103 amount=-1 +kerning first=99 second=106 amount=-1 +kerning first=89 second=111 amount=-1 +kerning first=87 second=122 amount=-1 +kerning first=86 second=44 amount=-1 +kerning first=87 second=101 amount=-1 +kerning first=70 second=65 amount=-1 +kerning first=84 second=97 amount=-1 +kerning first=70 second=44 amount=-3 +kerning first=69 second=115 amount=-1 +kerning first=76 second=103 amount=-1 +kerning first=89 second=46 amount=-1 +kerning first=112 second=106 amount=-1 +kerning first=89 second=119 amount=-1 +kerning first=86 second=111 amount=-1 +kerning first=87 second=79 amount=-1 +kerning first=101 second=106 amount=-1 +kerning first=87 second=65 amount=-2 +kerning first=80 second=44 amount=-5 +kerning first=65 second=86 amount=-2 +kerning first=75 second=103 amount=-1 +kerning first=70 second=46 amount=-3 +kerning first=98 second=106 amount=-1 +kerning first=76 second=86 amount=-2 +kerning first=84 second=113 amount=-1 +kerning first=89 second=97 amount=-1 +kerning first=65 second=89 amount=-1 +kerning first=89 second=113 amount=-1 +kerning first=84 second=101 amount=-1 +kerning first=86 second=101 amount=-1 +kerning first=89 second=103 amount=-1 +kerning first=89 second=99 amount=-1 +kerning first=87 second=99 amount=-1 diff --git a/core/assets/fonts/oswald/bm/oswald-regular-64.png b/core/assets/fonts/oswald/bm/oswald-regular-64.png new file mode 100644 index 0000000..ac616d1 Binary files /dev/null and b/core/assets/fonts/oswald/bm/oswald-regular-64.png differ diff --git a/core/assets/green.bmp b/core/assets/green.bmp new file mode 100644 index 0000000..da1fe05 Binary files /dev/null and b/core/assets/green.bmp differ diff --git a/core/assets/keybg.png b/core/assets/keybg.png new file mode 100644 index 0000000..5d4dcba Binary files /dev/null and b/core/assets/keybg.png differ diff --git a/core/assets/keybg_pressed.png b/core/assets/keybg_pressed.png new file mode 100644 index 0000000..f9aca0a Binary files /dev/null and b/core/assets/keybg_pressed.png differ diff --git a/core/assets/layouts/dvorak_left_uk.kmp b/core/assets/layouts/dvorak_left_uk.kmp new file mode 100644 index 0000000..8b671ab --- /dev/null +++ b/core/assets/layouts/dvorak_left_uk.kmp @@ -0,0 +1,23 @@ +{ + "name" : "dvorak left uk", + "combinations" : [ + { + "combination" : "default", + "lines" : [ + ["`","[","]","/","p","f","m","l","j","4","3","2","1","!"], + [";","q","b","y","u","r","s","o",".","6","5","="], + ["-","k","c","d","t","h","e","a","z","8","7"], + ["\\","'","x","g","v","w","n","i",",","0","9"] + ] + }, + { + "combination" : "shift", + "lines" : [ + ["~","{","}","?","P","F","M","L","J","$","#","@","!"], + [":","Q","B","Y","U","R","S","O",">","^","%","+"], + ["_","K","C","D","T","H","E","A","Z","*","&"], + ["|","\"","X","G","V","W","N","I","<",")","("] + ] + } + ] +} \ No newline at end of file diff --git a/core/assets/layouts/dvorak_right_uk.kmp b/core/assets/layouts/dvorak_right_uk.kmp new file mode 100644 index 0000000..5490e10 --- /dev/null +++ b/core/assets/layouts/dvorak_right_uk.kmp @@ -0,0 +1,23 @@ +{ + "name" : "dvorak right uk", + "combinations" : [ + { + "combination" : "default", + "lines" : [ + ["`","1","2","3","4","j","l","m","f","p","/","[","]"], + ["5","6","q",".","o","r","s","u","y","b",";","="], + ["7","8","z","a","e","h","t","d","c","k","-"], + ["\\","9","0","x",",","i","n","w","v","g","'"] + ] + }, + { + "combination" : "shift", + "lines" : [ + ["~","!","@","#","$","J","L","M","F","P","?","{","}"], + ["%","^","Q",">","O","R","S","U","Y","B",":","+"], + ["&","*","Z","A","E","H","T","D","C","K","_"], + ["|","(",")","X","<","I","N","W","V","G","\""] + ] + } + ] +} \ No newline at end of file diff --git a/core/assets/layouts/dvorak_uk.kmp b/core/assets/layouts/dvorak_uk.kmp new file mode 100644 index 0000000..7d70284 --- /dev/null +++ b/core/assets/layouts/dvorak_uk.kmp @@ -0,0 +1,23 @@ +{ + "name" : "dvorak uk", + "combinations" : [ + { + "combination" : "default", + "lines" : [ + ["`","1","2","3","4","5","6","7","8","9","0","[","]"], + ["'",".",".","p","y","f","g","c","r","l","/","="], + ["a","o","e","u","i","d","h","t","n","s","-","#"], + ["\\",";","q","j","k","x","b","m","w","v","z"] + ] + }, + { + "combination" : "shift", + "lines" : [ + ["~","!","\"","£","$","%","^","&","*","(",")","{","}"], + ["@","<",">","P","Y","F","G","C","R","L","?","+"], + ["A","O","E","U","I","D","H","T","N","S","_","~"], + ["|",":","Q","J","K","X","B","M","W","V","Z"] + ] + } + ] +} \ No newline at end of file diff --git a/core/assets/layouts/qwerty_uk.kmp b/core/assets/layouts/qwerty_uk.kmp new file mode 100644 index 0000000..8bff5c8 --- /dev/null +++ b/core/assets/layouts/qwerty_uk.kmp @@ -0,0 +1,23 @@ +{ + "name" : "qwerty uk", + "combinations" : [ + { + "combination" : "default", + "lines" : [ + ["`","1","2","3","4","5","6","7","8","9","0","-","="], + ["q","w","e","r","t","y","u","i","o","p","[","]"], + ["a","s","d","f","g","h","j","k","l",";","'","#"], + ["\\","z","x","c","v","b","n","m",",",".","/"] + ] + }, + { + "combination" : "shift", + "lines" : [ + ["¬","!","\"","£","$","%","^","&","*","(",")","_","+"], + ["Q","W","E","R","T","Y","U","I","O","P","{","}"], + ["A","S","D","F","G","H","J","K","L",":","@","~"], + ["|","Z","X","C","V","B","N","M","<",">","?"] + ] + } + ] +} \ No newline at end of file diff --git a/core/assets/layouts/qwerty_uk_mirror.kmp b/core/assets/layouts/qwerty_uk_mirror.kmp new file mode 100644 index 0000000..b115c0b --- /dev/null +++ b/core/assets/layouts/qwerty_uk_mirror.kmp @@ -0,0 +1,41 @@ +{ + "name" : "qwerty mirror uk", + "combinations" : [ + { + "combination" : "default", + "lines" : [ + ["`","1","2","3","4","5","6","7","8","9","0","-","="], + ["q","w","e","r","t","y","u","i","o","p","[","]"], + ["a","s","d","f","g","h","j","k","l",";","'"], + ["\\","z","x","c","v","b","n","m",",",".","/"] + ] + }, + { + "combination" : "shift", + "lines" : [ + ["!","\"","£","$","%","^","&","*","(",")","_","+"], + ["Q","W","E","R","T","Y","U","I","O","P","{","}"], + ["A","S","D","F","G","H","J","K","L",":","@"], + ["|","Z","X","C","V","B","N","M","<",">","?"] + ] + }, + { + "combination" : "space", + "lines" : [ + ["=","-","0","9","8","7","6","5","4","3","2","1","`"], + ["p","o","i","u","y","t","r","e","w","q","[","]"], + [";","l","k","j","h","g","f","d","s","a","'","#"], + ["m","n","b","v","c","x","z",",",".","/"] + ] + }, + { + "combination" : "shift_space", + "lines" : [ + ["+","_",")","(","*","&","^","%","$","£","\"","!","¬"], + ["P","O","I","U","Y","T","R","E","W","Q","{","}"], + [":","L","K","J","H","G","F","D","S","A","@","~"], + ["<",">","?","M","N","B","V","C","X","Z"] + ] + } + ] +} \ No newline at end of file diff --git a/core/assets/pixels/black.png b/core/assets/pixels/black.png new file mode 100644 index 0000000..3cf27f4 Binary files /dev/null and b/core/assets/pixels/black.png differ diff --git a/core/assets/pixels/white.png b/core/assets/pixels/white.png new file mode 100644 index 0000000..818c71d Binary files /dev/null and b/core/assets/pixels/white.png differ diff --git a/core/assets/red.bmp b/core/assets/red.bmp new file mode 100644 index 0000000..818f399 Binary files /dev/null and b/core/assets/red.bmp differ diff --git a/core/assets/selectbg.png b/core/assets/selectbg.png new file mode 100644 index 0000000..a530f53 Binary files /dev/null and b/core/assets/selectbg.png differ diff --git a/core/assets/transbg.png b/core/assets/transbg.png new file mode 100644 index 0000000..e3a5925 Binary files /dev/null and b/core/assets/transbg.png differ diff --git a/core/assets/transbg.xcf b/core/assets/transbg.xcf new file mode 100644 index 0000000..3d8c644 Binary files /dev/null and b/core/assets/transbg.xcf differ diff --git a/core/build.gradle b/core/build.gradle new file mode 100644 index 0000000..13c049a --- /dev/null +++ b/core/build.gradle @@ -0,0 +1,11 @@ +apply plugin: "java" + +sourceCompatibility = 1.8 +[compileJava, compileTestJava]*.options*.encoding = 'UTF-8' + +sourceSets.main.java.srcDirs = [ "src/" ] + + +eclipse.project { + name = appName + "-core" +} diff --git a/core/src/ooo/george/qwas/Application.java b/core/src/ooo/george/qwas/Application.java new file mode 100644 index 0000000..bc0e57b --- /dev/null +++ b/core/src/ooo/george/qwas/Application.java @@ -0,0 +1,28 @@ +package ooo.george.qwas; + +import com.badlogic.gdx.Game; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import ooo.george.qwas.display.*; + +public class Application extends Game { + private SpriteBatch batch; + + @Override + public void create () { + Assets.initialise(this); + + this.setScreen(new WarningScreen()); + + batch = new SpriteBatch(); + } + + public void resize(int width, int height) { + super.resize(width, height); + } + + @Override + public void dispose() { + Assets.dispose(); + batch.dispose(); + } +} diff --git a/core/src/ooo/george/qwas/Assets.java b/core/src/ooo/george/qwas/Assets.java new file mode 100644 index 0000000..d634f9f --- /dev/null +++ b/core/src/ooo/george/qwas/Assets.java @@ -0,0 +1,177 @@ +package ooo.george.qwas; + +import com.badlogic.gdx.Application; +import com.badlogic.gdx.Game; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.BitmapFont; +import com.badlogic.gdx.graphics.g2d.NinePatch; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import ooo.george.qwas.display.ExerciseListUI; +import ooo.george.qwas.display.MainMenuScreen; +import ooo.george.qwas.display.MetricSummary; +import ooo.george.qwas.exercise.Exercise; +import ooo.george.qwas.exercise.ExerciseList; +import ooo.george.qwas.keyboard.Combination; +import ooo.george.qwas.keyboard.CombinationOR; +import ooo.george.qwas.keyboard.layout.LayoutList; +import ooo.george.qwas.metrics.Table; + +import java.util.HashMap; + +public class Assets { + public static Game game; + + public static Exercise currentExercise; + + public static Table metricsStorage; + + public static HashMap combinations; + + public static TextureRegionDrawable img_bg; + public static NinePatchDrawable trans_bg; + + public static TextureRegionDrawable img_red; + public static TextureRegionDrawable img_green; + public static TextureRegionDrawable img_blue; + public static TextureRegionDrawable img_charbg; + public static TextureRegionDrawable img_keybg; + public static TextureRegionDrawable img_keybg_pressed; + public static TextureRegionDrawable img_selectbg; + public static TextureRegionDrawable img_checkbox_ticked; + public static TextureRegionDrawable img_checkbox_unticked; + + public static BitmapFont oswald_regular_32; + public static BitmapFont oswald_regular_48; + public static BitmapFont oswald_regular_64; + public static BitmapFont oswald_regular_128; + public static BitmapFont oswald_regular_256; + + public static Skin blackpx; + public static TextureRegionDrawable img_blackpx; + + public static LayoutList layouts; + + public static KeyboardInputListener keyboard; + + public static ExerciseList exercises; + + public static ScrollPane.ScrollPaneStyle defaultScrollPaneStyle; + + public static ChangeListener setScreenMainMenu; + public static ChangeListener setScreenExerciseListUI; + public static ChangeListener setScreenMetricSummary; + + public static boolean initialised = false; + + public static void initialise(Game p_game) { + if (initialised) { + return; + } + + game = p_game; + + metricsStorage = new Table(Gdx.files.local("metrics/db.json")); + + // Freetype not compatible with WebGL, so bitmap fonts are used instead + if (Gdx.app.getType() == Application.ApplicationType.WebGL) { + oswald_regular_32 = new BitmapFont(Gdx.files.internal("fonts/oswald/bm/oswald-regular-32.fnt")); + oswald_regular_48 = new BitmapFont(Gdx.files.internal("fonts/oswald/bm/oswald-regular-48.fnt")); + oswald_regular_64 = new BitmapFont(Gdx.files.internal("fonts/oswald/bm/oswald-regular-64.fnt")); + oswald_regular_128 = new BitmapFont(Gdx.files.internal("fonts/oswald/bm/oswald-regular-128.fnt")); + oswald_regular_256 = new BitmapFont(Gdx.files.internal("fonts/oswald/bm/oswald-regular-256.fnt")); + } else { + FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/oswald/Oswald-Regular.ttf")); + //FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/OxygenMono-Regular.otf")); + FreeTypeFontGenerator.FreeTypeFontParameter fontParameters = new FreeTypeFontGenerator.FreeTypeFontParameter(); + fontParameters.genMipMaps = true; + fontParameters.kerning = true; + fontParameters.minFilter = Texture.TextureFilter.Linear; + fontParameters.magFilter = Texture.TextureFilter.Linear; + fontParameters.size = 32; + oswald_regular_32 = generator.generateFont(fontParameters); + fontParameters.size = 48; + oswald_regular_48 = generator.generateFont(fontParameters); + fontParameters.size = 64; + oswald_regular_64 = generator.generateFont(fontParameters); + fontParameters.size = 128; + oswald_regular_128 = generator.generateFont(fontParameters); + fontParameters.size = 256; + oswald_regular_256 = generator.generateFont(fontParameters); + oswald_regular_32.setUseIntegerPositions(false); + oswald_regular_48.setUseIntegerPositions(false); + oswald_regular_64.setUseIntegerPositions(false); + generator.dispose(); + } + + combinations = new HashMap<>(); + Combination shift = new CombinationOR(Input.Keys.SHIFT_LEFT, "shift", 2); + shift.add(new Combination(Input.Keys.SHIFT_RIGHT, 0)); + Combination shift_space = new Combination(Input.Keys.SPACE, "shift_space", 1); + shift_space.add(shift); + combinations.put("shift_space", shift_space); + combinations.put("shift", shift); + combinations.put("space", new Combination(Input.Keys.SPACE, "space", 3)); + + img_bg = new TextureRegionDrawable((new TextureRegion(new Texture("bg.png")))); + trans_bg = new NinePatchDrawable(new NinePatch(new Texture(Gdx.files.internal("transbg.png")), 4, 4, 4, 4)); + + img_red = new TextureRegionDrawable(new TextureRegion(new Texture("red.bmp"))); + img_green = new TextureRegionDrawable(new TextureRegion(new Texture("green.bmp"))); + img_blue = new TextureRegionDrawable(new TextureRegion(new Texture("blue.bmp"))); + img_charbg = new TextureRegionDrawable(new TextureRegion(new Texture("charbg.png"))); + img_keybg = new TextureRegionDrawable(new TextureRegion(new Texture("keybg.png"))); + img_keybg_pressed = new TextureRegionDrawable(new TextureRegion(new Texture("keybg_pressed.png"))); + img_selectbg = new TextureRegionDrawable(new TextureRegion(new Texture("selectbg.png"))); + img_checkbox_ticked = new TextureRegionDrawable(new TextureRegion(new Texture("checkbox_ticked.png"))); + img_checkbox_unticked = new TextureRegionDrawable(new TextureRegion(new Texture("checkbox_unticked.png"))); + + blackpx = new Skin(); + blackpx.add("bg", new NinePatch(new Texture(Gdx.files.internal("pixels/black.png")))); + img_blackpx = new TextureRegionDrawable(new TextureRegion(new Texture("pixels/black.png"))); + + layouts = new LayoutList(Gdx.files.local("layouts/")); + + keyboard = new KeyboardInputListener(layouts); + + exercises = new ExerciseList(Gdx.files.internal("exercises/")); + + defaultScrollPaneStyle = new ScrollPane.ScrollPaneStyle(); + defaultScrollPaneStyle.vScrollKnob = Assets.trans_bg; + + setScreenMainMenu = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + Assets.game.setScreen(new MainMenuScreen()); + } + }; + + setScreenExerciseListUI = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + Assets.game.setScreen(new ExerciseListUI(exercises)); + } + }; + + setScreenMetricSummary = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + Assets.game.setScreen(new MetricSummary()); + } + }; + + initialised = true; + } + + public static void dispose() { + metricsStorage.dispose(); + } +} diff --git a/core/src/ooo/george/qwas/Constants.java b/core/src/ooo/george/qwas/Constants.java new file mode 100644 index 0000000..7d6d485 --- /dev/null +++ b/core/src/ooo/george/qwas/Constants.java @@ -0,0 +1,6 @@ +package ooo.george.qwas; + +public class Constants { + public static boolean DEBUG_MODE = false; + public static final float SPACE_BETWEEN_BUTTONS = 10; +} diff --git a/core/src/ooo/george/qwas/Factory.java b/core/src/ooo/george/qwas/Factory.java new file mode 100644 index 0000000..e267530 --- /dev/null +++ b/core/src/ooo/george/qwas/Factory.java @@ -0,0 +1,46 @@ +package ooo.george.qwas; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; +import com.badlogic.gdx.utils.Align; + + +public class Factory { + public static TextButton createButton(String p_txt, TextureRegionDrawable p_up, TextureRegionDrawable p_down, ChangeListener p_listener) { + if (p_listener == null) { + p_listener = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + + } + }; + Log.debug("Inactive button created."); + } + + TextButton buttonToAdd; + TextButton.TextButtonStyle style = new TextButton.TextButtonStyle(p_up, p_down, null, Assets.oswald_regular_32); + style.fontColor = Color.BLACK; + + buttonToAdd = new TextButton(p_txt, style); + buttonToAdd.addListener(p_listener); + + return buttonToAdd; + } + + public static Table generateTitle(String p_titleText, ChangeListener p_screen, String p_backText) { + if (p_backText == null) { + p_backText = "Back"; + } + Table title = new Table(); + TextButton backButton = Factory.createButton(p_backText, Assets.img_blue, Assets.img_red, p_screen); + title.add(backButton).align(Align.left).left().top().pad(25); + title.add(new Label(p_titleText, new Label.LabelStyle(Assets.oswald_regular_128, Color.BLACK))).expandX().padRight(backButton.getWidth()); + + return title; + } +} diff --git a/core/src/ooo/george/qwas/KeyboardInputListener.java b/core/src/ooo/george/qwas/KeyboardInputListener.java new file mode 100644 index 0000000..4d8dcfc --- /dev/null +++ b/core/src/ooo/george/qwas/KeyboardInputListener.java @@ -0,0 +1,130 @@ +package ooo.george.qwas; + +import com.badlogic.gdx.Input; +import com.badlogic.gdx.InputProcessor; +import ooo.george.qwas.display.MainMenuScreen; +import ooo.george.qwas.keyboard.KeyPress; +import ooo.george.qwas.keyboard.Keyboard; +import ooo.george.qwas.keyboard.layout.Layout; +import ooo.george.qwas.keyboard.layout.LayoutList; + +import java.util.Hashtable; + +import static com.badlogic.gdx.Gdx.graphics; + +public class KeyboardInputListener implements InputProcessor { + private final Keyboard m_keyboard; + private boolean m_emulateKeyboard; + + public KeyboardInputListener(LayoutList p_layouts) { + //a_mousePos = a_camera.unproject(new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0)); + m_keyboard = new Keyboard(p_layouts); + m_emulateKeyboard = false; + } + + public Layout getTarget() { + return m_keyboard.getTarget(); + } + + public void setSource(String p_layout) { + m_keyboard.setSource(p_layout); + } + + public void setTarget(String p_layout) { + m_keyboard.setTarget(p_layout); + } + + public void setEmulateKeyboard(boolean p_input) { + m_emulateKeyboard = p_input; + } + + public Hashtable getPressedKeys() { + return m_keyboard.getPressedKeys(); + } + + @Override + public boolean keyDown(int keycode) { + if (keycode == Input.Keys.ESCAPE) { + Assets.game.setScreen(new MainMenuScreen()); + return true; + } else if (keycode == Input.Keys.F11) { + if (graphics.isFullscreen()) { + graphics.setWindowedMode(1366, 768); + } else { + graphics.setFullscreenMode(graphics.getDisplayMode()); + } + } else if (keycode == Input.Keys.F9) { + Constants.DEBUG_MODE = !Constants.DEBUG_MODE; + } + m_keyboard.keyDown(keycode); + return true; + } + + @Override + public boolean keyUp(int keycode) { + if (keycode == Input.Keys.SPACE) { + if (!m_keyboard.getKeyTyped() && m_keyboard.getTime(Input.Keys.SPACE) < 0.5) { + Assets.currentExercise.attempt(' '); + } + } + + m_keyboard.keyUp(keycode); + return true; + } + + @Override + public boolean keyTyped(char p_character) { + if (m_emulateKeyboard) { + char m_lastPressMapped = m_keyboard.keyTyped(p_character); + if (m_lastPressMapped == '\0') { + m_lastPressMapped = p_character; + } + if ((p_character > 31 && p_character < 166) || p_character == 8 || p_character == '\t') { + if(m_lastPressMapped != ' ') { + Assets.currentExercise.attempt(m_lastPressMapped); + return true; + } + } + } else { + if (p_character == '\0') { + return false; + } + if ((p_character > 31 && p_character < 166) || p_character == 8 || p_character == '\t') { + if(p_character != ' ') { + Assets.currentExercise.attempt(p_character); + } + } + return true; + } + return false; + } + + @Override + public boolean touchDown(int screenX, int screenY, int pointer, int button) { + return false; + } + + @Override + public boolean touchUp(int screenX, int screenY, int pointer, int button) { + return false; + } + + @Override + public boolean touchDragged(int screenX, int screenY, int pointer) { + return false; + } + + @Override + public boolean mouseMoved(int screenX, int screenY) { + return false; + } + + @Override + public boolean scrolled(int amount) { + return false; + } + + public void render() { + m_keyboard.render(); + } +} diff --git a/core/src/ooo/george/qwas/Log.java b/core/src/ooo/george/qwas/Log.java new file mode 100644 index 0000000..485ed31 --- /dev/null +++ b/core/src/ooo/george/qwas/Log.java @@ -0,0 +1,15 @@ +package ooo.george.qwas; + +import com.badlogic.gdx.Gdx; + +public class Log { + public static void debug(String p_message) { + Gdx.app.debug("", p_message); + } + public static void error(String p_message) { + Gdx.app.error("", p_message); + } + public static void warning(String p_message) { + Gdx.app.debug("Warning", p_message); + } +} diff --git a/core/src/ooo/george/qwas/display/EndScreen.java b/core/src/ooo/george/qwas/display/EndScreen.java new file mode 100644 index 0000000..7e29001 --- /dev/null +++ b/core/src/ooo/george/qwas/display/EndScreen.java @@ -0,0 +1,97 @@ +package ooo.george.qwas.display; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.Camera; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.badlogic.gdx.utils.viewport.Viewport; +import ooo.george.qwas.Assets; +import ooo.george.qwas.Factory; +import ooo.george.qwas.exercise.Exercise; + +class EndScreen implements Screen { + private final Viewport m_viewport; + private final Label.LabelStyle m_labelSkin; + private final Stage m_stage; + private final TextButton m_menuButton; + + public EndScreen(Exercise p_exercise) { + Camera m_camera = new OrthographicCamera(Gdx.graphics.getWidth(),Gdx.graphics.getHeight()); + m_viewport = new FitViewport(1920, 1080, m_camera); + m_camera.translate(m_camera.viewportWidth / 2, m_camera.viewportHeight / 2, 0); + + m_labelSkin = new Label.LabelStyle(Assets.oswald_regular_64, Color.BLACK); + m_stage = new Stage(m_viewport); + m_menuButton = Factory.createButton("Back", Assets.img_blue, Assets.img_red, Assets.setScreenMainMenu); + constructScreen(p_exercise); + } + + private void constructScreen(Exercise p_exercise) { + Table screen = new Table(); + screen.setFillParent(true); + Table attributes = new Table(); + + attributes.add(new Label("CPM:", m_labelSkin)).left(); + attributes.add(new Label(String.format("%.2f", p_exercise.charactersPerSecond()), m_labelSkin)).expandX(); + attributes.row(); + attributes.add(new Label("Accuracy:", m_labelSkin)).left().padRight(25); + attributes.add(new Label(String.format("%.2f%%", p_exercise.correctlyTypedPercent()), m_labelSkin)).expandX(); + + TextButton.TextButtonStyle logoStyle = new TextButton.TextButtonStyle(Assets.trans_bg, Assets.trans_bg, Assets.trans_bg, Assets.oswald_regular_128); + logoStyle.fontColor = Color.BLACK; + + screen.add(new TextButton(String.format("Exercise: \"%s\" complete!", p_exercise.getName()), logoStyle)).align(Align.center).pad(25); + screen.row(); + screen.add(attributes).fillY(); + screen.row(); + screen.add(m_menuButton); + + m_stage.addActor(screen); + } + + @Override + public void show() { + Gdx.input.setInputProcessor(m_stage); + } + + @Override + public void render(float delta) { + Gdx.gl.glClearColor(33/255.0f, 99/255.0f, 255/255.0f, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + m_stage.act(); + m_stage.draw(); + } + + @Override + public void resize(int width, int height) { + m_viewport.update(width, height, true); + } + + @Override + public void pause() { + + } + + @Override + public void resume() { + + } + + @Override + public void hide() { + + } + + @Override + public void dispose() { + m_stage.dispose(); + } +} diff --git a/core/src/ooo/george/qwas/display/ExerciseListUI.java b/core/src/ooo/george/qwas/display/ExerciseListUI.java new file mode 100644 index 0000000..2aad7ec --- /dev/null +++ b/core/src/ooo/george/qwas/display/ExerciseListUI.java @@ -0,0 +1,134 @@ +package ooo.george.qwas.display; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.Camera; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.badlogic.gdx.utils.viewport.Viewport; +import ooo.george.qwas.Assets; +import ooo.george.qwas.Constants; +import ooo.george.qwas.Factory; +import ooo.george.qwas.exercise.Exercise; +import ooo.george.qwas.exercise.ExerciseList; + +public class ExerciseListUI implements Screen { + private final Viewport m_viewport; + private final Stage m_stage; + private final Table m_list; + private final ExerciseList m_root; + private ExerciseList m_back; + + public ExerciseListUI(ExerciseList p_exercises) { + Camera m_camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + m_viewport = new FitViewport(1920, 1080, m_camera); + m_camera.translate(m_camera.viewportWidth / 2, m_camera.viewportHeight / 2, 0); + + Table m_screen = new Table(); + m_stage = new Stage(m_viewport); + m_list = new Table(); + m_root = p_exercises; + + ScrollPane m_scrollPane = new ScrollPane(m_list, Assets.defaultScrollPaneStyle); + + display(p_exercises); + + m_screen.setFillParent(true); + + m_screen.add(Factory.generateTitle("Choose an Exercise", Assets.setScreenMainMenu, "Main Menu")).expandX().fill(); + m_screen.row(); + m_screen.add(m_scrollPane).fill().expand(); + m_stage.addActor(m_screen); + } + + private void display(final ExerciseList p_exerciseList) { + m_list.reset(); + + final ExerciseList previous = m_back; + + if (p_exerciseList != m_root) { + ChangeListener goBack = backButton(previous); + TextButton currentButton = Factory.createButton("Back", Assets.img_blue, Assets.img_red, goBack); + m_list.add(currentButton).pad(Constants.SPACE_BETWEEN_BUTTONS); + m_list.row(); + } + m_back = p_exerciseList; + + for(int iii = 0; iii < p_exerciseList.dirCount(); iii++) { + final ExerciseList currentDir = p_exerciseList.getDir(iii); + ChangeListener changeExercise = backButton(currentDir); + String dirName = p_exerciseList.getDir(iii).getName(); + + TextButton currentButton = Factory.createButton(dirName, Assets.img_red, Assets.img_blue, changeExercise); + m_list.add(currentButton).pad(Constants.SPACE_BETWEEN_BUTTONS); + m_list.row(); + } + for (int iii = 0; iii < p_exerciseList.exerciseCount(); iii++) { + final Exercise currentExercise = p_exerciseList.getExercise(iii); + ChangeListener changeExercise = new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + Assets.currentExercise = currentExercise; + currentExercise.start(); + Assets.game.setScreen(new ExerciseUI(currentExercise, Assets.keyboard.getTarget())); + } + }; + String exerciseName = p_exerciseList.getExercise(iii).getShortenedName(10); + + TextButton currentButton = Factory.createButton(exerciseName, Assets.img_green, Assets.img_blue, changeExercise); + m_list.add(currentButton).pad(Constants.SPACE_BETWEEN_BUTTONS); + m_list.row(); + } + } + + private ChangeListener backButton(ExerciseList p_target) { + return new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + display(p_target); + } + }; + } + + @Override + public void show() { + Gdx.input.setInputProcessor(m_stage); + } + + @Override + public void render(float delta) { + Gdx.gl.glClearColor(33/255.0f, 99/255.0f, 255/255.0f, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + m_stage.act(); + m_stage.draw(); + } + + @Override + public void resize(int width, int height) { + m_viewport.update(width, height, true); + } + + @Override + public void pause() { + } + + @Override + public void resume() { + + } + + @Override + public void hide() { + + } + + @Override + public void dispose() { + m_stage.dispose(); + } +} diff --git a/core/src/ooo/george/qwas/display/ExerciseUI.java b/core/src/ooo/george/qwas/display/ExerciseUI.java new file mode 100644 index 0000000..0528a91 --- /dev/null +++ b/core/src/ooo/george/qwas/display/ExerciseUI.java @@ -0,0 +1,106 @@ +package ooo.george.qwas.display; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.Camera; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.badlogic.gdx.utils.viewport.Viewport; +import ooo.george.qwas.Assets; +import ooo.george.qwas.Constants; +import ooo.george.qwas.exercise.Exercise; +import ooo.george.qwas.keyboard.layout.Layout; + +class ExerciseUI implements Screen { + private final Viewport m_viewport; + private final Stage m_stage; + private final Exercise m_exercise; + private final WordDisplay m_wordDisplay; + private final KeyboardDisplay m_keyboardDisplay; + private final MetricBar m_metricDisplay; + + public ExerciseUI(Exercise p_exercise, Layout p_layout) { + Camera m_camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + m_viewport = new FitViewport(1920, 1080, m_camera); + m_camera.translate(m_camera.viewportWidth / 2, m_camera.viewportHeight / 2, 0); + + m_stage = new Stage(m_viewport); + m_exercise = p_exercise; + m_wordDisplay = new WordDisplay(); + m_keyboardDisplay = new KeyboardDisplay(m_exercise); + m_metricDisplay = new MetricBar(); + + Table m_screen = new Table(); + m_screen.setFillParent(true); + m_screen.setDebug(Constants.DEBUG_MODE); + m_stage.addActor(m_screen); + + m_screen.add(m_metricDisplay.getTable()).expandX(); + m_screen.row(); + + m_screen.add(m_wordDisplay.getContainer()).expand(); + + m_screen.row(); + + constructLayout(p_layout); + m_screen.add(m_keyboardDisplay.getTable()); + + m_stage.addActor(m_screen); + } + + private void constructLayout(Layout p_layout) { + m_keyboardDisplay.constructLayout(p_layout); + } + + @Override + public void show() { + // Todo: need to exit somehow other than esc... + Gdx.input.setInputProcessor(Assets.keyboard); + } + + @Override + public void render(float delta) { + Gdx.gl.glClearColor(33/255.0f, 99/255.0f, 255/255.0f, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + m_stage.act(); + m_stage.draw(); + + if (m_exercise.isComplete()) { + Assets.metricsStorage.addRecord(Assets.keyboard.getTarget(), m_exercise); + Assets.game.setScreen(new EndScreen(m_exercise)); + } + + Assets.keyboard.render(); + m_keyboardDisplay.render(); + m_wordDisplay.render(m_exercise.getRemainingCharacter()); + m_metricDisplay.updateMetricDisplay(m_exercise); + } + + @Override + public void resize(int width, int height) { + m_viewport.update(width, height, true); + } + + @Override + public void pause() { + + } + + @Override + public void resume() { + + } + + @Override + public void hide() { + + } + + @Override + public void dispose() { + m_stage.dispose(); + } +} \ No newline at end of file diff --git a/core/src/ooo/george/qwas/display/KeyboardDisplay.java b/core/src/ooo/george/qwas/display/KeyboardDisplay.java new file mode 100644 index 0000000..33f1a2b --- /dev/null +++ b/core/src/ooo/george/qwas/display/KeyboardDisplay.java @@ -0,0 +1,87 @@ +package ooo.george.qwas.display; + +import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import ooo.george.qwas.Assets; +import ooo.george.qwas.exercise.Exercise; +import ooo.george.qwas.keyboard.layout.Layout; + +import java.util.ArrayList; +import java.util.List; + +class KeyboardDisplay { + private final Exercise m_exercise; + private final List> m_keys; + private final Table m_keyboardArea; + private final TextButton.TextButtonStyle m_keyStyle; + private final TextButton.TextButtonStyle m_keyStylePressed; + private TextButton m_lastSetKey; + private Layout m_layout; + + public KeyboardDisplay(Exercise p_exercise) { + m_keys = new ArrayList<>(); + m_keyboardArea = new Table(); + m_keyStyle = new TextButton.TextButtonStyle(Assets.img_keybg, Assets.img_keybg, null, Assets.oswald_regular_32); + m_keyStylePressed = new TextButton.TextButtonStyle(Assets.img_keybg_pressed, Assets.img_keybg_pressed, null, Assets.oswald_regular_32); + m_exercise = p_exercise; + } + + public Table getTable() { + return m_keyboardArea; + } + + public void constructLayout(Layout p_layout) { + m_layout = p_layout; + m_keyboardArea.reset(); + + m_keys.clear(); + + for (int iii = 0; iii < m_layout.Rows(); iii++) { + m_keys.add(new ArrayList<>()); + for (int jjj = 0; jjj < m_layout.RowLength(iii); jjj++) { + String key = Character.toString(m_layout.getKey(iii, jjj, Assets.keyboard.getPressedKeys())); + m_keys.get(iii).add(new TextButton(key, m_keyStyle)); + } + } + + for (int iii = 0; iii < m_layout.Rows(); iii++) { + HorizontalGroup rowGroup = new HorizontalGroup(); + for (int jjj = 0; jjj < m_layout.RowLength(iii); jjj++) { + rowGroup.addActor(m_keys.get(iii).get(jjj)); + rowGroup.pad(2); + rowGroup.space(2); + } + switch (iii) { + case 1: + m_keyboardArea.add(rowGroup).left().padLeft(48 + 12); + break; + case 2: + m_keyboardArea.add(rowGroup).left().padLeft(48 + 24); + break; + case 3: + m_keyboardArea.add(rowGroup).left().padLeft(48); + break; + default: + m_keyboardArea.add(rowGroup).left(); + break; + } + m_keyboardArea.row(); + } + } + + public void render() { + constructLayout(m_layout); + char nextChar = m_exercise.getNextChar(); + if (m_lastSetKey != null) + m_lastSetKey.setStyle(m_keyStyle); + for (List column: m_keys) { + for (TextButton key: column) { + if (key.getText().charAt(0) == nextChar) { + key.setStyle(m_keyStylePressed); + m_lastSetKey = key; + } + } + } + } +} diff --git a/core/src/ooo/george/qwas/display/LayoutSwitcher.java b/core/src/ooo/george/qwas/display/LayoutSwitcher.java new file mode 100644 index 0000000..0209569 --- /dev/null +++ b/core/src/ooo/george/qwas/display/LayoutSwitcher.java @@ -0,0 +1,94 @@ +package ooo.george.qwas.display; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import ooo.george.qwas.Assets; + +class LayoutSwitcher { + private final HorizontalGroup m_container; + private SelectBox m_sourceLayoutSelect; + private SelectBox m_targetLayoutSelect; + private boolean m_emulateLayout; + private String m_source; + private String m_target; + + public LayoutSwitcher(HorizontalGroup p_container) { + m_container = p_container; + + m_emulateLayout = true; + + Assets.keyboard.setEmulateKeyboard(true); + + construct(); + } + + private void construct() { + m_container.clear(); + + final CheckBox.CheckBoxStyle checkBoxStyle = new CheckBox.CheckBoxStyle(Assets.img_checkbox_unticked, Assets.img_checkbox_ticked, Assets.oswald_regular_32, Color.WHITE); + CheckBox m_checkBox = new CheckBox(null, checkBoxStyle); + m_checkBox.setChecked(m_emulateLayout); + m_checkBox.addCaptureListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + m_emulateLayout = !m_emulateLayout; + Assets.keyboard.setEmulateKeyboard(m_emulateLayout); + construct(); + } + }); + + setDialogue(); + + m_container.addActor(new Label("Emulate layout:", new Label.LabelStyle(Assets.oswald_regular_32, Color.BLACK))); + m_container.space(20); + m_container.addActor(m_checkBox); + } + + private void setDialogue() { + ScrollPane.ScrollPaneStyle scrollStyle = new ScrollPane.ScrollPaneStyle(Assets.img_selectbg, Assets.img_selectbg, Assets.img_selectbg, Assets.img_selectbg, Assets.img_selectbg); + List.ListStyle listStyle = new List.ListStyle(Assets.oswald_regular_32, Color.WHITE, Color.WHITE, Assets.img_red); + SelectBox.SelectBoxStyle style = new SelectBox.SelectBoxStyle(Assets.oswald_regular_32, Color.WHITE, Assets.img_selectbg, scrollStyle, listStyle); + + m_container.addActor(new Label("I am using the:", new Label.LabelStyle(Assets.oswald_regular_32, Color.BLACK))); + m_sourceLayoutSelect = new SelectBox<>(style); + m_sourceLayoutSelect.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + m_source = m_sourceLayoutSelect.getSelected(); + Assets.keyboard.setSource(m_source); + if (!m_emulateLayout) { + Assets.keyboard.setTarget(m_source); + } + } + }); + if (m_source != null) { + m_sourceLayoutSelect.setSelected(m_source); + } + m_sourceLayoutSelect.setItems(Assets.layouts.getNames(true)); + + m_container.addActor(m_sourceLayoutSelect); + + if (m_emulateLayout) { + m_container.addActor(new Label("layout and want to emulate the: ", new Label.LabelStyle(Assets.oswald_regular_32, Color.BLACK))); + + m_targetLayoutSelect = new SelectBox<>(style); + m_targetLayoutSelect.addListener(new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + m_target = m_targetLayoutSelect.getSelected(); + Assets.keyboard.setTarget(m_target); + } + }); + if (m_target != null) { + m_targetLayoutSelect.setSelected(m_target); + } + m_targetLayoutSelect.setItems(Assets.layouts.getNames(false)); + + m_container.addActor(m_targetLayoutSelect); + } + + m_container.addActor(new Label("layout.", new Label.LabelStyle(Assets.oswald_regular_32, Color.BLACK))); + } +} diff --git a/core/src/ooo/george/qwas/display/MainMenuScreen.java b/core/src/ooo/george/qwas/display/MainMenuScreen.java new file mode 100644 index 0000000..b76e1e8 --- /dev/null +++ b/core/src/ooo/george/qwas/display/MainMenuScreen.java @@ -0,0 +1,95 @@ +package ooo.george.qwas.display; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.Camera; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.badlogic.gdx.utils.viewport.Viewport; +import ooo.george.qwas.*; + +public class MainMenuScreen implements Screen { + private final Viewport m_viewport; + private final Stage m_stage; + + public MainMenuScreen() { + Camera m_camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + m_viewport = new FitViewport(1920, 1080, m_camera); + m_camera.translate(m_camera.viewportWidth / 2, m_camera.viewportHeight / 2, 0); + + m_stage = new Stage(m_viewport); + + constructScreen(); + } + + private void constructScreen() { + m_stage.clear(); + Table screen = new Table(); + screen.setFillParent(true); + m_stage.addActor(screen); + + VerticalGroup mainButtons = new VerticalGroup(); + HorizontalGroup layoutSelect = new HorizontalGroup(); + layoutSelect.bottom(); + + TextButtonStyle logoStyle = new TextButtonStyle(Assets.trans_bg, Assets.trans_bg, Assets.trans_bg, Assets.oswald_regular_128); + logoStyle.fontColor = Color.BLACK; + + m_stage.addActor(screen); + + mainButtons.addActor(Factory.createButton("Exercise", Assets.img_green, Assets.img_blue, Assets.setScreenExerciseListUI)); + mainButtons.space(Constants.SPACE_BETWEEN_BUTTONS); + mainButtons.addActor(Factory.createButton("Progress", Assets.img_green, Assets.img_blue, Assets.setScreenMetricSummary)); + + LayoutSwitcher m_switcher = new LayoutSwitcher(layoutSelect); + + screen.add(new TextButton("QWAS", logoStyle).padLeft(25).padRight(25).padTop(10).padBottom(10)).align(Align.center).pad(25); + screen.row(); + screen.add(mainButtons).expandY(); + screen.row(); + screen.add(layoutSelect).expandX().right(); + } + + @Override + public void show() { + Gdx.input.setInputProcessor(m_stage); + } + + @Override + public void render(float delta) { + Gdx.gl.glClearColor(33/255.0f, 99/255.0f, 255/255.0f, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + m_stage.act(); + m_stage.draw(); + } + + @Override + public void resize(int width, int height) { + m_viewport.update(width, height, true); + } + + @Override + public void pause() { + } + + @Override + public void resume() { + + } + + @Override + public void hide() { + + } + + @Override + public void dispose() { + m_stage.dispose(); + } +} diff --git a/core/src/ooo/george/qwas/display/MetricBar.java b/core/src/ooo/george/qwas/display/MetricBar.java new file mode 100644 index 0000000..a39d7b4 --- /dev/null +++ b/core/src/ooo/george/qwas/display/MetricBar.java @@ -0,0 +1,52 @@ +package ooo.george.qwas.display; + +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import ooo.george.qwas.Assets; +import ooo.george.qwas.exercise.Exercise; + +class MetricBar { + private final Table m_metricsDisplay; + private final Label m_metricCpm; + private final Label m_metricCorrectlyTyped; + private final Label m_exerciseName; + private final Label m_progress; + + public MetricBar() { + m_metricsDisplay = new Table(); + + Label.LabelStyle buttonStyle = new Label.LabelStyle(Assets.oswald_regular_32, Color.WHITE); + m_metricsDisplay.setBackground(Assets.img_blackpx); + + m_metricCpm = new Label("", buttonStyle); + m_metricCorrectlyTyped = new Label("", buttonStyle); + m_progress = new Label("", buttonStyle); + m_exerciseName = new Label("", buttonStyle); + //updateMetricDisplay(null); + + m_metricsDisplay.add(m_metricCpm).prefWidth(Integer.MAX_VALUE); + m_metricsDisplay.add(m_metricCorrectlyTyped).prefWidth(Integer.MAX_VALUE); + m_metricsDisplay.add(m_exerciseName).prefWidth(Integer.MAX_VALUE); + m_metricsDisplay.add(m_progress).prefWidth(Integer.MAX_VALUE); + m_metricsDisplay.pad(-1); + } + + public void updateMetricDisplay(Exercise p_exercise) { + if (p_exercise == null) { + m_metricCpm.setText("NO EXERCISE!"); + m_metricCorrectlyTyped.setText(""); + m_exerciseName.setText(""); + m_progress.setText(""); + } else { + m_metricCpm.setText(String.format("CPS: %.1f", p_exercise.charactersPerSecond(System.currentTimeMillis()))); + m_metricCorrectlyTyped.setText(String.format("Correctly typed: %.1f%%", p_exercise.correctlyTypedPercent())); + m_exerciseName.setText(String.format("Exercise: %s", p_exercise.getName())); + m_progress.setText(String.format("Progress: %.2f%%", p_exercise.percentComplete())); + } + } + + public Table getTable() { + return m_metricsDisplay; + } +} diff --git a/core/src/ooo/george/qwas/display/MetricSummary.java b/core/src/ooo/george/qwas/display/MetricSummary.java new file mode 100644 index 0000000..0195820 --- /dev/null +++ b/core/src/ooo/george/qwas/display/MetricSummary.java @@ -0,0 +1,103 @@ +package ooo.george.qwas.display; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.*; +import com.badlogic.gdx.scenes.scene2d.Actor; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.badlogic.gdx.utils.viewport.Viewport; +import ooo.george.qwas.Assets; +import ooo.george.qwas.Factory; + +import java.time.Duration; +import java.time.Instant; + +public class MetricSummary implements Screen { + private final Viewport m_viewport; + private final Instant m_now; + private final Stage m_stage; + + public MetricSummary() { + Camera m_camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + m_viewport = new FitViewport(1920, 1080, m_camera); + m_camera.translate(m_camera.viewportWidth / 2, m_camera.viewportHeight / 2, 0); + + m_stage = new Stage(m_viewport); + m_now = Instant.now(); + + Label.LabelStyle defaultLabel = new Label.LabelStyle(Assets.oswald_regular_32, Color.BLACK); + + Table screen = new Table(); + + screen.setFillParent(true); + m_stage.addActor(screen); + + screen.add(Factory.generateTitle("Progress", Assets.setScreenMainMenu, null)).expandX().fill(); + screen.row(); + screen.add(createButtons()).expand().fill(); + } + + private Table createButtons() { + Table buttons = new Table(); + + buttons.add(createRangeButton("All time", Instant.MIN, Instant.MAX)).pad(10); + buttons.row(); + buttons.add(createRangeButton("This month", m_now.minus(Duration.ofDays(30)), m_now)).pad(10); + buttons.row(); + buttons.add(createRangeButton("Last month", m_now.minus(Duration.ofDays(60)), m_now.minus(Duration.ofDays(30)))).pad(10); + buttons.row(); + buttons.add(createRangeButton("2 months ago", m_now.minus(Duration.ofDays(90)), m_now.minus(Duration.ofDays(60)))).pad(10); + + return buttons; + } + + private TextButton createRangeButton(final String p_text, final Instant p_start, final Instant p_end) { + return Factory.createButton(p_text, Assets.img_green, Assets.img_blue, new ChangeListener() { + @Override + public void changed(ChangeEvent event, Actor actor) { + Assets.game.setScreen(new MetricSummaryRange(p_text, p_start, p_end)); + } + }); + } + + @Override + public void show() { + Gdx.input.setInputProcessor(m_stage); + } + + @Override + public void render(float delta) { + Gdx.gl.glClearColor(33/255.0f, 99/255.0f, 255/255.0f, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + m_stage.act(); + m_stage.draw(); + } + + @Override + public void resize(int width, int height) { + m_viewport.update(width, height, true); + } + + @Override + public void pause() { + + } + + @Override + public void resume() { + + } + + @Override + public void hide() { + + } + + @Override + public void dispose() { + m_stage.dispose(); + } +} diff --git a/core/src/ooo/george/qwas/display/MetricSummaryRange.java b/core/src/ooo/george/qwas/display/MetricSummaryRange.java new file mode 100644 index 0000000..7cec935 --- /dev/null +++ b/core/src/ooo/george/qwas/display/MetricSummaryRange.java @@ -0,0 +1,152 @@ +package ooo.george.qwas.display; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.graphics.Camera; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.*; +import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.badlogic.gdx.utils.viewport.Viewport; +import ooo.george.qwas.Assets; +import ooo.george.qwas.Factory; +import ooo.george.qwas.metrics.Record; + +import java.time.Instant; +import java.util.ArrayList; + +class MetricSummaryRange implements Screen { + private final Viewport m_viewport; + + private final Stage m_stage; + + private final Label.LabelStyle m_defaultLabelStyle; + + public MetricSummaryRange(String p_labelText, Instant p_start, Instant p_end) { + Camera m_camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + m_viewport = new FitViewport(1920, 1080, m_camera); + m_camera.translate(m_camera.viewportWidth / 2, m_camera.viewportHeight / 2, 0); + + m_defaultLabelStyle = new Label.LabelStyle(Assets.oswald_regular_48, Color.BLACK); + + ArrayList records = new ArrayList<>(); + + for(Record r: Assets.metricsStorage) { + if (r.getInstant().isAfter(p_start) && r.getInstant().isBefore(p_end)) { + records.add(r); + } + } + + m_stage = new Stage(m_viewport); + Table m_screen = new Table(); + m_screen.setFillParent(true); + + m_screen.add(Factory.generateTitle(p_labelText, Assets.setScreenMetricSummary, null)).expandX().fill(); + m_screen.row(); + + if (records.isEmpty()) { + m_screen.add(new Label("Insufficient data available.", new Label.LabelStyle(Assets.oswald_regular_128, Color.BLACK))).align(Align.center).expand(); + } else { + ScrollPane recordListPane = new ScrollPane(generateRecordList(records).align(Align.topLeft), Assets.defaultScrollPaneStyle); + + m_screen.add(new Label("Averages:", new Label.LabelStyle(Assets.oswald_regular_64, Color.BLACK))).align(Align.left); + m_screen.row(); + m_screen.add(getAverage(records)).align(Align.left); + m_screen.row(); + m_screen.add(new Label("Records:", new Label.LabelStyle(Assets.oswald_regular_64, Color.BLACK))).align(Align.left); + m_screen.row(); + m_screen.add(recordListPane).fill().expand(); + } + + m_stage.addActor(m_screen); + } + + private Table generateRecordList(ArrayList p_records) { + Table recordList = new Table(); + recordList.add(new Label("Exercise", m_defaultLabelStyle)).padRight(50).align(Align.left); + recordList.add(new Label("CPS", m_defaultLabelStyle)).padRight(50).align(Align.left); + recordList.add(new Label("Accuracy", m_defaultLabelStyle)).align(Align.left); + recordList.row(); + + for(Record r: p_records) { + getRecord(recordList, r); + recordList.row(); + } + + return recordList; + } + + private void getRecord(Table p_recordList, Record p_record) { + p_recordList.add(new Label(p_record.getShortenedName(8), m_defaultLabelStyle)).align(Align.left); + p_recordList.add(new Label(String.format("%.2f", p_record.getCharactersPerSecond()), m_defaultLabelStyle)).align(Align.left); + p_recordList.add(new Label(String.format("%.2f%%", p_record.getAccuracy()), m_defaultLabelStyle)).align(Align.left); + } + + private HorizontalGroup getAverage(ArrayList p_records) { + HorizontalGroup average = new HorizontalGroup(); + + float cpm = 0; + float accuracy = 0; + int count = 0; + + for(Record r: p_records) { + cpm += r.getCharactersPerSecond(); + accuracy += r.getAccuracy(); + count++; + } + + cpm /= count; + accuracy /= count; + + average.addActor(new Label("Characters typed per second:", m_defaultLabelStyle)); + average.space(50); + average.addActor(new Label(String.format("%.2f", cpm), m_defaultLabelStyle)); + average.space(50); + average.addActor(new Label("Accuracy:", m_defaultLabelStyle)); + average.space(50); + average.addActor(new Label(String.format("%.2f%%", accuracy), m_defaultLabelStyle)); + + return average; + } + + @Override + public void show() { + Gdx.input.setInputProcessor(m_stage); + } + + @Override + public void render(float delta) { + Gdx.gl.glClearColor(33/255.0f, 99/255.0f, 255/255.0f, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + m_stage.act(); + m_stage.draw(); + } + + @Override + public void resize(int width, int height) { + m_viewport.update(width, height, true); + } + + @Override + public void pause() { + + } + + @Override + public void resume() { + + } + + @Override + public void hide() { + + } + + @Override + public void dispose() { + m_stage.dispose(); + } +} diff --git a/core/src/ooo/george/qwas/display/WarningScreen.java b/core/src/ooo/george/qwas/display/WarningScreen.java new file mode 100644 index 0000000..93e7754 --- /dev/null +++ b/core/src/ooo/george/qwas/display/WarningScreen.java @@ -0,0 +1,91 @@ +package ooo.george.qwas.display; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Camera; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.OrthographicCamera; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.Screen; +import com.badlogic.gdx.scenes.scene2d.ui.Label; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.badlogic.gdx.utils.viewport.Viewport; +import ooo.george.qwas.Assets; +import ooo.george.qwas.Factory; + +public class WarningScreen implements Screen { + private final Viewport m_viewport; + private final Stage m_stage; + + public WarningScreen() { + Camera m_camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + m_viewport = new FitViewport(1920, 1080, m_camera); + m_camera.translate(m_camera.viewportWidth / 2, m_camera.viewportHeight / 2, 0); + + m_stage = new Stage(m_viewport); + + constructScreen(); + } + + private void constructScreen() { + m_stage.clear(); + Table screen = new Table(); + screen.setFillParent(true); + m_stage.addActor(screen); + + + TextButton.TextButtonStyle logoStyle = new TextButton.TextButtonStyle(Assets.trans_bg, Assets.trans_bg, Assets.trans_bg, Assets.oswald_regular_128); + logoStyle.fontColor = Color.BLACK; + Label.LabelStyle warningStyle = new Label.LabelStyle(Assets.oswald_regular_48, Color.BLACK); + final String warningMessage = String.join(System.getProperty("line.separator") + ,"Warning:" + ,"The use of certain keyboard layouts may cause muscle strain if care is not taken." + ,"Please move your hand to keys that are not reached comfortably, rather than stretching unnecessarily." + ); + + Label warningText = new Label(warningMessage, warningStyle); + + screen.add(warningText).expand(); + screen.row(); + screen.add(Factory.createButton("Okay", Assets.img_green, Assets.img_blue, Assets.setScreenMainMenu)).bottom(); + } + + @Override + public void show() { + Gdx.input.setInputProcessor(m_stage); + } + + @Override + public void render(float delta) { + Gdx.gl.glClearColor(33/255.0f, 99/255.0f, 255/255.0f, 1); + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + m_stage.act(); + m_stage.draw(); + } + + @Override + public void resize(int width, int height) { + m_viewport.update(width, height, true); + } + + @Override + public void pause() { + } + + @Override + public void resume() { + + } + + @Override + public void hide() { + + } + + @Override + public void dispose() { + m_stage.dispose(); + } +} diff --git a/core/src/ooo/george/qwas/display/WordDisplay.java b/core/src/ooo/george/qwas/display/WordDisplay.java new file mode 100644 index 0000000..d24805e --- /dev/null +++ b/core/src/ooo/george/qwas/display/WordDisplay.java @@ -0,0 +1,39 @@ +package ooo.george.qwas.display; + +import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.utils.Array; +import ooo.george.qwas.Assets; + +class WordDisplay { + private final HorizontalGroup m_typingArea; + private final Array m_buttons; + + public WordDisplay() { + m_typingArea = new HorizontalGroup(); + m_buttons = new Array<>(); + + for (int iii = 0; iii < 6; iii++) { + TextButton.TextButtonStyle style = new TextButton.TextButtonStyle(Assets.img_charbg, Assets.img_charbg, null, Assets.oswald_regular_48); + m_buttons.add(new TextButton("?", style)); + } + + for (int iii = 0; iii < m_buttons.size; iii++) { + m_typingArea.addActor(m_buttons.get(iii)); + } + } + + public HorizontalGroup getContainer() { + return m_typingArea; + } + + public void render(String p_textToDisplay) { + for (int iii = 0; iii < m_buttons.size; iii++) { + if (iii < p_textToDisplay.length()) { + m_buttons.get(iii).setText(Character.toString(p_textToDisplay.charAt(iii))); + } else { + m_buttons.get(iii).setText(""); + } + } + } +} diff --git a/core/src/ooo/george/qwas/exercise/Exercise.java b/core/src/ooo/george/qwas/exercise/Exercise.java new file mode 100644 index 0000000..db3ab87 --- /dev/null +++ b/core/src/ooo/george/qwas/exercise/Exercise.java @@ -0,0 +1,135 @@ +package ooo.george.qwas.exercise; + +import ooo.george.qwas.exercise.content.ExerciseContent; +import ooo.george.qwas.exercise.content.StringExerciseContent; + +public class Exercise { + private ExerciseContent m_content; + private String m_name; + private int m_totalTyped; + private int m_correct; + private long m_startTime; + private long m_finishedTime; + private boolean m_isComplete; + + private Exercise() { + m_totalTyped = 0; + m_correct = 0; + m_startTime = System.currentTimeMillis(); + m_finishedTime = -1; + m_isComplete = false; + } + + public Exercise(String p_name, String p_content) { + this(); + m_content = new StringExerciseContent(p_content); + m_name = p_name; + } + + public Exercise(String p_name, ExerciseContent p_exerciseContent) { + this(); + m_content = p_exerciseContent; + m_name = p_name; + } + + public void start() { + m_totalTyped = 0; + m_correct = 0; + m_startTime = System.currentTimeMillis(); + m_finishedTime = -1; + m_isComplete = false; + m_content.start(); + } + + public char getNextChar() { + return m_content.getNextCharacter(); + } + + public void attempt(char p_typed) { + m_totalTyped++; + boolean success = m_content.attempt(p_typed); + isComplete(); + + if (success) { + m_correct++; + } + } + + public String getName() { + return m_name; + } + + public String getShortenedName(int p_length) { + if (m_name.length() <= p_length) { + return m_name; + } else { + return m_name.substring(0, p_length) + "..."; + } + } + + private int getTotalCharacters() { + return m_content.length(); + } + + private int getRemainingCharacterCount() { + return m_content.remainingCharacters(); + } + + public String getRemainingCharacter() { + return m_content.getRemainingText(); + } + + public boolean isComplete() { + if (m_isComplete) { + return true; + } else { + if (m_content.completed()) { + if (m_finishedTime < 0) { + m_finishedTime = System.currentTimeMillis(); + } + m_isComplete = true; + return true; + } else { + return false; + } + } + } + + public float charactersPerSecond(long p_time) { + long millisecondsElapsed = (p_time - m_startTime); + float secondsElapsed = (float)millisecondsElapsed / 1000; + if (m_totalTyped > 0) { + return m_correct / secondsElapsed; + } else { + return 0; + } + } + + public float charactersPerSecond() { + return charactersPerSecond(m_finishedTime); + } + + private int correctTypeCount() { + return getTotalCharacters() - getRemainingCharacterCount(); + } + + public float correctlyTypedPercent() { + if (m_totalTyped < 1) { + return 100; + } + + return (float)correctTypeCount() / (float)m_totalTyped * 100f; + } + + public float percentComplete() { + float percentComplete = getTotalCharacters(); + percentComplete -= getRemainingCharacterCount(); + percentComplete /= getTotalCharacters(); + percentComplete *= 100; + return percentComplete; + } + + public long getFinishedTime() { + return m_finishedTime; + } +} diff --git a/core/src/ooo/george/qwas/exercise/ExerciseList.java b/core/src/ooo/george/qwas/exercise/ExerciseList.java new file mode 100644 index 0000000..ffc2683 --- /dev/null +++ b/core/src/ooo/george/qwas/exercise/ExerciseList.java @@ -0,0 +1,73 @@ +package ooo.george.qwas.exercise; + +import com.badlogic.gdx.files.FileHandle; +import ooo.george.qwas.Log; + +import java.util.ArrayList; +import java.util.List; + +public class ExerciseList { + private String m_name; + private List m_directories; + private List m_exercises; + + public ExerciseList(FileHandle p_path) { + Construct(p_path); + } + + private void Construct(FileHandle p_path) { + m_directories = new ArrayList<>(); + m_exercises = new ArrayList<>(); + m_name = p_path.nameWithoutExtension(); + + for(FileHandle f:p_path.list()) { + if (f.isDirectory()) { + m_directories.add(new ExerciseList(f)); + } else if (!addExercise(f)) { + Log.warning(String.format("Exercise creation fail: %s", f.name())); + } + } + } + + private boolean addExercise(FileHandle p_path) { + byte[] byteArray = p_path.readBytes(); + String exerciseContents; + try { + exerciseContents = new String(byteArray, "UTF-8"); + } catch (Exception e) { + return false; + } + m_exercises.add(new Exercise(p_path.nameWithoutExtension(), exerciseContents)); + return true; + } + + public int dirCount() { + return m_directories.size(); + } + + public int exerciseCount() { + return m_exercises.size(); + } + + public String getName(){ + return m_name; + } + + public Exercise getExercise(int p_index) { + if (p_index < m_exercises.size()) { + return m_exercises.get(p_index); + } else { + Log.warning("Exercise out of range"); + return null; + } + } + + public ExerciseList getDir(int p_index) { + if (p_index < m_directories.size()) { + return m_directories.get(p_index); + } else { + Log.warning("Directory out of range"); + return null; + } + } +} diff --git a/core/src/ooo/george/qwas/exercise/content/ExerciseContent.java b/core/src/ooo/george/qwas/exercise/content/ExerciseContent.java new file mode 100644 index 0000000..1ce93cd --- /dev/null +++ b/core/src/ooo/george/qwas/exercise/content/ExerciseContent.java @@ -0,0 +1,17 @@ +package ooo.george.qwas.exercise.content; + +public interface ExerciseContent { + String getRemainingText(); + + int length(); + + char getNextCharacter(); + + int remainingCharacters(); + + boolean attempt(char p_attempt); + + boolean completed(); + + boolean start(); +} diff --git a/core/src/ooo/george/qwas/exercise/content/StringExerciseContent.java b/core/src/ooo/george/qwas/exercise/content/StringExerciseContent.java new file mode 100644 index 0000000..8546ca6 --- /dev/null +++ b/core/src/ooo/george/qwas/exercise/content/StringExerciseContent.java @@ -0,0 +1,59 @@ +package ooo.george.qwas.exercise.content; + +public class StringExerciseContent implements ExerciseContent{ + private final String m_content; + private int m_position; + + public StringExerciseContent(String p_text) { + m_content = p_text.replace('\n', ' '); + m_position = 0; + } + + private boolean initialised() { + return !(m_content == null || m_content.equals(" ")); + } + + public boolean start() { + m_position = 0; + return initialised(); + } + + public boolean attempt(char p_attempt) { + if (remainingCharacters() < 1) + return false; + if (p_attempt != m_content.charAt(m_position)) { + return false; + } else { + m_position++; + return true; + } + } + + public boolean completed() { + return remainingCharacters() < 1; + } + + public char getNextCharacter() { + if (m_position >= m_content.length()) { + return '\0'; + } else { + return m_content.charAt(m_position); + } + } + + public int length() { + return m_content.length(); + } + + public String getRemainingText() { + if (m_position >= m_content.length()) { + return ""; + } else { + return m_content.substring(m_position); + } + } + + public int remainingCharacters() { + return length() - m_position; + } +} diff --git a/core/src/ooo/george/qwas/file/File.java b/core/src/ooo/george/qwas/file/File.java new file mode 100644 index 0000000..eaf1ba0 --- /dev/null +++ b/core/src/ooo/george/qwas/file/File.java @@ -0,0 +1,62 @@ +package ooo.george.qwas.file; +import com.badlogic.gdx.files.FileHandle; +import java.util.ArrayList; +import java.util.List; + +public class File{ + private String m_name; + private String m_fileContents; + private List m_contents; + + public File(FileHandle p_path) { + Construct(p_path); + } + + private void Construct(FileHandle p_path) { + m_contents = new ArrayList<>(); + + if (p_path.isDirectory()) { + for (int iii = 0; iii < p_path.list().length; iii++) { + addFile(new File(p_path.list()[iii])); + } + } else { + byte[] byteArray = p_path.readBytes(); + try { + this.m_fileContents = new String(byteArray, "UTF-8"); + } catch (Exception e) { + this.m_fileContents= "[Invalid file]"; + } + this.m_name = p_path.nameWithoutExtension(); + } + } + + private void addFile(File p_file) { + m_contents.add(p_file); + } + + public String getFileContents() { + return m_fileContents; + } + + private boolean isDirectory() { + return m_fileContents == null && m_contents != null; + } + + public String getName(){ + return m_name; + } + + public List getFileList() { + List returnList = new ArrayList<>(); + + for (File f: m_contents) { + if (f.isDirectory()) { + returnList.addAll(f.getFileList()); + } else { + returnList.add(f); + } + } + + return returnList; + } +} diff --git a/core/src/ooo/george/qwas/keyboard/Combination.java b/core/src/ooo/george/qwas/keyboard/Combination.java new file mode 100644 index 0000000..2fa32fe --- /dev/null +++ b/core/src/ooo/george/qwas/keyboard/Combination.java @@ -0,0 +1,67 @@ +package ooo.george.qwas.keyboard; + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +public class Combination { + int m_key; + final List m_keys; + private String m_name; + private final int m_priority; + + Combination(int p_priority) { + m_keys = new ArrayList<>(); + m_priority = p_priority; + } + + public Combination(int p_key, int p_priority) { + this(p_priority); + m_key = p_key; + } + + Combination(Combination p_combination, int p_priority) { + this(p_priority); + add(p_combination); + } + + public Combination(int p_key, String p_name, int p_priority) { + this(p_priority); + m_key = p_key; + m_name = p_name; + } + + Combination(Combination p_combination, String p_name, int p_priority) { + this(p_priority); + add(p_combination); + m_name = p_name; + } + + public List getKeys() { + return m_keys; + } + + public int getPriority() { + return m_priority; + } + + public void add(Combination p_key){ + if (!m_keys.contains(p_key)) { + m_keys.add(p_key); + } + } + + public boolean evaluate(Hashtable p_keys) { + if (p_keys.get(m_key) == null || !p_keys.get(m_key).isPressed()) { + return false; + } + + for (Combination o: m_keys) { + if (!o.evaluate(p_keys)) { + return false; + } + } + + return true; + } +} diff --git a/core/src/ooo/george/qwas/keyboard/CombinationOR.java b/core/src/ooo/george/qwas/keyboard/CombinationOR.java new file mode 100644 index 0000000..cace028 --- /dev/null +++ b/core/src/ooo/george/qwas/keyboard/CombinationOR.java @@ -0,0 +1,40 @@ +package ooo.george.qwas.keyboard; + +import java.util.Hashtable; + +public class CombinationOR extends Combination { + public CombinationOR(int p_priority) { + super(p_priority); + } + + public CombinationOR(int p_int, int p_priority) { + super(p_int); + } + + public CombinationOR(Combination p_combination, int p_priority) { + super(p_combination, p_priority); + } + + public CombinationOR(int p_int, String p_name, int p_priority) { + super(p_int, p_name, p_priority); + } + + public CombinationOR(Combination p_combination, String p_name, int p_priority) { + super(p_combination,p_name, p_priority); + } + + @Override + public boolean evaluate(Hashtable p_keys) { + if (p_keys.get(m_key) != null && p_keys.get(m_key).isPressed()) { + return true; + } + + for (Combination o: m_keys) { + if (o.evaluate(p_keys)) { + return true; + } + } + + return false; + } +} diff --git a/core/src/ooo/george/qwas/keyboard/KeyPress.java b/core/src/ooo/george/qwas/keyboard/KeyPress.java new file mode 100644 index 0000000..201b7b9 --- /dev/null +++ b/core/src/ooo/george/qwas/keyboard/KeyPress.java @@ -0,0 +1,32 @@ +package ooo.george.qwas.keyboard; + +public class KeyPress { + private boolean m_pressed; + private double m_time; + + public KeyPress() { + m_pressed = true; + m_time = 0; + } + + public void reset() { + m_pressed = false; + m_time = 0; + } + + public boolean isPressed() { + return m_pressed; + } + + public double getTime() { + return m_time; + } + + public void increment(double p_delta) { + m_time += p_delta; + } + + public void press() { + m_pressed = true; + } +} diff --git a/core/src/ooo/george/qwas/keyboard/Keyboard.java b/core/src/ooo/george/qwas/keyboard/Keyboard.java new file mode 100644 index 0000000..396e114 --- /dev/null +++ b/core/src/ooo/george/qwas/keyboard/Keyboard.java @@ -0,0 +1,116 @@ +package ooo.george.qwas.keyboard; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; +import com.badlogic.gdx.math.Vector2; +import ooo.george.qwas.keyboard.layout.Layout; +import ooo.george.qwas.keyboard.layout.LayoutList; + +import java.util.Hashtable; +import java.util.Set; + +public class Keyboard { + private final Hashtable m_keys; + private Layout m_source; + private Layout m_target; + private LayoutList m_layouts; + private boolean m_keyTyped; + + private Keyboard() { + m_keys = new Hashtable<>(256); + m_keyTyped = false; + } + + public Keyboard(LayoutList p_layouts) { + this(); + m_layouts = p_layouts; + this.m_source = p_layouts.get("qwerty_uk"); + this.m_target = p_layouts.get("dvorak_uk"); + + m_keys.put(Input.Keys.SPACE, new KeyPress()); + m_keys.put(Input.Keys.SHIFT_LEFT, new KeyPress()); + m_keys.put(Input.Keys.SHIFT_RIGHT, new KeyPress()); + m_keys.get(Input.Keys.SPACE).reset(); + m_keys.get(Input.Keys.SHIFT_LEFT).reset(); + m_keys.get(Input.Keys.SHIFT_RIGHT).reset(); + } + + public void setSource(String p_name) { + Layout newLayout = m_layouts.get(p_name); + if (newLayout != null) { + m_source = newLayout; + } + } + + public void setTarget(String p_name) { + Layout newLayout = m_layouts.get(p_name); + if (newLayout != null) { + m_target = newLayout; + } + } + + public Hashtable getPressedKeys() { + return m_keys; + } + + /** + * Map character from source to target layout + * @param p_value source key value + * @return char Returns corresponding layout key value. Returns empty char \0 if not found or out of bounds + */ + public char keyTyped(char p_value) { + if (m_keys.get(Input.Keys.SPACE).isPressed() && p_value != ' ') { + m_keyTyped = true; + } + Vector2 position = m_source.getPosition(p_value); + if (position == null) { + return '\0'; + } + return m_target.getKey((int)position.x, (int)position.y, m_keys); + } + + public void keyDown(int p_keycode) { + if (!m_keys.containsKey(p_keycode)) { + m_keys.put(p_keycode, new KeyPress()); + } else { + m_keys.get(p_keycode).press(); + } + } + + public void keyUp(int p_keycode) { + if (m_keys.containsKey(p_keycode)) { + m_keys.get(p_keycode).reset(); + } + } + + public double getTime(int keyCode) { + if (m_keys.containsKey(keyCode)) { + return m_keys.get(keyCode).getTime(); + } else { + return -1; + } + } + + public boolean getKeyTyped() { + boolean returnValue = m_keyTyped; + m_keyTyped = false; + return returnValue; + } + + private void incrementPresses() { + Set keys = m_keys.keySet(); + for(Integer k: keys) { + if (m_keys.get(k).isPressed()) { + m_keys.get(k).increment(Gdx.graphics.getDeltaTime()); + } + } + } + + public Layout getTarget() { + return m_target; + } + + public void render() { + incrementPresses(); + } +} diff --git a/core/src/ooo/george/qwas/keyboard/key/HashKey.java b/core/src/ooo/george/qwas/keyboard/key/HashKey.java new file mode 100644 index 0000000..e6fcd2c --- /dev/null +++ b/core/src/ooo/george/qwas/keyboard/key/HashKey.java @@ -0,0 +1,44 @@ +package ooo.george.qwas.keyboard.key; + +import ooo.george.qwas.keyboard.Combination; + +import java.util.HashMap; +import java.util.Map; + +public class HashKey implements Key{ + private final char m_default; + private final HashMap m_values; + + public HashKey(char p_value) { + m_values = new HashMap<>(); + m_default = p_value; + } + + public void addKey(Combination p_key, char p_value) { + if (!m_values.containsKey(p_key)) { + m_values.put(p_key, p_value); + } + } + + public char getKey() { + return m_default; + } + + public char getKey(Combination p_modifier) { + return m_values.get(p_modifier); + } + + public boolean contains(char p_value) { + if (m_default == p_value) { + return true; + } + + for (Map.Entry entry: m_values.entrySet()) { + if (p_value == entry.getValue()) { + return true; + } + } + + return false; + } +} diff --git a/core/src/ooo/george/qwas/keyboard/key/Key.java b/core/src/ooo/george/qwas/keyboard/key/Key.java new file mode 100644 index 0000000..57161eb --- /dev/null +++ b/core/src/ooo/george/qwas/keyboard/key/Key.java @@ -0,0 +1,14 @@ +package ooo.george.qwas.keyboard.key; + +import ooo.george.qwas.keyboard.Combination; + +public interface Key { + + char getKey(); + + char getKey(Combination p_modifier); + + boolean contains(char p_value); + + void addKey(Combination p_key, char p_value); +} diff --git a/core/src/ooo/george/qwas/keyboard/layout/FlatLayout.java b/core/src/ooo/george/qwas/keyboard/layout/FlatLayout.java new file mode 100644 index 0000000..ba1af64 --- /dev/null +++ b/core/src/ooo/george/qwas/keyboard/layout/FlatLayout.java @@ -0,0 +1,198 @@ +/*package ooo.george.qwas.keyboard; + +import com.badlogic.gdx.math.Vector2; +import ooo.george.qwas.Assets; +import ooo.george.qwas.Constants; + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +public class FlatLayout implements Layout{ + private Key m_keys[][]; + private List m_combinations; + private boolean m_shift; + private boolean m_space; + private String m_name; + public boolean m_valid; + + public FlatLayout(String p_fileContents, String p_name) { + m_combinations = new ArrayList<>(); + m_valid = true; + m_shift = false; + m_space = false; + m_name = p_name; + m_valid = buildLayout(p_fileContents); + } + + private boolean buildLayout(String p_fileContents) { + if (p_fileContents == null || p_fileContents == "") { + return false; + } + + + + String[] lines = p_fileContents.split(Constants.LINE_DELIMITER); + for (String string: lines) { + if (string.toLowerCase().startsWith("shift")) { + m_shift = true; + } else if (string.toLowerCase().startsWith("mirror")) + m_space = true; + } + + return setKeys(lines); + } + + private boolean setKeys(String[] p_lines) { + if (!setArraySize(p_lines)) { + Constants.debugMessage = "setArraySize failed"; + return false; + } + + for (int iii = 0; iii < m_keys.length; iii++) { + String[] lowerLine = p_lines[iii].split(Constants.KEY_DELIMITER); + String[] upperLine = {""}; + String[] spaceLine = {""}; + + if (m_shift) { + addCombination(Assets.combinations.get("shift")); + upperLine = p_lines[iii + 5].split(Constants.KEY_DELIMITER); + if (lowerLine.length != upperLine.length) { + return false; + } + } + if (m_space) { + addCombination(Assets.combinations.get("space")); + spaceLine = p_lines[iii + 10].split(Constants.KEY_DELIMITER); + if (lowerLine.length != spaceLine.length) { + return false; + } + } + + for (int jjj = 0; jjj < lowerLine.length; jjj++) + try { + Key newKey; + newKey = new HashKey(stringToChar(lowerLine[jjj])); + + if (m_space) { + newKey.addKey(Assets.combinations.get("space"), stringToChar(spaceLine[jjj])); + } + if (m_shift) { + newKey.addKey(Assets.combinations.get("shift"), stringToChar(upperLine[jjj])); + } + m_keys[iii][jjj] = newKey; + } catch (Exception e) { + return false; + } + } + return true; + } + + private boolean setArraySize(String[] p_lines) { + int x = 0, y = 0; + + for (int iii = 0; iii < p_lines.length; iii++) { + + if (p_lines[iii].equals("") && x == 0) { + x = iii; + } + + int keyCount = p_lines[iii].split(Constants.KEY_DELIMITER).length; + + if (keyCount> y) { + y = keyCount; + } + } + + this.m_keys = new Key[x][y]; + + if (x > 0 && y > 0) { + return true; + } else { + return false; + } + } + + public boolean addCombination(Combination p_combination) { + if (m_combinations.contains(p_combination)) + return false; + else + return m_combinations.add(p_combination); + } + + private char stringToChar(String p_value) throws Exception { + if (p_value.length() == 1) { + return p_value.toCharArray()[0]; + } else if (p_value.toLowerCase().equals("comma")) { + return ','; + } else { + throw new Exception("Unrecognised string in layout file."); + } + } + + public char getKey(int x, int y, Hashtable p_keys) { + if (outOfBounds(x, y)) { + return '\0'; + } else { + Key key = m_keys[x][y]; + + for (Combination c: m_combinations) { + if (c.evaluate(p_keys)) { + return key.getKey(c); + } + } + + return key.getKey(); + } + } + + private boolean outOfBounds(int x, int y) { + if (x > m_keys.length - 1 || y > m_keys[x].length - 1) { + return true; + } else { + if (m_keys[x][y] == null) { + return true; + } else { + return false; + } + } + } + + public Vector2 getPosition(char p_key) { + for (int iii = 0; iii < m_keys.length; iii++) { + for (int jjj = 0; jjj < m_keys[iii].length; jjj++) { + if (m_keys[iii][jjj] == null) + break; + if (m_keys[iii][jjj].contains(p_key)) + return new Vector2(iii, jjj); + } + } + return null; + } + + public int Rows() { + return m_keys.length; + } + + public int RowLength(int p_row) { + if (p_row >= Rows() || p_row < 0) { + return -1; + } else { + int count = 0; + + for (Key key: m_keys[p_row]) { + if (key == null) { + return count; + } else { + count++; + } + } + return count; + } + } + + public String getName() { + return m_name; + } +} +*/ \ No newline at end of file diff --git a/core/src/ooo/george/qwas/keyboard/layout/JSONLayout.java b/core/src/ooo/george/qwas/keyboard/layout/JSONLayout.java new file mode 100644 index 0000000..3dab177 --- /dev/null +++ b/core/src/ooo/george/qwas/keyboard/layout/JSONLayout.java @@ -0,0 +1,148 @@ +package ooo.george.qwas.keyboard.layout; + +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.utils.Json; +import ooo.george.qwas.Assets; +import ooo.george.qwas.Log; +import ooo.george.qwas.keyboard.Combination; +import ooo.george.qwas.keyboard.KeyPress; +import ooo.george.qwas.keyboard.key.Key; +import ooo.george.qwas.keyboard.layout.json.layout; + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +public class JSONLayout implements Layout{ + private Key m_keys[][]; + private final List m_combinations; + private final String m_name; + + public JSONLayout(String p_fileContents, String p_name) { + m_combinations = new ArrayList<>(); + m_name = p_name; + boolean m_valid = buildLayout(p_fileContents); + } + + private boolean buildLayout(String p_fileContents) { + if (p_fileContents == null || p_fileContents.equals("")) { + return false; + } + + Json json = new Json(); + + layout layout = json.fromJson(ooo.george.qwas.keyboard.layout.json.layout.class, p_fileContents); + + if (!layout.valid()) { + Log.warning("Invalid layout: " + m_name); + return false; + } + + this.m_keys = new Key[layout.lineCount()][layout.maxCharacters()]; + + constructArray(layout); + + String[] combinationNames = layout.getCombinations(); + + for (String s: combinationNames) { + if (Assets.combinations.containsKey(s)) + addCombination(Assets.combinations.get(s)); + } + + return true; + } + + private void constructArray(layout p_layout) { + for (int iii = 0; iii < p_layout.lineCount(); iii++) { + for (int jjj = 0; p_layout.getKey(jjj, iii) != null; jjj++) { + m_keys[iii][jjj] = p_layout.getKey(jjj, iii); + } + } + } + + public boolean addCombination(Combination p_combination) { + return !m_combinations.contains(p_combination) && m_combinations.add(p_combination); + } + + private char stringToChar(String p_value) throws Exception { + if (p_value.length() == 1) { + return p_value.toCharArray()[0]; + } else if (p_value.toLowerCase().equals("comma")) { + return ','; + } else { + throw new Exception("Unrecognised string in layout file."); + } + } + + public char getKey(int x, int y, Hashtable p_keys) { + //KeyPress pp = new KeyPress(); + //pp.press(); + //p_keys.put(Input.Keys.SHIFT_LEFT, pp); + if (outOfBounds(x, y)) { + return '\0'; + } else { + Key key = m_keys[x][y]; + + Combination currentCombination = checkCombinations(p_keys); + + if (currentCombination != null) { + return key.getKey(currentCombination); + } else { + return key.getKey(); + } + } + } + + private Combination checkCombinations(Hashtable p_keys) { + int currentPriority = Integer.MAX_VALUE; + Combination currentCombination = null; + for (Combination c: m_combinations) { + if (c.evaluate(p_keys) && c.getPriority() < currentPriority) { + currentPriority = c.getPriority(); + currentCombination = c; + } + } + return currentCombination; + } + + private boolean outOfBounds(int x, int y) { + return x > m_keys.length - 1 || y > m_keys[x].length - 1 || m_keys[x][y] == null; + } + + public Vector2 getPosition(char p_key) { + for (int iii = 0; iii < m_keys.length; iii++) { + for (int jjj = 0; jjj < m_keys[iii].length; jjj++) { + if (m_keys[iii][jjj] == null) + break; + if (m_keys[iii][jjj].contains(p_key)) + return new Vector2(iii, jjj); + } + } + return null; + } + + public int Rows() { + return m_keys.length; + } + + public int RowLength(int p_row) { + if (p_row >= Rows() || p_row < 0) { + return -1; + } else { + int count = 0; + + for (Key key: m_keys[p_row]) { + if (key == null) { + return count; + } else { + count++; + } + } + return count; + } + } + + public String getName() { + return m_name; + } +} diff --git a/core/src/ooo/george/qwas/keyboard/layout/Layout.java b/core/src/ooo/george/qwas/keyboard/layout/Layout.java new file mode 100644 index 0000000..1ce8f92 --- /dev/null +++ b/core/src/ooo/george/qwas/keyboard/layout/Layout.java @@ -0,0 +1,22 @@ +package ooo.george.qwas.keyboard.layout; + +import com.badlogic.gdx.math.Vector2; +import ooo.george.qwas.keyboard.Combination; +import ooo.george.qwas.keyboard.KeyPress; + +import java.util.Hashtable; + +public interface Layout { + + char getKey(int x, int y, Hashtable p_keys); + + Vector2 getPosition(char p_key); + + int Rows(); + + int RowLength(int p_row); + + String getName(); + + boolean addCombination(Combination p_combination); +} diff --git a/core/src/ooo/george/qwas/keyboard/layout/LayoutList.java b/core/src/ooo/george/qwas/keyboard/layout/LayoutList.java new file mode 100644 index 0000000..269b3cc --- /dev/null +++ b/core/src/ooo/george/qwas/keyboard/layout/LayoutList.java @@ -0,0 +1,59 @@ +package ooo.george.qwas.keyboard.layout; + +import com.badlogic.gdx.files.FileHandle; +import ooo.george.qwas.file.File; + +import java.util.ArrayList; +import java.util.List; + +public class LayoutList { + private final List m_layouts; + + private int Count() { + return m_layouts.size(); + } + + private Layout getLayout(int p_index) { + return m_layouts.get(p_index); + } + + public LayoutList(FileHandle p_path) { + m_layouts = new ArrayList<>(); + + File files = new File(p_path); + + List fileList = files.getFileList(); + + for (File f: fileList) { + m_layouts.add(new JSONLayout(f.getFileContents(), f.getName())); + } + } + + public Layout get(String p_name) { + for (Layout l:m_layouts) { + if (l.getName().equals(p_name)) + return l; + } + return null; + } + + public String[] getNames(boolean p_skip){ + if (p_skip) { + String[] names = new String[Count() - 1]; + int actual = 0; + for (int iii = 0; iii < Count(); iii++) { + if (!getLayout(iii).getName().equals("qwerty_uk_mirror")) { + names[actual] = getLayout(iii).getName(); + actual++; + } + } + return names; + } else { + String[] names = new String[Count()]; + for (int iii = 0; iii < Count(); iii++) { + names[iii] = getLayout(iii).getName(); + } + return names; + } + } +} \ No newline at end of file diff --git a/core/src/ooo/george/qwas/keyboard/layout/json/combination.java b/core/src/ooo/george/qwas/keyboard/layout/json/combination.java new file mode 100644 index 0000000..4d482fa --- /dev/null +++ b/core/src/ooo/george/qwas/keyboard/layout/json/combination.java @@ -0,0 +1,45 @@ +package ooo.george.qwas.keyboard.layout.json; + +import ooo.george.qwas.Log; + +import java.util.ArrayList; + +class combination { + String combination; + ArrayList> lines; + + public int lineCount() { + return lines.size(); + } + + public boolean valid() { + return !(combination == null || combination.equals("") || lines == null || lines.size() < 1); + } + + public ArrayList getLine(int p_index) { + if (p_index >= lines.size()) { + return null; + } else { + return lines.get(p_index); + } + } + + public int maxLineLength() { + int size = 0; + for (ArrayList line : lines) { + if (line.size() > size) { + size = line.size(); + } + } + return size; + } + + public char getChar(int x, int y) { + if (y >= lines.size() || x >= lines.get(y).size()) { + Log.warning("Character index out of range"); + return '\0'; + } else { + return lines.get(y).get(x).charAt(0); + } + } +} diff --git a/core/src/ooo/george/qwas/keyboard/layout/json/layout.java b/core/src/ooo/george/qwas/keyboard/layout/json/layout.java new file mode 100644 index 0000000..8894e0f --- /dev/null +++ b/core/src/ooo/george/qwas/keyboard/layout/json/layout.java @@ -0,0 +1,80 @@ +package ooo.george.qwas.keyboard.layout.json; + +import java.util.ArrayList; + +import ooo.george.qwas.Assets; +import ooo.george.qwas.Log; +import ooo.george.qwas.keyboard.key.HashKey; +import ooo.george.qwas.keyboard.key.Key; + +public class layout { + private String name; + private ArrayList combinations; + + public String getName() { + return name; + } + + public boolean valid() { + if (combinations == null || combinations.size() < 1) { + return false; + } + + int charCount = combinations.get(0).lines.get(0).size(); + + int size = combinations.get(0).lineCount(); + for(combination m: combinations) { + if (!m.valid()) { + return false; + } + if (m.lineCount() != size) { + Log.warning("Size mismatch in combination: " + name + ", line: " + m.combination); + return false; + } + } + return true; + } + + public String[] getCombinations() { + String[] combinationNames = new String[combinations.size()]; + + for(int iii = 0; iii < combinationNames.length; iii++) { + combinationNames[iii] = combinations.get(iii).combination; + } + + return combinationNames; + } + + public int lineCount() { + return combinations.get(0).lineCount(); + } + + public int maxCharacters(){ + int size = 0; + for(combination c: combinations) + { + if (c.maxLineLength() > size) + size = c.maxLineLength(); + } + return combinations.get(0).maxLineLength(); + } + + public Key getKey(int x, int y) { + char defaultKey = '\0'; + for(combination c: combinations) { + if (c.combination.equals("default")) + defaultKey = c.getChar(x, y); + } + Key newKey = new HashKey(defaultKey); + + for(combination c: combinations) { + if (Assets.combinations.containsKey(c.combination) && !c.combination.equals("default")) + newKey.addKey(Assets.combinations.get((c.combination)), c.getChar(x, y)); + } + + if (newKey.contains('\0')) + return null; + else + return newKey; + } +} diff --git a/core/src/ooo/george/qwas/metrics/Record.java b/core/src/ooo/george/qwas/metrics/Record.java new file mode 100644 index 0000000..348a48d --- /dev/null +++ b/core/src/ooo/george/qwas/metrics/Record.java @@ -0,0 +1,80 @@ +package ooo.george.qwas.metrics; + +import com.badlogic.gdx.utils.Json; +import com.badlogic.gdx.utils.JsonValue; +import ooo.george.qwas.Log; +import ooo.george.qwas.keyboard.layout.Layout; + +import java.time.Instant; + +public class Record implements Json.Serializable { + private String m_keyboardLayout; + private float m_cpm; + private float m_accuracy; + private String m_name; + private Instant m_timeStamp; + + public Record(){} + + public Record(Layout p_keyboardLayout, float p_cpm, String p_exerciseName, float p_pcCorrectlyTyped) { + m_keyboardLayout = p_keyboardLayout.getName(); + m_cpm = p_cpm; + m_accuracy = p_pcCorrectlyTyped; + m_name = p_exerciseName; + m_timeStamp = Instant.now(); + } + + public String parse() { + Json json = new Json(); + return json.prettyPrint(this); + } + + public void write (Json json) { + json.writeValue("keyboardLayout", m_keyboardLayout); + json.writeValue("cpm", m_cpm); + json.writeValue("pcCorrectlyTyped", m_accuracy); + json.writeValue("exerciseName", m_name); + json.writeValue("date", m_timeStamp.toString()); + } + + public void read (Json json, JsonValue jsonMap) { + m_keyboardLayout = jsonMap.get("keyboardLayout").asString(); + m_cpm = jsonMap.get("cpm").asFloat(); + m_accuracy = jsonMap.get("pcCorrectlyTyped").asFloat(); + m_name = jsonMap.get("exerciseName").asString(); + try { + m_timeStamp = Instant.parse(jsonMap.get("date").asString()); + } catch (Exception e) { + Log.error(String.format("Exception [%s] encountered while creating record from Json", e.getLocalizedMessage())); + m_timeStamp = Instant.now(); + } + } + + public String getName() { + return m_name; + } + + public String getShortenedName(int p_length) { + if (m_name.length() <= p_length) { + return m_name; + } else { + return m_name.substring(0, p_length) + "..."; + } + } + + public float getCharactersPerSecond() { + return m_cpm; + } + + public float getAccuracy() { + return m_accuracy; + } + + public String getTimeStamp() { + return m_timeStamp.toString(); + } + + public Instant getInstant() { + return m_timeStamp; + } +} diff --git a/core/src/ooo/george/qwas/metrics/Table.java b/core/src/ooo/george/qwas/metrics/Table.java new file mode 100644 index 0000000..99d390f --- /dev/null +++ b/core/src/ooo/george/qwas/metrics/Table.java @@ -0,0 +1,80 @@ +package ooo.george.qwas.metrics; + +import com.badlogic.gdx.files.FileHandle; +import com.badlogic.gdx.utils.Json; +import com.badlogic.gdx.utils.JsonReader; +import com.badlogic.gdx.utils.JsonValue; +import ooo.george.qwas.Log; +import ooo.george.qwas.exercise.Exercise; +import ooo.george.qwas.keyboard.layout.Layout; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class Table implements Iterable, Json.Serializable { + private List m_records; + private FileHandle m_location; + + public Table() { + m_records = new ArrayList<>(); + } + + public Table(FileHandle p_location) { + m_records = new ArrayList<>(); + m_location = p_location; + + if (m_location.exists()) { + Json jsonObject = new Json(); + JsonValue jsonValue = new JsonReader().parse(m_location.readString()); + try { + this.read(jsonObject, jsonValue); + } catch (Exception e ) { + // Todo: restore from backup if exists + Log.error(String.format("Read failed: %s", m_location.name())); + } + } + } + + public void addRecord(Layout p_keyboardLayout, Exercise p_exercise) { + Record newRecord = new Record(p_keyboardLayout, + p_exercise.charactersPerSecond(p_exercise.getFinishedTime()), + p_exercise.getName(), p_exercise.correctlyTypedPercent()); + if (m_records.add(newRecord)) { + saveToFile(); + } else { + Log.warning(String.format("Record add failed. %s", newRecord.getName() == null ? "[NO NAME]" : newRecord.getName())); + } + } + + private String getJson() { + Json json = new Json(); + return json.prettyPrint(this); + } + + public void read(Json p_json, JsonValue p_jsonMap){ + m_records = new ArrayList<>(); + for (JsonValue f: p_jsonMap.child()) { + Record c = new Record(); + c.read(p_json, f); + m_records.add(c); + } + } + + public void write(Json p_json) { + p_json.writeValue("records", m_records); + } + + private void saveToFile() { + m_location.writeString(this.getJson(), false); + } + + @Override + public Iterator iterator() { + return m_records.iterator(); + } + + public void dispose() { + saveToFile(); + } +} diff --git a/desktop/build.gradle b/desktop/build.gradle new file mode 100644 index 0000000..6b9fdf4 --- /dev/null +++ b/desktop/build.gradle @@ -0,0 +1,46 @@ +apply plugin: "java" + +sourceCompatibility = 1.8 +sourceSets.main.java.srcDirs = [ "src/" ] + +project.ext.mainClassName = "ooo.george.qwas.desktop.DesktopLauncher" +project.ext.assetsDir = new File("../core/assets") + +task run(dependsOn: classes, type: JavaExec) { + main = project.mainClassName + classpath = sourceSets.main.runtimeClasspath + standardInput = System.in + workingDir = project.assetsDir + ignoreExitValue = true +} + +task dist(type: Jar) { + from files(sourceSets.main.output.classesDir) + from files(sourceSets.main.output.resourcesDir) + from {configurations.compile.collect {zipTree(it)}} + from files(project.assetsDir) + + manifest { + attributes 'Main-Class': project.mainClassName + } +} + +dist.dependsOn classes + +eclipse { + project { + name = appName + "-desktop" + linkedResource name: 'assets', type: '2', location: 'PARENT-1-PROJECT_LOC/core/assets' + } +} + +task afterEclipseImport(description: "Post processing after project generation", group: "IDE") { + doLast { + def classpath = new XmlParser().parse(file(".classpath")) + new Node(classpath, "classpathentry", [ kind: 'src', path: 'assets' ]) + def writer = new FileWriter(file(".classpath")) + def printer = new XmlNodePrinter(new PrintWriter(writer)) + printer.setPreserveWhitespace(true) + printer.print(classpath) + } +} \ No newline at end of file diff --git a/desktop/src/ooo/george/qwas/desktop/DesktopLauncher.java b/desktop/src/ooo/george/qwas/desktop/DesktopLauncher.java new file mode 100644 index 0000000..67eb04a --- /dev/null +++ b/desktop/src/ooo/george/qwas/desktop/DesktopLauncher.java @@ -0,0 +1,17 @@ +package ooo.george.qwas.desktop; + +import com.badlogic.gdx.backends.lwjgl.LwjglApplication; +import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; +import ooo.george.qwas.Application; + +class DesktopLauncher { + public static void main (String[] arg) { + LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); + config.title = "QWAS - A Typing Tutor for Single Handed Typing"; + config.width = 1366; + config.height = 768; + config.fullscreen = false; + System.setProperty("org.lwjgl.opengl.Display.allowSoftwareOpenGL", "true"); + new LwjglApplication(new Application(), config); + } +} diff --git a/html/build.gradle b/html/build.gradle new file mode 100644 index 0000000..59a761a --- /dev/null +++ b/html/build.gradle @@ -0,0 +1,70 @@ +apply plugin: "java" +apply plugin: "jetty" + +gwt { + gwtVersion='2.6.0' // Should match the gwt version used for building the gwt backend + maxHeapSize="1G" // Default 256m is not enough for gwt compiler. GWT is HUNGRY + minHeapSize="1G" + + src = files(file("src/")) // Needs to be in front of "modules" below. + modules 'ooo.george.qwas.GdxDefinition' + devModules 'ooo.george.qwas.GdxDefinitionSuperdev' + project.webAppDirName = 'webapp' + + compiler { + strict = true + enableClosureCompiler = true + disableCastChecking = true + } +} + +task draftRun(type: JettyRunWar) { + dependsOn draftWar + dependsOn.remove('war') + webApp=draftWar.archivePath + daemon=true +} + +task superDev(type: de.richsource.gradle.plugins.gwt.GwtSuperDev) { + dependsOn draftRun + doFirst { + gwt.modules = gwt.devModules + } +} + +task dist(dependsOn: [clean, compileGwt]) { + doLast { + file("build/dist").mkdirs() + copy { + from "build/gwt/out" + into "build/dist" + } + copy { + from "webapp" + into "build/dist" + } + copy { + from "war" + into "build/dist" + } + } +} + +draftWar { + from "war" +} + +task addSource << { + sourceSets.main.compileClasspath += files(project(':core').sourceSets.main.allJava.srcDirs) +} + +tasks.compileGwt.dependsOn(addSource) +tasks.draftCompileGwt.dependsOn(addSource) + +sourceCompatibility = 1.8 +sourceSets.main.java.srcDirs = [ "src/" ] + + +eclipse.project { + name = appName + "-html" +} diff --git a/html/src/ooo/george/qwas/GdxDefinition.gwt.xml b/html/src/ooo/george/qwas/GdxDefinition.gwt.xml new file mode 100644 index 0000000..55a7beb --- /dev/null +++ b/html/src/ooo/george/qwas/GdxDefinition.gwt.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/html/src/ooo/george/qwas/GdxDefinitionSuperdev.gwt.xml b/html/src/ooo/george/qwas/GdxDefinitionSuperdev.gwt.xml new file mode 100644 index 0000000..6841508 --- /dev/null +++ b/html/src/ooo/george/qwas/GdxDefinitionSuperdev.gwt.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/html/src/ooo/george/qwas/client/HtmlLauncher.java b/html/src/ooo/george/qwas/client/HtmlLauncher.java new file mode 100644 index 0000000..2dfcfc2 --- /dev/null +++ b/html/src/ooo/george/qwas/client/HtmlLauncher.java @@ -0,0 +1,19 @@ +package ooo.george.qwas.client; + +import com.badlogic.gdx.ApplicationListener; +import com.badlogic.gdx.backends.gwt.GwtApplication; +import com.badlogic.gdx.backends.gwt.GwtApplicationConfiguration; +import ooo.george.qwas.Application; + +public class HtmlLauncher extends GwtApplication { + + @Override + public GwtApplicationConfiguration getConfig () { + return new GwtApplicationConfiguration(480, 320); + } + + @Override + public ApplicationListener createApplicationListener () { + return new Application(); + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..7c74fc5 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +include 'desktop', 'html', 'core' \ No newline at end of file