Compare commits

..

4 Commits

  1. 2
      .gitmodules
  2. 5
      CMakeLists.txt
  3. 4
      assets/CMakeLists.txt
  4. 87
      assets/fnt/LICENSE
  5. 415
      assets/fnt/open-sans.fnt
  6. BIN
      assets/fnt/open-sans.hiero
  7. BIN
      assets/fnt/open-sans.png
  8. 10
      assets/scene/scene1.json
  9. 40
      example/src/cameracontroller.cpp
  10. 18
      example/src/cameracontroller.h
  11. 20
      src/inferno/component/nativescriptcomponent.h
  12. 2
      src/inferno/component/textareacomponent.cpp
  13. 88
      src/inferno/render/font.cpp
  14. 22
      src/inferno/render/font.h
  15. 7
      src/inferno/scene/scene.cpp
  16. 46
      src/inferno/script/nativescript.h
  17. 2
      src/inferno/system/scriptsystem.cpp
  18. 63
      src/inferno/system/textareasystem.cpp
  19. 2
      src/inferno/system/textareasystem.h

2
.gitmodules vendored

@ -16,6 +16,6 @@
[submodule "inferno/vendor/stb/stb"]
path = vendor/stb/stb
url = https://github.com/nothings/stb
[submodule "vendor/ruc"]
[submodule "inferno/vendor/ruc"]
path = vendor/ruc
url = https://github.com/Riyyi/ruc

5
CMakeLists.txt

@ -69,10 +69,7 @@ add_subdirectory("src")
# ------------------------------------------
# Assets target
add_custom_target(${ENGINE}-assets
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/copy-assets.cmake
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_dependencies(${ENGINE} ${ENGINE}-assets)
add_subdirectory("assets")
# ------------------------------------------
# Examples target

4
assets/CMakeLists.txt

@ -0,0 +1,4 @@
add_custom_target(${ENGINE}-assets
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/copy-assets.cmake
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_dependencies(${ENGINE} ${ENGINE}-assets)

87
assets/fnt/LICENSE

@ -0,0 +1,87 @@
SIL OPEN FONT LICENSE
Version 1.1, 26 February 2007
Copyright (C) 2010-2023 Steve Matteson
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:
Neither the Font Software nor any of its individual components, in Original
or Modified Versions, may be sold by itself.
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.
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.
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.
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.

415
assets/fnt/open-sans.fnt

@ -0,0 +1,415 @@
info face="Open Sans Regular" size=62 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=8,8,8,8 spacing=-2,-20
common lineHeight=82 base=67 scaleW=512 scaleH=512 pages=1 packed=0
page id=0 file="open-sans.png"
chars count=97
char id=0 x=377 y=326 width=41 height=60 xoffset=-2 yoffset=15 xadvance=51 page=0 chnl=0
char id=10 x=0 y=0 width=0 height=0 xoffset=-8 yoffset=0 xadvance=14 page=0 chnl=0
char id=32 x=0 y=0 width=0 height=0 xoffset=-8 yoffset=0 xadvance=30 page=0 chnl=0
char id=33 x=142 y=205 width=24 height=61 xoffset=-4 yoffset=15 xadvance=31 page=0 chnl=0
char id=34 x=319 y=437 width=33 height=32 xoffset=-4 yoffset=15 xadvance=39 page=0 chnl=0
char id=35 x=323 y=326 width=54 height=60 xoffset=-7 yoffset=15 xadvance=54 page=0 chnl=0
char id=36 x=349 y=0 width=44 height=67 xoffset=-5 yoffset=12 xadvance=49 page=0 chnl=0
char id=37 x=372 y=143 width=61 height=62 xoffset=-5 yoffset=14 xadvance=65 page=0 chnl=0
char id=38 x=433 y=143 width=58 height=62 xoffset=-5 yoffset=14 xadvance=59 page=0 chnl=0
char id=39 x=352 y=437 width=22 height=32 xoffset=-4 yoffset=15 xadvance=28 page=0 chnl=0
char id=40 x=151 y=0 width=31 height=70 xoffset=-6 yoffset=15 xadvance=32 page=0 chnl=0
char id=41 x=182 y=0 width=31 height=70 xoffset=-7 yoffset=15 xadvance=32 page=0 chnl=0
char id=42 x=273 y=437 width=46 height=44 xoffset=-6 yoffset=12 xadvance=48 page=0 chnl=0
char id=43 x=178 y=437 width=47 height=47 xoffset=-6 yoffset=22 xadvance=49 page=0 chnl=0
char id=44 x=419 y=437 width=26 height=31 xoffset=-7 yoffset=52 xadvance=29 page=0 chnl=0
char id=45 x=45 y=486 width=32 height=21 xoffset=-6 yoffset=40 xadvance=34 page=0 chnl=0
char id=46 x=474 y=437 width=25 height=25 xoffset=-4 yoffset=51 xadvance=31 page=0 chnl=0
char id=47 x=245 y=326 width=39 height=60 xoffset=-8 yoffset=15 xadvance=37 page=0 chnl=0
char id=48 x=285 y=143 width=45 height=62 xoffset=-5 yoffset=14 xadvance=49 page=0 chnl=0
char id=49 x=467 y=266 width=33 height=60 xoffset=-3 yoffset=15 xadvance=49 page=0 chnl=0
char id=50 x=51 y=205 width=46 height=61 xoffset=-6 yoffset=14 xadvance=49 page=0 chnl=0
char id=51 x=103 y=143 width=46 height=62 xoffset=-6 yoffset=14 xadvance=49 page=0 chnl=0
char id=52 x=150 y=326 width=49 height=60 xoffset=-7 yoffset=15 xadvance=49 page=0 chnl=0
char id=53 x=97 y=205 width=45 height=61 xoffset=-5 yoffset=15 xadvance=49 page=0 chnl=0
char id=54 x=149 y=143 width=46 height=62 xoffset=-5 yoffset=14 xadvance=49 page=0 chnl=0
char id=55 x=199 y=326 width=46 height=60 xoffset=-6 yoffset=15 xadvance=49 page=0 chnl=0
char id=56 x=195 y=143 width=45 height=62 xoffset=-5 yoffset=14 xadvance=49 page=0 chnl=0
char id=57 x=240 y=143 width=45 height=62 xoffset=-5 yoffset=14 xadvance=49 page=0 chnl=0
char id=58 x=174 y=386 width=25 height=51 xoffset=-4 yoffset=25 xadvance=31 page=0 chnl=0
char id=59 x=475 y=205 width=26 height=58 xoffset=-6 yoffset=25 xadvance=31 page=0 chnl=0
char id=60 x=88 y=437 width=45 height=47 xoffset=-5 yoffset=21 xadvance=49 page=0 chnl=0
char id=61 x=374 y=437 width=45 height=32 xoffset=-5 yoffset=29 xadvance=49 page=0 chnl=0
char id=62 x=133 y=437 width=45 height=47 xoffset=-5 yoffset=21 xadvance=49 page=0 chnl=0
char id=63 x=330 y=143 width=42 height=62 xoffset=-8 yoffset=14 xadvance=41 page=0 chnl=0
char id=64 x=393 y=0 width=66 height=66 xoffset=-5 yoffset=15 xadvance=70 page=0 chnl=0
char id=65 x=166 y=205 width=55 height=60 xoffset=-8 yoffset=15 xadvance=53 page=0 chnl=0
char id=66 x=221 y=205 width=47 height=60 xoffset=-2 yoffset=15 xadvance=54 page=0 chnl=0
char id=67 x=384 y=78 width=51 height=62 xoffset=-5 yoffset=14 xadvance=53 page=0 chnl=0
char id=68 x=268 y=205 width=52 height=60 xoffset=-2 yoffset=15 xadvance=59 page=0 chnl=0
char id=69 x=320 y=205 width=41 height=60 xoffset=-2 yoffset=15 xadvance=48 page=0 chnl=0
char id=70 x=361 y=205 width=41 height=60 xoffset=-2 yoffset=15 xadvance=46 page=0 chnl=0
char id=71 x=435 y=78 width=54 height=62 xoffset=-5 yoffset=14 xadvance=59 page=0 chnl=0
char id=72 x=402 y=205 width=50 height=60 xoffset=-2 yoffset=15 xadvance=60 page=0 chnl=0
char id=73 x=452 y=205 width=23 height=60 xoffset=-3 yoffset=15 xadvance=31 page=0 chnl=0
char id=74 x=114 y=0 width=37 height=71 xoffset=-13 yoffset=15 xadvance=31 page=0 chnl=0
char id=75 x=0 y=266 width=48 height=60 xoffset=-2 yoffset=15 xadvance=52 page=0 chnl=0
char id=76 x=48 y=266 width=41 height=60 xoffset=-2 yoffset=15 xadvance=46 page=0 chnl=0
char id=77 x=89 y=266 width=60 height=60 xoffset=-2 yoffset=15 xadvance=70 page=0 chnl=0
char id=78 x=149 y=266 width=51 height=60 xoffset=-2 yoffset=15 xadvance=61 page=0 chnl=0
char id=79 x=0 y=143 width=58 height=62 xoffset=-5 yoffset=14 xadvance=62 page=0 chnl=0
char id=80 x=200 y=266 width=44 height=60 xoffset=-2 yoffset=15 xadvance=51 page=0 chnl=0
char id=81 x=56 y=0 width=58 height=72 xoffset=-5 yoffset=14 xadvance=62 page=0 chnl=0
char id=82 x=244 y=266 width=47 height=60 xoffset=-2 yoffset=15 xadvance=52 page=0 chnl=0
char id=83 x=58 y=143 width=45 height=62 xoffset=-5 yoffset=14 xadvance=48 page=0 chnl=0
char id=84 x=291 y=266 width=50 height=60 xoffset=-8 yoffset=15 xadvance=48 page=0 chnl=0
char id=85 x=0 y=205 width=51 height=61 xoffset=-3 yoffset=15 xadvance=59 page=0 chnl=0
char id=86 x=341 y=266 width=53 height=60 xoffset=-8 yoffset=15 xadvance=51 page=0 chnl=0
char id=87 x=394 y=266 width=73 height=60 xoffset=-8 yoffset=15 xadvance=71 page=0 chnl=0
char id=88 x=0 y=326 width=52 height=60 xoffset=-8 yoffset=15 xadvance=50 page=0 chnl=0
char id=89 x=52 y=326 width=51 height=60 xoffset=-8 yoffset=15 xadvance=49 page=0 chnl=0
char id=90 x=103 y=326 width=47 height=60 xoffset=-6 yoffset=15 xadvance=49 page=0 chnl=0
char id=91 x=213 y=0 width=31 height=70 xoffset=-4 yoffset=15 xadvance=34 page=0 chnl=0
char id=92 x=284 y=326 width=39 height=60 xoffset=-8 yoffset=15 xadvance=37 page=0 chnl=0
char id=93 x=244 y=0 width=31 height=70 xoffset=-7 yoffset=15 xadvance=34 page=0 chnl=0
char id=94 x=225 y=437 width=48 height=44 xoffset=-7 yoffset=14 xadvance=48 page=0 chnl=0
char id=95 x=77 y=486 width=46 height=20 xoffset=-9 yoffset=65 xadvance=42 page=0 chnl=0
char id=96 x=445 y=437 width=29 height=26 xoffset=3 yoffset=11 xadvance=50 page=0 chnl=0
char id=97 x=455 y=326 width=44 height=51 xoffset=-6 yoffset=25 xadvance=48 page=0 chnl=0
char id=98 x=92 y=78 width=46 height=64 xoffset=-3 yoffset=12 xadvance=52 page=0 chnl=0
char id=99 x=0 y=386 width=41 height=51 xoffset=-5 yoffset=25 xadvance=44 page=0 chnl=0
char id=100 x=138 y=78 width=46 height=64 xoffset=-5 yoffset=12 xadvance=52 page=0 chnl=0
char id=101 x=41 y=386 width=45 height=51 xoffset=-5 yoffset=25 xadvance=49 page=0 chnl=0
char id=102 x=231 y=78 width=42 height=63 xoffset=-8 yoffset=12 xadvance=35 page=0 chnl=0
char id=103 x=459 y=0 width=48 height=65 xoffset=-7 yoffset=25 xadvance=48 page=0 chnl=0
char id=104 x=273 y=78 width=45 height=63 xoffset=-3 yoffset=12 xadvance=52 page=0 chnl=0
char id=105 x=489 y=78 width=22 height=62 xoffset=-3 yoffset=13 xadvance=30 page=0 chnl=0
char id=106 x=22 y=0 width=34 height=77 xoffset=-12 yoffset=13 xadvance=30 page=0 chnl=0
char id=107 x=318 y=78 width=44 height=63 xoffset=-3 yoffset=12 xadvance=47 page=0 chnl=0
char id=108 x=362 y=78 width=22 height=63 xoffset=-3 yoffset=12 xadvance=30 page=0 chnl=0
char id=109 x=199 y=386 width=64 height=50 xoffset=-3 yoffset=25 xadvance=72 page=0 chnl=0
char id=110 x=263 y=386 width=45 height=50 xoffset=-3 yoffset=25 xadvance=52 page=0 chnl=0
char id=111 x=86 y=386 width=47 height=51 xoffset=-5 yoffset=25 xadvance=51 page=0 chnl=0
char id=112 x=0 y=78 width=46 height=65 xoffset=-3 yoffset=25 xadvance=52 page=0 chnl=0
char id=113 x=46 y=78 width=46 height=65 xoffset=-5 yoffset=25 xadvance=52 page=0 chnl=0
char id=114 x=308 y=386 width=36 height=50 xoffset=-3 yoffset=25 xadvance=39 page=0 chnl=0
char id=115 x=133 y=386 width=41 height=51 xoffset=-5 yoffset=25 xadvance=44 page=0 chnl=0
char id=116 x=418 y=326 width=37 height=58 xoffset=-8 yoffset=18 xadvance=36 page=0 chnl=0
char id=117 x=344 y=386 width=45 height=50 xoffset=-4 yoffset=26 xadvance=52 page=0 chnl=0
char id=118 x=389 y=386 width=47 height=49 xoffset=-8 yoffset=26 xadvance=45 page=0 chnl=0
char id=119 x=436 y=386 width=64 height=49 xoffset=-8 yoffset=26 xadvance=62 page=0 chnl=0
char id=120 x=0 y=437 width=47 height=49 xoffset=-8 yoffset=26 xadvance=46 page=0 chnl=0
char id=121 x=184 y=78 width=47 height=64 xoffset=-8 yoffset=26 xadvance=45 page=0 chnl=0
char id=122 x=47 y=437 width=41 height=49 xoffset=-6 yoffset=26 xadvance=43 page=0 chnl=0
char id=123 x=275 y=0 width=37 height=70 xoffset=-7 yoffset=15 xadvance=38 page=0 chnl=0
char id=124 x=0 y=0 width=22 height=78 xoffset=6 yoffset=12 xadvance=48 page=0 chnl=0
char id=125 x=312 y=0 width=37 height=70 xoffset=-6 yoffset=15 xadvance=38 page=0 chnl=0
char id=126 x=0 y=486 width=45 height=24 xoffset=-5 yoffset=33 xadvance=49 page=0 chnl=0
kernings count=313
kerning first=70 second=46 amount=-4
kerning first=79 second=86 amount=-1
kerning first=107 second=113 amount=-1
kerning first=39 second=65 amount=-4
kerning first=86 second=79 amount=-1
kerning first=89 second=122 amount=-1
kerning first=68 second=88 amount=-1
kerning first=75 second=81 amount=-1
kerning first=84 second=121 amount=-1
kerning first=88 second=71 amount=-1
kerning first=89 second=67 amount=-1
kerning first=121 second=44 amount=-2
kerning first=39 second=99 amount=-4
kerning first=86 second=113 amount=-1
kerning first=65 second=79 amount=-1
kerning first=87 second=109 amount=-1
kerning first=79 second=65 amount=-1
kerning first=67 second=71 amount=-1
kerning first=89 second=101 amount=-3
kerning first=84 second=100 amount=-4
kerning first=44 second=79 amount=-3
kerning first=89 second=46 amount=-4
kerning first=84 second=45 amount=-2
kerning first=46 second=71 amount=-3
kerning first=40 second=74 amount=6
kerning first=79 second=44 amount=-2
kerning first=98 second=120 amount=-1
kerning first=68 second=46 amount=-2
kerning first=39 second=112 amount=-2
kerning first=84 second=79 amount=-1
kerning first=34 second=111 amount=-4
kerning first=66 second=88 amount=-1
kerning first=86 second=71 amount=-1
kerning first=89 second=114 amount=-2
kerning first=87 second=67 amount=-1
kerning first=119 second=44 amount=-2
kerning first=84 second=113 amount=-4
kerning first=65 second=71 amount=-1
kerning first=46 second=84 amount=-4
kerning first=87 second=101 amount=-1
kerning first=111 second=34 amount=-1
kerning first=87 second=46 amount=-3
kerning first=112 second=119 amount=-1
kerning first=44 second=71 amount=-3
kerning first=101 second=121 amount=-1
kerning first=114 second=111 amount=-1
kerning first=66 second=46 amount=-2
kerning first=84 second=71 amount=-1
kerning first=65 second=84 amount=-4
kerning first=87 second=114 amount=-1
kerning first=34 second=103 amount=-2
kerning first=86 second=63 amount=1
kerning first=44 second=84 amount=-4
kerning first=86 second=97 amount=-1
kerning first=109 second=34 amount=-1
kerning first=85 second=46 amount=-1
kerning first=39 second=117 amount=-2
kerning first=90 second=81 amount=-1
kerning first=84 second=84 amount=1
kerning first=120 second=100 amount=-1
kerning first=114 second=103 amount=-1
kerning first=84 second=118 amount=-1
kerning first=86 second=110 amount=-1
kerning first=84 second=63 amount=1
kerning first=46 second=89 amount=-4
kerning first=111 second=39 amount=-1
kerning first=84 second=97 amount=-5
kerning first=120 second=113 amount=-1
kerning first=81 second=88 amount=-1
kerning first=88 second=81 amount=-1
kerning first=76 second=87 amount=-1
kerning first=39 second=109 amount=-2
kerning first=65 second=89 amount=-4
kerning first=67 second=81 amount=-1
kerning first=65 second=34 amount=-4
kerning first=89 second=111 amount=-3
kerning first=84 second=110 amount=-3
kerning first=44 second=89 amount=-4
kerning first=109 second=39 amount=-1
kerning first=46 second=81 amount=-3
kerning first=34 second=87 amount=1
kerning first=111 second=120 amount=-1
kerning first=81 second=46 amount=-2
kerning first=79 second=88 amount=-1
kerning first=101 second=118 amount=-1
kerning first=86 second=81 amount=-1
kerning first=68 second=90 amount=-1
kerning first=76 second=79 amount=-1
kerning first=121 second=46 amount=-2
kerning first=39 second=101 amount=-4
kerning first=86 second=115 amount=-1
kerning first=65 second=81 amount=-1
kerning first=87 second=111 amount=-1
kerning first=34 second=100 amount=-4
kerning first=89 second=103 amount=-1
kerning first=44 second=81 amount=-3
kerning first=79 second=46 amount=-2
kerning first=98 second=122 amount=-1
kerning first=39 second=114 amount=-2
kerning first=84 second=81 amount=-1
kerning first=91 second=74 amount=6
kerning first=34 second=113 amount=-4
kerning first=66 second=90 amount=-1
kerning first=114 second=100 amount=-1
kerning first=65 second=39 amount=-4
kerning first=119 second=46 amount=-2
kerning first=84 second=115 amount=-4
kerning first=76 second=71 amount=-1
kerning first=46 second=86 amount=-4
kerning first=87 second=103 amount=-1
kerning first=112 second=121 amount=-1
kerning first=101 second=34 amount=-1
kerning first=114 second=113 amount=-1
kerning first=118 second=63 amount=1
kerning first=76 second=84 amount=-1
kerning first=65 second=86 amount=-2
kerning first=107 second=99 amount=-1
kerning first=86 second=65 amount=-2
kerning first=75 second=67 amount=-1
kerning first=44 second=86 amount=-4
kerning first=86 second=99 amount=-1
kerning first=34 second=84 amount=1
kerning first=86 second=44 amount=-3
kerning first=99 second=34 amount=1
kerning first=68 second=87 amount=-1
kerning first=84 second=120 amount=-1
kerning first=86 second=112 amount=-1
kerning first=84 second=65 amount=-4
kerning first=34 second=97 amount=-2
kerning first=118 second=34 amount=2
kerning first=89 second=100 amount=-3
kerning first=84 second=99 amount=-4
kerning first=101 second=39 amount=-1
kerning first=84 second=44 amount=-4
kerning first=97 second=34 amount=-1
kerning first=81 second=90 amount=-1
kerning first=76 second=89 amount=-2
kerning first=89 second=79 amount=-1
kerning first=98 second=119 amount=-1
kerning first=39 second=111 amount=-4
kerning first=76 second=34 amount=-5
kerning first=34 second=110 amount=-2
kerning first=66 second=87 amount=-1
kerning first=114 second=97 amount=-1
kerning first=89 second=113 amount=-3
kerning first=84 second=112 amount=-3
kerning first=116 second=34 amount=1
kerning first=87 second=100 amount=-1
kerning first=34 second=89 amount=1
kerning first=99 second=39 amount=1
kerning first=111 second=122 amount=-1
kerning first=112 second=118 amount=-1
kerning first=79 second=90 amount=-1
kerning first=101 second=120 amount=-1
kerning first=87 second=79 amount=-1
kerning first=76 second=81 amount=-1
kerning first=89 second=71 amount=-1
kerning first=39 second=103 amount=-2
kerning first=86 second=117 amount=-1
kerning first=90 second=67 amount=-1
kerning first=87 second=113 amount=-1
kerning first=118 second=39 amount=2
kerning first=80 second=65 amount=-3
kerning first=114 second=34 amount=2
kerning first=123 second=74 amount=6
kerning first=70 second=63 amount=1
kerning first=97 second=39 amount=-1
kerning first=80 second=44 amount=-8
kerning first=76 second=39 amount=-5
kerning first=34 second=115 amount=-2
kerning first=120 second=99 amount=-1
kerning first=87 second=71 amount=-1
kerning first=68 second=84 amount=-2
kerning first=84 second=117 amount=-3
kerning first=88 second=67 amount=-1
kerning first=89 second=63 amount=1
kerning first=86 second=109 amount=-1
kerning first=116 second=39 amount=1
kerning first=67 second=67 amount=-1
kerning first=89 second=97 amount=-3
kerning first=112 second=34 amount=-1
kerning first=46 second=67 amount=-3
kerning first=81 second=87 amount=-1
kerning first=76 second=86 amount=-1
kerning first=66 second=84 amount=-2
kerning first=107 second=101 amount=-1
kerning first=86 second=67 amount=-1
kerning first=118 second=44 amount=-2
kerning first=89 second=110 amount=-2
kerning first=87 second=63 amount=1
kerning first=84 second=109 amount=-3
kerning first=114 second=39 amount=2
kerning first=45 second=84 amount=-2
kerning first=39 second=87 amount=1
kerning first=86 second=101 amount=-1
kerning first=65 second=67 amount=-1
kerning first=87 second=97 amount=-1
kerning first=110 second=34 amount=-1
kerning first=34 second=86 amount=1
kerning first=86 second=46 amount=-3
kerning first=111 second=119 amount=-1
kerning first=44 second=67 amount=-3
kerning first=79 second=87 amount=-1
kerning first=68 second=89 amount=-1
kerning first=34 second=65 amount=-4
kerning first=84 second=122 amount=-2
kerning first=39 second=100 amount=-4
kerning first=86 second=114 amount=-1
kerning first=84 second=67 amount=-1
kerning first=87 second=110 amount=-1
kerning first=34 second=99 amount=-4
kerning first=112 second=39 amount=-1
kerning first=84 second=101 amount=-4
kerning first=84 second=46 amount=-4
kerning first=89 second=81 amount=-1
kerning first=98 second=121 amount=-1
kerning first=39 second=113 amount=-4
kerning first=34 second=112 amount=-2
kerning first=66 second=89 amount=-1
kerning first=114 second=99 amount=-1
kerning first=89 second=115 amount=-2
kerning first=84 second=114 amount=-3
kerning first=46 second=85 amount=-1
kerning first=110 second=39 amount=-1
kerning first=112 second=120 amount=-1
kerning first=101 second=122 amount=-1
kerning first=80 second=88 amount=-1
kerning first=87 second=81 amount=-1
kerning first=81 second=84 amount=-2
kerning first=87 second=115 amount=-1
kerning first=44 second=85 amount=-1
kerning first=70 second=65 amount=-1
kerning first=39 second=84 amount=1
kerning first=104 second=34 amount=-1
kerning first=80 second=46 amount=-8
kerning first=121 second=63 amount=1
kerning first=34 second=117 amount=-2
kerning first=70 second=44 amount=-4
kerning first=79 second=84 amount=-2
kerning first=107 second=111 amount=-1
kerning first=120 second=101 amount=-1
kerning first=68 second=86 amount=-1
kerning first=75 second=79 amount=-1
kerning first=84 second=119 amount=-1
kerning first=89 second=65 amount=-4
kerning first=39 second=97 amount=-2
kerning first=86 second=111 amount=-1
kerning first=89 second=99 amount=-3
kerning first=68 second=65 amount=-1
kerning first=89 second=44 amount=-4
kerning first=102 second=34 amount=4
kerning first=119 second=63 amount=1
kerning first=81 second=89 amount=-1
kerning first=98 second=118 amount=-1
kerning first=68 second=44 amount=-2
kerning first=39 second=110 amount=-2
kerning first=34 second=109 amount=-2
kerning first=66 second=86 amount=-1
kerning first=118 second=46 amount=-2
kerning first=89 second=112 amount=-2
kerning first=87 second=65 amount=-2
kerning first=75 second=71 amount=-1
kerning first=84 second=111 amount=-4
kerning first=69 second=74 amount=4
kerning first=76 second=67 amount=-1
kerning first=121 second=34 amount=2
kerning first=39 second=89 amount=1
kerning first=86 second=103 amount=-1
kerning first=87 second=99 amount=-1
kerning first=104 second=39 amount=-1
kerning first=66 second=65 amount=-1
kerning first=87 second=44 amount=-3
kerning first=111 second=121 amount=-1
kerning first=79 second=89 amount=-1
kerning first=101 second=119 amount=-1
kerning first=66 second=44 amount=-2
kerning first=87 second=112 amount=-1
kerning first=34 second=101 amount=-4
kerning first=85 second=65 amount=-1
kerning first=119 second=34 amount=2
kerning first=84 second=103 amount=-4
kerning first=102 second=39 amount=4
kerning first=85 second=44 amount=-1
kerning first=98 second=34 amount=-1
kerning first=39 second=115 amount=-2
kerning first=90 second=79 amount=-1
kerning first=34 second=114 amount=-2
kerning first=114 second=101 amount=-1
kerning first=89 second=117 amount=-2
kerning first=121 second=39 amount=2
kerning first=65 second=74 amount=8
kerning first=46 second=87 amount=-4
kerning first=112 second=122 amount=-1
kerning first=120 second=111 amount=-1
kerning first=80 second=90 amount=-1
kerning first=81 second=86 amount=-1
kerning first=88 second=79 amount=-1
kerning first=76 second=85 amount=-1
kerning first=90 second=71 amount=-1
kerning first=65 second=87 amount=-2
kerning first=87 second=117 amount=-1
kerning first=107 second=100 amount=-1
kerning first=67 second=79 amount=-1
kerning first=89 second=109 amount=-2
kerning first=119 second=39 amount=2
kerning first=81 second=65 amount=-1
kerning first=44 second=87 amount=-4
kerning first=39 second=86 amount=1
kerning first=86 second=100 amount=-1
kerning first=46 second=79 amount=-3
kerning first=98 second=39 amount=-1
kerning first=111 second=118 amount=-1
kerning first=81 second=44 amount=-2

BIN
assets/fnt/open-sans.hiero

Binary file not shown.

BIN
assets/fnt/open-sans.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

10
assets/scene/scene1.json

@ -36,5 +36,15 @@
"color": [ 1.0, 1.0, 1.0, 1.0 ],
"texture": "assets/gfx/test-inverted.png"
}
],
"text": [
{
"name": "Text",
"content": "Hello World!",
"font": "assets/fnt/open-sans",
"font-size": 10,
"width": 150,
"lines": 3
}
]
}

40
src/inferno/script/cameracontroller.cpp → example/src/cameracontroller.cpp

@ -10,9 +10,10 @@
#include "inferno/component/transformcomponent.h"
#include "inferno/io/input.h"
#include "inferno/keycodes.h"
#include "inferno/script/cameracontroller.h"
namespace Inferno {
#include "cameracontroller.h"
namespace example {
void CameraController::updateOrthographic(float deltaTime)
{
@ -20,10 +21,10 @@ void CameraController::updateOrthographic(float deltaTime)
float cameraRotateSpeed = ROTATE_SPEED * deltaTime;
if (Input::isKeyPressed(keyCode("GLFW_KEY_Q"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_Q"))) {
transform->rotate.z -= cameraRotateSpeed;
}
if (Input::isKeyPressed(keyCode("GLFW_KEY_E"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_E"))) {
transform->rotate.z += cameraRotateSpeed;
}
@ -39,19 +40,19 @@ void CameraController::updateOrthographic(float deltaTime)
float cameraTranslateSpeed = TRANSLATE_SPEED * deltaTime;
// WASD movement
if (Input::isKeyPressed(keyCode("GLFW_KEY_W"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_W"))) {
transform->translate.x += -sin(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
transform->translate.y += cos(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
}
if (Input::isKeyPressed(keyCode("GLFW_KEY_S"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_S"))) {
transform->translate.x -= -sin(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
transform->translate.y -= cos(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
}
if (Input::isKeyPressed(keyCode("GLFW_KEY_A"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_A"))) {
transform->translate.x -= cos(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
transform->translate.y -= sin(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
}
if (Input::isKeyPressed(keyCode("GLFW_KEY_D"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_D"))) {
transform->translate.x += cos(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
transform->translate.y += sin(glm::radians(transform->rotate.z)) * cameraTranslateSpeed;
}
@ -60,10 +61,10 @@ void CameraController::updateOrthographic(float deltaTime)
float zoomSpeed = ZOOM_SENSITIVITY * deltaTime;
if (Input::isKeyPressed(keyCode("GLFW_KEY_EQUAL"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_EQUAL"))) {
m_camera->zoomLevel -= zoomSpeed;
}
if (Input::isKeyPressed(keyCode("GLFW_KEY_MINUS"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_MINUS"))) {
m_camera->zoomLevel += zoomSpeed;
}
m_camera->zoomLevel = std::max(m_camera->zoomLevel, 0.25f);
@ -73,8 +74,8 @@ void CameraController::updateOrthographic(float deltaTime)
void CameraController::updatePerspective(float deltaTime)
{
// Get mouse movement offset compared to last frame
float xOffset = Input::getXOffset() * MOUSE_SENSITIVITY;
float yOffset = Input::getYOffset() * MOUSE_SENSITIVITY;
float xOffset = Inferno::Input::getXOffset() * MOUSE_SENSITIVITY;
float yOffset = Inferno::Input::getYOffset() * MOUSE_SENSITIVITY;
m_camera->yaw += xOffset;
m_camera->pitch += yOffset;
@ -107,24 +108,25 @@ void CameraController::updatePerspective(float deltaTime)
float cameraSpeed = TRANSLATE_SPEED * deltaTime;
// WASD movement
if (Input::isKeyPressed(keyCode("GLFW_KEY_W"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_W"))) {
transform->translate += transform->rotate * cameraSpeed;
}
if (Input::isKeyPressed(keyCode("GLFW_KEY_S"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_S"))) {
transform->translate -= transform->rotate * cameraSpeed;
}
if (Input::isKeyPressed(keyCode("GLFW_KEY_A"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_A"))) {
transform->translate -= glm::normalize(glm::cross(transform->rotate, m_camera->up)) * cameraSpeed;
}
if (Input::isKeyPressed(keyCode("GLFW_KEY_D"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_D"))) {
transform->translate += glm::normalize(glm::cross(transform->rotate, m_camera->up)) * cameraSpeed;
}
// Up / down movement
if (Input::isKeyPressed(keyCode("GLFW_KEY_SPACE"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_SPACE"))) {
transform->translate.y += cameraSpeed;
}
if (Input::isKeyPressed(keyCode("GLFW_KEY_LEFT_SHIFT"))) {
if (Inferno::Input::isKeyPressed(Inferno::keyCode("GLFW_KEY_LEFT_SHIFT"))) {
transform->translate.y -= cameraSpeed;
}
}
} // namespace Inferno
} // namespace example

18
src/inferno/script/cameracontroller.h → example/src/cameracontroller.h

@ -14,20 +14,18 @@
#define ZOOM_SENSITIVITY 2.5f
#define MOUSE_SENSITIVITY 0.25f
namespace Inferno {
namespace example {
struct CameraComponent;
class CameraController final : public NativeScript {
class CameraController final : public Inferno::NativeScript {
public:
virtual void update(float deltaTime) override
{
m_camera = &getComponent<CameraComponent>();
m_camera = &getComponent<Inferno::CameraComponent>();
if (m_camera->type == CameraType::Orthographic) {
if (m_camera->type == Inferno::CameraType::Orthographic) {
updateOrthographic(deltaTime);
}
else if (m_camera->type == CameraType::Perspective) {
else if (m_camera->type == Inferno::CameraType::Perspective) {
updatePerspective(deltaTime);
}
}
@ -36,7 +34,9 @@ public:
void updatePerspective(float deltaTime);
private:
CameraComponent* m_camera { nullptr };
Inferno::CameraComponent* m_camera { nullptr };
};
} // namespace Inferno
BIND_NATIVE(CameraController);
} // namespace example

20
src/inferno/component/nativescriptcomponent.h

@ -6,7 +6,7 @@
#pragma once
#include "ruc/meta/assert.h"
#include <string>
#include "inferno/script/nativescript.h"
@ -15,23 +15,15 @@ namespace Inferno {
struct NativeScriptComponent {
NativeScript* instance { nullptr };
NativeScript* (*initialize)() { nullptr };
NativeScript::InitializeFunction initialize { nullptr };
NativeScript::DestroyFunction destroy { nullptr };
// Dont allow manually setting instance during construction
NativeScriptComponent() {}
template<typename T>
void bind()
{
VERIFY(instance == nullptr, "NativeScript already bound");
initialize = []() { return static_cast<NativeScript*>(new T()); };
}
void destroy()
NativeScriptComponent(const std::string& binding)
{
VERIFY(instance, "Attempting to destroy an uninitialized NativeScript");
delete instance;
instance = nullptr;
initialize = NativeScriptBinding::the().initializeBinding(binding);
destroy = NativeScriptBinding::the().destroyBinding(binding);
}
};

2
src/inferno/component/textareacomponent.cpp

@ -27,7 +27,7 @@ void fromJson(const ruc::Json& json, TextAreaComponent& value)
json.at("width").getTo(value.width);
}
if (json.exists("lines") && json.at("lines").type() == ruc::Json::Type::Number) {
json.at("lines").getTo(value.width);
json.at("lines").getTo(value.lines);
}
}

88
src/inferno/render/font.cpp

@ -4,13 +4,18 @@
* SPDX-License-Identifier: MIT
*/
#include <array> // std::array
#include <charconv> // std;:from_chars
#include <cstdint> // int32_t, uint32_t
#include <limits> // std::numeric_limits
#include <string> // std::getline, std::stoi
#include <ranges> // std::views::split
#include <string> // std::getline
#include <utility> // std::move
#include "ruc/file.h"
#include "ruc/format/log.h"
#include "ruc/meta/assert.h"
#include "ruc/meta/concepts.h"
#include "inferno/render/font.h"
#include "inferno/render/texture.h"
@ -30,43 +35,96 @@ Font::Font(const std::string& name)
m_texture = std::make_shared<Texture>(image);
}
// TODO: Move this to ruc
template<Integral T>
static T convert(std::string_view value)
{
T tmp;
std::from_chars(value.data(), value.data() + value.size(), tmp);
return tmp;
}
void Font::parseFont(const std::string& font)
{
std::istringstream iss(font);
for (std::string line; std::getline(iss, line);) {
std::string action = findAction(line);
const std::vector<std::string> columns = findColumns(line);
// Info
// ---------------------------------
if (findAction(line).compare("info") != 0 && findAction(line).compare("char") != 0) {
if (action.compare("info") == 0) {
m_size = convert<uint32_t>(findValue("size", columns));
auto paddings = findValue("padding", columns) | std::views::split(',');
size_t i = 0;
for (const auto& padding : paddings) {
// top, right, bottom, left
m_padding[i++] = convert<uint32_t>(padding.data()) - PADDING;
}
continue;
}
const std::vector<std::string> columns = findColumns(line);
// Info
// Common
// ---------------------------------
if (findAction(line).compare("info") == 0) {
m_size = std::stou(findValue("size", columns));
if (action.compare("common") == 0) {
m_lineSpacing = convert<uint32_t>(findValue("lineHeight", columns)) - m_padding[Padding::Top] - m_padding[Padding::Bottom];
continue;
}
// Character
// ---------------------------------
unsigned char id = std::stoi(findValue("id", columns));
if (action.compare("char") == 0) {
unsigned char id = convert<unsigned char>(findValue("id", columns));
uint32_t width = convert<uint32_t>(findValue("width", columns));
uint32_t height = convert<uint32_t>(findValue("height", columns));
Character character = {
{ std::stou(findValue("x", columns)), std::stou(findValue("y", columns)) },
{ std::stou(findValue("width", columns)), std::stou(findValue("height", columns)) },
{ std::stoi(findValue("xoffset", columns)), std::stoi(findValue("yoffset", columns)) },
std::stou(findValue("xadvance", columns))
.position = {
convert<uint32_t>(findValue("x", columns)) + m_padding[Padding::Left],
convert<uint32_t>(findValue("y", columns)) + m_padding[Padding::Top],
},
.size = {
width == 0 ? 0 : width - m_padding[Padding::Left] - m_padding[Padding::Right],
height == 0 ? 0 : height - m_padding[Padding::Top] - m_padding[Padding::Bottom],
},
.offset = {
convert<int32_t>(findValue("xoffset", columns)) + m_padding[Padding::Left],
convert<int32_t>(findValue("yoffset", columns)) + m_padding[Padding::Top],
},
.advance = convert<uint32_t>(findValue("xadvance", columns)) - m_padding[Padding::Left] - m_padding[Padding::Right]
};
m_characterList.emplace(id, std::make_shared<Character>(character));
continue;
}
// Kerning
// ---------------------------------
if (action.compare("kerning") == 0) {
unsigned char first = convert<unsigned char>(findValue("first", columns));
unsigned char second = convert<unsigned char>(findValue("second", columns));
char amount = convert<char>(findValue("amount", columns));
// Add the kerning of the previous character to this character
if (m_characterList.find(second) != m_characterList.end()) {
auto character = m_characterList.at(second);
character->kernings.emplace(first, amount);
}
continue;
}
}
}
const std::string Font::findAction(const std::string& line)
std::string Font::findAction(const std::string& line) const
{
return line.substr(0, line.find(" "));
}
const std::vector<std::string> Font::findColumns(const std::string& line)
std::vector<std::string> Font::findColumns(const std::string& line) const
{
std::vector<std::string> elements;
@ -93,7 +151,7 @@ const std::vector<std::string> Font::findColumns(const std::string& line)
return elements;
}
const std::string Font::findValue(const std::string& key, const std::vector<std::string>& columns)
std::string Font::findValue(const std::string& key, const std::vector<std::string>& columns) const
{
size_t find = 0;
// Loop over columns

22
src/inferno/render/font.h

@ -6,6 +6,7 @@
#pragma once
#include <array> // std::array
#include <cstdint> // int32_t, uint32_t
#include <memory> // std::shared_ptr
#include <string> // std::string
@ -17,6 +18,8 @@
#include "ruc/format/format.h"
#include "ruc/singleton.h"
#define PADDING 3
namespace Inferno {
class Texture;
@ -26,6 +29,7 @@ struct Character {
glm::uvec2 size; // Width/height
glm::ivec2 offset; // Offset from baseline to left / top of glyph
uint32_t advance; // Amount to advance to next glyph
std::unordered_map<unsigned char, char> kernings; // Kernings for characters that come before this one
};
// -------------------------------------
@ -35,8 +39,16 @@ public:
Font(const std::string& name);
virtual ~Font() {}
enum Padding {
Top = 0,
Right,
Bottom,
Left,
};
inline std::string name() const { return m_name; }
inline uint32_t size() const { return m_size; }
inline uint32_t lineSpacing() const { return m_lineSpacing; }
inline std::shared_ptr<Texture> texture() const { return m_texture; }
inline std::shared_ptr<Character> get(unsigned char c) const { return m_characterList.at(c); }
@ -44,12 +56,14 @@ public:
private:
void parseFont(const std::string& font);
const std::string findAction(const std::string& line);
const std::vector<std::string> findColumns(const std::string& line);
const std::string findValue(const std::string& key, const std::vector<std::string>& columns);
std::string findAction(const std::string& line) const;
std::vector<std::string> findColumns(const std::string& line) const;
std::string findValue(const std::string& key, const std::vector<std::string>& columns) const;
std::string m_name;
uint32_t m_size;
uint32_t m_size = { 0 };
uint32_t m_lineSpacing = { 0 };
std::array<uint32_t, 4> m_padding = { 0 };
std::shared_ptr<Texture> m_texture;
std::unordered_map<unsigned char, std::shared_ptr<Character>> m_characterList;
};

7
src/inferno/scene/scene.cpp

@ -20,7 +20,6 @@
#include "inferno/component/textareacomponent.h"
#include "inferno/component/transformcomponent.h"
#include "inferno/scene/scene.h"
#include "inferno/script/cameracontroller.h"
#include "inferno/script/nativescript.h"
#include "inferno/system/camerasystem.h"
#include "inferno/system/rendersystem.h"
@ -65,12 +64,12 @@ void Scene::initialize()
if (cameraJson.exists("script")) {
auto& cameraScript = cameraJson.at("script");
if (cameraScript.exists("type") && cameraScript.exists("name")) {
auto name = cameraScript.at("name").get<std::string>();
if (cameraScript.at("type").get<std::string>() == "lua") {
addComponent<LuaScriptComponent>(camera, cameraScript.at("name").get<std::string>());
addComponent<LuaScriptComponent>(camera, name);
}
else {
// TODO: Allow usage of custom camera classes
addComponent<NativeScriptComponent>(camera).bind<CameraController>();
addComponent<NativeScriptComponent>(camera, name);
}
}
}

46
src/inferno/script/nativescript.h

@ -6,6 +6,9 @@
#pragma once
#include "ruc/meta/core.h"
#include "ruc/singleton.h"
#include "inferno/scene/scene.h"
namespace Inferno {
@ -14,6 +17,9 @@ struct TransformComponent;
class NativeScript {
public:
typedef NativeScript* (*InitializeFunction)();
typedef void (*DestroyFunction)(NativeScript*);
virtual ~NativeScript() {}
protected:
@ -36,4 +42,44 @@ private:
friend class ScriptSystem;
};
class NativeScriptBinding final : public ruc::Singleton<NativeScriptBinding> {
public:
NativeScriptBinding(s) {}
virtual ~NativeScriptBinding() {}
void registerBinding(const std::string& binding,
NativeScript::InitializeFunction initialize,
NativeScript::DestroyFunction destroy)
{
m_initializeBindings.emplace(binding, initialize);
m_detroyBindings.emplace(binding, destroy);
}
NativeScript::InitializeFunction initializeBinding(const std::string& binding) { return m_initializeBindings[binding]; }
NativeScript::DestroyFunction destroyBinding(const std::string& binding) { return m_detroyBindings[binding]; }
private:
std::unordered_map<std::string, NativeScript::InitializeFunction> m_initializeBindings;
std::unordered_map<std::string, NativeScript::DestroyFunction> m_detroyBindings;
};
} // namespace Inferno
#define BIND_NATIVE_IMPL(name, struct_name) \
struct struct_name { \
struct_name() \
{ \
Inferno::NativeScriptBinding::the().registerBinding( \
#name, \
[]() -> Inferno::NativeScript* { return static_cast<Inferno::NativeScript*>(new name()); }, \
[](Inferno::NativeScript* nativeScript) -> void { \
VERIFY(nativeScript, "Attempting to destroy an uninitialized NativeScript"); \
delete static_cast<name*>(nativeScript); \
nativeScript = nullptr; \
}); \
} \
}; \
static struct struct_name struct_name; // NOLINT(clang-diagnostic-unused-function)
#define BIND_NATIVE(name) \
BIND_NATIVE_IMPL(name, CONCAT(__BIND_NATIVE_FUNCTION_, __COUNTER__))

2
src/inferno/system/scriptsystem.cpp

@ -92,7 +92,7 @@ void ScriptSystem::cleanup(NativeScriptComponent& nativeScript)
{
if (nativeScript.instance) {
nativeScript.instance->destroy();
nativeScript.destroy();
nativeScript.destroy(nativeScript.instance);
}
}

63
src/inferno/system/textareasystem.cpp

@ -4,6 +4,8 @@
* SPDX-License-Identifier: MIT
*/
#include <algorithm> // std::max
#include "ruc/format/log.h"
#include "ruc/meta/assert.h"
@ -46,9 +48,12 @@ void TextAreaSystem::render()
std::shared_ptr<Font> font = FontManager::the().load(textarea.font);
// glm::mat4 translate = transform.translate;
float advance = 0.0f;
unsigned char previous = 0;
float advanceX = 0.0f;
float advanceY = 0.0f;
for (auto character : textarea.content) {
std::optional<CharacterQuad> quad = calculateCharacterQuad(character, font, advance);
std::optional<CharacterQuad> quad = calculateCharacterQuad(character, previous, font, advanceX, advanceY);
previous = character;
if (quad) {
RendererCharacter::the().drawCharacter(quad.value(), font->texture());
@ -57,53 +62,65 @@ void TextAreaSystem::render()
}
}
std::optional<CharacterQuad> TextAreaSystem::calculateCharacterQuad(unsigned char character, std::shared_ptr<Font> font, float& advance)
std::optional<CharacterQuad> TextAreaSystem::calculateCharacterQuad(unsigned char character, unsigned char previous, std::shared_ptr<Font> font, float& advanceX, float& advanceY)
{
CharacterQuad characterQuad;
auto c = font->get(character);
// Texture
// ---------------------------------
// -------------------------------------
float textureWidth = static_cast<float>(font->texture()->width());
float textureHeight = static_cast<float>(font->texture()->height());
VERIFY(textureWidth == textureHeight, "TextAreaSystem read invalid font texture");
// Skip empty characters
// Skip empty characters (like space)
if (c->size.x == 0 || c->size.y == 0) {
// Jump to the next glyph
advance += c->advance / textureWidth;
advanceX += c->advance;
return {};
}
// Position
// ---------------------------------
// -------------------------------------
float quadWidth = c->size.x / textureWidth;
float quadHeight = c->size.y / textureHeight;
characterQuad.at(0).quad.position = { -quadWidth, -quadHeight, 0.0f }; // bottom left
characterQuad.at(1).quad.position = { quadWidth, -quadHeight, 0.0f }; // bottom right
characterQuad.at(2).quad.position = { quadWidth, quadHeight, 0.0f }; // top right
characterQuad.at(3).quad.position = { -quadWidth, quadHeight, 0.0f }; // top left
// Kerning
if (c->kernings.find(previous) != c->kernings.end()) {
advanceX += c->kernings.at(previous);
}
for (auto& quad : characterQuad) {
quad.quad.position.x -= 0.5f;
// Line wrapping
if (advanceX + c->offset.x + c->size.x > textureWidth) {
advanceX = 0;
advanceY -= font->lineSpacing();
}
quad.quad.position.x += c->offset.x / (float)textureWidth;
quad.quad.position.y -= c->offset.y / (float)textureHeight;
glm::vec2 cursor = { std::max(advanceX + c->offset.x, 0.0f),
advanceY - c->offset.y };
glm::vec2 cursorMax = { cursor.x + c->size.x,
cursor.y - c->size.y };
quad.quad.position.x += advance;
}
// Scale the values from 0:512 (texture size) to -1:1 (screen space)
glm::vec2 cursorScreen = {
(cursor.x / textureWidth * 2) - 1,
(cursor.y / textureHeight * 2) + 1,
};
glm::vec2 cursorScreenMax = {
(cursorMax.x / textureWidth * 2) - 1,
(cursorMax.y / textureHeight * 2) + 1,
};
// ruc::debug("character: {} ({}) width: {} height: {} advance: {} x: {}",
// character, (int)character, quadWidth, quadHeight, advance, characterQuad.at(0).quad.position.x);
characterQuad.at(0).quad.position = { cursorScreen.x, cursorScreenMax.y, 0.0f }; // bottom left
characterQuad.at(1).quad.position = { cursorScreenMax.x, cursorScreenMax.y, 0.0f }; // bottom right
characterQuad.at(2).quad.position = { cursorScreenMax.x, cursorScreen.y, 0.0f }; // top right
characterQuad.at(3).quad.position = { cursorScreen.x, cursorScreen.y, 0.0f }; // top left
// Jump to the next glyph
advance += c->advance / textureWidth;
advanceX += c->advance;
// Texture coordinates
// ---------------------------------
// -------------------------------------
glm::vec2 x {
1 - (textureWidth - c->position.x) / textureWidth,

2
src/inferno/system/textareasystem.h

@ -33,7 +33,7 @@ public:
void setScene(Scene* scene) { m_scene = scene; }
private:
std::optional<CharacterQuad> calculateCharacterQuad(unsigned char character, std::shared_ptr<Font> font, float& advance);
std::optional<CharacterQuad> calculateCharacterQuad(unsigned char character, unsigned char previous, std::shared_ptr<Font> font, float& advanceX, float& advanceY);
Scene* m_scene { nullptr };
};

Loading…
Cancel
Save