283 Commits

Author SHA1 Message Date
Sandro Sobczyński 1fe12962b8 Merge pull request #136 from h4570/135-obj-get-texture-names-from-mtl-file-instead-of-material-name
Fix for obj loader and dynamic pipeline
2022-08-29 19:06:22 +02:00
h4570 e359bcbe2b patch 1 2022-08-29 19:00:47 +02:00
Sandro Sobczyński 13f4b5e626 Update README.MD 2022-08-29 17:16:45 +02:00
Sandro Sobczyński 2ae1ccd761 Update README.MD 2022-08-28 18:48:59 +02:00
h4570 d7013f302b Merge branch 'master' of https://github.com/h4570/tyra 2022-08-28 17:45:55 +02:00
h4570 b3fe92c996 Merge branch 'master' of https://github.com/h4570/tyra 2022-08-28 17:21:13 +02:00
h4570 822663f95e true fix 2022-08-28 17:21:10 +02:00
h4570 3f9bb33177 rename game setting 2022-08-28 17:11:12 +02:00
Sandro Sobczyński fa173f1e87 Update README.MD 2022-08-28 16:51:46 +02:00
h4570 f08da7b358 update extensions.json 2022-08-28 15:31:18 +02:00
h4570 945b9c462b fix template includes 2022-08-28 15:15:24 +02:00
h4570 c9535412a7 info about tutorials 2022-08-28 15:07:58 +02:00
Sandro Sobczyński 2c41930cb2 Update README.MD 2022-08-28 14:26:09 +02:00
h4570 2a4e2a2109 Merge branch 'master' of https://github.com/h4570/tyra 2022-08-28 13:50:34 +02:00
h4570 286b9e43a7 fix far plane 2022-08-28 13:50:32 +02:00
Sandro Sobczyński f62eaff37b Update README.MD 2022-08-27 15:37:32 +02:00
Sandro Sobczyński 48fa642cef Update README.MD 2022-08-25 00:03:34 +02:00
Sandro Sobczyński cad720a399 Update README.MD 2022-08-25 00:01:56 +02:00
Sandro Sobczyński cf3f5b3443 Update README.MD 2022-08-25 00:00:04 +02:00
Sandro Sobczyński 48a0eec86b Update README.MD 2022-08-24 23:42:02 +02:00
Sandro Sobczyński 6a9f3c6683 Update README.MD 2022-08-24 23:40:23 +02:00
Sandro Sobczyński 325fea1a8b Update README.MD 2022-08-24 23:36:00 +02:00
Sandro Sobczyński ce00f58b89 Update README.MD 2022-08-24 23:21:02 +02:00
h4570 5d4d2b0f06 remove roadmap text file 2022-08-24 23:20:16 +02:00
Sandro Sobczyński ca25a6de03 Update README.MD 2022-08-24 23:14:37 +02:00
Sandro Sobczyński a6c8eb5bce Update README.MD 2022-08-24 23:00:48 +02:00
Sandro Sobczyński 73b0cd90b4 Update README.MD 2022-08-24 23:00:01 +02:00
Sandro Sobczyński b69504c9b0 Merge pull request #125 from h4570/tyrav2-develop
Tyrav2 -> master
2022-08-24 22:54:58 +02:00
h4570 293113c4d0 fixed readme 2022-08-24 22:52:50 +02:00
h4570 ac335baa75 typo fix 2022-08-24 20:49:56 +02:00
h4570 0fd2478049 demo fixes 2022-08-24 19:50:11 +02:00
h4570 a21bcee671 finished tutorial 9 2022-08-24 19:27:16 +02:00
h4570 5c375dd24f finish 8 tutorial 2022-08-24 18:51:46 +02:00
h4570 b5147bba3a bbox fixes 2022-08-24 00:05:45 +02:00
h4570 989d2702e8 finished tutorial 7 2022-08-23 22:31:07 +02:00
h4570 9f831c7a6f finished 5 tutorial 2022-08-23 22:18:53 +02:00
h4570 3bbf3202ac tutorial templates 2022-08-23 09:57:34 +02:00
h4570 d469e78747 tutorial 04 2022-08-22 23:23:51 +02:00
h4570 4fa65fc535 overloads, tutorial 04 init 2022-08-21 19:44:47 +02:00
h4570 409ee294eb finished tutorial 03 2022-08-21 16:40:26 +02:00
h4570 4303cc2c97 add tutorial 2 comments 2022-08-20 21:44:00 +02:00
h4570 b4b48ae479 tutorial 1 and 2 2022-08-20 18:53:27 +02:00
h4570 d251df8704 irx, nullptr, threading patch 2022-08-20 16:38:44 +02:00
h4570 57767eee72 demo finish 2022-08-20 00:34:43 +02:00
h4570 405d5afd35 demo update 2022-08-20 00:10:07 +02:00
h4570 8eb01d34da ray bugfix 2022-08-19 20:19:05 +02:00
h4570 1456a79135 uncommented code 2022-08-18 23:55:23 +02:00
h4570 3817eadc14 render reorder 2022-08-18 23:09:35 +02:00
h4570 385849e3b2 fixed problem with compiler overoptimization 2022-08-18 23:06:07 +02:00
h4570 1ba2cb55b7 frustum check refactor 2022-08-18 09:51:13 +02:00
h4570 b9cde6346f roadmap update 2022-08-17 21:03:30 +02:00
h4570 a464fac9dc add hotfix 2022-08-17 13:37:54 +02:00
h4570 36098c9b62 add asm version of vec4 divide 2022-08-17 13:25:51 +02:00
h4570 2e41332dca small cleanup 2022-08-17 01:02:57 +02:00
h4570 fea2398699 utility functions 2022-08-17 00:19:23 +02:00
h4570 4fb0ab3b6c memory leak hotfix 2022-08-15 10:58:17 +02:00
h4570 2c3055c5a2 fixed typo in assert 2022-08-15 01:38:28 +02:00
h4570 60e3804c15 initial drawLine() 2022-08-15 01:37:24 +02:00
h4570 3af2493068 cleanup in vec4 2022-08-15 01:36:43 +02:00
Sandro Sobczyński ae0d5c52fd Merge pull request #124 from Wellinator/tyrav2-develop
refactor: improves ray box collision accuracy
2022-08-14 22:39:38 +02:00
Wellinator 83f07f4789 refactor: apply std min/max 2022-08-14 17:37:55 -03:00
Wellinator 0d15d0c7c8 feat: add vec4 division operator 2022-08-14 17:23:47 -03:00
Wellinator 0558dd7612 fix: MIN MAX definitions;
refactor: reduce t variables to Vec4
2022-08-14 17:20:33 -03:00
Wellinator 7a4ca89b14 refactor: implroves ray box collision accuracy 2022-08-14 16:52:06 -03:00
h4570 74c684fff8 mockup of utility functions 2022-08-14 21:07:16 +02:00
h4570 d0085e834e add getNormalized() 2022-08-14 20:59:59 +02:00
h4570 26596fa2c3 add basic shoot on enemy 2022-08-14 20:48:10 +02:00
h4570 37257b253a fix bbox const 2022-08-14 20:34:02 +02:00
h4570 d5261dbb0c change distance to output distance pointer 2022-08-14 20:29:56 +02:00
h4570 156973714b added missing const 2022-08-14 20:26:41 +02:00
h4570 65f40091db shoot action in demo 2022-08-14 20:20:56 +02:00
h4570 6e5b75e39b add print to ray 2022-08-14 20:20:03 +02:00
h4570 5c2ae9770e demo headers refactor 2022-08-14 20:11:57 +02:00
h4570 7ef0e73543 ray class api change 2022-08-14 20:01:49 +02:00
h4570 a78f430a6e add ship 2022-08-14 19:41:44 +02:00
h4570 b8aa40cba8 increased spammer count for stapip 2022-08-14 18:58:49 +02:00
h4570 58f45833fe fix typo in macro 2022-08-14 18:37:44 +02:00
h4570 03eaf726ed z buffer fix for minecraft pipeline 2022-08-14 18:18:41 +02:00
h4570 15391a81e0 z test patch 2022-08-14 18:05:57 +02:00
h4570 a9c91db594 change Ka to Kd in obj loader 2022-08-13 00:17:41 +02:00
h4570 8829bf3035 10 enemies in demo 2022-08-12 23:40:26 +02:00
h4570 2054dba4ec change enemy to monster 2022-08-12 12:04:52 +02:00
h4570 d65561487c enemy position and rotation 2022-08-12 10:24:40 +02:00
h4570 cbe346900d other fixes 2022-08-12 01:05:08 +02:00
h4570 00216da1cd minor audio fixes 2022-08-11 23:46:02 +02:00
h4570 472ab5c2ad audio rework 2022-08-11 23:18:50 +02:00
h4570 74c642bd83 minor fixes 2022-08-11 20:39:04 +02:00
h4570 5316abce42 demo roadmap 2022-08-11 10:32:00 +02:00
h4570 b6ffc11be3 cleanup 2022-08-11 10:20:35 +02:00
h4570 5f5f28b3fb skip not used materials 2022-08-10 22:43:10 +02:00
h4570 0a2d19b2d0 mesh refactor 3 2022-08-10 21:58:32 +02:00
h4570 10e0f52d44 math classes refactor 2022-08-10 20:51:19 +02:00
h4570 0df43e5a08 m4x4 identity 2022-08-10 19:22:59 +02:00
h4570 5cc5862810 obj options 2022-08-10 19:00:57 +02:00
h4570 a0898e7b4c mesh refactor 2 2022-08-10 17:57:42 +02:00
h4570 725c17f9d4 stapip patch 2022-08-10 17:46:07 +02:00
h4570 420a2d3eae add verbose logging 2022-08-10 10:32:50 +02:00
h4570 2dad96d396 mesh patch 1 2022-08-09 23:12:09 +02:00
h4570 6b45629595 Merge branch 'tyrav2-develop' of https://github.com/h4570/tyra into tyrav2-develop 2022-08-08 21:41:02 +02:00
h4570 0c4fff4f0c minor fixes 2022-08-08 21:40:47 +02:00
h4570 a3e4ee8496 obj loader refactor 2022-08-08 21:37:51 +02:00
h4570 599d44a491 add obj extension 2022-08-08 21:33:04 +02:00
h4570 5d632c36bf roadmap update 2022-08-08 21:32:49 +02:00
Sandro Sobczyński 01f4121242 Update bbox.cpp 2022-08-04 22:24:40 +02:00
h4570 153ebb52a5 mesh builder v2 2022-08-03 20:31:19 +02:00
h4570 689c8132d1 minor mesh refactor 2022-08-03 19:23:55 +02:00
h4570 82e5e87822 mcpip changes 2022-08-03 18:35:00 +02:00
h4570 0a024e745f renderer cleanup, demo changes 2022-08-03 10:37:27 +02:00
h4570 da958cb094 ztest option 2022-08-02 18:36:08 +02:00
h4570 5aae7cff7e demo skybox 2022-08-02 13:20:12 +02:00
h4570 cdadb932b7 clip comments 2022-08-01 18:37:49 +02:00
h4570 74668fba34 remove test code 2022-08-01 16:49:25 +02:00
h4570 4a9042b129 minor fixes 2022-08-01 13:37:48 +02:00
h4570 34b2956c08 demo buggy heightmap 2022-08-01 10:04:21 +02:00
h4570 47c323ec9e clip comments 2022-07-31 20:01:34 +02:00
h4570 4f3b731ad7 fixed clipper bug 2022-07-31 19:51:16 +02:00
h4570 b94ef8c416 demo player movement 2022-07-31 17:37:48 +02:00
h4570 12dd72f15e demo map and weapon 2022-07-31 16:24:46 +02:00
h4570 834d57ea32 demo memory leak fix 2022-07-31 11:52:49 +02:00
h4570 347fdb240b finished demo intro 2022-07-31 00:49:42 +02:00
h4570 bc1ac1b4a3 lod, prim refactor 2022-07-30 23:51:22 +02:00
h4570 927c10e82a deallocate pipeline in renderer on pipeline destroy 2022-07-30 18:17:48 +02:00
h4570 1bdb33e1a6 demo map 2022-07-30 17:00:22 +02:00
h4570 ff2967c7e5 support for 512x512 textures 2022-07-30 15:03:46 +02:00
h4570 b7b32fb35a demo 1 2022-07-30 14:48:59 +02:00
h4570 52a19f11a5 roadmap update 2022-07-29 23:11:54 +02:00
h4570 1a2f7026e5 fix copyrights 2022-07-29 23:11:12 +02:00
h4570 8591e35c4f add game template 2022-07-29 23:04:31 +02:00
h4570 d435d08cf8 fixed typos 2022-07-29 22:40:02 +02:00
h4570 b2f538bf1c roadmap fixes 2022-07-29 19:40:25 +02:00
h4570 97946e1c6d fixed textures overlapping 2022-07-29 19:04:55 +02:00
h4570 7ec6bb71b8 temporary fix for texture system 2022-07-28 23:54:53 +02:00
h4570 19e99eee56 fix coords 2022-07-28 21:29:58 +02:00
h4570 4366d6d6fb some bugfixes 2022-07-28 20:44:21 +02:00
h4570 960f4dd0c4 fix bug in deallocate tex 2022-07-28 11:51:16 +02:00
h4570 59077bcfe9 margin fix 2022-07-28 11:38:47 +02:00
h4570 e894039959 fix textures alloc problem 2022-07-28 11:34:28 +02:00
h4570 0107e888c7 vram margin fix 2022-07-28 11:02:52 +02:00
h4570 01e1d6adbf margin fix 2022-07-28 10:58:53 +02:00
h4570 31b7626bea fix roadmap 2022-07-28 10:52:59 +02:00
h4570 440f25d7d8 fix tex coords to full numbers 2022-07-28 10:52:38 +02:00
h4570 7a80c15ac8 disable interlacing and texture cache manager 2022-07-28 10:12:26 +02:00
h4570 dfb8bc73c3 add gitignore to bin 2022-07-27 00:15:15 +02:00
h4570 cf553b7376 remove irx file 2022-07-27 00:13:00 +02:00
h4570 af843fba87 add demo directory 2022-07-27 00:10:56 +02:00
h4570 21073a8a99 rename 2022-07-27 00:00:24 +02:00
h4570 b2c0bfbe11 fix roadmap 2022-07-26 23:17:42 +02:00
h4570 10164beadf some optimizations 2022-07-26 23:16:21 +02:00
h4570 97e44507ff obj loader 2022-07-26 20:27:01 +02:00
h4570 7a9b294945 free ram and tyrobj wip 2022-07-26 19:32:20 +02:00
h4570 70028a8f18 wellinator sample update 2022-07-25 21:18:15 +02:00
Sandro Sobczyński ff5757bf9b Merge pull request #121 from h4570/tyrav2-static-dynamic-pipelines
[Tyra2] Static/Dynamic pipeline/mesh
2022-07-25 21:11:05 +02:00
h4570 237066bfd4 finish of renderer refactor 2022-07-25 21:00:33 +02:00
h4570 0c63de8ac9 core renderer refactor finish 2022-07-25 20:10:46 +02:00
h4570 819a7c3de3 documentation update 2022-07-24 23:08:10 +02:00
h4570 c1f88d2f15 interlacing mode 2022-07-24 23:03:48 +02:00
h4570 7c1ab0bfaa texture allocation bugfix 2022-07-24 23:03:06 +02:00
h4570 9d18a81c2a vu1 packet spamming in static pipeline 2022-07-24 12:21:21 +02:00
h4570 cf8ca23ba9 small documentation 2022-07-23 21:47:18 +02:00
h4570 f5a7b7519e roadmap update 2022-07-23 21:14:17 +02:00
h4570 9a5993232a local todolist 2022-07-23 21:11:10 +02:00
h4570 91e425e0f8 small documentation 2022-07-23 21:05:20 +02:00
h4570 91ba265310 dynpip vu1 programs 2022-07-23 20:25:08 +02:00
h4570 1e2560c566 Merge branch 'tyrav2-develop' into tyrav2-static-dynamic-pipelines 2022-07-23 18:35:27 +02:00
h4570 23e98afe91 bbox fixes 2022-07-23 18:34:35 +02:00
h4570 e7a9230b59 vu1 animation 2022-07-23 18:32:38 +02:00
h4570 1ffba47119 spamming with vu1 packets 2 2022-07-23 15:55:38 +02:00
h4570 17d7634f1d Merge branch 'tyrav2-develop' into tyrav2-static-dynamic-pipelines 2022-07-23 14:37:17 +02:00
h4570 1ae7939cc3 tasks.json patch 2022-07-23 14:34:17 +02:00
h4570 22998fbbef allow recursive /res copy 2022-07-23 12:56:12 +02:00
h4570 c5aea0d50f spamming with multiple buffers to vu1 2022-07-22 00:12:36 +02:00
h4570 c8592e0c67 launching vu1 programs 2022-07-21 20:34:05 +02:00
h4570 0b60aa0f6d sending vu1 programs 2022-07-21 18:39:37 +02:00
h4570 aad634a241 Merge branch 'tyrav2-develop' into tyrav2-static-dynamic-pipelines 2022-07-21 17:56:17 +02:00
h4570 2c72abe081 dynamic pipeline - render 2022-07-21 17:47:10 +02:00
Sandro Sobczyński 04e89fd3a2 Merge pull request #117 from Wellinator/feature/tyrav2-physics
[Tyra2] Physics directory
2022-07-19 14:23:41 +02:00
Wellinator a9975c9da2 Merge branch 'tyrav2-develop' into feature/tyrav2-physics 2022-07-19 09:14:30 -03:00
Wellinator 81686a8033 refactor: apply review changes 2022-07-19 09:12:00 -03:00
Wellinator e7e4f375ba refactor: apply review changes 2022-07-19 08:59:04 -03:00
h4570 4e0785754e init of dynpip bag 2022-07-19 13:16:18 +02:00
h4570 86c11034bf roadmap update 2022-07-19 08:56:13 +02:00
Wellinator 07d7db97c2 feat: implements min and max bbox methods 2022-07-18 20:27:32 -03:00
h4570 7fd2926d1d some descriptions 2022-07-19 00:01:37 +02:00
h4570 dfd79a307e roadmap update 2022-07-18 23:53:25 +02:00
h4570 2fe40c8d90 dynpip rearrangment 2022-07-18 23:50:25 +02:00
h4570 f08fc1c8d3 bags refactor 2022-07-18 23:42:24 +02:00
h4570 0953ce3f19 init dynpip bag 2022-07-18 23:16:47 +02:00
h4570 efdec2c52e max vert count 2022-07-18 23:01:12 +02:00
h4570 9850028811 dynpip programs 2022-07-18 22:52:05 +02:00
h4570 a5e1a28164 dynpip files 2022-07-18 22:42:14 +02:00
h4570 95c01afa01 dynamic pipeline base 2022-07-18 21:49:38 +02:00
h4570 34c553af04 static mesh finish 2022-07-18 21:42:23 +02:00
Wellinator 85f4f2e666 refactor: moves isInFrustum from RenderBBox to CoreBBox 2022-07-18 16:11:46 -03:00
Wellinator f651ec76ac feat: implements ray 2022-07-18 16:11:18 -03:00
h4570 f249936981 dynamic mesh functions 2022-07-18 20:32:30 +02:00
h4570 c56c3d76db mesh base 2022-07-18 20:08:57 +02:00
h4570 ecfaef1b85 mesh -> dynamicmesh 2022-07-18 19:53:28 +02:00
h4570 bb02a3d9bf std pipeline rename 2022-07-18 19:46:28 +02:00
h4570 632be84ceb roadmap update 2022-07-18 19:33:14 +02:00
h4570 2797d71618 fixed gitignores 2022-07-17 11:31:46 +02:00
h4570 c8b22ff331 tyrav2 init 2022-07-17 10:21:35 +02:00
h4570 44c1ee4fe8 remove tyrav1 stuff 2022-07-17 10:15:37 +02:00
Sandro Sobczyński 7f619ec829 Merge pull request #99 from wolfysdl/master
fix some mistaken format on install.md
2021-11-23 16:03:31 +01:00
Wolf3s 94a77267a8 Merge branch 'master' into master 2021-11-23 10:38:56 -03:00
Wolfywolfy 950d0fc052 fix some mistaken typos 2021-11-23 10:33:55 -03:00
Sandro Sobczyński e11af10ba1 Merge pull request #98 from wolfysdl/master
Update information of installing on install.md and add new options on makefile
2021-11-23 14:28:52 +01:00
Wolfywolfy 4b0f2862d3 fix some mistaken typos 2021-11-23 10:26:34 -03:00
Wolfywolfy bb6956576b update install.md and fix typo 2021-11-23 08:30:16 -03:00
Wolfywolfy 288d27f97b add new tests option 2021-11-22 21:56:59 -03:00
Wolfywolfy 12de377525 update makefile 2021-11-22 21:39:18 -03:00
Sandro Sobczyński 0afd450c63 Merge pull request #97 from wolfysdl/master
Add new makefile to tyra
2021-11-22 20:15:26 +01:00
Wolfywolfy e9ff711c38 restore original makefile 2021-11-22 10:38:51 -03:00
Wolfywolfy 9a0504f94a typo fixed on makefile 2021-11-22 10:27:46 -03:00
Wolfywolfy 3ee31276ef examples 2021-11-22 10:02:12 -03:00
Wolfywolfy 3a68de50cb add new makefile, fix workflow errors and fix make 2021-11-22 09:14:44 -03:00
Sandro Sobczyński 7f9addbeb9 added additional unsets to prevent troubles 2021-06-01 22:16:01 +02:00
Sandro Sobczyński 3f3e6a0df4 fixed bounding box creation bug 2021-05-31 18:02:01 +02:00
h4570 7bfe7675cb added using of drawlist
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-29 17:57:12 +02:00
h4570 c7f210706d Merge branch 'master' into develop 2021-05-28 22:00:42 +02:00
Sandro Sobczyński 3a06ac548d Update README.MD 2021-05-28 21:59:34 +02:00
Sandro Sobczyński 8225abf328 Update README.MD 2021-05-28 21:59:24 +02:00
Sandro Sobczyński 2e23914c17 Update README.MD 2021-05-28 21:58:40 +02:00
Sandro Sobczyński e7c2f8a7c7 Update README.MD 2021-05-28 21:58:19 +02:00
Sandro Sobczyński 756fb216a4 Update README.MD 2021-05-28 21:58:00 +02:00
Sandro Sobczyński de4ce28839 Update README.MD 2021-05-28 21:57:16 +02:00
Sandro Sobczyński ed59d6b254 Update README.MD 2021-05-28 21:56:55 +02:00
Sandro Sobczyński 3fe9715958 Update README.MD 2021-05-28 21:56:39 +02:00
Sandro Sobczyński cba177f2db Update README.MD 2021-05-28 21:55:23 +02:00
Sandro Sobczyński 781c97eb73 updated version 2021-05-28 21:40:47 +02:00
Sandro Sobczyński 5245ba3f55 updated version 2021-05-28 21:40:09 +02:00
Sandro Sobczyński f0b5d25a27 updated version 2021-05-28 21:35:56 +02:00
h4570 5f22c02d2e added bin folders
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-28 21:31:28 +02:00
h4570 d63bd6cb0e fixed typo
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-28 21:26:47 +02:00
h4570 921f34eb4c fixed typo
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-28 21:26:16 +02:00
Sandro Sobczyński 385e553e5a changed tyra env path 2021-05-28 21:24:47 +02:00
Sandro Sobczyński e4230f1b62 added tyra env path 2021-05-28 21:22:10 +02:00
Sandro Sobczyński 94a353cdb8 Update CHANGELOG.MD 2021-05-28 21:17:51 +02:00
Sandro Sobczyński 8a162be036 Create compilation.yml 2021-05-28 21:16:56 +02:00
Sandro Sobczyński 1d273de455 Update README.MD 2021-05-28 21:08:57 +02:00
h4570 eecfc0b6c2 updated changelog
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-28 21:08:11 +02:00
h4570 7ff8153086 modified makefiles
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-28 21:08:07 +02:00
h4570 9cb52ff620 added install tutorial
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-28 21:07:58 +02:00
h4570 3023bb7501 update
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-28 21:07:46 +02:00
h4570 762e7eada2 modified changelog
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-28 19:40:20 +02:00
h4570 70ea8e47ba modified makefiles
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-28 19:31:23 +02:00
h4570 dd8499abad fixed PRINT_LOG in samples
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-28 19:30:45 +02:00
Sandro Sobczyński 0816f522bb Merge pull request #95 from h4570/assert
Add assertions
2021-05-26 19:39:08 +02:00
h4570 fafc66d35c replaced PRINT_LOG and PRINT_ERR
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-26 19:36:59 +02:00
h4570 d8458b98e0 added assert
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-25 21:31:20 +02:00
h4570 d0d7ed85e5 added pcsx2 to makefile (by wsl)
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-25 21:27:56 +02:00
Sandro Sobczyński a80f62e843 Merge pull request #94 from h4570/unit-test-proj
Unit tests support
2021-05-25 19:19:45 +02:00
h4570 8b0233a45d added unit tests support
Signed-off-by: h4570 <sandro.sobczynski@gmail.com>
2021-05-25 19:18:21 +02:00
Sandro Sobczyński 10b275055c Merge pull request #93 from Foxar/feature/bmploader_colordataoffset
bmp_loader: Auto skipping of color table information.
2021-04-23 20:02:09 +02:00
Sandro Sobczyński 164d9f558c Merge pull request #92 from Foxar/feature/bmploader_bitchecking
Feature/bmploader bitchecking
2021-04-23 20:00:45 +02:00
Foxar 247e71a407 Oops, uncommented function that was commented by accident. 2021-04-23 15:44:54 +02:00
Foxar ea49543542 Added offset to pixel data reading in bmp_loader 2021-04-23 15:36:44 +02:00
Foxar 20de0dc17d Removed redundant print 2021-04-21 10:55:25 +02:00
Foxar 1090801f4e Added checking for 24bitmap in file. 2021-04-21 10:41:32 +02:00
Sandro Sobczyński 7b43c0c90f Merge pull request #91 from Foxar/develop
Fixed loading erros in .obj loader when loading models without UVMap or Normals.
2021-04-19 11:35:06 +02:00
Foxar b0ae873a88 Adjusted scanf results checking to correct value, fixing the loading of models without set normals. 2021-04-19 11:19:18 +02:00
Foxar 7b3a28065b Fixed loading errors when loading models without Normals or UVMaps, by modifying the fscanf format, and adding a missing break statement. 2021-04-19 10:07:38 +02:00
Sandro Sobczyński 589b3b03a4 Merge pull request #90 from Foxar/develop
Dolphin sample deep diving crashing fix.
2021-04-18 23:41:09 +02:00
Foxar 611d4f76be Replaced renderer::draw() call with array of meshes and size of array as argument with a loop iterating through water tile array, calling draw on the individual water tiles. 2021-04-18 23:02:21 +02:00
Michał Mostowik bf0c65a14c Merge pull request #6 from h4570/develop
Update develop to newest version
2021-04-18 22:18:13 +02:00
Michał Mostowik ab0c999117 Merge pull request #5 from h4570/develop
Updating develop with h4570/tyra develop
2021-04-18 14:32:42 +02:00
Sandro Sobczyński 28599512e4 Update README.MD 2021-04-13 20:26:58 +02:00
Sandro Sobczyński db6c84ba11 Merge pull request #89 from Wellinator/cube-sample
Create basic cube sample
2021-04-13 20:22:33 +02:00
Wellinator b0c94a1602 Merge branch 'cube-sample' of github.com:Wellinator/tyra into cube-sample 2021-04-13 13:48:39 -03:00
Wellinator f34284591f Add README.MD 2021-04-13 13:48:29 -03:00
Sandro Sobczyński 7203f6f5c4 Delete readme.txt 2021-04-13 17:13:58 +02:00
Wellinator 94f6e9fbf2 Add header in all files in cube sample 2021-04-13 08:23:46 -03:00
Wellinator 18ba08dc7a Remove light_manager 2021-04-09 13:36:40 -03:00
Wellinator 9dd69317e3 Add readme file 2021-04-09 13:30:41 -03:00
Wellinator 24509f7f20 remove bin dir 2021-04-09 13:26:06 -03:00
Wellinator 9268628ccd update .gitignore 2021-04-09 13:23:25 -03:00
Wellinator 4160bddc4b Update scale and speed rotation 2021-04-09 13:19:12 -03:00
Wellinator e022fcdafe Update cube mesh object 2021-04-09 13:18:34 -03:00
Wellinator 444990a262 Change background color 2021-04-09 13:16:50 -03:00
Wellinator b749a80a25 Add rotation function 2021-04-08 08:33:06 -03:00
Wellinator e43fae88e8 Setup initial cube sample 2021-04-07 08:17:10 -03:00
Wellinator 11717f42eb Initial setup for Cube sample 2021-04-02 09:01:14 -03:00
Sandro Sobczyński 142bf60a6d Update README.MD 2021-02-07 17:03:16 +01:00
Sandro Sobczyński 9efd8ab3e1 Update README.MD 2021-02-07 14:13:31 +01:00
568 changed files with 35827 additions and 11604 deletions
+40
View File
@@ -0,0 +1,40 @@
# Use the Google style in this project.
BasedOnStyle: Google
# Some folks prefer to write "int& foo" while others prefer "int &foo". The
# Google Style Guide only asks for consistency within a project, we chose
# "int& foo" for this project:
DerivePointerAlignment: false
PointerAlignment: Left
SortIncludes: false
IncludeBlocks: Merge
IncludeCategories:
# Matches common headers first, but sorts them after project includes
- Regex: '^\"google/cloud/internal/disable_deprecation_warnings.inc\"$'
Priority: -1
- Regex: '^\"google/cloud/(internal/|grpc_utils/|testing_util/|[^/]+\.h)'
Priority: 1000
- Regex: '^\"google/cloud/' # project includes should sort first
Priority: 500
- Regex: '^\"'
Priority: 1500
- Regex: '^<grpc/'
Priority: 2000
- Regex: '^<google/*'
Priority: 3000
- Regex: '^<.*/.*'
Priority: 4000
- Regex: '^<[^/]*>'
Priority: 5000
# Format raw string literals with a `pb` or `proto` tag as proto.
RawStringFormats:
- Language: TextProto
Delimiters:
- 'pb'
- 'proto'
BasedOnStyle: Google
CommentPragmas: '(@copydoc)'
+5
View File
@@ -0,0 +1,5 @@
*.elf
.git/
.vscode/
docs/
tools/
+2
View File
@@ -0,0 +1,2 @@
# Ignore all differences in line endings
* -crlf
+33 -37
View File
@@ -1,37 +1,33 @@
.vscode/ # ---
# --- # Prerequisites
*.d
# Prerequisites
*.d # Compiled Object files
*.slo
# Compiled Object files *.lo
*.slo *.o
*.lo *.vsm
*.o
# Precompiled Headers
# Precompiled Headers *.gch
*.gch *.pch
*.pch
# Compiled Dynamic libraries
# Compiled Dynamic libraries *.so
*.so *.dylib
*.dylib *.dll
*.dll
# Compiled Static libraries
# Fortran module files *.lai
*.mod *.la
*.smod *.a
*.lib
# Compiled Static libraries
*.lai # Executables
*.la *.exe
*.a *.out
*.lib *.app
*.erl
# Executables *.elf
*.exe *.irx
*.out
*.app
*.erl
*.elf
+6
View File
@@ -0,0 +1,6 @@
*.log
# Configuration files
/c_cpp_properties.json
/tasks.json
/settings.json
@@ -0,0 +1,41 @@
{
"configurations": [
{
"name": "Docker PS2SDK",
"includePath": [
"${workspaceFolder}/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/ps2sdk/common/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/ps2sdk/ee/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/ps2sdk/iop/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/ps2sdk/ports/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/ee/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/ee/lib/gcc/mips64r5900el-ps2-elf/11.3.0/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/ee/lib/gcc/mips64r5900el-ps2-elf/11.3.0/include-fixed/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/ee/lib/gcc/mips64r5900el-ps2-elf/11.3.0/install-tools/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/ee/lib/gcc/mips64r5900el-ps2-elf/11.3.0/plugin/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/ee/mips64r5900el-ps2-elf/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/ee/mips64r5900el-ps2-elf/sys-include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/gsKit/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-elf/11.3.0/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-elf/11.3.0/install-tools/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-elf/11.3.0/plugin/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-elf/11.3.0/include-fixed/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-irx/11.3.0/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-irx/11.3.0/install-tools/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-irx/11.3.0/plugin/include/**",
"C:/Users/YOUR-INTELLISENSE-PATH/ps2dev-intellisense/iop/lib/gcc/mipsel-ps2-irx/11.3.0/include-fixed/**"
],
"defines": [
"_EE",
"_IOP",
"__SPU__",
"INTELLISENSE"
],
"cppStandard": "c++20",
"compilerPath": "", // Should be empty
"intelliSenseMode": "linux-gcc-x86",
"configurationProvider": "ms-vscode.cpptools"
}
],
"version": 4
}
+14
View File
@@ -0,0 +1,14 @@
{
"buildDirectory": "demo",
"C_Cpp.default.intelliSenseMode": "gcc-x86",
"files.associations": {
"*.vcl": "asm-collection",
"*.i": "asm-collection",
"*.vsm": "asm-collection",
"*.vclpp": "asm-collection",
"*.hpp": "cpp",
"*.cpp": "cpp",
"*.h": "c",
"*.c": "c"
}
}
+119
View File
@@ -0,0 +1,119 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Build & run",
"dependsOrder": "sequence",
"dependsOn": [
"1. Copy source code to docker volume",
"2. Compile via docker container",
"3. Copy binaries to host",
"4. Run PCSX2"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"type": "shell",
"label": "1. Copy source code to docker volume",
"command": "docker exec -t tyra-compiler sh -c 'rsync -ac --delete --exclude \".git\" --exclude \"docs\" --exclude \".vscode\" --exclude \"tools\" --exclude \"obj\" --exclude \"bin\" /host/ /src/'"
},
{
"type": "shell",
"label": "2. Compile via docker container",
"command": "docker exec -t tyra-compiler sh -c 'cd ${config:buildDirectory} && make build-engine all'",
"problemMatcher": {
"base": "$gcc",
"fileLocation": [
"autoDetect"
]
}
},
{
"type": "shell",
"label": "3. Copy binaries to host",
"command": "docker exec -t tyra-compiler sh -c 'rsync -zac --include=\"*/\" --include=\"bin/**\" --exclude=\"*\" /src/ /host/'"
},
{
"type": "shell",
"label": "4. Run PCSX2",
"options": {
"cwd": "${config:buildDirectory}"
},
"command": "./run.ps1"
},
{
"type": "shell",
"label": "Convert WAV to ADPCM",
"dependsOn": [
"1. Copy source code to docker volume"
],
"command": "docker exec -t tyra-compiler sh -c 'adpenc ${input:wav2adpcmSource} ${input:wav2adpcmTarget} && rsync -zac /src/${input:wav2adpcmTarget} /host/${input:wav2adpcmTarget}'"
},
{
"type": "shell",
"label": "Cleanup",
"command": "docker exec -t tyra-compiler sh -c 'rm -rf /src/*'"
},
{
"type": "shell",
"label": "Send to PS2",
"command": "docker exec -t tyra-compiler sh -c 'cd ${config:buildDirectory}/bin && killall -v ps2client || $true && ps2client -h ${input:ps2Ip} reset && ps2client -h ${input:ps2Ip} reset && ps2client -h ${input:ps2Ip} execee host:$(find . -maxdepth 1 -type f -name \"*.elf\")'"
},
{
"type": "shell",
"label": "Open PS2 output logger",
"command": "docker stop ps2-logs || $true && docker run -t --rm --name=ps2-logs -p ${input:local2Ip}:18194:18194/udp h4570/tyra sh -c 'ps2client -h ${input:ps2Ip} listen'",
"runOptions": {
"instanceLimit": 1
},
"presentation": {
"reveal": "always",
"panel": "new"
}
},
{
"type": "shell",
"label": "Start docker container",
"command": "docker compose up -d"
},
{
"type": "shell",
"label": "Stop docker container",
"command": "docker compose down"
},
{
"type": "shell",
"label": "[Debug] Copy obj directory to host",
"command": "docker exec -t tyra-compiler sh -c 'rsync -zac --include=\"*/\" --include=\"obj/**\" --exclude=\"*\" /src/ /host/'"
}
],
"inputs": [
{
"id": "wav2adpcmSource",
"description": "Source file path (ex. ):",
"default": "demo/res/sound.wav",
"type": "promptString"
},
{
"id": "wav2adpcmTarget",
"description": "Target file path (ex. ):",
"default": "demo/res/sound.adpcm",
"type": "promptString"
},
{
"id": "ps2Ip",
"description": "PS2link ip address:",
"default": "192.168.1.200",
"type": "promptString"
},
{
"id": "local2Ip",
"description": "Local ip address:",
"default": "192.168.1.245",
"type": "promptString"
}
]
}
+9
View File
@@ -0,0 +1,9 @@
{
"recommendations": [
"ms-vscode.cpptools-extension-pack",
"ryzngard.vscode-header-source",
"maziac.asm-code-lens",
"dmnsgn.vscode-wavefront",
"spmeesseman.vscode-taskexplorer"
]
}
-117
View File
@@ -1,117 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.31.2] - 2021-02-06
### Added
- Id to MeshFrame
- Non textured rendering (RGBA only)
### Changed
- Moved color from mesh to mesh material.
- OBJ Loader refactor
- Logic of loadFrom()
- Migrated to GCC9 (valid with latest PS2SDK)
### Removed
- Removed MeshId from TextureLink, TextureRepository
## [1.29.1] - 2020-12-27
### Added
- Created libpacket2 in PS2SDK
- Dolphin sample
- 2D support (Sprite class)
- Alpha blending (transparency)
- PNG support
- ADPCM support in audio class
- AudioFinish event in audio class
- BoundingBox class
- A lot of useful funcs in Matrix class
- Mock of file service
- Array mode to draw() (highly optimized for small meshes)
- VCLPP - Usage of VU1 Preprocessor
### Changed
- Project setup (makefile mostly)
- Readme
- Switched into libpacket2 in `vifsender` and `gifsender`
- Timer class refactor
- Engine base refactor
- MeshTexture into Texture
- Refactored floors sample
- Refactored Audio class
- Fixed Path 3 lighting
- Refactored, optimized math classes (vector, matrix..)
- Cleanup in camera base
- Refactored Path 3 and Path 1 rendering
- Synchronization functions (`renderer->waitForRender()`)
- BMP class refactor
- Dff Loader refactor
- Optimized rendering data preparation
### Removed
- Ari sample
- VU1 class
## [1.1.0] - 2020-11-03
### Added
- A lot of useful functions to Mesh class
- MeshFrame class
- MeshMaterial class
- MeshTexture class
- TextureLink struct
- Texture wrapping settings
- TextureRepository class
- PRINT_ERR()
- Ari sample
### Changed
- Project setup (gitignore etc.)
- Readme
- DFF loader refactor
- OBJ loader refactor
- MD2 loader refactor
- 3D data classes refactor (one interface for all)
- Rendering refactor
### Removed
- MeshSpec class
- Texture class
- Md2Model class
- ObjModel class
- DffModel class
## [1.0.0] - 2020-10-28
### Added
- Project setup (gitignore etc.)
- License
- Readme
- BMP support
- DFF support
- MD2 support
- OBJ support
- Animation support
- Engine base
- AudioListener class
- Rendering base
- Path 1 renderer (VU1)
- Path 3 renderer (GIF)
- Math classes (matrix, vector, plane..)
- Audio support (bg song only)
- Camera base
- Base lighting support (bugged) for Path 3
- Pad support
- EE Timer
- Math class
- String class
- Mesh class with AABB
- Makefile
- Primitive floors sample
[1.31.2]: https://github.com/h4570/tyra/compare/v1.29.1-alpha...v1.31.2-alpha
[1.29.1]: https://github.com/h4570/tyra/compare/1.1.0...v1.29.1-alpha
[1.1.0]: https://github.com/h4570/tyra/compare/1.0.0...1.1.0
[1.0.0]: https://github.com/h4570/tyra/compare/1.0.0
+67
View File
@@ -0,0 +1,67 @@
# syntax=docker/dockerfile:1
FROM ubuntu:20.04
# Install necessary packages for PS2DEV, VCLPP and VCL.
RUN apt-get update
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get install -y git make g++ texinfo bison flex gettext libgmp3-dev \
libmpfr-dev libmpc-dev gcc binutils cmake wget patch zlib1g-dev libgsl-dev \
unzip
# Setup PS2DEV env
ENV PS2DEV /usr/local/ps2dev
RUN mkdir -p $PS2DEV
RUN chown -R $USER: $PS2DEV
ENV PS2SDK $PS2DEV/ps2sdk
ENV GSKIT $PS2DEV/gsKit
ENV PATH $PATH:${PS2DEV}/bin:${PS2DEV}/ee/bin:${PS2DEV}/iop/bin:${PS2DEV}/dvp/bin:${PS2SDK}/bin
# Compile PS2DEV
RUN mkdir -p /temp/ps2dev
RUN git clone https://github.com/ps2dev/ps2dev.git /temp/ps2dev
WORKDIR "/temp/ps2dev"
RUN ./build-all.sh
# Compile VCLPP
RUN mkdir -p /temp/vclpp
RUN git clone https://github.com/glampert/vclpp.git /temp/vclpp
WORKDIR "/temp/vclpp"
RUN make
# Download VCL
RUN mkdir -p /temp/vcl
WORKDIR "/temp/vcl"
RUN wget http://apgcglz.cluster028.hosting.ovh.net/tyra/vcl.zip
RUN unzip vcl.zip
# ------------------------------------------------------------------------------
# Start from clean image
FROM ubuntu:20.04
# Set ENV variables
ENV PS2DEV /usr/local/ps2dev
ENV PS2SDK $PS2DEV/ps2sdk
ENV PATH $PATH:${PS2DEV}/bin:${PS2DEV}/ee/bin:${PS2DEV}/iop/bin:${PS2DEV}/dvp/bin:${PS2SDK}/bin
# Copy stuff from previous stage
COPY --from=0 ${PS2DEV} ${PS2DEV}
COPY --from=0 /temp/vcl/vcl /usr/bin/vcl
COPY --from=0 /temp/vclpp/vclpp /usr/bin/vclpp
# Install packages for emulating x86 and Tyra (make, libmpc, psmisc)
RUN apt-get update
RUN apt-get install -y make rsync libmpc-dev qemu qemu-user-static binfmt-support psmisc
# Add 32bit executables support for VCL
RUN dpkg --add-architecture i386
RUN apt-get update
RUN apt-get install -y libstdc++5:i386
RUN update-binfmts --install i386 /usr/bin/qemu-i386-static --magic '\x7fELF\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00' --mask '\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xf8\xff\xff\xff\xff\xff\xff\xff'
# Set chmod
RUN chmod 755 /usr/bin/vclpp
RUN chmod 755 /usr/bin/vcl
WORKDIR /src
CMD ["/bin/bash"]
-201
View File
@@ -1,201 +0,0 @@
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
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+117
View File
@@ -0,0 +1,117 @@
#Compiler and Linker
EE_PREFIX := mips64r5900el-ps2-elf-
AR := $(EE_PREFIX)ar
AS := $(EE_PREFIX)as
CC := $(EE_PREFIX)gcc
CXX := $(EE_PREFIX)g++
STRIP := $(EE_PREFIX)strip
BIN2S := $(PS2SDK)/bin/bin2s
VCL := vcl
VCLPP := vclpp
DVP := dvp-as
IRXEMBEDDEDEXT := irx-em
#Flags, Libraries and Includes
CFLAGS += -D_EE -Wall -O3
LINKFLAGS += -O3 -Wl,-zmax-page-size=128
ASFLAGS += -O3
LIB += -lstdc++ -ldma -lpacket2 -lgraph -ldraw -lmath3d -lpng -lz -lpad -laudsrv -lpatches -lcdvd
INC += -I$(PS2DEV)/ps2sdk/ee/include -I$(PS2DEV)/ps2sdk/common/include -I$(PS2DEV)/ps2sdk/ports/include
#---------------------------------------------------------------------------------
#DO NOT EDIT BELOW THIS LINE
#---------------------------------------------------------------------------------
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.$(OBJEXT)))
IRXEM_SOURCES := $(shell find $(SRCDIR) -type f -name *.$(IRXEMBEDDEDEXT))
IRXEM_OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(IRXEM_SOURCES:.$(IRXEMBEDDEDEXT)=.$(OBJEXT)))
VU_SOURCES_VCL := $(shell find $(SRCDIR) -type f -name *.$(VCLEXT))
VU_OBJECTS_VCL := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(VU_SOURCES_VCL:.$(VCLEXT)=.$(OBJEXT)))
VU_SOURCES_VSM := $(shell find $(SRCDIR) -type f -name *.$(VSMEXT))
VU_OBJECTS_VSM := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(VU_SOURCES_VSM:.$(VSMEXT)=.$(OBJEXT)))
VCL_SOURCES := $(shell find $(SRCDIR) -type f -name *.$(VCLPPEXT))
VCL_OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(VCL_SOURCES:.$(VCLPPEXT)=.$(OBJEXT)))
#Default Make
all: resources $(TARGET)
#all: resources irxcopy $(TARGET)
release:
$(MAKE) CFLAGS="-DNDEBUG $(CFLAGS)"
#Remake
remake: cleaner all
#Copy Resources from Resources Directory to Target Directory
resources: directories
@cp -r $(RESDIR)/* $(TARGETDIR)/ || true
#Make the Directories
directories:
@mkdir -p $(TARGETDIR)
@mkdir -p $(BUILDDIR)
#Clean only Objects
clean:
@$(RM) -rf $(BUILDDIR)
#Full Clean, Objects and Binaries
cleaner: clean
@$(RM) -rf $(TARGETDIR)
@$(RM) -rf $(BUILDDIR)
#irxcopy:
# @cp $(PS2SDK)/iop/irx/audsrv.irx $(TARGETDIR)/audsrv.irx
#Pull in dependency info for *existing* .o files
-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT))
#Link
$(TARGET): $(OBJECTS) $(VCL_OBJECTS) $(VU_OBJECTS_VCL) $(VU_OBJECTS_VSM) $(IRXEM_OBJECTS)
$(CXX) -T$(PS2DEV)/ps2sdk/ee/startup/linkfile -o $(TARGETDIR)/$(TARGET) $^ -L$(PS2DEV)/ps2sdk/ee/lib -L$(PS2SDK)/ports/lib $(LINKFLAGS) $(LIBDIRS) $(LIB)
$(STRIP) --strip-all $(TARGETDIR)/$(TARGET)
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(IRXEMBEDDEDEXT)
@mkdir -p $(dir $@)
@rm -f $@.s
$(BIN2S) $(shell head -1 $<) $@.s $(shell sed -n '2p' $<)
$(AS) $(ASFLAGS) $@.s -o $@
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SRCEXT)
@mkdir -p $(dir $@)
$(CXX) $(CFLAGS) $(INC) -c -o $@ $<
@$(CXX) $(CFLAGS) $(INCDEP) -MM $(SRCDIR)/$*.$(SRCEXT) > $(BUILDDIR)/$*.$(DEPEXT)
@cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp
@sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT)
@sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT)
@rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(VCLEXT)
@mkdir -p $(dir $@)
@rm -f $@.vsm
$(VCL) $< >> $@.vsm
$(DVP) $@.vsm -o $@
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(VSMEXT)
@mkdir -p $(dir $@)
$(DVP) $< -o $@
$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(VCLPPEXT)
@mkdir -p $(dir $@)
@rm -f $@.vcl
@rm -f $@.vsm
$(VCLPP) $< $@.vcl
$(VCL) $@.vcl > $@.vsm
$(DVP) $@.vsm -o $@
run-pcsx2:
taskkill.exe /f /t /im pcsx2x64.exe || true
$(WSL_LINUX_PCSX2)/pcsx2x64.exe --elf=$(WSL_MAKE_WINDOWS)$(CURDIR)/$(TARGETDIR)/$(TARGET)
#Non-File Targets
.PHONY: all remake clean cleaner resources
+168 -157
View File
@@ -1,157 +1,168 @@
[![Contributors][contributors-shield]][contributors-url] [![Codacy Badge](https://app.codacy.com/project/badge/Grade/b81ab27f1c774f839729829c9f772b1a)](https://www.codacy.com/gh/h4570/tyra/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=h4570/tyra&amp;utm_campaign=Badge_Grade)
[![MIT License][license-shield]][license-url] [![Contributors][contributors-shield]][contributors-url]
[![Discord](https://img.shields.io/badge/discord-Tyra-brightgreen?logo=discord)](https://discord.gg/NhhTmg3Gm5) [![MIT License][license-shield]][license-url]
[![Discord](https://img.shields.io/badge/discord-PS2--Scene-brightgreen?logo=discord)](https://discord.gg/7dCr6ThSN5) [![Discord](https://img.shields.io/badge/discord-Tyra-brightgreen?logo=discord)](https://discord.gg/NhhTmg3Gm5)
[![Discord](https://img.shields.io/badge/discord-PS2--Scene-brightgreen?logo=discord)](https://discord.gg/7dCr6ThSN5)
<br />
<p align="center"> <br />
<a href="https://github.com/h4570/tyra"> <p align="center">
<img src="http://apgcglz.cluster028.hosting.ovh.net/tyra/github-splash.png" alt="Logo" width="100%" height="auto"> <a href="https://github.com/h4570/tyra">
</a> <img src="http://apgcglz.cluster028.hosting.ovh.net/tyra/github-splash.png" alt="Logo" width="100%" height="auto">
</a>
<h3 align="center">Tyra - alpha 1.31.2</h3>
<h3 align="center">Tyra - 2.0.0</h3>
<p align="center">
Open source game engine for PlayStation 2™ <p align="center">
<br /> Open source game engine for PlayStation 2™
<a href="https://github.com/h4570/tyra/tree/master/src/samples/dolphin"><strong>Dolphin sample »</strong></a> <br />
&nbsp; <a href="https://youtube.com/playlist?list=PLdQVLBcXRRWvtMi-OqccDWLTEFEisD5RH"><strong>YouTube tutorials »</strong></a>
<a href="https://github.com/h4570/tyra/tree/master/src/samples/floors"><strong>Floors sample »</strong></a> &nbsp;
<br /> <br />
<br /> <br />
<a href="https://github.com/h4570/tyra/issues">Report Bug</a> <a href="https://github.com/h4570/tyra/issues">Report Bug</a>
· ·
<a href="https://github.com/h4570/tyra/issues">Request Feature</a> <a href="https://github.com/h4570/tyra/issues">Request Feature</a>
</p> </p>
</p> </p>
## Table of Contents [![Stargazers repo roster for h4570/tyra](https://reporoster.com/stars/h4570/tyra)](https://github.com/h4570/tyra/stargazers)
* [About the Project](#about-the-project) ## Table of Contents
* [Samples](#samples)
* [About project](#about-project) * [About the project](#about-the-project)
* [Tyra features](#tyra-features) * [Description](#description)
* [Branches](#branches) * [Tutorials](#tutorials)
* [Getting Started](#getting-started) * [Features](#features)
* [Installation](#installation) * [Branches](#branches)
* [Prerequisites](#prerequisites) * [Contributing](#contributing)
* [Roadmap](#roadmap) * [Games](#games)
* [Tyra team](#tyra-team) * [License](#license)
* [Contributing](#contributing) * [Built With](#built-with)
* [License](#license) * [Acronyms](#acronyms)
* [Built With](#built-with) * [Credits](#credits)
* [Acronyms](#acronyms)
* [Thanks](#thanks) ## About the Project
<p align="center">
## About The Project <img src="http://apgcglz.cluster028.hosting.ovh.net/tyra/tyra_code.gif" alt="Sample code" width="500" height="auto">
<img src="http://apgcglz.cluster028.hosting.ovh.net/tyra/showcase.gif " alt="Sample game" width="500" height="auto">
<img src="http://apgcglz.cluster028.hosting.ovh.net/tyra/1.31.2/tyra.gif" alt="sample" width="600" height="auto"> </p>
### Samples ---
* [Dolphin](https://github.com/h4570/tyra/tree/master/src/samples/dolphin) ### Description
* [Floors](https://github.com/h4570/tyra/tree/master/src/samples/floors) Tyra is a project that allows you to easily create games for the PlayStation 2 console.
When I tried to make a game for PS2 a few years ago, I realized how many things had to be done to tame this exotic console architecture.
### About project Decision was simple - I need to create an engine which will handle 3D file loading, 2D/3D rendering, animation, audio, handling between PS2 CPUs, synchronization.. It should be simple as possible - so people with no experience can create a simple game in a few hours.
Goal of Tyra project is to provide simple API for PS2 game creation, so you can just run PS2 emulator, grab .obj file, and put it into live in a seconds. Project is on alpha stage, so keep in mind that there are many things to be done and to fix. **And that's what Tyra is all about.**
YouTube tutorials soon! ### Tutorials
* 01 - Setup environment - [Text tutorial](https://github.com/h4570/tyra/tree/master/docs/install) or [Video](https://www.youtube.com/watch?v=9IXOU1SPdzc)
**Why Tyra is needed?** Raw PS2 development can be a big challenge. PS2 it's pretty low-level and there are a lot of stuff that you must do from scratch. * 02 - Cooking game assets - [Video](https://www.youtube.com/watch?v=LjO71ovPFJs)
Tyra takes care for you, and rendering, coprocessors communication, synchronization and many more low-level stuff is already done. * 03 - Create a game repository - [Video](https://www.youtube.com/watch?v=DKfIKar3GUM)
* 04 - Run game from USB in PS2 - [Video](https://www.youtube.com/watch?v=ZX8fTQqiNho)
### Tyra features ---
* 3D support - VU1 "Path 1 rendering" * 01 - [Code](https://github.com/h4570/tyra/tree/master/tutorials/01-hello) - Hello world
* 2D support - PNG & BMP * 02 - [Code](https://github.com/h4570/tyra/tree/master/tutorials/02-sprite) - 2D rendering
* Frustum culling, backface culling * 03 - [Code](https://github.com/h4570/tyra/tree/master/tutorials/03-minecraft) - 3D minecraft blocks
* OpenGL adaptions: Perspective projection, lookAt camera * 04 - [Code](https://github.com/h4570/tyra/tree/master/tutorials/04-de_dust2) - `de_dust2.obj` rendering
* Texture support - .bmp and png * 05 - [Code](https://github.com/h4570/tyra/tree/master/tutorials/05-animation) - 3D animation
* Mesh loaders: ".obj", ".dff" (RenderWare, GTA:SA) and ".md2" (Quake II) * 06 - [Code](https://github.com/h4570/tyra/tree/master/tutorials/06-audio) - Background music and sound effects
* Threading support * 07 - [Code](https://github.com/h4570/tyra/tree/master/tutorials/07-lighting) - Static lightmap and dynamic directional lights
* Animation support for obj and md2 * 08 - [Code](https://github.com/h4570/tyra/tree/master/tutorials/08-skybox-debug) - Skybox and debug rendering
* Audio support - .wav and .adpcm * 09 - [Code](https://github.com/h4570/tyra/tree/master/tutorials/09-manual-mode) - Manual rendering (a'la OpenGL)
* Pad support * Demo game - [Code](https://github.com/h4570/tyra/tree/master/demo)
---
### Branches
* Master - monthly releases - tested on PS2 & PCSX2. ### Features
* Develop - daily builds - can be unstable. * Docker image with Tyra, all tools and `PS2DEV` C++20 compiler
* 3D rendering via `VU1` coprocessor:
## Getting Started * Static rendering
* Morph animation rendering
### Installation [![Discord](https://img.shields.io/badge/discord-Tyra-brightgreen?logo=discord)](https://discord.gg/NhhTmg3Gm5) * Super optimized, custom minecraft block renderer
In our Discord channel, there is detailed tutorial which will help you with setting up the all environment - starting from installing dependencies and ending on emulator setup or intellisense. * Debug rendering (lines, boxes, bboxes)
* Manual rendering (a'la `OpenGL`)
### Prerequisites * 2D rendering
* Frustum culling:
This is an example of how to list things you need to use the software. * Simple - culling whole mesh
* PS2 DEV environment - [PS2DEV](https://github.com/ps2dev/ps2dev) * Precise - culling only visible parts of mesh
* At least #e8e9edb PS2SDK (06.02.2021) - [PS2SDK](https://github.com/ps2dev/ps2sdk) * Clipping:
* PS2 Emulator. For example [PCSX2](https://pcsx2.net/) * Standard "fake", but fast PS2 clipping done in `VU1`
* Software clipping done in `EE Core`
## Extra info * Optimized math functions via `VU0` coprocessor
* BMP loader needs some polishing so be sure that you exporting BMP with 24bit: RGB888 and without information about colors. * Background music and sound effects support
* If you want to run .elf in PCSX2, be sure that you have version >=1.6 and **Host access** enabled in PCSX2 configuration file. * Pad support
* If you want to use your own .obj file, please check "triangulate faces" in blender. PS2 is supporting only triangle primitive type. * USB support
* Memory card support
## Roadmap * `.wav` Audio file support
* `.obj` 3D file support
### Roadmap for next master release: * `.md2` 3D file support
[Next release roadmap](https://github.com/h4570/tyra/projects/4) * `.png` Texture file support
## Tyra team ### Branches
* `master` - stable releases - tested on PS2 & PCSX2.
Sandro Sobczyński - sandro.sobczynski@gmail.com * `develop` - daily builds.
[![LinkedIn][linkedin-shield]](https://linkedin.com/in/sandro-sobczyński-28820b15a)
Michał Mostowik - mostek3pl@gmail.com See the [open issues](https://github.com/h4570/tyra/issues) for a list of proposed features (and known issues).
[![LinkedIn][linkedin-shield]](https://www.linkedin.com/in/notfoxar)
## Contributing
See the [open issues](https://github.com/h4570/tyra/issues) for a list of proposed features (and known issues).
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.
## Contributing
1. Fork the Project
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. 2. Create your Feature Branch (`git checkout -b feature/amazing-feature`)
3. Commit your Changes (`git commit -m 'Add some amazing-feature'`)
1. Fork the Project 4. Push to the Branch (`git push origin feature/amazing-feature`)
2. Create your Feature Branch (`git checkout -b feature/amazing-feature`) 5. Open a Pull Request
3. Commit your Changes (`git commit -m 'Add some amazing-feature'`)
4. Push to the Branch (`git push origin feature/amazing-feature`) ## Games
5. Open a Pull Request
List of games developed with Tyra.
## License If you created one, please contact me - I will add it to the list :)
Distributed under the Apache License 2.0 License. See `LICENSE` for more information. * [Tyracraft](https://github.com/Wellinator/tyracraft)
## Built With ## License
* [PS2SDK](https://github.com/ps2dev/ps2sdk) Distributed under the Apache License 2.0 License. See `LICENSE` for more information.
### Acronyms ## Built With
* EE (Emotion Engine) - whole set of processors and subsystems that make up the PlayStation 2
* GS (Graphic synthesizer) - configurable rasterizer and texture mapper. Has only 2MB~ memory for textures, but for the opposite have very high transfer rate, so you can switch textures in the blink * [PS2DEV](https://github.com/ps2dev/ps2dev)
* VU0 - programmable (ASM) vector processor that is accessed by inline assembly code injected into C program. * [VCLPP](https://github.com/glampert/vclpp)
* VU1 - programmable (ASM) vector processor, which is similar to vertex shader. Accessed via DMA. * Sony VCL
* IOP - I/O processor which enables access to peripheral devices, such the game controller
## Acronyms
## Thanks * EE (Emotion Engine) - whole set of processors and subsystems that make up the PlayStation 2
* EE Core - main PS2 CPU (c++ done here)
Without these guys, everything would be harder: * GS (Graphic synthesizer) - configurable rasterizer and texture mapper. Has only 2MB~ memory for textures, but for the opposite have very high transfer rate, so you can switch textures in the blink
* Dr Henry Fortuna - for code sources * VU0 - programmable (ASM) vector processor that is accessed by inline assembly code injected into C program.
* Rick Gaiser - for help and new GCC! * VU1 - programmable (ASM) vector processor, which is similar to vertex shader. Accessed via DMA.
* Lukasz D.K. - for huge archive of PS2 stuff * IOP - I/O processor which enables access to peripheral devices, such the game controller
* Guilherme Lampert - for code sources
* Jesper Svennevid, Daniel Collin - for openvcl's code samples ## Credits
* Whole PS2DEV team
* Manieq - for nice splash screens! Without these guys, Tyra would not happen:
* And so many other guys. Thanks! * Dr Henry Fortuna - for code sources, PS2 academy tutorials
* Rick Gaiser, fjtrujy - for maintaining PS2DEV
Project Link: [https://github.com/h4570/tyra](https://github.com/h4570/tyra) * Wellington Carvalho - for testing, contributing to Tyra and sharing cool ideas!
* Leonardo Ono - for software renderer example (with clipping!)
<br /> * Lukasz D.K. - for huge archive of PS2 stuff
<a href="https://github.com/h4570/tyra"> * Guilherme Lampert - for code sources
<img src="http://apgcglz.cluster028.hosting.ovh.net/tyra/github-splash2.png" alt="Logo" width="100%" height="auto"> * Jesper Svennevid, Daniel Collin - for openvcl's code samples
</a> * Whole PS2DEV team
* Manieq - for nice splash screens!
[contributors-shield]: https://img.shields.io/github/contributors/h4570/tyra.svg?style=flat-square * And so many other guys. Thanks!
[contributors-url]: https://github.com/h4570/tyra/graphs/contributors
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=flat-square&logo=linkedin&colorB=555 Project Link: [https://github.com/h4570/tyra](https://github.com/h4570/tyra)
[license-shield]: https://img.shields.io/github/license/h4570/tyra.svg?style=flat-square Sandro Sobczyński - sandro.sobczynski@gmail.com
[license-url]: https://github.com/h4570/tyra/blob/master/LICENSE [![LinkedIn][linkedin-shield]](https://linkedin.com/in/sandro-sobczyński-28820b15a)
<br />
<a href="https://github.com/h4570/tyra">
<img src="http://apgcglz.cluster028.hosting.ovh.net/tyra/github-splash2.png" alt="Logo" width="100%" height="auto">
</a>
[contributors-shield]: https://img.shields.io/github/contributors/h4570/tyra.svg?style=flat-square
[contributors-url]: https://github.com/h4570/tyra/graphs/contributors
[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=flat-square&logo=linkedin&colorB=555
[license-shield]: https://img.shields.io/github/license/h4570/tyra.svg?style=flat-square
[license-url]: https://github.com/h4570/tyra/blob/master/LICENSE
+33
View File
@@ -0,0 +1,33 @@
TARGET := demo.elf
ENGINEDIR := ../engine
#The Directories, Source, Includes, Objects, Binary and Resources
SRCDIR := src
INCDIR := inc
BUILDDIR := obj
TARGETDIR := bin
RESDIR := res
SRCEXT := cpp
VSMEXT := vsm
VCLEXT := vcl
VCLPPEXT := vclpp
DEPEXT := d
OBJEXT := o
#Flags, Libraries and Includes
CFLAGS :=
LIB := -ltyra
LIBDIRS := -L$(ENGINEDIR)/bin
INC := -I$(INCDIR) -I$(ENGINEDIR)/inc
INCDEP := -I$(INCDIR) -I$(ENGINEDIR)/inc
include ../Makefile.base
clean-engine:
cd $(ENGINEDIR) && $(MAKE) cleaner
build-engine:
cd $(ENGINEDIR) && $(MAKE)
build-release-engine:
cd $(ENGINEDIR) && $(MAKE) release
+4
View File
@@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore
+34
View File
@@ -0,0 +1,34 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
#include "state/state_manager.hpp"
using Tyra::Engine;
using Tyra::Game;
namespace Demo {
class DemoGame : public Game {
public:
DemoGame(Engine* engine);
~DemoGame();
void init();
void loop();
private:
Engine* engine;
StateManager<GlobalStateType> stateManager;
};
} // namespace Demo
+17
View File
@@ -0,0 +1,17 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
namespace Demo {
const bool IS_REAL_PS2_VIA_USB = false;
} // namespace Demo
+17
View File
@@ -0,0 +1,17 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
namespace Demo {
enum GlobalStateType { STATE_INTRO, STATE_LOADING, STATE_GAME, STATE_EXIT };
} // namespace Demo
+40
View File
@@ -0,0 +1,40 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <engine.hpp>
using Tyra::Engine;
namespace Demo {
template <typename StateTypeT>
class State {
public:
State(Engine* t_engine) : engine(t_engine) {}
virtual ~State() {}
virtual const StateTypeT& getState() const = 0;
virtual const bool& wantFinish() const = 0;
virtual void onStart() = 0;
virtual void update() = 0;
/** @return Next game state */
virtual StateTypeT onFinish() = 0;
protected:
Engine* engine;
};
} // namespace Demo
+99
View File
@@ -0,0 +1,99 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <vector>
#include "./state.hpp"
#include "./global_state_type.hpp"
namespace Demo {
template <typename StateTypeT>
class StateManager {
public:
StateManager(const StateTypeT& t_initialState,
const StateTypeT& t_exitState) {
stateInitialized = false;
currentState = t_initialState;
exitState = t_exitState;
}
~StateManager() { freeAll(); }
const StateTypeT& getCurrentState() const { return currentState; }
const StateTypeT& getExitState() const { return exitState; }
bool finished() const { return currentState == exitState; }
std::vector<State<StateTypeT>*>* getAll() { return &states; }
State<StateTypeT>* get(const StateTypeT& stateType) {
for (auto& state : states) {
if (state->getState() == stateType) {
return state;
}
}
return nullptr;
}
void add(State<StateTypeT>* state) { states.push_back(state); }
/** remove (without free) */
void remove(const State<StateTypeT>* state) {
states.erase(std::remove(states.begin(), states.end(), state),
states.end());
}
/** free and remove */
void free(const State<StateTypeT>* state) {
auto* found = get(state);
if (!found) return;
remove(found);
delete found;
}
/** free and remove all */
void freeAll() {
for (auto& state : states) {
delete state;
}
states.clear();
}
void update() {
for (auto& state : states) {
if (state->getState() == currentState) {
if (state->wantFinish()) {
currentState = state->onFinish();
stateInitialized = false;
break;
}
if (!stateInitialized) {
state->onStart();
stateInitialized = true;
}
state->update();
break;
}
}
}
private:
bool stateInitialized;
std::vector<State<StateTypeT>*> states;
StateTypeT currentState, exitState;
};
} // namespace Demo
+63
View File
@@ -0,0 +1,63 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
#include "states/game/renderer/renderer_dynamic_pair.hpp"
#include "states/game/terrain/heightmap.hpp"
#include "states/game/player/player_shoot_action.hpp"
#include "./enemy_info.hpp"
using Tyra::AnimationSequenceCallback;
using Tyra::Audio;
using Tyra::DynamicMesh;
using Tyra::DynPipOptions;
using Tyra::Engine;
using Tyra::Renderer;
using Tyra::Renderer3DUtility;
using Tyra::TextureRepository;
using Tyra::Vec4;
namespace Demo {
class Enemy {
public:
Enemy(Engine* engine, const EnemyInfo& info);
~Enemy();
DynamicMesh* mesh;
DynPipOptions* options;
RendererDynamicPair* pair;
void update(const Heightmap& heightmap, const Vec4& playerPosition,
const PlayerShootAction& shootAction);
private:
std::vector<u32> walkSequence;
std::vector<u32> fightSequence;
void allocateOptions();
void walk(const Heightmap& heightmap, const Vec4& positionDiff);
void animationCallback(const AnimationSequenceCallback& callback);
void fight();
void handlePlayerShoot(const PlayerShootAction& shootAction);
void setMeshToSpawn();
bool isWalking = true;
bool isFighting = false;
Vec4 terrainLeftUp;
Vec4 terrainRightDown;
Audio* audio;
EnemyInfo info;
};
} // namespace Demo
+33
View File
@@ -0,0 +1,33 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
#include <audsrv.h>
using Tyra::DynamicMesh;
using Tyra::Texture;
using Tyra::Vec4;
namespace Demo {
struct EnemyInfo {
u8 adpcmChannel;
audsrv_adpcm_t* adpcmPunch;
audsrv_adpcm_t* adpcmDeath;
DynamicMesh* motherMesh;
Texture* bodyTexture;
Texture* clothTexture;
Vec4 terrainLeftUp;
Vec4 terrainRightDown;
};
} // namespace Demo
@@ -0,0 +1,45 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
#include <vector>
#include "states/game/terrain/heightmap.hpp"
#include "states/game/player/player_shoot_action.hpp"
#include "./enemy.hpp"
using Tyra::DynamicMesh;
using Tyra::Engine;
using Tyra::Texture;
using Tyra::TextureRepository;
using Tyra::Vec4;
namespace Demo {
class EnemyManager {
public:
EnemyManager(Engine* engine, const Heightmap& heightmap);
~EnemyManager();
void update(const Heightmap& heightmap, const Vec4& playerPosition,
const PlayerShootAction& shootAction);
std::vector<RendererDynamicPair*> getPairs() const;
private:
TextureRepository* textureRepo;
std::vector<Enemy*> enemies;
DynamicMesh* motherMesh;
Texture* bodyTexture;
Texture* clothTexture;
};
} // namespace Demo
+58
View File
@@ -0,0 +1,58 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "state/state.hpp"
#include "state/global_state_type.hpp"
#include "./player/player.hpp"
#include "./renderer/game_renderer.hpp"
#include "./terrain/terrain.hpp"
#include "./skybox/skybox.hpp"
#include "./ship/ship.hpp"
#include "./hud/hud.hpp"
#include "./enemy/enemy_manager.hpp"
using std::unique_ptr;
namespace Demo {
class GameState : public State<GlobalStateType> {
public:
GameState(Engine* t_engine);
~GameState();
const GlobalStateType& getState() const { return state; }
const bool& wantFinish() const { return _wantFinish; };
void onStart();
void update();
/** @return Next game state */
GlobalStateType onFinish();
private:
GlobalStateType state;
bool _wantFinish;
bool initialized;
u8 fpsChecker;
GameRenderer renderer;
unique_ptr<Player> player;
unique_ptr<EnemyManager> enemyManager;
unique_ptr<Terrain> terrain;
unique_ptr<Skybox> skybox;
unique_ptr<Ship> ship;
unique_ptr<Hud> hud;
};
} // namespace Demo
+39
View File
@@ -0,0 +1,39 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
#include <memory>
using std::unique_ptr;
using Tyra::Sprite;
using Tyra::Texture;
using Tyra::TextureRepository;
namespace Demo {
class Hud {
public:
Hud(TextureRepository* repo);
~Hud();
TextureRepository* repo;
unique_ptr<Sprite> hpSprite;
unique_ptr<Sprite> crosshairSprite;
unique_ptr<Sprite> soldierSprite;
Texture* hpTexture;
Texture* crosshairTexture;
Texture* soldierTexture;
};
} // namespace Demo
+40
View File
@@ -0,0 +1,40 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
using Tyra::CameraInfo3D;
using Tyra::Pad;
using Tyra::Vec4;
namespace Demo {
class Camera {
public:
Camera(Pad* pad);
~Camera();
Vec4 lookAt;
Vec4 position;
Vec4 unitCircle;
CameraInfo3D getCameraInfo() { return CameraInfo3D(&position, &lookAt); }
void update(const Vec4& playerPosition, const float& terrainHeight);
private:
float circleRotation, lengthFromOrigin, height;
Pad* pad;
};
} // namespace Demo
+53
View File
@@ -0,0 +1,53 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "states/game/renderer/renderer_dynamic_pair.hpp"
#include "states/game/renderer/renderer_static_pair.hpp"
#include "states/game/terrain/heightmap.hpp"
#include "./weapon.hpp"
#include "./camera.hpp"
#include "./player_shoot_action.hpp"
#include <tyra>
using Tyra::Engine;
using Tyra::Pad;
using Tyra::Renderer3DUtility;
using Tyra::Vec4;
namespace Demo {
class Player {
public:
Player(Engine* engine);
~Player();
const Vec4& getPosition() const { return position; }
CameraInfo3D getCameraInfo() { return camera.getCameraInfo(); }
RendererStaticPair* pair;
void update(const Heightmap& heightmap);
PlayerShootAction getShootAction() const;
private:
void handlePlayerPosition(const Heightmap& heightmap,
const float& terrainHeight);
float speed;
Pad* pad;
Vec4 position;
Weapon weapon;
Camera camera;
};
} // namespace Demo
@@ -0,0 +1,25 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
#include <optional>
using Tyra::Ray;
namespace Demo {
struct PlayerShootAction {
bool isShooting = false;
std::optional<Ray> ray;
};
} // namespace Demo
+54
View File
@@ -0,0 +1,54 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
using Tyra::Audio;
using Tyra::Engine;
using Tyra::Pad;
using Tyra::Renderer;
using Tyra::StaPipOptions;
using Tyra::StaticMesh;
using Tyra::TextureRepository;
using Tyra::Timer;
using Tyra::Vec4;
namespace Demo {
class Weapon {
public:
Weapon(Engine* engine);
~Weapon();
StaticMesh* mesh;
StaPipOptions* options;
bool isShooting = false;
void update();
private:
bool isShootAnimation1, isShootAnimation2;
Pad* pad;
Audio* audio;
Timer shootTimer;
Vec4 initialPosition;
u8 adpcmCurrentChannel;
u8 adpcmChannelsCount;
audsrv_adpcm_t* shootAdpcm;
void shoot();
void allocateOptions();
u8 getShootChannel();
};
} // namespace Demo
@@ -0,0 +1,52 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
#include "./renderer_static_pair.hpp"
#include "./renderer_dynamic_pair.hpp"
using Tyra::CoreBBox;
using Tyra::DynamicPipeline;
using Tyra::Renderer;
using Tyra::Sprite;
using Tyra::StaticPipeline;
namespace Demo {
class GameRenderer {
public:
GameRenderer(Renderer* renderer);
~GameRenderer();
void add(std::vector<RendererStaticPair*> staticPairs);
void add(std::vector<RendererDynamicPair*> dynamicPairs);
void add(RendererStaticPair* staticPair);
void add(RendererDynamicPair* dynamicPair);
void add(Sprite* sprite);
void add(const CoreBBox& bbox);
void clear();
void render();
private:
Renderer* renderer;
StaticPipeline stpip;
DynamicPipeline dypip;
std::vector<RendererStaticPair*> staticPairs;
std::vector<RendererDynamicPair*> dynamicPairs;
std::vector<Sprite*> sprites;
std::vector<CoreBBox> bboxes;
};
} // namespace Demo
@@ -0,0 +1,25 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
using Tyra::DynamicMesh;
using Tyra::DynPipOptions;
namespace Demo {
struct RendererDynamicPair {
DynamicMesh* mesh;
DynPipOptions* options;
};
} // namespace Demo
@@ -0,0 +1,25 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
using Tyra::StaPipOptions;
using Tyra::StaticMesh;
namespace Demo {
struct RendererStaticPair {
StaticMesh* mesh;
StaPipOptions* options;
};
} // namespace Demo
+37
View File
@@ -0,0 +1,37 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
#include "states/game/renderer/renderer_static_pair.hpp"
using Tyra::Renderer;
using Tyra::StaPipOptions;
using Tyra::StaticMesh;
using Tyra::TextureRepository;
using Tyra::Vec4;
namespace Demo {
class Ship {
public:
Ship(TextureRepository* repo);
~Ship();
StaticMesh* mesh;
StaPipOptions* options;
RendererStaticPair* pair;
private:
void allocateOptions();
};
} // namespace Demo
+39
View File
@@ -0,0 +1,39 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
#include "states/game/renderer/renderer_static_pair.hpp"
using Tyra::Renderer;
using Tyra::StaPipOptions;
using Tyra::StaticMesh;
using Tyra::TextureRepository;
using Tyra::Vec4;
namespace Demo {
class Skybox {
public:
Skybox(TextureRepository* repo);
~Skybox();
StaticMesh* mesh;
StaPipOptions* options;
RendererStaticPair* pair;
void update(const Vec4& playerPosition);
private:
void allocateOptions();
};
} // namespace Demo
@@ -0,0 +1,43 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
using Tyra::Vec4;
namespace Demo {
class Heightmap {
public:
Heightmap(const float& minHeight, const float& maxHeight, const Vec4& leftUp,
const Vec4& rightDown);
~Heightmap();
const float& getHeightOffset(const Vec4& playerPosition) const;
bool isOutside(const Vec4& position) const;
float** map;
s16 mapWidth, mapHeight;
float minHeight, maxHeight;
Vec4 leftUp, rightDown;
private:
float getWidthPercentage(const Vec4& playerPosition) const;
float getHeightPercentage(const Vec4& playerPosition) const;
void allocateMap(const unsigned char* data, const int& width,
const int& height);
float getGameHeight(const u8& inputColor, const u8& minColor,
const u8& maxColor) const;
};
} // namespace Demo
+40
View File
@@ -0,0 +1,40 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
#include "states/game/renderer/renderer_static_pair.hpp"
#include "./heightmap.hpp"
using Tyra::StaPipOptions;
using Tyra::StaticMesh;
using Tyra::TextureRepository;
using Tyra::Vec4;
namespace Demo {
class Terrain {
public:
Terrain(TextureRepository* repo);
~Terrain();
Heightmap heightmap;
StaticMesh* mesh;
StaPipOptions* options;
RendererStaticPair* pair;
float getHeightOffset(const Vec4& playerPosition);
private:
void allocateOptions();
};
} // namespace Demo
+44
View File
@@ -0,0 +1,44 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "state/state.hpp"
#include "state/global_state_type.hpp"
#include "state/state_manager.hpp"
#include "./intro_state_type.hpp"
namespace Demo {
class IntroState : public State<GlobalStateType> {
public:
IntroState(Engine* t_engine);
~IntroState();
const GlobalStateType& getState() const { return state; }
const bool& wantFinish() const { return _wantFinish; };
void onStart();
void update();
/** @return Next game state */
GlobalStateType onFinish();
private:
GlobalStateType state;
bool _wantFinish;
bool initialized;
StateManager<IntroStateType> stateManager;
};
} // namespace Demo
@@ -0,0 +1,22 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
namespace Demo {
enum IntroStateType {
STATE_PS2DEV,
STATE_TYRA,
STATE_PRESS_KEY,
STATE_INTRO_END
};
} // namespace Demo
@@ -0,0 +1,74 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "state/state.hpp"
#include "../intro_state_type.hpp"
#include <tyra>
using Tyra::Sprite;
using Tyra::Texture;
using Tyra::Timer;
using Tyra::Vec2;
namespace Demo {
class IntroPressKeyState : public State<IntroStateType> {
public:
IntroPressKeyState(Engine* t_engine);
~IntroPressKeyState();
const IntroStateType& getState() const { return state; }
const bool& wantFinish() const { return _wantFinish; };
void onStart();
/** @return Next game state */
IntroStateType onFinish();
void update();
private:
void renderFiller();
void updateMap();
IntroStateType state;
bool _wantFinish;
bool initialized;
bool mapFadeIn;
bool fillerFadeIn;
bool showPressKey;
bool pressKeyAlphaToggle;
u8 pressKeyAlphaDelayer;
float fillersOffset;
constexpr static float textureWidthHeight = 512.0F;
const static u8 mapRows = 3;
const static u8 mapCols = 3;
Vec2 mapPosition;
u8 mapDirection;
Texture* fillerTexture;
Sprite* fillerSprite;
Texture* logoTexture;
Sprite* logoSprite;
Texture* pressKeyTexture;
Sprite* pressKeySprite;
Texture* mapTextures[mapRows][mapCols];
Sprite* mapSprites[mapRows][mapCols];
};
} // namespace Demo
@@ -0,0 +1,54 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "state/state.hpp"
#include "../intro_state_type.hpp"
#include <tyra>
using Tyra::Sprite;
using Tyra::Texture;
using Tyra::Timer;
namespace Demo {
class IntroPs2DevState : public State<IntroStateType> {
public:
IntroPs2DevState(Engine* t_engine);
~IntroPs2DevState();
const IntroStateType& getState() const { return state; }
const bool& wantFinish() const { return _wantFinish; };
void onStart();
void update();
/** @return Next game state */
IntroStateType onFinish();
private:
IntroStateType state;
bool _wantFinish;
Texture* texture;
Timer initialDelayTimer;
bool initialized;
bool initialDelayElapsed;
bool fadeinActivated;
bool fadeoutActivated;
u8 frameSkipper;
Sprite* sprite;
};
} // namespace Demo
@@ -0,0 +1,63 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "state/state.hpp"
#include "../intro_state_type.hpp"
#include <tyra>
using Tyra::Sprite;
using Tyra::Texture;
using Tyra::Timer;
namespace Demo {
class IntroTyraState : public State<IntroStateType> {
public:
IntroTyraState(Engine* t_engine);
~IntroTyraState();
const IntroStateType& getState() const { return state; }
const bool& wantFinish() const { return _wantFinish; };
void onStart();
void update();
/** @return Next game state */
IntroStateType onFinish();
private:
IntroStateType state;
bool _wantFinish;
Texture* tyraTexture;
Texture* bgTexture;
Texture* bg2Texture;
Texture* fillerTexture;
Timer initialDelayTimer;
bool initialized;
bool initialDelayElapsed;
bool animActivated;
bool fadeoutActivated;
u8 frameSkipper;
Sprite* tyraSprite;
Sprite* bgSprite;
Sprite* bg2Sprite;
Sprite* fillerSprite;
void renderFillers();
};
} // namespace Demo
+41
View File
@@ -0,0 +1,41 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "state/state.hpp"
#include "state/global_state_type.hpp"
#include "state/state_manager.hpp"
namespace Demo {
class LoadingState : public State<GlobalStateType> {
public:
LoadingState(Engine* t_engine);
~LoadingState();
const GlobalStateType& getState() const { return state; }
const bool& wantFinish() const { return _wantFinish; };
void onStart();
void update();
/** @return Next game state */
GlobalStateType onFinish();
private:
GlobalStateType state;
bool _wantFinish;
bool initialized;
};
} // namespace Demo
+4
View File
@@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore
+4
View File
@@ -0,0 +1,4 @@
$ConfigFile = Join-Path $PSScriptRoot '../windows-pcsx2.ps1'
. $ConfigFile
RunPCSX2
+35
View File
@@ -0,0 +1,35 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "demo_game.hpp"
#include "states/intro/intro_state.hpp"
#include "states/loading/loading_state.hpp"
#include "states/game/game_state.hpp"
namespace Demo {
DemoGame::DemoGame(Engine* t_engine)
: engine(t_engine), stateManager(STATE_INTRO, STATE_EXIT) {}
DemoGame::~DemoGame() {}
void DemoGame::init() {
stateManager.add(new IntroState(engine));
stateManager.add(new LoadingState(engine));
stateManager.add(new GameState(engine));
}
void DemoGame::loop() {
stateManager.update();
if (stateManager.finished()) {
exit(0);
}
}
} // namespace Demo
+29
View File
@@ -0,0 +1,29 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include <tyra>
#include "demo_game.hpp"
#include "game_settings.hpp"
int main() {
Tyra::EngineOptions options;
if (Demo::IS_REAL_PS2_VIA_USB) {
options.writeLogsToFile = true;
options.loadUsbDriver = true;
}
Tyra::Engine engine(options);
Demo::DemoGame game(&engine);
engine.run(&game);
SleepThread();
return 0;
}
+159
View File
@@ -0,0 +1,159 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/game/enemy/enemy.hpp"
#include <functional>
using Tyra::Color;
using Tyra::Math;
namespace Demo {
Enemy::Enemy(Engine* engine, const EnemyInfo& t_info) {
info = t_info;
mesh = new DynamicMesh(*info.motherMesh);
auto* bodyMaterial = mesh->getMaterialByName("BodyMaterial");
auto* clothMaterial = mesh->getMaterialByName("ClothMaterial");
TYRA_ASSERT(bodyMaterial != nullptr && clothMaterial != nullptr,
"Body and cloth materials not found!");
info.bodyTexture->addLink(bodyMaterial->id);
info.clothTexture->addLink(clothMaterial->id);
float r = Math::randomf(75.0F, 128.0F);
float g = Math::randomf(75.0F, 128.0F);
float b = Math::randomf(75.0F, 128.0F);
bodyMaterial->ambient.set(r, g, b);
clothMaterial->ambient.set(r, g, b);
walkSequence = {0, 1, 2};
fightSequence = {3, 4, 5};
terrainLeftUp = info.terrainLeftUp;
terrainRightDown = info.terrainRightDown;
setMeshToSpawn();
mesh->animation.setSequence(walkSequence);
mesh->animation.loop = true;
mesh->animation.setCallback(
std::bind(&Enemy::animationCallback, this, std::placeholders::_1));
mesh->translation.translateY(-5.0F);
audio = &engine->audio;
audio->adpcm.setVolume(30, info.adpcmChannel);
allocateOptions();
pair = new RendererDynamicPair{mesh, options};
}
Enemy::~Enemy() {
delete mesh;
delete options;
delete pair;
}
void Enemy::setMeshToSpawn() {
auto spawnPoint =
Vec4(Math::randomf(terrainLeftUp.x, terrainRightDown.x), 0.0F,
Math::randomf(terrainLeftUp.z, terrainRightDown.z), 1.0F);
mesh->setPosition(spawnPoint);
}
void Enemy::update(const Heightmap& heightmap, const Vec4& playerPosition,
const PlayerShootAction& shootAction) {
auto* enemyPosition = mesh->getPosition();
handlePlayerShoot(shootAction);
auto diff = *enemyPosition - playerPosition;
auto ang = Math::atan2(diff.x, diff.z);
if (diff.length() > 150.0F) {
walk(heightmap, diff);
} else {
fight();
}
const float naturalRotation = 3.1F;
mesh->rotation.identity();
ang += naturalRotation;
mesh->rotation.rotateByAngle(ang, Vec4(0.0F, 1.0F, 0.0F, 0.0F));
mesh->update();
}
void Enemy::handlePlayerShoot(const PlayerShootAction& shootAction) {
if (!shootAction.isShooting) {
return;
}
const auto& ray = shootAction.ray.value();
auto bbox =
mesh->getCurrentBoundingBox().getTransformed(mesh->getModelMatrix());
auto isOnEnemy = ray.intersectBox(bbox.min(), bbox.max());
if (isOnEnemy) {
setMeshToSpawn();
audio->adpcm.tryPlay(info.adpcmDeath, info.adpcmChannel);
}
}
void Enemy::walk(const Heightmap& heightmap, const Vec4& positionDiff) {
if (isFighting) {
mesh->animation.setSequence(walkSequence);
}
isFighting = false;
isWalking = true;
auto* enemyPosition = mesh->getPosition();
auto normalized = positionDiff;
normalized.normalize();
const float speed = 2.5F;
auto nextPos = *enemyPosition - normalized * speed;
nextPos.y = heightmap.getHeightOffset(nextPos) - 60.0F;
mesh->translation.identity();
mesh->translation.translate(nextPos);
}
void Enemy::fight() {
if (isWalking) {
mesh->animation.setSequence(fightSequence);
}
isFighting = true;
isWalking = false;
}
void Enemy::animationCallback(const AnimationSequenceCallback& callback) {
if (callback == AnimationSequenceCallback::AnimationSequenceCallback_Loop) {
if (isFighting) {
audio->adpcm.tryPlay(info.adpcmPunch, info.adpcmChannel);
}
}
}
void Enemy::allocateOptions() {
options = new DynPipOptions();
options->frustumCulling =
Tyra::PipelineFrustumCulling::PipelineFrustumCulling_None;
}
} // namespace Demo
@@ -0,0 +1,92 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/game/enemy/enemy_manager.hpp"
#include <functional>
#include "game_settings.hpp"
using Tyra::FileUtils;
using Tyra::Math;
using Tyra::ObjLoader;
using Tyra::ObjLoaderOptions;
namespace Demo {
EnemyManager::EnemyManager(Engine* engine, const Heightmap& heightmap) {
textureRepo = &engine->renderer.core.texture.repository;
ObjLoader loader;
ObjLoaderOptions objOptions;
objOptions.animation.count = 6;
objOptions.flipUVs = true;
objOptions.scale = 250.0F;
auto data = loader.load(FileUtils::fromCwd("game/models/zombie/zombie.obj"),
objOptions);
data->loadNormals = false;
motherMesh = new DynamicMesh(data.get());
bodyTexture = textureRepo->add(
FileUtils::fromCwd("game/models/zombie/BodyMaterial.png"));
clothTexture = textureRepo->add(
FileUtils::fromCwd("game/models/zombie/ClothMaterial.png"));
auto* punch = engine->audio.adpcm.load(
FileUtils::fromCwd("game/models/zombie/punch.adpcm"));
auto* death = engine->audio.adpcm.load(
FileUtils::fromCwd("game/models/zombie/death.adpcm"));
const int enemyCount = IS_REAL_PS2_VIA_USB ? 8 : 12;
for (int i = 0; i < enemyCount; i++) {
EnemyInfo info;
info.adpcmChannel = 9 + i;
info.adpcmPunch = punch;
info.adpcmDeath = death;
info.motherMesh = motherMesh;
info.clothTexture = clothTexture;
info.bodyTexture = bodyTexture;
info.terrainLeftUp = heightmap.leftUp;
info.terrainRightDown = heightmap.rightDown;
enemies.push_back(new Enemy(engine, info));
}
}
EnemyManager::~EnemyManager() {
for (auto* enemy : enemies) {
delete enemy;
}
delete motherMesh;
textureRepo->free(bodyTexture->id);
textureRepo->free(clothTexture->id);
}
std::vector<RendererDynamicPair*> EnemyManager::getPairs() const {
std::vector<RendererDynamicPair*> result;
for (auto* enemy : enemies) {
result.push_back(enemy->pair);
}
return result;
}
void EnemyManager::update(const Heightmap& heightmap,
const Vec4& playerPosition,
const PlayerShootAction& shootAction) {
for (auto* enemy : enemies) {
enemy->update(heightmap, playerPosition, shootAction);
}
}
} // namespace Demo
+97
View File
@@ -0,0 +1,97 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/game/game_state.hpp"
#include "game_settings.hpp"
using std::make_unique;
using Tyra::FileUtils;
namespace Demo {
GameState::GameState(Engine* t_engine)
: State(t_engine), renderer(&t_engine->renderer) {
state = STATE_GAME;
_wantFinish = false;
initialized = false;
fpsChecker = 0;
}
GameState::~GameState() {}
void GameState::onStart() {
TYRA_LOG("Game. RAM: ", engine->info.getAvailableRAM(), "MB");
engine->audio.song.stop();
engine->audio.song.inLoop = true;
engine->audio.song.load(FileUtils::fromCwd("game/game-audio.wav"));
engine->audio.song.setVolume(0);
engine->audio.song.play();
auto* repository = &engine->renderer.core.texture.repository;
player = make_unique<Player>(engine);
terrain = make_unique<Terrain>(repository);
enemyManager = make_unique<EnemyManager>(engine, terrain->heightmap);
ship = make_unique<Ship>(repository);
skybox = make_unique<Skybox>(repository);
hud = make_unique<Hud>(repository);
engine->audio.song.setVolume(85);
if (IS_REAL_PS2_VIA_USB) engine->renderer.setFrameLimit(false);
initialized = true;
}
GlobalStateType GameState::onFinish() {
if (!initialized) return STATE_EXIT;
initialized = false;
return STATE_EXIT;
}
void GameState::update() {
// Check fps
if (fpsChecker++ > 50) {
TYRA_LOG("FPS: ", engine->info.getFps(),
" RAM: ", engine->info.getAvailableRAM());
fpsChecker = 0;
}
// Game logic
player->update(terrain->heightmap);
skybox->update(player->getPosition());
auto shootAction = player->getShootAction();
enemyManager->update(terrain->heightmap, player->getPosition(), shootAction);
auto* firstEnemyMesh = enemyManager->getPairs().front()->mesh;
// Render
engine->renderer.beginFrame(player->getCameraInfo());
{
renderer.clear();
{
renderer.add(skybox->pair); // First, because of ALLPASS
renderer.add(ship->pair);
renderer.add(player->pair);
renderer.add(enemyManager->getPairs());
renderer.add(terrain->pair);
renderer.add(firstEnemyMesh->getCurrentBoundingBox().getTransformed(
firstEnemyMesh->getModelMatrix()));
renderer.add(hud->crosshairSprite.get());
renderer.add(hud->hpSprite.get());
renderer.add(hud->soldierSprite.get());
}
renderer.render();
}
engine->renderer.endFrame();
}
} // namespace Demo
+51
View File
@@ -0,0 +1,51 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/game/hud/hud.hpp"
using Tyra::FileUtils;
namespace Demo {
Hud::Hud(TextureRepository* t_repo) {
repo = t_repo;
soldierSprite = std::make_unique<Sprite>();
soldierSprite->mode = Tyra::MODE_STRETCH;
soldierSprite->size.set(64.0F, 64.0F);
soldierSprite->position.set(5.0F, 448.0F - 64.0F - 5.0F);
soldierTexture = repo->add(FileUtils::fromCwd("game/soldier.png"));
soldierTexture->addLink(soldierSprite->id);
hpSprite = std::make_unique<Sprite>();
hpSprite->mode = Tyra::MODE_STRETCH;
hpSprite->size.set(128.0F, 64.0F);
hpSprite->position.set(70.0F, 448.0F - 64.0F - 5.0F);
hpTexture = repo->add(FileUtils::fromCwd("game/health_bar.png"));
hpTexture->addLink(hpSprite->id);
crosshairSprite = std::make_unique<Sprite>();
crosshairSprite->mode = Tyra::MODE_STRETCH;
crosshairSprite->size.set(16.0F, 16.0F);
crosshairSprite->position.set(512.0F / 2.0F - 16.0F / 2,
448.0F / 2.0F - 16.0F / 2);
crosshairTexture = repo->add(FileUtils::fromCwd("game/crosshair.png"));
crosshairTexture->addLink(crosshairSprite->id);
}
Hud::~Hud() {
repo->free(crosshairTexture->id);
repo->free(hpTexture->id);
}
} // namespace Demo
+49
View File
@@ -0,0 +1,49 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/game/player/camera.hpp"
namespace Demo {
Camera::Camera(Pad* t_pad) : lookAt(0.0F), position(0.0F), pad(t_pad) {
lengthFromOrigin = 30.0F;
circleRotation = -3.5F;
height = 1.5F;
}
Camera::~Camera() {}
void Camera::update(const Vec4& playerPosition, const float& terrainHeight) {
const float rotationOffset = 0.045F;
const float heightOffset = 0.5F;
const auto& rightJoy = pad->getRightJoyPad();
if (rightJoy.h <= 100) {
circleRotation -= rotationOffset;
} else if (rightJoy.h >= 200) {
circleRotation += rotationOffset;
}
if (rightJoy.v <= 100) {
height -= heightOffset;
} else if (rightJoy.v >= 200) {
height += heightOffset;
}
unitCircle.x = (sin(circleRotation) * lengthFromOrigin);
unitCircle.y = height;
unitCircle.z = (cos(circleRotation) * lengthFromOrigin);
position = playerPosition;
lookAt = unitCircle + playerPosition;
}
} // namespace Demo
+77
View File
@@ -0,0 +1,77 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/game/player/player.hpp"
namespace Demo {
Player::Player(Engine* engine)
: position(0.0F), weapon(engine), camera(&engine->pad) {
pair = new RendererStaticPair{weapon.mesh, weapon.options};
pad = &engine->pad;
position = Vec4(3.0F, 50.0F, 0.0F);
camera.lookAt = Vec4(0.0F, 0.0F, -30.0F);
speed = 6.0F;
}
Player::~Player() { delete pair; }
void Player::update(const Heightmap& heightmap) {
float terrainHeight = heightmap.getHeightOffset(getPosition());
handlePlayerPosition(heightmap, terrainHeight);
camera.update(position, terrainHeight);
weapon.update();
}
PlayerShootAction Player::getShootAction() const {
PlayerShootAction action;
action.isShooting = weapon.isShooting;
if (action.isShooting) {
action.ray =
Ray(camera.position, (camera.lookAt - camera.position).getNormalized());
}
return action;
}
void Player::handlePlayerPosition(const Heightmap& heightmap,
const float& terrainHeight) {
const auto& leftJoy = pad->getLeftJoyPad();
auto normalizedCamera = Vec4(camera.unitCircle);
normalizedCamera.normalize();
normalizedCamera *= speed;
Vec4 nextPosition(position);
nextPosition.y = terrainHeight + 50.0F;
if (leftJoy.v <= 100) {
nextPosition.x += normalizedCamera.x;
nextPosition.z += normalizedCamera.z;
} else if (leftJoy.v >= 200) {
nextPosition.x += -normalizedCamera.x;
nextPosition.z += -normalizedCamera.z;
}
if (leftJoy.h <= 100) {
nextPosition.x += normalizedCamera.z;
nextPosition.z += -normalizedCamera.x;
} else if (leftJoy.h >= 200) {
nextPosition.x += -normalizedCamera.z;
nextPosition.z += normalizedCamera.x;
}
if (!heightmap.isOutside(nextPosition)) position = nextPosition;
camera.position = position;
}
} // namespace Demo
+131
View File
@@ -0,0 +1,131 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/game/player/weapon.hpp"
using Tyra::FileUtils;
using Tyra::ObjLoader;
using Tyra::ObjLoaderOptions;
namespace Demo {
Weapon::Weapon(Engine* engine) {
ObjLoader loader;
ObjLoaderOptions objOptions;
objOptions.flipUVs = true;
objOptions.scale = .5F;
pad = &engine->pad;
audio = &engine->audio;
auto* repo = &engine->renderer.core.texture.repository;
auto data =
loader.load(FileUtils::fromCwd("game/models/ak47/ak47.obj"), objOptions);
data->loadNormals = false;
mesh = new StaticMesh(data.get());
mesh->translation.translateX(2.85F);
mesh->translation.translateY(-3.40F);
mesh->translation.translateZ(-10.50F);
mesh->rotation.rotateY(1.60F);
mesh->rotation.rotateZ(-6.30F);
mesh->scale.scale(0.5F);
repo->addByMesh(mesh, FileUtils::fromCwd("game/models/ak47/"), "png");
initialPosition = *mesh->getPosition();
allocateOptions();
shootAdpcm =
audio->adpcm.load(FileUtils::fromCwd("game/models/ak47/ak47.adpcm"));
isShootAnimation1 = isShootAnimation2 = false;
adpcmChannelsCount = 8;
adpcmCurrentChannel = 0;
const u8 shootVolume = 25;
for (u8 i = 0; i < adpcmChannelsCount; i++) {
audio->adpcm.setVolume(shootVolume, i);
}
}
Weapon::~Weapon() {
delete mesh;
delete options;
delete shootAdpcm;
}
u8 Weapon::getShootChannel() {
auto result = adpcmCurrentChannel++;
if (adpcmCurrentChannel >= adpcmChannelsCount) {
adpcmCurrentChannel = 0;
}
return result;
}
void Weapon::update() {
isShooting = false;
if (!isShootAnimation1 && !isShootAnimation2 && pad->getPressed().Cross) {
shoot();
}
auto* position = mesh->getPosition();
const float recoil = 0.5F;
const float speed = 500;
if (isShootAnimation1) {
position->z += recoil;
position->y -= recoil / 4;
if (shootTimer.getTimeDelta() > speed) {
isShootAnimation1 = false;
shootTimer.prime();
isShootAnimation2 = true;
}
}
if (isShootAnimation2) {
position->z -= recoil / 2;
position->y += recoil / 8;
if (shootTimer.getTimeDelta() > speed * 2) {
isShootAnimation2 = false;
*position = initialPosition;
if (pad->getPressed().Cross) {
shoot();
}
}
}
}
void Weapon::shoot() {
isShooting = true;
shootTimer.prime();
audio->adpcm.tryPlay(shootAdpcm, getShootChannel());
isShootAnimation1 = true;
}
void Weapon::allocateOptions() {
options = new StaPipOptions();
options->textureMappingType = Tyra::TyraNearest;
options->shadingType = Tyra::TyraShadingFlat;
options->blendingEnabled = false;
options->fullClipChecks = false;
options->frustumCulling = Tyra::PipelineFrustumCulling_None;
options->transformationType = Tyra::TyraMP;
options->antiAliasingEnabled = false;
}
} // namespace Demo
@@ -0,0 +1,89 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/game/renderer/game_renderer.hpp"
using Tyra::Threading;
namespace Demo {
GameRenderer::GameRenderer(Renderer* t_renderer) {
renderer = t_renderer;
stpip.setRenderer(&renderer->core);
dypip.setRenderer(&renderer->core);
}
GameRenderer::~GameRenderer() {}
void GameRenderer::add(std::vector<RendererStaticPair*> t_staticPairs) {
staticPairs.insert(staticPairs.end(), t_staticPairs.begin(),
t_staticPairs.end());
}
void GameRenderer::add(std::vector<RendererDynamicPair*> t_dynamicPairs) {
dynamicPairs.insert(dynamicPairs.end(), t_dynamicPairs.begin(),
t_dynamicPairs.end());
}
void GameRenderer::add(Sprite* sprite) { sprites.push_back(sprite); }
void GameRenderer::add(const CoreBBox& bbox) { bboxes.push_back(bbox); }
void GameRenderer::add(RendererStaticPair* staticPair) {
staticPairs.push_back(staticPair);
}
void GameRenderer::add(RendererDynamicPair* dynamicPair) {
dynamicPairs.push_back(dynamicPair);
}
void GameRenderer::clear() {
staticPairs.clear();
dynamicPairs.clear();
sprites.clear();
bboxes.clear();
}
void GameRenderer::render() {
// Render static stuff
if (staticPairs.size()) {
renderer->renderer3D.usePipeline(&stpip);
for (auto& pair : staticPairs) {
stpip.render(pair->mesh, pair->options);
}
}
Threading::switchThread(); // give some time for audio thread
// Render animated stuff
if (dynamicPairs.size()) {
renderer->renderer3D.usePipeline(&dypip);
for (auto& pair : dynamicPairs) {
dypip.render(pair->mesh, pair->options);
}
}
Threading::switchThread();
// Render debug stuff after stapip/dynpip, otherwise it will not be visible
for (auto& bbox : bboxes) {
renderer->renderer3D.utility.drawBBox(bbox);
}
// Render 2D
for (auto& sprite : sprites) {
renderer->renderer2D.render(sprite);
}
}
} // namespace Demo
+50
View File
@@ -0,0 +1,50 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/game/ship/ship.hpp"
using Tyra::FileUtils;
using Tyra::ObjLoader;
using Tyra::ObjLoaderOptions;
namespace Demo {
Ship::Ship(TextureRepository* repo) {
ObjLoader loader;
ObjLoaderOptions objOptions;
objOptions.flipUVs = true;
objOptions.scale = 200.0F;
auto data =
loader.load(FileUtils::fromCwd("game/models/ship/ship.obj"), objOptions);
mesh = new StaticMesh(data.get());
for (std::size_t i = 0; i < mesh->materials.size(); i++) {
mesh->materials[i]->ambient /= 2.0F;
mesh->materials[i]->ambient.a = 128.0F;
}
mesh->setPosition(Vec4(-800.0F, 10.0F, -2500.0F));
allocateOptions();
pair = new RendererStaticPair{mesh, options};
}
Ship::~Ship() {
delete mesh;
delete options;
delete pair;
}
void Ship::allocateOptions() { options = new StaPipOptions(); }
} // namespace Demo
+59
View File
@@ -0,0 +1,59 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/game/skybox/skybox.hpp"
using Tyra::FileUtils;
using Tyra::ObjLoader;
using Tyra::ObjLoaderOptions;
namespace Demo {
Skybox::Skybox(TextureRepository* repo) {
ObjLoader loader;
ObjLoaderOptions objOptions;
objOptions.flipUVs = true;
objOptions.scale = 100.0F;
auto data = loader.load(FileUtils::fromCwd("game/models/skybox/skybox.obj"),
objOptions);
data->loadNormals = false;
mesh = new StaticMesh(data.get());
repo->addByMesh(mesh, FileUtils::fromCwd("game/models/skybox/"), "png");
allocateOptions();
pair = new RendererStaticPair{mesh, options};
}
Skybox::~Skybox() {
delete mesh;
delete options;
delete pair;
}
void Skybox::update(const Vec4& playerPosition) {
mesh->translation.identity();
mesh->translation.translate(playerPosition);
}
void Skybox::allocateOptions() {
options = new StaPipOptions();
options->frustumCulling = Tyra::PipelineFrustumCulling_None;
options->shadingType = Tyra::TyraShadingGouraud;
options->zTestType = Tyra::PipelineZTest_AllPass;
options->textureMappingType = Tyra::TyraNearest;
options->blendingEnabled = true;
options->antiAliasingEnabled = false;
}
} // namespace Demo
+113
View File
@@ -0,0 +1,113 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/game/terrain/heightmap.hpp"
using Tyra::FileUtils;
using Tyra::PngLoader;
using Tyra::PngPixel3;
using Tyra::Vec4;
namespace Demo {
Heightmap::Heightmap(const float& t_minHeight, const float& t_maxHeight,
const Vec4& t_leftUp, const Vec4& t_rightDown)
: minHeight(t_minHeight),
maxHeight(t_maxHeight),
leftUp(t_leftUp),
rightDown(t_rightDown) {
PngLoader loader;
auto* data =
loader.load(FileUtils::fromCwd("game/models/terrain/heightmap.png"));
allocateMap(data->data, data->width, data->height);
delete data;
}
bool Heightmap::isOutside(const Vec4& position) const {
return position.x <= leftUp.x || position.x >= rightDown.x ||
position.z <= leftUp.z || position.z >= rightDown.z;
}
Heightmap::~Heightmap() {
if (map) {
for (int i = 0; i < mapHeight; i++) {
delete[] map[i];
}
delete[] map;
}
}
const float& Heightmap::getHeightOffset(const Vec4& playerPosition) const {
float widthPercentage = getWidthPercentage(playerPosition);
float heightPercentage = getHeightPercentage(playerPosition);
auto x = static_cast<s16>(widthPercentage * mapWidth);
auto y = static_cast<s16>(heightPercentage * mapHeight);
TYRA_ASSERT(x >= 0 && x < mapWidth, "x is out of range");
TYRA_ASSERT(y >= 0 && y < mapHeight, "y is out of range");
return map[x][y];
}
float Heightmap::getWidthPercentage(const Vec4& playerPosition) const {
return (playerPosition.x - leftUp.x) / (rightDown.x - leftUp.x);
}
float Heightmap::getHeightPercentage(const Vec4& playerPosition) const {
return (playerPosition.z - leftUp.z) / (rightDown.z - leftUp.z);
}
void Heightmap::allocateMap(const unsigned char* data, const int& width,
const int& height) {
auto* pixels = (struct PngPixel3*)data;
u8 min = pixels[0].r; // in grayscale every r,g,b is the same
u8 max = pixels[0].r;
// Get min and max
for (int i = 0; i < width * height; i++) {
const auto& value = pixels[i].r;
if (value < min) {
min = value;
}
if (value > max) {
max = value;
}
}
// Allocate
mapWidth = width;
mapHeight = height;
map = new float*[width];
for (int i = 0; i < width; i++) {
map[i] = new float[height];
}
// Fill
int k = 0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
map[i][j] = getGameHeight(pixels[k++].r, min, max);
}
}
}
float Heightmap::getGameHeight(const u8& inputColor, const u8& minColor,
const u8& maxColor) const {
const float mapRange = maxColor - minColor;
const float gameRange = maxHeight - minHeight;
return (inputColor - minColor) / mapRange * gameRange + minHeight;
}
} // namespace Demo
+60
View File
@@ -0,0 +1,60 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/game/terrain/terrain.hpp"
using Tyra::FileUtils;
using Tyra::ObjLoader;
using Tyra::ObjLoaderOptions;
namespace Demo {
Terrain::Terrain(TextureRepository* repo)
: heightmap(-70.0F, // Min height
240.0F, // Max height
Vec4(-750.0F, 0.0F, -1400.0F, 1.0F), // Left up
Vec4(920.0F, 0.0F, 1520.0F, 1.0F) // Right down
) {
ObjLoader loader;
ObjLoaderOptions objOptions;
objOptions.flipUVs = true;
objOptions.scale = 100.0F;
auto data = loader.load(FileUtils::fromCwd("game/models/terrain/terrain.obj"),
objOptions);
data->loadNormals = false;
mesh = new StaticMesh(data.get());
repo->addByMesh(mesh, FileUtils::fromCwd("game/models/terrain/"), "png");
allocateOptions();
pair = new RendererStaticPair{mesh, options};
}
float Terrain::getHeightOffset(const Vec4& playerPosition) {
return heightmap.getHeightOffset(playerPosition);
}
Terrain::~Terrain() {
delete mesh;
delete options;
delete pair;
}
void Terrain::allocateOptions() {
options = new StaPipOptions();
options->frustumCulling = Tyra::PipelineFrustumCulling_None;
options->shadingType = Tyra::TyraShadingGouraud;
options->blendingEnabled = true;
options->antiAliasingEnabled = false;
}
} // namespace Demo
+62
View File
@@ -0,0 +1,62 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/intro/intro_state.hpp"
#include "states/intro/states/intro_ps2dev_state.hpp"
#include "states/intro/states/intro_tyra_state.hpp"
#include "states/intro/states/intro_press_key_state.hpp"
using Tyra::FileUtils;
namespace Demo {
IntroState::IntroState(Engine* t_engine)
: State(t_engine), stateManager(STATE_PS2DEV, STATE_INTRO_END) {
state = STATE_INTRO;
_wantFinish = false;
initialized = false;
}
IntroState::~IntroState() {}
void IntroState::onStart() {
TYRA_LOG("Intro. RAM: ", engine->info.getAvailableRAM(), "MB");
engine->audio.song.load(FileUtils::fromCwd("intro/intro.wav"));
engine->audio.song.inLoop = false;
engine->audio.song.setVolume(80);
engine->audio.song.play();
stateManager.add(new IntroPs2DevState(engine));
stateManager.add(new IntroTyraState(engine));
stateManager.add(new IntroPressKeyState(engine));
initialized = true;
}
GlobalStateType IntroState::onFinish() {
if (!initialized) return STATE_LOADING;
stateManager.freeAll();
initialized = false;
return STATE_LOADING;
}
void IntroState::update() {
stateManager.update();
if (stateManager.finished()) {
_wantFinish = true;
}
}
} // namespace Demo
@@ -0,0 +1,198 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/intro/states/intro_press_key_state.hpp"
#include <string>
using Tyra::FileUtils;
using Tyra::Math;
using Tyra::PngLoader;
using Tyra::SpriteMode;
using Tyra::Threading;
namespace Demo {
IntroPressKeyState::IntroPressKeyState(Engine* t_engine)
: State(t_engine), mapPosition(0.0F, 0.0F) {
state = STATE_PRESS_KEY;
_wantFinish = false;
mapDirection = 0;
mapFadeIn = true;
fillerFadeIn = false;
showPressKey = false;
pressKeyAlphaToggle = false;
pressKeyAlphaDelayer = 0;
fillersOffset = -512.0F;
}
IntroPressKeyState::~IntroPressKeyState() {}
void IntroPressKeyState::onStart() {
TYRA_LOG("Intro - presskey. RAM: ", engine->info.getAvailableRAM(), "MB");
for (u8 i = 0; i < mapRows; i++) {
for (u8 j = 0; j < mapCols; j++) {
mapSprites[i][j] = new Sprite;
mapSprites[i][j]->color.a = 0.0F;
mapSprites[i][j]->mode = SpriteMode::MODE_STRETCH;
mapSprites[i][j]->size.set(textureWidthHeight, textureWidthHeight);
mapSprites[i][j]->position.set(i * textureWidthHeight,
j * textureWidthHeight);
std::string filename =
"map-" + std::to_string(i) + "-" + std::to_string(j);
std::string path = "intro/map/" + filename + ".png";
mapTextures[i][j] = engine->renderer.core.texture.repository.add(
FileUtils::fromCwd(path));
mapTextures[i][j]->addLink(mapSprites[i][j]->id);
}
}
fillerSprite = new Sprite;
fillerSprite->size.set(256.0F, 50.0F);
fillerSprite->position.set(0.0F, 224.0F - 25.0F);
fillerTexture = engine->renderer.core.texture.repository.add(
FileUtils::fromCwd("intro/filler.png"));
fillerTexture->addLink(fillerSprite->id);
pressKeySprite = new Sprite;
pressKeySprite->size.set(256.0F, 64.0F);
pressKeySprite->scale = 0.5F;
pressKeySprite->position.set(192.0F, 380.0F);
pressKeyTexture = engine->renderer.core.texture.repository.add(
FileUtils::fromCwd("intro/press-key.png"));
pressKeyTexture->addLink(pressKeySprite->id);
logoSprite = new Sprite;
logoSprite->size.set(256.0F, 128.0F);
logoSprite->position.set(256.0F - 128.0F, 224.0F - 64.0F);
logoTexture = engine->renderer.core.texture.repository.add(
FileUtils::fromCwd("intro/lastalive.png"));
logoTexture->addLink(logoSprite->id);
initialized = true;
}
IntroStateType IntroPressKeyState::onFinish() {
if (!initialized) return STATE_INTRO_END;
for (u8 i = 0; i < mapRows; i++)
for (u8 j = 0; j < mapCols; j++) {
engine->renderer.core.texture.repository.free(mapTextures[i][j]->id);
delete mapSprites[i][j];
}
engine->renderer.core.texture.repository.free(fillerTexture->id);
delete fillerSprite;
engine->renderer.core.texture.repository.free(logoTexture->id);
delete logoSprite;
engine->renderer.core.texture.repository.free(pressKeyTexture->id);
delete pressKeySprite;
initialized = false;
return STATE_INTRO_END;
}
void IntroPressKeyState::update() {
engine->renderer.beginFrame();
if (mapDirection == 0 &&
mapPosition.x >= textureWidthHeight * (mapRows - 1) &&
mapPosition.y >= textureWidthHeight * (mapCols - 1)) {
mapDirection = 1;
} else if (mapDirection == 1 && mapPosition.x <= 0.0F &&
mapPosition.y <= 0.0F) {
mapDirection = 0;
}
if (engine->pad.getClicked().Cross) {
_wantFinish = true;
}
const float offset = 0.1F;
if (mapDirection == 0) {
mapPosition += offset;
} else if (mapDirection == 1) {
mapPosition -= offset;
}
if (mapFadeIn) {
for (u8 i = 0; i < mapRows; i++) {
for (u8 j = 0; j < mapCols; j++) {
auto* sprite = mapSprites[i][j];
if (sprite->color.a >= 16.0F && sprite->color.a < 32.0F) {
fillerFadeIn = true;
}
if (sprite->color.a < 96.0F) {
sprite->color.a += 0.2F;
} else {
mapFadeIn = false;
}
}
}
}
if (fillerFadeIn) {
if (fillersOffset < -1.0F) {
fillersOffset += 4.0F;
} else {
fillerFadeIn = false;
showPressKey = true;
}
}
updateMap();
Threading::switchThread();
for (u8 i = 0; i < mapRows; i++)
for (u8 j = 0; j < mapCols; j++)
engine->renderer.renderer2D.render(mapSprites[i][j]);
renderFiller();
engine->renderer.renderer2D.render(logoSprite);
if (showPressKey) {
if (pressKeyAlphaDelayer++ > 50) {
pressKeyAlphaToggle = !pressKeyAlphaToggle;
pressKeyAlphaDelayer = 0;
}
if (pressKeyAlphaToggle) {
engine->renderer.renderer2D.render(pressKeySprite);
}
}
engine->renderer.endFrame();
}
void IntroPressKeyState::renderFiller() {
fillerSprite->position.x = -1.0F + fillersOffset;
engine->renderer.renderer2D.render(fillerSprite);
fillerSprite->position.x = 255.0F + fillersOffset;
engine->renderer.renderer2D.render(fillerSprite);
}
void IntroPressKeyState::updateMap() {
for (u8 i = 0; i < mapRows; i++)
for (u8 j = 0; j < mapCols; j++) {
mapSprites[i][j]->position.x =
i * (textureWidthHeight + 1.0F) - mapPosition.x;
mapSprites[i][j]->position.y =
j * (textureWidthHeight + 1.0F) - mapPosition.y;
}
}
} // namespace Demo
@@ -0,0 +1,104 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/intro/states/intro_ps2dev_state.hpp"
using Tyra::FileUtils;
using Tyra::PngLoader;
using Tyra::Threading;
namespace Demo {
IntroPs2DevState::IntroPs2DevState(Engine* t_engine) : State(t_engine) {
state = STATE_PS2DEV;
_wantFinish = false;
initialized = false;
initialDelayElapsed = false;
frameSkipper = 0;
fadeinActivated = true;
fadeoutActivated = false;
}
IntroPs2DevState::~IntroPs2DevState() {}
void IntroPs2DevState::onStart() {
TYRA_LOG("Intro - ps2dev. RAM: ", engine->info.getAvailableRAM(), "MB");
const auto& settings = engine->renderer.core.getSettings();
initialDelayTimer.prime();
sprite = new Sprite;
sprite->size.set(256.0F, 64.0F);
sprite->position.set(settings.getWidth() / 2 - sprite->size.x / 2,
settings.getHeight() / 2 - sprite->size.y / 2);
sprite->color.a = 0;
Threading::switchThread();
texture = engine->renderer.core.texture.repository.add(
FileUtils::fromCwd("intro/ps2dev.png"));
texture->addLink(sprite->id);
initialized = true;
}
IntroStateType IntroPs2DevState::onFinish() {
if (!initialized) return STATE_TYRA;
delete sprite;
engine->renderer.core.texture.repository.free(texture->id);
initialized = false;
return STATE_TYRA;
}
void IntroPs2DevState::update() {
engine->renderer.beginFrame();
if (initialDelayTimer.getTimeDelta() >= 60000) initialDelayElapsed = true;
if (engine->pad.getClicked().Cross) {
_wantFinish = true;
}
frameSkipper++;
if (frameSkipper > 3) {
frameSkipper = 0;
}
if (fadeinActivated && initialDelayElapsed && frameSkipper == 0) {
if (sprite->color.a < 128.0F)
sprite->color.a += 2.0F;
else {
fadeoutActivated = true;
fadeinActivated = false;
}
if (sprite->color.a >= 96.0F && sprite->color.a < 128.0F) {
sprite->color.g -= 6.0F;
sprite->color.b -= 6.0F;
}
}
Threading::switchThread();
if (fadeoutActivated && frameSkipper == 0) {
if (sprite->color.a > 0)
sprite->color.a -= 4;
else
_wantFinish = true;
}
engine->renderer.renderer2D.render(sprite);
engine->renderer.endFrame();
}
} // namespace Demo
@@ -0,0 +1,180 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include "states/intro/states/intro_tyra_state.hpp"
using Tyra::FileUtils;
using Tyra::Math;
using Tyra::PngLoader;
using Tyra::Threading;
namespace Demo {
IntroTyraState::IntroTyraState(Engine* t_engine) : State(t_engine) {
state = STATE_TYRA;
_wantFinish = false;
initialized = false;
initialDelayElapsed = false;
animActivated = true;
fadeoutActivated = false;
frameSkipper = 0;
}
IntroTyraState::~IntroTyraState() {}
void IntroTyraState::onStart() {
TYRA_LOG("Intro - tyra. RAM: ", engine->info.getAvailableRAM(), "MB");
const auto& settings = engine->renderer.core.getSettings();
initialDelayTimer.prime();
tyraSprite = new Sprite;
tyraSprite->size.set(256.0F, 64.0F);
tyraSprite->position.set(settings.getWidth() / 2 - tyraSprite->size.x / 2,
settings.getHeight() / 2 - tyraSprite->size.y / 2);
bgSprite = new Sprite;
bgSprite->size.set(256.0F, 256.0F);
bgSprite->position.set(settings.getWidth() / 2 - bgSprite->size.x / 2,
settings.getHeight() / 3 * 2.0F);
bg2Sprite = new Sprite;
bg2Sprite->size.set(256.0F, 256.0F);
bg2Sprite->position.set(
settings.getWidth() / 2 - bg2Sprite->size.x / 2,
(settings.getHeight() / 3 * 2.0F) + bg2Sprite->size.y + 1.0F);
fillerSprite = new Sprite;
fillerSprite->size.set(256.0F, 256.0F);
fillerSprite->position.set(0.0F, 0.0F);
tyraTexture = engine->renderer.core.texture.repository.add(
FileUtils::fromCwd("intro/tyra.png"));
tyraTexture->addLink(tyraSprite->id);
bgTexture = engine->renderer.core.texture.repository.add(
FileUtils::fromCwd("intro/tyra_bg.png"));
bgTexture->addLink(bgSprite->id);
Threading::switchThread();
bg2Texture = engine->renderer.core.texture.repository.add(
FileUtils::fromCwd("intro/tyra_bg2.png"));
bg2Texture->addLink(bg2Sprite->id);
fillerTexture = engine->renderer.core.texture.repository.add(
FileUtils::fromCwd("intro/filler.png"));
fillerTexture->addLink(fillerSprite->id);
initialized = true;
}
IntroStateType IntroTyraState::onFinish() {
if (!initialized) return STATE_PRESS_KEY;
engine->renderer.core.texture.repository.free(tyraTexture->id);
engine->renderer.core.texture.repository.free(bgTexture->id);
engine->renderer.core.texture.repository.free(bg2Texture->id);
engine->renderer.core.texture.repository.free(fillerTexture->id);
delete tyraSprite;
delete bgSprite;
delete bg2Sprite;
delete fillerSprite;
initialized = false;
return STATE_PRESS_KEY;
}
void IntroTyraState::update() {
engine->renderer.beginFrame();
if (initialDelayTimer.getTimeDelta() >= 15000) initialDelayElapsed = true;
frameSkipper++;
if (frameSkipper > 3) {
frameSkipper = 0;
}
if (engine->pad.getClicked().Cross) {
_wantFinish = true;
}
const float slideUpMaxPost = -128.0F;
if (initialDelayElapsed) {
if (bgSprite->position.y <= 32.0F) fadeoutActivated = true;
float offset = 1.0F;
if (bgSprite->position.y > slideUpMaxPost && bgSprite->position.y <= 64.0F)
offset /= 1.6F;
else if (bgSprite->position.y > 64.0F && bgSprite->position.y <= 128.0F)
offset /= 1.2F;
if (bgSprite->position.y > 32.0F && bgSprite->position.y <= 64.0F &&
bgSprite->color.g > 0.0F) {
const float colorOffset = 1.5F;
bgSprite->color.g -= colorOffset;
bgSprite->color.b -= colorOffset;
bg2Sprite->color.g -= colorOffset;
bg2Sprite->color.b -= colorOffset;
}
if (bgSprite->position.y > slideUpMaxPost) {
bgSprite->position.y -= offset;
bg2Sprite->position.y -= offset;
}
}
if (fadeoutActivated && frameSkipper == 0) {
if (bgSprite->color.a > 0) {
bgSprite->color.a -= 4.0F;
bg2Sprite->color.a -= 4.0F;
} else
_wantFinish = true;
}
Threading::switchThread();
engine->renderer.renderer2D.render(bgSprite);
engine->renderer.renderer2D.render(bg2Sprite);
engine->renderer.renderer2D.render(tyraSprite);
renderFillers();
engine->renderer.endFrame();
}
void IntroTyraState::renderFillers() {
// Up
fillerSprite->position.set(0.0F, -63.0F);
engine->renderer.renderer2D.render(fillerSprite);
fillerSprite->position.set(256.0F, -63.0F);
engine->renderer.renderer2D.render(fillerSprite);
// Left
fillerSprite->position.set(-124.0F, 128.0F);
engine->renderer.renderer2D.render(fillerSprite);
// Down
fillerSprite->position.set(0.0F, 256.0F);
engine->renderer.renderer2D.render(fillerSprite);
fillerSprite->position.set(256.0F, 256.0F);
engine->renderer.renderer2D.render(fillerSprite);
// Right
fillerSprite->position.set(386.0F, 128.0F);
engine->renderer.renderer2D.render(fillerSprite);
}
} // namespace Demo
+72
View File
@@ -0,0 +1,72 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#include <tyra>
#include "states/loading/loading_state.hpp"
#include <memory>
using std::make_unique;
using std::unique_ptr;
using Tyra::FileUtils;
using Tyra::Sprite;
namespace Demo {
LoadingState::LoadingState(Engine* t_engine) : State(t_engine) {
state = STATE_LOADING;
_wantFinish = false;
initialized = false;
}
LoadingState::~LoadingState() {}
void LoadingState::onStart() {
TYRA_LOG("Loading. RAM: ", engine->info.getAvailableRAM(), "MB");
auto* repo = &engine->renderer.core.texture.repository;
auto fillerTexture = repo->add(FileUtils::fromCwd("loading/filler.png"));
auto loadingTexture = repo->add(FileUtils::fromCwd("loading/loading.png"));
auto fillerSprite = make_unique<Sprite>();
auto loadingSprite = make_unique<Sprite>();
fillerSprite->position.set(0.0F, 0.0F);
fillerSprite->size.set(600.0F, 600.0F);
fillerSprite->mode = Tyra::MODE_STRETCH;
loadingSprite->size.set(128.0F, 64.0F);
loadingSprite->mode = Tyra::MODE_STRETCH;
loadingSprite->position.set(5.0F, 448.0F - 64.0F - 5.0F);
fillerTexture->addLink(fillerSprite->id);
loadingTexture->addLink(loadingSprite->id);
engine->renderer.beginFrame();
engine->renderer.renderer2D.render(fillerSprite.get());
engine->renderer.renderer2D.render(loadingSprite.get());
engine->renderer.endFrame();
repo->free(fillerTexture->id);
repo->free(loadingTexture->id);
initialized = true;
}
GlobalStateType LoadingState::onFinish() {
if (!initialized) return STATE_GAME;
initialized = false;
return STATE_GAME;
}
void LoadingState::update() { _wantFinish = true; }
} // namespace Demo
+14
View File
@@ -0,0 +1,14 @@
version: "3.9"
volumes:
tyra-volume:
services:
compiler:
environment:
TERM: xterm-256color
network_mode: host
image: "h4570/tyra"
tty: true
container_name: tyra-compiler
volumes:
- tyra-volume:/src
- ./:/host
+25
View File
@@ -0,0 +1,25 @@
# Installing Tyra
[![](https://img.shields.io/badge/Install%20time-5%20minutes-brightgreen)](#)
## Prerequisites:
1. Git
2. VSCode
3. Docker with PowerShell as a default terminal
4. [PCSX2](https://github.com/h4570/tyra/blob/master/docs/install/pcsx2.md#)
---
## Steps:
1. Download [intellisense package](https://github.com/h4570/tyra/releases) and unzip it somewhere in your computer.
2. Open terminal in your favourite repositories directory and execute:
```
docker pull h4570/tyra
git clone https://github.com/h4570/tyra.git
```
3. Open `VSCode` and open previously cloned directory.
4. In `VSCode` open `.vscode/configurations/windows-docker` and copy configuration files into `.vscode/`
5. In `c_cpp_properties.json` fix all `YOUR-INTELLISENSE-PATH` with path from point 2.
6. Click `CTRL+SHIFT+P`, type `Tasks: Run task` and run `Start docker container` - Repeat this step every time you want to start working with Tyra (every reboot)
7. Click `CTRL+SHIFT+P`, type `Tasks: Run build task`
8. Tyra should automatically compile engine, `demo` game and run `PCSX2`. If you want to compile & run tutorials, please change `buildDirectory` in `settings.json` to example `tutorials/01-hello`
+21
View File
@@ -0,0 +1,21 @@
## Install & configure PCSX2
- Download & install PCSX2 (1.6+ version) from https://pcsx2.net/
- Extract bios files from https://romsmania.cc/bios/pcsx2-playstation-2-bios-3 to `%UserProfile%\Documents\PCSX2\bios`
- Close `PCSX2` if you have opened!
- Open `%UserProfile%\Documents\PCSX2\inis\PCSX2_vm.ini` in notepad
```
HostFs=enabled
```
- Open PCSX2 and map pad to your keyboard, for example:
```
WASD = Left joy
Arrows = Right joy
Space = X
Circle = C
```
- Enable **"EE timing hack"** in PCSX2 hacks!
+26
View File
@@ -0,0 +1,26 @@
TARGET := libtyra.a
#The Directories, Source, Includes, Objects, Binary and Resources
SRCDIR := src
INCDIR := inc
BUILDDIR := obj
TARGETDIR := bin
RESDIR := res
SRCEXT := cpp
VSMEXT := vsm
VCLEXT := vcl
VCLPPEXT := vclpp
DEPEXT := d
OBJEXT := o
#Flags, Libraries and Includes
CFLAGS :=
LIB :=
LIBDIRS :=
INC := -I$(INCDIR)
INCDEP := -I$(INCDIR)
include ../Makefile.base
$(TARGET): $(OBJECTS) $(VCL_OBJECTS) $(VU_OBJECTS_VCL) $(VU_OBJECTS_VSM) $(IRXEM_OBJECTS)
$(AR) rcs $(TARGETDIR)/$(TARGET) $(OBJECTS) $(VCL_OBJECTS) $(VU_OBJECTS_VCL) $(VU_OBJECTS_VSM) $(IRXEM_OBJECTS)
+4
View File
@@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore
+28
View File
@@ -0,0 +1,28 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022-2022, Tyra - https://github.com/h4570/tyrav2
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
# Wellinator Carvalho <wellcoj@gmail.com>
*/
#pragma once
namespace Tyra {
enum AdpcmResult {
ADPCM_OK,
/** When provided channel by user is currently in use */
ADPCM_CHANNEL_USED,
/** When user did not provided channel and all are in use */
ADPCM_NO_FREE_CHANNELS,
ADPCM_ERROR
};
} // namespace Tyra
+42
View File
@@ -0,0 +1,42 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022-2022, Tyra - https://github.com/h4570/tyrav2
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
# Wellinator Carvalho <wellcoj@gmail.com>
*/
#pragma once
#include "./audio_adpcm.hpp"
#include "./audio_song.hpp"
namespace Tyra {
/** Class responsible for audio. */
class Audio {
public:
Audio();
~Audio();
void init();
AudioSong song;
AudioAdpcm adpcm;
void work();
private:
ee_thread_t thread;
int threadId;
static const u16 threadStackSize;
u8* threadStack;
void initAUDSRV();
void initThread();
};
} // namespace Tyra
+77
View File
@@ -0,0 +1,77 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022-2022, Tyra - https://github.com/h4570/tyrav2
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
# Wellinator Carvalho <wellcoj@gmail.com>
*/
#pragma once
#include "./audio_listener_ref.hpp"
#include "./adpcm_result.hpp"
#include <audsrv.h>
#include <string>
namespace Tyra {
/**
* Class responsible for playing ADPCM samples.
* ADPCM sample can't be stopped.
*/
class AudioAdpcm {
public:
AudioAdpcm();
~AudioAdpcm();
void init();
/**
* Load ADPCM sample.
* ADPCM sample is an output from "Convert WAV to ADPCM" task (adpenc tool).
* Adpenc expects 22kHz 16bit file.
* @param t_path Example: "host:hit.adpcm" or "host:folder/jump.adpcm"
*/
audsrv_adpcm_t* load(const char* t_path);
audsrv_adpcm_t* load(const std::string& t_path);
/**
* Frees up all memory taken by samples, and stops all voices from
* being played.
*/
void reset();
/**
* Try play ADPCM sample if channel(s) is not occupied.
* @param t_adpcm ADPCM data, created by load();
* @param t_ch Channel (0-23). Type -1 for use any free channel.
*/
AdpcmResult tryPlay(audsrv_adpcm_t* t_adpcm);
AdpcmResult tryPlay(audsrv_adpcm_t* t_adpcm, const s8& t_ch);
/**
* Play ADPCM sample, if channel is occupied, wait for it.
* If not used properly, can hugely reduce performance.
* @param t_adpcm ADPCM data, created by load();
* @param t_ch Channel (0-23). Type -1 for use any free channel.
*/
void playWait(audsrv_adpcm_t* t_adpcm);
void playWait(audsrv_adpcm_t* t_adpcm, const s8& t_ch);
/**
* Set ADPCM volume.
* @param t_vol Value 0-100
* @param t_ch Channel (0-23)
*/
void setVolume(const u8& t_vol, const s8& t_ch) {
audsrv_adpcm_set_volume(t_ch, t_vol);
}
private:
void initAUDSRV();
};
} // namespace Tyra
+25
View File
@@ -0,0 +1,25 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022-2022, Tyra - https://github.com/h4570/tyrav2
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
# Wellinator Carvalho <wellcoj@gmail.com>
*/
#pragma once
namespace Tyra {
class AudioListener {
public:
virtual ~AudioListener(){};
virtual void onAudioTick() = 0;
virtual void onAudioFinish() = 0;
private:
};
} // namespace Tyra
+24
View File
@@ -0,0 +1,24 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022-2022, Tyra - https://github.com/h4570/tyrav2
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
# Wellinator Carvalho <wellcoj@gmail.com>
*/
#pragma once
#include "./audio_listener.hpp"
#include <tamtypes.h>
namespace Tyra {
struct AudioListenerRef {
AudioListener* listener;
u32 id;
};
} // namespace Tyra
+90
View File
@@ -0,0 +1,90 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022-2022, Tyra - https://github.com/h4570/tyrav2
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
# Wellinator Carvalho <wellcoj@gmail.com>
*/
#pragma once
#include "./audio_listener_ref.hpp"
#include <audsrv.h>
#include <string>
#include <vector>
#include <kernel.h>
namespace Tyra {
/** Class responsible for background audio playing. */
class AudioSong {
public:
AudioSong();
~AudioSong();
void init();
bool inLoop;
/**
* Load 16bit 22kHz Stereo WAV.
* Can be used multiple times for song switching.
* @param t_path Example: "host:song.wav" or "host:folder/song.wav"
*/
void load(const char* t_path);
void load(const std::string& t_path);
void play();
void stop();
const bool& isPlaying() const;
const bool& isLoaded() const;
const u8& getVolume() const;
/**
* Set song volume.
* @param t_vol Value 0-100
*/
void setVolume(const u8& t_vol);
/**
* If you want to synchronize some actions with
* background song, add audio listener.
* @returns Listener id.
*/
u32 addListener(AudioListener* t_listener);
/** Remove song listener. */
void removeListener(const u32& t_id);
std::size_t getListenersCount() const;
void work();
private:
bool songLoaded, songPlaying, songFinished;
u8 tyraVolume, audsrvVolume;
FILE* wav;
audsrv_fmt_t format;
std::vector<AudioListenerRef*> songListeners;
ee_sema_t sema;
s32 fillbufferSema;
static const u16 chunkSize;
char* chunk;
s32 chunkReadStatus;
void initSema();
void initAUDSRV();
void setSongFormat();
void unloadSong();
void rewindSongToStart();
};
} // namespace Tyra
+117
View File
@@ -0,0 +1,117 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#ifdef NDEBUG
#define TYRA_LOG(...) ((void)0)
#define TYRA_WARN(...) ((void)0)
#define TYRA_ERROR(...) ((void)0)
#define TYRA_TRAP(...) ((void)0)
#define TYRA_ASSERT(condition, ...) ((void)0)
#else // IF Debug
#include <stdio.h>
#include <string>
#include <sstream>
#include <fstream>
#include <utility>
#include <memory>
#include "file/file_utils.hpp"
#include "info/info.hpp"
#define TYRA_LOG(...) TyraDebug::writeLines("LOG: ", ##__VA_ARGS__, "\n")
#define TYRA_WARN(...) TyraDebug::writeLines("==WARN: ", ##__VA_ARGS__, "\n")
#define TYRA_ERROR(...) TyraDebug::writeLines("====ERR: ", ##__VA_ARGS__, "\n")
#define TYRA_TRAP(...) TyraDebug::trap(__FILE__, __LINE__, ##__VA_ARGS__)
#define TYRA_BREAKPOINT() TyraDebug::trap(__FILE__, __LINE__, "Breakpoint")
#define TYRA_ASSERT(condition, ...) \
if (!(condition)) TyraDebug::trap(__FILE__, __LINE__, ##__VA_ARGS__)
class TyraDebug {
public:
template <typename Arg, typename... Args>
static void writeLines(Arg&& arg, Args&&... args) {
std::stringstream ss;
ss << std::forward<Arg>(arg);
using expander = int[];
(void)expander{0, (void(ss << std::forward<Args>(args)), 0)...};
if (Tyra::Info::writeLogsToFile) {
auto* logFile = getLogFile();
*logFile << ss.str();
logFile->flush();
} else {
printf("%s", ss.str().c_str());
}
}
template <typename... Args>
static void trap(const char* file, int line, Args... args) {
std::stringstream ss1;
ss1 << "\n";
ss1 << "============== TYRA ==============\n";
ss1 << "| Assertion failed!\n";
ss1 << "|\n";
if (Tyra::Info::writeLogsToFile) {
auto* logFile = getLogFile();
*logFile << ss1.str();
logFile->flush();
} else {
printf("%s", ss1.str().c_str());
}
writeAssertLines(args...);
std::stringstream ss2;
ss2 << "|\n";
ss2 << "| File : " << file << ":" << line << "\n";
ss2 << "====================================\n\n";
if (Tyra::Info::writeLogsToFile) {
auto* logFile = getLogFile();
*logFile << ss2.str();
logFile->flush();
} else {
printf("%s", ss2.str().c_str());
}
for (;;) {
}
}
private:
static std::unique_ptr<std::ofstream> logFile;
static std::ofstream* getLogFile();
template <typename Arg, typename... Args>
static void writeAssertLines(Arg&& arg, Args&&... args) {
std::stringstream ss;
ss << "| " << std::forward<Arg>(arg) << "\n";
using expander = int[];
(void)expander{
0, (void(ss << "| " << std::forward<Args>(args) << "\n"), 0)...};
if (Tyra::Info::writeLogsToFile) {
auto* logfile = getLogFile();
*logfile << ss.str();
logFile->flush();
} else {
printf("%s", ss.str().c_str());
}
}
};
#endif // NDEBUG
+56
View File
@@ -0,0 +1,56 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "./renderer/renderer.hpp"
#include "./pad/pad.hpp"
#include "./audio/audio.hpp"
#include "./irx/irx_loader.hpp"
#include "./info/info.hpp"
#include "./info/banner.hpp"
#include "./game.hpp"
namespace Tyra {
struct EngineOptions {
/**
* True -> logs will be written to file.
* False -> logs will be displayed in console
*/
bool writeLogsToFile = false;
bool loadUsbDriver = false;
};
class Engine {
public:
Engine();
Engine(const EngineOptions& options);
~Engine();
Renderer renderer;
Pad pad;
Audio audio;
Info info;
void run(Game* t_game);
private:
IrxLoader irx;
Game* game;
Banner banner;
void realLoop();
void initAll(const bool& loadUsbDriver);
};
} // namespace Tyra
+52
View File
@@ -0,0 +1,52 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Wellington Carvalho <wellcoj@gmail.com>
*/
#pragma once
#include <string>
namespace Tyra {
class FileUtils {
public:
FileUtils();
~FileUtils();
/**
* Get current working directory.
* Example: "host:" or "mass:"
*/
static std::string getCwd();
/**
* Add current working directory prefix to path
* Example: "host:..." or "mass:..."
*/
static std::string fromCwd(const std::string& relativePath);
static std::string fromCwd(const char* relativePath);
static std::string getFilenameFromPath(const std::string& path);
static std::string getPathFromFilename(const std::string& path);
static std::string getFilenameWithoutExtension(const std::string& filename);
static std::string getExtensionOfFilename(const std::string& filename);
const char* getElfName() const { return elfName; };
const char* getElfPath() const { return elfPath; };
private:
// Argv name+path & just path
char cwd[255];
char elfName[255];
char elfPath[255 - 14];
void setPathInfo(const char* path);
};
} // namespace Tyra
+21
View File
@@ -0,0 +1,21 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
namespace Tyra {
class Game {
public:
virtual void init() = 0;
virtual void loop() = 0;
};
} // namespace Tyra
+25
View File
@@ -0,0 +1,25 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Wellington Carvalho <wellcoj@gmail.com>
*/
#pragma once
#include "renderer/renderer.hpp"
namespace Tyra {
class Banner {
public:
Banner();
~Banner();
void show(Renderer* renderer);
};
} // namespace Tyra
+47
View File
@@ -0,0 +1,47 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Wellington Carvalho <wellcoj@gmail.com>
*/
#pragma once
#include <tamtypes.h>
#include <stddef.h>
#include "time/timer.hpp"
#include "./version.hpp"
namespace Tyra {
class Info {
public:
Info();
~Info();
Version version;
static bool writeLogsToFile;
/** Called by engine */
void update();
const u32& getFps() const { return fps; };
/** @return Available RAM in MB */
float getAvailableRAM();
private:
float calcFps();
void* allocateLargestFreeRAMBlock(size_t* size);
size_t getFreeRAMSize();
u8 fpsDelayer;
u32 fps;
Timer timer;
};
} // namespace Tyra
+33
View File
@@ -0,0 +1,33 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# André Guilherme <andregui17@outlook.com>
*/
#pragma once
#include <tamtypes.h>
#include <string>
namespace Tyra {
class Version {
public:
Version() {}
~Version() {}
static const u8 major = 2;
static const u8 minor = 0;
static const u8 patch = 0;
static std::string toString() {
return std::to_string(major) + "." + std::to_string(minor) + "." +
std::to_string(patch);
}
};
} // namespace Tyra
+38
View File
@@ -0,0 +1,38 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Wellington Carvalho <wellcoj@gmail.com>
*/
#pragma once
#include <tamtypes.h>
namespace Tyra {
class IrxLoader {
public:
IrxLoader();
~IrxLoader();
void loadAll(const bool& withUsb, const bool& isLoggingToFile);
private:
static bool isLoaded;
void loadSio2man(const bool& verbose);
void loadPadman(const bool& verbose);
void loadLibsd(const bool& verbose);
void loadUsbModules(const bool& verbose);
void loadAudsrv(const bool& verbose);
int applyRpcPatches();
void waitUntilUsbDeviceIsReady();
void delay(int count);
};
} // namespace Tyra
@@ -0,0 +1,34 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <vector>
#include "./mesh_builder_material_data.hpp"
namespace Tyra {
/**
* Data needed for constructing mesh class.
* All dynamic data ownership is moved to mesh class, so
* verts, coords.. are not deallocated!
*/
class MeshBuilderData {
public:
MeshBuilderData();
~MeshBuilderData();
std::vector<MeshBuilderMaterialData*> materials;
bool loadNormals, loadLightmap;
};
} // namespace Tyra
@@ -0,0 +1,33 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <vector>
#include <string>
#include <optional>
#include "./mesh_builder_material_frame_data.hpp"
#include "renderer/models/color.hpp"
namespace Tyra {
class MeshBuilderMaterialData {
public:
MeshBuilderMaterialData();
~MeshBuilderMaterialData();
std::vector<MeshBuilderMaterialFrameData*> frames;
std::string name;
std::optional<std::string> texturePath;
Color ambient;
};
} // namespace Tyra
@@ -0,0 +1,30 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tamtypes.h>
#include "math/vec4.hpp"
#include "renderer/models/color.hpp"
namespace Tyra {
class MeshBuilderMaterialFrameData {
public:
MeshBuilderMaterialFrameData();
~MeshBuilderMaterialFrameData();
u32 count;
Vec4 *vertices, *textureCoords, *normals;
Color* colors;
};
} // namespace Tyra
+103
View File
@@ -0,0 +1,103 @@
/*
Copyright (C) 1997-2001 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#pragma once
namespace Tyra {
const float ANORMS[162][3] = {
{-0.525731f, 0.000000f, 0.850651f}, {-0.442863f, 0.238856f, 0.864188f},
{-0.295242f, 0.000000f, 0.955423f}, {-0.309017f, 0.500000f, 0.809017f},
{-0.162460f, 0.262866f, 0.951056f}, {0.000000f, 0.000000f, 1.000000f},
{0.000000f, 0.850651f, 0.525731f}, {-0.147621f, 0.716567f, 0.681718f},
{0.147621f, 0.716567f, 0.681718f}, {0.000000f, 0.525731f, 0.850651f},
{0.309017f, 0.500000f, 0.809017f}, {0.525731f, 0.000000f, 0.850651f},
{0.295242f, 0.000000f, 0.955423f}, {0.442863f, 0.238856f, 0.864188f},
{0.162460f, 0.262866f, 0.951056f}, {-0.681718f, 0.147621f, 0.716567f},
{-0.809017f, 0.309017f, 0.500000f}, {-0.587785f, 0.425325f, 0.688191f},
{-0.850651f, 0.525731f, 0.000000f}, {-0.864188f, 0.442863f, 0.238856f},
{-0.716567f, 0.681718f, 0.147621f}, {-0.688191f, 0.587785f, 0.425325f},
{-0.500000f, 0.809017f, 0.309017f}, {-0.238856f, 0.864188f, 0.442863f},
{-0.425325f, 0.688191f, 0.587785f}, {-0.716567f, 0.681718f, -0.147621f},
{-0.500000f, 0.809017f, -0.309017f}, {-0.525731f, 0.850651f, 0.000000f},
{0.000000f, 0.850651f, -0.525731f}, {-0.238856f, 0.864188f, -0.442863f},
{0.000000f, 0.955423f, -0.295242f}, {-0.262866f, 0.951056f, -0.162460f},
{0.000000f, 1.000000f, 0.000000f}, {0.000000f, 0.955423f, 0.295242f},
{-0.262866f, 0.951056f, 0.162460f}, {0.238856f, 0.864188f, 0.442863f},
{0.262866f, 0.951056f, 0.162460f}, {0.500000f, 0.809017f, 0.309017f},
{0.238856f, 0.864188f, -0.442863f}, {0.262866f, 0.951056f, -0.162460f},
{0.500000f, 0.809017f, -0.309017f}, {0.850651f, 0.525731f, 0.000000f},
{0.716567f, 0.681718f, 0.147621f}, {0.716567f, 0.681718f, -0.147621f},
{0.525731f, 0.850651f, 0.000000f}, {0.425325f, 0.688191f, 0.587785f},
{0.864188f, 0.442863f, 0.238856f}, {0.688191f, 0.587785f, 0.425325f},
{0.809017f, 0.309017f, 0.500000f}, {0.681718f, 0.147621f, 0.716567f},
{0.587785f, 0.425325f, 0.688191f}, {0.955423f, 0.295242f, 0.000000f},
{1.000000f, 0.000000f, 0.000000f}, {0.951056f, 0.162460f, 0.262866f},
{0.850651f, -0.525731f, 0.000000f}, {0.955423f, -0.295242f, 0.000000f},
{0.864188f, -0.442863f, 0.238856f}, {0.951056f, -0.162460f, 0.262866f},
{0.809017f, -0.309017f, 0.500000f}, {0.681718f, -0.147621f, 0.716567f},
{0.850651f, 0.000000f, 0.525731f}, {0.864188f, 0.442863f, -0.238856f},
{0.809017f, 0.309017f, -0.500000f}, {0.951056f, 0.162460f, -0.262866f},
{0.525731f, 0.000000f, -0.850651f}, {0.681718f, 0.147621f, -0.716567f},
{0.681718f, -0.147621f, -0.716567f}, {0.850651f, 0.000000f, -0.525731f},
{0.809017f, -0.309017f, -0.500000f}, {0.864188f, -0.442863f, -0.238856f},
{0.951056f, -0.162460f, -0.262866f}, {0.147621f, 0.716567f, -0.681718f},
{0.309017f, 0.500000f, -0.809017f}, {0.425325f, 0.688191f, -0.587785f},
{0.442863f, 0.238856f, -0.864188f}, {0.587785f, 0.425325f, -0.688191f},
{0.688191f, 0.587785f, -0.425325f}, {-0.147621f, 0.716567f, -0.681718f},
{-0.309017f, 0.500000f, -0.809017f}, {0.000000f, 0.525731f, -0.850651f},
{-0.525731f, 0.000000f, -0.850651f}, {-0.442863f, 0.238856f, -0.864188f},
{-0.295242f, 0.000000f, -0.955423f}, {-0.162460f, 0.262866f, -0.951056f},
{0.000000f, 0.000000f, -1.000000f}, {0.295242f, 0.000000f, -0.955423f},
{0.162460f, 0.262866f, -0.951056f}, {-0.442863f, -0.238856f, -0.864188f},
{-0.309017f, -0.500000f, -0.809017f}, {-0.162460f, -0.262866f, -0.951056f},
{0.000000f, -0.850651f, -0.525731f}, {-0.147621f, -0.716567f, -0.681718f},
{0.147621f, -0.716567f, -0.681718f}, {0.000000f, -0.525731f, -0.850651f},
{0.309017f, -0.500000f, -0.809017f}, {0.442863f, -0.238856f, -0.864188f},
{0.162460f, -0.262866f, -0.951056f}, {0.238856f, -0.864188f, -0.442863f},
{0.500000f, -0.809017f, -0.309017f}, {0.425325f, -0.688191f, -0.587785f},
{0.716567f, -0.681718f, -0.147621f}, {0.688191f, -0.587785f, -0.425325f},
{0.587785f, -0.425325f, -0.688191f}, {0.000000f, -0.955423f, -0.295242f},
{0.000000f, -1.000000f, 0.000000f}, {0.262866f, -0.951056f, -0.162460f},
{0.000000f, -0.850651f, 0.525731f}, {0.000000f, -0.955423f, 0.295242f},
{0.238856f, -0.864188f, 0.442863f}, {0.262866f, -0.951056f, 0.162460f},
{0.500000f, -0.809017f, 0.309017f}, {0.716567f, -0.681718f, 0.147621f},
{0.525731f, -0.850651f, 0.000000f}, {-0.238856f, -0.864188f, -0.442863f},
{-0.500000f, -0.809017f, -0.309017f}, {-0.262866f, -0.951056f, -0.162460f},
{-0.850651f, -0.525731f, 0.000000f}, {-0.716567f, -0.681718f, -0.147621f},
{-0.716567f, -0.681718f, 0.147621f}, {-0.525731f, -0.850651f, 0.000000f},
{-0.500000f, -0.809017f, 0.309017f}, {-0.238856f, -0.864188f, 0.442863f},
{-0.262866f, -0.951056f, 0.162460f}, {-0.864188f, -0.442863f, 0.238856f},
{-0.809017f, -0.309017f, 0.500000f}, {-0.688191f, -0.587785f, 0.425325f},
{-0.681718f, -0.147621f, 0.716567f}, {-0.442863f, -0.238856f, 0.864188f},
{-0.587785f, -0.425325f, 0.688191f}, {-0.309017f, -0.500000f, 0.809017f},
{-0.147621f, -0.716567f, 0.681718f}, {-0.425325f, -0.688191f, 0.587785f},
{-0.162460f, -0.262866f, 0.951056f}, {0.442863f, -0.238856f, 0.864188f},
{0.162460f, -0.262866f, 0.951056f}, {0.309017f, -0.500000f, 0.809017f},
{0.147621f, -0.716567f, 0.681718f}, {0.000000f, -0.525731f, 0.850651f},
{0.425325f, -0.688191f, 0.587785f}, {0.587785f, -0.425325f, 0.688191f},
{0.688191f, -0.587785f, 0.425325f}, {-0.955423f, 0.295242f, 0.000000f},
{-0.951056f, 0.162460f, 0.262866f}, {-1.000000f, 0.000000f, 0.000000f},
{-0.850651f, 0.000000f, 0.525731f}, {-0.955423f, -0.295242f, 0.000000f},
{-0.951056f, -0.162460f, 0.262866f}, {-0.864188f, 0.442863f, -0.238856f},
{-0.951056f, 0.162460f, -0.262866f}, {-0.809017f, 0.309017f, -0.500000f},
{-0.864188f, -0.442863f, -0.238856f}, {-0.951056f, -0.162460f, -0.262866f},
{-0.809017f, -0.309017f, -0.500000f}, {-0.681718f, 0.147621f, -0.716567f},
{-0.681718f, -0.147621f, -0.716567f}, {-0.850651f, 0.000000f, -0.525731f},
{-0.688191f, 0.587785f, -0.425325f}, {-0.587785f, 0.425325f, -0.688191f},
{-0.425325f, 0.688191f, -0.587785f}, {-0.425325f, -0.688191f, -0.587785f},
{-0.587785f, -0.425325f, -0.688191f}, {-0.688191f, -0.587785f, -0.425325f}};
}
@@ -0,0 +1,35 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "../builder/mesh_builder_data.hpp"
#include <string>
#include <memory>
namespace Tyra {
struct MD2LoaderOptions {
bool flipUVs = false;
float scale = 1.0F;
};
/** Class responsible for loading & parsing Quake's II ".md2" 3D files */
class MD2Loader {
public:
static std::unique_ptr<MeshBuilderData> load(const char* fullpath);
static std::unique_ptr<MeshBuilderData> load(const char* fullpath,
MD2LoaderOptions options);
static std::unique_ptr<MeshBuilderData> load(const std::string& fullpath);
static std::unique_ptr<MeshBuilderData> load(const std::string& fullpath,
MD2LoaderOptions options);
};
} // namespace Tyra
@@ -0,0 +1,853 @@
#pragma once
#include <algorithm>
#include <cassert>
#include <cmath>
#include <memory>
#include <vector>
namespace mapbox {
namespace util {
template <std::size_t I, typename T>
struct nth {
inline static typename std::tuple_element<I, T>::type get(const T& t) {
return std::get<I>(t);
};
};
} // namespace util
namespace detail {
template <typename N = uint32_t>
class Earcut {
public:
std::vector<N> indices;
std::size_t vertices = 0;
template <typename Polygon>
void operator()(const Polygon& points);
private:
struct Node {
Node(N index, double x_, double y_) : i(index), x(x_), y(y_) {}
Node(const Node&) = delete;
Node& operator=(const Node&) = delete;
Node(Node&&) = delete;
Node& operator=(Node&&) = delete;
const N i;
const double x;
const double y;
// previous and next vertice nodes in a polygon ring
Node* prev = nullptr;
Node* next = nullptr;
// z-order curve value
int32_t z = 0;
// previous and next nodes in z-order
Node* prevZ = nullptr;
Node* nextZ = nullptr;
// indicates whether this is a steiner point
bool steiner = false;
};
template <typename Ring>
Node* linkedList(const Ring& points, const bool clockwise);
Node* filterPoints(Node* start, Node* end = nullptr);
void earcutLinked(Node* ear, int pass = 0);
bool isEar(Node* ear);
bool isEarHashed(Node* ear);
Node* cureLocalIntersections(Node* start);
void splitEarcut(Node* start);
template <typename Polygon>
Node* eliminateHoles(const Polygon& points, Node* outerNode);
Node* eliminateHole(Node* hole, Node* outerNode);
Node* findHoleBridge(Node* hole, Node* outerNode);
bool sectorContainsSector(const Node* m, const Node* p);
void indexCurve(Node* start);
Node* sortLinked(Node* list);
int32_t zOrder(const double x_, const double y_);
Node* getLeftmost(Node* start);
bool pointInTriangle(double ax, double ay, double bx, double by, double cx,
double cy, double px, double py) const;
bool isValidDiagonal(Node* a, Node* b);
double area(const Node* p, const Node* q, const Node* r) const;
bool equals(const Node* p1, const Node* p2);
bool intersects(const Node* p1, const Node* q1, const Node* p2,
const Node* q2);
bool onSegment(const Node* p, const Node* q, const Node* r);
int sign(double val);
bool intersectsPolygon(const Node* a, const Node* b);
bool locallyInside(const Node* a, const Node* b);
bool middleInside(const Node* a, const Node* b);
Node* splitPolygon(Node* a, Node* b);
template <typename Point>
Node* insertNode(std::size_t i, const Point& p, Node* last);
void removeNode(Node* p);
bool hashing;
double minX, maxX;
double minY, maxY;
double inv_size = 0;
template <typename T, typename Alloc = std::allocator<T>>
class ObjectPool {
public:
ObjectPool() {}
ObjectPool(std::size_t blockSize_) { reset(blockSize_); }
~ObjectPool() { clear(); }
template <typename... Args>
T* construct(Args&&... args) {
if (currentIndex >= blockSize) {
currentBlock = alloc_traits::allocate(alloc, blockSize);
allocations.emplace_back(currentBlock);
currentIndex = 0;
}
T* object = &currentBlock[currentIndex++];
alloc_traits::construct(alloc, object, std::forward<Args>(args)...);
return object;
}
void reset(std::size_t newBlockSize) {
for (auto allocation : allocations) {
alloc_traits::deallocate(alloc, allocation, blockSize);
}
allocations.clear();
blockSize = std::max<std::size_t>(1, newBlockSize);
currentBlock = nullptr;
currentIndex = blockSize;
}
void clear() { reset(blockSize); }
private:
T* currentBlock = nullptr;
std::size_t currentIndex = 1;
std::size_t blockSize = 1;
std::vector<T*> allocations;
Alloc alloc;
typedef typename std::allocator_traits<Alloc> alloc_traits;
};
ObjectPool<Node> nodes;
};
template <typename N>
template <typename Polygon>
void Earcut<N>::operator()(const Polygon& points) {
// reset
indices.clear();
vertices = 0;
if (points.empty()) return;
double x;
double y;
int threshold = 80;
std::size_t len = 0;
for (size_t i = 0; threshold >= 0 && i < points.size(); i++) {
threshold -= static_cast<int>(points[i].size());
len += points[i].size();
}
// estimate size of nodes and indices
nodes.reset(len * 3 / 2);
indices.reserve(len + points[0].size());
Node* outerNode = linkedList(points[0], true);
if (!outerNode || outerNode->prev == outerNode->next) return;
if (points.size() > 1) outerNode = eliminateHoles(points, outerNode);
// if the shape is not too simple, we'll use z-order curve hash later;
// calculate polygon bbox
hashing = threshold < 0;
if (hashing) {
Node* p = outerNode->next;
minX = maxX = outerNode->x;
minY = maxY = outerNode->y;
do {
x = p->x;
y = p->y;
minX = std::min<double>(minX, x);
minY = std::min<double>(minY, y);
maxX = std::max<double>(maxX, x);
maxY = std::max<double>(maxY, y);
p = p->next;
} while (p != outerNode);
// minX, minY and size are later used to transform coords into integers for
// z-order calculation
inv_size = std::max<double>(maxX - minX, maxY - minY);
inv_size = inv_size != .0 ? (1. / inv_size) : .0;
}
earcutLinked(outerNode);
nodes.clear();
}
// create a circular doubly linked list from polygon points in the specified
// winding order
template <typename N>
template <typename Ring>
typename Earcut<N>::Node* Earcut<N>::linkedList(const Ring& points,
const bool clockwise) {
using Point = typename Ring::value_type;
double sum = 0;
const std::size_t len = points.size();
std::size_t i, j;
Node* last = nullptr;
// calculate original winding order of a polygon ring
for (i = 0, j = len > 0 ? len - 1 : 0; i < len; j = i++) {
const auto& p1 = points[i];
const auto& p2 = points[j];
const double p20 = util::nth<0, Point>::get(p2);
const double p10 = util::nth<0, Point>::get(p1);
const double p11 = util::nth<1, Point>::get(p1);
const double p21 = util::nth<1, Point>::get(p2);
sum += (p20 - p10) * (p11 + p21);
}
// link points into circular doubly-linked list in the specified winding order
if (clockwise == (sum > 0)) {
for (i = 0; i < len; i++) last = insertNode(vertices + i, points[i], last);
} else {
for (i = len; i-- > 0;) last = insertNode(vertices + i, points[i], last);
}
if (last && equals(last, last->next)) {
removeNode(last);
last = last->next;
}
vertices += len;
return last;
}
// eliminate colinear or duplicate points
template <typename N>
typename Earcut<N>::Node* Earcut<N>::filterPoints(Node* start, Node* end) {
if (!end) end = start;
Node* p = start;
bool again;
do {
again = false;
if (!p->steiner && (equals(p, p->next) || area(p->prev, p, p->next) == 0)) {
removeNode(p);
p = end = p->prev;
if (p == p->next) break;
again = true;
} else {
p = p->next;
}
} while (again || p != end);
return end;
}
// main ear slicing loop which triangulates a polygon (given as a linked list)
template <typename N>
void Earcut<N>::earcutLinked(Node* ear, int pass) {
if (!ear) return;
// interlink polygon nodes in z-order
if (!pass && hashing) indexCurve(ear);
Node* stop = ear;
Node* prev;
Node* next;
int iterations = 0;
// iterate through ears, slicing them one by one
while (ear->prev != ear->next) {
iterations++;
prev = ear->prev;
next = ear->next;
if (hashing ? isEarHashed(ear) : isEar(ear)) {
// cut off the triangle
indices.emplace_back(prev->i);
indices.emplace_back(ear->i);
indices.emplace_back(next->i);
removeNode(ear);
// skipping the next vertice leads to less sliver triangles
ear = next->next;
stop = next->next;
continue;
}
ear = next;
// if we looped through the whole remaining polygon and can't find any more
// ears
if (ear == stop) {
// try filtering points and slicing again
if (!pass) earcutLinked(filterPoints(ear), 1);
// if this didn't work, try curing all small self-intersections locally
else if (pass == 1) {
ear = cureLocalIntersections(filterPoints(ear));
earcutLinked(ear, 2);
// as a last resort, try splitting the remaining polygon into two
} else if (pass == 2)
splitEarcut(ear);
break;
}
}
}
// check whether a polygon node forms a valid ear with adjacent nodes
template <typename N>
bool Earcut<N>::isEar(Node* ear) {
const Node* a = ear->prev;
const Node* b = ear;
const Node* c = ear->next;
if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
// now make sure we don't have other points inside the potential ear
Node* p = ear->next->next;
while (p != ear->prev) {
if (pointInTriangle(a->x, a->y, b->x, b->y, c->x, c->y, p->x, p->y) &&
area(p->prev, p, p->next) >= 0)
return false;
p = p->next;
}
return true;
}
template <typename N>
bool Earcut<N>::isEarHashed(Node* ear) {
const Node* a = ear->prev;
const Node* b = ear;
const Node* c = ear->next;
if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
// triangle bbox; min & max are calculated like this for speed
const double minTX = std::min<double>(a->x, std::min<double>(b->x, c->x));
const double minTY = std::min<double>(a->y, std::min<double>(b->y, c->y));
const double maxTX = std::max<double>(a->x, std::max<double>(b->x, c->x));
const double maxTY = std::max<double>(a->y, std::max<double>(b->y, c->y));
// z-order range for the current triangle bbox;
const int32_t minZ = zOrder(minTX, minTY);
const int32_t maxZ = zOrder(maxTX, maxTY);
// first look for points inside the triangle in increasing z-order
Node* p = ear->nextZ;
while (p && p->z <= maxZ) {
if (p != ear->prev && p != ear->next &&
pointInTriangle(a->x, a->y, b->x, b->y, c->x, c->y, p->x, p->y) &&
area(p->prev, p, p->next) >= 0)
return false;
p = p->nextZ;
}
// then look for points in decreasing z-order
p = ear->prevZ;
while (p && p->z >= minZ) {
if (p != ear->prev && p != ear->next &&
pointInTriangle(a->x, a->y, b->x, b->y, c->x, c->y, p->x, p->y) &&
area(p->prev, p, p->next) >= 0)
return false;
p = p->prevZ;
}
return true;
}
// go through all polygon nodes and cure small local self-intersections
template <typename N>
typename Earcut<N>::Node* Earcut<N>::cureLocalIntersections(Node* start) {
Node* p = start;
do {
Node* a = p->prev;
Node* b = p->next->next;
// a self-intersection where edge (v[i-1],v[i]) intersects (v[i+1],v[i+2])
if (!equals(a, b) && intersects(a, p, p->next, b) && locallyInside(a, b) &&
locallyInside(b, a)) {
indices.emplace_back(a->i);
indices.emplace_back(p->i);
indices.emplace_back(b->i);
// remove two nodes involved
removeNode(p);
removeNode(p->next);
p = start = b;
}
p = p->next;
} while (p != start);
return filterPoints(p);
}
// try splitting polygon into two and triangulate them independently
template <typename N>
void Earcut<N>::splitEarcut(Node* start) {
// look for a valid diagonal that divides the polygon into two
Node* a = start;
do {
Node* b = a->next->next;
while (b != a->prev) {
if (a->i != b->i && isValidDiagonal(a, b)) {
// split the polygon in two by the diagonal
Node* c = splitPolygon(a, b);
// filter colinear points around the cuts
a = filterPoints(a, a->next);
c = filterPoints(c, c->next);
// run earcut on each half
earcutLinked(a);
earcutLinked(c);
return;
}
b = b->next;
}
a = a->next;
} while (a != start);
}
// link every hole into the outer loop, producing a single-ring polygon without
// holes
template <typename N>
template <typename Polygon>
typename Earcut<N>::Node* Earcut<N>::eliminateHoles(const Polygon& points,
Node* outerNode) {
const size_t len = points.size();
std::vector<Node*> queue;
for (size_t i = 1; i < len; i++) {
Node* list = linkedList(points[i], false);
if (list) {
if (list == list->next) list->steiner = true;
queue.push_back(getLeftmost(list));
}
}
std::sort(queue.begin(), queue.end(),
[](const Node* a, const Node* b) { return a->x < b->x; });
// process holes from left to right
for (size_t i = 0; i < queue.size(); i++) {
outerNode = eliminateHole(queue[i], outerNode);
outerNode = filterPoints(outerNode, outerNode->next);
}
return outerNode;
}
// find a bridge between vertices that connects hole with an outer ring and and
// link it
template <typename N>
typename Earcut<N>::Node* Earcut<N>::eliminateHole(Node* hole,
Node* outerNode) {
Node* bridge = findHoleBridge(hole, outerNode);
if (!bridge) {
return outerNode;
}
Node* bridgeReverse = splitPolygon(bridge, hole);
// filter collinear points around the cuts
Node* filteredBridge = filterPoints(bridge, bridge->next);
filterPoints(bridgeReverse, bridgeReverse->next);
// Check if input node was removed by the filtering
return outerNode == bridge ? filteredBridge : outerNode;
}
// David Eberly's algorithm for finding a bridge between hole and outer polygon
template <typename N>
typename Earcut<N>::Node* Earcut<N>::findHoleBridge(Node* hole,
Node* outerNode) {
Node* p = outerNode;
double hx = hole->x;
double hy = hole->y;
double qx = -std::numeric_limits<double>::infinity();
Node* m = nullptr;
// find a segment intersected by a ray from the hole's leftmost Vertex to the
// left; segment's endpoint with lesser x will be potential connection Vertex
do {
if (hy <= p->y && hy >= p->next->y && p->next->y != p->y) {
double x = p->x + (hy - p->y) * (p->next->x - p->x) / (p->next->y - p->y);
if (x <= hx && x > qx) {
qx = x;
if (x == hx) {
if (hy == p->y) return p;
if (hy == p->next->y) return p->next;
}
m = p->x < p->next->x ? p : p->next;
}
}
p = p->next;
} while (p != outerNode);
if (!m) return 0;
if (hx == qx) return m; // hole touches outer segment; pick leftmost endpoint
// look for points inside the triangle of hole Vertex, segment intersection
// and endpoint; if there are no points found, we have a valid connection;
// otherwise choose the Vertex of the minimum angle with the ray as connection
// Vertex
const Node* stop = m;
double tanMin = std::numeric_limits<double>::infinity();
double tanCur = 0;
p = m;
double mx = m->x;
double my = m->y;
do {
if (hx >= p->x && p->x >= mx && hx != p->x &&
pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy,
p->x, p->y)) {
tanCur = std::abs(hy - p->y) / (hx - p->x); // tangential
if (locallyInside(p, hole) &&
(tanCur < tanMin ||
(tanCur == tanMin && (p->x > m->x || sectorContainsSector(m, p))))) {
m = p;
tanMin = tanCur;
}
}
p = p->next;
} while (p != stop);
return m;
}
// whether sector in vertex m contains sector in vertex p in the same
// coordinates
template <typename N>
bool Earcut<N>::sectorContainsSector(const Node* m, const Node* p) {
return area(m->prev, m, p->prev) < 0 && area(p->next, m, m->next) < 0;
}
// interlink polygon nodes in z-order
template <typename N>
void Earcut<N>::indexCurve(Node* start) {
assert(start);
Node* p = start;
do {
p->z = p->z ? p->z : zOrder(p->x, p->y);
p->prevZ = p->prev;
p->nextZ = p->next;
p = p->next;
} while (p != start);
p->prevZ->nextZ = nullptr;
p->prevZ = nullptr;
sortLinked(p);
}
// Simon Tatham's linked list merge sort algorithm
// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
template <typename N>
typename Earcut<N>::Node* Earcut<N>::sortLinked(Node* list) {
assert(list);
Node* p;
Node* q;
Node* e;
Node* tail;
int i, numMerges, pSize, qSize;
int inSize = 1;
for (;;) {
p = list;
list = nullptr;
tail = nullptr;
numMerges = 0;
while (p) {
numMerges++;
q = p;
pSize = 0;
for (i = 0; i < inSize; i++) {
pSize++;
q = q->nextZ;
if (!q) break;
}
qSize = inSize;
while (pSize > 0 || (qSize > 0 && q)) {
if (pSize == 0) {
e = q;
q = q->nextZ;
qSize--;
} else if (qSize == 0 || !q) {
e = p;
p = p->nextZ;
pSize--;
} else if (p->z <= q->z) {
e = p;
p = p->nextZ;
pSize--;
} else {
e = q;
q = q->nextZ;
qSize--;
}
if (tail)
tail->nextZ = e;
else
list = e;
e->prevZ = tail;
tail = e;
}
p = q;
}
tail->nextZ = nullptr;
if (numMerges <= 1) return list;
inSize *= 2;
}
}
// z-order of a Vertex given coords and size of the data bounding box
template <typename N>
int32_t Earcut<N>::zOrder(const double x_, const double y_) {
// coords are transformed into non-negative 15-bit integer range
int32_t x = static_cast<int32_t>(32767.0 * (x_ - minX) * inv_size);
int32_t y = static_cast<int32_t>(32767.0 * (y_ - minY) * inv_size);
x = (x | (x << 8)) & 0x00FF00FF;
x = (x | (x << 4)) & 0x0F0F0F0F;
x = (x | (x << 2)) & 0x33333333;
x = (x | (x << 1)) & 0x55555555;
y = (y | (y << 8)) & 0x00FF00FF;
y = (y | (y << 4)) & 0x0F0F0F0F;
y = (y | (y << 2)) & 0x33333333;
y = (y | (y << 1)) & 0x55555555;
return x | (y << 1);
}
// find the leftmost node of a polygon ring
template <typename N>
typename Earcut<N>::Node* Earcut<N>::getLeftmost(Node* start) {
Node* p = start;
Node* leftmost = start;
do {
if (p->x < leftmost->x || (p->x == leftmost->x && p->y < leftmost->y))
leftmost = p;
p = p->next;
} while (p != start);
return leftmost;
}
// check if a point lies within a convex triangle
template <typename N>
bool Earcut<N>::pointInTriangle(double ax, double ay, double bx, double by,
double cx, double cy, double px,
double py) const {
return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&
(ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&
(bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
}
// check if a diagonal between two polygon nodes is valid (lies in polygon
// interior)
template <typename N>
bool Earcut<N>::isValidDiagonal(Node* a, Node* b) {
return a->next->i != b->i && a->prev->i != b->i &&
!intersectsPolygon(a, b) && // dones't intersect other edges
((locallyInside(a, b) && locallyInside(b, a) &&
middleInside(a, b) && // locally visible
(area(a->prev, a, b->prev) != 0.0 ||
area(a, b->prev, b) !=
0.0)) || // does not create opposite-facing sectors
(equals(a, b) && area(a->prev, a, a->next) > 0 &&
area(b->prev, b, b->next) > 0)); // special zero-length case
}
// signed area of a triangle
template <typename N>
double Earcut<N>::area(const Node* p, const Node* q, const Node* r) const {
return (q->y - p->y) * (r->x - q->x) - (q->x - p->x) * (r->y - q->y);
}
// check if two points are equal
template <typename N>
bool Earcut<N>::equals(const Node* p1, const Node* p2) {
return p1->x == p2->x && p1->y == p2->y;
}
// check if two segments intersect
template <typename N>
bool Earcut<N>::intersects(const Node* p1, const Node* q1, const Node* p2,
const Node* q2) {
int o1 = sign(area(p1, q1, p2));
int o2 = sign(area(p1, q1, q2));
int o3 = sign(area(p2, q2, p1));
int o4 = sign(area(p2, q2, q1));
if (o1 != o2 && o3 != o4) return true; // general case
if (o1 == 0 && onSegment(p1, p2, q1))
return true; // p1, q1 and p2 are collinear and p2 lies on p1q1
if (o2 == 0 && onSegment(p1, q2, q1))
return true; // p1, q1 and q2 are collinear and q2 lies on p1q1
if (o3 == 0 && onSegment(p2, p1, q2))
return true; // p2, q2 and p1 are collinear and p1 lies on p2q2
if (o4 == 0 && onSegment(p2, q1, q2))
return true; // p2, q2 and q1 are collinear and q1 lies on p2q2
return false;
}
// for collinear points p, q, r, check if point q lies on segment pr
template <typename N>
bool Earcut<N>::onSegment(const Node* p, const Node* q, const Node* r) {
return q->x <= std::max<double>(p->x, r->x) &&
q->x >= std::min<double>(p->x, r->x) &&
q->y <= std::max<double>(p->y, r->y) &&
q->y >= std::min<double>(p->y, r->y);
}
template <typename N>
int Earcut<N>::sign(double val) {
return (0.0 < val) - (val < 0.0);
}
// check if a polygon diagonal intersects any polygon segments
template <typename N>
bool Earcut<N>::intersectsPolygon(const Node* a, const Node* b) {
const Node* p = a;
do {
if (p->i != a->i && p->next->i != a->i && p->i != b->i &&
p->next->i != b->i && intersects(p, p->next, a, b))
return true;
p = p->next;
} while (p != a);
return false;
}
// check if a polygon diagonal is locally inside the polygon
template <typename N>
bool Earcut<N>::locallyInside(const Node* a, const Node* b) {
return area(a->prev, a, a->next) < 0
? area(a, b, a->next) >= 0 && area(a, a->prev, b) >= 0
: area(a, b, a->prev) < 0 || area(a, a->next, b) < 0;
}
// check if the middle Vertex of a polygon diagonal is inside the polygon
template <typename N>
bool Earcut<N>::middleInside(const Node* a, const Node* b) {
const Node* p = a;
bool inside = false;
double px = (a->x + b->x) / 2;
double py = (a->y + b->y) / 2;
do {
if (((p->y > py) != (p->next->y > py)) && p->next->y != p->y &&
(px < (p->next->x - p->x) * (py - p->y) / (p->next->y - p->y) + p->x))
inside = !inside;
p = p->next;
} while (p != a);
return inside;
}
// link two polygon vertices with a bridge; if the vertices belong to the same
// ring, it splits polygon into two; if one belongs to the outer ring and
// another to a hole, it merges it into a single ring
template <typename N>
typename Earcut<N>::Node* Earcut<N>::splitPolygon(Node* a, Node* b) {
Node* a2 = nodes.construct(a->i, a->x, a->y);
Node* b2 = nodes.construct(b->i, b->x, b->y);
Node* an = a->next;
Node* bp = b->prev;
a->next = b;
b->prev = a;
a2->next = an;
an->prev = a2;
b2->next = a2;
a2->prev = b2;
bp->next = b2;
b2->prev = bp;
return b2;
}
// create a node and util::optionally link it with previous one (in a circular
// doubly linked list)
template <typename N>
template <typename Point>
typename Earcut<N>::Node* Earcut<N>::insertNode(std::size_t i, const Point& pt,
Node* last) {
Node* p = nodes.construct(static_cast<N>(i), util::nth<0, Point>::get(pt),
util::nth<1, Point>::get(pt));
if (!last) {
p->prev = p;
p->next = p;
} else {
assert(last);
p->next = last->next;
p->prev = last;
last->next->prev = p;
last->next = p;
}
return p;
}
template <typename N>
void Earcut<N>::removeNode(Node* p) {
p->next->prev = p->prev;
p->prev->next = p->next;
if (p->prevZ) p->prevZ->nextZ = p->nextZ;
if (p->nextZ) p->nextZ->prevZ = p->prevZ;
}
} // namespace detail
template <typename N = uint32_t, typename Polygon>
std::vector<N> earcut(const Polygon& poly) {
mapbox::detail::Earcut<N> earcut;
earcut(poly);
return std::move(earcut.indices);
}
} // namespace mapbox
@@ -0,0 +1,67 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "../builder/mesh_builder_data.hpp"
#include <string>
#include "renderer/models/color.hpp"
#include "loaders/3d/obj_loader/tiny_obj_loader.hpp"
#include <memory.h>
#include <optional>
namespace Tyra {
struct ObjLoaderAnimationOptions {
u16 count = 1;
u16 startingIndex = 1;
};
struct ObjLoaderOptions {
bool flipUVs = false;
float scale = 1.0F;
ObjLoaderAnimationOptions animation;
};
struct MaterialVertexCount {
size_t materialId;
int count;
};
/** Class responsible for loading & parsing obj files */
class ObjLoader {
public:
static std::unique_ptr<MeshBuilderData> load(const char* fullpath);
static std::unique_ptr<MeshBuilderData> load(const char* fullpath,
const ObjLoaderOptions& options);
static std::unique_ptr<MeshBuilderData> load(const std::string& fullpath);
static std::unique_ptr<MeshBuilderData> load(const std::string& fullpath,
const ObjLoaderOptions& options);
private:
static void addOutputMaterialsAndFrames(
MeshBuilderData* output, const tinyobj::attrib_t& attrib,
const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials, const u16& framesCount,
std::vector<MaterialVertexCount>& materialVertexCounts);
static std::vector<MaterialVertexCount> scan(
const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials);
static void importFrame(MeshBuilderData* output,
const tinyobj::attrib_t& attrib,
const std::vector<tinyobj::shape_t>& shapes,
const std::vector<tinyobj::material_t>& materials,
const u16& frameIndex, const float& scale,
const bool& invertY, const u16& count);
};
} // namespace Tyra
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,34 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "loaders/texture/builder/texture_builder_data.hpp"
#include "renderer/core/texture/models/texture_bpp.hpp"
#include <string>
namespace Tyra {
class TextureLoader {
public:
/**
* @brief Loads texture data from file.
* Sets size, name and data.
* @param fullpath Full path to texture file. Example: "host:texture.png"
*/
virtual TextureBuilderData* load(const char* fullpath) = 0;
inline TextureBuilderData* load(const std::string& fullpath) {
return load(fullpath.c_str());
}
u32 getTextureSize(const u32& width, const u32& height,
const TextureBpp& bpp);
};
} // namespace Tyra
@@ -0,0 +1,34 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "loaders/texture/base/texture_loader.hpp"
#include "loaders/texture/png_loader.hpp"
#include <string>
namespace Tyra {
class TextureLoaderSelector {
public:
TextureLoaderSelector();
~TextureLoaderSelector();
TextureLoader& getLoaderByFileName(const char* fullpath);
inline TextureLoader& getLoaderByFileName(const std::string& fullpath) {
return getLoaderByFileName(fullpath.c_str());
}
TextureLoader& getLoaderByExtension(const std::string& extension);
private:
PngLoader pngLoader;
};
} // namespace Tyra
@@ -0,0 +1,36 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tamtypes.h>
#include <string>
#include "renderer/core/texture/models/texture_bpp.hpp"
namespace Tyra {
class TextureBuilderData {
public:
TextureBuilderData();
~TextureBuilderData();
std::string name;
int width, height;
unsigned char* data;
TextureBpp bpp;
unsigned char gsComponents;
int clutWidth, clutHeight;
unsigned char* clut;
TextureBpp clutBpp;
unsigned char clutGsComponents;
};
} // namespace Tyra
+68
View File
@@ -0,0 +1,68 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "loaders/texture/base/texture_loader.hpp"
#include "renderer/core/texture/models/texture.hpp"
#ifdef INTELLISENSE
typedef void* png_structp;
typedef void* png_bytep;
typedef void* png_infop;
typedef void* png_colorp;
#else
#include <png.h>
#endif
namespace Tyra {
struct PngPixel3 {
u8 r, g, b;
};
struct PngPixel4 {
u8 r, g, b, a;
};
class PngLoader : public TextureLoader {
public:
PngLoader();
~PngLoader();
inline TextureBuilderData* load(const std::string& fullpath) {
return load(fullpath.c_str());
}
TextureBuilderData* load(const char* fullpath);
private:
void handle32bpp(TextureBuilderData* result, png_structp pngPtr,
png_infop infoPtr, png_bytep* rowPointers);
void handle24bpp(TextureBuilderData* result, png_structp pngPtr,
png_infop infoPtr, png_bytep* rowPointers);
void handlePalletized(TextureBuilderData* result, png_structp pngPtr,
png_infop infoPtr, png_bytep* rowPointers,
const int& bitDepth);
void handle8bppPalletized(TextureBuilderData* result, png_structp pngPtr,
png_infop infoPtr, png_bytep* rowPointers,
png_colorp palette, png_bytep trans,
const int& numPallete, const int& numTrans);
void handle4bppPalletized(TextureBuilderData* result, png_structp pngPtr,
png_infop infoPtr, png_bytep* rowPointers,
png_colorp palette, png_bytep trans,
const int& numPallete, const int& numTrans);
};
} // namespace Tyra
+116
View File
@@ -0,0 +1,116 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "math/vec4.hpp"
#include "math/math.hpp"
#include <string>
namespace Tyra {
class M4x4 {
public:
MATRIX data alignas(sizeof(float) * 16);
static const M4x4 Identity;
/** Create matrix with random values */
M4x4() {}
M4x4(const M4x4& v) { copy(this, v); }
explicit M4x4(const float* v) { copy(this, v); }
M4x4(const float& m11, const float& m12, const float& m13, const float& m14,
const float& m21, const float& m22, const float& m23, const float& m24,
const float& m31, const float& m32, const float& m33, const float& m34,
const float& m41, const float& m42, const float& m43, const float& m44);
static void copy(M4x4* out, const float* in);
static void copy(M4x4* out, const M4x4& in);
void operator=(const M4x4& v);
Vec4 operator*(const Vec4& v) const;
M4x4 operator*(const M4x4& v) const;
void operator*=(const M4x4& v);
float& operator[](const u8& index);
/**
* 1 0 0 0
* 0 1 0 0
* 0 0 1 0
* 0 0 0 1
*/
void identity();
inline void unit() { identity(); }
void set(const float& m11, const float& m12, const float& m13,
const float& m14, const float& m21, const float& m22,
const float& m23, const float& m24, const float& m31,
const float& m32, const float& m33, const float& m34,
const float& m41, const float& m42, const float& m43,
const float& m44);
void translate(const Vec4& v);
void translateX(const float& v);
void translateY(const float& v);
void translateZ(const float& v);
void rotateByAngle(const float& angle, const Vec4& axis);
void rotate(const Vec4& v);
void rotateX(const float& radians);
void rotateY(const float& radians);
void rotateZ(const float& radians);
void scale(const float& v);
void scale(const Vec4& v);
void scaleX(const float& v);
void scaleY(const float& v);
void scaleZ(const float& v);
/** Create perspective projection M4x4 (gluPerspective) */
static M4x4 perspective(const float& fov, const float& width,
const float& height, const float& projectionScale,
const float& aspectRatio, const float& near,
const float& far);
/**
* Create a view M4x4 that transforms coordinates in
* such a way that the user looks at a target vector
* direction from a position vector (glLookAt)
*/
static M4x4 lookAt(const Vec4& position, const Vec4& target);
static void lookAt(M4x4* res, const Vec4& position, const Vec4& target);
void print() const;
void print(const char* name) const;
void print(const std::string& name) const { print(name.c_str()); }
std::string getPrint(const char* name = nullptr) const;
private:
static float upVec[4] alignas(sizeof(float) * 4);
static float viewVec[4] alignas(sizeof(float) * 4);
static void cross(float res[16], const float a[16], const float b[16]);
void rotationX(const float& v);
void rotationY(const float& v);
void rotationZ(const float& v);
void rotationByAngle(const float& angle, const Vec4& axis);
void translationX(const float& v);
void translationY(const float& v);
void translationZ(const float& v);
void setScale(const Vec4& val);
static M4x4 setCamera(const float pos[4], const float vz[4],
const float vy[4]);
};
} // namespace Tyra
+44
View File
@@ -0,0 +1,44 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
extern "C" {
#include <tamtypes.h>
}
#include <math.h>
namespace Tyra {
class Math {
public:
constexpr static float HALF_ANG2RAD = 3.14159265358979323846F / 360.0F;
constexpr static float ANG2RAD = 3.14159265358979323846F / 180.0F;
constexpr static float PI = 3.1415926535897932384626433832795F;
constexpr static float HALF_PI = 1.5707963267948966192313216916398F;
static float cos(float x);
static float asin(float x);
static float atan2(float y, float x);
static float mod(const float& x, const float& y);
static float acos(const float& x);
static float sin(const float& x);
static float tan(const float& x);
static float invSqrt(const float& x);
static float randomf(const float& min, const float& max);
static int randomi(const int& min, const int& max);
static bool equalf(const float& a, const float& b,
const float& epsilon = 0.00001F);
private:
Math();
};
} // namespace Tyra
+37
View File
@@ -0,0 +1,37 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include "./vec4.hpp"
#include <string>
namespace Tyra {
class Plane {
public:
Vec4 normal;
float distance;
Plane();
Plane(const Vec4& a, const Vec4& b, const Vec4& c);
~Plane();
void update(const Vec4& a, const Vec4& b, const Vec4& c);
float distanceTo(const Vec4& t_vec) const;
void print() const;
void print(const char* name) const;
void print(const std::string& name) const { print(name.c_str()); }
std::string getPrint(const char* name = nullptr) const;
};
} // namespace Tyra
+70
View File
@@ -0,0 +1,70 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
extern "C" {
#include <stdio.h>
#include <tamtypes.h>
}
#include <string>
#include "math/math.hpp"
namespace Tyra {
class Vec2 {
public:
union {
struct {
float x;
float y;
};
float xy[2] alignas(sizeof(float) * 2);
};
Vec2(const float& t_x, const float& t_y);
Vec2(const Vec2& v);
Vec2();
~Vec2();
void operator=(const Vec2& v);
Vec2 operator+(const Vec2& v) const;
Vec2 operator-(const Vec2& v) const;
Vec2 operator*(const Vec2& v) const;
Vec2 operator/(const Vec2& v) const;
Vec2 operator+(const float& v) const;
Vec2 operator-(const float& v) const;
Vec2 operator*(const float& v) const;
Vec2 operator/(const float& v) const;
void operator+=(const Vec2& v);
void operator-=(const Vec2& v);
void operator*=(const Vec2& v);
void operator/=(const Vec2& v);
void operator+=(const float& v);
void operator-=(const float& v);
void operator*=(const float& v);
void operator/=(const float& v);
void set(const float& t_x, const float& t_y);
void set(const Vec2& v);
void rotate(const float& t_angle, const float& t_x, const float& t_y);
void print() const;
void print(const char* name) const;
void print(const std::string& name) const { print(name.c_str()); }
std::string getPrint(const char* name = nullptr) const;
};
} // namespace Tyra
+161
View File
@@ -0,0 +1,161 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
extern "C" {
#include <stdio.h>
#include <tamtypes.h>
}
#include <math3d.h>
#include <string>
#include "math/math.hpp"
namespace Tyra {
class Vec4 {
public:
union {
struct {
float x;
float y;
float z;
float w;
};
VECTOR xyzw alignas(sizeof(float) * 4);
};
static void copy(Vec4* out, const float* in);
static inline void copy(Vec4* out, const Vec4& in) { copy(out, in.xyzw); }
static const Vec4 Identity;
/** Initialize Vec4 without setting default values */
Vec4() {}
/** Initialize Vec4 with provided values */
Vec4(const float& x, const float& y = 0.0F, const float& z = 0.0F,
const float& w = 1.0F)
: x(x), y(y), z(z), w(w) {}
/** Initialize Vec4 with other Vec4 values */
Vec4(const Vec4& v) { copy(this, v); }
/** Initialize Vec4 with float[4] values */
explicit Vec4(const float* v) { copy(this, v); }
/** copy */
void operator=(const Vec4& v);
/** negate xyz */
Vec4 operator-(void) const;
/** xyz + xyz */
Vec4 operator+(const Vec4& v) const;
void operator+=(const Vec4& v);
/** xyz - xyz */
Vec4 operator-(const Vec4& v) const;
void operator-=(const Vec4& v);
/** xyzw * xyzw */
Vec4 operator*(const Vec4& v) const;
void operator*=(const Vec4& v);
/** xyzw / xyzw */
Vec4 operator/(const Vec4& v) const;
void operator/=(const Vec4& v);
/** xyz * v */
Vec4 operator*(const float& v) const;
void operator*=(const float& v);
/** xyz / v */
Vec4 operator/(const float& v) const;
void operator/=(const float& v);
/** (0,0,0,1) */
void unit();
inline void set(const Vec4& v) { copy(this, v.xyzw); }
inline void set(const float* v) { copy(this, v); }
void set(const float& x, const float& y = 0.0F, const float& z = 0.0F,
const float& w = 1.0F);
Vec4 cross(const Vec4& v) const;
void rotateZ(const int& angle);
int getRelativeCosBetween(const Vec4& v) const;
int getRelativeAngleBetween(const Vec4& v) const;
float innerProduct(const Vec4& v) const;
inline float dot3(const Vec4& v) const { return innerProduct(v); }
/** Get vector length */
float length() const;
/** Normalize vector */
void normalize();
Vec4 getNormalized() const;
/** Returns distance between two vectors */
float distanceTo(const Vec4& v) const;
/**
* Checks intersection with given box
* @param min Opposite min vertex (ex. near, left, down vertex of bounding
* box)
* @param max Opposite max vertex (ex. far, right, up vertex of bounding
* box)
*/
bool collidesBox(const Vec4& min, const Vec4& max) const;
/**
* Checks if this vector is on given box (this->y >= box.y)
* @param min Opposite min vertex (ex. near, left, down vertex of bounding
* box)
* @param max Opposite max vertex (ex. far, right, up vertex of bounding
* box)
*/
bool isOnBox(const Vec4& min, const Vec4& max) const;
/** Check if given triangle should be backface culled */
static u8 shouldBeBackfaceCulled(const Vec4* cameraPos, const Vec4* v0,
const Vec4* v1, const Vec4* v2);
/**
* Update this vector by linear interpolation between two vertices
* @param v1 Before vertex
* @param v2 After vertex
* @param interp State of interpolation
*/
void lerp(const Vec4& v1, const Vec4& v2, const float& interp);
/**
* Get vector by linear interpolation between two vertices
* @param v1 Before vertex
* @param v2 After vertex
* @param interp State of interpolation
*/
static Vec4 getByLerp(const Vec4& v1, const Vec4& v2, const float& interp);
void print() const;
void print(const char* name) const;
void print(const std::string& name) const { print(name.c_str()); }
std::string getPrint(const char* name = nullptr) const;
static void setLerp(Vec4* output, const Vec4& v1, const Vec4& v2,
const float& interp);
};
} // namespace Tyra

Some files were not shown because too many files have changed in this diff Show More